simpo-component-library 3.6.932 → 3.6.935

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 (268) hide show
  1. package/README.md +24 -24
  2. package/esm2022/lib/components/delete-hover-element/delete-hover-element.component.mjs +3 -3
  3. package/esm2022/lib/components/deprecated-section/deprecated-section.component.mjs +32 -0
  4. package/esm2022/lib/components/document/document.component.mjs +3 -3
  5. package/esm2022/lib/components/image-loading/image-loading.component.mjs +3 -3
  6. package/esm2022/lib/components/payment-details/payment-details.component.mjs +3 -3
  7. package/esm2022/lib/constants/business.constant.mjs +1 -1
  8. package/esm2022/lib/directive/alignment.directive.mjs +1 -1
  9. package/esm2022/lib/directive/blur-content.directive.mjs +1 -1
  10. package/esm2022/lib/directive/borderlessImage.directive.mjs +1 -1
  11. package/esm2022/lib/directive/button-directive.directive.mjs +1 -1
  12. package/esm2022/lib/directive/button-editor.directive.mjs +1 -1
  13. package/esm2022/lib/directive/color.directive.mjs +1 -1
  14. package/esm2022/lib/directive/column-directive.directive.mjs +1 -1
  15. package/esm2022/lib/directive/container-alignment.directive.mjs +1 -1
  16. package/esm2022/lib/directive/container-fir.directive.mjs +1 -1
  17. package/esm2022/lib/directive/content-title-spacing.directive.mjs +1 -1
  18. package/esm2022/lib/directive/contenteditable.directive.mjs +1 -1
  19. package/esm2022/lib/directive/corner-directive.mjs +1 -1
  20. package/esm2022/lib/directive/height.directive.mjs +1 -1
  21. package/esm2022/lib/directive/hover-animation.directive.mjs +1 -1
  22. package/esm2022/lib/directive/hoverborder.directive.mjs +1 -1
  23. package/esm2022/lib/directive/icon-directive.directive.mjs +1 -1
  24. package/esm2022/lib/directive/image-container.directive.mjs +1 -1
  25. package/esm2022/lib/directive/image-directive.directive.mjs +1 -1
  26. package/esm2022/lib/directive/image-editor.directive.mjs +1 -1
  27. package/esm2022/lib/directive/image-position.directive.mjs +1 -1
  28. package/esm2022/lib/directive/letters-only.directive.mjs +1 -1
  29. package/esm2022/lib/directive/merge-header.directive.mjs +1 -1
  30. package/esm2022/lib/directive/numbers-only.directive.mjs +1 -1
  31. package/esm2022/lib/directive/position-layout-directive.directive.mjs +1 -1
  32. package/esm2022/lib/directive/set-dynamic-background.directive.mjs +1 -1
  33. package/esm2022/lib/directive/spacing-around.directive.mjs +1 -1
  34. package/esm2022/lib/directive/spacing-horizontal.directive.mjs +1 -1
  35. package/esm2022/lib/directive/spacing.directive.mjs +1 -1
  36. package/esm2022/lib/directive/sticky-directive.mjs +1 -1
  37. package/esm2022/lib/directive/text-background-directive.directive.mjs +1 -1
  38. package/esm2022/lib/directive/text-size.directive.mjs +1 -1
  39. package/esm2022/lib/directive/translate-onhover.directive.mjs +1 -1
  40. package/esm2022/lib/directive/video-directive.directive.mjs +1 -1
  41. package/esm2022/lib/directive/wrap-containers.directive.mjs +1 -1
  42. package/esm2022/lib/ecommerce/sections/address/address.component.mjs +3 -3
  43. package/esm2022/lib/ecommerce/sections/authenticate-user/authenticate-user.component.mjs +3 -3
  44. package/esm2022/lib/ecommerce/sections/authentication-required/authentication-required.component.mjs +15 -3
  45. package/esm2022/lib/ecommerce/sections/authentication-required/authentication-required.model.mjs +1 -1
  46. package/esm2022/lib/ecommerce/sections/cart/cart.component.mjs +12 -61
  47. package/esm2022/lib/ecommerce/sections/cart/cart.modal.mjs +1 -1
  48. package/esm2022/lib/ecommerce/sections/categories-with-image-background-columns/categories-with-image-background-columns.component.mjs +3 -3
  49. package/esm2022/lib/ecommerce/sections/category-product/category-product.component.mjs +3 -3
  50. package/esm2022/lib/ecommerce/sections/category-product/category-product.model.mjs +1 -1
  51. package/esm2022/lib/ecommerce/sections/checkout/checkout.component.mjs +3 -3
  52. package/esm2022/lib/ecommerce/sections/checkout/checkout.modal.mjs +1 -1
  53. package/esm2022/lib/ecommerce/sections/customer-review/customer-review.component.mjs +3 -3
  54. package/esm2022/lib/ecommerce/sections/customer-review/customer-review.model.mjs +1 -1
  55. package/esm2022/lib/ecommerce/sections/enrollment-form/enrollment-form.component.mjs +3 -3
  56. package/esm2022/lib/ecommerce/sections/enrollment-form/enrollment-form.model.mjs +1 -1
  57. package/esm2022/lib/ecommerce/sections/featured-category/featured-category.component.mjs +3 -3
  58. package/esm2022/lib/ecommerce/sections/featured-category/featured-category.modal.mjs +1 -1
  59. package/esm2022/lib/ecommerce/sections/featured-category/featured-collection.component.mjs +3 -3
  60. package/esm2022/lib/ecommerce/sections/featured-products/featured-products.component.mjs +3 -3
  61. package/esm2022/lib/ecommerce/sections/featured-products/featured-products.modal.mjs +1 -1
  62. package/esm2022/lib/ecommerce/sections/item-varient/item-varient.component.mjs +3 -3
  63. package/esm2022/lib/ecommerce/sections/new-collection/new-collection.component.mjs +3 -3
  64. package/esm2022/lib/ecommerce/sections/new-collection/new-collection.modal.mjs +1 -1
  65. package/esm2022/lib/ecommerce/sections/order-details/order-details.component.mjs +3 -3
  66. package/esm2022/lib/ecommerce/sections/pagnination/pagnination.component.mjs +3 -3
  67. package/esm2022/lib/ecommerce/sections/passbook-transactions/passbook-transactions.component.mjs +3 -3
  68. package/esm2022/lib/ecommerce/sections/product-category-list/product-category-list.component.mjs +3 -3
  69. package/esm2022/lib/ecommerce/sections/product-category-list/product-category-list.model.mjs +1 -1
  70. package/esm2022/lib/ecommerce/sections/product-desc/product-desc.component.mjs +63 -37
  71. package/esm2022/lib/ecommerce/sections/product-desc/product-desc.modal.mjs +1 -1
  72. package/esm2022/lib/ecommerce/sections/product-list/product-list.component.mjs +48 -37
  73. package/esm2022/lib/ecommerce/sections/product-list/product-list.modal.mjs +1 -1
  74. package/esm2022/lib/ecommerce/sections/refer-earn/refer-earn.component.mjs +3 -3
  75. package/esm2022/lib/ecommerce/sections/refer-earn/refer-earn.modal.mjs +1 -1
  76. package/esm2022/lib/ecommerce/sections/returns-calculator/returns-calculator.component.mjs +1 -1
  77. package/esm2022/lib/ecommerce/sections/returns-calculator/returns-calculator.model.mjs +1 -1
  78. package/esm2022/lib/ecommerce/sections/scheme-details/scheme-details.component.mjs +3 -3
  79. package/esm2022/lib/ecommerce/sections/scheme-selection/scheme-selection.component.mjs +3 -3
  80. package/esm2022/lib/ecommerce/sections/schemes/schemes.component.mjs +3 -3
  81. package/esm2022/lib/ecommerce/sections/schemes/schemes.component.model.mjs +1 -1
  82. package/esm2022/lib/ecommerce/sections/small-product-listing/small-product-listing.component.mjs +3 -3
  83. package/esm2022/lib/ecommerce/sections/store-list/store-list.component.mjs +3 -3
  84. package/esm2022/lib/ecommerce/sections/store-list/store-list.modal.mjs +1 -1
  85. package/esm2022/lib/ecommerce/sections/store-page/store-page.component.mjs +3 -3
  86. package/esm2022/lib/ecommerce/sections/store-page/store-page.model.mjs +1 -1
  87. package/esm2022/lib/ecommerce/sections/user-basic-info/user-basic-info.component.mjs +3 -3
  88. package/esm2022/lib/ecommerce/sections/user-profile/user-profile.modal.mjs +1 -1
  89. package/esm2022/lib/ecommerce/sections/verify-payment/verify-payment.component.mjs +3 -3
  90. package/esm2022/lib/ecommerce/sections/verify-payment/verify-payment.model.mjs +1 -1
  91. package/esm2022/lib/ecommerce/sections/whislist/whislist.component.mjs +3 -3
  92. package/esm2022/lib/ecommerce/styles/BaseCollection.modal.mjs +1 -1
  93. package/esm2022/lib/ecommerce/styles/Collection.modal.mjs +1 -1
  94. package/esm2022/lib/ecommerce/styles/OrderedItems.modal.mjs +1 -1
  95. package/esm2022/lib/ecommerce/styles/PincodeLocation.model.mjs +1 -1
  96. package/esm2022/lib/ecommerce/styles/PincodeLocationInter.model.mjs +1 -1
  97. package/esm2022/lib/ecommerce/styles/cart.modal.mjs +1 -1
  98. package/esm2022/lib/ecommerce/styles/category.modal.mjs +1 -1
  99. package/esm2022/lib/ecommerce/styles/order.modal.mjs +1 -1
  100. package/esm2022/lib/ecommerce/styles/product.modal.mjs +1 -1
  101. package/esm2022/lib/ecommerce/styles/review.modal.mjs +1 -1
  102. package/esm2022/lib/ecommerce/styles/user.modal.mjs +1 -1
  103. package/esm2022/lib/elements/add-section/add-section.component.mjs +3 -3
  104. package/esm2022/lib/elements/address-list/address-list.component.mjs +3 -3
  105. package/esm2022/lib/elements/below-image-card/below-image-card.component.mjs +3 -3
  106. package/esm2022/lib/elements/booking-cart-groups/booking-cart-groups.component.mjs +82 -0
  107. package/esm2022/lib/elements/button/button.component.mjs +3 -3
  108. package/esm2022/lib/elements/button/button.model.mjs +1 -1
  109. package/esm2022/lib/elements/card-skeleton-loader/card-skeleton-loader.component.mjs +3 -3
  110. package/esm2022/lib/elements/covering-image-card/covering-image-card.component.mjs +3 -3
  111. package/esm2022/lib/elements/editor-service.service.mjs +1 -1
  112. package/esm2022/lib/elements/heading-element/heading-element.component.mjs +3 -3
  113. package/esm2022/lib/elements/index.mjs +1 -1
  114. package/esm2022/lib/elements/link-editor/link-editor.component.mjs +3 -3
  115. package/esm2022/lib/elements/list-home-appointment/list-home-appointment.component.mjs +3 -3
  116. package/esm2022/lib/elements/media-selector/media-selector.component.mjs +3 -3
  117. package/esm2022/lib/elements/portfolio/portfolio.component.mjs +3 -3
  118. package/esm2022/lib/elements/pricing-s1/pricing-s1.component.mjs +3 -3
  119. package/esm2022/lib/elements/property/property.component.mjs +3 -3
  120. package/esm2022/lib/elements/schedule-video-call/schedule-video-call.component.mjs +35 -22
  121. package/esm2022/lib/elements/simpo-button/simpo-button.component.mjs +3 -3
  122. package/esm2022/lib/elements/svg-divider/svg-divider.component.mjs +3 -3
  123. package/esm2022/lib/elements/text/text.component.mjs +3 -3
  124. package/esm2022/lib/elements/text-editor/text-editor.component.mjs +9 -9
  125. package/esm2022/lib/elements/top-of-image-card/top-of-image-card.component.mjs +3 -3
  126. package/esm2022/lib/pipes/amount.pipe.mjs +1 -1
  127. package/esm2022/lib/pipes/gender.pipe.mjs +1 -1
  128. package/esm2022/lib/sections/BaseSection.mjs +1 -1
  129. package/esm2022/lib/sections/add-new-section/add-new-section.component.mjs +3 -3
  130. package/esm2022/lib/sections/appointment-form/appointment-booking/appointment-booking/appointment-booking.component.mjs +320 -268
  131. package/esm2022/lib/sections/appointment-form/appointment-form.model.mjs +1 -1
  132. package/esm2022/lib/sections/banner-carousel/banner-carousel.component.mjs +3 -3
  133. package/esm2022/lib/sections/banner-carousel/banner-carousel.model.mjs +1 -1
  134. package/esm2022/lib/sections/banner-grid-section/banner-grid-section.component.mjs +3 -3
  135. package/esm2022/lib/sections/blog-list/blog-list.component.mjs +3 -3
  136. package/esm2022/lib/sections/blog-list/blog-list.model.mjs +1 -1
  137. package/esm2022/lib/sections/brand-story-section/brand-story-section.component.mjs +3 -3
  138. package/esm2022/lib/sections/brand-story-section/brand-story-section.modal.mjs +1 -1
  139. package/esm2022/lib/sections/button-grid-section/button-grid-section.component.mjs +3 -3
  140. package/esm2022/lib/sections/choose-us-section/choose-us-section.component.mjs +3 -3
  141. package/esm2022/lib/sections/choose-us-section/choose-us-section.model.mjs +1 -1
  142. package/esm2022/lib/sections/condensed-and-gradient/condensed-and-gradient.component.mjs +3 -3
  143. package/esm2022/lib/sections/countdown-banner/countdown-banner.component.mjs +3 -3
  144. package/esm2022/lib/sections/countdown-banner/countdown-banner.component.model.mjs +1 -1
  145. package/esm2022/lib/sections/faq-columns-cards/faq-columns-cards.component.mjs +3 -3
  146. package/esm2022/lib/sections/faq-columns-cards/faq-columns-cards.modal.mjs +1 -1
  147. package/esm2022/lib/sections/faq-section/faq-section.component.mjs +3 -3
  148. package/esm2022/lib/sections/faq-section/faq-section.modal.mjs +1 -1
  149. package/esm2022/lib/sections/feature-experience-section/feature-experience-section.component.mjs +3 -3
  150. package/esm2022/lib/sections/feature-experience-section/feature-experience-section.modal.mjs +1 -1
  151. package/esm2022/lib/sections/features-section/features-section.component.mjs +3 -3
  152. package/esm2022/lib/sections/features-section/features-section.model.mjs +1 -1
  153. package/esm2022/lib/sections/footer/footer.component.mjs +3 -3
  154. package/esm2022/lib/sections/footer/footer.modal.mjs +1 -1
  155. package/esm2022/lib/sections/four-features-centered-image/four-features-centered-image.component.mjs +3 -3
  156. package/esm2022/lib/sections/four-features-centered-image/four-features-centered-image.modal.mjs +1 -1
  157. package/esm2022/lib/sections/header-section/header-section.component.mjs +24 -3
  158. package/esm2022/lib/sections/header-section/header-section.model.mjs +1 -1
  159. package/esm2022/lib/sections/header-text/header-text.component.mjs +3 -3
  160. package/esm2022/lib/sections/header-text/header-text.model.mjs +1 -1
  161. package/esm2022/lib/sections/image-background/image-background/image-background.component.mjs +3 -3
  162. package/esm2022/lib/sections/image-background/image-background/image-background.component.model.mjs +1 -1
  163. package/esm2022/lib/sections/image-carousel-section/image-carousel-section.component.mjs +3 -3
  164. package/esm2022/lib/sections/image-carousel-section/image-carousel.model.mjs +1 -1
  165. package/esm2022/lib/sections/image-grid-hotspot/image-grid-hotspot.component.mjs +3 -3
  166. package/esm2022/lib/sections/image-grid-hotspot/image-grid-hotspot.model.mjs +1 -1
  167. package/esm2022/lib/sections/image-grid-section/image-grid-section.component.mjs +3 -3
  168. package/esm2022/lib/sections/image-grid-section/image-grid-section.model.mjs +1 -1
  169. package/esm2022/lib/sections/image-section/image-section.component.mjs +3 -3
  170. package/esm2022/lib/sections/image-section/image-section.model.mjs +1 -1
  171. package/esm2022/lib/sections/location-section/location-section.component.mjs +3 -3
  172. package/esm2022/lib/sections/location-section/location-section.modal.mjs +1 -1
  173. package/esm2022/lib/sections/logo-showcase/logo-showcase.component.mjs +3 -3
  174. package/esm2022/lib/sections/logo-showcase/logo-showcase.modal.mjs +1 -1
  175. package/esm2022/lib/sections/moving-text/moving-text.component.mjs +3 -3
  176. package/esm2022/lib/sections/moving-text/moving-text.modal.mjs +1 -1
  177. package/esm2022/lib/sections/navbar-section/navbar-section.component.mjs +10 -3
  178. package/esm2022/lib/sections/new-services/new-services.component.mjs +3 -3
  179. package/esm2022/lib/sections/new-services/new-services.model.mjs +1 -1
  180. package/esm2022/lib/sections/new-testimonials/new-testimonials.component.mjs +3 -3
  181. package/esm2022/lib/sections/new-testimonials/new-testimonials.model.mjs +1 -1
  182. package/esm2022/lib/sections/news-letter-component/news-letter-component.component.mjs +3 -3
  183. package/esm2022/lib/sections/news-letter-component/news-letter.modal.mjs +1 -1
  184. package/esm2022/lib/sections/overlapping-image/overlapping-image.component.mjs +3 -3
  185. package/esm2022/lib/sections/overlapping-image/overlapping-image.component.modal.mjs +1 -1
  186. package/esm2022/lib/sections/pricing-section/pricing-section.component.mjs +3 -3
  187. package/esm2022/lib/sections/pricing-section/pricing-section.modal.mjs +1 -1
  188. package/esm2022/lib/sections/process-modern/process-modern.component.mjs +3 -3
  189. package/esm2022/lib/sections/process-modern/process-modern.model.mjs +1 -1
  190. package/esm2022/lib/sections/process-section/process-section.component.mjs +3 -3
  191. package/esm2022/lib/sections/process-section/process-section.modal.mjs +1 -1
  192. package/esm2022/lib/sections/product-info-section/product-info-section.component.mjs +3 -3
  193. package/esm2022/lib/sections/product-info-section/product-info-section.component.modal.mjs +1 -1
  194. package/esm2022/lib/sections/property-component/property-component.component.mjs +3 -3
  195. package/esm2022/lib/sections/property-component/property-component.modal.mjs +1 -1
  196. package/esm2022/lib/sections/property-list/property-list.component.mjs +3 -3
  197. package/esm2022/lib/sections/property-list/property-list.modal.mjs +1 -1
  198. package/esm2022/lib/sections/recent-blog-post-section/recent-blog-post-section.component.mjs +3 -3
  199. package/esm2022/lib/sections/recent-blog-post-section/recent-blog-post-section.model.mjs +1 -1
  200. package/esm2022/lib/sections/registration-form/registration-form.component.mjs +3 -3
  201. package/esm2022/lib/sections/registration-form/registrationForm.model.mjs +1 -1
  202. package/esm2022/lib/sections/scheme-detail/scheme-detail.component.mjs +3 -3
  203. package/esm2022/lib/sections/scheme-detail/scheme-detail.modal.mjs +1 -1
  204. package/esm2022/lib/sections/service-section/service-section.component.mjs +3 -3
  205. package/esm2022/lib/sections/service-section/service-section.model.mjs +1 -1
  206. package/esm2022/lib/sections/skeleton-loader-section/skeleton-loader-section.component.mjs +3 -3
  207. package/esm2022/lib/sections/team-member-section/team-member-section.component.mjs +3 -3
  208. package/esm2022/lib/sections/team-member-section/team-member-section.model.mjs +1 -1
  209. package/esm2022/lib/sections/testimonial-fullwidth/testimonial-fullwidth.component.mjs +3 -3
  210. package/esm2022/lib/sections/testimonial-fullwidth/testimonial-fullwidth.model.mjs +1 -1
  211. package/esm2022/lib/sections/testimonial-masonry/testimonial-masonry.component.mjs +3 -3
  212. package/esm2022/lib/sections/testimonial-masonry/testimonial-masonry.model.mjs +1 -1
  213. package/esm2022/lib/sections/testimonial-section/testimonial-section.component.mjs +3 -3
  214. package/esm2022/lib/sections/testimonial-section/testimonial-section.model.mjs +1 -1
  215. package/esm2022/lib/sections/testimonial-slider/testimonial-slider.component.mjs +3 -3
  216. package/esm2022/lib/sections/testimonial-slider/testimonial-slider.model.mjs +1 -1
  217. package/esm2022/lib/sections/testimonial-video/testimonial-video.component.mjs +3 -3
  218. package/esm2022/lib/sections/testimonial-video/testimonial-video.model.mjs +1 -1
  219. package/esm2022/lib/sections/text-section/text-section.model.mjs +1 -1
  220. package/esm2022/lib/sections/usp-video-section/usp-video-section.component.mjs +3 -3
  221. package/esm2022/lib/sections/usp-video-section/usp-video-section.model.mjs +1 -1
  222. package/esm2022/lib/sections/video-carousel-section/video-carousel-section.component.mjs +3 -3
  223. package/esm2022/lib/sections/video-carousel-section/video-carousel.model.mjs +1 -1
  224. package/esm2022/lib/sections/video-grid-section/video-grid-section.component.mjs +3 -3
  225. package/esm2022/lib/sections/video-grid-section/video-grid-section.model.mjs +1 -1
  226. package/esm2022/lib/sections/video-section/video-section.component.mjs +3 -3
  227. package/esm2022/lib/sections/video-section/video-section.model.mjs +1 -1
  228. package/esm2022/lib/sections/video-showcase/video-showcase.component.mjs +3 -3
  229. package/esm2022/lib/sections/view-blog/view-blog.component.mjs +3 -3
  230. package/esm2022/lib/services/analytics.service.mjs +1 -1
  231. package/esm2022/lib/services/booking-product-cart.service.mjs +60 -0
  232. package/esm2022/lib/services/cart.service.mjs +1 -1
  233. package/esm2022/lib/services/endUser.service.mjs +1 -1
  234. package/esm2022/lib/services/image-upload-service.service.mjs +1 -1
  235. package/esm2022/lib/services/rest.service.mjs +15 -6
  236. package/esm2022/lib/services/sanitizeHtml.mjs +1 -1
  237. package/esm2022/lib/services/storage.service.mjs +79 -3
  238. package/esm2022/lib/styles/gradient-extension.mjs +1 -1
  239. package/esm2022/lib/styles/index.mjs +1 -1
  240. package/esm2022/lib/styles/style.model.mjs +1 -1
  241. package/esm2022/lib/styles/text-size.extension.mjs +1 -1
  242. package/esm2022/lib/styles/types.mjs +1 -1
  243. package/esm2022/lib/tokens/api-token.mjs +1 -1
  244. package/esm2022/public-api.mjs +2 -3
  245. package/fesm2022/simpo-component-library.mjs +6237 -6891
  246. package/fesm2022/simpo-component-library.mjs.map +1 -1
  247. package/lib/components/deprecated-section/deprecated-section.component.d.ts +19 -0
  248. package/lib/ecommerce/sections/cart/cart.component.d.ts +2 -6
  249. package/lib/ecommerce/sections/product-desc/product-desc.component.d.ts +13 -1
  250. package/lib/ecommerce/sections/product-list/product-list.component.d.ts +12 -2
  251. package/lib/elements/booking-cart-groups/booking-cart-groups.component.d.ts +38 -0
  252. package/lib/elements/schedule-video-call/schedule-video-call.component.d.ts +4 -3
  253. package/lib/sections/appointment-form/appointment-booking/appointment-booking/appointment-booking.component.d.ts +55 -23
  254. package/lib/sections/header-section/header-section.component.d.ts +7 -0
  255. package/lib/sections/navbar-section/navbar-section.component.d.ts +2 -0
  256. package/lib/services/booking-product-cart.service.d.ts +26 -0
  257. package/lib/services/rest.service.d.ts +5 -2
  258. package/lib/services/storage.service.d.ts +17 -0
  259. package/package.json +1 -1
  260. package/public-api.d.ts +1 -2
  261. package/simpo-component-library-3.6.935.tgz +0 -0
  262. package/esm2022/lib/ecommerce/sections/book-appointment/book-appointment.component.mjs +0 -199
  263. package/esm2022/lib/ecommerce/sections/book-appointment/book-appointment.model.mjs +0 -2
  264. package/esm2022/lib/sections/appointment-form/appointment-form.component.mjs +0 -866
  265. package/lib/ecommerce/sections/book-appointment/book-appointment.component.d.ts +0 -70
  266. package/lib/ecommerce/sections/book-appointment/book-appointment.model.d.ts +0 -14
  267. package/lib/sections/appointment-form/appointment-form.component.d.ts +0 -117
  268. package/simpo-component-library-3.6.932.tgz +0 -0
@@ -1,4 +1,4 @@
1
- import { Component, HostListener, Input } from '@angular/core';
1
+ import { Component, HostListener, Input, Optional } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import { CdkDragPlaceholder } from "@angular/cdk/drag-drop";
4
4
  import { MatIcon } from "@angular/material/icon";
@@ -16,16 +16,22 @@ import * as i1 from "../../../../services/rest.service";
16
16
  import * as i2 from "../../../../services/events.service";
17
17
  import * as i3 from "@angular/router";
18
18
  import * as i4 from "primeng/api";
19
- import * as i5 from "@angular/common";
20
- import * as i6 from "@angular/material/datepicker";
21
- import * as i7 from "@angular/forms";
22
- import * as i8 from "primeng/toast";
19
+ import * as i5 from "../../../../services/booking-product-cart.service";
20
+ import * as i6 from "../../../../services/storage.service";
21
+ import * as i7 from "@angular/material/dialog";
22
+ import * as i8 from "@angular/common";
23
+ import * as i9 from "@angular/material/datepicker";
24
+ import * as i10 from "@angular/forms";
25
+ import * as i11 from "primeng/toast";
23
26
  export class AppointmentBookingComponent {
24
- constructor(restService, _eventService, router, messageService) {
27
+ constructor(restService, _eventService, router, messageService, bookingProductCartService, storageService, dialogRef) {
25
28
  this.restService = restService;
26
29
  this._eventService = _eventService;
27
30
  this.router = router;
28
31
  this.messageService = messageService;
32
+ this.bookingProductCartService = bookingProductCartService;
33
+ this.storageService = storageService;
34
+ this.dialogRef = dialogRef;
29
35
  this.screenWidth = 0;
30
36
  this.accessedTabs = {
31
37
  serviceListing: false,
@@ -40,18 +46,24 @@ export class AppointmentBookingComponent {
40
46
  this.barWidth = '';
41
47
  this.showCancellationPolicy = false;
42
48
  this.showReducingPolicy = false;
43
- this.selectedService = {};
44
- this.homeAddress = '';
49
+ this.selectedMode = 'STORE_VISIT';
50
+ this.modePinned = false;
51
+ // Cart of services picked in serviceListing - clicking a card toggles membership. This is a
52
+ // straightforward superset of the old single-selectedService behavior: with exactly one
53
+ // service clicked it's the exact same 2-click (select, continue) flow as before.
54
+ this.cartServices = [];
55
+ this.resolvedLines = [];
56
+ this.resolvingCart = false;
57
+ // Products added to the cart before entering the wizard (e.g. "Try at Home" on a product
58
+ // page) - loaded from the local booking-product-cart once the mode is known.
59
+ this.productCartItems = [];
60
+ this.homeVisitAddress = { receiverName: '', receiverPhone: '', addressLine1: '', addressLine2: '', city: '', state: '', zipCode: '' };
45
61
  this.instructions = '';
46
62
  this.Object = Object;
47
63
  this.showCalendar = false;
48
64
  this.selectedDate = null;
49
65
  this.selectedDateStr = '';
50
- this.userDetails = {
51
- name: '',
52
- email: '',
53
- mobileNumber: ''
54
- };
66
+ this.bookingGroup = null;
55
67
  this.dateFilter = (d) => {
56
68
  const date = (d || new Date());
57
69
  const today = new Date();
@@ -60,48 +72,50 @@ export class AppointmentBookingComponent {
60
72
  };
61
73
  this.serviceData = [];
62
74
  this.locationData = [];
63
- this.staffPayload = {
64
- serviceId: '',
65
- storeId: '',
66
- businessId: ''
67
- };
68
75
  this.staffSearchQuery = '';
69
76
  this.staffData = [];
70
- this.slotsPayload = {
71
- storeId: "",
72
- serviceId: "",
73
- businessId: "",
74
- bookingDate: ""
75
- };
76
- this.locationTiming = [];
77
77
  this.loader = false;
78
78
  this.isProcessing = false;
79
79
  this.termsAndConditions = false;
80
80
  this.appointmentPayload = {
81
- staffDetail: {
82
- id: '',
83
- name: ''
84
- },
85
- bookingDate: '',
86
- startTime: '',
87
81
  customerDetail: {
88
82
  name: '',
89
83
  phoneNumber: '',
90
84
  email: ''
91
- },
92
- serviceDetail: {
93
- id: '',
94
- name: ''
95
- },
96
- storeId: '',
97
- businessId: this.businessId,
98
- businessName: this.businessName
85
+ }
99
86
  };
100
87
  this.apiStatus = false;
101
88
  }
102
89
  ngOnInit() {
103
- this.getAllServices();
90
+ // Login is required before entering the wizard at all (not mid-flow, like cart's
91
+ // checkout-commit gate) - the wizard's selections live only in component memory, so a
92
+ // redirect-and-back partway through would silently wipe whatever the customer had already
93
+ // picked. Checking here, before anything is picked, means there's nothing to lose. Skipped
94
+ // in builder edit/preview mode (`edit` is true when a business owner is editing their site,
95
+ // not a real customer session) - the same guard pattern used elsewhere in this codebase
96
+ // (e.g. AuthenticationRequiredComponent's own submit handlers).
97
+ if (!this.edit && !this.storageService.getUser()) {
98
+ this.dialogRef?.close();
99
+ this.router.navigate(['/login'], { queryParams: { redirectTo: this.router.url } });
100
+ return;
101
+ }
104
102
  this.getScreenSize();
103
+ if (this.prefillContact) {
104
+ this.appointmentPayload.customerDetail.name = this.prefillContact.name ?? '';
105
+ this.appointmentPayload.customerDetail.phoneNumber = this.prefillContact.phoneNumber ?? '';
106
+ }
107
+ // A business can pin this section to one mode via saved content config. There's no editor
108
+ // UI yet to set this field (the section content-editor doesn't have a mode picker built) -
109
+ // reading it here just keeps the component forward-compatible once one exists.
110
+ const pinnedMode = this.data?.content?.mode;
111
+ if (pinnedMode === 'STORE_VISIT' || pinnedMode === 'HOME_VISIT' || pinnedMode === 'VIDEO_CALL') {
112
+ this.modePinned = true;
113
+ this.selectMode(pinnedMode);
114
+ }
115
+ else {
116
+ this.selectedTab = 'modeSelection';
117
+ this.barWidth = '10';
118
+ }
105
119
  }
106
120
  getScreenSize() {
107
121
  this.screenWidth = window.innerWidth;
@@ -115,12 +129,11 @@ export class AppointmentBookingComponent {
115
129
  this.showCalendar = !this.showCalendar;
116
130
  }
117
131
  onDateSelected(date) {
118
- this.selectedTime = {};
119
132
  this.activeButton = false;
120
133
  this.selectedDate = date;
121
134
  this.selectedDateStr = this.formatDate(date);
122
135
  this.showCalendar = false;
123
- this.getAvailableSlots();
136
+ this.resolveCart();
124
137
  }
125
138
  formatDate(d) {
126
139
  const dd = String(d.getDate()).padStart(2, '0');
@@ -128,13 +141,36 @@ export class AppointmentBookingComponent {
128
141
  const yyyy = d.getFullYear();
129
142
  return `${dd}-${mm}-${yyyy}`;
130
143
  }
144
+ toIsoDate(d) {
145
+ const date = d ?? new Date();
146
+ const yyyy = date.getFullYear();
147
+ const mm = String(date.getMonth() + 1).padStart(2, '0');
148
+ const dd = String(date.getDate()).padStart(2, '0');
149
+ return `${yyyy}-${mm}-${dd}T00:00:00.000Z`;
150
+ }
151
+ selectMode(mode) {
152
+ this.selectedMode = mode;
153
+ this.loadProductCartForMode();
154
+ this.getAllServices();
155
+ }
156
+ async loadProductCartForMode() {
157
+ if (this.selectedMode === 'STORE_VISIT') {
158
+ this.productCartItems = [];
159
+ return;
160
+ }
161
+ this.productCartItems = await this.bookingProductCartService.getItems(this.selectedMode);
162
+ }
131
163
  selectService(service) {
132
- service.selected = true;
133
- if (this.selectedService && service.serviceId != this.selectedService.serviceId) {
134
- this.selectedService.selected = false;
164
+ const idx = this.cartServices.findIndex((s) => s.serviceId === service.serviceId);
165
+ if (idx >= 0) {
166
+ this.cartServices.splice(idx, 1);
167
+ service.selected = false;
168
+ }
169
+ else {
170
+ this.cartServices.push(service);
171
+ service.selected = true;
135
172
  }
136
- this.selectedService = service;
137
- this.activeButton = this.selectedService ? true : false;
173
+ this.activeButton = this.cartServices.length > 0 || this.productCartItems.length > 0;
138
174
  }
139
175
  selectLocation(location) {
140
176
  location.selected = true;
@@ -144,52 +180,23 @@ export class AppointmentBookingComponent {
144
180
  this.activeButton = true;
145
181
  this.selectedLocation = location;
146
182
  }
147
- selectStaff(staff) {
148
- staff.selected = true;
149
- if (this.selectedStaff && staff.staffId != this.selectedStaff.staffId) {
150
- this.selectedStaff.selected = false;
151
- }
152
- this.selectedStaff = staff;
153
- this.activeButton = true;
154
- }
155
183
  nextStep() {
156
184
  if (this.selectedTab === 'serviceListing') {
157
- this.activeButton = this.selectedLocation ? true : false;
158
185
  this.accessedTabs.serviceListing = true;
159
- // if (!this.activeButton) {
160
- // this.getAllLocations();
161
- // }
162
- // else {
163
- // if (this.accessedTabs.locationListing) {
164
- // this.selectedTab = 'locationListing';
165
- // this.barWidth = '29.28';
166
- // }
167
- // else if (this.accessedTabs.staffListing) {
168
- // this.selectedTab = 'staffListing';
169
- // this.barWidth = '43.57';
170
- // }
171
- // else {
172
- // this.selectedTab = 'dateSelection';
173
- // this.barWidth = '58.57';
174
- // if (this.selectedLocation && this.selectedService)
175
- // this.getAvailableSlots();
176
- // }
177
- // }
178
- this.getAllLocations();
186
+ if (this.selectedMode === 'STORE_VISIT') {
187
+ this.getAllLocations();
188
+ }
189
+ else {
190
+ this.goToDateSelection();
191
+ }
179
192
  }
180
193
  else if (this.selectedTab === 'locationListing') {
181
- this.activeButton = true;
182
194
  this.accessedTabs.locationListing = true;
183
- // if (!this.activeButton) {
184
- // this.getAllStaff();
185
- // }
186
- this.getAllStaff();
195
+ this.goToDateSelection();
187
196
  }
188
197
  else if (this.selectedTab === 'staffListing') {
189
198
  this.accessedTabs.staffListing = true;
190
- this.selectedTab = 'dateSelection';
191
- this.barWidth = '58.57';
192
- this.getAvailableSlots();
199
+ this.fetchAllLineSlots();
193
200
  }
194
201
  else if (this.selectedTab === 'dateSelection') {
195
202
  this.activeButton = this.appointmentPayload.customerDetail.name && this.appointmentPayload.customerDetail.email && this.appointmentPayload.customerDetail.phoneNumber.length === 10 ? true : false;
@@ -204,75 +211,78 @@ export class AppointmentBookingComponent {
204
211
  }
205
212
  previousStep() {
206
213
  this.loader = false;
207
- if (this.selectedTab != 'serviceListing') {
208
- this.activeButton = true;
209
- if (this.selectedTab === 'locationListing') {
210
- if (this.accessedTabs.serviceListing) {
211
- this.selectedTab = 'serviceListing';
212
- this.barWidth = '14.28';
213
- this.selectedLocation = null;
214
- }
214
+ if (this.selectedTab === 'modeSelection')
215
+ return;
216
+ if (this.selectedTab === 'serviceListing') {
217
+ if (!this.modePinned) {
218
+ this.selectedTab = 'modeSelection';
219
+ this.barWidth = '10';
215
220
  }
216
- else if (this.selectedTab === 'staffListing') {
217
- this.selectedStaff = null;
218
- if (this.accessedTabs.locationListing) {
219
- this.selectedTab = 'locationListing';
220
- this.barWidth = '29.28';
221
- }
222
- else if (this.accessedTabs.serviceListing) {
223
- this.selectedTab = 'serviceListing';
224
- this.barWidth = '14.28';
225
- }
221
+ return;
222
+ }
223
+ this.activeButton = true;
224
+ if (this.selectedTab === 'locationListing') {
225
+ this.selectedTab = 'serviceListing';
226
+ this.barWidth = '14.28';
227
+ this.selectedLocation = null;
228
+ }
229
+ else if (this.selectedTab === 'staffListing') {
230
+ this.resolvedLines.forEach((l) => { l.selectedStaffId = undefined; l.selectedStaffName = undefined; });
231
+ if (this.selectedMode === 'STORE_VISIT' && this.accessedTabs.locationListing) {
232
+ this.selectedTab = 'locationListing';
233
+ this.barWidth = '29.28';
226
234
  }
227
- else if (this.selectedTab === 'dateSelection') {
228
- if (this.accessedTabs.staffListing) {
229
- this.selectedTab = 'staffListing';
230
- this.barWidth = '43.57';
231
- }
232
- else if (this.accessedTabs.locationListing) {
233
- this.selectedTab = 'locationListing';
234
- this.barWidth = '29.28';
235
- }
236
- else if (this.accessedTabs.serviceListing) {
237
- this.selectedTab = 'serviceListing';
238
- this.barWidth = '14.28';
239
- }
235
+ else {
236
+ this.selectedTab = 'serviceListing';
237
+ this.barWidth = '14.28';
240
238
  }
241
- else if (this.selectedTab === 'contactDetails') {
242
- this.selectedTab = 'dateSelection';
243
- this.barWidth = '58.57';
239
+ }
240
+ else if (this.selectedTab === 'dateSelection') {
241
+ const needsStaffPick = this.resolvedLines.some((l) => !!l.candidateStaffPool?.length);
242
+ if (needsStaffPick) {
243
+ this.selectedTab = 'staffListing';
244
+ this.barWidth = '43.57';
244
245
  }
245
- else if (this.selectedTab === 'paymentTab') {
246
- this.selectedTab = 'contactDetails';
247
- this.barWidth = '70.57';
246
+ else if (this.selectedMode === 'STORE_VISIT' && this.accessedTabs.locationListing) {
247
+ this.selectedTab = 'locationListing';
248
+ this.barWidth = '29.28';
249
+ }
250
+ else {
251
+ this.selectedTab = 'serviceListing';
252
+ this.barWidth = '14.28';
248
253
  }
249
254
  }
255
+ else if (this.selectedTab === 'contactDetails') {
256
+ this.selectedTab = 'dateSelection';
257
+ this.barWidth = '58.57';
258
+ }
259
+ else if (this.selectedTab === 'paymentTab') {
260
+ this.selectedTab = 'contactDetails';
261
+ this.barWidth = '70.57';
262
+ }
250
263
  }
251
264
  getAllServices() {
252
265
  this.skeletonLoader = true;
253
266
  let servicePayload = {
254
267
  businessId: this.businessId ?? "",
255
- // businessId:'1f15cb67-d274-6ef7-8fc5-7b1ec5ec2d15',
256
268
  pageNo: 0,
257
269
  size: 100
258
270
  };
259
271
  this.restService.getAllAppointmentService(servicePayload).subscribe((res) => {
260
- if (res.content.length > 0) {
261
- this.skeletonLoader = false;
262
- this.serviceData = res.content.filter((service) => service.active === true);
263
- this.serviceData.forEach(service => service.selected = false);
264
- // console.log(this.serviceData)
265
- if (this.serviceData.length === 1 && !this.activeButton) {
266
- this.selectedService = this.serviceData[0];
267
- this.getAllLocations();
268
- }
269
- else {
270
- this.selectedTab = 'serviceListing';
271
- this.barWidth = '14.28';
272
- }
273
- }
272
+ this.skeletonLoader = false;
273
+ let services = (res.content || []).filter((service) => service.active === true);
274
+ if (this.selectedMode === 'HOME_VISIT')
275
+ services = services.filter((s) => s.homeAppointmentAvailable);
276
+ if (this.selectedMode === 'VIDEO_CALL')
277
+ services = services.filter((s) => s.availableOnline);
278
+ services.forEach((service) => service.selected = false);
279
+ this.serviceData = services;
280
+ this.cartServices = [];
281
+ this.selectedTab = 'serviceListing';
282
+ this.barWidth = '14.28';
283
+ this.activeButton = this.productCartItems.length > 0;
274
284
  }, (error) => {
275
- // Handle errors gracefully
285
+ this.skeletonLoader = false;
276
286
  });
277
287
  }
278
288
  getAllLocations() {
@@ -282,17 +292,21 @@ export class AppointmentBookingComponent {
282
292
  this.restService.getAllStores(payload).subscribe((res) => {
283
293
  if (res.data.data.length > 0) {
284
294
  let locations = res.data.data.filter((store) => { return store.status === 'ACTIVE'; });
285
- locations.forEach((location) => {
286
- if (this.selectedService.storeIds.includes(location.id)) {
287
- location.selected = false;
288
- this.locationData.push(location);
289
- }
290
- });
295
+ // Location-intersection check (design doc §2c): only offer stores that carry every
296
+ // service currently in the cart, not just the first one.
297
+ locations = locations.filter((location) => this.cartServices.every((s) => s.storeIds?.includes(location.id)));
298
+ locations.forEach((l) => l.selected = false);
299
+ this.locationData = locations;
300
+ if (this.locationData.length === 0) {
301
+ this.messageService.add({ severity: 'error', summary: 'No Location', detail: 'These services aren\'t all available at one location - remove one and book it separately' });
302
+ this.loader = false;
303
+ return;
304
+ }
291
305
  if (this.locationData.length === 1) {
292
306
  this.selectedLocation = this.locationData[0];
293
307
  this.loader = false;
294
308
  this.accessedTabs.locationListing = false;
295
- this.getAllStaff();
309
+ this.goToDateSelection();
296
310
  }
297
311
  else {
298
312
  this.loader = false;
@@ -306,9 +320,15 @@ export class AppointmentBookingComponent {
306
320
  this.loader = false;
307
321
  }
308
322
  }, (error) => {
309
- // Handle errors gracefully
323
+ this.loader = false;
310
324
  });
311
325
  }
326
+ goToDateSelection() {
327
+ this.selectedTab = 'dateSelection';
328
+ this.barWidth = '43.57';
329
+ this.activeButton = false;
330
+ this.resolvedLines = [];
331
+ }
312
332
  get filteredStaff() {
313
333
  if (!this.staffSearchQuery.trim()) {
314
334
  return this.staffData;
@@ -316,40 +336,109 @@ export class AppointmentBookingComponent {
316
336
  const query = this.staffSearchQuery.toLowerCase().trim();
317
337
  return this.staffData.filter(staff => staff?.staffName?.toLowerCase().includes(query));
318
338
  }
319
- getAllStaff() {
320
- this.staffSearchQuery = '';
321
- this.loader = true;
322
- this.activeButton = true;
323
- this.staffPayload.storeId = this.selectedLocation?.id ?? "";
324
- this.staffPayload.serviceId = this.selectedService?.serviceId ? this.selectedService.serviceId : '';
325
- this.staffPayload.businessId = this.businessId ?? "";
326
- this.restService.getAllStaff(this.staffPayload).subscribe((res) => {
327
- if (res.length > 0) {
328
- this.staffData = res.filter((staff) => staff.active === true && staff.bookingAllowed);
329
- this.staffData.forEach(staff => staff.selected = false);
330
- if (this.staffData.length === 1) {
331
- this.loader = false;
332
- this.selectedTab = 'dateSelection';
333
- this.barWidth = '58.57';
334
- this.selectedStaff = this.staffData[0];
335
- this.getAvailableSlots();
336
- this.accessedTabs.staffListing = false;
337
- }
338
- else if (this.staffData.length > 1) {
339
- this.loader = false;
340
- this.selectedTab = 'staffListing';
341
- this.barWidth = '43.57';
342
- this.accessedTabs.staffListing = true;
343
- }
339
+ resolveCart() {
340
+ if (this.cartServices.length === 0) {
341
+ // Pure product-only line (Home Visit / Video Call with no services attached) - resolution
342
+ // is built around service pools, so this needs an explicit staff pick instead. One line,
343
+ // no services, just a staff+time to carry the flat product-viewing allowance.
344
+ this.resolvedLines = [{ services: [], totalDurationMinutes: 0, slots: [] }];
345
+ this.getAllStaffForProductOnlyLine();
346
+ return;
347
+ }
348
+ this.resolvingCart = true;
349
+ this.skeletonLoader = true;
350
+ const payload = {
351
+ businessId: this.businessId,
352
+ mode: this.selectedMode,
353
+ storeId: this.selectedMode === 'STORE_VISIT' ? this.selectedLocation?.id : undefined,
354
+ bookingDate: this.toIsoDate(this.selectedDate),
355
+ serviceItems: this.cartServices.map((s) => ({ serviceId: s.serviceId }))
356
+ };
357
+ this.restService.resolveCart(payload).subscribe((res) => {
358
+ this.resolvingCart = false;
359
+ this.skeletonLoader = false;
360
+ this.resolvedLines = (res || []).map((line) => ({
361
+ services: line.services,
362
+ totalDurationMinutes: line.totalDurationMinutes,
363
+ staffId: line.staffId,
364
+ staffName: line.staffName,
365
+ candidateStaffPool: line.candidateStaffPool,
366
+ slots: []
367
+ }));
368
+ const needsStaffPick = this.resolvedLines.some((l) => !!l.candidateStaffPool?.length);
369
+ if (needsStaffPick) {
370
+ this.staffSearchQuery = '';
371
+ this.selectedTab = 'staffListing';
372
+ this.barWidth = '43.57';
344
373
  }
345
374
  else {
346
- this.messageService.add({ severity: 'error', summary: 'No Staff Present', detail: 'No Staff present for selected service' });
347
- this.loader = false;
375
+ this.fetchAllLineSlots();
348
376
  }
349
377
  }, (error) => {
350
- // Handle errors gracefully
378
+ this.resolvingCart = false;
379
+ this.skeletonLoader = false;
380
+ this.messageService.add({ severity: 'error', summary: 'Unable to check availability', detail: error.error?.message ?? 'Please try again' });
351
381
  });
352
382
  }
383
+ getAllStaffForProductOnlyLine() {
384
+ this.loader = true;
385
+ const payload = { serviceId: '', storeId: this.selectedLocation?.id ?? '', businessId: this.businessId ?? '' };
386
+ this.restService.getAllStaff(payload).subscribe((res) => {
387
+ this.loader = false;
388
+ this.staffData = (res || []).filter((staff) => staff.active === true && staff.bookingAllowed);
389
+ this.staffData.forEach((staff) => staff.selected = false);
390
+ this.selectedTab = 'staffListing';
391
+ this.barWidth = '43.57';
392
+ }, () => { this.loader = false; });
393
+ }
394
+ selectStaffForProductOnlyLine(staff) {
395
+ this.staffData.forEach((s) => s.selected = false);
396
+ staff.selected = true;
397
+ this.resolvedLines[0].selectedStaffId = staff.staffId;
398
+ this.resolvedLines[0].selectedStaffName = staff.staffName;
399
+ this.activeButton = true;
400
+ }
401
+ selectStaffForLine(line, staff) {
402
+ line.selectedStaffId = staff.id;
403
+ line.selectedStaffName = staff.name;
404
+ this.activeButton = this.resolvedLines.every((l) => !!(l.staffId || l.selectedStaffId));
405
+ }
406
+ fetchAllLineSlots() {
407
+ this.skeletonLoader = true;
408
+ this.selectedTab = 'dateSelection';
409
+ this.barWidth = '58.57';
410
+ let pending = this.resolvedLines.length;
411
+ this.resolvedLines.forEach((line) => {
412
+ const staffId = line.staffId || line.selectedStaffId;
413
+ const payload = {
414
+ storeId: this.selectedMode === 'STORE_VISIT' ? this.selectedLocation?.id : undefined,
415
+ serviceIds: line.services.map((s) => s.id),
416
+ businessId: this.businessId,
417
+ bookingDate: this.toIsoDate(this.selectedDate),
418
+ staffId,
419
+ mode: this.selectedMode
420
+ };
421
+ line.slotsLoading = true;
422
+ this.restService.getBookingSlots(payload).subscribe((res) => {
423
+ line.slots = (res || []).map((v) => ({ selected: false, value: v }));
424
+ line.slotsLoading = false;
425
+ pending--;
426
+ if (pending <= 0)
427
+ this.skeletonLoader = false;
428
+ }, () => {
429
+ line.slotsLoading = false;
430
+ pending--;
431
+ if (pending <= 0)
432
+ this.skeletonLoader = false;
433
+ });
434
+ });
435
+ }
436
+ selectSlotForLine(line, slot) {
437
+ line.slots.forEach((s) => s.selected = false);
438
+ slot.selected = true;
439
+ line.selectedSlot = slot;
440
+ this.activeButton = this.resolvedLines.every((l) => !!l.selectedSlot);
441
+ }
353
442
  convertTo24Hour(time) {
354
443
  const [hourMin, modifierRaw] = time.split(' ');
355
444
  const modifier = modifierRaw.toUpperCase(); // "AM" or "PM"
@@ -364,51 +453,14 @@ export class AppointmentBookingComponent {
364
453
  const mm = minutes.toString().padStart(2, '0');
365
454
  return `${hh}:${mm} ${modifier}`;
366
455
  }
367
- getAvailableSlots() {
368
- this.activeButton = false;
369
- this.skeletonLoader = true;
370
- this.loader = false;
371
- this.locationTiming = [];
372
- this.slotsPayload.storeId = this.selectedLocation?.id ?? "";
373
- this.slotsPayload.serviceId = this.selectedService?.serviceId ? this.selectedService.serviceId : '';
374
- this.slotsPayload.businessId = this.businessId ?? "";
375
- const date = this.selectedDate ?? new Date();
376
- this.selectedDateStr = this.formatDate(date);
377
- const yyyy = date.getFullYear();
378
- const mm = String(date.getMonth() + 1).padStart(2, '0');
379
- const dd = String(date.getDate()).padStart(2, '0');
380
- this.slotsPayload.bookingDate = `${yyyy}-${mm}-${dd}T00:00:00.000Z`;
381
- if (this.selectedStaff)
382
- this.slotsPayload.staffId = this.selectedStaff.staffId;
383
- this.restService.getBookingSlots(this.slotsPayload).subscribe((res) => {
384
- res.forEach((time) => {
385
- this.locationTiming.push({ selected: false, value: time });
386
- this.skeletonLoader = false;
387
- });
388
- if (res.length <= 0) {
389
- this.messageService.add({ severity: 'error', summary: 'Booking Failed', detail: 'Unable to fetch available slots. Please try again later' });
390
- }
391
- }, (error) => {
392
- this.messageService.add({ severity: 'error', summary: 'Unable to fetch slots', detail: error.error.message });
393
- this.loader = false;
394
- });
395
- }
396
- selectTimeSlot(time) {
397
- time.selected = true;
398
- if (this.selectedTime && time.value != this.selectedTime.value) {
399
- this.selectedTime.selected = false;
400
- }
401
- this.selectedTime = time;
402
- this.activeButton = true;
403
- }
404
456
  checkRequiredValues() {
405
457
  const isEmailValid = this.appointmentPayload.customerDetail.email &&
406
458
  /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/.test(this.appointmentPayload.customerDetail.email);
459
+ const anyPolicy = this.cartServices.some((s) => s?.cancellationPolicy?.length > 0 || s?.reschedulePolicy?.length > 0);
407
460
  if (this.appointmentPayload.customerDetail.name &&
408
461
  isEmailValid &&
409
462
  this.appointmentPayload.customerDetail.phoneNumber.length === 10) {
410
- if (this.selectedService?.cancellationPolicy?.length > 0 ||
411
- this.selectedService?.reschedulePolicy?.length > 0) {
463
+ if (anyPolicy) {
412
464
  this.activeButton = this.termsAndConditions ? true : false;
413
465
  }
414
466
  else {
@@ -419,63 +471,59 @@ export class AppointmentBookingComponent {
419
471
  this.activeButton = false;
420
472
  }
421
473
  }
422
- checkPayment() {
423
- this.isProcessing = true;
424
- const request_form = localStorage.getItem("REQUEST_FROM");
425
- if (request_form === 'ECOMMERCE') {
426
- this.createAppointment();
427
- this.isProcessing = false;
474
+ confirmBooking() {
475
+ // Defensive re-check (mirrors cart.component.ts's proceedToPayment() guard) - the entry
476
+ // check in ngOnInit() should make this unreachable in practice, but a long slot-picking
477
+ // session could still let the login session expire before the customer reaches this step.
478
+ if (!this.edit && !this.storageService.getUser()) {
479
+ this.router.navigate(['/login'], { queryParams: { redirectTo: this.router.url } });
480
+ return;
428
481
  }
429
- else {
430
- if (this.selectedService?.depositAmount?.depositRequired) {
431
- this.paymentBookingAppointment();
482
+ this.isProcessing = true;
483
+ const lines = this.resolvedLines.map((l) => {
484
+ const slot = l.selectedSlot;
485
+ return {
486
+ serviceIds: l.services.map((s) => s.id),
487
+ staffId: l.staffId || l.selectedStaffId,
488
+ startTime: slot ? this.convertTo24Hour(slot.value).slice(0, 5) : undefined
489
+ };
490
+ });
491
+ const holdPayload = {
492
+ businessId: this.businessId,
493
+ mode: this.selectedMode,
494
+ storeId: this.selectedMode === 'STORE_VISIT' ? this.selectedLocation?.id : undefined,
495
+ bookingDate: this.toIsoDate(this.selectedDate),
496
+ customerDetail: this.appointmentPayload.customerDetail,
497
+ lines,
498
+ productLines: this.productCartItems.map((p) => this.bookingProductCartService.toProductLine(p)),
499
+ addressDetails: this.selectedMode === 'HOME_VISIT' ? { ...this.homeVisitAddress, instructions: this.instructions } : undefined
500
+ };
501
+ this.restService.holdBooking(holdPayload).subscribe((group) => {
502
+ this.bookingGroup = group;
503
+ if (this.selectedMode !== 'STORE_VISIT' && this.productCartItems.length > 0) {
504
+ this.bookingProductCartService.clear(this.selectedMode);
505
+ }
506
+ if (group.status === 'HOLD' && group.totalCollectedAtBooking > 0) {
507
+ // Must act on this immediately - the hold expires in 10 minutes.
508
+ this.restService.generatePaymentToken(group.groupId).subscribe((order) => {
509
+ localStorage.setItem('appointmentPaymentId', order.pgOrderId);
510
+ this.isProcessing = false;
511
+ this._eventService.cashFreeEvent.emit({ data: { orderSignature: order.orderSignature } });
512
+ }, (error) => {
513
+ this.isProcessing = false;
514
+ this.messageService.add({ severity: 'error', summary: 'Payment Failed', detail: error.error?.message });
515
+ });
432
516
  }
433
517
  else {
434
- this.createAppointment();
518
+ this.apiStatus = true;
519
+ this.selectedTab = 'statusTemplate';
520
+ this.barWidth = '100';
521
+ this.isProcessing = false;
435
522
  }
436
- }
437
- // this.createAppointment();
438
- }
439
- createAppointment() {
440
- const date = this.selectedDate ?? new Date();
441
- const yyyy = date.getFullYear();
442
- const mm = String(date.getMonth() + 1).padStart(2, '0');
443
- const dd = String(date.getDate()).padStart(2, '0');
444
- this.appointmentPayload.staffDetail.id = this.selectedStaff?.staffId;
445
- this.appointmentPayload.staffDetail.name = this.selectedStaff?.staffName;
446
- this.appointmentPayload.storeId = this.selectedLocation?.id;
447
- this.appointmentPayload.serviceDetail.id = this.selectedService?.serviceId;
448
- this.appointmentPayload.serviceDetail.name = this.selectedService?.name;
449
- this.appointmentPayload.startTime = this.convertTo24Hour(this.selectedTime.value).slice(0, 5);
450
- this.appointmentPayload.bookingDate = `${yyyy}-${mm}-${dd}T00:00:00.000Z`;
451
- this.restService.bookAppointmentV2(this.appointmentPayload).subscribe((res) => {
452
- this.selectedTab = 'statusTemplate';
453
- this.barWidth = '100';
454
- this.apiStatus = true;
455
523
  }, (error) => {
456
- this.apiStatus = false;
457
- this.messageService.add({ severity: 'error', summary: 'Booking Failed', detail: error.error.message });
458
- });
459
- }
460
- paymentBookingAppointment() {
461
- const date = this.selectedDate ?? new Date();
462
- const yyyy = date.getFullYear();
463
- const mm = String(date.getMonth() + 1).padStart(2, '0');
464
- const dd = String(date.getDate()).padStart(2, '0');
465
- this.appointmentPayload.staffDetail.id = this.selectedStaff?.staffId;
466
- this.appointmentPayload.staffDetail.name = this.selectedStaff?.staffName;
467
- this.appointmentPayload.storeId = this.selectedLocation?.id;
468
- this.appointmentPayload.serviceDetail.id = this.selectedService?.serviceId;
469
- this.appointmentPayload.serviceDetail.name = this.selectedService?.name;
470
- this.appointmentPayload.startTime = this.convertTo24Hour(this.selectedTime.value).slice(0, 5);
471
- this.appointmentPayload.bookingDate = `${yyyy}-${mm}-${dd}T00:00:00.000Z`;
472
- this.restService.paymentForAppointment(this.appointmentPayload).subscribe((res) => {
473
- localStorage.setItem('appointmentPaymentId', res.pgOrderId);
474
524
  this.isProcessing = false;
475
- this._eventService.cashFreeEvent.emit({ data: { orderSignature: res.orderSignature } });
476
- }, (error) => {
477
- this.loader = false;
478
- this.messageService.add({ severity: 'error', summary: 'Payment Failed', detail: error.error.message });
525
+ this.apiStatus = false;
526
+ this.messageService.add({ severity: 'error', summary: 'Booking Failed', detail: error.error?.message });
479
527
  });
480
528
  }
481
529
  goBack() {
@@ -486,13 +534,15 @@ export class AppointmentBookingComponent {
486
534
  this.router.navigate(['']);
487
535
  }
488
536
  }
489
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AppointmentBookingComponent, deps: [{ token: i1.RestService }, { token: i2.EventsService }, { token: i3.Router }, { token: i4.MessageService }], target: i0.ɵɵFactoryTarget.Component }); }
490
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AppointmentBookingComponent, isStandalone: true, selector: "simpo-appointment-booking", inputs: { data: "data", index: "index", edit: "edit", delete: "delete", customClass: "customClass", nextComponentColor: "nextComponentColor" }, host: { listeners: { "window: resize": "getScreenSize($event)", "document:click": "closeOnOutsideClick()" } }, providers: [MessageService], ngImport: i0, template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\">\n <div class=\"main_header\">\n <div class=\"header d-flex justify-content-between align-items-center\">\n <div class=\"back-btn d-flex justify-content-center align-items-center cursor-pointer gap-2 mb-3\"\n (click)=\"goBack()\">\n <mat-icon>keyboard_backspace</mat-icon><span *ngIf=\"screenWidth > 475\">Back to Home</span>\n </div>\n <div class=\"header-title\">\n <h1>Book New Appointment</h1>\n <p>{{businessName ?? \"N/A\" }}</p>\n </div>\n </div>\n\n <div class=\"progress-bar\">\n <div class=\"progress-fill\" [style.width]=\"barWidth + '%'\"></div>\n </div>\n </div>\n <div class=\"main_body w-100 d-flex justify-content-center\"><ng-container *ngIf=\"selectedTab === 'serviceListing'\">\n <ng-container *ngIf=\"!skeletonLoader\">\n <ng-container *ngTemplateOutlet=\"serviceListing\"></ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'locationListing'\">\n <ng-container *ngTemplateOutlet=\"locationListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'staffListing'\">\n <ng-container *ngTemplateOutlet=\"staffListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'dateSelection'\">\n <ng-container *ngTemplateOutlet=\"dateSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='contactDetails'\">\n <ng-container *ngTemplateOutlet=\"contactDetails\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='paymentTab'\">\n <ng-container *ngTemplateOutlet=\"paymentTab\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='statusTemplate'\">\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\n </ng-container>\n </div>\n <div class=\"main_footer d-flex justify-content-center align-items-center\" *ngIf=\"selectedTab!=='statusTemplate'\">\n <div class=\"footer-buttons\"\n [ngStyle]=\"{'justify-content': selectedTab != 'serviceListing' ? 'space-between' : 'end'}\">\n <span class=\"back-footer-btn cursor-pointer\" (click)=\"previousStep()\"\n *ngIf=\"selectedTab != 'serviceListing'\">Back</span>\n <button class=\"continue-btn\" [disabled]=\"!activeButton\" (click)=\"nextStep()\"\n *ngIf=\"selectedTab!='paymentTab'\">{{!loader ? 'Continue' : 'Loading...'}}</button>\n <button class=\"cursor-pointer d-flex justify-content-evenly align-items-center\"\n *ngIf=\"selectedTab==='paymentTab'\" (click)=\"checkPayment()\" [disabled]=\"isProcessing\"\n [ngClass]=\"{'pay-now-btn' : selectedService?.depositAmount?.depositRequired,'complete_booking' : !selectedService?.depositAmount?.depositRequired}\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/304012c1753440087996Background.png\">\n {{selectedService?.depositAmount?.depositRequired ? 'Pay Now' : 'Complete Booking'}}\n </button>\n </div>\n </div>\n</section>\n<ng-template #serviceListing>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>Select a Service</h2>\n <p>Choose the service you'd like to book</p>\n\n <div class=\"services-grid\">\n <ng-container *ngFor=\"let service of serviceData\">\n <div class=\"\" (click)=\"selectService(service)\"\n [ngClass]=\"{ 'service-card-selected' : service?.selected, 'service-card': !service?.selected }\">\n <div class=\" service-header\">\n <div class=\"service-icon\"><mat-icon>person_outline</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">{{service?.name ? service?.name : 'N/A'}}</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B9{{service?.priceDetails?.price ?\n service?.priceDetails?.price : 'N/A' }}</div>\n <div class=\"service-duration\">{{service?.duration ? service?.duration : 'N/A'}} min\n </div>\n </div>\n </div>\n <div class=\"service-description\" *ngIf=\"service?.description\">\n {{service?.description ? service?.description : 'N/A'}}\n </div>\n <div class=\"home-visit\" *ngIf=\"service?.homeAppointmentAvailable\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/982126c1758628863129furniture_16406103.png\">Home\n Visit Available</div>\n </div>\n </ng-container>\n\n <!-- <div class=\"service-card\">\n <div class=\"service-header\">\n <div class=\"service-icon\">\uD83D\uDC64</div>\n <div class=\"service-info\">\n <div class=\"service-title\">General Consultation</div>\n <div class=\"service-category\">Medical</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B9800</div>\n <div class=\"service-duration\">30 min</div>\n </div>\n </div>\n <div class=\"service-description\">\n Comprehensive health consultation\n </div>\n </div>\n\n <div class=\"service-card\">\n <div class=\"service-header\">\n <div class=\"service-icon\">\uD83E\uDDE0</div>\n <div class=\"service-info\">\n <div class=\"service-title\">Mental Health Counseling</div>\n <div class=\"service-category\">Mental Health</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B91500</div>\n <div class=\"service-duration\">45 min</div>\n </div>\n </div>\n <div class=\"service-description\">\n Professional psychological support\n </div>\n <div class=\"home-visit\">Home Visit Available</div>\n </div>\n\n <div class=\"service-card\">\n <div class=\"service-header\">\n <div class=\"service-icon\">\u2702</div>\n <div class=\"service-info\">\n <div class=\"service-title\">Hair Cut & Styling</div>\n <div class=\"service-category\">Beauty</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B91200</div>\n <div class=\"service-duration\">45 min</div>\n </div>\n </div>\n <div class=\"service-description\">\n Professional hair cutting and styling\n </div>\n <div class=\"home-visit\">Home Visit Available</div>\n </div> -->\n </div>\n </div>\n </div>\n</ng-template>\n<ng-template #locationListing>\n <div class=\"location_section\">\n <div class=\"header flex-column align-items-start\">\n <h1>Choose Location</h1>\n <p>Select where you'd like to receive the service</p>\n </div>\n\n <div class=\"location-list\">\n <ng-container *ngFor=\"let location of locationData\">\n <div (click)=\"selectLocation(location)\"\n [ngClass]=\"{ 'location-card-selected' : location?.selected, 'location-card': !location?.selected }\">\n <div class=\"location-content\">\n <div class=\"location-info\">\n <div class=\"location-icon\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/427226c1758629157758store_3171510.png\">\n </div>\n <div class=\"location-details\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <h3>{{location?.storeName ? location?.storeName : 'N/A'}}</h3>\n <!-- <div class=\"distance\"><mat-icon>location_on</mat-icon> 2.3 km</div> -->\n </div>\n <p>{{location?.addressDetails?.addressLine}}, {{location?.addressDetails?.city}},\n {{location?.addressDetails?.state}} {{location?.pincode}}</p>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n <!-- <div class=\"location-card\">\n <div class=\"location-content\">\n <div class=\"location-info\">\n <div class=\"location-icon branch-icon\"></div>\n <div class=\"location-details\">\n <h3>Branch Clinic</h3>\n <p>456 Care Avenue, Health Zone, Mumbai 400015</p>\n </div>\n </div>\n <div class=\"distance\">5.8 km</div>\n </div>\n </div>\n\n <div class=\"location-card\">\n <div class=\"location-content\">\n <div class=\"location-info\">\n <div class=\"location-icon home-icon\"></div>\n <div class=\"location-details\">\n <h3>Home Visit</h3>\n <p>Your Location</p>\n </div>\n </div>\n <div class=\"distance\">0 km</div>\n </div>\n </div> -->\n </div>\n </div>\n</ng-template>\n<ng-template #staffListing>\n <div class=\"w-60 overflow-hidden staff-listing\">\n <div class=\"d-flex w-100 h-100\">\n <div class=\"w-100\">\n <!-- Header Section -->\n <div class=\"staff-header mb-3\">\n <h1>Select Staff Member</h1>\n <p class=\"staff-subtitle mb-0\">Choose your preferred professional</p>\n </div>\n\n <!-- Staff Search Bar -->\n <div class=\"search-container mb-4\">\n <div class=\"search-input-wrapper d-flex align-items-center\">\n <mat-icon class=\"search-icon me-2\">search</mat-icon>\n <input type=\"text\" class=\"search-input border-0 flex-grow-1\" placeholder=\"Search staff member by name...\" [(ngModel)]=\"staffSearchQuery\">\n <mat-icon class=\"clear-icon cursor-pointer ms-2\" *ngIf=\"staffSearchQuery\" (click)=\"staffSearchQuery = ''\">close</mat-icon>\n </div>\n </div>\n\n <!-- Staff Cards -->\n <div class=\"staff-list\">\n <ng-container *ngFor=\"let staff of filteredStaff\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaff(staff)\"\n [ngClass]=\"{ 'staff-card-selected' : staff?.selected, 'staff-card': !staff?.selected }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div\n class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.staffName.slice(0,2).toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.staffName ? staff?.staffName : 'N/A') | titlecase}}</h3>\n <p class=\"staff-specialty\">{{(businessName && businessName !== 'N/A') ? businessName : 'Booking Specialist'}}</p>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"staff?.selected\">\n <mat-icon *ngIf=\"staff?.selected\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n<ng-template #dateSelection>\n <div class=\"w-60 date_section\">\n <div class=\"row justify-content-center h-100\">\n <div class=\"col-12 h-100\">\n <div class=\"datetime-header mb-2\">\n <h1>Select Date & Time</h1>\n <p class=\"datetime-subtitle mb-0\">Choose when you'd like your appointment</p>\n </div>\n\n <!-- Main Content -->\n <div class=\"d-flex gap-4 main_container\">\n <!-- Left Column - Date Selection -->\n <div [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Select Date</h3>\n\n <div class=\"date-picker-container d-flex align-items-center justify-content-between\"\n (click)=\"$event.stopPropagation()\">\n <input type=\"text\" class=\"date-input border-0 rounded-2\" placeholder=\"dd-mm-yyyy\"\n [value]=\"selectedDateStr\" readonly (click)=\"toggleCalendar($event)\">\n\n <mat-icon class=\"ms-2\" (click)=\"toggleCalendar($event)\">calendar_today</mat-icon>\n </div>\n <div class=\"position-relative\" (click)=\"$event.stopPropagation()\">\n <div class=\"datepicker-popover\" *ngIf=\"showCalendar\">\n <mat-calendar [(selected)]=\"selectedDate\" [dateFilter]=\"dateFilter\"\n (selectedChange)=\"onDateSelected($event)\" class=\"datepicker-calendar\">\n </mat-calendar>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Right Column - Time Selection -->\n <div class=\"time_selection\" [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card h-100 rounded-3 p-4\">\n <h3 class=\"section-title\">Available Times</h3>\n\n <!-- Time Slots Grid -->\n <div class=\"row g-2 mb-4 overflow-scroll\">\n <ng-container *ngIf=\"!skeletonLoader ;else slotsLoader\">\n <div class=\"col-4\" *ngFor=\"let time of locationTiming\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectTimeSlot(time)\">{{time ?\n time?.value : 'N/A'}}</div>\n </div>\n </ng-container>\n <ng-template #slotsLoader>\n <!-- Time Slot Grid Skeleton Loader HTML -->\n <div class=\"time-slot-grid\">\n <!-- Row 1 -->\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n\n <!-- Row 2 -->\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n\n <!-- Row 3 -->\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n\n <!-- Row 4 -->\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n\n <!-- Row 5 -->\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n\n <!-- Row 6 -->\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n </div>\n\n </ng-template>\n </div>\n\n <!-- Waitlist Section -->\n <!-- <div class=\"waitlist-section rounded-3\">\n <div class=\"d-flex align-items-start\">\n <div class=\"d-flex h-100 justify-content-between flex-column\">\n <div class=\"waitlist-title d-flex align-items-center gap-2\"><span\n class=\"waitlist-icon check-icon\"></span>No\n slots available?</div>\n <div class=\"waitlist-description d-flex align-items-center gap-2\">\n <input class=\"form-check-input cursor-pointer\" type=\"checkbox\"\n id=\"flexCheckChecked\">\n Add me to the waitlist for earlier\n availability\n </div>\n </div>\n <div>\n </div>\n </div>\n </div> -->\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n</ng-template>\n<ng-template #contactDetails>\n <div class=\"w-60 contact_section\">\n <!-- Header Section -->\n <div class=\"contact-header mb-2\">\n <h1>Contact Details</h1>\n <p class=\"contact-subtitle mb-0\">Provide your contact information</p>\n </div>\n\n <!-- Form Sections -->\n <div class=\"d-flex gap-3 details_container flex-column w-100\">\n <!-- Left Column - Personal Information -->\n <div class=\"d-flex gap-4\">\n <div\n [ngClass]=\"{'w-50' : selectedService?.homeAppointmentAvailable, 'w-100' : !selectedService?.homeAppointmentAvailable}\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Personal Information</h3>\n\n <!-- Full Name -->\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Full Name\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"text\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.name\"\n (ngModelChange)=\"checkRequiredValues()\" simpoLettersOnly>\n </div>\n\n <!-- Email Address -->\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Email Address\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"email\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.email\"\n (ngModelChange)=\"checkRequiredValues()\"\n pattern=\"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" #emailField=\"ngModel\"\n name=\"email\" required>\n </div>\n\n <!-- Phone Number -->\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">\n Phone Number\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"tel\" class=\"form-control rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.phoneNumber\"\n (ngModelChange)=\"checkRequiredValues()\" simpoNumbersOnly\n [ngClass]=\"{'mobile_number' : appointmentPayload.customerDetail.phoneNumber.length != 10}\">\n </div>\n </div>\n </div>\n <!-- Right Column - Home Visit Details -->\n <div class=\"w-50\" *ngIf=\"selectedService?.homeAppointmentAvailable\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Home Visit Details</h3>\n\n <!-- Home Address -->\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Home Address\n </label>\n <textarea class=\"form-control form-textarea rounded-2\"\n placeholder=\"Enter your complete address\" [(ngModel)]=\"homeAddress\"></textarea>\n </div>\n\n <!-- Special Instructions -->\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">\n Special Instructions\n </label>\n <textarea class=\"form-control form-textarea rounded-2\"\n placeholder=\"Any special instructions for the professional (optional)\"\n [(ngModel)]=\"instructions\"></textarea>\n </div>\n </div>\n </div>\n </div>\n <div class=\"policies-container\"\n *ngIf=\"selectedService?.cancellationPolicy?.length > 0 || selectedService?.reschedulePolicy?.length\">\n <!-- Header -->\n <h2 class=\"policies-title\">Policies & Terms</h2>\n\n <!-- Policy Items -->\n <div class=\"policy-items-container d-flex flex-column gap-3\">\n <!-- Cancellation Policy -->\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showCancellationPolicy = !showCancellationPolicy\">\n <h3 class=\"policy-title\">Cancellation Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showCancellationPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showCancellationPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showCancellationPolicy\">\n <span *ngFor=\"let policy of selectedService?.cancellationPolicy\">&#8226;\n {{policy}}</span>\n </div>\n\n <!-- Rescheduling Policy -->\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showReducingPolicy = !showReducingPolicy\">\n <h3 class=\"policy-title\">Rescheduling Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showReducingPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showReducingPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showReducingPolicy\">\n <span *ngFor=\"let policy of selectedService?.reschedulePolicy\">&#8226; {{policy}}</span>\n </div>\n </div>\n\n <!-- Acceptance Section -->\n <div class=\"acceptance-section\">\n <input type=\"checkbox\" class=\"custom-checkbox\" [(ngModel)]=\"termsAndConditions\"\n (ngModelChange)=\"checkRequiredValues()\">\n <p class=\"acceptance-text\" style=\"margin-bottom:0px !important\">\n I understand and accept the cancellation & rescheduling policies.\n <!-- <span class=\"terms-link\">Terms & Conditions<span\n class=\"external-link-icon\"></span></span> -->\n </p>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n<ng-template #paymentTab>\n <div class=\"w-60 payment_section\">\n <div class=\"w-100 h-100\">\n <div class=\"w-100 d-flex justify-content-center align-items-center flex-column\">\n <!-- Header Section -->\n <div class=\"payment-header mb-3 w-100\">\n <h1 style=\"font-size:24px;font-weight: 600;\">\n {{selectedService?.depositAmount?.depositRequired ? 'Payment & Confirmation' : 'Booking Confirmation'}}\n </h1>\n <p class=\"payment-subtitle mb-0\">\n {{selectedService?.depositAmount?.depositRequired ? 'Review your booking and complete payment' : \n 'Before Confirmation Review your booking'}}\n </p>\n </div>\n\n <!-- Booking Summary Card -->\n <div class=\"booking-summary-card\" [ngClass]=\"{'w-100' : screenWidth < 475,'w-50':screenWidth > 475}\">\n <h2 class=\"summary-title\">Booking Summary</h2>\n\n <!-- Service -->\n <div class=\"summary-row\">\n <div class=\"summary-label\">Service</div>\n <div class=\"summary-value\">{{selectedService?.name ? selectedService?.name : 'N/A'}}</div>\n </div>\n\n <!-- Professional -->\n <div class=\"summary-row\" *ngIf=\"selectedStaff?.staffName\">\n <div class=\"summary-label\">Professional</div>\n <div class=\"summary-value\">{{selectedStaff?.staffName ? selectedStaff?.staffName : 'N/A'}}</div>\n </div>\n\n <!-- Location -->\n <div class=\"summary-row\">\n <div class=\"summary-label\">Location</div>\n <div class=\"summary-value\">{{selectedLocation?.storeName ? selectedLocation?.storeName : 'N/A'}}\n </div>\n </div>\n\n <!-- Date & Time -->\n <div class=\"summary-row\">\n <div class=\"summary-label\">Date & Time</div>\n <div class=\"summary-value\">{{selectedDateStr ? (selectedDateStr) : 'N/A'}} at\n {{selectedTime ? selectedTime.value : 'N/A'}}</div>\n </div>\n\n <!-- Duration -->\n <div class=\"summary-row\">\n <div class=\"summary-label\">Duration</div>\n <div class=\"summary-value\">{{selectedService?.duration ? selectedService?.duration : 'N/A'}}\n minutes</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Tax Percent</div>\n <div class=\"summary-value\">{{selectedService?.priceDetails?.taxPercent ?\n selectedService?.priceDetails?.taxPercent : 0}}%</div>\n </div>\n <!-- Total -->\n <div class=\"summary-row total-row\">\n <div class=\"summary-label\">Total</div>\n <div class=\"summary-value\">\n <span class=\"currency-symbol\">\u20B9</span>{{selectedService?.priceDetails?.totalPrice ?\n selectedService?.priceDetails?.totalPrice : '0'}}\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n<ng-template #statusTemplate>\n <div class=\"booking-confirmation\">\n <!-- Success Icon -->\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <!-- Main Content -->\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book you appointment. Please\n try again later'}}\n </p>\n\n <!-- Details Card -->\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n\n <div class=\"details-row\">\n <span class=\"detail-label\">Service</span>\n <span class=\"detail-value\">{{appointmentPayload.serviceDetail?.name ?\n appointmentPayload.serviceDetail?.name : 'N/A'}}</span>\n </div>\n\n <div class=\"details-row\" *ngIf=\"appointmentPayload?.staffDetail?.name\">\n <span class=\"detail-label\">Professional</span>\n <span class=\"detail-value\">{{appointmentPayload.staffDetail?.name ?\n appointmentPayload.staffDetail?.name : 'N/A'}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Date & Time</span>\n <span class=\"detail-value\">{{appointmentPayload.bookingDate ?\n appointmentPayload.bookingDate.slice(0,10) :\n 'N/A'}} at\n {{appointmentPayload.startTime ? appointmentPayload.startTime : 'N/A'}}</span>\n </div>\n </div>\n </div>\n\n\n <!-- Action Buttons -->\n <!-- <div class=\"action-buttons\">\n <button class=\"btn btn-outline\">View My Bookings</button>\n <button class=\"btn btn-primary\">Back to Admin</button>\n </div> -->\n </div>\n </div>\n</ng-template>\n<ng-template #skeletonLoader *ngIf=\"skeletonLoader\">\n <!-- Service Skeleton Loader HTML -->\n <div class=\"service-grid\">\n <!-- Skeleton Card 1 -->\n <div class=\"service-card skeleton-card\">\n <div class=\"service-header\">\n <div class=\"skeleton skeleton-icon\"></div>\n <div class=\"service-content\">\n <div class=\"skeleton skeleton-title\"></div>\n <div class=\"skeleton skeleton-price\"></div>\n <div class=\"skeleton skeleton-duration\"></div>\n </div>\n </div>\n <div class=\"skeleton skeleton-category\"></div>\n <div class=\"skeleton skeleton-description\"></div>\n <div class=\"skeleton skeleton-badge\"></div>\n </div>\n\n <!-- Skeleton Card 2 -->\n <div class=\"service-card skeleton-card\">\n <div class=\"service-header\">\n <div class=\"skeleton skeleton-icon\"></div>\n <div class=\"service-content\">\n <div class=\"skeleton skeleton-title\"></div>\n <div class=\"skeleton skeleton-price\"></div>\n <div class=\"skeleton skeleton-duration\"></div>\n </div>\n </div>\n <div class=\"skeleton skeleton-category\"></div>\n <div class=\"skeleton skeleton-description\"></div>\n <div class=\"skeleton skeleton-badge\"></div>\n </div>\n\n <!-- Skeleton Card 3 -->\n <div class=\"service-card skeleton-card\">\n <div class=\"service-header\">\n <div class=\"skeleton skeleton-icon\"></div>\n <div class=\"service-content\">\n <div class=\"skeleton skeleton-title\"></div>\n <div class=\"skeleton skeleton-price\"></div>\n <div class=\"skeleton skeleton-duration\"></div>\n </div>\n </div>\n <div class=\"skeleton skeleton-category\"></div>\n <div class=\"skeleton skeleton-description\"></div>\n <div class=\"skeleton skeleton-badge\"></div>\n </div>\n\n <!-- Skeleton Card 4 -->\n <div class=\"service-card skeleton-card\">\n <div class=\"service-header\">\n <div class=\"skeleton skeleton-icon\"></div>\n <div class=\"service-content\">\n <div class=\"skeleton skeleton-title\"></div>\n <div class=\"skeleton skeleton-price\"></div>\n <div class=\"skeleton skeleton-duration\"></div>\n </div>\n </div>\n <div class=\"skeleton skeleton-category\"></div>\n <div class=\"skeleton skeleton-description\"></div>\n <div class=\"skeleton skeleton-badge\"></div>\n </div>\n\n <!-- Skeleton Card 5 -->\n <div class=\"service-card skeleton-card\">\n <div class=\"service-header\">\n <div class=\"skeleton skeleton-icon\"></div>\n <div class=\"service-content\">\n <div class=\"skeleton skeleton-title\"></div>\n <div class=\"skeleton skeleton-price\"></div>\n <div class=\"skeleton skeleton-duration\"></div>\n </div>\n </div>\n <div class=\"skeleton skeleton-category\"></div>\n <div class=\"skeleton skeleton-description\"></div>\n <div class=\"skeleton skeleton-badge\"></div>\n </div>\n\n <!-- Skeleton Card 6 -->\n <div class=\"service-card skeleton-card\">\n <div class=\"service-header\">\n <div class=\"skeleton skeleton-icon\"></div>\n <div class=\"service-content\">\n <div class=\"skeleton skeleton-title\"></div>\n <div class=\"skeleton skeleton-price\"></div>\n <div class=\"skeleton skeleton-duration\"></div>\n </div>\n </div>\n <div class=\"skeleton skeleton-category\"></div>\n <div class=\"skeleton skeleton-description\"></div>\n <div class=\"skeleton skeleton-badge\"></div>\n </div>\n </div>\n</ng-template>", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.date-picker-container{border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;transition:var(--transition-smooth);background-color:var(--slate-50);cursor:pointer}.date-picker-container:hover{border-color:var(--slate-400);background-color:#fff}.date-input{font-size:.95rem;font-weight:600;color:var(--slate-800)!important;background:transparent;border:none;outline:none;cursor:pointer;width:100%}.date-picker-container mat-icon{color:var(--color-primary)!important;font-size:20px!important;width:20px!important;height:20px!important}.datepicker-popover{position:absolute;z-index:1000;margin-top:4px;border-radius:var(--border-radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);background:#fff;border:1px solid var(--slate-200);width:320px}::ng-deep .datepicker-calendar{border-radius:var(--border-radius-lg)!important;width:100%!important}::ng-deep .mat-calendar-header{background:var(--color-accent-gradient)!important;color:#fff!important;padding:.5rem!important}::ng-deep .mat-calendar-content{padding:8px!important}::ng-deep .mat-calendar-controls{margin:0!important}::ng-deep .mat-calendar-period-button{color:#fff!important;font-weight:700!important;font-size:1rem!important}::ng-deep .mat-calendar-arrow{fill:#fff!important}::ng-deep .mat-calendar-previous-button,::ng-deep .mat-calendar-next-button{color:#fff!important}::ng-deep .mat-calendar-body-cell{font-size:13px!important}::ng-deep .mat-calendar-body-cell-content{font-weight:600!important;color:var(--slate-800)!important;border-radius:8px!important}::ng-deep .mat-calendar-body-selected{background:var(--color-accent-gradient)!important;color:#fff!important;box-shadow:0 4px 10px #23086033!important}::ng-deep .mat-calendar-body-today:not(.mat-calendar-body-selected){border:2px solid var(--color-primary)!important;color:var(--color-primary)!important}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.9rem;font-weight:600;color:var(--slate-800)!important;padding:.75rem .5rem;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.main_footer{border-top:1px solid var(--slate-200);background-color:#fff;padding:15px;flex-shrink:0;display:flex;justify-content:center;box-shadow:0 -4px 12px #00000005}.footer-buttons{width:100%;max-width:800px;display:flex;align-items:center}.back-footer-btn{font-size:.95rem;font-weight:600;color:var(--slate-600)!important;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);cursor:pointer}.back-footer-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.complete_booking,.pay-now-btn{background:var(--color-accent-gradient)!important;color:#fff!important;border:none;padding:.75rem 2.25rem!important;font-size:.95rem!important;font-weight:600;border-radius:var(--border-radius-md)!important;box-shadow:0 4px 12px #23086040;transition:var(--transition-smooth);cursor:pointer;display:flex;align-items:center;gap:.5rem;width:max-content!important}.complete_booking img,.pay-now-btn img{width:20px;height:20px;filter:brightness(0) invert(1)}.complete_booking:hover:not([disabled]),.pay-now-btn:hover:not([disabled]){transform:translateY(-2px);box-shadow:0 6px 18px #23086059}.complete_booking:disabled,.pay-now-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed;box-shadow:none}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.datepicker-popover{width:100%;left:0}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}h1{font-size:24px!important;font-weight:600!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i5.TitleCasePipe, name: "titlecase" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i6.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i7.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: LettersOnlyDirective, selector: "[simpoLettersOnly]" }, { kind: "directive", type: NumbersOnlyDirective, selector: "[simpoNumbersOnly]" }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i8.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }] }); }
537
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AppointmentBookingComponent, deps: [{ token: i1.RestService }, { token: i2.EventsService }, { token: i3.Router }, { token: i4.MessageService }, { token: i5.BookingProductCartService }, { token: i6.StorageServiceService }, { token: i7.MatDialogRef, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
538
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AppointmentBookingComponent, isStandalone: true, selector: "simpo-appointment-booking", inputs: { data: "data", index: "index", edit: "edit", delete: "delete", customClass: "customClass", nextComponentColor: "nextComponentColor", prefillContact: "prefillContact" }, host: { listeners: { "window: resize": "getScreenSize($event)", "document:click": "closeOnOutsideClick()" } }, providers: [MessageService], ngImport: i0, template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\r\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\r\n<section class=\"main_section\">\r\n <div class=\"main_header\">\r\n <div class=\"header d-flex justify-content-between align-items-center\">\r\n <div class=\"back-btn d-flex justify-content-center align-items-center cursor-pointer gap-2 mb-3\"\r\n (click)=\"goBack()\">\r\n <mat-icon>keyboard_backspace</mat-icon><span *ngIf=\"screenWidth > 475\">Back to Home</span>\r\n </div>\r\n <div class=\"header-title\">\r\n <h1>Book New Appointment</h1>\r\n <p>{{businessName ?? \"N/A\" }}</p>\r\n </div>\r\n </div>\r\n\r\n <div class=\"progress-bar\">\r\n <div class=\"progress-fill\" [style.width]=\"barWidth + '%'\"></div>\r\n </div>\r\n </div>\r\n <div class=\"main_body w-100 d-flex justify-content-center\">\r\n <ng-container *ngIf=\"selectedTab === 'modeSelection'\">\r\n <ng-container *ngTemplateOutlet=\"modeSelection\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedTab === 'serviceListing'\">\r\n <ng-container *ngIf=\"!skeletonLoader\">\r\n <ng-container *ngTemplateOutlet=\"serviceListing\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedTab === 'locationListing'\">\r\n <ng-container *ngTemplateOutlet=\"locationListing\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedTab === 'staffListing'\">\r\n <ng-container *ngTemplateOutlet=\"staffListing\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedTab === 'dateSelection'\">\r\n <ng-container *ngTemplateOutlet=\"dateSelection\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedTab==='contactDetails'\">\r\n <ng-container *ngTemplateOutlet=\"contactDetails\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedTab==='paymentTab'\">\r\n <ng-container *ngTemplateOutlet=\"paymentTab\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedTab==='statusTemplate'\">\r\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\r\n </ng-container>\r\n </div>\r\n <div class=\"main_footer d-flex justify-content-center align-items-center\"\r\n *ngIf=\"selectedTab!=='statusTemplate' && selectedTab!=='modeSelection'\">\r\n <div class=\"footer-buttons\"\r\n [ngStyle]=\"{'justify-content': selectedTab != 'serviceListing' ? 'space-between' : 'end'}\">\r\n <span class=\"back-footer-btn cursor-pointer\" (click)=\"previousStep()\"\r\n *ngIf=\"selectedTab != 'serviceListing'\">Back</span>\r\n <button class=\"continue-btn\" [disabled]=\"!activeButton\" (click)=\"nextStep()\"\r\n *ngIf=\"selectedTab!='paymentTab'\">{{!loader ? 'Continue' : 'Loading...'}}</button>\r\n <button class=\"cursor-pointer d-flex justify-content-evenly align-items-center\"\r\n *ngIf=\"selectedTab==='paymentTab'\" (click)=\"confirmBooking()\" [disabled]=\"isProcessing\"\r\n [ngClass]=\"{'pay-now-btn' : bookingGroup?.totalCollectedAtBooking > 0 || !bookingGroup,'complete_booking' : bookingGroup && !bookingGroup?.totalCollectedAtBooking}\">\r\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/304012c1753440087996Background.png\">\r\n {{isProcessing ? 'Please wait...' : 'Confirm Booking'}}\r\n </button>\r\n </div>\r\n </div>\r\n</section>\r\n\r\n<ng-template #modeSelection>\r\n <div class=\"w-60 service_section\">\r\n <div class=\"service-selection\">\r\n <h2>How would you like this?</h2>\r\n <p>Choose how you'd like to be served</p>\r\n <div class=\"services-grid\">\r\n <div class=\"service-card\" (click)=\"selectMode('STORE_VISIT')\">\r\n <div class=\"service-header\">\r\n <div class=\"service-icon\"><mat-icon>storefront</mat-icon></div>\r\n <div class=\"service-info\">\r\n <div class=\"service-title\">Visit our Store</div>\r\n </div>\r\n </div>\r\n <div class=\"service-description\">Come to us at one of our locations</div>\r\n </div>\r\n <div class=\"service-card\" (click)=\"selectMode('HOME_VISIT')\">\r\n <div class=\"service-header\">\r\n <div class=\"service-icon\"><mat-icon>home</mat-icon></div>\r\n <div class=\"service-info\">\r\n <div class=\"service-title\">We come to you</div>\r\n </div>\r\n </div>\r\n <div class=\"service-description\">A professional visits your address</div>\r\n </div>\r\n <div class=\"service-card\" (click)=\"selectMode('VIDEO_CALL')\">\r\n <div class=\"service-header\">\r\n <div class=\"service-icon\"><mat-icon>videocam</mat-icon></div>\r\n <div class=\"service-info\">\r\n <div class=\"service-title\">Video consultation</div>\r\n </div>\r\n </div>\r\n <div class=\"service-description\">Connect over a video call</div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #serviceListing>\r\n <div class=\"w-60 service_section\">\r\n <div class=\"service-selection\">\r\n <h2>Select a Service</h2>\r\n <p>Choose the service(s) you'd like to book<span *ngIf=\"cartServices.length > 0\"> \u2014 {{cartServices.length}} selected</span></p>\r\n <p *ngIf=\"productCartItems.length > 0\" class=\"cart-hint\">{{productCartItems.length}} product(s) already in your cart \u2014 you can continue without picking a service.</p>\r\n\r\n <div class=\"services-grid\">\r\n <ng-container *ngFor=\"let service of serviceData\">\r\n <div class=\"\" (click)=\"selectService(service)\"\r\n [ngClass]=\"{ 'service-card-selected' : service?.selected, 'service-card': !service?.selected }\">\r\n <div class=\" service-header\">\r\n <div class=\"service-icon\"><mat-icon>person_outline</mat-icon></div>\r\n <div class=\"service-info\">\r\n <div class=\"service-title\">{{service?.name ? service?.name : 'N/A'}}</div>\r\n </div>\r\n <div>\r\n <div class=\"service-price\">\u20B9{{service?.priceDetails?.price ?\r\n service?.priceDetails?.price : 'N/A' }}</div>\r\n <div class=\"service-duration\">{{service?.duration ? service?.duration : 'N/A'}} min\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"service-description\" *ngIf=\"service?.description\">\r\n {{service?.description ? service?.description : 'N/A'}}\r\n </div>\r\n <div class=\"home-visit\" *ngIf=\"selectedMode === 'STORE_VISIT' && service?.homeAppointmentAvailable\"><img\r\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/982126c1758628863129furniture_16406103.png\">Home\r\n Visit Available</div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #locationListing>\r\n <div class=\"location_section\">\r\n <div class=\"header flex-column align-items-start\">\r\n <h1>Choose Location</h1>\r\n <p>Select where you'd like to receive the service</p>\r\n </div>\r\n\r\n <div class=\"location-list\">\r\n <ng-container *ngFor=\"let location of locationData\">\r\n <div (click)=\"selectLocation(location)\"\r\n [ngClass]=\"{ 'location-card-selected' : location?.selected, 'location-card': !location?.selected }\">\r\n <div class=\"location-content\">\r\n <div class=\"location-info\">\r\n <div class=\"location-icon\"><img\r\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/427226c1758629157758store_3171510.png\">\r\n </div>\r\n <div class=\"location-details\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <h3>{{location?.storeName ? location?.storeName : 'N/A'}}</h3>\r\n </div>\r\n <p>{{location?.addressDetails?.addressLine}}, {{location?.addressDetails?.city}},\r\n {{location?.addressDetails?.state}} {{location?.pincode}}</p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #staffListing>\r\n <div class=\"w-60 overflow-hidden staff-listing\">\r\n <div class=\"d-flex w-100 h-100\">\r\n <div class=\"w-100\">\r\n <div class=\"staff-header mb-3\">\r\n <h1>Select Staff Member</h1>\r\n <p class=\"staff-subtitle mb-0\">Choose your preferred professional</p>\r\n </div>\r\n\r\n <div class=\"search-container mb-4\">\r\n <div class=\"search-input-wrapper d-flex align-items-center\">\r\n <mat-icon class=\"search-icon me-2\">search</mat-icon>\r\n <input type=\"text\" class=\"search-input border-0 flex-grow-1\" placeholder=\"Search staff member by name...\" [(ngModel)]=\"staffSearchQuery\">\r\n <mat-icon class=\"clear-icon cursor-pointer ms-2\" *ngIf=\"staffSearchQuery\" (click)=\"staffSearchQuery = ''\">close</mat-icon>\r\n </div>\r\n </div>\r\n\r\n <!-- Pure product-only line: one flat staff list, same as the old single-service flow -->\r\n <div class=\"staff-list\" *ngIf=\"cartServices.length === 0\">\r\n <ng-container *ngFor=\"let staff of filteredStaff\">\r\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForProductOnlyLine(staff)\"\r\n [ngClass]=\"{ 'staff-card-selected' : staff?.selected, 'staff-card': !staff?.selected }\">\r\n <div class=\"d-flex align-items-center justify-content-between w-100\">\r\n <div class=\"d-flex align-items-center flex-grow-1\">\r\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\r\n {{staff?.staffName.slice(0,2).toUpperCase()}}\r\n </div>\r\n <div class=\"staff-details flex-grow-1\">\r\n <h3 class=\"staff-name\">{{(staff?.staffName ? staff?.staffName : 'N/A') | titlecase}}</h3>\r\n <p class=\"staff-specialty\">{{(businessName && businessName !== 'N/A') ? businessName : 'Booking Specialist'}}</p>\r\n </div>\r\n </div>\r\n <div class=\"selection-indicator\">\r\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"staff?.selected\">\r\n <mat-icon *ngIf=\"staff?.selected\">check</mat-icon>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Bundled cart: one pool per line that resolution couldn't collapse to a single provider -->\r\n <ng-container *ngIf=\"cartServices.length > 0\">\r\n <div class=\"staff-line-group mb-4\" *ngFor=\"let line of resolvedLines\">\r\n <ng-container *ngIf=\"line.candidateStaffPool?.length\">\r\n <h4 class=\"mb-2\">For {{line.services.length}} service(s): {{ (line.services | slice:0:3).length ? '' : '' }}<span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></h4>\r\n <div class=\"staff-list mb-3\">\r\n <ng-container *ngFor=\"let staff of line.candidateStaffPool\">\r\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForLine(line, staff)\"\r\n [ngClass]=\"{ 'staff-card-selected' : line.selectedStaffId === staff.id, 'staff-card': line.selectedStaffId !== staff.id }\">\r\n <div class=\"d-flex align-items-center justify-content-between w-100\">\r\n <div class=\"d-flex align-items-center flex-grow-1\">\r\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\r\n {{staff?.name?.slice(0,2)?.toUpperCase()}}\r\n </div>\r\n <div class=\"staff-details flex-grow-1\">\r\n <h3 class=\"staff-name\">{{(staff?.name ? staff?.name : 'N/A') | titlecase}}</h3>\r\n </div>\r\n </div>\r\n <div class=\"selection-indicator\">\r\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"line.selectedStaffId === staff.id\">\r\n <mat-icon *ngIf=\"line.selectedStaffId === staff.id\">check</mat-icon>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #dateSelection>\r\n <div class=\"w-60 date_section\">\r\n <div class=\"row justify-content-center h-100\">\r\n <div class=\"col-12 h-100\">\r\n <div class=\"datetime-header mb-2\">\r\n <h1>Select Date & Time</h1>\r\n <p class=\"datetime-subtitle mb-0\">Choose when you'd like your appointment</p>\r\n </div>\r\n\r\n <div class=\"d-flex gap-4 main_container\">\r\n <div [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\r\n <div class=\"section-card card rounded-3 p-4 h-100\">\r\n <h3 class=\"section-title\">Select Date</h3>\r\n\r\n <div class=\"date-picker-container d-flex align-items-center justify-content-between\"\r\n (click)=\"$event.stopPropagation()\">\r\n <input type=\"text\" class=\"date-input border-0 rounded-2\" placeholder=\"dd-mm-yyyy\"\r\n [value]=\"selectedDateStr\" readonly (click)=\"toggleCalendar($event)\">\r\n\r\n <mat-icon class=\"ms-2\" (click)=\"toggleCalendar($event)\">calendar_today</mat-icon>\r\n </div>\r\n <div class=\"position-relative\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"datepicker-popover\" *ngIf=\"showCalendar\">\r\n <mat-calendar [(selected)]=\"selectedDate\" [dateFilter]=\"dateFilter\"\r\n (selectedChange)=\"onDateSelected($event)\" class=\"datepicker-calendar\">\r\n </mat-calendar>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- One slot-picker per resolved line, side by side when there's more than one (design doc \u00A73b) -->\r\n <div class=\"time_selection\" [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\" *ngIf=\"resolvedLines.length <= 1\">\r\n <div class=\"section-card card h-100 rounded-3 p-4\">\r\n <h3 class=\"section-title\">Available Times</h3>\r\n <div class=\"row g-2 mb-4 overflow-scroll\">\r\n <ng-container *ngIf=\"!skeletonLoader && resolvedLines[0]\">\r\n <div class=\"col-4\" *ngFor=\"let time of resolvedLines[0].slots\">\r\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\r\n (click)=\"selectSlotForLine(resolvedLines[0], time)\">{{time ? time?.value : 'N/A'}}</div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Multi-line case: each line gets its own full-width card with a staff header -->\r\n <div class=\"d-flex gap-4 main_container flex-wrap\" *ngIf=\"resolvedLines.length > 1\">\r\n <div class=\"w-100\" *ngFor=\"let line of resolvedLines\">\r\n <div class=\"section-card card rounded-3 p-4\">\r\n <h3 class=\"section-title\">Professional: {{line.staffName || line.selectedStaffName}}</h3>\r\n <p class=\"mb-2\" *ngIf=\"line.services.length\"><span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></p>\r\n <div class=\"row g-2 mb-2 overflow-scroll\">\r\n <ng-container *ngIf=\"!line.slotsLoading\">\r\n <div class=\"col-4\" *ngFor=\"let time of line.slots\">\r\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\r\n (click)=\"selectSlotForLine(line, time)\">{{time ? time?.value : 'N/A'}}</div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #contactDetails>\r\n <div class=\"w-60 contact_section\">\r\n <div class=\"contact-header mb-2\">\r\n <h1>Contact Details</h1>\r\n <p class=\"contact-subtitle mb-0\">Provide your contact information</p>\r\n </div>\r\n\r\n <div class=\"d-flex gap-3 details_container flex-column w-100\">\r\n <div class=\"d-flex gap-4\">\r\n <div [ngClass]=\"{'w-50' : selectedMode === 'HOME_VISIT', 'w-100' : selectedMode !== 'HOME_VISIT'}\">\r\n <div class=\"form-section card rounded-3 p-4 h-100\">\r\n <h3 class=\"section-title\">Personal Information</h3>\r\n\r\n <div class=\"mb-4\">\r\n <label class=\"form-label d-flex align-items-center\">\r\n Full Name\r\n <span class=\"required-asterisk\">*</span>\r\n </label>\r\n <input type=\"text\" class=\"form-control form-input rounded-2\"\r\n [(ngModel)]=\"appointmentPayload.customerDetail.name\"\r\n (ngModelChange)=\"checkRequiredValues()\" simpoLettersOnly>\r\n </div>\r\n\r\n <div class=\"mb-4\">\r\n <label class=\"form-label d-flex align-items-center\">\r\n Email Address\r\n <span class=\"required-asterisk\">*</span>\r\n </label>\r\n <input type=\"email\" class=\"form-control form-input rounded-2\"\r\n [(ngModel)]=\"appointmentPayload.customerDetail.email\"\r\n (ngModelChange)=\"checkRequiredValues()\"\r\n pattern=\"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" #emailField=\"ngModel\"\r\n name=\"email\" required>\r\n </div>\r\n\r\n <div class=\"mb-0\">\r\n <label class=\"form-label d-flex align-items-center\">\r\n Phone Number\r\n <span class=\"required-asterisk\">*</span>\r\n </label>\r\n <input type=\"tel\" class=\"form-control rounded-2\"\r\n [(ngModel)]=\"appointmentPayload.customerDetail.phoneNumber\"\r\n (ngModelChange)=\"checkRequiredValues()\" simpoNumbersOnly\r\n [ngClass]=\"{'mobile_number' : appointmentPayload.customerDetail.phoneNumber.length != 10}\">\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Home Visit address - structured fields matching BookingGroupRequest.addressDetails exactly -->\r\n <div class=\"w-50\" *ngIf=\"selectedMode === 'HOME_VISIT'\">\r\n <div class=\"form-section card rounded-3 p-4 h-100\">\r\n <h3 class=\"section-title\">Home Visit Details</h3>\r\n\r\n <div class=\"mb-3\">\r\n <label class=\"form-label d-flex align-items-center\">Receiver Name</label>\r\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.receiverName\">\r\n </div>\r\n <div class=\"mb-3\">\r\n <label class=\"form-label d-flex align-items-center\">Receiver Phone</label>\r\n <input type=\"tel\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.receiverPhone\">\r\n </div>\r\n <div class=\"mb-3\">\r\n <label class=\"form-label d-flex align-items-center\">Address Line 1</label>\r\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine1\">\r\n </div>\r\n <div class=\"mb-3\">\r\n <label class=\"form-label d-flex align-items-center\">Address Line 2 (optional)</label>\r\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine2\">\r\n </div>\r\n <div class=\"d-flex gap-2 mb-3\">\r\n <div class=\"w-50\">\r\n <label class=\"form-label d-flex align-items-center\">City</label>\r\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.city\">\r\n </div>\r\n <div class=\"w-50\">\r\n <label class=\"form-label d-flex align-items-center\">State</label>\r\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.state\">\r\n </div>\r\n </div>\r\n <div class=\"mb-3\">\r\n <label class=\"form-label d-flex align-items-center\">Pincode</label>\r\n <input type=\"text\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.zipCode\">\r\n </div>\r\n <div class=\"mb-0\">\r\n <label class=\"form-label d-flex align-items-center\">Special Instructions</label>\r\n <textarea class=\"form-control form-textarea rounded-2\"\r\n placeholder=\"Any special instructions for the professional (optional)\"\r\n [(ngModel)]=\"instructions\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"policies-container\"\r\n *ngIf=\"cartServices[0]?.cancellationPolicy?.length > 0 || cartServices[0]?.reschedulePolicy?.length\">\r\n <h2 class=\"policies-title\">Policies & Terms</h2>\r\n\r\n <div class=\"policy-items-container d-flex flex-column gap-3\">\r\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\r\n (click)=\"showCancellationPolicy = !showCancellationPolicy\">\r\n <h3 class=\"policy-title\">Cancellation Policy</h3>\r\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\r\n *ngIf=\"!showCancellationPolicy\">keyboard_arrow_right</mat-icon>\r\n <mat-icon *ngIf=\"showCancellationPolicy\">keyboard_arrow_down</mat-icon>\r\n </div>\r\n </div>\r\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\r\n *ngIf=\"showCancellationPolicy\">\r\n <span *ngFor=\"let policy of cartServices[0]?.cancellationPolicy\">&#8226;\r\n {{policy}}</span>\r\n </div>\r\n\r\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\r\n (click)=\"showReducingPolicy = !showReducingPolicy\">\r\n <h3 class=\"policy-title\">Rescheduling Policy</h3>\r\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\r\n *ngIf=\"!showReducingPolicy\">keyboard_arrow_right</mat-icon>\r\n <mat-icon *ngIf=\"showReducingPolicy\">keyboard_arrow_down</mat-icon>\r\n </div>\r\n </div>\r\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\r\n *ngIf=\"showReducingPolicy\">\r\n <span *ngFor=\"let policy of cartServices[0]?.reschedulePolicy\">&#8226; {{policy}}</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"acceptance-section\">\r\n <input type=\"checkbox\" class=\"custom-checkbox\" [(ngModel)]=\"termsAndConditions\"\r\n (ngModelChange)=\"checkRequiredValues()\">\r\n <p class=\"acceptance-text\" style=\"margin-bottom:0px !important\">\r\n I understand and accept the cancellation & rescheduling policies.\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #paymentTab>\r\n <div class=\"w-60 payment_section\">\r\n <div class=\"w-100 h-100\">\r\n <div class=\"w-100 d-flex justify-content-center align-items-center flex-column\">\r\n <div class=\"payment-header mb-3 w-100\">\r\n <h1 style=\"font-size:24px;font-weight: 600;\">Booking Summary</h1>\r\n <p class=\"payment-subtitle mb-0\">Review your booking before confirming</p>\r\n </div>\r\n\r\n <div class=\"booking-summary-card\" [ngClass]=\"{'w-100' : screenWidth < 475,'w-50':screenWidth > 475}\">\r\n <div *ngFor=\"let line of resolvedLines; let i = index\">\r\n <h2 class=\"summary-title\" *ngIf=\"resolvedLines.length > 1\">Line {{i + 1}}</h2>\r\n <div class=\"summary-row\" *ngIf=\"line.services.length\">\r\n <div class=\"summary-label\">Service(s)</div>\r\n <div class=\"summary-value\"><span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></div>\r\n </div>\r\n <div class=\"summary-row\" *ngIf=\"line.staffName || line.selectedStaffName\">\r\n <div class=\"summary-label\">Professional</div>\r\n <div class=\"summary-value\">{{line.staffName || line.selectedStaffName}}</div>\r\n </div>\r\n <div class=\"summary-row\" *ngIf=\"selectedMode === 'STORE_VISIT'\">\r\n <div class=\"summary-label\">Location</div>\r\n <div class=\"summary-value\">{{selectedLocation?.storeName ?? 'N/A'}}</div>\r\n </div>\r\n <div class=\"summary-row\">\r\n <div class=\"summary-label\">Date & Time</div>\r\n <div class=\"summary-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"productCartItems.length > 0\">\r\n <h2 class=\"summary-title\">Products</h2>\r\n <div class=\"summary-row\" *ngFor=\"let p of productCartItems\">\r\n <div class=\"summary-label\">{{p.itemName}} x{{p.quantity}}</div>\r\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{(p.sellingPrice ?? p.price ?? 0) * (p.quantity ?? 1)}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #statusTemplate>\r\n <div class=\"booking-confirmation\">\r\n <div class=\"success-icon\">\r\n <div class=\"checkmark-circle\">\r\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\r\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\r\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\r\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"confirmation-content\">\r\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\r\n <p class=\"confirmation-message\">\r\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book you appointment. Please\r\n try again later'}}\r\n </p>\r\n\r\n <!-- Video Call link, when already present on the confirmed group (a paid Video Call's\r\n link only appears once payment verification completes, handled elsewhere - see\r\n verify-payment.component.ts, not this screen). -->\r\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && selectedMode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\r\n <div class=\"details-card\">\r\n <h3 class=\"details-title\">Your Video Call Link</h3>\r\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\r\n <div class=\"details-card\">\r\n <h3 class=\"details-title\">Appointment Details</h3>\r\n <div class=\"details-row\" *ngFor=\"let line of resolvedLines\">\r\n <span class=\"detail-label\">{{line.services.length ? (line.services[0].name) : 'Products'}}</span>\r\n <span class=\"detail-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.date-picker-container{border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;transition:var(--transition-smooth);background-color:var(--slate-50);cursor:pointer}.date-picker-container:hover{border-color:var(--slate-400);background-color:#fff}.date-input{font-size:.95rem;font-weight:600;color:var(--slate-800)!important;background:transparent;border:none;outline:none;cursor:pointer;width:100%}.date-picker-container mat-icon{color:var(--color-primary)!important;font-size:20px!important;width:20px!important;height:20px!important}.datepicker-popover{position:absolute;z-index:1000;margin-top:4px;border-radius:var(--border-radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);background:#fff;border:1px solid var(--slate-200);width:320px}::ng-deep .datepicker-calendar{border-radius:var(--border-radius-lg)!important;width:100%!important}::ng-deep .mat-calendar-header{background:var(--color-accent-gradient)!important;color:#fff!important;padding:.5rem!important}::ng-deep .mat-calendar-content{padding:8px!important}::ng-deep .mat-calendar-controls{margin:0!important}::ng-deep .mat-calendar-period-button{color:#fff!important;font-weight:700!important;font-size:1rem!important}::ng-deep .mat-calendar-arrow{fill:#fff!important}::ng-deep .mat-calendar-previous-button,::ng-deep .mat-calendar-next-button{color:#fff!important}::ng-deep .mat-calendar-body-cell{font-size:13px!important}::ng-deep .mat-calendar-body-cell-content{font-weight:600!important;color:var(--slate-800)!important;border-radius:8px!important}::ng-deep .mat-calendar-body-selected{background:var(--color-accent-gradient)!important;color:#fff!important;box-shadow:0 4px 10px #23086033!important}::ng-deep .mat-calendar-body-today:not(.mat-calendar-body-selected){border:2px solid var(--color-primary)!important;color:var(--color-primary)!important}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.9rem;font-weight:600;color:var(--slate-800)!important;padding:.75rem .5rem;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.main_footer{border-top:1px solid var(--slate-200);background-color:#fff;padding:15px;flex-shrink:0;display:flex;justify-content:center;box-shadow:0 -4px 12px #00000005}.footer-buttons{width:100%;max-width:800px;display:flex;align-items:center}.back-footer-btn{font-size:.95rem;font-weight:600;color:var(--slate-600)!important;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);cursor:pointer}.back-footer-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.complete_booking,.pay-now-btn{background:var(--color-accent-gradient)!important;color:#fff!important;border:none;padding:.75rem 2.25rem!important;font-size:.95rem!important;font-weight:600;border-radius:var(--border-radius-md)!important;box-shadow:0 4px 12px #23086040;transition:var(--transition-smooth);cursor:pointer;display:flex;align-items:center;gap:.5rem;width:max-content!important}.complete_booking img,.pay-now-btn img{width:20px;height:20px;filter:brightness(0) invert(1)}.complete_booking:hover:not([disabled]),.pay-now-btn:hover:not([disabled]){transform:translateY(-2px);box-shadow:0 6px 18px #23086059}.complete_booking:disabled,.pay-now-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed;box-shadow:none}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.datepicker-popover{width:100%;left:0}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}h1{font-size:24px!important;font-weight:600!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i8.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i8.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i8.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i8.SlicePipe, name: "slice" }, { kind: "pipe", type: i8.TitleCasePipe, name: "titlecase" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i9.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i10.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i10.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i10.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i10.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i10.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i10.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: LettersOnlyDirective, selector: "[simpoLettersOnly]" }, { kind: "directive", type: NumbersOnlyDirective, selector: "[simpoNumbersOnly]" }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i11.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }] }); }
491
539
  }
492
540
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AppointmentBookingComponent, decorators: [{
493
541
  type: Component,
494
- args: [{ selector: 'simpo-appointment-booking', standalone: true, imports: [CdkDragPlaceholder, CommonModule, MatIcon, MatFormFieldModule, MatDatepickerModule, FormsModule, MatNativeDateModule, MatInputModule, LettersOnlyDirective, NumbersOnlyDirective, ToastModule], providers: [MessageService], template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\">\n <div class=\"main_header\">\n <div class=\"header d-flex justify-content-between align-items-center\">\n <div class=\"back-btn d-flex justify-content-center align-items-center cursor-pointer gap-2 mb-3\"\n (click)=\"goBack()\">\n <mat-icon>keyboard_backspace</mat-icon><span *ngIf=\"screenWidth > 475\">Back to Home</span>\n </div>\n <div class=\"header-title\">\n <h1>Book New Appointment</h1>\n <p>{{businessName ?? \"N/A\" }}</p>\n </div>\n </div>\n\n <div class=\"progress-bar\">\n <div class=\"progress-fill\" [style.width]=\"barWidth + '%'\"></div>\n </div>\n </div>\n <div class=\"main_body w-100 d-flex justify-content-center\"><ng-container *ngIf=\"selectedTab === 'serviceListing'\">\n <ng-container *ngIf=\"!skeletonLoader\">\n <ng-container *ngTemplateOutlet=\"serviceListing\"></ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'locationListing'\">\n <ng-container *ngTemplateOutlet=\"locationListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'staffListing'\">\n <ng-container *ngTemplateOutlet=\"staffListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'dateSelection'\">\n <ng-container *ngTemplateOutlet=\"dateSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='contactDetails'\">\n <ng-container *ngTemplateOutlet=\"contactDetails\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='paymentTab'\">\n <ng-container *ngTemplateOutlet=\"paymentTab\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='statusTemplate'\">\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\n </ng-container>\n </div>\n <div class=\"main_footer d-flex justify-content-center align-items-center\" *ngIf=\"selectedTab!=='statusTemplate'\">\n <div class=\"footer-buttons\"\n [ngStyle]=\"{'justify-content': selectedTab != 'serviceListing' ? 'space-between' : 'end'}\">\n <span class=\"back-footer-btn cursor-pointer\" (click)=\"previousStep()\"\n *ngIf=\"selectedTab != 'serviceListing'\">Back</span>\n <button class=\"continue-btn\" [disabled]=\"!activeButton\" (click)=\"nextStep()\"\n *ngIf=\"selectedTab!='paymentTab'\">{{!loader ? 'Continue' : 'Loading...'}}</button>\n <button class=\"cursor-pointer d-flex justify-content-evenly align-items-center\"\n *ngIf=\"selectedTab==='paymentTab'\" (click)=\"checkPayment()\" [disabled]=\"isProcessing\"\n [ngClass]=\"{'pay-now-btn' : selectedService?.depositAmount?.depositRequired,'complete_booking' : !selectedService?.depositAmount?.depositRequired}\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/304012c1753440087996Background.png\">\n {{selectedService?.depositAmount?.depositRequired ? 'Pay Now' : 'Complete Booking'}}\n </button>\n </div>\n </div>\n</section>\n<ng-template #serviceListing>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>Select a Service</h2>\n <p>Choose the service you'd like to book</p>\n\n <div class=\"services-grid\">\n <ng-container *ngFor=\"let service of serviceData\">\n <div class=\"\" (click)=\"selectService(service)\"\n [ngClass]=\"{ 'service-card-selected' : service?.selected, 'service-card': !service?.selected }\">\n <div class=\" service-header\">\n <div class=\"service-icon\"><mat-icon>person_outline</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">{{service?.name ? service?.name : 'N/A'}}</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B9{{service?.priceDetails?.price ?\n service?.priceDetails?.price : 'N/A' }}</div>\n <div class=\"service-duration\">{{service?.duration ? service?.duration : 'N/A'}} min\n </div>\n </div>\n </div>\n <div class=\"service-description\" *ngIf=\"service?.description\">\n {{service?.description ? service?.description : 'N/A'}}\n </div>\n <div class=\"home-visit\" *ngIf=\"service?.homeAppointmentAvailable\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/982126c1758628863129furniture_16406103.png\">Home\n Visit Available</div>\n </div>\n </ng-container>\n\n <!-- <div class=\"service-card\">\n <div class=\"service-header\">\n <div class=\"service-icon\">\uD83D\uDC64</div>\n <div class=\"service-info\">\n <div class=\"service-title\">General Consultation</div>\n <div class=\"service-category\">Medical</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B9800</div>\n <div class=\"service-duration\">30 min</div>\n </div>\n </div>\n <div class=\"service-description\">\n Comprehensive health consultation\n </div>\n </div>\n\n <div class=\"service-card\">\n <div class=\"service-header\">\n <div class=\"service-icon\">\uD83E\uDDE0</div>\n <div class=\"service-info\">\n <div class=\"service-title\">Mental Health Counseling</div>\n <div class=\"service-category\">Mental Health</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B91500</div>\n <div class=\"service-duration\">45 min</div>\n </div>\n </div>\n <div class=\"service-description\">\n Professional psychological support\n </div>\n <div class=\"home-visit\">Home Visit Available</div>\n </div>\n\n <div class=\"service-card\">\n <div class=\"service-header\">\n <div class=\"service-icon\">\u2702</div>\n <div class=\"service-info\">\n <div class=\"service-title\">Hair Cut & Styling</div>\n <div class=\"service-category\">Beauty</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B91200</div>\n <div class=\"service-duration\">45 min</div>\n </div>\n </div>\n <div class=\"service-description\">\n Professional hair cutting and styling\n </div>\n <div class=\"home-visit\">Home Visit Available</div>\n </div> -->\n </div>\n </div>\n </div>\n</ng-template>\n<ng-template #locationListing>\n <div class=\"location_section\">\n <div class=\"header flex-column align-items-start\">\n <h1>Choose Location</h1>\n <p>Select where you'd like to receive the service</p>\n </div>\n\n <div class=\"location-list\">\n <ng-container *ngFor=\"let location of locationData\">\n <div (click)=\"selectLocation(location)\"\n [ngClass]=\"{ 'location-card-selected' : location?.selected, 'location-card': !location?.selected }\">\n <div class=\"location-content\">\n <div class=\"location-info\">\n <div class=\"location-icon\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/427226c1758629157758store_3171510.png\">\n </div>\n <div class=\"location-details\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <h3>{{location?.storeName ? location?.storeName : 'N/A'}}</h3>\n <!-- <div class=\"distance\"><mat-icon>location_on</mat-icon> 2.3 km</div> -->\n </div>\n <p>{{location?.addressDetails?.addressLine}}, {{location?.addressDetails?.city}},\n {{location?.addressDetails?.state}} {{location?.pincode}}</p>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n <!-- <div class=\"location-card\">\n <div class=\"location-content\">\n <div class=\"location-info\">\n <div class=\"location-icon branch-icon\"></div>\n <div class=\"location-details\">\n <h3>Branch Clinic</h3>\n <p>456 Care Avenue, Health Zone, Mumbai 400015</p>\n </div>\n </div>\n <div class=\"distance\">5.8 km</div>\n </div>\n </div>\n\n <div class=\"location-card\">\n <div class=\"location-content\">\n <div class=\"location-info\">\n <div class=\"location-icon home-icon\"></div>\n <div class=\"location-details\">\n <h3>Home Visit</h3>\n <p>Your Location</p>\n </div>\n </div>\n <div class=\"distance\">0 km</div>\n </div>\n </div> -->\n </div>\n </div>\n</ng-template>\n<ng-template #staffListing>\n <div class=\"w-60 overflow-hidden staff-listing\">\n <div class=\"d-flex w-100 h-100\">\n <div class=\"w-100\">\n <!-- Header Section -->\n <div class=\"staff-header mb-3\">\n <h1>Select Staff Member</h1>\n <p class=\"staff-subtitle mb-0\">Choose your preferred professional</p>\n </div>\n\n <!-- Staff Search Bar -->\n <div class=\"search-container mb-4\">\n <div class=\"search-input-wrapper d-flex align-items-center\">\n <mat-icon class=\"search-icon me-2\">search</mat-icon>\n <input type=\"text\" class=\"search-input border-0 flex-grow-1\" placeholder=\"Search staff member by name...\" [(ngModel)]=\"staffSearchQuery\">\n <mat-icon class=\"clear-icon cursor-pointer ms-2\" *ngIf=\"staffSearchQuery\" (click)=\"staffSearchQuery = ''\">close</mat-icon>\n </div>\n </div>\n\n <!-- Staff Cards -->\n <div class=\"staff-list\">\n <ng-container *ngFor=\"let staff of filteredStaff\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaff(staff)\"\n [ngClass]=\"{ 'staff-card-selected' : staff?.selected, 'staff-card': !staff?.selected }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div\n class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.staffName.slice(0,2).toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.staffName ? staff?.staffName : 'N/A') | titlecase}}</h3>\n <p class=\"staff-specialty\">{{(businessName && businessName !== 'N/A') ? businessName : 'Booking Specialist'}}</p>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"staff?.selected\">\n <mat-icon *ngIf=\"staff?.selected\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n<ng-template #dateSelection>\n <div class=\"w-60 date_section\">\n <div class=\"row justify-content-center h-100\">\n <div class=\"col-12 h-100\">\n <div class=\"datetime-header mb-2\">\n <h1>Select Date & Time</h1>\n <p class=\"datetime-subtitle mb-0\">Choose when you'd like your appointment</p>\n </div>\n\n <!-- Main Content -->\n <div class=\"d-flex gap-4 main_container\">\n <!-- Left Column - Date Selection -->\n <div [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Select Date</h3>\n\n <div class=\"date-picker-container d-flex align-items-center justify-content-between\"\n (click)=\"$event.stopPropagation()\">\n <input type=\"text\" class=\"date-input border-0 rounded-2\" placeholder=\"dd-mm-yyyy\"\n [value]=\"selectedDateStr\" readonly (click)=\"toggleCalendar($event)\">\n\n <mat-icon class=\"ms-2\" (click)=\"toggleCalendar($event)\">calendar_today</mat-icon>\n </div>\n <div class=\"position-relative\" (click)=\"$event.stopPropagation()\">\n <div class=\"datepicker-popover\" *ngIf=\"showCalendar\">\n <mat-calendar [(selected)]=\"selectedDate\" [dateFilter]=\"dateFilter\"\n (selectedChange)=\"onDateSelected($event)\" class=\"datepicker-calendar\">\n </mat-calendar>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Right Column - Time Selection -->\n <div class=\"time_selection\" [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card h-100 rounded-3 p-4\">\n <h3 class=\"section-title\">Available Times</h3>\n\n <!-- Time Slots Grid -->\n <div class=\"row g-2 mb-4 overflow-scroll\">\n <ng-container *ngIf=\"!skeletonLoader ;else slotsLoader\">\n <div class=\"col-4\" *ngFor=\"let time of locationTiming\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectTimeSlot(time)\">{{time ?\n time?.value : 'N/A'}}</div>\n </div>\n </ng-container>\n <ng-template #slotsLoader>\n <!-- Time Slot Grid Skeleton Loader HTML -->\n <div class=\"time-slot-grid\">\n <!-- Row 1 -->\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n\n <!-- Row 2 -->\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n\n <!-- Row 3 -->\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n\n <!-- Row 4 -->\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n\n <!-- Row 5 -->\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n\n <!-- Row 6 -->\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n <div class=\"skeleton-time-slot\"></div>\n </div>\n\n </ng-template>\n </div>\n\n <!-- Waitlist Section -->\n <!-- <div class=\"waitlist-section rounded-3\">\n <div class=\"d-flex align-items-start\">\n <div class=\"d-flex h-100 justify-content-between flex-column\">\n <div class=\"waitlist-title d-flex align-items-center gap-2\"><span\n class=\"waitlist-icon check-icon\"></span>No\n slots available?</div>\n <div class=\"waitlist-description d-flex align-items-center gap-2\">\n <input class=\"form-check-input cursor-pointer\" type=\"checkbox\"\n id=\"flexCheckChecked\">\n Add me to the waitlist for earlier\n availability\n </div>\n </div>\n <div>\n </div>\n </div>\n </div> -->\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n</ng-template>\n<ng-template #contactDetails>\n <div class=\"w-60 contact_section\">\n <!-- Header Section -->\n <div class=\"contact-header mb-2\">\n <h1>Contact Details</h1>\n <p class=\"contact-subtitle mb-0\">Provide your contact information</p>\n </div>\n\n <!-- Form Sections -->\n <div class=\"d-flex gap-3 details_container flex-column w-100\">\n <!-- Left Column - Personal Information -->\n <div class=\"d-flex gap-4\">\n <div\n [ngClass]=\"{'w-50' : selectedService?.homeAppointmentAvailable, 'w-100' : !selectedService?.homeAppointmentAvailable}\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Personal Information</h3>\n\n <!-- Full Name -->\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Full Name\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"text\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.name\"\n (ngModelChange)=\"checkRequiredValues()\" simpoLettersOnly>\n </div>\n\n <!-- Email Address -->\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Email Address\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"email\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.email\"\n (ngModelChange)=\"checkRequiredValues()\"\n pattern=\"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" #emailField=\"ngModel\"\n name=\"email\" required>\n </div>\n\n <!-- Phone Number -->\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">\n Phone Number\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"tel\" class=\"form-control rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.phoneNumber\"\n (ngModelChange)=\"checkRequiredValues()\" simpoNumbersOnly\n [ngClass]=\"{'mobile_number' : appointmentPayload.customerDetail.phoneNumber.length != 10}\">\n </div>\n </div>\n </div>\n <!-- Right Column - Home Visit Details -->\n <div class=\"w-50\" *ngIf=\"selectedService?.homeAppointmentAvailable\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Home Visit Details</h3>\n\n <!-- Home Address -->\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Home Address\n </label>\n <textarea class=\"form-control form-textarea rounded-2\"\n placeholder=\"Enter your complete address\" [(ngModel)]=\"homeAddress\"></textarea>\n </div>\n\n <!-- Special Instructions -->\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">\n Special Instructions\n </label>\n <textarea class=\"form-control form-textarea rounded-2\"\n placeholder=\"Any special instructions for the professional (optional)\"\n [(ngModel)]=\"instructions\"></textarea>\n </div>\n </div>\n </div>\n </div>\n <div class=\"policies-container\"\n *ngIf=\"selectedService?.cancellationPolicy?.length > 0 || selectedService?.reschedulePolicy?.length\">\n <!-- Header -->\n <h2 class=\"policies-title\">Policies & Terms</h2>\n\n <!-- Policy Items -->\n <div class=\"policy-items-container d-flex flex-column gap-3\">\n <!-- Cancellation Policy -->\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showCancellationPolicy = !showCancellationPolicy\">\n <h3 class=\"policy-title\">Cancellation Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showCancellationPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showCancellationPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showCancellationPolicy\">\n <span *ngFor=\"let policy of selectedService?.cancellationPolicy\">&#8226;\n {{policy}}</span>\n </div>\n\n <!-- Rescheduling Policy -->\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showReducingPolicy = !showReducingPolicy\">\n <h3 class=\"policy-title\">Rescheduling Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showReducingPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showReducingPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showReducingPolicy\">\n <span *ngFor=\"let policy of selectedService?.reschedulePolicy\">&#8226; {{policy}}</span>\n </div>\n </div>\n\n <!-- Acceptance Section -->\n <div class=\"acceptance-section\">\n <input type=\"checkbox\" class=\"custom-checkbox\" [(ngModel)]=\"termsAndConditions\"\n (ngModelChange)=\"checkRequiredValues()\">\n <p class=\"acceptance-text\" style=\"margin-bottom:0px !important\">\n I understand and accept the cancellation & rescheduling policies.\n <!-- <span class=\"terms-link\">Terms & Conditions<span\n class=\"external-link-icon\"></span></span> -->\n </p>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n<ng-template #paymentTab>\n <div class=\"w-60 payment_section\">\n <div class=\"w-100 h-100\">\n <div class=\"w-100 d-flex justify-content-center align-items-center flex-column\">\n <!-- Header Section -->\n <div class=\"payment-header mb-3 w-100\">\n <h1 style=\"font-size:24px;font-weight: 600;\">\n {{selectedService?.depositAmount?.depositRequired ? 'Payment & Confirmation' : 'Booking Confirmation'}}\n </h1>\n <p class=\"payment-subtitle mb-0\">\n {{selectedService?.depositAmount?.depositRequired ? 'Review your booking and complete payment' : \n 'Before Confirmation Review your booking'}}\n </p>\n </div>\n\n <!-- Booking Summary Card -->\n <div class=\"booking-summary-card\" [ngClass]=\"{'w-100' : screenWidth < 475,'w-50':screenWidth > 475}\">\n <h2 class=\"summary-title\">Booking Summary</h2>\n\n <!-- Service -->\n <div class=\"summary-row\">\n <div class=\"summary-label\">Service</div>\n <div class=\"summary-value\">{{selectedService?.name ? selectedService?.name : 'N/A'}}</div>\n </div>\n\n <!-- Professional -->\n <div class=\"summary-row\" *ngIf=\"selectedStaff?.staffName\">\n <div class=\"summary-label\">Professional</div>\n <div class=\"summary-value\">{{selectedStaff?.staffName ? selectedStaff?.staffName : 'N/A'}}</div>\n </div>\n\n <!-- Location -->\n <div class=\"summary-row\">\n <div class=\"summary-label\">Location</div>\n <div class=\"summary-value\">{{selectedLocation?.storeName ? selectedLocation?.storeName : 'N/A'}}\n </div>\n </div>\n\n <!-- Date & Time -->\n <div class=\"summary-row\">\n <div class=\"summary-label\">Date & Time</div>\n <div class=\"summary-value\">{{selectedDateStr ? (selectedDateStr) : 'N/A'}} at\n {{selectedTime ? selectedTime.value : 'N/A'}}</div>\n </div>\n\n <!-- Duration -->\n <div class=\"summary-row\">\n <div class=\"summary-label\">Duration</div>\n <div class=\"summary-value\">{{selectedService?.duration ? selectedService?.duration : 'N/A'}}\n minutes</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Tax Percent</div>\n <div class=\"summary-value\">{{selectedService?.priceDetails?.taxPercent ?\n selectedService?.priceDetails?.taxPercent : 0}}%</div>\n </div>\n <!-- Total -->\n <div class=\"summary-row total-row\">\n <div class=\"summary-label\">Total</div>\n <div class=\"summary-value\">\n <span class=\"currency-symbol\">\u20B9</span>{{selectedService?.priceDetails?.totalPrice ?\n selectedService?.priceDetails?.totalPrice : '0'}}\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n<ng-template #statusTemplate>\n <div class=\"booking-confirmation\">\n <!-- Success Icon -->\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <!-- Main Content -->\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book you appointment. Please\n try again later'}}\n </p>\n\n <!-- Details Card -->\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n\n <div class=\"details-row\">\n <span class=\"detail-label\">Service</span>\n <span class=\"detail-value\">{{appointmentPayload.serviceDetail?.name ?\n appointmentPayload.serviceDetail?.name : 'N/A'}}</span>\n </div>\n\n <div class=\"details-row\" *ngIf=\"appointmentPayload?.staffDetail?.name\">\n <span class=\"detail-label\">Professional</span>\n <span class=\"detail-value\">{{appointmentPayload.staffDetail?.name ?\n appointmentPayload.staffDetail?.name : 'N/A'}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Date & Time</span>\n <span class=\"detail-value\">{{appointmentPayload.bookingDate ?\n appointmentPayload.bookingDate.slice(0,10) :\n 'N/A'}} at\n {{appointmentPayload.startTime ? appointmentPayload.startTime : 'N/A'}}</span>\n </div>\n </div>\n </div>\n\n\n <!-- Action Buttons -->\n <!-- <div class=\"action-buttons\">\n <button class=\"btn btn-outline\">View My Bookings</button>\n <button class=\"btn btn-primary\">Back to Admin</button>\n </div> -->\n </div>\n </div>\n</ng-template>\n<ng-template #skeletonLoader *ngIf=\"skeletonLoader\">\n <!-- Service Skeleton Loader HTML -->\n <div class=\"service-grid\">\n <!-- Skeleton Card 1 -->\n <div class=\"service-card skeleton-card\">\n <div class=\"service-header\">\n <div class=\"skeleton skeleton-icon\"></div>\n <div class=\"service-content\">\n <div class=\"skeleton skeleton-title\"></div>\n <div class=\"skeleton skeleton-price\"></div>\n <div class=\"skeleton skeleton-duration\"></div>\n </div>\n </div>\n <div class=\"skeleton skeleton-category\"></div>\n <div class=\"skeleton skeleton-description\"></div>\n <div class=\"skeleton skeleton-badge\"></div>\n </div>\n\n <!-- Skeleton Card 2 -->\n <div class=\"service-card skeleton-card\">\n <div class=\"service-header\">\n <div class=\"skeleton skeleton-icon\"></div>\n <div class=\"service-content\">\n <div class=\"skeleton skeleton-title\"></div>\n <div class=\"skeleton skeleton-price\"></div>\n <div class=\"skeleton skeleton-duration\"></div>\n </div>\n </div>\n <div class=\"skeleton skeleton-category\"></div>\n <div class=\"skeleton skeleton-description\"></div>\n <div class=\"skeleton skeleton-badge\"></div>\n </div>\n\n <!-- Skeleton Card 3 -->\n <div class=\"service-card skeleton-card\">\n <div class=\"service-header\">\n <div class=\"skeleton skeleton-icon\"></div>\n <div class=\"service-content\">\n <div class=\"skeleton skeleton-title\"></div>\n <div class=\"skeleton skeleton-price\"></div>\n <div class=\"skeleton skeleton-duration\"></div>\n </div>\n </div>\n <div class=\"skeleton skeleton-category\"></div>\n <div class=\"skeleton skeleton-description\"></div>\n <div class=\"skeleton skeleton-badge\"></div>\n </div>\n\n <!-- Skeleton Card 4 -->\n <div class=\"service-card skeleton-card\">\n <div class=\"service-header\">\n <div class=\"skeleton skeleton-icon\"></div>\n <div class=\"service-content\">\n <div class=\"skeleton skeleton-title\"></div>\n <div class=\"skeleton skeleton-price\"></div>\n <div class=\"skeleton skeleton-duration\"></div>\n </div>\n </div>\n <div class=\"skeleton skeleton-category\"></div>\n <div class=\"skeleton skeleton-description\"></div>\n <div class=\"skeleton skeleton-badge\"></div>\n </div>\n\n <!-- Skeleton Card 5 -->\n <div class=\"service-card skeleton-card\">\n <div class=\"service-header\">\n <div class=\"skeleton skeleton-icon\"></div>\n <div class=\"service-content\">\n <div class=\"skeleton skeleton-title\"></div>\n <div class=\"skeleton skeleton-price\"></div>\n <div class=\"skeleton skeleton-duration\"></div>\n </div>\n </div>\n <div class=\"skeleton skeleton-category\"></div>\n <div class=\"skeleton skeleton-description\"></div>\n <div class=\"skeleton skeleton-badge\"></div>\n </div>\n\n <!-- Skeleton Card 6 -->\n <div class=\"service-card skeleton-card\">\n <div class=\"service-header\">\n <div class=\"skeleton skeleton-icon\"></div>\n <div class=\"service-content\">\n <div class=\"skeleton skeleton-title\"></div>\n <div class=\"skeleton skeleton-price\"></div>\n <div class=\"skeleton skeleton-duration\"></div>\n </div>\n </div>\n <div class=\"skeleton skeleton-category\"></div>\n <div class=\"skeleton skeleton-description\"></div>\n <div class=\"skeleton skeleton-badge\"></div>\n </div>\n </div>\n</ng-template>", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.date-picker-container{border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;transition:var(--transition-smooth);background-color:var(--slate-50);cursor:pointer}.date-picker-container:hover{border-color:var(--slate-400);background-color:#fff}.date-input{font-size:.95rem;font-weight:600;color:var(--slate-800)!important;background:transparent;border:none;outline:none;cursor:pointer;width:100%}.date-picker-container mat-icon{color:var(--color-primary)!important;font-size:20px!important;width:20px!important;height:20px!important}.datepicker-popover{position:absolute;z-index:1000;margin-top:4px;border-radius:var(--border-radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);background:#fff;border:1px solid var(--slate-200);width:320px}::ng-deep .datepicker-calendar{border-radius:var(--border-radius-lg)!important;width:100%!important}::ng-deep .mat-calendar-header{background:var(--color-accent-gradient)!important;color:#fff!important;padding:.5rem!important}::ng-deep .mat-calendar-content{padding:8px!important}::ng-deep .mat-calendar-controls{margin:0!important}::ng-deep .mat-calendar-period-button{color:#fff!important;font-weight:700!important;font-size:1rem!important}::ng-deep .mat-calendar-arrow{fill:#fff!important}::ng-deep .mat-calendar-previous-button,::ng-deep .mat-calendar-next-button{color:#fff!important}::ng-deep .mat-calendar-body-cell{font-size:13px!important}::ng-deep .mat-calendar-body-cell-content{font-weight:600!important;color:var(--slate-800)!important;border-radius:8px!important}::ng-deep .mat-calendar-body-selected{background:var(--color-accent-gradient)!important;color:#fff!important;box-shadow:0 4px 10px #23086033!important}::ng-deep .mat-calendar-body-today:not(.mat-calendar-body-selected){border:2px solid var(--color-primary)!important;color:var(--color-primary)!important}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.9rem;font-weight:600;color:var(--slate-800)!important;padding:.75rem .5rem;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.main_footer{border-top:1px solid var(--slate-200);background-color:#fff;padding:15px;flex-shrink:0;display:flex;justify-content:center;box-shadow:0 -4px 12px #00000005}.footer-buttons{width:100%;max-width:800px;display:flex;align-items:center}.back-footer-btn{font-size:.95rem;font-weight:600;color:var(--slate-600)!important;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);cursor:pointer}.back-footer-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.complete_booking,.pay-now-btn{background:var(--color-accent-gradient)!important;color:#fff!important;border:none;padding:.75rem 2.25rem!important;font-size:.95rem!important;font-weight:600;border-radius:var(--border-radius-md)!important;box-shadow:0 4px 12px #23086040;transition:var(--transition-smooth);cursor:pointer;display:flex;align-items:center;gap:.5rem;width:max-content!important}.complete_booking img,.pay-now-btn img{width:20px;height:20px;filter:brightness(0) invert(1)}.complete_booking:hover:not([disabled]),.pay-now-btn:hover:not([disabled]){transform:translateY(-2px);box-shadow:0 6px 18px #23086059}.complete_booking:disabled,.pay-now-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed;box-shadow:none}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.datepicker-popover{width:100%;left:0}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}h1{font-size:24px!important;font-weight:600!important}\n"] }]
495
- }], ctorParameters: () => [{ type: i1.RestService }, { type: i2.EventsService }, { type: i3.Router }, { type: i4.MessageService }], propDecorators: { data: [{
542
+ args: [{ selector: 'simpo-appointment-booking', standalone: true, imports: [CdkDragPlaceholder, CommonModule, MatIcon, MatFormFieldModule, MatDatepickerModule, FormsModule, MatNativeDateModule, MatInputModule, LettersOnlyDirective, NumbersOnlyDirective, ToastModule], providers: [MessageService], template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\r\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\r\n<section class=\"main_section\">\r\n <div class=\"main_header\">\r\n <div class=\"header d-flex justify-content-between align-items-center\">\r\n <div class=\"back-btn d-flex justify-content-center align-items-center cursor-pointer gap-2 mb-3\"\r\n (click)=\"goBack()\">\r\n <mat-icon>keyboard_backspace</mat-icon><span *ngIf=\"screenWidth > 475\">Back to Home</span>\r\n </div>\r\n <div class=\"header-title\">\r\n <h1>Book New Appointment</h1>\r\n <p>{{businessName ?? \"N/A\" }}</p>\r\n </div>\r\n </div>\r\n\r\n <div class=\"progress-bar\">\r\n <div class=\"progress-fill\" [style.width]=\"barWidth + '%'\"></div>\r\n </div>\r\n </div>\r\n <div class=\"main_body w-100 d-flex justify-content-center\">\r\n <ng-container *ngIf=\"selectedTab === 'modeSelection'\">\r\n <ng-container *ngTemplateOutlet=\"modeSelection\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedTab === 'serviceListing'\">\r\n <ng-container *ngIf=\"!skeletonLoader\">\r\n <ng-container *ngTemplateOutlet=\"serviceListing\"></ng-container>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedTab === 'locationListing'\">\r\n <ng-container *ngTemplateOutlet=\"locationListing\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedTab === 'staffListing'\">\r\n <ng-container *ngTemplateOutlet=\"staffListing\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedTab === 'dateSelection'\">\r\n <ng-container *ngTemplateOutlet=\"dateSelection\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedTab==='contactDetails'\">\r\n <ng-container *ngTemplateOutlet=\"contactDetails\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedTab==='paymentTab'\">\r\n <ng-container *ngTemplateOutlet=\"paymentTab\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"selectedTab==='statusTemplate'\">\r\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\r\n </ng-container>\r\n </div>\r\n <div class=\"main_footer d-flex justify-content-center align-items-center\"\r\n *ngIf=\"selectedTab!=='statusTemplate' && selectedTab!=='modeSelection'\">\r\n <div class=\"footer-buttons\"\r\n [ngStyle]=\"{'justify-content': selectedTab != 'serviceListing' ? 'space-between' : 'end'}\">\r\n <span class=\"back-footer-btn cursor-pointer\" (click)=\"previousStep()\"\r\n *ngIf=\"selectedTab != 'serviceListing'\">Back</span>\r\n <button class=\"continue-btn\" [disabled]=\"!activeButton\" (click)=\"nextStep()\"\r\n *ngIf=\"selectedTab!='paymentTab'\">{{!loader ? 'Continue' : 'Loading...'}}</button>\r\n <button class=\"cursor-pointer d-flex justify-content-evenly align-items-center\"\r\n *ngIf=\"selectedTab==='paymentTab'\" (click)=\"confirmBooking()\" [disabled]=\"isProcessing\"\r\n [ngClass]=\"{'pay-now-btn' : bookingGroup?.totalCollectedAtBooking > 0 || !bookingGroup,'complete_booking' : bookingGroup && !bookingGroup?.totalCollectedAtBooking}\">\r\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/304012c1753440087996Background.png\">\r\n {{isProcessing ? 'Please wait...' : 'Confirm Booking'}}\r\n </button>\r\n </div>\r\n </div>\r\n</section>\r\n\r\n<ng-template #modeSelection>\r\n <div class=\"w-60 service_section\">\r\n <div class=\"service-selection\">\r\n <h2>How would you like this?</h2>\r\n <p>Choose how you'd like to be served</p>\r\n <div class=\"services-grid\">\r\n <div class=\"service-card\" (click)=\"selectMode('STORE_VISIT')\">\r\n <div class=\"service-header\">\r\n <div class=\"service-icon\"><mat-icon>storefront</mat-icon></div>\r\n <div class=\"service-info\">\r\n <div class=\"service-title\">Visit our Store</div>\r\n </div>\r\n </div>\r\n <div class=\"service-description\">Come to us at one of our locations</div>\r\n </div>\r\n <div class=\"service-card\" (click)=\"selectMode('HOME_VISIT')\">\r\n <div class=\"service-header\">\r\n <div class=\"service-icon\"><mat-icon>home</mat-icon></div>\r\n <div class=\"service-info\">\r\n <div class=\"service-title\">We come to you</div>\r\n </div>\r\n </div>\r\n <div class=\"service-description\">A professional visits your address</div>\r\n </div>\r\n <div class=\"service-card\" (click)=\"selectMode('VIDEO_CALL')\">\r\n <div class=\"service-header\">\r\n <div class=\"service-icon\"><mat-icon>videocam</mat-icon></div>\r\n <div class=\"service-info\">\r\n <div class=\"service-title\">Video consultation</div>\r\n </div>\r\n </div>\r\n <div class=\"service-description\">Connect over a video call</div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #serviceListing>\r\n <div class=\"w-60 service_section\">\r\n <div class=\"service-selection\">\r\n <h2>Select a Service</h2>\r\n <p>Choose the service(s) you'd like to book<span *ngIf=\"cartServices.length > 0\"> \u2014 {{cartServices.length}} selected</span></p>\r\n <p *ngIf=\"productCartItems.length > 0\" class=\"cart-hint\">{{productCartItems.length}} product(s) already in your cart \u2014 you can continue without picking a service.</p>\r\n\r\n <div class=\"services-grid\">\r\n <ng-container *ngFor=\"let service of serviceData\">\r\n <div class=\"\" (click)=\"selectService(service)\"\r\n [ngClass]=\"{ 'service-card-selected' : service?.selected, 'service-card': !service?.selected }\">\r\n <div class=\" service-header\">\r\n <div class=\"service-icon\"><mat-icon>person_outline</mat-icon></div>\r\n <div class=\"service-info\">\r\n <div class=\"service-title\">{{service?.name ? service?.name : 'N/A'}}</div>\r\n </div>\r\n <div>\r\n <div class=\"service-price\">\u20B9{{service?.priceDetails?.price ?\r\n service?.priceDetails?.price : 'N/A' }}</div>\r\n <div class=\"service-duration\">{{service?.duration ? service?.duration : 'N/A'}} min\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"service-description\" *ngIf=\"service?.description\">\r\n {{service?.description ? service?.description : 'N/A'}}\r\n </div>\r\n <div class=\"home-visit\" *ngIf=\"selectedMode === 'STORE_VISIT' && service?.homeAppointmentAvailable\"><img\r\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/982126c1758628863129furniture_16406103.png\">Home\r\n Visit Available</div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #locationListing>\r\n <div class=\"location_section\">\r\n <div class=\"header flex-column align-items-start\">\r\n <h1>Choose Location</h1>\r\n <p>Select where you'd like to receive the service</p>\r\n </div>\r\n\r\n <div class=\"location-list\">\r\n <ng-container *ngFor=\"let location of locationData\">\r\n <div (click)=\"selectLocation(location)\"\r\n [ngClass]=\"{ 'location-card-selected' : location?.selected, 'location-card': !location?.selected }\">\r\n <div class=\"location-content\">\r\n <div class=\"location-info\">\r\n <div class=\"location-icon\"><img\r\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/427226c1758629157758store_3171510.png\">\r\n </div>\r\n <div class=\"location-details\">\r\n <div class=\"d-flex justify-content-between align-items-center\">\r\n <h3>{{location?.storeName ? location?.storeName : 'N/A'}}</h3>\r\n </div>\r\n <p>{{location?.addressDetails?.addressLine}}, {{location?.addressDetails?.city}},\r\n {{location?.addressDetails?.state}} {{location?.pincode}}</p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #staffListing>\r\n <div class=\"w-60 overflow-hidden staff-listing\">\r\n <div class=\"d-flex w-100 h-100\">\r\n <div class=\"w-100\">\r\n <div class=\"staff-header mb-3\">\r\n <h1>Select Staff Member</h1>\r\n <p class=\"staff-subtitle mb-0\">Choose your preferred professional</p>\r\n </div>\r\n\r\n <div class=\"search-container mb-4\">\r\n <div class=\"search-input-wrapper d-flex align-items-center\">\r\n <mat-icon class=\"search-icon me-2\">search</mat-icon>\r\n <input type=\"text\" class=\"search-input border-0 flex-grow-1\" placeholder=\"Search staff member by name...\" [(ngModel)]=\"staffSearchQuery\">\r\n <mat-icon class=\"clear-icon cursor-pointer ms-2\" *ngIf=\"staffSearchQuery\" (click)=\"staffSearchQuery = ''\">close</mat-icon>\r\n </div>\r\n </div>\r\n\r\n <!-- Pure product-only line: one flat staff list, same as the old single-service flow -->\r\n <div class=\"staff-list\" *ngIf=\"cartServices.length === 0\">\r\n <ng-container *ngFor=\"let staff of filteredStaff\">\r\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForProductOnlyLine(staff)\"\r\n [ngClass]=\"{ 'staff-card-selected' : staff?.selected, 'staff-card': !staff?.selected }\">\r\n <div class=\"d-flex align-items-center justify-content-between w-100\">\r\n <div class=\"d-flex align-items-center flex-grow-1\">\r\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\r\n {{staff?.staffName.slice(0,2).toUpperCase()}}\r\n </div>\r\n <div class=\"staff-details flex-grow-1\">\r\n <h3 class=\"staff-name\">{{(staff?.staffName ? staff?.staffName : 'N/A') | titlecase}}</h3>\r\n <p class=\"staff-specialty\">{{(businessName && businessName !== 'N/A') ? businessName : 'Booking Specialist'}}</p>\r\n </div>\r\n </div>\r\n <div class=\"selection-indicator\">\r\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"staff?.selected\">\r\n <mat-icon *ngIf=\"staff?.selected\">check</mat-icon>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n\r\n <!-- Bundled cart: one pool per line that resolution couldn't collapse to a single provider -->\r\n <ng-container *ngIf=\"cartServices.length > 0\">\r\n <div class=\"staff-line-group mb-4\" *ngFor=\"let line of resolvedLines\">\r\n <ng-container *ngIf=\"line.candidateStaffPool?.length\">\r\n <h4 class=\"mb-2\">For {{line.services.length}} service(s): {{ (line.services | slice:0:3).length ? '' : '' }}<span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></h4>\r\n <div class=\"staff-list mb-3\">\r\n <ng-container *ngFor=\"let staff of line.candidateStaffPool\">\r\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForLine(line, staff)\"\r\n [ngClass]=\"{ 'staff-card-selected' : line.selectedStaffId === staff.id, 'staff-card': line.selectedStaffId !== staff.id }\">\r\n <div class=\"d-flex align-items-center justify-content-between w-100\">\r\n <div class=\"d-flex align-items-center flex-grow-1\">\r\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\r\n {{staff?.name?.slice(0,2)?.toUpperCase()}}\r\n </div>\r\n <div class=\"staff-details flex-grow-1\">\r\n <h3 class=\"staff-name\">{{(staff?.name ? staff?.name : 'N/A') | titlecase}}</h3>\r\n </div>\r\n </div>\r\n <div class=\"selection-indicator\">\r\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"line.selectedStaffId === staff.id\">\r\n <mat-icon *ngIf=\"line.selectedStaffId === staff.id\">check</mat-icon>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #dateSelection>\r\n <div class=\"w-60 date_section\">\r\n <div class=\"row justify-content-center h-100\">\r\n <div class=\"col-12 h-100\">\r\n <div class=\"datetime-header mb-2\">\r\n <h1>Select Date & Time</h1>\r\n <p class=\"datetime-subtitle mb-0\">Choose when you'd like your appointment</p>\r\n </div>\r\n\r\n <div class=\"d-flex gap-4 main_container\">\r\n <div [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\r\n <div class=\"section-card card rounded-3 p-4 h-100\">\r\n <h3 class=\"section-title\">Select Date</h3>\r\n\r\n <div class=\"date-picker-container d-flex align-items-center justify-content-between\"\r\n (click)=\"$event.stopPropagation()\">\r\n <input type=\"text\" class=\"date-input border-0 rounded-2\" placeholder=\"dd-mm-yyyy\"\r\n [value]=\"selectedDateStr\" readonly (click)=\"toggleCalendar($event)\">\r\n\r\n <mat-icon class=\"ms-2\" (click)=\"toggleCalendar($event)\">calendar_today</mat-icon>\r\n </div>\r\n <div class=\"position-relative\" (click)=\"$event.stopPropagation()\">\r\n <div class=\"datepicker-popover\" *ngIf=\"showCalendar\">\r\n <mat-calendar [(selected)]=\"selectedDate\" [dateFilter]=\"dateFilter\"\r\n (selectedChange)=\"onDateSelected($event)\" class=\"datepicker-calendar\">\r\n </mat-calendar>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- One slot-picker per resolved line, side by side when there's more than one (design doc \u00A73b) -->\r\n <div class=\"time_selection\" [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\" *ngIf=\"resolvedLines.length <= 1\">\r\n <div class=\"section-card card h-100 rounded-3 p-4\">\r\n <h3 class=\"section-title\">Available Times</h3>\r\n <div class=\"row g-2 mb-4 overflow-scroll\">\r\n <ng-container *ngIf=\"!skeletonLoader && resolvedLines[0]\">\r\n <div class=\"col-4\" *ngFor=\"let time of resolvedLines[0].slots\">\r\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\r\n (click)=\"selectSlotForLine(resolvedLines[0], time)\">{{time ? time?.value : 'N/A'}}</div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Multi-line case: each line gets its own full-width card with a staff header -->\r\n <div class=\"d-flex gap-4 main_container flex-wrap\" *ngIf=\"resolvedLines.length > 1\">\r\n <div class=\"w-100\" *ngFor=\"let line of resolvedLines\">\r\n <div class=\"section-card card rounded-3 p-4\">\r\n <h3 class=\"section-title\">Professional: {{line.staffName || line.selectedStaffName}}</h3>\r\n <p class=\"mb-2\" *ngIf=\"line.services.length\"><span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></p>\r\n <div class=\"row g-2 mb-2 overflow-scroll\">\r\n <ng-container *ngIf=\"!line.slotsLoading\">\r\n <div class=\"col-4\" *ngFor=\"let time of line.slots\">\r\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\r\n (click)=\"selectSlotForLine(line, time)\">{{time ? time?.value : 'N/A'}}</div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #contactDetails>\r\n <div class=\"w-60 contact_section\">\r\n <div class=\"contact-header mb-2\">\r\n <h1>Contact Details</h1>\r\n <p class=\"contact-subtitle mb-0\">Provide your contact information</p>\r\n </div>\r\n\r\n <div class=\"d-flex gap-3 details_container flex-column w-100\">\r\n <div class=\"d-flex gap-4\">\r\n <div [ngClass]=\"{'w-50' : selectedMode === 'HOME_VISIT', 'w-100' : selectedMode !== 'HOME_VISIT'}\">\r\n <div class=\"form-section card rounded-3 p-4 h-100\">\r\n <h3 class=\"section-title\">Personal Information</h3>\r\n\r\n <div class=\"mb-4\">\r\n <label class=\"form-label d-flex align-items-center\">\r\n Full Name\r\n <span class=\"required-asterisk\">*</span>\r\n </label>\r\n <input type=\"text\" class=\"form-control form-input rounded-2\"\r\n [(ngModel)]=\"appointmentPayload.customerDetail.name\"\r\n (ngModelChange)=\"checkRequiredValues()\" simpoLettersOnly>\r\n </div>\r\n\r\n <div class=\"mb-4\">\r\n <label class=\"form-label d-flex align-items-center\">\r\n Email Address\r\n <span class=\"required-asterisk\">*</span>\r\n </label>\r\n <input type=\"email\" class=\"form-control form-input rounded-2\"\r\n [(ngModel)]=\"appointmentPayload.customerDetail.email\"\r\n (ngModelChange)=\"checkRequiredValues()\"\r\n pattern=\"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" #emailField=\"ngModel\"\r\n name=\"email\" required>\r\n </div>\r\n\r\n <div class=\"mb-0\">\r\n <label class=\"form-label d-flex align-items-center\">\r\n Phone Number\r\n <span class=\"required-asterisk\">*</span>\r\n </label>\r\n <input type=\"tel\" class=\"form-control rounded-2\"\r\n [(ngModel)]=\"appointmentPayload.customerDetail.phoneNumber\"\r\n (ngModelChange)=\"checkRequiredValues()\" simpoNumbersOnly\r\n [ngClass]=\"{'mobile_number' : appointmentPayload.customerDetail.phoneNumber.length != 10}\">\r\n </div>\r\n </div>\r\n </div>\r\n <!-- Home Visit address - structured fields matching BookingGroupRequest.addressDetails exactly -->\r\n <div class=\"w-50\" *ngIf=\"selectedMode === 'HOME_VISIT'\">\r\n <div class=\"form-section card rounded-3 p-4 h-100\">\r\n <h3 class=\"section-title\">Home Visit Details</h3>\r\n\r\n <div class=\"mb-3\">\r\n <label class=\"form-label d-flex align-items-center\">Receiver Name</label>\r\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.receiverName\">\r\n </div>\r\n <div class=\"mb-3\">\r\n <label class=\"form-label d-flex align-items-center\">Receiver Phone</label>\r\n <input type=\"tel\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.receiverPhone\">\r\n </div>\r\n <div class=\"mb-3\">\r\n <label class=\"form-label d-flex align-items-center\">Address Line 1</label>\r\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine1\">\r\n </div>\r\n <div class=\"mb-3\">\r\n <label class=\"form-label d-flex align-items-center\">Address Line 2 (optional)</label>\r\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine2\">\r\n </div>\r\n <div class=\"d-flex gap-2 mb-3\">\r\n <div class=\"w-50\">\r\n <label class=\"form-label d-flex align-items-center\">City</label>\r\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.city\">\r\n </div>\r\n <div class=\"w-50\">\r\n <label class=\"form-label d-flex align-items-center\">State</label>\r\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.state\">\r\n </div>\r\n </div>\r\n <div class=\"mb-3\">\r\n <label class=\"form-label d-flex align-items-center\">Pincode</label>\r\n <input type=\"text\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.zipCode\">\r\n </div>\r\n <div class=\"mb-0\">\r\n <label class=\"form-label d-flex align-items-center\">Special Instructions</label>\r\n <textarea class=\"form-control form-textarea rounded-2\"\r\n placeholder=\"Any special instructions for the professional (optional)\"\r\n [(ngModel)]=\"instructions\"></textarea>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"policies-container\"\r\n *ngIf=\"cartServices[0]?.cancellationPolicy?.length > 0 || cartServices[0]?.reschedulePolicy?.length\">\r\n <h2 class=\"policies-title\">Policies & Terms</h2>\r\n\r\n <div class=\"policy-items-container d-flex flex-column gap-3\">\r\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\r\n (click)=\"showCancellationPolicy = !showCancellationPolicy\">\r\n <h3 class=\"policy-title\">Cancellation Policy</h3>\r\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\r\n *ngIf=\"!showCancellationPolicy\">keyboard_arrow_right</mat-icon>\r\n <mat-icon *ngIf=\"showCancellationPolicy\">keyboard_arrow_down</mat-icon>\r\n </div>\r\n </div>\r\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\r\n *ngIf=\"showCancellationPolicy\">\r\n <span *ngFor=\"let policy of cartServices[0]?.cancellationPolicy\">&#8226;\r\n {{policy}}</span>\r\n </div>\r\n\r\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\r\n (click)=\"showReducingPolicy = !showReducingPolicy\">\r\n <h3 class=\"policy-title\">Rescheduling Policy</h3>\r\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\r\n *ngIf=\"!showReducingPolicy\">keyboard_arrow_right</mat-icon>\r\n <mat-icon *ngIf=\"showReducingPolicy\">keyboard_arrow_down</mat-icon>\r\n </div>\r\n </div>\r\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\r\n *ngIf=\"showReducingPolicy\">\r\n <span *ngFor=\"let policy of cartServices[0]?.reschedulePolicy\">&#8226; {{policy}}</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"acceptance-section\">\r\n <input type=\"checkbox\" class=\"custom-checkbox\" [(ngModel)]=\"termsAndConditions\"\r\n (ngModelChange)=\"checkRequiredValues()\">\r\n <p class=\"acceptance-text\" style=\"margin-bottom:0px !important\">\r\n I understand and accept the cancellation & rescheduling policies.\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #paymentTab>\r\n <div class=\"w-60 payment_section\">\r\n <div class=\"w-100 h-100\">\r\n <div class=\"w-100 d-flex justify-content-center align-items-center flex-column\">\r\n <div class=\"payment-header mb-3 w-100\">\r\n <h1 style=\"font-size:24px;font-weight: 600;\">Booking Summary</h1>\r\n <p class=\"payment-subtitle mb-0\">Review your booking before confirming</p>\r\n </div>\r\n\r\n <div class=\"booking-summary-card\" [ngClass]=\"{'w-100' : screenWidth < 475,'w-50':screenWidth > 475}\">\r\n <div *ngFor=\"let line of resolvedLines; let i = index\">\r\n <h2 class=\"summary-title\" *ngIf=\"resolvedLines.length > 1\">Line {{i + 1}}</h2>\r\n <div class=\"summary-row\" *ngIf=\"line.services.length\">\r\n <div class=\"summary-label\">Service(s)</div>\r\n <div class=\"summary-value\"><span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></div>\r\n </div>\r\n <div class=\"summary-row\" *ngIf=\"line.staffName || line.selectedStaffName\">\r\n <div class=\"summary-label\">Professional</div>\r\n <div class=\"summary-value\">{{line.staffName || line.selectedStaffName}}</div>\r\n </div>\r\n <div class=\"summary-row\" *ngIf=\"selectedMode === 'STORE_VISIT'\">\r\n <div class=\"summary-label\">Location</div>\r\n <div class=\"summary-value\">{{selectedLocation?.storeName ?? 'N/A'}}</div>\r\n </div>\r\n <div class=\"summary-row\">\r\n <div class=\"summary-label\">Date & Time</div>\r\n <div class=\"summary-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</div>\r\n </div>\r\n </div>\r\n\r\n <div *ngIf=\"productCartItems.length > 0\">\r\n <h2 class=\"summary-title\">Products</h2>\r\n <div class=\"summary-row\" *ngFor=\"let p of productCartItems\">\r\n <div class=\"summary-label\">{{p.itemName}} x{{p.quantity}}</div>\r\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{(p.sellingPrice ?? p.price ?? 0) * (p.quantity ?? 1)}}</div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #statusTemplate>\r\n <div class=\"booking-confirmation\">\r\n <div class=\"success-icon\">\r\n <div class=\"checkmark-circle\">\r\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\r\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\r\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\r\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\r\n </div>\r\n </div>\r\n\r\n <div class=\"confirmation-content\">\r\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\r\n <p class=\"confirmation-message\">\r\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book you appointment. Please\r\n try again later'}}\r\n </p>\r\n\r\n <!-- Video Call link, when already present on the confirmed group (a paid Video Call's\r\n link only appears once payment verification completes, handled elsewhere - see\r\n verify-payment.component.ts, not this screen). -->\r\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && selectedMode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\r\n <div class=\"details-card\">\r\n <h3 class=\"details-title\">Your Video Call Link</h3>\r\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\r\n </div>\r\n </div>\r\n\r\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\r\n <div class=\"details-card\">\r\n <h3 class=\"details-title\">Appointment Details</h3>\r\n <div class=\"details-row\" *ngFor=\"let line of resolvedLines\">\r\n <span class=\"detail-label\">{{line.services.length ? (line.services[0].name) : 'Products'}}</span>\r\n <span class=\"detail-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</ng-template>\r\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.date-picker-container{border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;transition:var(--transition-smooth);background-color:var(--slate-50);cursor:pointer}.date-picker-container:hover{border-color:var(--slate-400);background-color:#fff}.date-input{font-size:.95rem;font-weight:600;color:var(--slate-800)!important;background:transparent;border:none;outline:none;cursor:pointer;width:100%}.date-picker-container mat-icon{color:var(--color-primary)!important;font-size:20px!important;width:20px!important;height:20px!important}.datepicker-popover{position:absolute;z-index:1000;margin-top:4px;border-radius:var(--border-radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);background:#fff;border:1px solid var(--slate-200);width:320px}::ng-deep .datepicker-calendar{border-radius:var(--border-radius-lg)!important;width:100%!important}::ng-deep .mat-calendar-header{background:var(--color-accent-gradient)!important;color:#fff!important;padding:.5rem!important}::ng-deep .mat-calendar-content{padding:8px!important}::ng-deep .mat-calendar-controls{margin:0!important}::ng-deep .mat-calendar-period-button{color:#fff!important;font-weight:700!important;font-size:1rem!important}::ng-deep .mat-calendar-arrow{fill:#fff!important}::ng-deep .mat-calendar-previous-button,::ng-deep .mat-calendar-next-button{color:#fff!important}::ng-deep .mat-calendar-body-cell{font-size:13px!important}::ng-deep .mat-calendar-body-cell-content{font-weight:600!important;color:var(--slate-800)!important;border-radius:8px!important}::ng-deep .mat-calendar-body-selected{background:var(--color-accent-gradient)!important;color:#fff!important;box-shadow:0 4px 10px #23086033!important}::ng-deep .mat-calendar-body-today:not(.mat-calendar-body-selected){border:2px solid var(--color-primary)!important;color:var(--color-primary)!important}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.9rem;font-weight:600;color:var(--slate-800)!important;padding:.75rem .5rem;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.main_footer{border-top:1px solid var(--slate-200);background-color:#fff;padding:15px;flex-shrink:0;display:flex;justify-content:center;box-shadow:0 -4px 12px #00000005}.footer-buttons{width:100%;max-width:800px;display:flex;align-items:center}.back-footer-btn{font-size:.95rem;font-weight:600;color:var(--slate-600)!important;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);cursor:pointer}.back-footer-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.complete_booking,.pay-now-btn{background:var(--color-accent-gradient)!important;color:#fff!important;border:none;padding:.75rem 2.25rem!important;font-size:.95rem!important;font-weight:600;border-radius:var(--border-radius-md)!important;box-shadow:0 4px 12px #23086040;transition:var(--transition-smooth);cursor:pointer;display:flex;align-items:center;gap:.5rem;width:max-content!important}.complete_booking img,.pay-now-btn img{width:20px;height:20px;filter:brightness(0) invert(1)}.complete_booking:hover:not([disabled]),.pay-now-btn:hover:not([disabled]){transform:translateY(-2px);box-shadow:0 6px 18px #23086059}.complete_booking:disabled,.pay-now-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed;box-shadow:none}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.datepicker-popover{width:100%;left:0}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}h1{font-size:24px!important;font-weight:600!important}\n"] }]
543
+ }], ctorParameters: () => [{ type: i1.RestService }, { type: i2.EventsService }, { type: i3.Router }, { type: i4.MessageService }, { type: i5.BookingProductCartService }, { type: i6.StorageServiceService }, { type: i7.MatDialogRef, decorators: [{
544
+ type: Optional
545
+ }] }], propDecorators: { data: [{
496
546
  type: Input
497
547
  }], index: [{
498
548
  type: Input
@@ -504,6 +554,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
504
554
  type: Input
505
555
  }], nextComponentColor: [{
506
556
  type: Input
557
+ }], prefillContact: [{
558
+ type: Input
507
559
  }], getScreenSize: [{
508
560
  type: HostListener,
509
561
  args: ["window: resize", ["$event"]]
@@ -511,4 +563,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
511
563
  type: HostListener,
512
564
  args: ['document:click']
513
565
  }] } });
514
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwb2ludG1lbnQtYm9va2luZy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zaW1wby11aS9zcmMvbGliL3NlY3Rpb25zL2FwcG9pbnRtZW50LWZvcm0vYXBwb2ludG1lbnQtYm9va2luZy9hcHBvaW50bWVudC1ib29raW5nL2FwcG9pbnRtZW50LWJvb2tpbmcuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2ltcG8tdWkvc3JjL2xpYi9zZWN0aW9ucy9hcHBvaW50bWVudC1mb3JtL2FwcG9pbnRtZW50LWJvb2tpbmcvYXBwb2ludG1lbnQtYm9va2luZy9hcHBvaW50bWVudC1ib29raW5nLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDNUQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2pELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNuRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUk3RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHekQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDcEYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0s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Q3RCN0IsNDd0Q0Fvc0JjLDB4dEJEL3FCa0IsWUFBWSx1cEJBQUUsT0FBTywwSUFBRSxrQkFBa0IsOEJBQUUsbUJBQW1CLDBiQUFFLFdBQVcscXBDQUFFLG1CQUFtQiw4QkFBRSxjQUFjLCtCQUFFLG9CQUFvQiwrREFBRSxvQkFBb0IsOERBQUUsV0FBVzs7NEZBSzVMLDJCQUEyQjtrQkFSdkMsU0FBUzsrQkFDRSwyQkFBMkIsY0FDekIsSUFBSSxXQUNQLENBQUMsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxtQkFBbUIsRUFBRSxXQUFXLEVBQUUsbUJBQW1CLEVBQUUsY0FBYyxFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUFFLFdBQVcsQ0FBQyxhQUM3TCxDQUFDLGNBQWMsQ0FBQzs4SkFhbEIsSUFBSTtzQkFBWixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFFRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLO2dCQVFOLGFBQWE7c0JBRFosWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFLMUMsbUJBQW1CO3NCQURsQixZQUFZO3VCQUFDLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSG9zdExpc3RlbmVyLCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENka0RyYWdQbGFjZWhvbGRlciB9IGZyb20gXCJAYW5ndWxhci9jZGsvZHJhZy1kcm9wXCI7XG5pbXBvcnQgeyBNYXRJY29uIH0gZnJvbSBcIkBhbmd1bGFyL21hdGVyaWFsL2ljb25cIjtcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGRcIjtcbmltcG9ydCB7IE1hdERhdGVwaWNrZXJNb2R1bGUgfSBmcm9tIFwiQGFuZ3VsYXIvbWF0ZXJpYWwvZGF0ZXBpY2tlclwiO1xuaW1wb3J0IHsgTWF0TmF0aXZlRGF0ZU1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NvcmUnO1xuaW1wb3J0IHsgUmVzdFNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi8uLi9zZXJ2aWNlcy9yZXN0LnNlcnZpY2UnO1xuaW1wb3J0IHsgRXZlbnRzU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL2V2ZW50cy5zZXJ2aWNlJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBNYXRJbnB1dE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcbmltcG9ydCB7IEJhbm5lckNvbnRlbnRNb2RlbCwgQmFubmVyU2VjdGlvbk1vZGVsIH0gZnJvbSAnLi4vLi4vYXBwb2ludG1lbnQtZm9ybS5tb2RlbCc7XG5pbXBvcnQgeyBCYWNrZ3JvdW5kTW9kZWwsIEJhbm5lclN0eWxlc01vZGVsIH0gZnJvbSAnLi4vLi4vLi4vLi4vc3R5bGVzL3N0eWxlLm1vZGVsJztcbmltcG9ydCB7IExldHRlcnNPbmx5RGlyZWN0aXZlIH0gZnJvbSAnLi4vLi4vLi4vLi4vZGlyZWN0aXZlL2xldHRlcnMtb25seS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgTnVtYmVyc09ubHlEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi8uLi8uLi9kaXJlY3RpdmUvbnVtYmVycy1vbmx5LmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBUb2FzdE1vZHVsZSB9IGZyb20gXCJwcmltZW5nL3RvYXN0XCI7XG5pbXBvcnQgeyBNZXNzYWdlU2VydmljZSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3NpbXBvLWFwcG9pbnRtZW50LWJvb2tpbmcnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ2RrRHJhZ1BsYWNlaG9sZGVyLCBDb21tb25Nb2R1bGUsIE1hdEljb24sIE1hdEZvcm1GaWVsZE1vZHVsZSwgTWF0RGF0ZXBpY2tlck1vZHVsZSwgRm9ybXNNb2R1bGUsIE1hdE5hdGl2ZURhdGVNb2R1bGUsIE1hdElucHV0TW9kdWxlLCBMZXR0ZXJzT25seURpcmVjdGl2ZSwgTnVtYmVyc09ubHlEaXJlY3RpdmUsIFRvYXN0TW9kdWxlXSxcbiAgcHJvdmlkZXJzOiBbTWVzc2FnZVNlcnZpY2VdLFxuICB0ZW1wbGF0ZVVybDogJy4vYXBwb2ludG1lbnQtYm9va2luZy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9hcHBvaW50bWVudC1ib29raW5nLmNvbXBvbmVudC5jc3MnXG59KVxuZXhwb3J0IGNsYXNzIEFwcG9pbnRtZW50Qm9va2luZ0NvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVzdFNlcnZpY2U6IFJlc3RTZXJ2aWNlLFxuICAgIHByaXZhdGUgX2V2ZW50U2VydmljZTogRXZlbnRzU2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlcjogUm91dGVyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbWVzc2FnZVNlcnZpY2U6IE1lc3NhZ2VTZXJ2aWNlXG4gICkge1xuXG4gIH1cbiAgQElucHV0KCkgZGF0YT86IEJhbm5lclNlY3Rpb25Nb2RlbDtcbiAgQElucHV0KCkgaW5kZXg/OiBudW1iZXI7XG4gIGNvbnRlbnQ/OiBCYW5uZXJDb250ZW50TW9kZWw7XG4gIEBJbnB1dCgpIGVkaXQ/OiBib29sZWFuO1xuICBASW5wdXQoKSBkZWxldGU/OiBib29sZWFuO1xuICBASW5wdXQoKSBjdXN0b21DbGFzcz86IHN0cmluZztcbiAgQElucHV0KCkgbmV4dENvbXBvbmVudENvbG9yPzogQmFja2dyb3VuZE1vZGVsO1xuICBzdHlsZXM/OiBCYW5uZXJTdHlsZXNNb2RlbDtcbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5nZXRBbGxTZXJ2aWNlcygpO1xuICAgIHRoaXMuZ2V0U2NyZWVuU2l6ZSgpO1xuICB9XG4gIHNjcmVlbldpZHRoOiBudW1iZXIgPSAwO1xuICBASG9zdExpc3RlbmVyKFwid2luZG93OiByZXNpemVcIiwgW1wiJGV2ZW50XCJdKVxuICBnZXRTY3JlZW5TaXplKCkge1xuICAgIHRoaXMuc2NyZWVuV2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgfVxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycpXG4gIGNsb3NlT25PdXRzaWRlQ2xpY2soKSB7XG4gICAgdGhpcy5zaG93Q2FsZW5kYXIgPSBmYWxzZTtcbiAgfVxuICBhY2Nlc3NlZFRhYnMgPSB7XG4gICAgc2VydmljZUxpc3Rpbmc6IGZhbHNlLFxuICAgIGxvY2F0aW9uTGlzdGluZzogZmFsc2UsXG4gICAgc3RhZmZMaXN0aW5nOiBmYWxzZVxuICB9XG4gIHNrZWxldG9uTG9hZGVyOiBib29sZWFuID0gZmFsc2U7XG4gIGJ1c2luZXNzTmFtZSA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdidXNpbmVzc05hbWUnKSA/IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdidXNpbmVzc05hbWUnKSA6IChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYk5hbWUnKSA/IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdiTmFtZScpIDogJycpO1xuICBidXNpbmVzc0lkOiBhbnkgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYnVzaW5lc3NJZCcpID8gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2J1c2luZXNzSWQnKSA6IChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYklkJykgPyBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYklkJykgOiAnJyk7XG4gIGFjdGl2ZUJ1dHRvbjogYm9vbGVhbiA9IGZhbHNlO1xuICBzZWxlY3RlZFRhYjogc3RyaW5nID0gJyc7XG4gIGJhcldpZHRoOiBzdHJpbmcgPSAnJztcbiAgc2hvd0NhbmNlbGxhdGlvblBvbGljeTogYm9vbGVhbiA9IGZhbHNlO1xuICBzaG93UmVkdWNpbmdQb2xpY3k6IGJvb2xlYW4gPSBmYWxzZTtcbiAgc2VsZWN0ZWRTZXJ2aWNlOiBhbnkgPSB7fTtcbiAgc2VsZWN0ZWRMb2NhdGlvbjogYW55O1xuICBob21lQWRkcmVzczogc3RyaW5nID0gJyc7XG4gIGluc3RydWN0aW9uczogc3RyaW5nID0gJyc7XG4gIE9iamVjdCA9IE9iamVjdDtcbiAgc2hvd0NhbGVuZGFyID0gZmFsc2U7XG4gIHNlbGVjdGVkRGF0ZTogRGF0ZSB8IG51bGwgPSBudWxsO1xuICBzZWxlY3RlZERhdGVTdHIgPSAnJztcbiAgdXNlckRldGFpbHMgPSB7XG4gICAgbmFtZTogJycsXG4gICAgZW1haWw6ICcnLFxuICAgIG1vYmlsZU51bWJlcjogJydcbiAgfVxuICBkYXRlRmlsdGVyID0gKGQ6IERhdGUgfCBudWxsKTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3QgZGF0ZSA9IChkIHx8IG5ldyBEYXRlKCkpO1xuICAgIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgICB0b2RheS5zZXRIb3VycygwLCAwLCAwLCAwKTtcbiAgICByZXR1cm4gZGF0ZS5nZXRUaW1lKCkgPj0gdG9kYXkuZ2V0VGltZSgpO1xuICB9XG4gIHRvZ2dsZUNhbGVuZGFyKGV2ZW50PzogRXZlbnQpIHtcbiAgICBpZiAoZXZlbnQpIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuc2hvd0NhbGVuZGFyID0gIXRoaXMuc2hvd0NhbGVuZGFyO1xuICB9XG5cbiAgb25EYXRlU2VsZWN0ZWQoZGF0ZTogYW55KSB7XG4gICAgdGhpcy5zZWxlY3RlZFRpbWUgPSB7fTtcbiAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IGZhbHNlO1xuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gZGF0ZTtcbiAgICB0aGlzLnNlbGVjdGVkRGF0ZVN0ciA9IHRoaXMuZm9ybWF0RGF0ZShkYXRlKTtcbiAgICB0aGlzLnNob3dDYWxlbmRhciA9IGZhbHNlO1xuICAgIHRoaXMuZ2V0QXZhaWxhYmxlU2xvdHMoKTtcbiAgfVxuICBwcml2YXRlIGZvcm1hdERhdGUoZDogRGF0ZSk6IHN0cmluZyB7XG4gICAgY29uc3QgZGQgPSBTdHJpbmcoZC5nZXREYXRlKCkpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgY29uc3QgbW0gPSBTdHJpbmcoZC5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICBjb25zdCB5eXl5ID0gZC5nZXRGdWxsWWVhcigpO1xuICAgIHJldHVybiBgJHtkZH0tJHttbX0tJHt5eXl5fWA7XG4gIH1cblxuICBzZWxlY3RTZXJ2aWNlKHNlcnZpY2U6IGFueSkge1xuICAgIHNlcnZpY2Uuc2VsZWN0ZWQgPSB0cnVlO1xuICAgIGlmICh0aGlzLnNlbGVjdGVkU2VydmljZSAmJiBzZXJ2aWNlLnNlcnZpY2VJZCAhPSB0aGlzLnNlbGVjdGVkU2VydmljZS5zZXJ2aWNlSWQpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRTZXJ2aWNlLnNlbGVjdGVkID0gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMuc2VsZWN0ZWRTZXJ2aWNlID0gc2VydmljZVxuICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gdGhpcy5zZWxlY3RlZFNlcnZpY2UgPyB0cnVlIDogZmFsc2U7XG4gIH1cbiAgc2VsZWN0TG9jYXRpb24obG9jYXRpb246IGFueSkge1xuICAgIGxvY2F0aW9uLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICBpZiAodGhpcy5zZWxlY3RlZExvY2F0aW9uICYmIGxvY2F0aW9uLmlkICE9IHRoaXMuc2VsZWN0ZWRMb2NhdGlvbi5pZCkge1xuICAgICAgdGhpcy5zZWxlY3RlZExvY2F0aW9uLnNlbGVjdGVkID0gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gdHJ1ZTtcbiAgICB0aGlzLnNlbGVjdGVkTG9jYXRpb24gPSBsb2NhdGlvbjtcbiAgfVxuICBzZWxlY3RlZFN0YWZmOiBhbnk7XG4gIHNlbGVjdFN0YWZmKHN0YWZmOiBhbnkpIHtcbiAgICBzdGFmZi5zZWxlY3RlZCA9IHRydWU7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRTdGFmZiAmJiBzdGFmZi5zdGFmZklkICE9IHRoaXMuc2VsZWN0ZWRTdGFmZi5zdGFmZklkKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkU3RhZmYuc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgdGhpcy5zZWxlY3RlZFN0YWZmID0gc3RhZmY7XG4gICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0cnVlO1xuICB9XG4gIG5leHRTdGVwKCkge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkVGFiID09PSAnc2VydmljZUxpc3RpbmcnKSB7XG4gICAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IHRoaXMuc2VsZWN0ZWRMb2NhdGlvbiA/IHRydWUgOiBmYWxzZTtcbiAgICAgIHRoaXMuYWNjZXNzZWRUYWJzLnNlcnZpY2VMaXN0aW5nID0gdHJ1ZTtcbiAgICAgIC8vIGlmICghdGhpcy5hY3RpdmVCdXR0b24pIHtcbiAgICAgIC8vICAgdGhpcy5nZXRBbGxMb2NhdGlvbnMoKTtcbiAgICAgIC8vIH1cbiAgICAgIC8vIGVsc2Uge1xuICAgICAgLy8gICBpZiAodGhpcy5hY2Nlc3NlZFRhYnMubG9jYXRpb25MaXN0aW5nKSB7XG4gICAgICAvLyAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdsb2NhdGlvbkxpc3RpbmcnO1xuICAgICAgLy8gICAgIHRoaXMuYmFyV2lkdGggPSAnMjkuMjgnO1xuICAgICAgLy8gICB9XG4gICAgICAvLyAgIGVsc2UgaWYgKHRoaXMuYWNjZXNzZWRUYWJzLnN0YWZmTGlzdGluZykge1xuICAgICAgLy8gICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnc3RhZmZMaXN0aW5nJztcbiAgICAgIC8vICAgICB0aGlzLmJhcldpZHRoID0gJzQzLjU3JztcbiAgICAgIC8vICAgfVxuICAgICAgLy8gICBlbHNlIHtcbiAgICAgIC8vICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ2RhdGVTZWxlY3Rpb24nO1xuICAgICAgLy8gICAgIHRoaXMuYmFyV2lkdGggPSAnNTguNTcnO1xuICAgICAgLy8gICAgIGlmICh0aGlzLnNlbGVjdGVkTG9jYXRpb24gJiYgdGhpcy5zZWxlY3RlZFNlcnZpY2UpXG4gICAgICAvLyAgICAgICB0aGlzLmdldEF2YWlsYWJsZVNsb3RzKCk7XG4gICAgICAvLyAgIH1cbiAgICAgIC8vIH1cbiAgICAgIHRoaXMuZ2V0QWxsTG9jYXRpb25zKCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdsb2NhdGlvbkxpc3RpbmcnKSB7XG4gICAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IHRydWU7XG4gICAgICB0aGlzLmFjY2Vzc2VkVGFicy5sb2NhdGlvbkxpc3RpbmcgPSB0cnVlO1xuICAgICAgLy8gaWYgKCF0aGlzLmFjdGl2ZUJ1dHRvbikge1xuICAgICAgLy8gICB0aGlzLmdldEFsbFN0YWZmKCk7XG5cbiAgICAgIC8vIH1cbiAgICAgIHRoaXMuZ2V0QWxsU3RhZmYoKTtcbiAgICB9XG4gICAgZWxzZSBpZiAodGhpcy5zZWxlY3RlZFRhYiA9PT0gJ3N0YWZmTGlzdGluZycpIHtcbiAgICAgIHRoaXMuYWNjZXNzZWRUYWJzLnN0YWZmTGlzdGluZyA9IHRydWU7XG4gICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ2RhdGVTZWxlY3Rpb24nO1xuICAgICAgdGhpcy5iYXJXaWR0aCA9ICc1OC41Nyc7XG4gICAgICB0aGlzLmdldEF2YWlsYWJsZVNsb3RzKCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdkYXRlU2VsZWN0aW9uJykge1xuICAgICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5uYW1lICYmIHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLmVtYWlsICYmIHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLnBob25lTnVtYmVyLmxlbmd0aCA9PT0gMTAgPyB0cnVlIDogZmFsc2VcbiAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnY29udGFjdERldGFpbHMnO1xuICAgICAgdGhpcy5iYXJXaWR0aCA9ICc3MC41NydcbiAgICB9XG4gICAgZWxzZSBpZiAodGhpcy5zZWxlY3RlZFRhYiA9PT0gJ2NvbnRhY3REZXRhaWxzJykge1xuICAgICAgdGhpcy5jaGVja1JlcXVpcmVkVmFsdWVzKCk7XG4gICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ3BheW1lbnRUYWInO1xuICAgICAgdGhpcy5iYXJXaWR0aCA9ICc4NS41NydcbiAgICB9XG4gIH1cbiAgcHJldmlvdXNTdGVwKCkge1xuICAgIHRoaXMubG9hZGVyID0gZmFsc2U7XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgIT0gJ3NlcnZpY2VMaXN0aW5nJykge1xuICAgICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0cnVlO1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdsb2NhdGlvbkxpc3RpbmcnKSB7XG4gICAgICAgIGlmICh0aGlzLmFjY2Vzc2VkVGFicy5zZXJ2aWNlTGlzdGluZykge1xuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnc2VydmljZUxpc3RpbmcnO1xuICAgICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMTQuMjgnO1xuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRMb2NhdGlvbiA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdzdGFmZkxpc3RpbmcnKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRTdGFmZiA9IG51bGw7XG4gICAgICAgIGlmICh0aGlzLmFjY2Vzc2VkVGFicy5sb2NhdGlvbkxpc3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ2xvY2F0aW9uTGlzdGluZyc7XG4gICAgICAgICAgdGhpcy5iYXJXaWR0aCA9ICcyOS4yOCc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5hY2Nlc3NlZFRhYnMuc2VydmljZUxpc3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ3NlcnZpY2VMaXN0aW5nJztcbiAgICAgICAgICB0aGlzLmJhcldpZHRoID0gJzE0LjI4JztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZWxzZSBpZiAodGhpcy5zZWxlY3RlZFRhYiA9PT0gJ2RhdGVTZWxlY3Rpb24nKSB7XG4gICAgICAgIGlmICh0aGlzLmFjY2Vzc2VkVGFicy5zdGFmZkxpc3RpbmcpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ3N0YWZmTGlzdGluZyc7XG4gICAgICAgICAgdGhpcy5iYXJXaWR0aCA9ICc0My41Nyc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5hY2Nlc3NlZFRhYnMubG9jYXRpb25MaXN0aW5nKSB7XG4gICAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdsb2NhdGlvbkxpc3RpbmcnO1xuICAgICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMjkuMjgnO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuYWNjZXNzZWRUYWJzLnNlcnZpY2VMaXN0aW5nKSB7XG4gICAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdzZXJ2aWNlTGlzdGluZyc7XG4gICAgICAgICAgdGhpcy5iYXJXaWR0aCA9ICcxNC4yOCc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdjb250YWN0RGV0YWlscycpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdkYXRlU2VsZWN0aW9uJztcbiAgICAgICAgdGhpcy5iYXJXaWR0aCA9ICc1OC41Nyc7XG4gICAgICB9XG4gICAgICBlbHNlIGlmICh0aGlzLnNlbGVjdGVkVGFiID09PSAncGF5bWVudFRhYicpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdjb250YWN0RGV0YWlscyc7XG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnNzAuNTcnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBzZXJ2aWNlRGF0YTogYW55W10gPSBbXTtcbiAgZ2V0QWxsU2VydmljZXMoKSB7XG4gICAgdGhpcy5za2VsZXRvbkxvYWRlciA9IHRydWVcbiAgICBsZXQgc2VydmljZVBheWxvYWQ6IGFueSA9IHtcbiAgICAgIGJ1c2luZXNzSWQ6IHRoaXMuYnVzaW5lc3NJZCA/PyBcIlwiLFxuICAgICAgLy8gYnVzaW5lc3NJZDonMWYxNWNiNjctZDI3NC02ZWY3LThmYzUtN2IxZWM1ZWMyZDE1JyxcbiAgICAgIHBhZ2VObzogMCxcbiAgICAgIHNpemU6IDEwMFxuICAgIH1cbiAgICB0aGlzLnJlc3RTZXJ2aWNlLmdldEFsbEFwcG9pbnRtZW50U2VydmljZShzZXJ2aWNlUGF5bG9hZCkuc3Vic2NyaWJlKFxuICAgICAgKHJlczogYW55KSA9PiB7XG4gICAgICAgIGlmIChyZXMuY29udGVudC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGhpcy5za2VsZXRvbkxvYWRlciA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMuc2VydmljZURhdGEgPSByZXMuY29udGVudC5maWx0ZXIoKHNlcnZpY2U6IGFueSkgPT4gc2VydmljZS5hY3RpdmUgPT09IHRydWUpO1xuICAgICAgICAgIHRoaXMuc2VydmljZURhdGEuZm9yRWFjaChzZXJ2aWNlID0+IHNlcnZpY2Uuc2VsZWN0ZWQgPSBmYWxzZSk7XG4gICAgICAgICAgLy8gY29uc29sZS5sb2codGhpcy5zZXJ2aWNlRGF0YSlcbiAgICAgICAgICBpZiAodGhpcy5zZXJ2aWNlRGF0YS5sZW5ndGggPT09IDEgJiYgIXRoaXMuYWN0aXZlQnV0dG9uKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkU2VydmljZSA9IHRoaXMuc2VydmljZURhdGFbMF07XG4gICAgICAgICAgICB0aGlzLmdldEFsbExvY2F0aW9ucygpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnc2VydmljZUxpc3RpbmcnO1xuICAgICAgICAgICAgdGhpcy5iYXJXaWR0aCA9ICcxNC4yOCc7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIC8vIEhhbmRsZSBlcnJvcnMgZ3JhY2VmdWxseVxuICAgICAgfVxuICAgICk7XG4gIH1cbiAgbG9jYXRpb25EYXRhOiBhbnlbXSA9IFtdO1xuICBnZXRBbGxMb2NhdGlvbnMoKSB7XG4gICAgdGhpcy5sb2FkZXIgPSB0cnVlO1xuICAgIHRoaXMubG9jYXRpb25EYXRhID0gW107XG4gICAgbGV0IHBheWxvYWQgPSB7IGJ1c2luZXNzSWQ6IHRoaXMuYnVzaW5lc3NJZCA/PyBcIlwiIH1cbiAgICB0aGlzLnJlc3RTZXJ2aWNlLmdldEFsbFN0b3JlcyhwYXlsb2FkKS5zdWJzY3JpYmUoXG4gICAgICAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgaWYgKHJlcy5kYXRhLmRhdGEubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGxldCBsb2NhdGlvbnMgPSByZXMuZGF0YS5kYXRhLmZpbHRlcigoc3RvcmU6IGFueSkgPT4geyByZXR1cm4gc3RvcmUuc3RhdHVzID09PSAnQUNUSVZFJyB9KTtcbiAgICAgICAgICBsb2NhdGlvbnMuZm9yRWFjaCgobG9jYXRpb246IGFueSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRTZXJ2aWNlLnN0b3JlSWRzLmluY2x1ZGVzKGxvY2F0aW9uLmlkKSkge1xuICAgICAgICAgICAgICBsb2NhdGlvbi5zZWxlY3RlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICB0aGlzLmxvY2F0aW9uRGF0YS5wdXNoKGxvY2F0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICAgIGlmICh0aGlzLmxvY2F0aW9uRGF0YS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRMb2NhdGlvbiA9IHRoaXMubG9jYXRpb25EYXRhWzBdO1xuICAgICAgICAgICAgdGhpcy5sb2FkZXIgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuYWNjZXNzZWRUYWJzLmxvY2F0aW9uTGlzdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5nZXRBbGxTdGFmZigpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubG9hZGVyID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ2xvY2F0aW9uTGlzdGluZyc7XG4gICAgICAgICAgICB0aGlzLmJhcldpZHRoID0gJzI5LjI4JztcbiAgICAgICAgICAgIHRoaXMuYWNjZXNzZWRUYWJzLmxvY2F0aW9uTGlzdGluZyA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsgc2V2ZXJpdHk6ICdlcnJvcicsIHN1bW1hcnk6ICdObyBMb2NhdGlvbicsIGRldGFpbDogJ05vIExvY2F0aW9uIGFkZGVkIGZvciBzZWxlY3RlZCBzZXJ2aWNlJyB9KTtcbiAgICAgICAgICB0aGlzLmxvYWRlciA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIC8vIEhhbmRsZSBlcnJvcnMgZ3JhY2VmdWxseVxuICAgICAgfVxuICAgICk7XG4gIH1cbiAgc3RhZmZQYXlsb2FkOiBhbnkgPSB7XG4gICAgc2VydmljZUlkOiAnJyxcbiAgICBzdG9yZUlkOiAnJyxcbiAgICBidXNpbmVzc0lkOiAnJ1xuICB9XG4gIHN0YWZmU2VhcmNoUXVlcnk6IHN0cmluZyA9ICcnO1xuICBnZXQgZmlsdGVyZWRTdGFmZigpOiBhbnlbXSB7XG4gICAgaWYgKCF0aGlzLnN0YWZmU2VhcmNoUXVlcnkudHJpbSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5zdGFmZkRhdGE7XG4gICAgfVxuICAgIGNvbnN0IHF1ZXJ5ID0gdGhpcy5zdGFmZlNlYXJjaFF1ZXJ5LnRvTG93ZXJDYXNlKCkudHJpbSgpO1xuICAgIHJldHVybiB0aGlzLnN0YWZmRGF0YS5maWx0ZXIoc3RhZmYgPT4gXG4gICAgICBzdGFmZj8uc3RhZmZOYW1lPy50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHF1ZXJ5KVxuICAgICk7XG4gIH1cbiAgc3RhZmZEYXRhOiBhbnlbXSA9IFtdO1xuICBnZXRBbGxTdGFmZigpIHtcbiAgICB0aGlzLnN0YWZmU2VhcmNoUXVlcnkgPSAnJztcbiAgICB0aGlzLmxvYWRlciA9IHRydWU7XG4gICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0cnVlO1xuICAgIHRoaXMuc3RhZmZQYXlsb2FkLnN0b3JlSWQgPSB0aGlzLnNlbGVjdGVkTG9jYXRpb24/LmlkID8/IFwiXCI7XG4gICAgdGhpcy5zdGFmZlBheWxvYWQuc2VydmljZUlkID0gdGhpcy5zZWxlY3RlZFNlcnZpY2U/LnNlcnZpY2VJZCA/IHRoaXMuc2VsZWN0ZWRTZXJ2aWNlLnNlcnZpY2VJZCA6ICcnO1xuICAgIHRoaXMuc3RhZmZQYXlsb2FkLmJ1c2luZXNzSWQgPSB0aGlzLmJ1c2luZXNzSWQgPz8gXCJcIjtcbiAgICB0aGlzLnJlc3RTZXJ2aWNlLmdldEFsbFN0YWZmKHRoaXMuc3RhZmZQYXlsb2FkKS5zdWJzY3JpYmUoXG4gICAgICAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgaWYgKHJlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGhpcy5zdGFmZkRhdGEgPSByZXMuZmlsdGVyKChzdGFmZjogYW55KSA9PiBzdGFmZi5hY3RpdmUgPT09IHRydWUgJiYgc3RhZmYuYm9va2luZ0FsbG93ZWQpO1xuICAgICAgICAgIHRoaXMuc3RhZmZEYXRhLmZvckVhY2goc3RhZmYgPT4gc3RhZmYuc2VsZWN0ZWQgPSBmYWxzZSk7XG4gICAgICAgICAgaWYgKHRoaXMuc3RhZmZEYXRhLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgdGhpcy5sb2FkZXIgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnZGF0ZVNlbGVjdGlvbic7XG4gICAgICAgICAgICB0aGlzLmJhcldpZHRoID0gJzU4LjU3JztcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRTdGFmZiA9IHRoaXMuc3RhZmZEYXRhWzBdO1xuICAgICAgICAgICAgdGhpcy5nZXRBdmFpbGFibGVTbG90cygpO1xuICAgICAgICAgICAgdGhpcy5hY2Nlc3NlZFRhYnMuc3RhZmZMaXN0aW5nID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKHRoaXMuc3RhZmZEYXRhLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIHRoaXMubG9hZGVyID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ3N0YWZmTGlzdGluZyc7XG4gICAgICAgICAgICB0aGlzLmJhcldpZHRoID0gJzQzLjU3JztcbiAgICAgICAgICAgIHRoaXMuYWNjZXNzZWRUYWJzLnN0YWZmTGlzdGluZyA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsgc2V2ZXJpdHk6ICdlcnJvcicsIHN1bW1hcnk6ICdObyBTdGFmZiBQcmVzZW50JywgZGV0YWlsOiAnTm8gU3RhZmYgcHJlc2VudCBmb3Igc2VsZWN0ZWQgc2VydmljZScgfSk7XG4gICAgICAgICAgdGhpcy5sb2FkZXIgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAvLyBIYW5kbGUgZXJyb3JzIGdyYWNlZnVsbHlcbiAgICAgIH1cbiAgICApO1xuICB9XG4gIGNvbnZlcnRUbzI0SG91cih0aW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IFtob3VyTWluLCBtb2RpZmllclJhd10gPSB0aW1lLnNwbGl0KCcgJyk7XG4gICAgY29uc3QgbW9kaWZpZXIgPSBtb2RpZmllclJhdy50b1VwcGVyQ2FzZSgpOyAvLyBcIkFNXCIgb3IgXCJQTVwiXG4gICAgbGV0IFtob3VycywgbWludXRlc10gPSBob3VyTWluLnNwbGl0KCc6JykubWFwKE51bWJlcik7XG5cbiAgICBpZiAobW9kaWZpZXIgPT09ICdQTScgJiYgaG91cnMgPCAxMikge1xuICAgICAgaG91cnMgKz0gMTI7XG4gICAgfVxuICAgIGlmIChtb2RpZmllciA9PT0gJ0FNJyAmJiBob3VycyA9PT0gMTIpIHtcbiAgICAgIGhvdXJzID0gMDtcbiAgICB9XG5cbiAgICBjb25zdCBoaCA9IGhvdXJzLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICBjb25zdCBtbSA9IG1pbnV0ZXMudG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIHJldHVybiBgJHtoaH06JHttbX0gJHttb2RpZmllcn1gO1xuICB9XG4gIHNsb3RzUGF5bG9hZDogYW55ID0ge1xuICAgIHN0b3JlSWQ6IFwiXCIsXG4gICAgc2VydmljZUlkOiBcIlwiLFxuICAgIGJ1c2luZXNzSWQ6IFwiXCIsXG4gICAgYm9va2luZ0RhdGU6IFwiXCJcbiAgfVxuICBsb2NhdGlvblRpbWluZzogYW55W10gPSBbXTtcbiAgbG9hZGVyOiBib29sZWFuID0gZmFsc2U7XG4gIGdldEF2YWlsYWJsZVNsb3RzKCkge1xuICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gZmFsc2U7XG4gICAgdGhpcy5za2VsZXRvbkxvYWRlciA9IHRydWU7XG4gICAgdGhpcy5sb2FkZXIgPSBmYWxzZTtcbiAgICB0aGlzLmxvY2F0aW9uVGltaW5nID0gW107XG4gICAgdGhpcy5zbG90c1BheWxvYWQuc3RvcmVJZCA9IHRoaXMuc2VsZWN0ZWRMb2NhdGlvbj8uaWQgPz8gXCJcIjtcbiAgICB0aGlzLnNsb3RzUGF5bG9hZC5zZXJ2aWNlSWQgPSB0aGlzLnNlbGVjdGVkU2VydmljZT8uc2VydmljZUlkID8gdGhpcy5zZWxlY3RlZFNlcnZpY2Uuc2VydmljZUlkIDogJyc7XG4gICAgdGhpcy5zbG90c1BheWxvYWQuYnVzaW5lc3NJZCA9IHRoaXMuYnVzaW5lc3NJZCA/PyBcIlwiO1xuICAgIGNvbnN0IGRhdGUgPSB0aGlzLnNlbGVjdGVkRGF0ZSA/PyBuZXcgRGF0ZSgpO1xuICAgIHRoaXMuc2VsZWN0ZWREYXRlU3RyID0gdGhpcy5mb3JtYXREYXRlKGRhdGUpO1xuICAgIGNvbnN0IHl5eXkgPSBkYXRlLmdldEZ1bGxZZWFyKCk7XG4gICAgY29uc3QgbW0gPSBTdHJpbmcoZGF0ZS5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICBjb25zdCBkZCA9IFN0cmluZyhkYXRlLmdldERhdGUoKSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICB0aGlzLnNsb3RzUGF5bG9hZC5ib29raW5nRGF0ZSA9IGAke3l5eXl9LSR7bW19LSR7ZGR9VDAwOjAwOjAwLjAwMFpgO1xuICAgIGlmICh0aGlzLnNlbGVjdGVkU3RhZmYpXG4gICAgICB0aGlzLnNsb3RzUGF5bG9hZC5zdGFmZklkID0gdGhpcy5zZWxlY3RlZFN0YWZmLnN0YWZmSWQ7XG4gICAgdGhpcy5yZXN0U2VydmljZS5nZXRCb29raW5nU2xvdHModGhpcy5zbG90c1BheWxvYWQpLnN1YnNjcmliZSgocmVzOiBhbnkpID0+IHtcbiAgICAgIHJlcy5mb3JFYWNoKCh0aW1lOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5sb2NhdGlvblRpbWluZy5wdXNoKHsgc2VsZWN0ZWQ6IGZhbHNlLCB2YWx1ZTogdGltZSB9KTtcbiAgICAgICAgdGhpcy5za2VsZXRvbkxvYWRlciA9IGZhbHNlO1xuICAgICAgfSlcbiAgICAgIGlmIChyZXMubGVuZ3RoIDw9IDApIHtcbiAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBzZXZlcml0eTogJ2Vycm9yJywgc3VtbWFyeTogJ0Jvb2tpbmcgRmFpbGVkJywgZGV0YWlsOiAnVW5hYmxlIHRvIGZldGNoIGF2YWlsYWJsZSBzbG90cy4gUGxlYXNlIHRyeSBhZ2FpbiBsYXRlcicgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgICAgIChlcnJvcjogYW55KSA9PiB7XG4gICAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsgc2V2ZXJpdHk6ICdlcnJvcicsIHN1bW1hcnk6ICdVbmFibGUgdG8gZmV0Y2ggc2xvdHMnLCBkZXRhaWw6IGVycm9yLmVycm9yLm1lc3NhZ2UgfSk7XG4gICAgICAgIHRoaXMubG9hZGVyID0gZmFsc2U7XG4gICAgICB9KVxuICB9XG4gIGlzUHJvY2Vzc2luZzogYm9vbGVhbiA9IGZhbHNlO1xuICBzZWxlY3RlZFRpbWU6IGFueVxuICBzZWxlY3RUaW1lU2xvdCh0aW1lOiBhbnkpIHtcbiAgICB0aW1lLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICBpZiAodGhpcy5zZWxlY3RlZFRpbWUgJiYgdGltZS52YWx1ZSAhPSB0aGlzLnNlbGVjdGVkVGltZS52YWx1ZSkge1xuICAgICAgdGhpcy5zZWxlY3RlZFRpbWUuc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgdGhpcy5zZWxlY3RlZFRpbWUgPSB0aW1lO1xuICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gdHJ1ZTtcbiAgfVxuICB0ZXJtc0FuZENvbmRpdGlvbnM6IGJvb2xlYW4gPSBmYWxzZTtcbiAgY2hlY2tSZXF1aXJlZFZhbHVlcygpIHtcbiAgICBjb25zdCBpc0VtYWlsVmFsaWQgPSB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5lbWFpbCAmJlxuICAgICAgL15bYS16MC05Ll8lKy1dK0BbYS16MC05Li1dK1xcLlthLXpdezIsNH0kLy50ZXN0KHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLmVtYWlsKTtcblxuICAgIGlmICh0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5uYW1lICYmXG4gICAgICBpc0VtYWlsVmFsaWQgJiZcbiAgICAgIHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLnBob25lTnVtYmVyLmxlbmd0aCA9PT0gMTApIHtcbiAgICAgIGlmICh0aGlzLnNlbGVjdGVkU2VydmljZT8uY2FuY2VsbGF0aW9uUG9saWN5Py5sZW5ndGggPiAwIHx8XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRTZXJ2aWNlPy5yZXNjaGVkdWxlUG9saWN5Py5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gdGhpcy50ZXJtc0FuZENvbmRpdGlvbnMgPyB0cnVlIDogZmFsc2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IHRydWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgYXBwb2ludG1lbnRQYXlsb2FkOiBhbnkgPSB7XG4gICAgc3RhZmZEZXRhaWw6IHtcbiAgICAgIGlkOiAnJyxcbiAgICAgIG5hbWU6ICcnXG4gICAgfSxcbiAgICBib29raW5nRGF0ZTogJycsXG4gICAgc3RhcnRUaW1lOiAnJyxcbiAgICBjdXN0b21lckRldGFpbDoge1xuICAgICAgbmFtZTogJycsXG4gICAgICBwaG9uZU51bWJlcjogJycsXG4gICAgICBlbWFpbDogJydcbiAgICB9LFxuICAgIHNlcnZpY2VEZXRhaWw6IHtcbiAgICAgIGlkOiAnJyxcbiAgICAgIG5hbWU6ICcnXG4gICAgfSxcbiAgICBzdG9yZUlkOiAnJyxcbiAgICBidXNpbmVzc0lkOiB0aGlzLmJ1c2luZXNzSWQsXG4gICAgYnVzaW5lc3NOYW1lOiB0aGlzLmJ1c2luZXNzTmFtZVxuICB9XG4gIGNoZWNrUGF5bWVudCgpIHtcbiAgICB0aGlzLmlzUHJvY2Vzc2luZyA9IHRydWU7XG4gICAgY29uc3QgcmVxdWVzdF9mb3JtID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJSRVFVRVNUX0ZST01cIik7XG4gICAgaWYgKHJlcXVlc3RfZm9ybSA9PT0gJ0VDT01NRVJDRScpIHtcbiAgICAgIHRoaXMuY3JlYXRlQXBwb2ludG1lbnQoKTtcbiAgICAgIHRoaXMuaXNQcm9jZXNzaW5nID0gZmFsc2U7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRTZXJ2aWNlPy5kZXBvc2l0QW1vdW50Py5kZXBvc2l0UmVxdWlyZWQpIHtcbiAgICAgICAgdGhpcy5wYXltZW50Qm9va2luZ0FwcG9pbnRtZW50KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNyZWF0ZUFwcG9pbnRtZW50KCk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIHRoaXMuY3JlYXRlQXBwb2ludG1lbnQoKTtcbiAgfVxuICBhcGlTdGF0dXM6IGJvb2xlYW4gPSBmYWxzZTtcbiAgY3JlYXRlQXBwb2ludG1lbnQoKSB7XG4gICAgY29uc3QgZGF0ZSA9IHRoaXMuc2VsZWN0ZWREYXRlID8/IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgeXl5eSA9IGRhdGUuZ2V0RnVsbFllYXIoKTtcbiAgICBjb25zdCBtbSA9IFN0cmluZyhkYXRlLmdldE1vbnRoKCkgKyAxKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIGNvbnN0IGRkID0gU3RyaW5nKGRhdGUuZ2V0RGF0ZSgpKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgIHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLnN0YWZmRGV0YWlsLmlkID0gdGhpcy5zZWxlY3RlZFN0YWZmPy5zdGFmZklkO1xuICAgIHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLnN0YWZmRGV0YWlsLm5hbWUgPSB0aGlzLnNlbGVjdGVkU3RhZmY/LnN0YWZmTmFtZTtcbiAgICB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5zdG9yZUlkID0gdGhpcy5zZWxlY3RlZExvY2F0aW9uPy5pZDtcbiAgICB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5zZXJ2aWNlRGV0YWlsLmlkID0gdGhpcy5zZWxlY3RlZFNlcnZpY2U/LnNlcnZpY2VJZDtcbiAgICB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5zZXJ2aWNlRGV0YWlsLm5hbWUgPSB0aGlzLnNlbGVjdGVkU2VydmljZT8ubmFtZTtcbiAgICB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5zdGFydFRpbWUgPSB0aGlzLmNvbnZlcnRUbzI0SG91cih0aGlzLnNlbGVjdGVkVGltZS52YWx1ZSkuc2xpY2UoMCwgNSk7XG4gICAgdGhpcy5hcHBvaW50bWVudFBheWxvYWQuYm9va2luZ0RhdGUgPSBgJHt5eXl5fS0ke21tfS0ke2RkfVQwMDowMDowMC4wMDBaYDtcbiAgICB0aGlzLnJlc3RTZXJ2aWNlLmJvb2tBcHBvaW50bWVudFYyKHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkKS5zdWJzY3JpYmUoKHJlczogYW55KSA9PiB7XG4gICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ3N0YXR1c1RlbXBsYXRlJztcbiAgICAgIHRoaXMuYmFyV2lkdGggPSAnMTAwJztcbiAgICAgIHRoaXMuYXBpU3RhdHVzID0gdHJ1ZTtcbiAgICB9LFxuICAgICAgKGVycm9yOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5hcGlTdGF0dXMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBzZXZlcml0eTogJ2Vycm9yJywgc3VtbWFyeTogJ0Jvb2tpbmcgRmFpbGVkJywgZGV0YWlsOiBlcnJvci5lcnJvci5tZXNzYWdlIH0pO1xuICAgICAgfVxuICAgIClcbiAgfVxuICBwYXltZW50Qm9va2luZ0FwcG9pbnRtZW50KCkge1xuICAgIGNvbnN0IGRhdGUgPSB0aGlzLnNlbGVjdGVkRGF0ZSA/PyBuZXcgRGF0ZSgpO1xuICAgIGNvbnN0IHl5eXkgPSBkYXRlLmdldEZ1bGxZZWFyKCk7XG4gICAgY29uc3QgbW0gPSBTdHJpbmcoZGF0ZS5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICBjb25zdCBkZCA9IFN0cmluZyhkYXRlLmdldERhdGUoKSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5zdGFmZkRldGFpbC5pZCA9IHRoaXMuc2VsZWN0ZWRTdGFmZj8uc3RhZmZJZDtcbiAgICB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5zdGFmZkRldGFpbC5uYW1lID0gdGhpcy5zZWxlY3RlZFN0YWZmPy5zdGFmZk5hbWU7XG4gICAgdGhpcy5hcHBvaW50bWVudFBheWxvYWQuc3RvcmVJZCA9IHRoaXMuc2VsZWN0ZWRMb2NhdGlvbj8uaWQ7XG4gICAgdGhpcy5hcHBvaW50bWVudFBheWxvYWQuc2VydmljZURldGFpbC5pZCA9IHRoaXMuc2VsZWN0ZWRTZXJ2aWNlPy5zZXJ2aWNlSWQ7XG4gICAgdGhpcy5hcHBvaW50bWVudFBheWxvYWQuc2VydmljZURldGFpbC5uYW1lID0gdGhpcy5zZWxlY3RlZFNlcnZpY2U/Lm5hbWU7XG4gICAgdGhpcy5hcHBvaW50bWVudFBheWxvYWQuc3RhcnRUaW1lID0gdGhpcy5jb252ZXJ0VG8yNEhvdXIodGhpcy5zZWxlY3RlZFRpbWUudmFsdWUpLnNsaWNlKDAsIDUpO1xuICAgIHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmJvb2tpbmdEYXRlID0gYCR7eXl5eX0tJHttbX0tJHtkZH1UMDA6MDA6MDAuMDAwWmA7XG4gICAgdGhpcy5yZXN0U2VydmljZS5wYXltZW50Rm9yQXBwb2ludG1lbnQodGhpcy5hcHBvaW50bWVudFBheWxvYWQpLnN1YnNjcmliZShcbiAgICAgIChyZXM6IGFueSkgPT4ge1xuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnYXBwb2ludG1lbnRQYXltZW50SWQnLCByZXMucGdPcmRlcklkKTtcbiAgICAgICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fZXZlbnRTZXJ2aWNlLmNhc2hGcmVlRXZlbnQuZW1pdCh7IGRhdGE6IHsgb3JkZXJTaWduYXR1cmU6IHJlcy5vcmRlclNpZ25hdHVyZSB9IH0pO1xuICAgICAgfSxcbiAgICAgIChlcnJvcjogYW55KSA9PiB7XG4gICAgICAgIHRoaXMubG9hZGVyID0gZmFsc2U7XG4gICAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsgc2V2ZXJpdHk6ICdlcnJvcicsIHN1bW1hcnk6ICdQYXltZW50IEZhaWxlZCcsIGRldGFpbDogZXJyb3IuZXJyb3IubWVzc2FnZSB9KTtcbiAgICAgIH1cbiAgICApXG5cbiAgfVxuICBnb0JhY2soKSB7XG4gICAgaWYgKGxvY2FsU3RvcmFnZS5nZXRJdGVtKFwiUkVRVUVTVF9GUk9NXCIpID09PSAnRUNPTU1FUkNFJykge1xuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycvYWRtaW4vYXBwb2ludG1lbnRzL2xpc3QtYXBwb2ludG1lbnRzJ10pXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycnXSlcbiAgICB9XG4gIH1cbn1cbiIsIjxwLXRvYXN0IHBvc2l0aW9uPVwiYm90dG9tLXJpZ2h0XCIgW2Jhc2VaSW5kZXhdPVwiMTAwMDAwMDAwMDBcIiBbYXV0b1pJbmRleF09XCJ0cnVlXCJcbiAgICBbc2hvd1RyYW5zZm9ybU9wdGlvbnNdPVwic2NyZWVuV2lkdGggPCA0NzUgPyAndHJhbnNsYXRlWSgtMTAwJSknIDogJydcIj48L3AtdG9hc3Q+XG48c2VjdGlvbiBjbGFzcz1cIm1haW5fc2VjdGlvblwiPlxuICAgIDxkaXYgY2xhc3M9XCJtYWluX2hlYWRlclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJiYWNrLWJ0biBkLWZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlciBhbGlnbi1pdGVtcy1jZW50ZXIgY3Vyc29yLXBvaW50ZXIgZ2FwLTIgbWItM1wiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImdvQmFjaygpXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1pY29uPmtleWJvYXJkX2JhY2tzcGFjZTwvbWF0LWljb24+PHNwYW4gKm5nSWY9XCJzY3JlZW5XaWR0aCA+IDQ3NVwiPkJhY2sgdG8gSG9tZTwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhlYWRlci10aXRsZVwiPlxuICAgICAgICAgICAgICAgIDxoMT5Cb29rIE5ldyBBcHBvaW50bWVudDwvaDE+XG4gICAgICAgICAgICAgICAgPHA+e3tidXNpbmVzc05hbWUgPz8gXCJOL0FcIiB9fTwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3MtYmFyXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3MtZmlsbFwiIFtzdHlsZS53aWR0aF09XCJiYXJXaWR0aCArICclJ1wiPjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibWFpbl9ib2R5IHctMTAwIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCI+PG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGVkVGFiID09PSAnc2VydmljZUxpc3RpbmcnXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXNrZWxldG9uTG9hZGVyXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInNlcnZpY2VMaXN0aW5nXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFRhYiA9PT0gJ2xvY2F0aW9uTGlzdGluZydcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb2NhdGlvbkxpc3RpbmdcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFRhYiA9PT0gJ3N0YWZmTGlzdGluZydcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJzdGFmZkxpc3RpbmdcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFRhYiA9PT0gJ2RhdGVTZWxlY3Rpb24nXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiZGF0ZVNlbGVjdGlvblwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGVkVGFiPT09J2NvbnRhY3REZXRhaWxzJ1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImNvbnRhY3REZXRhaWxzXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0ZWRUYWI9PT0ncGF5bWVudFRhYidcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJwYXltZW50VGFiXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0ZWRUYWI9PT0nc3RhdHVzVGVtcGxhdGUnXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwic3RhdHVzVGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm1haW5fZm9vdGVyIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyIGFsaWduLWl0ZW1zLWNlbnRlclwiICpuZ0lmPVwic2VsZWN0ZWRUYWIhPT0nc3RhdHVzVGVtcGxhdGUnXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb290ZXItYnV0dG9uc1wiXG4gICAgICAgICAgICBbbmdTdHlsZV09XCJ7J2p1c3RpZnktY29udGVudCc6IHNlbGVjdGVkVGFiICE9ICdzZXJ2aWNlTGlzdGluZycgPyAnc3BhY2UtYmV0d2VlbicgOiAnZW5kJ31cIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFjay1mb290ZXItYnRuIGN1cnNvci1wb2ludGVyXCIgKGNsaWNrKT1cInByZXZpb3VzU3RlcCgpXCJcbiAgICAgICAgICAgICAgICAqbmdJZj1cInNlbGVjdGVkVGFiICE9ICdzZXJ2aWNlTGlzdGluZydcIj5CYWNrPC9zcGFuPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImNvbnRpbnVlLWJ0blwiIFtkaXNhYmxlZF09XCIhYWN0aXZlQnV0dG9uXCIgKGNsaWNrKT1cIm5leHRTdGVwKClcIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwic2VsZWN0ZWRUYWIhPSdwYXltZW50VGFiJ1wiPnt7IWxvYWRlciA/ICdDb250aW51ZScgOiAnTG9hZGluZy4uLid9fTwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImN1cnNvci1wb2ludGVyIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtZXZlbmx5IGFsaWduLWl0ZW1zLWNlbnRlclwiXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJzZWxlY3RlZFRhYj09PSdwYXltZW50VGFiJ1wiIChjbGljayk9XCJjaGVja1BheW1lbnQoKVwiIFtkaXNhYmxlZF09XCJpc1Byb2Nlc3NpbmdcIlxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsncGF5LW5vdy1idG4nIDogc2VsZWN0ZWRTZXJ2aWNlPy5kZXBvc2l0QW1vdW50Py5kZXBvc2l0UmVxdWlyZWQsJ2NvbXBsZXRlX2Jvb2tpbmcnIDogIXNlbGVjdGVkU2VydmljZT8uZGVwb3NpdEFtb3VudD8uZGVwb3NpdFJlcXVpcmVkfVwiPlxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiaHR0cHM6Ly9kMno5NDk3eHA4eGIxMi5jbG91ZGZyb250Lm5ldC9wcm9kLWltYWdlcy8zMDQwMTJjMTc1MzQ0MDA4Nzk5NkJhY2tncm91bmQucG5nXCI+XG4gICAgICAgICAgICAgICAge3tzZWxlY3RlZFNlcnZpY2U/LmRlcG9zaXRBbW91bnQ/LmRlcG9zaXRSZXF1aXJlZCA/ICdQYXkgTm93JyA6ICdDb21wbGV0ZSBCb29raW5nJ319XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L3NlY3Rpb24+XG48bmctdGVtcGxhdGUgI3NlcnZpY2VMaXN0aW5nPlxuICAgIDxkaXYgY2xhc3M9XCJ3LTYwIHNlcnZpY2Vfc2VjdGlvblwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1zZWxlY3Rpb25cIj5cbiAgICAgICAgICAgIDxoMj5TZWxlY3QgYSBTZXJ2aWNlPC9oMj5cbiAgICAgICAgICAgIDxwPkNob29zZSB0aGUgc2VydmljZSB5b3UnZCBsaWtlIHRvIGJvb2s8L3A+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlcy1ncmlkXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc2VydmljZSBvZiBzZXJ2aWNlRGF0YVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiXCIgKGNsaWNrKT1cInNlbGVjdFNlcnZpY2Uoc2VydmljZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAnc2VydmljZS1jYXJkLXNlbGVjdGVkJyA6IHNlcnZpY2U/LnNlbGVjdGVkLCAnc2VydmljZS1jYXJkJzogIXNlcnZpY2U/LnNlbGVjdGVkIH1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCIgc2VydmljZS1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1pY29uXCI+PG1hdC1pY29uPnBlcnNvbl9vdXRsaW5lPC9tYXQtaWNvbj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1pbmZvXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLXRpdGxlXCI+e3tzZXJ2aWNlPy5uYW1lID8gc2VydmljZT8ubmFtZSA6ICdOL0EnfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1wcmljZVwiPuKCuXt7c2VydmljZT8ucHJpY2VEZXRhaWxzPy5wcmljZSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2aWNlPy5wcmljZURldGFpbHM/LnByaWNlIDogJ04vQScgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtZHVyYXRpb25cIj57e3NlcnZpY2U/LmR1cmF0aW9uID8gc2VydmljZT8uZHVyYXRpb24gOiAnTi9BJ319IG1pblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtZGVzY3JpcHRpb25cIiAqbmdJZj1cInNlcnZpY2U/LmRlc2NyaXB0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3tzZXJ2aWNlPy5kZXNjcmlwdGlvbiA/IHNlcnZpY2U/LmRlc2NyaXB0aW9uIDogJ04vQSd9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaG9tZS12aXNpdFwiICpuZ0lmPVwic2VydmljZT8uaG9tZUFwcG9pbnRtZW50QXZhaWxhYmxlXCI+PGltZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmM9XCJodHRwczovL2Qyejk0OTd4cDh4YjEyLmNsb3VkZnJvbnQubmV0L3Byb2QtaW1hZ2VzLzk4MjEyNmMxNzU4NjI4ODYzMTI5ZnVybml0dXJlXzE2NDA2MTAzLnBuZ1wiPkhvbWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWaXNpdCBBdmFpbGFibGU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICA8IS0tIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWNhcmRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1pY29uXCI+8J+RpDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaW5mb1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLXRpdGxlXCI+R2VuZXJhbCBDb25zdWx0YXRpb248L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1jYXRlZ29yeVwiPk1lZGljYWw8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1wcmljZVwiPuKCuTgwMDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWR1cmF0aW9uXCI+MzAgbWluPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWRlc2NyaXB0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBDb21wcmVoZW5zaXZlIGhlYWx0aCBjb25zdWx0YXRpb25cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1jYXJkXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaWNvblwiPvCfp6A8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS10aXRsZVwiPk1lbnRhbCBIZWFsdGggQ291bnNlbGluZzwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWNhdGVnb3J5XCI+TWVudGFsIEhlYWx0aDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLXByaWNlXCI+4oK5MTUwMDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWR1cmF0aW9uXCI+NDUgbWluPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWRlc2NyaXB0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBQcm9mZXNzaW9uYWwgcHN5Y2hvbG9naWNhbCBzdXBwb3J0XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaG9tZS12aXNpdFwiPkhvbWUgVmlzaXQgQXZhaWxhYmxlPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1jYXJkXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaWNvblwiPuKcgjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaW5mb1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLXRpdGxlXCI+SGFpciBDdXQgJiBTdHlsaW5nPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtY2F0ZWdvcnlcIj5CZWF1dHk8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1wcmljZVwiPuKCuTEyMDA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1kdXJhdGlvblwiPjQ1IG1pbjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1kZXNjcmlwdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgUHJvZmVzc2lvbmFsIGhhaXIgY3V0dGluZyBhbmQgc3R5bGluZ1xuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhvbWUtdmlzaXRcIj5Ib21lIFZpc2l0IEF2YWlsYWJsZTwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PiAtLT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG48bmctdGVtcGxhdGUgI2xvY2F0aW9uTGlzdGluZz5cbiAgICA8ZGl2IGNsYXNzPVwibG9jYXRpb25fc2VjdGlvblwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyIGZsZXgtY29sdW1uIGFsaWduLWl0ZW1zLXN0YXJ0XCI+XG4gICAgICAgICAgICA8aDE+Q2hvb3NlIExvY2F0aW9uPC9oMT5cbiAgICAgICAgICAgIDxwPlNlbGVjdCB3aGVyZSB5b3UnZCBsaWtlIHRvIHJlY2VpdmUgdGhlIHNlcnZpY2U8L3A+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJsb2NhdGlvbi1saXN0XCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBsb2NhdGlvbiBvZiBsb2NhdGlvbkRhdGFcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IChjbGljayk9XCJzZWxlY3RMb2NhdGlvbihsb2NhdGlvbilcIlxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdsb2NhdGlvbi1jYXJkLXNlbGVjdGVkJyA6IGxvY2F0aW9uPy5zZWxlY3RlZCwgJ2xvY2F0aW9uLWNhcmQnOiAhbG9jYXRpb24/LnNlbGVjdGVkIH1cIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvY2F0aW9uLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2NhdGlvbi1pbmZvXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvY2F0aW9uLWljb25cIj48aW1nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmM9XCJodHRwczovL2Qyejk0OTd4cDh4YjEyLmNsb3VkZnJvbnQubmV0L3Byb2QtaW1hZ2VzLzQyNzIyNmMxNzU4NjI5MTU3NzU4c3RvcmVfMzE3MTUxMC5wbmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9jYXRpb24tZGV0YWlsc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzPnt7bG9jYXRpb24/LnN0b3JlTmFtZSA/IGxvY2F0aW9uPy5zdG9yZU5hbWUgOiAnTi9BJ319PC9oMz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPGRpdiBjbGFzcz1cImRpc3RhbmNlXCI+PG1hdC1pY29uPmxvY2F0aW9uX29uPC9tYXQtaWNvbj4gMi4zIGttPC9kaXY+IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+e3tsb2NhdGlvbj8uYWRkcmVzc0RldGFpbHM/LmFkZHJlc3NMaW5lfX0sIHt7bG9jYXRpb24/LmFkZHJlc3NEZXRhaWxzPy5jaXR5fX0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2xvY2F0aW9uPy5hZGRyZXNzRGV0YWlscz8uc3RhdGV9fSB7e2xvY2F0aW9uPy5waW5jb2RlfX08L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwhLS0gPGRpdiBjbGFzcz1cImxvY2F0aW9uLWNhcmRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9jYXRpb24tY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9jYXRpb24taW5mb1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvY2F0aW9uLWljb24gYnJhbmNoLWljb25cIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2NhdGlvbi1kZXRhaWxzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzPkJyYW5jaCBDbGluaWM8L2gzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwPjQ1NiBDYXJlIEF2ZW51ZSwgSGVhbHRoIFpvbmUsIE11bWJhaSA0MDAwMTU8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkaXN0YW5jZVwiPjUuOCBrbTwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2NhdGlvbi1jYXJkXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvY2F0aW9uLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvY2F0aW9uLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJsb2NhdGlvbi1pY29uIGhvbWUtaWNvblwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvY2F0aW9uLWRldGFpbHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDM+SG9tZSBWaXNpdDwvaDM+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+WW91ciBMb2NhdGlvbjwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRpc3RhbmNlXCI+MCBrbTwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+IC0tPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG48bmctdGVtcGxhdGUgI3N0YWZmTGlzdGluZz5cbiAgICA8ZGl2IGNsYXNzPVwidy02MCBvdmVyZmxvdy1oaWRkZW4gc3RhZmYtbGlzdGluZ1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IHctMTAwIGgtMTAwXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy0xMDBcIj5cbiAgICAgICAgICAgICAgICA8IS0tIEhlYWRlciBTZWN0aW9uIC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGFmZi1oZWFkZXIgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8aDE+U2VsZWN0IFN0YWZmIE1lbWJlcjwvaDE+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwic3RhZmYtc3VidGl0bGUgbWItMFwiPkNob29zZSB5b3VyIHByZWZlcnJlZCBwcm9mZXNzaW9uYWw8L3A+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8IS0tIFN0YWZmIFNlYXJjaCBCYXIgLS0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlYXJjaC1jb250YWluZXIgbWItNFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VhcmNoLWlucHV0LXdyYXBwZXIgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwic2VhcmNoLWljb24gbWUtMlwiPnNlYXJjaDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cInNlYXJjaC1pbnB1dCBib3JkZXItMCBmbGV4LWdyb3ctMVwiIHBsYWNlaG9sZGVyPVwiU2VhcmNoIHN0YWZmIG1lbWJlciBieSBuYW1lLi4uXCIgWyhuZ01vZGVsKV09XCJzdGFmZlNlYXJjaFF1ZXJ5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjbGVhci1pY29uIGN1cnNvci1wb2ludGVyIG1zLTJcIiAqbmdJZj1cInN0YWZmU2VhcmNoUXVlcnlcIiAoY2xpY2spPVwic3RhZmZTZWFyY2hRdWVyeSA9ICcnXCI+Y2xvc2U8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwhLS0gU3RhZmYgQ2FyZHMgLS0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0YWZmLWxpc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3RhZmYgb2YgZmlsdGVyZWRTdGFmZlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQgcm91bmRlZC0zIHAtM1wiIChjbGljayk9XCJzZWxlY3RTdGFmZihzdGFmZilcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ3N0YWZmLWNhcmQtc2VsZWN0ZWQnIDogc3RhZmY/LnNlbGVjdGVkLCAnc3RhZmYtY2FyZCc6ICFzdGFmZj8uc2VsZWN0ZWQgfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1iZXR3ZWVuIHctMTAwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGZsZXgtZ3Jvdy0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzdGFmZi1hdmF0YXIgcm91bmRlZC1jaXJjbGUgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyIG1lLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e3N0YWZmPy5zdGFmZk5hbWUuc2xpY2UoMCwyKS50b1VwcGVyQ2FzZSgpfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0YWZmLWRldGFpbHMgZmxleC1ncm93LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJzdGFmZi1uYW1lXCI+e3soc3RhZmY/LnN0YWZmTmFtZSA/IHN0YWZmPy5zdGFmZk5hbWUgOiAnTi9BJykgfCB0aXRsZWNhc2V9fTwvaDM+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJzdGFmZi1zcGVjaWFsdHlcIj57eyhidXNpbmVzc05hbWUgJiYgYnVzaW5lc3NOYW1lICE9PSAnTi9BJykgPyBidXNpbmVzc05hbWUgOiAnQm9va2luZyBTcGVjaWFsaXN0J319PC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VsZWN0aW9uLWluZGljYXRvclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNoZWNrbWFyay1jaXJjbGUtbWluaSBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXJcIiBbY2xhc3Muc2VsZWN0ZWRdPVwic3RhZmY/LnNlbGVjdGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uICpuZ0lmPVwic3RhZmY/LnNlbGVjdGVkXCI+Y2hlY2s8L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbjxuZy10ZW1wbGF0ZSAjZGF0ZVNlbGVjdGlvbj5cbiAgICA8ZGl2IGNsYXNzPVwidy02MCBkYXRlX3NlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJvdyBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyIGgtMTAwXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTEyIGgtMTAwXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRhdGV0aW1lLWhlYWRlciBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxoMT5TZWxlY3QgRGF0ZSAmIFRpbWU8L2gxPlxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cImRhdGV0aW1lLXN1YnRpdGxlIG1iLTBcIj5DaG9vc2Ugd2hlbiB5b3UnZCBsaWtlIHlvdXIgYXBwb2ludG1lbnQ8L3A+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8IS0tIE1haW4gQ29udGVudCAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGdhcC00IG1haW5fY29udGFpbmVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTGVmdCBDb2x1bW4gLSBEYXRlIFNlbGVjdGlvbiAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJ7J3ctNTAnIDogc2NyZWVuV2lkdGggPiA0NzUgLCAndy0xMDAnOnNjcmVlbldpZHRoIDwgNDc1fVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlY3Rpb24tY2FyZCBjYXJkIHJvdW5kZWQtMyBwLTQgaC0xMDBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJzZWN0aW9uLXRpdGxlXCI+U2VsZWN0IERhdGU8L2gzPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRhdGUtcGlja2VyLWNvbnRhaW5lciBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1iZXR3ZWVuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImRhdGUtaW5wdXQgYm9yZGVyLTAgcm91bmRlZC0yXCIgcGxhY2Vob2xkZXI9XCJkZC1tbS15eXl5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJzZWxlY3RlZERhdGVTdHJcIiByZWFkb25seSAoY2xpY2spPVwidG9nZ2xlQ2FsZW5kYXIoJGV2ZW50KVwiPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1zLTJcIiAoY2xpY2spPVwidG9nZ2xlQ2FsZW5kYXIoJGV2ZW50KVwiPmNhbGVuZGFyX3RvZGF5PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9zaXRpb24tcmVsYXRpdmVcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkYXRlcGlja2VyLXBvcG92ZXJcIiAqbmdJZj1cInNob3dDYWxlbmRhclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jYWxlbmRhciBbKHNlbGVjdGVkKV09XCJzZWxlY3RlZERhdGVcIiBbZGF0ZUZpbHRlcl09XCJkYXRlRmlsdGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc2VsZWN0ZWRDaGFuZ2UpPVwib25EYXRlU2VsZWN0ZWQoJGV2ZW50KVwiIGNsYXNzPVwiZGF0ZXBpY2tlci1jYWxlbmRhclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2FsZW5kYXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gUmlnaHQgQ29sdW1uIC0gVGltZSBTZWxlY3Rpb24gLS0+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0aW1lX3NlbGVjdGlvblwiIFtuZ0NsYXNzXT1cInsndy01MCcgOiBzY3JlZW5XaWR0aCA+IDQ3NSAsICd3LTEwMCc6c2NyZWVuV2lkdGggPCA0NzV9XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbi1jYXJkIGNhcmQgaC0xMDAgcm91bmRlZC0zIHAtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cInNlY3Rpb24tdGl0bGVcIj5BdmFpbGFibGUgVGltZXM8L2gzPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBUaW1lIFNsb3RzIEdyaWQgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvdyBnLTIgbWItNCBvdmVyZmxvdy1zY3JvbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFza2VsZXRvbkxvYWRlciA7ZWxzZSBzbG90c0xvYWRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC00XCIgKm5nRm9yPVwibGV0IHRpbWUgb2YgbG9jYXRpb25UaW1pbmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGltZS1zbG90IHJvdW5kZWQtMlwiIFtjbGFzcy5zZWxlY3RlZF09XCJ0aW1lLnNlbGVjdGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdFRpbWVTbG90KHRpbWUpXCI+e3t0aW1lID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZT8udmFsdWUgOiAnTi9BJ319PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjc2xvdHNMb2FkZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFRpbWUgU2xvdCBHcmlkIFNrZWxldG9uIExvYWRlciBIVE1MIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWUtc2xvdC1ncmlkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBSb3cgMSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24tdGltZS1zbG90XCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uLXRpbWUtc2xvdFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbi10aW1lLXNsb3RcIj48L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUm93IDIgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uLXRpbWUtc2xvdFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbi10aW1lLXNsb3RcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24tdGltZS1zbG90XCI+PC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFJvdyAzIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbi10aW1lLXNsb3RcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24tdGltZS1zbG90XCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uLXRpbWUtc2xvdFwiPjwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBSb3cgNCAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24tdGltZS1zbG90XCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uLXRpbWUtc2xvdFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbi10aW1lLXNsb3RcIj48L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUm93IDUgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uLXRpbWUtc2xvdFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbi10aW1lLXNsb3RcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24tdGltZS1zbG90XCI+PC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFJvdyA2IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbi10aW1lLXNsb3RcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24tdGltZS1zbG90XCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uLXRpbWUtc2xvdFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gV2FpdGxpc3QgU2VjdGlvbiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIDxkaXYgY2xhc3M9XCJ3YWl0bGlzdC1zZWN0aW9uIHJvdW5kZWQtM1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLXN0YXJ0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGgtMTAwIGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGZsZXgtY29sdW1uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIndhaXRsaXN0LXRpdGxlIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTJcIj48c3BhblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ3YWl0bGlzdC1pY29uIGNoZWNrLWljb25cIj48L3NwYW4+Tm9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2xvdHMgYXZhaWxhYmxlPzwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3YWl0bGlzdC1kZXNjcmlwdGlvbiBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXQgY3Vyc29yLXBvaW50ZXJcIiB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJmbGV4Q2hlY2tDaGVja2VkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFkZCBtZSB0byB0aGUgd2FpdGxpc3QgZm9yIGVhcmxpZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZhaWxhYmlsaXR5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG48L25nLXRlbXBsYXRlPlxuPG5nLXRlbXBsYXRlICNjb250YWN0RGV0YWlscz5cbiAgICA8ZGl2IGNsYXNzPVwidy02MCBjb250YWN0X3NlY3Rpb25cIj5cbiAgICAgICAgPCEtLSBIZWFkZXIgU2VjdGlvbiAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRhY3QtaGVhZGVyIG1iLTJcIj5cbiAgICAgICAgICAgIDxoMT5Db250YWN0IERldGFpbHM8L2gxPlxuICAgICAgICAgICAgPHAgY2xhc3M9XCJjb250YWN0LXN1YnRpdGxlIG1iLTBcIj5Qcm92aWRlIHlvdXIgY29udGFjdCBpbmZvcm1hdGlvbjwvcD5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBGb3JtIFNlY3Rpb25zIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGdhcC0zIGRldGFpbHNfY29udGFpbmVyIGZsZXgtY29sdW1uIHctMTAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gTGVmdCBDb2x1bW4gLSBQZXJzb25hbCBJbmZvcm1hdGlvbiAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsndy01MCcgOiBzZWxlY3RlZFNlcnZpY2U/LmhvbWVBcHBvaW50bWVudEF2YWlsYWJsZSwgJ3ctMTAwJyA6ICFzZWxlY3RlZFNlcnZpY2U/LmhvbWVBcHBvaW50bWVudEF2YWlsYWJsZX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1zZWN0aW9uIGNhcmQgcm91bmRlZC0zIHAtNCBoLTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJzZWN0aW9uLXRpdGxlXCI+UGVyc29uYWwgSW5mb3JtYXRpb248L2gzPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRnVsbCBOYW1lIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbCBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRnVsbCBOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXF1aXJlZC1hc3Rlcmlza1wiPio8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1pbnB1dCByb3VuZGVkLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLm5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImNoZWNrUmVxdWlyZWRWYWx1ZXMoKVwiIHNpbXBvTGV0dGVyc09ubHk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRW1haWwgQWRkcmVzcyAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVtYWlsIEFkZHJlc3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlcXVpcmVkLWFzdGVyaXNrXCI+Kjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImVtYWlsXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1pbnB1dCByb3VuZGVkLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLmVtYWlsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJjaGVja1JlcXVpcmVkVmFsdWVzKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdHRlcm49XCJeW2EtejAtOS5fJSstXStAW2EtejAtOS4tXStcXC5bYS16XXsyLDR9JFwiICNlbWFpbEZpZWxkPVwibmdNb2RlbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT1cImVtYWlsXCIgcmVxdWlyZWQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUGhvbmUgTnVtYmVyIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbCBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGhvbmUgTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXF1aXJlZC1hc3Rlcmlza1wiPio8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZWxcIiBjbGFzcz1cImZvcm0tY29udHJvbCAgcm91bmRlZC0yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5waG9uZU51bWJlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiY2hlY2tSZXF1aXJlZFZhbHVlcygpXCIgc2ltcG9OdW1iZXJzT25seVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnbW9iaWxlX251bWJlcicgOiBhcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwucGhvbmVOdW1iZXIubGVuZ3RoICE9IDEwfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBSaWdodCBDb2x1bW4gLSBIb21lIFZpc2l0IERldGFpbHMgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy01MFwiICpuZ0lmPVwic2VsZWN0ZWRTZXJ2aWNlPy5ob21lQXBwb2ludG1lbnRBdmFpbGFibGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1zZWN0aW9uIGNhcmQgcm91bmRlZC0zIHAtNCBoLTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJzZWN0aW9uLXRpdGxlXCI+SG9tZSBWaXNpdCBEZXRhaWxzPC9oMz5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEhvbWUgQWRkcmVzcyAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhvbWUgQWRkcmVzc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZXh0YXJlYSBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLXRleHRhcmVhIHJvdW5kZWQtMlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJFbnRlciB5b3VyIGNvbXBsZXRlIGFkZHJlc3NcIiBbKG5nTW9kZWwpXT1cImhvbWVBZGRyZXNzXCI+PC90ZXh0YXJlYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBTcGVjaWFsIEluc3RydWN0aW9ucyAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNwZWNpYWwgSW5zdHJ1Y3Rpb25zXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0tdGV4dGFyZWEgcm91bmRlZC0yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkFueSBzcGVjaWFsIGluc3RydWN0aW9ucyBmb3IgdGhlIHByb2Zlc3Npb25hbCAob3B0aW9uYWwpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImluc3RydWN0aW9uc1wiPjwvdGV4dGFyZWE+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWNpZXMtY29udGFpbmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwic2VsZWN0ZWRTZXJ2aWNlPy5jYW5jZWxsYXRpb25Qb2xpY3k/Lmxlbmd0aCA+IDAgfHwgc2VsZWN0ZWRTZXJ2aWNlPy5yZXNjaGVkdWxlUG9saWN5Py5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gSGVhZGVyIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGgyIGNsYXNzPVwicG9saWNpZXMtdGl0bGVcIj5Qb2xpY2llcyAmIFRlcm1zPC9oMj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBQb2xpY3kgSXRlbXMgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWN5LWl0ZW1zLWNvbnRhaW5lciBkLWZsZXggZmxleC1jb2x1bW4gZ2FwLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIENhbmNlbGxhdGlvbiBQb2xpY3kgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBvbGljeS1pdGVtIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2hvd0NhbmNlbGxhdGlvblBvbGljeSA9ICFzaG93Q2FuY2VsbGF0aW9uUG9saWN5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cInBvbGljeS10aXRsZVwiPkNhbmNlbGxhdGlvbiBQb2xpY3k8L2gzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWN5LWFycm93IGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiPjxtYXQtaWNvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIXNob3dDYW5jZWxsYXRpb25Qb2xpY3lcIj5rZXlib2FyZF9hcnJvd19yaWdodDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJzaG93Q2FuY2VsbGF0aW9uUG9saWN5XCI+a2V5Ym9hcmRfYXJyb3dfZG93bjwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW5jZWxsYXRpb25fcG9saWNpZXMgZC1mbGV4IGZsZXgtY29sdW1uIGdhcC0yIGZ3LTUwMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwic2hvd0NhbmNlbGxhdGlvblBvbGljeVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdGb3I9XCJsZXQgcG9saWN5IG9mIHNlbGVjdGVkU2VydmljZT8uY2FuY2VsbGF0aW9uUG9saWN5XCI+JiM4MjI2O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3twb2xpY3l9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUmVzY2hlZHVsaW5nIFBvbGljeSAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWN5LWl0ZW0gZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzaG93UmVkdWNpbmdQb2xpY3kgPSAhc2hvd1JlZHVjaW5nUG9saWN5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cInBvbGljeS10aXRsZVwiPlJlc2NoZWR1bGluZyBQb2xpY3k8L2gzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWN5LWFycm93IGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiPjxtYXQtaWNvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIXNob3dSZWR1Y2luZ1BvbGljeVwiPmtleWJvYXJkX2Fycm93X3JpZ2h0PC9tYXQtaWNvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cInNob3dSZWR1Y2luZ1BvbGljeVwiPmtleWJvYXJkX2Fycm93X2Rvd248L21hdC1pY29uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FuY2VsbGF0aW9uX3BvbGljaWVzIGQtZmxleCBmbGV4LWNvbHVtbiBnYXAtMiBmdy01MDBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInNob3dSZWR1Y2luZ1BvbGljeVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdGb3I9XCJsZXQgcG9saWN5IG9mIHNlbGVjdGVkU2VydmljZT8ucmVzY2hlZHVsZVBvbGljeVwiPiYjODIyNjsge3twb2xpY3l9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEFjY2VwdGFuY2UgU2VjdGlvbiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY2NlcHRhbmNlLXNlY3Rpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJjdXN0b20tY2hlY2tib3hcIiBbKG5nTW9kZWwpXT1cInRlcm1zQW5kQ29uZGl0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImNoZWNrUmVxdWlyZWRWYWx1ZXMoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwiYWNjZXB0YW5jZS10ZXh0XCIgc3R5bGU9XCJtYXJnaW4tYm90dG9tOjBweCAhaW1wb3J0YW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgdW5kZXJzdGFuZCBhbmQgYWNjZXB0IHRoZSBjYW5jZWxsYXRpb24gJiByZXNjaGVkdWxpbmcgcG9saWNpZXMuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gPHNwYW4gY2xhc3M9XCJ0ZXJtcy1saW5rXCI+VGVybXMgJiBDb25kaXRpb25zPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImV4dGVybmFsLWxpbmstaWNvblwiPjwvc3Bhbj48L3NwYW4+IC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbjxuZy10ZW1wbGF0ZSAjcGF5bWVudFRhYj5cbiAgICA8ZGl2IGNsYXNzPVwidy02MCBwYXltZW50X3NlY3Rpb25cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInctMTAwIGgtMTAwXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy0xMDAgZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXIgYWxpZ24taXRlbXMtY2VudGVyIGZsZXgtY29sdW1uXCI+XG4gICAgICAgICAgICAgICAgPCEtLSBIZWFkZXIgU2VjdGlvbiAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicGF5bWVudC1oZWFkZXIgbWItMyB3LTEwMFwiPlxuICAgICAgICAgICAgICAgICAgICA8aDEgc3R5bGU9XCJmb250LXNpemU6MjRweDtmb250LXdlaWdodDogNjAwO1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3tzZWxlY3RlZFNlcnZpY2U/LmRlcG9zaXRBbW91bnQ/LmRlcG9zaXRSZXF1aXJlZCA/ICdQYXltZW50ICYgQ29uZmlybWF0aW9uJyA6ICdCb29raW5nIENvbmZpcm1hdGlvbid9fVxuICAgICAgICAgICAgICAgICAgICA8L2gxPlxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInBheW1lbnQtc3VidGl0bGUgbWItMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3tzZWxlY3RlZFNlcnZpY2U/LmRlcG9zaXRBbW91bnQ/LmRlcG9zaXRSZXF1aXJlZCA/ICdSZXZpZXcgeW91ciBib29raW5nIGFuZCBjb21wbGV0ZSBwYXltZW50JyA6IFxuICAgICAgICAgICAgICAgICAgICAgICAgJ0JlZm9yZSBDb25maXJtYXRpb24gUmV2aWV3IHlvdXIgYm9va2luZyd9fVxuICAgICAgICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8IS0tIEJvb2tpbmcgU3VtbWFyeSBDYXJkIC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJib29raW5nLXN1bW1hcnktY2FyZFwiIFtuZ0NsYXNzXT1cInsndy0xMDAnIDogc2NyZWVuV2lkdGggPCA0NzUsJ3ctNTAnOnNjcmVlbldpZHRoID4gNDc1fVwiPlxuICAgICAgICAgICAgICAgICAgICA8aDIgY2xhc3M9XCJzdW1tYXJ5LXRpdGxlXCI+Qm9va2luZyBTdW1tYXJ5PC9oMj5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIFNlcnZpY2UgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5TZXJ2aWNlPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS12YWx1ZVwiPnt7c2VsZWN0ZWRTZXJ2aWNlPy5uYW1lID8gc2VsZWN0ZWRTZXJ2aWNlPy5uYW1lIDogJ04vQSd9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIFByb2Zlc3Npb25hbCAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktcm93XCIgKm5nSWY9XCJzZWxlY3RlZFN0YWZmPy5zdGFmZk5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+UHJvZmVzc2lvbmFsPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS12YWx1ZVwiPnt7c2VsZWN0ZWRTdGFmZj8uc3RhZmZOYW1lID8gc2VsZWN0ZWRTdGFmZj8uc3RhZmZOYW1lIDogJ04vQSd9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIExvY2F0aW9uIC0tPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+TG9jYXRpb248L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+e3tzZWxlY3RlZExvY2F0aW9uPy5zdG9yZU5hbWUgPyBzZWxlY3RlZExvY2F0aW9uPy5zdG9yZU5hbWUgOiAnTi9BJ319XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBEYXRlICYgVGltZSAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1sYWJlbFwiPkRhdGUgJiBUaW1lPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS12YWx1ZVwiPnt7c2VsZWN0ZWREYXRlU3RyID8gKHNlbGVjdGVkRGF0ZVN0cikgOiAnTi9BJ319IGF0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3tzZWxlY3RlZFRpbWUgPyBzZWxlY3RlZFRpbWUudmFsdWUgOiAnTi9BJ319PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gRHVyYXRpb24gLS0+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5EdXJhdGlvbjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj57e3NlbGVjdGVkU2VydmljZT8uZHVyYXRpb24gPyBzZWxlY3RlZFNlcnZpY2U/LmR1cmF0aW9uIDogJ04vQSd9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbnV0ZXM8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5UYXggUGVyY2VudDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj57e3NlbGVjdGVkU2VydmljZT8ucHJpY2VEZXRhaWxzPy50YXhQZXJjZW50ID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZFNlcnZpY2U/LnByaWNlRGV0YWlscz8udGF4UGVyY2VudCA6IDB9fSU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gVG90YWwgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXJvdyB0b3RhbC1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+VG90YWw8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjdXJyZW5jeS1zeW1ib2xcIj7igrk8L3NwYW4+e3tzZWxlY3RlZFNlcnZpY2U/LnByaWNlRGV0YWlscz8udG90YWxQcmljZSA/XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRTZXJ2aWNlPy5wcmljZURldGFpbHM/LnRvdGFsUHJpY2UgOiAnMCd9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbjxuZy10ZW1wbGF0ZSAjc3RhdHVzVGVtcGxhdGU+XG4gICAgPGRpdiBjbGFzcz1cImJvb2tpbmctY29uZmlybWF0aW9uXCI+XG4gICAgICAgIDwhLS0gU3VjY2VzcyBJY29uIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic3VjY2Vzcy1pY29uXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2hlY2ttYXJrLWNpcmNsZVwiPlxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiaHR0cHM6Ly9kMno5NDk3eHA4eGIxMi5jbG91ZGZyb250Lm5ldC9wcm9kLWltYWdlcy84ODEyOTNjMTc1ODY5NTU3ODUxOHN1Y2Nlc3MuZ2lmXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ3LTEwMCBoLTEwMFwiICpuZ0lmPVwiYXBpU3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCJodHRwczovL2Qyejk0OTd4cDh4YjEyLmNsb3VkZnJvbnQubmV0L3Byb2QtaW1hZ2VzLzMyNTAwMGMxNzU4Njk1NTY0NTE4ZmFpbC5naWZcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInctMTAwIGgtMTAwXCIgKm5nSWY9XCIhYXBpU3RhdHVzXCI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBNYWluIENvbnRlbnQgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb25maXJtYXRpb24tY29udGVudFwiPlxuICAgICAgICAgICAgPGgxIGNsYXNzPVwiY29uZmlybWF0aW9uLXRpdGxlXCI+e3thcGlTdGF0dXMgPyAnQm9va2luZyBDb25maXJtZWQhJyA6ICdCb29raW5nIEZhaWxlZCd9fTwvaDE+XG4gICAgICAgICAgICA8cCBjbGFzcz1cImNvbmZpcm1hdGlvbi1tZXNzYWdlXCI+XG4gICAgICAgICAgICAgICAge3thcGlTdGF0dXMgPyAnWW91ciBhcHBvaW50bWVudCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYm9va2VkLic6J0ZhaWxlZCB0byBib29rIHlvdSBhcHBvaW50bWVudC4gUGxlYXNlXG4gICAgICAgICAgICAgICAgdHJ5IGFnYWluIGxhdGVyJ319XG4gICAgICAgICAgICA8L3A+XG5cbiAgICAgICAgICAgIDwhLS0gRGV0YWlscyBDYXJkIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCB3LTEwMCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiICpuZ0lmPVwiYXBpU3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbHMtY2FyZFwiPlxuICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJkZXRhaWxzLXRpdGxlXCI+QXBwb2ludG1lbnQgRGV0YWlsczwvaDM+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbHMtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPlNlcnZpY2U8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPnt7YXBwb2ludG1lbnRQYXlsb2FkLnNlcnZpY2VEZXRhaWw/Lm5hbWUgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcG9pbnRtZW50UGF5bG9hZC5zZXJ2aWNlRGV0YWlsPy5uYW1lIDogJ04vQSd9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbHMtcm93XCIgKm5nSWY9XCJhcHBvaW50bWVudFBheWxvYWQ/LnN0YWZmRGV0YWlsPy5uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPlByb2Zlc3Npb25hbDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3thcHBvaW50bWVudFBheWxvYWQuc3RhZmZEZXRhaWw/Lm5hbWUgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFwcG9pbnRtZW50UGF5bG9hZC5zdGFmZkRldGFpbD8ubmFtZSA6ICdOL0EnfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlscy1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+RGF0ZSAmIFRpbWU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPnt7YXBwb2ludG1lbnRQYXlsb2FkLmJvb2tpbmdEYXRlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBvaW50bWVudFBheWxvYWQuYm9va2luZ0RhdGUuc2xpY2UoMCwxMCkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdOL0EnfX0gYXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e2FwcG9pbnRtZW50UGF5bG9hZC5zdGFydFRpbWUgPyBhcHBvaW50bWVudFBheWxvYWQuc3RhcnRUaW1lIDogJ04vQSd9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuXG4gICAgICAgICAgICA8IS0tIEFjdGlvbiBCdXR0b25zIC0tPlxuICAgICAgICAgICAgPCEtLSA8ZGl2IGNsYXNzPVwiYWN0aW9uLWJ1dHRvbnNcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lXCI+VmlldyBNeSBCb29raW5nczwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIj5CYWNrIHRvIEFkbWluPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj4gLS0+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbjxuZy10ZW1wbGF0ZSAjc2tlbGV0b25Mb2FkZXIgKm5nSWY9XCJza2VsZXRvbkxvYWRlclwiPlxuICAgIDwhLS0gU2VydmljZSBTa2VsZXRvbiBMb2FkZXIgSFRNTCAtLT5cbiAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1ncmlkXCI+XG4gICAgICAgIDwhLS0gU2tlbGV0b24gQ2FyZCAxIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1jYXJkIHNrZWxldG9uLWNhcmRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1pY29uXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24gc2tlbGV0b24tdGl0bGVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uIHNrZWxldG9uLXByaWNlXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1kdXJhdGlvblwiPjwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24gc2tlbGV0b24tY2F0ZWdvcnlcIj48L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1kZXNjcmlwdGlvblwiPjwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uIHNrZWxldG9uLWJhZGdlXCI+PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gU2tlbGV0b24gQ2FyZCAyIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1jYXJkIHNrZWxldG9uLWNhcmRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1pY29uXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24gc2tlbGV0b24tdGl0bGVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uIHNrZWxldG9uLXByaWNlXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1kdXJhdGlvblwiPjwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24gc2tlbGV0b24tY2F0ZWdvcnlcIj48L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1kZXNjcmlwdGlvblwiPjwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uIHNrZWxldG9uLWJhZGdlXCI+PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gU2tlbGV0b24gQ2FyZCAzIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1jYXJkIHNrZWxldG9uLWNhcmRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1pY29uXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24gc2tlbGV0b24tdGl0bGVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uIHNrZWxldG9uLXByaWNlXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1kdXJhdGlvblwiPjwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24gc2tlbGV0b24tY2F0ZWdvcnlcIj48L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1kZXNjcmlwdGlvblwiPjwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uIHNrZWxldG9uLWJhZGdlXCI+PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gU2tlbGV0b24gQ2FyZCA0IC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1jYXJkIHNrZWxldG9uLWNhcmRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1pY29uXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24gc2tlbGV0b24tdGl0bGVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uIHNrZWxldG9uLXByaWNlXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1kdXJhdGlvblwiPjwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24gc2tlbGV0b24tY2F0ZWdvcnlcIj48L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1kZXNjcmlwdGlvblwiPjwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uIHNrZWxldG9uLWJhZGdlXCI+PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gU2tlbGV0b24gQ2FyZCA1IC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1jYXJkIHNrZWxldG9uLWNhcmRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1pY29uXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24gc2tlbGV0b24tdGl0bGVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uIHNrZWxldG9uLXByaWNlXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1kdXJhdGlvblwiPjwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24gc2tlbGV0b24tY2F0ZWdvcnlcIj48L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1kZXNjcmlwdGlvblwiPjwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uIHNrZWxldG9uLWJhZGdlXCI+PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gU2tlbGV0b24gQ2FyZCA2IC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1jYXJkIHNrZWxldG9uLWNhcmRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1pY29uXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24gc2tlbGV0b24tdGl0bGVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uIHNrZWxldG9uLXByaWNlXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1kdXJhdGlvblwiPjwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2tlbGV0b24gc2tlbGV0b24tY2F0ZWdvcnlcIj48L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJza2VsZXRvbiBza2VsZXRvbi1kZXNjcmlwdGlvblwiPjwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNrZWxldG9uIHNrZWxldG9uLWJhZGdlXCI+PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT4iXX0=
566
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwb2ludG1lbnQtYm9va2luZy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zaW1wby11aS9zcmMvbGliL3NlY3Rpb25zL2FwcG9pbnRtZW50LWZvcm0vYXBwb2ludG1lbnQtYm9va2luZy9hcHBvaW50bWVudC1ib29raW5nL2FwcG9pbnRtZW50LWJvb2tpbmcuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2ltcG8tdWkvc3JjL2xpYi9zZWN0aW9ucy9hcHBvaW50bWVudC1mb3JtL2FwcG9pbnRtZW50LWJvb2tpbmcvYXBwb2ludG1lbnQtYm9va2luZy9hcHBvaW50bWVudC1ib29raW5nLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakYsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzVELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbkUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFLN0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBR3pELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDhDQUE4QyxDQUFDO0FBQ3BGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDhDQUE4QyxDQUFDO0FBQ3BGLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGFBQWEsQ0FBQzs7Ozs7Ozs7Ozs7OztBQTJCN0MsTUFBTSxPQUFPLDJCQUEyQjtJQUN0QyxZQUNVLFdBQXdCLEVBQ3hCLGFBQTRCLEVBQ25CLE1BQWMsRUFDZCxjQUE4QixFQUM5Qix5QkFBb0QsRUFDcEQsY0FBcUMsRUFDekIsU0FBb0Q7UUFOekUsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDbkIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUM5Qiw4QkFBeUIsR0FBekIseUJBQXlCLENBQTJCO1FBQ3BELG1CQUFjLEdBQWQsY0FBYyxDQUF1QjtRQUN6QixjQUFTLEdBQVQsU0FBUyxDQUEyQztRQTZDbkYsZ0JBQVcsR0FBVyxDQUFDLENBQUM7UUFTeEIsaUJBQVksR0FBRztZQUNiLGNBQWMsRUFBRSxLQUFLO1lBQ3JCLGVBQWUsRUFBRSxLQUFLO1lBQ3RCLFlBQVksRUFBRSxLQUFLO1NBQ3BCLENBQUE7UUFDRCxtQkFBYyxHQUFZLEtBQUssQ0FBQztRQUNoQyxpQkFBWSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDbEssZUFBVSxHQUFRLFlBQVksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDN0osaUJBQVksR0FBWSxLQUFLLENBQUM7UUFDOUIsZ0JBQVcsR0FBVyxFQUFFLENBQUM7UUFDekIsYUFBUSxHQUFXLEVBQUUsQ0FBQztRQUN0QiwyQkFBc0IsR0FBWSxLQUFLLENBQUM7UUFDeEMsdUJBQWtCLEdBQVksS0FBSyxDQUFDO1FBRXBDLGlCQUFZLEdBQWdCLGFBQWEsQ0FBQztRQUMxQyxlQUFVLEdBQVksS0FBSyxDQUFDO1FBRTVCLDRGQUE0RjtRQUM1Rix3RkFBd0Y7UUFDeEYsaUZBQWlGO1FBQ2pGLGlCQUFZLEdBQVUsRUFBRSxDQUFDO1FBQ3pCLGtCQUFhLEdBQW1CLEVBQUUsQ0FBQztRQUNuQyxrQkFBYSxHQUFZLEtBQUssQ0FBQztRQUUvQix5RkFBeUY7UUFDekYsNkVBQTZFO1FBQzdFLHFCQUFnQixHQUFVLEVBQUUsQ0FBQztRQUc3QixxQkFBZ0IsR0FBUSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsYUFBYSxFQUFFLEVBQUUsRUFBRSxZQUFZLEVBQUUsRUFBRSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUN0SSxpQkFBWSxHQUFXLEVBQUUsQ0FBQztRQUMxQixXQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ2hCLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLGlCQUFZLEdBQWdCLElBQUksQ0FBQztRQUNqQyxvQkFBZSxHQUFHLEVBQUUsQ0FBQztRQUVyQixpQkFBWSxHQUFRLElBQUksQ0FBQztRQUV6QixlQUFVLEdBQUcsQ0FBQyxDQUFjLEVBQVcsRUFBRTtZQUN2QyxNQUFNLElBQUksR0FBRyxDQUFDLENBQUMsSUFBSSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUM7WUFDL0IsTUFBTSxLQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUN6QixLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzNCLE9BQU8sSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMzQyxDQUFDLENBQUE7UUEySUQsZ0JBQVcsR0FBVSxFQUFFLENBQUM7UUEwQnhCLGlCQUFZLEdBQVUsRUFBRSxDQUFDO1FBb0R6QixxQkFBZ0IsR0FBVyxFQUFFLENBQUM7UUFVOUIsY0FBUyxHQUFVLEVBQUUsQ0FBQztRQTRIdEIsV0FBTSxHQUFZLEtBQUssQ0FBQztRQUN4QixpQkFBWSxHQUFZLEtBQUssQ0FBQztRQUM5Qix1QkFBa0IsR0FBWSxLQUFLLENBQUM7UUFvQnBDLHVCQUFrQixHQUFRO1lBQ3hCLGNBQWMsRUFBRTtnQkFDZCxJQUFJLEVBQUUsRUFBRTtnQkFDUixXQUFXLEVBQUUsRUFBRTtnQkFDZixLQUFLLEVBQUUsRUFBRTthQUNWO1NBQ0YsQ0FBQTtRQUNELGNBQVMsR0FBWSxLQUFLLENBQUM7SUExZDNCLENBQUM7SUFZRCxRQUFRO1FBQ04saUZBQWlGO1FBQ2pGLHNGQUFzRjtRQUN0RiwwRkFBMEY7UUFDMUYsMkZBQTJGO1FBQzNGLDRGQUE0RjtRQUM1Rix3RkFBd0Y7UUFDeEYsZ0VBQWdFO1FBQ2hFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO1lBQ2pELElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNuRixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNyQixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsa0JBQWtCLENBQUMsY0FBYyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7WUFDN0UsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDO1FBQzdGLENBQUM7UUFDRCwwRkFBMEY7UUFDMUYsMkZBQTJGO1FBQzNGLCtFQUErRTtRQUMvRSxNQUFNLFVBQVUsR0FBSSxJQUFJLENBQUMsSUFBSSxFQUFFLE9BQWUsRUFBRSxJQUFJLENBQUM7UUFDckQsSUFBSSxVQUFVLEtBQUssYUFBYSxJQUFJLFVBQVUsS0FBSyxZQUFZLElBQUksVUFBVSxLQUFLLFlBQVksRUFBRSxDQUFDO1lBQy9GLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDOUIsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsV0FBVyxHQUFHLGVBQWUsQ0FBQztZQUNuQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUN2QixDQUFDO0lBQ0gsQ0FBQztJQUdELGFBQWE7UUFDWCxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUM7SUFDdkMsQ0FBQztJQUVELG1CQUFtQjtRQUNqQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztJQUM1QixDQUFDO0lBNkNELGNBQWMsQ0FBQyxLQUFhO1FBQzFCLElBQUksS0FBSztZQUFFLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUNuQyxJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQztJQUN6QyxDQUFDO0lBRUQsY0FBYyxDQUFDLElBQVM7UUFDdEIsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7UUFDMUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDekIsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1FBQzFCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBQ08sVUFBVSxDQUFDLENBQU87UUFDeEIsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDaEQsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3JELE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM3QixPQUFPLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQztJQUMvQixDQUFDO0lBQ08sU0FBUyxDQUFDLENBQWM7UUFDOUIsTUFBTSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksSUFBSSxFQUFFLENBQUM7UUFDN0IsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2hDLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN4RCxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNuRCxPQUFPLEdBQUcsSUFBSSxJQUFJLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixDQUFDO0lBQzdDLENBQUM7SUFFRCxVQUFVLENBQUMsSUFBaUI7UUFDMUIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDekIsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7UUFDOUIsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFRCxLQUFLLENBQUMsc0JBQXNCO1FBQzFCLElBQUksSUFBSSxDQUFDLFlBQVksS0FBSyxhQUFhLEVBQUUsQ0FBQztZQUN4QyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO1lBQzNCLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGdCQUFnQixHQUFHLE1BQU0sSUFBSSxDQUFDLHlCQUF5QixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBK0IsQ0FBQyxDQUFDO0lBQzlHLENBQUM7SUFFRCxhQUFhLENBQUMsT0FBWTtRQUN4QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsS0FBSyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDdkYsSUFBSSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDakMsT0FBTyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDM0IsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNoQyxPQUFPLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUMxQixDQUFDO1FBQ0QsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDdkYsQ0FBQztJQUNELGNBQWMsQ0FBQyxRQUFhO1FBQzFCLFFBQVEsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ3pCLElBQUksSUFBSSxDQUFDLGdCQUFnQixJQUFJLFFBQVEsQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3JFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ3pDLENBQUM7UUFDRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUN6QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsUUFBUSxDQUFDO0lBQ25DLENBQUM7SUFFRCxRQUFRO1FBQ04sSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLGdCQUFnQixFQUFFLENBQUM7WUFDMUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO1lBQ3hDLElBQUksSUFBSSxDQUFDLFlBQVksS0FBSyxhQUFhLEVBQUUsQ0FBQztnQkFDeEMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3pCLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUMzQixDQUFDO1FBQ0gsQ0FBQzthQUNJLElBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxpQkFBaUIsRUFBRSxDQUFDO1lBQ2hELElBQUksQ0FBQyxZQUFZLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztZQUN6QyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUMzQixDQUFDO2FBQ0ksSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLGNBQWMsRUFBRSxDQUFDO1lBQzdDLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztZQUN0QyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUMzQixDQUFDO2FBQ0ksSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLGVBQWUsRUFBRSxDQUFDO1lBQzlDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUMsTUFBTSxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUE7WUFDbE0sSUFBSSxDQUFDLFdBQVcsR0FBRyxnQkFBZ0IsQ0FBQztZQUNwQyxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQTtRQUN6QixDQUFDO2FBQ0ksSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLGdCQUFnQixFQUFFLENBQUM7WUFDL0MsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxZQUFZLENBQUM7WUFDaEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUE7UUFDekIsQ0FBQztJQUNILENBQUM7SUFDRCxZQUFZO1FBQ1YsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7UUFDcEIsSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLGVBQWU7WUFBRSxPQUFPO1FBQ2pELElBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxXQUFXLEdBQUcsZUFBZSxDQUFDO2dCQUNuQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztZQUN2QixDQUFDO1lBQ0QsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUN6QixJQUFJLElBQUksQ0FBQyxXQUFXLEtBQUssaUJBQWlCLEVBQUUsQ0FBQztZQUMzQyxJQUFJLENBQUMsV0FBVyxHQUFHLGdCQUFnQixDQUFDO1lBQ3BDLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1lBQ3hCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDL0IsQ0FBQzthQUNJLElBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxjQUFjLEVBQUUsQ0FBQztZQUM3QyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQWUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLGVBQWUsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckgsSUFBSSxJQUFJLENBQUMsWUFBWSxLQUFLLGFBQWEsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUM3RSxJQUFJLENBQUMsV0FBVyxHQUFHLGlCQUFpQixDQUFDO2dCQUNyQyxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztZQUMxQixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLFdBQVcsR0FBRyxnQkFBZ0IsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUM7WUFDMUIsQ0FBQztRQUNILENBQUM7YUFDSSxJQUFJLElBQUksQ0FBQyxXQUFXLEtBQUssZUFBZSxFQUFFLENBQUM7WUFDOUMsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFlLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDcEcsSUFBSSxjQUFjLEVBQUUsQ0FBQztnQkFDbkIsSUFBSSxDQUFDLFdBQVcsR0FBRyxjQUFjLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1lBQzFCLENBQUM7aUJBQ0ksSUFBSSxJQUFJLENBQUMsWUFBWSxLQUFLLGFBQWEsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUNsRixJQUFJLENBQUMsV0FBVyxHQUFHLGlCQUFpQixDQUFDO2dCQUNyQyxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztZQUMxQixDQUFDO2lCQUNJLENBQUM7Z0JBQ0osSUFBSSxDQUFDLFdBQVcsR0FBRyxnQkFBZ0IsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUM7WUFDMUIsQ0FBQztRQUNILENBQUM7YUFDSSxJQUFJLElBQUksQ0FBQyxXQUFXLEtBQUssZ0JBQWdCLEVBQUUsQ0FBQztZQUMvQyxJQUFJLENBQUMsV0FBVyxHQUFHLGVBQWUsQ0FBQztZQUNuQyxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztRQUMxQixDQUFDO2FBQ0ksSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLFlBQVksRUFBRSxDQUFDO1lBQzNDLElBQUksQ0FBQyxXQUFXLEdBQUcsZ0JBQWdCLENBQUM7WUFDcEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUM7SUFFRCxjQUFjO1FBQ1osSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUE7UUFDMUIsSUFBSSxjQUFjLEdBQVE7WUFDeEIsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLElBQUksRUFBRTtZQUNqQyxNQUFNLEVBQUUsQ0FBQztZQUNULElBQUksRUFBRSxHQUFHO1NBQ1YsQ0FBQTtRQUNELElBQUksQ0FBQyxXQUFXLENBQUMsd0JBQXdCLENBQUMsY0FBYyxDQUFDLENBQUMsU0FBUyxDQUNqRSxDQUFDLEdBQVEsRUFBRSxFQUFFO1lBQ1gsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7WUFDNUIsSUFBSSxRQUFRLEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQVksRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsQ0FBQztZQUNyRixJQUFJLElBQUksQ0FBQyxZQUFZLEtBQUssWUFBWTtnQkFBRSxRQUFRLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLHdCQUF3QixDQUFDLENBQUM7WUFDM0csSUFBSSxJQUFJLENBQUMsWUFBWSxLQUFLLFlBQVk7Z0JBQUUsUUFBUSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUNsRyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBWSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxDQUFDO1lBQzdELElBQUksQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDO1lBQzVCLElBQUksQ0FBQyxZQUFZLEdBQUcsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxXQUFXLEdBQUcsZ0JBQWdCLENBQUM7WUFDcEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUM7WUFDeEIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUN2RCxDQUFDLEVBQ0QsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNSLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO1FBQzlCLENBQUMsQ0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELGVBQWU7UUFDYixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztRQUNuQixJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUN2QixJQUFJLE9BQU8sR0FBRyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxJQUFJLEVBQUUsRUFBRSxDQUFBO1FBQ25ELElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFNBQVMsQ0FDOUMsQ0FBQyxHQUFRLEVBQUUsRUFBRTtZQUNYLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUM3QixJQUFJLFNBQVMsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFVLEVBQUUsRUFBRSxHQUFHLE9BQU8sS0FBSyxDQUFDLE1BQU0sS0FBSyxRQUFRLENBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDM0YsbUZBQW1GO2dCQUNuRix5REFBeUQ7Z0JBQ3pELFNBQVMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBYSxFQUFFLEVBQUUsQ0FDN0MsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUN2RSxDQUFDO2dCQUNGLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDLENBQUM7Z0JBQ2xELElBQUksQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDO2dCQUM5QixJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUNuQyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLEVBQUUsMEZBQTBGLEVBQUUsQ0FBQyxDQUFDO29CQUMzSyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztvQkFDcEIsT0FBTztnQkFDVCxDQUFDO2dCQUNELElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7b0JBQ25DLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUM3QyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztvQkFDcEIsSUFBSSxDQUFDLFlBQVksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO29CQUMxQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztnQkFDM0IsQ0FBQztxQkFDSSxDQUFDO29CQUNKLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO29CQUNwQixJQUFJLENBQUMsV0FBVyxHQUFHLGlCQUFpQixDQUFDO29CQUNyQyxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztvQkFDeEIsSUFBSSxDQUFDLFlBQVksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO2dCQUMzQyxDQUFDO1lBQ0gsQ0FBQztpQkFDSSxDQUFDO2dCQUNKLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSx3Q0FBd0MsRUFBRSxDQUFDLENBQUM7Z0JBQ3pILElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1lBQ3RCLENBQUM7UUFDSCxDQUFDLEVBQ0QsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNSLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLENBQUMsQ0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELGlCQUFpQjtRQUNmLElBQUksQ0FBQyxXQUFXLEdBQUcsZUFBZSxDQUFDO1FBQ25DLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1FBQzFCLElBQUksQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFHRCxJQUFJLGFBQWE7UUFDZixJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7WUFDbEMsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQ3hCLENBQUM7UUFDRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDekQsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUNuQyxLQUFLLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FDaEQsQ0FBQztJQUNKLENBQUM7SUFHRCxXQUFXO1FBQ1QsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNuQywwRkFBMEY7WUFDMUYseUZBQXlGO1lBQ3pGLDhFQUE4RTtZQUM5RSxJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLG9CQUFvQixFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUM1RSxJQUFJLENBQUMsNkJBQTZCLEVBQUUsQ0FBQztZQUNyQyxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1FBQzFCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO1FBQzNCLE1BQU0sT0FBTyxHQUFRO1lBQ25CLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVTtZQUMzQixJQUFJLEVBQUUsSUFBSSxDQUFDLFlBQVk7WUFDdkIsT0FBTyxFQUFFLElBQUksQ0FBQyxZQUFZLEtBQUssYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTO1lBQ3BGLFdBQVcsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUM7WUFDOUMsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1NBQzlFLENBQUM7UUFDRixJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRTtZQUMzRCxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztZQUMzQixJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztZQUM1QixJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDbkQsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO2dCQUN2QixvQkFBb0IsRUFBRSxJQUFJLENBQUMsb0JBQW9CO2dCQUMvQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87Z0JBQ3JCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztnQkFDekIsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLGtCQUFrQjtnQkFDM0MsS0FBSyxFQUFFLEVBQUU7YUFDVixDQUFDLENBQUMsQ0FBQztZQUNKLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3BHLElBQUksY0FBYyxFQUFFLENBQUM7Z0JBQ25CLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7Z0JBQzNCLElBQUksQ0FBQyxXQUFXLEdBQUcsY0FBYyxDQUFDO2dCQUNsQyxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztZQUMxQixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDM0IsQ0FBQztRQUNILENBQUMsRUFBRSxDQUFDLEtBQVUsRUFBRSxFQUFFO1lBQ2hCLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO1lBQzNCLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO1lBQzVCLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsOEJBQThCLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsT0FBTyxJQUFJLGtCQUFrQixFQUFFLENBQUMsQ0FBQztRQUM5SSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCw2QkFBNkI7UUFDM0IsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7UUFDbkIsTUFBTSxPQUFPLEdBQUcsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsSUFBSSxFQUFFLEVBQUUsQ0FBQztRQUMvRyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRTtZQUMzRCxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztZQUNwQixJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQVUsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sS0FBSyxJQUFJLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ25HLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBVSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxDQUFDO1lBQy9ELElBQUksQ0FBQyxXQUFXLEdBQUcsY0FBYyxDQUFDO1lBQ2xDLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1FBQzFCLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRCw2QkFBNkIsQ0FBQyxLQUFVO1FBQ3RDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxDQUFDO1FBQ3ZELEtBQUssQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDdEQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDO1FBQzFELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO0lBQzNCLENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxJQUFrQixFQUFFLEtBQVU7UUFDL0MsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFlLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7SUFDeEcsQ0FBQztJQUVELGlCQUFpQjtRQUNmLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO1FBQzNCLElBQUksQ0FBQyxXQUFXLEdBQUcsZUFBZSxDQUFDO1FBQ25DLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1FBQ3hCLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBa0IsRUFBRSxFQUFFO1lBQ2hELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQztZQUNyRCxNQUFNLE9BQU8sR0FBUTtnQkFDbkIsT0FBTyxFQUFFLElBQUksQ0FBQyxZQUFZLEtBQUssYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTO2dCQUNwRixVQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQy9DLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVTtnQkFDM0IsV0FBVyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQztnQkFDOUMsT0FBTztnQkFDUCxJQUFJLEVBQUUsSUFBSSxDQUFDLFlBQVk7YUFDeEIsQ0FBQztZQUNGLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQVEsRUFBRSxFQUFFO2dCQUMvRCxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDN0UsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7Z0JBQzFCLE9BQU8sRUFBRSxDQUFDO2dCQUNWLElBQUksT0FBTyxJQUFJLENBQUM7b0JBQUUsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7WUFDaEQsQ0FBQyxFQUFFLEdBQUcsRUFBRTtnQkFDTixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztnQkFDMUIsT0FBTyxFQUFFLENBQUM7Z0JBQ1YsSUFBSSxPQUFPLElBQUksQ0FBQztvQkFBRSxJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztZQUNoRCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGlCQUFpQixDQUFDLElBQWtCLEVBQUUsSUFBUztRQUM3QyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUNyQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUN6QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3RGLENBQUM7SUFFRCxlQUFlLENBQUMsSUFBWTtRQUMxQixNQUFNLENBQUMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0MsTUFBTSxRQUFRLEdBQUcsV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsZUFBZTtRQUMzRCxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXRELElBQUksUUFBUSxLQUFLLElBQUksSUFBSSxLQUFLLEdBQUcsRUFBRSxFQUFFLENBQUM7WUFDcEMsS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUNkLENBQUM7UUFDRCxJQUFJLFFBQVEsS0FBSyxJQUFJLElBQUksS0FBSyxLQUFLLEVBQUUsRUFBRSxDQUFDO1lBQ3RDLEtBQUssR0FBRyxDQUFDLENBQUM7UUFDWixDQUFDO1FBRUQsTUFBTSxFQUFFLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDN0MsTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDL0MsT0FBTyxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksUUFBUSxFQUFFLENBQUM7SUFDbkMsQ0FBQztJQUlELG1CQUFtQjtRQUNqQixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsY0FBYyxDQUFDLEtBQUs7WUFDL0QsMENBQTBDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFaEcsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFM0gsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsY0FBYyxDQUFDLElBQUk7WUFDN0MsWUFBWTtZQUNaLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLE1BQU0sS0FBSyxFQUFFLEVBQUUsQ0FBQztZQUNuRSxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUNkLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztZQUM3RCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7WUFDM0IsQ0FBQztRQUNILENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7UUFDNUIsQ0FBQztJQUNILENBQUM7SUFXRCxjQUFjO1FBQ1osd0ZBQXdGO1FBQ3hGLHdGQUF3RjtRQUN4RiwwRkFBMEY7UUFDMUYsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDakQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLFdBQVcsRUFBRSxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNuRixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3pCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBZSxFQUFFLEVBQUU7WUFDdkQsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLFlBQVksQ0FBQztZQUM1QixPQUFPO2dCQUNMLFVBQVUsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDNUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLGVBQWU7Z0JBQ3ZDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7YUFDM0UsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxXQUFXLEdBQVE7WUFDdkIsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQzNCLElBQUksRUFBRSxJQUFJLENBQUMsWUFBWTtZQUN2QixPQUFPLEVBQUUsSUFBSSxDQUFDLFlBQVksS0FBSyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVM7WUFDcEYsV0FBVyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQztZQUM5QyxjQUFjLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGNBQWM7WUFDdEQsS0FBSztZQUNMLFlBQVksRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3BHLGNBQWMsRUFBRSxJQUFJLENBQUMsWUFBWSxLQUFLLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTO1NBQy9ILENBQUM7UUFFRixJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxLQUFVLEVBQUUsRUFBRTtZQUNqRSxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztZQUMxQixJQUFJLElBQUksQ0FBQyxZQUFZLEtBQUssYUFBYSxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzVFLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFlBQStCLENBQUMsQ0FBQztZQUM3RSxDQUFDO1lBQ0QsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLE1BQU0sSUFBSSxLQUFLLENBQUMsdUJBQXVCLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2pFLGlFQUFpRTtnQkFDakUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsS0FBVSxFQUFFLEVBQUU7b0JBQzVFLFlBQVksQ0FBQyxPQUFPLENBQUMsc0JBQXNCLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO29CQUM5RCxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztvQkFDMUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsY0FBYyxFQUFFLEtBQUssQ0FBQyxjQUFjLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQzVGLENBQUMsRUFBRSxDQUFDLEtBQVUsRUFBRSxFQUFFO29CQUNoQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztvQkFDMUIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUMxRyxDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztnQkFDdEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxnQkFBZ0IsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7Z0JBQ3RCLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1lBQzVCLENBQUM7UUFDSCxDQUFDLEVBQUUsQ0FBQyxLQUFVLEVBQUUsRUFBRTtZQUNoQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztZQUMxQixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztZQUN2QixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDMUcsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksWUFBWSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUN6RCxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLHVDQUF1QyxDQUFDLENBQUMsQ0FBQTtRQUNqRSxDQUFDO2FBQ0ksQ0FBQztZQUNKLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTtRQUM1QixDQUFDO0lBQ0gsQ0FBQzsrR0F2aUJVLDJCQUEyQjttR0FBM0IsMkJBQTJCLHlXQUozQixDQUFDLGNBQWMsQ0FBQywwQkN6QzdCLGt5akNBdWhCQSwweHRCRC9lZ0MsWUFBWSw0c0JBQUUsT0FBTywwSUFBRSxrQkFBa0IsOEJBQUUsbUJBQW1CLDBiQUFFLFdBQVcsMnBDQUFFLG1CQUFtQiw4QkFBRSxjQUFjLCtCQUFFLG9CQUFvQiwrREFBRSxvQkFBb0IsOERBQUUsV0FBVzs7NEZBSzVMLDJCQUEyQjtrQkFSdkMsU0FBUzsrQkFDRSwyQkFBMkIsY0FDekIsSUFBSSxXQUNQLENBQUMsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxtQkFBbUIsRUFBRSxXQUFXLEVBQUUsbUJBQW1CLEVBQUUsY0FBYyxFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUFFLFdBQVcsQ0FBQyxhQUM3TCxDQUFDLGNBQWMsQ0FBQzs7MEJBWXhCLFFBQVE7eUNBSUYsSUFBSTtzQkFBWixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFFRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUVHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBbUNOLGFBQWE7c0JBRFosWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFLMUMsbUJBQW1CO3NCQURsQixZQUFZO3VCQUFDLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT25Jbml0LCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBDZGtEcmFnUGxhY2Vob2xkZXIgfSBmcm9tIFwiQGFuZ3VsYXIvY2RrL2RyYWctZHJvcFwiO1xyXG5pbXBvcnQgeyBNYXRJY29uIH0gZnJvbSBcIkBhbmd1bGFyL21hdGVyaWFsL2ljb25cIjtcclxuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IE1hdEZvcm1GaWVsZE1vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkXCI7XHJcbmltcG9ydCB7IE1hdERhdGVwaWNrZXJNb2R1bGUgfSBmcm9tIFwiQGFuZ3VsYXIvbWF0ZXJpYWwvZGF0ZXBpY2tlclwiO1xyXG5pbXBvcnQgeyBNYXROYXRpdmVEYXRlTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY29yZSc7XHJcbmltcG9ydCB7IE1hdERpYWxvZ1JlZiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XHJcbmltcG9ydCB7IFJlc3RTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vc2VydmljZXMvcmVzdC5zZXJ2aWNlJztcclxuaW1wb3J0IHsgRXZlbnRzU2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL2V2ZW50cy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcclxuaW1wb3J0IHsgTWF0SW5wdXRNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XHJcbmltcG9ydCB7IEJhbm5lckNvbnRlbnRNb2RlbCwgQmFubmVyU2VjdGlvbk1vZGVsIH0gZnJvbSAnLi4vLi4vYXBwb2ludG1lbnQtZm9ybS5tb2RlbCc7XHJcbmltcG9ydCB7IEJhY2tncm91bmRNb2RlbCwgQmFubmVyU3R5bGVzTW9kZWwgfSBmcm9tICcuLi8uLi8uLi8uLi9zdHlsZXMvc3R5bGUubW9kZWwnO1xyXG5pbXBvcnQgeyBMZXR0ZXJzT25seURpcmVjdGl2ZSB9IGZyb20gJy4uLy4uLy4uLy4uL2RpcmVjdGl2ZS9sZXR0ZXJzLW9ubHkuZGlyZWN0aXZlJztcclxuaW1wb3J0IHsgTnVtYmVyc09ubHlEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi8uLi8uLi9kaXJlY3RpdmUvbnVtYmVycy1vbmx5LmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IFRvYXN0TW9kdWxlIH0gZnJvbSBcInByaW1lbmcvdG9hc3RcIjtcclxuaW1wb3J0IHsgTWVzc2FnZVNlcnZpY2UgfSBmcm9tICdwcmltZW5nL2FwaSc7XHJcbmltcG9ydCB7IEJvb2tpbmdQcm9kdWN0Q2FydFNlcnZpY2UsIEJvb2tpbmdDYXJ0TW9kZSB9IGZyb20gJy4uLy4uLy4uLy4uL3NlcnZpY2VzL2Jvb2tpbmctcHJvZHVjdC1jYXJ0LnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBTdG9yYWdlU2VydmljZVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi8uLi9zZXJ2aWNlcy9zdG9yYWdlLnNlcnZpY2UnO1xyXG5cclxudHlwZSBCb29raW5nTW9kZSA9ICdTVE9SRV9WSVNJVCcgfCAnSE9NRV9WSVNJVCcgfCAnVklERU9fQ0FMTCc7XHJcblxyXG5pbnRlcmZhY2UgUmVzb2x2ZWRMaW5lIHtcclxuICBzZXJ2aWNlczogeyBpZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcgfVtdO1xyXG4gIHRvdGFsRHVyYXRpb25NaW51dGVzOiBudW1iZXI7XHJcbiAgc3RhZmZJZD86IHN0cmluZztcclxuICBzdGFmZk5hbWU/OiBzdHJpbmc7XHJcbiAgY2FuZGlkYXRlU3RhZmZQb29sPzogeyBpZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcgfVtdO1xyXG4gIHNlbGVjdGVkU3RhZmZJZD86IHN0cmluZztcclxuICBzZWxlY3RlZFN0YWZmTmFtZT86IHN0cmluZztcclxuICBzbG90czogYW55W107XHJcbiAgc2VsZWN0ZWRTbG90PzogYW55O1xyXG4gIHNsb3RzTG9hZGluZz86IGJvb2xlYW47XHJcbn1cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnc2ltcG8tYXBwb2ludG1lbnQtYm9va2luZycsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbQ2RrRHJhZ1BsYWNlaG9sZGVyLCBDb21tb25Nb2R1bGUsIE1hdEljb24sIE1hdEZvcm1GaWVsZE1vZHVsZSwgTWF0RGF0ZXBpY2tlck1vZHVsZSwgRm9ybXNNb2R1bGUsIE1hdE5hdGl2ZURhdGVNb2R1bGUsIE1hdElucHV0TW9kdWxlLCBMZXR0ZXJzT25seURpcmVjdGl2ZSwgTnVtYmVyc09ubHlEaXJlY3RpdmUsIFRvYXN0TW9kdWxlXSxcclxuICBwcm92aWRlcnM6IFtNZXNzYWdlU2VydmljZV0sXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2FwcG9pbnRtZW50LWJvb2tpbmcuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsOiAnLi9hcHBvaW50bWVudC1ib29raW5nLmNvbXBvbmVudC5jc3MnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBBcHBvaW50bWVudEJvb2tpbmdDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSByZXN0U2VydmljZTogUmVzdFNlcnZpY2UsXHJcbiAgICBwcml2YXRlIF9ldmVudFNlcnZpY2U6IEV2ZW50c1NlcnZpY2UsXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJvdXRlcjogUm91dGVyLFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBtZXNzYWdlU2VydmljZTogTWVzc2FnZVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IGJvb2tpbmdQcm9kdWN0Q2FydFNlcnZpY2U6IEJvb2tpbmdQcm9kdWN0Q2FydFNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN0b3JhZ2VTZXJ2aWNlOiBTdG9yYWdlU2VydmljZVNlcnZpY2UsXHJcbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIHJlYWRvbmx5IGRpYWxvZ1JlZjogTWF0RGlhbG9nUmVmPEFwcG9pbnRtZW50Qm9va2luZ0NvbXBvbmVudD5cclxuICApIHtcclxuXHJcbiAgfVxyXG4gIEBJbnB1dCgpIGRhdGE/OiBCYW5uZXJTZWN0aW9uTW9kZWw7XHJcbiAgQElucHV0KCkgaW5kZXg/OiBudW1iZXI7XHJcbiAgY29udGVudD86IEJhbm5lckNvbnRlbnRNb2RlbDtcclxuICBASW5wdXQoKSBlZGl0PzogYm9vbGVhbjtcclxuICBASW5wdXQoKSBkZWxldGU/OiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIGN1c3RvbUNsYXNzPzogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIG5leHRDb21wb25lbnRDb2xvcj86IEJhY2tncm91bmRNb2RlbDtcclxuICAvKiogTGV0cyBhIGxhdW5jaGluZyBkaWFsb2cgKGUuZy4gdGhlIHZpZGVvLWNhbGwgcHJvZHVjdCBwaWNrZXIpIGNhcnJ5IG92ZXIgbmFtZS9waG9uZSBhbHJlYWR5IGNvbGxlY3RlZCwgc28gdGhlIGN1c3RvbWVyIGlzbid0IGFza2VkIHR3aWNlLiAqL1xyXG4gIEBJbnB1dCgpIHByZWZpbGxDb250YWN0PzogeyBuYW1lPzogc3RyaW5nLCBwaG9uZU51bWJlcj86IHN0cmluZyB9O1xyXG4gIHN0eWxlcz86IEJhbm5lclN0eWxlc01vZGVsO1xyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIC8vIExvZ2luIGlzIHJlcXVpcmVkIGJlZm9yZSBlbnRlcmluZyB0aGUgd2l6YXJkIGF0IGFsbCAobm90IG1pZC1mbG93LCBsaWtlIGNhcnQnc1xyXG4gICAgLy8gY2hlY2tvdXQtY29tbWl0IGdhdGUpIC0gdGhlIHdpemFyZCdzIHNlbGVjdGlvbnMgbGl2ZSBvbmx5IGluIGNvbXBvbmVudCBtZW1vcnksIHNvIGFcclxuICAgIC8vIHJlZGlyZWN0LWFuZC1iYWNrIHBhcnR3YXkgdGhyb3VnaCB3b3VsZCBzaWxlbnRseSB3aXBlIHdoYXRldmVyIHRoZSBjdXN0b21lciBoYWQgYWxyZWFkeVxyXG4gICAgLy8gcGlja2VkLiBDaGVja2luZyBoZXJlLCBiZWZvcmUgYW55dGhpbmcgaXMgcGlja2VkLCBtZWFucyB0aGVyZSdzIG5vdGhpbmcgdG8gbG9zZS4gU2tpcHBlZFxyXG4gICAgLy8gaW4gYnVpbGRlciBlZGl0L3ByZXZpZXcgbW9kZSAoYGVkaXRgIGlzIHRydWUgd2hlbiBhIGJ1c2luZXNzIG93bmVyIGlzIGVkaXRpbmcgdGhlaXIgc2l0ZSxcclxuICAgIC8vIG5vdCBhIHJlYWwgY3VzdG9tZXIgc2Vzc2lvbikgLSB0aGUgc2FtZSBndWFyZCBwYXR0ZXJuIHVzZWQgZWxzZXdoZXJlIGluIHRoaXMgY29kZWJhc2VcclxuICAgIC8vIChlLmcuIEF1dGhlbnRpY2F0aW9uUmVxdWlyZWRDb21wb25lbnQncyBvd24gc3VibWl0IGhhbmRsZXJzKS5cclxuICAgIGlmICghdGhpcy5lZGl0ICYmICF0aGlzLnN0b3JhZ2VTZXJ2aWNlLmdldFVzZXIoKSkge1xyXG4gICAgICB0aGlzLmRpYWxvZ1JlZj8uY2xvc2UoKTtcclxuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycvbG9naW4nXSwgeyBxdWVyeVBhcmFtczogeyByZWRpcmVjdFRvOiB0aGlzLnJvdXRlci51cmwgfSB9KTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5nZXRTY3JlZW5TaXplKCk7XHJcbiAgICBpZiAodGhpcy5wcmVmaWxsQ29udGFjdCkge1xyXG4gICAgICB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5uYW1lID0gdGhpcy5wcmVmaWxsQ29udGFjdC5uYW1lID8/ICcnO1xyXG4gICAgICB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5waG9uZU51bWJlciA9IHRoaXMucHJlZmlsbENvbnRhY3QucGhvbmVOdW1iZXIgPz8gJyc7XHJcbiAgICB9XHJcbiAgICAvLyBBIGJ1c2luZXNzIGNhbiBwaW4gdGhpcyBzZWN0aW9uIHRvIG9uZSBtb2RlIHZpYSBzYXZlZCBjb250ZW50IGNvbmZpZy4gVGhlcmUncyBubyBlZGl0b3JcclxuICAgIC8vIFVJIHlldCB0byBzZXQgdGhpcyBmaWVsZCAodGhlIHNlY3Rpb24gY29udGVudC1lZGl0b3IgZG9lc24ndCBoYXZlIGEgbW9kZSBwaWNrZXIgYnVpbHQpIC1cclxuICAgIC8vIHJlYWRpbmcgaXQgaGVyZSBqdXN0IGtlZXBzIHRoZSBjb21wb25lbnQgZm9yd2FyZC1jb21wYXRpYmxlIG9uY2Ugb25lIGV4aXN0cy5cclxuICAgIGNvbnN0IHBpbm5lZE1vZGUgPSAodGhpcy5kYXRhPy5jb250ZW50IGFzIGFueSk/Lm1vZGU7XHJcbiAgICBpZiAocGlubmVkTW9kZSA9PT0gJ1NUT1JFX1ZJU0lUJyB8fCBwaW5uZWRNb2RlID09PSAnSE9NRV9WSVNJVCcgfHwgcGlubmVkTW9kZSA9PT0gJ1ZJREVPX0NBTEwnKSB7XHJcbiAgICAgIHRoaXMubW9kZVBpbm5lZCA9IHRydWU7XHJcbiAgICAgIHRoaXMuc2VsZWN0TW9kZShwaW5uZWRNb2RlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnbW9kZVNlbGVjdGlvbic7XHJcbiAgICAgIHRoaXMuYmFyV2lkdGggPSAnMTAnO1xyXG4gICAgfVxyXG4gIH1cclxuICBzY3JlZW5XaWR0aDogbnVtYmVyID0gMDtcclxuICBASG9zdExpc3RlbmVyKFwid2luZG93OiByZXNpemVcIiwgW1wiJGV2ZW50XCJdKVxyXG4gIGdldFNjcmVlblNpemUoKSB7XHJcbiAgICB0aGlzLnNjcmVlbldpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XHJcbiAgfVxyXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJylcclxuICBjbG9zZU9uT3V0c2lkZUNsaWNrKCkge1xyXG4gICAgdGhpcy5zaG93Q2FsZW5kYXIgPSBmYWxzZTtcclxuICB9XHJcbiAgYWNjZXNzZWRUYWJzID0ge1xyXG4gICAgc2VydmljZUxpc3Rpbmc6IGZhbHNlLFxyXG4gICAgbG9jYXRpb25MaXN0aW5nOiBmYWxzZSxcclxuICAgIHN0YWZmTGlzdGluZzogZmFsc2VcclxuICB9XHJcbiAgc2tlbGV0b25Mb2FkZXI6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBidXNpbmVzc05hbWUgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYnVzaW5lc3NOYW1lJykgPyBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYnVzaW5lc3NOYW1lJykgOiAobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2JOYW1lJykgPyBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYk5hbWUnKSA6ICcnKTtcclxuICBidXNpbmVzc0lkOiBhbnkgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYnVzaW5lc3NJZCcpID8gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2J1c2luZXNzSWQnKSA6IChsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYklkJykgPyBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnYklkJykgOiAnJyk7XHJcbiAgYWN0aXZlQnV0dG9uOiBib29sZWFuID0gZmFsc2U7XHJcbiAgc2VsZWN0ZWRUYWI6IHN0cmluZyA9ICcnO1xyXG4gIGJhcldpZHRoOiBzdHJpbmcgPSAnJztcclxuICBzaG93Q2FuY2VsbGF0aW9uUG9saWN5OiBib29sZWFuID0gZmFsc2U7XHJcbiAgc2hvd1JlZHVjaW5nUG9saWN5OiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIHNlbGVjdGVkTW9kZTogQm9va2luZ01vZGUgPSAnU1RPUkVfVklTSVQnO1xyXG4gIG1vZGVQaW5uZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLy8gQ2FydCBvZiBzZXJ2aWNlcyBwaWNrZWQgaW4gc2VydmljZUxpc3RpbmcgLSBjbGlja2luZyBhIGNhcmQgdG9nZ2xlcyBtZW1iZXJzaGlwLiBUaGlzIGlzIGFcclxuICAvLyBzdHJhaWdodGZvcndhcmQgc3VwZXJzZXQgb2YgdGhlIG9sZCBzaW5nbGUtc2VsZWN0ZWRTZXJ2aWNlIGJlaGF2aW9yOiB3aXRoIGV4YWN0bHkgb25lXHJcbiAgLy8gc2VydmljZSBjbGlja2VkIGl0J3MgdGhlIGV4YWN0IHNhbWUgMi1jbGljayAoc2VsZWN0LCBjb250aW51ZSkgZmxvdyBhcyBiZWZvcmUuXHJcbiAgY2FydFNlcnZpY2VzOiBhbnlbXSA9IFtdO1xyXG4gIHJlc29sdmVkTGluZXM6IFJlc29sdmVkTGluZVtdID0gW107XHJcbiAgcmVzb2x2aW5nQ2FydDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAvLyBQcm9kdWN0cyBhZGRlZCB0byB0aGUgY2FydCBiZWZvcmUgZW50ZXJpbmcgdGhlIHdpemFyZCAoZS5nLiBcIlRyeSBhdCBIb21lXCIgb24gYSBwcm9kdWN0XHJcbiAgLy8gcGFnZSkgLSBsb2FkZWQgZnJvbSB0aGUgbG9jYWwgYm9va2luZy1wcm9kdWN0LWNhcnQgb25jZSB0aGUgbW9kZSBpcyBrbm93bi5cclxuICBwcm9kdWN0Q2FydEl0ZW1zOiBhbnlbXSA9IFtdO1xyXG5cclxuICBzZWxlY3RlZExvY2F0aW9uOiBhbnk7XHJcbiAgaG9tZVZpc2l0QWRkcmVzczogYW55ID0geyByZWNlaXZlck5hbWU6ICcnLCByZWNlaXZlclBob25lOiAnJywgYWRkcmVzc0xpbmUxOiAnJywgYWRkcmVzc0xpbmUyOiAnJywgY2l0eTogJycsIHN0YXRlOiAnJywgemlwQ29kZTogJycgfTtcclxuICBpbnN0cnVjdGlvbnM6IHN0cmluZyA9ICcnO1xyXG4gIE9iamVjdCA9IE9iamVjdDtcclxuICBzaG93Q2FsZW5kYXIgPSBmYWxzZTtcclxuICBzZWxlY3RlZERhdGU6IERhdGUgfCBudWxsID0gbnVsbDtcclxuICBzZWxlY3RlZERhdGVTdHIgPSAnJztcclxuXHJcbiAgYm9va2luZ0dyb3VwOiBhbnkgPSBudWxsO1xyXG5cclxuICBkYXRlRmlsdGVyID0gKGQ6IERhdGUgfCBudWxsKTogYm9vbGVhbiA9PiB7XHJcbiAgICBjb25zdCBkYXRlID0gKGQgfHwgbmV3IERhdGUoKSk7XHJcbiAgICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKCk7XHJcbiAgICB0b2RheS5zZXRIb3VycygwLCAwLCAwLCAwKTtcclxuICAgIHJldHVybiBkYXRlLmdldFRpbWUoKSA+PSB0b2RheS5nZXRUaW1lKCk7XHJcbiAgfVxyXG4gIHRvZ2dsZUNhbGVuZGFyKGV2ZW50PzogRXZlbnQpIHtcclxuICAgIGlmIChldmVudCkgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICB0aGlzLnNob3dDYWxlbmRhciA9ICF0aGlzLnNob3dDYWxlbmRhcjtcclxuICB9XHJcblxyXG4gIG9uRGF0ZVNlbGVjdGVkKGRhdGU6IGFueSkge1xyXG4gICAgdGhpcy5hY3RpdmVCdXR0b24gPSBmYWxzZTtcclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gZGF0ZTtcclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlU3RyID0gdGhpcy5mb3JtYXREYXRlKGRhdGUpO1xyXG4gICAgdGhpcy5zaG93Q2FsZW5kYXIgPSBmYWxzZTtcclxuICAgIHRoaXMucmVzb2x2ZUNhcnQoKTtcclxuICB9XHJcbiAgcHJpdmF0ZSBmb3JtYXREYXRlKGQ6IERhdGUpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgZGQgPSBTdHJpbmcoZC5nZXREYXRlKCkpLnBhZFN0YXJ0KDIsICcwJyk7XHJcbiAgICBjb25zdCBtbSA9IFN0cmluZyhkLmdldE1vbnRoKCkgKyAxKS5wYWRTdGFydCgyLCAnMCcpO1xyXG4gICAgY29uc3QgeXl5eSA9IGQuZ2V0RnVsbFllYXIoKTtcclxuICAgIHJldHVybiBgJHtkZH0tJHttbX0tJHt5eXl5fWA7XHJcbiAgfVxyXG4gIHByaXZhdGUgdG9Jc29EYXRlKGQ6IERhdGUgfCBudWxsKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IGRhdGUgPSBkID8/IG5ldyBEYXRlKCk7XHJcbiAgICBjb25zdCB5eXl5ID0gZGF0ZS5nZXRGdWxsWWVhcigpO1xyXG4gICAgY29uc3QgbW0gPSBTdHJpbmcoZGF0ZS5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgJzAnKTtcclxuICAgIGNvbnN0IGRkID0gU3RyaW5nKGRhdGUuZ2V0RGF0ZSgpKS5wYWRTdGFydCgyLCAnMCcpO1xyXG4gICAgcmV0dXJuIGAke3l5eXl9LSR7bW19LSR7ZGR9VDAwOjAwOjAwLjAwMFpgO1xyXG4gIH1cclxuXHJcbiAgc2VsZWN0TW9kZShtb2RlOiBCb29raW5nTW9kZSkge1xyXG4gICAgdGhpcy5zZWxlY3RlZE1vZGUgPSBtb2RlO1xyXG4gICAgdGhpcy5sb2FkUHJvZHVjdENhcnRGb3JNb2RlKCk7XHJcbiAgICB0aGlzLmdldEFsbFNlcnZpY2VzKCk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBsb2FkUHJvZHVjdENhcnRGb3JNb2RlKCkge1xyXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRNb2RlID09PSAnU1RPUkVfVklTSVQnKSB7XHJcbiAgICAgIHRoaXMucHJvZHVjdENhcnRJdGVtcyA9IFtdO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICB0aGlzLnByb2R1Y3RDYXJ0SXRlbXMgPSBhd2FpdCB0aGlzLmJvb2tpbmdQcm9kdWN0Q2FydFNlcnZpY2UuZ2V0SXRlbXModGhpcy5zZWxlY3RlZE1vZGUgYXMgQm9va2luZ0NhcnRNb2RlKTtcclxuICB9XHJcblxyXG4gIHNlbGVjdFNlcnZpY2Uoc2VydmljZTogYW55KSB7XHJcbiAgICBjb25zdCBpZHggPSB0aGlzLmNhcnRTZXJ2aWNlcy5maW5kSW5kZXgoKHM6IGFueSkgPT4gcy5zZXJ2aWNlSWQgPT09IHNlcnZpY2Uuc2VydmljZUlkKTtcclxuICAgIGlmIChpZHggPj0gMCkge1xyXG4gICAgICB0aGlzLmNhcnRTZXJ2aWNlcy5zcGxpY2UoaWR4LCAxKTtcclxuICAgICAgc2VydmljZS5zZWxlY3RlZCA9IGZhbHNlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5jYXJ0U2VydmljZXMucHVzaChzZXJ2aWNlKTtcclxuICAgICAgc2VydmljZS5zZWxlY3RlZCA9IHRydWU7XHJcbiAgICB9XHJcbiAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IHRoaXMuY2FydFNlcnZpY2VzLmxlbmd0aCA+IDAgfHwgdGhpcy5wcm9kdWN0Q2FydEl0ZW1zLmxlbmd0aCA+IDA7XHJcbiAgfVxyXG4gIHNlbGVjdExvY2F0aW9uKGxvY2F0aW9uOiBhbnkpIHtcclxuICAgIGxvY2F0aW9uLnNlbGVjdGVkID0gdHJ1ZTtcclxuICAgIGlmICh0aGlzLnNlbGVjdGVkTG9jYXRpb24gJiYgbG9jYXRpb24uaWQgIT0gdGhpcy5zZWxlY3RlZExvY2F0aW9uLmlkKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRMb2NhdGlvbi5zZWxlY3RlZCA9IGZhbHNlO1xyXG4gICAgfVxyXG4gICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0cnVlO1xyXG4gICAgdGhpcy5zZWxlY3RlZExvY2F0aW9uID0gbG9jYXRpb247XHJcbiAgfVxyXG5cclxuICBuZXh0U3RlcCgpIHtcclxuICAgIGlmICh0aGlzLnNlbGVjdGVkVGFiID09PSAnc2VydmljZUxpc3RpbmcnKSB7XHJcbiAgICAgIHRoaXMuYWNjZXNzZWRUYWJzLnNlcnZpY2VMaXN0aW5nID0gdHJ1ZTtcclxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRNb2RlID09PSAnU1RPUkVfVklTSVQnKSB7XHJcbiAgICAgICAgdGhpcy5nZXRBbGxMb2NhdGlvbnMoKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmdvVG9EYXRlU2VsZWN0aW9uKCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdsb2NhdGlvbkxpc3RpbmcnKSB7XHJcbiAgICAgIHRoaXMuYWNjZXNzZWRUYWJzLmxvY2F0aW9uTGlzdGluZyA9IHRydWU7XHJcbiAgICAgIHRoaXMuZ29Ub0RhdGVTZWxlY3Rpb24oKTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdzdGFmZkxpc3RpbmcnKSB7XHJcbiAgICAgIHRoaXMuYWNjZXNzZWRUYWJzLnN0YWZmTGlzdGluZyA9IHRydWU7XHJcbiAgICAgIHRoaXMuZmV0Y2hBbGxMaW5lU2xvdHMoKTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdkYXRlU2VsZWN0aW9uJykge1xyXG4gICAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLm5hbWUgJiYgdGhpcy5hcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwuZW1haWwgJiYgdGhpcy5hcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwucGhvbmVOdW1iZXIubGVuZ3RoID09PSAxMCA/IHRydWUgOiBmYWxzZVxyXG4gICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ2NvbnRhY3REZXRhaWxzJztcclxuICAgICAgdGhpcy5iYXJXaWR0aCA9ICc3MC41NydcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdjb250YWN0RGV0YWlscycpIHtcclxuICAgICAgdGhpcy5jaGVja1JlcXVpcmVkVmFsdWVzKCk7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAncGF5bWVudFRhYic7XHJcbiAgICAgIHRoaXMuYmFyV2lkdGggPSAnODUuNTcnXHJcbiAgICB9XHJcbiAgfVxyXG4gIHByZXZpb3VzU3RlcCgpIHtcclxuICAgIHRoaXMubG9hZGVyID0gZmFsc2U7XHJcbiAgICBpZiAodGhpcy5zZWxlY3RlZFRhYiA9PT0gJ21vZGVTZWxlY3Rpb24nKSByZXR1cm47XHJcbiAgICBpZiAodGhpcy5zZWxlY3RlZFRhYiA9PT0gJ3NlcnZpY2VMaXN0aW5nJykge1xyXG4gICAgICBpZiAoIXRoaXMubW9kZVBpbm5lZCkge1xyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnbW9kZVNlbGVjdGlvbic7XHJcbiAgICAgICAgdGhpcy5iYXJXaWR0aCA9ICcxMCc7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0cnVlO1xyXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdsb2NhdGlvbkxpc3RpbmcnKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnc2VydmljZUxpc3RpbmcnO1xyXG4gICAgICB0aGlzLmJhcldpZHRoID0gJzE0LjI4JztcclxuICAgICAgdGhpcy5zZWxlY3RlZExvY2F0aW9uID0gbnVsbDtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHRoaXMuc2VsZWN0ZWRUYWIgPT09ICdzdGFmZkxpc3RpbmcnKSB7XHJcbiAgICAgIHRoaXMucmVzb2x2ZWRMaW5lcy5mb3JFYWNoKChsOiBSZXNvbHZlZExpbmUpID0+IHsgbC5zZWxlY3RlZFN0YWZmSWQgPSB1bmRlZmluZWQ7IGwuc2VsZWN0ZWRTdGFmZk5hbWUgPSB1bmRlZmluZWQ7IH0pO1xyXG4gICAgICBpZiAodGhpcy5zZWxlY3RlZE1vZGUgPT09ICdTVE9SRV9WSVNJVCcgJiYgdGhpcy5hY2Nlc3NlZFRhYnMubG9jYXRpb25MaXN0aW5nKSB7XHJcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdsb2NhdGlvbkxpc3RpbmcnO1xyXG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMjkuMjgnO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnc2VydmljZUxpc3RpbmcnO1xyXG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMTQuMjgnO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmICh0aGlzLnNlbGVjdGVkVGFiID09PSAnZGF0ZVNlbGVjdGlvbicpIHtcclxuICAgICAgY29uc3QgbmVlZHNTdGFmZlBpY2sgPSB0aGlzLnJlc29sdmVkTGluZXMuc29tZSgobDogUmVzb2x2ZWRMaW5lKSA9PiAhIWwuY2FuZGlkYXRlU3RhZmZQb29sPy5sZW5ndGgpO1xyXG4gICAgICBpZiAobmVlZHNTdGFmZlBpY2spIHtcclxuICAgICAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ3N0YWZmTGlzdGluZyc7XHJcbiAgICAgICAgdGhpcy5iYXJXaWR0aCA9ICc0My41Nyc7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAodGhpcy5zZWxlY3RlZE1vZGUgPT09ICdTVE9SRV9WSVNJVCcgJiYgdGhpcy5hY2Nlc3NlZFRhYnMubG9jYXRpb25MaXN0aW5nKSB7XHJcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdsb2NhdGlvbkxpc3RpbmcnO1xyXG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMjkuMjgnO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2Uge1xyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnc2VydmljZUxpc3RpbmcnO1xyXG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMTQuMjgnO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmICh0aGlzLnNlbGVjdGVkVGFiID09PSAnY29udGFjdERldGFpbHMnKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnZGF0ZVNlbGVjdGlvbic7XHJcbiAgICAgIHRoaXMuYmFyV2lkdGggPSAnNTguNTcnO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAodGhpcy5zZWxlY3RlZFRhYiA9PT0gJ3BheW1lbnRUYWInKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnY29udGFjdERldGFpbHMnO1xyXG4gICAgICB0aGlzLmJhcldpZHRoID0gJzcwLjU3JztcclxuICAgIH1cclxuICB9XHJcbiAgc2VydmljZURhdGE6IGFueVtdID0gW107XHJcbiAgZ2V0QWxsU2VydmljZXMoKSB7XHJcbiAgICB0aGlzLnNrZWxldG9uTG9hZGVyID0gdHJ1ZVxyXG4gICAgbGV0IHNlcnZpY2VQYXlsb2FkOiBhbnkgPSB7XHJcbiAgICAgIGJ1c2luZXNzSWQ6IHRoaXMuYnVzaW5lc3NJZCA/PyBcIlwiLFxyXG4gICAgICBwYWdlTm86IDAsXHJcbiAgICAgIHNpemU6IDEwMFxyXG4gICAgfVxyXG4gICAgdGhpcy5yZXN0U2VydmljZS5nZXRBbGxBcHBvaW50bWVudFNlcnZpY2Uoc2VydmljZVBheWxvYWQpLnN1YnNjcmliZShcclxuICAgICAgKHJlczogYW55KSA9PiB7XHJcbiAgICAgICAgdGhpcy5za2VsZXRvbkxvYWRlciA9IGZhbHNlO1xyXG4gICAgICAgIGxldCBzZXJ2aWNlcyA9IChyZXMuY29udGVudCB8fCBbXSkuZmlsdGVyKChzZXJ2aWNlOiBhbnkpID0+IHNlcnZpY2UuYWN0aXZlID09PSB0cnVlKTtcclxuICAgICAgICBpZiAodGhpcy5zZWxlY3RlZE1vZGUgPT09ICdIT01FX1ZJU0lUJykgc2VydmljZXMgPSBzZXJ2aWNlcy5maWx0ZXIoKHM6IGFueSkgPT4gcy5ob21lQXBwb2ludG1lbnRBdmFpbGFibGUpO1xyXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkTW9kZSA9PT0gJ1ZJREVPX0NBTEwnKSBzZXJ2aWNlcyA9IHNlcnZpY2VzLmZpbHRlcigoczogYW55KSA9PiBzLmF2YWlsYWJsZU9ubGluZSk7XHJcbiAgICAgICAgc2VydmljZXMuZm9yRWFjaCgoc2VydmljZTogYW55KSA9PiBzZXJ2aWNlLnNlbGVjdGVkID0gZmFsc2UpO1xyXG4gICAgICAgIHRoaXMuc2VydmljZURhdGEgPSBzZXJ2aWNlcztcclxuICAgICAgICB0aGlzLmNhcnRTZXJ2aWNlcyA9IFtdO1xyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnc2VydmljZUxpc3RpbmcnO1xyXG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMTQuMjgnO1xyXG4gICAgICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gdGhpcy5wcm9kdWN0Q2FydEl0ZW1zLmxlbmd0aCA+IDA7XHJcbiAgICAgIH0sXHJcbiAgICAgIChlcnJvcikgPT4ge1xyXG4gICAgICAgIHRoaXMuc2tlbGV0b25Mb2FkZXIgPSBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgKTtcclxuICB9XHJcbiAgbG9jYXRpb25EYXRhOiBhbnlbXSA9IFtdO1xyXG4gIGdldEFsbExvY2F0aW9ucygpIHtcclxuICAgIHRoaXMubG9hZGVyID0gdHJ1ZTtcclxuICAgIHRoaXMubG9jYXRpb25EYXRhID0gW107XHJcbiAgICBsZXQgcGF5bG9hZCA9IHsgYnVzaW5lc3NJZDogdGhpcy5idXNpbmVzc0lkID8/IFwiXCIgfVxyXG4gICAgdGhpcy5yZXN0U2VydmljZS5nZXRBbGxTdG9yZXMocGF5bG9hZCkuc3Vic2NyaWJlKFxyXG4gICAgICAocmVzOiBhbnkpID0+IHtcclxuICAgICAgICBpZiAocmVzLmRhdGEuZGF0YS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICBsZXQgbG9jYXRpb25zID0gcmVzLmRhdGEuZGF0YS5maWx0ZXIoKHN0b3JlOiBhbnkpID0+IHsgcmV0dXJuIHN0b3JlLnN0YXR1cyA9PT0gJ0FDVElWRScgfSk7XHJcbiAgICAgICAgICAvLyBMb2NhdGlvbi1pbnRlcnNlY3Rpb24gY2hlY2sgKGRlc2lnbiBkb2MgwqcyYyk6IG9ubHkgb2ZmZXIgc3RvcmVzIHRoYXQgY2FycnkgZXZlcnlcclxuICAgICAgICAgIC8vIHNlcnZpY2UgY3VycmVudGx5IGluIHRoZSBjYXJ0LCBub3QganVzdCB0aGUgZmlyc3Qgb25lLlxyXG4gICAgICAgICAgbG9jYXRpb25zID0gbG9jYXRpb25zLmZpbHRlcigobG9jYXRpb246IGFueSkgPT5cclxuICAgICAgICAgICAgdGhpcy5jYXJ0U2VydmljZXMuZXZlcnkoKHM6IGFueSkgPT4gcy5zdG9yZUlkcz8uaW5jbHVkZXMobG9jYXRpb24uaWQpKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIGxvY2F0aW9ucy5mb3JFYWNoKChsOiBhbnkpID0+IGwuc2VsZWN0ZWQgPSBmYWxzZSk7XHJcbiAgICAgICAgICB0aGlzLmxvY2F0aW9uRGF0YSA9IGxvY2F0aW9ucztcclxuICAgICAgICAgIGlmICh0aGlzLmxvY2F0aW9uRGF0YS5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBzZXZlcml0eTogJ2Vycm9yJywgc3VtbWFyeTogJ05vIExvY2F0aW9uJywgZGV0YWlsOiAnVGhlc2Ugc2VydmljZXMgYXJlblxcJ3QgYWxsIGF2YWlsYWJsZSBhdCBvbmUgbG9jYXRpb24gLSByZW1vdmUgb25lIGFuZCBib29rIGl0IHNlcGFyYXRlbHknIH0pO1xyXG4gICAgICAgICAgICB0aGlzLmxvYWRlciA9IGZhbHNlO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZiAodGhpcy5sb2NhdGlvbkRhdGEubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRMb2NhdGlvbiA9IHRoaXMubG9jYXRpb25EYXRhWzBdO1xyXG4gICAgICAgICAgICB0aGlzLmxvYWRlciA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLmFjY2Vzc2VkVGFicy5sb2NhdGlvbkxpc3RpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5nb1RvRGF0ZVNlbGVjdGlvbigpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMubG9hZGVyID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnbG9jYXRpb25MaXN0aW5nJztcclxuICAgICAgICAgICAgdGhpcy5iYXJXaWR0aCA9ICcyOS4yOCc7XHJcbiAgICAgICAgICAgIHRoaXMuYWNjZXNzZWRUYWJzLmxvY2F0aW9uTGlzdGluZyA9IHRydWU7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBzZXZlcml0eTogJ2Vycm9yJywgc3VtbWFyeTogJ05vIExvY2F0aW9uJywgZGV0YWlsOiAnTm8gTG9jYXRpb24gYWRkZWQgZm9yIHNlbGVjdGVkIHNlcnZpY2UnIH0pO1xyXG4gICAgICAgICAgdGhpcy5sb2FkZXIgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sXHJcbiAgICAgIChlcnJvcikgPT4ge1xyXG4gICAgICAgIHRoaXMubG9hZGVyID0gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBnb1RvRGF0ZVNlbGVjdGlvbigpIHtcclxuICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnZGF0ZVNlbGVjdGlvbic7XHJcbiAgICB0aGlzLmJhcldpZHRoID0gJzQzLjU3JztcclxuICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gZmFsc2U7XHJcbiAgICB0aGlzLnJlc29sdmVkTGluZXMgPSBbXTtcclxuICB9XHJcblxyXG4gIHN0YWZmU2VhcmNoUXVlcnk6IHN0cmluZyA9ICcnO1xyXG4gIGdldCBmaWx0ZXJlZFN0YWZmKCk6IGFueVtdIHtcclxuICAgIGlmICghdGhpcy5zdGFmZlNlYXJjaFF1ZXJ5LnRyaW0oKSkge1xyXG4gICAgICByZXR1cm4gdGhpcy5zdGFmZkRhdGE7XHJcbiAgICB9XHJcbiAgICBjb25zdCBxdWVyeSA9IHRoaXMuc3RhZmZTZWFyY2hRdWVyeS50b0xvd2VyQ2FzZSgpLnRyaW0oKTtcclxuICAgIHJldHVybiB0aGlzLnN0YWZmRGF0YS5maWx0ZXIoc3RhZmYgPT5cclxuICAgICAgc3RhZmY/LnN0YWZmTmFtZT8udG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhxdWVyeSlcclxuICAgICk7XHJcbiAgfVxyXG4gIHN0YWZmRGF0YTogYW55W10gPSBbXTtcclxuXHJcbiAgcmVzb2x2ZUNhcnQoKSB7XHJcbiAgICBpZiAodGhpcy5jYXJ0U2VydmljZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIC8vIFB1cmUgcHJvZHVjdC1vbmx5IGxpbmUgKEhvbWUgVmlzaXQgLyBWaWRlbyBDYWxsIHdpdGggbm8gc2VydmljZXMgYXR0YWNoZWQpIC0gcmVzb2x1dGlvblxyXG4gICAgICAvLyBpcyBidWlsdCBhcm91bmQgc2VydmljZSBwb29scywgc28gdGhpcyBuZWVkcyBhbiBleHBsaWNpdCBzdGFmZiBwaWNrIGluc3RlYWQuIE9uZSBsaW5lLFxyXG4gICAgICAvLyBubyBzZXJ2aWNlcywganVzdCBhIHN0YWZmK3RpbWUgdG8gY2FycnkgdGhlIGZsYXQgcHJvZHVjdC12aWV3aW5nIGFsbG93YW5jZS5cclxuICAgICAgdGhpcy5yZXNvbHZlZExpbmVzID0gW3sgc2VydmljZXM6IFtdLCB0b3RhbER1cmF0aW9uTWludXRlczogMCwgc2xvdHM6IFtdIH1dO1xyXG4gICAgICB0aGlzLmdldEFsbFN0YWZmRm9yUHJvZHVjdE9ubHlMaW5lKCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRoaXMucmVzb2x2aW5nQ2FydCA9IHRydWU7XHJcbiAgICB0aGlzLnNrZWxldG9uTG9hZGVyID0gdHJ1ZTtcclxuICAgIGNvbnN0IHBheWxvYWQ6IGFueSA9IHtcclxuICAgICAgYnVzaW5lc3NJZDogdGhpcy5idXNpbmVzc0lkLFxyXG4gICAgICBtb2RlOiB0aGlzLnNlbGVjdGVkTW9kZSxcclxuICAgICAgc3RvcmVJZDogdGhpcy5zZWxlY3RlZE1vZGUgPT09ICdTVE9SRV9WSVNJVCcgPyB0aGlzLnNlbGVjdGVkTG9jYXRpb24/LmlkIDogdW5kZWZpbmVkLFxyXG4gICAgICBib29raW5nRGF0ZTogdGhpcy50b0lzb0RhdGUodGhpcy5zZWxlY3RlZERhdGUpLFxyXG4gICAgICBzZXJ2aWNlSXRlbXM6IHRoaXMuY2FydFNlcnZpY2VzLm1hcCgoczogYW55KSA9PiAoeyBzZXJ2aWNlSWQ6IHMuc2VydmljZUlkIH0pKVxyXG4gICAgfTtcclxuICAgIHRoaXMucmVzdFNlcnZpY2UucmVzb2x2ZUNhcnQocGF5bG9hZCkuc3Vic2NyaWJlKChyZXM6IGFueSkgPT4ge1xyXG4gICAgICB0aGlzLnJlc29sdmluZ0NhcnQgPSBmYWxzZTtcclxuICAgICAgdGhpcy5za2VsZXRvbkxvYWRlciA9IGZhbHNlO1xyXG4gICAgICB0aGlzLnJlc29sdmVkTGluZXMgPSAocmVzIHx8IFtdKS5tYXAoKGxpbmU6IGFueSkgPT4gKHtcclxuICAgICAgICBzZXJ2aWNlczogbGluZS5zZXJ2aWNlcyxcclxuICAgICAgICB0b3RhbER1cmF0aW9uTWludXRlczogbGluZS50b3RhbER1cmF0aW9uTWludXRlcyxcclxuICAgICAgICBzdGFmZklkOiBsaW5lLnN0YWZmSWQsXHJcbiAgICAgICAgc3RhZmZOYW1lOiBsaW5lLnN0YWZmTmFtZSxcclxuICAgICAgICBjYW5kaWRhdGVTdGFmZlBvb2w6IGxpbmUuY2FuZGlkYXRlU3RhZmZQb29sLFxyXG4gICAgICAgIHNsb3RzOiBbXVxyXG4gICAgICB9KSk7XHJcbiAgICAgIGNvbnN0IG5lZWRzU3RhZmZQaWNrID0gdGhpcy5yZXNvbHZlZExpbmVzLnNvbWUoKGw6IFJlc29sdmVkTGluZSkgPT4gISFsLmNhbmRpZGF0ZVN0YWZmUG9vbD8ubGVuZ3RoKTtcclxuICAgICAgaWYgKG5lZWRzU3RhZmZQaWNrKSB7XHJcbiAgICAgICAgdGhpcy5zdGFmZlNlYXJjaFF1ZXJ5ID0gJyc7XHJcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRhYiA9ICdzdGFmZkxpc3RpbmcnO1xyXG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnNDMuNTcnO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuZmV0Y2hBbGxMaW5lU2xvdHMoKTtcclxuICAgICAgfVxyXG4gICAgfSwgKGVycm9yOiBhbnkpID0+IHtcclxuICAgICAgdGhpcy5yZXNvbHZpbmdDYXJ0ID0gZmFsc2U7XHJcbiAgICAgIHRoaXMuc2tlbGV0b25Mb2FkZXIgPSBmYWxzZTtcclxuICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBzZXZlcml0eTogJ2Vycm9yJywgc3VtbWFyeTogJ1VuYWJsZSB0byBjaGVjayBhdmFpbGFiaWxpdHknLCBkZXRhaWw6IGVycm9yLmVycm9yPy5tZXNzYWdlID8/ICdQbGVhc2UgdHJ5IGFnYWluJyB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZ2V0QWxsU3RhZmZGb3JQcm9kdWN0T25seUxpbmUoKSB7XHJcbiAgICB0aGlzLmxvYWRlciA9IHRydWU7XHJcbiAgICBjb25zdCBwYXlsb2FkID0geyBzZXJ2aWNlSWQ6ICcnLCBzdG9yZUlkOiB0aGlzLnNlbGVjdGVkTG9jYXRpb24/LmlkID8/ICcnLCBidXNpbmVzc0lkOiB0aGlzLmJ1c2luZXNzSWQgPz8gJycgfTtcclxuICAgIHRoaXMucmVzdFNlcnZpY2UuZ2V0QWxsU3RhZmYocGF5bG9hZCkuc3Vic2NyaWJlKChyZXM6IGFueSkgPT4ge1xyXG4gICAgICB0aGlzLmxvYWRlciA9IGZhbHNlO1xyXG4gICAgICB0aGlzLnN0YWZmRGF0YSA9IChyZXMgfHwgW10pLmZpbHRlcigoc3RhZmY6IGFueSkgPT4gc3RhZmYuYWN0aXZlID09PSB0cnVlICYmIHN0YWZmLmJvb2tpbmdBbGxvd2VkKTtcclxuICAgICAgdGhpcy5zdGFmZkRhdGEuZm9yRWFjaCgoc3RhZmY6IGFueSkgPT4gc3RhZmYuc2VsZWN0ZWQgPSBmYWxzZSk7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnc3RhZmZMaXN0aW5nJztcclxuICAgICAgdGhpcy5iYXJXaWR0aCA9ICc0My41Nyc7XHJcbiAgICB9LCAoKSA9PiB7IHRoaXMubG9hZGVyID0gZmFsc2U7IH0pO1xyXG4gIH1cclxuXHJcbiAgc2VsZWN0U3RhZmZGb3JQcm9kdWN0T25seUxpbmUoc3RhZmY6IGFueSkge1xyXG4gICAgdGhpcy5zdGFmZkRhdGEuZm9yRWFjaCgoczogYW55KSA9PiBzLnNlbGVjdGVkID0gZmFsc2UpO1xyXG4gICAgc3RhZmYuc2VsZWN0ZWQgPSB0cnVlO1xyXG4gICAgdGhpcy5yZXNvbHZlZExpbmVzWzBdLnNlbGVjdGVkU3RhZmZJZCA9IHN0YWZmLnN0YWZmSWQ7XHJcbiAgICB0aGlzLnJlc29sdmVkTGluZXNbMF0uc2VsZWN0ZWRTdGFmZk5hbWUgPSBzdGFmZi5zdGFmZk5hbWU7XHJcbiAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IHRydWU7XHJcbiAgfVxyXG5cclxuICBzZWxlY3RTdGFmZkZvckxpbmUobGluZTogUmVzb2x2ZWRMaW5lLCBzdGFmZjogYW55KSB7XHJcbiAgICBsaW5lLnNlbGVjdGVkU3RhZmZJZCA9IHN0YWZmLmlkO1xyXG4gICAgbGluZS5zZWxlY3RlZFN0YWZmTmFtZSA9IHN0YWZmLm5hbWU7XHJcbiAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IHRoaXMucmVzb2x2ZWRMaW5lcy5ldmVyeSgobDogUmVzb2x2ZWRMaW5lKSA9PiAhIShsLnN0YWZmSWQgfHwgbC5zZWxlY3RlZFN0YWZmSWQpKTtcclxuICB9XHJcblxyXG4gIGZldGNoQWxsTGluZVNsb3RzKCkge1xyXG4gICAgdGhpcy5za2VsZXRvbkxvYWRlciA9IHRydWU7XHJcbiAgICB0aGlzLnNlbGVjdGVkVGFiID0gJ2RhdGVTZWxlY3Rpb24nO1xyXG4gICAgdGhpcy5iYXJXaWR0aCA9ICc1OC41Nyc7XHJcbiAgICBsZXQgcGVuZGluZyA9IHRoaXMucmVzb2x2ZWRMaW5lcy5sZW5ndGg7XHJcbiAgICB0aGlzLnJlc29sdmVkTGluZXMuZm9yRWFjaCgobGluZTogUmVzb2x2ZWRMaW5lKSA9PiB7XHJcbiAgICAgIGNvbnN0IHN0YWZmSWQgPSBsaW5lLnN0YWZmSWQgfHwgbGluZS5zZWxlY3RlZFN0YWZmSWQ7XHJcbiAgICAgIGNvbnN0IHBheWxvYWQ6IGFueSA9IHtcclxuICAgICAgICBzdG9yZUlkOiB0aGlzLnNlbGVjdGVkTW9kZSA9PT0gJ1NUT1JFX1ZJU0lUJyA/IHRoaXMuc2VsZWN0ZWRMb2NhdGlvbj8uaWQgOiB1bmRlZmluZWQsXHJcbiAgICAgICAgc2VydmljZUlkczogbGluZS5zZXJ2aWNlcy5tYXAoKHM6IGFueSkgPT4gcy5pZCksXHJcbiAgICAgICAgYnVzaW5lc3NJZDogdGhpcy5idXNpbmVzc0lkLFxyXG4gICAgICAgIGJvb2tpbmdEYXRlOiB0aGlzLnRvSXNvRGF0ZSh0aGlzLnNlbGVjdGVkRGF0ZSksXHJcbiAgICAgICAgc3RhZmZJZCxcclxuICAgICAgICBtb2RlOiB0aGlzLnNlbGVjdGVkTW9kZVxyXG4gICAgICB9O1xyXG4gICAgICBsaW5lLnNsb3RzTG9hZGluZyA9IHRydWU7XHJcbiAgICAgIHRoaXMucmVzdFNlcnZpY2UuZ2V0Qm9va2luZ1Nsb3RzKHBheWxvYWQpLnN1YnNjcmliZSgocmVzOiBhbnkpID0+IHtcclxuICAgICAgICBsaW5lLnNsb3RzID0gKHJlcyB8fCBbXSkubWFwKCh2OiBzdHJpbmcpID0+ICh7IHNlbGVjdGVkOiBmYWxzZSwgdmFsdWU6IHYgfSkpO1xyXG4gICAgICAgIGxpbmUuc2xvdHNMb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgICAgcGVuZGluZy0tO1xyXG4gICAgICAgIGlmIChwZW5kaW5nIDw9IDApIHRoaXMuc2tlbGV0b25Mb2FkZXIgPSBmYWxzZTtcclxuICAgICAgfSwgKCkgPT4ge1xyXG4gICAgICAgIGxpbmUuc2xvdHNMb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgICAgcGVuZGluZy0tO1xyXG4gICAgICAgIGlmIChwZW5kaW5nIDw9IDApIHRoaXMuc2tlbGV0b25Mb2FkZXIgPSBmYWxzZTtcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHNlbGVjdFNsb3RGb3JMaW5lKGxpbmU6IFJlc29sdmVkTGluZSwgc2xvdDogYW55KSB7XHJcbiAgICBsaW5lLnNsb3RzLmZvckVhY2goKHM6IGFueSkgPT4gcy5zZWxlY3RlZCA9IGZhbHNlKTtcclxuICAgIHNsb3Quc2VsZWN0ZWQgPSB0cnVlO1xyXG4gICAgbGluZS5zZWxlY3RlZFNsb3QgPSBzbG90O1xyXG4gICAgdGhpcy5hY3RpdmVCdXR0b24gPSB0aGlzLnJlc29sdmVkTGluZXMuZXZlcnkoKGw6IFJlc29sdmVkTGluZSkgPT4gISFsLnNlbGVjdGVkU2xvdCk7XHJcbiAgfVxyXG5cclxuICBjb252ZXJ0VG8yNEhvdXIodGltZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IFtob3VyTWluLCBtb2RpZmllclJhd10gPSB0aW1lLnNwbGl0KCcgJyk7XHJcbiAgICBjb25zdCBtb2RpZmllciA9IG1vZGlmaWVyUmF3LnRvVXBwZXJDYXNlKCk7IC8vIFwiQU1cIiBvciBcIlBNXCJcclxuICAgIGxldCBbaG91cnMsIG1pbnV0ZXNdID0gaG91ck1pbi5zcGxpdCgnOicpLm1hcChOdW1iZXIpO1xyXG5cclxuICAgIGlmIChtb2RpZmllciA9PT0gJ1BNJyAmJiBob3VycyA8IDEyKSB7XHJcbiAgICAgIGhvdXJzICs9IDEyO1xyXG4gICAgfVxyXG4gICAgaWYgKG1vZGlmaWVyID09PSAnQU0nICYmIGhvdXJzID09PSAxMikge1xyXG4gICAgICBob3VycyA9IDA7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgaGggPSBob3Vycy50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XHJcbiAgICBjb25zdCBtbSA9IG1pbnV0ZXMudG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpO1xyXG4gICAgcmV0dXJuIGAke2hofToke21tfSAke21vZGlmaWVyfWA7XHJcbiAgfVxyXG4gIGxvYWRlcjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIGlzUHJvY2Vzc2luZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIHRlcm1zQW5kQ29uZGl0aW9uczogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIGNoZWNrUmVxdWlyZWRWYWx1ZXMoKSB7XHJcbiAgICBjb25zdCBpc0VtYWlsVmFsaWQgPSB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5lbWFpbCAmJlxyXG4gICAgICAvXlthLXowLTkuXyUrLV0rQFthLXowLTkuLV0rXFwuW2Etel17Miw0fSQvLnRlc3QodGhpcy5hcHBvaW50bWVudFBheWxvYWQuY3VzdG9tZXJEZXRhaWwuZW1haWwpO1xyXG5cclxuICAgIGNvbnN0IGFueVBvbGljeSA9IHRoaXMuY2FydFNlcnZpY2VzLnNvbWUoKHM6IGFueSkgPT4gcz8uY2FuY2VsbGF0aW9uUG9saWN5Py5sZW5ndGggPiAwIHx8IHM/LnJlc2NoZWR1bGVQb2xpY3k/Lmxlbmd0aCA+IDApO1xyXG5cclxuICAgIGlmICh0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5uYW1lICYmXHJcbiAgICAgIGlzRW1haWxWYWxpZCAmJlxyXG4gICAgICB0aGlzLmFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5waG9uZU51bWJlci5sZW5ndGggPT09IDEwKSB7XHJcbiAgICAgIGlmIChhbnlQb2xpY3kpIHtcclxuICAgICAgICB0aGlzLmFjdGl2ZUJ1dHRvbiA9IHRoaXMudGVybXNBbmRDb25kaXRpb25zID8gdHJ1ZSA6IGZhbHNlO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuYWN0aXZlQnV0dG9uID0gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5hY3RpdmVCdXR0b24gPSBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGFwcG9pbnRtZW50UGF5bG9hZDogYW55ID0ge1xyXG4gICAgY3VzdG9tZXJEZXRhaWw6IHtcclxuICAgICAgbmFtZTogJycsXHJcbiAgICAgIHBob25lTnVtYmVyOiAnJyxcclxuICAgICAgZW1haWw6ICcnXHJcbiAgICB9XHJcbiAgfVxyXG4gIGFwaVN0YXR1czogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBjb25maXJtQm9va2luZygpIHtcclxuICAgIC8vIERlZmVuc2l2ZSByZS1jaGVjayAobWlycm9ycyBjYXJ0LmNvbXBvbmVudC50cydzIHByb2NlZWRUb1BheW1lbnQoKSBndWFyZCkgLSB0aGUgZW50cnlcclxuICAgIC8vIGNoZWNrIGluIG5nT25Jbml0KCkgc2hvdWxkIG1ha2UgdGhpcyB1bnJlYWNoYWJsZSBpbiBwcmFjdGljZSwgYnV0IGEgbG9uZyBzbG90LXBpY2tpbmdcclxuICAgIC8vIHNlc3Npb24gY291bGQgc3RpbGwgbGV0IHRoZSBsb2dpbiBzZXNzaW9uIGV4cGlyZSBiZWZvcmUgdGhlIGN1c3RvbWVyIHJlYWNoZXMgdGhpcyBzdGVwLlxyXG4gICAgaWYgKCF0aGlzLmVkaXQgJiYgIXRoaXMuc3RvcmFnZVNlcnZpY2UuZ2V0VXNlcigpKSB7XHJcbiAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnL2xvZ2luJ10sIHsgcXVlcnlQYXJhbXM6IHsgcmVkaXJlY3RUbzogdGhpcy5yb3V0ZXIudXJsIH0gfSk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIHRoaXMuaXNQcm9jZXNzaW5nID0gdHJ1ZTtcclxuICAgIGNvbnN0IGxpbmVzID0gdGhpcy5yZXNvbHZlZExpbmVzLm1hcCgobDogUmVzb2x2ZWRMaW5lKSA9PiB7XHJcbiAgICAgIGNvbnN0IHNsb3QgPSBsLnNlbGVjdGVkU2xvdDtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBzZXJ2aWNlSWRzOiBsLnNlcnZpY2VzLm1hcCgoczogYW55KSA9PiBzLmlkKSxcclxuICAgICAgICBzdGFmZklkOiBsLnN0YWZmSWQgfHwgbC5zZWxlY3RlZFN0YWZmSWQsXHJcbiAgICAgICAgc3RhcnRUaW1lOiBzbG90ID8gdGhpcy5jb252ZXJ0VG8yNEhvdXIoc2xvdC52YWx1ZSkuc2xpY2UoMCwgNSkgOiB1bmRlZmluZWRcclxuICAgICAgfTtcclxuICAgIH0pO1xyXG5cclxuICAgIGNvbnN0IGhvbGRQYXlsb2FkOiBhbnkgPSB7XHJcbiAgICAgIGJ1c2luZXNzSWQ6IHRoaXMuYnVzaW5lc3NJZCxcclxuICAgICAgbW9kZTogdGhpcy5zZWxlY3RlZE1vZGUsXHJcbiAgICAgIHN0b3JlSWQ6IHRoaXMuc2VsZWN0ZWRNb2RlID09PSAnU1RPUkVfVklTSVQnID8gdGhpcy5zZWxlY3RlZExvY2F0aW9uPy5pZCA6IHVuZGVmaW5lZCxcclxuICAgICAgYm9va2luZ0RhdGU6IHRoaXMudG9Jc29EYXRlKHRoaXMuc2VsZWN0ZWREYXRlKSxcclxuICAgICAgY3VzdG9tZXJEZXRhaWw6IHRoaXMuYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLFxyXG4gICAgICBsaW5lcyxcclxuICAgICAgcHJvZHVjdExpbmVzOiB0aGlzLnByb2R1Y3RDYXJ0SXRlbXMubWFwKChwOiBhbnkpID0+IHRoaXMuYm9va2luZ1Byb2R1Y3RDYXJ0U2VydmljZS50b1Byb2R1Y3RMaW5lKHApKSxcclxuICAgICAgYWRkcmVzc0RldGFpbHM6IHRoaXMuc2VsZWN0ZWRNb2RlID09PSAnSE9NRV9WSVNJVCcgPyB7IC4uLnRoaXMuaG9tZVZpc2l0QWRkcmVzcywgaW5zdHJ1Y3Rpb25zOiB0aGlzLmluc3RydWN0aW9ucyB9IDogdW5kZWZpbmVkXHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMucmVzdFNlcnZpY2UuaG9sZEJvb2tpbmcoaG9sZFBheWxvYWQpLnN1YnNjcmliZSgoZ3JvdXA6IGFueSkgPT4ge1xyXG4gICAgICB0aGlzLmJvb2tpbmdHcm91cCA9IGdyb3VwO1xyXG4gICAgICBpZiAodGhpcy5zZWxlY3RlZE1vZGUgIT09ICdTVE9SRV9WSVNJVCcgJiYgdGhpcy5wcm9kdWN0Q2FydEl0ZW1zLmxlbmd0aCA+IDApIHtcclxuICAgICAgICB0aGlzLmJvb2tpbmdQcm9kdWN0Q2FydFNlcnZpY2UuY2xlYXIodGhpcy5zZWxlY3RlZE1vZGUgYXMgQm9va2luZ0NhcnRNb2RlKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoZ3JvdXAuc3RhdHVzID09PSAnSE9MRCcgJiYgZ3JvdXAudG90YWxDb2xsZWN0ZWRBdEJvb2tpbmcgPiAwKSB7XHJcbiAgICAgICAgLy8gTXVzdCBhY3Qgb24gdGhpcyBpbW1lZGlhdGVseSAtIHRoZSBob2xkIGV4cGlyZXMgaW4gMTAgbWludXRlcy5cclxuICAgICAgICB0aGlzLnJlc3RTZXJ2aWNlLmdlbmVyYXRlUGF5bWVudFRva2VuKGdyb3VwLmdyb3VwSWQpLnN1YnNjcmliZSgob3JkZXI6IGFueSkgPT4ge1xyXG4gICAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2FwcG9pbnRtZW50UGF5bWVudElkJywgb3JkZXIucGdPcmRlcklkKTtcclxuICAgICAgICAgIHRoaXMuaXNQcm9jZXNzaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICB0aGlzLl9ldmVudFNlcnZpY2UuY2FzaEZyZWVFdmVudC5lbWl0KHsgZGF0YTogeyBvcmRlclNpZ25hdHVyZTogb3JkZXIub3JkZXJTaWduYXR1cmUgfSB9KTtcclxuICAgICAgICB9LCAoZXJyb3I6IGFueSkgPT4ge1xyXG4gICAgICAgICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSBmYWxzZTtcclxuICAgICAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsgc2V2ZXJpdHk6ICdlcnJvcicsIHN1bW1hcnk6ICdQYXltZW50IEZhaWxlZCcsIGRldGFpbDogZXJyb3IuZXJyb3I/Lm1lc3NhZ2UgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5hcGlTdGF0dXMgPSB0cnVlO1xyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRUYWIgPSAnc3RhdHVzVGVtcGxhdGUnO1xyXG4gICAgICAgIHRoaXMuYmFyV2lkdGggPSAnMTAwJztcclxuICAgICAgICB0aGlzLmlzUHJvY2Vzc2luZyA9IGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICB9LCAoZXJyb3I6IGFueSkgPT4ge1xyXG4gICAgICB0aGlzLmlzUHJvY2Vzc2luZyA9IGZhbHNlO1xyXG4gICAgICB0aGlzLmFwaVN0YXR1cyA9IGZhbHNlO1xyXG4gICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7IHNldmVyaXR5OiAnZXJyb3InLCBzdW1tYXJ5OiAnQm9va2luZyBGYWlsZWQnLCBkZXRhaWw6IGVycm9yLmVycm9yPy5tZXNzYWdlIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBnb0JhY2soKSB7XHJcbiAgICBpZiAobG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJSRVFVRVNUX0ZST01cIikgPT09ICdFQ09NTUVSQ0UnKSB7XHJcbiAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnL2FkbWluL2FwcG9pbnRtZW50cy9saXN0LWFwcG9pbnRtZW50cyddKVxyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnJ10pXHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiIsIjxwLXRvYXN0IHBvc2l0aW9uPVwiYm90dG9tLXJpZ2h0XCIgW2Jhc2VaSW5kZXhdPVwiMTAwMDAwMDAwMDBcIiBbYXV0b1pJbmRleF09XCJ0cnVlXCJcclxuICAgIFtzaG93VHJhbnNmb3JtT3B0aW9uc109XCJzY3JlZW5XaWR0aCA8IDQ3NSA/ICd0cmFuc2xhdGVZKC0xMDAlKScgOiAnJ1wiPjwvcC10b2FzdD5cclxuPHNlY3Rpb24gY2xhc3M9XCJtYWluX3NlY3Rpb25cIj5cclxuICAgIDxkaXYgY2xhc3M9XCJtYWluX2hlYWRlclwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXIgZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmFjay1idG4gZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXIgYWxpZ24taXRlbXMtY2VudGVyIGN1cnNvci1wb2ludGVyIGdhcC0yIG1iLTNcIlxyXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImdvQmFjaygpXCI+XHJcbiAgICAgICAgICAgICAgICA8bWF0LWljb24+a2V5Ym9hcmRfYmFja3NwYWNlPC9tYXQtaWNvbj48c3BhbiAqbmdJZj1cInNjcmVlbldpZHRoID4gNDc1XCI+QmFjayB0byBIb21lPC9zcGFuPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhlYWRlci10aXRsZVwiPlxyXG4gICAgICAgICAgICAgICAgPGgxPkJvb2sgTmV3IEFwcG9pbnRtZW50PC9oMT5cclxuICAgICAgICAgICAgICAgIDxwPnt7YnVzaW5lc3NOYW1lID8/IFwiTi9BXCIgfX08L3A+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3MtYmFyXCI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwcm9ncmVzcy1maWxsXCIgW3N0eWxlLndpZHRoXT1cImJhcldpZHRoICsgJyUnXCI+PC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxkaXYgY2xhc3M9XCJtYWluX2JvZHkgdy0xMDAgZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXJcIj5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0ZWRUYWIgPT09ICdtb2RlU2VsZWN0aW9uJ1wiPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibW9kZVNlbGVjdGlvblwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFRhYiA9PT0gJ3NlcnZpY2VMaXN0aW5nJ1wiPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXNrZWxldG9uTG9hZGVyXCI+XHJcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwic2VydmljZUxpc3RpbmdcIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGVkVGFiID09PSAnbG9jYXRpb25MaXN0aW5nJ1wiPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibG9jYXRpb25MaXN0aW5nXCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGVkVGFiID09PSAnc3RhZmZMaXN0aW5nJ1wiPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwic3RhZmZMaXN0aW5nXCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGVkVGFiID09PSAnZGF0ZVNlbGVjdGlvbidcIj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImRhdGVTZWxlY3Rpb25cIj48L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0ZWRUYWI9PT0nY29udGFjdERldGFpbHMnXCI+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjb250YWN0RGV0YWlsc1wiPjwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFRhYj09PSdwYXltZW50VGFiJ1wiPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwicGF5bWVudFRhYlwiPjwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzZWxlY3RlZFRhYj09PSdzdGF0dXNUZW1wbGF0ZSdcIj5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInN0YXR1c1RlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxkaXYgY2xhc3M9XCJtYWluX2Zvb3RlciBkLWZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlciBhbGlnbi1pdGVtcy1jZW50ZXJcIlxyXG4gICAgICAgICpuZ0lmPVwic2VsZWN0ZWRUYWIhPT0nc3RhdHVzVGVtcGxhdGUnICYmIHNlbGVjdGVkVGFiIT09J21vZGVTZWxlY3Rpb24nXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImZvb3Rlci1idXR0b25zXCJcclxuICAgICAgICAgICAgW25nU3R5bGVdPVwieydqdXN0aWZ5LWNvbnRlbnQnOiBzZWxlY3RlZFRhYiAhPSAnc2VydmljZUxpc3RpbmcnID8gJ3NwYWNlLWJldHdlZW4nIDogJ2VuZCd9XCI+XHJcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFjay1mb290ZXItYnRuIGN1cnNvci1wb2ludGVyXCIgKGNsaWNrKT1cInByZXZpb3VzU3RlcCgpXCJcclxuICAgICAgICAgICAgICAgICpuZ0lmPVwic2VsZWN0ZWRUYWIgIT0gJ3NlcnZpY2VMaXN0aW5nJ1wiPkJhY2s8L3NwYW4+XHJcbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJjb250aW51ZS1idG5cIiBbZGlzYWJsZWRdPVwiIWFjdGl2ZUJ1dHRvblwiIChjbGljayk9XCJuZXh0U3RlcCgpXCJcclxuICAgICAgICAgICAgICAgICpuZ0lmPVwic2VsZWN0ZWRUYWIhPSdwYXltZW50VGFiJ1wiPnt7IWxvYWRlciA/ICdDb250aW51ZScgOiAnTG9hZGluZy4uLid9fTwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgZC1mbGV4IGp1c3RpZnktY29udGVudC1ldmVubHkgYWxpZ24taXRlbXMtY2VudGVyXCJcclxuICAgICAgICAgICAgICAgICpuZ0lmPVwic2VsZWN0ZWRUYWI9PT0ncGF5bWVudFRhYidcIiAoY2xpY2spPVwiY29uZmlybUJvb2tpbmcoKVwiIFtkaXNhYmxlZF09XCJpc1Byb2Nlc3NpbmdcIlxyXG4gICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydwYXktbm93LWJ0bicgOiBib29raW5nR3JvdXA/LnRvdGFsQ29sbGVjdGVkQXRCb29raW5nID4gMCB8fCAhYm9va2luZ0dyb3VwLCdjb21wbGV0ZV9ib29raW5nJyA6IGJvb2tpbmdHcm91cCAmJiAhYm9va2luZ0dyb3VwPy50b3RhbENvbGxlY3RlZEF0Qm9va2luZ31cIj5cclxuICAgICAgICAgICAgICAgIDxpbWcgc3JjPVwiaHR0cHM6Ly9kMno5NDk3eHA4eGIxMi5jbG91ZGZyb250Lm5ldC9wcm9kLWltYWdlcy8zMDQwMTJjMTc1MzQ0MDA4Nzk5NkJhY2tncm91bmQucG5nXCI+XHJcbiAgICAgICAgICAgICAgICB7e2lzUHJvY2Vzc2luZyA/ICdQbGVhc2Ugd2FpdC4uLicgOiAnQ29uZmlybSBCb29raW5nJ319XHJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbjwvc2VjdGlvbj5cclxuXHJcbjxuZy10ZW1wbGF0ZSAjbW9kZVNlbGVjdGlvbj5cclxuICAgIDxkaXYgY2xhc3M9XCJ3LTYwIHNlcnZpY2Vfc2VjdGlvblwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLXNlbGVjdGlvblwiPlxyXG4gICAgICAgICAgICA8aDI+SG93IHdvdWxkIHlvdSBsaWtlIHRoaXM/PC9oMj5cclxuICAgICAgICAgICAgPHA+Q2hvb3NlIGhvdyB5b3UnZCBsaWtlIHRvIGJlIHNlcnZlZDwvcD5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2VzLWdyaWRcIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWNhcmRcIiAoY2xpY2spPVwic2VsZWN0TW9kZSgnU1RPUkVfVklTSVQnKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWhlYWRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1pY29uXCI+PG1hdC1pY29uPnN0b3JlZnJvbnQ8L21hdC1pY29uPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1pbmZvXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS10aXRsZVwiPlZpc2l0IG91ciBTdG9yZTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1kZXNjcmlwdGlvblwiPkNvbWUgdG8gdXMgYXQgb25lIG9mIG91ciBsb2NhdGlvbnM8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtY2FyZFwiIChjbGljayk9XCJzZWxlY3RNb2RlKCdIT01FX1ZJU0lUJylcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1oZWFkZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaWNvblwiPjxtYXQtaWNvbj5ob21lPC9tYXQtaWNvbj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaW5mb1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtdGl0bGVcIj5XZSBjb21lIHRvIHlvdTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1kZXNjcmlwdGlvblwiPkEgcHJvZmVzc2lvbmFsIHZpc2l0cyB5b3VyIGFkZHJlc3M8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtY2FyZFwiIChjbGljayk9XCJzZWxlY3RNb2RlKCdWSURFT19DQUxMJylcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1oZWFkZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtaWNvblwiPjxtYXQtaWNvbj52aWRlb2NhbTwvbWF0LWljb24+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWluZm9cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLXRpdGxlXCI+VmlkZW8gY29uc3VsdGF0aW9uPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWRlc2NyaXB0aW9uXCI+Q29ubmVjdCBvdmVyIGEgdmlkZW8gY2FsbDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbjwvbmctdGVtcGxhdGU+XHJcblxyXG48bmctdGVtcGxhdGUgI3NlcnZpY2VMaXN0aW5nPlxyXG4gICAgPGRpdiBjbGFzcz1cInctNjAgc2VydmljZV9zZWN0aW9uXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2Utc2VsZWN0aW9uXCI+XHJcbiAgICAgICAgICAgIDxoMj5TZWxlY3QgYSBTZXJ2aWNlPC9oMj5cclxuICAgICAgICAgICAgPHA+Q2hvb3NlIHRoZSBzZXJ2aWNlKHMpIHlvdSdkIGxpa2UgdG8gYm9vazxzcGFuICpuZ0lmPVwiY2FydFNlcnZpY2VzLmxlbmd0aCA+IDBcIj4g4oCUIHt7Y2FydFNlcnZpY2VzLmxlbmd0aH19IHNlbGVjdGVkPC9zcGFuPjwvcD5cclxuICAgICAgICAgICAgPHAgKm5nSWY9XCJwcm9kdWN0Q2FydEl0ZW1zLmxlbmd0aCA+IDBcIiBjbGFzcz1cImNhcnQtaGludFwiPnt7cHJvZHVjdENhcnRJdGVtcy5sZW5ndGh9fSBwcm9kdWN0KHMpIGFscmVhZHkgaW4geW91ciBjYXJ0IOKAlCB5b3UgY2FuIGNvbnRpbnVlIHdpdGhvdXQgcGlja2luZyBhIHNlcnZpY2UuPC9wPlxyXG5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2VzLWdyaWRcIj5cclxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHNlcnZpY2Ugb2Ygc2VydmljZURhdGFcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiXCIgKGNsaWNrKT1cInNlbGVjdFNlcnZpY2Uoc2VydmljZSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdzZXJ2aWNlLWNhcmQtc2VsZWN0ZWQnIDogc2VydmljZT8uc2VsZWN0ZWQsICdzZXJ2aWNlLWNhcmQnOiAhc2VydmljZT8uc2VsZWN0ZWQgfVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiIHNlcnZpY2UtaGVhZGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1pY29uXCI+PG1hdC1pY29uPnBlcnNvbl9vdXRsaW5lPC9tYXQtaWNvbj48L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWluZm9cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS10aXRsZVwiPnt7c2VydmljZT8ubmFtZSA/IHNlcnZpY2U/Lm5hbWUgOiAnTi9BJ319PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcnZpY2UtcHJpY2VcIj7igrl7e3NlcnZpY2U/LnByaWNlRGV0YWlscz8ucHJpY2UgP1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2aWNlPy5wcmljZURldGFpbHM/LnByaWNlIDogJ04vQScgfX08L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VydmljZS1kdXJhdGlvblwiPnt7c2VydmljZT8uZHVyYXRpb24gPyBzZXJ2aWNlPy5kdXJhdGlvbiA6ICdOL0EnfX0gbWluXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJ2aWNlLWRlc2NyaXB0aW9uXCIgKm5nSWY9XCJzZXJ2aWNlPy5kZXNjcmlwdGlvblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3tzZXJ2aWNlPy5kZXNjcmlwdGlvbiA/IHNlcnZpY2U/LmRlc2NyaXB0aW9uIDogJ04vQSd9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhvbWUtdmlzaXRcIiAqbmdJZj1cInNlbGVjdGVkTW9kZSA9PT0gJ1NUT1JFX1ZJU0lUJyAmJiBzZXJ2aWNlPy5ob21lQXBwb2ludG1lbnRBdmFpbGFibGVcIj48aW1nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjPVwiaHR0cHM6Ly9kMno5NDk3eHA4eGIxMi5jbG91ZGZyb250Lm5ldC9wcm9kLWltYWdlcy85ODIxMjZjMTc1ODYyODg2MzEyOWZ1cm5pdHVyZV8xNjQwNjEwMy5wbmdcIj5Ib21lXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWaXNpdCBBdmFpbGFibGU8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG48L25nLXRlbXBsYXRlPlxyXG5cclxuPG5nLXRlbXBsYXRlICNsb2NhdGlvbkxpc3Rpbmc+XHJcbiAgICA8ZGl2IGNsYXNzPVwibG9jYXRpb25fc2VjdGlvblwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXIgZmxleC1jb2x1bW4gYWxpZ24taXRlbXMtc3RhcnRcIj5cclxuICAgICAgICAgICAgPGgxPkNob29zZSBMb2NhdGlvbjwvaDE+XHJcbiAgICAgICAgICAgIDxwPlNlbGVjdCB3aGVyZSB5b3UnZCBsaWtlIHRvIHJlY2VpdmUgdGhlIHNlcnZpY2U8L3A+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJsb2NhdGlvbi1saXN0XCI+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGxvY2F0aW9uIG9mIGxvY2F0aW9uRGF0YVwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiAoY2xpY2spPVwic2VsZWN0TG9jYXRpb24obG9jYXRpb24pXCJcclxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdsb2NhdGlvbi1jYXJkLXNlbGVjdGVkJyA6IGxvY2F0aW9uPy5zZWxlY3RlZCwgJ2xvY2F0aW9uLWNhcmQnOiAhbG9jYXRpb24/LnNlbGVjdGVkIH1cIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9jYXRpb24tY29udGVudFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9jYXRpb24taW5mb1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxvY2F0aW9uLWljb25cIj48aW1nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyYz1cImh0dHBzOi8vZDJ6OTQ5N3hwOHhiMTIuY2xvdWRmcm9udC5uZXQvcHJvZC1pbWFnZXMvNDI3MjI2YzE3NTg2MjkxNTc3NThzdG9yZV8zMTcxNTEwLnBuZ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibG9jYXRpb24tZGV0YWlsc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMz57e2xvY2F0aW9uPy5zdG9yZU5hbWUgPyBsb2NhdGlvbj8uc3RvcmVOYW1lIDogJ04vQSd9fTwvaDM+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHA+e3tsb2NhdGlvbj8uYWRkcmVzc0RldGFpbHM/LmFkZHJlc3NMaW5lfX0sIHt7bG9jYXRpb24/LmFkZHJlc3NEZXRhaWxzPy5jaXR5fX0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7bG9jYXRpb24/LmFkZHJlc3NEZXRhaWxzPy5zdGF0ZX19IHt7bG9jYXRpb24/LnBpbmNvZGV9fTwvcD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG48L25nLXRlbXBsYXRlPlxyXG5cclxuPG5nLXRlbXBsYXRlICNzdGFmZkxpc3Rpbmc+XHJcbiAgICA8ZGl2IGNsYXNzPVwidy02MCBvdmVyZmxvdy1oaWRkZW4gc3RhZmYtbGlzdGluZ1wiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggdy0xMDAgaC0xMDBcIj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctMTAwXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhZmYtaGVhZGVyIG1iLTNcIj5cclxuICAgICAgICAgICAgICAgICAgICA8aDE+U2VsZWN0IFN0YWZmIE1lbWJlcjwvaDE+XHJcbiAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJzdGFmZi1zdWJ0aXRsZSBtYi0wXCI+Q2hvb3NlIHlvdXIgcHJlZmVycmVkIHByb2Zlc3Npb25hbDwvcD5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWFyY2gtY29udGFpbmVyIG1iLTRcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VhcmNoLWlucHV0LXdyYXBwZXIgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJzZWFyY2gtaWNvbiBtZS0yXCI+c2VhcmNoPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJzZWFyY2gtaW5wdXQgYm9yZGVyLTAgZmxleC1ncm93LTFcIiBwbGFjZWhvbGRlcj1cIlNlYXJjaCBzdGFmZiBtZW1iZXIgYnkgbmFtZS4uLlwiIFsobmdNb2RlbCldPVwic3RhZmZTZWFyY2hRdWVyeVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjbGVhci1pY29uIGN1cnNvci1wb2ludGVyIG1zLTJcIiAqbmdJZj1cInN0YWZmU2VhcmNoUXVlcnlcIiAoY2xpY2spPVwic3RhZmZTZWFyY2hRdWVyeSA9ICcnXCI+Y2xvc2U8L21hdC1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgPCEtLSBQdXJlIHByb2R1Y3Qtb25seSBsaW5lOiBvbmUgZmxhdCBzdGFmZiBsaXN0LCBzYW1lIGFzIHRoZSBvbGQgc2luZ2xlLXNlcnZpY2UgZmxvdyAtLT5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGFmZi1saXN0XCIgKm5nSWY9XCJjYXJ0U2VydmljZXMubGVuZ3RoID09PSAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3RhZmYgb2YgZmlsdGVyZWRTdGFmZlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZCByb3VuZGVkLTMgcC0zXCIgKGNsaWNrKT1cInNlbGVjdFN0YWZmRm9yUHJvZHVjdE9ubHlMaW5lKHN0YWZmKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdzdGFmZi1jYXJkLXNlbGVjdGVkJyA6IHN0YWZmPy5zZWxlY3RlZCwgJ3N0YWZmLWNhcmQnOiAhc3RhZmY/LnNlbGVjdGVkIH1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1iZXR3ZWVuIHctMTAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZmxleC1ncm93LTFcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0YWZmLWF2YXRhciByb3VuZGVkLWNpcmNsZSBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXIgbWUtNFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tzdGFmZj8uc3RhZmZOYW1lLnNsaWNlKDAsMikudG9VcHBlckNhc2UoKX19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhZmYtZGV0YWlscyBmbGV4LWdyb3ctMVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwic3RhZmYtbmFtZVwiPnt7KHN0YWZmPy5zdGFmZk5hbWUgPyBzdGFmZj8uc3RhZmZOYW1lIDogJ04vQScpIHwgdGl0bGVjYXNlfX08L2gzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJzdGFmZi1zcGVjaWFsdHlcIj57eyhidXNpbmVzc05hbWUgJiYgYnVzaW5lc3NOYW1lICE9PSAnTi9BJykgPyBidXNpbmVzc05hbWUgOiAnQm9va2luZyBTcGVjaWFsaXN0J319PC9wPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VsZWN0aW9uLWluZGljYXRvclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2hlY2ttYXJrLWNpcmNsZS1taW5pIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiIFtjbGFzcy5zZWxlY3RlZF09XCJzdGFmZj8uc2VsZWN0ZWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cInN0YWZmPy5zZWxlY3RlZFwiPmNoZWNrPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICA8IS0tIEJ1bmRsZWQgY2FydDogb25lIHBvb2wgcGVyIGxpbmUgdGhhdCByZXNvbHV0aW9uIGNvdWxkbid0IGNvbGxhcHNlIHRvIGEgc2luZ2xlIHByb3ZpZGVyIC0tPlxyXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNhcnRTZXJ2aWNlcy5sZW5ndGggPiAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0YWZmLWxpbmUtZ3JvdXAgbWItNFwiICpuZ0Zvcj1cImxldCBsaW5lIG9mIHJlc29sdmVkTGluZXNcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxpbmUuY2FuZGlkYXRlU3RhZmZQb29sPy5sZW5ndGhcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoNCBjbGFzcz1cIm1iLTJcIj5Gb3Ige3tsaW5lLnNlcnZpY2VzLmxlbmd0aH19IHNlcnZpY2Uocyk6IHt7IChsaW5lLnNlcnZpY2VzIHwgc2xpY2U6MDozKS5sZW5ndGggPyAnJyA6ICcnIH19PHNwYW4gKm5nRm9yPVwibGV0IHMgb2YgbGluZS5zZXJ2aWNlczsgbGV0IGxhc3QgPSBsYXN0XCI+e3tzLm5hbWV9fXt7bGFzdCA/ICcnIDogJywgJ319PC9zcGFuPjwvaDQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhZmYtbGlzdCBtYi0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgc3RhZmYgb2YgbGluZS5jYW5kaWRhdGVTdGFmZlBvb2xcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQgcm91bmRlZC0zIHAtM1wiIChjbGljayk9XCJzZWxlY3RTdGFmZkZvckxpbmUobGluZSwgc3RhZmYpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ3N0YWZmLWNhcmQtc2VsZWN0ZWQnIDogbGluZS5zZWxlY3RlZFN0YWZmSWQgPT09IHN0YWZmLmlkLCAnc3RhZmYtY2FyZCc6IGxpbmUuc2VsZWN0ZWRTdGFmZklkICE9PSBzdGFmZi5pZCB9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiB3LTEwMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGZsZXgtZ3Jvdy0xXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGFmZi1hdmF0YXIgcm91bmRlZC1jaXJjbGUgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyIG1lLTRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7c3RhZmY/Lm5hbWU/LnNsaWNlKDAsMik/LnRvVXBwZXJDYXNlKCl9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0YWZmLWRldGFpbHMgZmxleC1ncm93LTFcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cInN0YWZmLW5hbWVcIj57eyhzdGFmZj8ubmFtZSA/IHN0YWZmPy5uYW1lIDogJ04vQScpIHwgdGl0bGVjYXNlfX08L2gzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VsZWN0aW9uLWluZGljYXRvclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2hlY2ttYXJrLWNpcmNsZS1taW5pIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiIFtjbGFzcy5zZWxlY3RlZF09XCJsaW5lLnNlbGVjdGVkU3RhZmZJZCA9PT0gc3RhZmYuaWRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiAqbmdJZj1cImxpbmUuc2VsZWN0ZWRTdGFmZklkID09PSBzdGFmZi5pZFwiPmNoZWNrPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuPC9uZy10ZW1wbGF0ZT5cclxuXHJcbjxuZy10ZW1wbGF0ZSAjZGF0ZVNlbGVjdGlvbj5cclxuICAgIDxkaXYgY2xhc3M9XCJ3LTYwIGRhdGVfc2VjdGlvblwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJyb3cganVzdGlmeS1jb250ZW50LWNlbnRlciBoLTEwMFwiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTEyIGgtMTAwXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGF0ZXRpbWUtaGVhZGVyIG1iLTJcIj5cclxuICAgICAgICAgICAgICAgICAgICA8aDE+U2VsZWN0IERhdGUgJiBUaW1lPC9oMT5cclxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cImRhdGV0aW1lLXN1YnRpdGxlIG1iLTBcIj5DaG9vc2Ugd2hlbiB5b3UnZCBsaWtlIHlvdXIgYXBwb2ludG1lbnQ8L3A+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGdhcC00IG1haW5fY29udGFpbmVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJ7J3ctNTAnIDogc2NyZWVuV2lkdGggPiA0NzUgLCAndy0xMDAnOnNjcmVlbldpZHRoIDwgNDc1fVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbi1jYXJkIGNhcmQgcm91bmRlZC0zIHAtNCBoLTEwMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwic2VjdGlvbi10aXRsZVwiPlNlbGVjdCBEYXRlPC9oMz5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGF0ZS1waWNrZXItY29udGFpbmVyIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWJldHdlZW5cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImRhdGUtaW5wdXQgYm9yZGVyLTAgcm91bmRlZC0yXCIgcGxhY2Vob2xkZXI9XCJkZC1tbS15eXl5XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInNlbGVjdGVkRGF0ZVN0clwiIHJlYWRvbmx5IChjbGljayk9XCJ0b2dnbGVDYWxlbmRhcigkZXZlbnQpXCI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIm1zLTJcIiAoY2xpY2spPVwidG9nZ2xlQ2FsZW5kYXIoJGV2ZW50KVwiPmNhbGVuZGFyX3RvZGF5PC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBvc2l0aW9uLXJlbGF0aXZlXCIgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkYXRlcGlja2VyLXBvcG92ZXJcIiAqbmdJZj1cInNob3dDYWxlbmRhclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWNhbGVuZGFyIFsoc2VsZWN0ZWQpXT1cInNlbGVjdGVkRGF0ZVwiIFtkYXRlRmlsdGVyXT1cImRhdGVGaWx0ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlbGVjdGVkQ2hhbmdlKT1cIm9uRGF0ZVNlbGVjdGVkKCRldmVudClcIiBjbGFzcz1cImRhdGVwaWNrZXItY2FsZW5kYXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2FsZW5kYXI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gT25lIHNsb3QtcGlja2VyIHBlciByZXNvbHZlZCBsaW5lLCBzaWRlIGJ5IHNpZGUgd2hlbiB0aGVyZSdzIG1vcmUgdGhhbiBvbmUgKGRlc2lnbiBkb2MgwqczYikgLS0+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWVfc2VsZWN0aW9uXCIgW25nQ2xhc3NdPVwieyd3LTUwJyA6IHNjcmVlbldpZHRoID4gNDc1ICwgJ3ctMTAwJzpzY3JlZW5XaWR0aCA8IDQ3NX1cIiAqbmdJZj1cInJlc29sdmVkTGluZXMubGVuZ3RoIDw9IDFcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlY3Rpb24tY2FyZCBjYXJkIGgtMTAwIHJvdW5kZWQtMyBwLTRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cInNlY3Rpb24tdGl0bGVcIj5BdmFpbGFibGUgVGltZXM8L2gzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvdyBnLTIgbWItNCBvdmVyZmxvdy1zY3JvbGxcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXNrZWxldG9uTG9hZGVyICYmIHJlc29sdmVkTGluZXNbMF1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC00XCIgKm5nRm9yPVwibGV0IHRpbWUgb2YgcmVzb2x2ZWRMaW5lc1swXS5zbG90c1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWUtc2xvdCByb3VuZGVkLTJcIiBbY2xhc3Muc2VsZWN0ZWRdPVwidGltZS5zZWxlY3RlZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdFNsb3RGb3JMaW5lKHJlc29sdmVkTGluZXNbMF0sIHRpbWUpXCI+e3t0aW1lID8gdGltZT8udmFsdWUgOiAnTi9BJ319PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgPCEtLSBNdWx0aS1saW5lIGNhc2U6IGVhY2ggbGluZSBnZXRzIGl0cyBvd24gZnVsbC13aWR0aCBjYXJkIHdpdGggYSBzdGFmZiBoZWFkZXIgLS0+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGdhcC00IG1haW5fY29udGFpbmVyIGZsZXgtd3JhcFwiICpuZ0lmPVwicmVzb2x2ZWRMaW5lcy5sZW5ndGggPiAxXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctMTAwXCIgKm5nRm9yPVwibGV0IGxpbmUgb2YgcmVzb2x2ZWRMaW5lc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbi1jYXJkIGNhcmQgcm91bmRlZC0zIHAtNFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwic2VjdGlvbi10aXRsZVwiPlByb2Zlc3Npb25hbDoge3tsaW5lLnN0YWZmTmFtZSB8fCBsaW5lLnNlbGVjdGVkU3RhZmZOYW1lfX08L2gzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtYi0yXCIgKm5nSWY9XCJsaW5lLnNlcnZpY2VzLmxlbmd0aFwiPjxzcGFuICpuZ0Zvcj1cImxldCBzIG9mIGxpbmUuc2VydmljZXM7IGxldCBsYXN0ID0gbGFzdFwiPnt7cy5uYW1lfX17e2xhc3QgPyAnJyA6ICcsICd9fTwvc3Bhbj48L3A+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93IGctMiBtYi0yIG92ZXJmbG93LXNjcm9sbFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhbGluZS5zbG90c0xvYWRpbmdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC00XCIgKm5nRm9yPVwibGV0IHRpbWUgb2YgbGluZS5zbG90c1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRpbWUtc2xvdCByb3VuZGVkLTJcIiBbY2xhc3Muc2VsZWN0ZWRdPVwidGltZS5zZWxlY3RlZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdFNsb3RGb3JMaW5lKGxpbmUsIHRpbWUpXCI+e3t0aW1lID8gdGltZT8udmFsdWUgOiAnTi9BJ319PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbjwvbmctdGVtcGxhdGU+XHJcblxyXG48bmctdGVtcGxhdGUgI2NvbnRhY3REZXRhaWxzPlxyXG4gICAgPGRpdiBjbGFzcz1cInctNjAgY29udGFjdF9zZWN0aW9uXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRhY3QtaGVhZGVyIG1iLTJcIj5cclxuICAgICAgICAgICAgPGgxPkNvbnRhY3QgRGV0YWlsczwvaDE+XHJcbiAgICAgICAgICAgIDxwIGNsYXNzPVwiY29udGFjdC1zdWJ0aXRsZSBtYi0wXCI+UHJvdmlkZSB5b3VyIGNvbnRhY3QgaW5mb3JtYXRpb248L3A+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTMgZGV0YWlsc19jb250YWluZXIgZmxleC1jb2x1bW4gdy0xMDBcIj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtNFwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBbbmdDbGFzc109XCJ7J3ctNTAnIDogc2VsZWN0ZWRNb2RlID09PSAnSE9NRV9WSVNJVCcsICd3LTEwMCcgOiBzZWxlY3RlZE1vZGUgIT09ICdIT01FX1ZJU0lUJ31cIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1zZWN0aW9uIGNhcmQgcm91bmRlZC0zIHAtNCBoLTEwMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJzZWN0aW9uLXRpdGxlXCI+UGVyc29uYWwgSW5mb3JtYXRpb248L2gzPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZ1bGwgTmFtZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVxdWlyZWQtYXN0ZXJpc2tcIj4qPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5uYW1lXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJjaGVja1JlcXVpcmVkVmFsdWVzKClcIiBzaW1wb0xldHRlcnNPbmx5PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi00XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbWFpbCBBZGRyZXNzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZXF1aXJlZC1hc3Rlcmlza1wiPio8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJlbWFpbFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5lbWFpbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiY2hlY2tSZXF1aXJlZFZhbHVlcygpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuPVwiXlthLXowLTkuXyUrLV0rQFthLXowLTkuLV0rXFwuW2Etel17Miw0fSRcIiAjZW1haWxGaWVsZD1cIm5nTW9kZWxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJlbWFpbFwiIHJlcXVpcmVkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0wXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQaG9uZSBOdW1iZXJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJlcXVpcmVkLWFzdGVyaXNrXCI+Kjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRlbFwiIGNsYXNzPVwiZm9ybS1jb250cm9sICByb3VuZGVkLTJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiYXBwb2ludG1lbnRQYXlsb2FkLmN1c3RvbWVyRGV0YWlsLnBob25lTnVtYmVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJjaGVja1JlcXVpcmVkVmFsdWVzKClcIiBzaW1wb051bWJlcnNPbmx5XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieydtb2JpbGVfbnVtYmVyJyA6IGFwcG9pbnRtZW50UGF5bG9hZC5jdXN0b21lckRldGFpbC5waG9uZU51bWJlci5sZW5ndGggIT0gMTB9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8IS0tIEhvbWUgVmlzaXQgYWRkcmVzcyAtIHN0cnVjdHVyZWQgZmllbGRzIG1hdGNoaW5nIEJvb2tpbmdHcm91cFJlcXVlc3QuYWRkcmVzc0RldGFpbHMgZXhhY3RseSAtLT5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LTUwXCIgKm5nSWY9XCJzZWxlY3RlZE1vZGUgPT09ICdIT01FX1ZJU0lUJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLXNlY3Rpb24gY2FyZCByb3VuZGVkLTMgcC00IGgtMTAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cInNlY3Rpb24tdGl0bGVcIj5Ib21lIFZpc2l0IERldGFpbHM8L2gzPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTNcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlJlY2VpdmVyIE5hbWU8L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1pbnB1dCByb3VuZGVkLTJcIiBbKG5nTW9kZWwpXT1cImhvbWVWaXNpdEFkZHJlc3MucmVjZWl2ZXJOYW1lXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItM1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbCBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+UmVjZWl2ZXIgUGhvbmU8L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZWxcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWlucHV0IHJvdW5kZWQtMlwiIHNpbXBvTnVtYmVyc09ubHkgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLnJlY2VpdmVyUGhvbmVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5BZGRyZXNzIExpbmUgMTwvbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWlucHV0IHJvdW5kZWQtMlwiIFsobmdNb2RlbCldPVwiaG9tZVZpc2l0QWRkcmVzcy5hZGRyZXNzTGluZTFcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5BZGRyZXNzIExpbmUgMiAob3B0aW9uYWwpPC9sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCIgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLmFkZHJlc3NMaW5lMlwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtMiBtYi0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidy01MFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPkNpdHk8L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0taW5wdXQgcm91bmRlZC0yXCIgWyhuZ01vZGVsKV09XCJob21lVmlzaXRBZGRyZXNzLmNpdHlcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctNTBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5TdGF0ZTwvbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1pbnB1dCByb3VuZGVkLTJcIiBbKG5nTW9kZWwpXT1cImhvbWVWaXNpdEFkZHJlc3Muc3RhdGVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTNcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlBpbmNvZGU8L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1pbnB1dCByb3VuZGVkLTJcIiBzaW1wb051bWJlcnNPbmx5IFsobmdNb2RlbCldPVwiaG9tZVZpc2l0QWRkcmVzcy56aXBDb2RlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbCBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+U3BlY2lhbCBJbnN0cnVjdGlvbnM8L2xhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0tdGV4dGFyZWEgcm91bmRlZC0yXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkFueSBzcGVjaWFsIGluc3RydWN0aW9ucyBmb3IgdGhlIHByb2Zlc3Npb25hbCAob3B0aW9uYWwpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImluc3RydWN0aW9uc1wiPjwvdGV4dGFyZWE+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWNpZXMtY29udGFpbmVyXCJcclxuICAgICAgICAgICAgICAgICpuZ0lmPVwiY2FydFNlcnZpY2VzWzBdPy5jYW5jZWxsYXRpb25Qb2xpY3k/Lmxlbmd0aCA+IDAgfHwgY2FydFNlcnZpY2VzWzBdPy5yZXNjaGVkdWxlUG9saWN5Py5sZW5ndGhcIj5cclxuICAgICAgICAgICAgICAgIDxoMiBjbGFzcz1cInBvbGljaWVzLXRpdGxlXCI+UG9saWNpZXMgJiBUZXJtczwvaDI+XHJcblxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBvbGljeS1pdGVtcy1jb250YWluZXIgZC1mbGV4IGZsZXgtY29sdW1uIGdhcC0zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBvbGljeS1pdGVtIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2hvd0NhbmNlbGxhdGlvblBvbGljeSA9ICFzaG93Q2FuY2VsbGF0aW9uUG9saWN5XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cInBvbGljeS10aXRsZVwiPkNhbmNlbGxhdGlvbiBQb2xpY3k8L2gzPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicG9saWN5LWFycm93IGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiPjxtYXQtaWNvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIXNob3dDYW5jZWxsYXRpb25Qb2xpY3lcIj5rZXlib2FyZF9hcnJvd19yaWdodDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJzaG93Q2FuY2VsbGF0aW9uUG9saWN5XCI+a2V5Ym9hcmRfYXJyb3dfZG93bjwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW5jZWxsYXRpb25fcG9saWNpZXMgZC1mbGV4IGZsZXgtY29sdW1uIGdhcC0yIGZ3LTUwMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwic2hvd0NhbmNlbGxhdGlvblBvbGljeVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdGb3I9XCJsZXQgcG9saWN5IG9mIGNhcnRTZXJ2aWNlc1swXT8uY2FuY2VsbGF0aW9uUG9saWN5XCI+JiM4MjI2O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3twb2xpY3l9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBvbGljeS1pdGVtIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2hvd1JlZHVjaW5nUG9saWN5ID0gIXNob3dSZWR1Y2luZ1BvbGljeVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8aDMgY2xhc3M9XCJwb2xpY3ktdGl0bGVcIj5SZXNjaGVkdWxpbmcgUG9saWN5PC9oMz5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBvbGljeS1hcnJvdyBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXJcIj48bWF0LWljb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFzaG93UmVkdWNpbmdQb2xpY3lcIj5rZXlib2FyZF9hcnJvd19yaWdodDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWljb24gKm5nSWY9XCJzaG93UmVkdWNpbmdQb2xpY3lcIj5rZXlib2FyZF9hcnJvd19kb3duPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhbmNlbGxhdGlvbl9wb2xpY2llcyBkLWZsZXggZmxleC1jb2x1bW4gZ2FwLTIgZnctNTAwXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJzaG93UmVkdWNpbmdQb2xpY3lcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nRm9yPVwibGV0IHBvbGljeSBvZiBjYXJ0U2VydmljZXNbMF0/LnJlc2NoZWR1bGVQb2xpY3lcIj4mIzgyMjY7IHt7cG9saWN5fX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWNjZXB0YW5jZS1zZWN0aW9uXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwiY3VzdG9tLWNoZWNrYm94XCIgWyhuZ01vZGVsKV09XCJ0ZXJtc0FuZENvbmRpdGlvbnNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJjaGVja1JlcXVpcmVkVmFsdWVzKClcIj5cclxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cImFjY2VwdGFuY2UtdGV4dFwiIHN0eWxlPVwibWFyZ2luLWJvdHRvbTowcHggIWltcG9ydGFudFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBJIHVuZGVyc3RhbmQgYW5kIGFjY2VwdCB0aGUgY2FuY2VsbGF0aW9uICYgcmVzY2hlZHVsaW5nIHBvbGljaWVzLlxyXG4gICAgICAgICAgICAgICAgICAgIDwvcD5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG48L25nLXRlbXBsYXRlPlxyXG5cclxuPG5nLXRlbXBsYXRlICNwYXltZW50VGFiPlxyXG4gICAgPGRpdiBjbGFzcz1cInctNjAgcGF5bWVudF9zZWN0aW9uXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInctMTAwIGgtMTAwXCI+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LTEwMCBkLWZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlciBhbGlnbi1pdGVtcy1jZW50ZXIgZmxleC1jb2x1bW5cIj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYXltZW50LWhlYWRlciBtYi0zIHctMTAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGgxIHN0eWxlPVwiZm9udC1zaXplOjI0cHg7Zm9udC13ZWlnaHQ6IDYwMDtcIj5Cb29raW5nIFN1bW1hcnk8L2gxPlxyXG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwicGF5bWVudC1zdWJ0aXRsZSBtYi0wXCI+UmV2aWV3IHlvdXIgYm9va2luZyBiZWZvcmUgY29uZmlybWluZzwvcD5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJib29raW5nLXN1bW1hcnktY2FyZFwiIFtuZ0NsYXNzXT1cInsndy0xMDAnIDogc2NyZWVuV2lkdGggPCA0NzUsJ3ctNTAnOnNjcmVlbldpZHRoID4gNDc1fVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGxpbmUgb2YgcmVzb2x2ZWRMaW5lczsgbGV0IGkgPSBpbmRleFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8aDIgY2xhc3M9XCJzdW1tYXJ5LXRpdGxlXCIgKm5nSWY9XCJyZXNvbHZlZExpbmVzLmxlbmd0aCA+IDFcIj5MaW5lIHt7aSArIDF9fTwvaDI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXJvd1wiICpuZ0lmPVwibGluZS5zZXJ2aWNlcy5sZW5ndGhcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+U2VydmljZShzKTwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj48c3BhbiAqbmdGb3I9XCJsZXQgcyBvZiBsaW5lLnNlcnZpY2VzOyBsZXQgbGFzdCA9IGxhc3RcIj57e3MubmFtZX19e3tsYXN0ID8gJycgOiAnLCAnfX08L3NwYW4+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1yb3dcIiAqbmdJZj1cImxpbmUuc3RhZmZOYW1lIHx8IGxpbmUuc2VsZWN0ZWRTdGFmZk5hbWVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+UHJvZmVzc2lvbmFsPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS12YWx1ZVwiPnt7bGluZS5zdGFmZk5hbWUgfHwgbGluZS5zZWxlY3RlZFN0YWZmTmFtZX19PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1yb3dcIiAqbmdJZj1cInNlbGVjdGVkTW9kZSA9PT0gJ1NUT1JFX1ZJU0lUJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5Mb2NhdGlvbjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj57e3NlbGVjdGVkTG9jYXRpb24/LnN0b3JlTmFtZSA/PyAnTi9BJ319PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1yb3dcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+RGF0ZSAmIFRpbWU8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+e3tzZWxlY3RlZERhdGVTdHJ9fSBhdCB7e2xpbmUuc2VsZWN0ZWRTbG90Py52YWx1ZSA/PyAnTi9BJ319PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvZHVjdENhcnRJdGVtcy5sZW5ndGggPiAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxoMiBjbGFzcz1cInN1bW1hcnktdGl0bGVcIj5Qcm9kdWN0czwvaDI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXJvd1wiICpuZ0Zvcj1cImxldCBwIG9mIHByb2R1Y3RDYXJ0SXRlbXNcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+e3twLml0ZW1OYW1lfX0geHt7cC5xdWFudGl0eX19PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS12YWx1ZVwiPjxzcGFuIGNsYXNzPVwiY3VycmVuY3ktc3ltYm9sXCI+4oK5PC9zcGFuPnt7KHAuc2VsbGluZ1ByaWNlID8/IHAucHJpY2UgPz8gMCkgKiAocC5xdWFudGl0eSA/PyAxKX19PC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbjwvbmctdGVtcGxhdGU+XHJcblxyXG48bmctdGVtcGxhdGUgI3N0YXR1c1RlbXBsYXRlPlxyXG4gICAgPGRpdiBjbGFzcz1cImJvb2tpbmctY29uZmlybWF0aW9uXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInN1Y2Nlc3MtaWNvblwiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2hlY2ttYXJrLWNpcmNsZVwiPlxyXG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCJodHRwczovL2Qyejk0OTd4cDh4YjEyLmNsb3VkZnJvbnQubmV0L3Byb2QtaW1hZ2VzLzg4MTI5M2MxNzU4Njk1NTc4NTE4c3VjY2Vzcy5naWZcIlxyXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy0xMDAgaC0xMDBcIiAqbmdJZj1cImFwaVN0YXR1c1wiPlxyXG4gICAgICAgICAgICAgICAgPGltZyBzcmM9XCJodHRwczovL2Qyejk0OTd4cDh4YjEyLmNsb3VkZnJvbnQubmV0L3Byb2QtaW1hZ2VzLzMyNTAwMGMxNzU4Njk1NTY0NTE4ZmFpbC5naWZcIlxyXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidy0xMDAgaC0xMDBcIiAqbmdJZj1cIiFhcGlTdGF0dXNcIj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb25maXJtYXRpb24tY29udGVudFwiPlxyXG4gICAgICAgICAgICA8aDEgY2xhc3M9XCJjb25maXJtYXRpb24tdGl0bGVcIj57e2FwaVN0YXR1cyA/ICdCb29raW5nIENvbmZpcm1lZCEnIDogJ0Jvb2tpbmcgRmFpbGVkJ319PC9oMT5cclxuICAgICAgICAgICAgPHAgY2xhc3M9XCJjb25maXJtYXRpb24tbWVzc2FnZVwiPlxyXG4gICAgICAgICAgICAgICAge3thcGlTdGF0dXMgPyAnWW91ciBhcHBvaW50bWVudCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYm9va2VkLic6J0ZhaWxlZCB0byBib29rIHlvdSBhcHBvaW50bWVudC4gUGxlYXNlXHJcbiAgICAgICAgICAgICAgICB0cnkgYWdhaW4gbGF0ZXInfX1cclxuICAgICAgICAgICAgPC9wPlxyXG5cclxuICAgICAgICAgICAgPCEtLSBWaWRlbyBDYWxsIGxpbmssIHdoZW4gYWxyZWFkeSBwcmVzZW50IG9uIHRoZSBjb25maXJtZWQgZ3JvdXAgKGEgcGFpZCBWaWRlbyBDYWxsJ3NcclxuICAgICAgICAgICAgICAgICBsaW5rIG9ubHkgYXBwZWFycyBvbmNlIHBheW1lbnQgdmVyaWZpY2F0aW9uIGNvbXBsZXRlcywgaGFuZGxlZCBlbHNld2hlcmUgLSBzZWVcclxuICAgICAgICAgICAgICAgICB2ZXJpZnktcGF5bWVudC5jb21wb25lbnQudHMsIG5vdCB0aGlzIHNjcmVlbikuIC0tPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidmlkZW8tY2FsbC1saW5rLWNhcmQgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCIgKm5nSWY9XCJhcGlTdGF0dXMgJiYgc2VsZWN0ZWRNb2RlID09PSAnVklERU9fQ0FMTCcgJiYgYm9va2luZ0dyb3VwPy52aWRlb0NhbGxMaW5rXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlscy1jYXJkXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwiZGV0YWlscy10aXRsZVwiPllvdXIgVmlkZW8gQ2FsbCBMaW5rPC9oMz5cclxuICAgICAgICAgICAgICAgICAgICA8YSBbaHJlZl09XCJib29raW5nR3JvdXAudmlkZW9DYWxsTGlua1wiIHRhcmdldD1cIl9ibGFua1wiPnt7Ym9va2luZ0dyb3VwLnZpZGVvQ2FsbExpbmt9fTwvYT5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggdy0xMDAgYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXJcIiAqbmdJZj1cImFwaVN0YXR1c1wiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbHMtY2FyZFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cImRldGFpbHMtdGl0bGVcIj5BcHBvaW50bWVudCBEZXRhaWxzPC9oMz5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGV0YWlscy1yb3dcIiAqbmdGb3I9XCJsZXQgbGluZSBvZiByZXNvbHZlZExpbmVzXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+e3tsaW5lLnNlcnZpY2VzLmxlbmd0aCA/IChsaW5lLnNlcnZpY2VzWzBdLm5hbWUpIDogJ1Byb2R1Y3RzJ319PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC12YWx1ZVwiPnt7c2VsZWN0ZWREYXRlU3RyfX0gYXQge3tsaW5lLnNlbGVjdGVkU2xvdD8udmFsdWUgPz8gJ04vQSd9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG48L25nLXRlbXBsYXRlPlxyXG4iXX0=