@onepercentio/one-ui 1.3.5 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/WebpackConfigs/email-templates.js +99 -0
  2. package/dist/components/AdaptiveButton/AdaptiveButton.js +26 -24
  3. package/dist/components/AdaptiveButton/index.js +25 -22
  4. package/dist/components/AdaptiveContainer/AdaptiveContainer.js +140 -139
  5. package/dist/components/AdaptiveContainer/index.js +25 -22
  6. package/dist/components/AdaptiveDialog/AdaptiveDialog.js +76 -42
  7. package/dist/components/AdaptiveDialog/AdaptiveDialog.module.scss +17 -3
  8. package/dist/components/AdaptiveDialog/index.js +25 -22
  9. package/dist/components/AdaptiveSidebar/AdaptiveSidebar.js +70 -54
  10. package/dist/components/AdaptiveSidebar/AdaptiveSidebar.sample.js +10 -9
  11. package/dist/components/AdaptiveSidebar/index.js +25 -22
  12. package/dist/components/AnchoredTooltip/AnchoredTooltip.js +155 -154
  13. package/dist/components/AnchoredTooltip/AnchoredTooltip.module.scss +13 -10
  14. package/dist/components/AnchoredTooltip/index.js +25 -22
  15. package/dist/components/AnimatedEntrance/AnimatedEntrance.js +154 -121
  16. package/dist/components/AnimatedEntrance/index.js +25 -22
  17. package/dist/components/AsyncTriggerContainer/AsyncTriggerContainer.js +80 -40
  18. package/dist/components/AsyncTriggerContainer/index.js +25 -22
  19. package/dist/components/AsyncWrapper/AsyncWrapper.js +34 -16
  20. package/dist/components/AsyncWrapper/index.js +25 -22
  21. package/dist/components/Avatar/Avatar.js +33 -18
  22. package/dist/components/Avatar/index.js +25 -22
  23. package/dist/components/BucketFill/BucketFill.js +49 -36
  24. package/dist/components/BucketFill/index.js +25 -22
  25. package/dist/components/Button/Button.js +30 -22
  26. package/dist/components/Button/index.js +25 -22
  27. package/dist/components/Card/Card.js +17 -10
  28. package/dist/components/Card/index.js +25 -22
  29. package/dist/components/Chart/Chart.js +25 -22
  30. package/dist/components/Chart/Chart.logic.js +10 -9
  31. package/dist/components/Chart/Chart.types.js +5 -2
  32. package/dist/components/Chart/Chart.view.js +174 -98
  33. package/dist/components/Chart/index.js +25 -22
  34. package/dist/components/CheckBox/CheckBox.js +48 -30
  35. package/dist/components/CheckBox/CheckBox.module.scss +5 -0
  36. package/dist/components/CheckBox/index.js +25 -22
  37. package/dist/components/CodeInput/CodeInput.js +75 -93
  38. package/dist/components/CodeInput/index.js +25 -22
  39. package/dist/components/Collapsable/Collapsable.js +164 -134
  40. package/dist/components/Collapsable/index.js +25 -22
  41. package/dist/components/Countdown/Countdown.js +69 -86
  42. package/dist/components/Countdown/index.js +25 -22
  43. package/dist/components/CurrencyInput/CurrencyInput.hook.js +25 -25
  44. package/dist/components/CurrencyInput/CurrencyInput.js +48 -29
  45. package/dist/components/CurrencyInput/index.js +25 -22
  46. package/dist/components/Divider/Divider.js +16 -10
  47. package/dist/components/Divider/index.js +25 -22
  48. package/dist/components/EmailInput/EmailInput.js +37 -23
  49. package/dist/components/EmailInput/index.js +25 -22
  50. package/dist/components/FadeIn/FadeIn.js +57 -51
  51. package/dist/components/FadeIn/index.js +25 -22
  52. package/dist/components/FileInput/FileInput.js +45 -38
  53. package/dist/components/FileInput/View/BigFactory/BigFactory.js +48 -16
  54. package/dist/components/FileInput/View/BigFactory/index.js +25 -22
  55. package/dist/components/FileInput/View/Compact/Compact.js +114 -46
  56. package/dist/components/FileInput/View/Compact/index.js +25 -22
  57. package/dist/components/FileInput/View/View.types.js +5 -2
  58. package/dist/components/FileInput/index.js +25 -22
  59. package/dist/components/FlowController/FlowController.js +56 -25
  60. package/dist/components/FlowController/index.js +25 -22
  61. package/dist/components/Form/Form.hook.js +217 -202
  62. package/dist/components/Form/Form.js +103 -65
  63. package/dist/components/Form/Form.types.js +39 -53
  64. package/dist/components/Form/FormField/Extensions/DateField/DateField.js +68 -53
  65. package/dist/components/Form/FormField/Extensions/DateField/index.js +25 -22
  66. package/dist/components/Form/FormField/Extensions/PhoneField/PhoneField.js +81 -78
  67. package/dist/components/Form/FormField/Extensions/PhoneField/index.js +25 -22
  68. package/dist/components/Form/FormField/FormField.js +307 -148
  69. package/dist/components/Form/FormField/FormField.types.js +10 -7
  70. package/dist/components/Form/FormField/index.js +25 -22
  71. package/dist/components/Form/index.js +25 -22
  72. package/dist/components/Freeze/Freeze.js +13 -9
  73. package/dist/components/Freeze/index.js +25 -22
  74. package/dist/components/HSForms/HSForms.js +48 -69
  75. package/dist/components/HSForms/index.js +25 -22
  76. package/dist/components/HeaderCloseBtn/HeaderCloseBtn.js +19 -10
  77. package/dist/components/HeaderCloseBtn/index.js +25 -22
  78. package/dist/components/InfinityScroll/InfinityScroll.js +114 -94
  79. package/dist/components/InfinityScroll/index.js +25 -22
  80. package/dist/components/Input/Input.js +99 -57
  81. package/dist/components/Input/index.js +25 -22
  82. package/dist/components/InstantCounter/InstantCounter.js +49 -31
  83. package/dist/components/InstantCounter/index.js +25 -22
  84. package/dist/components/LavaLamp/LavaLamp.data.js +83 -86
  85. package/dist/components/LavaLamp/LavaLamp.js +119 -32
  86. package/dist/components/LavaLamp/index.js +25 -22
  87. package/dist/components/LavaLamp/v2/LavaLamp.js +149 -156
  88. package/dist/components/LinkToId/LinkToId.js +39 -27
  89. package/dist/components/LinkToId/index.js +25 -22
  90. package/dist/components/Loader/Loader.js +21 -22
  91. package/dist/components/Loader/index.js +25 -22
  92. package/dist/components/LoaderDotsIndicator/LoaderDotsIndicator.js +27 -15
  93. package/dist/components/LoaderDotsIndicator/index.js +25 -22
  94. package/dist/components/LoopableVideo/LoopableVideo.js +33 -25
  95. package/dist/components/LoopableVideo/index.js +25 -22
  96. package/dist/components/MainGrid/MainGrid.js +46 -23
  97. package/dist/components/MainGrid/index.js +25 -22
  98. package/dist/components/MutableHamburgerButton/MutableHamburgerButton.js +27 -23
  99. package/dist/components/MutableHamburgerButton/index.js +25 -22
  100. package/dist/components/Notification/Notification.js +18 -11
  101. package/dist/components/Notification/index.js +25 -22
  102. package/dist/components/NumberInput/NumberInput.js +43 -42
  103. package/dist/components/NumberInput/index.js +25 -22
  104. package/dist/components/OrderableList/OrderableList.js +416 -404
  105. package/dist/components/OrderableList/index.js +25 -22
  106. package/dist/components/PaginationIndicator/PaginationIndicator.js +243 -198
  107. package/dist/components/PaginationIndicator/index.js +25 -22
  108. package/dist/components/Parallax/Parallax.js +156 -130
  109. package/dist/components/Parallax/index.js +25 -22
  110. package/dist/components/Parallax/math/helpers.js +120 -216
  111. package/dist/components/PasswordInput/PasswordInput.js +88 -71
  112. package/dist/components/PasswordInput/index.js +25 -22
  113. package/dist/components/PingPongText/PingPongText.js +63 -67
  114. package/dist/components/PingPongText/index.js +25 -22
  115. package/dist/components/PixelatedScan/PixelatedScan.js +126 -74
  116. package/dist/components/PixelatedScan/index.js +25 -22
  117. package/dist/components/Portal/Portal.js +46 -43
  118. package/dist/components/Portal/index.js +25 -22
  119. package/dist/components/ProgressBar/ProgressBar.js +105 -47
  120. package/dist/components/ProgressBar/index.js +25 -22
  121. package/dist/components/ProgressTexts/ProgressTexts.js +43 -29
  122. package/dist/components/ProgressTexts/index.js +25 -22
  123. package/dist/components/Radio/Radio.js +51 -28
  124. package/dist/components/Radio/index.js +25 -22
  125. package/dist/components/Radio/variants/Checkmark/Checkmark.js +18 -12
  126. package/dist/components/Radio/variants/Checkmark/index.js +25 -22
  127. package/dist/components/Radio/variants/Generic/Generic.js +20 -12
  128. package/dist/components/Radio/variants/Generic/index.js +25 -22
  129. package/dist/components/ScrollendIndicator/ScrollendIndicator.js +118 -0
  130. package/dist/components/ScrollendIndicator/ScrollendIndicator.module.scss +76 -0
  131. package/dist/components/SectionContainer/SectionContainer.js +38 -16
  132. package/dist/components/SectionContainer/index.js +25 -22
  133. package/dist/components/Select/Select.js +128 -95
  134. package/dist/components/Select/index.js +25 -22
  135. package/dist/components/Skeleton/Skeleton.js +22 -14
  136. package/dist/components/Skeleton/index.js +25 -22
  137. package/dist/components/Slider/Slider.js +63 -59
  138. package/dist/components/Slider/index.js +25 -22
  139. package/dist/components/Spacing/Spacing.js +25 -17
  140. package/dist/components/Spacing/index.js +25 -22
  141. package/dist/components/StaticScroller/StaticScroller.js +65 -61
  142. package/dist/components/StaticScroller/index.js +25 -22
  143. package/dist/components/Switch/Switch.js +40 -26
  144. package/dist/components/Switch/index.js +25 -22
  145. package/dist/components/Table/Table.js +107 -56
  146. package/dist/components/Table/index.js +25 -22
  147. package/dist/components/Tabs/Tabs.js +59 -54
  148. package/dist/components/Tabs/index.js +25 -22
  149. package/dist/components/Text/Text.js +35 -30
  150. package/dist/components/Text/index.js +25 -22
  151. package/dist/components/Transition/MasksFactory/DiagonalReveal.js +46 -12
  152. package/dist/components/Transition/MasksFactory/DiagonalSquareToBalls.js +71 -49
  153. package/dist/components/Transition/MasksFactory/PhysicsSquares.js +89 -79
  154. package/dist/components/Transition/MasksFactory/SquareToBalls.js +60 -41
  155. package/dist/components/Transition/MasksFactory/utils.js +25 -27
  156. package/dist/components/Transition/Transition.js +298 -319
  157. package/dist/components/Transition/index.js +25 -22
  158. package/dist/components/UncontrolledTransition/UncontrolledTransition.js +101 -93
  159. package/dist/components/UncontrolledTransition/UncontrolledTransition.sample.js +27 -19
  160. package/dist/components/UncontrolledTransition/index.js +25 -22
  161. package/dist/components/WalletConnectionWrapper/WalletConnectionWrapper.js +101 -94
  162. package/dist/components/WalletConnectionWrapper/index.js +25 -22
  163. package/dist/components/utilitary/ScrollAndFocusLock/ScrollAndFocusLock.js +53 -43
  164. package/dist/components/utilitary/ScrollAndFocusLock/index.js +25 -22
  165. package/dist/context/AsyncProcess.js +68 -41
  166. package/dist/context/ContextAsyncControl.js +72 -51
  167. package/dist/context/CustomBrowserRouter.js +44 -30
  168. package/dist/context/OneUIProvider.js +102 -108
  169. package/dist/hooks/logs/useDependencyChangeDetection.js +17 -16
  170. package/dist/hooks/logs/useIsMounting.js +10 -7
  171. package/dist/hooks/persistence/useLocalStorage.js +41 -40
  172. package/dist/hooks/shims/ObjectWatchShim.js +47 -46
  173. package/dist/hooks/ui/useAdaptiveImage.js +29 -34
  174. package/dist/hooks/ui/useAlternating.js +18 -18
  175. package/dist/hooks/ui/useBreakpoint.js +19 -18
  176. package/dist/hooks/ui/useCustomScrollbar.js +26 -21
  177. package/dist/hooks/ui/useEffectIf.js +11 -9
  178. package/dist/hooks/ui/useMouseHover.js +22 -19
  179. package/dist/hooks/ui/usePaginationControls.js +129 -136
  180. package/dist/hooks/ui/useSnapToViewport.js +20 -19
  181. package/dist/hooks/ui/useTilt.js +145 -129
  182. package/dist/hooks/ui/useZoomable.js +123 -116
  183. package/dist/hooks/useAsyncControl.js +67 -52
  184. package/dist/hooks/useContainedRepositioning.js +75 -71
  185. package/dist/hooks/useCustomHistory.js +21 -12
  186. package/dist/hooks/useElementFit.js +43 -48
  187. package/dist/hooks/useFirestoreWatch.js +41 -41
  188. package/dist/hooks/useFreeze.js +10 -8
  189. package/dist/hooks/useHero.js +249 -271
  190. package/dist/hooks/useIntersection.js +32 -27
  191. package/dist/hooks/useMergeRefs.js +27 -24
  192. package/dist/hooks/useObserve.js +17 -14
  193. package/dist/hooks/usePagination.js +147 -164
  194. package/dist/hooks/usePooledOperation.js +41 -57
  195. package/dist/hooks/usePooling.js +46 -49
  196. package/dist/hooks/useRebound.js +23 -19
  197. package/dist/hooks/useShortIntl.js +72 -50
  198. package/dist/hooks/utility/useAsyncMemo.js +36 -42
  199. package/dist/hooks/utility/useDepChange.js +14 -12
  200. package/dist/hooks/utility/useEvents.js +26 -21
  201. package/dist/hooks/utility/useImmediate.js +8 -5
  202. package/dist/hooks/utility/useManualInit.js +19 -17
  203. package/dist/hooks/utility/useModule.js +12 -9
  204. package/dist/hooks/utility/useQuery.js +13 -7
  205. package/dist/hooks/utility/useUniqueEffect.js +17 -17
  206. package/dist/index.js +2159 -349
  207. package/dist/index.preprocess.js +35 -72
  208. package/dist/models/DebugLogger.js +8 -5
  209. package/dist/models/GenericContract.js +42 -13
  210. package/dist/models/ImageScales.js +13 -10
  211. package/dist/models/Orbs.js +53 -47
  212. package/dist/storybookUtils/index.js +40 -39
  213. package/dist/type-utils.js +5 -2
  214. package/dist/types.js +5 -2
  215. package/dist/utils/blockchain.js +35 -54
  216. package/dist/utils/e2e.js +21 -11
  217. package/dist/utils/flatten.js +15 -12
  218. package/dist/utils/formatters.js +48 -43
  219. package/dist/utils/html.utils.js +12 -6
  220. package/dist/utils/ownEvent.js +9 -7
  221. package/dist/utils/test.js +13 -11
  222. package/dist-ts/components/ScrollendIndicator/ScrollendIndicator.d.ts +10 -0
  223. package/dist-ts/components/ScrollendIndicator/ScrollendIndicator.js +68 -0
  224. package/dist-ts/components/ScrollendIndicator/ScrollendIndicator.js.map +1 -0
  225. package/dist-ts/components/ScrollendIndicator/ScrollendIndicator.module.scss +76 -0
  226. package/dist-ts/index.d.ts +1 -0
  227. package/dist-ts/index.js +1 -0
  228. package/dist-ts/index.js.map +1 -1
  229. package/package.json +1 -1
@@ -1,295 +1,273 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
6
  exports.TRANSITION_FACTORY = void 0;
7
- const react_1 = require("react");
8
- const ownEvent_1 = __importDefault(require("../utils/ownEvent"));
9
- const useHero_module_scss_1 = __importDefault(require("./useHero.module.scss"));
10
- const ID = (id) => `${id}-hero`;
7
+ exports.default = useHero;
8
+ var _react = require("react");
9
+ var _ownEvent = _interopRequireDefault(require("../utils/ownEvent"));
10
+ var _useHeroModule = _interopRequireDefault(require("./useHero.module.scss"));
11
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
13
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
14
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
15
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
16
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
17
+ const ID = id => "".concat(id, "-hero");
11
18
  const viewport = window.visualViewport;
12
19
  const DATA_TAG_HERO_COMPONENT = "data-hero-component";
13
20
  function triggerDynamicComponents(clone, componentsFromOriginThatWillAppear, origin) {
14
- const idsThatWillAppear = componentsFromOriginThatWillAppear.map((a) => a.getAttribute(DATA_TAG_HERO_COMPONENT));
15
- const preexistingComponents = Array.from(clone.querySelectorAll(`[${DATA_TAG_HERO_COMPONENT}]`));
16
- const removedElements = preexistingComponents.filter((el) => !idsThatWillAppear.includes(el.getAttribute(DATA_TAG_HERO_COMPONENT)));
21
+ const idsThatWillAppear = componentsFromOriginThatWillAppear.map(a => a.getAttribute(DATA_TAG_HERO_COMPONENT));
22
+ const preexistingComponents = Array.from(clone.querySelectorAll("[".concat(DATA_TAG_HERO_COMPONENT, "]")));
23
+ const removedElements = preexistingComponents.filter(el => !idsThatWillAppear.includes(el.getAttribute(DATA_TAG_HERO_COMPONENT)));
24
+ for (let elementThatIsBeingRemoved of removedElements) {
25
+ for (let heightKey of ["height", "minHeight", "maxHeight"]) elementThatIsBeingRemoved.style[heightKey] = "".concat(elementThatIsBeingRemoved.clientHeight, "px");
26
+ }
27
+ setTimeout(() => {
17
28
  for (let elementThatIsBeingRemoved of removedElements) {
18
- for (let heightKey of ["height", "minHeight", "maxHeight"])
19
- elementThatIsBeingRemoved.style[heightKey] = `${elementThatIsBeingRemoved.clientHeight}px`;
29
+ for (let heightKey of ["height", "minHeight", "maxHeight"]) elementThatIsBeingRemoved.style[heightKey] = "0px";
30
+ elementThatIsBeingRemoved.style.opacity = "0";
20
31
  }
21
- setTimeout(() => {
22
- for (let elementThatIsBeingRemoved of removedElements) {
23
- for (let heightKey of ["height", "minHeight", "maxHeight"])
24
- elementThatIsBeingRemoved.style[heightKey] = `0px`;
25
- elementThatIsBeingRemoved.style.opacity = `0`;
26
- }
27
- }, 0);
28
- for (let componentThatWillAppear of componentsFromOriginThatWillAppear) {
29
- const alreadyInjectedElement = !!clone.querySelector(`[${DATA_TAG_HERO_COMPONENT}="${componentThatWillAppear.getAttribute(DATA_TAG_HERO_COMPONENT)}"]`);
30
- if (!alreadyInjectedElement) {
31
- function recursiveBuildPath(fromElement, pathSuffix = "") {
32
- if (fromElement === origin)
33
- return pathSuffix;
34
- const parent = fromElement.parentElement;
35
- const parentChilds = Array.from(parent.children);
36
- const elChildSelector = `:nth-child(${parentChilds.indexOf(fromElement) + 1})`;
37
- if (fromElement !== origin)
38
- return recursiveBuildPath(parent, `${elChildSelector}${pathSuffix ? `>${pathSuffix}` : ""}`);
39
- else
40
- return pathSuffix;
41
- }
42
- const whatIsTheElementPathFromCloneElement = recursiveBuildPath(componentThatWillAppear.parentElement);
43
- const insertAtIndex = Array.from(componentThatWillAppear.parentElement.children).indexOf(componentThatWillAppear);
44
- const targetElementClone = componentThatWillAppear.cloneNode(true);
45
- for (let heightKey of ["height", "minHeight", "maxHeight"])
46
- targetElementClone.style[heightKey] = "0px";
47
- const shouldBeInsertedAtElement = whatIsTheElementPathFromCloneElement
48
- ? clone.querySelector(whatIsTheElementPathFromCloneElement)
49
- : clone;
50
- const remainingIndexes = Array.from(shouldBeInsertedAtElement.children)
51
- .map((el, i) => removedElements.includes(el) ? undefined : i)
52
- .filter((e) => e !== undefined);
53
- if (insertAtIndex === remainingIndexes.length)
54
- shouldBeInsertedAtElement.append(targetElementClone);
55
- else
56
- shouldBeInsertedAtElement.insertBefore(targetElementClone, shouldBeInsertedAtElement.childNodes.item(remainingIndexes[insertAtIndex]));
57
- setTimeout(() => {
58
- for (let heightKey of ["height", "minHeight", "maxHeight"])
59
- targetElementClone.style[heightKey] = `${componentThatWillAppear.clientHeight}px`;
60
- }, 0);
61
- }
32
+ }, 0);
33
+ for (let componentThatWillAppear of componentsFromOriginThatWillAppear) {
34
+ const alreadyInjectedElement = !!clone.querySelector("[".concat(DATA_TAG_HERO_COMPONENT, "=\"").concat(componentThatWillAppear.getAttribute(DATA_TAG_HERO_COMPONENT), "\"]"));
35
+ if (!alreadyInjectedElement) {
36
+ function recursiveBuildPath(fromElement) {
37
+ let pathSuffix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
38
+ if (fromElement === origin) return pathSuffix;
39
+ const parent = fromElement.parentElement;
40
+ const parentChilds = Array.from(parent.children);
41
+ const elChildSelector = ":nth-child(".concat(parentChilds.indexOf(fromElement) + 1, ")");
42
+ if (fromElement !== origin) return recursiveBuildPath(parent, "".concat(elChildSelector).concat(pathSuffix ? ">".concat(pathSuffix) : ""));else return pathSuffix;
43
+ }
44
+ const whatIsTheElementPathFromCloneElement = recursiveBuildPath(componentThatWillAppear.parentElement);
45
+ const insertAtIndex = Array.from(componentThatWillAppear.parentElement.children).indexOf(componentThatWillAppear);
46
+ const targetElementClone = componentThatWillAppear.cloneNode(true);
47
+ for (let heightKey of ["height", "minHeight", "maxHeight"]) targetElementClone.style[heightKey] = "0px";
48
+ const shouldBeInsertedAtElement = whatIsTheElementPathFromCloneElement ? clone.querySelector(whatIsTheElementPathFromCloneElement) : clone;
49
+ const remainingIndexes = Array.from(shouldBeInsertedAtElement.children).map((el, i) => removedElements.includes(el) ? undefined : i).filter(e => e !== undefined);
50
+ if (insertAtIndex === remainingIndexes.length) shouldBeInsertedAtElement.append(targetElementClone);else shouldBeInsertedAtElement.insertBefore(targetElementClone, shouldBeInsertedAtElement.childNodes.item(remainingIndexes[insertAtIndex]));
51
+ setTimeout(() => {
52
+ for (let heightKey of ["height", "minHeight", "maxHeight"]) targetElementClone.style[heightKey] = "".concat(componentThatWillAppear.clientHeight, "px");
53
+ }, 0);
62
54
  }
55
+ }
63
56
  }
64
57
  const ALWAYS_TRANSITION = ["top", "left"];
58
+
65
59
  /**
66
60
  * This hook implements the logic for a hero animation between 2 elements sharing the same id
67
61
  */
68
- function useHero(id, options = {
69
- propsToTransition: [],
70
- }, events = {}) {
71
- const { propsToTransition: _p = [], "data-preffix": dataPreffix, repeatable, } = options;
72
- const propsToTransition = (0, react_1.useMemo)(() => _p.map((p) => p.replace(/([A-Z])/g, (_, val) => `-${val.toLowerCase()}`)), [_p]);
73
- const _dataPreffix = dataPreffix ? `-${dataPreffix}` : "";
74
- const dataProperty = `data${_dataPreffix}-hero`;
75
- const heroRef = (0, react_1.useRef)(null);
76
- (0, react_1.useLayoutEffect)(() => {
77
- heroRef.current.setAttribute(dataProperty, id);
78
- }, [id]);
79
- const getHerosOnScreen = (0, react_1.useCallback)(() => {
80
- const otherElements = Array.from(document.querySelectorAll(`[${dataProperty}="${id}"]`)).filter((el) => el !== heroRef.current);
81
- return otherElements;
82
- }, [id]);
83
- function triggerHeroAnimation() {
84
- var _a, _b;
85
- const allPropsToTransition = options.overridePropsToTransition
86
- ? [...ALWAYS_TRANSITION, ...propsToTransition]
87
- : ["width", "height", ...ALWAYS_TRANSITION, ...propsToTransition];
88
- const shouldHeroFn = events.onHeroDetect || ((...a) => true);
89
- const otherElements = getHerosOnScreen().filter((el) => shouldHeroFn(el, heroRef.current));
90
- const currentElement = heroRef.current;
91
- const currentElCoordinates = currentElement.getBoundingClientRect();
92
- if (process.env.NODE_ENV === "development" && otherElements.length > 2)
93
- console.warn("There are too many elements to transition to, I will transition to the first I find", otherElements);
94
- const otherElement = otherElements.find((el) => el !== heroRef.current);
95
- if (otherElement) {
96
- const [originContainer, targetContainer] = events.onBeforeTransition
97
- ? events.onBeforeTransition(otherElement, heroRef.current)
98
- : [viewport, viewport];
99
- const shouldSkip = isElementOutsideContainer(targetContainer, currentElCoordinates) ||
100
- isElementOutsideContainer(originContainer, otherElement.getBoundingClientRect())
101
- ? (events.onHeroSkip || (() => true))(otherElement, heroRef.current)
102
- : false;
103
- if (shouldSkip) {
104
- (_a = events.onHeroSkipped) === null || _a === void 0 ? void 0 : _a.call(events);
105
- return;
106
- }
107
- const oldClone = document.querySelector(`[${dataProperty}-clone="${ID(id)}"]`);
108
- const clone = (oldClone ||
109
- otherElement.cloneNode(true));
110
- if (events.onHeroCloned && !oldClone)
111
- events.onHeroCloned(clone);
112
- // Clean up thos properties that can cause confusion since it's a clone
113
- clone.style.visibility = "";
114
- clone.removeAttribute(dataProperty);
115
- clone.setAttribute(`${dataProperty}-clone`, ID(id));
116
- /**
117
- * If it's repeatable, we should keep the flag that indicates the hero existance
118
- */
119
- if (!repeatable)
120
- // Since a transition is now triggering from the old element, he cannot be considered for other transitions
121
- otherElement.removeAttribute(dataProperty);
122
- function willTheHeroMove(origin, target) {
123
- const willItMove = !(Math.trunc(origin.top) === Math.trunc(target.top) &&
124
- Math.trunc(origin.left) === Math.trunc(target.left) &&
125
- Math.trunc(origin.width) === Math.trunc(target.width) &&
126
- Math.trunc(origin.height) === Math.trunc(target.height));
127
- return willItMove;
128
- }
129
- /**
130
- *
131
- * @param el
132
- * @returns Returns if it will move
133
- */
134
- function setCloneToCoordinatesOf(el) {
135
- const coordinates = el.getBoundingClientRect();
136
- const currentCoordinates = clone.getBoundingClientRect();
137
- const willMove = willTheHeroMove(coordinates, currentCoordinates);
138
- clone.style.position = "fixed";
139
- clone.style.top = `${coordinates.top}px`;
140
- clone.style.left = `${coordinates.left}px`;
141
- if (allPropsToTransition.includes("width"))
142
- clone.style.width = `${coordinates.width}px`;
143
- if (allPropsToTransition.includes("height"))
144
- clone.style.height = `${coordinates.height}px`;
145
- return willMove;
146
- }
147
- const coordinates = otherElement.getBoundingClientRect();
148
- const currentCoordinates = heroRef.current.getBoundingClientRect();
149
- const itWontMove = !willTheHeroMove(coordinates, currentCoordinates);
150
- if (itWontMove) {
151
- (_b = events.onHeroEnd) === null || _b === void 0 ? void 0 : _b.call(events);
152
- return;
153
- }
154
- if (!oldClone) {
155
- /** Set the clone over the starting element */
156
- setCloneToCoordinatesOf(otherElement);
157
- document.body.appendChild(clone);
158
- }
159
- heroRef.current.style.visibility = "hidden";
160
- otherElement.style.visibility = "hidden";
161
- for (let propToTransition of propsToTransition) {
162
- clone.style[propToTransition] =
163
- window.getComputedStyle(otherElement)[propToTransition];
62
+ function useHero(id) {
63
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
64
+ propsToTransition: []
65
+ };
66
+ let events = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
67
+ const {
68
+ propsToTransition: _p = [],
69
+ "data-preffix": dataPreffix,
70
+ repeatable
71
+ } = options;
72
+ const propsToTransition = (0, _react.useMemo)(() => _p.map(p => p.replace(/([A-Z])/g, (_, val) => "-".concat(val.toLowerCase()))), [_p]);
73
+ const _dataPreffix = dataPreffix ? "-".concat(dataPreffix) : "";
74
+ const dataProperty = "data".concat(_dataPreffix, "-hero");
75
+ const heroRef = (0, _react.useRef)(null);
76
+ (0, _react.useLayoutEffect)(() => {
77
+ heroRef.current.setAttribute(dataProperty, id);
78
+ }, [id]);
79
+ const getHerosOnScreen = (0, _react.useCallback)(() => {
80
+ const otherElements = Array.from(document.querySelectorAll("[".concat(dataProperty, "=\"").concat(id, "\"]"))).filter(el => el !== heroRef.current);
81
+ return otherElements;
82
+ }, [id]);
83
+ function triggerHeroAnimation() {
84
+ const allPropsToTransition = options.overridePropsToTransition ? [...ALWAYS_TRANSITION, ...propsToTransition] : ["width", "height", ...ALWAYS_TRANSITION, ...propsToTransition];
85
+ const shouldHeroFn = events.onHeroDetect || function () {
86
+ return true;
87
+ };
88
+ const otherElements = getHerosOnScreen().filter(el => shouldHeroFn(el, heroRef.current));
89
+ const currentElement = heroRef.current;
90
+ const currentElCoordinates = currentElement.getBoundingClientRect();
91
+ if (process.env.NODE_ENV === "development" && otherElements.length > 2) console.warn("There are too many elements to transition to, I will transition to the first I find", otherElements);
92
+ const otherElement = otherElements.find(el => el !== heroRef.current);
93
+ if (otherElement) {
94
+ const [originContainer, targetContainer] = events.onBeforeTransition ? events.onBeforeTransition(otherElement, heroRef.current) : [viewport, viewport];
95
+ const shouldSkip = isElementOutsideContainer(targetContainer, currentElCoordinates) || isElementOutsideContainer(originContainer, otherElement.getBoundingClientRect()) ? (events.onHeroSkip || (() => true))(otherElement, heroRef.current) : false;
96
+ if (shouldSkip) {
97
+ var _events$onHeroSkipped;
98
+ (_events$onHeroSkipped = events.onHeroSkipped) === null || _events$onHeroSkipped === void 0 || _events$onHeroSkipped.call(events);
99
+ return;
100
+ }
101
+ const oldClone = document.querySelector("[".concat(dataProperty, "-clone=\"").concat(ID(id), "\"]"));
102
+ const clone = oldClone || otherElement.cloneNode(true);
103
+ if (events.onHeroCloned && !oldClone) events.onHeroCloned(clone);
104
+
105
+ // Clean up thos properties that can cause confusion since it's a clone
106
+ clone.style.visibility = "";
107
+ clone.removeAttribute(dataProperty);
108
+ clone.setAttribute("".concat(dataProperty, "-clone"), ID(id));
109
+
110
+ /**
111
+ * If it's repeatable, we should keep the flag that indicates the hero existance
112
+ */
113
+ if (!repeatable)
114
+ // Since a transition is now triggering from the old element, he cannot be considered for other transitions
115
+ otherElement.removeAttribute(dataProperty);
116
+ function willTheHeroMove(origin, target) {
117
+ const willItMove = !(Math.trunc(origin.top) === Math.trunc(target.top) && Math.trunc(origin.left) === Math.trunc(target.left) && Math.trunc(origin.width) === Math.trunc(target.width) && Math.trunc(origin.height) === Math.trunc(target.height));
118
+ return willItMove;
119
+ }
120
+
121
+ /**
122
+ *
123
+ * @param el
124
+ * @returns Returns if it will move
125
+ */
126
+ function setCloneToCoordinatesOf(el) {
127
+ const coordinates = el.getBoundingClientRect();
128
+ const currentCoordinates = clone.getBoundingClientRect();
129
+ const willMove = willTheHeroMove(coordinates, currentCoordinates);
130
+ clone.style.position = "fixed";
131
+ clone.style.top = "".concat(coordinates.top, "px");
132
+ clone.style.left = "".concat(coordinates.left, "px");
133
+ if (allPropsToTransition.includes("width")) clone.style.width = "".concat(coordinates.width, "px");
134
+ if (allPropsToTransition.includes("height")) clone.style.height = "".concat(coordinates.height, "px");
135
+ return willMove;
136
+ }
137
+ const coordinates = otherElement.getBoundingClientRect();
138
+ const currentCoordinates = heroRef.current.getBoundingClientRect();
139
+ const itWontMove = !willTheHeroMove(coordinates, currentCoordinates);
140
+ if (itWontMove) {
141
+ var _events$onHeroEnd;
142
+ (_events$onHeroEnd = events.onHeroEnd) === null || _events$onHeroEnd === void 0 || _events$onHeroEnd.call(events);
143
+ return;
144
+ }
145
+ if (!oldClone) {
146
+ /** Set the clone over the starting element */
147
+ setCloneToCoordinatesOf(otherElement);
148
+ document.body.appendChild(clone);
149
+ }
150
+ heroRef.current.style.visibility = "hidden";
151
+ otherElement.style.visibility = "hidden";
152
+ for (let propToTransition of propsToTransition) {
153
+ clone.style[propToTransition] = window.getComputedStyle(otherElement)[propToTransition];
154
+ }
155
+ clone.style.transition = "".concat(allPropsToTransition.map(prop => "".concat(prop.replace(/[A-Z]/g, sub => "-".concat(sub.toLowerCase())), " var(--animation--speed-fast, 250ms) ease-out")).join(", "));
156
+ setTimeout(() => {
157
+ const elItWillTransitionTo = heroRef.current;
158
+ const cleanup = () => {
159
+ if (events.onHeroEnd) events.onHeroEnd();
160
+ if (elItWillTransitionTo) {
161
+ if (repeatable) elItWillTransitionTo.setAttribute(dataProperty, id);
162
+ elItWillTransitionTo.style.visibility = "";
163
+ }
164
+ setTimeout(() => {
165
+ clone.remove();
166
+ }, 0);
167
+ };
168
+ triggerDynamicComponents(clone, Array.from(heroRef.current.querySelectorAll("[".concat(DATA_TAG_HERO_COMPONENT, "]"))), currentElement);
169
+ if (events.onHeroStart) {
170
+ events.onHeroStart(clone, otherElement, heroRef.current);
171
+ }
172
+ if (!elItWillTransitionTo) {
173
+ cleanup();
174
+ return;
175
+ }
176
+ /** Set the clone over the new position */
177
+ const willMove = setCloneToCoordinatesOf(elItWillTransitionTo);
178
+ if (!willMove) cleanup();else {
179
+ for (let propToTransition of propsToTransition) clone.style[propToTransition] = window.getComputedStyle(elItWillTransitionTo)[propToTransition];
180
+ let initialOffset;
181
+ const s = _ref => {
182
+ let {
183
+ target
184
+ } = _ref;
185
+ const d = target;
186
+ if (d.contains(elItWillTransitionTo)) {
187
+ if (initialOffset === undefined) initialOffset = d.scrollTop;else clone.style.marginTop = "".concat(-(d.scrollTop - initialOffset), "px");
164
188
  }
165
- clone.style.transition = `${allPropsToTransition
166
- .map((prop) => `${prop.replace(/[A-Z]/g, (sub) => `-${sub.toLowerCase()}`)} var(--animation--speed-fast, 250ms) ease-out`)
167
- .join(", ")}`;
168
- setTimeout(() => {
169
- const elItWillTransitionTo = heroRef.current;
170
- const cleanup = () => {
171
- if (events.onHeroEnd)
172
- events.onHeroEnd();
173
- if (elItWillTransitionTo) {
174
- if (repeatable)
175
- elItWillTransitionTo.setAttribute(dataProperty, id);
176
- elItWillTransitionTo.style.visibility = "";
177
- }
178
- setTimeout(() => {
179
- clone.remove();
180
- }, 0);
181
- };
182
- triggerDynamicComponents(clone, Array.from(heroRef.current.querySelectorAll(`[${DATA_TAG_HERO_COMPONENT}]`)), currentElement);
183
- if (events.onHeroStart) {
184
- events.onHeroStart(clone, otherElement, heroRef.current);
185
- }
186
- if (!elItWillTransitionTo) {
187
- cleanup();
188
- return;
189
- }
190
- /** Set the clone over the new position */
191
- const willMove = setCloneToCoordinatesOf(elItWillTransitionTo);
192
- if (!willMove)
193
- cleanup();
194
- else {
195
- for (let propToTransition of propsToTransition)
196
- clone.style[propToTransition] =
197
- window.getComputedStyle(elItWillTransitionTo)[propToTransition];
198
- let initialOffset;
199
- const s = ({ target }) => {
200
- const d = target;
201
- if (d.contains(elItWillTransitionTo)) {
202
- if (initialOffset === undefined)
203
- initialOffset = d.scrollTop;
204
- else
205
- clone.style.marginTop = `${-(d.scrollTop - initialOffset)}px`;
206
- }
207
- };
208
- const transitionEndCb = (0, ownEvent_1.default)(({ target, currentTarget }) => {
209
- if (target === currentTarget)
210
- cleanup();
211
- document.removeEventListener("scroll", s, true);
212
- });
213
- document.addEventListener("scroll", s, true);
214
- clone.addEventListener("transitionend", transitionEndCb);
215
- clone.addEventListener("transitionstart", () => {
216
- const onCancelCb = (0, ownEvent_1.default)((e) => {
217
- clone.removeEventListener("transitionend", transitionEndCb);
218
- clone.removeEventListener("transitioncancel", onCancelCb);
219
- });
220
- clone.addEventListener("transitioncancel", onCancelCb);
221
- });
222
- }
223
- }, 0);
189
+ };
190
+ const transitionEndCb = (0, _ownEvent.default)(_ref2 => {
191
+ let {
192
+ target,
193
+ currentTarget
194
+ } = _ref2;
195
+ if (target === currentTarget) cleanup();
196
+ document.removeEventListener("scroll", s, true);
197
+ });
198
+ document.addEventListener("scroll", s, true);
199
+ clone.addEventListener("transitionend", transitionEndCb);
200
+ clone.addEventListener("transitionstart", () => {
201
+ const onCancelCb = (0, _ownEvent.default)(e => {
202
+ clone.removeEventListener("transitionend", transitionEndCb);
203
+ clone.removeEventListener("transitioncancel", onCancelCb);
204
+ });
205
+ clone.addEventListener("transitioncancel", onCancelCb);
206
+ });
224
207
  }
208
+ }, 0);
225
209
  }
226
- (0, react_1.useEffect)(() => {
227
- triggerHeroAnimation();
228
- }, []);
229
- return {
230
- heroRef,
231
- getHerosOnScreen,
232
- trigger: triggerHeroAnimation,
233
- heroComponentRef: (componentId) => (elRef) => {
234
- if (elRef) {
235
- elRef.setAttribute(DATA_TAG_HERO_COMPONENT, componentId);
236
- elRef.classList.add(useHero_module_scss_1.default.component);
237
- }
238
- },
239
- };
210
+ }
211
+ (0, _react.useEffect)(() => {
212
+ triggerHeroAnimation();
213
+ }, []);
214
+ return {
215
+ heroRef,
216
+ getHerosOnScreen,
217
+ trigger: triggerHeroAnimation,
218
+ heroComponentRef: componentId => elRef => {
219
+ if (elRef) {
220
+ elRef.setAttribute(DATA_TAG_HERO_COMPONENT, componentId);
221
+ elRef.classList.add(_useHeroModule.default.component);
222
+ }
223
+ }
224
+ };
240
225
  }
241
- exports.default = useHero;
242
226
  function isElementOutsideViewport(coordinates) {
243
- const elementOverflowsViewport = coordinates.left >= viewport.width || coordinates.top >= viewport.height;
244
- const elementUnderflowsViewport = coordinates.left <= -coordinates.width ||
245
- coordinates.top <= -coordinates.height;
246
- return elementOverflowsViewport || elementUnderflowsViewport;
227
+ const elementOverflowsViewport = coordinates.left >= viewport.width || coordinates.top >= viewport.height;
228
+ const elementUnderflowsViewport = coordinates.left <= -coordinates.width || coordinates.top <= -coordinates.height;
229
+ return elementOverflowsViewport || elementUnderflowsViewport;
247
230
  }
248
231
  function isElementOutsideContainer(container, coordinates) {
249
- if (container instanceof VisualViewport) {
250
- return isElementOutsideViewport(coordinates);
251
- }
252
- else {
253
- const containerBounds = container.getBoundingClientRect();
254
- const isContainerOutsideViewport = isElementOutsideViewport(containerBounds);
255
- if (isContainerOutsideViewport)
256
- return true;
257
- const elementOverflowsViewport = coordinates.left >= containerBounds.left + containerBounds.width ||
258
- coordinates.top >= containerBounds.top + containerBounds.height;
259
- const elementUnderflowsViewport = containerBounds.left - coordinates.left >= coordinates.width ||
260
- containerBounds.top - coordinates.top >= coordinates.height;
261
- return elementUnderflowsViewport || elementOverflowsViewport;
262
- }
232
+ if (container instanceof VisualViewport) {
233
+ return isElementOutsideViewport(coordinates);
234
+ } else {
235
+ const containerBounds = container.getBoundingClientRect();
236
+ const isContainerOutsideViewport = isElementOutsideViewport(containerBounds);
237
+ if (isContainerOutsideViewport) return true;
238
+ const elementOverflowsViewport = coordinates.left >= containerBounds.left + containerBounds.width || coordinates.top >= containerBounds.top + containerBounds.height;
239
+ const elementUnderflowsViewport = containerBounds.left - coordinates.left >= coordinates.width || containerBounds.top - coordinates.top >= coordinates.height;
240
+ return elementUnderflowsViewport || elementOverflowsViewport;
241
+ }
263
242
  }
264
243
  function centerPoint(rect) {
265
- return [rect.left + rect.width / 2, rect.top + rect.height / 2];
244
+ return [rect.left + rect.width / 2, rect.top + rect.height / 2];
266
245
  }
267
- const angle = (pointA, pointB) => Number((Math.atan2(pointA[1] - pointB[1], pointA[0] - pointB[0]) *
268
- (179.08 / Math.PI)).toFixed(5));
269
- exports.TRANSITION_FACTORY = {
270
- ACCELERATION: (events) => (Object.assign(Object.assign({}, events), { onHeroStart(clone, origin, target) {
271
- if (events === null || events === void 0 ? void 0 : events.onHeroStart)
272
- events.onHeroStart(clone, origin, target);
273
- clone.classList.add(useHero_module_scss_1.default.acceleration);
274
- const centerPointOrigin = centerPoint(origin.getBoundingClientRect());
275
- const centerPointDestination = centerPoint(target.getBoundingClientRect());
276
- const angleBetweenElements = angle(centerPointOrigin, centerPointDestination);
277
- const vectorX = Math.sin(angleBetweenElements);
278
- const vectorY = Math.cos(angleBetweenElements);
279
- const rotateY = (10 * vectorY).toFixed(0);
280
- const originX = (vectorY + 1) * 50;
281
- const rotateX = -(10 * vectorX).toFixed(0);
282
- const originY = (vectorX + 1) * 50;
283
- clone.style.setProperty("--stage-1", `rotateY(${rotateY}deg) rotateX(${-rotateX}deg)`);
284
- clone.style.setProperty("--stage-2", `rotateY(${-rotateY * 0.3}deg) rotateX(${rotateX * 0.3}deg)`);
285
- clone.style.setProperty("--origin-1", `${originX}% ${originY}%`);
286
- clone.style.setProperty("--origin-2", `${100 - originX}% ${100 - originY}%`);
287
- document.body.style.perspective = "100vw";
288
- },
289
- onHeroEnd() {
290
- if (events === null || events === void 0 ? void 0 : events.onHeroEnd)
291
- events.onHeroEnd();
292
- document.body.style.perspective = "";
293
- } })),
246
+ const angle = (pointA, pointB) => Number((Math.atan2(pointA[1] - pointB[1], pointA[0] - pointB[0]) * (179.08 / Math.PI)).toFixed(5));
247
+ const TRANSITION_FACTORY = exports.TRANSITION_FACTORY = {
248
+ ACCELERATION: events => _objectSpread(_objectSpread({}, events), {}, {
249
+ onHeroStart(clone, origin, target) {
250
+ if (events !== null && events !== void 0 && events.onHeroStart) events.onHeroStart(clone, origin, target);
251
+ clone.classList.add(_useHeroModule.default.acceleration);
252
+ const centerPointOrigin = centerPoint(origin.getBoundingClientRect());
253
+ const centerPointDestination = centerPoint(target.getBoundingClientRect());
254
+ const angleBetweenElements = angle(centerPointOrigin, centerPointDestination);
255
+ const vectorX = Math.sin(angleBetweenElements);
256
+ const vectorY = Math.cos(angleBetweenElements);
257
+ const rotateY = (10 * vectorY).toFixed(0);
258
+ const originX = (vectorY + 1) * 50;
259
+ const rotateX = -(10 * vectorX).toFixed(0);
260
+ const originY = (vectorX + 1) * 50;
261
+ clone.style.setProperty("--stage-1", "rotateY(".concat(rotateY, "deg) rotateX(").concat(-rotateX, "deg)"));
262
+ clone.style.setProperty("--stage-2", "rotateY(".concat(-rotateY * 0.3, "deg) rotateX(").concat(rotateX * 0.3, "deg)"));
263
+ clone.style.setProperty("--origin-1", "".concat(originX, "% ").concat(originY, "%"));
264
+ clone.style.setProperty("--origin-2", "".concat(100 - originX, "% ").concat(100 - originY, "%"));
265
+ document.body.style.perspective = "100vw";
266
+ },
267
+ onHeroEnd() {
268
+ if (events !== null && events !== void 0 && events.onHeroEnd) events.onHeroEnd();
269
+ document.body.style.perspective = "";
270
+ }
271
+ })
294
272
  };
295
- //# sourceMappingURL=useHero.js.map
273
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJyZXF1aXJlIiwiX293bkV2ZW50IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl91c2VIZXJvTW9kdWxlIiwib2JqIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJvd25LZXlzIiwib2JqZWN0IiwiZW51bWVyYWJsZU9ubHkiLCJrZXlzIiwiT2JqZWN0IiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwic3ltYm9scyIsImZpbHRlciIsInN5bSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwidGFyZ2V0IiwiaSIsImFyZ3VtZW50cyIsImxlbmd0aCIsInNvdXJjZSIsImZvckVhY2giLCJrZXkiLCJfZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzIiwiZGVmaW5lUHJvcGVydGllcyIsImRlZmluZVByb3BlcnR5IiwidmFsdWUiLCJfdG9Qcm9wZXJ0eUtleSIsImNvbmZpZ3VyYWJsZSIsIndyaXRhYmxlIiwiYXJnIiwiX3RvUHJpbWl0aXZlIiwiU3RyaW5nIiwiaW5wdXQiLCJoaW50IiwicHJpbSIsIlN5bWJvbCIsInRvUHJpbWl0aXZlIiwidW5kZWZpbmVkIiwicmVzIiwiY2FsbCIsIlR5cGVFcnJvciIsIk51bWJlciIsIklEIiwiaWQiLCJjb25jYXQiLCJ2aWV3cG9ydCIsIndpbmRvdyIsInZpc3VhbFZpZXdwb3J0IiwiREFUQV9UQUdfSEVST19DT01QT05FTlQiLCJ0cmlnZ2VyRHluYW1pY0NvbXBvbmVudHMiLCJjbG9uZSIsImNvbXBvbmVudHNGcm9tT3JpZ2luVGhhdFdpbGxBcHBlYXIiLCJvcmlnaW4iLCJpZHNUaGF0V2lsbEFwcGVhciIsIm1hcCIsImEiLCJnZXRBdHRyaWJ1dGUiLCJwcmVleGlzdGluZ0NvbXBvbmVudHMiLCJBcnJheSIsImZyb20iLCJxdWVyeVNlbGVjdG9yQWxsIiwicmVtb3ZlZEVsZW1lbnRzIiwiZWwiLCJpbmNsdWRlcyIsImVsZW1lbnRUaGF0SXNCZWluZ1JlbW92ZWQiLCJoZWlnaHRLZXkiLCJzdHlsZSIsImNsaWVudEhlaWdodCIsInNldFRpbWVvdXQiLCJvcGFjaXR5IiwiY29tcG9uZW50VGhhdFdpbGxBcHBlYXIiLCJhbHJlYWR5SW5qZWN0ZWRFbGVtZW50IiwicXVlcnlTZWxlY3RvciIsInJlY3Vyc2l2ZUJ1aWxkUGF0aCIsImZyb21FbGVtZW50IiwicGF0aFN1ZmZpeCIsInBhcmVudCIsInBhcmVudEVsZW1lbnQiLCJwYXJlbnRDaGlsZHMiLCJjaGlsZHJlbiIsImVsQ2hpbGRTZWxlY3RvciIsImluZGV4T2YiLCJ3aGF0SXNUaGVFbGVtZW50UGF0aEZyb21DbG9uZUVsZW1lbnQiLCJpbnNlcnRBdEluZGV4IiwidGFyZ2V0RWxlbWVudENsb25lIiwiY2xvbmVOb2RlIiwic2hvdWxkQmVJbnNlcnRlZEF0RWxlbWVudCIsInJlbWFpbmluZ0luZGV4ZXMiLCJlIiwiYXBwZW5kIiwiaW5zZXJ0QmVmb3JlIiwiY2hpbGROb2RlcyIsIml0ZW0iLCJBTFdBWVNfVFJBTlNJVElPTiIsInVzZUhlcm8iLCJvcHRpb25zIiwicHJvcHNUb1RyYW5zaXRpb24iLCJldmVudHMiLCJfcCIsImRhdGFQcmVmZml4IiwicmVwZWF0YWJsZSIsInVzZU1lbW8iLCJwIiwicmVwbGFjZSIsIl8iLCJ2YWwiLCJ0b0xvd2VyQ2FzZSIsIl9kYXRhUHJlZmZpeCIsImRhdGFQcm9wZXJ0eSIsImhlcm9SZWYiLCJ1c2VSZWYiLCJ1c2VMYXlvdXRFZmZlY3QiLCJjdXJyZW50Iiwic2V0QXR0cmlidXRlIiwiZ2V0SGVyb3NPblNjcmVlbiIsInVzZUNhbGxiYWNrIiwib3RoZXJFbGVtZW50cyIsImRvY3VtZW50IiwidHJpZ2dlckhlcm9BbmltYXRpb24iLCJhbGxQcm9wc1RvVHJhbnNpdGlvbiIsIm92ZXJyaWRlUHJvcHNUb1RyYW5zaXRpb24iLCJzaG91bGRIZXJvRm4iLCJvbkhlcm9EZXRlY3QiLCJjdXJyZW50RWxlbWVudCIsImN1cnJlbnRFbENvb3JkaW5hdGVzIiwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0IiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwiY29uc29sZSIsIndhcm4iLCJvdGhlckVsZW1lbnQiLCJmaW5kIiwib3JpZ2luQ29udGFpbmVyIiwidGFyZ2V0Q29udGFpbmVyIiwib25CZWZvcmVUcmFuc2l0aW9uIiwic2hvdWxkU2tpcCIsImlzRWxlbWVudE91dHNpZGVDb250YWluZXIiLCJvbkhlcm9Ta2lwIiwiX2V2ZW50cyRvbkhlcm9Ta2lwcGVkIiwib25IZXJvU2tpcHBlZCIsIm9sZENsb25lIiwib25IZXJvQ2xvbmVkIiwidmlzaWJpbGl0eSIsInJlbW92ZUF0dHJpYnV0ZSIsIndpbGxUaGVIZXJvTW92ZSIsIndpbGxJdE1vdmUiLCJNYXRoIiwidHJ1bmMiLCJ0b3AiLCJsZWZ0Iiwid2lkdGgiLCJoZWlnaHQiLCJzZXRDbG9uZVRvQ29vcmRpbmF0ZXNPZiIsImNvb3JkaW5hdGVzIiwiY3VycmVudENvb3JkaW5hdGVzIiwid2lsbE1vdmUiLCJwb3NpdGlvbiIsIml0V29udE1vdmUiLCJfZXZlbnRzJG9uSGVyb0VuZCIsIm9uSGVyb0VuZCIsImJvZHkiLCJhcHBlbmRDaGlsZCIsInByb3BUb1RyYW5zaXRpb24iLCJnZXRDb21wdXRlZFN0eWxlIiwidHJhbnNpdGlvbiIsInByb3AiLCJzdWIiLCJqb2luIiwiZWxJdFdpbGxUcmFuc2l0aW9uVG8iLCJjbGVhbnVwIiwicmVtb3ZlIiwib25IZXJvU3RhcnQiLCJpbml0aWFsT2Zmc2V0IiwicyIsIl9yZWYiLCJkIiwiY29udGFpbnMiLCJzY3JvbGxUb3AiLCJtYXJnaW5Ub3AiLCJ0cmFuc2l0aW9uRW5kQ2IiLCJvd25FdmVudCIsIl9yZWYyIiwiY3VycmVudFRhcmdldCIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJhZGRFdmVudExpc3RlbmVyIiwib25DYW5jZWxDYiIsInVzZUVmZmVjdCIsInRyaWdnZXIiLCJoZXJvQ29tcG9uZW50UmVmIiwiY29tcG9uZW50SWQiLCJlbFJlZiIsImNsYXNzTGlzdCIsImFkZCIsIlN0eWxlcyIsImNvbXBvbmVudCIsImlzRWxlbWVudE91dHNpZGVWaWV3cG9ydCIsImVsZW1lbnRPdmVyZmxvd3NWaWV3cG9ydCIsImVsZW1lbnRVbmRlcmZsb3dzVmlld3BvcnQiLCJjb250YWluZXIiLCJWaXN1YWxWaWV3cG9ydCIsImNvbnRhaW5lckJvdW5kcyIsImlzQ29udGFpbmVyT3V0c2lkZVZpZXdwb3J0IiwiY2VudGVyUG9pbnQiLCJyZWN0IiwiYW5nbGUiLCJwb2ludEEiLCJwb2ludEIiLCJhdGFuMiIsIlBJIiwidG9GaXhlZCIsIlRSQU5TSVRJT05fRkFDVE9SWSIsImV4cG9ydHMiLCJBQ0NFTEVSQVRJT04iLCJhY2NlbGVyYXRpb24iLCJjZW50ZXJQb2ludE9yaWdpbiIsImNlbnRlclBvaW50RGVzdGluYXRpb24iLCJhbmdsZUJldHdlZW5FbGVtZW50cyIsInZlY3RvclgiLCJzaW4iLCJ2ZWN0b3JZIiwiY29zIiwicm90YXRlWSIsIm9yaWdpblgiLCJyb3RhdGVYIiwib3JpZ2luWSIsInNldFByb3BlcnR5IiwicGVyc3BlY3RpdmUiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvaG9va3MvdXNlSGVyby50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHtcbiAgQ1NTUHJvcGVydGllcyxcbiAgdXNlQ2FsbGJhY2ssXG4gIHVzZUVmZmVjdCxcbiAgdXNlTGF5b3V0RWZmZWN0LFxuICB1c2VNZW1vLFxuICB1c2VSZWYsXG59IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IG93bkV2ZW50IGZyb20gXCIuLi91dGlscy9vd25FdmVudFwiO1xuaW1wb3J0IFN0eWxlcyBmcm9tIFwiLi91c2VIZXJvLm1vZHVsZS5zY3NzXCI7XG5cbmNvbnN0IElEID0gKGlkOiBzdHJpbmcpID0+IGAke2lkfS1oZXJvYDtcbnR5cGUgU2hvdWxkU2tpcCA9IGJvb2xlYW47XG50eXBlIFJlc3VsdCA9IFtcbiAgb3JpZ2luQ29udGFpbmVyOiBFbGVtZW50IHwgVmlzdWFsVmlld3BvcnQsXG4gIHRhcmdldENvbnRhaW5lcjogRWxlbWVudCB8IFZpc3VhbFZpZXdwb3J0XG5dO1xuY29uc3Qgdmlld3BvcnQgPSB3aW5kb3cudmlzdWFsVmlld3BvcnQhO1xuY29uc3QgREFUQV9UQUdfSEVST19DT01QT05FTlQgPSBcImRhdGEtaGVyby1jb21wb25lbnRcIjtcblxuZnVuY3Rpb24gdHJpZ2dlckR5bmFtaWNDb21wb25lbnRzKFxuICBjbG9uZTogSFRNTERpdkVsZW1lbnQsXG4gIGNvbXBvbmVudHNGcm9tT3JpZ2luVGhhdFdpbGxBcHBlYXI6IEhUTUxEaXZFbGVtZW50W10sXG4gIG9yaWdpbjogSFRNTERpdkVsZW1lbnRcbikge1xuICBjb25zdCBpZHNUaGF0V2lsbEFwcGVhciA9IGNvbXBvbmVudHNGcm9tT3JpZ2luVGhhdFdpbGxBcHBlYXIubWFwKChhKSA9PlxuICAgIGEuZ2V0QXR0cmlidXRlKERBVEFfVEFHX0hFUk9fQ09NUE9ORU5UKVxuICApO1xuICBjb25zdCBwcmVleGlzdGluZ0NvbXBvbmVudHMgPSBBcnJheS5mcm9tKFxuICAgIGNsb25lLnF1ZXJ5U2VsZWN0b3JBbGwoYFske0RBVEFfVEFHX0hFUk9fQ09NUE9ORU5UfV1gKVxuICApIGFzIEhUTUxEaXZFbGVtZW50W107XG4gIGNvbnN0IHJlbW92ZWRFbGVtZW50czogSFRNTERpdkVsZW1lbnRbXSA9IHByZWV4aXN0aW5nQ29tcG9uZW50cy5maWx0ZXIoXG4gICAgKGVsKSA9PlxuICAgICAgIWlkc1RoYXRXaWxsQXBwZWFyLmluY2x1ZGVzKGVsLmdldEF0dHJpYnV0ZShEQVRBX1RBR19IRVJPX0NPTVBPTkVOVCkpXG4gICk7XG5cbiAgZm9yIChsZXQgZWxlbWVudFRoYXRJc0JlaW5nUmVtb3ZlZCBvZiByZW1vdmVkRWxlbWVudHMpIHtcbiAgICBmb3IgKGxldCBoZWlnaHRLZXkgb2YgW1wiaGVpZ2h0XCIsIFwibWluSGVpZ2h0XCIsIFwibWF4SGVpZ2h0XCJdIGFzIGNvbnN0KVxuICAgICAgZWxlbWVudFRoYXRJc0JlaW5nUmVtb3ZlZC5zdHlsZVtcbiAgICAgICAgaGVpZ2h0S2V5XG4gICAgICBdID0gYCR7ZWxlbWVudFRoYXRJc0JlaW5nUmVtb3ZlZC5jbGllbnRIZWlnaHR9cHhgO1xuICB9XG4gIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgIGZvciAobGV0IGVsZW1lbnRUaGF0SXNCZWluZ1JlbW92ZWQgb2YgcmVtb3ZlZEVsZW1lbnRzKSB7XG4gICAgICBmb3IgKGxldCBoZWlnaHRLZXkgb2YgW1wiaGVpZ2h0XCIsIFwibWluSGVpZ2h0XCIsIFwibWF4SGVpZ2h0XCJdIGFzIGNvbnN0KVxuICAgICAgICBlbGVtZW50VGhhdElzQmVpbmdSZW1vdmVkLnN0eWxlW2hlaWdodEtleV0gPSBgMHB4YDtcbiAgICAgIGVsZW1lbnRUaGF0SXNCZWluZ1JlbW92ZWQuc3R5bGUub3BhY2l0eSA9IGAwYDtcbiAgICB9XG4gIH0sIDApO1xuXG4gIGZvciAobGV0IGNvbXBvbmVudFRoYXRXaWxsQXBwZWFyIG9mIGNvbXBvbmVudHNGcm9tT3JpZ2luVGhhdFdpbGxBcHBlYXIpIHtcbiAgICBjb25zdCBhbHJlYWR5SW5qZWN0ZWRFbGVtZW50ID0gISFjbG9uZS5xdWVyeVNlbGVjdG9yKFxuICAgICAgYFske0RBVEFfVEFHX0hFUk9fQ09NUE9ORU5UfT1cIiR7Y29tcG9uZW50VGhhdFdpbGxBcHBlYXIuZ2V0QXR0cmlidXRlKFxuICAgICAgICBEQVRBX1RBR19IRVJPX0NPTVBPTkVOVFxuICAgICAgKX1cIl1gXG4gICAgKTtcbiAgICBpZiAoIWFscmVhZHlJbmplY3RlZEVsZW1lbnQpIHtcbiAgICAgIGZ1bmN0aW9uIHJlY3Vyc2l2ZUJ1aWxkUGF0aChcbiAgICAgICAgZnJvbUVsZW1lbnQ6IEhUTUxFbGVtZW50LFxuICAgICAgICBwYXRoU3VmZml4OiBzdHJpbmcgPSBcIlwiXG4gICAgICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgICAgICBpZiAoZnJvbUVsZW1lbnQgPT09IG9yaWdpbikgcmV0dXJuIHBhdGhTdWZmaXg7XG4gICAgICAgIGNvbnN0IHBhcmVudCA9IGZyb21FbGVtZW50LnBhcmVudEVsZW1lbnQhO1xuICAgICAgICBjb25zdCBwYXJlbnRDaGlsZHMgPSBBcnJheS5mcm9tKHBhcmVudC5jaGlsZHJlbik7XG4gICAgICAgIGNvbnN0IGVsQ2hpbGRTZWxlY3RvciA9IGA6bnRoLWNoaWxkKCR7XG4gICAgICAgICAgcGFyZW50Q2hpbGRzLmluZGV4T2YoZnJvbUVsZW1lbnQpICsgMVxuICAgICAgICB9KWA7XG5cbiAgICAgICAgaWYgKGZyb21FbGVtZW50ICE9PSBvcmlnaW4pXG4gICAgICAgICAgcmV0dXJuIHJlY3Vyc2l2ZUJ1aWxkUGF0aChcbiAgICAgICAgICAgIHBhcmVudCxcbiAgICAgICAgICAgIGAke2VsQ2hpbGRTZWxlY3Rvcn0ke3BhdGhTdWZmaXggPyBgPiR7cGF0aFN1ZmZpeH1gIDogXCJcIn1gXG4gICAgICAgICAgKTtcbiAgICAgICAgZWxzZSByZXR1cm4gcGF0aFN1ZmZpeDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHdoYXRJc1RoZUVsZW1lbnRQYXRoRnJvbUNsb25lRWxlbWVudCA9IHJlY3Vyc2l2ZUJ1aWxkUGF0aChcbiAgICAgICAgY29tcG9uZW50VGhhdFdpbGxBcHBlYXIucGFyZW50RWxlbWVudCFcbiAgICAgICk7XG4gICAgICBjb25zdCBpbnNlcnRBdEluZGV4ID0gQXJyYXkuZnJvbShcbiAgICAgICAgY29tcG9uZW50VGhhdFdpbGxBcHBlYXIucGFyZW50RWxlbWVudCEuY2hpbGRyZW5cbiAgICAgICkuaW5kZXhPZihjb21wb25lbnRUaGF0V2lsbEFwcGVhcik7XG5cbiAgICAgIGNvbnN0IHRhcmdldEVsZW1lbnRDbG9uZSA9IGNvbXBvbmVudFRoYXRXaWxsQXBwZWFyLmNsb25lTm9kZShcbiAgICAgICAgdHJ1ZVxuICAgICAgKSBhcyBIVE1MRGl2RWxlbWVudDtcbiAgICAgIGZvciAobGV0IGhlaWdodEtleSBvZiBbXCJoZWlnaHRcIiwgXCJtaW5IZWlnaHRcIiwgXCJtYXhIZWlnaHRcIl0gYXMgY29uc3QpXG4gICAgICAgIHRhcmdldEVsZW1lbnRDbG9uZS5zdHlsZVtoZWlnaHRLZXldID0gXCIwcHhcIjtcbiAgICAgIGNvbnN0IHNob3VsZEJlSW5zZXJ0ZWRBdEVsZW1lbnQgPSB3aGF0SXNUaGVFbGVtZW50UGF0aEZyb21DbG9uZUVsZW1lbnRcbiAgICAgICAgPyBjbG9uZS5xdWVyeVNlbGVjdG9yKHdoYXRJc1RoZUVsZW1lbnRQYXRoRnJvbUNsb25lRWxlbWVudCkhXG4gICAgICAgIDogY2xvbmU7XG4gICAgICBjb25zdCByZW1haW5pbmdJbmRleGVzID0gQXJyYXkuZnJvbShzaG91bGRCZUluc2VydGVkQXRFbGVtZW50LmNoaWxkcmVuKVxuICAgICAgICAubWFwKChlbCwgaSkgPT5cbiAgICAgICAgICByZW1vdmVkRWxlbWVudHMuaW5jbHVkZXMoZWwgYXMgSFRNTERpdkVsZW1lbnQpID8gdW5kZWZpbmVkIDogaVxuICAgICAgICApXG4gICAgICAgIC5maWx0ZXIoKGUpID0+IGUgIT09IHVuZGVmaW5lZCkgYXMgbnVtYmVyW107XG5cbiAgICAgIGlmIChpbnNlcnRBdEluZGV4ID09PSByZW1haW5pbmdJbmRleGVzLmxlbmd0aClcbiAgICAgICAgc2hvdWxkQmVJbnNlcnRlZEF0RWxlbWVudC5hcHBlbmQodGFyZ2V0RWxlbWVudENsb25lKTtcbiAgICAgIGVsc2VcbiAgICAgICAgc2hvdWxkQmVJbnNlcnRlZEF0RWxlbWVudC5pbnNlcnRCZWZvcmUoXG4gICAgICAgICAgdGFyZ2V0RWxlbWVudENsb25lLFxuICAgICAgICAgIHNob3VsZEJlSW5zZXJ0ZWRBdEVsZW1lbnQuY2hpbGROb2Rlcy5pdGVtKFxuICAgICAgICAgICAgcmVtYWluaW5nSW5kZXhlc1tpbnNlcnRBdEluZGV4XVxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBmb3IgKGxldCBoZWlnaHRLZXkgb2YgW1wiaGVpZ2h0XCIsIFwibWluSGVpZ2h0XCIsIFwibWF4SGVpZ2h0XCJdIGFzIGNvbnN0KVxuICAgICAgICAgIHRhcmdldEVsZW1lbnRDbG9uZS5zdHlsZVtcbiAgICAgICAgICAgIGhlaWdodEtleVxuICAgICAgICAgIF0gPSBgJHtjb21wb25lbnRUaGF0V2lsbEFwcGVhci5jbGllbnRIZWlnaHR9cHhgO1xuICAgICAgfSwgMCk7XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IEFMV0FZU19UUkFOU0lUSU9OID0gW1widG9wXCIsIFwibGVmdFwiXTtcblxuLyoqXG4gKiBUaGlzIGhvb2sgaW1wbGVtZW50cyB0aGUgbG9naWMgZm9yIGEgaGVybyBhbmltYXRpb24gYmV0d2VlbiAyIGVsZW1lbnRzIHNoYXJpbmcgdGhlIHNhbWUgaWRcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXNlSGVybyhcbiAgaWQ6IHN0cmluZyxcbiAgb3B0aW9uczogUGFydGlhbDx7XG4gICAgcHJvcHNUb1RyYW5zaXRpb246IEV4Y2x1ZGU8XG4gICAgICBrZXlvZiBDU1NQcm9wZXJ0aWVzLFxuICAgICAgXCJ3aWR0aFwiIHwgXCJoZWlnaHRcIiB8IFwidG9wXCIgfCBcImxlZnRcIlxuICAgID5bXTtcbiAgICAvKiogSWYgc2V0LCB0aGUgZGVmYXVsdCBwcm9wZXJ0aWVzICh3aWR0aCwgaGVpZ2h0LCBldGMuLi4pIHdpbGwgbm90IHRyYW5zaXRpb24sIGFuZCBwcm9wc1RvVHJhbnNpdGlvbiB3aWxsIGJlIHRoZSBvbmx5IG9uZXMgdGhhdCB3aWxsIGJlIHRyYW5zaXRpb25lZCAqL1xuICAgIG92ZXJyaWRlUHJvcHNUb1RyYW5zaXRpb246IGJvb2xlYW47XG5cbiAgICBcImRhdGEtcHJlZmZpeFwiOiBzdHJpbmc7XG4gICAgLyoqIFRoaXMgaW5kaWNhdGVzIHRoaXMgaGVybyBhbmltYXRpb24gd2lsbCBwcm9iYWJseSBiZSByZXBlYXRlZCBtdWx0aXBsZSB0aW1lICovXG4gICAgcmVwZWF0YWJsZTogYm9vbGVhbjtcbiAgfT4gPSB7XG4gICAgcHJvcHNUb1RyYW5zaXRpb246IFtdLFxuICB9LFxuICBldmVudHM6IHtcbiAgICAvKipcbiAgICAgKiBTaG91bGQgcmV0dXJuIGlmIHRoZSBkZXRlY3RlZCBlbGVtZW50IHNob3VsZCBiZSBcImhlcm9lZFwiXG4gICAgICpcbiAgICAgKiBVc2VmdWxsIGZvciB3aGVuIHRoZSBoZXJvIGhhcyAyIHBvc3NpYmxlIG9yaWdpbnMuXG4gICAgICogRm9yIGV4YW1wbGUsIG9uZSBjb3VsZCBoZXJvIG9ubHkgdGhlIGN1cnJlbnQgaG92ZXJlZCBlbGVtZW50IHdpdGggZWwubWF0Y2hlcyhcIjpob3ZlclwiKVxuICAgICAqL1xuICAgIG9uSGVyb0RldGVjdD86IChvcmlnaW46IEhUTUxEaXZFbGVtZW50LCB0YXJnZXQ6IEhUTUxEaXZFbGVtZW50KSA9PiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogRG8gc29tZXRoaW5nIHdoZW4gdGhlIGhlcm8gZW5kc1xuICAgICAqXG4gICAgICogVXNlZnVsbCBmb3IgdHJpZ2dlcmluZyBzZWNvbmRhcnkgYW5pbWF0aW9uc1xuICAgICAqL1xuICAgIG9uSGVyb0VuZD86ICgpID0+IHZvaWQ7XG5cbiAgICAvKiogRG8gc29tZXRoaWduIHdpdGggdGhlIGNsb25lIGJlZm9yZSBpdCBnb2VzIHRvIHRoZSBodG1sICovXG4gICAgb25IZXJvQ2xvbmVkPzogKGNsb25lOiBIVE1MRGl2RWxlbWVudCkgPT4gdm9pZDtcblxuICAgIC8qKlxuICAgICAqIERvIHNvbWV0aGluZyB3aGVuIHRoZSBoZXJvIHN0YXJ0cyB0aGUgdHJhbnNpdGlvblxuICAgICAqIEhlcmUgaXQncyB1c2VmdWxsIHRvIHN3aXRjaCBjbGFzc05hbWVzIHdpdGggdGhlIHRhcmdldC5cbiAgICAgKlxuICAgICAqIElmIGRvbmUgY29ycmVjdGx5LCBpdCB3aWxsIHRyYW5zaXRpb24gZnJvbSBzdGF0ZSBhIHRvIGIgc21vb3RobHlcbiAgICAgKi9cbiAgICBvbkhlcm9TdGFydD86IChcbiAgICAgIGNsb25lOiBIVE1MRGl2RWxlbWVudCxcbiAgICAgIG9yaWdpbjogSFRNTERpdkVsZW1lbnQsXG4gICAgICB0YXJnZXQ6IEhUTUxEaXZFbGVtZW50XG4gICAgKSA9PiB2b2lkO1xuXG4gICAgLyoqXG4gICAgICogSXMgY2FsbGVkIHdoZW4gdGhlIGhlcm8gaXMgY29taW5nL2dvaW5nIG91dHNpZGUgdGhlIHZpZXdwb3J0XG4gICAgICpcbiAgICAgKiBCeSBkZWZhdWx0IGl0J3Mgc2V0IHRvIHNraXAgYWxsIGhlcm9lcyB0aGF0IGhhdmUgdGhlc2UgY29uZGl0aW9uc1xuICAgICAqXG4gICAgICogQHJldHVybnMgSWYgdGhlIGhlcm8gc2hvdWxkIGJlIHNraXBwZWQgb3Igbm90XG4gICAgICovXG4gICAgb25IZXJvU2tpcD86IChvcmlnaW46IEhUTUxEaXZFbGVtZW50LCB0YXJnZXQ6IEhUTUxEaXZFbGVtZW50KSA9PiBTaG91bGRTa2lwO1xuXG4gICAgLyoqXG4gICAgICogQ2FsbGVkIHdoZW4gYSBoZXJvIGlzIHNraXBwZWRcbiAgICAgKi9cbiAgICBvbkhlcm9Ta2lwcGVkPzogKCkgPT4gdm9pZDtcblxuICAgIC8qKlxuICAgICAqIEJlZm9yZSB0cmFuc2l0aW9uIHN0YXJ0LCBzZXR1cCB0aGUgcHJvcGVydGllcyB0aGF0IHdpbGwgYmUgdXNlZCBmb3IgaGVybyBhbmltYXRpb25cbiAgICAgKiBAcmV0dXJucyBUaGUgY29udGFpbmVyIHRoYXQgd2lsbCBiZSB1c2VkIHRvIGNoZWNrIGlmIHRoZSBoZXJvIGlzIG91dCBvciBpbiB0aGUgdmlld1xuICAgICAqL1xuICAgIG9uQmVmb3JlVHJhbnNpdGlvbj86IChcbiAgICAgIG9yaWdpbjogSFRNTERpdkVsZW1lbnQsXG4gICAgICB0YXJnZXQ6IEhUTUxEaXZFbGVtZW50XG4gICAgKSA9PiBSZXN1bHQgfCBSZWFkb25seTxSZXN1bHQ+O1xuICB9ID0ge31cbikge1xuICBjb25zdCB7XG4gICAgcHJvcHNUb1RyYW5zaXRpb246IF9wID0gW10sXG4gICAgXCJkYXRhLXByZWZmaXhcIjogZGF0YVByZWZmaXgsXG4gICAgcmVwZWF0YWJsZSxcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IHByb3BzVG9UcmFuc2l0aW9uID0gdXNlTWVtbyhcbiAgICAoKSA9PlxuICAgICAgX3AubWFwKChwKSA9PiBwLnJlcGxhY2UoLyhbQS1aXSkvZywgKF8sIHZhbCkgPT4gYC0ke3ZhbC50b0xvd2VyQ2FzZSgpfWApKSxcbiAgICBbX3BdXG4gICk7XG4gIGNvbnN0IF9kYXRhUHJlZmZpeCA9IGRhdGFQcmVmZml4ID8gYC0ke2RhdGFQcmVmZml4fWAgOiBcIlwiO1xuICBjb25zdCBkYXRhUHJvcGVydHkgPSBgZGF0YSR7X2RhdGFQcmVmZml4fS1oZXJvYDtcbiAgY29uc3QgaGVyb1JlZiA9IHVzZVJlZjxIVE1MRGl2RWxlbWVudD4obnVsbCk7XG5cbiAgdXNlTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBoZXJvUmVmLmN1cnJlbnQhLnNldEF0dHJpYnV0ZShkYXRhUHJvcGVydHksIGlkKTtcbiAgfSwgW2lkXSk7XG5cbiAgY29uc3QgZ2V0SGVyb3NPblNjcmVlbiA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBjb25zdCBvdGhlckVsZW1lbnRzID0gKFxuICAgICAgQXJyYXkuZnJvbShcbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChgWyR7ZGF0YVByb3BlcnR5fT1cIiR7aWR9XCJdYClcbiAgICAgICkgYXMgSFRNTERpdkVsZW1lbnRbXVxuICAgICkuZmlsdGVyKChlbCkgPT4gZWwgIT09IGhlcm9SZWYuY3VycmVudCk7XG4gICAgcmV0dXJuIG90aGVyRWxlbWVudHM7XG4gIH0sIFtpZF0pO1xuXG4gIGZ1bmN0aW9uIHRyaWdnZXJIZXJvQW5pbWF0aW9uKCkge1xuICAgIGNvbnN0IGFsbFByb3BzVG9UcmFuc2l0aW9uID0gb3B0aW9ucy5vdmVycmlkZVByb3BzVG9UcmFuc2l0aW9uXG4gICAgICA/IFsuLi5BTFdBWVNfVFJBTlNJVElPTiwgLi4ucHJvcHNUb1RyYW5zaXRpb25dXG4gICAgICA6IFtcIndpZHRoXCIsIFwiaGVpZ2h0XCIsIC4uLkFMV0FZU19UUkFOU0lUSU9OLCAuLi5wcm9wc1RvVHJhbnNpdGlvbl07XG4gICAgY29uc3Qgc2hvdWxkSGVyb0ZuID0gZXZlbnRzLm9uSGVyb0RldGVjdCB8fCAoKC4uLmE6IGFueVtdKSA9PiB0cnVlKTtcbiAgICBjb25zdCBvdGhlckVsZW1lbnRzID0gZ2V0SGVyb3NPblNjcmVlbigpLmZpbHRlcigoZWwpID0+XG4gICAgICBzaG91bGRIZXJvRm4oZWwsIGhlcm9SZWYuY3VycmVudCEpXG4gICAgKTtcbiAgICBjb25zdCBjdXJyZW50RWxlbWVudCA9IGhlcm9SZWYuY3VycmVudCE7XG4gICAgY29uc3QgY3VycmVudEVsQ29vcmRpbmF0ZXMgPSBjdXJyZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJkZXZlbG9wbWVudFwiICYmIG90aGVyRWxlbWVudHMubGVuZ3RoID4gMilcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgXCJUaGVyZSBhcmUgdG9vIG1hbnkgZWxlbWVudHMgdG8gdHJhbnNpdGlvbiB0bywgSSB3aWxsIHRyYW5zaXRpb24gdG8gdGhlIGZpcnN0IEkgZmluZFwiLFxuICAgICAgICBvdGhlckVsZW1lbnRzXG4gICAgICApO1xuICAgIGNvbnN0IG90aGVyRWxlbWVudCA9IG90aGVyRWxlbWVudHMuZmluZChcbiAgICAgIChlbCkgPT4gZWwgIT09IGhlcm9SZWYuY3VycmVudCFcbiAgICApIGFzIEhUTUxEaXZFbGVtZW50O1xuXG4gICAgaWYgKG90aGVyRWxlbWVudCkge1xuICAgICAgY29uc3QgW29yaWdpbkNvbnRhaW5lciwgdGFyZ2V0Q29udGFpbmVyXSA9IGV2ZW50cy5vbkJlZm9yZVRyYW5zaXRpb25cbiAgICAgICAgPyBldmVudHMub25CZWZvcmVUcmFuc2l0aW9uKG90aGVyRWxlbWVudCwgaGVyb1JlZi5jdXJyZW50ISlcbiAgICAgICAgOiBbdmlld3BvcnQsIHZpZXdwb3J0XTtcbiAgICAgIGNvbnN0IHNob3VsZFNraXAgPVxuICAgICAgICBpc0VsZW1lbnRPdXRzaWRlQ29udGFpbmVyKHRhcmdldENvbnRhaW5lciwgY3VycmVudEVsQ29vcmRpbmF0ZXMpIHx8XG4gICAgICAgIGlzRWxlbWVudE91dHNpZGVDb250YWluZXIoXG4gICAgICAgICAgb3JpZ2luQ29udGFpbmVyLFxuICAgICAgICAgIG90aGVyRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgICApXG4gICAgICAgICAgPyAoZXZlbnRzLm9uSGVyb1NraXAgfHwgKCgpID0+IHRydWUpKShvdGhlckVsZW1lbnQsIGhlcm9SZWYuY3VycmVudCEpXG4gICAgICAgICAgOiBmYWxzZTtcbiAgICAgIGlmIChzaG91bGRTa2lwKSB7XG4gICAgICAgIGV2ZW50cy5vbkhlcm9Ta2lwcGVkPy4oKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qgb2xkQ2xvbmUgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxuICAgICAgICBgWyR7ZGF0YVByb3BlcnR5fS1jbG9uZT1cIiR7SUQoaWQpfVwiXWBcbiAgICAgICk7XG4gICAgICBjb25zdCBjbG9uZSA9IChvbGRDbG9uZSB8fFxuICAgICAgICBvdGhlckVsZW1lbnQuY2xvbmVOb2RlKHRydWUpKSBhcyBIVE1MRGl2RWxlbWVudDtcblxuICAgICAgaWYgKGV2ZW50cy5vbkhlcm9DbG9uZWQgJiYgIW9sZENsb25lKSBldmVudHMub25IZXJvQ2xvbmVkKGNsb25lKTtcblxuICAgICAgLy8gQ2xlYW4gdXAgdGhvcyBwcm9wZXJ0aWVzIHRoYXQgY2FuIGNhdXNlIGNvbmZ1c2lvbiBzaW5jZSBpdCdzIGEgY2xvbmVcbiAgICAgIGNsb25lLnN0eWxlLnZpc2liaWxpdHkgPSBcIlwiO1xuICAgICAgY2xvbmUucmVtb3ZlQXR0cmlidXRlKGRhdGFQcm9wZXJ0eSk7XG5cbiAgICAgIGNsb25lLnNldEF0dHJpYnV0ZShgJHtkYXRhUHJvcGVydHl9LWNsb25lYCwgSUQoaWQpKTtcblxuICAgICAgLyoqXG4gICAgICAgKiBJZiBpdCdzIHJlcGVhdGFibGUsIHdlIHNob3VsZCBrZWVwIHRoZSBmbGFnIHRoYXQgaW5kaWNhdGVzIHRoZSBoZXJvIGV4aXN0YW5jZVxuICAgICAgICovXG4gICAgICBpZiAoIXJlcGVhdGFibGUpXG4gICAgICAgIC8vIFNpbmNlIGEgdHJhbnNpdGlvbiBpcyBub3cgdHJpZ2dlcmluZyBmcm9tIHRoZSBvbGQgZWxlbWVudCwgaGUgY2Fubm90IGJlIGNvbnNpZGVyZWQgZm9yIG90aGVyIHRyYW5zaXRpb25zXG4gICAgICAgIG90aGVyRWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoZGF0YVByb3BlcnR5KTtcblxuICAgICAgZnVuY3Rpb24gd2lsbFRoZUhlcm9Nb3ZlKG9yaWdpbjogRE9NUmVjdCwgdGFyZ2V0OiBET01SZWN0KSB7XG4gICAgICAgIGNvbnN0IHdpbGxJdE1vdmUgPSAhKFxuICAgICAgICAgIE1hdGgudHJ1bmMob3JpZ2luLnRvcCkgPT09IE1hdGgudHJ1bmModGFyZ2V0LnRvcCkgJiZcbiAgICAgICAgICBNYXRoLnRydW5jKG9yaWdpbi5sZWZ0KSA9PT0gTWF0aC50cnVuYyh0YXJnZXQubGVmdCkgJiZcbiAgICAgICAgICBNYXRoLnRydW5jKG9yaWdpbi53aWR0aCkgPT09IE1hdGgudHJ1bmModGFyZ2V0LndpZHRoKSAmJlxuICAgICAgICAgIE1hdGgudHJ1bmMob3JpZ2luLmhlaWdodCkgPT09IE1hdGgudHJ1bmModGFyZ2V0LmhlaWdodClcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4gd2lsbEl0TW92ZTtcbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKlxuICAgICAgICogQHBhcmFtIGVsXG4gICAgICAgKiBAcmV0dXJucyBSZXR1cm5zIGlmIGl0IHdpbGwgbW92ZVxuICAgICAgICovXG4gICAgICBmdW5jdGlvbiBzZXRDbG9uZVRvQ29vcmRpbmF0ZXNPZihlbDogSFRNTERpdkVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgY29vcmRpbmF0ZXMgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgY29uc3QgY3VycmVudENvb3JkaW5hdGVzID0gY2xvbmUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGNvbnN0IHdpbGxNb3ZlID0gd2lsbFRoZUhlcm9Nb3ZlKGNvb3JkaW5hdGVzLCBjdXJyZW50Q29vcmRpbmF0ZXMpO1xuXG4gICAgICAgIGNsb25lLnN0eWxlLnBvc2l0aW9uID0gXCJmaXhlZFwiO1xuICAgICAgICBjbG9uZS5zdHlsZS50b3AgPSBgJHtjb29yZGluYXRlcy50b3B9cHhgO1xuICAgICAgICBjbG9uZS5zdHlsZS5sZWZ0ID0gYCR7Y29vcmRpbmF0ZXMubGVmdH1weGA7XG4gICAgICAgIGlmIChhbGxQcm9wc1RvVHJhbnNpdGlvbi5pbmNsdWRlcyhcIndpZHRoXCIpKVxuICAgICAgICAgIGNsb25lLnN0eWxlLndpZHRoID0gYCR7Y29vcmRpbmF0ZXMud2lkdGh9cHhgO1xuICAgICAgICBpZiAoYWxsUHJvcHNUb1RyYW5zaXRpb24uaW5jbHVkZXMoXCJoZWlnaHRcIikpXG4gICAgICAgICAgY2xvbmUuc3R5bGUuaGVpZ2h0ID0gYCR7Y29vcmRpbmF0ZXMuaGVpZ2h0fXB4YDtcblxuICAgICAgICByZXR1cm4gd2lsbE1vdmU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNvb3JkaW5hdGVzID0gb3RoZXJFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3QgY3VycmVudENvb3JkaW5hdGVzID0gaGVyb1JlZi5jdXJyZW50IS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGNvbnN0IGl0V29udE1vdmUgPSAhd2lsbFRoZUhlcm9Nb3ZlKGNvb3JkaW5hdGVzLCBjdXJyZW50Q29vcmRpbmF0ZXMpO1xuICAgICAgaWYgKGl0V29udE1vdmUpIHtcbiAgICAgICAgZXZlbnRzLm9uSGVyb0VuZD8uKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKCFvbGRDbG9uZSkge1xuICAgICAgICAvKiogU2V0IHRoZSBjbG9uZSBvdmVyIHRoZSBzdGFydGluZyBlbGVtZW50ICovXG4gICAgICAgIHNldENsb25lVG9Db29yZGluYXRlc09mKG90aGVyRWxlbWVudCk7XG4gICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoY2xvbmUpO1xuICAgICAgfVxuICAgICAgaGVyb1JlZi5jdXJyZW50IS5zdHlsZS52aXNpYmlsaXR5ID0gXCJoaWRkZW5cIjtcbiAgICAgIG90aGVyRWxlbWVudC5zdHlsZS52aXNpYmlsaXR5ID0gXCJoaWRkZW5cIjtcblxuICAgICAgZm9yIChsZXQgcHJvcFRvVHJhbnNpdGlvbiBvZiBwcm9wc1RvVHJhbnNpdGlvbikge1xuICAgICAgICBjbG9uZS5zdHlsZVtwcm9wVG9UcmFuc2l0aW9uIGFzIGFueV0gPVxuICAgICAgICAgIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKG90aGVyRWxlbWVudClbcHJvcFRvVHJhbnNpdGlvbiBhcyBhbnldO1xuICAgICAgfVxuXG4gICAgICBjbG9uZS5zdHlsZS50cmFuc2l0aW9uID0gYCR7YWxsUHJvcHNUb1RyYW5zaXRpb25cbiAgICAgICAgLm1hcChcbiAgICAgICAgICAocHJvcCkgPT5cbiAgICAgICAgICAgIGAke3Byb3AucmVwbGFjZShcbiAgICAgICAgICAgICAgL1tBLVpdL2csXG4gICAgICAgICAgICAgIChzdWIpID0+IGAtJHtzdWIudG9Mb3dlckNhc2UoKX1gXG4gICAgICAgICAgICApfSB2YXIoLS1hbmltYXRpb24tLXNwZWVkLWZhc3QsIDI1MG1zKSBlYXNlLW91dGBcbiAgICAgICAgKVxuICAgICAgICAuam9pbihcIiwgXCIpfWA7XG5cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBjb25zdCBlbEl0V2lsbFRyYW5zaXRpb25UbyA9IGhlcm9SZWYuY3VycmVudDtcbiAgICAgICAgY29uc3QgY2xlYW51cCA9ICgpID0+IHtcbiAgICAgICAgICBpZiAoZXZlbnRzLm9uSGVyb0VuZCkgZXZlbnRzLm9uSGVyb0VuZCgpO1xuICAgICAgICAgIGlmIChlbEl0V2lsbFRyYW5zaXRpb25Ubykge1xuICAgICAgICAgICAgaWYgKHJlcGVhdGFibGUpXG4gICAgICAgICAgICAgIGVsSXRXaWxsVHJhbnNpdGlvblRvIS5zZXRBdHRyaWJ1dGUoZGF0YVByb3BlcnR5LCBpZCk7XG4gICAgICAgICAgICBlbEl0V2lsbFRyYW5zaXRpb25Uby5zdHlsZS52aXNpYmlsaXR5ID0gXCJcIjtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBjbG9uZS5yZW1vdmUoKTtcbiAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfTtcbiAgICAgICAgdHJpZ2dlckR5bmFtaWNDb21wb25lbnRzKFxuICAgICAgICAgIGNsb25lLFxuICAgICAgICAgIEFycmF5LmZyb20oXG4gICAgICAgICAgICBoZXJvUmVmLmN1cnJlbnQhLnF1ZXJ5U2VsZWN0b3JBbGwoYFske0RBVEFfVEFHX0hFUk9fQ09NUE9ORU5UfV1gKVxuICAgICAgICAgICkgYXMgSFRNTERpdkVsZW1lbnRbXSxcbiAgICAgICAgICBjdXJyZW50RWxlbWVudFxuICAgICAgICApO1xuICAgICAgICBpZiAoZXZlbnRzLm9uSGVyb1N0YXJ0KSB7XG4gICAgICAgICAgZXZlbnRzLm9uSGVyb1N0YXJ0KGNsb25lLCBvdGhlckVsZW1lbnQsIGhlcm9SZWYuY3VycmVudCEpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghZWxJdFdpbGxUcmFuc2l0aW9uVG8pIHtcbiAgICAgICAgICBjbGVhbnVwKCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8qKiBTZXQgdGhlIGNsb25lIG92ZXIgdGhlIG5ldyBwb3NpdGlvbiAqL1xuICAgICAgICBjb25zdCB3aWxsTW92ZSA9IHNldENsb25lVG9Db29yZGluYXRlc09mKGVsSXRXaWxsVHJhbnNpdGlvblRvKTtcbiAgICAgICAgaWYgKCF3aWxsTW92ZSkgY2xlYW51cCgpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBmb3IgKGxldCBwcm9wVG9UcmFuc2l0aW9uIG9mIHByb3BzVG9UcmFuc2l0aW9uKVxuICAgICAgICAgICAgY2xvbmUuc3R5bGVbcHJvcFRvVHJhbnNpdGlvbiBhcyBhbnldID1cbiAgICAgICAgICAgICAgd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWxJdFdpbGxUcmFuc2l0aW9uVG8pW1xuICAgICAgICAgICAgICAgIHByb3BUb1RyYW5zaXRpb24gYXMgYW55XG4gICAgICAgICAgICAgIF07XG4gICAgICAgICAgbGV0IGluaXRpYWxPZmZzZXQ6IG51bWJlcjtcbiAgICAgICAgICBjb25zdCBzID0gKHsgdGFyZ2V0IH06IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGQgPSB0YXJnZXQgYXMgSFRNTERpdkVsZW1lbnQ7XG4gICAgICAgICAgICBpZiAoZC5jb250YWlucyhlbEl0V2lsbFRyYW5zaXRpb25UbykpIHtcbiAgICAgICAgICAgICAgaWYgKGluaXRpYWxPZmZzZXQgPT09IHVuZGVmaW5lZCkgaW5pdGlhbE9mZnNldCA9IGQuc2Nyb2xsVG9wO1xuICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgY2xvbmUuc3R5bGUubWFyZ2luVG9wID0gYCR7LShkLnNjcm9sbFRvcCAtIGluaXRpYWxPZmZzZXQpfXB4YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICAgIGNvbnN0IHRyYW5zaXRpb25FbmRDYiA9IG93bkV2ZW50KFxuICAgICAgICAgICAgKHsgdGFyZ2V0LCBjdXJyZW50VGFyZ2V0IH06IFRyYW5zaXRpb25FdmVudCkgPT4ge1xuICAgICAgICAgICAgICBpZiAodGFyZ2V0ID09PSBjdXJyZW50VGFyZ2V0KSBjbGVhbnVwKCk7XG4gICAgICAgICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgcyBhcyBhbnksIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCBzIGFzIGFueSwgdHJ1ZSk7XG4gICAgICAgICAgY2xvbmUuYWRkRXZlbnRMaXN0ZW5lcihcInRyYW5zaXRpb25lbmRcIiwgdHJhbnNpdGlvbkVuZENiKTtcbiAgICAgICAgICBjbG9uZS5hZGRFdmVudExpc3RlbmVyKFwidHJhbnNpdGlvbnN0YXJ0XCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG9uQ2FuY2VsQ2IgPSBvd25FdmVudCgoZSkgPT4ge1xuICAgICAgICAgICAgICBjbG9uZS5yZW1vdmVFdmVudExpc3RlbmVyKFwidHJhbnNpdGlvbmVuZFwiLCB0cmFuc2l0aW9uRW5kQ2IpO1xuICAgICAgICAgICAgICBjbG9uZS5yZW1vdmVFdmVudExpc3RlbmVyKFwidHJhbnNpdGlvbmNhbmNlbFwiLCBvbkNhbmNlbENiKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY2xvbmUuYWRkRXZlbnRMaXN0ZW5lcihcInRyYW5zaXRpb25jYW5jZWxcIiwgb25DYW5jZWxDYik7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sIDApO1xuICAgIH1cbiAgfVxuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgdHJpZ2dlckhlcm9BbmltYXRpb24oKTtcbiAgfSwgW10pO1xuXG4gIHJldHVybiB7XG4gICAgaGVyb1JlZixcbiAgICBnZXRIZXJvc09uU2NyZWVuLFxuICAgIHRyaWdnZXI6IHRyaWdnZXJIZXJvQW5pbWF0aW9uLFxuICAgIGhlcm9Db21wb25lbnRSZWY6XG4gICAgICAoY29tcG9uZW50SWQ6IHN0cmluZykgPT4gKGVsUmVmOiBIVE1MRGl2RWxlbWVudCB8IG51bGwpID0+IHtcbiAgICAgICAgaWYgKGVsUmVmKSB7XG4gICAgICAgICAgZWxSZWYuc2V0QXR0cmlidXRlKERBVEFfVEFHX0hFUk9fQ09NUE9ORU5ULCBjb21wb25lbnRJZCk7XG4gICAgICAgICAgZWxSZWYuY2xhc3NMaXN0LmFkZChTdHlsZXMuY29tcG9uZW50KTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gaXNFbGVtZW50T3V0c2lkZVZpZXdwb3J0KGNvb3JkaW5hdGVzOiBET01SZWN0KSB7XG4gIGNvbnN0IGVsZW1lbnRPdmVyZmxvd3NWaWV3cG9ydCA9XG4gICAgY29vcmRpbmF0ZXMubGVmdCA+PSB2aWV3cG9ydC53aWR0aCB8fCBjb29yZGluYXRlcy50b3AgPj0gdmlld3BvcnQuaGVpZ2h0O1xuICBjb25zdCBlbGVtZW50VW5kZXJmbG93c1ZpZXdwb3J0ID1cbiAgICBjb29yZGluYXRlcy5sZWZ0IDw9IC1jb29yZGluYXRlcy53aWR0aCB8fFxuICAgIGNvb3JkaW5hdGVzLnRvcCA8PSAtY29vcmRpbmF0ZXMuaGVpZ2h0O1xuICByZXR1cm4gZWxlbWVudE92ZXJmbG93c1ZpZXdwb3J0IHx8IGVsZW1lbnRVbmRlcmZsb3dzVmlld3BvcnQ7XG59XG5cbmZ1bmN0aW9uIGlzRWxlbWVudE91dHNpZGVDb250YWluZXIoXG4gIGNvbnRhaW5lcjogVmlzdWFsVmlld3BvcnQgfCBFbGVtZW50LFxuICBjb29yZGluYXRlczogRE9NUmVjdFxuKSB7XG4gIGlmIChjb250YWluZXIgaW5zdGFuY2VvZiBWaXN1YWxWaWV3cG9ydCkge1xuICAgIHJldHVybiBpc0VsZW1lbnRPdXRzaWRlVmlld3BvcnQoY29vcmRpbmF0ZXMpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGNvbnRhaW5lckJvdW5kcyA9IGNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGNvbnN0IGlzQ29udGFpbmVyT3V0c2lkZVZpZXdwb3J0ID1cbiAgICAgIGlzRWxlbWVudE91dHNpZGVWaWV3cG9ydChjb250YWluZXJCb3VuZHMpO1xuXG4gICAgaWYgKGlzQ29udGFpbmVyT3V0c2lkZVZpZXdwb3J0KSByZXR1cm4gdHJ1ZTtcblxuICAgIGNvbnN0IGVsZW1lbnRPdmVyZmxvd3NWaWV3cG9ydCA9XG4gICAgICBjb29yZGluYXRlcy5sZWZ0ID49IGNvbnRhaW5lckJvdW5kcy5sZWZ0ICsgY29udGFpbmVyQm91bmRzLndpZHRoIHx8XG4gICAgICBjb29yZGluYXRlcy50b3AgPj0gY29udGFpbmVyQm91bmRzLnRvcCArIGNvbnRhaW5lckJvdW5kcy5oZWlnaHQ7XG5cbiAgICBjb25zdCBlbGVtZW50VW5kZXJmbG93c1ZpZXdwb3J0ID1cbiAgICAgIGNvbnRhaW5lckJvdW5kcy5sZWZ0IC0gY29vcmRpbmF0ZXMubGVmdCA+PSBjb29yZGluYXRlcy53aWR0aCB8fFxuICAgICAgY29udGFpbmVyQm91bmRzLnRvcCAtIGNvb3JkaW5hdGVzLnRvcCA+PSBjb29yZGluYXRlcy5oZWlnaHQ7XG5cbiAgICByZXR1cm4gZWxlbWVudFVuZGVyZmxvd3NWaWV3cG9ydCB8fCBlbGVtZW50T3ZlcmZsb3dzVmlld3BvcnQ7XG4gIH1cbn1cblxudHlwZSBFVkVOVFNfSU5URVJGQUNFID0gUGFyYW1ldGVyczx0eXBlb2YgdXNlSGVybz5bMl07XG50eXBlIFRSQU5TSVRJT05fVFlQRVMgPSBcIkFDQ0VMRVJBVElPTlwiO1xuZnVuY3Rpb24gY2VudGVyUG9pbnQocmVjdDogRE9NUmVjdCkge1xuICByZXR1cm4gW3JlY3QubGVmdCArIHJlY3Qud2lkdGggLyAyLCByZWN0LnRvcCArIHJlY3QuaGVpZ2h0IC8gMl0gYXMgY29uc3Q7XG59XG5jb25zdCBhbmdsZSA9IChcbiAgcG9pbnRBOiByZWFkb25seSBbeDogbnVtYmVyLCB5OiBudW1iZXJdLFxuICBwb2ludEI6IHJlYWRvbmx5IFt4OiBudW1iZXIsIHk6IG51bWJlcl1cbikgPT5cbiAgTnVtYmVyKFxuICAgIChcbiAgICAgIE1hdGguYXRhbjIocG9pbnRBWzFdIC0gcG9pbnRCWzFdLCBwb2ludEFbMF0gLSBwb2ludEJbMF0pICpcbiAgICAgICgxNzkuMDggLyBNYXRoLlBJKVxuICAgICkudG9GaXhlZCg1KVxuICApO1xuZXhwb3J0IGNvbnN0IFRSQU5TSVRJT05fRkFDVE9SWToge1xuICBbbiBpbiBUUkFOU0lUSU9OX1RZUEVTXTogKGV2ZW50cz86IEVWRU5UU19JTlRFUkZBQ0UpID0+IEVWRU5UU19JTlRFUkZBQ0U7XG59ID0ge1xuICBBQ0NFTEVSQVRJT046IChldmVudHMpID0+ICh7XG4gICAgLi4uZXZlbnRzLFxuICAgIG9uSGVyb1N0YXJ0KGNsb25lLCBvcmlnaW4sIHRhcmdldCkge1xuICAgICAgaWYgKGV2ZW50cz8ub25IZXJvU3RhcnQpIGV2ZW50cy5vbkhlcm9TdGFydChjbG9uZSwgb3JpZ2luLCB0YXJnZXQpO1xuICAgICAgY2xvbmUuY2xhc3NMaXN0LmFkZChTdHlsZXMuYWNjZWxlcmF0aW9uKTtcbiAgICAgIGNvbnN0IGNlbnRlclBvaW50T3JpZ2luID0gY2VudGVyUG9pbnQob3JpZ2luLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKTtcbiAgICAgIGNvbnN0IGNlbnRlclBvaW50RGVzdGluYXRpb24gPSBjZW50ZXJQb2ludChcbiAgICAgICAgdGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICApO1xuICAgICAgY29uc3QgYW5nbGVCZXR3ZWVuRWxlbWVudHMgPSBhbmdsZShcbiAgICAgICAgY2VudGVyUG9pbnRPcmlnaW4sXG4gICAgICAgIGNlbnRlclBvaW50RGVzdGluYXRpb25cbiAgICAgICk7XG4gICAgICBjb25zdCB2ZWN0b3JYID0gTWF0aC5zaW4oYW5nbGVCZXR3ZWVuRWxlbWVudHMpO1xuICAgICAgY29uc3QgdmVjdG9yWSA9IE1hdGguY29zKGFuZ2xlQmV0d2VlbkVsZW1lbnRzKTtcblxuICAgICAgY29uc3Qgcm90YXRlWSA9ICgxMCAqIHZlY3RvclkpLnRvRml4ZWQoMCk7XG4gICAgICBjb25zdCBvcmlnaW5YID0gKHZlY3RvclkgKyAxKSAqIDUwO1xuXG4gICAgICBjb25zdCByb3RhdGVYID0gLSgxMCAqIHZlY3RvclgpLnRvRml4ZWQoMCk7XG4gICAgICBjb25zdCBvcmlnaW5ZID0gKHZlY3RvclggKyAxKSAqIDUwO1xuXG4gICAgICBjbG9uZS5zdHlsZS5zZXRQcm9wZXJ0eShcbiAgICAgICAgXCItLXN0YWdlLTFcIixcbiAgICAgICAgYHJvdGF0ZVkoJHtyb3RhdGVZfWRlZykgcm90YXRlWCgkey1yb3RhdGVYfWRlZylgXG4gICAgICApO1xuICAgICAgY2xvbmUuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAgIFwiLS1zdGFnZS0yXCIsXG4gICAgICAgIGByb3RhdGVZKCR7LXJvdGF0ZVkgKiAwLjN9ZGVnKSByb3RhdGVYKCR7cm90YXRlWCAqIDAuM31kZWcpYFxuICAgICAgKTtcbiAgICAgIGNsb25lLnN0eWxlLnNldFByb3BlcnR5KFwiLS1vcmlnaW4tMVwiLCBgJHtvcmlnaW5YfSUgJHtvcmlnaW5ZfSVgKTtcbiAgICAgIGNsb25lLnN0eWxlLnNldFByb3BlcnR5KFxuICAgICAgICBcIi0tb3JpZ2luLTJcIixcbiAgICAgICAgYCR7MTAwIC0gb3JpZ2luWH0lICR7MTAwIC0gb3JpZ2luWX0lYFxuICAgICAgKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUucGVyc3BlY3RpdmUgPSBcIjEwMHZ3XCI7XG4gICAgfSxcbiAgICBvbkhlcm9FbmQoKSB7XG4gICAgICBpZiAoZXZlbnRzPy5vbkhlcm9FbmQpIGV2ZW50cy5vbkhlcm9FbmQoKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuc3R5bGUucGVyc3BlY3RpdmUgPSBcIlwiO1xuICAgIH0sXG4gIH0pLFxufTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLElBQUFBLE1BQUEsR0FBQUMsT0FBQTtBQVFBLElBQUFDLFNBQUEsR0FBQUMsc0JBQUEsQ0FBQUYsT0FBQTtBQUNBLElBQUFHLGNBQUEsR0FBQUQsc0JBQUEsQ0FBQUYsT0FBQTtBQUEyQyxTQUFBRSx1QkFBQUUsR0FBQSxXQUFBQSxHQUFBLElBQUFBLEdBQUEsQ0FBQUMsVUFBQSxH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