diff --git a/fullstack/lib/fullstack_web/live/public/public_transactions.ex b/fullstack/lib/fullstack_web/live/public/public_transactions.ex
index 6b56e51..8740e3e 100644
--- a/fullstack/lib/fullstack_web/live/public/public_transactions.ex
+++ b/fullstack/lib/fullstack_web/live/public/public_transactions.ex
@@ -1,13 +1,25 @@
defmodule FullstackWeb.Public.TransactionsLive.PublicTransactions do
use FullstackWeb, :live_view
- import FullstackWeb.CustomComponents
alias Fullstack.Financial
+ alias Contex.{Sparkline}
+ alias Contex
@impl true
- def mount(_params, session, socket) do
+ def mount(_params, _session, socket) do
+ socket =
+ socket
+ |> assign(:chart_options, %{
+ refresh_rate: 1000,
+ number_of_points: 50,
+ height: 400,
+ width: 600
+ })
+ |> assign(:process_counts, [0])
+ |> make_test_data()
+
if connected?(socket) do
- Phoenix.PubSub.subscribe(Fullstack.PubSub, "centralized_counter")
+ Process.send_after(self(), :tick, socket.assigns.chart_options.refresh_rate)
end
{:ok, socket}
@@ -22,4 +34,40 @@ defmodule FullstackWeb.Public.TransactionsLive.PublicTransactions do
{:noreply, socket}
end
+
+ @impl true
+ def handle_info(:tick, socket) do
+ Process.send_after(self(), :tick, socket.assigns.chart_options.refresh_rate)
+
+ socket =
+ socket
+ |> make_test_data()
+
+ {:noreply, socket}
+ end
+
+ defp make_plot(data) do
+ Sparkline.new(data)
+ |> Map.update!(:height, fn _ -> 300 end)
+ |> Map.update!(:width, fn _ -> 600 end)
+ |> Sparkline.draw()
+ end
+
+ defp make_red_plot(data) do
+ Sparkline.new(data)
+ |> Sparkline.colours("#fad48e", "#ff9838")
+ |> Map.update!(:height, fn _ -> 300 end)
+ |> Map.update!(:width, fn _ -> 600 end)
+ |> Sparkline.draw()
+ end
+
+ defp make_test_data(socket) do
+ number_of_points = socket.assigns.chart_options.number_of_points
+
+ result =
+ 1..number_of_points
+ |> Enum.map(fn _ -> :rand.uniform(50) - 100 end)
+
+ assign(socket, test_data: result)
+ end
end
diff --git a/fullstack/lib/fullstack_web/live/public/public_transactions.html.heex b/fullstack/lib/fullstack_web/live/public/public_transactions.html.heex
index 6d44d88..d172c57 100644
--- a/fullstack/lib/fullstack_web/live/public/public_transactions.html.heex
+++ b/fullstack/lib/fullstack_web/live/public/public_transactions.html.heex
@@ -1,6 +1,8 @@
-
Transactions
+
Sales
+ <%= make_plot(@test_data) %>
+ <%= make_red_plot(@test_data) %>
<%= inspect(@info, pretty: true ) %>
diff --git a/fullstack/mix.exs b/fullstack/mix.exs
index 0ed8ec4..346f692 100644
--- a/fullstack/mix.exs
+++ b/fullstack/mix.exs
@@ -64,7 +64,8 @@ defmodule Fullstack.MixProject do
{:credo, "~> 1.7", only: [:dev, :test], runtime: false},
{:vega_lite, "~> 0.1.9"},
{:cachex, "~> 3.6.0"},
- {:live_toast, "~> 0.6.4"}
+ {:live_toast, "~> 0.6.4"},
+ {:contex, "0.3.0"}
]
end
diff --git a/fullstack/mix.lock b/fullstack/mix.lock
index b3b117a..5e61185 100644
--- a/fullstack/mix.lock
+++ b/fullstack/mix.lock
@@ -6,6 +6,7 @@
"cachex": {:hex, :cachex, "3.6.0", "14a1bfbeee060dd9bec25a5b6f4e4691e3670ebda28c8ba2884b12fe30b36bf8", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "ebf24e373883bc8e0c8d894a63bbe102ae13d918f790121f5cfe6e485cc8e2e2"},
"castore": {:hex, :castore, "1.0.8", "dedcf20ea746694647f883590b82d9e96014057aff1d44d03ec90f36a5c0dc6e", [:mix], [], "hexpm", "0b2b66d2ee742cb1d9cb8c8be3b43c3a70ee8651f37b75a8b982e036752983f1"},
"comeonin": {:hex, :comeonin, "5.4.0", "246a56ca3f41d404380fc6465650ddaa532c7f98be4bda1b4656b3a37cc13abe", [:mix], [], "hexpm", "796393a9e50d01999d56b7b8420ab0481a7538d0caf80919da493b4a6e51faf1"},
+ "contex": {:hex, :contex, "0.3.0", "d390713efee604702600ba801a481bcb8534a9af43e118b29d9d37fe4495fcba", [:mix], [{:nimble_strftime, "~> 0.1.0", [hex: :nimble_strftime, repo: "hexpm", optional: false]}], "hexpm", "3fa7535cc3b265691a4eabc2707fe8622aa60a2565145a14da9aebd613817652"},
"cowboy": {:hex, :cowboy, "2.12.0", "f276d521a1ff88b2b9b4c54d0e753da6c66dd7be6c9fca3d9418b561828a3731", [:make, :rebar3], [{:cowlib, "2.13.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "8a7abe6d183372ceb21caa2709bec928ab2b72e18a3911aa1771639bef82651e"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
"cowlib": {:hex, :cowlib, "2.13.0", "db8f7505d8332d98ef50a3ef34b34c1afddec7506e4ee4dd4a3a266285d282ca", [:make, :rebar3], [], "hexpm", "e1e1284dc3fc030a64b1ad0d8382ae7e99da46c3246b815318a4b848873800a4"},
@@ -35,6 +36,7 @@
"money": {:hex, :money, "1.12.4", "9d9817aa79d1317871f6b006721c264bf1910fb28ba2af50746514f0d7e8ddbe", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.0 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "87e4bb907df1da184cb4640569d8df99ee6d88c84ce4f5da03cb2fab8d433eb9"},
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
"nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"},
+ "nimble_strftime": {:hex, :nimble_strftime, "0.1.1", "b988184d1bd945bc139b2c27dd00a6c0774ec94f6b0b580083abd62d5d07818b", [:mix], [], "hexpm", "89e599c9b8b4d1203b7bb5c79eb51ef7c6a28fbc6228230b312f8b796310d755"},
"number": {:hex, :number, "1.0.5", "d92136f9b9382aeb50145782f116112078b3465b7be58df1f85952b8bb399b0f", [:mix], [{:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "c0733a0a90773a66582b9e92a3f01290987f395c972cb7d685f51dd927cd5169"},
"phoenix": {:hex, :phoenix, "1.7.14", "a7d0b3f1bc95987044ddada111e77bd7f75646a08518942c72a8440278ae7825", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "c7859bc56cc5dfef19ecfc240775dae358cbaa530231118a9e014df392ace61a"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.6.2", "3b83b24ab5a2eb071a20372f740d7118767c272db386831b2e77638c4dcc606d", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.1", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "3f94d025f59de86be00f5f8c5dd7b5965a3298458d21ab1c328488be3b5fcd59"},
diff --git a/fullstack/priv/static/assets/app.css b/fullstack/priv/static/assets/app.css
index cb36067..59a7d1a 100644
--- a/fullstack/priv/static/assets/app.css
+++ b/fullstack/priv/static/assets/app.css
@@ -1 +1,2404 @@
-/*! tailwindcss v3.3.2 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-variation-settings:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}[multiple],[type=date],[type=datetime-local],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],select,textarea{--tw-shadow:0 0 #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem}[multiple]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,select:focus,textarea:focus{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);outline:2px solid #0000;outline-offset:2px}input::-moz-placeholder,textarea::-moz-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-date-and-time-value{min-height:1.5em}::-webkit-datetime-edit,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-meridiem-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-year-field{padding-bottom:0;padding-top:0}select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}[multiple]{background-image:none;background-position:0 0;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}[type=checkbox],[type=radio]{--tw-shadow:0 0 #0000;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;background-origin:border-box;border-color:#6b7280;border-width:1px;color:#2563eb;display:inline-block;flex-shrink:0;height:1rem;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:1rem}[type=checkbox]{border-radius:0}[type=radio]{border-radius:100%}[type=checkbox]:focus,[type=radio]:focus{--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);outline:2px solid #0000;outline-offset:2px}[type=checkbox]:checked,[type=radio]:checked{background-color:currentColor;background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:#0000}[type=checkbox]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Cpath d='M12.207 4.793a1 1 0 0 1 0 1.414l-5 5a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L6.5 9.086l4.293-4.293a1 1 0 0 1 1.414 0z'/%3E%3C/svg%3E")}[type=radio]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E")}[type=checkbox]:checked:focus,[type=checkbox]:checked:hover,[type=checkbox]:indeterminate,[type=radio]:checked:focus,[type=radio]:checked:hover{background-color:currentColor;border-color:#0000}[type=checkbox]:indeterminate{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%}[type=checkbox]:indeterminate:focus,[type=checkbox]:indeterminate:hover{background-color:currentColor;border-color:#0000}[type=file]{background:unset;border-color:inherit;border-radius:0;border-width:0;font-size:unset;line-height:inherit;padding:0}[type=file]:focus{outline:1px solid ButtonText;outline:1px auto -webkit-focus-ring-color}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.hero-arrow-left-solid{--hero-arrow-left-solid:url('data:image/svg+xml;utf8,
');-webkit-mask:var(--hero-arrow-left-solid);mask:var(--hero-arrow-left-solid);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.hero-arrow-left-solid,.hero-arrow-path{background-color:currentColor;display:inline-block;height:1.25rem;vertical-align:middle;width:1.25rem}.hero-arrow-path{--hero-arrow-path:url('data:image/svg+xml;utf8,
');-webkit-mask:var(--hero-arrow-path);mask:var(--hero-arrow-path);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.hero-exclamation-circle-mini{--hero-exclamation-circle-mini:url('data:image/svg+xml;utf8,
');-webkit-mask:var(--hero-exclamation-circle-mini);mask:var(--hero-exclamation-circle-mini);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.hero-exclamation-circle-mini,.hero-information-circle-mini{background-color:currentColor;display:inline-block;height:1.25rem;vertical-align:middle;width:1.25rem}.hero-information-circle-mini{--hero-information-circle-mini:url('data:image/svg+xml;utf8,
');-webkit-mask:var(--hero-information-circle-mini);mask:var(--hero-information-circle-mini);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.hero-x-mark-solid{--hero-x-mark-solid:url('data:image/svg+xml;utf8,
');background-color:currentColor;display:inline-block;height:1.25rem;-webkit-mask:var(--hero-x-mark-solid);mask:var(--hero-x-mark-solid);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;vertical-align:middle;width:1.25rem}.sr-only{clip:rect(0,0,0,0);border-width:0;height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.-inset-y-px{bottom:-1px;top:-1px}.-left-4{left:-1rem}.-right-4{right:-1rem}.bottom-0{bottom:0}.left-0{left:0}.right-0{right:0}.right-1{right:.25rem}.right-2{right:.5rem}.right-5{right:1.25rem}.right-\[5px\]{right:5px}.top-0{top:0}.top-1{top:.25rem}.top-2{top:.5rem}.top-6{top:1.5rem}.top-\[5px\]{top:5px}.z-10{z-index:10}.z-50{z-index:50}.col-start-1{grid-column-start:1}.col-end-1{grid-column-end:1}.row-start-1{grid-row-start:1}.row-end-2{grid-row-end:2}.-m-3{margin:-.75rem}.m-4{margin:1rem}.-my-4{margin-bottom:-1rem;margin-top:-1rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.ml-1{margin-left:.25rem}.ml-12{margin-left:3rem}.ml-2{margin-left:.5rem}.ml-4{margin-left:1rem}.ml-6{margin-left:1.5rem}.ml-8{margin-left:2rem}.mr-2{margin-right:.5rem}.mt-0{margin-top:0}.mt-0\.5{margin-top:.125rem}.mt-10{margin-top:2.5rem}.mt-11{margin-top:2.75rem}.mt-12{margin-top:3rem}.mt-14{margin-top:3.5rem}.mt-16{margin-top:4rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.flow-root{display:flow-root}.grid{display:grid}.contents{display:contents}.hidden{display:none}.aspect-square{aspect-ratio:1/1}.h-10{height:2.5rem}.h-14{height:3.5rem}.h-2\/3{height:66.666667%}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-\[14px\]{height:14px}.h-full{height:100%}.h-screen{height:100vh}.max-h-screen{max-height:100vh}.min-h-\[6rem\]{min-height:6rem}.min-h-full{min-height:100%}.w-1\/4{width:25%}.w-14{width:3.5rem}.w-3{width:.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-80{width:20rem}.w-\[14px\]{width:14px}.w-\[40rem\]{width:40rem}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-7xl{max-width:80rem}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-none{flex:none}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.origin-center{transform-origin:center}.translate-y-0{--tw-translate-y:0px}.translate-y-0,.translate-y-4{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-4{--tw-translate-y:1rem}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.cursor-pointer{cursor:pointer}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.space-x-1>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.25rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.25rem*var(--tw-space-x-reverse))}.space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.75rem*var(--tw-space-x-reverse))}.space-y-12>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(3rem*var(--tw-space-y-reverse));margin-top:calc(3rem*(1 - var(--tw-space-y-reverse)))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)))}.divide-zinc-100>:not([hidden])~:not([hidden]){--tw-divide-opacity:1;border-color:rgb(244 244 245/var(--tw-divide-opacity))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.whitespace-nowrap{white-space:nowrap}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.border-gray-400{--tw-border-opacity:1;border-color:rgb(156 163 175/var(--tw-border-opacity))}.border-red-200{--tw-border-opacity:1;border-color:rgb(254 202 202/var(--tw-border-opacity))}.border-rose-400{--tw-border-opacity:1;border-color:rgb(251 113 133/var(--tw-border-opacity))}.border-transparent{border-color:#0000}.border-zinc-100{--tw-border-opacity:1;border-color:rgb(244 244 245/var(--tw-border-opacity))}.border-zinc-200{--tw-border-opacity:1;border-color:rgb(228 228 231/var(--tw-border-opacity))}.border-zinc-300{--tw-border-opacity:1;border-color:rgb(212 212 216/var(--tw-border-opacity))}.\!bg-red-100{--tw-bg-opacity:1!important;background-color:rgb(254 226 226/var(--tw-bg-opacity))!important}.bg-brand\/5{background-color:#fd4f000d}.bg-emerald-50{--tw-bg-opacity:1;background-color:rgb(236 253 245/var(--tw-bg-opacity))}.bg-indigo-500{--tw-bg-opacity:1;background-color:rgb(99 102 241/var(--tw-bg-opacity))}.bg-orange-100{--tw-bg-opacity:1;background-color:rgb(255 237 213/var(--tw-bg-opacity))}.bg-orange-500{--tw-bg-opacity:1;background-color:rgb(249 115 22/var(--tw-bg-opacity))}.bg-red-700{--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity))}.bg-rose-50{--tw-bg-opacity:1;background-color:rgb(255 241 242/var(--tw-bg-opacity))}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-slate-200{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.bg-slate-400{--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-zinc-50\/90{background-color:#fafafae6}.bg-zinc-900{--tw-bg-opacity:1;background-color:rgb(24 24 27/var(--tw-bg-opacity))}.fill-cyan-900{fill:#164e63}.fill-rose-900{fill:#881337}.p-0{padding:0}.p-12{padding:3rem}.p-14{padding:3.5rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-\[5px\]{padding:5px}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.py-0{padding-bottom:0;padding-top:0}.py-0\.5{padding-bottom:.125rem;padding-top:.125rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-10{padding-bottom:2.5rem;padding-top:2.5rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.py-4{padding-top:1rem}.pb-4,.py-4{padding-bottom:1rem}.pr-6{padding-right:1.5rem}.pt-0{padding-top:0}.pt-12{padding-top:3rem}.pt-8{padding-top:2rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-sans{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[0\.8125rem\]{font-size:.8125rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.capitalize{text-transform:capitalize}.leading-5{line-height:1.25rem}.leading-6{line-height:1.5rem}.leading-8{line-height:2rem}.tracking-tight{letter-spacing:-.025em}.\!text-red-700{--tw-text-opacity:1!important;color:rgb(185 28 28/var(--tw-text-opacity))!important}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.text-black\/50{color:#00000080}.text-brand{--tw-text-opacity:1;color:rgb(253 79 0/var(--tw-text-opacity))}.text-emerald-800{--tw-text-opacity:1;color:rgb(6 95 70/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.text-orange-400{--tw-text-opacity:1;color:rgb(251 146 60/var(--tw-text-opacity))}.text-orange-600{--tw-text-opacity:1;color:rgb(234 88 12/var(--tw-text-opacity))}.text-orange-800{--tw-text-opacity:1;color:rgb(154 52 18/var(--tw-text-opacity))}.text-rose-600{--tw-text-opacity:1;color:rgb(225 29 72/var(--tw-text-opacity))}.text-rose-900{--tw-text-opacity:1;color:rgb(136 19 55/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-zinc-500{--tw-text-opacity:1;color:rgb(113 113 122/var(--tw-text-opacity))}.text-zinc-600{--tw-text-opacity:1;color:rgb(82 82 91/var(--tw-text-opacity))}.text-zinc-700{--tw-text-opacity:1;color:rgb(63 63 70/var(--tw-text-opacity))}.text-zinc-800{--tw-text-opacity:1;color:rgb(39 39 42/var(--tw-text-opacity))}.text-zinc-900{--tw-text-opacity:1;color:rgb(24 24 27/var(--tw-text-opacity))}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-0{opacity:0}.opacity-100{opacity:1}.opacity-20{opacity:.2}.opacity-40{opacity:.4}.shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-lg,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-zinc-700\/10{--tw-shadow-color:#3f3f461a;--tw-shadow:var(--tw-shadow-colored)}.outline{outline-style:solid}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-emerald-500{--tw-ring-opacity:1;--tw-ring-color:rgb(16 185 129/var(--tw-ring-opacity))}.ring-rose-500{--tw-ring-opacity:1;--tw-ring-color:rgb(244 63 94/var(--tw-ring-opacity))}.ring-zinc-700\/10{--tw-ring-color:#3f3f461a}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-all{transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-opacity{transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.\[scrollbar-gutter\:stable\]{scrollbar-gutter:stable}.hover\:cursor-pointer:hover{cursor:pointer}.hover\:border-orange-500:hover{--tw-border-opacity:1;border-color:rgb(249 115 22/var(--tw-border-opacity))}.hover\:bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.hover\:bg-red-600:hover{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity))}.hover\:bg-zinc-50:hover{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity))}.hover\:bg-zinc-700:hover{--tw-bg-opacity:1;background-color:rgb(63 63 70/var(--tw-bg-opacity))}.hover\:text-black:hover{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.hover\:text-zinc-700:hover{--tw-text-opacity:1;color:rgb(63 63 70/var(--tw-text-opacity))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-40:hover{opacity:.4}.hover\:ring-gray-400:hover{--tw-ring-opacity:1;--tw-ring-color:rgb(156 163 175/var(--tw-ring-opacity))}.hover\:ring-red-900:hover{--tw-ring-opacity:1;--tw-ring-color:rgb(127 29 29/var(--tw-ring-opacity))}.focus\:border-rose-400:focus{--tw-border-opacity:1;border-color:rgb(251 113 133/var(--tw-border-opacity))}.focus\:border-zinc-400:focus{--tw-border-opacity:1;border-color:rgb(161 161 170/var(--tw-border-opacity))}.focus\:opacity-100:focus{opacity:1}.focus\:outline-none:focus{outline:2px solid #0000;outline-offset:2px}.focus\:ring-0:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)}.focus\:ring-0:focus,.focus\:ring-1:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-1:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px}.focus-visible\:outline-none:focus-visible{outline:2px solid #0000;outline-offset:2px}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px}.active\:text-white\/80:active{color:#fffc}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:bg-zinc-50{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity))}.group:hover .group-hover\:opacity-100{opacity:1}.group:hover .group-hover\:opacity-70{opacity:.7}.phx-no-feedback.phx-no-feedback\:hidden{display:none}.phx-no-feedback.phx-no-feedback\:border-zinc-300{--tw-border-opacity:1;border-color:rgb(212 212 216/var(--tw-border-opacity))}.phx-no-feedback.phx-no-feedback\:focus\:border-zinc-400:focus{--tw-border-opacity:1;border-color:rgb(161 161 170/var(--tw-border-opacity))}.phx-no-feedback .phx-no-feedback\:hidden{display:none}.phx-no-feedback .phx-no-feedback\:border-zinc-300{--tw-border-opacity:1;border-color:rgb(212 212 216/var(--tw-border-opacity))}.phx-no-feedback .phx-no-feedback\:focus\:border-zinc-400:focus{--tw-border-opacity:1;border-color:rgb(161 161 170/var(--tw-border-opacity))}.phx-submit-loading .phx-submit-loading\:opacity-75,.phx-submit-loading.phx-submit-loading\:opacity-75{opacity:.75}@media (prefers-color-scheme:dark){.dark\:bg-blue-900{--tw-bg-opacity:1;background-color:rgb(30 58 138/var(--tw-bg-opacity))}.dark\:text-blue-300{--tw-text-opacity:1;color:rgb(147 197 253/var(--tw-text-opacity))}}@media (min-width:640px){.sm\:bottom-auto{bottom:auto}.sm\:top-auto{top:auto}.sm\:ml-3{margin-left:.75rem}.sm\:mt-0{margin-top:0}.sm\:mt-24{margin-top:6rem}.sm\:mt-5{margin-top:1.25rem}.sm\:block{display:block}.sm\:flex{display:flex}.sm\:w-96{width:24rem}.sm\:w-auto{width:auto}.sm\:w-full{width:100%}.sm\:flex-shrink-0{flex-shrink:0}.sm\:translate-y-0{--tw-translate-y:0px}.sm\:scale-100,.sm\:translate-y-0{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.sm\:scale-100{--tw-scale-x:1;--tw-scale-y:1}.sm\:scale-95{--tw-scale-x:.95;--tw-scale-y:.95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.sm\:items-center{align-items:center}.sm\:justify-center{justify-content:center}.sm\:gap-6{gap:1.5rem}.sm\:gap-8{gap:2rem}.sm\:overflow-visible{overflow:visible}.sm\:rounded-l-xl{border-bottom-left-radius:.75rem;border-top-left-radius:.75rem}.sm\:rounded-r-xl{border-bottom-right-radius:.75rem;border-top-right-radius:.75rem}.sm\:p-6{padding:1.5rem}.sm\:px-0{padding-left:0;padding-right:0}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:text-center{text-align:center}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}.sm\:text-xl{font-size:1.25rem;line-height:1.75rem}.sm\:leading-6{line-height:1.5rem}.sm\:leading-none{line-height:1}}@media (min-width:768px){.md\:mx-auto{margin-left:auto;margin-right:auto}.md\:block{display:block}.md\:max-w-2xl{max-width:42rem}.md\:max-w-\[420px\]{max-width:420px}}@media (min-width:1024px){.lg\:col-span-5{grid-column:span 5/span 5}.lg\:col-span-6{grid-column:span 6/span 6}.lg\:mt-0{margin-top:0}.lg\:mt-6{margin-top:1.5rem}.lg\:flex{display:flex}.lg\:grid{display:grid}.lg\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.lg\:items-center{align-items:center}.lg\:justify-start{justify-content:flex-start}.lg\:gap-6{gap:1.5rem}.lg\:gap-8{gap:2rem}.lg\:px-8{padding-left:2rem;padding-right:2rem}.lg\:py-8{padding-bottom:2rem;padding-top:2rem}.lg\:pt-0{padding-top:0}.lg\:text-left{text-align:left}.lg\:text-5xl{font-size:3rem;line-height:1}.lg\:text-lg{font-size:1.125rem;line-height:1.75rem}}@media (min-width:1280px){.xl\:gap-8{gap:2rem}.xl\:text-6xl{font-size:3.75rem;line-height:1}.xl\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media (scripting:enabled){.\[\@media\(scripting\:enabled\)\]\:opacity-0{opacity:0}[data-phx-main] .\[\@media\(scripting\:enabled\)\{\[data-phx-main\]_\&\}\]\:opacity-100{opacity:1}}
\ No newline at end of file
+/*
+! tailwindcss v3.3.2 | MIT License | https://tailwindcss.com
+*/
+
+/*
+1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
+2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
+*/
+
+*,
+::before,
+::after {
+ box-sizing: border-box;
+ /* 1 */
+ border-width: 0;
+ /* 2 */
+ border-style: solid;
+ /* 2 */
+ border-color: #e5e7eb;
+ /* 2 */
+}
+
+::before,
+::after {
+ --tw-content: '';
+}
+
+/*
+1. Use a consistent sensible line-height in all browsers.
+2. Prevent adjustments of font size after orientation changes in iOS.
+3. Use a more readable tab size.
+4. Use the user's configured `sans` font-family by default.
+5. Use the user's configured `sans` font-feature-settings by default.
+6. Use the user's configured `sans` font-variation-settings by default.
+*/
+
+html {
+ line-height: 1.5;
+ /* 1 */
+ -webkit-text-size-adjust: 100%;
+ /* 2 */
+ -moz-tab-size: 4;
+ /* 3 */
+ -o-tab-size: 4;
+ tab-size: 4;
+ /* 3 */
+ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ /* 4 */
+ font-feature-settings: normal;
+ /* 5 */
+ font-variation-settings: normal;
+ /* 6 */
+}
+
+/*
+1. Remove the margin in all browsers.
+2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
+*/
+
+body {
+ margin: 0;
+ /* 1 */
+ line-height: inherit;
+ /* 2 */
+}
+
+/*
+1. Add the correct height in Firefox.
+2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
+3. Ensure horizontal rules are visible by default.
+*/
+
+hr {
+ height: 0;
+ /* 1 */
+ color: inherit;
+ /* 2 */
+ border-top-width: 1px;
+ /* 3 */
+}
+
+/*
+Add the correct text decoration in Chrome, Edge, and Safari.
+*/
+
+abbr:where([title]) {
+ -webkit-text-decoration: underline dotted;
+ text-decoration: underline dotted;
+}
+
+/*
+Remove the default font size and weight for headings.
+*/
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-size: inherit;
+ font-weight: inherit;
+}
+
+/*
+Reset links to optimize for opt-in styling instead of opt-out.
+*/
+
+a {
+ color: inherit;
+ text-decoration: inherit;
+}
+
+/*
+Add the correct font weight in Edge and Safari.
+*/
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+/*
+1. Use the user's configured `mono` font family by default.
+2. Correct the odd `em` font sizing in all browsers.
+*/
+
+code,
+kbd,
+samp,
+pre {
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+ /* 1 */
+ font-size: 1em;
+ /* 2 */
+}
+
+/*
+Add the correct font size in all browsers.
+*/
+
+small {
+ font-size: 80%;
+}
+
+/*
+Prevent `sub` and `sup` elements from affecting the line height in all browsers.
+*/
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+/*
+1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
+2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
+3. Remove gaps between table borders by default.
+*/
+
+table {
+ text-indent: 0;
+ /* 1 */
+ border-color: inherit;
+ /* 2 */
+ border-collapse: collapse;
+ /* 3 */
+}
+
+/*
+1. Change the font styles in all browsers.
+2. Remove the margin in Firefox and Safari.
+3. Remove default padding in all browsers.
+*/
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: inherit;
+ /* 1 */
+ font-size: 100%;
+ /* 1 */
+ font-weight: inherit;
+ /* 1 */
+ line-height: inherit;
+ /* 1 */
+ color: inherit;
+ /* 1 */
+ margin: 0;
+ /* 2 */
+ padding: 0;
+ /* 3 */
+}
+
+/*
+Remove the inheritance of text transform in Edge and Firefox.
+*/
+
+button,
+select {
+ text-transform: none;
+}
+
+/*
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Remove default button styles.
+*/
+
+button,
+[type='button'],
+[type='reset'],
+[type='submit'] {
+ -webkit-appearance: button;
+ /* 1 */
+ background-color: transparent;
+ /* 2 */
+ background-image: none;
+ /* 2 */
+}
+
+/*
+Use the modern Firefox focus style for all focusable elements.
+*/
+
+:-moz-focusring {
+ outline: auto;
+}
+
+/*
+Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
+*/
+
+:-moz-ui-invalid {
+ box-shadow: none;
+}
+
+/*
+Add the correct vertical alignment in Chrome and Firefox.
+*/
+
+progress {
+ vertical-align: baseline;
+}
+
+/*
+Correct the cursor style of increment and decrement buttons in Safari.
+*/
+
+::-webkit-inner-spin-button,
+::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/*
+1. Correct the odd appearance in Chrome and Safari.
+2. Correct the outline style in Safari.
+*/
+
+[type='search'] {
+ -webkit-appearance: textfield;
+ /* 1 */
+ outline-offset: -2px;
+ /* 2 */
+}
+
+/*
+Remove the inner padding in Chrome and Safari on macOS.
+*/
+
+::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/*
+1. Correct the inability to style clickable types in iOS and Safari.
+2. Change font properties to `inherit` in Safari.
+*/
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ /* 1 */
+ font: inherit;
+ /* 2 */
+}
+
+/*
+Add the correct display in Chrome and Safari.
+*/
+
+summary {
+ display: list-item;
+}
+
+/*
+Removes the default spacing and border for appropriate elements.
+*/
+
+blockquote,
+dl,
+dd,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+hr,
+figure,
+p,
+pre {
+ margin: 0;
+}
+
+fieldset {
+ margin: 0;
+ padding: 0;
+}
+
+legend {
+ padding: 0;
+}
+
+ol,
+ul,
+menu {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+/*
+Prevent resizing textareas horizontally by default.
+*/
+
+textarea {
+ resize: vertical;
+}
+
+/*
+1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
+2. Set the default placeholder color to the user's configured gray 400 color.
+*/
+
+input::-moz-placeholder, textarea::-moz-placeholder {
+ opacity: 1;
+ /* 1 */
+ color: #9ca3af;
+ /* 2 */
+}
+
+input::placeholder,
+textarea::placeholder {
+ opacity: 1;
+ /* 1 */
+ color: #9ca3af;
+ /* 2 */
+}
+
+/*
+Set the default cursor for buttons.
+*/
+
+button,
+[role="button"] {
+ cursor: pointer;
+}
+
+/*
+Make sure disabled buttons don't get the pointer cursor.
+*/
+
+:disabled {
+ cursor: default;
+}
+
+/*
+1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
+2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
+ This can trigger a poorly considered lint error in some tools but is included by design.
+*/
+
+img,
+svg,
+video,
+canvas,
+audio,
+iframe,
+embed,
+object {
+ display: block;
+ /* 1 */
+ vertical-align: middle;
+ /* 2 */
+}
+
+/*
+Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
+*/
+
+img,
+video {
+ max-width: 100%;
+ height: auto;
+}
+
+/* Make elements with the HTML hidden attribute stay hidden by default */
+
+[hidden] {
+ display: none;
+}
+
+[type='text'],[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ background-color: #fff;
+ border-color: #6b7280;
+ border-width: 1px;
+ border-radius: 0px;
+ padding-top: 0.5rem;
+ padding-right: 0.75rem;
+ padding-bottom: 0.5rem;
+ padding-left: 0.75rem;
+ font-size: 1rem;
+ line-height: 1.5rem;
+ --tw-shadow: 0 0 #0000;
+}
+
+[type='text']:focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+ --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: #2563eb;
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
+ border-color: #2563eb;
+}
+
+input::-moz-placeholder, textarea::-moz-placeholder {
+ color: #6b7280;
+ opacity: 1;
+}
+
+input::placeholder,textarea::placeholder {
+ color: #6b7280;
+ opacity: 1;
+}
+
+::-webkit-datetime-edit-fields-wrapper {
+ padding: 0;
+}
+
+::-webkit-date-and-time-value {
+ min-height: 1.5em;
+}
+
+::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field {
+ padding-top: 0;
+ padding-bottom: 0;
+}
+
+select {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
+ background-position: right 0.5rem center;
+ background-repeat: no-repeat;
+ background-size: 1.5em 1.5em;
+ padding-right: 2.5rem;
+ -webkit-print-color-adjust: exact;
+ print-color-adjust: exact;
+}
+
+[multiple] {
+ background-image: initial;
+ background-position: initial;
+ background-repeat: unset;
+ background-size: initial;
+ padding-right: 0.75rem;
+ -webkit-print-color-adjust: unset;
+ print-color-adjust: unset;
+}
+
+[type='checkbox'],[type='radio'] {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ padding: 0;
+ -webkit-print-color-adjust: exact;
+ print-color-adjust: exact;
+ display: inline-block;
+ vertical-align: middle;
+ background-origin: border-box;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ flex-shrink: 0;
+ height: 1rem;
+ width: 1rem;
+ color: #2563eb;
+ background-color: #fff;
+ border-color: #6b7280;
+ border-width: 1px;
+ --tw-shadow: 0 0 #0000;
+}
+
+[type='checkbox'] {
+ border-radius: 0px;
+}
+
+[type='radio'] {
+ border-radius: 100%;
+}
+
+[type='checkbox']:focus,[type='radio']:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+ --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
+ --tw-ring-offset-width: 2px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: #2563eb;
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
+}
+
+[type='checkbox']:checked,[type='radio']:checked {
+ border-color: transparent;
+ background-color: currentColor;
+ background-size: 100% 100%;
+ background-position: center;
+ background-repeat: no-repeat;
+}
+
+[type='checkbox']:checked {
+ background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
+}
+
+[type='radio']:checked {
+ background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");
+}
+
+[type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus {
+ border-color: transparent;
+ background-color: currentColor;
+}
+
+[type='checkbox']:indeterminate {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e");
+ border-color: transparent;
+ background-color: currentColor;
+ background-size: 100% 100%;
+ background-position: center;
+ background-repeat: no-repeat;
+}
+
+[type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus {
+ border-color: transparent;
+ background-color: currentColor;
+}
+
+[type='file'] {
+ background: unset;
+ border-color: inherit;
+ border-width: 0;
+ border-radius: 0;
+ padding: 0;
+ font-size: unset;
+ line-height: inherit;
+}
+
+[type='file']:focus {
+ outline: 1px solid ButtonText;
+ outline: 1px auto -webkit-focus-ring-color;
+}
+
+*, ::before, ::after {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-gradient-from-position: ;
+ --tw-gradient-via-position: ;
+ --tw-gradient-to-position: ;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia: ;
+}
+
+::backdrop {
+ --tw-border-spacing-x: 0;
+ --tw-border-spacing-y: 0;
+ --tw-translate-x: 0;
+ --tw-translate-y: 0;
+ --tw-rotate: 0;
+ --tw-skew-x: 0;
+ --tw-skew-y: 0;
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ --tw-pan-x: ;
+ --tw-pan-y: ;
+ --tw-pinch-zoom: ;
+ --tw-scroll-snap-strictness: proximity;
+ --tw-gradient-from-position: ;
+ --tw-gradient-via-position: ;
+ --tw-gradient-to-position: ;
+ --tw-ordinal: ;
+ --tw-slashed-zero: ;
+ --tw-numeric-figure: ;
+ --tw-numeric-spacing: ;
+ --tw-numeric-fraction: ;
+ --tw-ring-inset: ;
+ --tw-ring-offset-width: 0px;
+ --tw-ring-offset-color: #fff;
+ --tw-ring-color: rgb(59 130 246 / 0.5);
+ --tw-ring-offset-shadow: 0 0 #0000;
+ --tw-ring-shadow: 0 0 #0000;
+ --tw-shadow: 0 0 #0000;
+ --tw-shadow-colored: 0 0 #0000;
+ --tw-blur: ;
+ --tw-brightness: ;
+ --tw-contrast: ;
+ --tw-grayscale: ;
+ --tw-hue-rotate: ;
+ --tw-invert: ;
+ --tw-saturate: ;
+ --tw-sepia: ;
+ --tw-drop-shadow: ;
+ --tw-backdrop-blur: ;
+ --tw-backdrop-brightness: ;
+ --tw-backdrop-contrast: ;
+ --tw-backdrop-grayscale: ;
+ --tw-backdrop-hue-rotate: ;
+ --tw-backdrop-invert: ;
+ --tw-backdrop-opacity: ;
+ --tw-backdrop-saturate: ;
+ --tw-backdrop-sepia: ;
+}
+
+.container {
+ width: 100%;
+}
+
+@media (min-width: 640px) {
+ .container {
+ max-width: 640px;
+ }
+}
+
+@media (min-width: 768px) {
+ .container {
+ max-width: 768px;
+ }
+}
+
+@media (min-width: 1024px) {
+ .container {
+ max-width: 1024px;
+ }
+}
+
+@media (min-width: 1280px) {
+ .container {
+ max-width: 1280px;
+ }
+}
+
+@media (min-width: 1536px) {
+ .container {
+ max-width: 1536px;
+ }
+}
+
+.hero-arrow-left-solid {
+ --hero-arrow-left-solid: url('data:image/svg+xml;utf8,
');
+ -webkit-mask: var(--hero-arrow-left-solid);
+ mask: var(--hero-arrow-left-solid);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ background-color: currentColor;
+ vertical-align: middle;
+ display: inline-block;
+ width: 1.25rem;
+ height: 1.25rem;
+}
+
+.hero-arrow-path {
+ --hero-arrow-path: url('data:image/svg+xml;utf8,
');
+ -webkit-mask: var(--hero-arrow-path);
+ mask: var(--hero-arrow-path);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ background-color: currentColor;
+ vertical-align: middle;
+ display: inline-block;
+ width: 1.25rem;
+ height: 1.25rem;
+}
+
+.hero-exclamation-circle-mini {
+ --hero-exclamation-circle-mini: url('data:image/svg+xml;utf8,
');
+ -webkit-mask: var(--hero-exclamation-circle-mini);
+ mask: var(--hero-exclamation-circle-mini);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ background-color: currentColor;
+ vertical-align: middle;
+ display: inline-block;
+ width: 1.25rem;
+ height: 1.25rem;
+}
+
+.hero-exclamation-triangle {
+ --hero-exclamation-triangle: url('data:image/svg+xml;utf8,
');
+ -webkit-mask: var(--hero-exclamation-triangle);
+ mask: var(--hero-exclamation-triangle);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ background-color: currentColor;
+ vertical-align: middle;
+ display: inline-block;
+ width: 1.25rem;
+ height: 1.25rem;
+}
+
+.hero-information-circle-mini {
+ --hero-information-circle-mini: url('data:image/svg+xml;utf8,
');
+ -webkit-mask: var(--hero-information-circle-mini);
+ mask: var(--hero-information-circle-mini);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ background-color: currentColor;
+ vertical-align: middle;
+ display: inline-block;
+ width: 1.25rem;
+ height: 1.25rem;
+}
+
+.hero-x-mark {
+ --hero-x-mark: url('data:image/svg+xml;utf8,
');
+ -webkit-mask: var(--hero-x-mark);
+ mask: var(--hero-x-mark);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ background-color: currentColor;
+ vertical-align: middle;
+ display: inline-block;
+ width: 1.25rem;
+ height: 1.25rem;
+}
+
+.hero-x-mark-solid {
+ --hero-x-mark-solid: url('data:image/svg+xml;utf8,
');
+ -webkit-mask: var(--hero-x-mark-solid);
+ mask: var(--hero-x-mark-solid);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ background-color: currentColor;
+ vertical-align: middle;
+ display: inline-block;
+ width: 1.25rem;
+ height: 1.25rem;
+}
+
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ white-space: nowrap;
+ border-width: 0;
+}
+
+.pointer-events-none {
+ pointer-events: none;
+}
+
+.pointer-events-auto {
+ pointer-events: auto;
+}
+
+.static {
+ position: static;
+}
+
+.fixed {
+ position: fixed;
+}
+
+.absolute {
+ position: absolute;
+}
+
+.relative {
+ position: relative;
+}
+
+.inset-0 {
+ inset: 0px;
+}
+
+.-inset-y-px {
+ top: -1px;
+ bottom: -1px;
+}
+
+.-left-4 {
+ left: -1rem;
+}
+
+.-right-4 {
+ right: -1rem;
+}
+
+.bottom-0 {
+ bottom: 0px;
+}
+
+.left-0 {
+ left: 0px;
+}
+
+.right-0 {
+ right: 0px;
+}
+
+.right-1 {
+ right: 0.25rem;
+}
+
+.right-2 {
+ right: 0.5rem;
+}
+
+.right-5 {
+ right: 1.25rem;
+}
+
+.right-\[5px\] {
+ right: 5px;
+}
+
+.top-0 {
+ top: 0px;
+}
+
+.top-1 {
+ top: 0.25rem;
+}
+
+.top-2 {
+ top: 0.5rem;
+}
+
+.top-6 {
+ top: 1.5rem;
+}
+
+.top-\[5px\] {
+ top: 5px;
+}
+
+.z-10 {
+ z-index: 10;
+}
+
+.z-50 {
+ z-index: 50;
+}
+
+.col-span-1 {
+ grid-column: span 1 / span 1;
+}
+
+.col-span-3 {
+ grid-column: span 3 / span 3;
+}
+
+.col-start-1 {
+ grid-column-start: 1;
+}
+
+.col-end-1 {
+ grid-column-end: 1;
+}
+
+.row-start-1 {
+ grid-row-start: 1;
+}
+
+.row-end-2 {
+ grid-row-end: 2;
+}
+
+.-m-3 {
+ margin: -0.75rem;
+}
+
+.m-4 {
+ margin: 1rem;
+}
+
+.-my-4 {
+ margin-top: -1rem;
+ margin-bottom: -1rem;
+}
+
+.mx-2 {
+ margin-left: 0.5rem;
+ margin-right: 0.5rem;
+}
+
+.mx-auto {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.mb-2 {
+ margin-bottom: 0.5rem;
+}
+
+.mb-4 {
+ margin-bottom: 1rem;
+}
+
+.ml-1 {
+ margin-left: 0.25rem;
+}
+
+.ml-12 {
+ margin-left: 3rem;
+}
+
+.ml-2 {
+ margin-left: 0.5rem;
+}
+
+.ml-4 {
+ margin-left: 1rem;
+}
+
+.ml-6 {
+ margin-left: 1.5rem;
+}
+
+.ml-8 {
+ margin-left: 2rem;
+}
+
+.mr-2 {
+ margin-right: 0.5rem;
+}
+
+.mt-0 {
+ margin-top: 0px;
+}
+
+.mt-0\.5 {
+ margin-top: 0.125rem;
+}
+
+.mt-10 {
+ margin-top: 2.5rem;
+}
+
+.mt-11 {
+ margin-top: 2.75rem;
+}
+
+.mt-12 {
+ margin-top: 3rem;
+}
+
+.mt-14 {
+ margin-top: 3.5rem;
+}
+
+.mt-16 {
+ margin-top: 4rem;
+}
+
+.mt-2 {
+ margin-top: 0.5rem;
+}
+
+.mt-3 {
+ margin-top: 0.75rem;
+}
+
+.mt-4 {
+ margin-top: 1rem;
+}
+
+.mt-6 {
+ margin-top: 1.5rem;
+}
+
+.block {
+ display: block;
+}
+
+.inline-block {
+ display: inline-block;
+}
+
+.flex {
+ display: flex;
+}
+
+.inline-flex {
+ display: inline-flex;
+}
+
+.table {
+ display: table;
+}
+
+.flow-root {
+ display: flow-root;
+}
+
+.grid {
+ display: grid;
+}
+
+.contents {
+ display: contents;
+}
+
+.hidden {
+ display: none;
+}
+
+.aspect-square {
+ aspect-ratio: 1 / 1;
+}
+
+.h-10 {
+ height: 2.5rem;
+}
+
+.h-14 {
+ height: 3.5rem;
+}
+
+.h-2\/3 {
+ height: 66.666667%;
+}
+
+.h-3 {
+ height: 0.75rem;
+}
+
+.h-4 {
+ height: 1rem;
+}
+
+.h-5 {
+ height: 1.25rem;
+}
+
+.h-6 {
+ height: 1.5rem;
+}
+
+.h-\[14px\] {
+ height: 14px;
+}
+
+.h-full {
+ height: 100%;
+}
+
+.h-screen {
+ height: 100vh;
+}
+
+.max-h-screen {
+ max-height: 100vh;
+}
+
+.min-h-\[6rem\] {
+ min-height: 6rem;
+}
+
+.min-h-full {
+ min-height: 100%;
+}
+
+.w-1\/4 {
+ width: 25%;
+}
+
+.w-14 {
+ width: 3.5rem;
+}
+
+.w-3 {
+ width: 0.75rem;
+}
+
+.w-4 {
+ width: 1rem;
+}
+
+.w-5 {
+ width: 1.25rem;
+}
+
+.w-6 {
+ width: 1.5rem;
+}
+
+.w-80 {
+ width: 20rem;
+}
+
+.w-\[14px\] {
+ width: 14px;
+}
+
+.w-\[40rem\] {
+ width: 40rem;
+}
+
+.w-fit {
+ width: -moz-fit-content;
+ width: fit-content;
+}
+
+.w-full {
+ width: 100%;
+}
+
+.max-w-2xl {
+ max-width: 42rem;
+}
+
+.max-w-3xl {
+ max-width: 48rem;
+}
+
+.max-w-7xl {
+ max-width: 80rem;
+}
+
+.max-w-sm {
+ max-width: 24rem;
+}
+
+.max-w-xl {
+ max-width: 36rem;
+}
+
+.flex-1 {
+ flex: 1 1 0%;
+}
+
+.flex-none {
+ flex: none;
+}
+
+.shrink-0 {
+ flex-shrink: 0;
+}
+
+.grow {
+ flex-grow: 1;
+}
+
+.origin-center {
+ transform-origin: center;
+}
+
+.translate-y-0 {
+ --tw-translate-y: 0px;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.translate-y-4 {
+ --tw-translate-y: 1rem;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+.transform {
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+
+@keyframes spin {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.animate-spin {
+ animation: spin 1s linear infinite;
+}
+
+.cursor-pointer {
+ cursor: pointer;
+}
+
+.grid-cols-3 {
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+}
+
+.flex-col {
+ flex-direction: column;
+}
+
+.flex-col-reverse {
+ flex-direction: column-reverse;
+}
+
+.items-start {
+ align-items: flex-start;
+}
+
+.items-end {
+ align-items: flex-end;
+}
+
+.items-center {
+ align-items: center;
+}
+
+.justify-start {
+ justify-content: flex-start;
+}
+
+.justify-end {
+ justify-content: flex-end;
+}
+
+.justify-center {
+ justify-content: center;
+}
+
+.justify-between {
+ justify-content: space-between;
+}
+
+.gap-1 {
+ gap: 0.25rem;
+}
+
+.gap-1\.5 {
+ gap: 0.375rem;
+}
+
+.gap-2 {
+ gap: 0.5rem;
+}
+
+.gap-3 {
+ gap: 0.75rem;
+}
+
+.gap-4 {
+ gap: 1rem;
+}
+
+.gap-6 {
+ gap: 1.5rem;
+}
+
+.gap-x-2 {
+ -moz-column-gap: 0.5rem;
+ column-gap: 0.5rem;
+}
+
+.space-x-1 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-x-reverse: 0;
+ margin-right: calc(0.25rem * var(--tw-space-x-reverse));
+ margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse)));
+}
+
+.space-x-3 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-x-reverse: 0;
+ margin-right: calc(0.75rem * var(--tw-space-x-reverse));
+ margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse)));
+}
+
+.space-y-12 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(3rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(3rem * var(--tw-space-y-reverse));
+}
+
+.space-y-8 > :not([hidden]) ~ :not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse)));
+ margin-bottom: calc(2rem * var(--tw-space-y-reverse));
+}
+
+.divide-y > :not([hidden]) ~ :not([hidden]) {
+ --tw-divide-y-reverse: 0;
+ border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
+ border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
+}
+
+.divide-zinc-100 > :not([hidden]) ~ :not([hidden]) {
+ --tw-divide-opacity: 1;
+ border-color: rgb(244 244 245 / var(--tw-divide-opacity));
+}
+
+.overflow-hidden {
+ overflow: hidden;
+}
+
+.overflow-y-auto {
+ overflow-y: auto;
+}
+
+.whitespace-nowrap {
+ white-space: nowrap;
+}
+
+.rounded {
+ border-radius: 0.25rem;
+}
+
+.rounded-2xl {
+ border-radius: 1rem;
+}
+
+.rounded-full {
+ border-radius: 9999px;
+}
+
+.rounded-lg {
+ border-radius: 0.5rem;
+}
+
+.rounded-md {
+ border-radius: 0.375rem;
+}
+
+.rounded-xl {
+ border-radius: 0.75rem;
+}
+
+.border {
+ border-width: 1px;
+}
+
+.border-2 {
+ border-width: 2px;
+}
+
+.border-b {
+ border-bottom-width: 1px;
+}
+
+.border-t {
+ border-top-width: 1px;
+}
+
+.border-gray-300 {
+ --tw-border-opacity: 1;
+ border-color: rgb(209 213 219 / var(--tw-border-opacity));
+}
+
+.border-gray-400 {
+ --tw-border-opacity: 1;
+ border-color: rgb(156 163 175 / var(--tw-border-opacity));
+}
+
+.border-red-200 {
+ --tw-border-opacity: 1;
+ border-color: rgb(254 202 202 / var(--tw-border-opacity));
+}
+
+.border-rose-400 {
+ --tw-border-opacity: 1;
+ border-color: rgb(251 113 133 / var(--tw-border-opacity));
+}
+
+.border-transparent {
+ border-color: transparent;
+}
+
+.border-zinc-100 {
+ --tw-border-opacity: 1;
+ border-color: rgb(244 244 245 / var(--tw-border-opacity));
+}
+
+.border-zinc-200 {
+ --tw-border-opacity: 1;
+ border-color: rgb(228 228 231 / var(--tw-border-opacity));
+}
+
+.border-zinc-300 {
+ --tw-border-opacity: 1;
+ border-color: rgb(212 212 216 / var(--tw-border-opacity));
+}
+
+.\!bg-red-100 {
+ --tw-bg-opacity: 1 !important;
+ background-color: rgb(254 226 226 / var(--tw-bg-opacity)) !important;
+}
+
+.bg-brand\/5 {
+ background-color: rgb(253 79 0 / 0.05);
+}
+
+.bg-emerald-50 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(236 253 245 / var(--tw-bg-opacity));
+}
+
+.bg-indigo-500 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(99 102 241 / var(--tw-bg-opacity));
+}
+
+.bg-orange-100 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(255 237 213 / var(--tw-bg-opacity));
+}
+
+.bg-orange-500 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(249 115 22 / var(--tw-bg-opacity));
+}
+
+.bg-red-700 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(185 28 28 / var(--tw-bg-opacity));
+}
+
+.bg-rose-50 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(255 241 242 / var(--tw-bg-opacity));
+}
+
+.bg-slate-100 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(241 245 249 / var(--tw-bg-opacity));
+}
+
+.bg-slate-200 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(226 232 240 / var(--tw-bg-opacity));
+}
+
+.bg-slate-400 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(148 163 184 / var(--tw-bg-opacity));
+}
+
+.bg-white {
+ --tw-bg-opacity: 1;
+ background-color: rgb(255 255 255 / var(--tw-bg-opacity));
+}
+
+.bg-zinc-50\/90 {
+ background-color: rgb(250 250 250 / 0.9);
+}
+
+.bg-zinc-900 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(24 24 27 / var(--tw-bg-opacity));
+}
+
+.fill-cyan-900 {
+ fill: #164e63;
+}
+
+.fill-rose-900 {
+ fill: #881337;
+}
+
+.p-0 {
+ padding: 0px;
+}
+
+.p-12 {
+ padding: 3rem;
+}
+
+.p-14 {
+ padding: 3.5rem;
+}
+
+.p-2 {
+ padding: 0.5rem;
+}
+
+.p-3 {
+ padding: 0.75rem;
+}
+
+.p-4 {
+ padding: 1rem;
+}
+
+.p-\[5px\] {
+ padding: 5px;
+}
+
+.px-1 {
+ padding-left: 0.25rem;
+ padding-right: 0.25rem;
+}
+
+.px-2 {
+ padding-left: 0.5rem;
+ padding-right: 0.5rem;
+}
+
+.px-2\.5 {
+ padding-left: 0.625rem;
+ padding-right: 0.625rem;
+}
+
+.px-3 {
+ padding-left: 0.75rem;
+ padding-right: 0.75rem;
+}
+
+.px-4 {
+ padding-left: 1rem;
+ padding-right: 1rem;
+}
+
+.py-0 {
+ padding-top: 0px;
+ padding-bottom: 0px;
+}
+
+.py-0\.5 {
+ padding-top: 0.125rem;
+ padding-bottom: 0.125rem;
+}
+
+.py-1 {
+ padding-top: 0.25rem;
+ padding-bottom: 0.25rem;
+}
+
+.py-10 {
+ padding-top: 2.5rem;
+ padding-bottom: 2.5rem;
+}
+
+.py-2 {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+}
+
+.py-3 {
+ padding-top: 0.75rem;
+ padding-bottom: 0.75rem;
+}
+
+.py-4 {
+ padding-top: 1rem;
+ padding-bottom: 1rem;
+}
+
+.pb-4 {
+ padding-bottom: 1rem;
+}
+
+.pr-6 {
+ padding-right: 1.5rem;
+}
+
+.pt-0 {
+ padding-top: 0px;
+}
+
+.pt-12 {
+ padding-top: 3rem;
+}
+
+.pt-8 {
+ padding-top: 2rem;
+}
+
+.text-left {
+ text-align: left;
+}
+
+.text-center {
+ text-align: center;
+}
+
+.text-right {
+ text-align: right;
+}
+
+.font-sans {
+ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+}
+
+.text-2xl {
+ font-size: 1.5rem;
+ line-height: 2rem;
+}
+
+.text-4xl {
+ font-size: 2.25rem;
+ line-height: 2.5rem;
+}
+
+.text-\[0\.8125rem\] {
+ font-size: 0.8125rem;
+}
+
+.text-base {
+ font-size: 1rem;
+ line-height: 1.5rem;
+}
+
+.text-lg {
+ font-size: 1.125rem;
+ line-height: 1.75rem;
+}
+
+.text-sm {
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+}
+
+.text-xl {
+ font-size: 1.25rem;
+ line-height: 1.75rem;
+}
+
+.font-bold {
+ font-weight: 700;
+}
+
+.font-extrabold {
+ font-weight: 800;
+}
+
+.font-medium {
+ font-weight: 500;
+}
+
+.font-normal {
+ font-weight: 400;
+}
+
+.font-semibold {
+ font-weight: 600;
+}
+
+.capitalize {
+ text-transform: capitalize;
+}
+
+.leading-5 {
+ line-height: 1.25rem;
+}
+
+.leading-6 {
+ line-height: 1.5rem;
+}
+
+.leading-8 {
+ line-height: 2rem;
+}
+
+.tracking-tight {
+ letter-spacing: -0.025em;
+}
+
+.\!text-red-700 {
+ --tw-text-opacity: 1 !important;
+ color: rgb(185 28 28 / var(--tw-text-opacity)) !important;
+}
+
+.text-black {
+ --tw-text-opacity: 1;
+ color: rgb(0 0 0 / var(--tw-text-opacity));
+}
+
+.text-black\/50 {
+ color: rgb(0 0 0 / 0.5);
+}
+
+.text-brand {
+ --tw-text-opacity: 1;
+ color: rgb(253 79 0 / var(--tw-text-opacity));
+}
+
+.text-emerald-800 {
+ --tw-text-opacity: 1;
+ color: rgb(6 95 70 / var(--tw-text-opacity));
+}
+
+.text-gray-500 {
+ --tw-text-opacity: 1;
+ color: rgb(107 114 128 / var(--tw-text-opacity));
+}
+
+.text-gray-600 {
+ --tw-text-opacity: 1;
+ color: rgb(75 85 99 / var(--tw-text-opacity));
+}
+
+.text-gray-700 {
+ --tw-text-opacity: 1;
+ color: rgb(55 65 81 / var(--tw-text-opacity));
+}
+
+.text-gray-900 {
+ --tw-text-opacity: 1;
+ color: rgb(17 24 39 / var(--tw-text-opacity));
+}
+
+.text-orange-400 {
+ --tw-text-opacity: 1;
+ color: rgb(251 146 60 / var(--tw-text-opacity));
+}
+
+.text-orange-600 {
+ --tw-text-opacity: 1;
+ color: rgb(234 88 12 / var(--tw-text-opacity));
+}
+
+.text-orange-800 {
+ --tw-text-opacity: 1;
+ color: rgb(154 52 18 / var(--tw-text-opacity));
+}
+
+.text-rose-600 {
+ --tw-text-opacity: 1;
+ color: rgb(225 29 72 / var(--tw-text-opacity));
+}
+
+.text-rose-900 {
+ --tw-text-opacity: 1;
+ color: rgb(136 19 55 / var(--tw-text-opacity));
+}
+
+.text-white {
+ --tw-text-opacity: 1;
+ color: rgb(255 255 255 / var(--tw-text-opacity));
+}
+
+.text-zinc-500 {
+ --tw-text-opacity: 1;
+ color: rgb(113 113 122 / var(--tw-text-opacity));
+}
+
+.text-zinc-600 {
+ --tw-text-opacity: 1;
+ color: rgb(82 82 91 / var(--tw-text-opacity));
+}
+
+.text-zinc-700 {
+ --tw-text-opacity: 1;
+ color: rgb(63 63 70 / var(--tw-text-opacity));
+}
+
+.text-zinc-800 {
+ --tw-text-opacity: 1;
+ color: rgb(39 39 42 / var(--tw-text-opacity));
+}
+
+.text-zinc-900 {
+ --tw-text-opacity: 1;
+ color: rgb(24 24 27 / var(--tw-text-opacity));
+}
+
+.antialiased {
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.opacity-0 {
+ opacity: 0;
+}
+
+.opacity-100 {
+ opacity: 1;
+}
+
+.opacity-20 {
+ opacity: 0.2;
+}
+
+.opacity-40 {
+ opacity: 0.4;
+}
+
+.shadow-lg {
+ --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
+ --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-md {
+ --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
+ --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-sm {
+ --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+
+.shadow-zinc-700\/10 {
+ --tw-shadow-color: rgb(63 63 70 / 0.1);
+ --tw-shadow: var(--tw-shadow-colored);
+}
+
+.outline {
+ outline-style: solid;
+}
+
+.ring-1 {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
+}
+
+.ring-emerald-500 {
+ --tw-ring-opacity: 1;
+ --tw-ring-color: rgb(16 185 129 / var(--tw-ring-opacity));
+}
+
+.ring-rose-500 {
+ --tw-ring-opacity: 1;
+ --tw-ring-color: rgb(244 63 94 / var(--tw-ring-opacity));
+}
+
+.ring-zinc-700\/10 {
+ --tw-ring-color: rgb(63 63 70 / 0.1);
+}
+
+.filter {
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
+}
+
+.transition {
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+
+.transition-all {
+ transition-property: all;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+
+.transition-colors {
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+
+.transition-opacity {
+ transition-property: opacity;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+
+.duration-200 {
+ transition-duration: 200ms;
+}
+
+.duration-300 {
+ transition-duration: 300ms;
+}
+
+.ease-in {
+ transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
+}
+
+.ease-out {
+ transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
+}
+
+.\[scrollbar-gutter\:stable\] {
+ scrollbar-gutter: stable;
+}
+
+/* This file is for your main application CSS */
+
+.ecosystem-logo {
+ position: relative;
+ display: flex;
+ height: 3.5rem;
+ width: 3.5rem;
+ flex-shrink: 0;
+ overflow: hidden;
+ border-radius: 9999px;
+}
+
+.hover\:cursor-pointer:hover {
+ cursor: pointer;
+}
+
+.hover\:border-orange-500:hover {
+ --tw-border-opacity: 1;
+ border-color: rgb(249 115 22 / var(--tw-border-opacity));
+}
+
+.hover\:bg-gray-100:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(243 244 246 / var(--tw-bg-opacity));
+}
+
+.hover\:bg-red-600:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(220 38 38 / var(--tw-bg-opacity));
+}
+
+.hover\:bg-zinc-50:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(250 250 250 / var(--tw-bg-opacity));
+}
+
+.hover\:bg-zinc-700:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(63 63 70 / var(--tw-bg-opacity));
+}
+
+.hover\:text-black:hover {
+ --tw-text-opacity: 1;
+ color: rgb(0 0 0 / var(--tw-text-opacity));
+}
+
+.hover\:text-zinc-700:hover {
+ --tw-text-opacity: 1;
+ color: rgb(63 63 70 / var(--tw-text-opacity));
+}
+
+.hover\:underline:hover {
+ text-decoration-line: underline;
+}
+
+.hover\:opacity-40:hover {
+ opacity: 0.4;
+}
+
+.hover\:ring-gray-400:hover {
+ --tw-ring-opacity: 1;
+ --tw-ring-color: rgb(156 163 175 / var(--tw-ring-opacity));
+}
+
+.hover\:ring-red-900:hover {
+ --tw-ring-opacity: 1;
+ --tw-ring-color: rgb(127 29 29 / var(--tw-ring-opacity));
+}
+
+.focus\:border-rose-400:focus {
+ --tw-border-opacity: 1;
+ border-color: rgb(251 113 133 / var(--tw-border-opacity));
+}
+
+.focus\:border-zinc-400:focus {
+ --tw-border-opacity: 1;
+ border-color: rgb(161 161 170 / var(--tw-border-opacity));
+}
+
+.focus\:opacity-100:focus {
+ opacity: 1;
+}
+
+.focus\:outline-none:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+.focus\:ring-0:focus {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
+}
+
+.focus\:ring-1:focus {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
+}
+
+.focus\:ring-2:focus {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
+}
+
+.focus\:ring-offset-2:focus {
+ --tw-ring-offset-width: 2px;
+}
+
+.focus-visible\:outline-none:focus-visible {
+ outline: 2px solid transparent;
+ outline-offset: 2px;
+}
+
+.focus-visible\:ring-2:focus-visible {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
+}
+
+.focus-visible\:ring-offset-2:focus-visible {
+ --tw-ring-offset-width: 2px;
+}
+
+.active\:text-white\/80:active {
+ color: rgb(255 255 255 / 0.8);
+}
+
+.disabled\:pointer-events-none:disabled {
+ pointer-events: none;
+}
+
+.disabled\:opacity-50:disabled {
+ opacity: 0.5;
+}
+
+.group:hover .group-hover\:bg-zinc-50 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(250 250 250 / var(--tw-bg-opacity));
+}
+
+.group:hover .group-hover\:opacity-100 {
+ opacity: 1;
+}
+
+.group:hover .group-hover\:opacity-70 {
+ opacity: 0.7;
+}
+
+.phx-no-feedback.phx-no-feedback\:hidden {
+ display: none;
+}
+
+.phx-no-feedback.phx-no-feedback\:border-zinc-300 {
+ --tw-border-opacity: 1;
+ border-color: rgb(212 212 216 / var(--tw-border-opacity));
+}
+
+.phx-no-feedback.phx-no-feedback\:focus\:border-zinc-400:focus {
+ --tw-border-opacity: 1;
+ border-color: rgb(161 161 170 / var(--tw-border-opacity));
+}
+
+.phx-no-feedback .phx-no-feedback\:hidden {
+ display: none;
+}
+
+.phx-no-feedback .phx-no-feedback\:border-zinc-300 {
+ --tw-border-opacity: 1;
+ border-color: rgb(212 212 216 / var(--tw-border-opacity));
+}
+
+.phx-no-feedback .phx-no-feedback\:focus\:border-zinc-400:focus {
+ --tw-border-opacity: 1;
+ border-color: rgb(161 161 170 / var(--tw-border-opacity));
+}
+
+.phx-submit-loading.phx-submit-loading\:opacity-75 {
+ opacity: 0.75;
+}
+
+.phx-submit-loading .phx-submit-loading\:opacity-75 {
+ opacity: 0.75;
+}
+
+@media (prefers-color-scheme: dark) {
+ .dark\:bg-blue-900 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(30 58 138 / var(--tw-bg-opacity));
+ }
+
+ .dark\:text-blue-300 {
+ --tw-text-opacity: 1;
+ color: rgb(147 197 253 / var(--tw-text-opacity));
+ }
+}
+
+@media (min-width: 640px) {
+ .sm\:bottom-auto {
+ bottom: auto;
+ }
+
+ .sm\:top-auto {
+ top: auto;
+ }
+
+ .sm\:col-span-1 {
+ grid-column: span 1 / span 1;
+ }
+
+ .sm\:ml-3 {
+ margin-left: 0.75rem;
+ }
+
+ .sm\:mt-0 {
+ margin-top: 0px;
+ }
+
+ .sm\:mt-24 {
+ margin-top: 6rem;
+ }
+
+ .sm\:mt-5 {
+ margin-top: 1.25rem;
+ }
+
+ .sm\:block {
+ display: block;
+ }
+
+ .sm\:flex {
+ display: flex;
+ }
+
+ .sm\:w-96 {
+ width: 24rem;
+ }
+
+ .sm\:w-auto {
+ width: auto;
+ }
+
+ .sm\:w-full {
+ width: 100%;
+ }
+
+ .sm\:flex-shrink-0 {
+ flex-shrink: 0;
+ }
+
+ .sm\:translate-y-0 {
+ --tw-translate-y: 0px;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+ }
+
+ .sm\:scale-100 {
+ --tw-scale-x: 1;
+ --tw-scale-y: 1;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+ }
+
+ .sm\:scale-95 {
+ --tw-scale-x: .95;
+ --tw-scale-y: .95;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+ }
+
+ .sm\:items-center {
+ align-items: center;
+ }
+
+ .sm\:justify-center {
+ justify-content: center;
+ }
+
+ .sm\:gap-6 {
+ gap: 1.5rem;
+ }
+
+ .sm\:gap-8 {
+ gap: 2rem;
+ }
+
+ .sm\:overflow-visible {
+ overflow: visible;
+ }
+
+ .sm\:rounded-l-xl {
+ border-top-left-radius: 0.75rem;
+ border-bottom-left-radius: 0.75rem;
+ }
+
+ .sm\:rounded-r-xl {
+ border-top-right-radius: 0.75rem;
+ border-bottom-right-radius: 0.75rem;
+ }
+
+ .sm\:p-6 {
+ padding: 1.5rem;
+ }
+
+ .sm\:px-0 {
+ padding-left: 0px;
+ padding-right: 0px;
+ }
+
+ .sm\:px-4 {
+ padding-left: 1rem;
+ padding-right: 1rem;
+ }
+
+ .sm\:px-6 {
+ padding-left: 1.5rem;
+ padding-right: 1.5rem;
+ }
+
+ .sm\:text-center {
+ text-align: center;
+ }
+
+ .sm\:text-sm {
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ }
+
+ .sm\:text-xl {
+ font-size: 1.25rem;
+ line-height: 1.75rem;
+ }
+
+ .sm\:leading-6 {
+ line-height: 1.5rem;
+ }
+
+ .sm\:leading-none {
+ line-height: 1;
+ }
+}
+
+@media (min-width: 768px) {
+ .md\:mx-auto {
+ margin-left: auto;
+ margin-right: auto;
+ }
+
+ .md\:block {
+ display: block;
+ }
+
+ .md\:max-w-2xl {
+ max-width: 42rem;
+ }
+
+ .md\:max-w-\[420px\] {
+ max-width: 420px;
+ }
+}
+
+@media (min-width: 1024px) {
+ .lg\:col-span-1 {
+ grid-column: span 1 / span 1;
+ }
+
+ .lg\:col-span-5 {
+ grid-column: span 5 / span 5;
+ }
+
+ .lg\:col-span-6 {
+ grid-column: span 6 / span 6;
+ }
+
+ .lg\:mt-0 {
+ margin-top: 0px;
+ }
+
+ .lg\:mt-6 {
+ margin-top: 1.5rem;
+ }
+
+ .lg\:flex {
+ display: flex;
+ }
+
+ .lg\:grid {
+ display: grid;
+ }
+
+ .lg\:grid-cols-12 {
+ grid-template-columns: repeat(12, minmax(0, 1fr));
+ }
+
+ .lg\:items-center {
+ align-items: center;
+ }
+
+ .lg\:justify-start {
+ justify-content: flex-start;
+ }
+
+ .lg\:gap-6 {
+ gap: 1.5rem;
+ }
+
+ .lg\:gap-8 {
+ gap: 2rem;
+ }
+
+ .lg\:px-8 {
+ padding-left: 2rem;
+ padding-right: 2rem;
+ }
+
+ .lg\:py-8 {
+ padding-top: 2rem;
+ padding-bottom: 2rem;
+ }
+
+ .lg\:pt-0 {
+ padding-top: 0px;
+ }
+
+ .lg\:text-left {
+ text-align: left;
+ }
+
+ .lg\:text-5xl {
+ font-size: 3rem;
+ line-height: 1;
+ }
+
+ .lg\:text-lg {
+ font-size: 1.125rem;
+ line-height: 1.75rem;
+ }
+}
+
+@media (min-width: 1280px) {
+ .xl\:gap-8 {
+ gap: 2rem;
+ }
+
+ .xl\:text-6xl {
+ font-size: 3.75rem;
+ line-height: 1;
+ }
+
+ .xl\:text-xl {
+ font-size: 1.25rem;
+ line-height: 1.75rem;
+ }
+}
+
+@media (scripting:enabled) {
+ .\[\@media\(scripting\:enabled\)\]\:opacity-0 {
+ opacity: 0;
+ }
+
+ [data-phx-main] .\[\@media\(scripting\:enabled\)\{\[data-phx-main\]_\&\}\]\:opacity-100 {
+ opacity: 1;
+ }
+}
diff --git a/fullstack/priv/static/assets/app.js b/fullstack/priv/static/assets/app.js
index 8eee8ab..cad9dfc 100644
--- a/fullstack/priv/static/assets/app.js
+++ b/fullstack/priv/static/assets/app.js
@@ -1,22 +1,7362 @@
-(()=>{var os=Object.create;var ft=Object.defineProperty,ls=Object.defineProperties,hs=Object.getOwnPropertyDescriptor,ds=Object.getOwnPropertyDescriptors,cs=Object.getOwnPropertyNames,Ue=Object.getOwnPropertySymbols,us=Object.getPrototypeOf,pt=Object.prototype.hasOwnProperty,zt=Object.prototype.propertyIsEnumerable;var Xt=(e,t,i)=>t in e?ft(e,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[t]=i,q=(e,t)=>{for(var i in t||(t={}))pt.call(t,i)&&Xt(e,i,t[i]);if(Ue)for(var i of Ue(t))zt.call(t,i)&&Xt(e,i,t[i]);return e},Kt=(e,t)=>ls(e,ds(t));var Gt=(e,t)=>{var i={};for(var s in e)pt.call(e,s)&&t.indexOf(s)<0&&(i[s]=e[s]);if(e!=null&&Ue)for(var s of Ue(e))t.indexOf(s)<0&&zt.call(e,s)&&(i[s]=e[s]);return i};var fs=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var ps=(e,t,i,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of cs(t))!pt.call(e,r)&&r!==i&&ft(e,r,{get:()=>t[r],enumerable:!(s=hs(t,r))||s.enumerable});return e};var ms=(e,t,i)=>(i=e!=null?os(us(e)):{},ps(t||!e||!e.__esModule?ft(i,"default",{value:e,enumerable:!0}):i,e));var Mi=fs((Hi,nt)=>{(function(e,t){"use strict";(function(){for(var f=0,g=["ms","moz","webkit","o"],v=0;v
p.show(),f)}else r=!0,a!==null&&e.cancelAnimationFrame(a),i||m(),i.style.opacity=1,i.style.display="block",p.progress(0),h.autoRun&&function g(){n=e.requestAnimationFrame(g),p.progress("+"+.05*Math.pow(1-Math.sqrt(s),2))}()},progress:function(f){return typeof f=="undefined"||(typeof f=="string"&&(f=(f.indexOf("+")>=0||f.indexOf("-")>=0?s:0)+parseFloat(f)),s=f>1?1:f,d()),s},hide:function(){clearTimeout(o),o=null,r&&(r=!1,n!=null&&(e.cancelAnimationFrame(n),n=null),function f(){if(p.progress("+.1")>=1&&(i.style.opacity-=.05,i.style.opacity<=.05)){i.style.display="none",a=null;return}a=e.requestAnimationFrame(f)}())}};typeof nt=="object"&&typeof nt.exports=="object"?nt.exports=p:typeof define=="function"&&define.amd?define(function(){return p}):this.topbar=p}).call(Hi,window,document)});(function(){var e=t();function t(){if(typeof window.CustomEvent=="function")return window.CustomEvent;function r(n,a){a=a||{bubbles:!1,cancelable:!1,detail:void 0};var o=document.createEvent("CustomEvent");return o.initCustomEvent(n,a.bubbles,a.cancelable,a.detail),o}return r.prototype=window.Event.prototype,r}function i(r,n){var a=document.createElement("input");return a.type="hidden",a.name=r,a.value=n,a}function s(r,n){var a=r.getAttribute("data-to"),o=i("_method",r.getAttribute("data-method")),l=i("_csrf_token",r.getAttribute("data-csrf")),h=document.createElement("form"),d=document.createElement("input"),m=r.getAttribute("target");h.method=r.getAttribute("data-method")==="get"?"get":"post",h.action=a,h.style.display="none",m?h.target=m:n&&(h.target="_blank"),h.appendChild(l),h.appendChild(o),document.body.appendChild(h),d.type="submit",h.appendChild(d),d.click()}window.addEventListener("click",function(r){var n=r.target;if(!r.defaultPrevented)for(;n&&n.getAttribute;){var a=new e("phoenix.link.click",{bubbles:!0,cancelable:!0});if(!n.dispatchEvent(a))return r.preventDefault(),r.stopImmediatePropagation(),!1;if(n.getAttribute("data-method")&&n.getAttribute("data-to"))return s(n,r.metaKey||r.shiftKey),r.preventDefault(),!1;n=n.parentNode}},!1),window.addEventListener("phoenix.link.click",function(r){var n=r.target.getAttribute("data-confirm");n&&!window.confirm(n)&&r.preventDefault()},!1)})();var Ce=e=>typeof e=="function"?e:function(){return e},gs=typeof self!="undefined"?self:null,ke=typeof window!="undefined"?window:null,le=gs||ke||le,vs="2.0.0",W={connecting:0,open:1,closing:2,closed:3},bs=1e4,ys=1e3,$={closed:"closed",errored:"errored",joined:"joined",joining:"joining",leaving:"leaving"},Y={close:"phx_close",error:"phx_error",join:"phx_join",reply:"phx_reply",leave:"phx_leave"},mt={longpoll:"longpoll",websocket:"websocket"},ws={complete:4},je=class{constructor(e,t,i,s){this.channel=e,this.event=t,this.payload=i||function(){return{}},this.receivedResp=null,this.timeout=s,this.timeoutTimer=null,this.recHooks=[],this.sent=!1}resend(e){this.timeout=e,this.reset(),this.send()}send(){this.hasReceived("timeout")||(this.startTimeout(),this.sent=!0,this.channel.socket.push({topic:this.channel.topic,event:this.event,payload:this.payload(),ref:this.ref,join_ref:this.channel.joinRef()}))}receive(e,t){return this.hasReceived(e)&&t(this.receivedResp.response),this.recHooks.push({status:e,callback:t}),this}reset(){this.cancelRefEvent(),this.ref=null,this.refEvent=null,this.receivedResp=null,this.sent=!1}matchReceive({status:e,response:t,_ref:i}){this.recHooks.filter(s=>s.status===e).forEach(s=>s.callback(t))}cancelRefEvent(){this.refEvent&&this.channel.off(this.refEvent)}cancelTimeout(){clearTimeout(this.timeoutTimer),this.timeoutTimer=null}startTimeout(){this.timeoutTimer&&this.cancelTimeout(),this.ref=this.channel.socket.makeRef(),this.refEvent=this.channel.replyEventName(this.ref),this.channel.on(this.refEvent,e=>{this.cancelRefEvent(),this.cancelTimeout(),this.receivedResp=e,this.matchReceive(e)}),this.timeoutTimer=setTimeout(()=>{this.trigger("timeout",{})},this.timeout)}hasReceived(e){return this.receivedResp&&this.receivedResp.status===e}trigger(e,t){this.channel.trigger(this.refEvent,{status:e,response:t})}},Yt=class{constructor(e,t){this.callback=e,this.timerCalc=t,this.timer=null,this.tries=0}reset(){this.tries=0,clearTimeout(this.timer)}scheduleTimeout(){clearTimeout(this.timer),this.timer=setTimeout(()=>{this.tries=this.tries+1,this.callback()},this.timerCalc(this.tries+1))}},As=class{constructor(e,t,i){this.state=$.closed,this.topic=e,this.params=Ce(t||{}),this.socket=i,this.bindings=[],this.bindingRef=0,this.timeout=this.socket.timeout,this.joinedOnce=!1,this.joinPush=new je(this,Y.join,this.params,this.timeout),this.pushBuffer=[],this.stateChangeRefs=[],this.rejoinTimer=new Yt(()=>{this.socket.isConnected()&&this.rejoin()},this.socket.rejoinAfterMs),this.stateChangeRefs.push(this.socket.onError(()=>this.rejoinTimer.reset())),this.stateChangeRefs.push(this.socket.onOpen(()=>{this.rejoinTimer.reset(),this.isErrored()&&this.rejoin()})),this.joinPush.receive("ok",()=>{this.state=$.joined,this.rejoinTimer.reset(),this.pushBuffer.forEach(s=>s.send()),this.pushBuffer=[]}),this.joinPush.receive("error",()=>{this.state=$.errored,this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.onClose(()=>{this.rejoinTimer.reset(),this.socket.hasLogger()&&this.socket.log("channel",`close ${this.topic} ${this.joinRef()}`),this.state=$.closed,this.socket.remove(this)}),this.onError(s=>{this.socket.hasLogger()&&this.socket.log("channel",`error ${this.topic}`,s),this.isJoining()&&this.joinPush.reset(),this.state=$.errored,this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.joinPush.receive("timeout",()=>{this.socket.hasLogger()&&this.socket.log("channel",`timeout ${this.topic} (${this.joinRef()})`,this.joinPush.timeout),new je(this,Y.leave,Ce({}),this.timeout).send(),this.state=$.errored,this.joinPush.reset(),this.socket.isConnected()&&this.rejoinTimer.scheduleTimeout()}),this.on(Y.reply,(s,r)=>{this.trigger(this.replyEventName(r),s)})}join(e=this.timeout){if(this.joinedOnce)throw new Error("tried to join multiple times. 'join' can only be called a single time per channel instance");return this.timeout=e,this.joinedOnce=!0,this.rejoin(),this.joinPush}onClose(e){this.on(Y.close,e)}onError(e){return this.on(Y.error,t=>e(t))}on(e,t){let i=this.bindingRef++;return this.bindings.push({event:e,ref:i,callback:t}),i}off(e,t){this.bindings=this.bindings.filter(i=>!(i.event===e&&(typeof t=="undefined"||t===i.ref)))}canPush(){return this.socket.isConnected()&&this.isJoined()}push(e,t,i=this.timeout){if(t=t||{},!this.joinedOnce)throw new Error(`tried to push '${e}' to '${this.topic}' before joining. Use channel.join() before pushing events`);let s=new je(this,e,function(){return t},i);return this.canPush()?s.send():(s.startTimeout(),this.pushBuffer.push(s)),s}leave(e=this.timeout){this.rejoinTimer.reset(),this.joinPush.cancelTimeout(),this.state=$.leaving;let t=()=>{this.socket.hasLogger()&&this.socket.log("channel",`leave ${this.topic}`),this.trigger(Y.close,"leave")},i=new je(this,Y.leave,Ce({}),e);return i.receive("ok",()=>t()).receive("timeout",()=>t()),i.send(),this.canPush()||i.trigger("ok",{}),i}onMessage(e,t,i){return t}isMember(e,t,i,s){return this.topic!==e?!1:s&&s!==this.joinRef()?(this.socket.hasLogger()&&this.socket.log("channel","dropping outdated message",{topic:e,event:t,payload:i,joinRef:s}),!1):!0}joinRef(){return this.joinPush.ref}rejoin(e=this.timeout){this.isLeaving()||(this.socket.leaveOpenTopic(this.topic),this.state=$.joining,this.joinPush.resend(e))}trigger(e,t,i,s){let r=this.onMessage(e,t,i,s);if(t&&!r)throw new Error("channel onMessage callbacks must return the payload, modified or unmodified");let n=this.bindings.filter(a=>a.event===e);for(let a=0;a{let o=this.parseJSON(e.responseText);a&&a(o)},n&&(e.ontimeout=n),e.onprogress=()=>{},e.send(s),e}static xhrRequest(e,t,i,s,r,n,a,o){return e.open(t,i,!0),e.timeout=n,e.setRequestHeader("Content-Type",s),e.onerror=()=>o&&o(null),e.onreadystatechange=()=>{if(e.readyState===ws.complete&&o){let l=this.parseJSON(e.responseText);o(l)}},a&&(e.ontimeout=a),e.send(r),e}static parseJSON(e){if(!e||e==="")return null;try{return JSON.parse(e)}catch(t){return console&&console.log("failed to parse JSON response",e),null}}static serialize(e,t){let i=[];for(var s in e){if(!Object.prototype.hasOwnProperty.call(e,s))continue;let r=t?`${t}[${s}]`:s,n=e[s];typeof n=="object"?i.push(this.serialize(n,r)):i.push(encodeURIComponent(r)+"="+encodeURIComponent(n))}return i.join("&")}static appendParams(e,t){if(Object.keys(t).length===0)return e;let i=e.match(/\?/)?"&":"?";return`${e}${i}${this.serialize(t)}`}},Ss=e=>{let t="",i=new Uint8Array(e),s=i.byteLength;for(let r=0;rthis.poll(),0)}normalizeEndpoint(e){return e.replace("ws://","http://").replace("wss://","https://").replace(new RegExp("(.*)/"+mt.websocket),"$1/"+mt.longpoll)}endpointURL(){return Ve.appendParams(this.pollEndpoint,{token:this.token})}closeAndRetry(e,t,i){this.close(e,t,i),this.readyState=W.connecting}ontimeout(){this.onerror("timeout"),this.closeAndRetry(1005,"timeout",!1)}isActive(){return this.readyState===W.open||this.readyState===W.connecting}poll(){this.ajax("GET","application/json",null,()=>this.ontimeout(),e=>{if(e){var{status:t,token:i,messages:s}=e;this.token=i}else t=0;switch(t){case 200:s.forEach(r=>{setTimeout(()=>this.onmessage({data:r}),0)}),this.poll();break;case 204:this.poll();break;case 410:this.readyState=W.open,this.onopen({}),this.poll();break;case 403:this.onerror(403),this.close(1008,"forbidden",!1);break;case 0:case 500:this.onerror(500),this.closeAndRetry(1011,"internal server error",500);break;default:throw new Error(`unhandled poll status ${t}`)}})}send(e){typeof e!="string"&&(e=Ss(e)),this.currentBatch?this.currentBatch.push(e):this.awaitingBatchAck?this.batchBuffer.push(e):(this.currentBatch=[e],this.currentBatchTimer=setTimeout(()=>{this.batchSend(this.currentBatch),this.currentBatch=null},0))}batchSend(e){this.awaitingBatchAck=!0,this.ajax("POST","application/x-ndjson",e.join(`
-`),()=>this.onerror("timeout"),t=>{this.awaitingBatchAck=!1,!t||t.status!==200?(this.onerror(t&&t.status),this.closeAndRetry(1011,"internal server error",!1)):this.batchBuffer.length>0&&(this.batchSend(this.batchBuffer),this.batchBuffer=[])})}close(e,t,i){for(let r of this.reqs)r.abort();this.readyState=W.closed;let s=Object.assign({code:1e3,reason:void 0,wasClean:!0},{code:e,reason:t,wasClean:i});this.batchBuffer=[],clearTimeout(this.currentBatchTimer),this.currentBatchTimer=null,typeof CloseEvent!="undefined"?this.onclose(new CloseEvent("close",s)):this.onclose(s)}ajax(e,t,i,s,r){let n,a=()=>{this.reqs.delete(n),s()};n=Ve.request(e,this.endpointURL(),t,i,this.timeout,a,o=>{this.reqs.delete(n),this.isActive()&&r(o)}),this.reqs.add(n)}};var Be={HEADER_LENGTH:1,META_LENGTH:4,KINDS:{push:0,reply:1,broadcast:2},encode(e,t){if(e.payload.constructor===ArrayBuffer)return t(this.binaryEncode(e));{let i=[e.join_ref,e.ref,e.topic,e.event,e.payload];return t(JSON.stringify(i))}},decode(e,t){if(e.constructor===ArrayBuffer)return t(this.binaryDecode(e));{let[i,s,r,n,a]=JSON.parse(e);return t({join_ref:i,ref:s,topic:r,event:n,payload:a})}},binaryEncode(e){let{join_ref:t,ref:i,event:s,topic:r,payload:n}=e,a=this.META_LENGTH+t.length+i.length+r.length+s.length,o=new ArrayBuffer(this.HEADER_LENGTH+a),l=new DataView(o),h=0;l.setUint8(h++,this.KINDS.push),l.setUint8(h++,t.length),l.setUint8(h++,i.length),l.setUint8(h++,r.length),l.setUint8(h++,s.length),Array.from(t,m=>l.setUint8(h++,m.charCodeAt(0))),Array.from(i,m=>l.setUint8(h++,m.charCodeAt(0))),Array.from(r,m=>l.setUint8(h++,m.charCodeAt(0))),Array.from(s,m=>l.setUint8(h++,m.charCodeAt(0)));var d=new Uint8Array(o.byteLength+n.byteLength);return d.set(new Uint8Array(o),0),d.set(new Uint8Array(n),o.byteLength),d.buffer},binaryDecode(e){let t=new DataView(e),i=t.getUint8(0),s=new TextDecoder;switch(i){case this.KINDS.push:return this.decodePush(e,t,s);case this.KINDS.reply:return this.decodeReply(e,t,s);case this.KINDS.broadcast:return this.decodeBroadcast(e,t,s)}},decodePush(e,t,i){let s=t.getUint8(1),r=t.getUint8(2),n=t.getUint8(3),a=this.HEADER_LENGTH+this.META_LENGTH-1,o=i.decode(e.slice(a,a+s));a=a+s;let l=i.decode(e.slice(a,a+r));a=a+r;let h=i.decode(e.slice(a,a+n));a=a+n;let d=e.slice(a,e.byteLength);return{join_ref:o,ref:null,topic:l,event:h,payload:d}},decodeReply(e,t,i){let s=t.getUint8(1),r=t.getUint8(2),n=t.getUint8(3),a=t.getUint8(4),o=this.HEADER_LENGTH+this.META_LENGTH,l=i.decode(e.slice(o,o+s));o=o+s;let h=i.decode(e.slice(o,o+r));o=o+r;let d=i.decode(e.slice(o,o+n));o=o+n;let m=i.decode(e.slice(o,o+a));o=o+a;let p=e.slice(o,e.byteLength),f={status:m,response:p};return{join_ref:l,ref:h,topic:d,event:Y.reply,payload:f}},decodeBroadcast(e,t,i){let s=t.getUint8(1),r=t.getUint8(2),n=this.HEADER_LENGTH+2,a=i.decode(e.slice(n,n+s));n=n+s;let o=i.decode(e.slice(n,n+r));n=n+r;let l=e.slice(n,e.byteLength);return{join_ref:null,ref:null,topic:a,event:o,payload:l}}},Zt=class{constructor(e,t={}){this.stateChangeCallbacks={open:[],close:[],error:[],message:[]},this.channels=[],this.sendBuffer=[],this.ref=0,this.timeout=t.timeout||bs,this.transport=t.transport||le.WebSocket||Ee,this.primaryPassedHealthCheck=!1,this.longPollFallbackMs=t.longPollFallbackMs,this.fallbackTimer=null,this.sessionStore=t.sessionStorage||le&&le.sessionStorage,this.establishedConnections=0,this.defaultEncoder=Be.encode.bind(Be),this.defaultDecoder=Be.decode.bind(Be),this.closeWasClean=!1,this.binaryType=t.binaryType||"arraybuffer",this.connectClock=1,this.transport!==Ee?(this.encode=t.encode||this.defaultEncoder,this.decode=t.decode||this.defaultDecoder):(this.encode=this.defaultEncoder,this.decode=this.defaultDecoder);let i=null;ke&&ke.addEventListener&&(ke.addEventListener("pagehide",s=>{this.conn&&(this.disconnect(),i=this.connectClock)}),ke.addEventListener("pageshow",s=>{i===this.connectClock&&(i=null,this.connect())})),this.heartbeatIntervalMs=t.heartbeatIntervalMs||3e4,this.rejoinAfterMs=s=>t.rejoinAfterMs?t.rejoinAfterMs(s):[1e3,2e3,5e3][s-1]||1e4,this.reconnectAfterMs=s=>t.reconnectAfterMs?t.reconnectAfterMs(s):[10,50,100,150,200,250,500,1e3,2e3][s-1]||5e3,this.logger=t.logger||null,!this.logger&&t.debug&&(this.logger=(s,r,n)=>{console.log(`${s}: ${r}`,n)}),this.longpollerTimeout=t.longpollerTimeout||2e4,this.params=Ce(t.params||{}),this.endPoint=`${e}/${mt.websocket}`,this.vsn=t.vsn||vs,this.heartbeatTimeoutTimer=null,this.heartbeatTimer=null,this.pendingHeartbeatRef=null,this.reconnectTimer=new Yt(()=>{this.teardown(()=>this.connect())},this.reconnectAfterMs)}getLongPollTransport(){return Ee}replaceTransport(e){this.connectClock++,this.closeWasClean=!0,clearTimeout(this.fallbackTimer),this.reconnectTimer.reset(),this.conn&&(this.conn.close(),this.conn=null),this.transport=e}protocol(){return location.protocol.match(/^https/)?"wss":"ws"}endPointURL(){let e=Ve.appendParams(Ve.appendParams(this.endPoint,this.params()),{vsn:this.vsn});return e.charAt(0)!=="/"?e:e.charAt(1)==="/"?`${this.protocol()}:${e}`:`${this.protocol()}://${location.host}${e}`}disconnect(e,t,i){this.connectClock++,this.closeWasClean=!0,clearTimeout(this.fallbackTimer),this.reconnectTimer.reset(),this.teardown(e,t,i)}connect(e){e&&(console&&console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor"),this.params=Ce(e)),!this.conn&&(this.longPollFallbackMs&&this.transport!==Ee?this.connectWithFallback(Ee,this.longPollFallbackMs):this.transportConnect())}log(e,t,i){this.logger&&this.logger(e,t,i)}hasLogger(){return this.logger!==null}onOpen(e){let t=this.makeRef();return this.stateChangeCallbacks.open.push([t,e]),t}onClose(e){let t=this.makeRef();return this.stateChangeCallbacks.close.push([t,e]),t}onError(e){let t=this.makeRef();return this.stateChangeCallbacks.error.push([t,e]),t}onMessage(e){let t=this.makeRef();return this.stateChangeCallbacks.message.push([t,e]),t}ping(e){if(!this.isConnected())return!1;let t=this.makeRef(),i=Date.now();this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:t});let s=this.onMessage(r=>{r.ref===t&&(this.off([s]),e(Date.now()-i))});return!0}transportConnect(){this.connectClock++,this.closeWasClean=!1,this.conn=new this.transport(this.endPointURL()),this.conn.binaryType=this.binaryType,this.conn.timeout=this.longpollerTimeout,this.conn.onopen=()=>this.onConnOpen(),this.conn.onerror=e=>this.onConnError(e),this.conn.onmessage=e=>this.onConnMessage(e),this.conn.onclose=e=>this.onConnClose(e)}getSession(e){return this.sessionStore&&this.sessionStore.getItem(e)}storeSession(e,t){this.sessionStore&&this.sessionStore.setItem(e,t)}connectWithFallback(e,t=2500){clearTimeout(this.fallbackTimer);let i=!1,s=!0,r,n,a=o=>{this.log("transport",`falling back to ${e.name}...`,o),this.off([r,n]),s=!1,this.replaceTransport(e),this.transportConnect()};if(this.getSession(`phx:fallback:${e.name}`))return a("memorized");this.fallbackTimer=setTimeout(a,t),n=this.onError(o=>{this.log("transport","error",o),s&&!i&&(clearTimeout(this.fallbackTimer),a(o))}),this.onOpen(()=>{if(i=!0,!s)return this.primaryPassedHealthCheck||this.storeSession(`phx:fallback:${e.name}`,"true"),this.log("transport",`established ${e.name} fallback`);clearTimeout(this.fallbackTimer),this.fallbackTimer=setTimeout(a,t),this.ping(o=>{this.log("transport","connected to primary after",o),this.primaryPassedHealthCheck=!0,clearTimeout(this.fallbackTimer)})}),this.transportConnect()}clearHeartbeats(){clearTimeout(this.heartbeatTimer),clearTimeout(this.heartbeatTimeoutTimer)}onConnOpen(){this.hasLogger()&&this.log("transport",`${this.transport.name} connected to ${this.endPointURL()}`),this.closeWasClean=!1,this.establishedConnections++,this.flushSendBuffer(),this.reconnectTimer.reset(),this.resetHeartbeat(),this.stateChangeCallbacks.open.forEach(([,e])=>e())}heartbeatTimeout(){this.pendingHeartbeatRef&&(this.pendingHeartbeatRef=null,this.hasLogger()&&this.log("transport","heartbeat timeout. Attempting to re-establish connection"),this.triggerChanError(),this.closeWasClean=!1,this.teardown(()=>this.reconnectTimer.scheduleTimeout(),ys,"heartbeat timeout"))}resetHeartbeat(){this.conn&&this.conn.skipHeartbeat||(this.pendingHeartbeatRef=null,this.clearHeartbeats(),this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs))}teardown(e,t,i){if(!this.conn)return e&&e();this.waitForBufferDone(()=>{this.conn&&(t?this.conn.close(t,i||""):this.conn.close()),this.waitForSocketClosed(()=>{this.conn&&(this.conn.onopen=function(){},this.conn.onerror=function(){},this.conn.onmessage=function(){},this.conn.onclose=function(){},this.conn=null),e&&e()})})}waitForBufferDone(e,t=1){if(t===5||!this.conn||!this.conn.bufferedAmount){e();return}setTimeout(()=>{this.waitForBufferDone(e,t+1)},150*t)}waitForSocketClosed(e,t=1){if(t===5||!this.conn||this.conn.readyState===W.closed){e();return}setTimeout(()=>{this.waitForSocketClosed(e,t+1)},150*t)}onConnClose(e){let t=e&&e.code;this.hasLogger()&&this.log("transport","close",e),this.triggerChanError(),this.clearHeartbeats(),!this.closeWasClean&&t!==1e3&&this.reconnectTimer.scheduleTimeout(),this.stateChangeCallbacks.close.forEach(([,i])=>i(e))}onConnError(e){this.hasLogger()&&this.log("transport",e);let t=this.transport,i=this.establishedConnections;this.stateChangeCallbacks.error.forEach(([,s])=>{s(e,t,i)}),(t===this.transport||i>0)&&this.triggerChanError()}triggerChanError(){this.channels.forEach(e=>{e.isErrored()||e.isLeaving()||e.isClosed()||e.trigger(Y.error)})}connectionState(){switch(this.conn&&this.conn.readyState){case W.connecting:return"connecting";case W.open:return"open";case W.closing:return"closing";default:return"closed"}}isConnected(){return this.connectionState()==="open"}remove(e){this.off(e.stateChangeRefs),this.channels=this.channels.filter(t=>t!==e)}off(e){for(let t in this.stateChangeCallbacks)this.stateChangeCallbacks[t]=this.stateChangeCallbacks[t].filter(([i])=>e.indexOf(i)===-1)}channel(e,t={}){let i=new As(e,t,this);return this.channels.push(i),i}push(e){if(this.hasLogger()){let{topic:t,event:i,payload:s,ref:r,join_ref:n}=e;this.log("push",`${t} ${i} (${n}, ${r})`,s)}this.isConnected()?this.encode(e,t=>this.conn.send(t)):this.sendBuffer.push(()=>this.encode(e,t=>this.conn.send(t)))}makeRef(){let e=this.ref+1;return e===this.ref?this.ref=0:this.ref=e,this.ref.toString()}sendHeartbeat(){this.pendingHeartbeatRef&&!this.isConnected()||(this.pendingHeartbeatRef=this.makeRef(),this.push({topic:"phoenix",event:"heartbeat",payload:{},ref:this.pendingHeartbeatRef}),this.heartbeatTimeoutTimer=setTimeout(()=>this.heartbeatTimeout(),this.heartbeatIntervalMs))}flushSendBuffer(){this.isConnected()&&this.sendBuffer.length>0&&(this.sendBuffer.forEach(e=>e()),this.sendBuffer=[])}onConnMessage(e){this.decode(e.data,t=>{let{topic:i,event:s,payload:r,ref:n,join_ref:a}=t;n&&n===this.pendingHeartbeatRef&&(this.clearHeartbeats(),this.pendingHeartbeatRef=null,this.heartbeatTimer=setTimeout(()=>this.sendHeartbeat(),this.heartbeatIntervalMs)),this.hasLogger()&&this.log("receive",`${r.status||""} ${i} ${s} ${n&&"("+n+")"||""}`,r);for(let o=0;oi.topic===e&&(i.isJoined()||i.isJoining()));t&&(this.hasLogger()&&this.log("transport",`leaving duplicate topic "${e}"`),t.leave())}};var Ci="consecutive-reloads",Es=10,ks=5e3,Cs=1e4,Ts=3e4,Ti=["phx-click-loading","phx-change-loading","phx-submit-loading","phx-keydown-loading","phx-keyup-loading","phx-blur-loading","phx-focus-loading","phx-hook-loading"],Q="data-phx-component",gt="data-phx-link",_s="track-static",Rs="data-phx-link-state",U="data-phx-ref",ne="data-phx-ref-src",_i="track-uploads",ee="data-phx-upload-ref",xt="data-phx-preflighted-refs",Ps="data-phx-done-refs",Qt="drop-target",Ct="data-phx-active-refs",Qe="phx:live-file:updated",Ri="data-phx-skip",Pi="data-phx-id",ei="data-phx-prune",ti="page-loading",ii="phx-connected",Te="phx-loading",Je="phx-no-feedback",qe="phx-error",si="phx-client-error",vt="phx-server-error",he="data-phx-parent-id",It="data-phx-main",de="data-phx-root-id",Tt="viewport-top",_t="viewport-bottom",xs="trigger-action",tt="feedback-for",it="feedback-group",Rt="phx-has-focused",Is=["text","textarea","number","email","password","search","tel","url","date","time","datetime-local","color","range"],xi=["checkbox","radio"],st="phx-has-submitted",te="data-phx-session",be=`[${te}]`,ri="data-phx-sticky",ge="data-phx-static",bt="data-phx-readonly",pe="data-phx-disabled",Pt="disable-with",We="data-phx-disable-with-restore",_e="hook",Ls="debounce",Os="throttle",rt="update",yt="stream",wt="data-phx-stream",Ds="key",X="phxPrivate",ni="auto-recover",Xe="phx:live-socket:debug",At="phx:live-socket:profiling",St="phx:live-socket:latency-sim",Fs="progress",ai="mounted",Hs=1,Ms=200,Ns="phx-",$s=3e4,Re="debounce-trigger",Pe="throttled",oi="debounce-prev-key",Us={debounce:300,throttle:300},ze="d",z="s",Et="r",H="c",li="e",hi="r",di="t",js="p",ci="stream",Bs=class{constructor(e,t,i){this.liveSocket=i,this.entry=e,this.offset=0,this.chunkSize=t,this.chunkTimer=null,this.errored=!1,this.uploadChannel=i.channel(`lvu:${e.ref}`,{token:e.metadata()})}error(e){this.errored||(this.uploadChannel.leave(),this.errored=!0,clearTimeout(this.chunkTimer),this.entry.error(e))}upload(){this.uploadChannel.onError(e=>this.error(e)),this.uploadChannel.join().receive("ok",e=>this.readNextChunk()).receive("error",e=>this.error(e))}isDone(){return this.offset>=this.entry.file.size}readNextChunk(){let e=new window.FileReader,t=this.entry.file.slice(this.offset,this.chunkSize+this.offset);e.onload=i=>{if(i.target.error===null)this.offset+=i.target.result.byteLength,this.pushChunk(i.target.result);else return j("Read error: "+i.target.error)},e.readAsArrayBuffer(t)}pushChunk(e){this.uploadChannel.isJoined()&&this.uploadChannel.push("chunk",e).receive("ok",()=>{this.entry.progress(this.offset/this.entry.file.size*100),this.isDone()||(this.chunkTimer=setTimeout(()=>this.readNextChunk(),this.liveSocket.getLatencySim()||0))}).receive("error",({reason:t})=>this.error(t))}},j=(e,t)=>console.error&&console.error(e,t),Z=e=>{let t=typeof e;return t==="number"||t==="string"&&/^(0|[1-9]\d*)$/.test(e)};function Vs(){let e=new Set,t=document.querySelectorAll("*[id]");for(let i=0,s=t.length;i{e.liveSocket.isDebugEnabled()&&console.log(`${e.id} ${t}: ${i} - `,s)},xe=e=>typeof e=="function"?e:function(){return e},et=e=>JSON.parse(JSON.stringify(e)),De=(e,t,i)=>{do{if(e.matches(`[${t}]`)&&!e.disabled)return e;e=e.parentElement||e.parentNode}while(e!==null&&e.nodeType===1&&!(i&&i.isSameNode(e)||e.matches(be)));return null},me=e=>e!==null&&typeof e=="object"&&!(e instanceof Array),qs=(e,t)=>JSON.stringify(e)===JSON.stringify(t),ui=e=>{for(let t in e)return!1;return!0},ae=(e,t)=>e&&t(e),Ws=function(e,t,i,s){e.forEach(r=>{new Bs(r,i.config.chunk_size,s).upload()})},Ii={canPushState(){return typeof history.pushState!="undefined"},dropLocal(e,t,i){return e.removeItem(this.localKey(t,i))},updateLocal(e,t,i,s,r){let n=this.getLocal(e,t,i),a=this.localKey(t,i),o=n===null?s:r(n);return e.setItem(a,JSON.stringify(o)),o},getLocal(e,t,i){return JSON.parse(e.getItem(this.localKey(t,i)))},updateCurrentState(e){this.canPushState()&&history.replaceState(e(history.state||{}),"",window.location.href)},pushState(e,t,i){if(this.canPushState()){if(i!==window.location.href){if(t.type=="redirect"&&t.scroll){let r=history.state||{};r.scroll=t.scroll,history.replaceState(r,"",window.location.href)}delete t.scroll,history[e+"State"](t,"",i||null);let s=this.getHashTargetEl(window.location.hash);s?s.scrollIntoView():t.type==="redirect"&&window.scroll(0,0)}}else this.redirect(i)},setCookie(e,t){document.cookie=`${e}=${t}`},getCookie(e){return document.cookie.replace(new RegExp(`(?:(?:^|.*;s*)${e}s*=s*([^;]*).*$)|^.*$`),"$1")},redirect(e,t){t&&Ii.setCookie("__phoenix_flash__",t+"; max-age=60000; path=/"),window.location=e},localKey(e,t){return`${e}-${t}`},getHashTargetEl(e){let t=e.toString().substring(1);if(t!=="")return document.getElementById(t)||document.querySelector(`a[name="${t}"]`)}},K=Ii,Xs={focusMain(){let e=document.querySelector("main h1, main, h1");if(e){let t=e.tabIndex;e.tabIndex=-1,e.focus(),e.tabIndex=t}},anyOf(e,t){return t.find(i=>e instanceof i)},isFocusable(e,t){return e instanceof HTMLAnchorElement&&e.rel!=="ignore"||e instanceof HTMLAreaElement&&e.href!==void 0||!e.disabled&&this.anyOf(e,[HTMLInputElement,HTMLSelectElement,HTMLTextAreaElement,HTMLButtonElement])||e instanceof HTMLIFrameElement||e.tabIndex>0||!t&&e.getAttribute("tabindex")!==null&&e.getAttribute("aria-hidden")!=="true"},attemptFocus(e,t){if(this.isFocusable(e,t))try{e.focus()}catch(i){}return!!document.activeElement&&document.activeElement.isSameNode(e)},focusFirstInteractive(e){let t=e.firstElementChild;for(;t;){if(this.attemptFocus(t,!0)||this.focusFirstInteractive(t,!0))return!0;t=t.nextElementSibling}},focusFirst(e){let t=e.firstElementChild;for(;t;){if(this.attemptFocus(t)||this.focusFirst(t))return!0;t=t.nextElementSibling}},focusLast(e){let t=e.lastElementChild;for(;t;){if(this.attemptFocus(t)||this.focusLast(t))return!0;t=t.previousElementSibling}}},ve=Xs,fi=[],pi=200,zs={exec(e,t,i,s,r){let[n,a]=r||[null,{callback:r&&r.callback}];(t.charAt(0)==="["?JSON.parse(t):[[n,a]]).forEach(([l,h])=>{l===n&&a.data&&(h.data=Object.assign(h.data||{},a.data),h.callback=h.callback||a.callback),this.filterToEls(s,h).forEach(d=>{this[`exec_${l}`](e,t,i,s,d,h)})})},isVisible(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length>0)},isInViewport(e){let t=e.getBoundingClientRect(),i=window.innerHeight||document.documentElement.clientHeight,s=window.innerWidth||document.documentElement.clientWidth;return t.right>0&&t.bottom>0&&t.left{let h=l.getAttribute(n);if(!h)throw new Error(`expected ${n} to contain JS command on "${a}"`);i.liveSocket.execJS(l,h,e)})},exec_dispatch(e,t,i,s,r,{to:n,event:a,detail:o,bubbles:l}){o=o||{},o.dispatcher=s,c.dispatchEvent(r,a,{detail:o,bubbles:l})},exec_push(e,t,i,s,r,n){let{event:a,data:o,target:l,page_loading:h,loading:d,value:m,dispatcher:p,callback:f}=n,g={loading:d,value:m,target:l,page_loading:!!h},v=e==="change"&&p?p:s,E=l||v.getAttribute(i.binding("target"))||v;i.withinTargets(E,(_,R)=>{if(_.isConnected())if(e==="change"){let{newCid:T,_target:x}=n;x=x||(c.isFormInput(s)?s.name:void 0),x&&(g._target=x),_.pushInput(s,R,T,a||t,g,f)}else if(e==="submit"){let{submitter:T}=n;_.submitForm(s,R,a||t,T,g,f)}else _.pushEvent(e,s,R,a||t,o,g,f)})},exec_navigate(e,t,i,s,r,{href:n,replace:a}){i.liveSocket.historyRedirect(n,a?"replace":"push")},exec_patch(e,t,i,s,r,{href:n,replace:a}){i.liveSocket.pushHistoryPatch(n,a?"replace":"push",s)},exec_focus(e,t,i,s,r){window.requestAnimationFrame(()=>ve.attemptFocus(r))},exec_focus_first(e,t,i,s,r){window.requestAnimationFrame(()=>ve.focusFirstInteractive(r)||ve.focusFirst(r))},exec_push_focus(e,t,i,s,r){window.requestAnimationFrame(()=>fi.push(r||s))},exec_pop_focus(e,t,i,s,r){window.requestAnimationFrame(()=>{let n=fi.pop();n&&n.focus()})},exec_add_class(e,t,i,s,r,{names:n,transition:a,time:o}){this.addOrRemoveClasses(r,n,[],a,o,i)},exec_remove_class(e,t,i,s,r,{names:n,transition:a,time:o}){this.addOrRemoveClasses(r,[],n,a,o,i)},exec_toggle_class(e,t,i,s,r,{to:n,names:a,transition:o,time:l}){this.toggleClasses(r,a,o,l,i)},exec_toggle_attr(e,t,i,s,r,{attr:[n,a,o]}){r.hasAttribute(n)?o!==void 0?r.getAttribute(n)===a?this.setOrRemoveAttrs(r,[[n,o]],[]):this.setOrRemoveAttrs(r,[[n,a]],[]):this.setOrRemoveAttrs(r,[],[n]):this.setOrRemoveAttrs(r,[[n,a]],[])},exec_transition(e,t,i,s,r,{time:n,transition:a}){this.addOrRemoveClasses(r,[],[],a,n,i)},exec_toggle(e,t,i,s,r,{display:n,ins:a,outs:o,time:l}){this.toggle(e,i,r,n,a,o,l)},exec_show(e,t,i,s,r,{display:n,transition:a,time:o}){this.show(e,i,r,n,a,o)},exec_hide(e,t,i,s,r,{display:n,transition:a,time:o}){this.hide(e,i,r,n,a,o)},exec_set_attr(e,t,i,s,r,{attr:[n,a]}){this.setOrRemoveAttrs(r,[[n,a]],[])},exec_remove_attr(e,t,i,s,r,{attr:n}){this.setOrRemoveAttrs(r,[],[n])},show(e,t,i,s,r,n){this.isVisible(i)||this.toggle(e,t,i,s,r,null,n)},hide(e,t,i,s,r,n){this.isVisible(i)&&this.toggle(e,t,i,s,null,r,n)},toggle(e,t,i,s,r,n,a){a=a||pi;let[o,l,h]=r||[[],[],[]],[d,m,p]=n||[[],[],[]];if(o.length>0||d.length>0)if(this.isVisible(i)){let f=()=>{this.addOrRemoveClasses(i,m,o.concat(l).concat(h)),window.requestAnimationFrame(()=>{this.addOrRemoveClasses(i,d,[]),window.requestAnimationFrame(()=>this.addOrRemoveClasses(i,p,m))})};i.dispatchEvent(new Event("phx:hide-start")),t.transition(a,f,()=>{this.addOrRemoveClasses(i,[],d.concat(p)),c.putSticky(i,"toggle",g=>g.style.display="none"),i.dispatchEvent(new Event("phx:hide-end"))})}else{if(e==="remove")return;let f=()=>{this.addOrRemoveClasses(i,l,d.concat(m).concat(p));let g=s||this.defaultDisplay(i);c.putSticky(i,"toggle",v=>v.style.display=g),window.requestAnimationFrame(()=>{this.addOrRemoveClasses(i,o,[]),window.requestAnimationFrame(()=>this.addOrRemoveClasses(i,h,l))})};i.dispatchEvent(new Event("phx:show-start")),t.transition(a,f,()=>{this.addOrRemoveClasses(i,[],o.concat(h)),i.dispatchEvent(new Event("phx:show-end"))})}else this.isVisible(i)?window.requestAnimationFrame(()=>{i.dispatchEvent(new Event("phx:hide-start")),c.putSticky(i,"toggle",f=>f.style.display="none"),i.dispatchEvent(new Event("phx:hide-end"))}):window.requestAnimationFrame(()=>{i.dispatchEvent(new Event("phx:show-start"));let f=s||this.defaultDisplay(i);c.putSticky(i,"toggle",g=>g.style.display=f),i.dispatchEvent(new Event("phx:show-end"))})},toggleClasses(e,t,i,s,r){window.requestAnimationFrame(()=>{let[n,a]=c.getSticky(e,"classes",[[],[]]),o=t.filter(h=>n.indexOf(h)<0&&!e.classList.contains(h)),l=t.filter(h=>a.indexOf(h)<0&&e.classList.contains(h));this.addOrRemoveClasses(e,o,l,i,s,r)})},addOrRemoveClasses(e,t,i,s,r,n){r=r||pi;let[a,o,l]=s||[[],[],[]];if(a.length>0){let h=()=>{this.addOrRemoveClasses(e,o,[].concat(a).concat(l)),window.requestAnimationFrame(()=>{this.addOrRemoveClasses(e,a,[]),window.requestAnimationFrame(()=>this.addOrRemoveClasses(e,l,o))})},d=()=>this.addOrRemoveClasses(e,t.concat(l),i.concat(a).concat(o));return n.transition(r,h,d)}window.requestAnimationFrame(()=>{let[h,d]=c.getSticky(e,"classes",[[],[]]),m=t.filter(v=>h.indexOf(v)<0&&!e.classList.contains(v)),p=i.filter(v=>d.indexOf(v)<0&&e.classList.contains(v)),f=h.filter(v=>i.indexOf(v)<0).concat(m),g=d.filter(v=>t.indexOf(v)<0).concat(p);c.putSticky(e,"classes",v=>(v.classList.remove(...g),v.classList.add(...f),[f,g]))})},setOrRemoveAttrs(e,t,i){let[s,r]=c.getSticky(e,"attrs",[[],[]]),n=t.map(([l,h])=>l).concat(i),a=s.filter(([l,h])=>!n.includes(l)).concat(t),o=r.filter(l=>!n.includes(l)).concat(i);c.putSticky(e,"attrs",l=>(o.forEach(h=>l.removeAttribute(h)),a.forEach(([h,d])=>l.setAttribute(h,d)),[a,o]))},hasAllClasses(e,t){return t.every(i=>e.classList.contains(i))},isToggledOut(e,t){return!this.isVisible(e)||this.hasAllClasses(e,t)},filterToEls(e,{to:t}){return t?c.all(document,t):[e]},defaultDisplay(e){return{tr:"table-row",td:"table-cell"}[e.tagName.toLowerCase()]||"block"}},M=zs,V={byId(e){return document.getElementById(e)||j(`no id found for ${e}`)},removeClass(e,t){e.classList.remove(t),e.classList.length===0&&e.removeAttribute("class")},all(e,t,i){if(!e)return[];let s=Array.from(e.querySelectorAll(t));return i?s.forEach(i):s},childNodeLength(e){let t=document.createElement("template");return t.innerHTML=e,t.content.childElementCount},isUploadInput(e){return e.type==="file"&&e.getAttribute(ee)!==null},isAutoUpload(e){return e.hasAttribute("data-phx-auto-upload")},findUploadInputs(e){let t=e.id,i=this.all(document,`input[type="file"][${ee}][form="${t}"]`);return this.all(e,`input[type="file"][${ee}]`).concat(i)},findComponentNodeList(e,t){return this.filterWithinSameLiveView(this.all(e,`[${Q}="${t}"]`),e)},isPhxDestroyed(e){return!!(e.id&&V.private(e,"destroyed"))},wantsNewTab(e){let t=e.ctrlKey||e.shiftKey||e.metaKey||e.button&&e.button===1,i=e.target instanceof HTMLAnchorElement&&e.target.hasAttribute("download"),s=e.target.hasAttribute("target")&&e.target.getAttribute("target").toLowerCase()==="_blank",r=e.target.hasAttribute("target")&&!e.target.getAttribute("target").startsWith("_");return t||s||i||r},isUnloadableFormSubmit(e){return e.target&&e.target.getAttribute("method")==="dialog"||e.submitter&&e.submitter.getAttribute("formmethod")==="dialog"?!1:!e.defaultPrevented&&!this.wantsNewTab(e)},isNewPageClick(e,t){let i=e.target instanceof HTMLAnchorElement?e.target.getAttribute("href"):null,s;if(e.defaultPrevented||i===null||this.wantsNewTab(e)||i.startsWith("mailto:")||i.startsWith("tel:")||e.target.isContentEditable)return!1;try{s=new URL(i)}catch(r){try{s=new URL(i,t)}catch(n){return!0}}return s.host===t.host&&s.protocol===t.protocol&&s.pathname===t.pathname&&s.search===t.search?s.hash===""&&!s.href.endsWith("#"):s.protocol.startsWith("http")},markPhxChildDestroyed(e){this.isPhxChild(e)&&e.setAttribute(te,""),this.putPrivate(e,"destroyed",!0)},findPhxChildrenInFragment(e,t){let i=document.createElement("template");return i.innerHTML=e,this.findPhxChildren(i.content,t)},isIgnored(e,t){return(e.getAttribute(t)||e.getAttribute("data-phx-update"))==="ignore"},isPhxUpdate(e,t,i){return e.getAttribute&&i.indexOf(e.getAttribute(t))>=0},findPhxSticky(e){return this.all(e,`[${ri}]`)},findPhxChildren(e,t){return this.all(e,`${be}[${he}="${t}"]`)},findExistingParentCIDs(e,t){let i=new Set,s=new Set;return t.forEach(r=>{this.filterWithinSameLiveView(this.all(e,`[${Q}="${r}"]`),e).forEach(n=>{i.add(r),this.all(n,`[${Q}]`).map(a=>parseInt(a.getAttribute(Q))).forEach(a=>s.add(a))})}),s.forEach(r=>i.delete(r)),i},filterWithinSameLiveView(e,t){return t.querySelector(be)?e.filter(i=>this.withinSameLiveView(i,t)):e},withinSameLiveView(e,t){for(;e=e.parentNode;){if(e.isSameNode(t))return!0;if(e.getAttribute(te)!==null)return!1}},private(e,t){return e[X]&&e[X][t]},deletePrivate(e,t){e[X]&&delete e[X][t]},putPrivate(e,t,i){e[X]||(e[X]={}),e[X][t]=i},updatePrivate(e,t,i,s){let r=this.private(e,t);r===void 0?this.putPrivate(e,t,s(i)):this.putPrivate(e,t,s(r))},copyPrivates(e,t){t[X]&&(e[X]=t[X])},putTitle(e){let t=document.querySelector("title");if(t){let{prefix:i,suffix:s}=t.dataset;document.title=`${i||""}${e}${s||""}`}else document.title=e},debounce(e,t,i,s,r,n,a,o){let l=e.getAttribute(i),h=e.getAttribute(r);l===""&&(l=s),h===""&&(h=n);let d=l||h;switch(d){case null:return o();case"blur":this.once(e,"debounce-blur")&&e.addEventListener("blur",()=>{a()&&o()});return;default:let m=parseInt(d),p=()=>h?this.deletePrivate(e,Pe):o(),f=this.incCycle(e,Re,p);if(isNaN(m))return j(`invalid throttle/debounce value: ${d}`);if(h){let v=!1;if(t.type==="keydown"){let E=this.private(e,oi);this.putPrivate(e,oi,t.key),v=E!==t.key}if(!v&&this.private(e,Pe))return!1;{o();let E=setTimeout(()=>{a()&&this.triggerCycle(e,Re)},m);this.putPrivate(e,Pe,E)}}else setTimeout(()=>{a()&&this.triggerCycle(e,Re,f)},m);let g=e.form;g&&this.once(g,"bind-debounce")&&g.addEventListener("submit",()=>{Array.from(new FormData(g).entries(),([v])=>{let E=g.querySelector(`[name="${v}"]`);this.incCycle(E,Re),this.deletePrivate(E,Pe)})}),this.once(e,"bind-debounce")&&e.addEventListener("blur",()=>{clearTimeout(this.private(e,Pe)),this.triggerCycle(e,Re)})}},triggerCycle(e,t,i){let[s,r]=this.private(e,t);i||(i=s),i===s&&(this.incCycle(e,t),r())},once(e,t){return this.private(e,t)===!0?!1:(this.putPrivate(e,t,!0),!0)},incCycle(e,t,i=function(){}){let[s]=this.private(e,t)||[0,i];return s++,this.putPrivate(e,t,[s,i]),s},maybeAddPrivateHooks(e,t,i){e.hasAttribute&&(e.hasAttribute(t)||e.hasAttribute(i))&&e.setAttribute("data-phx-hook","Phoenix.InfiniteScroll")},isFeedbackContainer(e,t){return e.hasAttribute&&e.hasAttribute(t)},maybeHideFeedback(e,t,i,s){let r={};t.forEach(n=>{if(!e.contains(n))return;let a=n.getAttribute(i);if(!a){M.addOrRemoveClasses(n,[],[Je]);return}if(r[a]===!0){this.hideFeedback(n);return}r[a]=this.shouldHideFeedback(e,a,s),r[a]===!0&&this.hideFeedback(n)})},hideFeedback(e){M.addOrRemoveClasses(e,[Je],[])},shouldHideFeedback(e,t,i){let s=`[name="${t}"],
- [name="${t}[]"],
- [${i}="${t}"]`,r=!1;return V.all(e,s,n=>{(this.private(n,Rt)||this.private(n,st))&&(r=!0)}),!r},feedbackSelector(e,t,i){let s=`[${t}="${e.name}"],
- [${t}="${e.name.replace(/\[\]$/,"")}"]`;return e.getAttribute(i)&&(s+=`,[${t}="${e.getAttribute(i)}"]`),s},resetForm(e,t,i){Array.from(e.elements).forEach(s=>{let r=this.feedbackSelector(s,t,i);this.deletePrivate(s,Rt),this.deletePrivate(s,st),this.all(document,r,n=>{M.addOrRemoveClasses(n,[Je],[])})})},showError(e,t,i){if(e.name){let s=this.feedbackSelector(e,t,i);this.all(document,s,r=>{M.addOrRemoveClasses(r,[],[Je])})}},isPhxChild(e){return e.getAttribute&&e.getAttribute(he)},isPhxSticky(e){return e.getAttribute&&e.getAttribute(ri)!==null},isChildOfAny(e,t){return!!t.find(i=>i.contains(e))},firstPhxChild(e){return this.isPhxChild(e)?e:this.all(e,`[${he}]`)[0]},dispatchEvent(e,t,i={}){let s=!0;e.nodeName==="INPUT"&&e.type==="file"&&t==="click"&&(s=!1);let a={bubbles:i.bubbles===void 0?s:!!i.bubbles,cancelable:!0,detail:i.detail||{}},o=t==="click"?new MouseEvent("click",a):new CustomEvent(t,a);e.dispatchEvent(o)},cloneNode(e,t){if(typeof t=="undefined")return e.cloneNode(!0);{let i=e.cloneNode(!1);return i.innerHTML=t,i}},mergeAttrs(e,t,i={}){let s=new Set(i.exclude||[]),r=i.isIgnored,n=t.attributes;for(let o=n.length-1;o>=0;o--){let l=n[o].name;if(s.has(l))l==="value"&&e.value===t.value&&e.setAttribute("value",t.getAttribute(l));else{let h=t.getAttribute(l);e.getAttribute(l)!==h&&(!r||r&&l.startsWith("data-"))&&e.setAttribute(l,h)}}let a=e.attributes;for(let o=a.length-1;o>=0;o--){let l=a[o].name;r?l.startsWith("data-")&&!t.hasAttribute(l)&&![U,ne].includes(l)&&e.removeAttribute(l):t.hasAttribute(l)||e.removeAttribute(l)}},mergeFocusedInput(e,t){e instanceof HTMLSelectElement||V.mergeAttrs(e,t,{exclude:["value"]}),t.readOnly?e.setAttribute("readonly",!0):e.removeAttribute("readonly")},hasSelectionRange(e){return e.setSelectionRange&&(e.type==="text"||e.type==="textarea")},restoreFocus(e,t,i){if(e instanceof HTMLSelectElement&&e.focus(),!V.isTextualInput(e))return;e.matches(":focus")||e.focus(),this.hasSelectionRange(e)&&e.setSelectionRange(t,i)},isFormInput(e){return/^(?:input|select|textarea)$/i.test(e.tagName)&&e.type!=="button"},syncAttrsToProps(e){e instanceof HTMLInputElement&&xi.indexOf(e.type.toLocaleLowerCase())>=0&&(e.checked=e.getAttribute("checked")!==null)},isTextualInput(e){return Is.indexOf(e.type)>=0},isNowTriggerFormExternal(e,t){return e.getAttribute&&e.getAttribute(t)!==null},syncPendingRef(e,t,i){let s=e.getAttribute(U);if(s===null)return!0;let r=e.getAttribute(ne);return V.isFormInput(e)||e.getAttribute(i)!==null?(V.isUploadInput(e)&&V.mergeAttrs(e,t,{isIgnored:!0}),V.putPrivate(e,U,t),!1):(Ti.forEach(n=>{e.classList.contains(n)&&t.classList.add(n)}),t.setAttribute(U,s),t.setAttribute(ne,r),!0)},cleanChildNodes(e,t){if(V.isPhxUpdate(e,t,["append","prepend"])){let i=[];e.childNodes.forEach(s=>{s.id||(!(s.nodeType===Node.TEXT_NODE&&s.nodeValue.trim()==="")&&s.nodeType!==Node.COMMENT_NODE&&j(`only HTML element tags with an id are allowed inside containers with phx-update.
+(() => {
+ var __create = Object.create;
+ var __defProp = Object.defineProperty;
+ var __defProps = Object.defineProperties;
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
+ var __getOwnPropNames = Object.getOwnPropertyNames;
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
+ var __getProtoOf = Object.getPrototypeOf;
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
+ var __spreadValues = (a, b) => {
+ for (var prop in b || (b = {}))
+ if (__hasOwnProp.call(b, prop))
+ __defNormalProp(a, prop, b[prop]);
+ if (__getOwnPropSymbols)
+ for (var prop of __getOwnPropSymbols(b)) {
+ if (__propIsEnum.call(b, prop))
+ __defNormalProp(a, prop, b[prop]);
+ }
+ return a;
+ };
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
+ var __objRest = (source, exclude) => {
+ var target = {};
+ for (var prop in source)
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
+ target[prop] = source[prop];
+ if (source != null && __getOwnPropSymbols)
+ for (var prop of __getOwnPropSymbols(source)) {
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
+ target[prop] = source[prop];
+ }
+ return target;
+ };
+ var __commonJS = (cb, mod) => function __require() {
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
+ };
+ var __copyProps = (to, from, except, desc) => {
+ if (from && typeof from === "object" || typeof from === "function") {
+ for (let key of __getOwnPropNames(from))
+ if (!__hasOwnProp.call(to, key) && key !== except)
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
+ }
+ return to;
+ };
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
+ // If the importer is in node compatibility mode or this is not an ESM
+ // file that has been converted to a CommonJS file using a Babel-
+ // compatible transform (i.e. "__esModule" has not been set), then set
+ // "default" to the CommonJS "module.exports" for node compatibility.
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
+ mod
+ ));
-removing illegal node: "${(s.outerHTML||s.nodeValue).trim()}"
+ // vendor/topbar.js
+ var require_topbar = __commonJS({
+ "vendor/topbar.js"(exports, module) {
+ (function(window2, document2) {
+ "use strict";
+ (function() {
+ var lastTime = 0;
+ var vendors = ["ms", "moz", "webkit", "o"];
+ for (var x = 0; x < vendors.length && !window2.requestAnimationFrame; ++x) {
+ window2.requestAnimationFrame = window2[vendors[x] + "RequestAnimationFrame"];
+ window2.cancelAnimationFrame = window2[vendors[x] + "CancelAnimationFrame"] || window2[vendors[x] + "CancelRequestAnimationFrame"];
+ }
+ if (!window2.requestAnimationFrame)
+ window2.requestAnimationFrame = function(callback, element) {
+ var currTime = (/* @__PURE__ */ new Date()).getTime();
+ var timeToCall = Math.max(0, 16 - (currTime - lastTime));
+ var id = window2.setTimeout(function() {
+ callback(currTime + timeToCall);
+ }, timeToCall);
+ lastTime = currTime + timeToCall;
+ return id;
+ };
+ if (!window2.cancelAnimationFrame)
+ window2.cancelAnimationFrame = function(id) {
+ clearTimeout(id);
+ };
+ })();
+ var canvas, currentProgress, showing, progressTimerId = null, fadeTimerId = null, delayTimerId = null, addEvent = function(elem, type, handler) {
+ if (elem.addEventListener)
+ elem.addEventListener(type, handler, false);
+ else if (elem.attachEvent)
+ elem.attachEvent("on" + type, handler);
+ else
+ elem["on" + type] = handler;
+ }, options = {
+ autoRun: true,
+ barThickness: 3,
+ barColors: {
+ 0: "rgba(26, 188, 156, .9)",
+ ".25": "rgba(52, 152, 219, .9)",
+ ".50": "rgba(241, 196, 15, .9)",
+ ".75": "rgba(230, 126, 34, .9)",
+ "1.0": "rgba(211, 84, 0, .9)"
+ },
+ shadowBlur: 10,
+ shadowColor: "rgba(0, 0, 0, .6)",
+ className: null
+ }, repaint = function() {
+ canvas.width = window2.innerWidth;
+ canvas.height = options.barThickness * 5;
+ var ctx = canvas.getContext("2d");
+ ctx.shadowBlur = options.shadowBlur;
+ ctx.shadowColor = options.shadowColor;
+ var lineGradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
+ for (var stop in options.barColors)
+ lineGradient.addColorStop(stop, options.barColors[stop]);
+ ctx.lineWidth = options.barThickness;
+ ctx.beginPath();
+ ctx.moveTo(0, options.barThickness / 2);
+ ctx.lineTo(
+ Math.ceil(currentProgress * canvas.width),
+ options.barThickness / 2
+ );
+ ctx.strokeStyle = lineGradient;
+ ctx.stroke();
+ }, createCanvas = function() {
+ canvas = document2.createElement("canvas");
+ var style2 = canvas.style;
+ style2.position = "fixed";
+ style2.top = style2.left = style2.right = style2.margin = style2.padding = 0;
+ style2.zIndex = 100001;
+ style2.display = "none";
+ if (options.className)
+ canvas.classList.add(options.className);
+ document2.body.appendChild(canvas);
+ addEvent(window2, "resize", repaint);
+ }, topbar2 = {
+ config: function(opts) {
+ for (var key in opts)
+ if (options.hasOwnProperty(key))
+ options[key] = opts[key];
+ },
+ show: function(delay) {
+ if (showing)
+ return;
+ if (delay) {
+ if (delayTimerId)
+ return;
+ delayTimerId = setTimeout(() => topbar2.show(), delay);
+ } else {
+ showing = true;
+ if (fadeTimerId !== null)
+ window2.cancelAnimationFrame(fadeTimerId);
+ if (!canvas)
+ createCanvas();
+ canvas.style.opacity = 1;
+ canvas.style.display = "block";
+ topbar2.progress(0);
+ if (options.autoRun) {
+ (function loop() {
+ progressTimerId = window2.requestAnimationFrame(loop);
+ topbar2.progress(
+ "+" + 0.05 * Math.pow(1 - Math.sqrt(currentProgress), 2)
+ );
+ })();
+ }
+ }
+ },
+ progress: function(to) {
+ if (typeof to === "undefined")
+ return currentProgress;
+ if (typeof to === "string") {
+ to = (to.indexOf("+") >= 0 || to.indexOf("-") >= 0 ? currentProgress : 0) + parseFloat(to);
+ }
+ currentProgress = to > 1 ? 1 : to;
+ repaint();
+ return currentProgress;
+ },
+ hide: function() {
+ clearTimeout(delayTimerId);
+ delayTimerId = null;
+ if (!showing)
+ return;
+ showing = false;
+ if (progressTimerId != null) {
+ window2.cancelAnimationFrame(progressTimerId);
+ progressTimerId = null;
+ }
+ (function loop() {
+ if (topbar2.progress("+.1") >= 1) {
+ canvas.style.opacity -= 0.05;
+ if (canvas.style.opacity <= 0.05) {
+ canvas.style.display = "none";
+ fadeTimerId = null;
+ return;
+ }
+ }
+ fadeTimerId = window2.requestAnimationFrame(loop);
+ })();
+ }
+ };
+ if (typeof module === "object" && typeof module.exports === "object") {
+ module.exports = topbar2;
+ } else if (typeof define === "function" && define.amd) {
+ define(function() {
+ return topbar2;
+ });
+ } else {
+ this.topbar = topbar2;
+ }
+ }).call(exports, window, document);
+ }
+ });
-`),i.push(s))}),i.forEach(s=>s.remove())}},replaceRootContainer(e,t,i){let s=new Set(["id",te,ge,It,de]);if(e.tagName.toLowerCase()===t.toLowerCase())return Array.from(e.attributes).filter(r=>!s.has(r.name.toLowerCase())).forEach(r=>e.removeAttribute(r.name)),Object.keys(i).filter(r=>!s.has(r.toLowerCase())).forEach(r=>e.setAttribute(r,i[r])),e;{let r=document.createElement(t);return Object.keys(i).forEach(n=>r.setAttribute(n,i[n])),s.forEach(n=>r.setAttribute(n,e.getAttribute(n))),r.innerHTML=e.innerHTML,e.replaceWith(r),r}},getSticky(e,t,i){let s=(V.private(e,"sticky")||[]).find(([r])=>t===r);if(s){let[r,n,a]=s;return a}else return typeof i=="function"?i():i},deleteSticky(e,t){this.updatePrivate(e,"sticky",[],i=>i.filter(([s,r])=>s!==t))},putSticky(e,t,i){let s=i(e);this.updatePrivate(e,"sticky",[],r=>{let n=r.findIndex(([a])=>t===a);return n>=0?r[n]=[t,i,s]:r.push([t,i,s]),r})},applyStickyOperations(e){let t=V.private(e,"sticky");t&&t.forEach(([i,s,r])=>this.putSticky(e,i,s))}},c=V,Ie=class{static isActive(e,t){let i=t._phxRef===void 0,r=e.getAttribute(Ct).split(",").indexOf(L.genFileRef(t))>=0;return t.size>0&&(i||r)}static isPreflighted(e,t){return e.getAttribute(xt).split(",").indexOf(L.genFileRef(t))>=0&&this.isActive(e,t)}static isPreflightInProgress(e){return e._preflightInProgress===!0}static markPreflightInProgress(e){e._preflightInProgress=!0}constructor(e,t,i,s){this.ref=L.genFileRef(t),this.fileEl=e,this.file=t,this.view=i,this.meta=null,this._isCancelled=!1,this._isDone=!1,this._progress=0,this._lastProgressSent=-1,this._onDone=function(){},this._onElUpdated=this.onElUpdated.bind(this),this.fileEl.addEventListener(Qe,this._onElUpdated),this.autoUpload=s}metadata(){return this.meta}progress(e){this._progress=Math.floor(e),this._progress>this._lastProgressSent&&(this._progress>=100?(this._progress=100,this._lastProgressSent=100,this._isDone=!0,this.view.pushFileProgress(this.fileEl,this.ref,100,()=>{L.untrackFile(this.fileEl,this.file),this._onDone()})):(this._lastProgressSent=this._progress,this.view.pushFileProgress(this.fileEl,this.ref,this._progress)))}isCancelled(){return this._isCancelled}cancel(){this.file._preflightInProgress=!1,this._isCancelled=!0,this._isDone=!0,this._onDone()}isDone(){return this._isDone}error(e="failed"){this.fileEl.removeEventListener(Qe,this._onElUpdated),this.view.pushFileProgress(this.fileEl,this.ref,{error:e}),this.isAutoUpload()||L.clearFiles(this.fileEl)}isAutoUpload(){return this.autoUpload}onDone(e){this._onDone=()=>{this.fileEl.removeEventListener(Qe,this._onElUpdated),e()}}onElUpdated(){this.fileEl.getAttribute(Ct).split(",").indexOf(this.ref)===-1&&(L.untrackFile(this.fileEl,this.file),this.cancel())}toPreflightPayload(){return{last_modified:this.file.lastModified,name:this.file.name,relative_path:this.file.webkitRelativePath,size:this.file.size,type:this.file.type,ref:this.ref,meta:typeof this.file.meta=="function"?this.file.meta():void 0}}uploader(e){if(this.meta.uploader){let t=e[this.meta.uploader]||j(`no uploader configured for ${this.meta.uploader}`);return{name:this.meta.uploader,callback:t}}else return{name:"channel",callback:Ws}}zipPostFlight(e){this.meta=e.entries[this.ref],this.meta||j(`no preflight upload response returned with ref ${this.ref}`,{input:this.fileEl,response:e})}},Ks=0,L=class{static genFileRef(e){let t=e._phxRef;return t!==void 0?t:(e._phxRef=(Ks++).toString(),e._phxRef)}static getEntryDataURL(e,t,i){let s=this.activeFiles(e).find(r=>this.genFileRef(r)===t);i(URL.createObjectURL(s))}static hasUploadsInProgress(e){let t=0;return c.findUploadInputs(e).forEach(i=>{i.getAttribute(xt)!==i.getAttribute(Ps)&&t++}),t>0}static serializeUploads(e){let t=this.activeFiles(e),i={};return t.forEach(s=>{let r={path:e.name},n=e.getAttribute(ee);i[n]=i[n]||[],r.ref=this.genFileRef(s),r.last_modified=s.lastModified,r.name=s.name||r.ref,r.relative_path=s.webkitRelativePath,r.type=s.type,r.size=s.size,typeof s.meta=="function"&&(r.meta=s.meta()),i[n].push(r)}),i}static clearFiles(e){e.value=null,e.removeAttribute(ee),c.putPrivate(e,"files",[])}static untrackFile(e,t){c.putPrivate(e,"files",c.private(e,"files").filter(i=>!Object.is(i,t)))}static trackFiles(e,t,i){if(e.getAttribute("multiple")!==null){let s=t.filter(r=>!this.activeFiles(e).find(n=>Object.is(n,r)));c.updatePrivate(e,"files",[],r=>r.concat(s)),e.value=null}else i&&i.files.length>0&&(e.files=i.files),c.putPrivate(e,"files",t)}static activeFileInputs(e){let t=c.findUploadInputs(e);return Array.from(t).filter(i=>i.files&&this.activeFiles(i).length>0)}static activeFiles(e){return(c.private(e,"files")||[]).filter(t=>Ie.isActive(e,t))}static inputsAwaitingPreflight(e){let t=c.findUploadInputs(e);return Array.from(t).filter(i=>this.filesAwaitingPreflight(i).length>0)}static filesAwaitingPreflight(e){return this.activeFiles(e).filter(t=>!Ie.isPreflighted(e,t)&&!Ie.isPreflightInProgress(t))}static markPreflightInProgress(e){e.forEach(t=>Ie.markPreflightInProgress(t.file))}constructor(e,t,i){this.autoUpload=c.isAutoUpload(e),this.view=t,this.onComplete=i,this._entries=Array.from(L.filesAwaitingPreflight(e)||[]).map(s=>new Ie(e,s,t,this.autoUpload)),L.markPreflightInProgress(this._entries),this.numEntriesInProgress=this._entries.length}isAutoUpload(){return this.autoUpload}entries(){return this._entries}initAdapterUpload(e,t,i){this._entries=this._entries.map(r=>(r.isCancelled()?(this.numEntriesInProgress--,this.numEntriesInProgress===0&&this.onComplete()):(r.zipPostFlight(e),r.onDone(()=>{this.numEntriesInProgress--,this.numEntriesInProgress===0&&this.onComplete()})),r));let s=this._entries.reduce((r,n)=>{if(!n.meta)return r;let{name:a,callback:o}=n.uploader(i.uploaders);return r[a]=r[a]||{callback:o,entries:[]},r[a].entries.push(n),r},{});for(let r in s){let{callback:n,entries:a}=s[r];n(a,t,e,i)}}},Li={LiveFileUpload:{activeRefs(){return this.el.getAttribute(Ct)},preflightedRefs(){return this.el.getAttribute(xt)},mounted(){this.preflightedWas=this.preflightedRefs()},updated(){let e=this.preflightedRefs();this.preflightedWas!==e&&(this.preflightedWas=e,e===""&&this.__view.cancelSubmit(this.el.form)),this.activeRefs()===""&&(this.el.value=null),this.el.dispatchEvent(new CustomEvent(Qe))}},LiveImgPreview:{mounted(){this.ref=this.el.getAttribute("data-phx-entry-ref"),this.inputEl=document.getElementById(this.el.getAttribute(ee)),L.getEntryDataURL(this.inputEl,this.ref,e=>{this.url=e,this.el.src=e})},destroyed(){URL.revokeObjectURL(this.url)}},FocusWrap:{mounted(){this.focusStart=this.el.firstElementChild,this.focusEnd=this.el.lastElementChild,this.focusStart.addEventListener("focus",()=>ve.focusLast(this.el)),this.focusEnd.addEventListener("focus",()=>ve.focusFirst(this.el)),this.el.addEventListener("phx:show-end",()=>this.el.focus()),window.getComputedStyle(this.el).display!=="none"&&ve.focusFirst(this.el)}}},Oi=e=>["HTML","BODY"].indexOf(e.nodeName.toUpperCase())>=0?null:["scroll","auto"].indexOf(getComputedStyle(e).overflowY)>=0?e:Oi(e.parentElement),mi=e=>e?e.scrollTop:document.documentElement.scrollTop||document.body.scrollTop,Lt=e=>e?e.getBoundingClientRect().bottom:window.innerHeight||document.documentElement.clientHeight,Ot=e=>e?e.getBoundingClientRect().top:0,Gs=(e,t)=>{let i=e.getBoundingClientRect();return i.top>=Ot(t)&&i.left>=0&&i.top<=Lt(t)},Ys=(e,t)=>{let i=e.getBoundingClientRect();return i.right>=Ot(t)&&i.left>=0&&i.bottom<=Lt(t)},gi=(e,t)=>{let i=e.getBoundingClientRect();return i.top>=Ot(t)&&i.left>=0&&i.top<=Lt(t)};Li.InfiniteScroll={mounted(){this.scrollContainer=Oi(this.el);let e=mi(this.scrollContainer),t=!1,i=500,s=null,r=this.throttle(i,(o,l)=>{s=()=>!0,this.liveSocket.execJSHookPush(this.el,o,{id:l.id,_overran:!0},()=>{s=null})}),n=this.throttle(i,(o,l)=>{s=()=>l.scrollIntoView({block:"start"}),this.liveSocket.execJSHookPush(this.el,o,{id:l.id},()=>{s=null,window.requestAnimationFrame(()=>{gi(l,this.scrollContainer)||l.scrollIntoView({block:"start"})})})}),a=this.throttle(i,(o,l)=>{s=()=>l.scrollIntoView({block:"end"}),this.liveSocket.execJSHookPush(this.el,o,{id:l.id},()=>{s=null,window.requestAnimationFrame(()=>{gi(l,this.scrollContainer)||l.scrollIntoView({block:"end"})})})});this.onScroll=o=>{let l=mi(this.scrollContainer);if(s)return e=l,s();let h=this.el.getBoundingClientRect(),d=this.el.getAttribute(this.liveSocket.binding("viewport-top")),m=this.el.getAttribute(this.liveSocket.binding("viewport-bottom")),p=this.el.lastElementChild,f=this.el.firstElementChild,g=le;g&&d&&!t&&h.top>=0?(t=!0,r(d,f)):v&&t&&h.top<=0&&(t=!1),d&&g&&Gs(f,this.scrollContainer)?n(d,f):m&&v&&Ys(p,this.scrollContainer)&&a(m,p),e=l},this.scrollContainer?this.scrollContainer.addEventListener("scroll",this.onScroll):window.addEventListener("scroll",this.onScroll)},destroyed(){this.scrollContainer?this.scrollContainer.removeEventListener("scroll",this.onScroll):window.removeEventListener("scroll",this.onScroll)},throttle(e,t){let i=0,s;return(...r)=>{let n=Date.now(),a=e-(n-i);a<=0||a>e?(s&&(clearTimeout(s),s=null),i=n,t(...r)):s||(s=setTimeout(()=>{i=Date.now(),s=null,t(...r)},a))}}};var Zs=Li,Qs=class{constructor(e,t,i){let s=new Set,r=new Set([...t.children].map(a=>a.id)),n=[];Array.from(e.children).forEach(a=>{if(a.id&&(s.add(a.id),r.has(a.id))){let o=a.previousElementSibling&&a.previousElementSibling.id;n.push({elementId:a.id,previousElementId:o})}}),this.containerId=t.id,this.updateType=i,this.elementsToModify=n,this.elementIdsToAdd=[...r].filter(a=>!s.has(a))}perform(){let e=c.byId(this.containerId);this.elementsToModify.forEach(t=>{t.previousElementId?ae(document.getElementById(t.previousElementId),i=>{ae(document.getElementById(t.elementId),s=>{s.previousElementSibling&&s.previousElementSibling.id==i.id||i.insertAdjacentElement("afterend",s)})}):ae(document.getElementById(t.elementId),i=>{i.previousElementSibling==null||e.insertAdjacentElement("afterbegin",i)})}),this.updateType=="prepend"&&this.elementIdsToAdd.reverse().forEach(t=>{ae(document.getElementById(t),i=>e.insertAdjacentElement("afterbegin",i))})}},vi=11;function er(e,t){var i=t.attributes,s,r,n,a,o;if(!(t.nodeType===vi||e.nodeType===vi)){for(var l=i.length-1;l>=0;l--)s=i[l],r=s.name,n=s.namespaceURI,a=s.value,n?(r=s.localName||r,o=e.getAttributeNS(n,r),o!==a&&(s.prefix==="xmlns"&&(r=s.name),e.setAttributeNS(n,r,a))):(o=e.getAttribute(r),o!==a&&e.setAttribute(r,a));for(var h=e.attributes,d=h.length-1;d>=0;d--)s=h[d],r=s.name,n=s.namespaceURI,n?(r=s.localName||r,t.hasAttributeNS(n,r)||e.removeAttributeNS(n,r)):t.hasAttribute(r)||e.removeAttribute(r)}}var Ke,tr="http://www.w3.org/1999/xhtml",N=typeof document=="undefined"?void 0:document,ir=!!N&&"content"in N.createElement("template"),sr=!!N&&N.createRange&&"createContextualFragment"in N.createRange();function rr(e){var t=N.createElement("template");return t.innerHTML=e,t.content.childNodes[0]}function nr(e){Ke||(Ke=N.createRange(),Ke.selectNode(N.body));var t=Ke.createContextualFragment(e);return t.childNodes[0]}function ar(e){var t=N.createElement("body");return t.innerHTML=e,t.childNodes[0]}function or(e){return e=e.trim(),ir?rr(e):sr?nr(e):ar(e)}function Ge(e,t){var i=e.nodeName,s=t.nodeName,r,n;return i===s?!0:(r=i.charCodeAt(0),n=s.charCodeAt(0),r<=90&&n>=97?i===s.toUpperCase():n<=90&&r>=97?s===i.toUpperCase():!1)}function lr(e,t){return!t||t===tr?N.createElement(e):N.createElementNS(t,e)}function hr(e,t){for(var i=e.firstChild;i;){var s=i.nextSibling;t.appendChild(i),i=s}return t}function kt(e,t,i){e[i]!==t[i]&&(e[i]=t[i],e[i]?e.setAttribute(i,""):e.removeAttribute(i))}var bi={OPTION:function(e,t){var i=e.parentNode;if(i){var s=i.nodeName.toUpperCase();s==="OPTGROUP"&&(i=i.parentNode,s=i&&i.nodeName.toUpperCase()),s==="SELECT"&&!i.hasAttribute("multiple")&&(e.hasAttribute("selected")&&!t.selected&&(e.setAttribute("selected","selected"),e.removeAttribute("selected")),i.selectedIndex=-1)}kt(e,t,"selected")},INPUT:function(e,t){kt(e,t,"checked"),kt(e,t,"disabled"),e.value!==t.value&&(e.value=t.value),t.hasAttribute("value")||e.removeAttribute("value")},TEXTAREA:function(e,t){var i=t.value;e.value!==i&&(e.value=i);var s=e.firstChild;if(s){var r=s.nodeValue;if(r==i||!i&&r==e.placeholder)return;s.nodeValue=i}},SELECT:function(e,t){if(!t.hasAttribute("multiple")){for(var i=-1,s=0,r=e.firstChild,n,a;r;)if(a=r.nodeName&&r.nodeName.toUpperCase(),a==="OPTGROUP")n=r,r=n.firstChild;else{if(a==="OPTION"){if(r.hasAttribute("selected")){i=s;break}s++}r=r.nextSibling,!r&&n&&(r=n.nextSibling,n=null)}e.selectedIndex=i}}},Le=1,yi=11,wi=3,Ai=8;function re(){}function dr(e){if(e)return e.getAttribute&&e.getAttribute("id")||e.id}function cr(e){return function(i,s,r){if(r||(r={}),typeof s=="string")if(i.nodeName==="#document"||i.nodeName==="HTML"||i.nodeName==="BODY"){var n=s;s=N.createElement("html"),s.innerHTML=n}else s=or(s);else s.nodeType===yi&&(s=s.firstElementChild);var a=r.getNodeKey||dr,o=r.onBeforeNodeAdded||re,l=r.onNodeAdded||re,h=r.onBeforeElUpdated||re,d=r.onElUpdated||re,m=r.onBeforeNodeDiscarded||re,p=r.onNodeDiscarded||re,f=r.onBeforeElChildrenUpdated||re,g=r.skipFromChildren||re,v=r.addChild||function(A,w){return A.appendChild(w)},E=r.childrenOnly===!0,_=Object.create(null),R=[];function T(A){R.push(A)}function x(A,w){if(A.nodeType===Le)for(var P=A.firstChild;P;){var S=void 0;w&&(S=a(P))?T(S):(p(P),P.firstChild&&x(P,w)),P=P.nextSibling}}function O(A,w,P){m(A)!==!1&&(w&&w.removeChild(A),p(A),x(A,P))}function k(A){if(A.nodeType===Le||A.nodeType===yi)for(var w=A.firstChild;w;){var P=a(w);P&&(_[P]=w),k(w),w=w.nextSibling}}k(i);function D(A){l(A);for(var w=A.firstChild;w;){var P=w.nextSibling,S=a(w);if(S){var C=_[S];C&&Ge(w,C)?(w.parentNode.replaceChild(C,w),u(C,w)):D(w)}else D(w);w=P}}function B(A,w,P){for(;w;){var S=w.nextSibling;(P=a(w))?T(P):O(w,A,!0),w=S}}function u(A,w,P){var S=a(w);S&&delete _[S],!(!P&&(h(A,w)===!1||(e(A,w),d(A),f(A,w)===!1)))&&(A.nodeName!=="TEXTAREA"?y(A,w):bi.TEXTAREA(A,w))}function y(A,w){var P=g(A,w),S=w.firstChild,C=A.firstChild,ue,G,fe,Ne,ie;e:for(;S;){for(Ne=S.nextSibling,ue=a(S);!P&&C;){if(fe=C.nextSibling,S.isSameNode&&S.isSameNode(C)){S=Ne,C=fe;continue e}G=a(C);var $e=C.nodeType,se=void 0;if($e===S.nodeType&&($e===Le?(ue?ue!==G&&((ie=_[ue])?fe===ie?se=!1:(A.insertBefore(ie,C),G?T(G):O(C,A,!0),C=ie,G=a(C)):se=!1):G&&(se=!1),se=se!==!1&&Ge(C,S),se&&u(C,S)):($e===wi||$e==Ai)&&(se=!0,C.nodeValue!==S.nodeValue&&(C.nodeValue=S.nodeValue))),se){S=Ne,C=fe;continue e}G?T(G):O(C,A,!0),C=fe}if(ue&&(ie=_[ue])&&Ge(ie,S))P||v(A,ie),u(ie,S);else{var ut=o(S);ut!==!1&&(ut&&(S=ut),S.actualize&&(S=S.actualize(A.ownerDocument||N)),v(A,S),D(S))}S=Ne,C=fe}B(A,C,G);var Wt=bi[A.nodeName];Wt&&Wt(A,w)}var b=i,I=b.nodeType,F=s.nodeType;if(!E){if(I===Le)F===Le?Ge(i,s)||(p(i),b=hr(i,lr(s.nodeName,s.namespaceURI))):b=s;else if(I===wi||I===Ai){if(F===I)return b.nodeValue!==s.nodeValue&&(b.nodeValue=s.nodeValue),b;b=s}}if(b===s)p(i);else{if(s.isSameNode&&s.isSameNode(b))return;if(u(b,s,E),R)for(var Se=0,as=R.length;Se{if(i&&i.isSameNode(s)&&c.isFormInput(s))return c.mergeFocusedInput(s,r),!1}})}constructor(e,t,i,s,r,n){this.view=e,this.liveSocket=e.liveSocket,this.container=t,this.id=i,this.rootID=e.root.id,this.html=s,this.streams=r,this.streamInserts={},this.streamComponentRestore={},this.targetCID=n,this.cidPatch=Z(this.targetCID),this.pendingRemoves=[],this.phxRemove=this.liveSocket.binding("remove"),this.callbacks={beforeadded:[],beforeupdated:[],beforephxChildAdded:[],afteradded:[],afterupdated:[],afterdiscarded:[],afterphxChildAdded:[],aftertransitionsDiscarded:[]}}before(e,t){this.callbacks[`before${e}`].push(t)}after(e,t){this.callbacks[`after${e}`].push(t)}trackBefore(e,...t){this.callbacks[`before${e}`].forEach(i=>i(...t))}trackAfter(e,...t){this.callbacks[`after${e}`].forEach(i=>i(...t))}markPrunableContentForRemoval(){let e=this.liveSocket.binding(rt);c.all(this.container,`[${e}=append] > *, [${e}=prepend] > *`,t=>{t.setAttribute(ei,"")})}perform(e){let{view:t,liveSocket:i,container:s,html:r}=this,n=this.isCIDPatch()?this.targetCIDContainer(r):s;if(this.isCIDPatch()&&!n)return;let a=i.getActiveElement(),{selectionStart:o,selectionEnd:l}=a&&c.hasSelectionRange(a)?a:{},h=i.binding(rt),d=i.binding(tt),m=i.binding(it),p=i.binding(Pt),f=i.binding(Tt),g=i.binding(_t),v=i.binding(xs),E=[],_=[],R=[],T=[],x=null;function O(k,D,B=!1){Si(k,D,{childrenOnly:k.getAttribute(Q)===null&&!B,getNodeKey:u=>c.isPhxDestroyed(u)?null:e?u.id:u.id||u.getAttribute&&u.getAttribute(Pi),skipFromChildren:u=>u.getAttribute(h)===yt,addChild:(u,y)=>{let{ref:b,streamAt:I}=this.getStreamInsert(y);if(b===void 0)return u.appendChild(y);if(this.setStreamRef(y,b),I===0)u.insertAdjacentElement("afterbegin",y);else if(I===-1)u.appendChild(y);else if(I>0){let F=Array.from(u.children)[I];u.insertBefore(y,F)}},onBeforeNodeAdded:u=>{c.maybeAddPrivateHooks(u,f,g),this.trackBefore("added",u);let y=u;return!e&&this.streamComponentRestore[u.id]&&(y=this.streamComponentRestore[u.id],delete this.streamComponentRestore[u.id],O.call(this,y,u,!0)),y},onNodeAdded:u=>{u.getAttribute&&this.maybeReOrderStream(u,!0),c.isFeedbackContainer(u,d)&&_.push(u),u instanceof HTMLImageElement&&u.srcset?u.srcset=u.srcset:u instanceof HTMLVideoElement&&u.autoplay&&u.play(),c.isNowTriggerFormExternal(u,v)&&(x=u),(c.isPhxChild(u)&&t.ownsElement(u)||c.isPhxSticky(u)&&t.ownsElement(u.parentNode))&&this.trackAfter("phxChildAdded",u),E.push(u)},onNodeDiscarded:u=>this.onNodeDiscarded(u),onBeforeNodeDiscarded:u=>u.getAttribute&&u.getAttribute(ei)!==null?!0:!(u.parentElement!==null&&u.id&&c.isPhxUpdate(u.parentElement,h,[yt,"append","prepend"])||this.maybePendingRemove(u)||this.skipCIDSibling(u)),onElUpdated:u=>{c.isNowTriggerFormExternal(u,v)&&(x=u),R.push(u),this.maybeReOrderStream(u,!1)},onBeforeElUpdated:(u,y)=>{if(c.maybeAddPrivateHooks(y,f,g),(c.isFeedbackContainer(u,d)||c.isFeedbackContainer(y,d))&&(_.push(u),_.push(y)),c.cleanChildNodes(y,h),this.skipCIDSibling(y))return this.maybeReOrderStream(u),!1;if(c.isPhxSticky(u))return!1;if(c.isIgnored(u,h)||u.form&&u.form.isSameNode(x))return this.trackBefore("updated",u,y),c.mergeAttrs(u,y,{isIgnored:c.isIgnored(u,h)}),R.push(u),c.applyStickyOperations(u),!1;if(u.type==="number"&&u.validity&&u.validity.badInput)return!1;if(!c.syncPendingRef(u,y,p))return c.isUploadInput(u)&&(this.trackBefore("updated",u,y),R.push(u)),c.applyStickyOperations(u),!1;if(c.isPhxChild(y)){let F=u.getAttribute(te);return c.mergeAttrs(u,y,{exclude:[ge]}),F!==""&&u.setAttribute(te,F),u.setAttribute(de,this.rootID),c.applyStickyOperations(u),!1}c.copyPrivates(y,u);let b=a&&u.isSameNode(a)&&c.isFormInput(u),I=b&&this.isChangedSelect(u,y);return b&&u.type!=="hidden"&&!I?(this.trackBefore("updated",u,y),c.mergeFocusedInput(u,y),c.syncAttrsToProps(u),R.push(u),c.applyStickyOperations(u),!1):(I&&u.blur(),c.isPhxUpdate(y,h,["append","prepend"])&&T.push(new Qs(u,y,y.getAttribute(h))),c.syncAttrsToProps(y),c.applyStickyOperations(y),this.trackBefore("updated",u,y),!0)}})}return this.trackBefore("added",s),this.trackBefore("updated",s,s),i.time("morphdom",()=>{this.streams.forEach(([k,D,B,u])=>{D.forEach(([y,b,I])=>{this.streamInserts[y]={ref:k,streamAt:b,limit:I,reset:u}}),u!==void 0&&c.all(s,`[${wt}="${k}"]`,y=>{this.removeStreamChildElement(y)}),B.forEach(y=>{let b=s.querySelector(`[id="${y}"]`);b&&this.removeStreamChildElement(b)})}),e&&c.all(this.container,`[${h}=${yt}]`,k=>{this.liveSocket.owner(k,D=>{D===this.view&&Array.from(k.children).forEach(B=>{this.removeStreamChildElement(B)})})}),O.call(this,n,r)}),i.isDebugEnabled()&&(Vs(),Array.from(document.querySelectorAll("input[name=id]")).forEach(k=>{k.form&&console.error(`Detected an input with name="id" inside a form! This will cause problems when patching the DOM.
-`,k)})),T.length>0&&i.time("post-morph append/prepend restoration",()=>{T.forEach(k=>k.perform())}),c.maybeHideFeedback(n,_,d,m),i.silenceEvents(()=>c.restoreFocus(a,o,l)),c.dispatchEvent(document,"phx:update"),E.forEach(k=>this.trackAfter("added",k)),R.forEach(k=>this.trackAfter("updated",k)),this.transitionPendingRemoves(),x&&(i.unload(),Object.getPrototypeOf(x).submit.call(x)),!0}onNodeDiscarded(e){(c.isPhxChild(e)||c.isPhxSticky(e))&&this.liveSocket.destroyViewByEl(e),this.trackAfter("discarded",e)}maybePendingRemove(e){return e.getAttribute&&e.getAttribute(this.phxRemove)!==null?(this.pendingRemoves.push(e),!0):!1}removeStreamChildElement(e){this.streamInserts[e.id]?(this.streamComponentRestore[e.id]=e,e.remove()):this.maybePendingRemove(e)||(e.remove(),this.onNodeDiscarded(e))}getStreamInsert(e){return(e.id?this.streamInserts[e.id]:{})||{}}setStreamRef(e,t){c.putSticky(e,wt,i=>i.setAttribute(wt,t))}maybeReOrderStream(e,t){let{ref:i,streamAt:s,reset:r}=this.getStreamInsert(e);if(s!==void 0&&(this.setStreamRef(e,i),!(!r&&!t)&&e.parentElement)){if(s===0)e.parentElement.insertBefore(e,e.parentElement.firstElementChild);else if(s>0){let n=Array.from(e.parentElement.children),a=n.indexOf(e);if(s>=n.length-1)e.parentElement.appendChild(e);else{let o=n[s];a>s?e.parentElement.insertBefore(e,o):e.parentElement.insertBefore(e,o.nextElementSibling)}}this.maybeLimitStream(e)}}maybeLimitStream(e){let{limit:t}=this.getStreamInsert(e),i=t!==null&&Array.from(e.parentElement.children);t&&t<0&&i.length>t*-1?i.slice(0,i.length+t).forEach(s=>this.removeStreamChildElement(s)):t&&t>=0&&i.length>t&&i.slice(t).forEach(s=>this.removeStreamChildElement(s))}transitionPendingRemoves(){let{pendingRemoves:e,liveSocket:t}=this;e.length>0&&(t.transitionRemoves(e),t.requestDOMUpdate(()=>{e.forEach(i=>{let s=c.firstPhxChild(i);s&&t.destroyViewByEl(s),i.remove()}),this.trackAfter("transitionsDiscarded",e)}))}isChangedSelect(e,t){if(!(e instanceof HTMLSelectElement)||e.multiple)return!1;if(e.options.length!==t.options.length)return!0;let i=e.selectedOptions[0],s=t.selectedOptions[0];return i&&i.hasAttribute("selected")&&s.setAttribute("selected",i.getAttribute("selected")),!e.isEqualNode(t)}isCIDPatch(){return this.cidPatch}skipCIDSibling(e){return e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute(Ri)}targetCIDContainer(e){if(!this.isCIDPatch())return;let[t,...i]=c.findComponentNodeList(this.container,this.targetCID);return i.length===0&&c.childNodeLength(e)===1?t:t&&t.parentNode}indexOf(e,t){return Array.from(e.children).indexOf(t)}},fr=new Set(["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"]),pr=new Set(["'",'"']),Ei=(e,t,i)=>{let s=0,r=!1,n,a,o,l,h,d,m=e.match(/^(\s*(?:\s*)*)<([^\s\/>]+)/);if(m===null)throw new Error(`malformed html ${e}`);for(s=m[0].length,n=m[1],o=m[2],l=s,s;s";s++)if(e.charAt(s)==="="){let g=e.slice(s-3,s)===" id";s++;let v=e.charAt(s);if(pr.has(v)){let E=s;for(s++,s;s=n.length+o.length;){let g=e.charAt(p);if(r)g==="-"&&e.slice(p-3,p)===""&&e.slice(p-2,p)==="--")r=!0,p-=3;else{if(g===">")break;p-=1}}a=e.slice(p+1,e.length);let f=Object.keys(t).map(g=>t[g]===!0?g:`${g}="${t[g]}"`).join(" ");if(i){let g=h?` id="${h}"`:"";fr.has(o)?d=`<${o}${g}${f===""?"":" "}${f}/>`:d=`<${o}${g}${f===""?"":" "}${f}>${o}>`}else{let g=e.slice(l,p+1);d=`<${o}${f===""?"":" "}${f}${g}`}return[d,n,a]},ki=class{static extract(e){let{[hi]:t,[li]:i,[di]:s}=e;return delete e[hi],delete e[li],delete e[di],{diff:e,title:s,reply:t||null,events:i||[]}}constructor(e,t){this.viewId=e,this.rendered={},this.magicId=0,this.mergeDiff(t)}parentViewId(){return this.viewId}toString(e){let[t,i]=this.recursiveToString(this.rendered,this.rendered[H],e,!0,{});return[t,i]}recursiveToString(e,t=e[H],i,s,r){i=i?new Set(i):null;let n={buffer:"",components:t,onlyCids:i,streams:new Set};return this.toOutputBuffer(e,null,n,s,r),[n.buffer,n.streams]}componentCIDs(e){return Object.keys(e[H]||{}).map(t=>parseInt(t))}isComponentOnlyDiff(e){return e[H]?Object.keys(e).length===1:!1}getComponent(e,t){return e[H][t]}resetRender(e){this.rendered[H][e]&&(this.rendered[H][e].reset=!0)}mergeDiff(e){let t=e[H],i={};if(delete e[H],this.rendered=this.mutableMerge(this.rendered,e),this.rendered[H]=this.rendered[H]||{},t){let s=this.rendered[H];for(let r in t)t[r]=this.cachedFindComponent(r,t[r],s,t,i);for(let r in t)s[r]=t[r];e[H]=t}}cachedFindComponent(e,t,i,s,r){if(r[e])return r[e];{let n,a,o=t[z];if(Z(o)){let l;o>0?l=this.cachedFindComponent(o,s[o],i,s,r):l=i[-o],a=l[z],n=this.cloneMerge(l,t,!0),n[z]=a}else n=t[z]!==void 0||i[e]===void 0?t:this.cloneMerge(i[e],t,!1);return r[e]=n,n}}mutableMerge(e,t){return t[z]!==void 0?t:(this.doMutableMerge(e,t),e)}doMutableMerge(e,t){for(let i in t){let s=t[i],r=e[i];me(s)&&s[z]===void 0&&me(r)?this.doMutableMerge(r,s):e[i]=s}e[Et]&&(e.newRender=!0)}cloneMerge(e,t,i){let s=q(q({},e),t);for(let r in s){let n=t[r],a=e[r];me(n)&&n[z]===void 0&&me(a)?s[r]=this.cloneMerge(a,n,i):n===void 0&&me(a)&&(s[r]=this.cloneMerge(a,{},i))}return i?(delete s.magicId,delete s.newRender):e[Et]&&(s.newRender=!0),s}componentToString(e){let[t,i]=this.recursiveCIDToString(this.rendered[H],e,null),[s,r,n]=Ei(t,{});return[s,i]}pruneCIDs(e){e.forEach(t=>delete this.rendered[H][t])}get(){return this.rendered}isNewFingerprint(e={}){return!!e[z]}templateStatic(e,t){return typeof e=="number"?t[e]:e}nextMagicID(){return this.magicId++,`m${this.magicId}-${this.parentViewId()}`}toOutputBuffer(e,t,i,s,r={}){if(e[ze])return this.comprehensionToBuffer(e,t,i);let{[z]:n}=e;n=this.templateStatic(n,t);let a=e[Et],o=i.buffer;a&&(i.buffer=""),s&&a&&!e.magicId&&(e.newRender=!0,e.magicId=this.nextMagicID()),i.buffer+=n[0];for(let l=1;l0||l.length>0||h)&&(delete e[ci],e[ze]=[],i.streams.add(n))}dynamicToBuffer(e,t,i,s){if(typeof e=="number"){let[r,n]=this.recursiveCIDToString(i.components,e,i.onlyCids);i.buffer+=r,i.streams=new Set([...i.streams,...n])}else me(e)?this.toOutputBuffer(e,t,i,s,{}):i.buffer+=e}recursiveCIDToString(e,t,i){let s=e[t]||j(`no component for CID ${t}`,e),r={[Q]:t},n=i&&!i.has(t);s.newRender=!n,s.magicId=`c${t}-${this.parentViewId()}`;let a=!s.reset,[o,l]=this.recursiveToString(s,e,i,a,r);return delete s.reset,[o,l]}},mr=1,Oe=class{static makeID(){return mr++}static elementID(e){return e.phxHookId}constructor(e,t,i){this.__view=e,this.liveSocket=e.liveSocket,this.__callbacks=i,this.__listeners=new Set,this.__isDisconnected=!1,this.el=t,this.el.phxHookId=this.constructor.makeID();for(let s in this.__callbacks)this[s]=this.__callbacks[s]}__mounted(){this.mounted&&this.mounted()}__updated(){this.updated&&this.updated()}__beforeUpdate(){this.beforeUpdate&&this.beforeUpdate()}__destroyed(){this.destroyed&&this.destroyed()}__reconnected(){this.__isDisconnected&&(this.__isDisconnected=!1,this.reconnected&&this.reconnected())}__disconnected(){this.__isDisconnected=!0,this.disconnected&&this.disconnected()}pushEvent(e,t={},i=function(){}){return this.__view.pushHookEvent(this.el,null,e,t,i)}pushEventTo(e,t,i={},s=function(){}){return this.__view.withinTargets(e,(r,n)=>r.pushHookEvent(this.el,n,t,i,s))}handleEvent(e,t){let i=(s,r)=>r?e:t(s.detail);return window.addEventListener(`phx:${e}`,i),this.__listeners.add(i),i}removeHandleEvent(e){let t=e(null,!0);window.removeEventListener(`phx:${t}`,e),this.__listeners.delete(e)}upload(e,t){return this.__view.dispatchUploads(null,e,t)}uploadTo(e,t,i){return this.__view.withinTargets(e,(s,r)=>{s.dispatchUploads(r,t,i)})}__cleanup__(){this.__listeners.forEach(e=>this.removeHandleEvent(e))}},Ze=(e,t,i=[])=>{let h=t,{submitter:s}=h,r=Gt(h,["submitter"]),n;if(s&&s.name){let d=document.createElement("input");d.type="hidden";let m=s.getAttribute("form");m&&d.setAttribute("form",m),d.name=s.name,d.value=s.value,s.parentElement.insertBefore(d,s),n=d}let a=new FormData(e),o=[];a.forEach((d,m,p)=>{d instanceof File&&o.push(m)}),o.forEach(d=>a.delete(d));let l=new URLSearchParams;for(let[d,m]of a.entries())(i.length===0||i.indexOf(d)>=0)&&l.append(d,m);s&&n&&s.parentElement.removeChild(n);for(let d in r)l.append(d,r[d]);return l.toString()},Di=class{constructor(e,t,i,s,r){this.isDead=!1,this.liveSocket=t,this.flash=s,this.parent=i,this.root=i?i.root:this,this.el=e,this.id=this.el.id,this.ref=0,this.childJoins=0,this.loaderTimer=null,this.pendingDiffs=[],this.pendingForms=new Set,this.redirect=!1,this.href=null,this.joinCount=this.parent?this.parent.joinCount-1:0,this.joinPending=!0,this.destroyed=!1,this.joinCallback=function(n){n&&n()},this.stopCallback=function(){},this.pendingJoinOps=this.parent?null:[],this.viewHooks={},this.formSubmits=[],this.children=this.parent?null:{},this.root.children[this.id]={},this.formsForRecovery={},this.channel=this.liveSocket.channel(`lv:${this.id}`,()=>{let n=this.href&&this.expandURL(this.href);return{redirect:this.redirect?n:void 0,url:this.redirect?void 0:n||void 0,params:this.connectParams(r),session:this.getSession(),static:this.getStatic(),flash:this.flash}})}setHref(e){this.href=e}setRedirect(e){this.redirect=!0,this.href=e}isMain(){return this.el.hasAttribute(It)}connectParams(e){let t=this.liveSocket.params(this.el),i=c.all(document,`[${this.binding(_s)}]`).map(s=>s.src||s.href).filter(s=>typeof s=="string");return i.length>0&&(t._track_static=i),t._mounts=this.joinCount,t._live_referer=e,t}isConnected(){return this.channel.canPush()}getSession(){return this.el.getAttribute(te)}getStatic(){let e=this.el.getAttribute(ge);return e===""?null:e}destroy(e=function(){}){this.destroyAllChildren(),this.destroyed=!0,delete this.root.children[this.id],this.parent&&delete this.root.children[this.parent.id][this.id],clearTimeout(this.loaderTimer);let t=()=>{e();for(let i in this.viewHooks)this.destroyHook(this.viewHooks[i])};c.markPhxChildDestroyed(this.el),this.log("destroyed",()=>["the child has been removed from the parent"]),this.channel.leave().receive("ok",t).receive("error",t).receive("timeout",t)}setContainerClasses(...e){this.el.classList.remove(ii,Te,qe,si,vt),this.el.classList.add(...e)}showLoader(e){if(clearTimeout(this.loaderTimer),e)this.loaderTimer=setTimeout(()=>this.showLoader(),e);else{for(let t in this.viewHooks)this.viewHooks[t].__disconnected();this.setContainerClasses(Te)}}execAll(e){c.all(this.el,`[${e}]`,t=>this.liveSocket.execJS(t,t.getAttribute(e)))}hideLoader(){clearTimeout(this.loaderTimer),this.setContainerClasses(ii),this.execAll(this.binding("connected"))}triggerReconnected(){for(let e in this.viewHooks)this.viewHooks[e].__reconnected()}log(e,t){this.liveSocket.log(this,e,t)}transition(e,t,i=function(){}){this.liveSocket.transition(e,t,i)}withinTargets(e,t,i=document,s){if(e instanceof HTMLElement||e instanceof SVGElement)return this.liveSocket.owner(e,r=>t(r,e));if(Z(e))c.findComponentNodeList(s||this.el,e).length===0?j(`no component found matching phx-target of ${e}`):t(this,parseInt(e));else{let r=Array.from(i.querySelectorAll(e));r.length===0&&j(`nothing found matching the phx-target selector "${e}"`),r.forEach(n=>this.liveSocket.owner(n,a=>t(a,n)))}}applyDiff(e,t,i){this.log(e,()=>["",et(t)]);let{diff:s,reply:r,events:n,title:a}=ki.extract(t);i({diff:s,reply:r,events:n}),typeof a=="string"&&window.requestAnimationFrame(()=>c.putTitle(a))}onJoin(e){let{rendered:t,container:i,liveview_version:s}=e;if(i){let[r,n]=i;this.el=c.replaceRootContainer(this.el,r,n)}this.childJoins=0,this.joinPending=!0,this.flash=null,this.root===this&&(this.formsForRecovery=this.getFormsForRecovery()),s!==this.liveSocket.version()&&console.error(`LiveView asset version mismatch. JavaScript version ${this.liveSocket.version()} vs. server ${s}. To avoid issues, please ensure that your assets use the same version as the server.`),K.dropLocal(this.liveSocket.localStorage,window.location.pathname,Ci),this.applyDiff("mount",t,({diff:r,events:n})=>{this.rendered=new ki(this.id,r);let[a,o]=this.renderContainer(null,"join");this.dropPendingRefs(),this.joinCount++,this.maybeRecoverForms(a,()=>{this.onJoinComplete(e,a,o,n)})})}dropPendingRefs(){c.all(document,`[${ne}="${this.id}"][${U}]`,e=>{e.removeAttribute(U),e.removeAttribute(ne)})}onJoinComplete({live_patch:e},t,i,s){if(this.joinCount>1||this.parent&&!this.parent.isJoinPending())return this.applyJoinPatch(e,t,i,s);c.findPhxChildrenInFragment(t,this.id).filter(n=>{let a=n.id&&this.el.querySelector(`[id="${n.id}"]`),o=a&&a.getAttribute(ge);return o&&n.setAttribute(ge,o),a&&a.setAttribute(de,this.root.id),this.joinChild(n)}).length===0?this.parent?(this.root.pendingJoinOps.push([this,()=>this.applyJoinPatch(e,t,i,s)]),this.parent.ackJoin(this)):(this.onAllChildJoinsComplete(),this.applyJoinPatch(e,t,i,s)):this.root.pendingJoinOps.push([this,()=>this.applyJoinPatch(e,t,i,s)])}attachTrueDocEl(){this.el=c.byId(this.id),this.el.setAttribute(de,this.root.id)}execNewMounted(){let e=this.binding(Tt),t=this.binding(_t);c.all(this.el,`[${e}], [${t}]`,i=>{this.ownsElement(i)&&(c.maybeAddPrivateHooks(i,e,t),this.maybeAddNewHook(i))}),c.all(this.el,`[${this.binding(_e)}], [data-phx-${_e}]`,i=>{this.ownsElement(i)&&this.maybeAddNewHook(i)}),c.all(this.el,`[${this.binding(ai)}]`,i=>{this.ownsElement(i)&&this.maybeMounted(i)})}applyJoinPatch(e,t,i,s){this.attachTrueDocEl();let r=new Ye(this,this.el,this.id,t,i,null);if(r.markPrunableContentForRemoval(),this.performPatch(r,!1,!0),this.joinNewChildren(),this.execNewMounted(),this.joinPending=!1,this.liveSocket.dispatchEvents(s),this.applyPendingUpdates(),e){let{kind:n,to:a}=e;this.liveSocket.historyPatch(a,n)}this.hideLoader(),this.joinCount>1&&this.triggerReconnected(),this.stopCallback()}triggerBeforeUpdateHook(e,t){this.liveSocket.triggerDOM("onBeforeElUpdated",[e,t]);let i=this.getHook(e),s=i&&c.isIgnored(e,this.binding(rt));if(i&&!e.isEqualNode(t)&&!(s&&qs(e.dataset,t.dataset)))return i.__beforeUpdate(),i}maybeMounted(e){let t=e.getAttribute(this.binding(ai)),i=t&&c.private(e,"mounted");t&&!i&&(this.liveSocket.execJS(e,t),c.putPrivate(e,"mounted",!0))}maybeAddNewHook(e,t){let i=this.addHook(e);i&&i.__mounted()}performPatch(e,t,i=!1){let s=[],r=!1,n=new Set;return e.after("added",a=>{this.liveSocket.triggerDOM("onNodeAdded",[a]);let o=this.binding(Tt),l=this.binding(_t);c.maybeAddPrivateHooks(a,o,l),this.maybeAddNewHook(a),a.getAttribute&&this.maybeMounted(a)}),e.after("phxChildAdded",a=>{c.isPhxSticky(a)?this.liveSocket.joinRootViews():r=!0}),e.before("updated",(a,o)=>{this.triggerBeforeUpdateHook(a,o)&&n.add(a.id)}),e.after("updated",a=>{n.has(a.id)&&this.getHook(a).__updated()}),e.after("discarded",a=>{a.nodeType===Node.ELEMENT_NODE&&s.push(a)}),e.after("transitionsDiscarded",a=>this.afterElementsRemoved(a,t)),e.perform(i),this.afterElementsRemoved(s,t),r}afterElementsRemoved(e,t){let i=[];e.forEach(s=>{let r=c.all(s,`[${Q}]`),n=c.all(s,`[${this.binding(_e)}]`);r.concat(s).forEach(a=>{let o=this.componentID(a);Z(o)&&i.indexOf(o)===-1&&i.push(o)}),n.concat(s).forEach(a=>{let o=this.getHook(a);o&&this.destroyHook(o)})}),t&&this.maybePushComponentsDestroyed(i)}joinNewChildren(){c.findPhxChildren(this.el,this.id).forEach(e=>this.joinChild(e))}maybeRecoverForms(e,t){let i=this.binding("change"),s=this.root.formsForRecovery,r=document.createElement("template");r.innerHTML=e;let n=r.content.firstElementChild;n.id=this.id,n.setAttribute(de,this.root.id),n.setAttribute(te,this.getSession()),n.setAttribute(ge,this.getStatic()),n.setAttribute(he,this.parent?this.parent.id:null);let a=c.all(r.content,"form").filter(o=>o.id&&s[o.id]).filter(o=>!this.pendingForms.has(o.id)).filter(o=>s[o.id].getAttribute(i)===o.getAttribute(i)).map(o=>[s[o.id],o]);if(a.length===0)return t();a.forEach(([o,l],h)=>{this.pendingForms.add(l.id),this.pushFormRecovery(o,l,r.content,()=>{this.pendingForms.delete(l.id),h===a.length-1&&t()})})}getChildById(e){return this.root.children[this.id][e]}getDescendentByEl(e){return e.id===this.id?this:this.children[e.getAttribute(he)][e.id]}destroyDescendent(e){for(let t in this.root.children)for(let i in this.root.children[t])if(i===e)return this.root.children[t][i].destroy()}joinChild(e){if(!this.getChildById(e.id)){let i=new Di(e,this.liveSocket,this);return this.root.children[this.id][i.id]=i,i.join(),this.childJoins++,!0}}isJoinPending(){return this.joinPending}ackJoin(e){this.childJoins--,this.childJoins===0&&(this.parent?this.parent.ackJoin(this):this.onAllChildJoinsComplete())}onAllChildJoinsComplete(){this.pendingForms.clear(),this.formsForRecovery={},this.joinCallback(()=>{this.pendingJoinOps.forEach(([e,t])=>{e.isDestroyed()||t()}),this.pendingJoinOps=[]})}update(e,t){if(this.isJoinPending()||this.liveSocket.hasPendingLink()&&this.root.isMain())return this.pendingDiffs.push({diff:e,events:t});this.rendered.mergeDiff(e);let i=!1;this.rendered.isComponentOnlyDiff(e)?this.liveSocket.time("component patch complete",()=>{c.findExistingParentCIDs(this.el,this.rendered.componentCIDs(e)).forEach(r=>{this.componentPatch(this.rendered.getComponent(e,r),r)&&(i=!0)})}):ui(e)||this.liveSocket.time("full patch complete",()=>{let[s,r]=this.renderContainer(e,"update"),n=new Ye(this,this.el,this.id,s,r,null);i=this.performPatch(n,!0)}),this.liveSocket.dispatchEvents(t),i&&this.joinNewChildren()}renderContainer(e,t){return this.liveSocket.time(`toString diff (${t})`,()=>{let i=this.el.tagName,s=e?this.rendered.componentCIDs(e):null,[r,n]=this.rendered.toString(s);return[`<${i}>${r}${i}>`,n]})}componentPatch(e,t){if(ui(e))return!1;let[i,s]=this.rendered.componentToString(t),r=new Ye(this,this.el,this.id,i,s,t);return this.performPatch(r,!0)}getHook(e){return this.viewHooks[Oe.elementID(e)]}addHook(e){if(Oe.elementID(e)||!e.getAttribute)return;let t=e.getAttribute(`data-phx-${_e}`)||e.getAttribute(this.binding(_e));if(t&&!this.ownsElement(e))return;let i=this.liveSocket.getHookCallbacks(t);if(i){e.id||j(`no DOM ID for hook "${t}". Hooks require a unique ID on each element.`,e);let s=new Oe(this,e,i);return this.viewHooks[Oe.elementID(s.el)]=s,s}else t!==null&&j(`unknown hook found for "${t}"`,e)}destroyHook(e){e.__destroyed(),e.__cleanup__(),delete this.viewHooks[Oe.elementID(e.el)]}applyPendingUpdates(){this.pendingDiffs.forEach(({diff:e,events:t})=>this.update(e,t)),this.pendingDiffs=[],this.eachChild(e=>e.applyPendingUpdates())}eachChild(e){let t=this.root.children[this.id]||{};for(let i in t)e(this.getChildById(i))}onChannel(e,t){this.liveSocket.onChannel(this.channel,e,i=>{this.isJoinPending()?this.root.pendingJoinOps.push([this,()=>t(i)]):this.liveSocket.requestDOMUpdate(()=>t(i))})}bindChannel(){this.liveSocket.onChannel(this.channel,"diff",e=>{this.liveSocket.requestDOMUpdate(()=>{this.applyDiff("update",e,({diff:t,events:i})=>this.update(t,i))})}),this.onChannel("redirect",({to:e,flash:t})=>this.onRedirect({to:e,flash:t})),this.onChannel("live_patch",e=>this.onLivePatch(e)),this.onChannel("live_redirect",e=>this.onLiveRedirect(e)),this.channel.onError(e=>this.onError(e)),this.channel.onClose(e=>this.onClose(e))}destroyAllChildren(){this.eachChild(e=>e.destroy())}onLiveRedirect(e){let{to:t,kind:i,flash:s}=e,r=this.expandURL(t);this.liveSocket.historyRedirect(r,i,s)}onLivePatch(e){let{to:t,kind:i}=e;this.href=this.expandURL(t),this.liveSocket.historyPatch(t,i)}expandURL(e){return e.startsWith("/")?`${window.location.protocol}//${window.location.host}${e}`:e}onRedirect({to:e,flash:t}){this.liveSocket.redirect(e,t)}isDestroyed(){return this.destroyed}joinDead(){this.isDead=!0}join(e){this.showLoader(this.liveSocket.loaderTimeout),this.bindChannel(),this.isMain()&&(this.stopCallback=this.liveSocket.withPageLoading({to:this.href,kind:"initial"})),this.joinCallback=t=>{t=t||function(){},e?e(this.joinCount,t):t()},this.liveSocket.wrapPush(this,{timeout:!1},()=>this.channel.join().receive("ok",t=>{this.isDestroyed()||this.liveSocket.requestDOMUpdate(()=>this.onJoin(t))}).receive("error",t=>!this.isDestroyed()&&this.onJoinError(t)).receive("timeout",()=>!this.isDestroyed()&&this.onJoinError({reason:"timeout"})))}onJoinError(e){if(e.reason==="reload"){this.log("error",()=>[`failed mount with ${e.status}. Falling back to page request`,e]),this.isMain()&&this.onRedirect({to:this.href});return}else if(e.reason==="unauthorized"||e.reason==="stale"){this.log("error",()=>["unauthorized live_redirect. Falling back to page request",e]),this.isMain()&&this.onRedirect({to:this.href});return}if((e.redirect||e.live_redirect)&&(this.joinPending=!1,this.channel.leave()),e.redirect)return this.onRedirect(e.redirect);if(e.live_redirect)return this.onLiveRedirect(e.live_redirect);this.displayError([Te,qe,vt]),this.log("error",()=>["unable to join",e]),this.liveSocket.isConnected()&&this.liveSocket.reloadWithJitter(this)}onClose(e){if(!this.isDestroyed()){if(this.liveSocket.hasPendingLink()&&e!=="leave")return this.liveSocket.reloadWithJitter(this);this.destroyAllChildren(),this.liveSocket.dropActiveElement(this),document.activeElement&&document.activeElement.blur(),this.liveSocket.isUnloaded()&&this.showLoader(Ms)}}onError(e){this.onClose(e),this.liveSocket.isConnected()&&this.log("error",()=>["view crashed",e]),this.liveSocket.isUnloaded()||(this.liveSocket.isConnected()?this.displayError([Te,qe,vt]):this.displayError([Te,qe,si]))}displayError(e){this.isMain()&&c.dispatchEvent(window,"phx:page-loading-start",{detail:{to:this.href,kind:"error"}}),this.showLoader(),this.setContainerClasses(...e),this.execAll(this.binding("disconnected"))}pushWithReply(e,t,i,s=function(){}){if(!this.isConnected())return;let[r,[n],a]=e?e():[null,[],{}],o=function(){};return(a.page_loading||n&&n.getAttribute(this.binding(ti))!==null)&&(o=this.liveSocket.withPageLoading({kind:"element",target:n})),typeof i.cid!="number"&&delete i.cid,this.liveSocket.wrapPush(this,{timeout:!0},()=>this.channel.push(t,i,$s).receive("ok",l=>{let h=d=>{l.redirect&&this.onRedirect(l.redirect),l.live_patch&&this.onLivePatch(l.live_patch),l.live_redirect&&this.onLiveRedirect(l.live_redirect),o(),s(l,d)};l.diff?this.liveSocket.requestDOMUpdate(()=>{this.applyDiff("update",l.diff,({diff:d,reply:m,events:p})=>{r!==null&&this.undoRefs(r),this.update(d,p),h(m)})}):(r!==null&&this.undoRefs(r),h(null))}))}undoRefs(e,t){t=t?new Set(t):null,this.isConnected()&&c.all(document,`[${ne}="${this.id}"][${U}="${e}"]`,i=>{if(t&&!t.has(i))return;i.dispatchEvent(new CustomEvent("phx:unlock",{bubbles:!0,cancelable:!1}));let s=i.getAttribute(pe),r=i.getAttribute(bt);i.removeAttribute(U),i.removeAttribute(ne),r!==null&&(i.readOnly=r==="true",i.removeAttribute(bt)),s!==null&&(i.disabled=s==="true",i.removeAttribute(pe)),Ti.forEach(o=>c.removeClass(i,o));let n=i.getAttribute(We);n!==null&&(i.innerText=n,i.removeAttribute(We));let a=c.private(i,U);if(a){let o=this.triggerBeforeUpdateHook(i,a);Ye.patchEl(i,a,this.liveSocket.getActiveElement()),o&&o.__updated(),c.deletePrivate(i,U)}})}putRef(e,t,i={}){let s=this.ref++,r=this.binding(Pt);i.loading&&(e=e.concat(c.all(document,i.loading)));for(let n of e){if(n.setAttribute(U,s),n.setAttribute(ne,this.el.id),i.submitter&&!(n===i.submitter||n===i.form))continue;n.classList.add(`phx-${t}-loading`),n.dispatchEvent(new CustomEvent(`phx:${t}-loading`,{bubbles:!0,cancelable:!1}));let a=n.getAttribute(r);a!==null&&(n.getAttribute(We)||n.setAttribute(We,n.innerText),a!==""&&(n.innerText=a),n.setAttribute(pe,n.getAttribute(pe)||n.disabled),n.setAttribute("disabled",""))}return[s,e,i]}componentID(e){let t=e.getAttribute&&e.getAttribute(Q);return t?parseInt(t):null}targetComponentID(e,t,i={}){if(Z(t))return t;let s=i.target||e.getAttribute(this.binding("target"));return Z(s)?parseInt(s):t&&(s!==null||i.target)?this.closestComponentID(t):null}closestComponentID(e){return Z(e)?e:e?ae(e.closest(`[${Q}]`),t=>this.ownsElement(t)&&this.componentID(t)):null}pushHookEvent(e,t,i,s,r){if(!this.isConnected())return this.log("hook",()=>["unable to push hook event. LiveView not connected",i,s]),!1;let[n,a,o]=this.putRef([e],"hook");return this.pushWithReply(()=>[n,a,o],"event",{type:"hook",event:i,value:s,cid:this.closestComponentID(t)},(l,h)=>r(h,n)),n}extractMeta(e,t,i){let s=this.binding("value-");for(let r=0;r=0&&!e.checked&&delete t.value),i){t||(t={});for(let r in i)t[r]=i[r]}return t}pushEvent(e,t,i,s,r,n={},a){this.pushWithReply(()=>this.putRef([t],e,n),"event",{type:e,event:s,value:this.extractMeta(t,r,n.value),cid:this.targetComponentID(t,i,n)},(o,l)=>a&&a(l))}pushFileProgress(e,t,i,s=function(){}){this.liveSocket.withinOwners(e.form,(r,n)=>{r.pushWithReply(null,"progress",{event:e.getAttribute(r.binding(Fs)),ref:e.getAttribute(ee),entry_ref:t,progress:i,cid:r.targetComponentID(e.form,n)},s)})}pushInput(e,t,i,s,r,n){let a,o=Z(i)?i:this.targetComponentID(e.form,t,r),l=()=>this.putRef([e,e.form],"change",r),h,d=this.extractMeta(e.form);e instanceof HTMLButtonElement&&(d.submitter=e),e.getAttribute(this.binding("change"))?h=Ze(e.form,q({_target:r._target},d),[e.name]):h=Ze(e.form,q({_target:r._target},d)),c.isUploadInput(e)&&e.files&&e.files.length>0&&L.trackFiles(e,Array.from(e.files)),a=L.serializeUploads(e);let m={type:"form",event:s,value:h,uploads:a,cid:o};this.pushWithReply(l,"event",m,p=>{if(c.showError(e,this.liveSocket.binding(tt),this.liveSocket.binding(it)),c.isUploadInput(e)&&c.isAutoUpload(e)){if(L.filesAwaitingPreflight(e).length>0){let[f,g]=l();this.undoRefs(f,[e.form]),this.uploadFiles(e.form,t,f,o,v=>{n&&n(p),this.triggerAwaitingSubmit(e.form),this.undoRefs(f)})}}else n&&n(p)})}triggerAwaitingSubmit(e){let t=this.getScheduledSubmit(e);if(t){let[i,s,r,n]=t;this.cancelSubmit(e),n()}}getScheduledSubmit(e){return this.formSubmits.find(([t,i,s,r])=>t.isSameNode(e))}scheduleSubmit(e,t,i,s){if(this.getScheduledSubmit(e))return!0;this.formSubmits.push([e,t,i,s])}cancelSubmit(e){this.formSubmits=this.formSubmits.filter(([t,i,s])=>t.isSameNode(e)?(this.undoRefs(i),!1):!0)}disableForm(e,t={}){let i=d=>!(De(d,`${this.binding(rt)}=ignore`,d.form)||De(d,"data-phx-update=ignore",d.form)),s=d=>d.hasAttribute(this.binding(Pt)),r=d=>d.tagName=="BUTTON",n=d=>["INPUT","TEXTAREA","SELECT"].includes(d.tagName),a=Array.from(e.elements),o=a.filter(s),l=a.filter(r).filter(i),h=a.filter(n).filter(i);return l.forEach(d=>{d.setAttribute(pe,d.disabled),d.disabled=!0}),h.forEach(d=>{d.setAttribute(bt,d.readOnly),d.readOnly=!0,d.files&&(d.setAttribute(pe,d.disabled),d.disabled=!0)}),e.setAttribute(this.binding(ti),""),this.putRef([e].concat(o).concat(l).concat(h),"submit",t)}pushFormSubmit(e,t,i,s,r,n){let a=()=>this.disableForm(e,Kt(q({},r),{form:e,submitter:s})),o=this.targetComponentID(e,t);if(L.hasUploadsInProgress(e)){let[l,h]=a(),d=()=>this.pushFormSubmit(e,t,i,s,r,n);return this.scheduleSubmit(e,l,r,d)}else if(L.inputsAwaitingPreflight(e).length>0){let[l,h]=a(),d=()=>[l,h,r];this.uploadFiles(e,t,l,o,m=>{if(L.inputsAwaitingPreflight(e).length>0)return this.undoRefs(l);let p=this.extractMeta(e),f=Ze(e,q({submitter:s},p));this.pushWithReply(d,"event",{type:"form",event:i,value:f,cid:o},n)})}else if(!(e.hasAttribute(U)&&e.classList.contains("phx-submit-loading"))){let l=this.extractMeta(e),h=Ze(e,q({submitter:s},l));this.pushWithReply(a,"event",{type:"form",event:i,value:h,cid:o},n)}}uploadFiles(e,t,i,s,r){let n=this.joinCount,a=L.activeFileInputs(e),o=a.length;a.forEach(l=>{let h=new L(l,this,()=>{o--,o===0&&r()}),d=h.entries().map(p=>p.toPreflightPayload());if(d.length===0){o--;return}let m={ref:l.getAttribute(ee),entries:d,cid:this.targetComponentID(l.form,t)};this.log("upload",()=>["sending preflight request",m]),this.pushWithReply(null,"allow_upload",m,p=>{if(this.log("upload",()=>["got preflight response",p]),h.entries().forEach(f=>{p.entries&&!p.entries[f.ref]&&this.handleFailedEntryPreflight(f.ref,"failed preflight",h)}),p.error||Object.keys(p.entries).length===0)this.undoRefs(i),(p.error||[]).map(([g,v])=>{this.handleFailedEntryPreflight(g,v,h)});else{let f=g=>{this.channel.onError(()=>{this.joinCount===n&&g()})};h.initAdapterUpload(p,f,this.liveSocket)}})})}handleFailedEntryPreflight(e,t,i){if(i.isAutoUpload()){let s=i.entries().find(r=>r.ref===e.toString());s&&s.cancel()}else i.entries().map(s=>s.cancel());this.log("upload",()=>[`error for entry ${e}`,t])}dispatchUploads(e,t,i){let s=this.targetCtxElement(e)||this.el,r=c.findUploadInputs(s).filter(n=>n.name===t);r.length===0?j(`no live file inputs found matching the name "${t}"`):r.length>1?j(`duplicate live file inputs found matching the name "${t}"`):c.dispatchEvent(r[0],_i,{detail:{files:i}})}targetCtxElement(e){if(Z(e)){let[t]=c.findComponentNodeList(this.el,e);return t}else return e||null}pushFormRecovery(e,t,i,s){let r=this.binding("change"),n=t.getAttribute(this.binding("target"))||t,a=t.getAttribute(this.binding(ni))||t.getAttribute(this.binding("change")),o=Array.from(e.elements).filter(d=>c.isFormInput(d)&&d.name&&!d.hasAttribute(r));if(o.length===0)return;o.forEach(d=>d.hasAttribute(ee)&&L.clearFiles(d));let l=o.find(d=>d.type!=="hidden")||o[0],h=0;this.withinTargets(n,(d,m)=>{let p=this.targetComponentID(t,m);h++,d.pushInput(l,m,p,a,{_target:l.name},()=>{h--,h===0&&s()})},i,i)}pushLinkPatch(e,t,i){let s=this.liveSocket.setPendingLink(e),r=t?()=>this.putRef([t],"click"):null,n=()=>this.liveSocket.redirect(window.location.href),a=e.startsWith("/")?`${location.protocol}//${location.host}${e}`:e,o=this.pushWithReply(r,"live_patch",{url:a},l=>{this.liveSocket.requestDOMUpdate(()=>{l.link_redirect?this.liveSocket.replaceMain(e,null,i,s):(this.liveSocket.commitPendingLink(s)&&(this.href=e),this.applyPendingUpdates(),i&&i(s))})});o?o.receive("timeout",n):n()}getFormsForRecovery(){if(this.joinCount===0)return{};let e=this.binding("change");return c.all(this.el,`form[${e}]`).filter(t=>t.id).filter(t=>t.elements.length>0).filter(t=>t.getAttribute(this.binding(ni))!=="ignore").map(t=>t.cloneNode(!0)).reduce((t,i)=>(t[i.id]=i,t),{})}maybePushComponentsDestroyed(e){let t=e.filter(i=>c.findComponentNodeList(this.el,i).length===0);t.length>0&&(t.forEach(i=>this.rendered.resetRender(i)),this.pushWithReply(null,"cids_will_destroy",{cids:t},()=>{this.liveSocket.requestDOMUpdate(()=>{let i=t.filter(s=>c.findComponentNodeList(this.el,s).length===0);i.length>0&&this.pushWithReply(null,"cids_destroyed",{cids:i},s=>{this.rendered.pruneCIDs(s.cids)})})}))}ownsElement(e){let t=e.closest(be);return e.getAttribute(he)===this.id||t&&t.id===this.id||!t&&this.isDead}submitForm(e,t,i,s,r={}){c.putPrivate(e,st,!0);let n=this.liveSocket.binding(tt),a=this.liveSocket.binding(it),o=Array.from(e.elements);o.forEach(l=>c.putPrivate(l,st,!0)),this.liveSocket.blurActiveElement(this),this.pushFormSubmit(e,t,i,s,r,()=>{o.forEach(l=>c.showError(l,n,a)),this.liveSocket.restorePreviouslyActiveFocus()})}binding(e){return this.liveSocket.binding(e)}},Fi=class{constructor(e,t,i={}){if(this.unloaded=!1,!t||t.constructor.name==="Object")throw new Error(`
+ // ../deps/phoenix_html/priv/static/phoenix_html.js
+ (function() {
+ var PolyfillEvent = eventConstructor();
+ function eventConstructor() {
+ if (typeof window.CustomEvent === "function")
+ return window.CustomEvent;
+ function CustomEvent2(event, params) {
+ params = params || { bubbles: false, cancelable: false, detail: void 0 };
+ var evt = document.createEvent("CustomEvent");
+ evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
+ return evt;
+ }
+ CustomEvent2.prototype = window.Event.prototype;
+ return CustomEvent2;
+ }
+ function buildHiddenInput(name, value) {
+ var input = document.createElement("input");
+ input.type = "hidden";
+ input.name = name;
+ input.value = value;
+ return input;
+ }
+ function handleClick(element, targetModifierKey) {
+ var to = element.getAttribute("data-to"), method = buildHiddenInput("_method", element.getAttribute("data-method")), csrf = buildHiddenInput("_csrf_token", element.getAttribute("data-csrf")), form = document.createElement("form"), submit = document.createElement("input"), target = element.getAttribute("target");
+ form.method = element.getAttribute("data-method") === "get" ? "get" : "post";
+ form.action = to;
+ form.style.display = "none";
+ if (target)
+ form.target = target;
+ else if (targetModifierKey)
+ form.target = "_blank";
+ form.appendChild(csrf);
+ form.appendChild(method);
+ document.body.appendChild(form);
+ submit.type = "submit";
+ form.appendChild(submit);
+ submit.click();
+ }
+ window.addEventListener("click", function(e) {
+ var element = e.target;
+ if (e.defaultPrevented)
+ return;
+ while (element && element.getAttribute) {
+ var phoenixLinkEvent = new PolyfillEvent("phoenix.link.click", {
+ "bubbles": true,
+ "cancelable": true
+ });
+ if (!element.dispatchEvent(phoenixLinkEvent)) {
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ return false;
+ }
+ if (element.getAttribute("data-method") && element.getAttribute("data-to")) {
+ handleClick(element, e.metaKey || e.shiftKey);
+ e.preventDefault();
+ return false;
+ } else {
+ element = element.parentNode;
+ }
+ }
+ }, false);
+ window.addEventListener("phoenix.link.click", function(e) {
+ var message = e.target.getAttribute("data-confirm");
+ if (message && !window.confirm(message)) {
+ e.preventDefault();
+ }
+ }, false);
+ })();
+
+ // ../deps/phoenix/priv/static/phoenix.mjs
+ var closure = (value) => {
+ if (typeof value === "function") {
+ return value;
+ } else {
+ let closure22 = function() {
+ return value;
+ };
+ return closure22;
+ }
+ };
+ var globalSelf = typeof self !== "undefined" ? self : null;
+ var phxWindow = typeof window !== "undefined" ? window : null;
+ var global = globalSelf || phxWindow || global;
+ var DEFAULT_VSN = "2.0.0";
+ var SOCKET_STATES = { connecting: 0, open: 1, closing: 2, closed: 3 };
+ var DEFAULT_TIMEOUT = 1e4;
+ var WS_CLOSE_NORMAL = 1e3;
+ var CHANNEL_STATES = {
+ closed: "closed",
+ errored: "errored",
+ joined: "joined",
+ joining: "joining",
+ leaving: "leaving"
+ };
+ var CHANNEL_EVENTS = {
+ close: "phx_close",
+ error: "phx_error",
+ join: "phx_join",
+ reply: "phx_reply",
+ leave: "phx_leave"
+ };
+ var TRANSPORTS = {
+ longpoll: "longpoll",
+ websocket: "websocket"
+ };
+ var XHR_STATES = {
+ complete: 4
+ };
+ var Push = class {
+ constructor(channel, event, payload, timeout) {
+ this.channel = channel;
+ this.event = event;
+ this.payload = payload || function() {
+ return {};
+ };
+ this.receivedResp = null;
+ this.timeout = timeout;
+ this.timeoutTimer = null;
+ this.recHooks = [];
+ this.sent = false;
+ }
+ /**
+ *
+ * @param {number} timeout
+ */
+ resend(timeout) {
+ this.timeout = timeout;
+ this.reset();
+ this.send();
+ }
+ /**
+ *
+ */
+ send() {
+ if (this.hasReceived("timeout")) {
+ return;
+ }
+ this.startTimeout();
+ this.sent = true;
+ this.channel.socket.push({
+ topic: this.channel.topic,
+ event: this.event,
+ payload: this.payload(),
+ ref: this.ref,
+ join_ref: this.channel.joinRef()
+ });
+ }
+ /**
+ *
+ * @param {*} status
+ * @param {*} callback
+ */
+ receive(status, callback) {
+ if (this.hasReceived(status)) {
+ callback(this.receivedResp.response);
+ }
+ this.recHooks.push({ status, callback });
+ return this;
+ }
+ /**
+ * @private
+ */
+ reset() {
+ this.cancelRefEvent();
+ this.ref = null;
+ this.refEvent = null;
+ this.receivedResp = null;
+ this.sent = false;
+ }
+ /**
+ * @private
+ */
+ matchReceive({ status, response, _ref }) {
+ this.recHooks.filter((h) => h.status === status).forEach((h) => h.callback(response));
+ }
+ /**
+ * @private
+ */
+ cancelRefEvent() {
+ if (!this.refEvent) {
+ return;
+ }
+ this.channel.off(this.refEvent);
+ }
+ /**
+ * @private
+ */
+ cancelTimeout() {
+ clearTimeout(this.timeoutTimer);
+ this.timeoutTimer = null;
+ }
+ /**
+ * @private
+ */
+ startTimeout() {
+ if (this.timeoutTimer) {
+ this.cancelTimeout();
+ }
+ this.ref = this.channel.socket.makeRef();
+ this.refEvent = this.channel.replyEventName(this.ref);
+ this.channel.on(this.refEvent, (payload) => {
+ this.cancelRefEvent();
+ this.cancelTimeout();
+ this.receivedResp = payload;
+ this.matchReceive(payload);
+ });
+ this.timeoutTimer = setTimeout(() => {
+ this.trigger("timeout", {});
+ }, this.timeout);
+ }
+ /**
+ * @private
+ */
+ hasReceived(status) {
+ return this.receivedResp && this.receivedResp.status === status;
+ }
+ /**
+ * @private
+ */
+ trigger(status, response) {
+ this.channel.trigger(this.refEvent, { status, response });
+ }
+ };
+ var Timer = class {
+ constructor(callback, timerCalc) {
+ this.callback = callback;
+ this.timerCalc = timerCalc;
+ this.timer = null;
+ this.tries = 0;
+ }
+ reset() {
+ this.tries = 0;
+ clearTimeout(this.timer);
+ }
+ /**
+ * Cancels any previous scheduleTimeout and schedules callback
+ */
+ scheduleTimeout() {
+ clearTimeout(this.timer);
+ this.timer = setTimeout(() => {
+ this.tries = this.tries + 1;
+ this.callback();
+ }, this.timerCalc(this.tries + 1));
+ }
+ };
+ var Channel = class {
+ constructor(topic, params, socket) {
+ this.state = CHANNEL_STATES.closed;
+ this.topic = topic;
+ this.params = closure(params || {});
+ this.socket = socket;
+ this.bindings = [];
+ this.bindingRef = 0;
+ this.timeout = this.socket.timeout;
+ this.joinedOnce = false;
+ this.joinPush = new Push(this, CHANNEL_EVENTS.join, this.params, this.timeout);
+ this.pushBuffer = [];
+ this.stateChangeRefs = [];
+ this.rejoinTimer = new Timer(() => {
+ if (this.socket.isConnected()) {
+ this.rejoin();
+ }
+ }, this.socket.rejoinAfterMs);
+ this.stateChangeRefs.push(this.socket.onError(() => this.rejoinTimer.reset()));
+ this.stateChangeRefs.push(
+ this.socket.onOpen(() => {
+ this.rejoinTimer.reset();
+ if (this.isErrored()) {
+ this.rejoin();
+ }
+ })
+ );
+ this.joinPush.receive("ok", () => {
+ this.state = CHANNEL_STATES.joined;
+ this.rejoinTimer.reset();
+ this.pushBuffer.forEach((pushEvent) => pushEvent.send());
+ this.pushBuffer = [];
+ });
+ this.joinPush.receive("error", () => {
+ this.state = CHANNEL_STATES.errored;
+ if (this.socket.isConnected()) {
+ this.rejoinTimer.scheduleTimeout();
+ }
+ });
+ this.onClose(() => {
+ this.rejoinTimer.reset();
+ if (this.socket.hasLogger())
+ this.socket.log("channel", `close ${this.topic} ${this.joinRef()}`);
+ this.state = CHANNEL_STATES.closed;
+ this.socket.remove(this);
+ });
+ this.onError((reason) => {
+ if (this.socket.hasLogger())
+ this.socket.log("channel", `error ${this.topic}`, reason);
+ if (this.isJoining()) {
+ this.joinPush.reset();
+ }
+ this.state = CHANNEL_STATES.errored;
+ if (this.socket.isConnected()) {
+ this.rejoinTimer.scheduleTimeout();
+ }
+ });
+ this.joinPush.receive("timeout", () => {
+ if (this.socket.hasLogger())
+ this.socket.log("channel", `timeout ${this.topic} (${this.joinRef()})`, this.joinPush.timeout);
+ let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), this.timeout);
+ leavePush.send();
+ this.state = CHANNEL_STATES.errored;
+ this.joinPush.reset();
+ if (this.socket.isConnected()) {
+ this.rejoinTimer.scheduleTimeout();
+ }
+ });
+ this.on(CHANNEL_EVENTS.reply, (payload, ref) => {
+ this.trigger(this.replyEventName(ref), payload);
+ });
+ }
+ /**
+ * Join the channel
+ * @param {integer} timeout
+ * @returns {Push}
+ */
+ join(timeout = this.timeout) {
+ if (this.joinedOnce) {
+ throw new Error("tried to join multiple times. 'join' can only be called a single time per channel instance");
+ } else {
+ this.timeout = timeout;
+ this.joinedOnce = true;
+ this.rejoin();
+ return this.joinPush;
+ }
+ }
+ /**
+ * Hook into channel close
+ * @param {Function} callback
+ */
+ onClose(callback) {
+ this.on(CHANNEL_EVENTS.close, callback);
+ }
+ /**
+ * Hook into channel errors
+ * @param {Function} callback
+ */
+ onError(callback) {
+ return this.on(CHANNEL_EVENTS.error, (reason) => callback(reason));
+ }
+ /**
+ * Subscribes on channel events
+ *
+ * Subscription returns a ref counter, which can be used later to
+ * unsubscribe the exact event listener
+ *
+ * @example
+ * const ref1 = channel.on("event", do_stuff)
+ * const ref2 = channel.on("event", do_other_stuff)
+ * channel.off("event", ref1)
+ * // Since unsubscription, do_stuff won't fire,
+ * // while do_other_stuff will keep firing on the "event"
+ *
+ * @param {string} event
+ * @param {Function} callback
+ * @returns {integer} ref
+ */
+ on(event, callback) {
+ let ref = this.bindingRef++;
+ this.bindings.push({ event, ref, callback });
+ return ref;
+ }
+ /**
+ * Unsubscribes off of channel events
+ *
+ * Use the ref returned from a channel.on() to unsubscribe one
+ * handler, or pass nothing for the ref to unsubscribe all
+ * handlers for the given event.
+ *
+ * @example
+ * // Unsubscribe the do_stuff handler
+ * const ref1 = channel.on("event", do_stuff)
+ * channel.off("event", ref1)
+ *
+ * // Unsubscribe all handlers from event
+ * channel.off("event")
+ *
+ * @param {string} event
+ * @param {integer} ref
+ */
+ off(event, ref) {
+ this.bindings = this.bindings.filter((bind) => {
+ return !(bind.event === event && (typeof ref === "undefined" || ref === bind.ref));
+ });
+ }
+ /**
+ * @private
+ */
+ canPush() {
+ return this.socket.isConnected() && this.isJoined();
+ }
+ /**
+ * Sends a message `event` to phoenix with the payload `payload`.
+ * Phoenix receives this in the `handle_in(event, payload, socket)`
+ * function. if phoenix replies or it times out (default 10000ms),
+ * then optionally the reply can be received.
+ *
+ * @example
+ * channel.push("event")
+ * .receive("ok", payload => console.log("phoenix replied:", payload))
+ * .receive("error", err => console.log("phoenix errored", err))
+ * .receive("timeout", () => console.log("timed out pushing"))
+ * @param {string} event
+ * @param {Object} payload
+ * @param {number} [timeout]
+ * @returns {Push}
+ */
+ push(event, payload, timeout = this.timeout) {
+ payload = payload || {};
+ if (!this.joinedOnce) {
+ throw new Error(`tried to push '${event}' to '${this.topic}' before joining. Use channel.join() before pushing events`);
+ }
+ let pushEvent = new Push(this, event, function() {
+ return payload;
+ }, timeout);
+ if (this.canPush()) {
+ pushEvent.send();
+ } else {
+ pushEvent.startTimeout();
+ this.pushBuffer.push(pushEvent);
+ }
+ return pushEvent;
+ }
+ /** Leaves the channel
+ *
+ * Unsubscribes from server events, and
+ * instructs channel to terminate on server
+ *
+ * Triggers onClose() hooks
+ *
+ * To receive leave acknowledgements, use the `receive`
+ * hook to bind to the server ack, ie:
+ *
+ * @example
+ * channel.leave().receive("ok", () => alert("left!") )
+ *
+ * @param {integer} timeout
+ * @returns {Push}
+ */
+ leave(timeout = this.timeout) {
+ this.rejoinTimer.reset();
+ this.joinPush.cancelTimeout();
+ this.state = CHANNEL_STATES.leaving;
+ let onClose = () => {
+ if (this.socket.hasLogger())
+ this.socket.log("channel", `leave ${this.topic}`);
+ this.trigger(CHANNEL_EVENTS.close, "leave");
+ };
+ let leavePush = new Push(this, CHANNEL_EVENTS.leave, closure({}), timeout);
+ leavePush.receive("ok", () => onClose()).receive("timeout", () => onClose());
+ leavePush.send();
+ if (!this.canPush()) {
+ leavePush.trigger("ok", {});
+ }
+ return leavePush;
+ }
+ /**
+ * Overridable message hook
+ *
+ * Receives all events for specialized message handling
+ * before dispatching to the channel callbacks.
+ *
+ * Must return the payload, modified or unmodified
+ * @param {string} event
+ * @param {Object} payload
+ * @param {integer} ref
+ * @returns {Object}
+ */
+ onMessage(_event, payload, _ref) {
+ return payload;
+ }
+ /**
+ * @private
+ */
+ isMember(topic, event, payload, joinRef) {
+ if (this.topic !== topic) {
+ return false;
+ }
+ if (joinRef && joinRef !== this.joinRef()) {
+ if (this.socket.hasLogger())
+ this.socket.log("channel", "dropping outdated message", { topic, event, payload, joinRef });
+ return false;
+ } else {
+ return true;
+ }
+ }
+ /**
+ * @private
+ */
+ joinRef() {
+ return this.joinPush.ref;
+ }
+ /**
+ * @private
+ */
+ rejoin(timeout = this.timeout) {
+ if (this.isLeaving()) {
+ return;
+ }
+ this.socket.leaveOpenTopic(this.topic);
+ this.state = CHANNEL_STATES.joining;
+ this.joinPush.resend(timeout);
+ }
+ /**
+ * @private
+ */
+ trigger(event, payload, ref, joinRef) {
+ let handledPayload = this.onMessage(event, payload, ref, joinRef);
+ if (payload && !handledPayload) {
+ throw new Error("channel onMessage callbacks must return the payload, modified or unmodified");
+ }
+ let eventBindings = this.bindings.filter((bind) => bind.event === event);
+ for (let i = 0; i < eventBindings.length; i++) {
+ let bind = eventBindings[i];
+ bind.callback(handledPayload, ref, joinRef || this.joinRef());
+ }
+ }
+ /**
+ * @private
+ */
+ replyEventName(ref) {
+ return `chan_reply_${ref}`;
+ }
+ /**
+ * @private
+ */
+ isClosed() {
+ return this.state === CHANNEL_STATES.closed;
+ }
+ /**
+ * @private
+ */
+ isErrored() {
+ return this.state === CHANNEL_STATES.errored;
+ }
+ /**
+ * @private
+ */
+ isJoined() {
+ return this.state === CHANNEL_STATES.joined;
+ }
+ /**
+ * @private
+ */
+ isJoining() {
+ return this.state === CHANNEL_STATES.joining;
+ }
+ /**
+ * @private
+ */
+ isLeaving() {
+ return this.state === CHANNEL_STATES.leaving;
+ }
+ };
+ var Ajax = class {
+ static request(method, endPoint, accept, body, timeout, ontimeout, callback) {
+ if (global.XDomainRequest) {
+ let req = new global.XDomainRequest();
+ return this.xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback);
+ } else {
+ let req = new global.XMLHttpRequest();
+ return this.xhrRequest(req, method, endPoint, accept, body, timeout, ontimeout, callback);
+ }
+ }
+ static xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback) {
+ req.timeout = timeout;
+ req.open(method, endPoint);
+ req.onload = () => {
+ let response = this.parseJSON(req.responseText);
+ callback && callback(response);
+ };
+ if (ontimeout) {
+ req.ontimeout = ontimeout;
+ }
+ req.onprogress = () => {
+ };
+ req.send(body);
+ return req;
+ }
+ static xhrRequest(req, method, endPoint, accept, body, timeout, ontimeout, callback) {
+ req.open(method, endPoint, true);
+ req.timeout = timeout;
+ req.setRequestHeader("Content-Type", accept);
+ req.onerror = () => callback && callback(null);
+ req.onreadystatechange = () => {
+ if (req.readyState === XHR_STATES.complete && callback) {
+ let response = this.parseJSON(req.responseText);
+ callback(response);
+ }
+ };
+ if (ontimeout) {
+ req.ontimeout = ontimeout;
+ }
+ req.send(body);
+ return req;
+ }
+ static parseJSON(resp) {
+ if (!resp || resp === "") {
+ return null;
+ }
+ try {
+ return JSON.parse(resp);
+ } catch (e) {
+ console && console.log("failed to parse JSON response", resp);
+ return null;
+ }
+ }
+ static serialize(obj, parentKey) {
+ let queryStr = [];
+ for (var key in obj) {
+ if (!Object.prototype.hasOwnProperty.call(obj, key)) {
+ continue;
+ }
+ let paramKey = parentKey ? `${parentKey}[${key}]` : key;
+ let paramVal = obj[key];
+ if (typeof paramVal === "object") {
+ queryStr.push(this.serialize(paramVal, paramKey));
+ } else {
+ queryStr.push(encodeURIComponent(paramKey) + "=" + encodeURIComponent(paramVal));
+ }
+ }
+ return queryStr.join("&");
+ }
+ static appendParams(url, params) {
+ if (Object.keys(params).length === 0) {
+ return url;
+ }
+ let prefix = url.match(/\?/) ? "&" : "?";
+ return `${url}${prefix}${this.serialize(params)}`;
+ }
+ };
+ var arrayBufferToBase64 = (buffer) => {
+ let binary = "";
+ let bytes = new Uint8Array(buffer);
+ let len = bytes.byteLength;
+ for (let i = 0; i < len; i++) {
+ binary += String.fromCharCode(bytes[i]);
+ }
+ return btoa(binary);
+ };
+ var LongPoll = class {
+ constructor(endPoint) {
+ this.endPoint = null;
+ this.token = null;
+ this.skipHeartbeat = true;
+ this.reqs = /* @__PURE__ */ new Set();
+ this.awaitingBatchAck = false;
+ this.currentBatch = null;
+ this.currentBatchTimer = null;
+ this.batchBuffer = [];
+ this.onopen = function() {
+ };
+ this.onerror = function() {
+ };
+ this.onmessage = function() {
+ };
+ this.onclose = function() {
+ };
+ this.pollEndpoint = this.normalizeEndpoint(endPoint);
+ this.readyState = SOCKET_STATES.connecting;
+ setTimeout(() => this.poll(), 0);
+ }
+ normalizeEndpoint(endPoint) {
+ return endPoint.replace("ws://", "http://").replace("wss://", "https://").replace(new RegExp("(.*)/" + TRANSPORTS.websocket), "$1/" + TRANSPORTS.longpoll);
+ }
+ endpointURL() {
+ return Ajax.appendParams(this.pollEndpoint, { token: this.token });
+ }
+ closeAndRetry(code, reason, wasClean) {
+ this.close(code, reason, wasClean);
+ this.readyState = SOCKET_STATES.connecting;
+ }
+ ontimeout() {
+ this.onerror("timeout");
+ this.closeAndRetry(1005, "timeout", false);
+ }
+ isActive() {
+ return this.readyState === SOCKET_STATES.open || this.readyState === SOCKET_STATES.connecting;
+ }
+ poll() {
+ this.ajax("GET", "application/json", null, () => this.ontimeout(), (resp) => {
+ if (resp) {
+ var { status, token, messages } = resp;
+ this.token = token;
+ } else {
+ status = 0;
+ }
+ switch (status) {
+ case 200:
+ messages.forEach((msg) => {
+ setTimeout(() => this.onmessage({ data: msg }), 0);
+ });
+ this.poll();
+ break;
+ case 204:
+ this.poll();
+ break;
+ case 410:
+ this.readyState = SOCKET_STATES.open;
+ this.onopen({});
+ this.poll();
+ break;
+ case 403:
+ this.onerror(403);
+ this.close(1008, "forbidden", false);
+ break;
+ case 0:
+ case 500:
+ this.onerror(500);
+ this.closeAndRetry(1011, "internal server error", 500);
+ break;
+ default:
+ throw new Error(`unhandled poll status ${status}`);
+ }
+ });
+ }
+ // we collect all pushes within the current event loop by
+ // setTimeout 0, which optimizes back-to-back procedural
+ // pushes against an empty buffer
+ send(body) {
+ if (typeof body !== "string") {
+ body = arrayBufferToBase64(body);
+ }
+ if (this.currentBatch) {
+ this.currentBatch.push(body);
+ } else if (this.awaitingBatchAck) {
+ this.batchBuffer.push(body);
+ } else {
+ this.currentBatch = [body];
+ this.currentBatchTimer = setTimeout(() => {
+ this.batchSend(this.currentBatch);
+ this.currentBatch = null;
+ }, 0);
+ }
+ }
+ batchSend(messages) {
+ this.awaitingBatchAck = true;
+ this.ajax("POST", "application/x-ndjson", messages.join("\n"), () => this.onerror("timeout"), (resp) => {
+ this.awaitingBatchAck = false;
+ if (!resp || resp.status !== 200) {
+ this.onerror(resp && resp.status);
+ this.closeAndRetry(1011, "internal server error", false);
+ } else if (this.batchBuffer.length > 0) {
+ this.batchSend(this.batchBuffer);
+ this.batchBuffer = [];
+ }
+ });
+ }
+ close(code, reason, wasClean) {
+ for (let req of this.reqs) {
+ req.abort();
+ }
+ this.readyState = SOCKET_STATES.closed;
+ let opts = Object.assign({ code: 1e3, reason: void 0, wasClean: true }, { code, reason, wasClean });
+ this.batchBuffer = [];
+ clearTimeout(this.currentBatchTimer);
+ this.currentBatchTimer = null;
+ if (typeof CloseEvent !== "undefined") {
+ this.onclose(new CloseEvent("close", opts));
+ } else {
+ this.onclose(opts);
+ }
+ }
+ ajax(method, contentType, body, onCallerTimeout, callback) {
+ let req;
+ let ontimeout = () => {
+ this.reqs.delete(req);
+ onCallerTimeout();
+ };
+ req = Ajax.request(method, this.endpointURL(), contentType, body, this.timeout, ontimeout, (resp) => {
+ this.reqs.delete(req);
+ if (this.isActive()) {
+ callback(resp);
+ }
+ });
+ this.reqs.add(req);
+ }
+ };
+ var serializer_default = {
+ HEADER_LENGTH: 1,
+ META_LENGTH: 4,
+ KINDS: { push: 0, reply: 1, broadcast: 2 },
+ encode(msg, callback) {
+ if (msg.payload.constructor === ArrayBuffer) {
+ return callback(this.binaryEncode(msg));
+ } else {
+ let payload = [msg.join_ref, msg.ref, msg.topic, msg.event, msg.payload];
+ return callback(JSON.stringify(payload));
+ }
+ },
+ decode(rawPayload, callback) {
+ if (rawPayload.constructor === ArrayBuffer) {
+ return callback(this.binaryDecode(rawPayload));
+ } else {
+ let [join_ref, ref, topic, event, payload] = JSON.parse(rawPayload);
+ return callback({ join_ref, ref, topic, event, payload });
+ }
+ },
+ // private
+ binaryEncode(message) {
+ let { join_ref, ref, event, topic, payload } = message;
+ let metaLength = this.META_LENGTH + join_ref.length + ref.length + topic.length + event.length;
+ let header = new ArrayBuffer(this.HEADER_LENGTH + metaLength);
+ let view = new DataView(header);
+ let offset = 0;
+ view.setUint8(offset++, this.KINDS.push);
+ view.setUint8(offset++, join_ref.length);
+ view.setUint8(offset++, ref.length);
+ view.setUint8(offset++, topic.length);
+ view.setUint8(offset++, event.length);
+ Array.from(join_ref, (char) => view.setUint8(offset++, char.charCodeAt(0)));
+ Array.from(ref, (char) => view.setUint8(offset++, char.charCodeAt(0)));
+ Array.from(topic, (char) => view.setUint8(offset++, char.charCodeAt(0)));
+ Array.from(event, (char) => view.setUint8(offset++, char.charCodeAt(0)));
+ var combined = new Uint8Array(header.byteLength + payload.byteLength);
+ combined.set(new Uint8Array(header), 0);
+ combined.set(new Uint8Array(payload), header.byteLength);
+ return combined.buffer;
+ },
+ binaryDecode(buffer) {
+ let view = new DataView(buffer);
+ let kind = view.getUint8(0);
+ let decoder = new TextDecoder();
+ switch (kind) {
+ case this.KINDS.push:
+ return this.decodePush(buffer, view, decoder);
+ case this.KINDS.reply:
+ return this.decodeReply(buffer, view, decoder);
+ case this.KINDS.broadcast:
+ return this.decodeBroadcast(buffer, view, decoder);
+ }
+ },
+ decodePush(buffer, view, decoder) {
+ let joinRefSize = view.getUint8(1);
+ let topicSize = view.getUint8(2);
+ let eventSize = view.getUint8(3);
+ let offset = this.HEADER_LENGTH + this.META_LENGTH - 1;
+ let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize));
+ offset = offset + joinRefSize;
+ let topic = decoder.decode(buffer.slice(offset, offset + topicSize));
+ offset = offset + topicSize;
+ let event = decoder.decode(buffer.slice(offset, offset + eventSize));
+ offset = offset + eventSize;
+ let data2 = buffer.slice(offset, buffer.byteLength);
+ return { join_ref: joinRef, ref: null, topic, event, payload: data2 };
+ },
+ decodeReply(buffer, view, decoder) {
+ let joinRefSize = view.getUint8(1);
+ let refSize = view.getUint8(2);
+ let topicSize = view.getUint8(3);
+ let eventSize = view.getUint8(4);
+ let offset = this.HEADER_LENGTH + this.META_LENGTH;
+ let joinRef = decoder.decode(buffer.slice(offset, offset + joinRefSize));
+ offset = offset + joinRefSize;
+ let ref = decoder.decode(buffer.slice(offset, offset + refSize));
+ offset = offset + refSize;
+ let topic = decoder.decode(buffer.slice(offset, offset + topicSize));
+ offset = offset + topicSize;
+ let event = decoder.decode(buffer.slice(offset, offset + eventSize));
+ offset = offset + eventSize;
+ let data2 = buffer.slice(offset, buffer.byteLength);
+ let payload = { status: event, response: data2 };
+ return { join_ref: joinRef, ref, topic, event: CHANNEL_EVENTS.reply, payload };
+ },
+ decodeBroadcast(buffer, view, decoder) {
+ let topicSize = view.getUint8(1);
+ let eventSize = view.getUint8(2);
+ let offset = this.HEADER_LENGTH + 2;
+ let topic = decoder.decode(buffer.slice(offset, offset + topicSize));
+ offset = offset + topicSize;
+ let event = decoder.decode(buffer.slice(offset, offset + eventSize));
+ offset = offset + eventSize;
+ let data2 = buffer.slice(offset, buffer.byteLength);
+ return { join_ref: null, ref: null, topic, event, payload: data2 };
+ }
+ };
+ var Socket = class {
+ constructor(endPoint, opts = {}) {
+ this.stateChangeCallbacks = { open: [], close: [], error: [], message: [] };
+ this.channels = [];
+ this.sendBuffer = [];
+ this.ref = 0;
+ this.timeout = opts.timeout || DEFAULT_TIMEOUT;
+ this.transport = opts.transport || global.WebSocket || LongPoll;
+ this.primaryPassedHealthCheck = false;
+ this.longPollFallbackMs = opts.longPollFallbackMs;
+ this.fallbackTimer = null;
+ this.sessionStore = opts.sessionStorage || global && global.sessionStorage;
+ this.establishedConnections = 0;
+ this.defaultEncoder = serializer_default.encode.bind(serializer_default);
+ this.defaultDecoder = serializer_default.decode.bind(serializer_default);
+ this.closeWasClean = false;
+ this.binaryType = opts.binaryType || "arraybuffer";
+ this.connectClock = 1;
+ if (this.transport !== LongPoll) {
+ this.encode = opts.encode || this.defaultEncoder;
+ this.decode = opts.decode || this.defaultDecoder;
+ } else {
+ this.encode = this.defaultEncoder;
+ this.decode = this.defaultDecoder;
+ }
+ let awaitingConnectionOnPageShow = null;
+ if (phxWindow && phxWindow.addEventListener) {
+ phxWindow.addEventListener("pagehide", (_e) => {
+ if (this.conn) {
+ this.disconnect();
+ awaitingConnectionOnPageShow = this.connectClock;
+ }
+ });
+ phxWindow.addEventListener("pageshow", (_e) => {
+ if (awaitingConnectionOnPageShow === this.connectClock) {
+ awaitingConnectionOnPageShow = null;
+ this.connect();
+ }
+ });
+ }
+ this.heartbeatIntervalMs = opts.heartbeatIntervalMs || 3e4;
+ this.rejoinAfterMs = (tries) => {
+ if (opts.rejoinAfterMs) {
+ return opts.rejoinAfterMs(tries);
+ } else {
+ return [1e3, 2e3, 5e3][tries - 1] || 1e4;
+ }
+ };
+ this.reconnectAfterMs = (tries) => {
+ if (opts.reconnectAfterMs) {
+ return opts.reconnectAfterMs(tries);
+ } else {
+ return [10, 50, 100, 150, 200, 250, 500, 1e3, 2e3][tries - 1] || 5e3;
+ }
+ };
+ this.logger = opts.logger || null;
+ if (!this.logger && opts.debug) {
+ this.logger = (kind, msg, data2) => {
+ console.log(`${kind}: ${msg}`, data2);
+ };
+ }
+ this.longpollerTimeout = opts.longpollerTimeout || 2e4;
+ this.params = closure(opts.params || {});
+ this.endPoint = `${endPoint}/${TRANSPORTS.websocket}`;
+ this.vsn = opts.vsn || DEFAULT_VSN;
+ this.heartbeatTimeoutTimer = null;
+ this.heartbeatTimer = null;
+ this.pendingHeartbeatRef = null;
+ this.reconnectTimer = new Timer(() => {
+ this.teardown(() => this.connect());
+ }, this.reconnectAfterMs);
+ }
+ /**
+ * Returns the LongPoll transport reference
+ */
+ getLongPollTransport() {
+ return LongPoll;
+ }
+ /**
+ * Disconnects and replaces the active transport
+ *
+ * @param {Function} newTransport - The new transport class to instantiate
+ *
+ */
+ replaceTransport(newTransport) {
+ this.connectClock++;
+ this.closeWasClean = true;
+ clearTimeout(this.fallbackTimer);
+ this.reconnectTimer.reset();
+ if (this.conn) {
+ this.conn.close();
+ this.conn = null;
+ }
+ this.transport = newTransport;
+ }
+ /**
+ * Returns the socket protocol
+ *
+ * @returns {string}
+ */
+ protocol() {
+ return location.protocol.match(/^https/) ? "wss" : "ws";
+ }
+ /**
+ * The fully qualified socket url
+ *
+ * @returns {string}
+ */
+ endPointURL() {
+ let uri = Ajax.appendParams(
+ Ajax.appendParams(this.endPoint, this.params()),
+ { vsn: this.vsn }
+ );
+ if (uri.charAt(0) !== "/") {
+ return uri;
+ }
+ if (uri.charAt(1) === "/") {
+ return `${this.protocol()}:${uri}`;
+ }
+ return `${this.protocol()}://${location.host}${uri}`;
+ }
+ /**
+ * Disconnects the socket
+ *
+ * See https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes for valid status codes.
+ *
+ * @param {Function} callback - Optional callback which is called after socket is disconnected.
+ * @param {integer} code - A status code for disconnection (Optional).
+ * @param {string} reason - A textual description of the reason to disconnect. (Optional)
+ */
+ disconnect(callback, code, reason) {
+ this.connectClock++;
+ this.closeWasClean = true;
+ clearTimeout(this.fallbackTimer);
+ this.reconnectTimer.reset();
+ this.teardown(callback, code, reason);
+ }
+ /**
+ *
+ * @param {Object} params - The params to send when connecting, for example `{user_id: userToken}`
+ *
+ * Passing params to connect is deprecated; pass them in the Socket constructor instead:
+ * `new Socket("/socket", {params: {user_id: userToken}})`.
+ */
+ connect(params) {
+ if (params) {
+ console && console.log("passing params to connect is deprecated. Instead pass :params to the Socket constructor");
+ this.params = closure(params);
+ }
+ if (this.conn) {
+ return;
+ }
+ if (this.longPollFallbackMs && this.transport !== LongPoll) {
+ this.connectWithFallback(LongPoll, this.longPollFallbackMs);
+ } else {
+ this.transportConnect();
+ }
+ }
+ /**
+ * Logs the message. Override `this.logger` for specialized logging. noops by default
+ * @param {string} kind
+ * @param {string} msg
+ * @param {Object} data
+ */
+ log(kind, msg, data2) {
+ this.logger && this.logger(kind, msg, data2);
+ }
+ /**
+ * Returns true if a logger has been set on this socket.
+ */
+ hasLogger() {
+ return this.logger !== null;
+ }
+ /**
+ * Registers callbacks for connection open events
+ *
+ * @example socket.onOpen(function(){ console.info("the socket was opened") })
+ *
+ * @param {Function} callback
+ */
+ onOpen(callback) {
+ let ref = this.makeRef();
+ this.stateChangeCallbacks.open.push([ref, callback]);
+ return ref;
+ }
+ /**
+ * Registers callbacks for connection close events
+ * @param {Function} callback
+ */
+ onClose(callback) {
+ let ref = this.makeRef();
+ this.stateChangeCallbacks.close.push([ref, callback]);
+ return ref;
+ }
+ /**
+ * Registers callbacks for connection error events
+ *
+ * @example socket.onError(function(error){ alert("An error occurred") })
+ *
+ * @param {Function} callback
+ */
+ onError(callback) {
+ let ref = this.makeRef();
+ this.stateChangeCallbacks.error.push([ref, callback]);
+ return ref;
+ }
+ /**
+ * Registers callbacks for connection message events
+ * @param {Function} callback
+ */
+ onMessage(callback) {
+ let ref = this.makeRef();
+ this.stateChangeCallbacks.message.push([ref, callback]);
+ return ref;
+ }
+ /**
+ * Pings the server and invokes the callback with the RTT in milliseconds
+ * @param {Function} callback
+ *
+ * Returns true if the ping was pushed or false if unable to be pushed.
+ */
+ ping(callback) {
+ if (!this.isConnected()) {
+ return false;
+ }
+ let ref = this.makeRef();
+ let startTime = Date.now();
+ this.push({ topic: "phoenix", event: "heartbeat", payload: {}, ref });
+ let onMsgRef = this.onMessage((msg) => {
+ if (msg.ref === ref) {
+ this.off([onMsgRef]);
+ callback(Date.now() - startTime);
+ }
+ });
+ return true;
+ }
+ /**
+ * @private
+ */
+ transportConnect() {
+ this.connectClock++;
+ this.closeWasClean = false;
+ this.conn = new this.transport(this.endPointURL());
+ this.conn.binaryType = this.binaryType;
+ this.conn.timeout = this.longpollerTimeout;
+ this.conn.onopen = () => this.onConnOpen();
+ this.conn.onerror = (error) => this.onConnError(error);
+ this.conn.onmessage = (event) => this.onConnMessage(event);
+ this.conn.onclose = (event) => this.onConnClose(event);
+ }
+ getSession(key) {
+ return this.sessionStore && this.sessionStore.getItem(key);
+ }
+ storeSession(key, val) {
+ this.sessionStore && this.sessionStore.setItem(key, val);
+ }
+ connectWithFallback(fallbackTransport, fallbackThreshold = 2500) {
+ clearTimeout(this.fallbackTimer);
+ let established = false;
+ let primaryTransport = true;
+ let openRef, errorRef;
+ let fallback = (reason) => {
+ this.log("transport", `falling back to ${fallbackTransport.name}...`, reason);
+ this.off([openRef, errorRef]);
+ primaryTransport = false;
+ this.replaceTransport(fallbackTransport);
+ this.transportConnect();
+ };
+ if (this.getSession(`phx:fallback:${fallbackTransport.name}`)) {
+ return fallback("memorized");
+ }
+ this.fallbackTimer = setTimeout(fallback, fallbackThreshold);
+ errorRef = this.onError((reason) => {
+ this.log("transport", "error", reason);
+ if (primaryTransport && !established) {
+ clearTimeout(this.fallbackTimer);
+ fallback(reason);
+ }
+ });
+ this.onOpen(() => {
+ established = true;
+ if (!primaryTransport) {
+ if (!this.primaryPassedHealthCheck) {
+ this.storeSession(`phx:fallback:${fallbackTransport.name}`, "true");
+ }
+ return this.log("transport", `established ${fallbackTransport.name} fallback`);
+ }
+ clearTimeout(this.fallbackTimer);
+ this.fallbackTimer = setTimeout(fallback, fallbackThreshold);
+ this.ping((rtt) => {
+ this.log("transport", "connected to primary after", rtt);
+ this.primaryPassedHealthCheck = true;
+ clearTimeout(this.fallbackTimer);
+ });
+ });
+ this.transportConnect();
+ }
+ clearHeartbeats() {
+ clearTimeout(this.heartbeatTimer);
+ clearTimeout(this.heartbeatTimeoutTimer);
+ }
+ onConnOpen() {
+ if (this.hasLogger())
+ this.log("transport", `${this.transport.name} connected to ${this.endPointURL()}`);
+ this.closeWasClean = false;
+ this.establishedConnections++;
+ this.flushSendBuffer();
+ this.reconnectTimer.reset();
+ this.resetHeartbeat();
+ this.stateChangeCallbacks.open.forEach(([, callback]) => callback());
+ }
+ /**
+ * @private
+ */
+ heartbeatTimeout() {
+ if (this.pendingHeartbeatRef) {
+ this.pendingHeartbeatRef = null;
+ if (this.hasLogger()) {
+ this.log("transport", "heartbeat timeout. Attempting to re-establish connection");
+ }
+ this.triggerChanError();
+ this.closeWasClean = false;
+ this.teardown(() => this.reconnectTimer.scheduleTimeout(), WS_CLOSE_NORMAL, "heartbeat timeout");
+ }
+ }
+ resetHeartbeat() {
+ if (this.conn && this.conn.skipHeartbeat) {
+ return;
+ }
+ this.pendingHeartbeatRef = null;
+ this.clearHeartbeats();
+ this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs);
+ }
+ teardown(callback, code, reason) {
+ if (!this.conn) {
+ return callback && callback();
+ }
+ this.waitForBufferDone(() => {
+ if (this.conn) {
+ if (code) {
+ this.conn.close(code, reason || "");
+ } else {
+ this.conn.close();
+ }
+ }
+ this.waitForSocketClosed(() => {
+ if (this.conn) {
+ this.conn.onopen = function() {
+ };
+ this.conn.onerror = function() {
+ };
+ this.conn.onmessage = function() {
+ };
+ this.conn.onclose = function() {
+ };
+ this.conn = null;
+ }
+ callback && callback();
+ });
+ });
+ }
+ waitForBufferDone(callback, tries = 1) {
+ if (tries === 5 || !this.conn || !this.conn.bufferedAmount) {
+ callback();
+ return;
+ }
+ setTimeout(() => {
+ this.waitForBufferDone(callback, tries + 1);
+ }, 150 * tries);
+ }
+ waitForSocketClosed(callback, tries = 1) {
+ if (tries === 5 || !this.conn || this.conn.readyState === SOCKET_STATES.closed) {
+ callback();
+ return;
+ }
+ setTimeout(() => {
+ this.waitForSocketClosed(callback, tries + 1);
+ }, 150 * tries);
+ }
+ onConnClose(event) {
+ let closeCode = event && event.code;
+ if (this.hasLogger())
+ this.log("transport", "close", event);
+ this.triggerChanError();
+ this.clearHeartbeats();
+ if (!this.closeWasClean && closeCode !== 1e3) {
+ this.reconnectTimer.scheduleTimeout();
+ }
+ this.stateChangeCallbacks.close.forEach(([, callback]) => callback(event));
+ }
+ /**
+ * @private
+ */
+ onConnError(error) {
+ if (this.hasLogger())
+ this.log("transport", error);
+ let transportBefore = this.transport;
+ let establishedBefore = this.establishedConnections;
+ this.stateChangeCallbacks.error.forEach(([, callback]) => {
+ callback(error, transportBefore, establishedBefore);
+ });
+ if (transportBefore === this.transport || establishedBefore > 0) {
+ this.triggerChanError();
+ }
+ }
+ /**
+ * @private
+ */
+ triggerChanError() {
+ this.channels.forEach((channel) => {
+ if (!(channel.isErrored() || channel.isLeaving() || channel.isClosed())) {
+ channel.trigger(CHANNEL_EVENTS.error);
+ }
+ });
+ }
+ /**
+ * @returns {string}
+ */
+ connectionState() {
+ switch (this.conn && this.conn.readyState) {
+ case SOCKET_STATES.connecting:
+ return "connecting";
+ case SOCKET_STATES.open:
+ return "open";
+ case SOCKET_STATES.closing:
+ return "closing";
+ default:
+ return "closed";
+ }
+ }
+ /**
+ * @returns {boolean}
+ */
+ isConnected() {
+ return this.connectionState() === "open";
+ }
+ /**
+ * @private
+ *
+ * @param {Channel}
+ */
+ remove(channel) {
+ this.off(channel.stateChangeRefs);
+ this.channels = this.channels.filter((c) => c !== channel);
+ }
+ /**
+ * Removes `onOpen`, `onClose`, `onError,` and `onMessage` registrations.
+ *
+ * @param {refs} - list of refs returned by calls to
+ * `onOpen`, `onClose`, `onError,` and `onMessage`
+ */
+ off(refs) {
+ for (let key in this.stateChangeCallbacks) {
+ this.stateChangeCallbacks[key] = this.stateChangeCallbacks[key].filter(([ref]) => {
+ return refs.indexOf(ref) === -1;
+ });
+ }
+ }
+ /**
+ * Initiates a new channel for the given topic
+ *
+ * @param {string} topic
+ * @param {Object} chanParams - Parameters for the channel
+ * @returns {Channel}
+ */
+ channel(topic, chanParams = {}) {
+ let chan = new Channel(topic, chanParams, this);
+ this.channels.push(chan);
+ return chan;
+ }
+ /**
+ * @param {Object} data
+ */
+ push(data2) {
+ if (this.hasLogger()) {
+ let { topic, event, payload, ref, join_ref } = data2;
+ this.log("push", `${topic} ${event} (${join_ref}, ${ref})`, payload);
+ }
+ if (this.isConnected()) {
+ this.encode(data2, (result) => this.conn.send(result));
+ } else {
+ this.sendBuffer.push(() => this.encode(data2, (result) => this.conn.send(result)));
+ }
+ }
+ /**
+ * Return the next message ref, accounting for overflows
+ * @returns {string}
+ */
+ makeRef() {
+ let newRef = this.ref + 1;
+ if (newRef === this.ref) {
+ this.ref = 0;
+ } else {
+ this.ref = newRef;
+ }
+ return this.ref.toString();
+ }
+ sendHeartbeat() {
+ if (this.pendingHeartbeatRef && !this.isConnected()) {
+ return;
+ }
+ this.pendingHeartbeatRef = this.makeRef();
+ this.push({ topic: "phoenix", event: "heartbeat", payload: {}, ref: this.pendingHeartbeatRef });
+ this.heartbeatTimeoutTimer = setTimeout(() => this.heartbeatTimeout(), this.heartbeatIntervalMs);
+ }
+ flushSendBuffer() {
+ if (this.isConnected() && this.sendBuffer.length > 0) {
+ this.sendBuffer.forEach((callback) => callback());
+ this.sendBuffer = [];
+ }
+ }
+ onConnMessage(rawMessage) {
+ this.decode(rawMessage.data, (msg) => {
+ let { topic, event, payload, ref, join_ref } = msg;
+ if (ref && ref === this.pendingHeartbeatRef) {
+ this.clearHeartbeats();
+ this.pendingHeartbeatRef = null;
+ this.heartbeatTimer = setTimeout(() => this.sendHeartbeat(), this.heartbeatIntervalMs);
+ }
+ if (this.hasLogger())
+ this.log("receive", `${payload.status || ""} ${topic} ${event} ${ref && "(" + ref + ")" || ""}`, payload);
+ for (let i = 0; i < this.channels.length; i++) {
+ const channel = this.channels[i];
+ if (!channel.isMember(topic, event, payload, join_ref)) {
+ continue;
+ }
+ channel.trigger(event, payload, ref, join_ref);
+ }
+ for (let i = 0; i < this.stateChangeCallbacks.message.length; i++) {
+ let [, callback] = this.stateChangeCallbacks.message[i];
+ callback(msg);
+ }
+ });
+ }
+ leaveOpenTopic(topic) {
+ let dupChannel = this.channels.find((c) => c.topic === topic && (c.isJoined() || c.isJoining()));
+ if (dupChannel) {
+ if (this.hasLogger())
+ this.log("transport", `leaving duplicate topic "${topic}"`);
+ dupChannel.leave();
+ }
+ }
+ };
+
+ // ../deps/phoenix_live_view/priv/static/phoenix_live_view.esm.js
+ var CONSECUTIVE_RELOADS = "consecutive-reloads";
+ var MAX_RELOADS = 10;
+ var RELOAD_JITTER_MIN = 5e3;
+ var RELOAD_JITTER_MAX = 1e4;
+ var FAILSAFE_JITTER = 3e4;
+ var PHX_EVENT_CLASSES = [
+ "phx-click-loading",
+ "phx-change-loading",
+ "phx-submit-loading",
+ "phx-keydown-loading",
+ "phx-keyup-loading",
+ "phx-blur-loading",
+ "phx-focus-loading",
+ "phx-hook-loading"
+ ];
+ var PHX_COMPONENT = "data-phx-component";
+ var PHX_LIVE_LINK = "data-phx-link";
+ var PHX_TRACK_STATIC = "track-static";
+ var PHX_LINK_STATE = "data-phx-link-state";
+ var PHX_REF = "data-phx-ref";
+ var PHX_REF_SRC = "data-phx-ref-src";
+ var PHX_TRACK_UPLOADS = "track-uploads";
+ var PHX_UPLOAD_REF = "data-phx-upload-ref";
+ var PHX_PREFLIGHTED_REFS = "data-phx-preflighted-refs";
+ var PHX_DONE_REFS = "data-phx-done-refs";
+ var PHX_DROP_TARGET = "drop-target";
+ var PHX_ACTIVE_ENTRY_REFS = "data-phx-active-refs";
+ var PHX_LIVE_FILE_UPDATED = "phx:live-file:updated";
+ var PHX_SKIP = "data-phx-skip";
+ var PHX_MAGIC_ID = "data-phx-id";
+ var PHX_PRUNE = "data-phx-prune";
+ var PHX_PAGE_LOADING = "page-loading";
+ var PHX_CONNECTED_CLASS = "phx-connected";
+ var PHX_LOADING_CLASS = "phx-loading";
+ var PHX_NO_FEEDBACK_CLASS = "phx-no-feedback";
+ var PHX_ERROR_CLASS = "phx-error";
+ var PHX_CLIENT_ERROR_CLASS = "phx-client-error";
+ var PHX_SERVER_ERROR_CLASS = "phx-server-error";
+ var PHX_PARENT_ID = "data-phx-parent-id";
+ var PHX_MAIN = "data-phx-main";
+ var PHX_ROOT_ID = "data-phx-root-id";
+ var PHX_VIEWPORT_TOP = "viewport-top";
+ var PHX_VIEWPORT_BOTTOM = "viewport-bottom";
+ var PHX_TRIGGER_ACTION = "trigger-action";
+ var PHX_FEEDBACK_FOR = "feedback-for";
+ var PHX_FEEDBACK_GROUP = "feedback-group";
+ var PHX_HAS_FOCUSED = "phx-has-focused";
+ var FOCUSABLE_INPUTS = ["text", "textarea", "number", "email", "password", "search", "tel", "url", "date", "time", "datetime-local", "color", "range"];
+ var CHECKABLE_INPUTS = ["checkbox", "radio"];
+ var PHX_HAS_SUBMITTED = "phx-has-submitted";
+ var PHX_SESSION = "data-phx-session";
+ var PHX_VIEW_SELECTOR = `[${PHX_SESSION}]`;
+ var PHX_STICKY = "data-phx-sticky";
+ var PHX_STATIC = "data-phx-static";
+ var PHX_READONLY = "data-phx-readonly";
+ var PHX_DISABLED = "data-phx-disabled";
+ var PHX_DISABLE_WITH = "disable-with";
+ var PHX_DISABLE_WITH_RESTORE = "data-phx-disable-with-restore";
+ var PHX_HOOK = "hook";
+ var PHX_DEBOUNCE = "debounce";
+ var PHX_THROTTLE = "throttle";
+ var PHX_UPDATE = "update";
+ var PHX_STREAM = "stream";
+ var PHX_STREAM_REF = "data-phx-stream";
+ var PHX_KEY = "key";
+ var PHX_PRIVATE = "phxPrivate";
+ var PHX_AUTO_RECOVER = "auto-recover";
+ var PHX_LV_DEBUG = "phx:live-socket:debug";
+ var PHX_LV_PROFILE = "phx:live-socket:profiling";
+ var PHX_LV_LATENCY_SIM = "phx:live-socket:latency-sim";
+ var PHX_PROGRESS = "progress";
+ var PHX_MOUNTED = "mounted";
+ var LOADER_TIMEOUT = 1;
+ var BEFORE_UNLOAD_LOADER_TIMEOUT = 200;
+ var BINDING_PREFIX = "phx-";
+ var PUSH_TIMEOUT = 3e4;
+ var DEBOUNCE_TRIGGER = "debounce-trigger";
+ var THROTTLED = "throttled";
+ var DEBOUNCE_PREV_KEY = "debounce-prev-key";
+ var DEFAULTS = {
+ debounce: 300,
+ throttle: 300
+ };
+ var DYNAMICS = "d";
+ var STATIC = "s";
+ var ROOT = "r";
+ var COMPONENTS = "c";
+ var EVENTS = "e";
+ var REPLY = "r";
+ var TITLE = "t";
+ var TEMPLATES = "p";
+ var STREAM = "stream";
+ var EntryUploader = class {
+ constructor(entry, chunkSize, liveSocket2) {
+ this.liveSocket = liveSocket2;
+ this.entry = entry;
+ this.offset = 0;
+ this.chunkSize = chunkSize;
+ this.chunkTimer = null;
+ this.errored = false;
+ this.uploadChannel = liveSocket2.channel(`lvu:${entry.ref}`, { token: entry.metadata() });
+ }
+ error(reason) {
+ if (this.errored) {
+ return;
+ }
+ this.uploadChannel.leave();
+ this.errored = true;
+ clearTimeout(this.chunkTimer);
+ this.entry.error(reason);
+ }
+ upload() {
+ this.uploadChannel.onError((reason) => this.error(reason));
+ this.uploadChannel.join().receive("ok", (_data) => this.readNextChunk()).receive("error", (reason) => this.error(reason));
+ }
+ isDone() {
+ return this.offset >= this.entry.file.size;
+ }
+ readNextChunk() {
+ let reader = new window.FileReader();
+ let blob = this.entry.file.slice(this.offset, this.chunkSize + this.offset);
+ reader.onload = (e) => {
+ if (e.target.error === null) {
+ this.offset += e.target.result.byteLength;
+ this.pushChunk(e.target.result);
+ } else {
+ return logError("Read error: " + e.target.error);
+ }
+ };
+ reader.readAsArrayBuffer(blob);
+ }
+ pushChunk(chunk) {
+ if (!this.uploadChannel.isJoined()) {
+ return;
+ }
+ this.uploadChannel.push("chunk", chunk).receive("ok", () => {
+ this.entry.progress(this.offset / this.entry.file.size * 100);
+ if (!this.isDone()) {
+ this.chunkTimer = setTimeout(() => this.readNextChunk(), this.liveSocket.getLatencySim() || 0);
+ }
+ }).receive("error", ({ reason }) => this.error(reason));
+ }
+ };
+ var logError = (msg, obj) => console.error && console.error(msg, obj);
+ var isCid = (cid) => {
+ let type = typeof cid;
+ return type === "number" || type === "string" && /^(0|[1-9]\d*)$/.test(cid);
+ };
+ function detectDuplicateIds() {
+ let ids = /* @__PURE__ */ new Set();
+ let elems = document.querySelectorAll("*[id]");
+ for (let i = 0, len = elems.length; i < len; i++) {
+ if (ids.has(elems[i].id)) {
+ console.error(`Multiple IDs detected: ${elems[i].id}. Ensure unique element ids.`);
+ } else {
+ ids.add(elems[i].id);
+ }
+ }
+ }
+ var debug = (view, kind, msg, obj) => {
+ if (view.liveSocket.isDebugEnabled()) {
+ console.log(`${view.id} ${kind}: ${msg} - `, obj);
+ }
+ };
+ var closure2 = (val) => typeof val === "function" ? val : function() {
+ return val;
+ };
+ var clone = (obj) => {
+ return JSON.parse(JSON.stringify(obj));
+ };
+ var closestPhxBinding = (el, binding, borderEl) => {
+ do {
+ if (el.matches(`[${binding}]`) && !el.disabled) {
+ return el;
+ }
+ el = el.parentElement || el.parentNode;
+ } while (el !== null && el.nodeType === 1 && !(borderEl && borderEl.isSameNode(el) || el.matches(PHX_VIEW_SELECTOR)));
+ return null;
+ };
+ var isObject = (obj) => {
+ return obj !== null && typeof obj === "object" && !(obj instanceof Array);
+ };
+ var isEqualObj = (obj1, obj2) => JSON.stringify(obj1) === JSON.stringify(obj2);
+ var isEmpty = (obj) => {
+ for (let x in obj) {
+ return false;
+ }
+ return true;
+ };
+ var maybe = (el, callback) => el && callback(el);
+ var channelUploader = function(entries, onError, resp, liveSocket2) {
+ entries.forEach((entry) => {
+ let entryUploader = new EntryUploader(entry, resp.config.chunk_size, liveSocket2);
+ entryUploader.upload();
+ });
+ };
+ var Browser = {
+ canPushState() {
+ return typeof history.pushState !== "undefined";
+ },
+ dropLocal(localStorage, namespace, subkey) {
+ return localStorage.removeItem(this.localKey(namespace, subkey));
+ },
+ updateLocal(localStorage, namespace, subkey, initial, func) {
+ let current = this.getLocal(localStorage, namespace, subkey);
+ let key = this.localKey(namespace, subkey);
+ let newVal = current === null ? initial : func(current);
+ localStorage.setItem(key, JSON.stringify(newVal));
+ return newVal;
+ },
+ getLocal(localStorage, namespace, subkey) {
+ return JSON.parse(localStorage.getItem(this.localKey(namespace, subkey)));
+ },
+ updateCurrentState(callback) {
+ if (!this.canPushState()) {
+ return;
+ }
+ history.replaceState(callback(history.state || {}), "", window.location.href);
+ },
+ pushState(kind, meta, to) {
+ if (this.canPushState()) {
+ if (to !== window.location.href) {
+ if (meta.type == "redirect" && meta.scroll) {
+ let currentState = history.state || {};
+ currentState.scroll = meta.scroll;
+ history.replaceState(currentState, "", window.location.href);
+ }
+ delete meta.scroll;
+ history[kind + "State"](meta, "", to || null);
+ let hashEl = this.getHashTargetEl(window.location.hash);
+ if (hashEl) {
+ hashEl.scrollIntoView();
+ } else if (meta.type === "redirect") {
+ window.scroll(0, 0);
+ }
+ }
+ } else {
+ this.redirect(to);
+ }
+ },
+ setCookie(name, value) {
+ document.cookie = `${name}=${value}`;
+ },
+ getCookie(name) {
+ return document.cookie.replace(new RegExp(`(?:(?:^|.*;s*)${name}s*=s*([^;]*).*$)|^.*$`), "$1");
+ },
+ redirect(toURL, flash) {
+ if (flash) {
+ Browser.setCookie("__phoenix_flash__", flash + "; max-age=60000; path=/");
+ }
+ window.location = toURL;
+ },
+ localKey(namespace, subkey) {
+ return `${namespace}-${subkey}`;
+ },
+ getHashTargetEl(maybeHash) {
+ let hash = maybeHash.toString().substring(1);
+ if (hash === "") {
+ return;
+ }
+ return document.getElementById(hash) || document.querySelector(`a[name="${hash}"]`);
+ }
+ };
+ var browser_default = Browser;
+ var ARIA = {
+ focusMain() {
+ let target = document.querySelector("main h1, main, h1");
+ if (target) {
+ let origTabIndex = target.tabIndex;
+ target.tabIndex = -1;
+ target.focus();
+ target.tabIndex = origTabIndex;
+ }
+ },
+ anyOf(instance, classes) {
+ return classes.find((name) => instance instanceof name);
+ },
+ isFocusable(el, interactiveOnly) {
+ return el instanceof HTMLAnchorElement && el.rel !== "ignore" || el instanceof HTMLAreaElement && el.href !== void 0 || !el.disabled && this.anyOf(el, [HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement, HTMLButtonElement]) || el instanceof HTMLIFrameElement || (el.tabIndex > 0 || !interactiveOnly && el.getAttribute("tabindex") !== null && el.getAttribute("aria-hidden") !== "true");
+ },
+ attemptFocus(el, interactiveOnly) {
+ if (this.isFocusable(el, interactiveOnly)) {
+ try {
+ el.focus();
+ } catch (e) {
+ }
+ }
+ return !!document.activeElement && document.activeElement.isSameNode(el);
+ },
+ focusFirstInteractive(el) {
+ let child = el.firstElementChild;
+ while (child) {
+ if (this.attemptFocus(child, true) || this.focusFirstInteractive(child, true)) {
+ return true;
+ }
+ child = child.nextElementSibling;
+ }
+ },
+ focusFirst(el) {
+ let child = el.firstElementChild;
+ while (child) {
+ if (this.attemptFocus(child) || this.focusFirst(child)) {
+ return true;
+ }
+ child = child.nextElementSibling;
+ }
+ },
+ focusLast(el) {
+ let child = el.lastElementChild;
+ while (child) {
+ if (this.attemptFocus(child) || this.focusLast(child)) {
+ return true;
+ }
+ child = child.previousElementSibling;
+ }
+ }
+ };
+ var aria_default = ARIA;
+ var focusStack = [];
+ var default_transition_time = 200;
+ var JS = {
+ exec(eventType, phxEvent, view, sourceEl, defaults2) {
+ let [defaultKind, defaultArgs] = defaults2 || [null, { callback: defaults2 && defaults2.callback }];
+ let commands = phxEvent.charAt(0) === "[" ? JSON.parse(phxEvent) : [[defaultKind, defaultArgs]];
+ commands.forEach(([kind, args]) => {
+ if (kind === defaultKind && defaultArgs.data) {
+ args.data = Object.assign(args.data || {}, defaultArgs.data);
+ args.callback = args.callback || defaultArgs.callback;
+ }
+ this.filterToEls(sourceEl, args).forEach((el) => {
+ this[`exec_${kind}`](eventType, phxEvent, view, sourceEl, el, args);
+ });
+ });
+ },
+ isVisible(el) {
+ return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length > 0);
+ },
+ isInViewport(el) {
+ const rect = el.getBoundingClientRect();
+ const windowHeight = window.innerHeight || document.documentElement.clientHeight;
+ const windowWidth = window.innerWidth || document.documentElement.clientWidth;
+ return rect.right > 0 && rect.bottom > 0 && rect.left < windowWidth && rect.top < windowHeight;
+ },
+ exec_exec(eventType, phxEvent, view, sourceEl, el, { attr, to }) {
+ let nodes = to ? dom_default.all(document, to) : [sourceEl];
+ nodes.forEach((node) => {
+ let encodedJS = node.getAttribute(attr);
+ if (!encodedJS) {
+ throw new Error(`expected ${attr} to contain JS command on "${to}"`);
+ }
+ view.liveSocket.execJS(node, encodedJS, eventType);
+ });
+ },
+ exec_dispatch(eventType, phxEvent, view, sourceEl, el, { to, event, detail, bubbles }) {
+ detail = detail || {};
+ detail.dispatcher = sourceEl;
+ dom_default.dispatchEvent(el, event, { detail, bubbles });
+ },
+ exec_push(eventType, phxEvent, view, sourceEl, el, args) {
+ let { event, data: data2, target, page_loading, loading, value, dispatcher, callback } = args;
+ let pushOpts = { loading, value, target, page_loading: !!page_loading };
+ let targetSrc = eventType === "change" && dispatcher ? dispatcher : sourceEl;
+ let phxTarget = target || targetSrc.getAttribute(view.binding("target")) || targetSrc;
+ view.withinTargets(phxTarget, (targetView, targetCtx) => {
+ if (!targetView.isConnected()) {
+ return;
+ }
+ if (eventType === "change") {
+ let { newCid, _target } = args;
+ _target = _target || (dom_default.isFormInput(sourceEl) ? sourceEl.name : void 0);
+ if (_target) {
+ pushOpts._target = _target;
+ }
+ targetView.pushInput(sourceEl, targetCtx, newCid, event || phxEvent, pushOpts, callback);
+ } else if (eventType === "submit") {
+ let { submitter } = args;
+ targetView.submitForm(sourceEl, targetCtx, event || phxEvent, submitter, pushOpts, callback);
+ } else {
+ targetView.pushEvent(eventType, sourceEl, targetCtx, event || phxEvent, data2, pushOpts, callback);
+ }
+ });
+ },
+ exec_navigate(eventType, phxEvent, view, sourceEl, el, { href, replace }) {
+ view.liveSocket.historyRedirect(href, replace ? "replace" : "push");
+ },
+ exec_patch(eventType, phxEvent, view, sourceEl, el, { href, replace }) {
+ view.liveSocket.pushHistoryPatch(href, replace ? "replace" : "push", sourceEl);
+ },
+ exec_focus(eventType, phxEvent, view, sourceEl, el) {
+ window.requestAnimationFrame(() => aria_default.attemptFocus(el));
+ },
+ exec_focus_first(eventType, phxEvent, view, sourceEl, el) {
+ window.requestAnimationFrame(() => aria_default.focusFirstInteractive(el) || aria_default.focusFirst(el));
+ },
+ exec_push_focus(eventType, phxEvent, view, sourceEl, el) {
+ window.requestAnimationFrame(() => focusStack.push(el || sourceEl));
+ },
+ exec_pop_focus(eventType, phxEvent, view, sourceEl, el) {
+ window.requestAnimationFrame(() => {
+ const el2 = focusStack.pop();
+ if (el2) {
+ el2.focus();
+ }
+ });
+ },
+ exec_add_class(eventType, phxEvent, view, sourceEl, el, { names, transition, time: time2 }) {
+ this.addOrRemoveClasses(el, names, [], transition, time2, view);
+ },
+ exec_remove_class(eventType, phxEvent, view, sourceEl, el, { names, transition, time: time2 }) {
+ this.addOrRemoveClasses(el, [], names, transition, time2, view);
+ },
+ exec_toggle_class(eventType, phxEvent, view, sourceEl, el, { to, names, transition, time: time2 }) {
+ this.toggleClasses(el, names, transition, time2, view);
+ },
+ exec_toggle_attr(eventType, phxEvent, view, sourceEl, el, { attr: [attr, val1, val2] }) {
+ if (el.hasAttribute(attr)) {
+ if (val2 !== void 0) {
+ if (el.getAttribute(attr) === val1) {
+ this.setOrRemoveAttrs(el, [[attr, val2]], []);
+ } else {
+ this.setOrRemoveAttrs(el, [[attr, val1]], []);
+ }
+ } else {
+ this.setOrRemoveAttrs(el, [], [attr]);
+ }
+ } else {
+ this.setOrRemoveAttrs(el, [[attr, val1]], []);
+ }
+ },
+ exec_transition(eventType, phxEvent, view, sourceEl, el, { time: time2, transition }) {
+ this.addOrRemoveClasses(el, [], [], transition, time2, view);
+ },
+ exec_toggle(eventType, phxEvent, view, sourceEl, el, { display, ins, outs, time: time2 }) {
+ this.toggle(eventType, view, el, display, ins, outs, time2);
+ },
+ exec_show(eventType, phxEvent, view, sourceEl, el, { display, transition, time: time2 }) {
+ this.show(eventType, view, el, display, transition, time2);
+ },
+ exec_hide(eventType, phxEvent, view, sourceEl, el, { display, transition, time: time2 }) {
+ this.hide(eventType, view, el, display, transition, time2);
+ },
+ exec_set_attr(eventType, phxEvent, view, sourceEl, el, { attr: [attr, val] }) {
+ this.setOrRemoveAttrs(el, [[attr, val]], []);
+ },
+ exec_remove_attr(eventType, phxEvent, view, sourceEl, el, { attr }) {
+ this.setOrRemoveAttrs(el, [], [attr]);
+ },
+ show(eventType, view, el, display, transition, time2) {
+ if (!this.isVisible(el)) {
+ this.toggle(eventType, view, el, display, transition, null, time2);
+ }
+ },
+ hide(eventType, view, el, display, transition, time2) {
+ if (this.isVisible(el)) {
+ this.toggle(eventType, view, el, display, null, transition, time2);
+ }
+ },
+ toggle(eventType, view, el, display, ins, outs, time2) {
+ time2 = time2 || default_transition_time;
+ let [inClasses, inStartClasses, inEndClasses] = ins || [[], [], []];
+ let [outClasses, outStartClasses, outEndClasses] = outs || [[], [], []];
+ if (inClasses.length > 0 || outClasses.length > 0) {
+ if (this.isVisible(el)) {
+ let onStart = () => {
+ this.addOrRemoveClasses(el, outStartClasses, inClasses.concat(inStartClasses).concat(inEndClasses));
+ window.requestAnimationFrame(() => {
+ this.addOrRemoveClasses(el, outClasses, []);
+ window.requestAnimationFrame(() => this.addOrRemoveClasses(el, outEndClasses, outStartClasses));
+ });
+ };
+ el.dispatchEvent(new Event("phx:hide-start"));
+ view.transition(time2, onStart, () => {
+ this.addOrRemoveClasses(el, [], outClasses.concat(outEndClasses));
+ dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = "none");
+ el.dispatchEvent(new Event("phx:hide-end"));
+ });
+ } else {
+ if (eventType === "remove") {
+ return;
+ }
+ let onStart = () => {
+ this.addOrRemoveClasses(el, inStartClasses, outClasses.concat(outStartClasses).concat(outEndClasses));
+ let stickyDisplay = display || this.defaultDisplay(el);
+ dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = stickyDisplay);
+ window.requestAnimationFrame(() => {
+ this.addOrRemoveClasses(el, inClasses, []);
+ window.requestAnimationFrame(() => this.addOrRemoveClasses(el, inEndClasses, inStartClasses));
+ });
+ };
+ el.dispatchEvent(new Event("phx:show-start"));
+ view.transition(time2, onStart, () => {
+ this.addOrRemoveClasses(el, [], inClasses.concat(inEndClasses));
+ el.dispatchEvent(new Event("phx:show-end"));
+ });
+ }
+ } else {
+ if (this.isVisible(el)) {
+ window.requestAnimationFrame(() => {
+ el.dispatchEvent(new Event("phx:hide-start"));
+ dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = "none");
+ el.dispatchEvent(new Event("phx:hide-end"));
+ });
+ } else {
+ window.requestAnimationFrame(() => {
+ el.dispatchEvent(new Event("phx:show-start"));
+ let stickyDisplay = display || this.defaultDisplay(el);
+ dom_default.putSticky(el, "toggle", (currentEl) => currentEl.style.display = stickyDisplay);
+ el.dispatchEvent(new Event("phx:show-end"));
+ });
+ }
+ }
+ },
+ toggleClasses(el, classes, transition, time2, view) {
+ window.requestAnimationFrame(() => {
+ let [prevAdds, prevRemoves] = dom_default.getSticky(el, "classes", [[], []]);
+ let newAdds = classes.filter((name) => prevAdds.indexOf(name) < 0 && !el.classList.contains(name));
+ let newRemoves = classes.filter((name) => prevRemoves.indexOf(name) < 0 && el.classList.contains(name));
+ this.addOrRemoveClasses(el, newAdds, newRemoves, transition, time2, view);
+ });
+ },
+ addOrRemoveClasses(el, adds, removes, transition, time2, view) {
+ time2 = time2 || default_transition_time;
+ let [transitionRun, transitionStart, transitionEnd] = transition || [[], [], []];
+ if (transitionRun.length > 0) {
+ let onStart = () => {
+ this.addOrRemoveClasses(el, transitionStart, [].concat(transitionRun).concat(transitionEnd));
+ window.requestAnimationFrame(() => {
+ this.addOrRemoveClasses(el, transitionRun, []);
+ window.requestAnimationFrame(() => this.addOrRemoveClasses(el, transitionEnd, transitionStart));
+ });
+ };
+ let onDone = () => this.addOrRemoveClasses(el, adds.concat(transitionEnd), removes.concat(transitionRun).concat(transitionStart));
+ return view.transition(time2, onStart, onDone);
+ }
+ window.requestAnimationFrame(() => {
+ let [prevAdds, prevRemoves] = dom_default.getSticky(el, "classes", [[], []]);
+ let keepAdds = adds.filter((name) => prevAdds.indexOf(name) < 0 && !el.classList.contains(name));
+ let keepRemoves = removes.filter((name) => prevRemoves.indexOf(name) < 0 && el.classList.contains(name));
+ let newAdds = prevAdds.filter((name) => removes.indexOf(name) < 0).concat(keepAdds);
+ let newRemoves = prevRemoves.filter((name) => adds.indexOf(name) < 0).concat(keepRemoves);
+ dom_default.putSticky(el, "classes", (currentEl) => {
+ currentEl.classList.remove(...newRemoves);
+ currentEl.classList.add(...newAdds);
+ return [newAdds, newRemoves];
+ });
+ });
+ },
+ setOrRemoveAttrs(el, sets, removes) {
+ let [prevSets, prevRemoves] = dom_default.getSticky(el, "attrs", [[], []]);
+ let alteredAttrs = sets.map(([attr, _val]) => attr).concat(removes);
+ let newSets = prevSets.filter(([attr, _val]) => !alteredAttrs.includes(attr)).concat(sets);
+ let newRemoves = prevRemoves.filter((attr) => !alteredAttrs.includes(attr)).concat(removes);
+ dom_default.putSticky(el, "attrs", (currentEl) => {
+ newRemoves.forEach((attr) => currentEl.removeAttribute(attr));
+ newSets.forEach(([attr, val]) => currentEl.setAttribute(attr, val));
+ return [newSets, newRemoves];
+ });
+ },
+ hasAllClasses(el, classes) {
+ return classes.every((name) => el.classList.contains(name));
+ },
+ isToggledOut(el, outClasses) {
+ return !this.isVisible(el) || this.hasAllClasses(el, outClasses);
+ },
+ filterToEls(sourceEl, { to }) {
+ return to ? dom_default.all(document, to) : [sourceEl];
+ },
+ defaultDisplay(el) {
+ return { tr: "table-row", td: "table-cell" }[el.tagName.toLowerCase()] || "block";
+ }
+ };
+ var js_default = JS;
+ var DOM = {
+ byId(id) {
+ return document.getElementById(id) || logError(`no id found for ${id}`);
+ },
+ removeClass(el, className) {
+ el.classList.remove(className);
+ if (el.classList.length === 0) {
+ el.removeAttribute("class");
+ }
+ },
+ all(node, query, callback) {
+ if (!node) {
+ return [];
+ }
+ let array = Array.from(node.querySelectorAll(query));
+ return callback ? array.forEach(callback) : array;
+ },
+ childNodeLength(html) {
+ let template = document.createElement("template");
+ template.innerHTML = html;
+ return template.content.childElementCount;
+ },
+ isUploadInput(el) {
+ return el.type === "file" && el.getAttribute(PHX_UPLOAD_REF) !== null;
+ },
+ isAutoUpload(inputEl) {
+ return inputEl.hasAttribute("data-phx-auto-upload");
+ },
+ findUploadInputs(node) {
+ const formId = node.id;
+ const inputsOutsideForm = this.all(document, `input[type="file"][${PHX_UPLOAD_REF}][form="${formId}"]`);
+ return this.all(node, `input[type="file"][${PHX_UPLOAD_REF}]`).concat(inputsOutsideForm);
+ },
+ findComponentNodeList(node, cid) {
+ return this.filterWithinSameLiveView(this.all(node, `[${PHX_COMPONENT}="${cid}"]`), node);
+ },
+ isPhxDestroyed(node) {
+ return node.id && DOM.private(node, "destroyed") ? true : false;
+ },
+ wantsNewTab(e) {
+ let wantsNewTab = e.ctrlKey || e.shiftKey || e.metaKey || e.button && e.button === 1;
+ let isDownload = e.target instanceof HTMLAnchorElement && e.target.hasAttribute("download");
+ let isTargetBlank = e.target.hasAttribute("target") && e.target.getAttribute("target").toLowerCase() === "_blank";
+ let isTargetNamedTab = e.target.hasAttribute("target") && !e.target.getAttribute("target").startsWith("_");
+ return wantsNewTab || isTargetBlank || isDownload || isTargetNamedTab;
+ },
+ isUnloadableFormSubmit(e) {
+ let isDialogSubmit = e.target && e.target.getAttribute("method") === "dialog" || e.submitter && e.submitter.getAttribute("formmethod") === "dialog";
+ if (isDialogSubmit) {
+ return false;
+ } else {
+ return !e.defaultPrevented && !this.wantsNewTab(e);
+ }
+ },
+ isNewPageClick(e, currentLocation) {
+ let href = e.target instanceof HTMLAnchorElement ? e.target.getAttribute("href") : null;
+ let url;
+ if (e.defaultPrevented || href === null || this.wantsNewTab(e)) {
+ return false;
+ }
+ if (href.startsWith("mailto:") || href.startsWith("tel:")) {
+ return false;
+ }
+ if (e.target.isContentEditable) {
+ return false;
+ }
+ try {
+ url = new URL(href);
+ } catch (e2) {
+ try {
+ url = new URL(href, currentLocation);
+ } catch (e3) {
+ return true;
+ }
+ }
+ if (url.host === currentLocation.host && url.protocol === currentLocation.protocol) {
+ if (url.pathname === currentLocation.pathname && url.search === currentLocation.search) {
+ return url.hash === "" && !url.href.endsWith("#");
+ }
+ }
+ return url.protocol.startsWith("http");
+ },
+ markPhxChildDestroyed(el) {
+ if (this.isPhxChild(el)) {
+ el.setAttribute(PHX_SESSION, "");
+ }
+ this.putPrivate(el, "destroyed", true);
+ },
+ findPhxChildrenInFragment(html, parentId) {
+ let template = document.createElement("template");
+ template.innerHTML = html;
+ return this.findPhxChildren(template.content, parentId);
+ },
+ isIgnored(el, phxUpdate) {
+ return (el.getAttribute(phxUpdate) || el.getAttribute("data-phx-update")) === "ignore";
+ },
+ isPhxUpdate(el, phxUpdate, updateTypes) {
+ return el.getAttribute && updateTypes.indexOf(el.getAttribute(phxUpdate)) >= 0;
+ },
+ findPhxSticky(el) {
+ return this.all(el, `[${PHX_STICKY}]`);
+ },
+ findPhxChildren(el, parentId) {
+ return this.all(el, `${PHX_VIEW_SELECTOR}[${PHX_PARENT_ID}="${parentId}"]`);
+ },
+ findExistingParentCIDs(node, cids) {
+ let parentCids = /* @__PURE__ */ new Set();
+ let childrenCids = /* @__PURE__ */ new Set();
+ cids.forEach((cid) => {
+ this.filterWithinSameLiveView(this.all(node, `[${PHX_COMPONENT}="${cid}"]`), node).forEach((parent) => {
+ parentCids.add(cid);
+ this.all(parent, `[${PHX_COMPONENT}]`).map((el) => parseInt(el.getAttribute(PHX_COMPONENT))).forEach((childCID) => childrenCids.add(childCID));
+ });
+ });
+ childrenCids.forEach((childCid) => parentCids.delete(childCid));
+ return parentCids;
+ },
+ filterWithinSameLiveView(nodes, parent) {
+ if (parent.querySelector(PHX_VIEW_SELECTOR)) {
+ return nodes.filter((el) => this.withinSameLiveView(el, parent));
+ } else {
+ return nodes;
+ }
+ },
+ withinSameLiveView(node, parent) {
+ while (node = node.parentNode) {
+ if (node.isSameNode(parent)) {
+ return true;
+ }
+ if (node.getAttribute(PHX_SESSION) !== null) {
+ return false;
+ }
+ }
+ },
+ private(el, key) {
+ return el[PHX_PRIVATE] && el[PHX_PRIVATE][key];
+ },
+ deletePrivate(el, key) {
+ el[PHX_PRIVATE] && delete el[PHX_PRIVATE][key];
+ },
+ putPrivate(el, key, value) {
+ if (!el[PHX_PRIVATE]) {
+ el[PHX_PRIVATE] = {};
+ }
+ el[PHX_PRIVATE][key] = value;
+ },
+ updatePrivate(el, key, defaultVal, updateFunc) {
+ let existing = this.private(el, key);
+ if (existing === void 0) {
+ this.putPrivate(el, key, updateFunc(defaultVal));
+ } else {
+ this.putPrivate(el, key, updateFunc(existing));
+ }
+ },
+ copyPrivates(target, source) {
+ if (source[PHX_PRIVATE]) {
+ target[PHX_PRIVATE] = source[PHX_PRIVATE];
+ }
+ },
+ putTitle(str) {
+ let titleEl = document.querySelector("title");
+ if (titleEl) {
+ let { prefix, suffix } = titleEl.dataset;
+ document.title = `${prefix || ""}${str}${suffix || ""}`;
+ } else {
+ document.title = str;
+ }
+ },
+ debounce(el, event, phxDebounce, defaultDebounce, phxThrottle, defaultThrottle, asyncFilter, callback) {
+ let debounce = el.getAttribute(phxDebounce);
+ let throttle = el.getAttribute(phxThrottle);
+ if (debounce === "") {
+ debounce = defaultDebounce;
+ }
+ if (throttle === "") {
+ throttle = defaultThrottle;
+ }
+ let value = debounce || throttle;
+ switch (value) {
+ case null:
+ return callback();
+ case "blur":
+ if (this.once(el, "debounce-blur")) {
+ el.addEventListener("blur", () => {
+ if (asyncFilter()) {
+ callback();
+ }
+ });
+ }
+ return;
+ default:
+ let timeout = parseInt(value);
+ let trigger = () => throttle ? this.deletePrivate(el, THROTTLED) : callback();
+ let currentCycle = this.incCycle(el, DEBOUNCE_TRIGGER, trigger);
+ if (isNaN(timeout)) {
+ return logError(`invalid throttle/debounce value: ${value}`);
+ }
+ if (throttle) {
+ let newKeyDown = false;
+ if (event.type === "keydown") {
+ let prevKey = this.private(el, DEBOUNCE_PREV_KEY);
+ this.putPrivate(el, DEBOUNCE_PREV_KEY, event.key);
+ newKeyDown = prevKey !== event.key;
+ }
+ if (!newKeyDown && this.private(el, THROTTLED)) {
+ return false;
+ } else {
+ callback();
+ const t = setTimeout(() => {
+ if (asyncFilter()) {
+ this.triggerCycle(el, DEBOUNCE_TRIGGER);
+ }
+ }, timeout);
+ this.putPrivate(el, THROTTLED, t);
+ }
+ } else {
+ setTimeout(() => {
+ if (asyncFilter()) {
+ this.triggerCycle(el, DEBOUNCE_TRIGGER, currentCycle);
+ }
+ }, timeout);
+ }
+ let form = el.form;
+ if (form && this.once(form, "bind-debounce")) {
+ form.addEventListener("submit", () => {
+ Array.from(new FormData(form).entries(), ([name]) => {
+ let input = form.querySelector(`[name="${name}"]`);
+ this.incCycle(input, DEBOUNCE_TRIGGER);
+ this.deletePrivate(input, THROTTLED);
+ });
+ });
+ }
+ if (this.once(el, "bind-debounce")) {
+ el.addEventListener("blur", () => {
+ clearTimeout(this.private(el, THROTTLED));
+ this.triggerCycle(el, DEBOUNCE_TRIGGER);
+ });
+ }
+ }
+ },
+ triggerCycle(el, key, currentCycle) {
+ let [cycle, trigger] = this.private(el, key);
+ if (!currentCycle) {
+ currentCycle = cycle;
+ }
+ if (currentCycle === cycle) {
+ this.incCycle(el, key);
+ trigger();
+ }
+ },
+ once(el, key) {
+ if (this.private(el, key) === true) {
+ return false;
+ }
+ this.putPrivate(el, key, true);
+ return true;
+ },
+ incCycle(el, key, trigger = function() {
+ }) {
+ let [currentCycle] = this.private(el, key) || [0, trigger];
+ currentCycle++;
+ this.putPrivate(el, key, [currentCycle, trigger]);
+ return currentCycle;
+ },
+ maybeAddPrivateHooks(el, phxViewportTop, phxViewportBottom) {
+ if (el.hasAttribute && (el.hasAttribute(phxViewportTop) || el.hasAttribute(phxViewportBottom))) {
+ el.setAttribute("data-phx-hook", "Phoenix.InfiniteScroll");
+ }
+ },
+ isFeedbackContainer(el, phxFeedbackFor) {
+ return el.hasAttribute && el.hasAttribute(phxFeedbackFor);
+ },
+ maybeHideFeedback(container, feedbackContainers, phxFeedbackFor, phxFeedbackGroup) {
+ const feedbackResults = {};
+ feedbackContainers.forEach((el) => {
+ if (!container.contains(el))
+ return;
+ const feedback = el.getAttribute(phxFeedbackFor);
+ if (!feedback) {
+ js_default.addOrRemoveClasses(el, [], [PHX_NO_FEEDBACK_CLASS]);
+ return;
+ }
+ if (feedbackResults[feedback] === true) {
+ this.hideFeedback(el);
+ return;
+ }
+ feedbackResults[feedback] = this.shouldHideFeedback(container, feedback, phxFeedbackGroup);
+ if (feedbackResults[feedback] === true) {
+ this.hideFeedback(el);
+ }
+ });
+ },
+ hideFeedback(container) {
+ js_default.addOrRemoveClasses(container, [PHX_NO_FEEDBACK_CLASS], []);
+ },
+ shouldHideFeedback(container, nameOrGroup, phxFeedbackGroup) {
+ const query = `[name="${nameOrGroup}"],
+ [name="${nameOrGroup}[]"],
+ [${phxFeedbackGroup}="${nameOrGroup}"]`;
+ let focused = false;
+ DOM.all(container, query, (input) => {
+ if (this.private(input, PHX_HAS_FOCUSED) || this.private(input, PHX_HAS_SUBMITTED)) {
+ focused = true;
+ }
+ });
+ return !focused;
+ },
+ feedbackSelector(input, phxFeedbackFor, phxFeedbackGroup) {
+ let query = `[${phxFeedbackFor}="${input.name}"],
+ [${phxFeedbackFor}="${input.name.replace(/\[\]$/, "")}"]`;
+ if (input.getAttribute(phxFeedbackGroup)) {
+ query += `,[${phxFeedbackFor}="${input.getAttribute(phxFeedbackGroup)}"]`;
+ }
+ return query;
+ },
+ resetForm(form, phxFeedbackFor, phxFeedbackGroup) {
+ Array.from(form.elements).forEach((input) => {
+ let query = this.feedbackSelector(input, phxFeedbackFor, phxFeedbackGroup);
+ this.deletePrivate(input, PHX_HAS_FOCUSED);
+ this.deletePrivate(input, PHX_HAS_SUBMITTED);
+ this.all(document, query, (feedbackEl) => {
+ js_default.addOrRemoveClasses(feedbackEl, [PHX_NO_FEEDBACK_CLASS], []);
+ });
+ });
+ },
+ showError(inputEl, phxFeedbackFor, phxFeedbackGroup) {
+ if (inputEl.name) {
+ let query = this.feedbackSelector(inputEl, phxFeedbackFor, phxFeedbackGroup);
+ this.all(document, query, (el) => {
+ js_default.addOrRemoveClasses(el, [], [PHX_NO_FEEDBACK_CLASS]);
+ });
+ }
+ },
+ isPhxChild(node) {
+ return node.getAttribute && node.getAttribute(PHX_PARENT_ID);
+ },
+ isPhxSticky(node) {
+ return node.getAttribute && node.getAttribute(PHX_STICKY) !== null;
+ },
+ isChildOfAny(el, parents) {
+ return !!parents.find((parent) => parent.contains(el));
+ },
+ firstPhxChild(el) {
+ return this.isPhxChild(el) ? el : this.all(el, `[${PHX_PARENT_ID}]`)[0];
+ },
+ dispatchEvent(target, name, opts = {}) {
+ let defaultBubble = true;
+ let isUploadTarget = target.nodeName === "INPUT" && target.type === "file";
+ if (isUploadTarget && name === "click") {
+ defaultBubble = false;
+ }
+ let bubbles = opts.bubbles === void 0 ? defaultBubble : !!opts.bubbles;
+ let eventOpts = { bubbles, cancelable: true, detail: opts.detail || {} };
+ let event = name === "click" ? new MouseEvent("click", eventOpts) : new CustomEvent(name, eventOpts);
+ target.dispatchEvent(event);
+ },
+ cloneNode(node, html) {
+ if (typeof html === "undefined") {
+ return node.cloneNode(true);
+ } else {
+ let cloned = node.cloneNode(false);
+ cloned.innerHTML = html;
+ return cloned;
+ }
+ },
+ mergeAttrs(target, source, opts = {}) {
+ let exclude = new Set(opts.exclude || []);
+ let isIgnored = opts.isIgnored;
+ let sourceAttrs = source.attributes;
+ for (let i = sourceAttrs.length - 1; i >= 0; i--) {
+ let name = sourceAttrs[i].name;
+ if (!exclude.has(name)) {
+ const sourceValue = source.getAttribute(name);
+ if (target.getAttribute(name) !== sourceValue && (!isIgnored || isIgnored && name.startsWith("data-"))) {
+ target.setAttribute(name, sourceValue);
+ }
+ } else {
+ if (name === "value" && target.value === source.value) {
+ target.setAttribute("value", source.getAttribute(name));
+ }
+ }
+ }
+ let targetAttrs = target.attributes;
+ for (let i = targetAttrs.length - 1; i >= 0; i--) {
+ let name = targetAttrs[i].name;
+ if (isIgnored) {
+ if (name.startsWith("data-") && !source.hasAttribute(name) && ![PHX_REF, PHX_REF_SRC].includes(name)) {
+ target.removeAttribute(name);
+ }
+ } else {
+ if (!source.hasAttribute(name)) {
+ target.removeAttribute(name);
+ }
+ }
+ }
+ },
+ mergeFocusedInput(target, source) {
+ if (!(target instanceof HTMLSelectElement)) {
+ DOM.mergeAttrs(target, source, { exclude: ["value"] });
+ }
+ if (source.readOnly) {
+ target.setAttribute("readonly", true);
+ } else {
+ target.removeAttribute("readonly");
+ }
+ },
+ hasSelectionRange(el) {
+ return el.setSelectionRange && (el.type === "text" || el.type === "textarea");
+ },
+ restoreFocus(focused, selectionStart, selectionEnd) {
+ if (focused instanceof HTMLSelectElement) {
+ focused.focus();
+ }
+ if (!DOM.isTextualInput(focused)) {
+ return;
+ }
+ let wasFocused = focused.matches(":focus");
+ if (!wasFocused) {
+ focused.focus();
+ }
+ if (this.hasSelectionRange(focused)) {
+ focused.setSelectionRange(selectionStart, selectionEnd);
+ }
+ },
+ isFormInput(el) {
+ return /^(?:input|select|textarea)$/i.test(el.tagName) && el.type !== "button";
+ },
+ syncAttrsToProps(el) {
+ if (el instanceof HTMLInputElement && CHECKABLE_INPUTS.indexOf(el.type.toLocaleLowerCase()) >= 0) {
+ el.checked = el.getAttribute("checked") !== null;
+ }
+ },
+ isTextualInput(el) {
+ return FOCUSABLE_INPUTS.indexOf(el.type) >= 0;
+ },
+ isNowTriggerFormExternal(el, phxTriggerExternal) {
+ return el.getAttribute && el.getAttribute(phxTriggerExternal) !== null;
+ },
+ syncPendingRef(fromEl, toEl, disableWith) {
+ let ref = fromEl.getAttribute(PHX_REF);
+ if (ref === null) {
+ return true;
+ }
+ let refSrc = fromEl.getAttribute(PHX_REF_SRC);
+ if (DOM.isFormInput(fromEl) || fromEl.getAttribute(disableWith) !== null) {
+ if (DOM.isUploadInput(fromEl)) {
+ DOM.mergeAttrs(fromEl, toEl, { isIgnored: true });
+ }
+ DOM.putPrivate(fromEl, PHX_REF, toEl);
+ return false;
+ } else {
+ PHX_EVENT_CLASSES.forEach((className) => {
+ fromEl.classList.contains(className) && toEl.classList.add(className);
+ });
+ toEl.setAttribute(PHX_REF, ref);
+ toEl.setAttribute(PHX_REF_SRC, refSrc);
+ return true;
+ }
+ },
+ cleanChildNodes(container, phxUpdate) {
+ if (DOM.isPhxUpdate(container, phxUpdate, ["append", "prepend"])) {
+ let toRemove = [];
+ container.childNodes.forEach((childNode) => {
+ if (!childNode.id) {
+ let isEmptyTextNode = childNode.nodeType === Node.TEXT_NODE && childNode.nodeValue.trim() === "";
+ if (!isEmptyTextNode && childNode.nodeType !== Node.COMMENT_NODE) {
+ logError(`only HTML element tags with an id are allowed inside containers with phx-update.
+
+removing illegal node: "${(childNode.outerHTML || childNode.nodeValue).trim()}"
+
+`);
+ }
+ toRemove.push(childNode);
+ }
+ });
+ toRemove.forEach((childNode) => childNode.remove());
+ }
+ },
+ replaceRootContainer(container, tagName, attrs) {
+ let retainedAttrs = /* @__PURE__ */ new Set(["id", PHX_SESSION, PHX_STATIC, PHX_MAIN, PHX_ROOT_ID]);
+ if (container.tagName.toLowerCase() === tagName.toLowerCase()) {
+ Array.from(container.attributes).filter((attr) => !retainedAttrs.has(attr.name.toLowerCase())).forEach((attr) => container.removeAttribute(attr.name));
+ Object.keys(attrs).filter((name) => !retainedAttrs.has(name.toLowerCase())).forEach((attr) => container.setAttribute(attr, attrs[attr]));
+ return container;
+ } else {
+ let newContainer = document.createElement(tagName);
+ Object.keys(attrs).forEach((attr) => newContainer.setAttribute(attr, attrs[attr]));
+ retainedAttrs.forEach((attr) => newContainer.setAttribute(attr, container.getAttribute(attr)));
+ newContainer.innerHTML = container.innerHTML;
+ container.replaceWith(newContainer);
+ return newContainer;
+ }
+ },
+ getSticky(el, name, defaultVal) {
+ let op = (DOM.private(el, "sticky") || []).find(([existingName]) => name === existingName);
+ if (op) {
+ let [_name, _op, stashedResult] = op;
+ return stashedResult;
+ } else {
+ return typeof defaultVal === "function" ? defaultVal() : defaultVal;
+ }
+ },
+ deleteSticky(el, name) {
+ this.updatePrivate(el, "sticky", [], (ops) => {
+ return ops.filter(([existingName, _]) => existingName !== name);
+ });
+ },
+ putSticky(el, name, op) {
+ let stashedResult = op(el);
+ this.updatePrivate(el, "sticky", [], (ops) => {
+ let existingIndex = ops.findIndex(([existingName]) => name === existingName);
+ if (existingIndex >= 0) {
+ ops[existingIndex] = [name, op, stashedResult];
+ } else {
+ ops.push([name, op, stashedResult]);
+ }
+ return ops;
+ });
+ },
+ applyStickyOperations(el) {
+ let ops = DOM.private(el, "sticky");
+ if (!ops) {
+ return;
+ }
+ ops.forEach(([name, op, _stashed]) => this.putSticky(el, name, op));
+ }
+ };
+ var dom_default = DOM;
+ var UploadEntry = class {
+ static isActive(fileEl, file) {
+ let isNew = file._phxRef === void 0;
+ let activeRefs = fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",");
+ let isActive = activeRefs.indexOf(LiveUploader.genFileRef(file)) >= 0;
+ return file.size > 0 && (isNew || isActive);
+ }
+ static isPreflighted(fileEl, file) {
+ let preflightedRefs = fileEl.getAttribute(PHX_PREFLIGHTED_REFS).split(",");
+ let isPreflighted = preflightedRefs.indexOf(LiveUploader.genFileRef(file)) >= 0;
+ return isPreflighted && this.isActive(fileEl, file);
+ }
+ static isPreflightInProgress(file) {
+ return file._preflightInProgress === true;
+ }
+ static markPreflightInProgress(file) {
+ file._preflightInProgress = true;
+ }
+ constructor(fileEl, file, view, autoUpload) {
+ this.ref = LiveUploader.genFileRef(file);
+ this.fileEl = fileEl;
+ this.file = file;
+ this.view = view;
+ this.meta = null;
+ this._isCancelled = false;
+ this._isDone = false;
+ this._progress = 0;
+ this._lastProgressSent = -1;
+ this._onDone = function() {
+ };
+ this._onElUpdated = this.onElUpdated.bind(this);
+ this.fileEl.addEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);
+ this.autoUpload = autoUpload;
+ }
+ metadata() {
+ return this.meta;
+ }
+ progress(progress2) {
+ this._progress = Math.floor(progress2);
+ if (this._progress > this._lastProgressSent) {
+ if (this._progress >= 100) {
+ this._progress = 100;
+ this._lastProgressSent = 100;
+ this._isDone = true;
+ this.view.pushFileProgress(this.fileEl, this.ref, 100, () => {
+ LiveUploader.untrackFile(this.fileEl, this.file);
+ this._onDone();
+ });
+ } else {
+ this._lastProgressSent = this._progress;
+ this.view.pushFileProgress(this.fileEl, this.ref, this._progress);
+ }
+ }
+ }
+ isCancelled() {
+ return this._isCancelled;
+ }
+ cancel() {
+ this.file._preflightInProgress = false;
+ this._isCancelled = true;
+ this._isDone = true;
+ this._onDone();
+ }
+ isDone() {
+ return this._isDone;
+ }
+ error(reason = "failed") {
+ this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);
+ this.view.pushFileProgress(this.fileEl, this.ref, { error: reason });
+ if (!this.isAutoUpload()) {
+ LiveUploader.clearFiles(this.fileEl);
+ }
+ }
+ isAutoUpload() {
+ return this.autoUpload;
+ }
+ onDone(callback) {
+ this._onDone = () => {
+ this.fileEl.removeEventListener(PHX_LIVE_FILE_UPDATED, this._onElUpdated);
+ callback();
+ };
+ }
+ onElUpdated() {
+ let activeRefs = this.fileEl.getAttribute(PHX_ACTIVE_ENTRY_REFS).split(",");
+ if (activeRefs.indexOf(this.ref) === -1) {
+ LiveUploader.untrackFile(this.fileEl, this.file);
+ this.cancel();
+ }
+ }
+ toPreflightPayload() {
+ return {
+ last_modified: this.file.lastModified,
+ name: this.file.name,
+ relative_path: this.file.webkitRelativePath,
+ size: this.file.size,
+ type: this.file.type,
+ ref: this.ref,
+ meta: typeof this.file.meta === "function" ? this.file.meta() : void 0
+ };
+ }
+ uploader(uploaders) {
+ if (this.meta.uploader) {
+ let callback = uploaders[this.meta.uploader] || logError(`no uploader configured for ${this.meta.uploader}`);
+ return { name: this.meta.uploader, callback };
+ } else {
+ return { name: "channel", callback: channelUploader };
+ }
+ }
+ zipPostFlight(resp) {
+ this.meta = resp.entries[this.ref];
+ if (!this.meta) {
+ logError(`no preflight upload response returned with ref ${this.ref}`, { input: this.fileEl, response: resp });
+ }
+ }
+ };
+ var liveUploaderFileRef = 0;
+ var LiveUploader = class {
+ static genFileRef(file) {
+ let ref = file._phxRef;
+ if (ref !== void 0) {
+ return ref;
+ } else {
+ file._phxRef = (liveUploaderFileRef++).toString();
+ return file._phxRef;
+ }
+ }
+ static getEntryDataURL(inputEl, ref, callback) {
+ let file = this.activeFiles(inputEl).find((file2) => this.genFileRef(file2) === ref);
+ callback(URL.createObjectURL(file));
+ }
+ static hasUploadsInProgress(formEl) {
+ let active = 0;
+ dom_default.findUploadInputs(formEl).forEach((input) => {
+ if (input.getAttribute(PHX_PREFLIGHTED_REFS) !== input.getAttribute(PHX_DONE_REFS)) {
+ active++;
+ }
+ });
+ return active > 0;
+ }
+ static serializeUploads(inputEl) {
+ let files = this.activeFiles(inputEl);
+ let fileData = {};
+ files.forEach((file) => {
+ let entry = { path: inputEl.name };
+ let uploadRef = inputEl.getAttribute(PHX_UPLOAD_REF);
+ fileData[uploadRef] = fileData[uploadRef] || [];
+ entry.ref = this.genFileRef(file);
+ entry.last_modified = file.lastModified;
+ entry.name = file.name || entry.ref;
+ entry.relative_path = file.webkitRelativePath;
+ entry.type = file.type;
+ entry.size = file.size;
+ if (typeof file.meta === "function") {
+ entry.meta = file.meta();
+ }
+ fileData[uploadRef].push(entry);
+ });
+ return fileData;
+ }
+ static clearFiles(inputEl) {
+ inputEl.value = null;
+ inputEl.removeAttribute(PHX_UPLOAD_REF);
+ dom_default.putPrivate(inputEl, "files", []);
+ }
+ static untrackFile(inputEl, file) {
+ dom_default.putPrivate(inputEl, "files", dom_default.private(inputEl, "files").filter((f) => !Object.is(f, file)));
+ }
+ static trackFiles(inputEl, files, dataTransfer) {
+ if (inputEl.getAttribute("multiple") !== null) {
+ let newFiles = files.filter((file) => !this.activeFiles(inputEl).find((f) => Object.is(f, file)));
+ dom_default.updatePrivate(inputEl, "files", [], (existing) => existing.concat(newFiles));
+ inputEl.value = null;
+ } else {
+ if (dataTransfer && dataTransfer.files.length > 0) {
+ inputEl.files = dataTransfer.files;
+ }
+ dom_default.putPrivate(inputEl, "files", files);
+ }
+ }
+ static activeFileInputs(formEl) {
+ let fileInputs = dom_default.findUploadInputs(formEl);
+ return Array.from(fileInputs).filter((el) => el.files && this.activeFiles(el).length > 0);
+ }
+ static activeFiles(input) {
+ return (dom_default.private(input, "files") || []).filter((f) => UploadEntry.isActive(input, f));
+ }
+ static inputsAwaitingPreflight(formEl) {
+ let fileInputs = dom_default.findUploadInputs(formEl);
+ return Array.from(fileInputs).filter((input) => this.filesAwaitingPreflight(input).length > 0);
+ }
+ static filesAwaitingPreflight(input) {
+ return this.activeFiles(input).filter((f) => !UploadEntry.isPreflighted(input, f) && !UploadEntry.isPreflightInProgress(f));
+ }
+ static markPreflightInProgress(entries) {
+ entries.forEach((entry) => UploadEntry.markPreflightInProgress(entry.file));
+ }
+ constructor(inputEl, view, onComplete) {
+ this.autoUpload = dom_default.isAutoUpload(inputEl);
+ this.view = view;
+ this.onComplete = onComplete;
+ this._entries = Array.from(LiveUploader.filesAwaitingPreflight(inputEl) || []).map((file) => new UploadEntry(inputEl, file, view, this.autoUpload));
+ LiveUploader.markPreflightInProgress(this._entries);
+ this.numEntriesInProgress = this._entries.length;
+ }
+ isAutoUpload() {
+ return this.autoUpload;
+ }
+ entries() {
+ return this._entries;
+ }
+ initAdapterUpload(resp, onError, liveSocket2) {
+ this._entries = this._entries.map((entry) => {
+ if (entry.isCancelled()) {
+ this.numEntriesInProgress--;
+ if (this.numEntriesInProgress === 0) {
+ this.onComplete();
+ }
+ } else {
+ entry.zipPostFlight(resp);
+ entry.onDone(() => {
+ this.numEntriesInProgress--;
+ if (this.numEntriesInProgress === 0) {
+ this.onComplete();
+ }
+ });
+ }
+ return entry;
+ });
+ let groupedEntries = this._entries.reduce((acc, entry) => {
+ if (!entry.meta) {
+ return acc;
+ }
+ let { name, callback } = entry.uploader(liveSocket2.uploaders);
+ acc[name] = acc[name] || { callback, entries: [] };
+ acc[name].entries.push(entry);
+ return acc;
+ }, {});
+ for (let name in groupedEntries) {
+ let { callback, entries } = groupedEntries[name];
+ callback(entries, onError, resp, liveSocket2);
+ }
+ }
+ };
+ var Hooks = {
+ LiveFileUpload: {
+ activeRefs() {
+ return this.el.getAttribute(PHX_ACTIVE_ENTRY_REFS);
+ },
+ preflightedRefs() {
+ return this.el.getAttribute(PHX_PREFLIGHTED_REFS);
+ },
+ mounted() {
+ this.preflightedWas = this.preflightedRefs();
+ },
+ updated() {
+ let newPreflights = this.preflightedRefs();
+ if (this.preflightedWas !== newPreflights) {
+ this.preflightedWas = newPreflights;
+ if (newPreflights === "") {
+ this.__view.cancelSubmit(this.el.form);
+ }
+ }
+ if (this.activeRefs() === "") {
+ this.el.value = null;
+ }
+ this.el.dispatchEvent(new CustomEvent(PHX_LIVE_FILE_UPDATED));
+ }
+ },
+ LiveImgPreview: {
+ mounted() {
+ this.ref = this.el.getAttribute("data-phx-entry-ref");
+ this.inputEl = document.getElementById(this.el.getAttribute(PHX_UPLOAD_REF));
+ LiveUploader.getEntryDataURL(this.inputEl, this.ref, (url) => {
+ this.url = url;
+ this.el.src = url;
+ });
+ },
+ destroyed() {
+ URL.revokeObjectURL(this.url);
+ }
+ },
+ FocusWrap: {
+ mounted() {
+ this.focusStart = this.el.firstElementChild;
+ this.focusEnd = this.el.lastElementChild;
+ this.focusStart.addEventListener("focus", () => aria_default.focusLast(this.el));
+ this.focusEnd.addEventListener("focus", () => aria_default.focusFirst(this.el));
+ this.el.addEventListener("phx:show-end", () => this.el.focus());
+ if (window.getComputedStyle(this.el).display !== "none") {
+ aria_default.focusFirst(this.el);
+ }
+ }
+ }
+ };
+ var findScrollContainer = (el) => {
+ if (["HTML", "BODY"].indexOf(el.nodeName.toUpperCase()) >= 0)
+ return null;
+ if (["scroll", "auto"].indexOf(getComputedStyle(el).overflowY) >= 0)
+ return el;
+ return findScrollContainer(el.parentElement);
+ };
+ var scrollTop = (scrollContainer) => {
+ if (scrollContainer) {
+ return scrollContainer.scrollTop;
+ } else {
+ return document.documentElement.scrollTop || document.body.scrollTop;
+ }
+ };
+ var bottom = (scrollContainer) => {
+ if (scrollContainer) {
+ return scrollContainer.getBoundingClientRect().bottom;
+ } else {
+ return window.innerHeight || document.documentElement.clientHeight;
+ }
+ };
+ var top = (scrollContainer) => {
+ if (scrollContainer) {
+ return scrollContainer.getBoundingClientRect().top;
+ } else {
+ return 0;
+ }
+ };
+ var isAtViewportTop = (el, scrollContainer) => {
+ let rect = el.getBoundingClientRect();
+ return rect.top >= top(scrollContainer) && rect.left >= 0 && rect.top <= bottom(scrollContainer);
+ };
+ var isAtViewportBottom = (el, scrollContainer) => {
+ let rect = el.getBoundingClientRect();
+ return rect.right >= top(scrollContainer) && rect.left >= 0 && rect.bottom <= bottom(scrollContainer);
+ };
+ var isWithinViewport = (el, scrollContainer) => {
+ let rect = el.getBoundingClientRect();
+ return rect.top >= top(scrollContainer) && rect.left >= 0 && rect.top <= bottom(scrollContainer);
+ };
+ Hooks.InfiniteScroll = {
+ mounted() {
+ this.scrollContainer = findScrollContainer(this.el);
+ let scrollBefore = scrollTop(this.scrollContainer);
+ let topOverran = false;
+ let throttleInterval = 500;
+ let pendingOp = null;
+ let onTopOverrun = this.throttle(throttleInterval, (topEvent, firstChild) => {
+ pendingOp = () => true;
+ this.liveSocket.execJSHookPush(this.el, topEvent, { id: firstChild.id, _overran: true }, () => {
+ pendingOp = null;
+ });
+ });
+ let onFirstChildAtTop = this.throttle(throttleInterval, (topEvent, firstChild) => {
+ pendingOp = () => firstChild.scrollIntoView({ block: "start" });
+ this.liveSocket.execJSHookPush(this.el, topEvent, { id: firstChild.id }, () => {
+ pendingOp = null;
+ window.requestAnimationFrame(() => {
+ if (!isWithinViewport(firstChild, this.scrollContainer)) {
+ firstChild.scrollIntoView({ block: "start" });
+ }
+ });
+ });
+ });
+ let onLastChildAtBottom = this.throttle(throttleInterval, (bottomEvent, lastChild) => {
+ pendingOp = () => lastChild.scrollIntoView({ block: "end" });
+ this.liveSocket.execJSHookPush(this.el, bottomEvent, { id: lastChild.id }, () => {
+ pendingOp = null;
+ window.requestAnimationFrame(() => {
+ if (!isWithinViewport(lastChild, this.scrollContainer)) {
+ lastChild.scrollIntoView({ block: "end" });
+ }
+ });
+ });
+ });
+ this.onScroll = (_e) => {
+ let scrollNow = scrollTop(this.scrollContainer);
+ if (pendingOp) {
+ scrollBefore = scrollNow;
+ return pendingOp();
+ }
+ let rect = this.el.getBoundingClientRect();
+ let topEvent = this.el.getAttribute(this.liveSocket.binding("viewport-top"));
+ let bottomEvent = this.el.getAttribute(this.liveSocket.binding("viewport-bottom"));
+ let lastChild = this.el.lastElementChild;
+ let firstChild = this.el.firstElementChild;
+ let isScrollingUp = scrollNow < scrollBefore;
+ let isScrollingDown = scrollNow > scrollBefore;
+ if (isScrollingUp && topEvent && !topOverran && rect.top >= 0) {
+ topOverran = true;
+ onTopOverrun(topEvent, firstChild);
+ } else if (isScrollingDown && topOverran && rect.top <= 0) {
+ topOverran = false;
+ }
+ if (topEvent && isScrollingUp && isAtViewportTop(firstChild, this.scrollContainer)) {
+ onFirstChildAtTop(topEvent, firstChild);
+ } else if (bottomEvent && isScrollingDown && isAtViewportBottom(lastChild, this.scrollContainer)) {
+ onLastChildAtBottom(bottomEvent, lastChild);
+ }
+ scrollBefore = scrollNow;
+ };
+ if (this.scrollContainer) {
+ this.scrollContainer.addEventListener("scroll", this.onScroll);
+ } else {
+ window.addEventListener("scroll", this.onScroll);
+ }
+ },
+ destroyed() {
+ if (this.scrollContainer) {
+ this.scrollContainer.removeEventListener("scroll", this.onScroll);
+ } else {
+ window.removeEventListener("scroll", this.onScroll);
+ }
+ },
+ throttle(interval, callback) {
+ let lastCallAt = 0;
+ let timer;
+ return (...args) => {
+ let now = Date.now();
+ let remainingTime = interval - (now - lastCallAt);
+ if (remainingTime <= 0 || remainingTime > interval) {
+ if (timer) {
+ clearTimeout(timer);
+ timer = null;
+ }
+ lastCallAt = now;
+ callback(...args);
+ } else if (!timer) {
+ timer = setTimeout(() => {
+ lastCallAt = Date.now();
+ timer = null;
+ callback(...args);
+ }, remainingTime);
+ }
+ };
+ }
+ };
+ var hooks_default = Hooks;
+ var DOMPostMorphRestorer = class {
+ constructor(containerBefore, containerAfter, updateType) {
+ let idsBefore = /* @__PURE__ */ new Set();
+ let idsAfter = new Set([...containerAfter.children].map((child) => child.id));
+ let elementsToModify = [];
+ Array.from(containerBefore.children).forEach((child) => {
+ if (child.id) {
+ idsBefore.add(child.id);
+ if (idsAfter.has(child.id)) {
+ let previousElementId = child.previousElementSibling && child.previousElementSibling.id;
+ elementsToModify.push({ elementId: child.id, previousElementId });
+ }
+ }
+ });
+ this.containerId = containerAfter.id;
+ this.updateType = updateType;
+ this.elementsToModify = elementsToModify;
+ this.elementIdsToAdd = [...idsAfter].filter((id) => !idsBefore.has(id));
+ }
+ perform() {
+ let container = dom_default.byId(this.containerId);
+ this.elementsToModify.forEach((elementToModify) => {
+ if (elementToModify.previousElementId) {
+ maybe(document.getElementById(elementToModify.previousElementId), (previousElem) => {
+ maybe(document.getElementById(elementToModify.elementId), (elem) => {
+ let isInRightPlace = elem.previousElementSibling && elem.previousElementSibling.id == previousElem.id;
+ if (!isInRightPlace) {
+ previousElem.insertAdjacentElement("afterend", elem);
+ }
+ });
+ });
+ } else {
+ maybe(document.getElementById(elementToModify.elementId), (elem) => {
+ let isInRightPlace = elem.previousElementSibling == null;
+ if (!isInRightPlace) {
+ container.insertAdjacentElement("afterbegin", elem);
+ }
+ });
+ }
+ });
+ if (this.updateType == "prepend") {
+ this.elementIdsToAdd.reverse().forEach((elemId) => {
+ maybe(document.getElementById(elemId), (elem) => container.insertAdjacentElement("afterbegin", elem));
+ });
+ }
+ }
+ };
+ var DOCUMENT_FRAGMENT_NODE = 11;
+ function morphAttrs(fromNode, toNode) {
+ var toNodeAttrs = toNode.attributes;
+ var attr;
+ var attrName;
+ var attrNamespaceURI;
+ var attrValue;
+ var fromValue;
+ if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE || fromNode.nodeType === DOCUMENT_FRAGMENT_NODE) {
+ return;
+ }
+ for (var i = toNodeAttrs.length - 1; i >= 0; i--) {
+ attr = toNodeAttrs[i];
+ attrName = attr.name;
+ attrNamespaceURI = attr.namespaceURI;
+ attrValue = attr.value;
+ if (attrNamespaceURI) {
+ attrName = attr.localName || attrName;
+ fromValue = fromNode.getAttributeNS(attrNamespaceURI, attrName);
+ if (fromValue !== attrValue) {
+ if (attr.prefix === "xmlns") {
+ attrName = attr.name;
+ }
+ fromNode.setAttributeNS(attrNamespaceURI, attrName, attrValue);
+ }
+ } else {
+ fromValue = fromNode.getAttribute(attrName);
+ if (fromValue !== attrValue) {
+ fromNode.setAttribute(attrName, attrValue);
+ }
+ }
+ }
+ var fromNodeAttrs = fromNode.attributes;
+ for (var d = fromNodeAttrs.length - 1; d >= 0; d--) {
+ attr = fromNodeAttrs[d];
+ attrName = attr.name;
+ attrNamespaceURI = attr.namespaceURI;
+ if (attrNamespaceURI) {
+ attrName = attr.localName || attrName;
+ if (!toNode.hasAttributeNS(attrNamespaceURI, attrName)) {
+ fromNode.removeAttributeNS(attrNamespaceURI, attrName);
+ }
+ } else {
+ if (!toNode.hasAttribute(attrName)) {
+ fromNode.removeAttribute(attrName);
+ }
+ }
+ }
+ }
+ var range;
+ var NS_XHTML = "http://www.w3.org/1999/xhtml";
+ var doc = typeof document === "undefined" ? void 0 : document;
+ var HAS_TEMPLATE_SUPPORT = !!doc && "content" in doc.createElement("template");
+ var HAS_RANGE_SUPPORT = !!doc && doc.createRange && "createContextualFragment" in doc.createRange();
+ function createFragmentFromTemplate(str) {
+ var template = doc.createElement("template");
+ template.innerHTML = str;
+ return template.content.childNodes[0];
+ }
+ function createFragmentFromRange(str) {
+ if (!range) {
+ range = doc.createRange();
+ range.selectNode(doc.body);
+ }
+ var fragment = range.createContextualFragment(str);
+ return fragment.childNodes[0];
+ }
+ function createFragmentFromWrap(str) {
+ var fragment = doc.createElement("body");
+ fragment.innerHTML = str;
+ return fragment.childNodes[0];
+ }
+ function toElement(str) {
+ str = str.trim();
+ if (HAS_TEMPLATE_SUPPORT) {
+ return createFragmentFromTemplate(str);
+ } else if (HAS_RANGE_SUPPORT) {
+ return createFragmentFromRange(str);
+ }
+ return createFragmentFromWrap(str);
+ }
+ function compareNodeNames(fromEl, toEl) {
+ var fromNodeName = fromEl.nodeName;
+ var toNodeName = toEl.nodeName;
+ var fromCodeStart, toCodeStart;
+ if (fromNodeName === toNodeName) {
+ return true;
+ }
+ fromCodeStart = fromNodeName.charCodeAt(0);
+ toCodeStart = toNodeName.charCodeAt(0);
+ if (fromCodeStart <= 90 && toCodeStart >= 97) {
+ return fromNodeName === toNodeName.toUpperCase();
+ } else if (toCodeStart <= 90 && fromCodeStart >= 97) {
+ return toNodeName === fromNodeName.toUpperCase();
+ } else {
+ return false;
+ }
+ }
+ function createElementNS(name, namespaceURI) {
+ return !namespaceURI || namespaceURI === NS_XHTML ? doc.createElement(name) : doc.createElementNS(namespaceURI, name);
+ }
+ function moveChildren(fromEl, toEl) {
+ var curChild = fromEl.firstChild;
+ while (curChild) {
+ var nextChild = curChild.nextSibling;
+ toEl.appendChild(curChild);
+ curChild = nextChild;
+ }
+ return toEl;
+ }
+ function syncBooleanAttrProp(fromEl, toEl, name) {
+ if (fromEl[name] !== toEl[name]) {
+ fromEl[name] = toEl[name];
+ if (fromEl[name]) {
+ fromEl.setAttribute(name, "");
+ } else {
+ fromEl.removeAttribute(name);
+ }
+ }
+ }
+ var specialElHandlers = {
+ OPTION: function(fromEl, toEl) {
+ var parentNode = fromEl.parentNode;
+ if (parentNode) {
+ var parentName = parentNode.nodeName.toUpperCase();
+ if (parentName === "OPTGROUP") {
+ parentNode = parentNode.parentNode;
+ parentName = parentNode && parentNode.nodeName.toUpperCase();
+ }
+ if (parentName === "SELECT" && !parentNode.hasAttribute("multiple")) {
+ if (fromEl.hasAttribute("selected") && !toEl.selected) {
+ fromEl.setAttribute("selected", "selected");
+ fromEl.removeAttribute("selected");
+ }
+ parentNode.selectedIndex = -1;
+ }
+ }
+ syncBooleanAttrProp(fromEl, toEl, "selected");
+ },
+ INPUT: function(fromEl, toEl) {
+ syncBooleanAttrProp(fromEl, toEl, "checked");
+ syncBooleanAttrProp(fromEl, toEl, "disabled");
+ if (fromEl.value !== toEl.value) {
+ fromEl.value = toEl.value;
+ }
+ if (!toEl.hasAttribute("value")) {
+ fromEl.removeAttribute("value");
+ }
+ },
+ TEXTAREA: function(fromEl, toEl) {
+ var newValue = toEl.value;
+ if (fromEl.value !== newValue) {
+ fromEl.value = newValue;
+ }
+ var firstChild = fromEl.firstChild;
+ if (firstChild) {
+ var oldValue = firstChild.nodeValue;
+ if (oldValue == newValue || !newValue && oldValue == fromEl.placeholder) {
+ return;
+ }
+ firstChild.nodeValue = newValue;
+ }
+ },
+ SELECT: function(fromEl, toEl) {
+ if (!toEl.hasAttribute("multiple")) {
+ var selectedIndex = -1;
+ var i = 0;
+ var curChild = fromEl.firstChild;
+ var optgroup;
+ var nodeName;
+ while (curChild) {
+ nodeName = curChild.nodeName && curChild.nodeName.toUpperCase();
+ if (nodeName === "OPTGROUP") {
+ optgroup = curChild;
+ curChild = optgroup.firstChild;
+ } else {
+ if (nodeName === "OPTION") {
+ if (curChild.hasAttribute("selected")) {
+ selectedIndex = i;
+ break;
+ }
+ i++;
+ }
+ curChild = curChild.nextSibling;
+ if (!curChild && optgroup) {
+ curChild = optgroup.nextSibling;
+ optgroup = null;
+ }
+ }
+ }
+ fromEl.selectedIndex = selectedIndex;
+ }
+ }
+ };
+ var ELEMENT_NODE = 1;
+ var DOCUMENT_FRAGMENT_NODE$1 = 11;
+ var TEXT_NODE = 3;
+ var COMMENT_NODE = 8;
+ function noop() {
+ }
+ function defaultGetNodeKey(node) {
+ if (node) {
+ return node.getAttribute && node.getAttribute("id") || node.id;
+ }
+ }
+ function morphdomFactory(morphAttrs2) {
+ return function morphdom2(fromNode, toNode, options) {
+ if (!options) {
+ options = {};
+ }
+ if (typeof toNode === "string") {
+ if (fromNode.nodeName === "#document" || fromNode.nodeName === "HTML" || fromNode.nodeName === "BODY") {
+ var toNodeHtml = toNode;
+ toNode = doc.createElement("html");
+ toNode.innerHTML = toNodeHtml;
+ } else {
+ toNode = toElement(toNode);
+ }
+ } else if (toNode.nodeType === DOCUMENT_FRAGMENT_NODE$1) {
+ toNode = toNode.firstElementChild;
+ }
+ var getNodeKey = options.getNodeKey || defaultGetNodeKey;
+ var onBeforeNodeAdded = options.onBeforeNodeAdded || noop;
+ var onNodeAdded = options.onNodeAdded || noop;
+ var onBeforeElUpdated = options.onBeforeElUpdated || noop;
+ var onElUpdated = options.onElUpdated || noop;
+ var onBeforeNodeDiscarded = options.onBeforeNodeDiscarded || noop;
+ var onNodeDiscarded = options.onNodeDiscarded || noop;
+ var onBeforeElChildrenUpdated = options.onBeforeElChildrenUpdated || noop;
+ var skipFromChildren = options.skipFromChildren || noop;
+ var addChild = options.addChild || function(parent, child) {
+ return parent.appendChild(child);
+ };
+ var childrenOnly = options.childrenOnly === true;
+ var fromNodesLookup = /* @__PURE__ */ Object.create(null);
+ var keyedRemovalList = [];
+ function addKeyedRemoval(key) {
+ keyedRemovalList.push(key);
+ }
+ function walkDiscardedChildNodes(node, skipKeyedNodes) {
+ if (node.nodeType === ELEMENT_NODE) {
+ var curChild = node.firstChild;
+ while (curChild) {
+ var key = void 0;
+ if (skipKeyedNodes && (key = getNodeKey(curChild))) {
+ addKeyedRemoval(key);
+ } else {
+ onNodeDiscarded(curChild);
+ if (curChild.firstChild) {
+ walkDiscardedChildNodes(curChild, skipKeyedNodes);
+ }
+ }
+ curChild = curChild.nextSibling;
+ }
+ }
+ }
+ function removeNode(node, parentNode, skipKeyedNodes) {
+ if (onBeforeNodeDiscarded(node) === false) {
+ return;
+ }
+ if (parentNode) {
+ parentNode.removeChild(node);
+ }
+ onNodeDiscarded(node);
+ walkDiscardedChildNodes(node, skipKeyedNodes);
+ }
+ function indexTree(node) {
+ if (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE$1) {
+ var curChild = node.firstChild;
+ while (curChild) {
+ var key = getNodeKey(curChild);
+ if (key) {
+ fromNodesLookup[key] = curChild;
+ }
+ indexTree(curChild);
+ curChild = curChild.nextSibling;
+ }
+ }
+ }
+ indexTree(fromNode);
+ function handleNodeAdded(el) {
+ onNodeAdded(el);
+ var curChild = el.firstChild;
+ while (curChild) {
+ var nextSibling = curChild.nextSibling;
+ var key = getNodeKey(curChild);
+ if (key) {
+ var unmatchedFromEl = fromNodesLookup[key];
+ if (unmatchedFromEl && compareNodeNames(curChild, unmatchedFromEl)) {
+ curChild.parentNode.replaceChild(unmatchedFromEl, curChild);
+ morphEl(unmatchedFromEl, curChild);
+ } else {
+ handleNodeAdded(curChild);
+ }
+ } else {
+ handleNodeAdded(curChild);
+ }
+ curChild = nextSibling;
+ }
+ }
+ function cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey) {
+ while (curFromNodeChild) {
+ var fromNextSibling = curFromNodeChild.nextSibling;
+ if (curFromNodeKey = getNodeKey(curFromNodeChild)) {
+ addKeyedRemoval(curFromNodeKey);
+ } else {
+ removeNode(curFromNodeChild, fromEl, true);
+ }
+ curFromNodeChild = fromNextSibling;
+ }
+ }
+ function morphEl(fromEl, toEl, childrenOnly2) {
+ var toElKey = getNodeKey(toEl);
+ if (toElKey) {
+ delete fromNodesLookup[toElKey];
+ }
+ if (!childrenOnly2) {
+ if (onBeforeElUpdated(fromEl, toEl) === false) {
+ return;
+ }
+ morphAttrs2(fromEl, toEl);
+ onElUpdated(fromEl);
+ if (onBeforeElChildrenUpdated(fromEl, toEl) === false) {
+ return;
+ }
+ }
+ if (fromEl.nodeName !== "TEXTAREA") {
+ morphChildren(fromEl, toEl);
+ } else {
+ specialElHandlers.TEXTAREA(fromEl, toEl);
+ }
+ }
+ function morphChildren(fromEl, toEl) {
+ var skipFrom = skipFromChildren(fromEl, toEl);
+ var curToNodeChild = toEl.firstChild;
+ var curFromNodeChild = fromEl.firstChild;
+ var curToNodeKey;
+ var curFromNodeKey;
+ var fromNextSibling;
+ var toNextSibling;
+ var matchingFromEl;
+ outer:
+ while (curToNodeChild) {
+ toNextSibling = curToNodeChild.nextSibling;
+ curToNodeKey = getNodeKey(curToNodeChild);
+ while (!skipFrom && curFromNodeChild) {
+ fromNextSibling = curFromNodeChild.nextSibling;
+ if (curToNodeChild.isSameNode && curToNodeChild.isSameNode(curFromNodeChild)) {
+ curToNodeChild = toNextSibling;
+ curFromNodeChild = fromNextSibling;
+ continue outer;
+ }
+ curFromNodeKey = getNodeKey(curFromNodeChild);
+ var curFromNodeType = curFromNodeChild.nodeType;
+ var isCompatible = void 0;
+ if (curFromNodeType === curToNodeChild.nodeType) {
+ if (curFromNodeType === ELEMENT_NODE) {
+ if (curToNodeKey) {
+ if (curToNodeKey !== curFromNodeKey) {
+ if (matchingFromEl = fromNodesLookup[curToNodeKey]) {
+ if (fromNextSibling === matchingFromEl) {
+ isCompatible = false;
+ } else {
+ fromEl.insertBefore(matchingFromEl, curFromNodeChild);
+ if (curFromNodeKey) {
+ addKeyedRemoval(curFromNodeKey);
+ } else {
+ removeNode(curFromNodeChild, fromEl, true);
+ }
+ curFromNodeChild = matchingFromEl;
+ curFromNodeKey = getNodeKey(curFromNodeChild);
+ }
+ } else {
+ isCompatible = false;
+ }
+ }
+ } else if (curFromNodeKey) {
+ isCompatible = false;
+ }
+ isCompatible = isCompatible !== false && compareNodeNames(curFromNodeChild, curToNodeChild);
+ if (isCompatible) {
+ morphEl(curFromNodeChild, curToNodeChild);
+ }
+ } else if (curFromNodeType === TEXT_NODE || curFromNodeType == COMMENT_NODE) {
+ isCompatible = true;
+ if (curFromNodeChild.nodeValue !== curToNodeChild.nodeValue) {
+ curFromNodeChild.nodeValue = curToNodeChild.nodeValue;
+ }
+ }
+ }
+ if (isCompatible) {
+ curToNodeChild = toNextSibling;
+ curFromNodeChild = fromNextSibling;
+ continue outer;
+ }
+ if (curFromNodeKey) {
+ addKeyedRemoval(curFromNodeKey);
+ } else {
+ removeNode(curFromNodeChild, fromEl, true);
+ }
+ curFromNodeChild = fromNextSibling;
+ }
+ if (curToNodeKey && (matchingFromEl = fromNodesLookup[curToNodeKey]) && compareNodeNames(matchingFromEl, curToNodeChild)) {
+ if (!skipFrom) {
+ addChild(fromEl, matchingFromEl);
+ }
+ morphEl(matchingFromEl, curToNodeChild);
+ } else {
+ var onBeforeNodeAddedResult = onBeforeNodeAdded(curToNodeChild);
+ if (onBeforeNodeAddedResult !== false) {
+ if (onBeforeNodeAddedResult) {
+ curToNodeChild = onBeforeNodeAddedResult;
+ }
+ if (curToNodeChild.actualize) {
+ curToNodeChild = curToNodeChild.actualize(fromEl.ownerDocument || doc);
+ }
+ addChild(fromEl, curToNodeChild);
+ handleNodeAdded(curToNodeChild);
+ }
+ }
+ curToNodeChild = toNextSibling;
+ curFromNodeChild = fromNextSibling;
+ }
+ cleanupFromEl(fromEl, curFromNodeChild, curFromNodeKey);
+ var specialElHandler = specialElHandlers[fromEl.nodeName];
+ if (specialElHandler) {
+ specialElHandler(fromEl, toEl);
+ }
+ }
+ var morphedNode = fromNode;
+ var morphedNodeType = morphedNode.nodeType;
+ var toNodeType = toNode.nodeType;
+ if (!childrenOnly) {
+ if (morphedNodeType === ELEMENT_NODE) {
+ if (toNodeType === ELEMENT_NODE) {
+ if (!compareNodeNames(fromNode, toNode)) {
+ onNodeDiscarded(fromNode);
+ morphedNode = moveChildren(fromNode, createElementNS(toNode.nodeName, toNode.namespaceURI));
+ }
+ } else {
+ morphedNode = toNode;
+ }
+ } else if (morphedNodeType === TEXT_NODE || morphedNodeType === COMMENT_NODE) {
+ if (toNodeType === morphedNodeType) {
+ if (morphedNode.nodeValue !== toNode.nodeValue) {
+ morphedNode.nodeValue = toNode.nodeValue;
+ }
+ return morphedNode;
+ } else {
+ morphedNode = toNode;
+ }
+ }
+ }
+ if (morphedNode === toNode) {
+ onNodeDiscarded(fromNode);
+ } else {
+ if (toNode.isSameNode && toNode.isSameNode(morphedNode)) {
+ return;
+ }
+ morphEl(morphedNode, toNode, childrenOnly);
+ if (keyedRemovalList) {
+ for (var i = 0, len = keyedRemovalList.length; i < len; i++) {
+ var elToRemove = fromNodesLookup[keyedRemovalList[i]];
+ if (elToRemove) {
+ removeNode(elToRemove, elToRemove.parentNode, false);
+ }
+ }
+ }
+ }
+ if (!childrenOnly && morphedNode !== fromNode && fromNode.parentNode) {
+ if (morphedNode.actualize) {
+ morphedNode = morphedNode.actualize(fromNode.ownerDocument || doc);
+ }
+ fromNode.parentNode.replaceChild(morphedNode, fromNode);
+ }
+ return morphedNode;
+ };
+ }
+ var morphdom = morphdomFactory(morphAttrs);
+ var morphdom_esm_default = morphdom;
+ var DOMPatch = class {
+ static patchEl(fromEl, toEl, activeElement) {
+ morphdom_esm_default(fromEl, toEl, {
+ childrenOnly: false,
+ onBeforeElUpdated: (fromEl2, toEl2) => {
+ if (activeElement && activeElement.isSameNode(fromEl2) && dom_default.isFormInput(fromEl2)) {
+ dom_default.mergeFocusedInput(fromEl2, toEl2);
+ return false;
+ }
+ }
+ });
+ }
+ constructor(view, container, id, html, streams, targetCID) {
+ this.view = view;
+ this.liveSocket = view.liveSocket;
+ this.container = container;
+ this.id = id;
+ this.rootID = view.root.id;
+ this.html = html;
+ this.streams = streams;
+ this.streamInserts = {};
+ this.streamComponentRestore = {};
+ this.targetCID = targetCID;
+ this.cidPatch = isCid(this.targetCID);
+ this.pendingRemoves = [];
+ this.phxRemove = this.liveSocket.binding("remove");
+ this.callbacks = {
+ beforeadded: [],
+ beforeupdated: [],
+ beforephxChildAdded: [],
+ afteradded: [],
+ afterupdated: [],
+ afterdiscarded: [],
+ afterphxChildAdded: [],
+ aftertransitionsDiscarded: []
+ };
+ }
+ before(kind, callback) {
+ this.callbacks[`before${kind}`].push(callback);
+ }
+ after(kind, callback) {
+ this.callbacks[`after${kind}`].push(callback);
+ }
+ trackBefore(kind, ...args) {
+ this.callbacks[`before${kind}`].forEach((callback) => callback(...args));
+ }
+ trackAfter(kind, ...args) {
+ this.callbacks[`after${kind}`].forEach((callback) => callback(...args));
+ }
+ markPrunableContentForRemoval() {
+ let phxUpdate = this.liveSocket.binding(PHX_UPDATE);
+ dom_default.all(this.container, `[${phxUpdate}=append] > *, [${phxUpdate}=prepend] > *`, (el) => {
+ el.setAttribute(PHX_PRUNE, "");
+ });
+ }
+ perform(isJoinPatch) {
+ let { view, liveSocket: liveSocket2, container, html } = this;
+ let targetContainer = this.isCIDPatch() ? this.targetCIDContainer(html) : container;
+ if (this.isCIDPatch() && !targetContainer) {
+ return;
+ }
+ let focused = liveSocket2.getActiveElement();
+ let { selectionStart, selectionEnd } = focused && dom_default.hasSelectionRange(focused) ? focused : {};
+ let phxUpdate = liveSocket2.binding(PHX_UPDATE);
+ let phxFeedbackFor = liveSocket2.binding(PHX_FEEDBACK_FOR);
+ let phxFeedbackGroup = liveSocket2.binding(PHX_FEEDBACK_GROUP);
+ let disableWith = liveSocket2.binding(PHX_DISABLE_WITH);
+ let phxViewportTop = liveSocket2.binding(PHX_VIEWPORT_TOP);
+ let phxViewportBottom = liveSocket2.binding(PHX_VIEWPORT_BOTTOM);
+ let phxTriggerExternal = liveSocket2.binding(PHX_TRIGGER_ACTION);
+ let added = [];
+ let feedbackContainers = [];
+ let updates = [];
+ let appendPrependUpdates = [];
+ let externalFormTriggered = null;
+ function morph(targetContainer2, source, withChildren = false) {
+ morphdom_esm_default(targetContainer2, source, {
+ childrenOnly: targetContainer2.getAttribute(PHX_COMPONENT) === null && !withChildren,
+ getNodeKey: (node) => {
+ if (dom_default.isPhxDestroyed(node)) {
+ return null;
+ }
+ if (isJoinPatch) {
+ return node.id;
+ }
+ return node.id || node.getAttribute && node.getAttribute(PHX_MAGIC_ID);
+ },
+ skipFromChildren: (from) => {
+ return from.getAttribute(phxUpdate) === PHX_STREAM;
+ },
+ addChild: (parent, child) => {
+ let { ref, streamAt } = this.getStreamInsert(child);
+ if (ref === void 0) {
+ return parent.appendChild(child);
+ }
+ this.setStreamRef(child, ref);
+ if (streamAt === 0) {
+ parent.insertAdjacentElement("afterbegin", child);
+ } else if (streamAt === -1) {
+ parent.appendChild(child);
+ } else if (streamAt > 0) {
+ let sibling = Array.from(parent.children)[streamAt];
+ parent.insertBefore(child, sibling);
+ }
+ },
+ onBeforeNodeAdded: (el) => {
+ dom_default.maybeAddPrivateHooks(el, phxViewportTop, phxViewportBottom);
+ this.trackBefore("added", el);
+ let morphedEl = el;
+ if (!isJoinPatch && this.streamComponentRestore[el.id]) {
+ morphedEl = this.streamComponentRestore[el.id];
+ delete this.streamComponentRestore[el.id];
+ morph.call(this, morphedEl, el, true);
+ }
+ return morphedEl;
+ },
+ onNodeAdded: (el) => {
+ if (el.getAttribute) {
+ this.maybeReOrderStream(el, true);
+ }
+ if (dom_default.isFeedbackContainer(el, phxFeedbackFor))
+ feedbackContainers.push(el);
+ if (el instanceof HTMLImageElement && el.srcset) {
+ el.srcset = el.srcset;
+ } else if (el instanceof HTMLVideoElement && el.autoplay) {
+ el.play();
+ }
+ if (dom_default.isNowTriggerFormExternal(el, phxTriggerExternal)) {
+ externalFormTriggered = el;
+ }
+ if (dom_default.isPhxChild(el) && view.ownsElement(el) || dom_default.isPhxSticky(el) && view.ownsElement(el.parentNode)) {
+ this.trackAfter("phxChildAdded", el);
+ }
+ added.push(el);
+ },
+ onNodeDiscarded: (el) => this.onNodeDiscarded(el),
+ onBeforeNodeDiscarded: (el) => {
+ if (el.getAttribute && el.getAttribute(PHX_PRUNE) !== null) {
+ return true;
+ }
+ if (el.parentElement !== null && el.id && dom_default.isPhxUpdate(el.parentElement, phxUpdate, [PHX_STREAM, "append", "prepend"])) {
+ return false;
+ }
+ if (this.maybePendingRemove(el)) {
+ return false;
+ }
+ if (this.skipCIDSibling(el)) {
+ return false;
+ }
+ return true;
+ },
+ onElUpdated: (el) => {
+ if (dom_default.isNowTriggerFormExternal(el, phxTriggerExternal)) {
+ externalFormTriggered = el;
+ }
+ updates.push(el);
+ this.maybeReOrderStream(el, false);
+ },
+ onBeforeElUpdated: (fromEl, toEl) => {
+ dom_default.maybeAddPrivateHooks(toEl, phxViewportTop, phxViewportBottom);
+ if (dom_default.isFeedbackContainer(fromEl, phxFeedbackFor) || dom_default.isFeedbackContainer(toEl, phxFeedbackFor)) {
+ feedbackContainers.push(fromEl);
+ feedbackContainers.push(toEl);
+ }
+ dom_default.cleanChildNodes(toEl, phxUpdate);
+ if (this.skipCIDSibling(toEl)) {
+ this.maybeReOrderStream(fromEl);
+ return false;
+ }
+ if (dom_default.isPhxSticky(fromEl)) {
+ return false;
+ }
+ if (dom_default.isIgnored(fromEl, phxUpdate) || fromEl.form && fromEl.form.isSameNode(externalFormTriggered)) {
+ this.trackBefore("updated", fromEl, toEl);
+ dom_default.mergeAttrs(fromEl, toEl, { isIgnored: dom_default.isIgnored(fromEl, phxUpdate) });
+ updates.push(fromEl);
+ dom_default.applyStickyOperations(fromEl);
+ return false;
+ }
+ if (fromEl.type === "number" && (fromEl.validity && fromEl.validity.badInput)) {
+ return false;
+ }
+ if (!dom_default.syncPendingRef(fromEl, toEl, disableWith)) {
+ if (dom_default.isUploadInput(fromEl)) {
+ this.trackBefore("updated", fromEl, toEl);
+ updates.push(fromEl);
+ }
+ dom_default.applyStickyOperations(fromEl);
+ return false;
+ }
+ if (dom_default.isPhxChild(toEl)) {
+ let prevSession = fromEl.getAttribute(PHX_SESSION);
+ dom_default.mergeAttrs(fromEl, toEl, { exclude: [PHX_STATIC] });
+ if (prevSession !== "") {
+ fromEl.setAttribute(PHX_SESSION, prevSession);
+ }
+ fromEl.setAttribute(PHX_ROOT_ID, this.rootID);
+ dom_default.applyStickyOperations(fromEl);
+ return false;
+ }
+ dom_default.copyPrivates(toEl, fromEl);
+ let isFocusedFormEl = focused && fromEl.isSameNode(focused) && dom_default.isFormInput(fromEl);
+ let focusedSelectChanged = isFocusedFormEl && this.isChangedSelect(fromEl, toEl);
+ if (isFocusedFormEl && fromEl.type !== "hidden" && !focusedSelectChanged) {
+ this.trackBefore("updated", fromEl, toEl);
+ dom_default.mergeFocusedInput(fromEl, toEl);
+ dom_default.syncAttrsToProps(fromEl);
+ updates.push(fromEl);
+ dom_default.applyStickyOperations(fromEl);
+ return false;
+ } else {
+ if (focusedSelectChanged) {
+ fromEl.blur();
+ }
+ if (dom_default.isPhxUpdate(toEl, phxUpdate, ["append", "prepend"])) {
+ appendPrependUpdates.push(new DOMPostMorphRestorer(fromEl, toEl, toEl.getAttribute(phxUpdate)));
+ }
+ dom_default.syncAttrsToProps(toEl);
+ dom_default.applyStickyOperations(toEl);
+ this.trackBefore("updated", fromEl, toEl);
+ return true;
+ }
+ }
+ });
+ }
+ this.trackBefore("added", container);
+ this.trackBefore("updated", container, container);
+ liveSocket2.time("morphdom", () => {
+ this.streams.forEach(([ref, inserts, deleteIds, reset]) => {
+ inserts.forEach(([key, streamAt, limit]) => {
+ this.streamInserts[key] = { ref, streamAt, limit, reset };
+ });
+ if (reset !== void 0) {
+ dom_default.all(container, `[${PHX_STREAM_REF}="${ref}"]`, (child) => {
+ this.removeStreamChildElement(child);
+ });
+ }
+ deleteIds.forEach((id) => {
+ let child = container.querySelector(`[id="${id}"]`);
+ if (child) {
+ this.removeStreamChildElement(child);
+ }
+ });
+ });
+ if (isJoinPatch) {
+ dom_default.all(this.container, `[${phxUpdate}=${PHX_STREAM}]`, (el) => {
+ this.liveSocket.owner(el, (view2) => {
+ if (view2 === this.view) {
+ Array.from(el.children).forEach((child) => {
+ this.removeStreamChildElement(child);
+ });
+ }
+ });
+ });
+ }
+ morph.call(this, targetContainer, html);
+ });
+ if (liveSocket2.isDebugEnabled()) {
+ detectDuplicateIds();
+ Array.from(document.querySelectorAll("input[name=id]")).forEach((node) => {
+ if (node.form) {
+ console.error('Detected an input with name="id" inside a form! This will cause problems when patching the DOM.\n', node);
+ }
+ });
+ }
+ if (appendPrependUpdates.length > 0) {
+ liveSocket2.time("post-morph append/prepend restoration", () => {
+ appendPrependUpdates.forEach((update) => update.perform());
+ });
+ }
+ dom_default.maybeHideFeedback(targetContainer, feedbackContainers, phxFeedbackFor, phxFeedbackGroup);
+ liveSocket2.silenceEvents(() => dom_default.restoreFocus(focused, selectionStart, selectionEnd));
+ dom_default.dispatchEvent(document, "phx:update");
+ added.forEach((el) => this.trackAfter("added", el));
+ updates.forEach((el) => this.trackAfter("updated", el));
+ this.transitionPendingRemoves();
+ if (externalFormTriggered) {
+ liveSocket2.unload();
+ Object.getPrototypeOf(externalFormTriggered).submit.call(externalFormTriggered);
+ }
+ return true;
+ }
+ onNodeDiscarded(el) {
+ if (dom_default.isPhxChild(el) || dom_default.isPhxSticky(el)) {
+ this.liveSocket.destroyViewByEl(el);
+ }
+ this.trackAfter("discarded", el);
+ }
+ maybePendingRemove(node) {
+ if (node.getAttribute && node.getAttribute(this.phxRemove) !== null) {
+ this.pendingRemoves.push(node);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ removeStreamChildElement(child) {
+ if (this.streamInserts[child.id]) {
+ this.streamComponentRestore[child.id] = child;
+ child.remove();
+ } else {
+ if (!this.maybePendingRemove(child)) {
+ child.remove();
+ this.onNodeDiscarded(child);
+ }
+ }
+ }
+ getStreamInsert(el) {
+ let insert = el.id ? this.streamInserts[el.id] : {};
+ return insert || {};
+ }
+ setStreamRef(el, ref) {
+ dom_default.putSticky(el, PHX_STREAM_REF, (el2) => el2.setAttribute(PHX_STREAM_REF, ref));
+ }
+ maybeReOrderStream(el, isNew) {
+ let { ref, streamAt, reset } = this.getStreamInsert(el);
+ if (streamAt === void 0) {
+ return;
+ }
+ this.setStreamRef(el, ref);
+ if (!reset && !isNew) {
+ return;
+ }
+ if (!el.parentElement) {
+ return;
+ }
+ if (streamAt === 0) {
+ el.parentElement.insertBefore(el, el.parentElement.firstElementChild);
+ } else if (streamAt > 0) {
+ let children = Array.from(el.parentElement.children);
+ let oldIndex = children.indexOf(el);
+ if (streamAt >= children.length - 1) {
+ el.parentElement.appendChild(el);
+ } else {
+ let sibling = children[streamAt];
+ if (oldIndex > streamAt) {
+ el.parentElement.insertBefore(el, sibling);
+ } else {
+ el.parentElement.insertBefore(el, sibling.nextElementSibling);
+ }
+ }
+ }
+ this.maybeLimitStream(el);
+ }
+ maybeLimitStream(el) {
+ let { limit } = this.getStreamInsert(el);
+ let children = limit !== null && Array.from(el.parentElement.children);
+ if (limit && limit < 0 && children.length > limit * -1) {
+ children.slice(0, children.length + limit).forEach((child) => this.removeStreamChildElement(child));
+ } else if (limit && limit >= 0 && children.length > limit) {
+ children.slice(limit).forEach((child) => this.removeStreamChildElement(child));
+ }
+ }
+ transitionPendingRemoves() {
+ let { pendingRemoves, liveSocket: liveSocket2 } = this;
+ if (pendingRemoves.length > 0) {
+ liveSocket2.transitionRemoves(pendingRemoves);
+ liveSocket2.requestDOMUpdate(() => {
+ pendingRemoves.forEach((el) => {
+ let child = dom_default.firstPhxChild(el);
+ if (child) {
+ liveSocket2.destroyViewByEl(child);
+ }
+ el.remove();
+ });
+ this.trackAfter("transitionsDiscarded", pendingRemoves);
+ });
+ }
+ }
+ isChangedSelect(fromEl, toEl) {
+ if (!(fromEl instanceof HTMLSelectElement) || fromEl.multiple) {
+ return false;
+ }
+ if (fromEl.options.length !== toEl.options.length) {
+ return true;
+ }
+ let fromSelected = fromEl.selectedOptions[0];
+ let toSelected = toEl.selectedOptions[0];
+ if (fromSelected && fromSelected.hasAttribute("selected")) {
+ toSelected.setAttribute("selected", fromSelected.getAttribute("selected"));
+ }
+ return !fromEl.isEqualNode(toEl);
+ }
+ isCIDPatch() {
+ return this.cidPatch;
+ }
+ skipCIDSibling(el) {
+ return el.nodeType === Node.ELEMENT_NODE && el.hasAttribute(PHX_SKIP);
+ }
+ targetCIDContainer(html) {
+ if (!this.isCIDPatch()) {
+ return;
+ }
+ let [first, ...rest] = dom_default.findComponentNodeList(this.container, this.targetCID);
+ if (rest.length === 0 && dom_default.childNodeLength(html) === 1) {
+ return first;
+ } else {
+ return first && first.parentNode;
+ }
+ }
+ indexOf(parent, child) {
+ return Array.from(parent.children).indexOf(child);
+ }
+ };
+ var VOID_TAGS = /* @__PURE__ */ new Set([
+ "area",
+ "base",
+ "br",
+ "col",
+ "command",
+ "embed",
+ "hr",
+ "img",
+ "input",
+ "keygen",
+ "link",
+ "meta",
+ "param",
+ "source",
+ "track",
+ "wbr"
+ ]);
+ var quoteChars = /* @__PURE__ */ new Set(["'", '"']);
+ var modifyRoot = (html, attrs, clearInnerHTML) => {
+ let i = 0;
+ let insideComment = false;
+ let beforeTag, afterTag, tag, tagNameEndsAt, id, newHTML;
+ let lookahead = html.match(/^(\s*(?:\s*)*)<([^\s\/>]+)/);
+ if (lookahead === null) {
+ throw new Error(`malformed html ${html}`);
+ }
+ i = lookahead[0].length;
+ beforeTag = lookahead[1];
+ tag = lookahead[2];
+ tagNameEndsAt = i;
+ for (i; i < html.length; i++) {
+ if (html.charAt(i) === ">") {
+ break;
+ }
+ if (html.charAt(i) === "=") {
+ let isId = html.slice(i - 3, i) === " id";
+ i++;
+ let char = html.charAt(i);
+ if (quoteChars.has(char)) {
+ let attrStartsAt = i;
+ i++;
+ for (i; i < html.length; i++) {
+ if (html.charAt(i) === char) {
+ break;
+ }
+ }
+ if (isId) {
+ id = html.slice(attrStartsAt + 1, i);
+ break;
+ }
+ }
+ }
+ }
+ let closeAt = html.length - 1;
+ insideComment = false;
+ while (closeAt >= beforeTag.length + tag.length) {
+ let char = html.charAt(closeAt);
+ if (insideComment) {
+ if (char === "-" && html.slice(closeAt - 3, closeAt) === "" && html.slice(closeAt - 2, closeAt) === "--") {
+ insideComment = true;
+ closeAt -= 3;
+ } else if (char === ">") {
+ break;
+ } else {
+ closeAt -= 1;
+ }
+ }
+ afterTag = html.slice(closeAt + 1, html.length);
+ let attrsStr = Object.keys(attrs).map((attr) => attrs[attr] === true ? attr : `${attr}="${attrs[attr]}"`).join(" ");
+ if (clearInnerHTML) {
+ let idAttrStr = id ? ` id="${id}"` : "";
+ if (VOID_TAGS.has(tag)) {
+ newHTML = `<${tag}${idAttrStr}${attrsStr === "" ? "" : " "}${attrsStr}/>`;
+ } else {
+ newHTML = `<${tag}${idAttrStr}${attrsStr === "" ? "" : " "}${attrsStr}>${tag}>`;
+ }
+ } else {
+ let rest = html.slice(tagNameEndsAt, closeAt + 1);
+ newHTML = `<${tag}${attrsStr === "" ? "" : " "}${attrsStr}${rest}`;
+ }
+ return [newHTML, beforeTag, afterTag];
+ };
+ var Rendered = class {
+ static extract(diff) {
+ let { [REPLY]: reply, [EVENTS]: events, [TITLE]: title } = diff;
+ delete diff[REPLY];
+ delete diff[EVENTS];
+ delete diff[TITLE];
+ return { diff, title, reply: reply || null, events: events || [] };
+ }
+ constructor(viewId, rendered) {
+ this.viewId = viewId;
+ this.rendered = {};
+ this.magicId = 0;
+ this.mergeDiff(rendered);
+ }
+ parentViewId() {
+ return this.viewId;
+ }
+ toString(onlyCids) {
+ let [str, streams] = this.recursiveToString(this.rendered, this.rendered[COMPONENTS], onlyCids, true, {});
+ return [str, streams];
+ }
+ recursiveToString(rendered, components = rendered[COMPONENTS], onlyCids, changeTracking, rootAttrs) {
+ onlyCids = onlyCids ? new Set(onlyCids) : null;
+ let output = { buffer: "", components, onlyCids, streams: /* @__PURE__ */ new Set() };
+ this.toOutputBuffer(rendered, null, output, changeTracking, rootAttrs);
+ return [output.buffer, output.streams];
+ }
+ componentCIDs(diff) {
+ return Object.keys(diff[COMPONENTS] || {}).map((i) => parseInt(i));
+ }
+ isComponentOnlyDiff(diff) {
+ if (!diff[COMPONENTS]) {
+ return false;
+ }
+ return Object.keys(diff).length === 1;
+ }
+ getComponent(diff, cid) {
+ return diff[COMPONENTS][cid];
+ }
+ resetRender(cid) {
+ if (this.rendered[COMPONENTS][cid]) {
+ this.rendered[COMPONENTS][cid].reset = true;
+ }
+ }
+ mergeDiff(diff) {
+ let newc = diff[COMPONENTS];
+ let cache = {};
+ delete diff[COMPONENTS];
+ this.rendered = this.mutableMerge(this.rendered, diff);
+ this.rendered[COMPONENTS] = this.rendered[COMPONENTS] || {};
+ if (newc) {
+ let oldc = this.rendered[COMPONENTS];
+ for (let cid in newc) {
+ newc[cid] = this.cachedFindComponent(cid, newc[cid], oldc, newc, cache);
+ }
+ for (let cid in newc) {
+ oldc[cid] = newc[cid];
+ }
+ diff[COMPONENTS] = newc;
+ }
+ }
+ cachedFindComponent(cid, cdiff, oldc, newc, cache) {
+ if (cache[cid]) {
+ return cache[cid];
+ } else {
+ let ndiff, stat, scid = cdiff[STATIC];
+ if (isCid(scid)) {
+ let tdiff;
+ if (scid > 0) {
+ tdiff = this.cachedFindComponent(scid, newc[scid], oldc, newc, cache);
+ } else {
+ tdiff = oldc[-scid];
+ }
+ stat = tdiff[STATIC];
+ ndiff = this.cloneMerge(tdiff, cdiff, true);
+ ndiff[STATIC] = stat;
+ } else {
+ ndiff = cdiff[STATIC] !== void 0 || oldc[cid] === void 0 ? cdiff : this.cloneMerge(oldc[cid], cdiff, false);
+ }
+ cache[cid] = ndiff;
+ return ndiff;
+ }
+ }
+ mutableMerge(target, source) {
+ if (source[STATIC] !== void 0) {
+ return source;
+ } else {
+ this.doMutableMerge(target, source);
+ return target;
+ }
+ }
+ doMutableMerge(target, source) {
+ for (let key in source) {
+ let val = source[key];
+ let targetVal = target[key];
+ let isObjVal = isObject(val);
+ if (isObjVal && val[STATIC] === void 0 && isObject(targetVal)) {
+ this.doMutableMerge(targetVal, val);
+ } else {
+ target[key] = val;
+ }
+ }
+ if (target[ROOT]) {
+ target.newRender = true;
+ }
+ }
+ cloneMerge(target, source, pruneMagicId) {
+ let merged = __spreadValues(__spreadValues({}, target), source);
+ for (let key in merged) {
+ let val = source[key];
+ let targetVal = target[key];
+ if (isObject(val) && val[STATIC] === void 0 && isObject(targetVal)) {
+ merged[key] = this.cloneMerge(targetVal, val, pruneMagicId);
+ } else if (val === void 0 && isObject(targetVal)) {
+ merged[key] = this.cloneMerge(targetVal, {}, pruneMagicId);
+ }
+ }
+ if (pruneMagicId) {
+ delete merged.magicId;
+ delete merged.newRender;
+ } else if (target[ROOT]) {
+ merged.newRender = true;
+ }
+ return merged;
+ }
+ componentToString(cid) {
+ let [str, streams] = this.recursiveCIDToString(this.rendered[COMPONENTS], cid, null);
+ let [strippedHTML, _before, _after] = modifyRoot(str, {});
+ return [strippedHTML, streams];
+ }
+ pruneCIDs(cids) {
+ cids.forEach((cid) => delete this.rendered[COMPONENTS][cid]);
+ }
+ get() {
+ return this.rendered;
+ }
+ isNewFingerprint(diff = {}) {
+ return !!diff[STATIC];
+ }
+ templateStatic(part, templates) {
+ if (typeof part === "number") {
+ return templates[part];
+ } else {
+ return part;
+ }
+ }
+ nextMagicID() {
+ this.magicId++;
+ return `m${this.magicId}-${this.parentViewId()}`;
+ }
+ toOutputBuffer(rendered, templates, output, changeTracking, rootAttrs = {}) {
+ if (rendered[DYNAMICS]) {
+ return this.comprehensionToBuffer(rendered, templates, output);
+ }
+ let { [STATIC]: statics } = rendered;
+ statics = this.templateStatic(statics, templates);
+ let isRoot = rendered[ROOT];
+ let prevBuffer = output.buffer;
+ if (isRoot) {
+ output.buffer = "";
+ }
+ if (changeTracking && isRoot && !rendered.magicId) {
+ rendered.newRender = true;
+ rendered.magicId = this.nextMagicID();
+ }
+ output.buffer += statics[0];
+ for (let i = 1; i < statics.length; i++) {
+ this.dynamicToBuffer(rendered[i - 1], templates, output, changeTracking);
+ output.buffer += statics[i];
+ }
+ if (isRoot) {
+ let skip = false;
+ let attrs;
+ if (changeTracking || rendered.magicId) {
+ skip = changeTracking && !rendered.newRender;
+ attrs = __spreadValues({ [PHX_MAGIC_ID]: rendered.magicId }, rootAttrs);
+ } else {
+ attrs = rootAttrs;
+ }
+ if (skip) {
+ attrs[PHX_SKIP] = true;
+ }
+ let [newRoot, commentBefore, commentAfter] = modifyRoot(output.buffer, attrs, skip);
+ rendered.newRender = false;
+ output.buffer = prevBuffer + commentBefore + newRoot + commentAfter;
+ }
+ }
+ comprehensionToBuffer(rendered, templates, output) {
+ let { [DYNAMICS]: dynamics, [STATIC]: statics, [STREAM]: stream } = rendered;
+ let [_ref, _inserts, deleteIds, reset] = stream || [null, {}, [], null];
+ statics = this.templateStatic(statics, templates);
+ let compTemplates = templates || rendered[TEMPLATES];
+ for (let d = 0; d < dynamics.length; d++) {
+ let dynamic = dynamics[d];
+ output.buffer += statics[0];
+ for (let i = 1; i < statics.length; i++) {
+ let changeTracking = false;
+ this.dynamicToBuffer(dynamic[i - 1], compTemplates, output, changeTracking);
+ output.buffer += statics[i];
+ }
+ }
+ if (stream !== void 0 && (rendered[DYNAMICS].length > 0 || deleteIds.length > 0 || reset)) {
+ delete rendered[STREAM];
+ rendered[DYNAMICS] = [];
+ output.streams.add(stream);
+ }
+ }
+ dynamicToBuffer(rendered, templates, output, changeTracking) {
+ if (typeof rendered === "number") {
+ let [str, streams] = this.recursiveCIDToString(output.components, rendered, output.onlyCids);
+ output.buffer += str;
+ output.streams = /* @__PURE__ */ new Set([...output.streams, ...streams]);
+ } else if (isObject(rendered)) {
+ this.toOutputBuffer(rendered, templates, output, changeTracking, {});
+ } else {
+ output.buffer += rendered;
+ }
+ }
+ recursiveCIDToString(components, cid, onlyCids) {
+ let component = components[cid] || logError(`no component for CID ${cid}`, components);
+ let attrs = { [PHX_COMPONENT]: cid };
+ let skip = onlyCids && !onlyCids.has(cid);
+ component.newRender = !skip;
+ component.magicId = `c${cid}-${this.parentViewId()}`;
+ let changeTracking = !component.reset;
+ let [html, streams] = this.recursiveToString(component, components, onlyCids, changeTracking, attrs);
+ delete component.reset;
+ return [html, streams];
+ }
+ };
+ var viewHookID = 1;
+ var ViewHook = class {
+ static makeID() {
+ return viewHookID++;
+ }
+ static elementID(el) {
+ return el.phxHookId;
+ }
+ constructor(view, el, callbacks) {
+ this.__view = view;
+ this.liveSocket = view.liveSocket;
+ this.__callbacks = callbacks;
+ this.__listeners = /* @__PURE__ */ new Set();
+ this.__isDisconnected = false;
+ this.el = el;
+ this.el.phxHookId = this.constructor.makeID();
+ for (let key in this.__callbacks) {
+ this[key] = this.__callbacks[key];
+ }
+ }
+ __mounted() {
+ this.mounted && this.mounted();
+ }
+ __updated() {
+ this.updated && this.updated();
+ }
+ __beforeUpdate() {
+ this.beforeUpdate && this.beforeUpdate();
+ }
+ __destroyed() {
+ this.destroyed && this.destroyed();
+ }
+ __reconnected() {
+ if (this.__isDisconnected) {
+ this.__isDisconnected = false;
+ this.reconnected && this.reconnected();
+ }
+ }
+ __disconnected() {
+ this.__isDisconnected = true;
+ this.disconnected && this.disconnected();
+ }
+ pushEvent(event, payload = {}, onReply = function() {
+ }) {
+ return this.__view.pushHookEvent(this.el, null, event, payload, onReply);
+ }
+ pushEventTo(phxTarget, event, payload = {}, onReply = function() {
+ }) {
+ return this.__view.withinTargets(phxTarget, (view, targetCtx) => {
+ return view.pushHookEvent(this.el, targetCtx, event, payload, onReply);
+ });
+ }
+ handleEvent(event, callback) {
+ let callbackRef = (customEvent, bypass) => bypass ? event : callback(customEvent.detail);
+ window.addEventListener(`phx:${event}`, callbackRef);
+ this.__listeners.add(callbackRef);
+ return callbackRef;
+ }
+ removeHandleEvent(callbackRef) {
+ let event = callbackRef(null, true);
+ window.removeEventListener(`phx:${event}`, callbackRef);
+ this.__listeners.delete(callbackRef);
+ }
+ upload(name, files) {
+ return this.__view.dispatchUploads(null, name, files);
+ }
+ uploadTo(phxTarget, name, files) {
+ return this.__view.withinTargets(phxTarget, (view, targetCtx) => {
+ view.dispatchUploads(targetCtx, name, files);
+ });
+ }
+ __cleanup__() {
+ this.__listeners.forEach((callbackRef) => this.removeHandleEvent(callbackRef));
+ }
+ };
+ var serializeForm = (form, metadata, onlyNames = []) => {
+ const _a = metadata, { submitter } = _a, meta = __objRest(_a, ["submitter"]);
+ let injectedElement;
+ if (submitter && submitter.name) {
+ const input = document.createElement("input");
+ input.type = "hidden";
+ const formId = submitter.getAttribute("form");
+ if (formId) {
+ input.setAttribute("form", formId);
+ }
+ input.name = submitter.name;
+ input.value = submitter.value;
+ submitter.parentElement.insertBefore(input, submitter);
+ injectedElement = input;
+ }
+ const formData = new FormData(form);
+ const toRemove = [];
+ formData.forEach((val, key, _index) => {
+ if (val instanceof File) {
+ toRemove.push(key);
+ }
+ });
+ toRemove.forEach((key) => formData.delete(key));
+ const params = new URLSearchParams();
+ for (let [key, val] of formData.entries()) {
+ if (onlyNames.length === 0 || onlyNames.indexOf(key) >= 0) {
+ params.append(key, val);
+ }
+ }
+ if (submitter && injectedElement) {
+ submitter.parentElement.removeChild(injectedElement);
+ }
+ for (let metaKey in meta) {
+ params.append(metaKey, meta[metaKey]);
+ }
+ return params.toString();
+ };
+ var View = class {
+ constructor(el, liveSocket2, parentView, flash, liveReferer) {
+ this.isDead = false;
+ this.liveSocket = liveSocket2;
+ this.flash = flash;
+ this.parent = parentView;
+ this.root = parentView ? parentView.root : this;
+ this.el = el;
+ this.id = this.el.id;
+ this.ref = 0;
+ this.childJoins = 0;
+ this.loaderTimer = null;
+ this.pendingDiffs = [];
+ this.pendingForms = /* @__PURE__ */ new Set();
+ this.redirect = false;
+ this.href = null;
+ this.joinCount = this.parent ? this.parent.joinCount - 1 : 0;
+ this.joinPending = true;
+ this.destroyed = false;
+ this.joinCallback = function(onDone) {
+ onDone && onDone();
+ };
+ this.stopCallback = function() {
+ };
+ this.pendingJoinOps = this.parent ? null : [];
+ this.viewHooks = {};
+ this.formSubmits = [];
+ this.children = this.parent ? null : {};
+ this.root.children[this.id] = {};
+ this.formsForRecovery = {};
+ this.channel = this.liveSocket.channel(`lv:${this.id}`, () => {
+ let url = this.href && this.expandURL(this.href);
+ return {
+ redirect: this.redirect ? url : void 0,
+ url: this.redirect ? void 0 : url || void 0,
+ params: this.connectParams(liveReferer),
+ session: this.getSession(),
+ static: this.getStatic(),
+ flash: this.flash
+ };
+ });
+ }
+ setHref(href) {
+ this.href = href;
+ }
+ setRedirect(href) {
+ this.redirect = true;
+ this.href = href;
+ }
+ isMain() {
+ return this.el.hasAttribute(PHX_MAIN);
+ }
+ connectParams(liveReferer) {
+ let params = this.liveSocket.params(this.el);
+ let manifest = dom_default.all(document, `[${this.binding(PHX_TRACK_STATIC)}]`).map((node) => node.src || node.href).filter((url) => typeof url === "string");
+ if (manifest.length > 0) {
+ params["_track_static"] = manifest;
+ }
+ params["_mounts"] = this.joinCount;
+ params["_live_referer"] = liveReferer;
+ return params;
+ }
+ isConnected() {
+ return this.channel.canPush();
+ }
+ getSession() {
+ return this.el.getAttribute(PHX_SESSION);
+ }
+ getStatic() {
+ let val = this.el.getAttribute(PHX_STATIC);
+ return val === "" ? null : val;
+ }
+ destroy(callback = function() {
+ }) {
+ this.destroyAllChildren();
+ this.destroyed = true;
+ delete this.root.children[this.id];
+ if (this.parent) {
+ delete this.root.children[this.parent.id][this.id];
+ }
+ clearTimeout(this.loaderTimer);
+ let onFinished = () => {
+ callback();
+ for (let id in this.viewHooks) {
+ this.destroyHook(this.viewHooks[id]);
+ }
+ };
+ dom_default.markPhxChildDestroyed(this.el);
+ this.log("destroyed", () => ["the child has been removed from the parent"]);
+ this.channel.leave().receive("ok", onFinished).receive("error", onFinished).receive("timeout", onFinished);
+ }
+ setContainerClasses(...classes) {
+ this.el.classList.remove(PHX_CONNECTED_CLASS, PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_CLIENT_ERROR_CLASS, PHX_SERVER_ERROR_CLASS);
+ this.el.classList.add(...classes);
+ }
+ showLoader(timeout) {
+ clearTimeout(this.loaderTimer);
+ if (timeout) {
+ this.loaderTimer = setTimeout(() => this.showLoader(), timeout);
+ } else {
+ for (let id in this.viewHooks) {
+ this.viewHooks[id].__disconnected();
+ }
+ this.setContainerClasses(PHX_LOADING_CLASS);
+ }
+ }
+ execAll(binding) {
+ dom_default.all(this.el, `[${binding}]`, (el) => this.liveSocket.execJS(el, el.getAttribute(binding)));
+ }
+ hideLoader() {
+ clearTimeout(this.loaderTimer);
+ this.setContainerClasses(PHX_CONNECTED_CLASS);
+ this.execAll(this.binding("connected"));
+ }
+ triggerReconnected() {
+ for (let id in this.viewHooks) {
+ this.viewHooks[id].__reconnected();
+ }
+ }
+ log(kind, msgCallback) {
+ this.liveSocket.log(this, kind, msgCallback);
+ }
+ transition(time2, onStart, onDone = function() {
+ }) {
+ this.liveSocket.transition(time2, onStart, onDone);
+ }
+ withinTargets(phxTarget, callback, dom = document, viewEl) {
+ if (phxTarget instanceof HTMLElement || phxTarget instanceof SVGElement) {
+ return this.liveSocket.owner(phxTarget, (view) => callback(view, phxTarget));
+ }
+ if (isCid(phxTarget)) {
+ let targets = dom_default.findComponentNodeList(viewEl || this.el, phxTarget);
+ if (targets.length === 0) {
+ logError(`no component found matching phx-target of ${phxTarget}`);
+ } else {
+ callback(this, parseInt(phxTarget));
+ }
+ } else {
+ let targets = Array.from(dom.querySelectorAll(phxTarget));
+ if (targets.length === 0) {
+ logError(`nothing found matching the phx-target selector "${phxTarget}"`);
+ }
+ targets.forEach((target) => this.liveSocket.owner(target, (view) => callback(view, target)));
+ }
+ }
+ applyDiff(type, rawDiff, callback) {
+ this.log(type, () => ["", clone(rawDiff)]);
+ let { diff, reply, events, title } = Rendered.extract(rawDiff);
+ callback({ diff, reply, events });
+ if (typeof title === "string") {
+ window.requestAnimationFrame(() => dom_default.putTitle(title));
+ }
+ }
+ onJoin(resp) {
+ let { rendered, container, liveview_version } = resp;
+ if (container) {
+ let [tag, attrs] = container;
+ this.el = dom_default.replaceRootContainer(this.el, tag, attrs);
+ }
+ this.childJoins = 0;
+ this.joinPending = true;
+ this.flash = null;
+ if (this.root === this) {
+ this.formsForRecovery = this.getFormsForRecovery();
+ }
+ if (liveview_version !== this.liveSocket.version()) {
+ console.error(`LiveView asset version mismatch. JavaScript version ${this.liveSocket.version()} vs. server ${liveview_version}. To avoid issues, please ensure that your assets use the same version as the server.`);
+ }
+ browser_default.dropLocal(this.liveSocket.localStorage, window.location.pathname, CONSECUTIVE_RELOADS);
+ this.applyDiff("mount", rendered, ({ diff, events }) => {
+ this.rendered = new Rendered(this.id, diff);
+ let [html, streams] = this.renderContainer(null, "join");
+ this.dropPendingRefs();
+ this.joinCount++;
+ this.maybeRecoverForms(html, () => {
+ this.onJoinComplete(resp, html, streams, events);
+ });
+ });
+ }
+ dropPendingRefs() {
+ dom_default.all(document, `[${PHX_REF_SRC}="${this.id}"][${PHX_REF}]`, (el) => {
+ el.removeAttribute(PHX_REF);
+ el.removeAttribute(PHX_REF_SRC);
+ });
+ }
+ onJoinComplete({ live_patch }, html, streams, events) {
+ if (this.joinCount > 1 || this.parent && !this.parent.isJoinPending()) {
+ return this.applyJoinPatch(live_patch, html, streams, events);
+ }
+ let newChildren = dom_default.findPhxChildrenInFragment(html, this.id).filter((toEl) => {
+ let fromEl = toEl.id && this.el.querySelector(`[id="${toEl.id}"]`);
+ let phxStatic = fromEl && fromEl.getAttribute(PHX_STATIC);
+ if (phxStatic) {
+ toEl.setAttribute(PHX_STATIC, phxStatic);
+ }
+ if (fromEl) {
+ fromEl.setAttribute(PHX_ROOT_ID, this.root.id);
+ }
+ return this.joinChild(toEl);
+ });
+ if (newChildren.length === 0) {
+ if (this.parent) {
+ this.root.pendingJoinOps.push([this, () => this.applyJoinPatch(live_patch, html, streams, events)]);
+ this.parent.ackJoin(this);
+ } else {
+ this.onAllChildJoinsComplete();
+ this.applyJoinPatch(live_patch, html, streams, events);
+ }
+ } else {
+ this.root.pendingJoinOps.push([this, () => this.applyJoinPatch(live_patch, html, streams, events)]);
+ }
+ }
+ attachTrueDocEl() {
+ this.el = dom_default.byId(this.id);
+ this.el.setAttribute(PHX_ROOT_ID, this.root.id);
+ }
+ execNewMounted() {
+ let phxViewportTop = this.binding(PHX_VIEWPORT_TOP);
+ let phxViewportBottom = this.binding(PHX_VIEWPORT_BOTTOM);
+ dom_default.all(this.el, `[${phxViewportTop}], [${phxViewportBottom}]`, (hookEl) => {
+ if (this.ownsElement(hookEl)) {
+ dom_default.maybeAddPrivateHooks(hookEl, phxViewportTop, phxViewportBottom);
+ this.maybeAddNewHook(hookEl);
+ }
+ });
+ dom_default.all(this.el, `[${this.binding(PHX_HOOK)}], [data-phx-${PHX_HOOK}]`, (hookEl) => {
+ if (this.ownsElement(hookEl)) {
+ this.maybeAddNewHook(hookEl);
+ }
+ });
+ dom_default.all(this.el, `[${this.binding(PHX_MOUNTED)}]`, (el) => {
+ if (this.ownsElement(el)) {
+ this.maybeMounted(el);
+ }
+ });
+ }
+ applyJoinPatch(live_patch, html, streams, events) {
+ this.attachTrueDocEl();
+ let patch = new DOMPatch(this, this.el, this.id, html, streams, null);
+ patch.markPrunableContentForRemoval();
+ this.performPatch(patch, false, true);
+ this.joinNewChildren();
+ this.execNewMounted();
+ this.joinPending = false;
+ this.liveSocket.dispatchEvents(events);
+ this.applyPendingUpdates();
+ if (live_patch) {
+ let { kind, to } = live_patch;
+ this.liveSocket.historyPatch(to, kind);
+ }
+ this.hideLoader();
+ if (this.joinCount > 1) {
+ this.triggerReconnected();
+ }
+ this.stopCallback();
+ }
+ triggerBeforeUpdateHook(fromEl, toEl) {
+ this.liveSocket.triggerDOM("onBeforeElUpdated", [fromEl, toEl]);
+ let hook = this.getHook(fromEl);
+ let isIgnored = hook && dom_default.isIgnored(fromEl, this.binding(PHX_UPDATE));
+ if (hook && !fromEl.isEqualNode(toEl) && !(isIgnored && isEqualObj(fromEl.dataset, toEl.dataset))) {
+ hook.__beforeUpdate();
+ return hook;
+ }
+ }
+ maybeMounted(el) {
+ let phxMounted = el.getAttribute(this.binding(PHX_MOUNTED));
+ let hasBeenInvoked = phxMounted && dom_default.private(el, "mounted");
+ if (phxMounted && !hasBeenInvoked) {
+ this.liveSocket.execJS(el, phxMounted);
+ dom_default.putPrivate(el, "mounted", true);
+ }
+ }
+ maybeAddNewHook(el, force) {
+ let newHook = this.addHook(el);
+ if (newHook) {
+ newHook.__mounted();
+ }
+ }
+ performPatch(patch, pruneCids, isJoinPatch = false) {
+ let removedEls = [];
+ let phxChildrenAdded = false;
+ let updatedHookIds = /* @__PURE__ */ new Set();
+ patch.after("added", (el) => {
+ this.liveSocket.triggerDOM("onNodeAdded", [el]);
+ let phxViewportTop = this.binding(PHX_VIEWPORT_TOP);
+ let phxViewportBottom = this.binding(PHX_VIEWPORT_BOTTOM);
+ dom_default.maybeAddPrivateHooks(el, phxViewportTop, phxViewportBottom);
+ this.maybeAddNewHook(el);
+ if (el.getAttribute) {
+ this.maybeMounted(el);
+ }
+ });
+ patch.after("phxChildAdded", (el) => {
+ if (dom_default.isPhxSticky(el)) {
+ this.liveSocket.joinRootViews();
+ } else {
+ phxChildrenAdded = true;
+ }
+ });
+ patch.before("updated", (fromEl, toEl) => {
+ let hook = this.triggerBeforeUpdateHook(fromEl, toEl);
+ if (hook) {
+ updatedHookIds.add(fromEl.id);
+ }
+ });
+ patch.after("updated", (el) => {
+ if (updatedHookIds.has(el.id)) {
+ this.getHook(el).__updated();
+ }
+ });
+ patch.after("discarded", (el) => {
+ if (el.nodeType === Node.ELEMENT_NODE) {
+ removedEls.push(el);
+ }
+ });
+ patch.after("transitionsDiscarded", (els) => this.afterElementsRemoved(els, pruneCids));
+ patch.perform(isJoinPatch);
+ this.afterElementsRemoved(removedEls, pruneCids);
+ return phxChildrenAdded;
+ }
+ afterElementsRemoved(elements, pruneCids) {
+ let destroyedCIDs = [];
+ elements.forEach((parent) => {
+ let components = dom_default.all(parent, `[${PHX_COMPONENT}]`);
+ let hooks2 = dom_default.all(parent, `[${this.binding(PHX_HOOK)}]`);
+ components.concat(parent).forEach((el) => {
+ let cid = this.componentID(el);
+ if (isCid(cid) && destroyedCIDs.indexOf(cid) === -1) {
+ destroyedCIDs.push(cid);
+ }
+ });
+ hooks2.concat(parent).forEach((hookEl) => {
+ let hook = this.getHook(hookEl);
+ hook && this.destroyHook(hook);
+ });
+ });
+ if (pruneCids) {
+ this.maybePushComponentsDestroyed(destroyedCIDs);
+ }
+ }
+ joinNewChildren() {
+ dom_default.findPhxChildren(this.el, this.id).forEach((el) => this.joinChild(el));
+ }
+ maybeRecoverForms(html, callback) {
+ const phxChange = this.binding("change");
+ const oldForms = this.root.formsForRecovery;
+ let template = document.createElement("template");
+ template.innerHTML = html;
+ const rootEl = template.content.firstElementChild;
+ rootEl.id = this.id;
+ rootEl.setAttribute(PHX_ROOT_ID, this.root.id);
+ rootEl.setAttribute(PHX_SESSION, this.getSession());
+ rootEl.setAttribute(PHX_STATIC, this.getStatic());
+ rootEl.setAttribute(PHX_PARENT_ID, this.parent ? this.parent.id : null);
+ const formsToRecover = dom_default.all(template.content, "form").filter((newForm) => newForm.id && oldForms[newForm.id]).filter((newForm) => !this.pendingForms.has(newForm.id)).filter((newForm) => oldForms[newForm.id].getAttribute(phxChange) === newForm.getAttribute(phxChange)).map((newForm) => {
+ return [oldForms[newForm.id], newForm];
+ });
+ if (formsToRecover.length === 0) {
+ return callback();
+ }
+ formsToRecover.forEach(([oldForm, newForm], i) => {
+ this.pendingForms.add(newForm.id);
+ this.pushFormRecovery(oldForm, newForm, template.content, () => {
+ this.pendingForms.delete(newForm.id);
+ if (i === formsToRecover.length - 1) {
+ callback();
+ }
+ });
+ });
+ }
+ getChildById(id) {
+ return this.root.children[this.id][id];
+ }
+ getDescendentByEl(el) {
+ if (el.id === this.id) {
+ return this;
+ } else {
+ return this.children[el.getAttribute(PHX_PARENT_ID)][el.id];
+ }
+ }
+ destroyDescendent(id) {
+ for (let parentId in this.root.children) {
+ for (let childId in this.root.children[parentId]) {
+ if (childId === id) {
+ return this.root.children[parentId][childId].destroy();
+ }
+ }
+ }
+ }
+ joinChild(el) {
+ let child = this.getChildById(el.id);
+ if (!child) {
+ let view = new View(el, this.liveSocket, this);
+ this.root.children[this.id][view.id] = view;
+ view.join();
+ this.childJoins++;
+ return true;
+ }
+ }
+ isJoinPending() {
+ return this.joinPending;
+ }
+ ackJoin(_child) {
+ this.childJoins--;
+ if (this.childJoins === 0) {
+ if (this.parent) {
+ this.parent.ackJoin(this);
+ } else {
+ this.onAllChildJoinsComplete();
+ }
+ }
+ }
+ onAllChildJoinsComplete() {
+ this.pendingForms.clear();
+ this.formsForRecovery = {};
+ this.joinCallback(() => {
+ this.pendingJoinOps.forEach(([view, op]) => {
+ if (!view.isDestroyed()) {
+ op();
+ }
+ });
+ this.pendingJoinOps = [];
+ });
+ }
+ update(diff, events) {
+ if (this.isJoinPending() || this.liveSocket.hasPendingLink() && this.root.isMain()) {
+ return this.pendingDiffs.push({ diff, events });
+ }
+ this.rendered.mergeDiff(diff);
+ let phxChildrenAdded = false;
+ if (this.rendered.isComponentOnlyDiff(diff)) {
+ this.liveSocket.time("component patch complete", () => {
+ let parentCids = dom_default.findExistingParentCIDs(this.el, this.rendered.componentCIDs(diff));
+ parentCids.forEach((parentCID) => {
+ if (this.componentPatch(this.rendered.getComponent(diff, parentCID), parentCID)) {
+ phxChildrenAdded = true;
+ }
+ });
+ });
+ } else if (!isEmpty(diff)) {
+ this.liveSocket.time("full patch complete", () => {
+ let [html, streams] = this.renderContainer(diff, "update");
+ let patch = new DOMPatch(this, this.el, this.id, html, streams, null);
+ phxChildrenAdded = this.performPatch(patch, true);
+ });
+ }
+ this.liveSocket.dispatchEvents(events);
+ if (phxChildrenAdded) {
+ this.joinNewChildren();
+ }
+ }
+ renderContainer(diff, kind) {
+ return this.liveSocket.time(`toString diff (${kind})`, () => {
+ let tag = this.el.tagName;
+ let cids = diff ? this.rendered.componentCIDs(diff) : null;
+ let [html, streams] = this.rendered.toString(cids);
+ return [`<${tag}>${html}${tag}>`, streams];
+ });
+ }
+ componentPatch(diff, cid) {
+ if (isEmpty(diff))
+ return false;
+ let [html, streams] = this.rendered.componentToString(cid);
+ let patch = new DOMPatch(this, this.el, this.id, html, streams, cid);
+ let childrenAdded = this.performPatch(patch, true);
+ return childrenAdded;
+ }
+ getHook(el) {
+ return this.viewHooks[ViewHook.elementID(el)];
+ }
+ addHook(el) {
+ if (ViewHook.elementID(el) || !el.getAttribute) {
+ return;
+ }
+ let hookName = el.getAttribute(`data-phx-${PHX_HOOK}`) || el.getAttribute(this.binding(PHX_HOOK));
+ if (hookName && !this.ownsElement(el)) {
+ return;
+ }
+ let callbacks = this.liveSocket.getHookCallbacks(hookName);
+ if (callbacks) {
+ if (!el.id) {
+ logError(`no DOM ID for hook "${hookName}". Hooks require a unique ID on each element.`, el);
+ }
+ let hook = new ViewHook(this, el, callbacks);
+ this.viewHooks[ViewHook.elementID(hook.el)] = hook;
+ return hook;
+ } else if (hookName !== null) {
+ logError(`unknown hook found for "${hookName}"`, el);
+ }
+ }
+ destroyHook(hook) {
+ hook.__destroyed();
+ hook.__cleanup__();
+ delete this.viewHooks[ViewHook.elementID(hook.el)];
+ }
+ applyPendingUpdates() {
+ this.pendingDiffs.forEach(({ diff, events }) => this.update(diff, events));
+ this.pendingDiffs = [];
+ this.eachChild((child) => child.applyPendingUpdates());
+ }
+ eachChild(callback) {
+ let children = this.root.children[this.id] || {};
+ for (let id in children) {
+ callback(this.getChildById(id));
+ }
+ }
+ onChannel(event, cb) {
+ this.liveSocket.onChannel(this.channel, event, (resp) => {
+ if (this.isJoinPending()) {
+ this.root.pendingJoinOps.push([this, () => cb(resp)]);
+ } else {
+ this.liveSocket.requestDOMUpdate(() => cb(resp));
+ }
+ });
+ }
+ bindChannel() {
+ this.liveSocket.onChannel(this.channel, "diff", (rawDiff) => {
+ this.liveSocket.requestDOMUpdate(() => {
+ this.applyDiff("update", rawDiff, ({ diff, events }) => this.update(diff, events));
+ });
+ });
+ this.onChannel("redirect", ({ to, flash }) => this.onRedirect({ to, flash }));
+ this.onChannel("live_patch", (redir) => this.onLivePatch(redir));
+ this.onChannel("live_redirect", (redir) => this.onLiveRedirect(redir));
+ this.channel.onError((reason) => this.onError(reason));
+ this.channel.onClose((reason) => this.onClose(reason));
+ }
+ destroyAllChildren() {
+ this.eachChild((child) => child.destroy());
+ }
+ onLiveRedirect(redir) {
+ let { to, kind, flash } = redir;
+ let url = this.expandURL(to);
+ this.liveSocket.historyRedirect(url, kind, flash);
+ }
+ onLivePatch(redir) {
+ let { to, kind } = redir;
+ this.href = this.expandURL(to);
+ this.liveSocket.historyPatch(to, kind);
+ }
+ expandURL(to) {
+ return to.startsWith("/") ? `${window.location.protocol}//${window.location.host}${to}` : to;
+ }
+ onRedirect({ to, flash }) {
+ this.liveSocket.redirect(to, flash);
+ }
+ isDestroyed() {
+ return this.destroyed;
+ }
+ joinDead() {
+ this.isDead = true;
+ }
+ join(callback) {
+ this.showLoader(this.liveSocket.loaderTimeout);
+ this.bindChannel();
+ if (this.isMain()) {
+ this.stopCallback = this.liveSocket.withPageLoading({ to: this.href, kind: "initial" });
+ }
+ this.joinCallback = (onDone) => {
+ onDone = onDone || function() {
+ };
+ callback ? callback(this.joinCount, onDone) : onDone();
+ };
+ this.liveSocket.wrapPush(this, { timeout: false }, () => {
+ return this.channel.join().receive("ok", (data2) => {
+ if (!this.isDestroyed()) {
+ this.liveSocket.requestDOMUpdate(() => this.onJoin(data2));
+ }
+ }).receive("error", (resp) => !this.isDestroyed() && this.onJoinError(resp)).receive("timeout", () => !this.isDestroyed() && this.onJoinError({ reason: "timeout" }));
+ });
+ }
+ onJoinError(resp) {
+ if (resp.reason === "reload") {
+ this.log("error", () => [`failed mount with ${resp.status}. Falling back to page request`, resp]);
+ if (this.isMain()) {
+ this.onRedirect({ to: this.href });
+ }
+ return;
+ } else if (resp.reason === "unauthorized" || resp.reason === "stale") {
+ this.log("error", () => ["unauthorized live_redirect. Falling back to page request", resp]);
+ if (this.isMain()) {
+ this.onRedirect({ to: this.href });
+ }
+ return;
+ }
+ if (resp.redirect || resp.live_redirect) {
+ this.joinPending = false;
+ this.channel.leave();
+ }
+ if (resp.redirect) {
+ return this.onRedirect(resp.redirect);
+ }
+ if (resp.live_redirect) {
+ return this.onLiveRedirect(resp.live_redirect);
+ }
+ this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS]);
+ this.log("error", () => ["unable to join", resp]);
+ if (this.liveSocket.isConnected()) {
+ this.liveSocket.reloadWithJitter(this);
+ }
+ }
+ onClose(reason) {
+ if (this.isDestroyed()) {
+ return;
+ }
+ if (this.liveSocket.hasPendingLink() && reason !== "leave") {
+ return this.liveSocket.reloadWithJitter(this);
+ }
+ this.destroyAllChildren();
+ this.liveSocket.dropActiveElement(this);
+ if (document.activeElement) {
+ document.activeElement.blur();
+ }
+ if (this.liveSocket.isUnloaded()) {
+ this.showLoader(BEFORE_UNLOAD_LOADER_TIMEOUT);
+ }
+ }
+ onError(reason) {
+ this.onClose(reason);
+ if (this.liveSocket.isConnected()) {
+ this.log("error", () => ["view crashed", reason]);
+ }
+ if (!this.liveSocket.isUnloaded()) {
+ if (this.liveSocket.isConnected()) {
+ this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_SERVER_ERROR_CLASS]);
+ } else {
+ this.displayError([PHX_LOADING_CLASS, PHX_ERROR_CLASS, PHX_CLIENT_ERROR_CLASS]);
+ }
+ }
+ }
+ displayError(classes) {
+ if (this.isMain()) {
+ dom_default.dispatchEvent(window, "phx:page-loading-start", { detail: { to: this.href, kind: "error" } });
+ }
+ this.showLoader();
+ this.setContainerClasses(...classes);
+ this.execAll(this.binding("disconnected"));
+ }
+ pushWithReply(refGenerator, event, payload, onReply = function() {
+ }) {
+ if (!this.isConnected()) {
+ return;
+ }
+ let [ref, [el], opts] = refGenerator ? refGenerator() : [null, [], {}];
+ let onLoadingDone = function() {
+ };
+ if (opts.page_loading || el && el.getAttribute(this.binding(PHX_PAGE_LOADING)) !== null) {
+ onLoadingDone = this.liveSocket.withPageLoading({ kind: "element", target: el });
+ }
+ if (typeof payload.cid !== "number") {
+ delete payload.cid;
+ }
+ return this.liveSocket.wrapPush(this, { timeout: true }, () => {
+ return this.channel.push(event, payload, PUSH_TIMEOUT).receive("ok", (resp) => {
+ let finish = (hookReply) => {
+ if (resp.redirect) {
+ this.onRedirect(resp.redirect);
+ }
+ if (resp.live_patch) {
+ this.onLivePatch(resp.live_patch);
+ }
+ if (resp.live_redirect) {
+ this.onLiveRedirect(resp.live_redirect);
+ }
+ onLoadingDone();
+ onReply(resp, hookReply);
+ };
+ if (resp.diff) {
+ this.liveSocket.requestDOMUpdate(() => {
+ this.applyDiff("update", resp.diff, ({ diff, reply, events }) => {
+ if (ref !== null) {
+ this.undoRefs(ref);
+ }
+ this.update(diff, events);
+ finish(reply);
+ });
+ });
+ } else {
+ if (ref !== null) {
+ this.undoRefs(ref);
+ }
+ finish(null);
+ }
+ });
+ });
+ }
+ undoRefs(ref, onlyEls) {
+ onlyEls = onlyEls ? new Set(onlyEls) : null;
+ if (!this.isConnected()) {
+ return;
+ }
+ dom_default.all(document, `[${PHX_REF_SRC}="${this.id}"][${PHX_REF}="${ref}"]`, (el) => {
+ if (onlyEls && !onlyEls.has(el)) {
+ return;
+ }
+ el.dispatchEvent(new CustomEvent("phx:unlock", { bubbles: true, cancelable: false }));
+ let disabledVal = el.getAttribute(PHX_DISABLED);
+ let readOnlyVal = el.getAttribute(PHX_READONLY);
+ el.removeAttribute(PHX_REF);
+ el.removeAttribute(PHX_REF_SRC);
+ if (readOnlyVal !== null) {
+ el.readOnly = readOnlyVal === "true" ? true : false;
+ el.removeAttribute(PHX_READONLY);
+ }
+ if (disabledVal !== null) {
+ el.disabled = disabledVal === "true" ? true : false;
+ el.removeAttribute(PHX_DISABLED);
+ }
+ PHX_EVENT_CLASSES.forEach((className) => dom_default.removeClass(el, className));
+ let disableRestore = el.getAttribute(PHX_DISABLE_WITH_RESTORE);
+ if (disableRestore !== null) {
+ el.innerText = disableRestore;
+ el.removeAttribute(PHX_DISABLE_WITH_RESTORE);
+ }
+ let toEl = dom_default.private(el, PHX_REF);
+ if (toEl) {
+ let hook = this.triggerBeforeUpdateHook(el, toEl);
+ DOMPatch.patchEl(el, toEl, this.liveSocket.getActiveElement());
+ if (hook) {
+ hook.__updated();
+ }
+ dom_default.deletePrivate(el, PHX_REF);
+ }
+ });
+ }
+ putRef(elements, event, opts = {}) {
+ let newRef = this.ref++;
+ let disableWith = this.binding(PHX_DISABLE_WITH);
+ if (opts.loading) {
+ elements = elements.concat(dom_default.all(document, opts.loading));
+ }
+ for (let el of elements) {
+ el.setAttribute(PHX_REF, newRef);
+ el.setAttribute(PHX_REF_SRC, this.el.id);
+ if (opts.submitter && !(el === opts.submitter || el === opts.form)) {
+ continue;
+ }
+ el.classList.add(`phx-${event}-loading`);
+ el.dispatchEvent(new CustomEvent(`phx:${event}-loading`, { bubbles: true, cancelable: false }));
+ let disableText = el.getAttribute(disableWith);
+ if (disableText !== null) {
+ if (!el.getAttribute(PHX_DISABLE_WITH_RESTORE)) {
+ el.setAttribute(PHX_DISABLE_WITH_RESTORE, el.innerText);
+ }
+ if (disableText !== "") {
+ el.innerText = disableText;
+ }
+ el.setAttribute(PHX_DISABLED, el.getAttribute(PHX_DISABLED) || el.disabled);
+ el.setAttribute("disabled", "");
+ }
+ }
+ return [newRef, elements, opts];
+ }
+ componentID(el) {
+ let cid = el.getAttribute && el.getAttribute(PHX_COMPONENT);
+ return cid ? parseInt(cid) : null;
+ }
+ targetComponentID(target, targetCtx, opts = {}) {
+ if (isCid(targetCtx)) {
+ return targetCtx;
+ }
+ let cidOrSelector = opts.target || target.getAttribute(this.binding("target"));
+ if (isCid(cidOrSelector)) {
+ return parseInt(cidOrSelector);
+ } else if (targetCtx && (cidOrSelector !== null || opts.target)) {
+ return this.closestComponentID(targetCtx);
+ } else {
+ return null;
+ }
+ }
+ closestComponentID(targetCtx) {
+ if (isCid(targetCtx)) {
+ return targetCtx;
+ } else if (targetCtx) {
+ return maybe(targetCtx.closest(`[${PHX_COMPONENT}]`), (el) => this.ownsElement(el) && this.componentID(el));
+ } else {
+ return null;
+ }
+ }
+ pushHookEvent(el, targetCtx, event, payload, onReply) {
+ if (!this.isConnected()) {
+ this.log("hook", () => ["unable to push hook event. LiveView not connected", event, payload]);
+ return false;
+ }
+ let [ref, els, opts] = this.putRef([el], "hook");
+ this.pushWithReply(() => [ref, els, opts], "event", {
+ type: "hook",
+ event,
+ value: payload,
+ cid: this.closestComponentID(targetCtx)
+ }, (resp, reply) => onReply(reply, ref));
+ return ref;
+ }
+ extractMeta(el, meta, value) {
+ let prefix = this.binding("value-");
+ for (let i = 0; i < el.attributes.length; i++) {
+ if (!meta) {
+ meta = {};
+ }
+ let name = el.attributes[i].name;
+ if (name.startsWith(prefix)) {
+ meta[name.replace(prefix, "")] = el.getAttribute(name);
+ }
+ }
+ if (el.value !== void 0 && !(el instanceof HTMLFormElement)) {
+ if (!meta) {
+ meta = {};
+ }
+ meta.value = el.value;
+ if (el.tagName === "INPUT" && CHECKABLE_INPUTS.indexOf(el.type) >= 0 && !el.checked) {
+ delete meta.value;
+ }
+ }
+ if (value) {
+ if (!meta) {
+ meta = {};
+ }
+ for (let key in value) {
+ meta[key] = value[key];
+ }
+ }
+ return meta;
+ }
+ pushEvent(type, el, targetCtx, phxEvent, meta, opts = {}, onReply) {
+ this.pushWithReply(() => this.putRef([el], type, opts), "event", {
+ type,
+ event: phxEvent,
+ value: this.extractMeta(el, meta, opts.value),
+ cid: this.targetComponentID(el, targetCtx, opts)
+ }, (resp, reply) => onReply && onReply(reply));
+ }
+ pushFileProgress(fileEl, entryRef, progress2, onReply = function() {
+ }) {
+ this.liveSocket.withinOwners(fileEl.form, (view, targetCtx) => {
+ view.pushWithReply(null, "progress", {
+ event: fileEl.getAttribute(view.binding(PHX_PROGRESS)),
+ ref: fileEl.getAttribute(PHX_UPLOAD_REF),
+ entry_ref: entryRef,
+ progress: progress2,
+ cid: view.targetComponentID(fileEl.form, targetCtx)
+ }, onReply);
+ });
+ }
+ pushInput(inputEl, targetCtx, forceCid, phxEvent, opts, callback) {
+ let uploads;
+ let cid = isCid(forceCid) ? forceCid : this.targetComponentID(inputEl.form, targetCtx, opts);
+ let refGenerator = () => this.putRef([inputEl, inputEl.form], "change", opts);
+ let formData;
+ let meta = this.extractMeta(inputEl.form);
+ if (inputEl instanceof HTMLButtonElement) {
+ meta.submitter = inputEl;
+ }
+ if (inputEl.getAttribute(this.binding("change"))) {
+ formData = serializeForm(inputEl.form, __spreadValues({ _target: opts._target }, meta), [inputEl.name]);
+ } else {
+ formData = serializeForm(inputEl.form, __spreadValues({ _target: opts._target }, meta));
+ }
+ if (dom_default.isUploadInput(inputEl) && inputEl.files && inputEl.files.length > 0) {
+ LiveUploader.trackFiles(inputEl, Array.from(inputEl.files));
+ }
+ uploads = LiveUploader.serializeUploads(inputEl);
+ let event = {
+ type: "form",
+ event: phxEvent,
+ value: formData,
+ uploads,
+ cid
+ };
+ this.pushWithReply(refGenerator, "event", event, (resp) => {
+ dom_default.showError(inputEl, this.liveSocket.binding(PHX_FEEDBACK_FOR), this.liveSocket.binding(PHX_FEEDBACK_GROUP));
+ if (dom_default.isUploadInput(inputEl) && dom_default.isAutoUpload(inputEl)) {
+ if (LiveUploader.filesAwaitingPreflight(inputEl).length > 0) {
+ let [ref, _els] = refGenerator();
+ this.undoRefs(ref, [inputEl.form]);
+ this.uploadFiles(inputEl.form, targetCtx, ref, cid, (_uploads) => {
+ callback && callback(resp);
+ this.triggerAwaitingSubmit(inputEl.form);
+ this.undoRefs(ref);
+ });
+ }
+ } else {
+ callback && callback(resp);
+ }
+ });
+ }
+ triggerAwaitingSubmit(formEl) {
+ let awaitingSubmit = this.getScheduledSubmit(formEl);
+ if (awaitingSubmit) {
+ let [_el, _ref, _opts, callback] = awaitingSubmit;
+ this.cancelSubmit(formEl);
+ callback();
+ }
+ }
+ getScheduledSubmit(formEl) {
+ return this.formSubmits.find(([el, _ref, _opts, _callback]) => el.isSameNode(formEl));
+ }
+ scheduleSubmit(formEl, ref, opts, callback) {
+ if (this.getScheduledSubmit(formEl)) {
+ return true;
+ }
+ this.formSubmits.push([formEl, ref, opts, callback]);
+ }
+ cancelSubmit(formEl) {
+ this.formSubmits = this.formSubmits.filter(([el, ref, _callback]) => {
+ if (el.isSameNode(formEl)) {
+ this.undoRefs(ref);
+ return false;
+ } else {
+ return true;
+ }
+ });
+ }
+ disableForm(formEl, opts = {}) {
+ let filterIgnored = (el) => {
+ let userIgnored = closestPhxBinding(el, `${this.binding(PHX_UPDATE)}=ignore`, el.form);
+ return !(userIgnored || closestPhxBinding(el, "data-phx-update=ignore", el.form));
+ };
+ let filterDisables = (el) => {
+ return el.hasAttribute(this.binding(PHX_DISABLE_WITH));
+ };
+ let filterButton = (el) => el.tagName == "BUTTON";
+ let filterInput = (el) => ["INPUT", "TEXTAREA", "SELECT"].includes(el.tagName);
+ let formElements = Array.from(formEl.elements);
+ let disables = formElements.filter(filterDisables);
+ let buttons = formElements.filter(filterButton).filter(filterIgnored);
+ let inputs = formElements.filter(filterInput).filter(filterIgnored);
+ buttons.forEach((button) => {
+ button.setAttribute(PHX_DISABLED, button.disabled);
+ button.disabled = true;
+ });
+ inputs.forEach((input) => {
+ input.setAttribute(PHX_READONLY, input.readOnly);
+ input.readOnly = true;
+ if (input.files) {
+ input.setAttribute(PHX_DISABLED, input.disabled);
+ input.disabled = true;
+ }
+ });
+ formEl.setAttribute(this.binding(PHX_PAGE_LOADING), "");
+ return this.putRef([formEl].concat(disables).concat(buttons).concat(inputs), "submit", opts);
+ }
+ pushFormSubmit(formEl, targetCtx, phxEvent, submitter, opts, onReply) {
+ let refGenerator = () => this.disableForm(formEl, __spreadProps(__spreadValues({}, opts), { form: formEl, submitter }));
+ let cid = this.targetComponentID(formEl, targetCtx);
+ if (LiveUploader.hasUploadsInProgress(formEl)) {
+ let [ref, _els] = refGenerator();
+ let push = () => this.pushFormSubmit(formEl, targetCtx, phxEvent, submitter, opts, onReply);
+ return this.scheduleSubmit(formEl, ref, opts, push);
+ } else if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) {
+ let [ref, els] = refGenerator();
+ let proxyRefGen = () => [ref, els, opts];
+ this.uploadFiles(formEl, targetCtx, ref, cid, (uploads) => {
+ if (LiveUploader.inputsAwaitingPreflight(formEl).length > 0) {
+ return this.undoRefs(ref);
+ }
+ let meta = this.extractMeta(formEl);
+ let formData = serializeForm(formEl, __spreadValues({ submitter }, meta));
+ this.pushWithReply(proxyRefGen, "event", {
+ type: "form",
+ event: phxEvent,
+ value: formData,
+ cid
+ }, onReply);
+ });
+ } else if (!(formEl.hasAttribute(PHX_REF) && formEl.classList.contains("phx-submit-loading"))) {
+ let meta = this.extractMeta(formEl);
+ let formData = serializeForm(formEl, __spreadValues({ submitter }, meta));
+ this.pushWithReply(refGenerator, "event", {
+ type: "form",
+ event: phxEvent,
+ value: formData,
+ cid
+ }, onReply);
+ }
+ }
+ uploadFiles(formEl, targetCtx, ref, cid, onComplete) {
+ let joinCountAtUpload = this.joinCount;
+ let inputEls = LiveUploader.activeFileInputs(formEl);
+ let numFileInputsInProgress = inputEls.length;
+ inputEls.forEach((inputEl) => {
+ let uploader = new LiveUploader(inputEl, this, () => {
+ numFileInputsInProgress--;
+ if (numFileInputsInProgress === 0) {
+ onComplete();
+ }
+ });
+ let entries = uploader.entries().map((entry) => entry.toPreflightPayload());
+ if (entries.length === 0) {
+ numFileInputsInProgress--;
+ return;
+ }
+ let payload = {
+ ref: inputEl.getAttribute(PHX_UPLOAD_REF),
+ entries,
+ cid: this.targetComponentID(inputEl.form, targetCtx)
+ };
+ this.log("upload", () => ["sending preflight request", payload]);
+ this.pushWithReply(null, "allow_upload", payload, (resp) => {
+ this.log("upload", () => ["got preflight response", resp]);
+ uploader.entries().forEach((entry) => {
+ if (resp.entries && !resp.entries[entry.ref]) {
+ this.handleFailedEntryPreflight(entry.ref, "failed preflight", uploader);
+ }
+ });
+ if (resp.error || Object.keys(resp.entries).length === 0) {
+ this.undoRefs(ref);
+ let errors = resp.error || [];
+ errors.map(([entry_ref, reason]) => {
+ this.handleFailedEntryPreflight(entry_ref, reason, uploader);
+ });
+ } else {
+ let onError = (callback) => {
+ this.channel.onError(() => {
+ if (this.joinCount === joinCountAtUpload) {
+ callback();
+ }
+ });
+ };
+ uploader.initAdapterUpload(resp, onError, this.liveSocket);
+ }
+ });
+ });
+ }
+ handleFailedEntryPreflight(uploadRef, reason, uploader) {
+ if (uploader.isAutoUpload()) {
+ let entry = uploader.entries().find((entry2) => entry2.ref === uploadRef.toString());
+ if (entry) {
+ entry.cancel();
+ }
+ } else {
+ uploader.entries().map((entry) => entry.cancel());
+ }
+ this.log("upload", () => [`error for entry ${uploadRef}`, reason]);
+ }
+ dispatchUploads(targetCtx, name, filesOrBlobs) {
+ let targetElement = this.targetCtxElement(targetCtx) || this.el;
+ let inputs = dom_default.findUploadInputs(targetElement).filter((el) => el.name === name);
+ if (inputs.length === 0) {
+ logError(`no live file inputs found matching the name "${name}"`);
+ } else if (inputs.length > 1) {
+ logError(`duplicate live file inputs found matching the name "${name}"`);
+ } else {
+ dom_default.dispatchEvent(inputs[0], PHX_TRACK_UPLOADS, { detail: { files: filesOrBlobs } });
+ }
+ }
+ targetCtxElement(targetCtx) {
+ if (isCid(targetCtx)) {
+ let [target] = dom_default.findComponentNodeList(this.el, targetCtx);
+ return target;
+ } else if (targetCtx) {
+ return targetCtx;
+ } else {
+ return null;
+ }
+ }
+ pushFormRecovery(oldForm, newForm, templateDom, callback) {
+ const phxChange = this.binding("change");
+ const phxTarget = newForm.getAttribute(this.binding("target")) || newForm;
+ const phxEvent = newForm.getAttribute(this.binding(PHX_AUTO_RECOVER)) || newForm.getAttribute(this.binding("change"));
+ const inputs = Array.from(oldForm.elements).filter((el) => dom_default.isFormInput(el) && el.name && !el.hasAttribute(phxChange));
+ if (inputs.length === 0) {
+ return;
+ }
+ inputs.forEach((input2) => input2.hasAttribute(PHX_UPLOAD_REF) && LiveUploader.clearFiles(input2));
+ let input = inputs.find((el) => el.type !== "hidden") || inputs[0];
+ let pending = 0;
+ this.withinTargets(phxTarget, (targetView, targetCtx) => {
+ const cid = this.targetComponentID(newForm, targetCtx);
+ pending++;
+ targetView.pushInput(input, targetCtx, cid, phxEvent, { _target: input.name }, () => {
+ pending--;
+ if (pending === 0) {
+ callback();
+ }
+ });
+ }, templateDom, templateDom);
+ }
+ pushLinkPatch(href, targetEl, callback) {
+ let linkRef = this.liveSocket.setPendingLink(href);
+ let refGen = targetEl ? () => this.putRef([targetEl], "click") : null;
+ let fallback = () => this.liveSocket.redirect(window.location.href);
+ let url = href.startsWith("/") ? `${location.protocol}//${location.host}${href}` : href;
+ let push = this.pushWithReply(refGen, "live_patch", { url }, (resp) => {
+ this.liveSocket.requestDOMUpdate(() => {
+ if (resp.link_redirect) {
+ this.liveSocket.replaceMain(href, null, callback, linkRef);
+ } else {
+ if (this.liveSocket.commitPendingLink(linkRef)) {
+ this.href = href;
+ }
+ this.applyPendingUpdates();
+ callback && callback(linkRef);
+ }
+ });
+ });
+ if (push) {
+ push.receive("timeout", fallback);
+ } else {
+ fallback();
+ }
+ }
+ getFormsForRecovery() {
+ if (this.joinCount === 0) {
+ return {};
+ }
+ let phxChange = this.binding("change");
+ return dom_default.all(this.el, `form[${phxChange}]`).filter((form) => form.id).filter((form) => form.elements.length > 0).filter((form) => form.getAttribute(this.binding(PHX_AUTO_RECOVER)) !== "ignore").map((form) => form.cloneNode(true)).reduce((acc, form) => {
+ acc[form.id] = form;
+ return acc;
+ }, {});
+ }
+ maybePushComponentsDestroyed(destroyedCIDs) {
+ let willDestroyCIDs = destroyedCIDs.filter((cid) => {
+ return dom_default.findComponentNodeList(this.el, cid).length === 0;
+ });
+ if (willDestroyCIDs.length > 0) {
+ willDestroyCIDs.forEach((cid) => this.rendered.resetRender(cid));
+ this.pushWithReply(null, "cids_will_destroy", { cids: willDestroyCIDs }, () => {
+ this.liveSocket.requestDOMUpdate(() => {
+ let completelyDestroyCIDs = willDestroyCIDs.filter((cid) => {
+ return dom_default.findComponentNodeList(this.el, cid).length === 0;
+ });
+ if (completelyDestroyCIDs.length > 0) {
+ this.pushWithReply(null, "cids_destroyed", { cids: completelyDestroyCIDs }, (resp) => {
+ this.rendered.pruneCIDs(resp.cids);
+ });
+ }
+ });
+ });
+ }
+ }
+ ownsElement(el) {
+ let parentViewEl = el.closest(PHX_VIEW_SELECTOR);
+ return el.getAttribute(PHX_PARENT_ID) === this.id || parentViewEl && parentViewEl.id === this.id || !parentViewEl && this.isDead;
+ }
+ submitForm(form, targetCtx, phxEvent, submitter, opts = {}) {
+ dom_default.putPrivate(form, PHX_HAS_SUBMITTED, true);
+ const phxFeedbackFor = this.liveSocket.binding(PHX_FEEDBACK_FOR);
+ const phxFeedbackGroup = this.liveSocket.binding(PHX_FEEDBACK_GROUP);
+ const inputs = Array.from(form.elements);
+ inputs.forEach((input) => dom_default.putPrivate(input, PHX_HAS_SUBMITTED, true));
+ this.liveSocket.blurActiveElement(this);
+ this.pushFormSubmit(form, targetCtx, phxEvent, submitter, opts, () => {
+ inputs.forEach((input) => dom_default.showError(input, phxFeedbackFor, phxFeedbackGroup));
+ this.liveSocket.restorePreviouslyActiveFocus();
+ });
+ }
+ binding(kind) {
+ return this.liveSocket.binding(kind);
+ }
+ };
+ var LiveSocket = class {
+ constructor(url, phxSocket, opts = {}) {
+ this.unloaded = false;
+ if (!phxSocket || phxSocket.constructor.name === "Object") {
+ throw new Error(`
a phoenix Socket must be provided as the second argument to the LiveSocket constructor. For example:
import {Socket} from "phoenix"
import {LiveSocket} from "phoenix_live_view"
let liveSocket = new LiveSocket("/live", Socket, {...})
- `);this.socket=new t(e,i),this.bindingPrefix=i.bindingPrefix||Ns,this.opts=i,this.params=xe(i.params||{}),this.viewLogger=i.viewLogger,this.metadataCallbacks=i.metadata||{},this.defaults=Object.assign(et(Us),i.defaults||{}),this.activeElement=null,this.prevActive=null,this.silenced=!1,this.main=null,this.outgoingMainEl=null,this.clickStartedAtTarget=null,this.linkRef=1,this.roots={},this.href=window.location.href,this.pendingLink=null,this.currentLocation=et(window.location),this.hooks=i.hooks||{},this.uploaders=i.uploaders||{},this.loaderTimeout=i.loaderTimeout||Hs,this.reloadWithJitterTimer=null,this.maxReloads=i.maxReloads||Es,this.reloadJitterMin=i.reloadJitterMin||ks,this.reloadJitterMax=i.reloadJitterMax||Cs,this.failsafeJitter=i.failsafeJitter||Ts,this.localStorage=i.localStorage||window.localStorage,this.sessionStorage=i.sessionStorage||window.sessionStorage,this.boundTopLevelEvents=!1,this.serverCloseRef=null,this.domCallbacks=Object.assign({onPatchStart:xe(),onPatchEnd:xe(),onNodeAdded:xe(),onBeforeElUpdated:xe()},i.dom||{}),this.transitions=new gr,window.addEventListener("pagehide",s=>{this.unloaded=!0}),this.socket.onOpen(()=>{this.isUnloaded()&&window.location.reload()})}version(){return"0.20.17"}isProfileEnabled(){return this.sessionStorage.getItem(At)==="true"}isDebugEnabled(){return this.sessionStorage.getItem(Xe)==="true"}isDebugDisabled(){return this.sessionStorage.getItem(Xe)==="false"}enableDebug(){this.sessionStorage.setItem(Xe,"true")}enableProfiling(){this.sessionStorage.setItem(At,"true")}disableDebug(){this.sessionStorage.setItem(Xe,"false")}disableProfiling(){this.sessionStorage.removeItem(At)}enableLatencySim(e){this.enableDebug(),console.log("latency simulator enabled for the duration of this browser session. Call disableLatencySim() to disable"),this.sessionStorage.setItem(St,e)}disableLatencySim(){this.sessionStorage.removeItem(St)}getLatencySim(){let e=this.sessionStorage.getItem(St);return e?parseInt(e):null}getSocket(){return this.socket}connect(){window.location.hostname==="localhost"&&!this.isDebugDisabled()&&this.enableDebug();let e=()=>{this.joinRootViews()?(this.bindTopLevelEvents(),this.socket.connect()):this.main?this.socket.connect():this.bindTopLevelEvents({dead:!0}),this.joinDeadView()};["complete","loaded","interactive"].indexOf(document.readyState)>=0?e():document.addEventListener("DOMContentLoaded",()=>e())}disconnect(e){clearTimeout(this.reloadWithJitterTimer),this.serverCloseRef&&(this.socket.off(this.serverCloseRef),this.serverCloseRef=null),this.socket.disconnect(e)}replaceTransport(e){clearTimeout(this.reloadWithJitterTimer),this.socket.replaceTransport(e),this.connect()}execJS(e,t,i=null){this.owner(e,s=>M.exec(i,t,s,e))}execJSHookPush(e,t,i,s){this.withinOwners(e,r=>{M.exec("hook",t,r,e,["push",{data:i,callback:s}])})}unload(){this.unloaded||(this.main&&this.isConnected()&&this.log(this.main,"socket",()=>["disconnect for page nav"]),this.unloaded=!0,this.destroyAllViews(),this.disconnect())}triggerDOM(e,t){this.domCallbacks[e](...t)}time(e,t){if(!this.isProfileEnabled()||!console.time)return t();console.time(e);let i=t();return console.timeEnd(e),i}log(e,t,i){if(this.viewLogger){let[s,r]=i();this.viewLogger(e,t,s,r)}else if(this.isDebugEnabled()){let[s,r]=i();Js(e,t,s,r)}}requestDOMUpdate(e){this.transitions.after(e)}transition(e,t,i=function(){}){this.transitions.addTransition(e,t,i)}onChannel(e,t,i){e.on(t,s=>{let r=this.getLatencySim();r?setTimeout(()=>i(s),r):i(s)})}wrapPush(e,t,i){let s=this.getLatencySim(),r=e.joinCount;if(!s)return this.isConnected()&&t.timeout?i().receive("timeout",()=>{e.joinCount===r&&!e.isDestroyed()&&this.reloadWithJitter(e,()=>{this.log(e,"timeout",()=>["received timeout while communicating with server. Falling back to hard refresh for recovery"])})}):i();let n={receives:[],receive(a,o){this.receives.push([a,o])}};return setTimeout(()=>{e.isDestroyed()||n.receives.reduce((a,[o,l])=>a.receive(o,l),i())},s),n}reloadWithJitter(e,t){clearTimeout(this.reloadWithJitterTimer),this.disconnect();let i=this.reloadJitterMin,s=this.reloadJitterMax,r=Math.floor(Math.random()*(s-i+1))+i,n=K.updateLocal(this.localStorage,window.location.pathname,Ci,0,a=>a+1);n>this.maxReloads&&(r=this.failsafeJitter),this.reloadWithJitterTimer=setTimeout(()=>{e.isDestroyed()||e.isConnected()||(e.destroy(),t?t():this.log(e,"join",()=>[`encountered ${n} consecutive reloads`]),n>this.maxReloads&&this.log(e,"join",()=>[`exceeded ${this.maxReloads} consecutive reloads. Entering failsafe mode`]),this.hasPendingLink()?window.location=this.pendingLink:window.location.reload())},r)}getHookCallbacks(e){return e&&e.startsWith("Phoenix.")?Zs[e.split(".")[1]]:this.hooks[e]}isUnloaded(){return this.unloaded}isConnected(){return this.socket.isConnected()}getBindingPrefix(){return this.bindingPrefix}binding(e){return`${this.getBindingPrefix()}${e}`}channel(e,t){return this.socket.channel(e,t)}joinDeadView(){let e=document.body;if(e&&!this.isPhxView(e)&&!this.isPhxView(document.firstElementChild)){let t=this.newRootView(e);t.setHref(this.getHref()),t.joinDead(),this.main||(this.main=t),window.requestAnimationFrame(()=>t.execNewMounted())}}joinRootViews(){let e=!1;return c.all(document,`${be}:not([${he}])`,t=>{if(!this.getRootById(t.id)){let i=this.newRootView(t);i.setHref(this.getHref()),i.join(),t.hasAttribute(It)&&(this.main=i)}e=!0}),e}redirect(e,t){this.unload(),K.redirect(e,t)}replaceMain(e,t,i=null,s=this.setPendingLink(e)){let r=this.currentLocation.href;this.outgoingMainEl=this.outgoingMainEl||this.main.el;let n=c.cloneNode(this.outgoingMainEl,"");this.main.showLoader(this.loaderTimeout),this.main.destroy(),this.main=this.newRootView(n,t,r),this.main.setRedirect(e),this.transitionRemoves(null,!0),this.main.join((a,o)=>{a===1&&this.commitPendingLink(s)&&this.requestDOMUpdate(()=>{c.findPhxSticky(document).forEach(l=>n.appendChild(l)),this.outgoingMainEl.replaceWith(n),this.outgoingMainEl=null,i&&i(s),o()})})}transitionRemoves(e,t){let i=this.binding("remove");if(e=e||c.all(document,`[${i}]`),t){let s=c.findPhxSticky(document)||[];e=e.filter(r=>!c.isChildOfAny(r,s))}e.forEach(s=>{this.execJS(s,s.getAttribute(i),"remove")})}isPhxView(e){return e.getAttribute&&e.getAttribute(te)!==null}newRootView(e,t,i){let s=new Di(e,this,null,t,i);return this.roots[s.id]=s,s}owner(e,t){let i=ae(e.closest(be),s=>this.getViewByEl(s))||this.main;i&&t(i)}withinOwners(e,t){this.owner(e,i=>t(i,e))}getViewByEl(e){let t=e.getAttribute(de);return ae(this.getRootById(t),i=>i.getDescendentByEl(e))}getRootById(e){return this.roots[e]}destroyAllViews(){for(let e in this.roots)this.roots[e].destroy(),delete this.roots[e];this.main=null}destroyViewByEl(e){let t=this.getRootById(e.getAttribute(de));t&&t.id===e.id?(t.destroy(),delete this.roots[t.id]):t&&t.destroyDescendent(e.id)}setActiveElement(e){if(this.activeElement===e)return;this.activeElement=e;let t=()=>{e===this.activeElement&&(this.activeElement=null),e.removeEventListener("mouseup",this),e.removeEventListener("touchend",this)};e.addEventListener("mouseup",t),e.addEventListener("touchend",t)}getActiveElement(){return document.activeElement===document.body?this.activeElement||document.activeElement:document.activeElement||document.body}dropActiveElement(e){this.prevActive&&e.ownsElement(this.prevActive)&&(this.prevActive=null)}restorePreviouslyActiveFocus(){this.prevActive&&this.prevActive!==document.body&&this.prevActive.focus()}blurActiveElement(){this.prevActive=this.getActiveElement(),this.prevActive!==document.body&&this.prevActive.blur()}bindTopLevelEvents({dead:e}={}){this.boundTopLevelEvents||(this.boundTopLevelEvents=!0,this.serverCloseRef=this.socket.onClose(t=>{if(t&&t.code===1e3&&this.main)return this.reloadWithJitter(this.main)}),document.body.addEventListener("click",function(){}),window.addEventListener("pageshow",t=>{t.persisted&&(this.getSocket().disconnect(),this.withPageLoading({to:window.location.href,kind:"redirect"}),window.location.reload())},!0),e||this.bindNav(),this.bindClicks(),e||this.bindForms(),this.bind({keyup:"keyup",keydown:"keydown"},(t,i,s,r,n,a)=>{let o=r.getAttribute(this.binding(Ds)),l=t.key&&t.key.toLowerCase();if(o&&o.toLowerCase()!==l)return;let h=q({key:t.key},this.eventMeta(i,t,r));M.exec(i,n,s,r,["push",{data:h}])}),this.bind({blur:"focusout",focus:"focusin"},(t,i,s,r,n,a)=>{if(!a){let o=q({key:t.key},this.eventMeta(i,t,r));M.exec(i,n,s,r,["push",{data:o}])}}),this.bind({blur:"blur",focus:"focus"},(t,i,s,r,n,a)=>{if(a==="window"){let o=this.eventMeta(i,t,r);M.exec(i,n,s,r,["push",{data:o}])}}),window.addEventListener("dragover",t=>t.preventDefault()),window.addEventListener("drop",t=>{t.preventDefault();let i=ae(De(t.target,this.binding(Qt)),n=>n.getAttribute(this.binding(Qt))),s=i&&document.getElementById(i),r=Array.from(t.dataTransfer.files||[]);!s||s.disabled||r.length===0||!(s.files instanceof FileList)||(L.trackFiles(s,r,t.dataTransfer),s.dispatchEvent(new Event("input",{bubbles:!0})))}),this.on(_i,t=>{let i=t.target;if(!c.isUploadInput(i))return;let s=Array.from(t.detail.files||[]).filter(r=>r instanceof File||r instanceof Blob);L.trackFiles(i,s),i.dispatchEvent(new Event("input",{bubbles:!0}))}))}eventMeta(e,t,i){let s=this.metadataCallbacks[e];return s?s(t,i):{}}setPendingLink(e){return this.linkRef++,this.pendingLink=e,this.linkRef}commitPendingLink(e){return this.linkRef!==e?!1:(this.href=this.pendingLink,this.pendingLink=null,!0)}getHref(){return this.href}hasPendingLink(){return!!this.pendingLink}bind(e,t){for(let i in e){let s=e[i];this.on(s,r=>{let n=this.binding(i),a=this.binding(`window-${i}`),o=r.target.getAttribute&&r.target.getAttribute(n);o?this.debounce(r.target,r,s,()=>{this.withinOwners(r.target,l=>{t(r,i,l,r.target,o,null)})}):c.all(document,`[${a}]`,l=>{let h=l.getAttribute(a);this.debounce(l,r,s,()=>{this.withinOwners(l,d=>{t(r,i,d,l,h,"window")})})})})}}bindClicks(){window.addEventListener("mousedown",e=>this.clickStartedAtTarget=e.target),this.bindClick("click","click")}bindClick(e,t){let i=this.binding(t);window.addEventListener(e,s=>{let r=null;s.detail===0&&(this.clickStartedAtTarget=s.target);let n=this.clickStartedAtTarget||s.target;r=De(n,i),this.dispatchClickAway(s,n),this.clickStartedAtTarget=null;let a=r&&r.getAttribute(i);if(!a){c.isNewPageClick(s,window.location)&&this.unload();return}r.getAttribute("href")==="#"&&s.preventDefault(),!r.hasAttribute(U)&&this.debounce(r,s,"click",()=>{this.withinOwners(r,o=>{M.exec("click",a,o,r,["push",{data:this.eventMeta("click",s,r)}])})})},!1)}dispatchClickAway(e,t){let i=this.binding("click-away");c.all(document,`[${i}]`,s=>{s.isSameNode(t)||s.contains(t)||this.withinOwners(s,r=>{let n=s.getAttribute(i);M.isVisible(s)&&M.isInViewport(s)&&M.exec("click",n,r,s,["push",{data:this.eventMeta("click",e,e.target)}])})})}bindNav(){if(!K.canPushState())return;history.scrollRestoration&&(history.scrollRestoration="manual");let e=null;window.addEventListener("scroll",t=>{clearTimeout(e),e=setTimeout(()=>{K.updateCurrentState(i=>Object.assign(i,{scroll:window.scrollY}))},100)}),window.addEventListener("popstate",t=>{if(!this.registerNewLocation(window.location))return;let{type:i,id:s,root:r,scroll:n}=t.state||{},a=window.location.href;c.dispatchEvent(window,"phx:navigate",{detail:{href:a,patch:i==="patch",pop:!0}}),this.requestDOMUpdate(()=>{this.main.isConnected()&&i==="patch"&&s===this.main.id?this.main.pushLinkPatch(a,null,()=>{this.maybeScroll(n)}):this.replaceMain(a,null,()=>{r&&this.replaceRootHistory(),this.maybeScroll(n)})})},!1),window.addEventListener("click",t=>{let i=De(t.target,gt),s=i&&i.getAttribute(gt);if(!s||!this.isConnected()||!this.main||c.wantsNewTab(t))return;let r=i.href instanceof SVGAnimatedString?i.href.baseVal:i.href,n=i.getAttribute(Rs);t.preventDefault(),t.stopImmediatePropagation(),this.pendingLink!==r&&this.requestDOMUpdate(()=>{if(s==="patch")this.pushHistoryPatch(r,n,i);else if(s==="redirect")this.historyRedirect(r,n);else throw new Error(`expected ${gt} to be "patch" or "redirect", got: ${s}`);let a=i.getAttribute(this.binding("click"));a&&this.requestDOMUpdate(()=>this.execJS(i,a,"click"))})},!1)}maybeScroll(e){typeof e=="number"&&requestAnimationFrame(()=>{window.scrollTo(0,e)})}dispatchEvent(e,t={}){c.dispatchEvent(window,`phx:${e}`,{detail:t})}dispatchEvents(e){e.forEach(([t,i])=>this.dispatchEvent(t,i))}withPageLoading(e,t){c.dispatchEvent(window,"phx:page-loading-start",{detail:e});let i=()=>c.dispatchEvent(window,"phx:page-loading-stop",{detail:e});return t?t(i):i}pushHistoryPatch(e,t,i){if(!this.isConnected()||!this.main.isMain())return K.redirect(e);this.withPageLoading({to:e,kind:"patch"},s=>{this.main.pushLinkPatch(e,i,r=>{this.historyPatch(e,t,r),s()})})}historyPatch(e,t,i=this.setPendingLink(e)){this.commitPendingLink(i)&&(K.pushState(t,{type:"patch",id:this.main.id},e),c.dispatchEvent(window,"phx:navigate",{detail:{patch:!0,href:e,pop:!1}}),this.registerNewLocation(window.location))}historyRedirect(e,t,i){if(!this.isConnected()||!this.main.isMain())return K.redirect(e,i);if(/^\/$|^\/[^\/]+.*$/.test(e)){let{protocol:r,host:n}=window.location;e=`${r}//${n}${e}`}let s=window.scrollY;this.withPageLoading({to:e,kind:"redirect"},r=>{this.replaceMain(e,i,n=>{n===this.linkRef&&(K.pushState(t,{type:"redirect",id:this.main.id,scroll:s},e),c.dispatchEvent(window,"phx:navigate",{detail:{href:e,patch:!1,pop:!1}}),this.registerNewLocation(window.location)),r()})})}replaceRootHistory(){K.pushState("replace",{root:!0,type:"patch",id:this.main.id})}registerNewLocation(e){let{pathname:t,search:i}=this.currentLocation;return t+i===e.pathname+e.search?!1:(this.currentLocation=et(e),!0)}bindForms(){let e=0,t=!1;this.on("submit",i=>{let s=i.target.getAttribute(this.binding("submit")),r=i.target.getAttribute(this.binding("change"));!t&&r&&!s&&(t=!0,i.preventDefault(),this.withinOwners(i.target,n=>{n.disableForm(i.target),window.requestAnimationFrame(()=>{c.isUnloadableFormSubmit(i)&&this.unload(),i.target.submit()})}))},!0),this.on("submit",i=>{let s=i.target.getAttribute(this.binding("submit"));if(!s){c.isUnloadableFormSubmit(i)&&this.unload();return}i.preventDefault(),i.target.disabled=!0,this.withinOwners(i.target,r=>{M.exec("submit",s,r,i.target,["push",{submitter:i.submitter}])})},!1);for(let i of["change","input"])this.on(i,s=>{let r=this.binding("change"),n=s.target,a=n.getAttribute(r),o=n.form&&n.form.getAttribute(r),l=a||o;if(!l||n.type==="number"&&n.validity&&n.validity.badInput)return;let h=a?n:n.form,d=e;e++;let{at:m,type:p}=c.private(n,"prev-iteration")||{};m===d-1&&i==="change"&&p==="input"||(c.putPrivate(n,"prev-iteration",{at:d,type:i}),this.debounce(n,s,i,()=>{this.withinOwners(h,f=>{c.putPrivate(n,Rt,!0),c.isTextualInput(n)||this.setActiveElement(n),M.exec("change",l,f,n,["push",{_target:s.target.name,dispatcher:h}])})}))},!1);this.on("reset",i=>{let s=i.target;c.resetForm(s,this.binding(tt),this.binding(it));let r=Array.from(s.elements).find(n=>n.type==="reset");r&&window.requestAnimationFrame(()=>{r.dispatchEvent(new Event("input",{bubbles:!0,cancelable:!1}))})})}debounce(e,t,i,s){if(i==="blur"||i==="focusout")return s();let r=this.binding(Ls),n=this.binding(Os),a=this.defaults.debounce.toString(),o=this.defaults.throttle.toString();this.withinOwners(e,l=>{let h=()=>!l.isDestroyed()&&document.body.contains(e);c.debounce(e,t,r,a,n,o,h,()=>{s()})})}silenceEvents(e){this.silenced=!0,e(),this.silenced=!1}on(e,t){window.addEventListener(e,i=>{this.silenced||t(i)})}},gr=class{constructor(){this.transitions=new Set,this.pendingOps=[]}reset(){this.transitions.forEach(e=>{clearTimeout(e),this.transitions.delete(e)}),this.flushPendingOps()}after(e){this.size()===0?e():this.pushPendingOp(e)}addTransition(e,t,i){t();let s=setTimeout(()=>{this.transitions.delete(s),i(),this.flushPendingOps()},e);this.transitions.add(s)}pushPendingOp(e){this.pendingOps.push(e)}size(){return this.transitions.size}flushPendingOps(){if(this.size()>0)return;let e=this.pendingOps.shift();e&&(e(),this.flushPendingOps())}};var dt=ms(Mi());function vr(e,t){e.indexOf(t)===-1&&e.push(t)}var Wi=(e,t,i)=>Math.min(Math.max(i,e),t),J={duration:.3,delay:0,endDelay:0,repeat:0,easing:"ease"},ot=e=>typeof e=="number",we=e=>Array.isArray(e)&&!ot(e[0]),br=(e,t,i)=>{let s=t-e;return((i-e)%s+s)%s+e};function yr(e,t){return we(e)?e[br(0,e.length,t)]:e}var Xi=(e,t,i)=>-i*e+i*t+e,zi=()=>{},oe=e=>e,Vt=(e,t,i)=>t-e===0?1:(i-e)/(t-e);function Ki(e,t){let i=e[e.length-1];for(let s=1;s<=t;s++){let r=Vt(0,t,s);e.push(Xi(i,1,r))}}function wr(e){let t=[0];return Ki(t,e-1),t}function Ar(e,t=wr(e.length),i=oe){let s=e.length,r=s-t.length;return r>0&&Ki(t,r),n=>{let a=0;for(;aArray.isArray(e)&&ot(e[0]),Nt=e=>typeof e=="object"&&!!e.createAnimation,Ae=e=>typeof e=="function",Sr=e=>typeof e=="string",He={ms:e=>e*1e3,s:e=>e/1e3},Yi=(e,t,i)=>(((1-3*i+3*t)*e+(3*i-6*t))*e+3*t)*e,Er=1e-7,kr=12;function Cr(e,t,i,s,r){let n,a,o=0;do a=t+(i-t)/2,n=Yi(a,s,r)-e,n>0?i=a:t=a;while(Math.abs(n)>Er&&++oCr(n,0,1,e,i);return n=>n===0||n===1?n:Yi(r(n),t,s)}var Tr=(e,t="end")=>i=>{i=t==="end"?Math.min(i,.999):Math.max(i,.001);let s=i*e,r=t==="end"?Math.floor(s):Math.ceil(s);return Wi(0,1,r/e)},Ni={ease:Fe(.25,.1,.25,1),"ease-in":Fe(.42,0,1,1),"ease-in-out":Fe(.42,0,.58,1),"ease-out":Fe(0,0,.58,1)},_r=/\((.*?)\)/;function $i(e){if(Ae(e))return e;if(Gi(e))return Fe(...e);if(Ni[e])return Ni[e];if(e.startsWith("steps")){let t=_r.exec(e);if(t){let i=t[1].split(",");return Tr(parseFloat(i[0]),i[1].trim())}}return oe}var Zi=class{constructor(e,t=[0,1],{easing:i,duration:s=J.duration,delay:r=J.delay,endDelay:n=J.endDelay,repeat:a=J.repeat,offset:o,direction:l="normal",autoplay:h=!0}={}){if(this.startTime=null,this.rate=1,this.t=0,this.cancelTimestamp=null,this.easing=oe,this.duration=0,this.totalDuration=0,this.repeat=0,this.playState="idle",this.finished=new Promise((m,p)=>{this.resolve=m,this.reject=p}),i=i||J.easing,Nt(i)){let m=i.createAnimation(t);i=m.easing,t=m.keyframes||t,s=m.duration||s}this.repeat=a,this.easing=we(i)?oe:$i(i),this.updateDuration(s);let d=Ar(t,o,we(i)?i.map($i):oe);this.tick=m=>{var p;r=r;let f=0;this.pauseTime!==void 0?f=this.pauseTime:f=(m-this.startTime)*this.rate,this.t=f,f/=1e3,f=Math.max(f-r,0),this.playState==="finished"&&this.pauseTime===void 0&&(f=this.totalDuration);let g=f/this.duration,v=Math.floor(g),E=g%1;!E&&g>=1&&(E=1),E===1&&v--;let _=v%2;(l==="reverse"||l==="alternate"&&_||l==="alternate-reverse"&&!_)&&(E=1-E);let R=f>=this.totalDuration?1:Math.min(E,1),T=d(this.easing(R));e(T),this.pauseTime===void 0&&(this.playState==="finished"||f>=this.totalDuration+n)?(this.playState="finished",(p=this.resolve)===null||p===void 0||p.call(this,T)):this.playState!=="idle"&&(this.frameRequestId=requestAnimationFrame(this.tick))},h&&this.play()}play(){let e=performance.now();this.playState="running",this.pauseTime!==void 0?this.startTime=e-this.pauseTime:this.startTime||(this.startTime=e),this.cancelTimestamp=this.startTime,this.pauseTime=void 0,this.frameRequestId=requestAnimationFrame(this.tick)}pause(){this.playState="paused",this.pauseTime=this.t}finish(){this.playState="finished",this.tick(0)}stop(){var e;this.playState="idle",this.frameRequestId!==void 0&&cancelAnimationFrame(this.frameRequestId),(e=this.reject)===null||e===void 0||e.call(this,!1)}cancel(){this.stop(),this.tick(this.cancelTimestamp)}reverse(){this.rate*=-1}commitStyles(){}updateDuration(e){this.duration=e,this.totalDuration=e*(this.repeat+1)}get currentTime(){return this.t}set currentTime(e){this.pauseTime!==void 0||this.rate===0?this.pauseTime=e:this.startTime=performance.now()-e/this.rate}get playbackRate(){return this.rate}set playbackRate(e){this.rate=e}},Rr=function(){},$t=function(){};Rr=function(e,t){!e&&typeof console!="undefined"&&console.warn(t)},$t=function(e,t){if(!e)throw new Error(t)};var Pr=class{setAnimation(e){this.animation=e,e==null||e.finished.then(()=>this.clearAnimation()).catch(()=>{})}clearAnimation(){this.animation=this.generator=void 0}},Dt=new WeakMap;function Qi(e){return Dt.has(e)||Dt.set(e,{transforms:[],values:new Map}),Dt.get(e)}function xr(e,t){return e.has(t)||e.set(t,new Pr),e.get(t)}var Ir=["","X","Y","Z"],Lr=["translate","scale","rotate","skew"],lt={x:"translateX",y:"translateY",z:"translateZ"},Ui={syntax:"",initialValue:"0deg",toDefaultUnit:e=>e+"deg"},Or={translate:{syntax:"",initialValue:"0px",toDefaultUnit:e=>e+"px"},rotate:Ui,scale:{syntax:"",initialValue:1,toDefaultUnit:oe},skew:Ui},Me=new Map,Jt=e=>`--motion-${e}`,ht=["x","y","z"];Lr.forEach(e=>{Ir.forEach(t=>{ht.push(e+t),Me.set(Jt(e+t),Or[e])})});var Dr=(e,t)=>ht.indexOf(e)-ht.indexOf(t),Fr=new Set(ht),es=e=>Fr.has(e),Hr=(e,t)=>{lt[t]&&(t=lt[t]);let{transforms:i}=Qi(e);vr(i,t),e.style.transform=Mr(i)},Mr=e=>e.sort(Dr).reduce(Nr,"").trim(),Nr=(e,t)=>`${e} ${t}(var(${Jt(t)}))`,Ut=e=>e.startsWith("--"),ji=new Set;function $r(e){if(!ji.has(e)){ji.add(e);try{let{syntax:t,initialValue:i}=Me.has(e)?Me.get(e):{};CSS.registerProperty({name:e,inherits:!1,syntax:t,initialValue:i})}catch(t){}}}var Ft=(e,t)=>document.createElement("div").animate(e,t),Bi={cssRegisterProperty:()=>typeof CSS!="undefined"&&Object.hasOwnProperty.call(CSS,"registerProperty"),waapi:()=>Object.hasOwnProperty.call(Element.prototype,"animate"),partialKeyframes:()=>{try{Ft({opacity:[1]})}catch(e){return!1}return!0},finished:()=>!!Ft({opacity:[0,1]},{duration:.001}).finished,linearEasing:()=>{try{Ft({opacity:0},{easing:"linear(0, 1)"})}catch(e){return!1}return!0}},Ht={},ye={};for(let e in Bi)ye[e]=()=>(Ht[e]===void 0&&(Ht[e]=Bi[e]()),Ht[e]);var Ur=.015,jr=(e,t)=>{let i="",s=Math.round(t/Ur);for(let r=0;rAe(e)?ye.linearEasing()?`linear(${jr(e,t)})`:J.easing:Gi(e)?Br(e):e,Br=([e,t,i,s])=>`cubic-bezier(${e}, ${t}, ${i}, ${s})`;function Vr(e,t){for(let i=0;iArray.isArray(e)?e:[e];function jt(e){return lt[e]&&(e=lt[e]),es(e)?Jt(e):e}var at={get:(e,t)=>{t=jt(t);let i=Ut(t)?e.style.getPropertyValue(t):getComputedStyle(e)[t];if(!i&&i!==0){let s=Me.get(t);s&&(i=s.initialValue)}return i},set:(e,t,i)=>{t=jt(t),Ut(t)?e.style.setProperty(t,i):e.style[t]=i}};function ts(e,t=!0){if(!(!e||e.playState==="finished"))try{e.stop?e.stop():(t&&e.commitStyles(),e.cancel())}catch(i){}}function qr(e,t){var i;let s=(t==null?void 0:t.toDefaultUnit)||oe,r=e[e.length-1];if(Sr(r)){let n=((i=r.match(/(-?[\d.]+)([a-z%]*)/))===null||i===void 0?void 0:i[2])||"";n&&(s=a=>a+n)}return s}function Wr(){return window.__MOTION_DEV_TOOLS_RECORD}function Xr(e,t,i,s={},r){let n=Wr(),a=s.record!==!1&&n,o,{duration:l=J.duration,delay:h=J.delay,endDelay:d=J.endDelay,repeat:m=J.repeat,easing:p=J.easing,persist:f=!1,direction:g,offset:v,allowWebkitAcceleration:E=!1,autoplay:_=!0}=s,R=Qi(e),T=es(t),x=ye.waapi();T&&Hr(e,t);let O=jt(t),k=xr(R.values,O),D=Me.get(O);return ts(k.animation,!(Nt(p)&&k.generator)&&s.record!==!1),()=>{let B=()=>{var b,I;return(I=(b=at.get(e,O))!==null&&b!==void 0?b:D==null?void 0:D.initialValue)!==null&&I!==void 0?I:0},u=Vr(Jr(i),B),y=qr(u,D);if(Nt(p)){let b=p.createAnimation(u,t!=="opacity",B,O,k);p=b.easing,u=b.keyframes||u,l=b.duration||l}if(Ut(O)&&(ye.cssRegisterProperty()?$r(O):x=!1),T&&!ye.linearEasing()&&(Ae(p)||we(p)&&p.some(Ae))&&(x=!1),x){D&&(u=u.map(F=>ot(F)?D.toDefaultUnit(F):F)),u.length===1&&(!ye.partialKeyframes()||a)&&u.unshift(B());let b={delay:He.ms(h),duration:He.ms(l),endDelay:He.ms(d),easing:we(p)?void 0:Vi(p,l),direction:g,iterations:m+1,fill:"both"};o=e.animate({[O]:u,offset:v,easing:we(p)?p.map(F=>Vi(F,l)):void 0},b),o.finished||(o.finished=new Promise((F,Se)=>{o.onfinish=F,o.oncancel=Se}));let I=u[u.length-1];o.finished.then(()=>{f||(at.set(e,O,I),o.cancel())}).catch(zi),E||(o.playbackRate=1.000001)}else if(r&&T)u=u.map(b=>typeof b=="string"?parseFloat(b):b),u.length===1&&u.unshift(parseFloat(B())),o=new r(b=>{at.set(e,O,y?y(b):b)},u,Object.assign(Object.assign({},s),{duration:l,easing:p}));else{let b=u[u.length-1];at.set(e,O,D&&ot(b)?D.toDefaultUnit(b):b)}return a&&n(e,t,u,{duration:l,delay:h,easing:p,repeat:m,offset:v},"motion-one"),k.setAnimation(o),o&&!_&&o.pause(),o}}var zr=(e,t)=>e[t]?Object.assign(Object.assign({},e),e[t]):Object.assign({},e);function Kr(e,t){var i;return typeof e=="string"?t?((i=t[e])!==null&&i!==void 0||(t[e]=document.querySelectorAll(e)),e=t[e]):e=document.querySelectorAll(e):e instanceof Element&&(e=[e]),Array.from(e||[])}var Gr=e=>e(),is=(e,t,i=J.duration)=>new Proxy({animations:e.map(Gr).filter(Boolean),duration:i,options:t},Zr),Yr=e=>e.animations[0],Zr={get:(e,t)=>{let i=Yr(e);switch(t){case"duration":return e.duration;case"currentTime":return He.s((i==null?void 0:i[t])||0);case"playbackRate":case"playState":return i==null?void 0:i[t];case"finished":return e.finished||(e.finished=Promise.all(e.animations.map(Qr)).catch(zi)),e.finished;case"stop":return()=>{e.animations.forEach(s=>ts(s))};case"forEachNative":return s=>{e.animations.forEach(r=>s(r,e))};default:return typeof(i==null?void 0:i[t])=="undefined"?void 0:()=>e.animations.forEach(s=>s[t]())}},set:(e,t,i)=>{switch(t){case"currentTime":i=He.ms(i);case"playbackRate":for(let s=0;se.finished;function en(e,t,i){return Ae(e)?e(t,i):e}function tn(e){return function(i,s,r={}){i=Kr(i);let n=i.length;$t(!!n,"No valid element provided."),$t(!!s,"No keyframes defined.");let a=[];for(let o=0;o{let i=new Zi(e,[0,1],t);return i.finished.catch(()=>{}),i}],t,t.duration)}function qt(e,t,i){return(Ae(e)?rn:sn)(e,t,i)}function ce(e){return e===null?!0:e.offsetParent===null}function nn(e){return e.dataset.component==="flash"}function an(){let e=0;return ce(document.getElementById("server-error"))||(e+=1),ce(document.getElementById("client-error"))||(e+=1),ce(document.getElementById("flash-info"))||(e+=1),ce(document.getElementById("flash-error"))||(e+=1),e}var ss=5,on=550,ln=!0,Bt=15,Ji=[];function Mt(e,t,i){let s=[],r=Array.from(document.querySelectorAll('#toast-group [phx-hook="LiveToast"]')).map(n=>ce(n)?null:n).filter(Boolean).reverse();i&&(r=r.filter(n=>n!==i));for(let n=0;na?0:1-(o.order-a+1);o.order>=a?o.classList.remove("pointer-events-auto"):o.classList.add("pointer-events-auto");let m={y:[`${l}${h}px`],opacity:[d]};if(o.order===0&&Ji.includes(o)===!1){let f=o.offsetHeight+Bt,g=l==="-"?"":"-";m.y.unshift(`${g}${f}px`),m.opacity.unshift(0)}o.targetDestination=`${l}${h}px`;let p=on/1e3;qt(o,m,{duration:p,easing:[.22,1,.36,1]}),o.order+=1,o.style.zIndex=(50-o.order).toString(),window.setTimeout(()=>{o.order>a&&this.pushEventTo("#toast-group","clear",{id:o.id})},e+ss),Ji=s}}async function qi(){let e=(this.el.order-2)*100+(this.el.order-2)*Bt,t="";(this.el.dataset.corner==="bottom_left"||this.el.dataset.corner==="bottom_right")&&(t="-"),await qt(this.el,{y:`${t}${e}%`,opacity:0},{opacity:{duration:.2,easing:"ease-out"},duration:.3,easing:"ease-out"}).finished}function rs(e=6e3,t=3){return{destroyed(){Mt.bind(this)(e,t)},updated(){let i={y:[this.el.targetDestination]};qt(this.el,i,{duration:0})},mounted(){if(["server-error","client-error"].includes(this.el.id)&&ce(document.getElementById(this.el.id))||(window.addEventListener("flash-leave",async s=>{s.target===this.el&&(Mt.bind(this,e,t,this.el)(),await qi.bind(this)())}),Mt.bind(this)(e,t),nn(this.el)))return;let i=e;this.el.dataset.duration!==void 0&&(i=Number.parseInt(this.el.dataset.duration)),window.setTimeout(async()=>{await qi.bind(this)(),this.pushEventTo("#toast-group","clear",{id:this.el.id})},i+ss)}}}var hn=document.querySelector("meta[name='csrf-token']").getAttribute("content"),dn={LiveToast:rs()},ns=new Fi("/live",Zt,{params:{_csrf_token:hn},hooks:dn});dt.default.config({barColors:{0:"#29d"},shadowColor:"rgba(0, 0, 0, .3)"});window.addEventListener("phx:page-loading-start",e=>dt.default.show(300));window.addEventListener("phx:page-loading-stop",e=>dt.default.hide());ns.connect();window.liveSocket=ns;})();
+ `);
+ }
+ this.socket = new phxSocket(url, opts);
+ this.bindingPrefix = opts.bindingPrefix || BINDING_PREFIX;
+ this.opts = opts;
+ this.params = closure2(opts.params || {});
+ this.viewLogger = opts.viewLogger;
+ this.metadataCallbacks = opts.metadata || {};
+ this.defaults = Object.assign(clone(DEFAULTS), opts.defaults || {});
+ this.activeElement = null;
+ this.prevActive = null;
+ this.silenced = false;
+ this.main = null;
+ this.outgoingMainEl = null;
+ this.clickStartedAtTarget = null;
+ this.linkRef = 1;
+ this.roots = {};
+ this.href = window.location.href;
+ this.pendingLink = null;
+ this.currentLocation = clone(window.location);
+ this.hooks = opts.hooks || {};
+ this.uploaders = opts.uploaders || {};
+ this.loaderTimeout = opts.loaderTimeout || LOADER_TIMEOUT;
+ this.reloadWithJitterTimer = null;
+ this.maxReloads = opts.maxReloads || MAX_RELOADS;
+ this.reloadJitterMin = opts.reloadJitterMin || RELOAD_JITTER_MIN;
+ this.reloadJitterMax = opts.reloadJitterMax || RELOAD_JITTER_MAX;
+ this.failsafeJitter = opts.failsafeJitter || FAILSAFE_JITTER;
+ this.localStorage = opts.localStorage || window.localStorage;
+ this.sessionStorage = opts.sessionStorage || window.sessionStorage;
+ this.boundTopLevelEvents = false;
+ this.serverCloseRef = null;
+ this.domCallbacks = Object.assign({
+ onPatchStart: closure2(),
+ onPatchEnd: closure2(),
+ onNodeAdded: closure2(),
+ onBeforeElUpdated: closure2()
+ }, opts.dom || {});
+ this.transitions = new TransitionSet();
+ window.addEventListener("pagehide", (_e) => {
+ this.unloaded = true;
+ });
+ this.socket.onOpen(() => {
+ if (this.isUnloaded()) {
+ window.location.reload();
+ }
+ });
+ }
+ version() {
+ return "0.20.17";
+ }
+ isProfileEnabled() {
+ return this.sessionStorage.getItem(PHX_LV_PROFILE) === "true";
+ }
+ isDebugEnabled() {
+ return this.sessionStorage.getItem(PHX_LV_DEBUG) === "true";
+ }
+ isDebugDisabled() {
+ return this.sessionStorage.getItem(PHX_LV_DEBUG) === "false";
+ }
+ enableDebug() {
+ this.sessionStorage.setItem(PHX_LV_DEBUG, "true");
+ }
+ enableProfiling() {
+ this.sessionStorage.setItem(PHX_LV_PROFILE, "true");
+ }
+ disableDebug() {
+ this.sessionStorage.setItem(PHX_LV_DEBUG, "false");
+ }
+ disableProfiling() {
+ this.sessionStorage.removeItem(PHX_LV_PROFILE);
+ }
+ enableLatencySim(upperBoundMs) {
+ this.enableDebug();
+ console.log("latency simulator enabled for the duration of this browser session. Call disableLatencySim() to disable");
+ this.sessionStorage.setItem(PHX_LV_LATENCY_SIM, upperBoundMs);
+ }
+ disableLatencySim() {
+ this.sessionStorage.removeItem(PHX_LV_LATENCY_SIM);
+ }
+ getLatencySim() {
+ let str = this.sessionStorage.getItem(PHX_LV_LATENCY_SIM);
+ return str ? parseInt(str) : null;
+ }
+ getSocket() {
+ return this.socket;
+ }
+ connect() {
+ if (window.location.hostname === "localhost" && !this.isDebugDisabled()) {
+ this.enableDebug();
+ }
+ let doConnect = () => {
+ if (this.joinRootViews()) {
+ this.bindTopLevelEvents();
+ this.socket.connect();
+ } else if (this.main) {
+ this.socket.connect();
+ } else {
+ this.bindTopLevelEvents({ dead: true });
+ }
+ this.joinDeadView();
+ };
+ if (["complete", "loaded", "interactive"].indexOf(document.readyState) >= 0) {
+ doConnect();
+ } else {
+ document.addEventListener("DOMContentLoaded", () => doConnect());
+ }
+ }
+ disconnect(callback) {
+ clearTimeout(this.reloadWithJitterTimer);
+ if (this.serverCloseRef) {
+ this.socket.off(this.serverCloseRef);
+ this.serverCloseRef = null;
+ }
+ this.socket.disconnect(callback);
+ }
+ replaceTransport(transport) {
+ clearTimeout(this.reloadWithJitterTimer);
+ this.socket.replaceTransport(transport);
+ this.connect();
+ }
+ execJS(el, encodedJS, eventType = null) {
+ this.owner(el, (view) => js_default.exec(eventType, encodedJS, view, el));
+ }
+ execJSHookPush(el, phxEvent, data2, callback) {
+ this.withinOwners(el, (view) => {
+ js_default.exec("hook", phxEvent, view, el, ["push", { data: data2, callback }]);
+ });
+ }
+ unload() {
+ if (this.unloaded) {
+ return;
+ }
+ if (this.main && this.isConnected()) {
+ this.log(this.main, "socket", () => ["disconnect for page nav"]);
+ }
+ this.unloaded = true;
+ this.destroyAllViews();
+ this.disconnect();
+ }
+ triggerDOM(kind, args) {
+ this.domCallbacks[kind](...args);
+ }
+ time(name, func) {
+ if (!this.isProfileEnabled() || !console.time) {
+ return func();
+ }
+ console.time(name);
+ let result = func();
+ console.timeEnd(name);
+ return result;
+ }
+ log(view, kind, msgCallback) {
+ if (this.viewLogger) {
+ let [msg, obj] = msgCallback();
+ this.viewLogger(view, kind, msg, obj);
+ } else if (this.isDebugEnabled()) {
+ let [msg, obj] = msgCallback();
+ debug(view, kind, msg, obj);
+ }
+ }
+ requestDOMUpdate(callback) {
+ this.transitions.after(callback);
+ }
+ transition(time2, onStart, onDone = function() {
+ }) {
+ this.transitions.addTransition(time2, onStart, onDone);
+ }
+ onChannel(channel, event, cb) {
+ channel.on(event, (data2) => {
+ let latency = this.getLatencySim();
+ if (!latency) {
+ cb(data2);
+ } else {
+ setTimeout(() => cb(data2), latency);
+ }
+ });
+ }
+ wrapPush(view, opts, push) {
+ let latency = this.getLatencySim();
+ let oldJoinCount = view.joinCount;
+ if (!latency) {
+ if (this.isConnected() && opts.timeout) {
+ return push().receive("timeout", () => {
+ if (view.joinCount === oldJoinCount && !view.isDestroyed()) {
+ this.reloadWithJitter(view, () => {
+ this.log(view, "timeout", () => ["received timeout while communicating with server. Falling back to hard refresh for recovery"]);
+ });
+ }
+ });
+ } else {
+ return push();
+ }
+ }
+ let fakePush = {
+ receives: [],
+ receive(kind, cb) {
+ this.receives.push([kind, cb]);
+ }
+ };
+ setTimeout(() => {
+ if (view.isDestroyed()) {
+ return;
+ }
+ fakePush.receives.reduce((acc, [kind, cb]) => acc.receive(kind, cb), push());
+ }, latency);
+ return fakePush;
+ }
+ reloadWithJitter(view, log) {
+ clearTimeout(this.reloadWithJitterTimer);
+ this.disconnect();
+ let minMs = this.reloadJitterMin;
+ let maxMs = this.reloadJitterMax;
+ let afterMs = Math.floor(Math.random() * (maxMs - minMs + 1)) + minMs;
+ let tries = browser_default.updateLocal(this.localStorage, window.location.pathname, CONSECUTIVE_RELOADS, 0, (count) => count + 1);
+ if (tries > this.maxReloads) {
+ afterMs = this.failsafeJitter;
+ }
+ this.reloadWithJitterTimer = setTimeout(() => {
+ if (view.isDestroyed() || view.isConnected()) {
+ return;
+ }
+ view.destroy();
+ log ? log() : this.log(view, "join", () => [`encountered ${tries} consecutive reloads`]);
+ if (tries > this.maxReloads) {
+ this.log(view, "join", () => [`exceeded ${this.maxReloads} consecutive reloads. Entering failsafe mode`]);
+ }
+ if (this.hasPendingLink()) {
+ window.location = this.pendingLink;
+ } else {
+ window.location.reload();
+ }
+ }, afterMs);
+ }
+ getHookCallbacks(name) {
+ return name && name.startsWith("Phoenix.") ? hooks_default[name.split(".")[1]] : this.hooks[name];
+ }
+ isUnloaded() {
+ return this.unloaded;
+ }
+ isConnected() {
+ return this.socket.isConnected();
+ }
+ getBindingPrefix() {
+ return this.bindingPrefix;
+ }
+ binding(kind) {
+ return `${this.getBindingPrefix()}${kind}`;
+ }
+ channel(topic, params) {
+ return this.socket.channel(topic, params);
+ }
+ joinDeadView() {
+ let body = document.body;
+ if (body && !this.isPhxView(body) && !this.isPhxView(document.firstElementChild)) {
+ let view = this.newRootView(body);
+ view.setHref(this.getHref());
+ view.joinDead();
+ if (!this.main) {
+ this.main = view;
+ }
+ window.requestAnimationFrame(() => view.execNewMounted());
+ }
+ }
+ joinRootViews() {
+ let rootsFound = false;
+ dom_default.all(document, `${PHX_VIEW_SELECTOR}:not([${PHX_PARENT_ID}])`, (rootEl) => {
+ if (!this.getRootById(rootEl.id)) {
+ let view = this.newRootView(rootEl);
+ view.setHref(this.getHref());
+ view.join();
+ if (rootEl.hasAttribute(PHX_MAIN)) {
+ this.main = view;
+ }
+ }
+ rootsFound = true;
+ });
+ return rootsFound;
+ }
+ redirect(to, flash) {
+ this.unload();
+ browser_default.redirect(to, flash);
+ }
+ replaceMain(href, flash, callback = null, linkRef = this.setPendingLink(href)) {
+ let liveReferer = this.currentLocation.href;
+ this.outgoingMainEl = this.outgoingMainEl || this.main.el;
+ let newMainEl = dom_default.cloneNode(this.outgoingMainEl, "");
+ this.main.showLoader(this.loaderTimeout);
+ this.main.destroy();
+ this.main = this.newRootView(newMainEl, flash, liveReferer);
+ this.main.setRedirect(href);
+ this.transitionRemoves(null, true);
+ this.main.join((joinCount, onDone) => {
+ if (joinCount === 1 && this.commitPendingLink(linkRef)) {
+ this.requestDOMUpdate(() => {
+ dom_default.findPhxSticky(document).forEach((el) => newMainEl.appendChild(el));
+ this.outgoingMainEl.replaceWith(newMainEl);
+ this.outgoingMainEl = null;
+ callback && callback(linkRef);
+ onDone();
+ });
+ }
+ });
+ }
+ transitionRemoves(elements, skipSticky) {
+ let removeAttr = this.binding("remove");
+ elements = elements || dom_default.all(document, `[${removeAttr}]`);
+ if (skipSticky) {
+ const stickies = dom_default.findPhxSticky(document) || [];
+ elements = elements.filter((el) => !dom_default.isChildOfAny(el, stickies));
+ }
+ elements.forEach((el) => {
+ this.execJS(el, el.getAttribute(removeAttr), "remove");
+ });
+ }
+ isPhxView(el) {
+ return el.getAttribute && el.getAttribute(PHX_SESSION) !== null;
+ }
+ newRootView(el, flash, liveReferer) {
+ let view = new View(el, this, null, flash, liveReferer);
+ this.roots[view.id] = view;
+ return view;
+ }
+ owner(childEl, callback) {
+ let view = maybe(childEl.closest(PHX_VIEW_SELECTOR), (el) => this.getViewByEl(el)) || this.main;
+ if (view) {
+ callback(view);
+ }
+ }
+ withinOwners(childEl, callback) {
+ this.owner(childEl, (view) => callback(view, childEl));
+ }
+ getViewByEl(el) {
+ let rootId = el.getAttribute(PHX_ROOT_ID);
+ return maybe(this.getRootById(rootId), (root) => root.getDescendentByEl(el));
+ }
+ getRootById(id) {
+ return this.roots[id];
+ }
+ destroyAllViews() {
+ for (let id in this.roots) {
+ this.roots[id].destroy();
+ delete this.roots[id];
+ }
+ this.main = null;
+ }
+ destroyViewByEl(el) {
+ let root = this.getRootById(el.getAttribute(PHX_ROOT_ID));
+ if (root && root.id === el.id) {
+ root.destroy();
+ delete this.roots[root.id];
+ } else if (root) {
+ root.destroyDescendent(el.id);
+ }
+ }
+ setActiveElement(target) {
+ if (this.activeElement === target) {
+ return;
+ }
+ this.activeElement = target;
+ let cancel = () => {
+ if (target === this.activeElement) {
+ this.activeElement = null;
+ }
+ target.removeEventListener("mouseup", this);
+ target.removeEventListener("touchend", this);
+ };
+ target.addEventListener("mouseup", cancel);
+ target.addEventListener("touchend", cancel);
+ }
+ getActiveElement() {
+ if (document.activeElement === document.body) {
+ return this.activeElement || document.activeElement;
+ } else {
+ return document.activeElement || document.body;
+ }
+ }
+ dropActiveElement(view) {
+ if (this.prevActive && view.ownsElement(this.prevActive)) {
+ this.prevActive = null;
+ }
+ }
+ restorePreviouslyActiveFocus() {
+ if (this.prevActive && this.prevActive !== document.body) {
+ this.prevActive.focus();
+ }
+ }
+ blurActiveElement() {
+ this.prevActive = this.getActiveElement();
+ if (this.prevActive !== document.body) {
+ this.prevActive.blur();
+ }
+ }
+ bindTopLevelEvents({ dead } = {}) {
+ if (this.boundTopLevelEvents) {
+ return;
+ }
+ this.boundTopLevelEvents = true;
+ this.serverCloseRef = this.socket.onClose((event) => {
+ if (event && event.code === 1e3 && this.main) {
+ return this.reloadWithJitter(this.main);
+ }
+ });
+ document.body.addEventListener("click", function() {
+ });
+ window.addEventListener("pageshow", (e) => {
+ if (e.persisted) {
+ this.getSocket().disconnect();
+ this.withPageLoading({ to: window.location.href, kind: "redirect" });
+ window.location.reload();
+ }
+ }, true);
+ if (!dead) {
+ this.bindNav();
+ }
+ this.bindClicks();
+ if (!dead) {
+ this.bindForms();
+ }
+ this.bind({ keyup: "keyup", keydown: "keydown" }, (e, type, view, targetEl, phxEvent, phxTarget) => {
+ let matchKey = targetEl.getAttribute(this.binding(PHX_KEY));
+ let pressedKey = e.key && e.key.toLowerCase();
+ if (matchKey && matchKey.toLowerCase() !== pressedKey) {
+ return;
+ }
+ let data2 = __spreadValues({ key: e.key }, this.eventMeta(type, e, targetEl));
+ js_default.exec(type, phxEvent, view, targetEl, ["push", { data: data2 }]);
+ });
+ this.bind({ blur: "focusout", focus: "focusin" }, (e, type, view, targetEl, phxEvent, phxTarget) => {
+ if (!phxTarget) {
+ let data2 = __spreadValues({ key: e.key }, this.eventMeta(type, e, targetEl));
+ js_default.exec(type, phxEvent, view, targetEl, ["push", { data: data2 }]);
+ }
+ });
+ this.bind({ blur: "blur", focus: "focus" }, (e, type, view, targetEl, phxEvent, phxTarget) => {
+ if (phxTarget === "window") {
+ let data2 = this.eventMeta(type, e, targetEl);
+ js_default.exec(type, phxEvent, view, targetEl, ["push", { data: data2 }]);
+ }
+ });
+ window.addEventListener("dragover", (e) => e.preventDefault());
+ window.addEventListener("drop", (e) => {
+ e.preventDefault();
+ let dropTargetId = maybe(closestPhxBinding(e.target, this.binding(PHX_DROP_TARGET)), (trueTarget) => {
+ return trueTarget.getAttribute(this.binding(PHX_DROP_TARGET));
+ });
+ let dropTarget = dropTargetId && document.getElementById(dropTargetId);
+ let files = Array.from(e.dataTransfer.files || []);
+ if (!dropTarget || dropTarget.disabled || files.length === 0 || !(dropTarget.files instanceof FileList)) {
+ return;
+ }
+ LiveUploader.trackFiles(dropTarget, files, e.dataTransfer);
+ dropTarget.dispatchEvent(new Event("input", { bubbles: true }));
+ });
+ this.on(PHX_TRACK_UPLOADS, (e) => {
+ let uploadTarget = e.target;
+ if (!dom_default.isUploadInput(uploadTarget)) {
+ return;
+ }
+ let files = Array.from(e.detail.files || []).filter((f) => f instanceof File || f instanceof Blob);
+ LiveUploader.trackFiles(uploadTarget, files);
+ uploadTarget.dispatchEvent(new Event("input", { bubbles: true }));
+ });
+ }
+ eventMeta(eventName, e, targetEl) {
+ let callback = this.metadataCallbacks[eventName];
+ return callback ? callback(e, targetEl) : {};
+ }
+ setPendingLink(href) {
+ this.linkRef++;
+ this.pendingLink = href;
+ return this.linkRef;
+ }
+ commitPendingLink(linkRef) {
+ if (this.linkRef !== linkRef) {
+ return false;
+ } else {
+ this.href = this.pendingLink;
+ this.pendingLink = null;
+ return true;
+ }
+ }
+ getHref() {
+ return this.href;
+ }
+ hasPendingLink() {
+ return !!this.pendingLink;
+ }
+ bind(events, callback) {
+ for (let event in events) {
+ let browserEventName = events[event];
+ this.on(browserEventName, (e) => {
+ let binding = this.binding(event);
+ let windowBinding = this.binding(`window-${event}`);
+ let targetPhxEvent = e.target.getAttribute && e.target.getAttribute(binding);
+ if (targetPhxEvent) {
+ this.debounce(e.target, e, browserEventName, () => {
+ this.withinOwners(e.target, (view) => {
+ callback(e, event, view, e.target, targetPhxEvent, null);
+ });
+ });
+ } else {
+ dom_default.all(document, `[${windowBinding}]`, (el) => {
+ let phxEvent = el.getAttribute(windowBinding);
+ this.debounce(el, e, browserEventName, () => {
+ this.withinOwners(el, (view) => {
+ callback(e, event, view, el, phxEvent, "window");
+ });
+ });
+ });
+ }
+ });
+ }
+ }
+ bindClicks() {
+ window.addEventListener("mousedown", (e) => this.clickStartedAtTarget = e.target);
+ this.bindClick("click", "click");
+ }
+ bindClick(eventName, bindingName) {
+ let click = this.binding(bindingName);
+ window.addEventListener(eventName, (e) => {
+ let target = null;
+ if (e.detail === 0)
+ this.clickStartedAtTarget = e.target;
+ let clickStartedAtTarget = this.clickStartedAtTarget || e.target;
+ target = closestPhxBinding(clickStartedAtTarget, click);
+ this.dispatchClickAway(e, clickStartedAtTarget);
+ this.clickStartedAtTarget = null;
+ let phxEvent = target && target.getAttribute(click);
+ if (!phxEvent) {
+ if (dom_default.isNewPageClick(e, window.location)) {
+ this.unload();
+ }
+ return;
+ }
+ if (target.getAttribute("href") === "#") {
+ e.preventDefault();
+ }
+ if (target.hasAttribute(PHX_REF)) {
+ return;
+ }
+ this.debounce(target, e, "click", () => {
+ this.withinOwners(target, (view) => {
+ js_default.exec("click", phxEvent, view, target, ["push", { data: this.eventMeta("click", e, target) }]);
+ });
+ });
+ }, false);
+ }
+ dispatchClickAway(e, clickStartedAt) {
+ let phxClickAway = this.binding("click-away");
+ dom_default.all(document, `[${phxClickAway}]`, (el) => {
+ if (!(el.isSameNode(clickStartedAt) || el.contains(clickStartedAt))) {
+ this.withinOwners(el, (view) => {
+ let phxEvent = el.getAttribute(phxClickAway);
+ if (js_default.isVisible(el) && js_default.isInViewport(el)) {
+ js_default.exec("click", phxEvent, view, el, ["push", { data: this.eventMeta("click", e, e.target) }]);
+ }
+ });
+ }
+ });
+ }
+ bindNav() {
+ if (!browser_default.canPushState()) {
+ return;
+ }
+ if (history.scrollRestoration) {
+ history.scrollRestoration = "manual";
+ }
+ let scrollTimer = null;
+ window.addEventListener("scroll", (_e) => {
+ clearTimeout(scrollTimer);
+ scrollTimer = setTimeout(() => {
+ browser_default.updateCurrentState((state) => Object.assign(state, { scroll: window.scrollY }));
+ }, 100);
+ });
+ window.addEventListener("popstate", (event) => {
+ if (!this.registerNewLocation(window.location)) {
+ return;
+ }
+ let { type, id, root, scroll } = event.state || {};
+ let href = window.location.href;
+ dom_default.dispatchEvent(window, "phx:navigate", { detail: { href, patch: type === "patch", pop: true } });
+ this.requestDOMUpdate(() => {
+ if (this.main.isConnected() && (type === "patch" && id === this.main.id)) {
+ this.main.pushLinkPatch(href, null, () => {
+ this.maybeScroll(scroll);
+ });
+ } else {
+ this.replaceMain(href, null, () => {
+ if (root) {
+ this.replaceRootHistory();
+ }
+ this.maybeScroll(scroll);
+ });
+ }
+ });
+ }, false);
+ window.addEventListener("click", (e) => {
+ let target = closestPhxBinding(e.target, PHX_LIVE_LINK);
+ let type = target && target.getAttribute(PHX_LIVE_LINK);
+ if (!type || !this.isConnected() || !this.main || dom_default.wantsNewTab(e)) {
+ return;
+ }
+ let href = target.href instanceof SVGAnimatedString ? target.href.baseVal : target.href;
+ let linkState = target.getAttribute(PHX_LINK_STATE);
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ if (this.pendingLink === href) {
+ return;
+ }
+ this.requestDOMUpdate(() => {
+ if (type === "patch") {
+ this.pushHistoryPatch(href, linkState, target);
+ } else if (type === "redirect") {
+ this.historyRedirect(href, linkState);
+ } else {
+ throw new Error(`expected ${PHX_LIVE_LINK} to be "patch" or "redirect", got: ${type}`);
+ }
+ let phxClick = target.getAttribute(this.binding("click"));
+ if (phxClick) {
+ this.requestDOMUpdate(() => this.execJS(target, phxClick, "click"));
+ }
+ });
+ }, false);
+ }
+ maybeScroll(scroll) {
+ if (typeof scroll === "number") {
+ requestAnimationFrame(() => {
+ window.scrollTo(0, scroll);
+ });
+ }
+ }
+ dispatchEvent(event, payload = {}) {
+ dom_default.dispatchEvent(window, `phx:${event}`, { detail: payload });
+ }
+ dispatchEvents(events) {
+ events.forEach(([event, payload]) => this.dispatchEvent(event, payload));
+ }
+ withPageLoading(info, callback) {
+ dom_default.dispatchEvent(window, "phx:page-loading-start", { detail: info });
+ let done = () => dom_default.dispatchEvent(window, "phx:page-loading-stop", { detail: info });
+ return callback ? callback(done) : done;
+ }
+ pushHistoryPatch(href, linkState, targetEl) {
+ if (!this.isConnected() || !this.main.isMain()) {
+ return browser_default.redirect(href);
+ }
+ this.withPageLoading({ to: href, kind: "patch" }, (done) => {
+ this.main.pushLinkPatch(href, targetEl, (linkRef) => {
+ this.historyPatch(href, linkState, linkRef);
+ done();
+ });
+ });
+ }
+ historyPatch(href, linkState, linkRef = this.setPendingLink(href)) {
+ if (!this.commitPendingLink(linkRef)) {
+ return;
+ }
+ browser_default.pushState(linkState, { type: "patch", id: this.main.id }, href);
+ dom_default.dispatchEvent(window, "phx:navigate", { detail: { patch: true, href, pop: false } });
+ this.registerNewLocation(window.location);
+ }
+ historyRedirect(href, linkState, flash) {
+ if (!this.isConnected() || !this.main.isMain()) {
+ return browser_default.redirect(href, flash);
+ }
+ if (/^\/$|^\/[^\/]+.*$/.test(href)) {
+ let { protocol, host } = window.location;
+ href = `${protocol}//${host}${href}`;
+ }
+ let scroll = window.scrollY;
+ this.withPageLoading({ to: href, kind: "redirect" }, (done) => {
+ this.replaceMain(href, flash, (linkRef) => {
+ if (linkRef === this.linkRef) {
+ browser_default.pushState(linkState, { type: "redirect", id: this.main.id, scroll }, href);
+ dom_default.dispatchEvent(window, "phx:navigate", { detail: { href, patch: false, pop: false } });
+ this.registerNewLocation(window.location);
+ }
+ done();
+ });
+ });
+ }
+ replaceRootHistory() {
+ browser_default.pushState("replace", { root: true, type: "patch", id: this.main.id });
+ }
+ registerNewLocation(newLocation) {
+ let { pathname, search } = this.currentLocation;
+ if (pathname + search === newLocation.pathname + newLocation.search) {
+ return false;
+ } else {
+ this.currentLocation = clone(newLocation);
+ return true;
+ }
+ }
+ bindForms() {
+ let iterations = 0;
+ let externalFormSubmitted = false;
+ this.on("submit", (e) => {
+ let phxSubmit = e.target.getAttribute(this.binding("submit"));
+ let phxChange = e.target.getAttribute(this.binding("change"));
+ if (!externalFormSubmitted && phxChange && !phxSubmit) {
+ externalFormSubmitted = true;
+ e.preventDefault();
+ this.withinOwners(e.target, (view) => {
+ view.disableForm(e.target);
+ window.requestAnimationFrame(() => {
+ if (dom_default.isUnloadableFormSubmit(e)) {
+ this.unload();
+ }
+ e.target.submit();
+ });
+ });
+ }
+ }, true);
+ this.on("submit", (e) => {
+ let phxEvent = e.target.getAttribute(this.binding("submit"));
+ if (!phxEvent) {
+ if (dom_default.isUnloadableFormSubmit(e)) {
+ this.unload();
+ }
+ return;
+ }
+ e.preventDefault();
+ e.target.disabled = true;
+ this.withinOwners(e.target, (view) => {
+ js_default.exec("submit", phxEvent, view, e.target, ["push", { submitter: e.submitter }]);
+ });
+ }, false);
+ for (let type of ["change", "input"]) {
+ this.on(type, (e) => {
+ let phxChange = this.binding("change");
+ let input = e.target;
+ let inputEvent = input.getAttribute(phxChange);
+ let formEvent = input.form && input.form.getAttribute(phxChange);
+ let phxEvent = inputEvent || formEvent;
+ if (!phxEvent) {
+ return;
+ }
+ if (input.type === "number" && input.validity && input.validity.badInput) {
+ return;
+ }
+ let dispatcher = inputEvent ? input : input.form;
+ let currentIterations = iterations;
+ iterations++;
+ let { at, type: lastType } = dom_default.private(input, "prev-iteration") || {};
+ if (at === currentIterations - 1 && type === "change" && lastType === "input") {
+ return;
+ }
+ dom_default.putPrivate(input, "prev-iteration", { at: currentIterations, type });
+ this.debounce(input, e, type, () => {
+ this.withinOwners(dispatcher, (view) => {
+ dom_default.putPrivate(input, PHX_HAS_FOCUSED, true);
+ if (!dom_default.isTextualInput(input)) {
+ this.setActiveElement(input);
+ }
+ js_default.exec("change", phxEvent, view, input, ["push", { _target: e.target.name, dispatcher }]);
+ });
+ });
+ }, false);
+ }
+ this.on("reset", (e) => {
+ let form = e.target;
+ dom_default.resetForm(form, this.binding(PHX_FEEDBACK_FOR), this.binding(PHX_FEEDBACK_GROUP));
+ let input = Array.from(form.elements).find((el) => el.type === "reset");
+ if (input) {
+ window.requestAnimationFrame(() => {
+ input.dispatchEvent(new Event("input", { bubbles: true, cancelable: false }));
+ });
+ }
+ });
+ }
+ debounce(el, event, eventType, callback) {
+ if (eventType === "blur" || eventType === "focusout") {
+ return callback();
+ }
+ let phxDebounce = this.binding(PHX_DEBOUNCE);
+ let phxThrottle = this.binding(PHX_THROTTLE);
+ let defaultDebounce = this.defaults.debounce.toString();
+ let defaultThrottle = this.defaults.throttle.toString();
+ this.withinOwners(el, (view) => {
+ let asyncFilter = () => !view.isDestroyed() && document.body.contains(el);
+ dom_default.debounce(el, event, phxDebounce, defaultDebounce, phxThrottle, defaultThrottle, asyncFilter, () => {
+ callback();
+ });
+ });
+ }
+ silenceEvents(callback) {
+ this.silenced = true;
+ callback();
+ this.silenced = false;
+ }
+ on(event, callback) {
+ window.addEventListener(event, (e) => {
+ if (!this.silenced) {
+ callback(e);
+ }
+ });
+ }
+ };
+ var TransitionSet = class {
+ constructor() {
+ this.transitions = /* @__PURE__ */ new Set();
+ this.pendingOps = [];
+ }
+ reset() {
+ this.transitions.forEach((timer) => {
+ clearTimeout(timer);
+ this.transitions.delete(timer);
+ });
+ this.flushPendingOps();
+ }
+ after(callback) {
+ if (this.size() === 0) {
+ callback();
+ } else {
+ this.pushPendingOp(callback);
+ }
+ }
+ addTransition(time2, onStart, onDone) {
+ onStart();
+ let timer = setTimeout(() => {
+ this.transitions.delete(timer);
+ onDone();
+ this.flushPendingOps();
+ }, time2);
+ this.transitions.add(timer);
+ }
+ pushPendingOp(op) {
+ this.pendingOps.push(op);
+ }
+ size() {
+ return this.transitions.size;
+ }
+ flushPendingOps() {
+ if (this.size() > 0) {
+ return;
+ }
+ let op = this.pendingOps.shift();
+ if (op) {
+ op();
+ this.flushPendingOps();
+ }
+ }
+ };
+
+ // js/app.js
+ var import_topbar = __toESM(require_topbar());
+
+ // ../deps/live_toast/priv/static/live_toast.esm.js
+ function addUniqueItem(array, item) {
+ array.indexOf(item) === -1 && array.push(item);
+ }
+ var clamp = (min, max, v) => Math.min(Math.max(v, min), max);
+ var defaults = {
+ duration: 0.3,
+ delay: 0,
+ endDelay: 0,
+ repeat: 0,
+ easing: "ease"
+ };
+ var isNumber = (value) => typeof value === "number";
+ var isEasingList = (easing) => Array.isArray(easing) && !isNumber(easing[0]);
+ var wrap = (min, max, v) => {
+ const rangeSize = max - min;
+ return ((v - min) % rangeSize + rangeSize) % rangeSize + min;
+ };
+ function getEasingForSegment(easing, i) {
+ return isEasingList(easing) ? easing[wrap(0, easing.length, i)] : easing;
+ }
+ var mix = (min, max, progress2) => -progress2 * min + progress2 * max + min;
+ var noop2 = () => {
+ };
+ var noopReturn = (v) => v;
+ var progress = (min, max, value) => max - min === 0 ? 1 : (value - min) / (max - min);
+ function fillOffset(offset, remaining) {
+ const min = offset[offset.length - 1];
+ for (let i = 1; i <= remaining; i++) {
+ const offsetProgress = progress(0, remaining, i);
+ offset.push(mix(min, 1, offsetProgress));
+ }
+ }
+ function defaultOffset(length) {
+ const offset = [0];
+ fillOffset(offset, length - 1);
+ return offset;
+ }
+ function interpolate(output, input = defaultOffset(output.length), easing = noopReturn) {
+ const length = output.length;
+ const remainder = length - input.length;
+ remainder > 0 && fillOffset(input, remainder);
+ return (t) => {
+ let i = 0;
+ for (; i < length - 2; i++) {
+ if (t < input[i + 1])
+ break;
+ }
+ let progressInRange = clamp(0, 1, progress(input[i], input[i + 1], t));
+ const segmentEasing = getEasingForSegment(easing, i);
+ progressInRange = segmentEasing(progressInRange);
+ return mix(output[i], output[i + 1], progressInRange);
+ };
+ }
+ var isCubicBezier = (easing) => Array.isArray(easing) && isNumber(easing[0]);
+ var isEasingGenerator = (easing) => typeof easing === "object" && Boolean(easing.createAnimation);
+ var isFunction = (value) => typeof value === "function";
+ var isString = (value) => typeof value === "string";
+ var time = {
+ ms: (seconds) => seconds * 1e3,
+ s: (milliseconds) => milliseconds / 1e3
+ };
+ var calcBezier = (t, a1, a2) => (((1 - 3 * a2 + 3 * a1) * t + (3 * a2 - 6 * a1)) * t + 3 * a1) * t;
+ var subdivisionPrecision = 1e-7;
+ var subdivisionMaxIterations = 12;
+ function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
+ let currentX;
+ let currentT;
+ let i = 0;
+ do {
+ currentT = lowerBound + (upperBound - lowerBound) / 2;
+ currentX = calcBezier(currentT, mX1, mX2) - x;
+ if (currentX > 0) {
+ upperBound = currentT;
+ } else {
+ lowerBound = currentT;
+ }
+ } while (Math.abs(currentX) > subdivisionPrecision && ++i < subdivisionMaxIterations);
+ return currentT;
+ }
+ function cubicBezier(mX1, mY1, mX2, mY2) {
+ if (mX1 === mY1 && mX2 === mY2)
+ return noopReturn;
+ const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
+ return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
+ }
+ var steps = (steps2, direction = "end") => (progress2) => {
+ progress2 = direction === "end" ? Math.min(progress2, 0.999) : Math.max(progress2, 1e-3);
+ const expanded = progress2 * steps2;
+ const rounded = direction === "end" ? Math.floor(expanded) : Math.ceil(expanded);
+ return clamp(0, 1, rounded / steps2);
+ };
+ var namedEasings = {
+ ease: cubicBezier(0.25, 0.1, 0.25, 1),
+ "ease-in": cubicBezier(0.42, 0, 1, 1),
+ "ease-in-out": cubicBezier(0.42, 0, 0.58, 1),
+ "ease-out": cubicBezier(0, 0, 0.58, 1)
+ };
+ var functionArgsRegex = /\((.*?)\)/;
+ function getEasingFunction(definition) {
+ if (isFunction(definition))
+ return definition;
+ if (isCubicBezier(definition))
+ return cubicBezier(...definition);
+ if (namedEasings[definition])
+ return namedEasings[definition];
+ if (definition.startsWith("steps")) {
+ const args = functionArgsRegex.exec(definition);
+ if (args) {
+ const argsArray = args[1].split(",");
+ return steps(parseFloat(argsArray[0]), argsArray[1].trim());
+ }
+ }
+ return noopReturn;
+ }
+ var Animation = class {
+ constructor(output, keyframes = [0, 1], { easing, duration: initialDuration = defaults.duration, delay = defaults.delay, endDelay = defaults.endDelay, repeat = defaults.repeat, offset, direction = "normal", autoplay = true } = {}) {
+ this.startTime = null;
+ this.rate = 1;
+ this.t = 0;
+ this.cancelTimestamp = null;
+ this.easing = noopReturn;
+ this.duration = 0;
+ this.totalDuration = 0;
+ this.repeat = 0;
+ this.playState = "idle";
+ this.finished = new Promise((resolve, reject) => {
+ this.resolve = resolve;
+ this.reject = reject;
+ });
+ easing = easing || defaults.easing;
+ if (isEasingGenerator(easing)) {
+ const custom = easing.createAnimation(keyframes);
+ easing = custom.easing;
+ keyframes = custom.keyframes || keyframes;
+ initialDuration = custom.duration || initialDuration;
+ }
+ this.repeat = repeat;
+ this.easing = isEasingList(easing) ? noopReturn : getEasingFunction(easing);
+ this.updateDuration(initialDuration);
+ const interpolate$1 = interpolate(keyframes, offset, isEasingList(easing) ? easing.map(getEasingFunction) : noopReturn);
+ this.tick = (timestamp) => {
+ var _a;
+ delay = delay;
+ let t = 0;
+ if (this.pauseTime !== void 0) {
+ t = this.pauseTime;
+ } else {
+ t = (timestamp - this.startTime) * this.rate;
+ }
+ this.t = t;
+ t /= 1e3;
+ t = Math.max(t - delay, 0);
+ if (this.playState === "finished" && this.pauseTime === void 0) {
+ t = this.totalDuration;
+ }
+ const progress2 = t / this.duration;
+ let currentIteration = Math.floor(progress2);
+ let iterationProgress = progress2 % 1;
+ if (!iterationProgress && progress2 >= 1) {
+ iterationProgress = 1;
+ }
+ iterationProgress === 1 && currentIteration--;
+ const iterationIsOdd = currentIteration % 2;
+ if (direction === "reverse" || direction === "alternate" && iterationIsOdd || direction === "alternate-reverse" && !iterationIsOdd) {
+ iterationProgress = 1 - iterationProgress;
+ }
+ const p = t >= this.totalDuration ? 1 : Math.min(iterationProgress, 1);
+ const latest = interpolate$1(this.easing(p));
+ output(latest);
+ const isAnimationFinished = this.pauseTime === void 0 && (this.playState === "finished" || t >= this.totalDuration + endDelay);
+ if (isAnimationFinished) {
+ this.playState = "finished";
+ (_a = this.resolve) === null || _a === void 0 ? void 0 : _a.call(this, latest);
+ } else if (this.playState !== "idle") {
+ this.frameRequestId = requestAnimationFrame(this.tick);
+ }
+ };
+ if (autoplay)
+ this.play();
+ }
+ play() {
+ const now = performance.now();
+ this.playState = "running";
+ if (this.pauseTime !== void 0) {
+ this.startTime = now - this.pauseTime;
+ } else if (!this.startTime) {
+ this.startTime = now;
+ }
+ this.cancelTimestamp = this.startTime;
+ this.pauseTime = void 0;
+ this.frameRequestId = requestAnimationFrame(this.tick);
+ }
+ pause() {
+ this.playState = "paused";
+ this.pauseTime = this.t;
+ }
+ finish() {
+ this.playState = "finished";
+ this.tick(0);
+ }
+ stop() {
+ var _a;
+ this.playState = "idle";
+ if (this.frameRequestId !== void 0) {
+ cancelAnimationFrame(this.frameRequestId);
+ }
+ (_a = this.reject) === null || _a === void 0 ? void 0 : _a.call(this, false);
+ }
+ cancel() {
+ this.stop();
+ this.tick(this.cancelTimestamp);
+ }
+ reverse() {
+ this.rate *= -1;
+ }
+ commitStyles() {
+ }
+ updateDuration(duration) {
+ this.duration = duration;
+ this.totalDuration = duration * (this.repeat + 1);
+ }
+ get currentTime() {
+ return this.t;
+ }
+ set currentTime(t) {
+ if (this.pauseTime !== void 0 || this.rate === 0) {
+ this.pauseTime = t;
+ } else {
+ this.startTime = performance.now() - t / this.rate;
+ }
+ }
+ get playbackRate() {
+ return this.rate;
+ }
+ set playbackRate(rate) {
+ this.rate = rate;
+ }
+ };
+ var warning = function() {
+ };
+ var invariant = function() {
+ };
+ if (true) {
+ warning = function(check, message) {
+ if (!check && typeof console !== "undefined") {
+ console.warn(message);
+ }
+ };
+ invariant = function(check, message) {
+ if (!check) {
+ throw new Error(message);
+ }
+ };
+ }
+ var MotionValue = class {
+ setAnimation(animation) {
+ this.animation = animation;
+ animation === null || animation === void 0 ? void 0 : animation.finished.then(() => this.clearAnimation()).catch(() => {
+ });
+ }
+ clearAnimation() {
+ this.animation = this.generator = void 0;
+ }
+ };
+ var data = /* @__PURE__ */ new WeakMap();
+ function getAnimationData(element) {
+ if (!data.has(element)) {
+ data.set(element, {
+ transforms: [],
+ values: /* @__PURE__ */ new Map()
+ });
+ }
+ return data.get(element);
+ }
+ function getMotionValue(motionValues, name) {
+ if (!motionValues.has(name)) {
+ motionValues.set(name, new MotionValue());
+ }
+ return motionValues.get(name);
+ }
+ var axes = ["", "X", "Y", "Z"];
+ var order = ["translate", "scale", "rotate", "skew"];
+ var transformAlias = {
+ x: "translateX",
+ y: "translateY",
+ z: "translateZ"
+ };
+ var rotation = {
+ syntax: "",
+ initialValue: "0deg",
+ toDefaultUnit: (v) => v + "deg"
+ };
+ var baseTransformProperties = {
+ translate: {
+ syntax: "",
+ initialValue: "0px",
+ toDefaultUnit: (v) => v + "px"
+ },
+ rotate: rotation,
+ scale: {
+ syntax: "",
+ initialValue: 1,
+ toDefaultUnit: noopReturn
+ },
+ skew: rotation
+ };
+ var transformDefinitions = /* @__PURE__ */ new Map();
+ var asTransformCssVar = (name) => `--motion-${name}`;
+ var transforms = ["x", "y", "z"];
+ order.forEach((name) => {
+ axes.forEach((axis) => {
+ transforms.push(name + axis);
+ transformDefinitions.set(asTransformCssVar(name + axis), baseTransformProperties[name]);
+ });
+ });
+ var compareTransformOrder = (a, b) => transforms.indexOf(a) - transforms.indexOf(b);
+ var transformLookup = new Set(transforms);
+ var isTransform = (name) => transformLookup.has(name);
+ var addTransformToElement = (element, name) => {
+ if (transformAlias[name])
+ name = transformAlias[name];
+ const { transforms: transforms2 } = getAnimationData(element);
+ addUniqueItem(transforms2, name);
+ element.style.transform = buildTransformTemplate(transforms2);
+ };
+ var buildTransformTemplate = (transforms2) => transforms2.sort(compareTransformOrder).reduce(transformListToString, "").trim();
+ var transformListToString = (template, name) => `${template} ${name}(var(${asTransformCssVar(name)}))`;
+ var isCssVar = (name) => name.startsWith("--");
+ var registeredProperties = /* @__PURE__ */ new Set();
+ function registerCssVariable(name) {
+ if (registeredProperties.has(name))
+ return;
+ registeredProperties.add(name);
+ try {
+ const { syntax, initialValue } = transformDefinitions.has(name) ? transformDefinitions.get(name) : {};
+ CSS.registerProperty({
+ name,
+ inherits: false,
+ syntax,
+ initialValue
+ });
+ } catch (e) {
+ }
+ }
+ var testAnimation = (keyframes, options) => document.createElement("div").animate(keyframes, options);
+ var featureTests = {
+ cssRegisterProperty: () => typeof CSS !== "undefined" && Object.hasOwnProperty.call(CSS, "registerProperty"),
+ waapi: () => Object.hasOwnProperty.call(Element.prototype, "animate"),
+ partialKeyframes: () => {
+ try {
+ testAnimation({ opacity: [1] });
+ } catch (e) {
+ return false;
+ }
+ return true;
+ },
+ finished: () => Boolean(testAnimation({ opacity: [0, 1] }, { duration: 1e-3 }).finished),
+ linearEasing: () => {
+ try {
+ testAnimation({ opacity: 0 }, { easing: "linear(0, 1)" });
+ } catch (e) {
+ return false;
+ }
+ return true;
+ }
+ };
+ var results = {};
+ var supports = {};
+ for (const key in featureTests) {
+ supports[key] = () => {
+ if (results[key] === void 0)
+ results[key] = featureTests[key]();
+ return results[key];
+ };
+ }
+ var resolution = 0.015;
+ var generateLinearEasingPoints = (easing, duration) => {
+ let points = "";
+ const numPoints = Math.round(duration / resolution);
+ for (let i = 0; i < numPoints; i++) {
+ points += easing(progress(0, numPoints - 1, i)) + ", ";
+ }
+ return points.substring(0, points.length - 2);
+ };
+ var convertEasing = (easing, duration) => {
+ if (isFunction(easing)) {
+ return supports.linearEasing() ? `linear(${generateLinearEasingPoints(easing, duration)})` : defaults.easing;
+ } else {
+ return isCubicBezier(easing) ? cubicBezierAsString(easing) : easing;
+ }
+ };
+ var cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
+ function hydrateKeyframes(keyframes, readInitialValue) {
+ for (let i = 0; i < keyframes.length; i++) {
+ if (keyframes[i] === null) {
+ keyframes[i] = i ? keyframes[i - 1] : readInitialValue();
+ }
+ }
+ return keyframes;
+ }
+ var keyframesList = (keyframes) => Array.isArray(keyframes) ? keyframes : [keyframes];
+ function getStyleName(key) {
+ if (transformAlias[key])
+ key = transformAlias[key];
+ return isTransform(key) ? asTransformCssVar(key) : key;
+ }
+ var style = {
+ get: (element, name) => {
+ name = getStyleName(name);
+ let value = isCssVar(name) ? element.style.getPropertyValue(name) : getComputedStyle(element)[name];
+ if (!value && value !== 0) {
+ const definition = transformDefinitions.get(name);
+ if (definition)
+ value = definition.initialValue;
+ }
+ return value;
+ },
+ set: (element, name, value) => {
+ name = getStyleName(name);
+ if (isCssVar(name)) {
+ element.style.setProperty(name, value);
+ } else {
+ element.style[name] = value;
+ }
+ }
+ };
+ function stopAnimation(animation, needsCommit = true) {
+ if (!animation || animation.playState === "finished")
+ return;
+ try {
+ if (animation.stop) {
+ animation.stop();
+ } else {
+ needsCommit && animation.commitStyles();
+ animation.cancel();
+ }
+ } catch (e) {
+ }
+ }
+ function getUnitConverter(keyframes, definition) {
+ var _a;
+ let toUnit = (definition === null || definition === void 0 ? void 0 : definition.toDefaultUnit) || noopReturn;
+ const finalKeyframe = keyframes[keyframes.length - 1];
+ if (isString(finalKeyframe)) {
+ const unit = ((_a = finalKeyframe.match(/(-?[\d.]+)([a-z%]*)/)) === null || _a === void 0 ? void 0 : _a[2]) || "";
+ if (unit)
+ toUnit = (value) => value + unit;
+ }
+ return toUnit;
+ }
+ function getDevToolsRecord() {
+ return window.__MOTION_DEV_TOOLS_RECORD;
+ }
+ function animateStyle(element, key, keyframesDefinition, options = {}, AnimationPolyfill) {
+ const record = getDevToolsRecord();
+ const isRecording = options.record !== false && record;
+ let animation;
+ let { duration = defaults.duration, delay = defaults.delay, endDelay = defaults.endDelay, repeat = defaults.repeat, easing = defaults.easing, persist = false, direction, offset, allowWebkitAcceleration = false, autoplay = true } = options;
+ const data2 = getAnimationData(element);
+ const valueIsTransform = isTransform(key);
+ let canAnimateNatively = supports.waapi();
+ valueIsTransform && addTransformToElement(element, key);
+ const name = getStyleName(key);
+ const motionValue = getMotionValue(data2.values, name);
+ const definition = transformDefinitions.get(name);
+ stopAnimation(motionValue.animation, !(isEasingGenerator(easing) && motionValue.generator) && options.record !== false);
+ return () => {
+ const readInitialValue = () => {
+ var _a, _b;
+ return (_b = (_a = style.get(element, name)) !== null && _a !== void 0 ? _a : definition === null || definition === void 0 ? void 0 : definition.initialValue) !== null && _b !== void 0 ? _b : 0;
+ };
+ let keyframes = hydrateKeyframes(keyframesList(keyframesDefinition), readInitialValue);
+ const toUnit = getUnitConverter(keyframes, definition);
+ if (isEasingGenerator(easing)) {
+ const custom = easing.createAnimation(keyframes, key !== "opacity", readInitialValue, name, motionValue);
+ easing = custom.easing;
+ keyframes = custom.keyframes || keyframes;
+ duration = custom.duration || duration;
+ }
+ if (isCssVar(name)) {
+ if (supports.cssRegisterProperty()) {
+ registerCssVariable(name);
+ } else {
+ canAnimateNatively = false;
+ }
+ }
+ if (valueIsTransform && !supports.linearEasing() && (isFunction(easing) || isEasingList(easing) && easing.some(isFunction))) {
+ canAnimateNatively = false;
+ }
+ if (canAnimateNatively) {
+ if (definition) {
+ keyframes = keyframes.map((value) => isNumber(value) ? definition.toDefaultUnit(value) : value);
+ }
+ if (keyframes.length === 1 && (!supports.partialKeyframes() || isRecording)) {
+ keyframes.unshift(readInitialValue());
+ }
+ const animationOptions = {
+ delay: time.ms(delay),
+ duration: time.ms(duration),
+ endDelay: time.ms(endDelay),
+ easing: !isEasingList(easing) ? convertEasing(easing, duration) : void 0,
+ direction,
+ iterations: repeat + 1,
+ fill: "both"
+ };
+ animation = element.animate({
+ [name]: keyframes,
+ offset,
+ easing: isEasingList(easing) ? easing.map((thisEasing) => convertEasing(thisEasing, duration)) : void 0
+ }, animationOptions);
+ if (!animation.finished) {
+ animation.finished = new Promise((resolve, reject) => {
+ animation.onfinish = resolve;
+ animation.oncancel = reject;
+ });
+ }
+ const target = keyframes[keyframes.length - 1];
+ animation.finished.then(() => {
+ if (persist)
+ return;
+ style.set(element, name, target);
+ animation.cancel();
+ }).catch(noop2);
+ if (!allowWebkitAcceleration)
+ animation.playbackRate = 1.000001;
+ } else if (AnimationPolyfill && valueIsTransform) {
+ keyframes = keyframes.map((value) => typeof value === "string" ? parseFloat(value) : value);
+ if (keyframes.length === 1) {
+ keyframes.unshift(parseFloat(readInitialValue()));
+ }
+ animation = new AnimationPolyfill((latest) => {
+ style.set(element, name, toUnit ? toUnit(latest) : latest);
+ }, keyframes, Object.assign(Object.assign({}, options), {
+ duration,
+ easing
+ }));
+ } else {
+ const target = keyframes[keyframes.length - 1];
+ style.set(element, name, definition && isNumber(target) ? definition.toDefaultUnit(target) : target);
+ }
+ if (isRecording) {
+ record(element, key, keyframes, {
+ duration,
+ delay,
+ easing,
+ repeat,
+ offset
+ }, "motion-one");
+ }
+ motionValue.setAnimation(animation);
+ if (animation && !autoplay)
+ animation.pause();
+ return animation;
+ };
+ }
+ var getOptions = (options, key) => options[key] ? Object.assign(Object.assign({}, options), options[key]) : Object.assign({}, options);
+ function resolveElements(elements, selectorCache) {
+ var _a;
+ if (typeof elements === "string") {
+ if (selectorCache) {
+ (_a = selectorCache[elements]) !== null && _a !== void 0 ? _a : selectorCache[elements] = document.querySelectorAll(elements);
+ elements = selectorCache[elements];
+ } else {
+ elements = document.querySelectorAll(elements);
+ }
+ } else if (elements instanceof Element) {
+ elements = [elements];
+ }
+ return Array.from(elements || []);
+ }
+ var createAnimation = (factory) => factory();
+ var withControls = (animationFactory, options, duration = defaults.duration) => {
+ return new Proxy({
+ animations: animationFactory.map(createAnimation).filter(Boolean),
+ duration,
+ options
+ }, controls);
+ };
+ var getActiveAnimation = (state) => state.animations[0];
+ var controls = {
+ get: (target, key) => {
+ const activeAnimation = getActiveAnimation(target);
+ switch (key) {
+ case "duration":
+ return target.duration;
+ case "currentTime":
+ return time.s((activeAnimation === null || activeAnimation === void 0 ? void 0 : activeAnimation[key]) || 0);
+ case "playbackRate":
+ case "playState":
+ return activeAnimation === null || activeAnimation === void 0 ? void 0 : activeAnimation[key];
+ case "finished":
+ if (!target.finished) {
+ target.finished = Promise.all(target.animations.map(selectFinished)).catch(noop2);
+ }
+ return target.finished;
+ case "stop":
+ return () => {
+ target.animations.forEach((animation) => stopAnimation(animation));
+ };
+ case "forEachNative":
+ return (callback) => {
+ target.animations.forEach((animation) => callback(animation, target));
+ };
+ default:
+ return typeof (activeAnimation === null || activeAnimation === void 0 ? void 0 : activeAnimation[key]) === "undefined" ? void 0 : () => target.animations.forEach((animation) => animation[key]());
+ }
+ },
+ set: (target, key, value) => {
+ switch (key) {
+ case "currentTime":
+ value = time.ms(value);
+ case "playbackRate":
+ for (let i = 0; i < target.animations.length; i++) {
+ target.animations[i][key] = value;
+ }
+ return true;
+ }
+ return false;
+ }
+ };
+ var selectFinished = (animation) => animation.finished;
+ function resolveOption(option, i, total) {
+ return isFunction(option) ? option(i, total) : option;
+ }
+ function createAnimate(AnimatePolyfill) {
+ return function animate3(elements, keyframes, options = {}) {
+ elements = resolveElements(elements);
+ const numElements = elements.length;
+ invariant(Boolean(numElements), "No valid element provided.");
+ invariant(Boolean(keyframes), "No keyframes defined.");
+ const animationFactories = [];
+ for (let i = 0; i < numElements; i++) {
+ const element = elements[i];
+ for (const key in keyframes) {
+ const valueOptions = getOptions(options, key);
+ valueOptions.delay = resolveOption(valueOptions.delay, i, numElements);
+ const animation = animateStyle(element, key, keyframes[key], valueOptions, AnimatePolyfill);
+ animationFactories.push(animation);
+ }
+ }
+ return withControls(animationFactories, options, options.duration);
+ };
+ }
+ var animate = createAnimate(Animation);
+ function animateProgress(target, options = {}) {
+ return withControls([
+ () => {
+ const animation = new Animation(target, [0, 1], options);
+ animation.finished.catch(() => {
+ });
+ return animation;
+ }
+ ], options, options.duration);
+ }
+ function animate2(target, keyframesOrOptions, options) {
+ const factory = isFunction(target) ? animateProgress : animate;
+ return factory(target, keyframesOrOptions, options);
+ }
+ function isHidden(el) {
+ if (el === null) {
+ return true;
+ }
+ return el.offsetParent === null;
+ }
+ function isFlash(el) {
+ return el.dataset.component === "flash";
+ }
+ function flashCount() {
+ let num = 0;
+ if (!isHidden(document.getElementById("server-error"))) {
+ num += 1;
+ }
+ if (!isHidden(document.getElementById("client-error"))) {
+ num += 1;
+ }
+ if (!isHidden(document.getElementById("flash-info"))) {
+ num += 1;
+ }
+ if (!isHidden(document.getElementById("flash-error"))) {
+ num += 1;
+ }
+ return num;
+ }
+ var removalTime = 5;
+ var animationTime = 550;
+ var maxItemsIgnoresFlashes = true;
+ var gap = 15;
+ var lastTS = [];
+ function doAnimations(delayTime, maxItems, elToRemove) {
+ const ts = [];
+ let toasts = Array.from(document.querySelectorAll('#toast-group [phx-hook="LiveToast"]')).map((t) => {
+ if (isHidden(t)) {
+ return null;
+ } else {
+ return t;
+ }
+ }).filter(Boolean).reverse();
+ if (elToRemove) {
+ toasts = toasts.filter((t) => t !== elToRemove);
+ }
+ for (let i = 0; i < toasts.length; i++) {
+ const toast = toasts[i];
+ if (isHidden(toast)) {
+ continue;
+ }
+ toast.order = i;
+ ts[i] = toast;
+ }
+ for (let i = 0; i < ts.length; i++) {
+ const max = maxItemsIgnoresFlashes ? maxItems + flashCount() : maxItems;
+ const toast = ts[i];
+ let direction = "";
+ if (toast.dataset.corner === "bottom_left" || toast.dataset.corner === "bottom_right") {
+ direction = "-";
+ }
+ let val = 0;
+ for (let j = 0; j < toast.order; j++) {
+ val += ts[j].offsetHeight + gap;
+ }
+ const opacity = toast.order > max ? 0 : 1 - (toast.order - max + 1);
+ if (toast.order >= max) {
+ toast.classList.remove("pointer-events-auto");
+ } else {
+ toast.classList.add("pointer-events-auto");
+ }
+ const keyframes = { y: [`${direction}${val}px`], opacity: [opacity] };
+ if (toast.order === 0 && lastTS.includes(toast) === false) {
+ const val2 = toast.offsetHeight + gap;
+ const oppositeDirection = direction === "-" ? "" : "-";
+ keyframes.y.unshift(`${oppositeDirection}${val2}px`);
+ keyframes.opacity.unshift(0);
+ }
+ toast.targetDestination = `${direction}${val}px`;
+ const duration = animationTime / 1e3;
+ animate2(toast, keyframes, {
+ duration,
+ easing: [0.22, 1, 0.36, 1]
+ });
+ toast.order += 1;
+ toast.style.zIndex = (50 - toast.order).toString();
+ window.setTimeout(() => {
+ if (toast.order > max) {
+ this.pushEventTo("#toast-group", "clear", { id: toast.id });
+ }
+ }, delayTime + removalTime);
+ lastTS = ts;
+ }
+ }
+ async function animateOut() {
+ const val = (this.el.order - 2) * 100 + (this.el.order - 2) * gap;
+ let direction = "";
+ if (this.el.dataset.corner === "bottom_left" || this.el.dataset.corner === "bottom_right") {
+ direction = "-";
+ }
+ const animation = animate2(this.el, { y: `${direction}${val}%`, opacity: 0 }, {
+ opacity: {
+ duration: 0.2,
+ easing: "ease-out"
+ },
+ duration: 0.3,
+ easing: "ease-out"
+ });
+ await animation.finished;
+ }
+ function createLiveToastHook(duration = 6e3, maxItems = 3) {
+ return {
+ destroyed() {
+ doAnimations.bind(this)(duration, maxItems);
+ },
+ updated() {
+ const keyframes = { y: [this.el.targetDestination] };
+ animate2(this.el, keyframes, { duration: 0 });
+ },
+ mounted() {
+ if (["server-error", "client-error"].includes(this.el.id)) {
+ if (isHidden(document.getElementById(this.el.id))) {
+ return;
+ }
+ }
+ window.addEventListener("flash-leave", async (event) => {
+ if (event.target === this.el) {
+ doAnimations.bind(this, duration, maxItems, this.el)();
+ await animateOut.bind(this)();
+ }
+ });
+ doAnimations.bind(this)(duration, maxItems);
+ if (isFlash(this.el)) {
+ return;
+ }
+ let durationOverride = duration;
+ if (this.el.dataset.duration !== void 0) {
+ durationOverride = Number.parseInt(this.el.dataset.duration);
+ }
+ window.setTimeout(async () => {
+ await animateOut.bind(this)();
+ this.pushEventTo("#toast-group", "clear", { id: this.el.id });
+ }, durationOverride + removalTime);
+ }
+ };
+ }
+
+ // js/app.js
+ var csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content");
+ var hooks = {
+ LiveToast: createLiveToastHook()
+ };
+ var liveSocket = new LiveSocket("/live", Socket, { params: { _csrf_token: csrfToken }, hooks });
+ import_topbar.default.config({ barColors: { 0: "#29d" }, shadowColor: "rgba(0, 0, 0, .3)" });
+ window.addEventListener("phx:page-loading-start", (_info) => import_topbar.default.show(300));
+ window.addEventListener("phx:page-loading-stop", (_info) => import_topbar.default.hide());
+ liveSocket.connect();
+ window.liveSocket = liveSocket;
+})();
/**
* @license MIT
* topbar 2.0.0, 2023-02-04
* https://buunguyen.github.io/topbar
* Copyright (c) 2021 Buu Nguyen
*/
+//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vYXNzZXRzL3ZlbmRvci90b3BiYXIuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2h0bWwvcHJpdi9zdGF0aWMvcGhvZW5peF9odG1sLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC91dGlscy5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXgvYXNzZXRzL2pzL3Bob2VuaXgvY29uc3RhbnRzLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC9wdXNoLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC90aW1lci5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXgvYXNzZXRzL2pzL3Bob2VuaXgvY2hhbm5lbC5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXgvYXNzZXRzL2pzL3Bob2VuaXgvYWpheC5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXgvYXNzZXRzL2pzL3Bob2VuaXgvbG9uZ3BvbGwuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4L2Fzc2V0cy9qcy9waG9lbml4L3ByZXNlbmNlLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC9zZXJpYWxpemVyLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peC9hc3NldHMvanMvcGhvZW5peC9zb2NrZXQuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvY29uc3RhbnRzLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2VudHJ5X3VwbG9hZGVyLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L3V0aWxzLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2Jyb3dzZXIuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvYXJpYS5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9qcy5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9kb20uanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvdXBsb2FkX2VudHJ5LmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2xpdmVfdXBsb2FkZXIuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvaG9va3MuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvZG9tX3Bvc3RfbW9ycGhfcmVzdG9yZXIuanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvbm9kZV9tb2R1bGVzL21vcnBoZG9tL2Rpc3QvbW9ycGhkb20tZXNtLmpzIiwgIi4uLy4uLy4uL2RlcHMvcGhvZW5peF9saXZlX3ZpZXcvYXNzZXRzL2pzL3Bob2VuaXhfbGl2ZV92aWV3L2RvbV9wYXRjaC5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9yZW5kZXJlZC5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy92aWV3X2hvb2suanMiLCAiLi4vLi4vLi4vZGVwcy9waG9lbml4X2xpdmVfdmlldy9hc3NldHMvanMvcGhvZW5peF9saXZlX3ZpZXcvdmlldy5qcyIsICIuLi8uLi8uLi9kZXBzL3Bob2VuaXhfbGl2ZV92aWV3L2Fzc2V0cy9qcy9waG9lbml4X2xpdmVfdmlldy9saXZlX3NvY2tldC5qcyIsICIuLi8uLi8uLi9hc3NldHMvanMvYXBwLmpzIiwgIi4uLy4uLy4uL2RlcHMvbGl2ZV90b2FzdC9hc3NldHMvbm9kZV9tb2R1bGVzL0Btb3Rpb25vbmUvdXRpbHMvZGlzdC9hcnJheS5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL3V0aWxzL2Rpc3QvY2xhbXAuZXMuanMiLCAiLi4vLi4vLi4vZGVwcy9saXZlX3RvYXN0L2Fzc2V0cy9ub2RlX21vZHVsZXMvQG1vdGlvbm9uZS91dGlscy9kaXN0L2RlZmF1bHRzLmVzLmpzIiwgIi4uLy4uLy4uL2RlcHMvbGl2ZV90b2FzdC9hc3NldHMvbm9kZV9tb2R1bGVzL0Btb3Rpb25vbmUvdXRpbHMvZGlzdC9pcy1udW1iZXIuZXMuanMiLCAiLi4vLi4vLi4vZGVwcy9saXZlX3RvYXN0L2Fzc2V0cy9ub2RlX21vZHVsZXMvQG1vdGlvbm9uZS91dGlscy9kaXN0L2lzLWVhc2luZy1saXN0LmVzLmpzIiwgIi4uLy4uLy4uL2RlcHMvbGl2ZV90b2FzdC9hc3NldHMvbm9kZV9tb2R1bGVzL0Btb3Rpb25vbmUvdXRpbHMvZGlzdC93cmFwLmVzLmpzIiwgIi4uLy4uLy4uL2RlcHMvbGl2ZV90b2FzdC9hc3NldHMvbm9kZV9tb2R1bGVzL0Btb3Rpb25vbmUvdXRpbHMvZGlzdC9lYXNpbmcuZXMuanMiLCAiLi4vLi4vLi4vZGVwcy9saXZlX3RvYXN0L2Fzc2V0cy9ub2RlX21vZHVsZXMvQG1vdGlvbm9uZS91dGlscy9kaXN0L21peC5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL3V0aWxzL2Rpc3Qvbm9vcC5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL3V0aWxzL2Rpc3QvcHJvZ3Jlc3MuZXMuanMiLCAiLi4vLi4vLi4vZGVwcy9saXZlX3RvYXN0L2Fzc2V0cy9ub2RlX21vZHVsZXMvQG1vdGlvbm9uZS91dGlscy9kaXN0L29mZnNldC5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL3V0aWxzL2Rpc3QvaW50ZXJwb2xhdGUuZXMuanMiLCAiLi4vLi4vLi4vZGVwcy9saXZlX3RvYXN0L2Fzc2V0cy9ub2RlX21vZHVsZXMvQG1vdGlvbm9uZS91dGlscy9kaXN0L2lzLWN1YmljLWJlemllci5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL3V0aWxzL2Rpc3QvaXMtZWFzaW5nLWdlbmVyYXRvci5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL3V0aWxzL2Rpc3QvaXMtZnVuY3Rpb24uZXMuanMiLCAiLi4vLi4vLi4vZGVwcy9saXZlX3RvYXN0L2Fzc2V0cy9ub2RlX21vZHVsZXMvQG1vdGlvbm9uZS91dGlscy9kaXN0L2lzLXN0cmluZy5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL3V0aWxzL2Rpc3QvdGltZS5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL2Vhc2luZy9kaXN0L2N1YmljLWJlemllci5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL2Vhc2luZy9kaXN0L3N0ZXBzLmVzLmpzIiwgIi4uLy4uLy4uL2RlcHMvbGl2ZV90b2FzdC9hc3NldHMvbm9kZV9tb2R1bGVzL0Btb3Rpb25vbmUvYW5pbWF0aW9uL2Rpc3QvdXRpbHMvZWFzaW5nLmVzLmpzIiwgIi4uLy4uLy4uL2RlcHMvbGl2ZV90b2FzdC9hc3NldHMvbm9kZV9tb2R1bGVzL0Btb3Rpb25vbmUvYW5pbWF0aW9uL2Rpc3QvQW5pbWF0aW9uLmVzLmpzIiwgIi4uLy4uLy4uL2RlcHMvbGl2ZV90b2FzdC9hc3NldHMvbm9kZV9tb2R1bGVzL2hleS1saXN0ZW4vZGlzdC9oZXktbGlzdGVuLmVzLmpzIiwgIi4uLy4uLy4uL2RlcHMvbGl2ZV90b2FzdC9hc3NldHMvbm9kZV9tb2R1bGVzL0Btb3Rpb25vbmUvdHlwZXMvZGlzdC9Nb3Rpb25WYWx1ZS5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL2RvbS9kaXN0L2FuaW1hdGUvZGF0YS5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL2RvbS9kaXN0L2FuaW1hdGUvdXRpbHMvdHJhbnNmb3Jtcy5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL2RvbS9kaXN0L2FuaW1hdGUvdXRpbHMvY3NzLXZhci5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL2RvbS9kaXN0L2FuaW1hdGUvdXRpbHMvZmVhdHVyZS1kZXRlY3Rpb24uZXMuanMiLCAiLi4vLi4vLi4vZGVwcy9saXZlX3RvYXN0L2Fzc2V0cy9ub2RlX21vZHVsZXMvQG1vdGlvbm9uZS9kb20vZGlzdC9hbmltYXRlL3V0aWxzL2Vhc2luZy5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL2RvbS9kaXN0L2FuaW1hdGUvdXRpbHMva2V5ZnJhbWVzLmVzLmpzIiwgIi4uLy4uLy4uL2RlcHMvbGl2ZV90b2FzdC9hc3NldHMvbm9kZV9tb2R1bGVzL0Btb3Rpb25vbmUvZG9tL2Rpc3QvYW5pbWF0ZS91dGlscy9nZXQtc3R5bGUtbmFtZS5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL2RvbS9kaXN0L2FuaW1hdGUvc3R5bGUuZXMuanMiLCAiLi4vLi4vLi4vZGVwcy9saXZlX3RvYXN0L2Fzc2V0cy9ub2RlX21vZHVsZXMvQG1vdGlvbm9uZS9kb20vZGlzdC9hbmltYXRlL3V0aWxzL3N0b3AtYW5pbWF0aW9uLmVzLmpzIiwgIi4uLy4uLy4uL2RlcHMvbGl2ZV90b2FzdC9hc3NldHMvbm9kZV9tb2R1bGVzL0Btb3Rpb25vbmUvZG9tL2Rpc3QvYW5pbWF0ZS91dGlscy9nZXQtdW5pdC5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL2RvbS9kaXN0L2FuaW1hdGUvYW5pbWF0ZS1zdHlsZS5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL2RvbS9kaXN0L2FuaW1hdGUvdXRpbHMvb3B0aW9ucy5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL2RvbS9kaXN0L3V0aWxzL3Jlc29sdmUtZWxlbWVudHMuZXMuanMiLCAiLi4vLi4vLi4vZGVwcy9saXZlX3RvYXN0L2Fzc2V0cy9ub2RlX21vZHVsZXMvQG1vdGlvbm9uZS9kb20vZGlzdC9hbmltYXRlL3V0aWxzL2NvbnRyb2xzLmVzLmpzIiwgIi4uLy4uLy4uL2RlcHMvbGl2ZV90b2FzdC9hc3NldHMvbm9kZV9tb2R1bGVzL0Btb3Rpb25vbmUvZG9tL2Rpc3QvdXRpbHMvc3RhZ2dlci5lcy5qcyIsICIuLi8uLi8uLi9kZXBzL2xpdmVfdG9hc3QvYXNzZXRzL25vZGVfbW9kdWxlcy9AbW90aW9ub25lL2RvbS9kaXN0L2FuaW1hdGUvY3JlYXRlLWFuaW1hdGUuZXMuanMiLCAiLi4vLi4vLi4vZGVwcy9saXZlX3RvYXN0L2Fzc2V0cy9ub2RlX21vZHVsZXMvQG1vdGlvbm9uZS9kb20vZGlzdC9hbmltYXRlL2luZGV4LmVzLmpzIiwgIi4uLy4uLy4uL2RlcHMvbGl2ZV90b2FzdC9hc3NldHMvbm9kZV9tb2R1bGVzL21vdGlvbi9kaXN0L2FuaW1hdGUuZXMuanMiLCAiLi4vLi4vLi4vZGVwcy9saXZlX3RvYXN0L2Fzc2V0cy9qcy9saXZlX3RvYXN0L2xpdmVfdG9hc3QudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGxpY2Vuc2UgTUlUXG4gKiB0b3BiYXIgMi4wLjAsIDIwMjMtMDItMDRcbiAqIGh0dHBzOi8vYnV1bmd1eWVuLmdpdGh1Yi5pby90b3BiYXJcbiAqIENvcHlyaWdodCAoYykgMjAyMSBCdXUgTmd1eWVuXG4gKi9cbihmdW5jdGlvbiAod2luZG93LCBkb2N1bWVudCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICAvLyBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9wYXVsaXJpc2gvMTU3OTY3MVxuICAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBsYXN0VGltZSA9IDA7XG4gICAgdmFyIHZlbmRvcnMgPSBbXCJtc1wiLCBcIm1velwiLCBcIndlYmtpdFwiLCBcIm9cIl07XG4gICAgZm9yICh2YXIgeCA9IDA7IHggPCB2ZW5kb3JzLmxlbmd0aCAmJiAhd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZTsgKyt4KSB7XG4gICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lID1cbiAgICAgICAgd2luZG93W3ZlbmRvcnNbeF0gKyBcIlJlcXVlc3RBbmltYXRpb25GcmFtZVwiXTtcbiAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSA9XG4gICAgICAgIHdpbmRvd1t2ZW5kb3JzW3hdICsgXCJDYW5jZWxBbmltYXRpb25GcmFtZVwiXSB8fFxuICAgICAgICB3aW5kb3dbdmVuZG9yc1t4XSArIFwiQ2FuY2VsUmVxdWVzdEFuaW1hdGlvbkZyYW1lXCJdO1xuICAgIH1cbiAgICBpZiAoIXdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUpXG4gICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lID0gZnVuY3Rpb24gKGNhbGxiYWNrLCBlbGVtZW50KSB7XG4gICAgICAgIHZhciBjdXJyVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgICAgICB2YXIgdGltZVRvQ2FsbCA9IE1hdGgubWF4KDAsIDE2IC0gKGN1cnJUaW1lIC0gbGFzdFRpbWUpKTtcbiAgICAgICAgdmFyIGlkID0gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNhbGxiYWNrKGN1cnJUaW1lICsgdGltZVRvQ2FsbCk7XG4gICAgICAgIH0sIHRpbWVUb0NhbGwpO1xuICAgICAgICBsYXN0VGltZSA9IGN1cnJUaW1lICsgdGltZVRvQ2FsbDtcbiAgICAgICAgcmV0dXJuIGlkO1xuICAgICAgfTtcbiAgICBpZiAoIXdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSlcbiAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgICBjbGVhclRpbWVvdXQoaWQpO1xuICAgICAgfTtcbiAgfSkoKTtcblxuICB2YXIgY2FudmFzLFxuICAgIGN1cnJlbnRQcm9ncmVzcyxcbiAgICBzaG93aW5nLFxuICAgIHByb2dyZXNzVGltZXJJZCA9IG51bGwsXG4gICAgZmFkZVRpbWVySWQgPSBudWxsLFxuICAgIGRlbGF5VGltZXJJZCA9IG51bGwsXG4gICAgYWRkRXZlbnQgPSBmdW5jdGlvbiAoZWxlbSwgdHlwZSwgaGFuZGxlcikge1xuICAgICAgaWYgKGVsZW0uYWRkRXZlbnRMaXN0ZW5lcikgZWxlbS5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGhhbmRsZXIsIGZhbHNlKTtcbiAgICAgIGVsc2UgaWYgKGVsZW0uYXR0YWNoRXZlbnQpIGVsZW0uYXR0YWNoRXZlbnQoXCJvblwiICsgdHlwZSwgaGFuZGxlcik7XG4gICAgICBlbHNlIGVsZW1bXCJvblwiICsgdHlwZV0gPSBoYW5kbGVyO1xuICAgIH0sXG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIGF1dG9SdW46IHRydWUsXG4gICAgICBiYXJUaGlja25lc3M6IDMsXG4gICAgICBiYXJDb2xvcnM6IHtcbiAgICAgICAgMDogXCJyZ2JhKDI2LCAgMTg4LCAxNTYsIC45KVwiLFxuICAgICAgICBcIi4yNVwiOiBcInJnYmEoNTIsICAxNTIsIDIxOSwgLjkpXCIsXG4gICAgICAgIFwiLjUwXCI6IFwicmdiYSgyNDEsIDE5NiwgMTUsICAuOSlcIixcbiAgICAgICAgXCIuNzVcIjogXCJyZ2JhKDIzMCwgMTI2LCAzNCwgIC45KVwiLFxuICAgICAgICBcIjEuMFwiOiBcInJnYmEoMjExLCA4NCwgIDAsICAgLjkpXCIsXG4gICAgICB9LFxuICAgICAgc2hhZG93Qmx1cjogMTAsXG4gICAgICBzaGFkb3dDb2xvcjogXCJyZ2JhKDAsICAgMCwgICAwLCAgIC42KVwiLFxuICAgICAgY2xhc3NOYW1lOiBudWxsLFxuICAgIH0sXG4gICAgcmVwYWludCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIGNhbnZhcy53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuICAgICAgY2FudmFzLmhlaWdodCA9IG9wdGlvbnMuYmFyVGhpY2tuZXNzICogNTsgLy8gbmVlZCBzcGFjZSBmb3Igc2hhZG93XG5cbiAgICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xuICAgICAgY3R4LnNoYWRvd0JsdXIgPSBvcHRpb25zLnNoYWRvd0JsdXI7XG4gICAgICBjdHguc2hhZG93Q29sb3IgPSBvcHRpb25zLnNoYWRvd0NvbG9yO1xuXG4gICAgICB2YXIgbGluZUdyYWRpZW50ID0gY3R4LmNyZWF0ZUxpbmVhckdyYWRpZW50KDAsIDAsIGNhbnZhcy53aWR0aCwgMCk7XG4gICAgICBmb3IgKHZhciBzdG9wIGluIG9wdGlvbnMuYmFyQ29sb3JzKVxuICAgICAgICBsaW5lR3JhZGllbnQuYWRkQ29sb3JTdG9wKHN0b3AsIG9wdGlvbnMuYmFyQ29sb3JzW3N0b3BdKTtcbiAgICAgIGN0eC5saW5lV2lkdGggPSBvcHRpb25zLmJhclRoaWNrbmVzcztcbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgIGN0eC5tb3ZlVG8oMCwgb3B0aW9ucy5iYXJUaGlja25lc3MgLyAyKTtcbiAgICAgIGN0eC5saW5lVG8oXG4gICAgICAgIE1hdGguY2VpbChjdXJyZW50UHJvZ3Jlc3MgKiBjYW52YXMud2lkdGgpLFxuICAgICAgICBvcHRpb25zLmJhclRoaWNrbmVzcyAvIDJcbiAgICAgICk7XG4gICAgICBjdHguc3Ryb2tlU3R5bGUgPSBsaW5lR3JhZGllbnQ7XG4gICAgICBjdHguc3Ryb2tlKCk7XG4gICAgfSxcbiAgICBjcmVhdGVDYW52YXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICAgICAgdmFyIHN0eWxlID0gY2FudmFzLnN0eWxlO1xuICAgICAgc3R5bGUucG9zaXRpb24gPSBcImZpeGVkXCI7XG4gICAgICBzdHlsZS50b3AgPSBzdHlsZS5sZWZ0ID0gc3R5bGUucmlnaHQgPSBzdHlsZS5tYXJnaW4gPSBzdHlsZS5wYWRkaW5nID0gMDtcbiAgICAgIHN0eWxlLnpJbmRleCA9IDEwMDAwMTtcbiAgICAgIHN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICAgIGlmIChvcHRpb25zLmNsYXNzTmFtZSkgY2FudmFzLmNsYXNzTGlzdC5hZGQob3B0aW9ucy5jbGFzc05hbWUpO1xuICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChjYW52YXMpO1xuICAgICAgYWRkRXZlbnQod2luZG93LCBcInJlc2l6ZVwiLCByZXBhaW50KTtcbiAgICB9LFxuICAgIHRvcGJhciA9IHtcbiAgICAgIGNvbmZpZzogZnVuY3Rpb24gKG9wdHMpIHtcbiAgICAgICAgZm9yICh2YXIga2V5IGluIG9wdHMpXG4gICAgICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkoa2V5KSkgb3B0aW9uc1trZXldID0gb3B0c1trZXldO1xuICAgICAgfSxcbiAgICAgIHNob3c6IGZ1bmN0aW9uIChkZWxheSkge1xuICAgICAgICBpZiAoc2hvd2luZykgcmV0dXJuO1xuICAgICAgICBpZiAoZGVsYXkpIHtcbiAgICAgICAgICBpZiAoZGVsYXlUaW1lcklkKSByZXR1cm47XG4gICAgICAgICAgZGVsYXlUaW1lcklkID0gc2V0VGltZW91dCgoKSA9PiB0b3BiYXIuc2hvdygpLCBkZWxheSk7XG4gICAgICAgIH0gZWxzZSAge1xuICAgICAgICAgIHNob3dpbmcgPSB0cnVlO1xuICAgICAgICAgIGlmIChmYWRlVGltZXJJZCAhPT0gbnVsbCkgd2luZG93LmNhbmNlbEFuaW1hdGlvbkZyYW1lKGZhZGVUaW1lcklkKTtcbiAgICAgICAgICBpZiAoIWNhbnZhcykgY3JlYXRlQ2FudmFzKCk7XG4gICAgICAgICAgY2FudmFzLnN0eWxlLm9wYWNpdHkgPSAxO1xuICAgICAgICAgIGNhbnZhcy5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuICAgICAgICAgIHRvcGJhci5wcm9ncmVzcygwKTtcbiAgICAgICAgICBpZiAob3B0aW9ucy5hdXRvUnVuKSB7XG4gICAgICAgICAgICAoZnVuY3Rpb24gbG9vcCgpIHtcbiAgICAgICAgICAgICAgcHJvZ3Jlc3NUaW1lcklkID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZShsb29wKTtcbiAgICAgICAgICAgICAgdG9wYmFyLnByb2dyZXNzKFxuICAgICAgICAgICAgICAgIFwiK1wiICsgMC4wNSAqIE1hdGgucG93KDEgLSBNYXRoLnNxcnQoY3VycmVudFByb2dyZXNzKSwgMilcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgcHJvZ3Jlc3M6IGZ1bmN0aW9uICh0bykge1xuICAgICAgICBpZiAodHlwZW9mIHRvID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm4gY3VycmVudFByb2dyZXNzO1xuICAgICAgICBpZiAodHlwZW9mIHRvID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgdG8gPVxuICAgICAgICAgICAgKHRvLmluZGV4T2YoXCIrXCIpID49IDAgfHwgdG8uaW5kZXhPZihcIi1cIikgPj0gMFxuICAgICAgICAgICAgICA/IGN1cnJlbnRQcm9ncmVzc1xuICAgICAgICAgICAgICA6IDApICsgcGFyc2VGbG9hdCh0byk7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudFByb2dyZXNzID0gdG8gPiAxID8gMSA6IHRvO1xuICAgICAgICByZXBhaW50KCk7XG4gICAgICAgIHJldHVybiBjdXJyZW50UHJvZ3Jlc3M7XG4gICAgICB9LFxuICAgICAgaGlkZTogZnVuY3Rpb24gKCkge1xuICAgICAgICBjbGVhclRpbWVvdXQoZGVsYXlUaW1lcklkKTtcbiAgICAgICAgZGVsYXlUaW1lcklkID0gbnVsbDtcbiAgICAgICAgaWYgKCFzaG93aW5nKSByZXR1cm47XG4gICAgICAgIHNob3dpbmcgPSBmYWxzZTtcbiAgICAgICAgaWYgKHByb2dyZXNzVGltZXJJZCAhPSBudWxsKSB7XG4gICAgICAgICAgd2luZG93LmNhbmNlbEFuaW1hdGlvbkZyYW1lKHByb2dyZXNzVGltZXJJZCk7XG4gICAgICAgICAgcHJvZ3Jlc3NUaW1lcklkID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICAoZnVuY3Rpb24gbG9vcCgpIHtcbiAgICAgICAgICBpZiAodG9wYmFyLnByb2dyZXNzKFwiKy4xXCIpID49IDEpIHtcbiAgICAgICAgICAgIGNhbnZhcy5zdHlsZS5vcGFjaXR5IC09IDAuMDU7XG4gICAgICAgICAgICBpZiAoY2FudmFzLnN0eWxlLm9wYWNpdHkgPD0gMC4wNSkge1xuICAgICAgICAgICAgICBjYW52YXMuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuICAgICAgICAgICAgICBmYWRlVGltZXJJZCA9IG51bGw7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgZmFkZVRpbWVySWQgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKGxvb3ApO1xuICAgICAgICB9KSgpO1xuICAgICAgfSxcbiAgICB9O1xuXG4gIGlmICh0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gXCJvYmplY3RcIikge1xuICAgIG1vZHVsZS5leHBvcnRzID0gdG9wYmFyO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG4gICAgZGVmaW5lKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB0b3BiYXI7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy50b3BiYXIgPSB0b3BiYXI7XG4gIH1cbn0uY2FsbCh0aGlzLCB3aW5kb3csIGRvY3VtZW50KSk7XG4iLCAiXCJ1c2Ugc3RyaWN0XCI7XG5cbihmdW5jdGlvbigpIHtcbiAgdmFyIFBvbHlmaWxsRXZlbnQgPSBldmVudENvbnN0cnVjdG9yKCk7XG5cbiAgZnVuY3Rpb24gZXZlbnRDb25zdHJ1Y3RvcigpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdy5DdXN0b21FdmVudCA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gd2luZG93LkN1c3RvbUV2ZW50O1xuICAgIC8vIElFPD05IFN1cHBvcnRcbiAgICBmdW5jdGlvbiBDdXN0b21FdmVudChldmVudCwgcGFyYW1zKSB7XG4gICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge2J1YmJsZXM6IGZhbHNlLCBjYW5jZWxhYmxlOiBmYWxzZSwgZGV0YWlsOiB1bmRlZmluZWR9O1xuICAgICAgdmFyIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdDdXN0b21FdmVudCcpO1xuICAgICAgZXZ0LmluaXRDdXN0b21FdmVudChldmVudCwgcGFyYW1zLmJ1YmJsZXMsIHBhcmFtcy5jYW5jZWxhYmxlLCBwYXJhbXMuZGV0YWlsKTtcbiAgICAgIHJldHVybiBldnQ7XG4gICAgfVxuICAgIEN1c3RvbUV2ZW50LnByb3RvdHlwZSA9IHdpbmRvdy5FdmVudC5wcm90b3R5cGU7XG4gICAgcmV0dXJuIEN1c3RvbUV2ZW50O1xuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRIaWRkZW5JbnB1dChuYW1lLCB2YWx1ZSkge1xuICAgIHZhciBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKTtcbiAgICBpbnB1dC50eXBlID0gXCJoaWRkZW5cIjtcbiAgICBpbnB1dC5uYW1lID0gbmFtZTtcbiAgICBpbnB1dC52YWx1ZSA9IHZhbHVlO1xuICAgIHJldHVybiBpbnB1dDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZUNsaWNrKGVsZW1lbnQsIHRhcmdldE1vZGlmaWVyS2V5KSB7XG4gICAgdmFyIHRvID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXRvXCIpLFxuICAgICAgICBtZXRob2QgPSBidWlsZEhpZGRlbklucHV0KFwiX21ldGhvZFwiLCBlbGVtZW50LmdldEF0dHJpYnV0ZShcImRhdGEtbWV0aG9kXCIpKSxcbiAgICAgICAgY3NyZiA9IGJ1aWxkSGlkZGVuSW5wdXQoXCJfY3NyZl90b2tlblwiLCBlbGVtZW50LmdldEF0dHJpYnV0ZShcImRhdGEtY3NyZlwiKSksXG4gICAgICAgIGZvcm0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZm9ybVwiKSxcbiAgICAgICAgc3VibWl0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlucHV0XCIpLFxuICAgICAgICB0YXJnZXQgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShcInRhcmdldFwiKTtcblxuICAgIGZvcm0ubWV0aG9kID0gKGVsZW1lbnQuZ2V0QXR0cmlidXRlKFwiZGF0YS1tZXRob2RcIikgPT09IFwiZ2V0XCIpID8gXCJnZXRcIiA6IFwicG9zdFwiO1xuICAgIGZvcm0uYWN0aW9uID0gdG87XG4gICAgZm9ybS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XG5cbiAgICBpZiAodGFyZ2V0KSBmb3JtLnRhcmdldCA9IHRhcmdldDtcbiAgICBlbHNlIGlmICh0YXJnZXRNb2RpZmllcktleSkgZm9ybS50YXJnZXQgPSBcIl9ibGFua1wiO1xuXG4gICAgZm9ybS5hcHBlbmRDaGlsZChjc3JmKTtcbiAgICBmb3JtLmFwcGVuZENoaWxkKG1ldGhvZCk7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChmb3JtKTtcblxuICAgIC8vIEluc2VydCBhIGJ1dHRvbiBhbmQgY2xpY2sgaXQgaW5zdGVhZCBvZiB1c2luZyBgZm9ybS5zdWJtaXRgXG4gICAgLy8gYmVjYXVzZSB0aGUgYHN1Ym1pdGAgZnVuY3Rpb24gZG9lcyBub3QgZW1pdCBhIGBzdWJtaXRgIGV2ZW50LlxuICAgIHN1Ym1pdC50eXBlID0gXCJzdWJtaXRcIjtcbiAgICBmb3JtLmFwcGVuZENoaWxkKHN1Ym1pdCk7XG4gICAgc3VibWl0LmNsaWNrKCk7XG4gIH1cblxuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZWxlbWVudCA9IGUudGFyZ2V0O1xuICAgIGlmIChlLmRlZmF1bHRQcmV2ZW50ZWQpIHJldHVybjtcblxuICAgIHdoaWxlIChlbGVtZW50ICYmIGVsZW1lbnQuZ2V0QXR0cmlidXRlKSB7XG4gICAgICB2YXIgcGhvZW5peExpbmtFdmVudCA9IG5ldyBQb2x5ZmlsbEV2ZW50KCdwaG9lbml4LmxpbmsuY2xpY2snLCB7XG4gICAgICAgIFwiYnViYmxlc1wiOiB0cnVlLCBcImNhbmNlbGFibGVcIjogdHJ1ZVxuICAgICAgfSk7XG5cbiAgICAgIGlmICghZWxlbWVudC5kaXNwYXRjaEV2ZW50KHBob2VuaXhMaW5rRXZlbnQpKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoZWxlbWVudC5nZXRBdHRyaWJ1dGUoXCJkYXRhLW1ldGhvZFwiKSAmJiBlbGVtZW50LmdldEF0dHJpYnV0ZShcImRhdGEtdG9cIikpIHtcbiAgICAgICAgaGFuZGxlQ2xpY2soZWxlbWVudCwgZS5tZXRhS2V5IHx8IGUuc2hpZnRLZXkpO1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7XG4gICAgICB9XG4gICAgfVxuICB9LCBmYWxzZSk7XG5cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Bob2VuaXgubGluay5jbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIG1lc3NhZ2UgPSBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNvbmZpcm1cIik7XG4gICAgaWYobWVzc2FnZSAmJiAhd2luZG93LmNvbmZpcm0obWVzc2FnZSkpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH0sIGZhbHNlKTtcbn0pKCk7XG4iLCAiLy8gd3JhcHMgdmFsdWUgaW4gY2xvc3VyZSBvciByZXR1cm5zIGNsb3N1cmVcbmV4cG9ydCBsZXQgY2xvc3VyZSA9ICh2YWx1ZSkgPT4ge1xuICBpZih0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIil7XG4gICAgcmV0dXJuIHZhbHVlXG4gIH0gZWxzZSB7XG4gICAgbGV0IGNsb3N1cmUgPSBmdW5jdGlvbiAoKXsgcmV0dXJuIHZhbHVlIH1cbiAgICByZXR1cm4gY2xvc3VyZVxuICB9XG59XG4iLCAiZXhwb3J0IGNvbnN0IGdsb2JhbFNlbGYgPSB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiBudWxsXG5leHBvcnQgY29uc3QgcGh4V2luZG93ID0gdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IG51bGxcbmV4cG9ydCBjb25zdCBnbG9iYWwgPSBnbG9iYWxTZWxmIHx8IHBoeFdpbmRvdyB8fCBnbG9iYWxcbmV4cG9ydCBjb25zdCBERUZBVUxUX1ZTTiA9IFwiMi4wLjBcIlxuZXhwb3J0IGNvbnN0IFNPQ0tFVF9TVEFURVMgPSB7Y29ubmVjdGluZzogMCwgb3BlbjogMSwgY2xvc2luZzogMiwgY2xvc2VkOiAzfVxuZXhwb3J0IGNvbnN0IERFRkFVTFRfVElNRU9VVCA9IDEwMDAwXG5leHBvcnQgY29uc3QgV1NfQ0xPU0VfTk9STUFMID0gMTAwMFxuZXhwb3J0IGNvbnN0IENIQU5ORUxfU1RBVEVTID0ge1xuICBjbG9zZWQ6IFwiY2xvc2VkXCIsXG4gIGVycm9yZWQ6IFwiZXJyb3JlZFwiLFxuICBqb2luZWQ6IFwiam9pbmVkXCIsXG4gIGpvaW5pbmc6IFwiam9pbmluZ1wiLFxuICBsZWF2aW5nOiBcImxlYXZpbmdcIixcbn1cbmV4cG9ydCBjb25zdCBDSEFOTkVMX0VWRU5UUyA9IHtcbiAgY2xvc2U6IFwicGh4X2Nsb3NlXCIsXG4gIGVycm9yOiBcInBoeF9lcnJvclwiLFxuICBqb2luOiBcInBoeF9qb2luXCIsXG4gIHJlcGx5OiBcInBoeF9yZXBseVwiLFxuICBsZWF2ZTogXCJwaHhfbGVhdmVcIlxufVxuXG5leHBvcnQgY29uc3QgVFJBTlNQT1JUUyA9IHtcbiAgbG9uZ3BvbGw6IFwibG9uZ3BvbGxcIixcbiAgd2Vic29ja2V0OiBcIndlYnNvY2tldFwiXG59XG5leHBvcnQgY29uc3QgWEhSX1NUQVRFUyA9IHtcbiAgY29tcGxldGU6IDRcbn1cbiIsICIvKipcbiAqIEluaXRpYWxpemVzIHRoZSBQdXNoXG4gKiBAcGFyYW0ge0NoYW5uZWx9IGNoYW5uZWwgLSBUaGUgQ2hhbm5lbFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IC0gVGhlIGV2ZW50LCBmb3IgZXhhbXBsZSBgXCJwaHhfam9pblwiYFxuICogQHBhcmFtIHtPYmplY3R9IHBheWxvYWQgLSBUaGUgcGF5bG9hZCwgZm9yIGV4YW1wbGUgYHt1c2VyX2lkOiAxMjN9YFxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXQgLSBUaGUgcHVzaCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kc1xuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQdXNoIHtcbiAgY29uc3RydWN0b3IoY2hhbm5lbCwgZXZlbnQsIHBheWxvYWQsIHRpbWVvdXQpe1xuICAgIHRoaXMuY2hhbm5lbCA9IGNoYW5uZWxcbiAgICB0aGlzLmV2ZW50ID0gZXZlbnRcbiAgICB0aGlzLnBheWxvYWQgPSBwYXlsb2FkIHx8IGZ1bmN0aW9uICgpeyByZXR1cm4ge30gfVxuICAgIHRoaXMucmVjZWl2ZWRSZXNwID0gbnVsbFxuICAgIHRoaXMudGltZW91dCA9IHRpbWVvdXRcbiAgICB0aGlzLnRpbWVvdXRUaW1lciA9IG51bGxcbiAgICB0aGlzLnJlY0hvb2tzID0gW11cbiAgICB0aGlzLnNlbnQgPSBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lb3V0XG4gICAqL1xuICByZXNlbmQodGltZW91dCl7XG4gICAgdGhpcy50aW1lb3V0ID0gdGltZW91dFxuICAgIHRoaXMucmVzZXQoKVxuICAgIHRoaXMuc2VuZCgpXG4gIH1cblxuICAvKipcbiAgICpcbiAgICovXG4gIHNlbmQoKXtcbiAgICBpZih0aGlzLmhhc1JlY2VpdmVkKFwidGltZW91dFwiKSl7IHJldHVybiB9XG4gICAgdGhpcy5zdGFydFRpbWVvdXQoKVxuICAgIHRoaXMuc2VudCA9IHRydWVcbiAgICB0aGlzLmNoYW5uZWwuc29ja2V0LnB1c2goe1xuICAgICAgdG9waWM6IHRoaXMuY2hhbm5lbC50b3BpYyxcbiAgICAgIGV2ZW50OiB0aGlzLmV2ZW50LFxuICAgICAgcGF5bG9hZDogdGhpcy5wYXlsb2FkKCksXG4gICAgICByZWY6IHRoaXMucmVmLFxuICAgICAgam9pbl9yZWY6IHRoaXMuY2hhbm5lbC5qb2luUmVmKClcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gc3RhdHVzXG4gICAqIEBwYXJhbSB7Kn0gY2FsbGJhY2tcbiAgICovXG4gIHJlY2VpdmUoc3RhdHVzLCBjYWxsYmFjayl7XG4gICAgaWYodGhpcy5oYXNSZWNlaXZlZChzdGF0dXMpKXtcbiAgICAgIGNhbGxiYWNrKHRoaXMucmVjZWl2ZWRSZXNwLnJlc3BvbnNlKVxuICAgIH1cblxuICAgIHRoaXMucmVjSG9va3MucHVzaCh7c3RhdHVzLCBjYWxsYmFja30pXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcmVzZXQoKXtcbiAgICB0aGlzLmNhbmNlbFJlZkV2ZW50KClcbiAgICB0aGlzLnJlZiA9IG51bGxcbiAgICB0aGlzLnJlZkV2ZW50ID0gbnVsbFxuICAgIHRoaXMucmVjZWl2ZWRSZXNwID0gbnVsbFxuICAgIHRoaXMuc2VudCA9IGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIG1hdGNoUmVjZWl2ZSh7c3RhdHVzLCByZXNwb25zZSwgX3JlZn0pe1xuICAgIHRoaXMucmVjSG9va3MuZmlsdGVyKGggPT4gaC5zdGF0dXMgPT09IHN0YXR1cylcbiAgICAgIC5mb3JFYWNoKGggPT4gaC5jYWxsYmFjayhyZXNwb25zZSkpXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGNhbmNlbFJlZkV2ZW50KCl7XG4gICAgaWYoIXRoaXMucmVmRXZlbnQpeyByZXR1cm4gfVxuICAgIHRoaXMuY2hhbm5lbC5vZmYodGhpcy5yZWZFdmVudClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgY2FuY2VsVGltZW91dCgpe1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXRUaW1lcilcbiAgICB0aGlzLnRpbWVvdXRUaW1lciA9IG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgc3RhcnRUaW1lb3V0KCl7XG4gICAgaWYodGhpcy50aW1lb3V0VGltZXIpeyB0aGlzLmNhbmNlbFRpbWVvdXQoKSB9XG4gICAgdGhpcy5yZWYgPSB0aGlzLmNoYW5uZWwuc29ja2V0Lm1ha2VSZWYoKVxuICAgIHRoaXMucmVmRXZlbnQgPSB0aGlzLmNoYW5uZWwucmVwbHlFdmVudE5hbWUodGhpcy5yZWYpXG5cbiAgICB0aGlzLmNoYW5uZWwub24odGhpcy5yZWZFdmVudCwgcGF5bG9hZCA9PiB7XG4gICAgICB0aGlzLmNhbmNlbFJlZkV2ZW50KClcbiAgICAgIHRoaXMuY2FuY2VsVGltZW91dCgpXG4gICAgICB0aGlzLnJlY2VpdmVkUmVzcCA9IHBheWxvYWRcbiAgICAgIHRoaXMubWF0Y2hSZWNlaXZlKHBheWxvYWQpXG4gICAgfSlcblxuICAgIHRoaXMudGltZW91dFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnRyaWdnZXIoXCJ0aW1lb3V0XCIsIHt9KVxuICAgIH0sIHRoaXMudGltZW91dClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaGFzUmVjZWl2ZWQoc3RhdHVzKXtcbiAgICByZXR1cm4gdGhpcy5yZWNlaXZlZFJlc3AgJiYgdGhpcy5yZWNlaXZlZFJlc3Auc3RhdHVzID09PSBzdGF0dXNcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdHJpZ2dlcihzdGF0dXMsIHJlc3BvbnNlKXtcbiAgICB0aGlzLmNoYW5uZWwudHJpZ2dlcih0aGlzLnJlZkV2ZW50LCB7c3RhdHVzLCByZXNwb25zZX0pXG4gIH1cbn1cbiIsICIvKipcbiAqXG4gKiBDcmVhdGVzIGEgdGltZXIgdGhhdCBhY2NlcHRzIGEgYHRpbWVyQ2FsY2AgZnVuY3Rpb24gdG8gcGVyZm9ybVxuICogY2FsY3VsYXRlZCB0aW1lb3V0IHJldHJpZXMsIHN1Y2ggYXMgZXhwb25lbnRpYWwgYmFja29mZi5cbiAqXG4gKiBAZXhhbXBsZVxuICogbGV0IHJlY29ubmVjdFRpbWVyID0gbmV3IFRpbWVyKCgpID0+IHRoaXMuY29ubmVjdCgpLCBmdW5jdGlvbih0cmllcyl7XG4gKiAgIHJldHVybiBbMTAwMCwgNTAwMCwgMTAwMDBdW3RyaWVzIC0gMV0gfHwgMTAwMDBcbiAqIH0pXG4gKiByZWNvbm5lY3RUaW1lci5zY2hlZHVsZVRpbWVvdXQoKSAvLyBmaXJlcyBhZnRlciAxMDAwXG4gKiByZWNvbm5lY3RUaW1lci5zY2hlZHVsZVRpbWVvdXQoKSAvLyBmaXJlcyBhZnRlciA1MDAwXG4gKiByZWNvbm5lY3RUaW1lci5yZXNldCgpXG4gKiByZWNvbm5lY3RUaW1lci5zY2hlZHVsZVRpbWVvdXQoKSAvLyBmaXJlcyBhZnRlciAxMDAwXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRpbWVyQ2FsY1xuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUaW1lciB7XG4gIGNvbnN0cnVjdG9yKGNhbGxiYWNrLCB0aW1lckNhbGMpe1xuICAgIHRoaXMuY2FsbGJhY2sgPSBjYWxsYmFja1xuICAgIHRoaXMudGltZXJDYWxjID0gdGltZXJDYWxjXG4gICAgdGhpcy50aW1lciA9IG51bGxcbiAgICB0aGlzLnRyaWVzID0gMFxuICB9XG5cbiAgcmVzZXQoKXtcbiAgICB0aGlzLnRyaWVzID0gMFxuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKVxuICB9XG5cbiAgLyoqXG4gICAqIENhbmNlbHMgYW55IHByZXZpb3VzIHNjaGVkdWxlVGltZW91dCBhbmQgc2NoZWR1bGVzIGNhbGxiYWNrXG4gICAqL1xuICBzY2hlZHVsZVRpbWVvdXQoKXtcbiAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lcilcblxuICAgIHRoaXMudGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMudHJpZXMgPSB0aGlzLnRyaWVzICsgMVxuICAgICAgdGhpcy5jYWxsYmFjaygpXG4gICAgfSwgdGhpcy50aW1lckNhbGModGhpcy50cmllcyArIDEpKVxuICB9XG59XG4iLCAiaW1wb3J0IHtjbG9zdXJlfSBmcm9tIFwiLi91dGlsc1wiXG5pbXBvcnQge1xuICBDSEFOTkVMX0VWRU5UUyxcbiAgQ0hBTk5FTF9TVEFURVMsXG59IGZyb20gXCIuL2NvbnN0YW50c1wiXG5cbmltcG9ydCBQdXNoIGZyb20gXCIuL3B1c2hcIlxuaW1wb3J0IFRpbWVyIGZyb20gXCIuL3RpbWVyXCJcblxuLyoqXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRvcGljXG4gKiBAcGFyYW0geyhPYmplY3R8ZnVuY3Rpb24pfSBwYXJhbXNcbiAqIEBwYXJhbSB7U29ja2V0fSBzb2NrZXRcbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ2hhbm5lbCB7XG4gIGNvbnN0cnVjdG9yKHRvcGljLCBwYXJhbXMsIHNvY2tldCl7XG4gICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmNsb3NlZFxuICAgIHRoaXMudG9waWMgPSB0b3BpY1xuICAgIHRoaXMucGFyYW1zID0gY2xvc3VyZShwYXJhbXMgfHwge30pXG4gICAgdGhpcy5zb2NrZXQgPSBzb2NrZXRcbiAgICB0aGlzLmJpbmRpbmdzID0gW11cbiAgICB0aGlzLmJpbmRpbmdSZWYgPSAwXG4gICAgdGhpcy50aW1lb3V0ID0gdGhpcy5zb2NrZXQudGltZW91dFxuICAgIHRoaXMuam9pbmVkT25jZSA9IGZhbHNlXG4gICAgdGhpcy5qb2luUHVzaCA9IG5ldyBQdXNoKHRoaXMsIENIQU5ORUxfRVZFTlRTLmpvaW4sIHRoaXMucGFyYW1zLCB0aGlzLnRpbWVvdXQpXG4gICAgdGhpcy5wdXNoQnVmZmVyID0gW11cbiAgICB0aGlzLnN0YXRlQ2hhbmdlUmVmcyA9IFtdXG5cbiAgICB0aGlzLnJlam9pblRpbWVyID0gbmV3IFRpbWVyKCgpID0+IHtcbiAgICAgIGlmKHRoaXMuc29ja2V0LmlzQ29ubmVjdGVkKCkpeyB0aGlzLnJlam9pbigpIH1cbiAgICB9LCB0aGlzLnNvY2tldC5yZWpvaW5BZnRlck1zKVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VSZWZzLnB1c2godGhpcy5zb2NrZXQub25FcnJvcigoKSA9PiB0aGlzLnJlam9pblRpbWVyLnJlc2V0KCkpKVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VSZWZzLnB1c2godGhpcy5zb2NrZXQub25PcGVuKCgpID0+IHtcbiAgICAgIHRoaXMucmVqb2luVGltZXIucmVzZXQoKVxuICAgICAgaWYodGhpcy5pc0Vycm9yZWQoKSl7IHRoaXMucmVqb2luKCkgfVxuICAgIH0pXG4gICAgKVxuICAgIHRoaXMuam9pblB1c2gucmVjZWl2ZShcIm9rXCIsICgpID0+IHtcbiAgICAgIHRoaXMuc3RhdGUgPSBDSEFOTkVMX1NUQVRFUy5qb2luZWRcbiAgICAgIHRoaXMucmVqb2luVGltZXIucmVzZXQoKVxuICAgICAgdGhpcy5wdXNoQnVmZmVyLmZvckVhY2gocHVzaEV2ZW50ID0+IHB1c2hFdmVudC5zZW5kKCkpXG4gICAgICB0aGlzLnB1c2hCdWZmZXIgPSBbXVxuICAgIH0pXG4gICAgdGhpcy5qb2luUHVzaC5yZWNlaXZlKFwiZXJyb3JcIiwgKCkgPT4ge1xuICAgICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmVycm9yZWRcbiAgICAgIGlmKHRoaXMuc29ja2V0LmlzQ29ubmVjdGVkKCkpeyB0aGlzLnJlam9pblRpbWVyLnNjaGVkdWxlVGltZW91dCgpIH1cbiAgICB9KVxuICAgIHRoaXMub25DbG9zZSgoKSA9PiB7XG4gICAgICB0aGlzLnJlam9pblRpbWVyLnJlc2V0KClcbiAgICAgIGlmKHRoaXMuc29ja2V0Lmhhc0xvZ2dlcigpKSB0aGlzLnNvY2tldC5sb2coXCJjaGFubmVsXCIsIGBjbG9zZSAke3RoaXMudG9waWN9ICR7dGhpcy5qb2luUmVmKCl9YClcbiAgICAgIHRoaXMuc3RhdGUgPSBDSEFOTkVMX1NUQVRFUy5jbG9zZWRcbiAgICAgIHRoaXMuc29ja2V0LnJlbW92ZSh0aGlzKVxuICAgIH0pXG4gICAgdGhpcy5vbkVycm9yKHJlYXNvbiA9PiB7XG4gICAgICBpZih0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBgZXJyb3IgJHt0aGlzLnRvcGljfWAsIHJlYXNvbilcbiAgICAgIGlmKHRoaXMuaXNKb2luaW5nKCkpeyB0aGlzLmpvaW5QdXNoLnJlc2V0KCkgfVxuICAgICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmVycm9yZWRcbiAgICAgIGlmKHRoaXMuc29ja2V0LmlzQ29ubmVjdGVkKCkpeyB0aGlzLnJlam9pblRpbWVyLnNjaGVkdWxlVGltZW91dCgpIH1cbiAgICB9KVxuICAgIHRoaXMuam9pblB1c2gucmVjZWl2ZShcInRpbWVvdXRcIiwgKCkgPT4ge1xuICAgICAgaWYodGhpcy5zb2NrZXQuaGFzTG9nZ2VyKCkpIHRoaXMuc29ja2V0LmxvZyhcImNoYW5uZWxcIiwgYHRpbWVvdXQgJHt0aGlzLnRvcGljfSAoJHt0aGlzLmpvaW5SZWYoKX0pYCwgdGhpcy5qb2luUHVzaC50aW1lb3V0KVxuICAgICAgbGV0IGxlYXZlUHVzaCA9IG5ldyBQdXNoKHRoaXMsIENIQU5ORUxfRVZFTlRTLmxlYXZlLCBjbG9zdXJlKHt9KSwgdGhpcy50aW1lb3V0KVxuICAgICAgbGVhdmVQdXNoLnNlbmQoKVxuICAgICAgdGhpcy5zdGF0ZSA9IENIQU5ORUxfU1RBVEVTLmVycm9yZWRcbiAgICAgIHRoaXMuam9pblB1c2gucmVzZXQoKVxuICAgICAgaWYodGhpcy5zb2NrZXQuaXNDb25uZWN0ZWQoKSl7IHRoaXMucmVqb2luVGltZXIuc2NoZWR1bGVUaW1lb3V0KCkgfVxuICAgIH0pXG4gICAgdGhpcy5vbihDSEFOTkVMX0VWRU5UUy5yZXBseSwgKHBheWxvYWQsIHJlZikgPT4ge1xuICAgICAgdGhpcy50cmlnZ2VyKHRoaXMucmVwbHlFdmVudE5hbWUocmVmKSwgcGF5bG9hZClcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEpvaW4gdGhlIGNoYW5uZWxcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSB0aW1lb3V0XG4gICAqIEByZXR1cm5zIHtQdXNofVxuICAgKi9cbiAgam9pbih0aW1lb3V0ID0gdGhpcy50aW1lb3V0KXtcbiAgICBpZih0aGlzLmpvaW5lZE9uY2Upe1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwidHJpZWQgdG8gam9pbiBtdWx0aXBsZSB0aW1lcy4gJ2pvaW4nIGNhbiBvbmx5IGJlIGNhbGxlZCBhIHNpbmdsZSB0aW1lIHBlciBjaGFubmVsIGluc3RhbmNlXCIpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudGltZW91dCA9IHRpbWVvdXRcbiAgICAgIHRoaXMuam9pbmVkT25jZSA9IHRydWVcbiAgICAgIHRoaXMucmVqb2luKClcbiAgICAgIHJldHVybiB0aGlzLmpvaW5QdXNoXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEhvb2sgaW50byBjaGFubmVsIGNsb3NlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBvbkNsb3NlKGNhbGxiYWNrKXtcbiAgICB0aGlzLm9uKENIQU5ORUxfRVZFTlRTLmNsb3NlLCBjYWxsYmFjaylcbiAgfVxuXG4gIC8qKlxuICAgKiBIb29rIGludG8gY2hhbm5lbCBlcnJvcnNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIG9uRXJyb3IoY2FsbGJhY2spe1xuICAgIHJldHVybiB0aGlzLm9uKENIQU5ORUxfRVZFTlRTLmVycm9yLCByZWFzb24gPT4gY2FsbGJhY2socmVhc29uKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJzY3JpYmVzIG9uIGNoYW5uZWwgZXZlbnRzXG4gICAqXG4gICAqIFN1YnNjcmlwdGlvbiByZXR1cm5zIGEgcmVmIGNvdW50ZXIsIHdoaWNoIGNhbiBiZSB1c2VkIGxhdGVyIHRvXG4gICAqIHVuc3Vic2NyaWJlIHRoZSBleGFjdCBldmVudCBsaXN0ZW5lclxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjb25zdCByZWYxID0gY2hhbm5lbC5vbihcImV2ZW50XCIsIGRvX3N0dWZmKVxuICAgKiBjb25zdCByZWYyID0gY2hhbm5lbC5vbihcImV2ZW50XCIsIGRvX290aGVyX3N0dWZmKVxuICAgKiBjaGFubmVsLm9mZihcImV2ZW50XCIsIHJlZjEpXG4gICAqIC8vIFNpbmNlIHVuc3Vic2NyaXB0aW9uLCBkb19zdHVmZiB3b24ndCBmaXJlLFxuICAgKiAvLyB3aGlsZSBkb19vdGhlcl9zdHVmZiB3aWxsIGtlZXAgZmlyaW5nIG9uIHRoZSBcImV2ZW50XCJcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqIEByZXR1cm5zIHtpbnRlZ2VyfSByZWZcbiAgICovXG4gIG9uKGV2ZW50LCBjYWxsYmFjayl7XG4gICAgbGV0IHJlZiA9IHRoaXMuYmluZGluZ1JlZisrXG4gICAgdGhpcy5iaW5kaW5ncy5wdXNoKHtldmVudCwgcmVmLCBjYWxsYmFja30pXG4gICAgcmV0dXJuIHJlZlxuICB9XG5cbiAgLyoqXG4gICAqIFVuc3Vic2NyaWJlcyBvZmYgb2YgY2hhbm5lbCBldmVudHNcbiAgICpcbiAgICogVXNlIHRoZSByZWYgcmV0dXJuZWQgZnJvbSBhIGNoYW5uZWwub24oKSB0byB1bnN1YnNjcmliZSBvbmVcbiAgICogaGFuZGxlciwgb3IgcGFzcyBub3RoaW5nIGZvciB0aGUgcmVmIHRvIHVuc3Vic2NyaWJlIGFsbFxuICAgKiBoYW5kbGVycyBmb3IgdGhlIGdpdmVuIGV2ZW50LlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBVbnN1YnNjcmliZSB0aGUgZG9fc3R1ZmYgaGFuZGxlclxuICAgKiBjb25zdCByZWYxID0gY2hhbm5lbC5vbihcImV2ZW50XCIsIGRvX3N0dWZmKVxuICAgKiBjaGFubmVsLm9mZihcImV2ZW50XCIsIHJlZjEpXG4gICAqXG4gICAqIC8vIFVuc3Vic2NyaWJlIGFsbCBoYW5kbGVycyBmcm9tIGV2ZW50XG4gICAqIGNoYW5uZWwub2ZmKFwiZXZlbnRcIilcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7aW50ZWdlcn0gcmVmXG4gICAqL1xuICBvZmYoZXZlbnQsIHJlZil7XG4gICAgdGhpcy5iaW5kaW5ncyA9IHRoaXMuYmluZGluZ3MuZmlsdGVyKChiaW5kKSA9PiB7XG4gICAgICByZXR1cm4gIShiaW5kLmV2ZW50ID09PSBldmVudCAmJiAodHlwZW9mIHJlZiA9PT0gXCJ1bmRlZmluZWRcIiB8fCByZWYgPT09IGJpbmQucmVmKSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBjYW5QdXNoKCl7IHJldHVybiB0aGlzLnNvY2tldC5pc0Nvbm5lY3RlZCgpICYmIHRoaXMuaXNKb2luZWQoKSB9XG5cbiAgLyoqXG4gICAqIFNlbmRzIGEgbWVzc2FnZSBgZXZlbnRgIHRvIHBob2VuaXggd2l0aCB0aGUgcGF5bG9hZCBgcGF5bG9hZGAuXG4gICAqIFBob2VuaXggcmVjZWl2ZXMgdGhpcyBpbiB0aGUgYGhhbmRsZV9pbihldmVudCwgcGF5bG9hZCwgc29ja2V0KWBcbiAgICogZnVuY3Rpb24uIGlmIHBob2VuaXggcmVwbGllcyBvciBpdCB0aW1lcyBvdXQgKGRlZmF1bHQgMTAwMDBtcyksXG4gICAqIHRoZW4gb3B0aW9uYWxseSB0aGUgcmVwbHkgY2FuIGJlIHJlY2VpdmVkLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjaGFubmVsLnB1c2goXCJldmVudFwiKVxuICAgKiAgIC5yZWNlaXZlKFwib2tcIiwgcGF5bG9hZCA9PiBjb25zb2xlLmxvZyhcInBob2VuaXggcmVwbGllZDpcIiwgcGF5bG9hZCkpXG4gICAqICAgLnJlY2VpdmUoXCJlcnJvclwiLCBlcnIgPT4gY29uc29sZS5sb2coXCJwaG9lbml4IGVycm9yZWRcIiwgZXJyKSlcbiAgICogICAucmVjZWl2ZShcInRpbWVvdXRcIiwgKCkgPT4gY29uc29sZS5sb2coXCJ0aW1lZCBvdXQgcHVzaGluZ1wiKSlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXlsb2FkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbdGltZW91dF1cbiAgICogQHJldHVybnMge1B1c2h9XG4gICAqL1xuICBwdXNoKGV2ZW50LCBwYXlsb2FkLCB0aW1lb3V0ID0gdGhpcy50aW1lb3V0KXtcbiAgICBwYXlsb2FkID0gcGF5bG9hZCB8fCB7fVxuICAgIGlmKCF0aGlzLmpvaW5lZE9uY2Upe1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGB0cmllZCB0byBwdXNoICcke2V2ZW50fScgdG8gJyR7dGhpcy50b3BpY30nIGJlZm9yZSBqb2luaW5nLiBVc2UgY2hhbm5lbC5qb2luKCkgYmVmb3JlIHB1c2hpbmcgZXZlbnRzYClcbiAgICB9XG4gICAgbGV0IHB1c2hFdmVudCA9IG5ldyBQdXNoKHRoaXMsIGV2ZW50LCBmdW5jdGlvbiAoKXsgcmV0dXJuIHBheWxvYWQgfSwgdGltZW91dClcbiAgICBpZih0aGlzLmNhblB1c2goKSl7XG4gICAgICBwdXNoRXZlbnQuc2VuZCgpXG4gICAgfSBlbHNlIHtcbiAgICAgIHB1c2hFdmVudC5zdGFydFRpbWVvdXQoKVxuICAgICAgdGhpcy5wdXNoQnVmZmVyLnB1c2gocHVzaEV2ZW50KVxuICAgIH1cblxuICAgIHJldHVybiBwdXNoRXZlbnRcbiAgfVxuXG4gIC8qKiBMZWF2ZXMgdGhlIGNoYW5uZWxcbiAgICpcbiAgICogVW5zdWJzY3JpYmVzIGZyb20gc2VydmVyIGV2ZW50cywgYW5kXG4gICAqIGluc3RydWN0cyBjaGFubmVsIHRvIHRlcm1pbmF0ZSBvbiBzZXJ2ZXJcbiAgICpcbiAgICogVHJpZ2dlcnMgb25DbG9zZSgpIGhvb2tzXG4gICAqXG4gICAqIFRvIHJlY2VpdmUgbGVhdmUgYWNrbm93bGVkZ2VtZW50cywgdXNlIHRoZSBgcmVjZWl2ZWBcbiAgICogaG9vayB0byBiaW5kIHRvIHRoZSBzZXJ2ZXIgYWNrLCBpZTpcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY2hhbm5lbC5sZWF2ZSgpLnJlY2VpdmUoXCJva1wiLCAoKSA9PiBhbGVydChcImxlZnQhXCIpIClcbiAgICpcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSB0aW1lb3V0XG4gICAqIEByZXR1cm5zIHtQdXNofVxuICAgKi9cbiAgbGVhdmUodGltZW91dCA9IHRoaXMudGltZW91dCl7XG4gICAgdGhpcy5yZWpvaW5UaW1lci5yZXNldCgpXG4gICAgdGhpcy5qb2luUHVzaC5jYW5jZWxUaW1lb3V0KClcblxuICAgIHRoaXMuc3RhdGUgPSBDSEFOTkVMX1NUQVRFUy5sZWF2aW5nXG4gICAgbGV0IG9uQ2xvc2UgPSAoKSA9PiB7XG4gICAgICBpZih0aGlzLnNvY2tldC5oYXNMb2dnZXIoKSkgdGhpcy5zb2NrZXQubG9nKFwiY2hhbm5lbFwiLCBgbGVhdmUgJHt0aGlzLnRvcGljfWApXG4gICAgICB0aGlzLnRyaWdnZXIoQ0hBTk5FTF9FVkVOVFMuY2xvc2UsIFwibGVhdmVcIilcbiAgICB9XG4gICAgbGV0IGxlYXZlUHVzaCA9IG5ldyBQdXNoKHRoaXMsIENIQU5ORUxfRVZFTlRTLmxlYXZlLCBjbG9zdXJlKHt9KSwgdGltZW91dClcbiAgICBsZWF2ZVB1c2gucmVjZWl2ZShcIm9rXCIsICgpID0+IG9uQ2xvc2UoKSlcbiAgICAgIC5yZWNlaXZlKFwidGltZW91dFwiLCAoKSA9PiBvbkNsb3NlKCkpXG4gICAgbGVhdmVQdXNoLnNlbmQoKVxuICAgIGlmKCF0aGlzLmNhblB1c2goKSl7IGxlYXZlUHVzaC50cmlnZ2VyKFwib2tcIiwge30pIH1cblxuICAgIHJldHVybiBsZWF2ZVB1c2hcbiAgfVxuXG4gIC8qKlxuICAgKiBPdmVycmlkYWJsZSBtZXNzYWdlIGhvb2tcbiAgICpcbiAgICogUmVjZWl2ZXMgYWxsIGV2ZW50cyBmb3Igc3BlY2lhbGl6ZWQgbWVzc2FnZSBoYW5kbGluZ1xuICAgKiBiZWZvcmUgZGlzcGF0Y2hpbmcgdG8gdGhlIGNoYW5uZWwgY2FsbGJhY2tzLlxuICAgKlxuICAgKiBNdXN0IHJldHVybiB0aGUgcGF5bG9hZCwgbW9kaWZpZWQgb3IgdW5tb2RpZmllZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRcbiAgICogQHBhcmFtIHtPYmplY3R9IHBheWxvYWRcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSByZWZcbiAgICogQHJldHVybnMge09iamVjdH1cbiAgICovXG4gIG9uTWVzc2FnZShfZXZlbnQsIHBheWxvYWQsIF9yZWYpeyByZXR1cm4gcGF5bG9hZCB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBpc01lbWJlcih0b3BpYywgZXZlbnQsIHBheWxvYWQsIGpvaW5SZWYpe1xuICAgIGlmKHRoaXMudG9waWMgIT09IHRvcGljKXsgcmV0dXJuIGZhbHNlIH1cblxuICAgIGlmKGpvaW5SZWYgJiYgam9pblJlZiAhPT0gdGhpcy5qb2luUmVmKCkpe1xuICAgICAgaWYodGhpcy5zb2NrZXQuaGFzTG9nZ2VyKCkpIHRoaXMuc29ja2V0LmxvZyhcImNoYW5uZWxcIiwgXCJkcm9wcGluZyBvdXRkYXRlZCBtZXNzYWdlXCIsIHt0b3BpYywgZXZlbnQsIHBheWxvYWQsIGpvaW5SZWZ9KVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBqb2luUmVmKCl7IHJldHVybiB0aGlzLmpvaW5QdXNoLnJlZiB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICByZWpvaW4odGltZW91dCA9IHRoaXMudGltZW91dCl7XG4gICAgaWYodGhpcy5pc0xlYXZpbmcoKSl7IHJldHVybiB9XG4gICAgdGhpcy5zb2NrZXQubGVhdmVPcGVuVG9waWModGhpcy50b3BpYylcbiAgICB0aGlzLnN0YXRlID0gQ0hBTk5FTF9TVEFURVMuam9pbmluZ1xuICAgIHRoaXMuam9pblB1c2gucmVzZW5kKHRpbWVvdXQpXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHRyaWdnZXIoZXZlbnQsIHBheWxvYWQsIHJlZiwgam9pblJlZil7XG4gICAgbGV0IGhhbmRsZWRQYXlsb2FkID0gdGhpcy5vbk1lc3NhZ2UoZXZlbnQsIHBheWxvYWQsIHJlZiwgam9pblJlZilcbiAgICBpZihwYXlsb2FkICYmICFoYW5kbGVkUGF5bG9hZCl7IHRocm93IG5ldyBFcnJvcihcImNoYW5uZWwgb25NZXNzYWdlIGNhbGxiYWNrcyBtdXN0IHJldHVybiB0aGUgcGF5bG9hZCwgbW9kaWZpZWQgb3IgdW5tb2RpZmllZFwiKSB9XG5cbiAgICBsZXQgZXZlbnRCaW5kaW5ncyA9IHRoaXMuYmluZGluZ3MuZmlsdGVyKGJpbmQgPT4gYmluZC5ldmVudCA9PT0gZXZlbnQpXG5cbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgZXZlbnRCaW5kaW5ncy5sZW5ndGg7IGkrKyl7XG4gICAgICBsZXQgYmluZCA9IGV2ZW50QmluZGluZ3NbaV1cbiAgICAgIGJpbmQuY2FsbGJhY2soaGFuZGxlZFBheWxvYWQsIHJlZiwgam9pblJlZiB8fCB0aGlzLmpvaW5SZWYoKSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHJlcGx5RXZlbnROYW1lKHJlZil7IHJldHVybiBgY2hhbl9yZXBseV8ke3JlZn1gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGlzQ2xvc2VkKCl7IHJldHVybiB0aGlzLnN0YXRlID09PSBDSEFOTkVMX1NUQVRFUy5jbG9zZWQgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaXNFcnJvcmVkKCl7IHJldHVybiB0aGlzLnN0YXRlID09PSBDSEFOTkVMX1NUQVRFUy5lcnJvcmVkIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGlzSm9pbmVkKCl7IHJldHVybiB0aGlzLnN0YXRlID09PSBDSEFOTkVMX1NUQVRFUy5qb2luZWQgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgaXNKb2luaW5nKCl7IHJldHVybiB0aGlzLnN0YXRlID09PSBDSEFOTkVMX1NUQVRFUy5qb2luaW5nIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIGlzTGVhdmluZygpeyByZXR1cm4gdGhpcy5zdGF0ZSA9PT0gQ0hBTk5FTF9TVEFURVMubGVhdmluZyB9XG59XG4iLCAiaW1wb3J0IHtcbiAgZ2xvYmFsLFxuICBYSFJfU1RBVEVTXG59IGZyb20gXCIuL2NvbnN0YW50c1wiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFqYXgge1xuXG4gIHN0YXRpYyByZXF1ZXN0KG1ldGhvZCwgZW5kUG9pbnQsIGFjY2VwdCwgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjayl7XG4gICAgaWYoZ2xvYmFsLlhEb21haW5SZXF1ZXN0KXtcbiAgICAgIGxldCByZXEgPSBuZXcgZ2xvYmFsLlhEb21haW5SZXF1ZXN0KCkgLy8gSUU4LCBJRTlcbiAgICAgIHJldHVybiB0aGlzLnhkb21haW5SZXF1ZXN0KHJlcSwgbWV0aG9kLCBlbmRQb2ludCwgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjaylcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHJlcSA9IG5ldyBnbG9iYWwuWE1MSHR0cFJlcXVlc3QoKSAvLyBJRTcrLCBGaXJlZm94LCBDaHJvbWUsIE9wZXJhLCBTYWZhcmlcbiAgICAgIHJldHVybiB0aGlzLnhoclJlcXVlc3QocmVxLCBtZXRob2QsIGVuZFBvaW50LCBhY2NlcHQsIGJvZHksIHRpbWVvdXQsIG9udGltZW91dCwgY2FsbGJhY2spXG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHhkb21haW5SZXF1ZXN0KHJlcSwgbWV0aG9kLCBlbmRQb2ludCwgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjayl7XG4gICAgcmVxLnRpbWVvdXQgPSB0aW1lb3V0XG4gICAgcmVxLm9wZW4obWV0aG9kLCBlbmRQb2ludClcbiAgICByZXEub25sb2FkID0gKCkgPT4ge1xuICAgICAgbGV0IHJlc3BvbnNlID0gdGhpcy5wYXJzZUpTT04ocmVxLnJlc3BvbnNlVGV4dClcbiAgICAgIGNhbGxiYWNrICYmIGNhbGxiYWNrKHJlc3BvbnNlKVxuICAgIH1cbiAgICBpZihvbnRpbWVvdXQpeyByZXEub250aW1lb3V0ID0gb250aW1lb3V0IH1cblxuICAgIC8vIFdvcmsgYXJvdW5kIGJ1ZyBpbiBJRTkgdGhhdCByZXF1aXJlcyBhbiBhdHRhY2hlZCBvbnByb2dyZXNzIGhhbmRsZXJcbiAgICByZXEub25wcm9ncmVzcyA9ICgpID0+IHsgfVxuXG4gICAgcmVxLnNlbmQoYm9keSlcbiAgICByZXR1cm4gcmVxXG4gIH1cblxuICBzdGF0aWMgeGhyUmVxdWVzdChyZXEsIG1ldGhvZCwgZW5kUG9pbnQsIGFjY2VwdCwgYm9keSwgdGltZW91dCwgb250aW1lb3V0LCBjYWxsYmFjayl7XG4gICAgcmVxLm9wZW4obWV0aG9kLCBlbmRQb2ludCwgdHJ1ZSlcbiAgICByZXEudGltZW91dCA9IHRpbWVvdXRcbiAgICByZXEuc2V0UmVxdWVzdEhlYWRlcihcIkNvbnRlbnQtVHlwZVwiLCBhY2NlcHQpXG4gICAgcmVxLm9uZXJyb3IgPSAoKSA9PiBjYWxsYmFjayAmJiBjYWxsYmFjayhudWxsKVxuICAgIHJlcS5vbnJlYWR5c3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICBpZihyZXEucmVhZHlTdGF0ZSA9PT0gWEhSX1NUQVRFUy5jb21wbGV0ZSAmJiBjYWxsYmFjayl7XG4gICAgICAgIGxldCByZXNwb25zZSA9IHRoaXMucGFyc2VKU09OKHJlcS5yZXNwb25zZVRleHQpXG4gICAgICAgIGNhbGxiYWNrKHJlc3BvbnNlKVxuICAgICAgfVxuICAgIH1cbiAgICBpZihvbnRpbWVvdXQpeyByZXEub250aW1lb3V0ID0gb250aW1lb3V0IH1cblxuICAgIHJlcS5zZW5kKGJvZHkpXG4gICAgcmV0dXJuIHJlcVxuICB9XG5cbiAgc3RhdGljIHBhcnNlSlNPTihyZXNwKXtcbiAgICBpZighcmVzcCB8fCByZXNwID09PSBcIlwiKXsgcmV0dXJuIG51bGwgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBKU09OLnBhcnNlKHJlc3ApXG4gICAgfSBjYXRjaCAoZSl7XG4gICAgICBjb25zb2xlICYmIGNvbnNvbGUubG9nKFwiZmFpbGVkIHRvIHBhcnNlIEpTT04gcmVzcG9uc2VcIiwgcmVzcClcbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHNlcmlhbGl6ZShvYmosIHBhcmVudEtleSl7XG4gICAgbGV0IHF1ZXJ5U3RyID0gW11cbiAgICBmb3IodmFyIGtleSBpbiBvYmope1xuICAgICAgaWYoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpeyBjb250aW51ZSB9XG4gICAgICBsZXQgcGFyYW1LZXkgPSBwYXJlbnRLZXkgPyBgJHtwYXJlbnRLZXl9WyR7a2V5fV1gIDoga2V5XG4gICAgICBsZXQgcGFyYW1WYWwgPSBvYmpba2V5XVxuICAgICAgaWYodHlwZW9mIHBhcmFtVmFsID09PSBcIm9iamVjdFwiKXtcbiAgICAgICAgcXVlcnlTdHIucHVzaCh0aGlzLnNlcmlhbGl6ZShwYXJhbVZhbCwgcGFyYW1LZXkpKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcnlTdHIucHVzaChlbmNvZGVVUklDb21wb25lbnQocGFyYW1LZXkpICsgXCI9XCIgKyBlbmNvZGVVUklDb21wb25lbnQocGFyYW1WYWwpKVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcXVlcnlTdHIuam9pbihcIiZcIilcbiAgfVxuXG4gIHN0YXRpYyBhcHBlbmRQYXJhbXModXJsLCBwYXJhbXMpe1xuICAgIGlmKE9iamVjdC5rZXlzKHBhcmFtcykubGVuZ3RoID09PSAwKXsgcmV0dXJuIHVybCB9XG5cbiAgICBsZXQgcHJlZml4ID0gdXJsLm1hdGNoKC9cXD8vKSA/IFwiJlwiIDogXCI/XCJcbiAgICByZXR1cm4gYCR7dXJsfSR7cHJlZml4fSR7dGhpcy5zZXJpYWxpemUocGFyYW1zKX1gXG4gIH1cbn1cbiIsICJpbXBvcnQge1xuICBTT0NLRVRfU1RBVEVTLFxuICBUUkFOU1BPUlRTXG59IGZyb20gXCIuL2NvbnN0YW50c1wiXG5cbmltcG9ydCBBamF4IGZyb20gXCIuL2FqYXhcIlxuXG5sZXQgYXJyYXlCdWZmZXJUb0Jhc2U2NCA9IChidWZmZXIpID0+IHtcbiAgbGV0IGJpbmFyeSA9IFwiXCJcbiAgbGV0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKVxuICBsZXQgbGVuID0gYnl0ZXMuYnl0ZUxlbmd0aFxuICBmb3IobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSkgfVxuICByZXR1cm4gYnRvYShiaW5hcnkpXG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExvbmdQb2xsIHtcblxuICBjb25zdHJ1Y3RvcihlbmRQb2ludCl7XG4gICAgdGhpcy5lbmRQb2ludCA9IG51bGxcbiAgICB0aGlzLnRva2VuID0gbnVsbFxuICAgIHRoaXMuc2tpcEhlYXJ0YmVhdCA9IHRydWVcbiAgICB0aGlzLnJlcXMgPSBuZXcgU2V0KClcbiAgICB0aGlzLmF3YWl0aW5nQmF0Y2hBY2sgPSBmYWxzZVxuICAgIHRoaXMuY3VycmVudEJhdGNoID0gbnVsbFxuICAgIHRoaXMuY3VycmVudEJhdGNoVGltZXIgPSBudWxsXG4gICAgdGhpcy5iYXRjaEJ1ZmZlciA9IFtdXG4gICAgdGhpcy5vbm9wZW4gPSBmdW5jdGlvbiAoKXsgfSAvLyBub29wXG4gICAgdGhpcy5vbmVycm9yID0gZnVuY3Rpb24gKCl7IH0gLy8gbm9vcFxuICAgIHRoaXMub25tZXNzYWdlID0gZnVuY3Rpb24gKCl7IH0gLy8gbm9vcFxuICAgIHRoaXMub25jbG9zZSA9IGZ1bmN0aW9uICgpeyB9IC8vIG5vb3BcbiAgICB0aGlzLnBvbGxFbmRwb2ludCA9IHRoaXMubm9ybWFsaXplRW5kcG9pbnQoZW5kUG9pbnQpXG4gICAgdGhpcy5yZWFkeVN0YXRlID0gU09DS0VUX1NUQVRFUy5jb25uZWN0aW5nXG4gICAgLy8gd2UgbXVzdCB3YWl0IGZvciB0aGUgY2FsbGVyIHRvIGZpbmlzaCBzZXR0aW5nIHVwIG91ciBjYWxsYmFja3MgYW5kIHRpbWVvdXQgcHJvcGVydGllc1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5wb2xsKCksIDApXG4gIH1cblxuICBub3JtYWxpemVFbmRwb2ludChlbmRQb2ludCl7XG4gICAgcmV0dXJuIChlbmRQb2ludFxuICAgICAgLnJlcGxhY2UoXCJ3czovL1wiLCBcImh0dHA6Ly9cIilcbiAgICAgIC5yZXBsYWNlKFwid3NzOi8vXCIsIFwiaHR0cHM6Ly9cIilcbiAgICAgIC5yZXBsYWNlKG5ldyBSZWdFeHAoXCIoLiopXFwvXCIgKyBUUkFOU1BPUlRTLndlYnNvY2tldCksIFwiJDEvXCIgKyBUUkFOU1BPUlRTLmxvbmdwb2xsKSlcbiAgfVxuXG4gIGVuZHBvaW50VVJMKCl7XG4gICAgcmV0dXJuIEFqYXguYXBwZW5kUGFyYW1zKHRoaXMucG9sbEVuZHBvaW50LCB7dG9rZW46IHRoaXMudG9rZW59KVxuICB9XG5cbiAgY2xvc2VBbmRSZXRyeShjb2RlLCByZWFzb24sIHdhc0NsZWFuKXtcbiAgICB0aGlzLmNsb3NlKGNvZGUsIHJlYXNvbiwgd2FzQ2xlYW4pXG4gICAgdGhpcy5yZWFkeVN0YXRlID0gU09DS0VUX1NUQVRFUy5jb25uZWN0aW5nXG4gIH1cblxuICBvbnRpbWVvdXQoKXtcbiAgICB0aGlzLm9uZXJyb3IoXCJ0aW1lb3V0XCIpXG4gICAgdGhpcy5jbG9zZUFuZFJldHJ5KDEwMDUsIFwidGltZW91dFwiLCBmYWxzZSlcbiAgfVxuXG4gIGlzQWN0aXZlKCl7IHJldHVybiB0aGlzLnJlYWR5U3RhdGUgPT09IFNPQ0tFVF9TVEFURVMub3BlbiB8fCB0aGlzLnJlYWR5U3RhdGUgPT09IFNPQ0tFVF9TVEFURVMuY29ubmVjdGluZyB9XG5cbiAgcG9sbCgpe1xuICAgIHRoaXMuYWpheChcIkdFVFwiLCBcImFwcGxpY2F0aW9uL2pzb25cIiwgbnVsbCwgKCkgPT4gdGhpcy5vbnRpbWVvdXQoKSwgcmVzcCA9PiB7XG4gICAgICBpZihyZXNwKXtcbiAgICAgICAgdmFyIHtzdGF0dXMsIHRva2VuLCBtZXNzYWdlc30gPSByZXNwXG4gICAgICAgIHRoaXMudG9rZW4gPSB0b2tlblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdHVzID0gMFxuICAgICAgfVxuXG4gICAgICBzd2l0Y2goc3RhdHVzKXtcbiAgICAgICAgY2FzZSAyMDA6XG4gICAgICAgICAgbWVzc2FnZXMuZm9yRWFjaChtc2cgPT4ge1xuICAgICAgICAgICAgLy8gVGFza3MgYXJlIHdoYXQgdGhpbmdzIGxpa2UgZXZlbnQgaGFuZGxlcnMsIHNldFRpbWVvdXQgY2FsbGJhY2tzLFxuICAgICAgICAgICAgLy8gcHJvbWlzZSByZXNvbHZlcyBhbmQgbW9yZSBhcmUgcnVuIHdpdGhpbi5cbiAgICAgICAgICAgIC8vIEluIG1vZGVybiBicm93c2VycywgdGhlcmUgYXJlIHR3byBkaWZmZXJlbnQga2luZHMgb2YgdGFza3MsXG4gICAgICAgICAgICAvLyBtaWNyb3Rhc2tzIGFuZCBtYWNyb3Rhc2tzLlxuICAgICAgICAgICAgLy8gTWljcm90YXNrcyBhcmUgbWFpbmx5IHVzZWQgZm9yIFByb21pc2VzLCB3aGlsZSBtYWNyb3Rhc2tzIGFyZVxuICAgICAgICAgICAgLy8gdXNlZCBmb3IgZXZlcnl0aGluZyBlbHNlLlxuICAgICAgICAgICAgLy8gTWljcm90YXNrcyBhbHdheXMgaGF2ZSBwcmlvcml0eSBvdmVyIG1hY3JvdGFza3MuIElmIHRoZSBKUyBlbmdpbmVcbiAgICAgICAgICAgIC8vIGlzIGxvb2tpbmcgZm9yIGEgdGFzayB0byBydW4sIGl0IHdpbGwgYWx3YXlzIHRyeSB0byBlbXB0eSB0aGVcbiAgICAgICAgICAgIC8vIG1pY3JvdGFzayBxdWV1ZSBiZWZvcmUgYXR0ZW1wdGluZyB0byBydW4gYW55dGhpbmcgZnJvbSB0aGVcbiAgICAgICAgICAgIC8vIG1hY3JvdGFzayBxdWV1ZS5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBGb3IgdGhlIFdlYlNvY2tldCB0cmFuc3BvcnQsIG1lc3NhZ2VzIGFsd2F5cyBhcnJpdmUgaW4gdGhlaXIgb3duXG4gICAgICAgICAgICAvLyBldmVudC4gVGhpcyBtZWFucyB0aGF0IGlmIGFueSBwcm9taXNlcyBhcmUgcmVzb2x2ZWQgZnJvbSB3aXRoaW4sXG4gICAgICAgICAgICAvLyB0aGVpciBjYWxsYmFja3Mgd2lsbCBhbHdheXMgZmluaXNoIGV4ZWN1dGlvbiBieSB0aGUgdGltZSB0aGVcbiAgICAgICAgICAgIC8vIG5leHQgbWVzc2FnZSBldmVudCBoYW5kbGVyIGlzIHJ1bi5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBJbiBvcmRlciB0byBlbXVsYXRlIHRoaXMgYmVoYXZpb3VyLCB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSBlYWNoXG4gICAgICAgICAgICAvLyBvbm1lc3NhZ2UgaGFuZGxlciBpcyBydW4gd2l0aGluIGl0cyBvd24gbWFjcm90YXNrLlxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLm9ubWVzc2FnZSh7ZGF0YTogbXNnfSksIDApXG4gICAgICAgICAgfSlcbiAgICAgICAgICB0aGlzLnBvbGwoKVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMjA0OlxuICAgICAgICAgIHRoaXMucG9sbCgpXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSA0MTA6XG4gICAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gU09DS0VUX1NUQVRFUy5vcGVuXG4gICAgICAgICAgdGhpcy5vbm9wZW4oe30pXG4gICAgICAgICAgdGhpcy5wb2xsKClcbiAgICAgICAgICBicmVha1xuICAgICAgICBjYXNlIDQwMzpcbiAgICAgICAgICB0aGlzLm9uZXJyb3IoNDAzKVxuICAgICAgICAgIHRoaXMuY2xvc2UoMTAwOCwgXCJmb3JiaWRkZW5cIiwgZmFsc2UpXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAwOlxuICAgICAgICBjYXNlIDUwMDpcbiAgICAgICAgICB0aGlzLm9uZXJyb3IoNTAwKVxuICAgICAgICAgIHRoaXMuY2xvc2VBbmRSZXRyeSgxMDExLCBcImludGVybmFsIHNlcnZlciBlcnJvclwiLCA1MDApXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKGB1bmhhbmRsZWQgcG9sbCBzdGF0dXMgJHtzdGF0dXN9YClcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLy8gd2UgY29sbGVjdCBhbGwgcHVzaGVzIHdpdGhpbiB0aGUgY3VycmVudCBldmVudCBsb29wIGJ5XG4gIC8vIHNldFRpbWVvdXQgMCwgd2hpY2ggb3B0aW1pemVzIGJhY2stdG8tYmFjayBwcm9jZWR1cmFsXG4gIC8vIHB1c2hlcyBhZ2FpbnN0IGFuIGVtcHR5IGJ1ZmZlclxuXG4gIHNlbmQoYm9keSl7XG4gICAgaWYodHlwZW9mKGJvZHkpICE9PSBcInN0cmluZ1wiKXsgYm9keSA9IGFycmF5QnVmZmVyVG9CYXNlNjQoYm9keSkgfVxuICAgIGlmKHRoaXMuY3VycmVudEJhdGNoKXtcbiAgICAgIHRoaXMuY3VycmVudEJhdGNoLnB1c2goYm9keSlcbiAgICB9IGVsc2UgaWYodGhpcy5hd2FpdGluZ0JhdGNoQWNrKXtcbiAgICAgIHRoaXMuYmF0Y2hCdWZmZXIucHVzaChib2R5KVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmN1cnJlbnRCYXRjaCA9IFtib2R5XVxuICAgICAgdGhpcy5jdXJyZW50QmF0Y2hUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmJhdGNoU2VuZCh0aGlzLmN1cnJlbnRCYXRjaClcbiAgICAgICAgdGhpcy5jdXJyZW50QmF0Y2ggPSBudWxsXG4gICAgICB9LCAwKVxuICAgIH1cbiAgfVxuXG4gIGJhdGNoU2VuZChtZXNzYWdlcyl7XG4gICAgdGhpcy5hd2FpdGluZ0JhdGNoQWNrID0gdHJ1ZVxuICAgIHRoaXMuYWpheChcIlBPU1RcIiwgXCJhcHBsaWNhdGlvbi94LW5kanNvblwiLCBtZXNzYWdlcy5qb2luKFwiXFxuXCIpLCAoKSA9PiB0aGlzLm9uZXJyb3IoXCJ0aW1lb3V0XCIpLCByZXNwID0+IHtcbiAgICAgIHRoaXMuYXdhaXRpbmdCYXRjaEFjayA9IGZhbHNlXG4gICAgICBpZighcmVzcCB8fCByZXNwLnN0YXR1cyAhPT0gMjAwKXtcbiAgICAgICAgdGhpcy5vbmVycm9yKHJlc3AgJiYgcmVzcC5zdGF0dXMpXG4gICAgICAgIHRoaXMuY2xvc2VBbmRSZXRyeSgxMDExLCBcImludGVybmFsIHNlcnZlciBlcnJvclwiLCBmYWxzZSlcbiAgICAgIH0gZWxzZSBpZih0aGlzLmJhdGNoQnVmZmVyLmxlbmd0aCA+IDApe1xuICAgICAgICB0aGlzLmJhdGNoU2VuZCh0aGlzLmJhdGNoQnVmZmVyKVxuICAgICAgICB0aGlzLmJhdGNoQnVmZmVyID0gW11cbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgY2xvc2UoY29kZSwgcmVhc29uLCB3YXNDbGVhbil7XG4gICAgZm9yKGxldCByZXEgb2YgdGhpcy5yZXFzKXsgcmVxLmFib3J0KCkgfVxuICAgIHRoaXMucmVhZHlTdGF0ZSA9IFNPQ0tFVF9TVEFURVMuY2xvc2VkXG4gICAgbGV0IG9wdHMgPSBPYmplY3QuYXNzaWduKHtjb2RlOiAxMDAwLCByZWFzb246IHVuZGVmaW5lZCwgd2FzQ2xlYW46IHRydWV9LCB7Y29kZSwgcmVhc29uLCB3YXNDbGVhbn0pXG4gICAgdGhpcy5iYXRjaEJ1ZmZlciA9IFtdXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuY3VycmVudEJhdGNoVGltZXIpXG4gICAgdGhpcy5jdXJyZW50QmF0Y2hUaW1lciA9IG51bGxcbiAgICBpZih0eXBlb2YoQ2xvc2VFdmVudCkgIT09IFwidW5kZWZpbmVkXCIpe1xuICAgICAgdGhpcy5vbmNsb3NlKG5ldyBDbG9zZUV2ZW50KFwiY2xvc2VcIiwgb3B0cykpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMub25jbG9zZShvcHRzKVxuICAgIH1cbiAgfVxuXG4gIGFqYXgobWV0aG9kLCBjb250ZW50VHlwZSwgYm9keSwgb25DYWxsZXJUaW1lb3V0LCBjYWxsYmFjayl7XG4gICAgbGV0IHJlcVxuICAgIGxldCBvbnRpbWVvdXQgPSAoKSA9PiB7XG4gICAgICB0aGlzLnJlcXMuZGVsZXRlKHJlcSlcbiAgICAgIG9uQ2FsbGVyVGltZW91dCgpXG4gICAgfVxuICAgIHJlcSA9IEFqYXgucmVxdWVzdChtZXRob2QsIHRoaXMuZW5kcG9pbnRVUkwoKSwgY29udGVudFR5cGUsIGJvZHksIHRoaXMudGltZW91dCwgb250aW1lb3V0LCByZXNwID0+IHtcbiAgICAgIHRoaXMucmVxcy5kZWxldGUocmVxKVxuICAgICAgaWYodGhpcy5pc0FjdGl2ZSgpKXsgY2FsbGJhY2socmVzcCkgfVxuICAgIH0pXG4gICAgdGhpcy5yZXFzLmFkZChyZXEpXG4gIH1cbn1cbiIsICIvKipcbiAqIEluaXRpYWxpemVzIHRoZSBQcmVzZW5jZVxuICogQHBhcmFtIHtDaGFubmVsfSBjaGFubmVsIC0gVGhlIENoYW5uZWxcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIC0gVGhlIG9wdGlvbnMsXG4gKiAgICAgICAgZm9yIGV4YW1wbGUgYHtldmVudHM6IHtzdGF0ZTogXCJzdGF0ZVwiLCBkaWZmOiBcImRpZmZcIn19YFxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQcmVzZW5jZSB7XG5cbiAgY29uc3RydWN0b3IoY2hhbm5lbCwgb3B0cyA9IHt9KXtcbiAgICBsZXQgZXZlbnRzID0gb3B0cy5ldmVudHMgfHwge3N0YXRlOiBcInByZXNlbmNlX3N0YXRlXCIsIGRpZmY6IFwicHJlc2VuY2VfZGlmZlwifVxuICAgIHRoaXMuc3RhdGUgPSB7fVxuICAgIHRoaXMucGVuZGluZ0RpZmZzID0gW11cbiAgICB0aGlzLmNoYW5uZWwgPSBjaGFubmVsXG4gICAgdGhpcy5qb2luUmVmID0gbnVsbFxuICAgIHRoaXMuY2FsbGVyID0ge1xuICAgICAgb25Kb2luOiBmdW5jdGlvbiAoKXsgfSxcbiAgICAgIG9uTGVhdmU6IGZ1bmN0aW9uICgpeyB9LFxuICAgICAgb25TeW5jOiBmdW5jdGlvbiAoKXsgfVxuICAgIH1cblxuICAgIHRoaXMuY2hhbm5lbC5vbihldmVudHMuc3RhdGUsIG5ld1N0YXRlID0+IHtcbiAgICAgIGxldCB7b25Kb2luLCBvbkxlYXZlLCBvblN5bmN9ID0gdGhpcy5jYWxsZXJcblxuICAgICAgdGhpcy5qb2luUmVmID0gdGhpcy5jaGFubmVsLmpvaW5SZWYoKVxuICAgICAgdGhpcy5zdGF0ZSA9IFByZXNlbmNlLnN5bmNTdGF0ZSh0aGlzLnN0YXRlLCBuZXdTdGF0ZSwgb25Kb2luLCBvbkxlYXZlKVxuXG4gICAgICB0aGlzLnBlbmRpbmdEaWZmcy5mb3JFYWNoKGRpZmYgPT4ge1xuICAgICAgICB0aGlzLnN0YXRlID0gUHJlc2VuY2Uuc3luY0RpZmYodGhpcy5zdGF0ZSwgZGlmZiwgb25Kb2luLCBvbkxlYXZlKVxuICAgICAgfSlcbiAgICAgIHRoaXMucGVuZGluZ0RpZmZzID0gW11cbiAgICAgIG9uU3luYygpXG4gICAgfSlcblxuICAgIHRoaXMuY2hhbm5lbC5vbihldmVudHMuZGlmZiwgZGlmZiA9PiB7XG4gICAgICBsZXQge29uSm9pbiwgb25MZWF2ZSwgb25TeW5jfSA9IHRoaXMuY2FsbGVyXG5cbiAgICAgIGlmKHRoaXMuaW5QZW5kaW5nU3luY1N0YXRlKCkpe1xuICAgICAgICB0aGlzLnBlbmRpbmdEaWZmcy5wdXNoKGRpZmYpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnN0YXRlID0gUHJlc2VuY2Uuc3luY0RpZmYodGhpcy5zdGF0ZSwgZGlmZiwgb25Kb2luLCBvbkxlYXZlKVxuICAgICAgICBvblN5bmMoKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBvbkpvaW4oY2FsbGJhY2speyB0aGlzLmNhbGxlci5vbkpvaW4gPSBjYWxsYmFjayB9XG5cbiAgb25MZWF2ZShjYWxsYmFjayl7IHRoaXMuY2FsbGVyLm9uTGVhdmUgPSBjYWxsYmFjayB9XG5cbiAgb25TeW5jKGNhbGxiYWNrKXsgdGhpcy5jYWxsZXIub25TeW5jID0gY2FsbGJhY2sgfVxuXG4gIGxpc3QoYnkpeyByZXR1cm4gUHJlc2VuY2UubGlzdCh0aGlzLnN0YXRlLCBieSkgfVxuXG4gIGluUGVuZGluZ1N5bmNTdGF0ZSgpe1xuICAgIHJldHVybiAhdGhpcy5qb2luUmVmIHx8ICh0aGlzLmpvaW5SZWYgIT09IHRoaXMuY2hhbm5lbC5qb2luUmVmKCkpXG4gIH1cblxuICAvLyBsb3dlci1sZXZlbCBwdWJsaWMgc3RhdGljIEFQSVxuXG4gIC8qKlxuICAgKiBVc2VkIHRvIHN5bmMgdGhlIGxpc3Qgb2YgcHJlc2VuY2VzIG9uIHRoZSBzZXJ2ZXJcbiAgICogd2l0aCB0aGUgY2xpZW50J3Mgc3RhdGUuIEFuIG9wdGlvbmFsIGBvbkpvaW5gIGFuZCBgb25MZWF2ZWAgY2FsbGJhY2sgY2FuXG4gICAqIGJlIHByb3ZpZGVkIHRvIHJlYWN0IHRvIGNoYW5nZXMgaW4gdGhlIGNsaWVudCdzIGxvY2FsIHByZXNlbmNlcyBhY3Jvc3NcbiAgICogZGlzY29ubmVjdHMgYW5kIHJlY29ubmVjdHMgd2l0aCB0aGUgc2VydmVyLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJlc2VuY2V9XG4gICAqL1xuICBzdGF0aWMgc3luY1N0YXRlKGN1cnJlbnRTdGF0ZSwgbmV3U3RhdGUsIG9uSm9pbiwgb25MZWF2ZSl7XG4gICAgbGV0IHN0YXRlID0gdGhpcy5jbG9uZShjdXJyZW50U3RhdGUpXG4gICAgbGV0IGpvaW5zID0ge31cbiAgICBsZXQgbGVhdmVzID0ge31cblxuICAgIHRoaXMubWFwKHN0YXRlLCAoa2V5LCBwcmVzZW5jZSkgPT4ge1xuICAgICAgaWYoIW5ld1N0YXRlW2tleV0pe1xuICAgICAgICBsZWF2ZXNba2V5XSA9IHByZXNlbmNlXG4gICAgICB9XG4gICAgfSlcbiAgICB0aGlzLm1hcChuZXdTdGF0ZSwgKGtleSwgbmV3UHJlc2VuY2UpID0+IHtcbiAgICAgIGxldCBjdXJyZW50UHJlc2VuY2UgPSBzdGF0ZVtrZXldXG4gICAgICBpZihjdXJyZW50UHJlc2VuY2Upe1xuICAgICAgICBsZXQgbmV3UmVmcyA9IG5ld1ByZXNlbmNlLm1ldGFzLm1hcChtID0+IG0ucGh4X3JlZilcbiAgICAgICAgbGV0IGN1clJlZnMgPSBjdXJyZW50UHJlc2VuY2UubWV0YXMubWFwKG0gPT4gbS5waHhfcmVmKVxuICAgICAgICBsZXQgam9pbmVkTWV0YXMgPSBuZXdQcmVzZW5jZS5tZXRhcy5maWx0ZXIobSA9PiBjdXJSZWZzLmluZGV4T2YobS5waHhfcmVmKSA8IDApXG4gICAgICAgIGxldCBsZWZ0TWV0YXMgPSBjdXJyZW50UHJlc2VuY2UubWV0YXMuZmlsdGVyKG0gPT4gbmV3UmVmcy5pbmRleE9mKG0ucGh4X3JlZikgPCAwKVxuICAgICAgICBpZihqb2luZWRNZXRhcy5sZW5ndGggPiAwKXtcbiAgICAgICAgICBqb2luc1trZXldID0gbmV3UHJlc2VuY2VcbiAgICAgICAgICBqb2luc1trZXldLm1ldGFzID0gam9pbmVkTWV0YXNcbiAgICAgICAgfVxuICAgICAgICBpZihsZWZ0TWV0YXMubGVuZ3RoID4gMCl7XG4gICAgICAgICAgbGVhdmVzW2tleV0gPSB0aGlzLmNsb25lKGN1cnJlbnRQcmVzZW5jZSlcbiAgICAgICAgICBsZWF2ZXNba2V5XS5tZXRhcyA9IGxlZnRNZXRhc1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBqb2luc1trZXldID0gbmV3UHJlc2VuY2VcbiAgICAgIH1cbiAgICB9KVxuICAgIHJldHVybiB0aGlzLnN5bmNEaWZmKHN0YXRlLCB7am9pbnM6IGpvaW5zLCBsZWF2ZXM6IGxlYXZlc30sIG9uSm9pbiwgb25MZWF2ZSlcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBVc2VkIHRvIHN5bmMgYSBkaWZmIG9mIHByZXNlbmNlIGpvaW4gYW5kIGxlYXZlXG4gICAqIGV2ZW50cyBmcm9tIHRoZSBzZXJ2ZXIsIGFzIHRoZXkgaGFwcGVuLiBMaWtlIGBzeW5jU3RhdGVgLCBgc3luY0RpZmZgXG4gICAqIGFjY2VwdHMgb3B0aW9uYWwgYG9uSm9pbmAgYW5kIGBvbkxlYXZlYCBjYWxsYmFja3MgdG8gcmVhY3QgdG8gYSB1c2VyXG4gICAqIGpvaW5pbmcgb3IgbGVhdmluZyBmcm9tIGEgZGV2aWNlLlxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJlc2VuY2V9XG4gICAqL1xuICBzdGF0aWMgc3luY0RpZmYoc3RhdGUsIGRpZmYsIG9uSm9pbiwgb25MZWF2ZSl7XG4gICAgbGV0IHtqb2lucywgbGVhdmVzfSA9IHRoaXMuY2xvbmUoZGlmZilcbiAgICBpZighb25Kb2luKXsgb25Kb2luID0gZnVuY3Rpb24gKCl7IH0gfVxuICAgIGlmKCFvbkxlYXZlKXsgb25MZWF2ZSA9IGZ1bmN0aW9uICgpeyB9IH1cblxuICAgIHRoaXMubWFwKGpvaW5zLCAoa2V5LCBuZXdQcmVzZW5jZSkgPT4ge1xuICAgICAgbGV0IGN1cnJlbnRQcmVzZW5jZSA9IHN0YXRlW2tleV1cbiAgICAgIHN0YXRlW2tleV0gPSB0aGlzLmNsb25lKG5ld1ByZXNlbmNlKVxuICAgICAgaWYoY3VycmVudFByZXNlbmNlKXtcbiAgICAgICAgbGV0IGpvaW5lZFJlZnMgPSBzdGF0ZVtrZXldLm1ldGFzLm1hcChtID0+IG0ucGh4X3JlZilcbiAgICAgICAgbGV0IGN1ck1ldGFzID0gY3VycmVudFByZXNlbmNlLm1ldGFzLmZpbHRlcihtID0+IGpvaW5lZFJlZnMuaW5kZXhPZihtLnBoeF9yZWYpIDwgMClcbiAgICAgICAgc3RhdGVba2V5XS5tZXRhcy51bnNoaWZ0KC4uLmN1ck1ldGFzKVxuICAgICAgfVxuICAgICAgb25Kb2luKGtleSwgY3VycmVudFByZXNlbmNlLCBuZXdQcmVzZW5jZSlcbiAgICB9KVxuICAgIHRoaXMubWFwKGxlYXZlcywgKGtleSwgbGVmdFByZXNlbmNlKSA9PiB7XG4gICAgICBsZXQgY3VycmVudFByZXNlbmNlID0gc3RhdGVba2V5XVxuICAgICAgaWYoIWN1cnJlbnRQcmVzZW5jZSl7IHJldHVybiB9XG4gICAgICBsZXQgcmVmc1RvUmVtb3ZlID0gbGVmdFByZXNlbmNlLm1ldGFzLm1hcChtID0+IG0ucGh4X3JlZilcbiAgICAgIGN1cnJlbnRQcmVzZW5jZS5tZXRhcyA9IGN1cnJlbnRQcmVzZW5jZS5tZXRhcy5maWx0ZXIocCA9PiB7XG4gICAgICAgIHJldHVybiByZWZzVG9SZW1vdmUuaW5kZXhPZihwLnBoeF9yZWYpIDwgMFxuICAgICAgfSlcbiAgICAgIG9uTGVhdmUoa2V5LCBjdXJyZW50UHJlc2VuY2UsIGxlZnRQcmVzZW5jZSlcbiAgICAgIGlmKGN1cnJlbnRQcmVzZW5jZS5tZXRhcy5sZW5ndGggPT09IDApe1xuICAgICAgICBkZWxldGUgc3RhdGVba2V5XVxuICAgICAgfVxuICAgIH0pXG4gICAgcmV0dXJuIHN0YXRlXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJlc2VuY2VzLCB3aXRoIHNlbGVjdGVkIG1ldGFkYXRhLlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcHJlc2VuY2VzXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNob29zZXJcbiAgICpcbiAgICogQHJldHVybnMge1ByZXNlbmNlfVxuICAgKi9cbiAgc3RhdGljIGxpc3QocHJlc2VuY2VzLCBjaG9vc2VyKXtcbiAgICBpZighY2hvb3Nlcil7IGNob29zZXIgPSBmdW5jdGlvbiAoa2V5LCBwcmVzKXsgcmV0dXJuIHByZXMgfSB9XG5cbiAgICByZXR1cm4gdGhpcy5tYXAocHJlc2VuY2VzLCAoa2V5LCBwcmVzZW5jZSkgPT4ge1xuICAgICAgcmV0dXJuIGNob29zZXIoa2V5LCBwcmVzZW5jZSlcbiAgICB9KVxuICB9XG5cbiAgLy8gcHJpdmF0ZVxuXG4gIHN0YXRpYyBtYXAob2JqLCBmdW5jKXtcbiAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMob2JqKS5tYXAoa2V5ID0+IGZ1bmMoa2V5LCBvYmpba2V5XSkpXG4gIH1cblxuICBzdGF0aWMgY2xvbmUob2JqKXsgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkob2JqKSkgfVxufVxuIiwgIi8qIFRoZSBkZWZhdWx0IHNlcmlhbGl6ZXIgZm9yIGVuY29kaW5nIGFuZCBkZWNvZGluZyBtZXNzYWdlcyAqL1xuaW1wb3J0IHtcbiAgQ0hBTk5FTF9FVkVOVFNcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCJcblxuZXhwb3J0IGRlZmF1bHQge1xuICBIRUFERVJfTEVOR1RIOiAxLFxuICBNRVRBX0xFTkdUSDogNCxcbiAgS0lORFM6IHtwdXNoOiAwLCByZXBseTogMSwgYnJvYWRjYXN0OiAyfSxcblxuICBlbmNvZGUobXNnLCBjYWxsYmFjayl7XG4gICAgaWYobXNnLnBheWxvYWQuY29uc3RydWN0b3IgPT09IEFycmF5QnVmZmVyKXtcbiAgICAgIHJldHVybiBjYWxsYmFjayh0aGlzLmJpbmFyeUVuY29kZShtc2cpKVxuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgcGF5bG9hZCA9IFttc2cuam9pbl9yZWYsIG1zZy5yZWYsIG1zZy50b3BpYywgbXNnLmV2ZW50LCBtc2cucGF5bG9hZF1cbiAgICAgIHJldHVybiBjYWxsYmFjayhKU09OLnN0cmluZ2lmeShwYXlsb2FkKSlcbiAgICB9XG4gIH0sXG5cbiAgZGVjb2RlKHJhd1BheWxvYWQsIGNhbGxiYWNrKXtcbiAgICBpZihyYXdQYXlsb2FkLmNvbnN0cnVjdG9yID09PSBBcnJheUJ1ZmZlcil7XG4gICAgICByZXR1cm4gY2FsbGJhY2sodGhpcy5iaW5hcnlEZWNvZGUocmF3UGF5bG9hZCkpXG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBbam9pbl9yZWYsIHJlZiwgdG9waWMsIGV2ZW50LCBwYXlsb2FkXSA9IEpTT04ucGFyc2UocmF3UGF5bG9hZClcbiAgICAgIHJldHVybiBjYWxsYmFjayh7am9pbl9yZWYsIHJlZiwgdG9waWMsIGV2ZW50LCBwYXlsb2FkfSlcbiAgICB9XG4gIH0sXG5cbiAgLy8gcHJpdmF0ZVxuXG4gIGJpbmFyeUVuY29kZShtZXNzYWdlKXtcbiAgICBsZXQge2pvaW5fcmVmLCByZWYsIGV2ZW50LCB0b3BpYywgcGF5bG9hZH0gPSBtZXNzYWdlXG4gICAgbGV0IG1ldGFMZW5ndGggPSB0aGlzLk1FVEFfTEVOR1RIICsgam9pbl9yZWYubGVuZ3RoICsgcmVmLmxlbmd0aCArIHRvcGljLmxlbmd0aCArIGV2ZW50Lmxlbmd0aFxuICAgIGxldCBoZWFkZXIgPSBuZXcgQXJyYXlCdWZmZXIodGhpcy5IRUFERVJfTEVOR1RIICsgbWV0YUxlbmd0aClcbiAgICBsZXQgdmlldyA9IG5ldyBEYXRhVmlldyhoZWFkZXIpXG4gICAgbGV0IG9mZnNldCA9IDBcblxuICAgIHZpZXcuc2V0VWludDgob2Zmc2V0KyssIHRoaXMuS0lORFMucHVzaCkgLy8ga2luZFxuICAgIHZpZXcuc2V0VWludDgob2Zmc2V0KyssIGpvaW5fcmVmLmxlbmd0aClcbiAgICB2aWV3LnNldFVpbnQ4KG9mZnNldCsrLCByZWYubGVuZ3RoKVxuICAgIHZpZXcuc2V0VWludDgob2Zmc2V0KyssIHRvcGljLmxlbmd0aClcbiAgICB2aWV3LnNldFVpbnQ4KG9mZnNldCsrLCBldmVudC5sZW5ndGgpXG4gICAgQXJyYXkuZnJvbShqb2luX3JlZiwgY2hhciA9PiB2aWV3LnNldFVpbnQ4KG9mZnNldCsrLCBjaGFyLmNoYXJDb2RlQXQoMCkpKVxuICAgIEFycmF5LmZyb20ocmVmLCBjaGFyID0+IHZpZXcuc2V0VWludDgob2Zmc2V0KyssIGNoYXIuY2hhckNvZGVBdCgwKSkpXG4gICAgQXJyYXkuZnJvbSh0b3BpYywgY2hhciA9PiB2aWV3LnNldFVpbnQ4KG9mZnNldCsrLCBjaGFyLmNoYXJDb2RlQXQoMCkpKVxuICAgIEFycmF5LmZyb20oZXZlbnQsIGNoYXIgPT4gdmlldy5zZXRVaW50OChvZmZzZXQrKywgY2hhci5jaGFyQ29kZUF0KDApKSlcblxuICAgIHZhciBjb21iaW5lZCA9IG5ldyBVaW50OEFycmF5KGhlYWRlci5ieXRlTGVuZ3RoICsgcGF5bG9hZC5ieXRlTGVuZ3RoKVxuICAgIGNvbWJpbmVkLnNldChuZXcgVWludDhBcnJheShoZWFkZXIpLCAwKVxuICAgIGNvbWJpbmVkLnNldChuZXcgVWludDhBcnJheShwYXlsb2FkKSwgaGVhZGVyLmJ5dGVMZW5ndGgpXG5cbiAgICByZXR1cm4gY29tYmluZWQuYnVmZmVyXG4gIH0sXG5cbiAgYmluYXJ5RGVjb2RlKGJ1ZmZlcil7XG4gICAgbGV0IHZpZXcgPSBuZXcgRGF0YVZpZXcoYnVmZmVyKVxuICAgIGxldCBraW5kID0gdmlldy5nZXRVaW50OCgwKVxuICAgIGxldCBkZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKClcbiAgICBzd2l0Y2goa2luZCl7XG4gICAgICBjYXNlIHRoaXMuS0lORFMucHVzaDogcmV0dXJuIHRoaXMuZGVjb2RlUHVzaChidWZmZXIsIHZpZXcsIGRlY29kZXIpXG4gICAgICBjYXNlIHRoaXMuS0lORFMucmVwbHk6IHJldHVybiB0aGlzLmRlY29kZVJlcGx5KGJ1ZmZlciwgdmlldywgZGVjb2RlcilcbiAgICAgIGNhc2UgdGhpcy5LSU5EUy5icm9hZGNhc3Q6IHJldHVybiB0aGlzLmRlY29kZUJyb2FkY2FzdChidWZmZXIsIHZpZXcsIGRlY29kZXIpXG4gICAgfVxuICB9LFxuXG4gIGRlY29kZVB1c2goYnVmZmVyLCB2aWV3LCBkZWNvZGVyKXtcbiAgICBsZXQgam9pblJlZlNpemUgPSB2aWV3LmdldFVpbnQ4KDEpXG4gICAgbGV0IHRvcGljU2l6ZSA9IHZpZXcuZ2V0VWludDgoMilcbiAgICBsZXQgZXZlbnRTaXplID0gdmlldy5nZXRVaW50OCgzKVxuICAgIGxldCBvZmZzZXQgPSB0aGlzLkhFQURFUl9MRU5HVEggKyB0aGlzLk1FVEFfTEVOR1RIIC0gMSAvLyBwdXNoZXMgaGF2ZSBubyByZWZcbiAgICBsZXQgam9pblJlZiA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIGpvaW5SZWZTaXplKSlcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyBqb2luUmVmU2l6ZVxuICAgIGxldCB0b3BpYyA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIHRvcGljU2l6ZSkpXG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgdG9waWNTaXplXG4gICAgbGV0IGV2ZW50ID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgZXZlbnRTaXplKSlcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyBldmVudFNpemVcbiAgICBsZXQgZGF0YSA9IGJ1ZmZlci5zbGljZShvZmZzZXQsIGJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgIHJldHVybiB7am9pbl9yZWY6IGpvaW5SZWYsIHJlZjogbnVsbCwgdG9waWM6IHRvcGljLCBldmVudDogZXZlbnQsIHBheWxvYWQ6IGRhdGF9XG4gIH0sXG5cbiAgZGVjb2RlUmVwbHkoYnVmZmVyLCB2aWV3LCBkZWNvZGVyKXtcbiAgICBsZXQgam9pblJlZlNpemUgPSB2aWV3LmdldFVpbnQ4KDEpXG4gICAgbGV0IHJlZlNpemUgPSB2aWV3LmdldFVpbnQ4KDIpXG4gICAgbGV0IHRvcGljU2l6ZSA9IHZpZXcuZ2V0VWludDgoMylcbiAgICBsZXQgZXZlbnRTaXplID0gdmlldy5nZXRVaW50OCg0KVxuICAgIGxldCBvZmZzZXQgPSB0aGlzLkhFQURFUl9MRU5HVEggKyB0aGlzLk1FVEFfTEVOR1RIXG4gICAgbGV0IGpvaW5SZWYgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBqb2luUmVmU2l6ZSkpXG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgam9pblJlZlNpemVcbiAgICBsZXQgcmVmID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgcmVmU2l6ZSkpXG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgcmVmU2l6ZVxuICAgIGxldCB0b3BpYyA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIHRvcGljU2l6ZSkpXG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgdG9waWNTaXplXG4gICAgbGV0IGV2ZW50ID0gZGVjb2Rlci5kZWNvZGUoYnVmZmVyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgZXZlbnRTaXplKSlcbiAgICBvZmZzZXQgPSBvZmZzZXQgKyBldmVudFNpemVcbiAgICBsZXQgZGF0YSA9IGJ1ZmZlci5zbGljZShvZmZzZXQsIGJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgIGxldCBwYXlsb2FkID0ge3N0YXR1czogZXZlbnQsIHJlc3BvbnNlOiBkYXRhfVxuICAgIHJldHVybiB7am9pbl9yZWY6IGpvaW5SZWYsIHJlZjogcmVmLCB0b3BpYzogdG9waWMsIGV2ZW50OiBDSEFOTkVMX0VWRU5UUy5yZXBseSwgcGF5bG9hZDogcGF5bG9hZH1cbiAgfSxcblxuICBkZWNvZGVCcm9hZGNhc3QoYnVmZmVyLCB2aWV3LCBkZWNvZGVyKXtcbiAgICBsZXQgdG9waWNTaXplID0gdmlldy5nZXRVaW50OCgxKVxuICAgIGxldCBldmVudFNpemUgPSB2aWV3LmdldFVpbnQ4KDIpXG4gICAgbGV0IG9mZnNldCA9IHRoaXMuSEVBREVSX0xFTkdUSCArIDJcbiAgICBsZXQgdG9waWMgPSBkZWNvZGVyLmRlY29kZShidWZmZXIuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyB0b3BpY1NpemUpKVxuICAgIG9mZnNldCA9IG9mZnNldCArIHRvcGljU2l6ZVxuICAgIGxldCBldmVudCA9IGRlY29kZXIuZGVjb2RlKGJ1ZmZlci5zbGljZShvZmZzZXQsIG9mZnNldCArIGV2ZW50U2l6ZSkpXG4gICAgb2Zmc2V0ID0gb2Zmc2V0ICsgZXZlbnRTaXplXG4gICAgbGV0IGRhdGEgPSBidWZmZXIuc2xpY2Uob2Zmc2V0LCBidWZmZXIuYnl0ZUxlbmd0aClcblxuICAgIHJldHVybiB7am9pbl9yZWY6IG51bGwsIHJlZjogbnVsbCwgdG9waWM6IHRvcGljLCBldmVudDogZXZlbnQsIHBheWxvYWQ6IGRhdGF9XG4gIH1cbn1cbiIsICJpbXBvcnQge1xuICBnbG9iYWwsXG4gIHBoeFdpbmRvdyxcbiAgQ0hBTk5FTF9FVkVOVFMsXG4gIERFRkFVTFRfVElNRU9VVCxcbiAgREVGQVVMVF9WU04sXG4gIFNPQ0tFVF9TVEFURVMsXG4gIFRSQU5TUE9SVFMsXG4gIFdTX0NMT1NFX05PUk1BTFxufSBmcm9tIFwiLi9jb25zdGFudHNcIlxuXG5pbXBvcnQge1xuICBjbG9zdXJlXG59IGZyb20gXCIuL3V0aWxzXCJcblxuaW1wb3J0IEFqYXggZnJvbSBcIi4vYWpheFwiXG5pbXBvcnQgQ2hhbm5lbCBmcm9tIFwiLi9jaGFubmVsXCJcbmltcG9ydCBMb25nUG9sbCBmcm9tIFwiLi9sb25ncG9sbFwiXG5pbXBvcnQgU2VyaWFsaXplciBmcm9tIFwiLi9zZXJpYWxpemVyXCJcbmltcG9ydCBUaW1lciBmcm9tIFwiLi90aW1lclwiXG5cbi8qKiBJbml0aWFsaXplcyB0aGUgU29ja2V0ICpcbiAqXG4gKiBGb3IgSUU4IHN1cHBvcnQgdXNlIGFuIEVTNS1zaGltIChodHRwczovL2dpdGh1Yi5jb20vZXMtc2hpbXMvZXM1LXNoaW0pXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGVuZFBvaW50IC0gVGhlIHN0cmluZyBXZWJTb2NrZXQgZW5kcG9pbnQsIGllLCBgXCJ3czovL2V4YW1wbGUuY29tL3NvY2tldFwiYCxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgXCJ3c3M6Ly9leGFtcGxlLmNvbVwiYFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBcIi9zb2NrZXRcImAgKGluaGVyaXRlZCBob3N0ICYgcHJvdG9jb2wpXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdHNdIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdHMudHJhbnNwb3J0XSAtIFRoZSBXZWJzb2NrZXQgVHJhbnNwb3J0LCBmb3IgZXhhbXBsZSBXZWJTb2NrZXQgb3IgUGhvZW5peC5Mb25nUG9sbC5cbiAqXG4gKiBEZWZhdWx0cyB0byBXZWJTb2NrZXQgd2l0aCBhdXRvbWF0aWMgTG9uZ1BvbGwgZmFsbGJhY2sgaWYgV2ViU29ja2V0IGlzIG5vdCBkZWZpbmVkLlxuICogVG8gZmFsbGJhY2sgdG8gTG9uZ1BvbGwgd2hlbiBXZWJTb2NrZXQgYXR0ZW1wdHMgZmFpbCwgdXNlIGBsb25nUG9sbEZhbGxiYWNrTXM6IDI1MDBgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRzLmxvbmdQb2xsRmFsbGJhY2tNc10gLSBUaGUgbWlsbGlzZWNvbmQgdGltZSB0byBhdHRlbXB0IHRoZSBwcmltYXJ5IHRyYW5zcG9ydFxuICogYmVmb3JlIGZhbGxpbmcgYmFjayB0byB0aGUgTG9uZ1BvbGwgdHJhbnNwb3J0LiBEaXNhYmxlZCBieSBkZWZhdWx0LlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRzLmRlYnVnXSAtIFdoZW4gdHJ1ZSwgZW5hYmxlcyBkZWJ1ZyBsb2dnaW5nLiBEZWZhdWx0IGZhbHNlLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRzLmVuY29kZV0gLSBUaGUgZnVuY3Rpb24gdG8gZW5jb2RlIG91dGdvaW5nIG1lc3NhZ2VzLlxuICpcbiAqIERlZmF1bHRzIHRvIEpTT04gZW5jb2Rlci5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0cy5kZWNvZGVdIC0gVGhlIGZ1bmN0aW9uIHRvIGRlY29kZSBpbmNvbWluZyBtZXNzYWdlcy5cbiAqXG4gKiBEZWZhdWx0cyB0byBKU09OOlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIChwYXlsb2FkLCBjYWxsYmFjaykgPT4gY2FsbGJhY2soSlNPTi5wYXJzZShwYXlsb2FkKSlcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0cy50aW1lb3V0XSAtIFRoZSBkZWZhdWx0IHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIHRvIHRyaWdnZXIgcHVzaCB0aW1lb3V0cy5cbiAqXG4gKiBEZWZhdWx0cyBgREVGQVVMVF9USU1FT1VUYFxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmhlYXJ0YmVhdEludGVydmFsTXNdIC0gVGhlIG1pbGxpc2VjIGludGVydmFsIHRvIHNlbmQgYSBoZWFydGJlYXQgbWVzc2FnZVxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnJlY29ubmVjdEFmdGVyTXNdIC0gVGhlIG9wdGlvbmFsIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgbWlsbGlzZWNcbiAqIHNvY2tldCByZWNvbm5lY3QgaW50ZXJ2YWwuXG4gKlxuICogRGVmYXVsdHMgdG8gc3RlcHBlZCBiYWNrb2ZmIG9mOlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIGZ1bmN0aW9uKHRyaWVzKXtcbiAqICAgcmV0dXJuIFsxMCwgNTAsIDEwMCwgMTUwLCAyMDAsIDI1MCwgNTAwLCAxMDAwLCAyMDAwXVt0cmllcyAtIDFdIHx8IDUwMDBcbiAqIH1cbiAqIGBgYGBcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdHMucmVqb2luQWZ0ZXJNc10gLSBUaGUgb3B0aW9uYWwgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBtaWxsaXNlY1xuICogcmVqb2luIGludGVydmFsIGZvciBpbmRpdmlkdWFsIGNoYW5uZWxzLlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIGZ1bmN0aW9uKHRyaWVzKXtcbiAqICAgcmV0dXJuIFsxMDAwLCAyMDAwLCA1MDAwXVt0cmllcyAtIDFdIHx8IDEwMDAwXG4gKiB9XG4gKiBgYGBgXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdHMubG9nZ2VyXSAtIFRoZSBvcHRpb25hbCBmdW5jdGlvbiBmb3Igc3BlY2lhbGl6ZWQgbG9nZ2luZywgaWU6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogZnVuY3Rpb24oa2luZCwgbXNnLCBkYXRhKSB7XG4gKiAgIGNvbnNvbGUubG9nKGAke2tpbmR9OiAke21zZ31gLCBkYXRhKVxuICogfVxuICogYGBgXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLmxvbmdwb2xsZXJUaW1lb3V0XSAtIFRoZSBtYXhpbXVtIHRpbWVvdXQgb2YgYSBsb25nIHBvbGwgQUpBWCByZXF1ZXN0LlxuICpcbiAqIERlZmF1bHRzIHRvIDIwcyAoZG91YmxlIHRoZSBzZXJ2ZXIgbG9uZyBwb2xsIHRpbWVyKS5cbiAqXG4gKiBAcGFyYW0geyhPYmplY3R8ZnVuY3Rpb24pfSBbb3B0cy5wYXJhbXNdIC0gVGhlIG9wdGlvbmFsIHBhcmFtcyB0byBwYXNzIHdoZW4gY29ubmVjdGluZ1xuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmJpbmFyeVR5cGVdIC0gVGhlIGJpbmFyeSB0eXBlIHRvIHVzZSBmb3IgYmluYXJ5IFdlYlNvY2tldCBmcmFtZXMuXG4gKlxuICogRGVmYXVsdHMgdG8gXCJhcnJheWJ1ZmZlclwiXG4gKlxuICogQHBhcmFtIHt2c259IFtvcHRzLnZzbl0gLSBUaGUgc2VyaWFsaXplcidzIHByb3RvY29sIHZlcnNpb24gdG8gc2VuZCBvbiBjb25uZWN0LlxuICpcbiAqIERlZmF1bHRzIHRvIERFRkFVTFRfVlNOLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0cy5zZXNzaW9uU3RvcmFnZV0gLSBBbiBvcHRpb25hbCBTdG9yYWdlIGNvbXBhdGlibGUgb2JqZWN0XG4gKiBQaG9lbml4IHVzZXMgc2Vzc2lvblN0b3JhZ2UgZm9yIGxvbmdwb2xsIGZhbGxiYWNrIGhpc3RvcnkuIE92ZXJyaWRpbmcgdGhlIHN0b3JlIGlzXG4gKiB1c2VmdWwgd2hlbiBQaG9lbml4IHdvbid0IGhhdmUgYWNjZXNzIHRvIGBzZXNzaW9uU3RvcmFnZWAuIEZvciBleGFtcGxlLCBUaGlzIGNvdWxkXG4gKiBoYXBwZW4gaWYgYSBzaXRlIGxvYWRzIGEgY3Jvc3MtZG9tYWluIGNoYW5uZWwgaW4gYW4gaWZyYW1lLiBFeGFtcGxlIHVzYWdlOlxuICpcbiAqICAgICBjbGFzcyBJbk1lbW9yeVN0b3JhZ2Uge1xuICogICAgICAgY29uc3RydWN0b3IoKSB7IHRoaXMuc3RvcmFnZSA9IHt9IH1cbiAqICAgICAgIGdldEl0ZW0oa2V5TmFtZSkgeyByZXR1cm4gdGhpcy5zdG9yYWdlW2tleU5hbWVdIHx8IG51bGwgfVxuICogICAgICAgcmVtb3ZlSXRlbShrZXlOYW1lKSB7IGRlbGV0ZSB0aGlzLnN0b3JhZ2Vba2V5TmFtZV0gfVxuICogICAgICAgc2V0SXRlbShrZXlOYW1lLCBrZXlWYWx1ZSkgeyB0aGlzLnN0b3JhZ2Vba2V5TmFtZV0gPSBrZXlWYWx1ZSB9XG4gKiAgICAgfVxuICpcbiovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTb2NrZXQge1xuICBjb25zdHJ1Y3RvcihlbmRQb2ludCwgb3B0cyA9IHt9KXtcbiAgICB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzID0ge29wZW46IFtdLCBjbG9zZTogW10sIGVycm9yOiBbXSwgbWVzc2FnZTogW119XG4gICAgdGhpcy5jaGFubmVscyA9IFtdXG4gICAgdGhpcy5zZW5kQnVmZmVyID0gW11cbiAgICB0aGlzLnJlZiA9IDBcbiAgICB0aGlzLnRpbWVvdXQgPSBvcHRzLnRpbWVvdXQgfHwgREVGQVVMVF9USU1FT1VUXG4gICAgdGhpcy50cmFuc3BvcnQgPSBvcHRzLnRyYW5zcG9ydCB8fCBnbG9iYWwuV2ViU29ja2V0IHx8IExvbmdQb2xsXG4gICAgdGhpcy5wcmltYXJ5UGFzc2VkSGVhbHRoQ2hlY2sgPSBmYWxzZVxuICAgIHRoaXMubG9uZ1BvbGxGYWxsYmFja01zID0gb3B0cy5sb25nUG9sbEZhbGxiYWNrTXNcbiAgICB0aGlzLmZhbGxiYWNrVGltZXIgPSBudWxsXG4gICAgdGhpcy5zZXNzaW9uU3RvcmUgPSBvcHRzLnNlc3Npb25TdG9yYWdlIHx8IChnbG9iYWwgJiYgZ2xvYmFsLnNlc3Npb25TdG9yYWdlKVxuICAgIHRoaXMuZXN0YWJsaXNoZWRDb25uZWN0aW9ucyA9IDBcbiAgICB0aGlzLmRlZmF1bHRFbmNvZGVyID0gU2VyaWFsaXplci5lbmNvZGUuYmluZChTZXJpYWxpemVyKVxuICAgIHRoaXMuZGVmYXVsdERlY29kZXIgPSBTZXJpYWxpemVyLmRlY29kZS5iaW5kKFNlcmlhbGl6ZXIpXG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gZmFsc2VcbiAgICB0aGlzLmJpbmFyeVR5cGUgPSBvcHRzLmJpbmFyeVR5cGUgfHwgXCJhcnJheWJ1ZmZlclwiXG4gICAgdGhpcy5jb25uZWN0Q2xvY2sgPSAxXG4gICAgaWYodGhpcy50cmFuc3BvcnQgIT09IExvbmdQb2xsKXtcbiAgICAgIHRoaXMuZW5jb2RlID0gb3B0cy5lbmNvZGUgfHwgdGhpcy5kZWZhdWx0RW5jb2RlclxuICAgICAgdGhpcy5kZWNvZGUgPSBvcHRzLmRlY29kZSB8fCB0aGlzLmRlZmF1bHREZWNvZGVyXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW5jb2RlID0gdGhpcy5kZWZhdWx0RW5jb2RlclxuICAgICAgdGhpcy5kZWNvZGUgPSB0aGlzLmRlZmF1bHREZWNvZGVyXG4gICAgfVxuICAgIGxldCBhd2FpdGluZ0Nvbm5lY3Rpb25PblBhZ2VTaG93ID0gbnVsbFxuICAgIGlmKHBoeFdpbmRvdyAmJiBwaHhXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lcil7XG4gICAgICBwaHhXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBhZ2VoaWRlXCIsIF9lID0+IHtcbiAgICAgICAgaWYodGhpcy5jb25uKXtcbiAgICAgICAgICB0aGlzLmRpc2Nvbm5lY3QoKVxuICAgICAgICAgIGF3YWl0aW5nQ29ubmVjdGlvbk9uUGFnZVNob3cgPSB0aGlzLmNvbm5lY3RDbG9ja1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgcGh4V2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJwYWdlc2hvd1wiLCBfZSA9PiB7XG4gICAgICAgIGlmKGF3YWl0aW5nQ29ubmVjdGlvbk9uUGFnZVNob3cgPT09IHRoaXMuY29ubmVjdENsb2NrKXtcbiAgICAgICAgICBhd2FpdGluZ0Nvbm5lY3Rpb25PblBhZ2VTaG93ID0gbnVsbFxuICAgICAgICAgIHRoaXMuY29ubmVjdCgpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICAgIHRoaXMuaGVhcnRiZWF0SW50ZXJ2YWxNcyA9IG9wdHMuaGVhcnRiZWF0SW50ZXJ2YWxNcyB8fCAzMDAwMFxuICAgIHRoaXMucmVqb2luQWZ0ZXJNcyA9ICh0cmllcykgPT4ge1xuICAgICAgaWYob3B0cy5yZWpvaW5BZnRlck1zKXtcbiAgICAgICAgcmV0dXJuIG9wdHMucmVqb2luQWZ0ZXJNcyh0cmllcylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbMTAwMCwgMjAwMCwgNTAwMF1bdHJpZXMgLSAxXSB8fCAxMDAwMFxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnJlY29ubmVjdEFmdGVyTXMgPSAodHJpZXMpID0+IHtcbiAgICAgIGlmKG9wdHMucmVjb25uZWN0QWZ0ZXJNcyl7XG4gICAgICAgIHJldHVybiBvcHRzLnJlY29ubmVjdEFmdGVyTXModHJpZXMpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gWzEwLCA1MCwgMTAwLCAxNTAsIDIwMCwgMjUwLCA1MDAsIDEwMDAsIDIwMDBdW3RyaWVzIC0gMV0gfHwgNTAwMFxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmxvZ2dlciA9IG9wdHMubG9nZ2VyIHx8IG51bGxcbiAgICBpZighdGhpcy5sb2dnZXIgJiYgb3B0cy5kZWJ1Zyl7XG4gICAgICB0aGlzLmxvZ2dlciA9IChraW5kLCBtc2csIGRhdGEpID0+IHsgY29uc29sZS5sb2coYCR7a2luZH06ICR7bXNnfWAsIGRhdGEpIH1cbiAgICB9XG4gICAgdGhpcy5sb25ncG9sbGVyVGltZW91dCA9IG9wdHMubG9uZ3BvbGxlclRpbWVvdXQgfHwgMjAwMDBcbiAgICB0aGlzLnBhcmFtcyA9IGNsb3N1cmUob3B0cy5wYXJhbXMgfHwge30pXG4gICAgdGhpcy5lbmRQb2ludCA9IGAke2VuZFBvaW50fS8ke1RSQU5TUE9SVFMud2Vic29ja2V0fWBcbiAgICB0aGlzLnZzbiA9IG9wdHMudnNuIHx8IERFRkFVTFRfVlNOXG4gICAgdGhpcy5oZWFydGJlYXRUaW1lb3V0VGltZXIgPSBudWxsXG4gICAgdGhpcy5oZWFydGJlYXRUaW1lciA9IG51bGxcbiAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSBudWxsXG4gICAgdGhpcy5yZWNvbm5lY3RUaW1lciA9IG5ldyBUaW1lcigoKSA9PiB7XG4gICAgICB0aGlzLnRlYXJkb3duKCgpID0+IHRoaXMuY29ubmVjdCgpKVxuICAgIH0sIHRoaXMucmVjb25uZWN0QWZ0ZXJNcylcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBMb25nUG9sbCB0cmFuc3BvcnQgcmVmZXJlbmNlXG4gICAqL1xuICBnZXRMb25nUG9sbFRyYW5zcG9ydCgpeyByZXR1cm4gTG9uZ1BvbGwgfVxuXG4gIC8qKlxuICAgKiBEaXNjb25uZWN0cyBhbmQgcmVwbGFjZXMgdGhlIGFjdGl2ZSB0cmFuc3BvcnRcbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbmV3VHJhbnNwb3J0IC0gVGhlIG5ldyB0cmFuc3BvcnQgY2xhc3MgdG8gaW5zdGFudGlhdGVcbiAgICpcbiAgICovXG4gIHJlcGxhY2VUcmFuc3BvcnQobmV3VHJhbnNwb3J0KXtcbiAgICB0aGlzLmNvbm5lY3RDbG9jaysrXG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gdHJ1ZVxuICAgIGNsZWFyVGltZW91dCh0aGlzLmZhbGxiYWNrVGltZXIpXG4gICAgdGhpcy5yZWNvbm5lY3RUaW1lci5yZXNldCgpXG4gICAgaWYodGhpcy5jb25uKXtcbiAgICAgIHRoaXMuY29ubi5jbG9zZSgpXG4gICAgICB0aGlzLmNvbm4gPSBudWxsXG4gICAgfVxuICAgIHRoaXMudHJhbnNwb3J0ID0gbmV3VHJhbnNwb3J0XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgc29ja2V0IHByb3RvY29sXG4gICAqXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICBwcm90b2NvbCgpeyByZXR1cm4gbG9jYXRpb24ucHJvdG9jb2wubWF0Y2goL15odHRwcy8pID8gXCJ3c3NcIiA6IFwid3NcIiB9XG5cbiAgLyoqXG4gICAqIFRoZSBmdWxseSBxdWFsaWZpZWQgc29ja2V0IHVybFxuICAgKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgZW5kUG9pbnRVUkwoKXtcbiAgICBsZXQgdXJpID0gQWpheC5hcHBlbmRQYXJhbXMoXG4gICAgICBBamF4LmFwcGVuZFBhcmFtcyh0aGlzLmVuZFBvaW50LCB0aGlzLnBhcmFtcygpKSwge3ZzbjogdGhpcy52c259KVxuICAgIGlmKHVyaS5jaGFyQXQoMCkgIT09IFwiL1wiKXsgcmV0dXJuIHVyaSB9XG4gICAgaWYodXJpLmNoYXJBdCgxKSA9PT0gXCIvXCIpeyByZXR1cm4gYCR7dGhpcy5wcm90b2NvbCgpfToke3VyaX1gIH1cblxuICAgIHJldHVybiBgJHt0aGlzLnByb3RvY29sKCl9Oi8vJHtsb2NhdGlvbi5ob3N0fSR7dXJpfWBcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNjb25uZWN0cyB0aGUgc29ja2V0XG4gICAqXG4gICAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvQ2xvc2VFdmVudCNTdGF0dXNfY29kZXMgZm9yIHZhbGlkIHN0YXR1cyBjb2Rlcy5cbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgLSBPcHRpb25hbCBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgYWZ0ZXIgc29ja2V0IGlzIGRpc2Nvbm5lY3RlZC5cbiAgICogQHBhcmFtIHtpbnRlZ2VyfSBjb2RlIC0gQSBzdGF0dXMgY29kZSBmb3IgZGlzY29ubmVjdGlvbiAoT3B0aW9uYWwpLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVhc29uIC0gQSB0ZXh0dWFsIGRlc2NyaXB0aW9uIG9mIHRoZSByZWFzb24gdG8gZGlzY29ubmVjdC4gKE9wdGlvbmFsKVxuICAgKi9cbiAgZGlzY29ubmVjdChjYWxsYmFjaywgY29kZSwgcmVhc29uKXtcbiAgICB0aGlzLmNvbm5lY3RDbG9jaysrXG4gICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gdHJ1ZVxuICAgIGNsZWFyVGltZW91dCh0aGlzLmZhbGxiYWNrVGltZXIpXG4gICAgdGhpcy5yZWNvbm5lY3RUaW1lci5yZXNldCgpXG4gICAgdGhpcy50ZWFyZG93bihjYWxsYmFjaywgY29kZSwgcmVhc29uKVxuICB9XG5cbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgLSBUaGUgcGFyYW1zIHRvIHNlbmQgd2hlbiBjb25uZWN0aW5nLCBmb3IgZXhhbXBsZSBge3VzZXJfaWQ6IHVzZXJUb2tlbn1gXG4gICAqXG4gICAqIFBhc3NpbmcgcGFyYW1zIHRvIGNvbm5lY3QgaXMgZGVwcmVjYXRlZDsgcGFzcyB0aGVtIGluIHRoZSBTb2NrZXQgY29uc3RydWN0b3IgaW5zdGVhZDpcbiAgICogYG5ldyBTb2NrZXQoXCIvc29ja2V0XCIsIHtwYXJhbXM6IHt1c2VyX2lkOiB1c2VyVG9rZW59fSlgLlxuICAgKi9cbiAgY29ubmVjdChwYXJhbXMpe1xuICAgIGlmKHBhcmFtcyl7XG4gICAgICBjb25zb2xlICYmIGNvbnNvbGUubG9nKFwicGFzc2luZyBwYXJhbXMgdG8gY29ubmVjdCBpcyBkZXByZWNhdGVkLiBJbnN0ZWFkIHBhc3MgOnBhcmFtcyB0byB0aGUgU29ja2V0IGNvbnN0cnVjdG9yXCIpXG4gICAgICB0aGlzLnBhcmFtcyA9IGNsb3N1cmUocGFyYW1zKVxuICAgIH1cbiAgICBpZih0aGlzLmNvbm4peyByZXR1cm4gfVxuICAgIGlmKHRoaXMubG9uZ1BvbGxGYWxsYmFja01zICYmIHRoaXMudHJhbnNwb3J0ICE9PSBMb25nUG9sbCl7XG4gICAgICB0aGlzLmNvbm5lY3RXaXRoRmFsbGJhY2soTG9uZ1BvbGwsIHRoaXMubG9uZ1BvbGxGYWxsYmFja01zKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRyYW5zcG9ydENvbm5lY3QoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMb2dzIHRoZSBtZXNzYWdlLiBPdmVycmlkZSBgdGhpcy5sb2dnZXJgIGZvciBzcGVjaWFsaXplZCBsb2dnaW5nLiBub29wcyBieSBkZWZhdWx0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBraW5kXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtc2dcbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFcbiAgICovXG4gIGxvZyhraW5kLCBtc2csIGRhdGEpeyB0aGlzLmxvZ2dlciAmJiB0aGlzLmxvZ2dlcihraW5kLCBtc2csIGRhdGEpIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0cnVlIGlmIGEgbG9nZ2VyIGhhcyBiZWVuIHNldCBvbiB0aGlzIHNvY2tldC5cbiAgICovXG4gIGhhc0xvZ2dlcigpeyByZXR1cm4gdGhpcy5sb2dnZXIgIT09IG51bGwgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgY2FsbGJhY2tzIGZvciBjb25uZWN0aW9uIG9wZW4gZXZlbnRzXG4gICAqXG4gICAqIEBleGFtcGxlIHNvY2tldC5vbk9wZW4oZnVuY3Rpb24oKXsgY29uc29sZS5pbmZvKFwidGhlIHNvY2tldCB3YXMgb3BlbmVkXCIpIH0pXG4gICAqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gICAqL1xuICBvbk9wZW4oY2FsbGJhY2spe1xuICAgIGxldCByZWYgPSB0aGlzLm1ha2VSZWYoKVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3Mub3Blbi5wdXNoKFtyZWYsIGNhbGxiYWNrXSlcbiAgICByZXR1cm4gcmVmXG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGNhbGxiYWNrcyBmb3IgY29ubmVjdGlvbiBjbG9zZSBldmVudHNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICovXG4gIG9uQ2xvc2UoY2FsbGJhY2spe1xuICAgIGxldCByZWYgPSB0aGlzLm1ha2VSZWYoKVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MuY2xvc2UucHVzaChbcmVmLCBjYWxsYmFja10pXG4gICAgcmV0dXJuIHJlZlxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBjYWxsYmFja3MgZm9yIGNvbm5lY3Rpb24gZXJyb3IgZXZlbnRzXG4gICAqXG4gICAqIEBleGFtcGxlIHNvY2tldC5vbkVycm9yKGZ1bmN0aW9uKGVycm9yKXsgYWxlcnQoXCJBbiBlcnJvciBvY2N1cnJlZFwiKSB9KVxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgb25FcnJvcihjYWxsYmFjayl7XG4gICAgbGV0IHJlZiA9IHRoaXMubWFrZVJlZigpXG4gICAgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5lcnJvci5wdXNoKFtyZWYsIGNhbGxiYWNrXSlcbiAgICByZXR1cm4gcmVmXG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGNhbGxiYWNrcyBmb3IgY29ubmVjdGlvbiBtZXNzYWdlIGV2ZW50c1xuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgKi9cbiAgb25NZXNzYWdlKGNhbGxiYWNrKXtcbiAgICBsZXQgcmVmID0gdGhpcy5tYWtlUmVmKClcbiAgICB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLm1lc3NhZ2UucHVzaChbcmVmLCBjYWxsYmFja10pXG4gICAgcmV0dXJuIHJlZlxuICB9XG5cbiAgLyoqXG4gICAqIFBpbmdzIHRoZSBzZXJ2ZXIgYW5kIGludm9rZXMgdGhlIGNhbGxiYWNrIHdpdGggdGhlIFJUVCBpbiBtaWxsaXNlY29uZHNcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICpcbiAgICogUmV0dXJucyB0cnVlIGlmIHRoZSBwaW5nIHdhcyBwdXNoZWQgb3IgZmFsc2UgaWYgdW5hYmxlIHRvIGJlIHB1c2hlZC5cbiAgICovXG4gIHBpbmcoY2FsbGJhY2spe1xuICAgIGlmKCF0aGlzLmlzQ29ubmVjdGVkKCkpeyByZXR1cm4gZmFsc2UgfVxuICAgIGxldCByZWYgPSB0aGlzLm1ha2VSZWYoKVxuICAgIGxldCBzdGFydFRpbWUgPSBEYXRlLm5vdygpXG4gICAgdGhpcy5wdXNoKHt0b3BpYzogXCJwaG9lbml4XCIsIGV2ZW50OiBcImhlYXJ0YmVhdFwiLCBwYXlsb2FkOiB7fSwgcmVmOiByZWZ9KVxuICAgIGxldCBvbk1zZ1JlZiA9IHRoaXMub25NZXNzYWdlKG1zZyA9PiB7XG4gICAgICBpZihtc2cucmVmID09PSByZWYpe1xuICAgICAgICB0aGlzLm9mZihbb25Nc2dSZWZdKVxuICAgICAgICBjYWxsYmFjayhEYXRlLm5vdygpIC0gc3RhcnRUaW1lKVxuICAgICAgfVxuICAgIH0pXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cblxuICB0cmFuc3BvcnRDb25uZWN0KCl7XG4gICAgdGhpcy5jb25uZWN0Q2xvY2srK1xuICAgIHRoaXMuY2xvc2VXYXNDbGVhbiA9IGZhbHNlXG4gICAgdGhpcy5jb25uID0gbmV3IHRoaXMudHJhbnNwb3J0KHRoaXMuZW5kUG9pbnRVUkwoKSlcbiAgICB0aGlzLmNvbm4uYmluYXJ5VHlwZSA9IHRoaXMuYmluYXJ5VHlwZVxuICAgIHRoaXMuY29ubi50aW1lb3V0ID0gdGhpcy5sb25ncG9sbGVyVGltZW91dFxuICAgIHRoaXMuY29ubi5vbm9wZW4gPSAoKSA9PiB0aGlzLm9uQ29ubk9wZW4oKVxuICAgIHRoaXMuY29ubi5vbmVycm9yID0gZXJyb3IgPT4gdGhpcy5vbkNvbm5FcnJvcihlcnJvcilcbiAgICB0aGlzLmNvbm4ub25tZXNzYWdlID0gZXZlbnQgPT4gdGhpcy5vbkNvbm5NZXNzYWdlKGV2ZW50KVxuICAgIHRoaXMuY29ubi5vbmNsb3NlID0gZXZlbnQgPT4gdGhpcy5vbkNvbm5DbG9zZShldmVudClcbiAgfVxuXG4gIGdldFNlc3Npb24oa2V5KXsgcmV0dXJuIHRoaXMuc2Vzc2lvblN0b3JlICYmIHRoaXMuc2Vzc2lvblN0b3JlLmdldEl0ZW0oa2V5KSB9XG5cbiAgc3RvcmVTZXNzaW9uKGtleSwgdmFsKXsgdGhpcy5zZXNzaW9uU3RvcmUgJiYgdGhpcy5zZXNzaW9uU3RvcmUuc2V0SXRlbShrZXksIHZhbCkgfVxuXG4gIGNvbm5lY3RXaXRoRmFsbGJhY2soZmFsbGJhY2tUcmFuc3BvcnQsIGZhbGxiYWNrVGhyZXNob2xkID0gMjUwMCl7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuZmFsbGJhY2tUaW1lcilcbiAgICBsZXQgZXN0YWJsaXNoZWQgPSBmYWxzZVxuICAgIGxldCBwcmltYXJ5VHJhbnNwb3J0ID0gdHJ1ZVxuICAgIGxldCBvcGVuUmVmLCBlcnJvclJlZlxuICAgIGxldCBmYWxsYmFjayA9IChyZWFzb24pID0+IHtcbiAgICAgIHRoaXMubG9nKFwidHJhbnNwb3J0XCIsIGBmYWxsaW5nIGJhY2sgdG8gJHtmYWxsYmFja1RyYW5zcG9ydC5uYW1lfS4uLmAsIHJlYXNvbilcbiAgICAgIHRoaXMub2ZmKFtvcGVuUmVmLCBlcnJvclJlZl0pXG4gICAgICBwcmltYXJ5VHJhbnNwb3J0ID0gZmFsc2VcbiAgICAgIHRoaXMucmVwbGFjZVRyYW5zcG9ydChmYWxsYmFja1RyYW5zcG9ydClcbiAgICAgIHRoaXMudHJhbnNwb3J0Q29ubmVjdCgpXG4gICAgfVxuICAgIGlmKHRoaXMuZ2V0U2Vzc2lvbihgcGh4OmZhbGxiYWNrOiR7ZmFsbGJhY2tUcmFuc3BvcnQubmFtZX1gKSl7IHJldHVybiBmYWxsYmFjayhcIm1lbW9yaXplZFwiKSB9XG5cbiAgICB0aGlzLmZhbGxiYWNrVGltZXIgPSBzZXRUaW1lb3V0KGZhbGxiYWNrLCBmYWxsYmFja1RocmVzaG9sZClcblxuICAgIGVycm9yUmVmID0gdGhpcy5vbkVycm9yKHJlYXNvbiA9PiB7XG4gICAgICB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBcImVycm9yXCIsIHJlYXNvbilcbiAgICAgIGlmKHByaW1hcnlUcmFuc3BvcnQgJiYgIWVzdGFibGlzaGVkKXtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuZmFsbGJhY2tUaW1lcilcbiAgICAgICAgZmFsbGJhY2socmVhc29uKVxuICAgICAgfVxuICAgIH0pXG4gICAgdGhpcy5vbk9wZW4oKCkgPT4ge1xuICAgICAgZXN0YWJsaXNoZWQgPSB0cnVlXG4gICAgICBpZighcHJpbWFyeVRyYW5zcG9ydCl7XG4gICAgICAgIC8vIG9ubHkgbWVtb3JpemUgTFAgaWYgd2UgbmV2ZXIgY29ubmVjdGVkIHRvIHByaW1hcnlcbiAgICAgICAgaWYoIXRoaXMucHJpbWFyeVBhc3NlZEhlYWx0aENoZWNrKXsgdGhpcy5zdG9yZVNlc3Npb24oYHBoeDpmYWxsYmFjazoke2ZhbGxiYWNrVHJhbnNwb3J0Lm5hbWV9YCwgXCJ0cnVlXCIpIH1cbiAgICAgICAgcmV0dXJuIHRoaXMubG9nKFwidHJhbnNwb3J0XCIsIGBlc3RhYmxpc2hlZCAke2ZhbGxiYWNrVHJhbnNwb3J0Lm5hbWV9IGZhbGxiYWNrYClcbiAgICAgIH1cbiAgICAgIC8vIGlmIHdlJ3ZlIGVzdGFibGlzaGVkIHByaW1hcnksIGdpdmUgdGhlIGZhbGxiYWNrIGEgbmV3IHBlcmlvZCB0byBhdHRlbXB0IHBpbmdcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLmZhbGxiYWNrVGltZXIpXG4gICAgICB0aGlzLmZhbGxiYWNrVGltZXIgPSBzZXRUaW1lb3V0KGZhbGxiYWNrLCBmYWxsYmFja1RocmVzaG9sZClcbiAgICAgIHRoaXMucGluZyhydHQgPT4ge1xuICAgICAgICB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBcImNvbm5lY3RlZCB0byBwcmltYXJ5IGFmdGVyXCIsIHJ0dClcbiAgICAgICAgdGhpcy5wcmltYXJ5UGFzc2VkSGVhbHRoQ2hlY2sgPSB0cnVlXG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmZhbGxiYWNrVGltZXIpXG4gICAgICB9KVxuICAgIH0pXG4gICAgdGhpcy50cmFuc3BvcnRDb25uZWN0KClcbiAgfVxuXG4gIGNsZWFySGVhcnRiZWF0cygpe1xuICAgIGNsZWFyVGltZW91dCh0aGlzLmhlYXJ0YmVhdFRpbWVyKVxuICAgIGNsZWFyVGltZW91dCh0aGlzLmhlYXJ0YmVhdFRpbWVvdXRUaW1lcilcbiAgfVxuXG4gIG9uQ29ubk9wZW4oKXtcbiAgICBpZih0aGlzLmhhc0xvZ2dlcigpKSB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBgJHt0aGlzLnRyYW5zcG9ydC5uYW1lfSBjb25uZWN0ZWQgdG8gJHt0aGlzLmVuZFBvaW50VVJMKCl9YClcbiAgICB0aGlzLmNsb3NlV2FzQ2xlYW4gPSBmYWxzZVxuICAgIHRoaXMuZXN0YWJsaXNoZWRDb25uZWN0aW9ucysrXG4gICAgdGhpcy5mbHVzaFNlbmRCdWZmZXIoKVxuICAgIHRoaXMucmVjb25uZWN0VGltZXIucmVzZXQoKVxuICAgIHRoaXMucmVzZXRIZWFydGJlYXQoKVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3Mub3Blbi5mb3JFYWNoKChbLCBjYWxsYmFja10pID0+IGNhbGxiYWNrKCkpXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cbiAgaGVhcnRiZWF0VGltZW91dCgpe1xuICAgIGlmKHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZil7XG4gICAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSBudWxsXG4gICAgICBpZih0aGlzLmhhc0xvZ2dlcigpKXsgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgXCJoZWFydGJlYXQgdGltZW91dC4gQXR0ZW1wdGluZyB0byByZS1lc3RhYmxpc2ggY29ubmVjdGlvblwiKSB9XG4gICAgICB0aGlzLnRyaWdnZXJDaGFuRXJyb3IoKVxuICAgICAgdGhpcy5jbG9zZVdhc0NsZWFuID0gZmFsc2VcbiAgICAgIHRoaXMudGVhcmRvd24oKCkgPT4gdGhpcy5yZWNvbm5lY3RUaW1lci5zY2hlZHVsZVRpbWVvdXQoKSwgV1NfQ0xPU0VfTk9STUFMLCBcImhlYXJ0YmVhdCB0aW1lb3V0XCIpXG4gICAgfVxuICB9XG5cbiAgcmVzZXRIZWFydGJlYXQoKXtcbiAgICBpZih0aGlzLmNvbm4gJiYgdGhpcy5jb25uLnNraXBIZWFydGJlYXQpeyByZXR1cm4gfVxuICAgIHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZiA9IG51bGxcbiAgICB0aGlzLmNsZWFySGVhcnRiZWF0cygpXG4gICAgdGhpcy5oZWFydGJlYXRUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZW5kSGVhcnRiZWF0KCksIHRoaXMuaGVhcnRiZWF0SW50ZXJ2YWxNcylcbiAgfVxuXG4gIHRlYXJkb3duKGNhbGxiYWNrLCBjb2RlLCByZWFzb24pe1xuICAgIGlmKCF0aGlzLmNvbm4pe1xuICAgICAgcmV0dXJuIGNhbGxiYWNrICYmIGNhbGxiYWNrKClcbiAgICB9XG5cbiAgICB0aGlzLndhaXRGb3JCdWZmZXJEb25lKCgpID0+IHtcbiAgICAgIGlmKHRoaXMuY29ubil7XG4gICAgICAgIGlmKGNvZGUpeyB0aGlzLmNvbm4uY2xvc2UoY29kZSwgcmVhc29uIHx8IFwiXCIpIH0gZWxzZSB7IHRoaXMuY29ubi5jbG9zZSgpIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy53YWl0Rm9yU29ja2V0Q2xvc2VkKCgpID0+IHtcbiAgICAgICAgaWYodGhpcy5jb25uKXtcbiAgICAgICAgICB0aGlzLmNvbm4ub25vcGVuID0gZnVuY3Rpb24gKCl7IH0gLy8gbm9vcFxuICAgICAgICAgIHRoaXMuY29ubi5vbmVycm9yID0gZnVuY3Rpb24gKCl7IH0gLy8gbm9vcFxuICAgICAgICAgIHRoaXMuY29ubi5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoKXsgfSAvLyBub29wXG4gICAgICAgICAgdGhpcy5jb25uLm9uY2xvc2UgPSBmdW5jdGlvbiAoKXsgfSAvLyBub29wXG4gICAgICAgICAgdGhpcy5jb25uID0gbnVsbFxuICAgICAgICB9XG5cbiAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgd2FpdEZvckJ1ZmZlckRvbmUoY2FsbGJhY2ssIHRyaWVzID0gMSl7XG4gICAgaWYodHJpZXMgPT09IDUgfHwgIXRoaXMuY29ubiB8fCAhdGhpcy5jb25uLmJ1ZmZlcmVkQW1vdW50KXtcbiAgICAgIGNhbGxiYWNrKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy53YWl0Rm9yQnVmZmVyRG9uZShjYWxsYmFjaywgdHJpZXMgKyAxKVxuICAgIH0sIDE1MCAqIHRyaWVzKVxuICB9XG5cbiAgd2FpdEZvclNvY2tldENsb3NlZChjYWxsYmFjaywgdHJpZXMgPSAxKXtcbiAgICBpZih0cmllcyA9PT0gNSB8fCAhdGhpcy5jb25uIHx8IHRoaXMuY29ubi5yZWFkeVN0YXRlID09PSBTT0NLRVRfU1RBVEVTLmNsb3NlZCl7XG4gICAgICBjYWxsYmFjaygpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMud2FpdEZvclNvY2tldENsb3NlZChjYWxsYmFjaywgdHJpZXMgKyAxKVxuICAgIH0sIDE1MCAqIHRyaWVzKVxuICB9XG5cbiAgb25Db25uQ2xvc2UoZXZlbnQpe1xuICAgIGxldCBjbG9zZUNvZGUgPSBldmVudCAmJiBldmVudC5jb2RlXG4gICAgaWYodGhpcy5oYXNMb2dnZXIoKSkgdGhpcy5sb2coXCJ0cmFuc3BvcnRcIiwgXCJjbG9zZVwiLCBldmVudClcbiAgICB0aGlzLnRyaWdnZXJDaGFuRXJyb3IoKVxuICAgIHRoaXMuY2xlYXJIZWFydGJlYXRzKClcbiAgICBpZighdGhpcy5jbG9zZVdhc0NsZWFuICYmIGNsb3NlQ29kZSAhPT0gMTAwMCl7XG4gICAgICB0aGlzLnJlY29ubmVjdFRpbWVyLnNjaGVkdWxlVGltZW91dCgpXG4gICAgfVxuICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MuY2xvc2UuZm9yRWFjaCgoWywgY2FsbGJhY2tdKSA9PiBjYWxsYmFjayhldmVudCkpXG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIG9uQ29ubkVycm9yKGVycm9yKXtcbiAgICBpZih0aGlzLmhhc0xvZ2dlcigpKSB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBlcnJvcilcbiAgICBsZXQgdHJhbnNwb3J0QmVmb3JlID0gdGhpcy50cmFuc3BvcnRcbiAgICBsZXQgZXN0YWJsaXNoZWRCZWZvcmUgPSB0aGlzLmVzdGFibGlzaGVkQ29ubmVjdGlvbnNcbiAgICB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzLmVycm9yLmZvckVhY2goKFssIGNhbGxiYWNrXSkgPT4ge1xuICAgICAgY2FsbGJhY2soZXJyb3IsIHRyYW5zcG9ydEJlZm9yZSwgZXN0YWJsaXNoZWRCZWZvcmUpXG4gICAgfSlcbiAgICBpZih0cmFuc3BvcnRCZWZvcmUgPT09IHRoaXMudHJhbnNwb3J0IHx8IGVzdGFibGlzaGVkQmVmb3JlID4gMCl7XG4gICAgICB0aGlzLnRyaWdnZXJDaGFuRXJyb3IoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdHJpZ2dlckNoYW5FcnJvcigpe1xuICAgIHRoaXMuY2hhbm5lbHMuZm9yRWFjaChjaGFubmVsID0+IHtcbiAgICAgIGlmKCEoY2hhbm5lbC5pc0Vycm9yZWQoKSB8fCBjaGFubmVsLmlzTGVhdmluZygpIHx8IGNoYW5uZWwuaXNDbG9zZWQoKSkpe1xuICAgICAgICBjaGFubmVsLnRyaWdnZXIoQ0hBTk5FTF9FVkVOVFMuZXJyb3IpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgY29ubmVjdGlvblN0YXRlKCl7XG4gICAgc3dpdGNoKHRoaXMuY29ubiAmJiB0aGlzLmNvbm4ucmVhZHlTdGF0ZSl7XG4gICAgICBjYXNlIFNPQ0tFVF9TVEFURVMuY29ubmVjdGluZzogcmV0dXJuIFwiY29ubmVjdGluZ1wiXG4gICAgICBjYXNlIFNPQ0tFVF9TVEFURVMub3BlbjogcmV0dXJuIFwib3BlblwiXG4gICAgICBjYXNlIFNPQ0tFVF9TVEFURVMuY2xvc2luZzogcmV0dXJuIFwiY2xvc2luZ1wiXG4gICAgICBkZWZhdWx0OiByZXR1cm4gXCJjbG9zZWRcIlxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICovXG4gIGlzQ29ubmVjdGVkKCl7IHJldHVybiB0aGlzLmNvbm5lY3Rpb25TdGF0ZSgpID09PSBcIm9wZW5cIiB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqXG4gICAqIEBwYXJhbSB7Q2hhbm5lbH1cbiAgICovXG4gIHJlbW92ZShjaGFubmVsKXtcbiAgICB0aGlzLm9mZihjaGFubmVsLnN0YXRlQ2hhbmdlUmVmcylcbiAgICB0aGlzLmNoYW5uZWxzID0gdGhpcy5jaGFubmVscy5maWx0ZXIoYyA9PiBjICE9PSBjaGFubmVsKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYG9uT3BlbmAsIGBvbkNsb3NlYCwgYG9uRXJyb3IsYCBhbmQgYG9uTWVzc2FnZWAgcmVnaXN0cmF0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIHtyZWZzfSAtIGxpc3Qgb2YgcmVmcyByZXR1cm5lZCBieSBjYWxscyB0b1xuICAgKiAgICAgICAgICAgICAgICAgYG9uT3BlbmAsIGBvbkNsb3NlYCwgYG9uRXJyb3IsYCBhbmQgYG9uTWVzc2FnZWBcbiAgICovXG4gIG9mZihyZWZzKXtcbiAgICBmb3IobGV0IGtleSBpbiB0aGlzLnN0YXRlQ2hhbmdlQ2FsbGJhY2tzKXtcbiAgICAgIHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3Nba2V5XSA9IHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3Nba2V5XS5maWx0ZXIoKFtyZWZdKSA9PiB7XG4gICAgICAgIHJldHVybiByZWZzLmluZGV4T2YocmVmKSA9PT0gLTFcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYXRlcyBhIG5ldyBjaGFubmVsIGZvciB0aGUgZ2l2ZW4gdG9waWNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRvcGljXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjaGFuUGFyYW1zIC0gUGFyYW1ldGVycyBmb3IgdGhlIGNoYW5uZWxcbiAgICogQHJldHVybnMge0NoYW5uZWx9XG4gICAqL1xuICBjaGFubmVsKHRvcGljLCBjaGFuUGFyYW1zID0ge30pe1xuICAgIGxldCBjaGFuID0gbmV3IENoYW5uZWwodG9waWMsIGNoYW5QYXJhbXMsIHRoaXMpXG4gICAgdGhpcy5jaGFubmVscy5wdXNoKGNoYW4pXG4gICAgcmV0dXJuIGNoYW5cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICAgKi9cbiAgcHVzaChkYXRhKXtcbiAgICBpZih0aGlzLmhhc0xvZ2dlcigpKXtcbiAgICAgIGxldCB7dG9waWMsIGV2ZW50LCBwYXlsb2FkLCByZWYsIGpvaW5fcmVmfSA9IGRhdGFcbiAgICAgIHRoaXMubG9nKFwicHVzaFwiLCBgJHt0b3BpY30gJHtldmVudH0gKCR7am9pbl9yZWZ9LCAke3JlZn0pYCwgcGF5bG9hZClcbiAgICB9XG5cbiAgICBpZih0aGlzLmlzQ29ubmVjdGVkKCkpe1xuICAgICAgdGhpcy5lbmNvZGUoZGF0YSwgcmVzdWx0ID0+IHRoaXMuY29ubi5zZW5kKHJlc3VsdCkpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VuZEJ1ZmZlci5wdXNoKCgpID0+IHRoaXMuZW5jb2RlKGRhdGEsIHJlc3VsdCA9PiB0aGlzLmNvbm4uc2VuZChyZXN1bHQpKSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBuZXh0IG1lc3NhZ2UgcmVmLCBhY2NvdW50aW5nIGZvciBvdmVyZmxvd3NcbiAgICogQHJldHVybnMge3N0cmluZ31cbiAgICovXG4gIG1ha2VSZWYoKXtcbiAgICBsZXQgbmV3UmVmID0gdGhpcy5yZWYgKyAxXG4gICAgaWYobmV3UmVmID09PSB0aGlzLnJlZil7IHRoaXMucmVmID0gMCB9IGVsc2UgeyB0aGlzLnJlZiA9IG5ld1JlZiB9XG5cbiAgICByZXR1cm4gdGhpcy5yZWYudG9TdHJpbmcoKVxuICB9XG5cbiAgc2VuZEhlYXJ0YmVhdCgpe1xuICAgIGlmKHRoaXMucGVuZGluZ0hlYXJ0YmVhdFJlZiAmJiAhdGhpcy5pc0Nvbm5lY3RlZCgpKXsgcmV0dXJuIH1cbiAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSB0aGlzLm1ha2VSZWYoKVxuICAgIHRoaXMucHVzaCh7dG9waWM6IFwicGhvZW5peFwiLCBldmVudDogXCJoZWFydGJlYXRcIiwgcGF5bG9hZDoge30sIHJlZjogdGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmfSlcbiAgICB0aGlzLmhlYXJ0YmVhdFRpbWVvdXRUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5oZWFydGJlYXRUaW1lb3V0KCksIHRoaXMuaGVhcnRiZWF0SW50ZXJ2YWxNcylcbiAgfVxuXG4gIGZsdXNoU2VuZEJ1ZmZlcigpe1xuICAgIGlmKHRoaXMuaXNDb25uZWN0ZWQoKSAmJiB0aGlzLnNlbmRCdWZmZXIubGVuZ3RoID4gMCl7XG4gICAgICB0aGlzLnNlbmRCdWZmZXIuZm9yRWFjaChjYWxsYmFjayA9PiBjYWxsYmFjaygpKVxuICAgICAgdGhpcy5zZW5kQnVmZmVyID0gW11cbiAgICB9XG4gIH1cblxuICBvbkNvbm5NZXNzYWdlKHJhd01lc3NhZ2Upe1xuICAgIHRoaXMuZGVjb2RlKHJhd01lc3NhZ2UuZGF0YSwgbXNnID0+IHtcbiAgICAgIGxldCB7dG9waWMsIGV2ZW50LCBwYXlsb2FkLCByZWYsIGpvaW5fcmVmfSA9IG1zZ1xuICAgICAgaWYocmVmICYmIHJlZiA9PT0gdGhpcy5wZW5kaW5nSGVhcnRiZWF0UmVmKXtcbiAgICAgICAgdGhpcy5jbGVhckhlYXJ0YmVhdHMoKVxuICAgICAgICB0aGlzLnBlbmRpbmdIZWFydGJlYXRSZWYgPSBudWxsXG4gICAgICAgIHRoaXMuaGVhcnRiZWF0VGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMuc2VuZEhlYXJ0YmVhdCgpLCB0aGlzLmhlYXJ0YmVhdEludGVydmFsTXMpXG4gICAgICB9XG5cbiAgICAgIGlmKHRoaXMuaGFzTG9nZ2VyKCkpIHRoaXMubG9nKFwicmVjZWl2ZVwiLCBgJHtwYXlsb2FkLnN0YXR1cyB8fCBcIlwifSAke3RvcGljfSAke2V2ZW50fSAke3JlZiAmJiBcIihcIiArIHJlZiArIFwiKVwiIHx8IFwiXCJ9YCwgcGF5bG9hZClcblxuICAgICAgZm9yKGxldCBpID0gMDsgaSA8IHRoaXMuY2hhbm5lbHMubGVuZ3RoOyBpKyspe1xuICAgICAgICBjb25zdCBjaGFubmVsID0gdGhpcy5jaGFubmVsc1tpXVxuICAgICAgICBpZighY2hhbm5lbC5pc01lbWJlcih0b3BpYywgZXZlbnQsIHBheWxvYWQsIGpvaW5fcmVmKSl7IGNvbnRpbnVlIH1cbiAgICAgICAgY2hhbm5lbC50cmlnZ2VyKGV2ZW50LCBwYXlsb2FkLCByZWYsIGpvaW5fcmVmKVxuICAgICAgfVxuXG4gICAgICBmb3IobGV0IGkgPSAwOyBpIDwgdGhpcy5zdGF0ZUNoYW5nZUNhbGxiYWNrcy5tZXNzYWdlLmxlbmd0aDsgaSsrKXtcbiAgICAgICAgbGV0IFssIGNhbGxiYWNrXSA9IHRoaXMuc3RhdGVDaGFuZ2VDYWxsYmFja3MubWVzc2FnZVtpXVxuICAgICAgICBjYWxsYmFjayhtc2cpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIGxlYXZlT3BlblRvcGljKHRvcGljKXtcbiAgICBsZXQgZHVwQ2hhbm5lbCA9IHRoaXMuY2hhbm5lbHMuZmluZChjID0+IGMudG9waWMgPT09IHRvcGljICYmIChjLmlzSm9pbmVkKCkgfHwgYy5pc0pvaW5pbmcoKSkpXG4gICAgaWYoZHVwQ2hhbm5lbCl7XG4gICAgICBpZih0aGlzLmhhc0xvZ2dlcigpKSB0aGlzLmxvZyhcInRyYW5zcG9ydFwiLCBgbGVhdmluZyBkdXBsaWNhdGUgdG9waWMgXCIke3RvcGljfVwiYClcbiAgICAgIGR1cENoYW5uZWwubGVhdmUoKVxuICAgIH1cbiAgfVxufVxuIiwgImV4cG9ydCBjb25zdCBDT05TRUNVVElWRV9SRUxPQURTID0gXCJjb25zZWN1dGl2ZS1yZWxvYWRzXCJcbmV4cG9ydCBjb25zdCBNQVhfUkVMT0FEUyA9IDEwXG5leHBvcnQgY29uc3QgUkVMT0FEX0pJVFRFUl9NSU4gPSA1MDAwXG5leHBvcnQgY29uc3QgUkVMT0FEX0pJVFRFUl9NQVggPSAxMDAwMFxuZXhwb3J0IGNvbnN0IEZBSUxTQUZFX0pJVFRFUiA9IDMwMDAwXG5leHBvcnQgY29uc3QgUEhYX0VWRU5UX0NMQVNTRVMgPSBbXG4gIFwicGh4LWNsaWNrLWxvYWRpbmdcIiwgXCJwaHgtY2hhbmdlLWxvYWRpbmdcIiwgXCJwaHgtc3VibWl0LWxvYWRpbmdcIixcbiAgXCJwaHgta2V5ZG93bi1sb2FkaW5nXCIsIFwicGh4LWtleXVwLWxvYWRpbmdcIiwgXCJwaHgtYmx1ci1sb2FkaW5nXCIsIFwicGh4LWZvY3VzLWxvYWRpbmdcIixcbiAgXCJwaHgtaG9vay1sb2FkaW5nXCJcbl1cbmV4cG9ydCBjb25zdCBQSFhfQ09NUE9ORU5UID0gXCJkYXRhLXBoeC1jb21wb25lbnRcIlxuZXhwb3J0IGNvbnN0IFBIWF9MSVZFX0xJTksgPSBcImRhdGEtcGh4LWxpbmtcIlxuZXhwb3J0IGNvbnN0IFBIWF9UUkFDS19TVEFUSUMgPSBcInRyYWNrLXN0YXRpY1wiXG5leHBvcnQgY29uc3QgUEhYX0xJTktfU1RBVEUgPSBcImRhdGEtcGh4LWxpbmstc3RhdGVcIlxuZXhwb3J0IGNvbnN0IFBIWF9SRUYgPSBcImRhdGEtcGh4LXJlZlwiXG5leHBvcnQgY29uc3QgUEhYX1JFRl9TUkMgPSBcImRhdGEtcGh4LXJlZi1zcmNcIlxuZXhwb3J0IGNvbnN0IFBIWF9UUkFDS19VUExPQURTID0gXCJ0cmFjay11cGxvYWRzXCJcbmV4cG9ydCBjb25zdCBQSFhfVVBMT0FEX1JFRiA9IFwiZGF0YS1waHgtdXBsb2FkLXJlZlwiXG5leHBvcnQgY29uc3QgUEhYX1BSRUZMSUdIVEVEX1JFRlMgPSBcImRhdGEtcGh4LXByZWZsaWdodGVkLXJlZnNcIlxuZXhwb3J0IGNvbnN0IFBIWF9ET05FX1JFRlMgPSBcImRhdGEtcGh4LWRvbmUtcmVmc1wiXG5leHBvcnQgY29uc3QgUEhYX0RST1BfVEFSR0VUID0gXCJkcm9wLXRhcmdldFwiXG5leHBvcnQgY29uc3QgUEhYX0FDVElWRV9FTlRSWV9SRUZTID0gXCJkYXRhLXBoeC1hY3RpdmUtcmVmc1wiXG5leHBvcnQgY29uc3QgUEhYX0xJVkVfRklMRV9VUERBVEVEID0gXCJwaHg6bGl2ZS1maWxlOnVwZGF0ZWRcIlxuZXhwb3J0IGNvbnN0IFBIWF9TS0lQID0gXCJkYXRhLXBoeC1za2lwXCJcbmV4cG9ydCBjb25zdCBQSFhfTUFHSUNfSUQgPSBcImRhdGEtcGh4LWlkXCJcbmV4cG9ydCBjb25zdCBQSFhfUFJVTkUgPSBcImRhdGEtcGh4LXBydW5lXCJcbmV4cG9ydCBjb25zdCBQSFhfUEFHRV9MT0FESU5HID0gXCJwYWdlLWxvYWRpbmdcIlxuZXhwb3J0IGNvbnN0IFBIWF9DT05ORUNURURfQ0xBU1MgPSBcInBoeC1jb25uZWN0ZWRcIlxuZXhwb3J0IGNvbnN0IFBIWF9MT0FESU5HX0NMQVNTID0gXCJwaHgtbG9hZGluZ1wiXG5leHBvcnQgY29uc3QgUEhYX05PX0ZFRURCQUNLX0NMQVNTID0gXCJwaHgtbm8tZmVlZGJhY2tcIlxuZXhwb3J0IGNvbnN0IFBIWF9FUlJPUl9DTEFTUyA9IFwicGh4LWVycm9yXCJcbmV4cG9ydCBjb25zdCBQSFhfQ0xJRU5UX0VSUk9SX0NMQVNTID0gXCJwaHgtY2xpZW50LWVycm9yXCJcbmV4cG9ydCBjb25zdCBQSFhfU0VSVkVSX0VSUk9SX0NMQVNTID0gXCJwaHgtc2VydmVyLWVycm9yXCJcbmV4cG9ydCBjb25zdCBQSFhfUEFSRU5UX0lEID0gXCJkYXRhLXBoeC1wYXJlbnQtaWRcIlxuZXhwb3J0IGNvbnN0IFBIWF9NQUlOID0gXCJkYXRhLXBoeC1tYWluXCJcbmV4cG9ydCBjb25zdCBQSFhfUk9PVF9JRCA9IFwiZGF0YS1waHgtcm9vdC1pZFwiXG5leHBvcnQgY29uc3QgUEhYX1ZJRVdQT1JUX1RPUCA9IFwidmlld3BvcnQtdG9wXCJcbmV4cG9ydCBjb25zdCBQSFhfVklFV1BPUlRfQk9UVE9NID0gXCJ2aWV3cG9ydC1ib3R0b21cIlxuZXhwb3J0IGNvbnN0IFBIWF9UUklHR0VSX0FDVElPTiA9IFwidHJpZ2dlci1hY3Rpb25cIlxuZXhwb3J0IGNvbnN0IFBIWF9GRUVEQkFDS19GT1IgPSBcImZlZWRiYWNrLWZvclwiXG5leHBvcnQgY29uc3QgUEhYX0ZFRURCQUNLX0dST1VQID0gXCJmZWVkYmFjay1ncm91cFwiXG5leHBvcnQgY29uc3QgUEhYX0hBU19GT0NVU0VEID0gXCJwaHgtaGFzLWZvY3VzZWRcIlxuZXhwb3J0IGNvbnN0IEZPQ1VTQUJMRV9JTlBVVFMgPSBbXCJ0ZXh0XCIsIFwidGV4dGFyZWFcIiwgXCJudW1iZXJcIiwgXCJlbWFpbFwiLCBcInBhc3N3b3JkXCIsIFwic2VhcmNoXCIsIFwidGVsXCIsIFwidXJsXCIsIFwiZGF0ZVwiLCBcInRpbWVcIiwgXCJkYXRldGltZS1sb2NhbFwiLCBcImNvbG9yXCIsIFwicmFuZ2VcIl1cbmV4cG9ydCBjb25zdCBDSEVDS0FCTEVfSU5QVVRTID0gW1wiY2hlY2tib3hcIiwgXCJyYWRpb1wiXVxuZXhwb3J0IGNvbnN0IFBIWF9IQVNfU1VCTUlUVEVEID0gXCJwaHgtaGFzLXN1Ym1pdHRlZFwiXG5leHBvcnQgY29uc3QgUEhYX1NFU1NJT04gPSBcImRhdGEtcGh4LXNlc3Npb25cIlxuZXhwb3J0IGNvbnN0IFBIWF9WSUVXX1NFTEVDVE9SID0gYFske1BIWF9TRVNTSU9OfV1gXG5leHBvcnQgY29uc3QgUEhYX1NUSUNLWSA9IFwiZGF0YS1waHgtc3RpY2t5XCJcbmV4cG9ydCBjb25zdCBQSFhfU1RBVElDID0gXCJkYXRhLXBoeC1zdGF0aWNcIlxuZXhwb3J0IGNvbnN0IFBIWF9SRUFET05MWSA9IFwiZGF0YS1waHgtcmVhZG9ubHlcIlxuZXhwb3J0IGNvbnN0IFBIWF9ESVNBQkxFRCA9IFwiZGF0YS1waHgtZGlzYWJsZWRcIlxuZXhwb3J0IGNvbnN0IFBIWF9ESVNBQkxFX1dJVEggPSBcImRpc2FibGUtd2l0aFwiXG5leHBvcnQgY29uc3QgUEhYX0RJU0FCTEVfV0lUSF9SRVNUT1JFID0gXCJkYXRhLXBoeC1kaXNhYmxlLXdpdGgtcmVzdG9yZVwiXG5leHBvcnQgY29uc3QgUEhYX0hPT0sgPSBcImhvb2tcIlxuZXhwb3J0IGNvbnN0IFBIWF9ERUJPVU5DRSA9IFwiZGVib3VuY2VcIlxuZXhwb3J0IGNvbnN0IFBIWF9USFJPVFRMRSA9IFwidGhyb3R0bGVcIlxuZXhwb3J0IGNvbnN0IFBIWF9VUERBVEUgPSBcInVwZGF0ZVwiXG5leHBvcnQgY29uc3QgUEhYX1NUUkVBTSA9IFwic3RyZWFtXCJcbmV4cG9ydCBjb25zdCBQSFhfU1RSRUFNX1JFRiA9IFwiZGF0YS1waHgtc3RyZWFtXCJcbmV4cG9ydCBjb25zdCBQSFhfS0VZID0gXCJrZXlcIlxuZXhwb3J0IGNvbnN0IFBIWF9QUklWQVRFID0gXCJwaHhQcml2YXRlXCJcbmV4cG9ydCBjb25zdCBQSFhfQVVUT19SRUNPVkVSID0gXCJhdXRvLXJlY292ZXJcIlxuZXhwb3J0IGNvbnN0IFBIWF9MVl9ERUJVRyA9IFwicGh4OmxpdmUtc29ja2V0OmRlYnVnXCJcbmV4cG9ydCBjb25zdCBQSFhfTFZfUFJPRklMRSA9IFwicGh4OmxpdmUtc29ja2V0OnByb2ZpbGluZ1wiXG5leHBvcnQgY29uc3QgUEhYX0xWX0xBVEVOQ1lfU0lNID0gXCJwaHg6bGl2ZS1zb2NrZXQ6bGF0ZW5jeS1zaW1cIlxuZXhwb3J0IGNvbnN0IFBIWF9QUk9HUkVTUyA9IFwicHJvZ3Jlc3NcIlxuZXhwb3J0IGNvbnN0IFBIWF9NT1VOVEVEID0gXCJtb3VudGVkXCJcbmV4cG9ydCBjb25zdCBMT0FERVJfVElNRU9VVCA9IDFcbmV4cG9ydCBjb25zdCBCRUZPUkVfVU5MT0FEX0xPQURFUl9USU1FT1VUID0gMjAwXG5leHBvcnQgY29uc3QgQklORElOR19QUkVGSVggPSBcInBoeC1cIlxuZXhwb3J0IGNvbnN0IFBVU0hfVElNRU9VVCA9IDMwMDAwXG5leHBvcnQgY29uc3QgTElOS19IRUFERVIgPSBcIngtcmVxdWVzdGVkLXdpdGhcIlxuZXhwb3J0IGNvbnN0IFJFU1BPTlNFX1VSTF9IRUFERVIgPSBcIngtcmVzcG9uc2UtdXJsXCJcbmV4cG9ydCBjb25zdCBERUJPVU5DRV9UUklHR0VSID0gXCJkZWJvdW5jZS10cmlnZ2VyXCJcbmV4cG9ydCBjb25zdCBUSFJPVFRMRUQgPSBcInRocm90dGxlZFwiXG5leHBvcnQgY29uc3QgREVCT1VOQ0VfUFJFVl9LRVkgPSBcImRlYm91bmNlLXByZXYta2V5XCJcbmV4cG9ydCBjb25zdCBERUZBVUxUUyA9IHtcbiAgZGVib3VuY2U6IDMwMCxcbiAgdGhyb3R0bGU6IDMwMFxufVxuXG4vLyBSZW5kZXJlZFxuZXhwb3J0IGNvbnN0IERZTkFNSUNTID0gXCJkXCJcbmV4cG9ydCBjb25zdCBTVEFUSUMgPSBcInNcIlxuZXhwb3J0IGNvbnN0IFJPT1QgPSBcInJcIlxuZXhwb3J0IGNvbnN0IENPTVBPTkVOVFMgPSBcImNcIlxuZXhwb3J0IGNvbnN0IEVWRU5UUyA9IFwiZVwiXG5leHBvcnQgY29uc3QgUkVQTFkgPSBcInJcIlxuZXhwb3J0IGNvbnN0IFRJVExFID0gXCJ0XCJcbmV4cG9ydCBjb25zdCBURU1QTEFURVMgPSBcInBcIlxuZXhwb3J0IGNvbnN0IFNUUkVBTSA9IFwic3RyZWFtXCIiLCAiaW1wb3J0IHtcbiAgbG9nRXJyb3Jcbn0gZnJvbSBcIi4vdXRpbHNcIlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFbnRyeVVwbG9hZGVyIHtcbiAgY29uc3RydWN0b3IoZW50cnksIGNodW5rU2l6ZSwgbGl2ZVNvY2tldCl7XG4gICAgdGhpcy5saXZlU29ja2V0ID0gbGl2ZVNvY2tldFxuICAgIHRoaXMuZW50cnkgPSBlbnRyeVxuICAgIHRoaXMub2Zmc2V0ID0gMFxuICAgIHRoaXMuY2h1bmtTaXplID0gY2h1bmtTaXplXG4gICAgdGhpcy5jaHVua1RpbWVyID0gbnVsbFxuICAgIHRoaXMuZXJyb3JlZCA9IGZhbHNlXG4gICAgdGhpcy51cGxvYWRDaGFubmVsID0gbGl2ZVNvY2tldC5jaGFubmVsKGBsdnU6JHtlbnRyeS5yZWZ9YCwge3Rva2VuOiBlbnRyeS5tZXRhZGF0YSgpfSlcbiAgfVxuXG4gIGVycm9yKHJlYXNvbil7XG4gICAgaWYodGhpcy5lcnJvcmVkKXsgcmV0dXJuIH1cbiAgICB0aGlzLnVwbG9hZENoYW5uZWwubGVhdmUoKVxuICAgIHRoaXMuZXJyb3JlZCA9IHRydWVcbiAgICBjbGVhclRpbWVvdXQodGhpcy5jaHVua1RpbWVyKVxuICAgIHRoaXMuZW50cnkuZXJyb3IocmVhc29uKVxuICB9XG5cbiAgdXBsb2FkKCl7XG4gICAgdGhpcy51cGxvYWRDaGFubmVsLm9uRXJyb3IocmVhc29uID0+IHRoaXMuZXJyb3IocmVhc29uKSlcbiAgICB0aGlzLnVwbG9hZENoYW5uZWwuam9pbigpXG4gICAgICAucmVjZWl2ZShcIm9rXCIsIF9kYXRhID0+IHRoaXMucmVhZE5leHRDaHVuaygpKVxuICAgICAgLnJlY2VpdmUoXCJlcnJvclwiLCByZWFzb24gPT4gdGhpcy5lcnJvcihyZWFzb24pKVxuICB9XG5cbiAgaXNEb25lKCl7IHJldHVybiB0aGlzLm9mZnNldCA+PSB0aGlzLmVudHJ5LmZpbGUuc2l6ZSB9XG5cbiAgcmVhZE5leHRDaHVuaygpe1xuICAgIGxldCByZWFkZXIgPSBuZXcgd2luZG93LkZpbGVSZWFkZXIoKVxuICAgIGxldCBibG9iID0gdGhpcy5lbnRyeS5maWxlLnNsaWNlKHRoaXMub2Zmc2V0LCB0aGlzLmNodW5rU2l6ZSArIHRoaXMub2Zmc2V0KVxuICAgIHJlYWRlci5vbmxvYWQgPSAoZSkgPT4ge1xuICAgICAgaWYoZS50YXJnZXQuZXJyb3IgPT09IG51bGwpe1xuICAgICAgICB0aGlzLm9mZnNldCArPSBlLnRhcmdldC5yZXN1bHQuYnl0ZUxlbmd0aFxuICAgICAgICB0aGlzLnB1c2hDaHVuayhlLnRhcmdldC5yZXN1bHQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbG9nRXJyb3IoXCJSZWFkIGVycm9yOiBcIiArIGUudGFyZ2V0LmVycm9yKVxuICAgICAgfVxuICAgIH1cbiAgICByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoYmxvYilcbiAgfVxuXG4gIHB1c2hDaHVuayhjaHVuayl7XG4gICAgaWYoIXRoaXMudXBsb2FkQ2hhbm5lbC5pc0pvaW5lZCgpKXsgcmV0dXJuIH1cbiAgICB0aGlzLnVwbG9hZENoYW5uZWwucHVzaChcImNodW5rXCIsIGNodW5rKVxuICAgICAgLnJlY2VpdmUoXCJva1wiLCAoKSA9PiB7XG4gICAgICAgIHRoaXMuZW50cnkucHJvZ3Jlc3MoKHRoaXMub2Zmc2V0IC8gdGhpcy5lbnRyeS5maWxlLnNpemUpICogMTAwKVxuICAgICAgICBpZighdGhpcy5pc0RvbmUoKSl7XG4gICAgICAgICAgdGhpcy5jaHVua1RpbWVyID0gc2V0VGltZW91dCgoKSA9PiB0aGlzLnJlYWROZXh0Q2h1bmsoKSwgdGhpcy5saXZlU29ja2V0LmdldExhdGVuY3lTaW0oKSB8fCAwKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLnJlY2VpdmUoXCJlcnJvclwiLCAoe3JlYXNvbn0pID0+IHRoaXMuZXJyb3IocmVhc29uKSlcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIFBIWF9WSUVXX1NFTEVDVE9SXG59IGZyb20gXCIuL2NvbnN0YW50c1wiXG5cbmltcG9ydCBFbnRyeVVwbG9hZGVyIGZyb20gXCIuL2VudHJ5X3VwbG9hZGVyXCJcblxuZXhwb3J0IGxldCBsb2dFcnJvciA9IChtc2csIG9iaikgPT4gY29uc29sZS5lcnJvciAmJiBjb25zb2xlLmVycm9yKG1zZywgb2JqKVxuXG5leHBvcnQgbGV0IGlzQ2lkID0gKGNpZCkgPT4ge1xuICBsZXQgdHlwZSA9IHR5cGVvZihjaWQpXG4gIHJldHVybiB0eXBlID09PSBcIm51bWJlclwiIHx8ICh0eXBlID09PSBcInN0cmluZ1wiICYmIC9eKDB8WzEtOV1cXGQqKSQvLnRlc3QoY2lkKSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRldGVjdER1cGxpY2F0ZUlkcygpe1xuICBsZXQgaWRzID0gbmV3IFNldCgpXG4gIGxldCBlbGVtcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIqW2lkXVwiKVxuICBmb3IobGV0IGkgPSAwLCBsZW4gPSBlbGVtcy5sZW5ndGg7IGkgPCBsZW47IGkrKyl7XG4gICAgaWYoaWRzLmhhcyhlbGVtc1tpXS5pZCkpe1xuICAgICAgY29uc29sZS5lcnJvcihgTXVsdGlwbGUgSURzIGRldGVjdGVkOiAke2VsZW1zW2ldLmlkfS4gRW5zdXJlIHVuaXF1ZSBlbGVtZW50IGlkcy5gKVxuICAgIH0gZWxzZSB7XG4gICAgICBpZHMuYWRkKGVsZW1zW2ldLmlkKVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgbGV0IGRlYnVnID0gKHZpZXcsIGtpbmQsIG1zZywgb2JqKSA9PiB7XG4gIGlmKHZpZXcubGl2ZVNvY2tldC5pc0RlYnVnRW5hYmxlZCgpKXtcbiAgICBjb25zb2xlLmxvZyhgJHt2aWV3LmlkfSAke2tpbmR9OiAke21zZ30gLSBgLCBvYmopXG4gIH1cbn1cblxuLy8gd3JhcHMgdmFsdWUgaW4gY2xvc3VyZSBvciByZXR1cm5zIGNsb3N1cmVcbmV4cG9ydCBsZXQgY2xvc3VyZSA9ICh2YWwpID0+IHR5cGVvZiB2YWwgPT09IFwiZnVuY3Rpb25cIiA/IHZhbCA6IGZ1bmN0aW9uICgpeyByZXR1cm4gdmFsIH1cblxuZXhwb3J0IGxldCBjbG9uZSA9IChvYmopID0+IHsgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkob2JqKSkgfVxuXG5leHBvcnQgbGV0IGNsb3Nlc3RQaHhCaW5kaW5nID0gKGVsLCBiaW5kaW5nLCBib3JkZXJFbCkgPT4ge1xuICBkbyB7XG4gICAgaWYoZWwubWF0Y2hlcyhgWyR7YmluZGluZ31dYCkgJiYgIWVsLmRpc2FibGVkKXsgcmV0dXJuIGVsIH1cbiAgICBlbCA9IGVsLnBhcmVudEVsZW1lbnQgfHwgZWwucGFyZW50Tm9kZVxuICB9IHdoaWxlKGVsICE9PSBudWxsICYmIGVsLm5vZGVUeXBlID09PSAxICYmICEoKGJvcmRlckVsICYmIGJvcmRlckVsLmlzU2FtZU5vZGUoZWwpKSB8fCBlbC5tYXRjaGVzKFBIWF9WSUVXX1NFTEVDVE9SKSkpXG4gIHJldHVybiBudWxsXG59XG5cbmV4cG9ydCBsZXQgaXNPYmplY3QgPSAob2JqKSA9PiB7XG4gIHJldHVybiBvYmogIT09IG51bGwgJiYgdHlwZW9mIG9iaiA9PT0gXCJvYmplY3RcIiAmJiAhKG9iaiBpbnN0YW5jZW9mIEFycmF5KVxufVxuXG5leHBvcnQgbGV0IGlzRXF1YWxPYmogPSAob2JqMSwgb2JqMikgPT4gSlNPTi5zdHJpbmdpZnkob2JqMSkgPT09IEpTT04uc3RyaW5naWZ5KG9iajIpXG5cbmV4cG9ydCBsZXQgaXNFbXB0eSA9IChvYmopID0+IHtcbiAgZm9yKGxldCB4IGluIG9iail7IHJldHVybiBmYWxzZSB9XG4gIHJldHVybiB0cnVlXG59XG5cbmV4cG9ydCBsZXQgbWF5YmUgPSAoZWwsIGNhbGxiYWNrKSA9PiBlbCAmJiBjYWxsYmFjayhlbClcblxuZXhwb3J0IGxldCBjaGFubmVsVXBsb2FkZXIgPSBmdW5jdGlvbiAoZW50cmllcywgb25FcnJvciwgcmVzcCwgbGl2ZVNvY2tldCl7XG4gIGVudHJpZXMuZm9yRWFjaChlbnRyeSA9PiB7XG4gICAgbGV0IGVudHJ5VXBsb2FkZXIgPSBuZXcgRW50cnlVcGxvYWRlcihlbnRyeSwgcmVzcC5jb25maWcuY2h1bmtfc2l6ZSwgbGl2ZVNvY2tldClcbiAgICBlbnRyeVVwbG9hZGVyLnVwbG9hZCgpXG4gIH0pXG59XG4iLCAibGV0IEJyb3dzZXIgPSB7XG4gIGNhblB1c2hTdGF0ZSgpeyByZXR1cm4gKHR5cGVvZiAoaGlzdG9yeS5wdXNoU3RhdGUpICE9PSBcInVuZGVmaW5lZFwiKSB9LFxuXG4gIGRyb3BMb2NhbChsb2NhbFN0b3JhZ2UsIG5hbWVzcGFjZSwgc3Via2V5KXtcbiAgICByZXR1cm4gbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0odGhpcy5sb2NhbEtleShuYW1lc3BhY2UsIHN1YmtleSkpXG4gIH0sXG5cbiAgdXBkYXRlTG9jYWwobG9jYWxTdG9yYWdlLCBuYW1lc3BhY2UsIHN1YmtleSwgaW5pdGlhbCwgZnVuYyl7XG4gICAgbGV0IGN1cnJlbnQgPSB0aGlzLmdldExvY2FsKGxvY2FsU3RvcmFnZSwgbmFtZXNwYWNlLCBzdWJrZXkpXG4gICAgbGV0IGtleSA9IHRoaXMubG9jYWxLZXkobmFtZXNwYWNlLCBzdWJrZXkpXG4gICAgbGV0IG5ld1ZhbCA9IGN1cnJlbnQgPT09IG51bGwgPyBpbml0aWFsIDogZnVuYyhjdXJyZW50KVxuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKGtleSwgSlNPTi5zdHJpbmdpZnkobmV3VmFsKSlcbiAgICByZXR1cm4gbmV3VmFsXG4gIH0sXG5cbiAgZ2V0TG9jYWwobG9jYWxTdG9yYWdlLCBuYW1lc3BhY2UsIHN1YmtleSl7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5sb2NhbEtleShuYW1lc3BhY2UsIHN1YmtleSkpKVxuICB9LFxuXG4gIHVwZGF0ZUN1cnJlbnRTdGF0ZShjYWxsYmFjayl7XG4gICAgaWYoIXRoaXMuY2FuUHVzaFN0YXRlKCkpeyByZXR1cm4gfVxuICAgIGhpc3RvcnkucmVwbGFjZVN0YXRlKGNhbGxiYWNrKGhpc3Rvcnkuc3RhdGUgfHwge30pLCBcIlwiLCB3aW5kb3cubG9jYXRpb24uaHJlZilcbiAgfSxcblxuICBwdXNoU3RhdGUoa2luZCwgbWV0YSwgdG8pe1xuICAgIGlmKHRoaXMuY2FuUHVzaFN0YXRlKCkpe1xuICAgICAgaWYodG8gIT09IHdpbmRvdy5sb2NhdGlvbi5ocmVmKXtcbiAgICAgICAgaWYobWV0YS50eXBlID09IFwicmVkaXJlY3RcIiAmJiBtZXRhLnNjcm9sbCl7XG4gICAgICAgICAgLy8gSWYgd2UncmUgcmVkaXJlY3Rpbmcgc3RvcmUgdGhlIGN1cnJlbnQgc2Nyb2xsWSBmb3IgdGhlIGN1cnJlbnQgaGlzdG9yeSBzdGF0ZS5cbiAgICAgICAgICBsZXQgY3VycmVudFN0YXRlID0gaGlzdG9yeS5zdGF0ZSB8fCB7fVxuICAgICAgICAgIGN1cnJlbnRTdGF0ZS5zY3JvbGwgPSBtZXRhLnNjcm9sbFxuICAgICAgICAgIGhpc3RvcnkucmVwbGFjZVN0YXRlKGN1cnJlbnRTdGF0ZSwgXCJcIiwgd2luZG93LmxvY2F0aW9uLmhyZWYpXG4gICAgICAgIH1cblxuICAgICAgICBkZWxldGUgbWV0YS5zY3JvbGwgLy8gT25seSBzdG9yZSB0aGUgc2Nyb2xsIGluIHRoZSByZWRpcmVjdCBjYXNlLlxuICAgICAgICBoaXN0b3J5W2tpbmQgKyBcIlN0YXRlXCJdKG1ldGEsIFwiXCIsIHRvIHx8IG51bGwpIC8vIElFIHdpbGwgY29lcmNlIHVuZGVmaW5lZCB0byBzdHJpbmdcbiAgICAgICAgbGV0IGhhc2hFbCA9IHRoaXMuZ2V0SGFzaFRhcmdldEVsKHdpbmRvdy5sb2NhdGlvbi5oYXNoKVxuXG4gICAgICAgIGlmKGhhc2hFbCl7XG4gICAgICAgICAgaGFzaEVsLnNjcm9sbEludG9WaWV3KClcbiAgICAgICAgfSBlbHNlIGlmKG1ldGEudHlwZSA9PT0gXCJyZWRpcmVjdFwiKXtcbiAgICAgICAgICB3aW5kb3cuc2Nyb2xsKDAsIDApXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yZWRpcmVjdCh0bylcbiAgICB9XG4gIH0sXG5cbiAgc2V0Q29va2llKG5hbWUsIHZhbHVlKXtcbiAgICBkb2N1bWVudC5jb29raWUgPSBgJHtuYW1lfT0ke3ZhbHVlfWBcbiAgfSxcblxuICBnZXRDb29raWUobmFtZSl7XG4gICAgcmV0dXJuIGRvY3VtZW50LmNvb2tpZS5yZXBsYWNlKG5ldyBSZWdFeHAoYCg/Oig/Ol58Lio7XFxzKikke25hbWV9XFxzKlxcPVxccyooW147XSopLiokKXxeLiokYCksIFwiJDFcIilcbiAgfSxcblxuICByZWRpcmVjdCh0b1VSTCwgZmxhc2gpe1xuICAgIGlmKGZsYXNoKXsgQnJvd3Nlci5zZXRDb29raWUoXCJfX3Bob2VuaXhfZmxhc2hfX1wiLCBmbGFzaCArIFwiOyBtYXgtYWdlPTYwMDAwOyBwYXRoPS9cIikgfVxuICAgIHdpbmRvdy5sb2NhdGlvbiA9IHRvVVJMXG4gIH0sXG5cbiAgbG9jYWxLZXkobmFtZXNwYWNlLCBzdWJrZXkpeyByZXR1cm4gYCR7bmFtZXNwYWNlfS0ke3N1YmtleX1gIH0sXG5cbiAgZ2V0SGFzaFRhcmdldEVsKG1heWJlSGFzaCl7XG4gICAgbGV0IGhhc2ggPSBtYXliZUhhc2gudG9TdHJpbmcoKS5zdWJzdHJpbmcoMSlcbiAgICBpZihoYXNoID09PSBcIlwiKXsgcmV0dXJuIH1cbiAgICByZXR1cm4gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaGFzaCkgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgYVtuYW1lPVwiJHtoYXNofVwiXWApXG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQnJvd3NlclxuIiwgImxldCBBUklBID0ge1xuICBmb2N1c01haW4oKXtcbiAgICBsZXQgdGFyZ2V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIm1haW4gaDEsIG1haW4sIGgxXCIpXG4gICAgaWYodGFyZ2V0KXtcbiAgICAgIGxldCBvcmlnVGFiSW5kZXggPSB0YXJnZXQudGFiSW5kZXhcbiAgICAgIHRhcmdldC50YWJJbmRleCA9IC0xXG4gICAgICB0YXJnZXQuZm9jdXMoKVxuICAgICAgdGFyZ2V0LnRhYkluZGV4ID0gb3JpZ1RhYkluZGV4XG4gICAgfVxuICB9LFxuXG4gIGFueU9mKGluc3RhbmNlLCBjbGFzc2VzKXsgcmV0dXJuIGNsYXNzZXMuZmluZChuYW1lID0+IGluc3RhbmNlIGluc3RhbmNlb2YgbmFtZSkgfSxcblxuICBpc0ZvY3VzYWJsZShlbCwgaW50ZXJhY3RpdmVPbmx5KXtcbiAgICByZXR1cm4oXG4gICAgICAoZWwgaW5zdGFuY2VvZiBIVE1MQW5jaG9yRWxlbWVudCAmJiBlbC5yZWwgIT09IFwiaWdub3JlXCIpIHx8XG4gICAgICAoZWwgaW5zdGFuY2VvZiBIVE1MQXJlYUVsZW1lbnQgJiYgZWwuaHJlZiAhPT0gdW5kZWZpbmVkKSB8fFxuICAgICAgKCFlbC5kaXNhYmxlZCAmJiAodGhpcy5hbnlPZihlbCwgW0hUTUxJbnB1dEVsZW1lbnQsIEhUTUxTZWxlY3RFbGVtZW50LCBIVE1MVGV4dEFyZWFFbGVtZW50LCBIVE1MQnV0dG9uRWxlbWVudF0pKSkgfHxcbiAgICAgIChlbCBpbnN0YW5jZW9mIEhUTUxJRnJhbWVFbGVtZW50KSB8fFxuICAgICAgKGVsLnRhYkluZGV4ID4gMCB8fCAoIWludGVyYWN0aXZlT25seSAmJiBlbC5nZXRBdHRyaWJ1dGUoXCJ0YWJpbmRleFwiKSAhPT0gbnVsbCAmJiBlbC5nZXRBdHRyaWJ1dGUoXCJhcmlhLWhpZGRlblwiKSAhPT0gXCJ0cnVlXCIpKVxuICAgIClcbiAgfSxcblxuICBhdHRlbXB0Rm9jdXMoZWwsIGludGVyYWN0aXZlT25seSl7XG4gICAgaWYodGhpcy5pc0ZvY3VzYWJsZShlbCwgaW50ZXJhY3RpdmVPbmx5KSl7IHRyeXsgZWwuZm9jdXMoKSB9IGNhdGNoKGUpe30gfVxuICAgIHJldHVybiAhIWRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgJiYgZG9jdW1lbnQuYWN0aXZlRWxlbWVudC5pc1NhbWVOb2RlKGVsKVxuICB9LFxuXG4gIGZvY3VzRmlyc3RJbnRlcmFjdGl2ZShlbCl7XG4gICAgbGV0IGNoaWxkID0gZWwuZmlyc3RFbGVtZW50Q2hpbGRcbiAgICB3aGlsZShjaGlsZCl7XG4gICAgICBpZih0aGlzLmF0dGVtcHRGb2N1cyhjaGlsZCwgdHJ1ZSkgfHwgdGhpcy5mb2N1c0ZpcnN0SW50ZXJhY3RpdmUoY2hpbGQsIHRydWUpKXtcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH1cbiAgICAgIGNoaWxkID0gY2hpbGQubmV4dEVsZW1lbnRTaWJsaW5nXG4gICAgfVxuICB9LFxuXG4gIGZvY3VzRmlyc3QoZWwpe1xuICAgIGxldCBjaGlsZCA9IGVsLmZpcnN0RWxlbWVudENoaWxkXG4gICAgd2hpbGUoY2hpbGQpe1xuICAgICAgaWYodGhpcy5hdHRlbXB0Rm9jdXMoY2hpbGQpIHx8IHRoaXMuZm9jdXNGaXJzdChjaGlsZCkpe1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuICAgICAgY2hpbGQgPSBjaGlsZC5uZXh0RWxlbWVudFNpYmxpbmdcbiAgICB9XG4gIH0sXG5cbiAgZm9jdXNMYXN0KGVsKXtcbiAgICBsZXQgY2hpbGQgPSBlbC5sYXN0RWxlbWVudENoaWxkXG4gICAgd2hpbGUoY2hpbGQpe1xuICAgICAgaWYodGhpcy5hdHRlbXB0Rm9jdXMoY2hpbGQpIHx8IHRoaXMuZm9jdXNMYXN0KGNoaWxkKSl7XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgICB9XG4gICAgICBjaGlsZCA9IGNoaWxkLnByZXZpb3VzRWxlbWVudFNpYmxpbmdcbiAgICB9XG4gIH1cbn1cbmV4cG9ydCBkZWZhdWx0IEFSSUEiLCAiaW1wb3J0IERPTSBmcm9tIFwiLi9kb21cIlxuaW1wb3J0IEFSSUEgZnJvbSBcIi4vYXJpYVwiXG5cbmxldCBmb2N1c1N0YWNrID0gW11cbmxldCBkZWZhdWx0X3RyYW5zaXRpb25fdGltZSA9IDIwMFxuXG5sZXQgSlMgPSB7XG4gIGV4ZWMoZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGRlZmF1bHRzKXtcbiAgICBsZXQgW2RlZmF1bHRLaW5kLCBkZWZhdWx0QXJnc10gPSBkZWZhdWx0cyB8fCBbbnVsbCwge2NhbGxiYWNrOiBkZWZhdWx0cyAmJiBkZWZhdWx0cy5jYWxsYmFja31dXG4gICAgbGV0IGNvbW1hbmRzID0gcGh4RXZlbnQuY2hhckF0KDApID09PSBcIltcIiA/XG4gICAgICBKU09OLnBhcnNlKHBoeEV2ZW50KSA6IFtbZGVmYXVsdEtpbmQsIGRlZmF1bHRBcmdzXV1cblxuICAgIGNvbW1hbmRzLmZvckVhY2goKFtraW5kLCBhcmdzXSkgPT4ge1xuICAgICAgaWYoa2luZCA9PT0gZGVmYXVsdEtpbmQgJiYgZGVmYXVsdEFyZ3MuZGF0YSl7XG4gICAgICAgIGFyZ3MuZGF0YSA9IE9iamVjdC5hc3NpZ24oYXJncy5kYXRhIHx8IHt9LCBkZWZhdWx0QXJncy5kYXRhKVxuICAgICAgICBhcmdzLmNhbGxiYWNrID0gYXJncy5jYWxsYmFjayB8fCBkZWZhdWx0QXJncy5jYWxsYmFja1xuICAgICAgfVxuICAgICAgdGhpcy5maWx0ZXJUb0Vscyhzb3VyY2VFbCwgYXJncykuZm9yRWFjaChlbCA9PiB7XG4gICAgICAgIHRoaXNbYGV4ZWNfJHtraW5kfWBdKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwgYXJncylcbiAgICAgIH0pXG4gICAgfSlcbiAgfSxcblxuICBpc1Zpc2libGUoZWwpe1xuICAgIHJldHVybiAhIShlbC5vZmZzZXRXaWR0aCB8fCBlbC5vZmZzZXRIZWlnaHQgfHwgZWwuZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGggPiAwKVxuICB9LFxuXG4gIC8vIHJldHVybnMgdHJ1ZSBpZiBhbnkgcGFydCBvZiB0aGUgZWxlbWVudCBpcyBpbnNpZGUgdGhlIHZpZXdwb3J0XG4gIGlzSW5WaWV3cG9ydChlbCl7XG4gICAgY29uc3QgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgY29uc3Qgd2luZG93SGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHRcbiAgICBjb25zdCB3aW5kb3dXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aFxuXG4gICAgcmV0dXJuIChcbiAgICAgIHJlY3QucmlnaHQgPiAwICYmXG4gICAgICByZWN0LmJvdHRvbSA+IDAgJiZcbiAgICAgIHJlY3QubGVmdCA8IHdpbmRvd1dpZHRoICYmXG4gICAgICByZWN0LnRvcCA8IHdpbmRvd0hlaWdodFxuICAgIClcbiAgfSxcblxuICAvLyBwcml2YXRlXG5cbiAgLy8gY29tbWFuZHNcblxuICBleGVjX2V4ZWMoZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7YXR0ciwgdG99KXtcbiAgICBsZXQgbm9kZXMgPSB0byA/IERPTS5hbGwoZG9jdW1lbnQsIHRvKSA6IFtzb3VyY2VFbF1cbiAgICBub2Rlcy5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgbGV0IGVuY29kZWRKUyA9IG5vZGUuZ2V0QXR0cmlidXRlKGF0dHIpXG4gICAgICBpZighZW5jb2RlZEpTKXsgdGhyb3cgbmV3IEVycm9yKGBleHBlY3RlZCAke2F0dHJ9IHRvIGNvbnRhaW4gSlMgY29tbWFuZCBvbiBcIiR7dG99XCJgKSB9XG4gICAgICB2aWV3LmxpdmVTb2NrZXQuZXhlY0pTKG5vZGUsIGVuY29kZWRKUywgZXZlbnRUeXBlKVxuICAgIH0pXG4gIH0sXG5cbiAgZXhlY19kaXNwYXRjaChldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHt0bywgZXZlbnQsIGRldGFpbCwgYnViYmxlc30pe1xuICAgIGRldGFpbCA9IGRldGFpbCB8fCB7fVxuICAgIGRldGFpbC5kaXNwYXRjaGVyID0gc291cmNlRWxcbiAgICBET00uZGlzcGF0Y2hFdmVudChlbCwgZXZlbnQsIHtkZXRhaWwsIGJ1YmJsZXN9KVxuICB9LFxuXG4gIGV4ZWNfcHVzaChldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIGFyZ3Mpe1xuICAgIGxldCB7ZXZlbnQsIGRhdGEsIHRhcmdldCwgcGFnZV9sb2FkaW5nLCBsb2FkaW5nLCB2YWx1ZSwgZGlzcGF0Y2hlciwgY2FsbGJhY2t9ID0gYXJnc1xuICAgIGxldCBwdXNoT3B0cyA9IHtsb2FkaW5nLCB2YWx1ZSwgdGFyZ2V0LCBwYWdlX2xvYWRpbmc6ICEhcGFnZV9sb2FkaW5nfVxuICAgIGxldCB0YXJnZXRTcmMgPSBldmVudFR5cGUgPT09IFwiY2hhbmdlXCIgJiYgZGlzcGF0Y2hlciA/IGRpc3BhdGNoZXIgOiBzb3VyY2VFbFxuICAgIGxldCBwaHhUYXJnZXQgPSB0YXJnZXQgfHwgdGFyZ2V0U3JjLmdldEF0dHJpYnV0ZSh2aWV3LmJpbmRpbmcoXCJ0YXJnZXRcIikpIHx8IHRhcmdldFNyY1xuICAgIHZpZXcud2l0aGluVGFyZ2V0cyhwaHhUYXJnZXQsICh0YXJnZXRWaWV3LCB0YXJnZXRDdHgpID0+IHtcbiAgICAgIGlmKCF0YXJnZXRWaWV3LmlzQ29ubmVjdGVkKCkpeyByZXR1cm4gfVxuICAgICAgaWYoZXZlbnRUeXBlID09PSBcImNoYW5nZVwiKXtcbiAgICAgICAgbGV0IHtuZXdDaWQsIF90YXJnZXR9ID0gYXJnc1xuICAgICAgICBfdGFyZ2V0ID0gX3RhcmdldCB8fCAoRE9NLmlzRm9ybUlucHV0KHNvdXJjZUVsKSA/IHNvdXJjZUVsLm5hbWUgOiB1bmRlZmluZWQpXG4gICAgICAgIGlmKF90YXJnZXQpeyBwdXNoT3B0cy5fdGFyZ2V0ID0gX3RhcmdldCB9XG4gICAgICAgIHRhcmdldFZpZXcucHVzaElucHV0KHNvdXJjZUVsLCB0YXJnZXRDdHgsIG5ld0NpZCwgZXZlbnQgfHwgcGh4RXZlbnQsIHB1c2hPcHRzLCBjYWxsYmFjaylcbiAgICAgIH0gZWxzZSBpZihldmVudFR5cGUgPT09IFwic3VibWl0XCIpe1xuICAgICAgICBsZXQge3N1Ym1pdHRlcn0gPSBhcmdzXG4gICAgICAgIHRhcmdldFZpZXcuc3VibWl0Rm9ybShzb3VyY2VFbCwgdGFyZ2V0Q3R4LCBldmVudCB8fCBwaHhFdmVudCwgc3VibWl0dGVyLCBwdXNoT3B0cywgY2FsbGJhY2spXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0YXJnZXRWaWV3LnB1c2hFdmVudChldmVudFR5cGUsIHNvdXJjZUVsLCB0YXJnZXRDdHgsIGV2ZW50IHx8IHBoeEV2ZW50LCBkYXRhLCBwdXNoT3B0cywgY2FsbGJhY2spXG4gICAgICB9XG4gICAgfSlcbiAgfSxcblxuICBleGVjX25hdmlnYXRlKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwge2hyZWYsIHJlcGxhY2V9KXtcbiAgICB2aWV3LmxpdmVTb2NrZXQuaGlzdG9yeVJlZGlyZWN0KGhyZWYsIHJlcGxhY2UgPyBcInJlcGxhY2VcIiA6IFwicHVzaFwiKVxuICB9LFxuXG4gIGV4ZWNfcGF0Y2goZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7aHJlZiwgcmVwbGFjZX0pe1xuICAgIHZpZXcubGl2ZVNvY2tldC5wdXNoSGlzdG9yeVBhdGNoKGhyZWYsIHJlcGxhY2UgPyBcInJlcGxhY2VcIiA6IFwicHVzaFwiLCBzb3VyY2VFbClcbiAgfSxcblxuICBleGVjX2ZvY3VzKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCl7XG4gICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiBBUklBLmF0dGVtcHRGb2N1cyhlbCkpXG4gIH0sXG5cbiAgZXhlY19mb2N1c19maXJzdChldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwpe1xuICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gQVJJQS5mb2N1c0ZpcnN0SW50ZXJhY3RpdmUoZWwpIHx8IEFSSUEuZm9jdXNGaXJzdChlbCkpXG4gIH0sXG5cbiAgZXhlY19wdXNoX2ZvY3VzKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCl7XG4gICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiBmb2N1c1N0YWNrLnB1c2goZWwgfHwgc291cmNlRWwpKVxuICB9LFxuXG4gIGV4ZWNfcG9wX2ZvY3VzKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCl7XG4gICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICBjb25zdCBlbCA9IGZvY3VzU3RhY2sucG9wKClcbiAgICAgIGlmKGVsKXsgZWwuZm9jdXMoKSB9XG4gICAgfSlcbiAgfSxcblxuICBleGVjX2FkZF9jbGFzcyhldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHtuYW1lcywgdHJhbnNpdGlvbiwgdGltZX0pe1xuICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBuYW1lcywgW10sIHRyYW5zaXRpb24sIHRpbWUsIHZpZXcpXG4gIH0sXG5cbiAgZXhlY19yZW1vdmVfY2xhc3MoZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7bmFtZXMsIHRyYW5zaXRpb24sIHRpbWV9KXtcbiAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgW10sIG5hbWVzLCB0cmFuc2l0aW9uLCB0aW1lLCB2aWV3KVxuICB9LFxuXG4gIGV4ZWNfdG9nZ2xlX2NsYXNzKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwge3RvLCBuYW1lcywgdHJhbnNpdGlvbiwgdGltZX0pe1xuICAgIHRoaXMudG9nZ2xlQ2xhc3NlcyhlbCwgbmFtZXMsIHRyYW5zaXRpb24sIHRpbWUsIHZpZXcpXG4gIH0sXG5cbiAgZXhlY190b2dnbGVfYXR0cihldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHthdHRyOiBbYXR0ciwgdmFsMSwgdmFsMl19KXtcbiAgICBpZihlbC5oYXNBdHRyaWJ1dGUoYXR0cikpe1xuICAgICAgaWYodmFsMiAhPT0gdW5kZWZpbmVkKXtcbiAgICAgICAgLy8gdG9nZ2xlIGJldHdlZW4gdmFsMSBhbmQgdmFsMlxuICAgICAgICBpZihlbC5nZXRBdHRyaWJ1dGUoYXR0cikgPT09IHZhbDEpe1xuICAgICAgICAgIHRoaXMuc2V0T3JSZW1vdmVBdHRycyhlbCwgW1thdHRyLCB2YWwyXV0sIFtdKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuc2V0T3JSZW1vdmVBdHRycyhlbCwgW1thdHRyLCB2YWwxXV0sIFtdKVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyByZW1vdmUgYXR0clxuICAgICAgICB0aGlzLnNldE9yUmVtb3ZlQXR0cnMoZWwsIFtdLCBbYXR0cl0pXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0T3JSZW1vdmVBdHRycyhlbCwgW1thdHRyLCB2YWwxXV0sIFtdKVxuICAgIH1cbiAgfSxcblxuICBleGVjX3RyYW5zaXRpb24oZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7dGltZSwgdHJhbnNpdGlvbn0pe1xuICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBbXSwgW10sIHRyYW5zaXRpb24sIHRpbWUsIHZpZXcpXG4gIH0sXG5cbiAgZXhlY190b2dnbGUoZXZlbnRUeXBlLCBwaHhFdmVudCwgdmlldywgc291cmNlRWwsIGVsLCB7ZGlzcGxheSwgaW5zLCBvdXRzLCB0aW1lfSl7XG4gICAgdGhpcy50b2dnbGUoZXZlbnRUeXBlLCB2aWV3LCBlbCwgZGlzcGxheSwgaW5zLCBvdXRzLCB0aW1lKVxuICB9LFxuXG4gIGV4ZWNfc2hvdyhldmVudFR5cGUsIHBoeEV2ZW50LCB2aWV3LCBzb3VyY2VFbCwgZWwsIHtkaXNwbGF5LCB0cmFuc2l0aW9uLCB0aW1lfSl7XG4gICAgdGhpcy5zaG93KGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIHRyYW5zaXRpb24sIHRpbWUpXG4gIH0sXG5cbiAgZXhlY19oaWRlKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwge2Rpc3BsYXksIHRyYW5zaXRpb24sIHRpbWV9KXtcbiAgICB0aGlzLmhpZGUoZXZlbnRUeXBlLCB2aWV3LCBlbCwgZGlzcGxheSwgdHJhbnNpdGlvbiwgdGltZSlcbiAgfSxcblxuICBleGVjX3NldF9hdHRyKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwge2F0dHI6IFthdHRyLCB2YWxdfSl7XG4gICAgdGhpcy5zZXRPclJlbW92ZUF0dHJzKGVsLCBbW2F0dHIsIHZhbF1dLCBbXSlcbiAgfSxcblxuICBleGVjX3JlbW92ZV9hdHRyKGV2ZW50VHlwZSwgcGh4RXZlbnQsIHZpZXcsIHNvdXJjZUVsLCBlbCwge2F0dHJ9KXtcbiAgICB0aGlzLnNldE9yUmVtb3ZlQXR0cnMoZWwsIFtdLCBbYXR0cl0pXG4gIH0sXG5cbiAgLy8gdXRpbHMgZm9yIGNvbW1hbmRzXG5cbiAgc2hvdyhldmVudFR5cGUsIHZpZXcsIGVsLCBkaXNwbGF5LCB0cmFuc2l0aW9uLCB0aW1lKXtcbiAgICBpZighdGhpcy5pc1Zpc2libGUoZWwpKXtcbiAgICAgIHRoaXMudG9nZ2xlKGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIHRyYW5zaXRpb24sIG51bGwsIHRpbWUpXG4gICAgfVxuICB9LFxuXG4gIGhpZGUoZXZlbnRUeXBlLCB2aWV3LCBlbCwgZGlzcGxheSwgdHJhbnNpdGlvbiwgdGltZSl7XG4gICAgaWYodGhpcy5pc1Zpc2libGUoZWwpKXtcbiAgICAgIHRoaXMudG9nZ2xlKGV2ZW50VHlwZSwgdmlldywgZWwsIGRpc3BsYXksIG51bGwsIHRyYW5zaXRpb24sIHRpbWUpXG4gICAgfVxuICB9LFxuXG4gIHRvZ2dsZShldmVudFR5cGUsIHZpZXcsIGVsLCBkaXNwbGF5LCBpbnMsIG91dHMsIHRpbWUpe1xuICAgIHRpbWUgPSB0aW1lIHx8IGRlZmF1bHRfdHJhbnNpdGlvbl90aW1lXG4gICAgbGV0IFtpbkNsYXNzZXMsIGluU3RhcnRDbGFzc2VzLCBpbkVuZENsYXNzZXNdID0gaW5zIHx8IFtbXSwgW10sIFtdXVxuICAgIGxldCBbb3V0Q2xhc3Nlcywgb3V0U3RhcnRDbGFzc2VzLCBvdXRFbmRDbGFzc2VzXSA9IG91dHMgfHwgW1tdLCBbXSwgW11dXG4gICAgaWYoaW5DbGFzc2VzLmxlbmd0aCA+IDAgfHwgb3V0Q2xhc3Nlcy5sZW5ndGggPiAwKXtcbiAgICAgIGlmKHRoaXMuaXNWaXNpYmxlKGVsKSl7XG4gICAgICAgIGxldCBvblN0YXJ0ID0gKCkgPT4ge1xuICAgICAgICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBvdXRTdGFydENsYXNzZXMsIGluQ2xhc3Nlcy5jb25jYXQoaW5TdGFydENsYXNzZXMpLmNvbmNhdChpbkVuZENsYXNzZXMpKVxuICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIG91dENsYXNzZXMsIFtdKVxuICAgICAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgb3V0RW5kQ2xhc3Nlcywgb3V0U3RhcnRDbGFzc2VzKSlcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OmhpZGUtc3RhcnRcIikpXG4gICAgICAgIHZpZXcudHJhbnNpdGlvbih0aW1lLCBvblN0YXJ0LCAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIFtdLCBvdXRDbGFzc2VzLmNvbmNhdChvdXRFbmRDbGFzc2VzKSlcbiAgICAgICAgICBET00ucHV0U3RpY2t5KGVsLCBcInRvZ2dsZVwiLCBjdXJyZW50RWwgPT4gY3VycmVudEVsLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIilcbiAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInBoeDpoaWRlLWVuZFwiKSlcbiAgICAgICAgfSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmKGV2ZW50VHlwZSA9PT0gXCJyZW1vdmVcIil7IHJldHVybiB9XG4gICAgICAgIGxldCBvblN0YXJ0ID0gKCkgPT4ge1xuICAgICAgICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBpblN0YXJ0Q2xhc3Nlcywgb3V0Q2xhc3Nlcy5jb25jYXQob3V0U3RhcnRDbGFzc2VzKS5jb25jYXQob3V0RW5kQ2xhc3NlcykpXG4gICAgICAgICAgbGV0IHN0aWNreURpc3BsYXkgPSBkaXNwbGF5IHx8IHRoaXMuZGVmYXVsdERpc3BsYXkoZWwpXG4gICAgICAgICAgRE9NLnB1dFN0aWNreShlbCwgXCJ0b2dnbGVcIiwgY3VycmVudEVsID0+IGN1cnJlbnRFbC5zdHlsZS5kaXNwbGF5ID0gc3RpY2t5RGlzcGxheSlcbiAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBpbkNsYXNzZXMsIFtdKVxuICAgICAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgaW5FbmRDbGFzc2VzLCBpblN0YXJ0Q2xhc3NlcykpXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInBoeDpzaG93LXN0YXJ0XCIpKVxuICAgICAgICB2aWV3LnRyYW5zaXRpb24odGltZSwgb25TdGFydCwgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBbXSwgaW5DbGFzc2VzLmNvbmNhdChpbkVuZENsYXNzZXMpKVxuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OnNob3ctZW5kXCIpKVxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZih0aGlzLmlzVmlzaWJsZShlbCkpe1xuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcInBoeDpoaWRlLXN0YXJ0XCIpKVxuICAgICAgICAgIERPTS5wdXRTdGlja3koZWwsIFwidG9nZ2xlXCIsIGN1cnJlbnRFbCA9PiBjdXJyZW50RWwuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiKVxuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OmhpZGUtZW5kXCIpKVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoXCJwaHg6c2hvdy1zdGFydFwiKSlcbiAgICAgICAgICBsZXQgc3RpY2t5RGlzcGxheSA9IGRpc3BsYXkgfHwgdGhpcy5kZWZhdWx0RGlzcGxheShlbClcbiAgICAgICAgICBET00ucHV0U3RpY2t5KGVsLCBcInRvZ2dsZVwiLCBjdXJyZW50RWwgPT4gY3VycmVudEVsLnN0eWxlLmRpc3BsYXkgPSBzdGlja3lEaXNwbGF5KVxuICAgICAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwicGh4OnNob3ctZW5kXCIpKVxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICB0b2dnbGVDbGFzc2VzKGVsLCBjbGFzc2VzLCB0cmFuc2l0aW9uLCB0aW1lLCB2aWV3KXtcbiAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgIGxldCBbcHJldkFkZHMsIHByZXZSZW1vdmVzXSA9IERPTS5nZXRTdGlja3koZWwsIFwiY2xhc3Nlc1wiLCBbW10sIFtdXSlcbiAgICAgIGxldCBuZXdBZGRzID0gY2xhc3Nlcy5maWx0ZXIobmFtZSA9PiBwcmV2QWRkcy5pbmRleE9mKG5hbWUpIDwgMCAmJiAhZWwuY2xhc3NMaXN0LmNvbnRhaW5zKG5hbWUpKVxuICAgICAgbGV0IG5ld1JlbW92ZXMgPSBjbGFzc2VzLmZpbHRlcihuYW1lID0+IHByZXZSZW1vdmVzLmluZGV4T2YobmFtZSkgPCAwICYmIGVsLmNsYXNzTGlzdC5jb250YWlucyhuYW1lKSlcbiAgICAgIHRoaXMuYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBuZXdBZGRzLCBuZXdSZW1vdmVzLCB0cmFuc2l0aW9uLCB0aW1lLCB2aWV3KVxuICAgIH0pXG4gIH0sXG5cbiAgYWRkT3JSZW1vdmVDbGFzc2VzKGVsLCBhZGRzLCByZW1vdmVzLCB0cmFuc2l0aW9uLCB0aW1lLCB2aWV3KXtcbiAgICB0aW1lID0gdGltZSB8fCBkZWZhdWx0X3RyYW5zaXRpb25fdGltZVxuICAgIGxldCBbdHJhbnNpdGlvblJ1biwgdHJhbnNpdGlvblN0YXJ0LCB0cmFuc2l0aW9uRW5kXSA9IHRyYW5zaXRpb24gfHwgW1tdLCBbXSwgW11dXG4gICAgaWYodHJhbnNpdGlvblJ1bi5sZW5ndGggPiAwKXtcbiAgICAgIGxldCBvblN0YXJ0ID0gKCkgPT4ge1xuICAgICAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgdHJhbnNpdGlvblN0YXJ0LCBbXS5jb25jYXQodHJhbnNpdGlvblJ1bikuY29uY2F0KHRyYW5zaXRpb25FbmQpKVxuICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgdHJhbnNpdGlvblJ1biwgW10pXG4gICAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgdHJhbnNpdGlvbkVuZCwgdHJhbnNpdGlvblN0YXJ0KSlcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIGxldCBvbkRvbmUgPSAoKSA9PiB0aGlzLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgYWRkcy5jb25jYXQodHJhbnNpdGlvbkVuZCksIHJlbW92ZXMuY29uY2F0KHRyYW5zaXRpb25SdW4pLmNvbmNhdCh0cmFuc2l0aW9uU3RhcnQpKVxuICAgICAgcmV0dXJuIHZpZXcudHJhbnNpdGlvbih0aW1lLCBvblN0YXJ0LCBvbkRvbmUpXG4gICAgfVxuXG4gICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICBsZXQgW3ByZXZBZGRzLCBwcmV2UmVtb3Zlc10gPSBET00uZ2V0U3RpY2t5KGVsLCBcImNsYXNzZXNcIiwgW1tdLCBbXV0pXG4gICAgICBsZXQga2VlcEFkZHMgPSBhZGRzLmZpbHRlcihuYW1lID0+IHByZXZBZGRzLmluZGV4T2YobmFtZSkgPCAwICYmICFlbC5jbGFzc0xpc3QuY29udGFpbnMobmFtZSkpXG4gICAgICBsZXQga2VlcFJlbW92ZXMgPSByZW1vdmVzLmZpbHRlcihuYW1lID0+IHByZXZSZW1vdmVzLmluZGV4T2YobmFtZSkgPCAwICYmIGVsLmNsYXNzTGlzdC5jb250YWlucyhuYW1lKSlcbiAgICAgIGxldCBuZXdBZGRzID0gcHJldkFkZHMuZmlsdGVyKG5hbWUgPT4gcmVtb3Zlcy5pbmRleE9mKG5hbWUpIDwgMCkuY29uY2F0KGtlZXBBZGRzKVxuICAgICAgbGV0IG5ld1JlbW92ZXMgPSBwcmV2UmVtb3Zlcy5maWx0ZXIobmFtZSA9PiBhZGRzLmluZGV4T2YobmFtZSkgPCAwKS5jb25jYXQoa2VlcFJlbW92ZXMpXG5cbiAgICAgIERPTS5wdXRTdGlja3koZWwsIFwiY2xhc3Nlc1wiLCBjdXJyZW50RWwgPT4ge1xuICAgICAgICBjdXJyZW50RWwuY2xhc3NMaXN0LnJlbW92ZSguLi5uZXdSZW1vdmVzKVxuICAgICAgICBjdXJyZW50RWwuY2xhc3NMaXN0LmFkZCguLi5uZXdBZGRzKVxuICAgICAgICByZXR1cm4gW25ld0FkZHMsIG5ld1JlbW92ZXNdXG4gICAgICB9KVxuICAgIH0pXG4gIH0sXG5cbiAgc2V0T3JSZW1vdmVBdHRycyhlbCwgc2V0cywgcmVtb3Zlcyl7XG4gICAgbGV0IFtwcmV2U2V0cywgcHJldlJlbW92ZXNdID0gRE9NLmdldFN0aWNreShlbCwgXCJhdHRyc1wiLCBbW10sIFtdXSlcblxuICAgIGxldCBhbHRlcmVkQXR0cnMgPSBzZXRzLm1hcCgoW2F0dHIsIF92YWxdKSA9PiBhdHRyKS5jb25jYXQocmVtb3ZlcylcbiAgICBsZXQgbmV3U2V0cyA9IHByZXZTZXRzLmZpbHRlcigoW2F0dHIsIF92YWxdKSA9PiAhYWx0ZXJlZEF0dHJzLmluY2x1ZGVzKGF0dHIpKS5jb25jYXQoc2V0cylcbiAgICBsZXQgbmV3UmVtb3ZlcyA9IHByZXZSZW1vdmVzLmZpbHRlcigoYXR0cikgPT4gIWFsdGVyZWRBdHRycy5pbmNsdWRlcyhhdHRyKSkuY29uY2F0KHJlbW92ZXMpXG5cbiAgICBET00ucHV0U3RpY2t5KGVsLCBcImF0dHJzXCIsIGN1cnJlbnRFbCA9PiB7XG4gICAgICBuZXdSZW1vdmVzLmZvckVhY2goYXR0ciA9PiBjdXJyZW50RWwucmVtb3ZlQXR0cmlidXRlKGF0dHIpKVxuICAgICAgbmV3U2V0cy5mb3JFYWNoKChbYXR0ciwgdmFsXSkgPT4gY3VycmVudEVsLnNldEF0dHJpYnV0ZShhdHRyLCB2YWwpKVxuICAgICAgcmV0dXJuIFtuZXdTZXRzLCBuZXdSZW1vdmVzXVxuICAgIH0pXG4gIH0sXG5cbiAgaGFzQWxsQ2xhc3NlcyhlbCwgY2xhc3Nlcyl7IHJldHVybiBjbGFzc2VzLmV2ZXJ5KG5hbWUgPT4gZWwuY2xhc3NMaXN0LmNvbnRhaW5zKG5hbWUpKSB9LFxuXG4gIGlzVG9nZ2xlZE91dChlbCwgb3V0Q2xhc3Nlcyl7XG4gICAgcmV0dXJuICF0aGlzLmlzVmlzaWJsZShlbCkgfHwgdGhpcy5oYXNBbGxDbGFzc2VzKGVsLCBvdXRDbGFzc2VzKVxuICB9LFxuXG4gIGZpbHRlclRvRWxzKHNvdXJjZUVsLCB7dG99KXtcbiAgICByZXR1cm4gdG8gPyBET00uYWxsKGRvY3VtZW50LCB0bykgOiBbc291cmNlRWxdXG4gIH0sXG5cbiAgZGVmYXVsdERpc3BsYXkoZWwpe1xuICAgIHJldHVybiB7dHI6IFwidGFibGUtcm93XCIsIHRkOiBcInRhYmxlLWNlbGxcIn1bZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpXSB8fCBcImJsb2NrXCJcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBKUyIsICJpbXBvcnQge1xuICBDSEVDS0FCTEVfSU5QVVRTLFxuICBERUJPVU5DRV9QUkVWX0tFWSxcbiAgREVCT1VOQ0VfVFJJR0dFUixcbiAgRk9DVVNBQkxFX0lOUFVUUyxcbiAgUEhYX0NPTVBPTkVOVCxcbiAgUEhYX0VWRU5UX0NMQVNTRVMsXG4gIFBIWF9IQVNfRk9DVVNFRCxcbiAgUEhYX0hBU19TVUJNSVRURUQsXG4gIFBIWF9NQUlOLFxuICBQSFhfTk9fRkVFREJBQ0tfQ0xBU1MsXG4gIFBIWF9QQVJFTlRfSUQsXG4gIFBIWF9QUklWQVRFLFxuICBQSFhfUkVGLFxuICBQSFhfUkVGX1NSQyxcbiAgUEhYX1JPT1RfSUQsXG4gIFBIWF9TRVNTSU9OLFxuICBQSFhfU1RBVElDLFxuICBQSFhfVVBMT0FEX1JFRixcbiAgUEhYX1ZJRVdfU0VMRUNUT1IsXG4gIFBIWF9TVElDS1ksXG4gIFRIUk9UVExFRFxufSBmcm9tIFwiLi9jb25zdGFudHNcIlxuXG5pbXBvcnQgSlMgZnJvbSBcIi4vanNcIlxuXG5pbXBvcnQge1xuICBsb2dFcnJvclxufSBmcm9tIFwiLi91dGlsc1wiXG5cbmxldCBET00gPSB7XG4gIGJ5SWQoaWQpeyByZXR1cm4gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpIHx8IGxvZ0Vycm9yKGBubyBpZCBmb3VuZCBmb3IgJHtpZH1gKSB9LFxuXG4gIHJlbW92ZUNsYXNzKGVsLCBjbGFzc05hbWUpe1xuICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUoY2xhc3NOYW1lKVxuICAgIGlmKGVsLmNsYXNzTGlzdC5sZW5ndGggPT09IDApeyBlbC5yZW1vdmVBdHRyaWJ1dGUoXCJjbGFzc1wiKSB9XG4gIH0sXG5cbiAgYWxsKG5vZGUsIHF1ZXJ5LCBjYWxsYmFjayl7XG4gICAgaWYoIW5vZGUpeyByZXR1cm4gW10gfVxuICAgIGxldCBhcnJheSA9IEFycmF5LmZyb20obm9kZS5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5KSlcbiAgICByZXR1cm4gY2FsbGJhY2sgPyBhcnJheS5mb3JFYWNoKGNhbGxiYWNrKSA6IGFycmF5XG4gIH0sXG5cbiAgY2hpbGROb2RlTGVuZ3RoKGh0bWwpe1xuICAgIGxldCB0ZW1wbGF0ZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ0ZW1wbGF0ZVwiKVxuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGh0bWxcbiAgICByZXR1cm4gdGVtcGxhdGUuY29udGVudC5jaGlsZEVsZW1lbnRDb3VudFxuICB9LFxuXG4gIGlzVXBsb2FkSW5wdXQoZWwpeyByZXR1cm4gZWwudHlwZSA9PT0gXCJmaWxlXCIgJiYgZWwuZ2V0QXR0cmlidXRlKFBIWF9VUExPQURfUkVGKSAhPT0gbnVsbCB9LFxuXG4gIGlzQXV0b1VwbG9hZChpbnB1dEVsKXsgcmV0dXJuIGlucHV0RWwuaGFzQXR0cmlidXRlKFwiZGF0YS1waHgtYXV0by11cGxvYWRcIikgfSxcblxuICBmaW5kVXBsb2FkSW5wdXRzKG5vZGUpe1xuICAgIGNvbnN0IGZvcm1JZCA9IG5vZGUuaWRcbiAgICBjb25zdCBpbnB1dHNPdXRzaWRlRm9ybSA9IHRoaXMuYWxsKGRvY3VtZW50LCBgaW5wdXRbdHlwZT1cImZpbGVcIl1bJHtQSFhfVVBMT0FEX1JFRn1dW2Zvcm09XCIke2Zvcm1JZH1cIl1gKVxuICAgIHJldHVybiB0aGlzLmFsbChub2RlLCBgaW5wdXRbdHlwZT1cImZpbGVcIl1bJHtQSFhfVVBMT0FEX1JFRn1dYCkuY29uY2F0KGlucHV0c091dHNpZGVGb3JtKVxuICB9LFxuXG4gIGZpbmRDb21wb25lbnROb2RlTGlzdChub2RlLCBjaWQpe1xuICAgIHJldHVybiB0aGlzLmZpbHRlcldpdGhpblNhbWVMaXZlVmlldyh0aGlzLmFsbChub2RlLCBgWyR7UEhYX0NPTVBPTkVOVH09XCIke2NpZH1cIl1gKSwgbm9kZSlcbiAgfSxcblxuICBpc1BoeERlc3Ryb3llZChub2RlKXtcbiAgICByZXR1cm4gbm9kZS5pZCAmJiBET00ucHJpdmF0ZShub2RlLCBcImRlc3Ryb3llZFwiKSA/IHRydWUgOiBmYWxzZVxuICB9LFxuXG4gIHdhbnRzTmV3VGFiKGUpe1xuICAgIGxldCB3YW50c05ld1RhYiA9IGUuY3RybEtleSB8fCBlLnNoaWZ0S2V5IHx8IGUubWV0YUtleSB8fCAoZS5idXR0b24gJiYgZS5idXR0b24gPT09IDEpXG4gICAgbGV0IGlzRG93bmxvYWQgPSAoZS50YXJnZXQgaW5zdGFuY2VvZiBIVE1MQW5jaG9yRWxlbWVudCAmJiBlLnRhcmdldC5oYXNBdHRyaWJ1dGUoXCJkb3dubG9hZFwiKSlcbiAgICBsZXQgaXNUYXJnZXRCbGFuayA9IGUudGFyZ2V0Lmhhc0F0dHJpYnV0ZShcInRhcmdldFwiKSAmJiBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoXCJ0YXJnZXRcIikudG9Mb3dlckNhc2UoKSA9PT0gXCJfYmxhbmtcIlxuICAgIGxldCBpc1RhcmdldE5hbWVkVGFiID0gZS50YXJnZXQuaGFzQXR0cmlidXRlKFwidGFyZ2V0XCIpICYmICFlLnRhcmdldC5nZXRBdHRyaWJ1dGUoXCJ0YXJnZXRcIikuc3RhcnRzV2l0aChcIl9cIilcbiAgICByZXR1cm4gd2FudHNOZXdUYWIgfHwgaXNUYXJnZXRCbGFuayB8fCBpc0Rvd25sb2FkIHx8IGlzVGFyZ2V0TmFtZWRUYWJcbiAgfSxcblxuICBpc1VubG9hZGFibGVGb3JtU3VibWl0KGUpe1xuICAgIC8vIElnbm9yZSBmb3JtIHN1Ym1pc3Npb25zIGludGVuZGVkIHRvIGNsb3NlIGEgbmF0aXZlIDxkaWFsb2c+IGVsZW1lbnRcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVE1ML0VsZW1lbnQvZGlhbG9nI3VzYWdlX25vdGVzXG4gICAgbGV0IGlzRGlhbG9nU3VibWl0ID0gKGUudGFyZ2V0ICYmIGUudGFyZ2V0LmdldEF0dHJpYnV0ZShcIm1ldGhvZFwiKSA9PT0gXCJkaWFsb2dcIikgfHxcbiAgICAgIChlLnN1Ym1pdHRlciAmJiBlLnN1Ym1pdHRlci5nZXRBdHRyaWJ1dGUoXCJmb3JtbWV0aG9kXCIpID09PSBcImRpYWxvZ1wiKVxuXG4gICAgaWYoaXNEaWFsb2dTdWJtaXQpe1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAhZS5kZWZhdWx0UHJldmVudGVkICYmICF0aGlzLndhbnRzTmV3VGFiKGUpXG4gICAgfVxuICB9LFxuXG4gIGlzTmV3UGFnZUNsaWNrKGUsIGN1cnJlbnRMb2NhdGlvbil7XG4gICAgbGV0IGhyZWYgPSBlLnRhcmdldCBpbnN0YW5jZW9mIEhUTUxBbmNob3JFbGVtZW50ID8gZS50YXJnZXQuZ2V0QXR0cmlidXRlKFwiaHJlZlwiKSA6IG51bGxcbiAgICBsZXQgdXJsXG5cbiAgICBpZihlLmRlZmF1bHRQcmV2ZW50ZWQgfHwgaHJlZiA9PT0gbnVsbCB8fCB0aGlzLndhbnRzTmV3VGFiKGUpKXsgcmV0dXJuIGZhbHNlIH1cbiAgICBpZihocmVmLnN0YXJ0c1dpdGgoXCJtYWlsdG86XCIpIHx8IGhyZWYuc3RhcnRzV2l0aChcInRlbDpcIikpeyByZXR1cm4gZmFsc2UgfVxuICAgIGlmKGUudGFyZ2V0LmlzQ29udGVudEVkaXRhYmxlKXsgcmV0dXJuIGZhbHNlIH1cblxuICAgIHRyeSB7XG4gICAgICB1cmwgPSBuZXcgVVJMKGhyZWYpXG4gICAgfSBjYXRjaChlKSB7XG4gICAgICB0cnkge1xuICAgICAgICB1cmwgPSBuZXcgVVJMKGhyZWYsIGN1cnJlbnRMb2NhdGlvbilcbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAvLyBiYWQgVVJMLCBmYWxsYmFjayB0byBsZXQgYnJvd3NlciB0cnkgaXQgYXMgZXh0ZXJuYWxcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZih1cmwuaG9zdCA9PT0gY3VycmVudExvY2F0aW9uLmhvc3QgJiYgdXJsLnByb3RvY29sID09PSBjdXJyZW50TG9jYXRpb24ucHJvdG9jb2wpe1xuICAgICAgaWYodXJsLnBhdGhuYW1lID09PSBjdXJyZW50TG9jYXRpb24ucGF0aG5hbWUgJiYgdXJsLnNlYXJjaCA9PT0gY3VycmVudExvY2F0aW9uLnNlYXJjaCl7XG4gICAgICAgIHJldHVybiB1cmwuaGFzaCA9PT0gXCJcIiAmJiAhdXJsLmhyZWYuZW5kc1dpdGgoXCIjXCIpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB1cmwucHJvdG9jb2wuc3RhcnRzV2l0aChcImh0dHBcIilcbiAgfSxcblxuICBtYXJrUGh4Q2hpbGREZXN0cm95ZWQoZWwpe1xuICAgIGlmKHRoaXMuaXNQaHhDaGlsZChlbCkpeyBlbC5zZXRBdHRyaWJ1dGUoUEhYX1NFU1NJT04sIFwiXCIpIH1cbiAgICB0aGlzLnB1dFByaXZhdGUoZWwsIFwiZGVzdHJveWVkXCIsIHRydWUpXG4gIH0sXG5cbiAgZmluZFBoeENoaWxkcmVuSW5GcmFnbWVudChodG1sLCBwYXJlbnRJZCl7XG4gICAgbGV0IHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRlbXBsYXRlXCIpXG4gICAgdGVtcGxhdGUuaW5uZXJIVE1MID0gaHRtbFxuICAgIHJldHVybiB0aGlzLmZpbmRQaHhDaGlsZHJlbih0ZW1wbGF0ZS5jb250ZW50LCBwYXJlbnRJZClcbiAgfSxcblxuICBpc0lnbm9yZWQoZWwsIHBoeFVwZGF0ZSl7XG4gICAgcmV0dXJuIChlbC5nZXRBdHRyaWJ1dGUocGh4VXBkYXRlKSB8fCBlbC5nZXRBdHRyaWJ1dGUoXCJkYXRhLXBoeC11cGRhdGVcIikpID09PSBcImlnbm9yZVwiXG4gIH0sXG5cbiAgaXNQaHhVcGRhdGUoZWwsIHBoeFVwZGF0ZSwgdXBkYXRlVHlwZXMpe1xuICAgIHJldHVybiBlbC5nZXRBdHRyaWJ1dGUgJiYgdXBkYXRlVHlwZXMuaW5kZXhPZihlbC5nZXRBdHRyaWJ1dGUocGh4VXBkYXRlKSkgPj0gMFxuICB9LFxuXG4gIGZpbmRQaHhTdGlja3koZWwpeyByZXR1cm4gdGhpcy5hbGwoZWwsIGBbJHtQSFhfU1RJQ0tZfV1gKSB9LFxuXG4gIGZpbmRQaHhDaGlsZHJlbihlbCwgcGFyZW50SWQpe1xuICAgIHJldHVybiB0aGlzLmFsbChlbCwgYCR7UEhYX1ZJRVdfU0VMRUNUT1J9WyR7UEhYX1BBUkVOVF9JRH09XCIke3BhcmVudElkfVwiXWApXG4gIH0sXG5cbiAgZmluZEV4aXN0aW5nUGFyZW50Q0lEcyhub2RlLCBjaWRzKXtcbiAgICAvLyB3ZSBvbmx5IHdhbnQgdG8gZmluZCBwYXJlbnRzIHRoYXQgZXhpc3Qgb24gdGhlIHBhZ2VcbiAgICAvLyBpZiBhIGNpZCBpcyBub3Qgb24gdGhlIHBhZ2UsIHRoZSBvbmx5IHdheSBpdCBjYW4gYmUgYWRkZWQgYmFjayB0byB0aGUgcGFnZVxuICAgIC8vIGlzIGlmIGEgcGFyZW50IGFkZHMgaXQgYmFjaywgdGhlcmVmb3JlIGlmIGEgY2lkIGRvZXMgbm90IGV4aXN0IG9uIHRoZSBwYWdlLFxuICAgIC8vIHdlIHNob3VsZCBub3QgdHJ5IHRvIHJlbmRlciBpdCBieSBpdHNlbGYgKGJlY2F1c2UgaXQgd291bGQgYmUgcmVuZGVyZWQgdHdpY2UsXG4gICAgLy8gb25lIGJ5IHRoZSBwYXJlbnQsIGFuZCBhIHNlY29uZCB0aW1lIGJ5IGl0c2VsZilcbiAgICBsZXQgcGFyZW50Q2lkcyA9IG5ldyBTZXQoKVxuICAgIGxldCBjaGlsZHJlbkNpZHMgPSBuZXcgU2V0KClcblxuICAgIGNpZHMuZm9yRWFjaChjaWQgPT4ge1xuICAgICAgdGhpcy5maWx0ZXJXaXRoaW5TYW1lTGl2ZVZpZXcodGhpcy5hbGwobm9kZSwgYFske1BIWF9DT01QT05FTlR9PVwiJHtjaWR9XCJdYCksIG5vZGUpLmZvckVhY2gocGFyZW50ID0+IHtcbiAgICAgICAgcGFyZW50Q2lkcy5hZGQoY2lkKVxuICAgICAgICB0aGlzLmFsbChwYXJlbnQsIGBbJHtQSFhfQ09NUE9ORU5UfV1gKVxuICAgICAgICAgIC5tYXAoZWwgPT4gcGFyc2VJbnQoZWwuZ2V0QXR0cmlidXRlKFBIWF9DT01QT05FTlQpKSlcbiAgICAgICAgICAuZm9yRWFjaChjaGlsZENJRCA9PiBjaGlsZHJlbkNpZHMuYWRkKGNoaWxkQ0lEKSlcbiAgICAgIH0pXG4gICAgfSlcblxuICAgIGNoaWxkcmVuQ2lkcy5mb3JFYWNoKGNoaWxkQ2lkID0+IHBhcmVudENpZHMuZGVsZXRlKGNoaWxkQ2lkKSlcblxuICAgIHJldHVybiBwYXJlbnRDaWRzXG4gIH0sXG5cbiAgZmlsdGVyV2l0aGluU2FtZUxpdmVWaWV3KG5vZGVzLCBwYXJlbnQpe1xuICAgIGlmKHBhcmVudC5xdWVyeVNlbGVjdG9yKFBIWF9WSUVXX1NFTEVDVE9SKSl7XG4gICAgICByZXR1cm4gbm9kZXMuZmlsdGVyKGVsID0+IHRoaXMud2l0aGluU2FtZUxpdmVWaWV3KGVsLCBwYXJlbnQpKVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbm9kZXNcbiAgICB9XG4gIH0sXG5cbiAgd2l0aGluU2FtZUxpdmVWaWV3KG5vZGUsIHBhcmVudCl7XG4gICAgd2hpbGUobm9kZSA9IG5vZGUucGFyZW50Tm9kZSl7XG4gICAgICBpZihub2RlLmlzU2FtZU5vZGUocGFyZW50KSl7IHJldHVybiB0cnVlIH1cbiAgICAgIGlmKG5vZGUuZ2V0QXR0cmlidXRlKFBIWF9TRVNTSU9OKSAhPT0gbnVsbCl7IHJldHVybiBmYWxzZSB9XG4gICAgfVxuICB9LFxuXG4gIHByaXZhdGUoZWwsIGtleSl7IHJldHVybiBlbFtQSFhfUFJJVkFURV0gJiYgZWxbUEhYX1BSSVZBVEVdW2tleV0gfSxcblxuICBkZWxldGVQcml2YXRlKGVsLCBrZXkpeyBlbFtQSFhfUFJJVkFURV0gJiYgZGVsZXRlIChlbFtQSFhfUFJJVkFURV1ba2V5XSkgfSxcblxuICBwdXRQcml2YXRlKGVsLCBrZXksIHZhbHVlKXtcbiAgICBpZighZWxbUEhYX1BSSVZBVEVdKXsgZWxbUEhYX1BSSVZBVEVdID0ge30gfVxuICAgIGVsW1BIWF9QUklWQVRFXVtrZXldID0gdmFsdWVcbiAgfSxcblxuICB1cGRhdGVQcml2YXRlKGVsLCBrZXksIGRlZmF1bHRWYWwsIHVwZGF0ZUZ1bmMpe1xuICAgIGxldCBleGlzdGluZyA9IHRoaXMucHJpdmF0ZShlbCwga2V5KVxuICAgIGlmKGV4aXN0aW5nID09PSB1bmRlZmluZWQpe1xuICAgICAgdGhpcy5wdXRQcml2YXRlKGVsLCBrZXksIHVwZGF0ZUZ1bmMoZGVmYXVsdFZhbCkpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHV0UHJpdmF0ZShlbCwga2V5LCB1cGRhdGVGdW5jKGV4aXN0aW5nKSlcbiAgICB9XG4gIH0sXG5cbiAgY29weVByaXZhdGVzKHRhcmdldCwgc291cmNlKXtcbiAgICBpZihzb3VyY2VbUEhYX1BSSVZBVEVdKXtcbiAgICAgIHRhcmdldFtQSFhfUFJJVkFURV0gPSBzb3VyY2VbUEhYX1BSSVZBVEVdXG4gICAgfVxuICB9LFxuXG4gIHB1dFRpdGxlKHN0cil7XG4gICAgbGV0IHRpdGxlRWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwidGl0bGVcIilcbiAgICBpZih0aXRsZUVsKXtcbiAgICAgIGxldCB7cHJlZml4LCBzdWZmaXh9ID0gdGl0bGVFbC5kYXRhc2V0XG4gICAgICBkb2N1bWVudC50aXRsZSA9IGAke3ByZWZpeCB8fCBcIlwifSR7c3RyfSR7c3VmZml4IHx8IFwiXCJ9YFxuICAgIH0gZWxzZSB7XG4gICAgICBkb2N1bWVudC50aXRsZSA9IHN0clxuICAgIH1cbiAgfSxcblxuICBkZWJvdW5jZShlbCwgZXZlbnQsIHBoeERlYm91bmNlLCBkZWZhdWx0RGVib3VuY2UsIHBoeFRocm90dGxlLCBkZWZhdWx0VGhyb3R0bGUsIGFzeW5jRmlsdGVyLCBjYWxsYmFjayl7XG4gICAgbGV0IGRlYm91bmNlID0gZWwuZ2V0QXR0cmlidXRlKHBoeERlYm91bmNlKVxuICAgIGxldCB0aHJvdHRsZSA9IGVsLmdldEF0dHJpYnV0ZShwaHhUaHJvdHRsZSlcblxuICAgIGlmKGRlYm91bmNlID09PSBcIlwiKXsgZGVib3VuY2UgPSBkZWZhdWx0RGVib3VuY2UgfVxuICAgIGlmKHRocm90dGxlID09PSBcIlwiKXsgdGhyb3R0bGUgPSBkZWZhdWx0VGhyb3R0bGUgfVxuICAgIGxldCB2YWx1ZSA9IGRlYm91bmNlIHx8IHRocm90dGxlXG4gICAgc3dpdGNoKHZhbHVlKXtcbiAgICAgIGNhc2UgbnVsbDogcmV0dXJuIGNhbGxiYWNrKClcblxuICAgICAgY2FzZSBcImJsdXJcIjpcbiAgICAgICAgaWYodGhpcy5vbmNlKGVsLCBcImRlYm91bmNlLWJsdXJcIikpe1xuICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsICgpID0+IHtcbiAgICAgICAgICAgIGlmKGFzeW5jRmlsdGVyKCkpeyBjYWxsYmFjaygpIH1cbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIHJldHVyblxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBsZXQgdGltZW91dCA9IHBhcnNlSW50KHZhbHVlKVxuICAgICAgICBsZXQgdHJpZ2dlciA9ICgpID0+IHRocm90dGxlID8gdGhpcy5kZWxldGVQcml2YXRlKGVsLCBUSFJPVFRMRUQpIDogY2FsbGJhY2soKVxuICAgICAgICBsZXQgY3VycmVudEN5Y2xlID0gdGhpcy5pbmNDeWNsZShlbCwgREVCT1VOQ0VfVFJJR0dFUiwgdHJpZ2dlcilcbiAgICAgICAgaWYoaXNOYU4odGltZW91dCkpeyByZXR1cm4gbG9nRXJyb3IoYGludmFsaWQgdGhyb3R0bGUvZGVib3VuY2UgdmFsdWU6ICR7dmFsdWV9YCkgfVxuICAgICAgICBpZih0aHJvdHRsZSl7XG4gICAgICAgICAgbGV0IG5ld0tleURvd24gPSBmYWxzZVxuICAgICAgICAgIGlmKGV2ZW50LnR5cGUgPT09IFwia2V5ZG93blwiKXtcbiAgICAgICAgICAgIGxldCBwcmV2S2V5ID0gdGhpcy5wcml2YXRlKGVsLCBERUJPVU5DRV9QUkVWX0tFWSlcbiAgICAgICAgICAgIHRoaXMucHV0UHJpdmF0ZShlbCwgREVCT1VOQ0VfUFJFVl9LRVksIGV2ZW50LmtleSlcbiAgICAgICAgICAgIG5ld0tleURvd24gPSBwcmV2S2V5ICE9PSBldmVudC5rZXlcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZighbmV3S2V5RG93biAmJiB0aGlzLnByaXZhdGUoZWwsIFRIUk9UVExFRCkpe1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKClcbiAgICAgICAgICAgIGNvbnN0IHQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgaWYoYXN5bmNGaWx0ZXIoKSl7IHRoaXMudHJpZ2dlckN5Y2xlKGVsLCBERUJPVU5DRV9UUklHR0VSKSB9XG4gICAgICAgICAgICB9LCB0aW1lb3V0KVxuICAgICAgICAgICAgdGhpcy5wdXRQcml2YXRlKGVsLCBUSFJPVFRMRUQsIHQpXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgaWYoYXN5bmNGaWx0ZXIoKSl7IHRoaXMudHJpZ2dlckN5Y2xlKGVsLCBERUJPVU5DRV9UUklHR0VSLCBjdXJyZW50Q3ljbGUpIH1cbiAgICAgICAgICB9LCB0aW1lb3V0KVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGZvcm0gPSBlbC5mb3JtXG4gICAgICAgIGlmKGZvcm0gJiYgdGhpcy5vbmNlKGZvcm0sIFwiYmluZC1kZWJvdW5jZVwiKSl7XG4gICAgICAgICAgZm9ybS5hZGRFdmVudExpc3RlbmVyKFwic3VibWl0XCIsICgpID0+IHtcbiAgICAgICAgICAgIEFycmF5LmZyb20oKG5ldyBGb3JtRGF0YShmb3JtKSkuZW50cmllcygpLCAoW25hbWVdKSA9PiB7XG4gICAgICAgICAgICAgIGxldCBpbnB1dCA9IGZvcm0ucXVlcnlTZWxlY3RvcihgW25hbWU9XCIke25hbWV9XCJdYClcbiAgICAgICAgICAgICAgdGhpcy5pbmNDeWNsZShpbnB1dCwgREVCT1VOQ0VfVFJJR0dFUilcbiAgICAgICAgICAgICAgdGhpcy5kZWxldGVQcml2YXRlKGlucHV0LCBUSFJPVFRMRUQpXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgaWYodGhpcy5vbmNlKGVsLCBcImJpbmQtZGVib3VuY2VcIikpe1xuICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsICgpID0+IHtcbiAgICAgICAgICAgIC8vIGJlY2F1c2Ugd2UgdHJpZ2dlciB0aGUgY2FsbGJhY2sgaGVyZSxcbiAgICAgICAgICAgIC8vIHdlIGFsc28gY2xlYXIgdGhlIHRocm90dGxlIHRpbWVvdXQgdG8gcHJldmVudCB0aGUgY2FsbGJhY2tcbiAgICAgICAgICAgIC8vIGZyb20gYmVpbmcgY2FsbGVkIGFnYWluIGFmdGVyIHRoZSB0aW1lb3V0IGZpcmVzXG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wcml2YXRlKGVsLCBUSFJPVFRMRUQpKVxuICAgICAgICAgICAgdGhpcy50cmlnZ2VyQ3ljbGUoZWwsIERFQk9VTkNFX1RSSUdHRVIpXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cbiAgfSxcblxuICB0cmlnZ2VyQ3ljbGUoZWwsIGtleSwgY3VycmVudEN5Y2xlKXtcbiAgICBsZXQgW2N5Y2xlLCB0cmlnZ2VyXSA9IHRoaXMucHJpdmF0ZShlbCwga2V5KVxuICAgIGlmKCFjdXJyZW50Q3ljbGUpeyBjdXJyZW50Q3ljbGUgPSBjeWNsZSB9XG4gICAgaWYoY3VycmVudEN5Y2xlID09PSBjeWNsZSl7XG4gICAgICB0aGlzLmluY0N5Y2xlKGVsLCBrZXkpXG4gICAgICB0cmlnZ2VyKClcbiAgICB9XG4gIH0sXG5cbiAgb25jZShlbCwga2V5KXtcbiAgICBpZih0aGlzLnByaXZhdGUoZWwsIGtleSkgPT09IHRydWUpeyByZXR1cm4gZmFsc2UgfVxuICAgIHRoaXMucHV0UHJpdmF0ZShlbCwga2V5LCB0cnVlKVxuICAgIHJldHVybiB0cnVlXG4gIH0sXG5cbiAgaW5jQ3ljbGUoZWwsIGtleSwgdHJpZ2dlciA9IGZ1bmN0aW9uICgpeyB9KXtcbiAgICBsZXQgW2N1cnJlbnRDeWNsZV0gPSB0aGlzLnByaXZhdGUoZWwsIGtleSkgfHwgWzAsIHRyaWdnZXJdXG4gICAgY3VycmVudEN5Y2xlKytcbiAgICB0aGlzLnB1dFByaXZhdGUoZWwsIGtleSwgW2N1cnJlbnRDeWNsZSwgdHJpZ2dlcl0pXG4gICAgcmV0dXJuIGN1cnJlbnRDeWNsZVxuICB9LFxuXG4gIG1heWJlQWRkUHJpdmF0ZUhvb2tzKGVsLCBwaHhWaWV3cG9ydFRvcCwgcGh4Vmlld3BvcnRCb3R0b20pe1xuICAgIGlmKGVsLmhhc0F0dHJpYnV0ZSAmJiAoZWwuaGFzQXR0cmlidXRlKHBoeFZpZXdwb3J0VG9wKSB8fCBlbC5oYXNBdHRyaWJ1dGUocGh4Vmlld3BvcnRCb3R0b20pKSl7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoXCJkYXRhLXBoeC1ob29rXCIsIFwiUGhvZW5peC5JbmZpbml0ZVNjcm9sbFwiKVxuICAgIH1cbiAgfSxcblxuICBpc0ZlZWRiYWNrQ29udGFpbmVyKGVsLCBwaHhGZWVkYmFja0Zvcil7XG4gICAgcmV0dXJuIGVsLmhhc0F0dHJpYnV0ZSAmJiBlbC5oYXNBdHRyaWJ1dGUocGh4RmVlZGJhY2tGb3IpXG4gIH0sXG5cbiAgbWF5YmVIaWRlRmVlZGJhY2soY29udGFpbmVyLCBmZWVkYmFja0NvbnRhaW5lcnMsIHBoeEZlZWRiYWNrRm9yLCBwaHhGZWVkYmFja0dyb3VwKXtcbiAgICAvLyBiZWNhdXNlIHdlIGNhbiBoYXZlIG11bHRpcGxlIGNvbnRhaW5lcnMgd2l0aCB0aGUgc2FtZSBwaHhGZWVkYmFja0ZvciB2YWx1ZVxuICAgIC8vIHdlIHBlcmZvcm0gdGhlIGNoZWNrIG9ubHkgb25jZSBhbmQgc3RvcmUgdGhlIHJlc3VsdDtcbiAgICAvLyB3ZSBvZnRlbiBoYXZlIG11bHRpcGxlIGNvbnRhaW5lcnMsIGJlY2F1c2Ugd2UgcHVzaCBib3RoIGZyb21FbCBhbmQgdG9FbCBpbiBkb21wYXRjaFxuICAgIC8vIHdoZW4gYSBjb250YWluZXIgaXMgdXBkYXRlZFxuICAgIGNvbnN0IGZlZWRiYWNrUmVzdWx0cyA9IHt9XG4gICAgZmVlZGJhY2tDb250YWluZXJzLmZvckVhY2goZWwgPT4ge1xuICAgICAgLy8gc2tpcCBlbGVtZW50cyB0aGF0IGFyZSBub3QgaW4gdGhlIERPTVxuICAgICAgaWYoIWNvbnRhaW5lci5jb250YWlucyhlbCkpIHJldHVyblxuICAgICAgY29uc3QgZmVlZGJhY2sgPSBlbC5nZXRBdHRyaWJ1dGUocGh4RmVlZGJhY2tGb3IpXG4gICAgICBpZighZmVlZGJhY2spe1xuICAgICAgICAvLyB0aGUgY29udGFpbmVyIHByZXZpb3VzbHkgaGFkIHBoeC1mZWVkYmFjay1mb3IsIGJ1dCBub3cgaXQgZG9lc24ndFxuICAgICAgICAvLyByZW1vdmUgdGhlIGNsYXNzIGZyb20gdGhlIGNvbnRhaW5lciAoaWYgaXQgZXhpc3RzKVxuICAgICAgICBKUy5hZGRPclJlbW92ZUNsYXNzZXMoZWwsIFtdLCBbUEhYX05PX0ZFRURCQUNLX0NMQVNTXSlcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICBpZihmZWVkYmFja1Jlc3VsdHNbZmVlZGJhY2tdID09PSB0cnVlKXtcbiAgICAgICAgdGhpcy5oaWRlRmVlZGJhY2soZWwpXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgZmVlZGJhY2tSZXN1bHRzW2ZlZWRiYWNrXSA9IHRoaXMuc2hvdWxkSGlkZUZlZWRiYWNrKGNvbnRhaW5lciwgZmVlZGJhY2ssIHBoeEZlZWRiYWNrR3JvdXApXG4gICAgICBpZihmZWVkYmFja1Jlc3VsdHNbZmVlZGJhY2tdID09PSB0cnVlKXtcbiAgICAgICAgdGhpcy5oaWRlRmVlZGJhY2soZWwpXG4gICAgICB9XG4gICAgfSlcbiAgfSxcblxuICBoaWRlRmVlZGJhY2soY29udGFpbmVyKXtcbiAgICBKUy5hZGRPclJlbW92ZUNsYXNzZXMoY29udGFpbmVyLCBbUEhYX05PX0ZFRURCQUNLX0NMQVNTXSwgW10pXG4gIH0sXG5cbiAgc2hvdWxkSGlkZUZlZWRiYWNrKGNvbnRhaW5lciwgbmFtZU9yR3JvdXAsIHBoeEZlZWRiYWNrR3JvdXApe1xuICAgIGNvbnN0IHF1ZXJ5ID0gYFtuYW1lPVwiJHtuYW1lT3JHcm91cH1cIl0sXG4gICAgICAgICAgICAgICAgICAgW25hbWU9XCIke25hbWVPckdyb3VwfVtdXCJdLFxuICAgICAgICAgICAgICAgICAgIFske3BoeEZlZWRiYWNrR3JvdXB9PVwiJHtuYW1lT3JHcm91cH1cIl1gXG4gICAgbGV0IGZvY3VzZWQgPSBmYWxzZVxuICAgIERPTS5hbGwoY29udGFpbmVyLCBxdWVyeSwgKGlucHV0KSA9PiB7XG4gICAgICBpZih0aGlzLnByaXZhdGUoaW5wdXQsIFBIWF9IQVNfRk9DVVNFRCkgfHwgdGhpcy5wcml2YXRlKGlucHV0LCBQSFhfSEFTX1NVQk1JVFRFRCkpe1xuICAgICAgICBmb2N1c2VkID0gdHJ1ZVxuICAgICAgfVxuICAgIH0pXG4gICAgcmV0dXJuICFmb2N1c2VkXG4gIH0sXG5cbiAgZmVlZGJhY2tTZWxlY3RvcihpbnB1dCwgcGh4RmVlZGJhY2tGb3IsIHBoeEZlZWRiYWNrR3JvdXApe1xuICAgIGxldCBxdWVyeSA9IGBbJHtwaHhGZWVkYmFja0Zvcn09XCIke2lucHV0Lm5hbWV9XCJdLFxuICAgICAgICAgICAgICAgICBbJHtwaHhGZWVkYmFja0Zvcn09XCIke2lucHV0Lm5hbWUucmVwbGFjZSgvXFxbXFxdJC8sIFwiXCIpfVwiXWBcbiAgICBpZihpbnB1dC5nZXRBdHRyaWJ1dGUocGh4RmVlZGJhY2tHcm91cCkpe1xuICAgICAgcXVlcnkgKz0gYCxbJHtwaHhGZWVkYmFja0Zvcn09XCIke2lucHV0LmdldEF0dHJpYnV0ZShwaHhGZWVkYmFja0dyb3VwKX1cIl1gXG4gICAgfVxuICAgIHJldHVybiBxdWVyeVxuICB9LFxuXG4gIHJlc2V0Rm9ybShmb3JtLCBwaHhGZWVkYmFja0ZvciwgcGh4RmVlZGJhY2tHcm91cCl7XG4gICAgQXJyYXkuZnJvbShmb3JtLmVsZW1lbnRzKS5mb3JFYWNoKGlucHV0ID0+IHtcbiAgICAgIGxldCBxdWVyeSA9IHRoaXMuZmVlZGJhY2tTZWxlY3RvcihpbnB1dCwgcGh4RmVlZGJhY2tGb3IsIHBoeEZlZWRiYWNrR3JvdXApXG4gICAgICB0aGlzLmRlbGV0ZVByaXZhdGUoaW5wdXQsIFBIWF9IQVNfRk9DVVNFRClcbiAgICAgIHRoaXMuZGVsZXRlUHJpdmF0ZShpbnB1dCwgUEhYX0hBU19TVUJNSVRURUQpXG4gICAgICB0aGlzLmFsbChkb2N1bWVudCwgcXVlcnksIGZlZWRiYWNrRWwgPT4ge1xuICAgICAgICBKUy5hZGRPclJlbW92ZUNsYXNzZXMoZmVlZGJhY2tFbCwgW1BIWF9OT19GRUVEQkFDS19DTEFTU10sIFtdKVxuICAgICAgfSlcbiAgICB9KVxuICB9LFxuXG4gIHNob3dFcnJvcihpbnB1dEVsLCBwaHhGZWVkYmFja0ZvciwgcGh4RmVlZGJhY2tHcm91cCl7XG4gICAgaWYoaW5wdXRFbC5uYW1lKXtcbiAgICAgIGxldCBxdWVyeSA9IHRoaXMuZmVlZGJhY2tTZWxlY3RvcihpbnB1dEVsLCBwaHhGZWVkYmFja0ZvciwgcGh4RmVlZGJhY2tHcm91cClcbiAgICAgIHRoaXMuYWxsKGRvY3VtZW50LCBxdWVyeSwgKGVsKSA9PiB7XG4gICAgICAgIEpTLmFkZE9yUmVtb3ZlQ2xhc3NlcyhlbCwgW10sIFtQSFhfTk9fRkVFREJBQ0tfQ0xBU1NdKVxuICAgICAgfSlcbiAgICB9XG4gIH0sXG5cbiAgaXNQaHhDaGlsZChub2RlKXtcbiAgICByZXR1cm4gbm9kZS5nZXRBdHRyaWJ1dGUgJiYgbm9kZS5nZXRBdHRyaWJ1dGUoUEhYX1BBUkVOVF9JRClcbiAgfSxcblxuICBpc1BoeFN0aWNreShub2RlKXtcbiAgICByZXR1cm4gbm9kZS5nZXRBdHRyaWJ1dGUgJiYgbm9kZS5nZXRBdHRyaWJ1dGUoUEhYX1NUSUNLWSkgIT09IG51bGxcbiAgfSxcblxuICBpc0NoaWxkT2ZBbnkoZWwsIHBhcmVudHMpe1xuICAgIHJldHVybiAhIXBhcmVudHMuZmluZChwYXJlbnQgPT4gcGFyZW50LmNvbnRhaW5zKGVsKSlcbiAgfSxcblxuICBmaXJzdFBoeENoaWxkKGVsKXtcbiAgICByZXR1cm4gdGhpcy5pc1BoeENoaWxkKGVsKSA/IGVsIDogdGhpcy5hbGwoZWwsIGBbJHtQSFhfUEFSRU5UX0lEfV1gKVswXVxuICB9LFxuXG4gIGRpc3BhdGNoRXZlbnQodGFyZ2V0LCBuYW1lLCBvcHRzID0ge30pe1xuICAgIGxldCBkZWZhdWx0QnViYmxlID0gdHJ1ZVxuICAgIGxldCBpc1VwbG9hZFRhcmdldCA9IHRhcmdldC5ub2RlTmFtZSA9PT0gXCJJTlBVVFwiICYmIHRhcmdldC50eXBlID09PSBcImZpbGVcIlxuICAgIGlmKGlzVXBsb2FkVGFyZ2V0ICYmIG5hbWUgPT09IFwiY2xpY2tcIil7XG4gICAgICBkZWZhdWx0QnViYmxlID0gZmFsc2VcbiAgICB9XG4gICAgbGV0IGJ1YmJsZXMgPSBvcHRzLmJ1YmJsZXMgPT09IHVuZGVmaW5lZCA/IGRlZmF1bHRCdWJibGUgOiAhIW9wdHMuYnViYmxlc1xuICAgIGxldCBldmVudE9wdHMgPSB7YnViYmxlczogYnViYmxlcywgY2FuY2VsYWJsZTogdHJ1ZSwgZGV0YWlsOiBvcHRzLmRldGFpbCB8fCB7fX1cbiAgICBsZXQgZXZlbnQgPSBuYW1lID09PSBcImNsaWNrXCIgPyBuZXcgTW91c2VFdmVudChcImNsaWNrXCIsIGV2ZW50T3B0cykgOiBuZXcgQ3VzdG9tRXZlbnQobmFtZSwgZXZlbnRPcHRzKVxuICAgIHRhcmdldC5kaXNwYXRjaEV2ZW50KGV2ZW50KVxuICB9LFxuXG4gIGNsb25lTm9kZShub2RlLCBodG1sKXtcbiAgICBpZih0eXBlb2YgKGh0bWwpID09PSBcInVuZGVmaW5lZFwiKXtcbiAgICAgIHJldHVybiBub2RlLmNsb25lTm9kZSh0cnVlKVxuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgY2xvbmVkID0gbm9kZS5jbG9uZU5vZGUoZmFsc2UpXG4gICAgICBjbG9uZWQuaW5uZXJIVE1MID0gaHRtbFxuICAgICAgcmV0dXJuIGNsb25lZFxuICAgIH1cbiAgfSxcblxuICAvLyBtZXJnZSBhdHRyaWJ1dGVzIGZyb20gc291cmNlIHRvIHRhcmdldFxuICAvLyBpZiBhbiBlbGVtZW50IGlzIGlnbm9yZWQsIHdlIG9ubHkgbWVyZ2UgZGF0YSBhdHRyaWJ1dGVzXG4gIC8vIGluY2x1ZGluZyByZW1vdmluZyBkYXRhIGF0dHJpYnV0ZXMgdGhhdCBhcmUgbm8gbG9uZ2VyIGluIHRoZSBzb3VyY2VcbiAgbWVyZ2VBdHRycyh0YXJnZXQsIHNvdXJjZSwgb3B0cyA9IHt9KXtcbiAgICBsZXQgZXhjbHVkZSA9IG5ldyBTZXQob3B0cy5leGNsdWRlIHx8IFtdKVxuICAgIGxldCBpc0lnbm9yZWQgPSBvcHRzLmlzSWdub3JlZFxuICAgIGxldCBzb3VyY2VBdHRycyA9IHNvdXJjZS5hdHRyaWJ1dGVzXG4gICAgZm9yKGxldCBpID0gc291cmNlQXR0cnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pe1xuICAgICAgbGV0IG5hbWUgPSBzb3VyY2VBdHRyc1tpXS5uYW1lXG4gICAgICBpZighZXhjbHVkZS5oYXMobmFtZSkpe1xuICAgICAgICBjb25zdCBzb3VyY2VWYWx1ZSA9IHNvdXJjZS5nZXRBdHRyaWJ1dGUobmFtZSlcbiAgICAgICAgaWYodGFyZ2V0LmdldEF0dHJpYnV0ZShuYW1lKSAhPT0gc291cmNlVmFsdWUgJiYgKCFpc0lnbm9yZWQgfHwgKGlzSWdub3JlZCAmJiBuYW1lLnN0YXJ0c1dpdGgoXCJkYXRhLVwiKSkpKXtcbiAgICAgICAgICB0YXJnZXQuc2V0QXR0cmlidXRlKG5hbWUsIHNvdXJjZVZhbHVlKVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBXZSBleGNsdWRlIHRoZSB2YWx1ZSBmcm9tIGJlaW5nIG1lcmdlZCBvbiBmb2N1c2VkIGlucHV0cywgYmVjYXVzZSB0aGVcbiAgICAgICAgLy8gdXNlcidzIGlucHV0IHNob3VsZCBhbHdheXMgd2luLlxuICAgICAgICAvLyBXZSBjYW4gc3RpbGwgYXNzaWduIGl0IGFzIGxvbmcgYXMgdGhlIHZhbHVlIHByb3BlcnR5IGlzIHRoZSBzYW1lLCB0aG91Z2guXG4gICAgICAgIC8vIFRoaXMgcHJldmVudHMgYSBzaXR1YXRpb24gd2hlcmUgdGhlIHVwZGF0ZWQgaG9vayBpcyBub3QgYmVpbmcgdHJpZ2dlcmVkXG4gICAgICAgIC8vIHdoZW4gYW4gaW5wdXQgaXMgYmFjayBpbiBpdHMgXCJvcmlnaW5hbCBzdGF0ZVwiLCBiZWNhdXNlIHRoZSBhdHRyaWJ1dGVcbiAgICAgICAgLy8gd2FzIG5ldmVyIGNoYW5nZWQsIHNlZTpcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3Bob2VuaXhmcmFtZXdvcmsvcGhvZW5peF9saXZlX3ZpZXcvaXNzdWVzLzIxNjNcbiAgICAgICAgaWYobmFtZSA9PT0gXCJ2YWx1ZVwiICYmIHRhcmdldC52YWx1ZSA9PT0gc291cmNlLnZhbHVlKXtcbiAgICAgICAgICAvLyBhY3R1YWxseSBzZXQgdGhlIHZhbHVlIGF0dHJpYnV0ZSB0byBzeW5jIGl0IHdpdGggdGhlIHZhbHVlIHByb3BlcnR5XG4gICAgICAgICAgdGFyZ2V0LnNldEF0dHJpYnV0ZShcInZhbHVlXCIsIHNvdXJjZS5nZXRBdHRyaWJ1dGUobmFtZSkpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgdGFyZ2V0QXR0cnMgPSB0YXJnZXQuYXR0cmlidXRlc1xuICAgIGZvcihsZXQgaSA9IHRhcmdldEF0dHJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKXtcbiAgICAgIGxldCBuYW1lID0gdGFyZ2V0QXR0cnNbaV0ubmFtZVxuICAgICAgaWYoaXNJZ25vcmVkKXtcbiAgICAgICAgaWYobmFtZS5zdGFydHNXaXRoKFwiZGF0YS1cIikgJiYgIXNvdXJjZS5oYXNBdHRyaWJ1dGUobmFtZSkgJiYgIVtQSFhfUkVGLCBQSFhfUkVGX1NSQ10uaW5jbHVkZXMobmFtZSkpeyB0YXJnZXQucmVtb3ZlQXR0cmlidXRlKG5hbWUpIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmKCFzb3VyY2UuaGFzQXR0cmlidXRlKG5hbWUpKXsgdGFyZ2V0LnJlbW92ZUF0dHJpYnV0ZShuYW1lKSB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIG1lcmdlRm9jdXNlZElucHV0KHRhcmdldCwgc291cmNlKXtcbiAgICAvLyBza2lwIHNlbGVjdHMgYmVjYXVzZSBGRiB3aWxsIHJlc2V0IGhpZ2hsaWdodGVkIGluZGV4IGZvciBhbnkgc2V0QXR0cmlidXRlXG4gICAgaWYoISh0YXJnZXQgaW5zdGFuY2VvZiBIVE1MU2VsZWN0RWxlbWVudCkpeyBET00ubWVyZ2VBdHRycyh0YXJnZXQsIHNvdXJjZSwge2V4Y2x1ZGU6IFtcInZhbHVlXCJdfSkgfVxuXG4gICAgaWYoc291cmNlLnJlYWRPbmx5KXtcbiAgICAgIHRhcmdldC5zZXRBdHRyaWJ1dGUoXCJyZWFkb25seVwiLCB0cnVlKVxuICAgIH0gZWxzZSB7XG4gICAgICB0YXJnZXQucmVtb3ZlQXR0cmlidXRlKFwicmVhZG9ubHlcIilcbiAgICB9XG4gIH0sXG5cbiAgaGFzU2VsZWN0aW9uUmFuZ2UoZWwpe1xuICAgIHJldHVybiBlbC5zZXRTZWxlY3Rpb25SYW5nZSAmJiAoZWwudHlwZSA9PT0gXCJ0ZXh0XCIgfHwgZWwudHlwZSA9PT0gXCJ0ZXh0YXJlYVwiKVxuICB9LFxuXG4gIHJlc3RvcmVGb2N1cyhmb2N1c2VkLCBzZWxlY3Rpb25TdGFydCwgc2VsZWN0aW9uRW5kKXtcbiAgICBpZihmb2N1c2VkIGluc3RhbmNlb2YgSFRNTFNlbGVjdEVsZW1lbnQpeyBmb2N1c2VkLmZvY3VzKCkgfVxuICAgIGlmKCFET00uaXNUZXh0dWFsSW5wdXQoZm9jdXNlZCkpeyByZXR1cm4gfVxuXG4gICAgbGV0IHdhc0ZvY3VzZWQgPSBmb2N1c2VkLm1hdGNoZXMoXCI6Zm9jdXNcIilcbiAgICBpZighd2FzRm9jdXNlZCl7IGZvY3VzZWQuZm9jdXMoKSB9XG4gICAgaWYodGhpcy5oYXNTZWxlY3Rpb25SYW5nZShmb2N1c2VkKSl7XG4gICAgICBmb2N1c2VkLnNldFNlbGVjdGlvblJhbmdlKHNlbGVjdGlvblN0YXJ0LCBzZWxlY3Rpb25FbmQpXG4gICAgfVxuICB9LFxuXG4gIGlzRm9ybUlucHV0KGVsKXsgcmV0dXJuIC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhKSQvaS50ZXN0KGVsLnRhZ05hbWUpICYmIGVsLnR5cGUgIT09IFwiYnV0dG9uXCIgfSxcblxuICBzeW5jQXR0cnNUb1Byb3BzKGVsKXtcbiAgICBpZihlbCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQgJiYgQ0hFQ0tBQkxFX0lOUFVUUy5pbmRleE9mKGVsLnR5cGUudG9Mb2NhbGVMb3dlckNhc2UoKSkgPj0gMCl7XG4gICAgICBlbC5jaGVja2VkID0gZWwuZ2V0QXR0cmlidXRlKFwiY2hlY2tlZFwiKSAhPT0gbnVsbFxuICAgIH1cbiAgfSxcblxuICBpc1RleHR1YWxJbnB1dChlbCl7IHJldHVybiBGT0NVU0FCTEVfSU5QVVRTLmluZGV4T2YoZWwudHlwZSkgPj0gMCB9LFxuXG4gIGlzTm93VHJpZ2dlckZvcm1FeHRlcm5hbChlbCwgcGh4VHJpZ2dlckV4dGVybmFsKXtcbiAgICByZXR1cm4gZWwuZ2V0QXR0cmlidXRlICYmIGVsLmdldEF0dHJpYnV0ZShwaHhUcmlnZ2VyRXh0ZXJuYWwpICE9PSBudWxsXG4gIH0sXG5cbiAgc3luY1BlbmRpbmdSZWYoZnJvbUVsLCB0b0VsLCBkaXNhYmxlV2l0aCl7XG4gICAgbGV0IHJlZiA9IGZyb21FbC5nZXRBdHRyaWJ1dGUoUEhYX1JFRilcbiAgICBpZihyZWYgPT09IG51bGwpeyByZXR1cm4gdHJ1ZSB9XG4gICAgbGV0IHJlZlNyYyA9IGZyb21FbC5nZXRBdHRyaWJ1dGUoUEhYX1JFRl9TUkMpXG5cbiAgICBpZihET00uaXNGb3JtSW5wdXQoZnJvbUVsKSB8fCBmcm9tRWwuZ2V0QXR0cmlidXRlKGRpc2FibGVXaXRoKSAhPT0gbnVsbCl7XG4gICAgICBpZihET00uaXNVcGxvYWRJbnB1dChmcm9tRWwpKXsgRE9NLm1lcmdlQXR0cnMoZnJvbUVsLCB0b0VsLCB7aXNJZ25vcmVkOiB0cnVlfSkgfVxuICAgICAgRE9NLnB1dFByaXZhdGUoZnJvbUVsLCBQSFhfUkVGLCB0b0VsKVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfSBlbHNlIHtcbiAgICAgIFBIWF9FVkVOVF9DTEFTU0VTLmZvckVhY2goY2xhc3NOYW1lID0+IHtcbiAgICAgICAgZnJvbUVsLmNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpICYmIHRvRWwuY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpXG4gICAgICB9KVxuICAgICAgdG9FbC5zZXRBdHRyaWJ1dGUoUEhYX1JFRiwgcmVmKVxuICAgICAgdG9FbC5zZXRBdHRyaWJ1dGUoUEhYX1JFRl9TUkMsIHJlZlNyYylcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9LFxuXG4gIGNsZWFuQ2hpbGROb2Rlcyhjb250YWluZXIsIHBoeFVwZGF0ZSl7XG4gICAgaWYoRE9NLmlzUGh4VXBkYXRlKGNvbnRhaW5lciwgcGh4VXBkYXRlLCBbXCJhcHBlbmRcIiwgXCJwcmVwZW5kXCJdKSl7XG4gICAgICBsZXQgdG9SZW1vdmUgPSBbXVxuICAgICAgY29udGFpbmVyLmNoaWxkTm9kZXMuZm9yRWFjaChjaGlsZE5vZGUgPT4ge1xuICAgICAgICBpZighY2hpbGROb2RlLmlkKXtcbiAgICAgICAgICAvLyBTa2lwIHdhcm5pbmcgaWYgaXQncyBhbiBlbXB0eSB0ZXh0IG5vZGUgKGUuZy4gYSBuZXctbGluZSlcbiAgICAgICAgICBsZXQgaXNFbXB0eVRleHROb2RlID0gY2hpbGROb2RlLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSAmJiBjaGlsZE5vZGUubm9kZVZhbHVlLnRyaW0oKSA9PT0gXCJcIlxuICAgICAgICAgIGlmKCFpc0VtcHR5VGV4dE5vZGUgJiYgY2hpbGROb2RlLm5vZGVUeXBlICE9PSBOb2RlLkNPTU1FTlRfTk9ERSl7XG4gICAgICAgICAgICBsb2dFcnJvcihcIm9ubHkgSFRNTCBlbGVtZW50IHRhZ3Mgd2l0aCBhbiBpZCBhcmUgYWxsb3dlZCBpbnNpZGUgY29udGFpbmVycyB3aXRoIHBoeC11cGRhdGUuXFxuXFxuXCIgK1xuICAgICAgICAgICAgICBgcmVtb3ZpbmcgaWxsZWdhbCBub2RlOiBcIiR7KGNoaWxkTm9kZS5vdXRlckhUTUwgfHwgY2hpbGROb2RlLm5vZGVWYWx1ZSkudHJpbSgpfVwiXFxuXFxuYClcbiAgICAgICAgICB9XG4gICAgICAgICAgdG9SZW1vdmUucHVzaChjaGlsZE5vZGUpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICB0b1JlbW92ZS5mb3JFYWNoKGNoaWxkTm9kZSA9PiBjaGlsZE5vZGUucmVtb3ZlKCkpXG4gICAgfVxuICB9LFxuXG4gIHJlcGxhY2VSb290Q29udGFpbmVyKGNvbnRhaW5lciwgdGFnTmFtZSwgYXR0cnMpe1xuICAgIGxldCByZXRhaW5lZEF0dHJzID0gbmV3IFNldChbXCJpZFwiLCBQSFhfU0VTU0lPTiwgUEhYX1NUQVRJQywgUEhYX01BSU4sIFBIWF9ST09UX0lEXSlcbiAgICBpZihjb250YWluZXIudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSB0YWdOYW1lLnRvTG93ZXJDYXNlKCkpe1xuICAgICAgQXJyYXkuZnJvbShjb250YWluZXIuYXR0cmlidXRlcylcbiAgICAgICAgLmZpbHRlcihhdHRyID0+ICFyZXRhaW5lZEF0dHJzLmhhcyhhdHRyLm5hbWUudG9Mb3dlckNhc2UoKSkpXG4gICAgICAgIC5mb3JFYWNoKGF0dHIgPT4gY29udGFpbmVyLnJlbW92ZUF0dHJpYnV0ZShhdHRyLm5hbWUpKVxuXG4gICAgICBPYmplY3Qua2V5cyhhdHRycylcbiAgICAgICAgLmZpbHRlcihuYW1lID0+ICFyZXRhaW5lZEF0dHJzLmhhcyhuYW1lLnRvTG93ZXJDYXNlKCkpKVxuICAgICAgICAuZm9yRWFjaChhdHRyID0+IGNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoYXR0ciwgYXR0cnNbYXR0cl0pKVxuXG4gICAgICByZXR1cm4gY29udGFpbmVyXG5cbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IG5ld0NvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSlcbiAgICAgIE9iamVjdC5rZXlzKGF0dHJzKS5mb3JFYWNoKGF0dHIgPT4gbmV3Q29udGFpbmVyLnNldEF0dHJpYnV0ZShhdHRyLCBhdHRyc1thdHRyXSkpXG4gICAgICByZXRhaW5lZEF0dHJzLmZvckVhY2goYXR0ciA9PiBuZXdDb250YWluZXIuc2V0QXR0cmlidXRlKGF0dHIsIGNvbnRhaW5lci5nZXRBdHRyaWJ1dGUoYXR0cikpKVxuICAgICAgbmV3Q29udGFpbmVyLmlubmVySFRNTCA9IGNvbnRhaW5lci5pbm5lckhUTUxcbiAgICAgIGNvbnRhaW5lci5yZXBsYWNlV2l0aChuZXdDb250YWluZXIpXG4gICAgICByZXR1cm4gbmV3Q29udGFpbmVyXG4gICAgfVxuICB9LFxuXG4gIGdldFN0aWNreShlbCwgbmFtZSwgZGVmYXVsdFZhbCl7XG4gICAgbGV0IG9wID0gKERPTS5wcml2YXRlKGVsLCBcInN0aWNreVwiKSB8fCBbXSkuZmluZCgoW2V4aXN0aW5nTmFtZSwgXSkgPT4gbmFtZSA9PT0gZXhpc3RpbmdOYW1lKVxuICAgIGlmKG9wKXtcbiAgICAgIGxldCBbX25hbWUsIF9vcCwgc3Rhc2hlZFJlc3VsdF0gPSBvcFxuICAgICAgcmV0dXJuIHN0YXNoZWRSZXN1bHRcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHR5cGVvZihkZWZhdWx0VmFsKSA9PT0gXCJmdW5jdGlvblwiID8gZGVmYXVsdFZhbCgpIDogZGVmYXVsdFZhbFxuICAgIH1cbiAgfSxcblxuICBkZWxldGVTdGlja3koZWwsIG5hbWUpe1xuICAgIHRoaXMudXBkYXRlUHJpdmF0ZShlbCwgXCJzdGlja3lcIiwgW10sIG9wcyA9PiB7XG4gICAgICByZXR1cm4gb3BzLmZpbHRlcigoW2V4aXN0aW5nTmFtZSwgX10pID0+IGV4aXN0aW5nTmFtZSAhPT0gbmFtZSlcbiAgICB9KVxuICB9LFxuXG4gIHB1dFN0aWNreShlbCwgbmFtZSwgb3Ape1xuICAgIGxldCBzdGFzaGVkUmVzdWx0ID0gb3AoZWwpXG4gICAgdGhpcy51cGRhdGVQcml2YXRlKGVsLCBcInN0aWNreVwiLCBbXSwgb3BzID0+IHtcbiAgICAgIGxldCBleGlzdGluZ0luZGV4ID0gb3BzLmZpbmRJbmRleCgoW2V4aXN0aW5nTmFtZSwgXSkgPT4gbmFtZSA9PT0gZXhpc3RpbmdOYW1lKVxuICAgICAgaWYoZXhpc3RpbmdJbmRleCA+PSAwKXtcbiAgICAgICAgb3BzW2V4aXN0aW5nSW5kZXhdID0gW25hbWUsIG9wLCBzdGFzaGVkUmVzdWx0XVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3BzLnB1c2goW25hbWUsIG9wLCBzdGFzaGVkUmVzdWx0XSlcbiAgICAgIH1cbiAgICAgIHJldHVybiBvcHNcbiAgICB9KVxuICB9LFxuXG4gIGFwcGx5U3RpY2t5T3BlcmF0aW9ucyhlbCl7XG4gICAgbGV0IG9wcyA9IERPTS5wcml2YXRlKGVsLCBcInN0aWNreVwiKVxuICAgIGlmKCFvcHMpeyByZXR1cm4gfVxuXG4gICAgb3BzLmZvckVhY2goKFtuYW1lLCBvcCwgX3N0YXNoZWRdKSA9PiB0aGlzLnB1dFN0aWNreShlbCwgbmFtZSwgb3ApKVxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IERPTVxuIiwgImltcG9ydCB7XG4gIFBIWF9BQ1RJVkVfRU5UUllfUkVGUyxcbiAgUEhYX0xJVkVfRklMRV9VUERBVEVELFxuICBQSFhfUFJFRkxJR0hURURfUkVGU1xufSBmcm9tIFwiLi9jb25zdGFudHNcIlxuXG5pbXBvcnQge1xuICBjaGFubmVsVXBsb2FkZXIsXG4gIGxvZ0Vycm9yXG59IGZyb20gXCIuL3V0aWxzXCJcblxuaW1wb3J0IExpdmVVcGxvYWRlciBmcm9tIFwiLi9saXZlX3VwbG9hZGVyXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVXBsb2FkRW50cnkge1xuICBzdGF0aWMgaXNBY3RpdmUoZmlsZUVsLCBmaWxlKXtcbiAgICBsZXQgaXNOZXcgPSBmaWxlLl9waHhSZWYgPT09IHVuZGVmaW5lZFxuICAgIGxldCBhY3RpdmVSZWZzID0gZmlsZUVsLmdldEF0dHJpYnV0ZShQSFhfQUNUSVZFX0VOVFJZX1JFRlMpLnNwbGl0KFwiLFwiKVxuICAgIGxldCBpc0FjdGl2ZSA9IGFjdGl2ZVJlZnMuaW5kZXhPZihMaXZlVXBsb2FkZXIuZ2VuRmlsZVJlZihmaWxlKSkgPj0gMFxuICAgIHJldHVybiBmaWxlLnNpemUgPiAwICYmIChpc05ldyB8fCBpc0FjdGl2ZSlcbiAgfVxuXG4gIHN0YXRpYyBpc1ByZWZsaWdodGVkKGZpbGVFbCwgZmlsZSl7XG4gICAgbGV0IHByZWZsaWdodGVkUmVmcyA9IGZpbGVFbC5nZXRBdHRyaWJ1dGUoUEhYX1BSRUZMSUdIVEVEX1JFRlMpLnNwbGl0KFwiLFwiKVxuICAgIGxldCBpc1ByZWZsaWdodGVkID0gcHJlZmxpZ2h0ZWRSZWZzLmluZGV4T2YoTGl2ZVVwbG9hZGVyLmdlbkZpbGVSZWYoZmlsZSkpID49IDBcbiAgICByZXR1cm4gaXNQcmVmbGlnaHRlZCAmJiB0aGlzLmlzQWN0aXZlKGZpbGVFbCwgZmlsZSlcbiAgfVxuXG4gIHN0YXRpYyBpc1ByZWZsaWdodEluUHJvZ3Jlc3MoZmlsZSl7XG4gICAgcmV0dXJuIGZpbGUuX3ByZWZsaWdodEluUHJvZ3Jlc3MgPT09IHRydWVcbiAgfVxuXG4gIHN0YXRpYyBtYXJrUHJlZmxpZ2h0SW5Qcm9ncmVzcyhmaWxlKXtcbiAgICBmaWxlLl9wcmVmbGlnaHRJblByb2dyZXNzID0gdHJ1ZVxuICB9XG5cbiAgY29uc3RydWN0b3IoZmlsZUVsLCBmaWxlLCB2aWV3LCBhdXRvVXBsb2FkKXtcbiAgICB0aGlzLnJlZiA9IExpdmVVcGxvYWRlci5nZW5GaWxlUmVmKGZpbGUpXG4gICAgdGhpcy5maWxlRWwgPSBmaWxlRWxcbiAgICB0aGlzLmZpbGUgPSBmaWxlXG4gICAgdGhpcy52aWV3ID0gdmlld1xuICAgIHRoaXMubWV0YSA9IG51bGxcbiAgICB0aGlzLl9pc0NhbmNlbGxlZCA9IGZhbHNlXG4gICAgdGhpcy5faXNEb25lID0gZmFsc2VcbiAgICB0aGlzLl9wcm9ncmVzcyA9IDBcbiAgICB0aGlzLl9sYXN0UHJvZ3Jlc3NTZW50ID0gLTFcbiAgICB0aGlzLl9vbkRvbmUgPSBmdW5jdGlvbigpeyB9XG4gICAgdGhpcy5fb25FbFVwZGF0ZWQgPSB0aGlzLm9uRWxVcGRhdGVkLmJpbmQodGhpcylcbiAgICB0aGlzLmZpbGVFbC5hZGRFdmVudExpc3RlbmVyKFBIWF9MSVZFX0ZJTEVfVVBEQVRFRCwgdGhpcy5fb25FbFVwZGF0ZWQpXG4gICAgdGhpcy5hdXRvVXBsb2FkID0gYXV0b1VwbG9hZFxuICB9XG5cbiAgbWV0YWRhdGEoKXsgcmV0dXJuIHRoaXMubWV0YSB9XG5cbiAgcHJvZ3Jlc3MocHJvZ3Jlc3Mpe1xuICAgIHRoaXMuX3Byb2dyZXNzID0gTWF0aC5mbG9vcihwcm9ncmVzcylcbiAgICBpZih0aGlzLl9wcm9ncmVzcyA+IHRoaXMuX2xhc3RQcm9ncmVzc1NlbnQpe1xuICAgICAgaWYodGhpcy5fcHJvZ3Jlc3MgPj0gMTAwKXtcbiAgICAgICAgdGhpcy5fcHJvZ3Jlc3MgPSAxMDBcbiAgICAgICAgdGhpcy5fbGFzdFByb2dyZXNzU2VudCA9IDEwMFxuICAgICAgICB0aGlzLl9pc0RvbmUgPSB0cnVlXG4gICAgICAgIHRoaXMudmlldy5wdXNoRmlsZVByb2dyZXNzKHRoaXMuZmlsZUVsLCB0aGlzLnJlZiwgMTAwLCAoKSA9PiB7XG4gICAgICAgICAgTGl2ZVVwbG9hZGVyLnVudHJhY2tGaWxlKHRoaXMuZmlsZUVsLCB0aGlzLmZpbGUpXG4gICAgICAgICAgdGhpcy5fb25Eb25lKClcbiAgICAgICAgfSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2xhc3RQcm9ncmVzc1NlbnQgPSB0aGlzLl9wcm9ncmVzc1xuICAgICAgICB0aGlzLnZpZXcucHVzaEZpbGVQcm9ncmVzcyh0aGlzLmZpbGVFbCwgdGhpcy5yZWYsIHRoaXMuX3Byb2dyZXNzKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlzQ2FuY2VsbGVkKCl7IHJldHVybiB0aGlzLl9pc0NhbmNlbGxlZCB9XG5cbiAgY2FuY2VsKCl7XG4gICAgdGhpcy5maWxlLl9wcmVmbGlnaHRJblByb2dyZXNzID0gZmFsc2VcbiAgICB0aGlzLl9pc0NhbmNlbGxlZCA9IHRydWVcbiAgICB0aGlzLl9pc0RvbmUgPSB0cnVlXG4gICAgdGhpcy5fb25Eb25lKClcbiAgfVxuXG4gIGlzRG9uZSgpeyByZXR1cm4gdGhpcy5faXNEb25lIH1cblxuICBlcnJvcihyZWFzb24gPSBcImZhaWxlZFwiKXtcbiAgICB0aGlzLmZpbGVFbC5yZW1vdmVFdmVudExpc3RlbmVyKFBIWF9MSVZFX0ZJTEVfVVBEQVRFRCwgdGhpcy5fb25FbFVwZGF0ZWQpXG4gICAgdGhpcy52aWV3LnB1c2hGaWxlUHJvZ3Jlc3ModGhpcy5maWxlRWwsIHRoaXMucmVmLCB7ZXJyb3I6IHJlYXNvbn0pXG4gICAgaWYoIXRoaXMuaXNBdXRvVXBsb2FkKCkpeyBMaXZlVXBsb2FkZXIuY2xlYXJGaWxlcyh0aGlzLmZpbGVFbCkgfVxuICB9XG5cbiAgaXNBdXRvVXBsb2FkKCl7IHJldHVybiB0aGlzLmF1dG9VcGxvYWQgfVxuXG4gIC8vcHJpdmF0ZVxuXG4gIG9uRG9uZShjYWxsYmFjayl7XG4gICAgdGhpcy5fb25Eb25lID0gKCkgPT4ge1xuICAgICAgdGhpcy5maWxlRWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihQSFhfTElWRV9GSUxFX1VQREFURUQsIHRoaXMuX29uRWxVcGRhdGVkKVxuICAgICAgY2FsbGJhY2soKVxuICAgIH1cbiAgfVxuXG4gIG9uRWxVcGRhdGVkKCl7XG4gICAgbGV0IGFjdGl2ZVJlZnMgPSB0aGlzLmZpbGVFbC5nZXRBdHRyaWJ1dGUoUEhYX0FDVElWRV9FTlRSWV9SRUZTKS5zcGxpdChcIixcIilcbiAgICBpZihhY3RpdmVSZWZzLmluZGV4T2YodGhpcy5yZWYpID09PSAtMSl7XG4gICAgICBMaXZlVXBsb2FkZXIudW50cmFja0ZpbGUodGhpcy5maWxlRWwsIHRoaXMuZmlsZSlcbiAgICAgIHRoaXMuY2FuY2VsKClcbiAgICB9XG4gIH1cblxuICB0b1ByZWZsaWdodFBheWxvYWQoKXtcbiAgICByZXR1cm4ge1xuICAgICAgbGFzdF9tb2RpZmllZDogdGhpcy5maWxlLmxhc3RNb2RpZmllZCxcbiAgICAgIG5hbWU6IHRoaXMuZmlsZS5uYW1lLFxuICAgICAgcmVsYXRpdmVfcGF0aDogdGhpcy5maWxlLndlYmtpdFJlbGF0aXZlUGF0aCxcbiAgICAgIHNpemU6IHRoaXMuZmlsZS5zaXplLFxuICAgICAgdHlwZTogdGhpcy5maWxlLnR5cGUsXG4gICAgICByZWY6IHRoaXMucmVmLFxuICAgICAgbWV0YTogdHlwZW9mKHRoaXMuZmlsZS5tZXRhKSA9PT0gXCJmdW5jdGlvblwiID8gdGhpcy5maWxlLm1ldGEoKSA6IHVuZGVmaW5lZFxuICAgIH1cbiAgfVxuXG4gIHVwbG9hZGVyKHVwbG9hZGVycyl7XG4gICAgaWYodGhpcy5tZXRhLnVwbG9hZGVyKXtcbiAgICAgIGxldCBjYWxsYmFjayA9IHVwbG9hZGVyc1t0aGlzLm1ldGEudXBsb2FkZXJdIHx8IGxvZ0Vycm9yKGBubyB1cGxvYWRlciBjb25maWd1cmVkIGZvciAke3RoaXMubWV0YS51cGxvYWRlcn1gKVxuICAgICAgcmV0dXJuIHtuYW1lOiB0aGlzLm1ldGEudXBsb2FkZXIsIGNhbGxiYWNrOiBjYWxsYmFja31cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHtuYW1lOiBcImNoYW5uZWxcIiwgY2FsbGJhY2s6IGNoYW5uZWxVcGxvYWRlcn1cbiAgICB9XG4gIH1cblxuICB6aXBQb3N0RmxpZ2h0KHJlc3Ape1xuICAgIHRoaXMubWV0YSA9IHJlc3AuZW50cmllc1t0aGlzLnJlZl1cbiAgICBpZighdGhpcy5tZXRhKXsgbG9nRXJyb3IoYG5vIHByZWZsaWdodCB1cGxvYWQgcmVzcG9uc2UgcmV0dXJuZWQgd2l0aCByZWYgJHt0aGlzLnJlZn1gLCB7aW5wdXQ6IHRoaXMuZmlsZUVsLCByZXNwb25zZTogcmVzcH0pIH1cbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIFBIWF9ET05FX1JFRlMsXG4gIFBIWF9QUkVGTElHSFRFRF9SRUZTLFxuICBQSFhfVVBMT0FEX1JFRlxufSBmcm9tIFwiLi9jb25zdGFudHNcIlxuXG5pbXBvcnQge1xufSBmcm9tIFwiLi91dGlsc1wiXG5cbmltcG9ydCBET00gZnJvbSBcIi4vZG9tXCJcbmltcG9ydCBVcGxvYWRFbnRyeSBmcm9tIFwiLi91cGxvYWRfZW50cnlcIlxuXG5sZXQgbGl2ZVVwbG9hZGVyRmlsZVJlZiA9IDBcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGl2ZVVwbG9hZGVyIHtcbiAgc3RhdGljIGdlbkZpbGVSZWYoZmlsZSl7XG4gICAgbGV0IHJlZiA9IGZpbGUuX3BoeFJlZlxuICAgIGlmKHJlZiAhPT0gdW5kZWZpbmVkKXtcbiAgICAgIHJldHVybiByZWZcbiAgICB9IGVsc2Uge1xuICAgICAgZmlsZS5fcGh4UmVmID0gKGxpdmVVcGxvYWRlckZpbGVSZWYrKykudG9TdHJpbmcoKVxuICAgICAgcmV0dXJuIGZpbGUuX3BoeFJlZlxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBnZXRFbnRyeURhdGFVUkwoaW5wdXRFbCwgcmVmLCBjYWxsYmFjayl7XG4gICAgbGV0IGZpbGUgPSB0aGlzLmFjdGl2ZUZpbGVzKGlucHV0RWwpLmZpbmQoZmlsZSA9PiB0aGlzLmdlbkZpbGVSZWYoZmlsZSkgPT09IHJlZilcbiAgICBjYWxsYmFjayhVUkwuY3JlYXRlT2JqZWN0VVJMKGZpbGUpKVxuICB9XG5cbiAgc3RhdGljIGhhc1VwbG9hZHNJblByb2dyZXNzKGZvcm1FbCl7XG4gICAgbGV0IGFjdGl2ZSA9IDBcbiAgICBET00uZmluZFVwbG9hZElucHV0cyhmb3JtRWwpLmZvckVhY2goaW5wdXQgPT4ge1xuICAgICAgaWYoaW5wdXQuZ2V0QXR0cmlidXRlKFBIWF9QUkVGTElHSFRFRF9SRUZTKSAhPT0gaW5wdXQuZ2V0QXR0cmlidXRlKFBIWF9ET05FX1JFRlMpKXtcbiAgICAgICAgYWN0aXZlKytcbiAgICAgIH1cbiAgICB9KVxuICAgIHJldHVybiBhY3RpdmUgPiAwXG4gIH1cblxuICBzdGF0aWMgc2VyaWFsaXplVXBsb2FkcyhpbnB1dEVsKXtcbiAgICBsZXQgZmlsZXMgPSB0aGlzLmFjdGl2ZUZpbGVzKGlucHV0RWwpXG4gICAgbGV0IGZpbGVEYXRhID0ge31cbiAgICBmaWxlcy5mb3JFYWNoKGZpbGUgPT4ge1xuICAgICAgbGV0IGVudHJ5ID0ge3BhdGg6IGlucHV0RWwubmFtZX1cbiAgICAgIGxldCB1cGxvYWRSZWYgPSBpbnB1dEVsLmdldEF0dHJpYnV0ZShQSFhfVVBMT0FEX1JFRilcbiAgICAgIGZpbGVEYXRhW3VwbG9hZFJlZl0gPSBmaWxlRGF0YVt1cGxvYWRSZWZdIHx8IFtdXG4gICAgICBlbnRyeS5yZWYgPSB0aGlzLmdlbkZpbGVSZWYoZmlsZSlcbiAgICAgIGVudHJ5Lmxhc3RfbW9kaWZpZWQgPSBmaWxlLmxhc3RNb2RpZmllZFxuICAgICAgZW50cnkubmFtZSA9IGZpbGUubmFtZSB8fCBlbnRyeS5yZWZcbiAgICAgIGVudHJ5LnJlbGF0aXZlX3BhdGggPSBmaWxlLndlYmtpdFJlbGF0aXZlUGF0aFxuICAgICAgZW50cnkudHlwZSA9IGZpbGUudHlwZVxuICAgICAgZW50cnkuc2l6ZSA9IGZpbGUuc2l6ZVxuICAgICAgaWYodHlwZW9mKGZpbGUubWV0YSkgPT09IFwiZnVuY3Rpb25cIil7IGVudHJ5Lm1ldGEgPSBmaWxlLm1ldGEoKSB9XG4gICAgICBmaWxlRGF0YVt1cGxvYWRSZWZdLnB1c2goZW50cnkpXG4gICAgfSlcbiAgICByZXR1cm4gZmlsZURhdGFcbiAgfVxuXG4gIHN0YXRpYyBjbGVhckZpbGVzKGlucHV0RWwpe1xuICAgIGlucHV0RWwudmFsdWUgPSBudWxsXG4gICAgaW5wdXRFbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1VQTE9BRF9SRUYpXG4gICAgRE9NLnB1dFByaXZhdGUoaW5wdXRFbCwgXCJmaWxlc1wiLCBbXSlcbiAgfVxuXG4gIHN0YXRpYyB1bnRyYWNrRmlsZShpbnB1dEVsLCBmaWxlKXtcbiAgICBET00ucHV0UHJpdmF0ZShpbnB1dEVsLCBcImZpbGVzXCIsIERPTS5wcml2YXRlKGlucHV0RWwsIFwiZmlsZXNcIikuZmlsdGVyKGYgPT4gIU9iamVjdC5pcyhmLCBmaWxlKSkpXG4gIH1cblxuICBzdGF0aWMgdHJhY2tGaWxlcyhpbnB1dEVsLCBmaWxlcywgZGF0YVRyYW5zZmVyKXtcbiAgICBpZihpbnB1dEVsLmdldEF0dHJpYnV0ZShcIm11bHRpcGxlXCIpICE9PSBudWxsKXtcbiAgICAgIGxldCBuZXdGaWxlcyA9IGZpbGVzLmZpbHRlcihmaWxlID0+ICF0aGlzLmFjdGl2ZUZpbGVzKGlucHV0RWwpLmZpbmQoZiA9PiBPYmplY3QuaXMoZiwgZmlsZSkpKVxuICAgICAgRE9NLnVwZGF0ZVByaXZhdGUoaW5wdXRFbCwgXCJmaWxlc1wiLCBbXSwgKGV4aXN0aW5nKSA9PiBleGlzdGluZy5jb25jYXQobmV3RmlsZXMpKVxuICAgICAgaW5wdXRFbC52YWx1ZSA9IG51bGxcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUmVzZXQgaW5wdXRFbCBmaWxlcyB0byBhbGlnbiBvdXRwdXQgd2l0aCBwcm9ncmFtbWF0aWMgY2hhbmdlcyAoaS5lLiBkcmFnIGFuZCBkcm9wKVxuICAgICAgaWYoZGF0YVRyYW5zZmVyICYmIGRhdGFUcmFuc2Zlci5maWxlcy5sZW5ndGggPiAwKXsgaW5wdXRFbC5maWxlcyA9IGRhdGFUcmFuc2Zlci5maWxlcyB9XG4gICAgICBET00ucHV0UHJpdmF0ZShpbnB1dEVsLCBcImZpbGVzXCIsIGZpbGVzKVxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBhY3RpdmVGaWxlSW5wdXRzKGZvcm1FbCl7XG4gICAgbGV0IGZpbGVJbnB1dHMgPSBET00uZmluZFVwbG9hZElucHV0cyhmb3JtRWwpXG4gICAgcmV0dXJuIEFycmF5LmZyb20oZmlsZUlucHV0cykuZmlsdGVyKGVsID0+IGVsLmZpbGVzICYmIHRoaXMuYWN0aXZlRmlsZXMoZWwpLmxlbmd0aCA+IDApXG4gIH1cblxuICBzdGF0aWMgYWN0aXZlRmlsZXMoaW5wdXQpe1xuICAgIHJldHVybiAoRE9NLnByaXZhdGUoaW5wdXQsIFwiZmlsZXNcIikgfHwgW10pLmZpbHRlcihmID0+IFVwbG9hZEVudHJ5LmlzQWN0aXZlKGlucHV0LCBmKSlcbiAgfVxuXG4gIHN0YXRpYyBpbnB1dHNBd2FpdGluZ1ByZWZsaWdodChmb3JtRWwpe1xuICAgIGxldCBmaWxlSW5wdXRzID0gRE9NLmZpbmRVcGxvYWRJbnB1dHMoZm9ybUVsKVxuICAgIHJldHVybiBBcnJheS5mcm9tKGZpbGVJbnB1dHMpLmZpbHRlcihpbnB1dCA9PiB0aGlzLmZpbGVzQXdhaXRpbmdQcmVmbGlnaHQoaW5wdXQpLmxlbmd0aCA+IDApXG4gIH1cblxuICBzdGF0aWMgZmlsZXNBd2FpdGluZ1ByZWZsaWdodChpbnB1dCl7XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlRmlsZXMoaW5wdXQpLmZpbHRlcihmID0+ICFVcGxvYWRFbnRyeS5pc1ByZWZsaWdodGVkKGlucHV0LCBmKSAmJiAhVXBsb2FkRW50cnkuaXNQcmVmbGlnaHRJblByb2dyZXNzKGYpKVxuICB9XG5cbiAgc3RhdGljIG1hcmtQcmVmbGlnaHRJblByb2dyZXNzKGVudHJpZXMpe1xuICAgIGVudHJpZXMuZm9yRWFjaChlbnRyeSA9PiBVcGxvYWRFbnRyeS5tYXJrUHJlZmxpZ2h0SW5Qcm9ncmVzcyhlbnRyeS5maWxlKSlcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKGlucHV0RWwsIHZpZXcsIG9uQ29tcGxldGUpe1xuICAgIHRoaXMuYXV0b1VwbG9hZCA9IERPTS5pc0F1dG9VcGxvYWQoaW5wdXRFbClcbiAgICB0aGlzLnZpZXcgPSB2aWV3XG4gICAgdGhpcy5vbkNvbXBsZXRlID0gb25Db21wbGV0ZVxuICAgIHRoaXMuX2VudHJpZXMgPVxuICAgICAgQXJyYXkuZnJvbShMaXZlVXBsb2FkZXIuZmlsZXNBd2FpdGluZ1ByZWZsaWdodChpbnB1dEVsKSB8fCBbXSlcbiAgICAgICAgLm1hcChmaWxlID0+IG5ldyBVcGxvYWRFbnRyeShpbnB1dEVsLCBmaWxlLCB2aWV3LCB0aGlzLmF1dG9VcGxvYWQpKVxuXG4gICAgLy8gcHJldmVudCBzZW5kaW5nIGR1cGxpY2F0ZSBwcmVmbGlnaHQgcmVxdWVzdHNcbiAgICBMaXZlVXBsb2FkZXIubWFya1ByZWZsaWdodEluUHJvZ3Jlc3ModGhpcy5fZW50cmllcylcblxuICAgIHRoaXMubnVtRW50cmllc0luUHJvZ3Jlc3MgPSB0aGlzLl9lbnRyaWVzLmxlbmd0aFxuICB9XG5cbiAgaXNBdXRvVXBsb2FkKCl7IHJldHVybiB0aGlzLmF1dG9VcGxvYWQgfVxuXG4gIGVudHJpZXMoKXsgcmV0dXJuIHRoaXMuX2VudHJpZXMgfVxuXG4gIGluaXRBZGFwdGVyVXBsb2FkKHJlc3AsIG9uRXJyb3IsIGxpdmVTb2NrZXQpe1xuICAgIHRoaXMuX2VudHJpZXMgPVxuICAgICAgdGhpcy5fZW50cmllcy5tYXAoZW50cnkgPT4ge1xuICAgICAgICBpZihlbnRyeS5pc0NhbmNlbGxlZCgpKXtcbiAgICAgICAgICB0aGlzLm51bUVudHJpZXNJblByb2dyZXNzLS1cbiAgICAgICAgICBpZih0aGlzLm51bUVudHJpZXNJblByb2dyZXNzID09PSAwKXsgdGhpcy5vbkNvbXBsZXRlKCkgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVudHJ5LnppcFBvc3RGbGlnaHQocmVzcClcbiAgICAgICAgICBlbnRyeS5vbkRvbmUoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5udW1FbnRyaWVzSW5Qcm9ncmVzcy0tXG4gICAgICAgICAgICBpZih0aGlzLm51bUVudHJpZXNJblByb2dyZXNzID09PSAwKXsgdGhpcy5vbkNvbXBsZXRlKCkgfVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGVudHJ5XG4gICAgICB9KVxuXG4gICAgbGV0IGdyb3VwZWRFbnRyaWVzID0gdGhpcy5fZW50cmllcy5yZWR1Y2UoKGFjYywgZW50cnkpID0+IHtcbiAgICAgIGlmKCFlbnRyeS5tZXRhKXsgcmV0dXJuIGFjYyB9XG4gICAgICBsZXQge25hbWUsIGNhbGxiYWNrfSA9IGVudHJ5LnVwbG9hZGVyKGxpdmVTb2NrZXQudXBsb2FkZXJzKVxuICAgICAgYWNjW25hbWVdID0gYWNjW25hbWVdIHx8IHtjYWxsYmFjazogY2FsbGJhY2ssIGVudHJpZXM6IFtdfVxuICAgICAgYWNjW25hbWVdLmVudHJpZXMucHVzaChlbnRyeSlcbiAgICAgIHJldHVybiBhY2NcbiAgICB9LCB7fSlcblxuICAgIGZvcihsZXQgbmFtZSBpbiBncm91cGVkRW50cmllcyl7XG4gICAgICBsZXQge2NhbGxiYWNrLCBlbnRyaWVzfSA9IGdyb3VwZWRFbnRyaWVzW25hbWVdXG4gICAgICBjYWxsYmFjayhlbnRyaWVzLCBvbkVycm9yLCByZXNwLCBsaXZlU29ja2V0KVxuICAgIH1cbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIFBIWF9BQ1RJVkVfRU5UUllfUkVGUyxcbiAgUEhYX0xJVkVfRklMRV9VUERBVEVELFxuICBQSFhfUFJFRkxJR0hURURfUkVGUyxcbiAgUEhYX1VQTE9BRF9SRUZcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCJcblxuaW1wb3J0IExpdmVVcGxvYWRlciBmcm9tIFwiLi9saXZlX3VwbG9hZGVyXCJcbmltcG9ydCBBUklBIGZyb20gXCIuL2FyaWFcIlxuXG5sZXQgSG9va3MgPSB7XG4gIExpdmVGaWxlVXBsb2FkOiB7XG4gICAgYWN0aXZlUmVmcygpeyByZXR1cm4gdGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX0FDVElWRV9FTlRSWV9SRUZTKSB9LFxuXG4gICAgcHJlZmxpZ2h0ZWRSZWZzKCl7IHJldHVybiB0aGlzLmVsLmdldEF0dHJpYnV0ZShQSFhfUFJFRkxJR0hURURfUkVGUykgfSxcblxuICAgIG1vdW50ZWQoKXsgdGhpcy5wcmVmbGlnaHRlZFdhcyA9IHRoaXMucHJlZmxpZ2h0ZWRSZWZzKCkgfSxcblxuICAgIHVwZGF0ZWQoKXtcbiAgICAgIGxldCBuZXdQcmVmbGlnaHRzID0gdGhpcy5wcmVmbGlnaHRlZFJlZnMoKVxuICAgICAgaWYodGhpcy5wcmVmbGlnaHRlZFdhcyAhPT0gbmV3UHJlZmxpZ2h0cyl7XG4gICAgICAgIHRoaXMucHJlZmxpZ2h0ZWRXYXMgPSBuZXdQcmVmbGlnaHRzXG4gICAgICAgIGlmKG5ld1ByZWZsaWdodHMgPT09IFwiXCIpe1xuICAgICAgICAgIHRoaXMuX192aWV3LmNhbmNlbFN1Ym1pdCh0aGlzLmVsLmZvcm0pXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYodGhpcy5hY3RpdmVSZWZzKCkgPT09IFwiXCIpeyB0aGlzLmVsLnZhbHVlID0gbnVsbCB9XG4gICAgICB0aGlzLmVsLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KFBIWF9MSVZFX0ZJTEVfVVBEQVRFRCkpXG4gICAgfVxuICB9LFxuXG4gIExpdmVJbWdQcmV2aWV3OiB7XG4gICAgbW91bnRlZCgpe1xuICAgICAgdGhpcy5yZWYgPSB0aGlzLmVsLmdldEF0dHJpYnV0ZShcImRhdGEtcGh4LWVudHJ5LXJlZlwiKVxuICAgICAgdGhpcy5pbnB1dEVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5lbC5nZXRBdHRyaWJ1dGUoUEhYX1VQTE9BRF9SRUYpKVxuICAgICAgTGl2ZVVwbG9hZGVyLmdldEVudHJ5RGF0YVVSTCh0aGlzLmlucHV0RWwsIHRoaXMucmVmLCB1cmwgPT4ge1xuICAgICAgICB0aGlzLnVybCA9IHVybFxuICAgICAgICB0aGlzLmVsLnNyYyA9IHVybFxuICAgICAgfSlcbiAgICB9LFxuICAgIGRlc3Ryb3llZCgpe1xuICAgICAgVVJMLnJldm9rZU9iamVjdFVSTCh0aGlzLnVybClcbiAgICB9XG4gIH0sXG4gIEZvY3VzV3JhcDoge1xuICAgIG1vdW50ZWQoKXtcbiAgICAgIHRoaXMuZm9jdXNTdGFydCA9IHRoaXMuZWwuZmlyc3RFbGVtZW50Q2hpbGRcbiAgICAgIHRoaXMuZm9jdXNFbmQgPSB0aGlzLmVsLmxhc3RFbGVtZW50Q2hpbGRcbiAgICAgIHRoaXMuZm9jdXNTdGFydC5hZGRFdmVudExpc3RlbmVyKFwiZm9jdXNcIiwgKCkgPT4gQVJJQS5mb2N1c0xhc3QodGhpcy5lbCkpXG4gICAgICB0aGlzLmZvY3VzRW5kLmFkZEV2ZW50TGlzdGVuZXIoXCJmb2N1c1wiLCAoKSA9PiBBUklBLmZvY3VzRmlyc3QodGhpcy5lbCkpXG4gICAgICB0aGlzLmVsLmFkZEV2ZW50TGlzdGVuZXIoXCJwaHg6c2hvdy1lbmRcIiwgKCkgPT4gdGhpcy5lbC5mb2N1cygpKVxuICAgICAgaWYod2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy5lbCkuZGlzcGxheSAhPT0gXCJub25lXCIpe1xuICAgICAgICBBUklBLmZvY3VzRmlyc3QodGhpcy5lbClcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxubGV0IGZpbmRTY3JvbGxDb250YWluZXIgPSAoZWwpID0+IHtcbiAgLy8gdGhlIHNjcm9sbCBldmVudCB3b24ndCBiZSBmaXJlZCBvbiB0aGUgaHRtbC9ib2R5IGVsZW1lbnQgZXZlbiBpZiBvdmVyZmxvdyBpcyBzZXRcbiAgLy8gdGhlcmVmb3JlIHdlIHJldHVybiBudWxsIHRvIGluc3RlYWQgbGlzdGVuIGZvciBzY3JvbGwgZXZlbnRzIG9uIGRvY3VtZW50XG4gIGlmIChbXCJIVE1MXCIsIFwiQk9EWVwiXS5pbmRleE9mKGVsLm5vZGVOYW1lLnRvVXBwZXJDYXNlKCkpID49IDApIHJldHVybiBudWxsXG4gIGlmKFtcInNjcm9sbFwiLCBcImF1dG9cIl0uaW5kZXhPZihnZXRDb21wdXRlZFN0eWxlKGVsKS5vdmVyZmxvd1kpID49IDApIHJldHVybiBlbFxuICByZXR1cm4gZmluZFNjcm9sbENvbnRhaW5lcihlbC5wYXJlbnRFbGVtZW50KVxufVxuXG5sZXQgc2Nyb2xsVG9wID0gKHNjcm9sbENvbnRhaW5lcikgPT4ge1xuICBpZihzY3JvbGxDb250YWluZXIpe1xuICAgIHJldHVybiBzY3JvbGxDb250YWluZXIuc2Nyb2xsVG9wXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxUb3BcbiAgfVxufVxuXG5sZXQgYm90dG9tID0gKHNjcm9sbENvbnRhaW5lcikgPT4ge1xuICBpZihzY3JvbGxDb250YWluZXIpe1xuICAgIHJldHVybiBzY3JvbGxDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuYm90dG9tXG4gIH0gZWxzZSB7XG4gICAgLy8gd2hlbiB3ZSBoYXZlIG5vIGNvbnRhaW5lciwgdGhlIHdob2xlIHBhZ2Ugc2Nyb2xscyxcbiAgICAvLyB0aGVyZWZvcmUgdGhlIGJvdHRvbSBjb29yZGluYXRlIGlzIHRoZSB2aWV3cG9ydCBoZWlnaHRcbiAgICByZXR1cm4gd2luZG93LmlubmVySGVpZ2h0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHRcbiAgfVxufVxuXG5sZXQgdG9wID0gKHNjcm9sbENvbnRhaW5lcikgPT4ge1xuICBpZihzY3JvbGxDb250YWluZXIpe1xuICAgIHJldHVybiBzY3JvbGxDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wXG4gIH0gZWxzZSB7XG4gICAgLy8gd2hlbiB3ZSBoYXZlIG5vIGNvbnRhaW5lciB0aGUgd2hvbGUgcGFnZSBzY3JvbGxzLFxuICAgIC8vIHRoZXJlZm9yZSB0aGUgdG9wIGNvb3JkaW5hdGUgaXMgMFxuICAgIHJldHVybiAwXG4gIH1cbn1cblxubGV0IGlzQXRWaWV3cG9ydFRvcCA9IChlbCwgc2Nyb2xsQ29udGFpbmVyKSA9PiB7XG4gIGxldCByZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgcmV0dXJuIHJlY3QudG9wID49IHRvcChzY3JvbGxDb250YWluZXIpICYmIHJlY3QubGVmdCA+PSAwICYmIHJlY3QudG9wIDw9IGJvdHRvbShzY3JvbGxDb250YWluZXIpXG59XG5cbmxldCBpc0F0Vmlld3BvcnRCb3R0b20gPSAoZWwsIHNjcm9sbENvbnRhaW5lcikgPT4ge1xuICBsZXQgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gIHJldHVybiByZWN0LnJpZ2h0ID49IHRvcChzY3JvbGxDb250YWluZXIpICYmIHJlY3QubGVmdCA+PSAwICYmIHJlY3QuYm90dG9tIDw9IGJvdHRvbShzY3JvbGxDb250YWluZXIpXG59XG5cbmxldCBpc1dpdGhpblZpZXdwb3J0ID0gKGVsLCBzY3JvbGxDb250YWluZXIpID0+IHtcbiAgbGV0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICByZXR1cm4gcmVjdC50b3AgPj0gdG9wKHNjcm9sbENvbnRhaW5lcikgJiYgcmVjdC5sZWZ0ID49IDAgJiYgcmVjdC50b3AgPD0gYm90dG9tKHNjcm9sbENvbnRhaW5lcilcbn1cblxuSG9va3MuSW5maW5pdGVTY3JvbGwgPSB7XG4gIG1vdW50ZWQoKXtcbiAgICB0aGlzLnNjcm9sbENvbnRhaW5lciA9IGZpbmRTY3JvbGxDb250YWluZXIodGhpcy5lbClcbiAgICBsZXQgc2Nyb2xsQmVmb3JlID0gc2Nyb2xsVG9wKHRoaXMuc2Nyb2xsQ29udGFpbmVyKVxuICAgIGxldCB0b3BPdmVycmFuID0gZmFsc2VcbiAgICBsZXQgdGhyb3R0bGVJbnRlcnZhbCA9IDUwMFxuICAgIGxldCBwZW5kaW5nT3AgPSBudWxsXG5cbiAgICBsZXQgb25Ub3BPdmVycnVuID0gdGhpcy50aHJvdHRsZSh0aHJvdHRsZUludGVydmFsLCAodG9wRXZlbnQsIGZpcnN0Q2hpbGQpID0+IHtcbiAgICAgIHBlbmRpbmdPcCA9ICgpID0+IHRydWVcbiAgICAgIHRoaXMubGl2ZVNvY2tldC5leGVjSlNIb29rUHVzaCh0aGlzLmVsLCB0b3BFdmVudCwge2lkOiBmaXJzdENoaWxkLmlkLCBfb3ZlcnJhbjogdHJ1ZX0sICgpID0+IHtcbiAgICAgICAgcGVuZGluZ09wID0gbnVsbFxuICAgICAgfSlcbiAgICB9KVxuXG4gICAgbGV0IG9uRmlyc3RDaGlsZEF0VG9wID0gdGhpcy50aHJvdHRsZSh0aHJvdHRsZUludGVydmFsLCAodG9wRXZlbnQsIGZpcnN0Q2hpbGQpID0+IHtcbiAgICAgIHBlbmRpbmdPcCA9ICgpID0+IGZpcnN0Q2hpbGQuc2Nyb2xsSW50b1ZpZXcoe2Jsb2NrOiBcInN0YXJ0XCJ9KVxuICAgICAgdGhpcy5saXZlU29ja2V0LmV4ZWNKU0hvb2tQdXNoKHRoaXMuZWwsIHRvcEV2ZW50LCB7aWQ6IGZpcnN0Q2hpbGQuaWR9LCAoKSA9PiB7XG4gICAgICAgIHBlbmRpbmdPcCA9IG51bGxcbiAgICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgdGhlIERPTSBpcyBwYXRjaGVkIGJ5IHdhaXRpbmcgZm9yIHRoZSBuZXh0IHRpY2tcbiAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgaWYoIWlzV2l0aGluVmlld3BvcnQoZmlyc3RDaGlsZCwgdGhpcy5zY3JvbGxDb250YWluZXIpKXtcbiAgICAgICAgICAgIGZpcnN0Q2hpbGQuc2Nyb2xsSW50b1ZpZXcoe2Jsb2NrOiBcInN0YXJ0XCJ9KVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgIH0pXG4gICAgfSlcblxuICAgIGxldCBvbkxhc3RDaGlsZEF0Qm90dG9tID0gdGhpcy50aHJvdHRsZSh0aHJvdHRsZUludGVydmFsLCAoYm90dG9tRXZlbnQsIGxhc3RDaGlsZCkgPT4ge1xuICAgICAgcGVuZGluZ09wID0gKCkgPT4gbGFzdENoaWxkLnNjcm9sbEludG9WaWV3KHtibG9jazogXCJlbmRcIn0pXG4gICAgICB0aGlzLmxpdmVTb2NrZXQuZXhlY0pTSG9va1B1c2godGhpcy5lbCwgYm90dG9tRXZlbnQsIHtpZDogbGFzdENoaWxkLmlkfSwgKCkgPT4ge1xuICAgICAgICBwZW5kaW5nT3AgPSBudWxsXG4gICAgICAgIC8vIG1ha2Ugc3VyZSB0aGF0IHRoZSBET00gaXMgcGF0Y2hlZCBieSB3YWl0aW5nIGZvciB0aGUgbmV4dCB0aWNrXG4gICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgIGlmKCFpc1dpdGhpblZpZXdwb3J0KGxhc3RDaGlsZCwgdGhpcy5zY3JvbGxDb250YWluZXIpKXtcbiAgICAgICAgICAgIGxhc3RDaGlsZC5zY3JvbGxJbnRvVmlldyh7YmxvY2s6IFwiZW5kXCJ9KVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgIH0pXG4gICAgfSlcblxuICAgIHRoaXMub25TY3JvbGwgPSAoX2UpID0+IHtcbiAgICAgIGxldCBzY3JvbGxOb3cgPSBzY3JvbGxUb3AodGhpcy5zY3JvbGxDb250YWluZXIpXG5cbiAgICAgIGlmKHBlbmRpbmdPcCl7XG4gICAgICAgIHNjcm9sbEJlZm9yZSA9IHNjcm9sbE5vd1xuICAgICAgICByZXR1cm4gcGVuZGluZ09wKClcbiAgICAgIH1cbiAgICAgIGxldCByZWN0ID0gdGhpcy5lbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgbGV0IHRvcEV2ZW50ID0gdGhpcy5lbC5nZXRBdHRyaWJ1dGUodGhpcy5saXZlU29ja2V0LmJpbmRpbmcoXCJ2aWV3cG9ydC10b3BcIikpXG4gICAgICBsZXQgYm90dG9tRXZlbnQgPSB0aGlzLmVsLmdldEF0dHJpYnV0ZSh0aGlzLmxpdmVTb2NrZXQuYmluZGluZyhcInZpZXdwb3J0LWJvdHRvbVwiKSlcbiAgICAgIGxldCBsYXN0Q2hpbGQgPSB0aGlzLmVsLmxhc3RFbGVtZW50Q2hpbGRcbiAgICAgIGxldCBmaXJzdENoaWxkID0gdGhpcy5lbC5maXJzdEVsZW1lbnRDaGlsZFxuICAgICAgbGV0IGlzU2Nyb2xsaW5nVXAgPSBzY3JvbGxOb3cgPCBzY3JvbGxCZWZvcmVcbiAgICAgIGxldCBpc1Njcm9sbGluZ0Rvd24gPSBzY3JvbGxOb3cgPiBzY3JvbGxCZWZvcmVcblxuICAgICAgLy8gZWwgb3ZlcnJhbiB3aGlsZSBzY3JvbGxpbmcgdXBcbiAgICAgIGlmKGlzU2Nyb2xsaW5nVXAgJiYgdG9wRXZlbnQgJiYgIXRvcE92ZXJyYW4gJiYgcmVjdC50b3AgPj0gMCl7XG4gICAgICAgIHRvcE92ZXJyYW4gPSB0cnVlXG4gICAgICAgIG9uVG9wT3ZlcnJ1bih0b3BFdmVudCwgZmlyc3RDaGlsZClcbiAgICAgIH0gZWxzZSBpZihpc1Njcm9sbGluZ0Rvd24gJiYgdG9wT3ZlcnJhbiAmJiByZWN0LnRvcCA8PSAwKXtcbiAgICAgICAgdG9wT3ZlcnJhbiA9IGZhbHNlXG4gICAgICB9XG5cbiAgICAgIGlmKHRvcEV2ZW50ICYmIGlzU2Nyb2xsaW5nVXAgJiYgaXNBdFZpZXdwb3J0VG9wKGZpcnN0Q2hpbGQsIHRoaXMuc2Nyb2xsQ29udGFpbmVyKSl7XG4gICAgICAgIG9uRmlyc3RDaGlsZEF0VG9wKHRvcEV2ZW50LCBmaXJzdENoaWxkKVxuICAgICAgfSBlbHNlIGlmKGJvdHRvbUV2ZW50ICYmIGlzU2Nyb2xsaW5nRG93biAmJiBpc0F0Vmlld3BvcnRCb3R0b20obGFzdENoaWxkLCB0aGlzLnNjcm9sbENvbnRhaW5lcikpe1xuICAgICAgICBvbkxhc3RDaGlsZEF0Qm90dG9tKGJvdHRvbUV2ZW50LCBsYXN0Q2hpbGQpXG4gICAgICB9XG4gICAgICBzY3JvbGxCZWZvcmUgPSBzY3JvbGxOb3dcbiAgICB9XG5cbiAgICBpZih0aGlzLnNjcm9sbENvbnRhaW5lcil7XG4gICAgICB0aGlzLnNjcm9sbENvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIHRoaXMub25TY3JvbGwpXG4gICAgfSBlbHNlIHtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIHRoaXMub25TY3JvbGwpXG4gICAgfVxuICB9LFxuICBcbiAgZGVzdHJveWVkKCl7XG4gICAgaWYodGhpcy5zY3JvbGxDb250YWluZXIpe1xuICAgICAgdGhpcy5zY3JvbGxDb250YWluZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCB0aGlzLm9uU2Nyb2xsKVxuICAgIH0gZWxzZSB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCB0aGlzLm9uU2Nyb2xsKVxuICAgIH1cbiAgfSxcblxuICB0aHJvdHRsZShpbnRlcnZhbCwgY2FsbGJhY2spe1xuICAgIGxldCBsYXN0Q2FsbEF0ID0gMFxuICAgIGxldCB0aW1lclxuXG4gICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICBsZXQgbm93ID0gRGF0ZS5ub3coKVxuICAgICAgbGV0IHJlbWFpbmluZ1RpbWUgPSBpbnRlcnZhbCAtIChub3cgLSBsYXN0Q2FsbEF0KVxuXG4gICAgICBpZihyZW1haW5pbmdUaW1lIDw9IDAgfHwgcmVtYWluaW5nVGltZSA+IGludGVydmFsKXtcbiAgICAgICAgaWYodGltZXIpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpXG4gICAgICAgICAgdGltZXIgPSBudWxsXG4gICAgICAgIH1cbiAgICAgICAgbGFzdENhbGxBdCA9IG5vd1xuICAgICAgICBjYWxsYmFjayguLi5hcmdzKVxuICAgICAgfSBlbHNlIGlmKCF0aW1lcil7XG4gICAgICAgIHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgbGFzdENhbGxBdCA9IERhdGUubm93KClcbiAgICAgICAgICB0aW1lciA9IG51bGxcbiAgICAgICAgICBjYWxsYmFjayguLi5hcmdzKVxuICAgICAgICB9LCByZW1haW5pbmdUaW1lKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuZXhwb3J0IGRlZmF1bHQgSG9va3NcbiIsICJpbXBvcnQge1xuICBtYXliZVxufSBmcm9tIFwiLi91dGlsc1wiXG5cbmltcG9ydCBET00gZnJvbSBcIi4vZG9tXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRE9NUG9zdE1vcnBoUmVzdG9yZXIge1xuICBjb25zdHJ1Y3Rvcihjb250YWluZXJCZWZvcmUsIGNvbnRhaW5lckFmdGVyLCB1cGRhdGVUeXBlKXtcbiAgICBsZXQgaWRzQmVmb3JlID0gbmV3IFNldCgpXG4gICAgbGV0IGlkc0FmdGVyID0gbmV3IFNldChbLi4uY29udGFpbmVyQWZ0ZXIuY2hpbGRyZW5dLm1hcChjaGlsZCA9PiBjaGlsZC5pZCkpXG5cbiAgICBsZXQgZWxlbWVudHNUb01vZGlmeSA9IFtdXG5cbiAgICBBcnJheS5mcm9tKGNvbnRhaW5lckJlZm9yZS5jaGlsZHJlbikuZm9yRWFjaChjaGlsZCA9PiB7XG4gICAgICBpZihjaGlsZC5pZCl7IC8vIGFsbCBvZiBvdXIgY2hpbGRyZW4gc2hvdWxkIGJlIGVsZW1lbnRzIHdpdGggaWRzXG4gICAgICAgIGlkc0JlZm9yZS5hZGQoY2hpbGQuaWQpXG4gICAgICAgIGlmKGlkc0FmdGVyLmhhcyhjaGlsZC5pZCkpe1xuICAgICAgICAgIGxldCBwcmV2aW91c0VsZW1lbnRJZCA9IGNoaWxkLnByZXZpb3VzRWxlbWVudFNpYmxpbmcgJiYgY2hpbGQucHJldmlvdXNFbGVtZW50U2libGluZy5pZFxuICAgICAgICAgIGVsZW1lbnRzVG9Nb2RpZnkucHVzaCh7ZWxlbWVudElkOiBjaGlsZC5pZCwgcHJldmlvdXNFbGVtZW50SWQ6IHByZXZpb3VzRWxlbWVudElkfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG5cbiAgICB0aGlzLmNvbnRhaW5lcklkID0gY29udGFpbmVyQWZ0ZXIuaWRcbiAgICB0aGlzLnVwZGF0ZVR5cGUgPSB1cGRhdGVUeXBlXG4gICAgdGhpcy5lbGVtZW50c1RvTW9kaWZ5ID0gZWxlbWVudHNUb01vZGlmeVxuICAgIHRoaXMuZWxlbWVudElkc1RvQWRkID0gWy4uLmlkc0FmdGVyXS5maWx0ZXIoaWQgPT4gIWlkc0JlZm9yZS5oYXMoaWQpKVxuICB9XG5cbiAgLy8gV2UgZG8gdGhlIGZvbGxvd2luZyB0byBvcHRpbWl6ZSBhcHBlbmQvcHJlcGVuZCBvcGVyYXRpb25zOlxuICAvLyAgIDEpIFRyYWNrIGlkcyBvZiBtb2RpZmllZCBlbGVtZW50cyAmIG9mIG5ldyBlbGVtZW50c1xuICAvLyAgIDIpIEFsbCB0aGUgbW9kaWZpZWQgZWxlbWVudHMgYXJlIHB1dCBiYWNrIGluIHRoZSBjb3JyZWN0IHBvc2l0aW9uIGluIHRoZSBET00gdHJlZVxuICAvLyAgICAgIGJ5IHN0b3JpbmcgdGhlIGlkIG9mIHRoZWlyIHByZXZpb3VzIHNpYmxpbmdcbiAgLy8gICAzKSBOZXcgZWxlbWVudHMgYXJlIGdvaW5nIHRvIGJlIHB1dCBpbiB0aGUgcmlnaHQgcGxhY2UgYnkgbW9ycGhkb20gZHVyaW5nIGFwcGVuZC5cbiAgLy8gICAgICBGb3IgcHJlcGVuZCwgd2UgbW92ZSB0aGVtIHRvIHRoZSBmaXJzdCBwb3NpdGlvbiBpbiB0aGUgY29udGFpbmVyXG4gIHBlcmZvcm0oKXtcbiAgICBsZXQgY29udGFpbmVyID0gRE9NLmJ5SWQodGhpcy5jb250YWluZXJJZClcbiAgICB0aGlzLmVsZW1lbnRzVG9Nb2RpZnkuZm9yRWFjaChlbGVtZW50VG9Nb2RpZnkgPT4ge1xuICAgICAgaWYoZWxlbWVudFRvTW9kaWZ5LnByZXZpb3VzRWxlbWVudElkKXtcbiAgICAgICAgbWF5YmUoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxlbWVudFRvTW9kaWZ5LnByZXZpb3VzRWxlbWVudElkKSwgcHJldmlvdXNFbGVtID0+IHtcbiAgICAgICAgICBtYXliZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50VG9Nb2RpZnkuZWxlbWVudElkKSwgZWxlbSA9PiB7XG4gICAgICAgICAgICBsZXQgaXNJblJpZ2h0UGxhY2UgPSBlbGVtLnByZXZpb3VzRWxlbWVudFNpYmxpbmcgJiYgZWxlbS5wcmV2aW91c0VsZW1lbnRTaWJsaW5nLmlkID09IHByZXZpb3VzRWxlbS5pZFxuICAgICAgICAgICAgaWYoIWlzSW5SaWdodFBsYWNlKXtcbiAgICAgICAgICAgICAgcHJldmlvdXNFbGVtLmluc2VydEFkamFjZW50RWxlbWVudChcImFmdGVyZW5kXCIsIGVsZW0pXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRoaXMgaXMgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIGNvbnRhaW5lclxuICAgICAgICBtYXliZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50VG9Nb2RpZnkuZWxlbWVudElkKSwgZWxlbSA9PiB7XG4gICAgICAgICAgbGV0IGlzSW5SaWdodFBsYWNlID0gZWxlbS5wcmV2aW91c0VsZW1lbnRTaWJsaW5nID09IG51bGxcbiAgICAgICAgICBpZighaXNJblJpZ2h0UGxhY2Upe1xuICAgICAgICAgICAgY29udGFpbmVyLmluc2VydEFkamFjZW50RWxlbWVudChcImFmdGVyYmVnaW5cIiwgZWxlbSlcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSlcblxuICAgIGlmKHRoaXMudXBkYXRlVHlwZSA9PSBcInByZXBlbmRcIil7XG4gICAgICB0aGlzLmVsZW1lbnRJZHNUb0FkZC5yZXZlcnNlKCkuZm9yRWFjaChlbGVtSWQgPT4ge1xuICAgICAgICBtYXliZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtSWQpLCBlbGVtID0+IGNvbnRhaW5lci5pbnNlcnRBZGphY2VudEVsZW1lbnQoXCJhZnRlcmJlZ2luXCIsIGVsZW0pKVxuICAgICAgfSlcbiAgICB9XG4gIH1cbn1cbiIsICJ2YXIgRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA9IDExO1xuXG5mdW5jdGlvbiBtb3JwaEF0dHJzKGZyb21Ob2RlLCB0b05vZGUpIHtcbiAgICB2YXIgdG9Ob2RlQXR0cnMgPSB0b05vZGUuYXR0cmlidXRlcztcbiAgICB2YXIgYXR0cjtcbiAgICB2YXIgYXR0ck5hbWU7XG4gICAgdmFyIGF0dHJOYW1lc3BhY2VVUkk7XG4gICAgdmFyIGF0dHJWYWx1ZTtcbiAgICB2YXIgZnJvbVZhbHVlO1xuXG4gICAgLy8gZG9jdW1lbnQtZnJhZ21lbnRzIGRvbnQgaGF2ZSBhdHRyaWJ1dGVzIHNvIGxldHMgbm90IGRvIGFueXRoaW5nXG4gICAgaWYgKHRvTm9kZS5ub2RlVHlwZSA9PT0gRE9DVU1FTlRfRlJBR01FTlRfTk9ERSB8fCBmcm9tTm9kZS5ub2RlVHlwZSA9PT0gRE9DVU1FTlRfRlJBR01FTlRfTk9ERSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHVwZGF0ZSBhdHRyaWJ1dGVzIG9uIG9yaWdpbmFsIERPTSBlbGVtZW50XG4gICAgZm9yICh2YXIgaSA9IHRvTm9kZUF0dHJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGF0dHIgPSB0b05vZGVBdHRyc1tpXTtcbiAgICAgICAgYXR0ck5hbWUgPSBhdHRyLm5hbWU7XG4gICAgICAgIGF0dHJOYW1lc3BhY2VVUkkgPSBhdHRyLm5hbWVzcGFjZVVSSTtcbiAgICAgICAgYXR0clZhbHVlID0gYXR0ci52YWx1ZTtcblxuICAgICAgICBpZiAoYXR0ck5hbWVzcGFjZVVSSSkge1xuICAgICAgICAgICAgYXR0ck5hbWUgPSBhdHRyLmxvY2FsTmFtZSB8fCBhdHRyTmFtZTtcbiAgICAgICAgICAgIGZyb21WYWx1ZSA9IGZyb21Ob2RlLmdldEF0dHJpYnV0ZU5TKGF0dHJOYW1lc3BhY2VVUkksIGF0dHJOYW1lKTtcblxuICAgICAgICAgICAgaWYgKGZyb21WYWx1ZSAhPT0gYXR0clZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGF0dHIucHJlZml4ID09PSAneG1sbnMnKXtcbiAgICAgICAgICAgICAgICAgICAgYXR0ck5hbWUgPSBhdHRyLm5hbWU7IC8vIEl0J3Mgbm90IGFsbG93ZWQgdG8gc2V0IGFuIGF0dHJpYnV0ZSB3aXRoIHRoZSBYTUxOUyBuYW1lc3BhY2Ugd2l0aG91dCBzcGVjaWZ5aW5nIHRoZSBgeG1sbnNgIHByZWZpeFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmcm9tTm9kZS5zZXRBdHRyaWJ1dGVOUyhhdHRyTmFtZXNwYWNlVVJJLCBhdHRyTmFtZSwgYXR0clZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZyb21WYWx1ZSA9IGZyb21Ob2RlLmdldEF0dHJpYnV0ZShhdHRyTmFtZSk7XG5cbiAgICAgICAgICAgIGlmIChmcm9tVmFsdWUgIT09IGF0dHJWYWx1ZSkge1xuICAgICAgICAgICAgICAgIGZyb21Ob2RlLnNldEF0dHJpYnV0ZShhdHRyTmFtZSwgYXR0clZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJlbW92ZSBhbnkgZXh0cmEgYXR0cmlidXRlcyBmb3VuZCBvbiB0aGUgb3JpZ2luYWwgRE9NIGVsZW1lbnQgdGhhdFxuICAgIC8vIHdlcmVuJ3QgZm91bmQgb24gdGhlIHRhcmdldCBlbGVtZW50LlxuICAgIHZhciBmcm9tTm9kZUF0dHJzID0gZnJvbU5vZGUuYXR0cmlidXRlcztcblxuICAgIGZvciAodmFyIGQgPSBmcm9tTm9kZUF0dHJzLmxlbmd0aCAtIDE7IGQgPj0gMDsgZC0tKSB7XG4gICAgICAgIGF0dHIgPSBmcm9tTm9kZUF0dHJzW2RdO1xuICAgICAgICBhdHRyTmFtZSA9IGF0dHIubmFtZTtcbiAgICAgICAgYXR0ck5hbWVzcGFjZVVSSSA9IGF0dHIubmFtZXNwYWNlVVJJO1xuXG4gICAgICAgIGlmIChhdHRyTmFtZXNwYWNlVVJJKSB7XG4gICAgICAgICAgICBhdHRyTmFtZSA9IGF0dHIubG9jYWxOYW1lIHx8IGF0dHJOYW1lO1xuXG4gICAgICAgICAgICBpZiAoIXRvTm9kZS5oYXNBdHRyaWJ1dGVOUyhhdHRyTmFtZXNwYWNlVVJJLCBhdHRyTmFtZSkpIHtcbiAgICAgICAgICAgICAgICBmcm9tTm9kZS5yZW1vdmVBdHRyaWJ1dGVOUyhhdHRyTmFtZXNwYWNlVVJJLCBhdHRyTmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoIXRvTm9kZS5oYXNBdHRyaWJ1dGUoYXR0ck5hbWUpKSB7XG4gICAgICAgICAgICAgICAgZnJvbU5vZGUucmVtb3ZlQXR0cmlidXRlKGF0dHJOYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxudmFyIHJhbmdlOyAvLyBDcmVhdGUgYSByYW5nZSBvYmplY3QgZm9yIGVmZmljZW50bHkgcmVuZGVyaW5nIHN0cmluZ3MgdG8gZWxlbWVudHMuXG52YXIgTlNfWEhUTUwgPSAnaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCc7XG5cbnZhciBkb2MgPSB0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnID8gdW5kZWZpbmVkIDogZG9jdW1lbnQ7XG52YXIgSEFTX1RFTVBMQVRFX1NVUFBPUlQgPSAhIWRvYyAmJiAnY29udGVudCcgaW4gZG9jLmNyZWF0ZUVsZW1lbnQoJ3RlbXBsYXRlJyk7XG52YXIgSEFTX1JBTkdFX1NVUFBPUlQgPSAhIWRvYyAmJiBkb2MuY3JlYXRlUmFuZ2UgJiYgJ2NyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCcgaW4gZG9jLmNyZWF0ZVJhbmdlKCk7XG5cbmZ1bmN0aW9uIGNyZWF0ZUZyYWdtZW50RnJvbVRlbXBsYXRlKHN0cikge1xuICAgIHZhciB0ZW1wbGF0ZSA9IGRvYy5jcmVhdGVFbGVtZW50KCd0ZW1wbGF0ZScpO1xuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IHN0cjtcbiAgICByZXR1cm4gdGVtcGxhdGUuY29udGVudC5jaGlsZE5vZGVzWzBdO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVGcmFnbWVudEZyb21SYW5nZShzdHIpIHtcbiAgICBpZiAoIXJhbmdlKSB7XG4gICAgICAgIHJhbmdlID0gZG9jLmNyZWF0ZVJhbmdlKCk7XG4gICAgICAgIHJhbmdlLnNlbGVjdE5vZGUoZG9jLmJvZHkpO1xuICAgIH1cblxuICAgIHZhciBmcmFnbWVudCA9IHJhbmdlLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChzdHIpO1xuICAgIHJldHVybiBmcmFnbWVudC5jaGlsZE5vZGVzWzBdO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVGcmFnbWVudEZyb21XcmFwKHN0cikge1xuICAgIHZhciBmcmFnbWVudCA9IGRvYy5jcmVhdGVFbGVtZW50KCdib2R5Jyk7XG4gICAgZnJhZ21lbnQuaW5uZXJIVE1MID0gc3RyO1xuICAgIHJldHVybiBmcmFnbWVudC5jaGlsZE5vZGVzWzBdO1xufVxuXG4vKipcbiAqIFRoaXMgaXMgYWJvdXQgdGhlIHNhbWVcbiAqIHZhciBodG1sID0gbmV3IERPTVBhcnNlcigpLnBhcnNlRnJvbVN0cmluZyhzdHIsICd0ZXh0L2h0bWwnKTtcbiAqIHJldHVybiBodG1sLmJvZHkuZmlyc3RDaGlsZDtcbiAqXG4gKiBAbWV0aG9kIHRvRWxlbWVudFxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICovXG5mdW5jdGlvbiB0b0VsZW1lbnQoc3RyKSB7XG4gICAgc3RyID0gc3RyLnRyaW0oKTtcbiAgICBpZiAoSEFTX1RFTVBMQVRFX1NVUFBPUlQpIHtcbiAgICAgIC8vIGF2b2lkIHJlc3RyaWN0aW9ucyBvbiBjb250ZW50IGZvciB0aGluZ3MgbGlrZSBgPHRyPjx0aD5IaTwvdGg+PC90cj5gIHdoaWNoXG4gICAgICAvLyBjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQgZG9lc24ndCBzdXBwb3J0XG4gICAgICAvLyA8dGVtcGxhdGU+IHN1cHBvcnQgbm90IGF2YWlsYWJsZSBpbiBJRVxuICAgICAgcmV0dXJuIGNyZWF0ZUZyYWdtZW50RnJvbVRlbXBsYXRlKHN0cik7XG4gICAgfSBlbHNlIGlmIChIQVNfUkFOR0VfU1VQUE9SVCkge1xuICAgICAgcmV0dXJuIGNyZWF0ZUZyYWdtZW50RnJvbVJhbmdlKHN0cik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNyZWF0ZUZyYWdtZW50RnJvbVdyYXAoc3RyKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdHdvIG5vZGUncyBuYW1lcyBhcmUgdGhlIHNhbWUuXG4gKlxuICogTk9URTogV2UgZG9uJ3QgYm90aGVyIGNoZWNraW5nIGBuYW1lc3BhY2VVUklgIGJlY2F1c2UgeW91IHdpbGwgbmV2ZXIgZmluZCB0d28gSFRNTCBlbGVtZW50cyB3aXRoIHRoZSBzYW1lXG4gKiAgICAgICBub2RlTmFtZSBhbmQgZGlmZmVyZW50IG5hbWVzcGFjZSBVUklzLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gYVxuICogQHBhcmFtIHtFbGVtZW50fSBiIFRoZSB0YXJnZXQgZWxlbWVudFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gY29tcGFyZU5vZGVOYW1lcyhmcm9tRWwsIHRvRWwpIHtcbiAgICB2YXIgZnJvbU5vZGVOYW1lID0gZnJvbUVsLm5vZGVOYW1lO1xuICAgIHZhciB0b05vZGVOYW1lID0gdG9FbC5ub2RlTmFtZTtcbiAgICB2YXIgZnJvbUNvZGVTdGFydCwgdG9Db2RlU3RhcnQ7XG5cbiAgICBpZiAoZnJvbU5vZGVOYW1lID09PSB0b05vZGVOYW1lKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGZyb21Db2RlU3RhcnQgPSBmcm9tTm9kZU5hbWUuY2hhckNvZGVBdCgwKTtcbiAgICB0b0NvZGVTdGFydCA9IHRvTm9kZU5hbWUuY2hhckNvZGVBdCgwKTtcblxuICAgIC8vIElmIHRoZSB0YXJnZXQgZWxlbWVudCBpcyBhIHZpcnR1YWwgRE9NIG5vZGUgb3IgU1ZHIG5vZGUgdGhlbiB3ZSBtYXlcbiAgICAvLyBuZWVkIHRvIG5vcm1hbGl6ZSB0aGUgdGFnIG5hbWUgYmVmb3JlIGNvbXBhcmluZy4gTm9ybWFsIEhUTUwgZWxlbWVudHMgdGhhdCBhcmVcbiAgICAvLyBpbiB0aGUgXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCJcbiAgICAvLyBhcmUgY29udmVydGVkIHRvIHVwcGVyIGNhc2VcbiAgICBpZiAoZnJvbUNvZGVTdGFydCA8PSA5MCAmJiB0b0NvZGVTdGFydCA+PSA5NykgeyAvLyBmcm9tIGlzIHVwcGVyIGFuZCB0byBpcyBsb3dlclxuICAgICAgICByZXR1cm4gZnJvbU5vZGVOYW1lID09PSB0b05vZGVOYW1lLnRvVXBwZXJDYXNlKCk7XG4gICAgfSBlbHNlIGlmICh0b0NvZGVTdGFydCA8PSA5MCAmJiBmcm9tQ29kZVN0YXJ0ID49IDk3KSB7IC8vIHRvIGlzIHVwcGVyIGFuZCBmcm9tIGlzIGxvd2VyXG4gICAgICAgIHJldHVybiB0b05vZGVOYW1lID09PSBmcm9tTm9kZU5hbWUudG9VcHBlckNhc2UoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuXG4vKipcbiAqIENyZWF0ZSBhbiBlbGVtZW50LCBvcHRpb25hbGx5IHdpdGggYSBrbm93biBuYW1lc3BhY2UgVVJJLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIHRoZSBlbGVtZW50IG5hbWUsIGUuZy4gJ2Rpdicgb3IgJ3N2ZydcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbmFtZXNwYWNlVVJJXSB0aGUgZWxlbWVudCdzIG5hbWVzcGFjZSBVUkksIGkuZS4gdGhlIHZhbHVlIG9mXG4gKiBpdHMgYHhtbG5zYCBhdHRyaWJ1dGUgb3IgaXRzIGluZmVycmVkIG5hbWVzcGFjZS5cbiAqXG4gKiBAcmV0dXJuIHtFbGVtZW50fVxuICovXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50TlMobmFtZSwgbmFtZXNwYWNlVVJJKSB7XG4gICAgcmV0dXJuICFuYW1lc3BhY2VVUkkgfHwgbmFtZXNwYWNlVVJJID09PSBOU19YSFRNTCA/XG4gICAgICAgIGRvYy5jcmVhdGVFbGVtZW50KG5hbWUpIDpcbiAgICAgICAgZG9jLmNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2VVUkksIG5hbWUpO1xufVxuXG4vKipcbiAqIENvcGllcyB0aGUgY2hpbGRyZW4gb2Ygb25lIERPTSBlbGVtZW50IHRvIGFub3RoZXIgRE9NIGVsZW1lbnRcbiAqL1xuZnVuY3Rpb24gbW92ZUNoaWxkcmVuKGZyb21FbCwgdG9FbCkge1xuICAgIHZhciBjdXJDaGlsZCA9IGZyb21FbC5maXJzdENoaWxkO1xuICAgIHdoaWxlIChjdXJDaGlsZCkge1xuICAgICAgICB2YXIgbmV4dENoaWxkID0gY3VyQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgIHRvRWwuYXBwZW5kQ2hpbGQoY3VyQ2hpbGQpO1xuICAgICAgICBjdXJDaGlsZCA9IG5leHRDaGlsZDtcbiAgICB9XG4gICAgcmV0dXJuIHRvRWw7XG59XG5cbmZ1bmN0aW9uIHN5bmNCb29sZWFuQXR0clByb3AoZnJvbUVsLCB0b0VsLCBuYW1lKSB7XG4gICAgaWYgKGZyb21FbFtuYW1lXSAhPT0gdG9FbFtuYW1lXSkge1xuICAgICAgICBmcm9tRWxbbmFtZV0gPSB0b0VsW25hbWVdO1xuICAgICAgICBpZiAoZnJvbUVsW25hbWVdKSB7XG4gICAgICAgICAgICBmcm9tRWwuc2V0QXR0cmlidXRlKG5hbWUsICcnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZyb21FbC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbnZhciBzcGVjaWFsRWxIYW5kbGVycyA9IHtcbiAgICBPUFRJT046IGZ1bmN0aW9uKGZyb21FbCwgdG9FbCkge1xuICAgICAgICB2YXIgcGFyZW50Tm9kZSA9IGZyb21FbC5wYXJlbnROb2RlO1xuICAgICAgICBpZiAocGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgdmFyIHBhcmVudE5hbWUgPSBwYXJlbnROb2RlLm5vZGVOYW1lLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgICAgICBpZiAocGFyZW50TmFtZSA9PT0gJ09QVEdST1VQJykge1xuICAgICAgICAgICAgICAgIHBhcmVudE5vZGUgPSBwYXJlbnROb2RlLnBhcmVudE5vZGU7XG4gICAgICAgICAgICAgICAgcGFyZW50TmFtZSA9IHBhcmVudE5vZGUgJiYgcGFyZW50Tm9kZS5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBhcmVudE5hbWUgPT09ICdTRUxFQ1QnICYmICFwYXJlbnROb2RlLmhhc0F0dHJpYnV0ZSgnbXVsdGlwbGUnKSkge1xuICAgICAgICAgICAgICAgIGlmIChmcm9tRWwuaGFzQXR0cmlidXRlKCdzZWxlY3RlZCcpICYmICF0b0VsLnNlbGVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdvcmthcm91bmQgZm9yIE1TIEVkZ2UgYnVnIHdoZXJlIHRoZSAnc2VsZWN0ZWQnIGF0dHJpYnV0ZSBjYW4gb25seSBiZVxuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmVkIGlmIHNldCB0byBhIG5vbi1lbXB0eSB2YWx1ZTpcbiAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubWljcm9zb2Z0LmNvbS9lbi11cy9taWNyb3NvZnQtZWRnZS9wbGF0Zm9ybS9pc3N1ZXMvMTIwODc2NzkvXG4gICAgICAgICAgICAgICAgICAgIGZyb21FbC5zZXRBdHRyaWJ1dGUoJ3NlbGVjdGVkJywgJ3NlbGVjdGVkJyk7XG4gICAgICAgICAgICAgICAgICAgIGZyb21FbC5yZW1vdmVBdHRyaWJ1dGUoJ3NlbGVjdGVkJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFdlIGhhdmUgdG8gcmVzZXQgc2VsZWN0IGVsZW1lbnQncyBzZWxlY3RlZEluZGV4IHRvIC0xLCBvdGhlcndpc2Ugc2V0dGluZ1xuICAgICAgICAgICAgICAgIC8vIGZyb21FbC5zZWxlY3RlZCB1c2luZyB0aGUgc3luY0Jvb2xlYW5BdHRyUHJvcCBiZWxvdyBoYXMgbm8gZWZmZWN0LlxuICAgICAgICAgICAgICAgIC8vIFRoZSBjb3JyZWN0IHNlbGVjdGVkSW5kZXggd2lsbCBiZSBzZXQgaW4gdGhlIFNFTEVDVCBzcGVjaWFsIGhhbmRsZXIgYmVsb3cuXG4gICAgICAgICAgICAgICAgcGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4ID0gLTE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3luY0Jvb2xlYW5BdHRyUHJvcChmcm9tRWwsIHRvRWwsICdzZWxlY3RlZCcpO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICogVGhlIFwidmFsdWVcIiBhdHRyaWJ1dGUgaXMgc3BlY2lhbCBmb3IgdGhlIDxpbnB1dD4gZWxlbWVudCBzaW5jZSBpdCBzZXRzXG4gICAgICogdGhlIGluaXRpYWwgdmFsdWUuIENoYW5naW5nIHRoZSBcInZhbHVlXCIgYXR0cmlidXRlIHdpdGhvdXQgY2hhbmdpbmcgdGhlXG4gICAgICogXCJ2YWx1ZVwiIHByb3BlcnR5IHdpbGwgaGF2ZSBubyBlZmZlY3Qgc2luY2UgaXQgaXMgb25seSB1c2VkIHRvIHRoZSBzZXQgdGhlXG4gICAgICogaW5pdGlhbCB2YWx1ZS4gIFNpbWlsYXIgZm9yIHRoZSBcImNoZWNrZWRcIiBhdHRyaWJ1dGUsIGFuZCBcImRpc2FibGVkXCIuXG4gICAgICovXG4gICAgSU5QVVQ6IGZ1bmN0aW9uKGZyb21FbCwgdG9FbCkge1xuICAgICAgICBzeW5jQm9vbGVhbkF0dHJQcm9wKGZyb21FbCwgdG9FbCwgJ2NoZWNrZWQnKTtcbiAgICAgICAgc3luY0Jvb2xlYW5BdHRyUHJvcChmcm9tRWwsIHRvRWwsICdkaXNhYmxlZCcpO1xuXG4gICAgICAgIGlmIChmcm9tRWwudmFsdWUgIT09IHRvRWwudmFsdWUpIHtcbiAgICAgICAgICAgIGZyb21FbC52YWx1ZSA9IHRvRWwudmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRvRWwuaGFzQXR0cmlidXRlKCd2YWx1ZScpKSB7XG4gICAgICAgICAgICBmcm9tRWwucmVtb3ZlQXR0cmlidXRlKCd2YWx1ZScpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIFRFWFRBUkVBOiBmdW5jdGlvbihmcm9tRWwsIHRvRWwpIHtcbiAgICAgICAgdmFyIG5ld1ZhbHVlID0gdG9FbC52YWx1ZTtcbiAgICAgICAgaWYgKGZyb21FbC52YWx1ZSAhPT0gbmV3VmFsdWUpIHtcbiAgICAgICAgICAgIGZyb21FbC52YWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGZpcnN0Q2hpbGQgPSBmcm9tRWwuZmlyc3RDaGlsZDtcbiAgICAgICAgaWYgKGZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgIC8vIE5lZWRlZCBmb3IgSUUuIEFwcGFyZW50bHkgSUUgc2V0cyB0aGUgcGxhY2Vob2xkZXIgYXMgdGhlXG4gICAgICAgICAgICAvLyBub2RlIHZhbHVlIGFuZCB2aXNlIHZlcnNhLiBUaGlzIGlnbm9yZXMgYW4gZW1wdHkgdXBkYXRlLlxuICAgICAgICAgICAgdmFyIG9sZFZhbHVlID0gZmlyc3RDaGlsZC5ub2RlVmFsdWU7XG5cbiAgICAgICAgICAgIGlmIChvbGRWYWx1ZSA9PSBuZXdWYWx1ZSB8fCAoIW5ld1ZhbHVlICYmIG9sZFZhbHVlID09IGZyb21FbC5wbGFjZWhvbGRlcikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZpcnN0Q2hpbGQubm9kZVZhbHVlID0gbmV3VmFsdWU7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIFNFTEVDVDogZnVuY3Rpb24oZnJvbUVsLCB0b0VsKSB7XG4gICAgICAgIGlmICghdG9FbC5oYXNBdHRyaWJ1dGUoJ211bHRpcGxlJykpIHtcbiAgICAgICAgICAgIHZhciBzZWxlY3RlZEluZGV4ID0gLTE7XG4gICAgICAgICAgICB2YXIgaSA9IDA7XG4gICAgICAgICAgICAvLyBXZSBoYXZlIHRvIGxvb3AgdGhyb3VnaCBjaGlsZHJlbiBvZiBmcm9tRWwsIG5vdCB0b0VsIHNpbmNlIG5vZGVzIGNhbiBiZSBtb3ZlZFxuICAgICAgICAgICAgLy8gZnJvbSB0b0VsIHRvIGZyb21FbCBkaXJlY3RseSB3aGVuIG1vcnBoaW5nLlxuICAgICAgICAgICAgLy8gQXQgdGhlIHRpbWUgdGhpcyBzcGVjaWFsIGhhbmRsZXIgaXMgaW52b2tlZCwgYWxsIGNoaWxkcmVuIGhhdmUgYWxyZWFkeSBiZWVuIG1vcnBoZWRcbiAgICAgICAgICAgIC8vIGFuZCBhcHBlbmRlZCB0byAvIHJlbW92ZWQgZnJvbSBmcm9tRWwsIHNvIHVzaW5nIGZyb21FbCBoZXJlIGlzIHNhZmUgYW5kIGNvcnJlY3QuXG4gICAgICAgICAgICB2YXIgY3VyQ2hpbGQgPSBmcm9tRWwuZmlyc3RDaGlsZDtcbiAgICAgICAgICAgIHZhciBvcHRncm91cDtcbiAgICAgICAgICAgIHZhciBub2RlTmFtZTtcbiAgICAgICAgICAgIHdoaWxlKGN1ckNoaWxkKSB7XG4gICAgICAgICAgICAgICAgbm9kZU5hbWUgPSBjdXJDaGlsZC5ub2RlTmFtZSAmJiBjdXJDaGlsZC5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgICAgICAgICAgICAgIGlmIChub2RlTmFtZSA9PT0gJ09QVEdST1VQJykge1xuICAgICAgICAgICAgICAgICAgICBvcHRncm91cCA9IGN1ckNoaWxkO1xuICAgICAgICAgICAgICAgICAgICBjdXJDaGlsZCA9IG9wdGdyb3VwLmZpcnN0Q2hpbGQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVOYW1lID09PSAnT1BUSU9OJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1ckNoaWxkLmhhc0F0dHJpYnV0ZSgnc2VsZWN0ZWQnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkSW5kZXggPSBpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaSsrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGN1ckNoaWxkID0gY3VyQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY3VyQ2hpbGQgJiYgb3B0Z3JvdXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1ckNoaWxkID0gb3B0Z3JvdXAubmV4dFNpYmxpbmc7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRncm91cCA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZyb21FbC5zZWxlY3RlZEluZGV4ID0gc2VsZWN0ZWRJbmRleDtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbnZhciBFTEVNRU5UX05PREUgPSAxO1xudmFyIERPQ1VNRU5UX0ZSQUdNRU5UX05PREUkMSA9IDExO1xudmFyIFRFWFRfTk9ERSA9IDM7XG52YXIgQ09NTUVOVF9OT0RFID0gODtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbmZ1bmN0aW9uIGRlZmF1bHRHZXROb2RlS2V5KG5vZGUpIHtcbiAgaWYgKG5vZGUpIHtcbiAgICByZXR1cm4gKG5vZGUuZ2V0QXR0cmlidXRlICYmIG5vZGUuZ2V0QXR0cmlidXRlKCdpZCcpKSB8fCBub2RlLmlkO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1vcnBoZG9tRmFjdG9yeShtb3JwaEF0dHJzKSB7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uIG1vcnBoZG9tKGZyb21Ob2RlLCB0b05vZGUsIG9wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHRvTm9kZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmIChmcm9tTm9kZS5ub2RlTmFtZSA9PT0gJyNkb2N1bWVudCcgfHwgZnJvbU5vZGUubm9kZU5hbWUgPT09ICdIVE1MJyB8fCBmcm9tTm9kZS5ub2RlTmFtZSA9PT0gJ0JPRFknKSB7XG4gICAgICAgIHZhciB0b05vZGVIdG1sID0gdG9Ob2RlO1xuICAgICAgICB0b05vZGUgPSBkb2MuY3JlYXRlRWxlbWVudCgnaHRtbCcpO1xuICAgICAgICB0b05vZGUuaW5uZXJIVE1MID0gdG9Ob2RlSHRtbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRvTm9kZSA9IHRvRWxlbWVudCh0b05vZGUpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodG9Ob2RlLm5vZGVUeXBlID09PSBET0NVTUVOVF9GUkFHTUVOVF9OT0RFJDEpIHtcbiAgICAgIHRvTm9kZSA9IHRvTm9kZS5maXJzdEVsZW1lbnRDaGlsZDtcbiAgICB9XG5cbiAgICB2YXIgZ2V0Tm9kZUtleSA9IG9wdGlvbnMuZ2V0Tm9kZUtleSB8fCBkZWZhdWx0R2V0Tm9kZUtleTtcbiAgICB2YXIgb25CZWZvcmVOb2RlQWRkZWQgPSBvcHRpb25zLm9uQmVmb3JlTm9kZUFkZGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uTm9kZUFkZGVkID0gb3B0aW9ucy5vbk5vZGVBZGRlZCB8fCBub29wO1xuICAgIHZhciBvbkJlZm9yZUVsVXBkYXRlZCA9IG9wdGlvbnMub25CZWZvcmVFbFVwZGF0ZWQgfHwgbm9vcDtcbiAgICB2YXIgb25FbFVwZGF0ZWQgPSBvcHRpb25zLm9uRWxVcGRhdGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uQmVmb3JlTm9kZURpc2NhcmRlZCA9IG9wdGlvbnMub25CZWZvcmVOb2RlRGlzY2FyZGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uTm9kZURpc2NhcmRlZCA9IG9wdGlvbnMub25Ob2RlRGlzY2FyZGVkIHx8IG5vb3A7XG4gICAgdmFyIG9uQmVmb3JlRWxDaGlsZHJlblVwZGF0ZWQgPSBvcHRpb25zLm9uQmVmb3JlRWxDaGlsZHJlblVwZGF0ZWQgfHwgbm9vcDtcbiAgICB2YXIgc2tpcEZyb21DaGlsZHJlbiA9IG9wdGlvbnMuc2tpcEZyb21DaGlsZHJlbiB8fCBub29wO1xuICAgIHZhciBhZGRDaGlsZCA9IG9wdGlvbnMuYWRkQ2hpbGQgfHwgZnVuY3Rpb24ocGFyZW50LCBjaGlsZCl7IHJldHVybiBwYXJlbnQuYXBwZW5kQ2hpbGQoY2hpbGQpOyB9O1xuICAgIHZhciBjaGlsZHJlbk9ubHkgPSBvcHRpb25zLmNoaWxkcmVuT25seSA9PT0gdHJ1ZTtcblxuICAgIC8vIFRoaXMgb2JqZWN0IGlzIHVzZWQgYXMgYSBsb29rdXAgdG8gcXVpY2tseSBmaW5kIGFsbCBrZXllZCBlbGVtZW50cyBpbiB0aGUgb3JpZ2luYWwgRE9NIHRyZWUuXG4gICAgdmFyIGZyb21Ob2Rlc0xvb2t1cCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdmFyIGtleWVkUmVtb3ZhbExpc3QgPSBbXTtcblxuICAgIGZ1bmN0aW9uIGFkZEtleWVkUmVtb3ZhbChrZXkpIHtcbiAgICAgIGtleWVkUmVtb3ZhbExpc3QucHVzaChrZXkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHdhbGtEaXNjYXJkZWRDaGlsZE5vZGVzKG5vZGUsIHNraXBLZXllZE5vZGVzKSB7XG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgIHZhciBjdXJDaGlsZCA9IG5vZGUuZmlyc3RDaGlsZDtcbiAgICAgICAgd2hpbGUgKGN1ckNoaWxkKSB7XG5cbiAgICAgICAgICB2YXIga2V5ID0gdW5kZWZpbmVkO1xuXG4gICAgICAgICAgaWYgKHNraXBLZXllZE5vZGVzICYmIChrZXkgPSBnZXROb2RlS2V5KGN1ckNoaWxkKSkpIHtcbiAgICAgICAgICAgIC8vIElmIHdlIGFyZSBza2lwcGluZyBrZXllZCBub2RlcyB0aGVuIHdlIGFkZCB0aGUga2V5XG4gICAgICAgICAgICAvLyB0byBhIGxpc3Qgc28gdGhhdCBpdCBjYW4gYmUgaGFuZGxlZCBhdCB0aGUgdmVyeSBlbmQuXG4gICAgICAgICAgICBhZGRLZXllZFJlbW92YWwoa2V5KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gT25seSByZXBvcnQgdGhlIG5vZGUgYXMgZGlzY2FyZGVkIGlmIGl0IGlzIG5vdCBrZXllZC4gV2UgZG8gdGhpcyBiZWNhdXNlXG4gICAgICAgICAgICAvLyBhdCB0aGUgZW5kIHdlIGxvb3AgdGhyb3VnaCBhbGwga2V5ZWQgZWxlbWVudHMgdGhhdCB3ZXJlIHVubWF0Y2hlZFxuICAgICAgICAgICAgLy8gYW5kIHRoZW4gZGlzY2FyZCB0aGVtIGluIG9uZSBmaW5hbCBwYXNzLlxuICAgICAgICAgICAgb25Ob2RlRGlzY2FyZGVkKGN1ckNoaWxkKTtcbiAgICAgICAgICAgIGlmIChjdXJDaGlsZC5maXJzdENoaWxkKSB7XG4gICAgICAgICAgICAgIHdhbGtEaXNjYXJkZWRDaGlsZE5vZGVzKGN1ckNoaWxkLCBza2lwS2V5ZWROb2Rlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY3VyQ2hpbGQgPSBjdXJDaGlsZC5uZXh0U2libGluZztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICogUmVtb3ZlcyBhIERPTSBub2RlIG91dCBvZiB0aGUgb3JpZ2luYWwgRE9NXG4gICAgKlxuICAgICogQHBhcmFtICB7Tm9kZX0gbm9kZSBUaGUgbm9kZSB0byByZW1vdmVcbiAgICAqIEBwYXJhbSAge05vZGV9IHBhcmVudE5vZGUgVGhlIG5vZGVzIHBhcmVudFxuICAgICogQHBhcmFtICB7Qm9vbGVhbn0gc2tpcEtleWVkTm9kZXMgSWYgdHJ1ZSB0aGVuIGVsZW1lbnRzIHdpdGgga2V5cyB3aWxsIGJlIHNraXBwZWQgYW5kIG5vdCBkaXNjYXJkZWQuXG4gICAgKiBAcmV0dXJuIHt1bmRlZmluZWR9XG4gICAgKi9cbiAgICBmdW5jdGlvbiByZW1vdmVOb2RlKG5vZGUsIHBhcmVudE5vZGUsIHNraXBLZXllZE5vZGVzKSB7XG4gICAgICBpZiAob25CZWZvcmVOb2RlRGlzY2FyZGVkKG5vZGUpID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXJlbnROb2RlKSB7XG4gICAgICAgIHBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7XG4gICAgICB9XG5cbiAgICAgIG9uTm9kZURpc2NhcmRlZChub2RlKTtcbiAgICAgIHdhbGtEaXNjYXJkZWRDaGlsZE5vZGVzKG5vZGUsIHNraXBLZXllZE5vZGVzKTtcbiAgICB9XG5cbiAgICAvLyAvLyBUcmVlV2Fsa2VyIGltcGxlbWVudGF0aW9uIGlzIG5vIGZhc3RlciwgYnV0IGtlZXBpbmcgdGhpcyBhcm91bmQgaW4gY2FzZSB0aGlzIGNoYW5nZXMgaW4gdGhlIGZ1dHVyZVxuICAgIC8vIGZ1bmN0aW9uIGluZGV4VHJlZShyb290KSB7XG4gICAgLy8gICAgIHZhciB0cmVlV2Fsa2VyID0gZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlcihcbiAgICAvLyAgICAgICAgIHJvb3QsXG4gICAgLy8gICAgICAgICBOb2RlRmlsdGVyLlNIT1dfRUxFTUVOVCk7XG4gICAgLy9cbiAgICAvLyAgICAgdmFyIGVsO1xuICAgIC8vICAgICB3aGlsZSgoZWwgPSB0cmVlV2Fsa2VyLm5leHROb2RlKCkpKSB7XG4gICAgLy8gICAgICAgICB2YXIga2V5ID0gZ2V0Tm9kZUtleShlbCk7XG4gICAgLy8gICAgICAgICBpZiAoa2V5KSB7XG4gICAgLy8gICAgICAgICAgICAgZnJvbU5vZGVzTG9va3VwW2tleV0gPSBlbDtcbiAgICAvLyAgICAgICAgIH1cbiAgICAvLyAgICAgfVxuICAgIC8vIH1cblxuICAgIC8vIC8vIE5vZGVJdGVyYXRvciBpbXBsZW1lbnRhdGlvbiBpcyBubyBmYXN0ZXIsIGJ1dCBrZWVwaW5nIHRoaXMgYXJvdW5kIGluIGNhc2UgdGhpcyBjaGFuZ2VzIGluIHRoZSBmdXR1cmVcbiAgICAvL1xuICAgIC8vIGZ1bmN0aW9uIGluZGV4VHJlZShub2RlKSB7XG4gICAgLy8gICAgIHZhciBub2RlSXRlcmF0b3IgPSBkb2N1bWVudC5jcmVhdGVOb2RlSXRlcmF0b3Iobm9kZSwgTm9kZUZpbHRlci5TSE9XX0VMRU1FTlQpO1xuICAgIC8vICAgICB2YXIgZWw7XG4gICAgLy8gICAgIHdoaWxlKChlbCA9IG5vZGVJdGVyYXRvci5uZXh0Tm9kZSgpKSkge1xuICAgIC8vICAgICAgICAgdmFyIGtleSA9IGdldE5vZGVLZXkoZWwpO1xuICAgIC8vICAgICAgICAgaWYgKGtleSkge1xuICAgIC8vICAgICAgICAgICAgIGZyb21Ob2Rlc0xvb2t1cFtrZXldID0gZWw7XG4gICAgLy8gICAgICAgICB9XG4gICAgLy8gICAgIH1cbiAgICAvLyB9XG5cbiAgICBmdW5jdGlvbiBpbmRleFRyZWUobm9kZSkge1xuICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSB8fCBub2RlLm5vZGVUeXBlID09PSBET0NVTUVOVF9GUkFHTUVOVF9OT0RFJDEpIHtcbiAgICAgICAgdmFyIGN1ckNoaWxkID0gbm9kZS5maXJzdENoaWxkO1xuICAgICAgICB3aGlsZSAoY3VyQ2hpbGQpIHtcbiAgICAgICAgICB2YXIga2V5ID0gZ2V0Tm9kZUtleShjdXJDaGlsZCk7XG4gICAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgZnJvbU5vZGVzTG9va3VwW2tleV0gPSBjdXJDaGlsZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBXYWxrIHJlY3Vyc2l2ZWx5XG4gICAgICAgICAgaW5kZXhUcmVlKGN1ckNoaWxkKTtcblxuICAgICAgICAgIGN1ckNoaWxkID0gY3VyQ2hpbGQubmV4dFNpYmxpbmc7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpbmRleFRyZWUoZnJvbU5vZGUpO1xuXG4gICAgZnVuY3Rpb24gaGFuZGxlTm9kZUFkZGVkKGVsKSB7XG4gICAgICBvbk5vZGVBZGRlZChlbCk7XG5cbiAgICAgIHZhciBjdXJDaGlsZCA9IGVsLmZpcnN0Q2hpbGQ7XG4gICAgICB3aGlsZSAoY3VyQ2hpbGQpIHtcbiAgICAgICAgdmFyIG5leHRTaWJsaW5nID0gY3VyQ2hpbGQubmV4dFNpYmxpbmc7XG5cbiAgICAgICAgdmFyIGtleSA9IGdldE5vZGVLZXkoY3VyQ2hpbGQpO1xuICAgICAgICBpZiAoa2V5KSB7XG4gICAgICAgICAgdmFyIHVubWF0Y2hlZEZyb21FbCA9IGZyb21Ob2Rlc0xvb2t1cFtrZXldO1xuICAgICAgICAgIC8vIGlmIHdlIGZpbmQgYSBkdXBsaWNhdGUgI2lkIG5vZGUgaW4gY2FjaGUsIHJlcGxhY2UgYGVsYCB3aXRoIGNhY2hlIHZhbHVlXG4gICAgICAgICAgLy8gYW5kIG1vcnBoIGl0IHRvIHRoZSBjaGlsZCBub2RlLlxuICAgICAgICAgIGlmICh1bm1hdGNoZWRGcm9tRWwgJiYgY29tcGFyZU5vZGVOYW1lcyhjdXJDaGlsZCwgdW5tYXRjaGVkRnJvbUVsKSkge1xuICAgICAgICAgICAgY3VyQ2hpbGQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQodW5tYXRjaGVkRnJvbUVsLCBjdXJDaGlsZCk7XG4gICAgICAgICAgICBtb3JwaEVsKHVubWF0Y2hlZEZyb21FbCwgY3VyQ2hpbGQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBoYW5kbGVOb2RlQWRkZWQoY3VyQ2hpbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyByZWN1cnNpdmVseSBjYWxsIGZvciBjdXJDaGlsZCBhbmQgaXQncyBjaGlsZHJlbiB0byBzZWUgaWYgd2UgZmluZCBzb21ldGhpbmcgaW5cbiAgICAgICAgICAvLyBmcm9tTm9kZXNMb29rdXBcbiAgICAgICAgICBoYW5kbGVOb2RlQWRkZWQoY3VyQ2hpbGQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY3VyQ2hpbGQgPSBuZXh0U2libGluZztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjbGVhbnVwRnJvbUVsKGZyb21FbCwgY3VyRnJvbU5vZGVDaGlsZCwgY3VyRnJvbU5vZGVLZXkpIHtcbiAgICAgIC8vIFdlIGhhdmUgcHJvY2Vzc2VkIGFsbCBvZiB0aGUgXCJ0byBub2Rlc1wiLiBJZiBjdXJGcm9tTm9kZUNoaWxkIGlzXG4gICAgICAvLyBub24tbnVsbCB0aGVuIHdlIHN0aWxsIGhhdmUgc29tZSBmcm9tIG5vZGVzIGxlZnQgb3ZlciB0aGF0IG5lZWRcbiAgICAgIC8vIHRvIGJlIHJlbW92ZWRcbiAgICAgIHdoaWxlIChjdXJGcm9tTm9kZUNoaWxkKSB7XG4gICAgICAgIHZhciBmcm9tTmV4dFNpYmxpbmcgPSBjdXJGcm9tTm9kZUNoaWxkLm5leHRTaWJsaW5nO1xuICAgICAgICBpZiAoKGN1ckZyb21Ob2RlS2V5ID0gZ2V0Tm9kZUtleShjdXJGcm9tTm9kZUNoaWxkKSkpIHtcbiAgICAgICAgICAvLyBTaW5jZSB0aGUgbm9kZSBpcyBrZXllZCBpdCBtaWdodCBiZSBtYXRjaGVkIHVwIGxhdGVyIHNvIHdlIGRlZmVyXG4gICAgICAgICAgLy8gdGhlIGFjdHVhbCByZW1vdmFsIHRvIGxhdGVyXG4gICAgICAgICAgYWRkS2V5ZWRSZW1vdmFsKGN1ckZyb21Ob2RlS2V5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBOT1RFOiB3ZSBza2lwIG5lc3RlZCBrZXllZCBub2RlcyBmcm9tIGJlaW5nIHJlbW92ZWQgc2luY2UgdGhlcmUgaXNcbiAgICAgICAgICAvLyAgICAgICBzdGlsbCBhIGNoYW5jZSB0aGV5IHdpbGwgYmUgbWF0Y2hlZCB1cCBsYXRlclxuICAgICAgICAgIHJlbW92ZU5vZGUoY3VyRnJvbU5vZGVDaGlsZCwgZnJvbUVsLCB0cnVlIC8qIHNraXAga2V5ZWQgbm9kZXMgKi8pO1xuICAgICAgICB9XG4gICAgICAgIGN1ckZyb21Ob2RlQ2hpbGQgPSBmcm9tTmV4dFNpYmxpbmc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbW9ycGhFbChmcm9tRWwsIHRvRWwsIGNoaWxkcmVuT25seSkge1xuICAgICAgdmFyIHRvRWxLZXkgPSBnZXROb2RlS2V5KHRvRWwpO1xuXG4gICAgICBpZiAodG9FbEtleSkge1xuICAgICAgICAvLyBJZiBhbiBlbGVtZW50IHdpdGggYW4gSUQgaXMgYmVpbmcgbW9ycGhlZCB0aGVuIGl0IHdpbGwgYmUgaW4gdGhlIGZpbmFsXG4gICAgICAgIC8vIERPTSBzbyBjbGVhciBpdCBvdXQgb2YgdGhlIHNhdmVkIGVsZW1lbnRzIGNvbGxlY3Rpb25cbiAgICAgICAgZGVsZXRlIGZyb21Ob2Rlc0xvb2t1cFt0b0VsS2V5XTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFjaGlsZHJlbk9ubHkpIHtcbiAgICAgICAgLy8gb3B0aW9uYWxcbiAgICAgICAgaWYgKG9uQmVmb3JlRWxVcGRhdGVkKGZyb21FbCwgdG9FbCkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdXBkYXRlIGF0dHJpYnV0ZXMgb24gb3JpZ2luYWwgRE9NIGVsZW1lbnQgZmlyc3RcbiAgICAgICAgbW9ycGhBdHRycyhmcm9tRWwsIHRvRWwpO1xuICAgICAgICAvLyBvcHRpb25hbFxuICAgICAgICBvbkVsVXBkYXRlZChmcm9tRWwpO1xuXG4gICAgICAgIGlmIChvbkJlZm9yZUVsQ2hpbGRyZW5VcGRhdGVkKGZyb21FbCwgdG9FbCkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChmcm9tRWwubm9kZU5hbWUgIT09ICdURVhUQVJFQScpIHtcbiAgICAgICAgbW9ycGhDaGlsZHJlbihmcm9tRWwsIHRvRWwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3BlY2lhbEVsSGFuZGxlcnMuVEVYVEFSRUEoZnJvbUVsLCB0b0VsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb3JwaENoaWxkcmVuKGZyb21FbCwgdG9FbCkge1xuICAgICAgdmFyIHNraXBGcm9tID0gc2tpcEZyb21DaGlsZHJlbihmcm9tRWwsIHRvRWwpO1xuICAgICAgdmFyIGN1clRvTm9kZUNoaWxkID0gdG9FbC5maXJzdENoaWxkO1xuICAgICAgdmFyIGN1ckZyb21Ob2RlQ2hpbGQgPSBmcm9tRWwuZmlyc3RDaGlsZDtcbiAgICAgIHZhciBjdXJUb05vZGVLZXk7XG4gICAgICB2YXIgY3VyRnJvbU5vZGVLZXk7XG5cbiAgICAgIHZhciBmcm9tTmV4dFNpYmxpbmc7XG4gICAgICB2YXIgdG9OZXh0U2libGluZztcbiAgICAgIHZhciBtYXRjaGluZ0Zyb21FbDtcblxuICAgICAgLy8gd2FsayB0aGUgY2hpbGRyZW5cbiAgICAgIG91dGVyOiB3aGlsZSAoY3VyVG9Ob2RlQ2hpbGQpIHtcbiAgICAgICAgdG9OZXh0U2libGluZyA9IGN1clRvTm9kZUNoaWxkLm5leHRTaWJsaW5nO1xuICAgICAgICBjdXJUb05vZGVLZXkgPSBnZXROb2RlS2V5KGN1clRvTm9kZUNoaWxkKTtcblxuICAgICAgICAvLyB3YWxrIHRoZSBmcm9tTm9kZSBjaGlsZHJlbiBhbGwgdGhlIHdheSB0aHJvdWdoXG4gICAgICAgIHdoaWxlICghc2tpcEZyb20gJiYgY3VyRnJvbU5vZGVDaGlsZCkge1xuICAgICAgICAgIGZyb21OZXh0U2libGluZyA9IGN1ckZyb21Ob2RlQ2hpbGQubmV4dFNpYmxpbmc7XG5cbiAgICAgICAgICBpZiAoY3VyVG9Ob2RlQ2hpbGQuaXNTYW1lTm9kZSAmJiBjdXJUb05vZGVDaGlsZC5pc1NhbWVOb2RlKGN1ckZyb21Ob2RlQ2hpbGQpKSB7XG4gICAgICAgICAgICBjdXJUb05vZGVDaGlsZCA9IHRvTmV4dFNpYmxpbmc7XG4gICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gZnJvbU5leHRTaWJsaW5nO1xuICAgICAgICAgICAgY29udGludWUgb3V0ZXI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY3VyRnJvbU5vZGVLZXkgPSBnZXROb2RlS2V5KGN1ckZyb21Ob2RlQ2hpbGQpO1xuXG4gICAgICAgICAgdmFyIGN1ckZyb21Ob2RlVHlwZSA9IGN1ckZyb21Ob2RlQ2hpbGQubm9kZVR5cGU7XG5cbiAgICAgICAgICAvLyB0aGlzIG1lYW5zIGlmIHRoZSBjdXJGcm9tTm9kZUNoaWxkIGRvZXNudCBoYXZlIGEgbWF0Y2ggd2l0aCB0aGUgY3VyVG9Ob2RlQ2hpbGRcbiAgICAgICAgICB2YXIgaXNDb21wYXRpYmxlID0gdW5kZWZpbmVkO1xuXG4gICAgICAgICAgaWYgKGN1ckZyb21Ob2RlVHlwZSA9PT0gY3VyVG9Ob2RlQ2hpbGQubm9kZVR5cGUpIHtcbiAgICAgICAgICAgIGlmIChjdXJGcm9tTm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSkge1xuICAgICAgICAgICAgICAvLyBCb3RoIG5vZGVzIGJlaW5nIGNvbXBhcmVkIGFyZSBFbGVtZW50IG5vZGVzXG5cbiAgICAgICAgICAgICAgaWYgKGN1clRvTm9kZUtleSkge1xuICAgICAgICAgICAgICAgIC8vIFRoZSB0YXJnZXQgbm9kZSBoYXMgYSBrZXkgc28gd2Ugd2FudCB0byBtYXRjaCBpdCB1cCB3aXRoIHRoZSBjb3JyZWN0IGVsZW1lbnRcbiAgICAgICAgICAgICAgICAvLyBpbiB0aGUgb3JpZ2luYWwgRE9NIHRyZWVcbiAgICAgICAgICAgICAgICBpZiAoY3VyVG9Ob2RlS2V5ICE9PSBjdXJGcm9tTm9kZUtleSkge1xuICAgICAgICAgICAgICAgICAgLy8gVGhlIGN1cnJlbnQgZWxlbWVudCBpbiB0aGUgb3JpZ2luYWwgRE9NIHRyZWUgZG9lcyBub3QgaGF2ZSBhIG1hdGNoaW5nIGtleSBzb1xuICAgICAgICAgICAgICAgICAgLy8gbGV0J3MgY2hlY2sgb3VyIGxvb2t1cCB0byBzZWUgaWYgdGhlcmUgaXMgYSBtYXRjaGluZyBlbGVtZW50IGluIHRoZSBvcmlnaW5hbFxuICAgICAgICAgICAgICAgICAgLy8gRE9NIHRyZWVcbiAgICAgICAgICAgICAgICAgIGlmICgobWF0Y2hpbmdGcm9tRWwgPSBmcm9tTm9kZXNMb29rdXBbY3VyVG9Ob2RlS2V5XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZyb21OZXh0U2libGluZyA9PT0gbWF0Y2hpbmdGcm9tRWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBTcGVjaWFsIGNhc2UgZm9yIHNpbmdsZSBlbGVtZW50IHJlbW92YWxzLiBUbyBhdm9pZCByZW1vdmluZyB0aGUgb3JpZ2luYWxcbiAgICAgICAgICAgICAgICAgICAgICAvLyBET00gbm9kZSBvdXQgb2YgdGhlIHRyZWUgKHNpbmNlIHRoYXQgY2FuIGJyZWFrIENTUyB0cmFuc2l0aW9ucywgZXRjLiksXG4gICAgICAgICAgICAgICAgICAgICAgLy8gd2Ugd2lsbCBpbnN0ZWFkIGRpc2NhcmQgdGhlIGN1cnJlbnQgbm9kZSBhbmQgd2FpdCB1bnRpbCB0aGUgbmV4dFxuICAgICAgICAgICAgICAgICAgICAgIC8vIGl0ZXJhdGlvbiB0byBwcm9wZXJseSBtYXRjaCB1cCB0aGUga2V5ZWQgdGFyZ2V0IGVsZW1lbnQgd2l0aCBpdHMgbWF0Y2hpbmdcbiAgICAgICAgICAgICAgICAgICAgICAvLyBlbGVtZW50IGluIHRoZSBvcmlnaW5hbCB0cmVlXG4gICAgICAgICAgICAgICAgICAgICAgaXNDb21wYXRpYmxlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gV2UgZm91bmQgYSBtYXRjaGluZyBrZXllZCBlbGVtZW50IHNvbWV3aGVyZSBpbiB0aGUgb3JpZ2luYWwgRE9NIHRyZWUuXG4gICAgICAgICAgICAgICAgICAgICAgLy8gTGV0J3MgbW92ZSB0aGUgb3JpZ2luYWwgRE9NIG5vZGUgaW50byB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmQgbW9ycGhcbiAgICAgICAgICAgICAgICAgICAgICAvLyBpdC5cblxuICAgICAgICAgICAgICAgICAgICAgIC8vIE5PVEU6IFdlIHVzZSBpbnNlcnRCZWZvcmUgaW5zdGVhZCBvZiByZXBsYWNlQ2hpbGQgYmVjYXVzZSB3ZSB3YW50IHRvIGdvIHRocm91Z2hcbiAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgYHJlbW92ZU5vZGUoKWAgZnVuY3Rpb24gZm9yIHRoZSBub2RlIHRoYXQgaXMgYmVpbmcgZGlzY2FyZGVkIHNvIHRoYXRcbiAgICAgICAgICAgICAgICAgICAgICAvLyBhbGwgbGlmZWN5Y2xlIGhvb2tzIGFyZSBjb3JyZWN0bHkgaW52b2tlZFxuICAgICAgICAgICAgICAgICAgICAgIGZyb21FbC5pbnNlcnRCZWZvcmUobWF0Y2hpbmdGcm9tRWwsIGN1ckZyb21Ob2RlQ2hpbGQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgLy8gZnJvbU5leHRTaWJsaW5nID0gY3VyRnJvbU5vZGVDaGlsZC5uZXh0U2libGluZztcblxuICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJGcm9tTm9kZUtleSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2luY2UgdGhlIG5vZGUgaXMga2V5ZWQgaXQgbWlnaHQgYmUgbWF0Y2hlZCB1cCBsYXRlciBzbyB3ZSBkZWZlclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGFjdHVhbCByZW1vdmFsIHRvIGxhdGVyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRLZXllZFJlbW92YWwoY3VyRnJvbU5vZGVLZXkpO1xuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBOT1RFOiB3ZSBza2lwIG5lc3RlZCBrZXllZCBub2RlcyBmcm9tIGJlaW5nIHJlbW92ZWQgc2luY2UgdGhlcmUgaXNcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgIHN0aWxsIGEgY2hhbmNlIHRoZXkgd2lsbCBiZSBtYXRjaGVkIHVwIGxhdGVyXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVOb2RlKGN1ckZyb21Ob2RlQ2hpbGQsIGZyb21FbCwgdHJ1ZSAvKiBza2lwIGtleWVkIG5vZGVzICovKTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkID0gbWF0Y2hpbmdGcm9tRWw7XG4gICAgICAgICAgICAgICAgICAgICAgY3VyRnJvbU5vZGVLZXkgPSBnZXROb2RlS2V5KGN1ckZyb21Ob2RlQ2hpbGQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgbm9kZXMgYXJlIG5vdCBjb21wYXRpYmxlIHNpbmNlIHRoZSBcInRvXCIgbm9kZSBoYXMgYSBrZXkgYW5kIHRoZXJlXG4gICAgICAgICAgICAgICAgICAgIC8vIGlzIG5vIG1hdGNoaW5nIGtleWVkIG5vZGUgaW4gdGhlIHNvdXJjZSB0cmVlXG4gICAgICAgICAgICAgICAgICAgIGlzQ29tcGF0aWJsZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChjdXJGcm9tTm9kZUtleSkge1xuICAgICAgICAgICAgICAgIC8vIFRoZSBvcmlnaW5hbCBoYXMgYSBrZXlcbiAgICAgICAgICAgICAgICBpc0NvbXBhdGlibGUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlzQ29tcGF0aWJsZSA9IGlzQ29tcGF0aWJsZSAhPT0gZmFsc2UgJiYgY29tcGFyZU5vZGVOYW1lcyhjdXJGcm9tTm9kZUNoaWxkLCBjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgICAgIGlmIChpc0NvbXBhdGlibGUpIHtcbiAgICAgICAgICAgICAgICAvLyBXZSBmb3VuZCBjb21wYXRpYmxlIERPTSBlbGVtZW50cyBzbyB0cmFuc2Zvcm1cbiAgICAgICAgICAgICAgICAvLyB0aGUgY3VycmVudCBcImZyb21cIiBub2RlIHRvIG1hdGNoIHRoZSBjdXJyZW50XG4gICAgICAgICAgICAgICAgLy8gdGFyZ2V0IERPTSBub2RlLlxuICAgICAgICAgICAgICAgIC8vIE1PUlBIXG4gICAgICAgICAgICAgICAgbW9ycGhFbChjdXJGcm9tTm9kZUNoaWxkLCBjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgfSBlbHNlIGlmIChjdXJGcm9tTm9kZVR5cGUgPT09IFRFWFRfTk9ERSB8fCBjdXJGcm9tTm9kZVR5cGUgPT0gQ09NTUVOVF9OT0RFKSB7XG4gICAgICAgICAgICAgIC8vIEJvdGggbm9kZXMgYmVpbmcgY29tcGFyZWQgYXJlIFRleHQgb3IgQ29tbWVudCBub2Rlc1xuICAgICAgICAgICAgICBpc0NvbXBhdGlibGUgPSB0cnVlO1xuICAgICAgICAgICAgICAvLyBTaW1wbHkgdXBkYXRlIG5vZGVWYWx1ZSBvbiB0aGUgb3JpZ2luYWwgbm9kZSB0b1xuICAgICAgICAgICAgICAvLyBjaGFuZ2UgdGhlIHRleHQgdmFsdWVcbiAgICAgICAgICAgICAgaWYgKGN1ckZyb21Ob2RlQ2hpbGQubm9kZVZhbHVlICE9PSBjdXJUb05vZGVDaGlsZC5ub2RlVmFsdWUpIHtcbiAgICAgICAgICAgICAgICBjdXJGcm9tTm9kZUNoaWxkLm5vZGVWYWx1ZSA9IGN1clRvTm9kZUNoaWxkLm5vZGVWYWx1ZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGlzQ29tcGF0aWJsZSkge1xuICAgICAgICAgICAgLy8gQWR2YW5jZSBib3RoIHRoZSBcInRvXCIgY2hpbGQgYW5kIHRoZSBcImZyb21cIiBjaGlsZCBzaW5jZSB3ZSBmb3VuZCBhIG1hdGNoXG4gICAgICAgICAgICAvLyBOb3RoaW5nIGVsc2UgdG8gZG8gYXMgd2UgYWxyZWFkeSByZWN1cnNpdmVseSBjYWxsZWQgbW9ycGhDaGlsZHJlbiBhYm92ZVxuICAgICAgICAgICAgY3VyVG9Ob2RlQ2hpbGQgPSB0b05leHRTaWJsaW5nO1xuICAgICAgICAgICAgY3VyRnJvbU5vZGVDaGlsZCA9IGZyb21OZXh0U2libGluZztcbiAgICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIE5vIGNvbXBhdGlibGUgbWF0Y2ggc28gcmVtb3ZlIHRoZSBvbGQgbm9kZSBmcm9tIHRoZSBET00gYW5kIGNvbnRpbnVlIHRyeWluZyB0byBmaW5kIGFcbiAgICAgICAgICAvLyBtYXRjaCBpbiB0aGUgb3JpZ2luYWwgRE9NLiBIb3dldmVyLCB3ZSBvbmx5IGRvIHRoaXMgaWYgdGhlIGZyb20gbm9kZSBpcyBub3Qga2V5ZWRcbiAgICAgICAgICAvLyBzaW5jZSBpdCBpcyBwb3NzaWJsZSB0aGF0IGEga2V5ZWQgbm9kZSBtaWdodCBtYXRjaCB1cCB3aXRoIGEgbm9kZSBzb21ld2hlcmUgZWxzZSBpbiB0aGVcbiAgICAgICAgICAvLyB0YXJnZXQgdHJlZSBhbmQgd2UgZG9uJ3Qgd2FudCB0byBkaXNjYXJkIGl0IGp1c3QgeWV0IHNpbmNlIGl0IHN0aWxsIG1pZ2h0IGZpbmQgYVxuICAgICAgICAgIC8vIGhvbWUgaW4gdGhlIGZpbmFsIERPTSB0cmVlLiBBZnRlciBldmVyeXRoaW5nIGlzIGRvbmUgd2Ugd2lsbCByZW1vdmUgYW55IGtleWVkIG5vZGVzXG4gICAgICAgICAgLy8gdGhhdCBkaWRuJ3QgZmluZCBhIGhvbWVcbiAgICAgICAgICBpZiAoY3VyRnJvbU5vZGVLZXkpIHtcbiAgICAgICAgICAgIC8vIFNpbmNlIHRoZSBub2RlIGlzIGtleWVkIGl0IG1pZ2h0IGJlIG1hdGNoZWQgdXAgbGF0ZXIgc28gd2UgZGVmZXJcbiAgICAgICAgICAgIC8vIHRoZSBhY3R1YWwgcmVtb3ZhbCB0byBsYXRlclxuICAgICAgICAgICAgYWRkS2V5ZWRSZW1vdmFsKGN1ckZyb21Ob2RlS2V5KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gTk9URTogd2Ugc2tpcCBuZXN0ZWQga2V5ZWQgbm9kZXMgZnJvbSBiZWluZyByZW1vdmVkIHNpbmNlIHRoZXJlIGlzXG4gICAgICAgICAgICAvLyAgICAgICBzdGlsbCBhIGNoYW5jZSB0aGV5IHdpbGwgYmUgbWF0Y2hlZCB1cCBsYXRlclxuICAgICAgICAgICAgcmVtb3ZlTm9kZShjdXJGcm9tTm9kZUNoaWxkLCBmcm9tRWwsIHRydWUgLyogc2tpcCBrZXllZCBub2RlcyAqLyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY3VyRnJvbU5vZGVDaGlsZCA9IGZyb21OZXh0U2libGluZztcbiAgICAgICAgfSAvLyBFTkQ6IHdoaWxlKGN1ckZyb21Ob2RlQ2hpbGQpIHt9XG5cbiAgICAgICAgLy8gSWYgd2UgZ290IHRoaXMgZmFyIHRoZW4gd2UgZGlkIG5vdCBmaW5kIGEgY2FuZGlkYXRlIG1hdGNoIGZvclxuICAgICAgICAvLyBvdXIgXCJ0byBub2RlXCIgYW5kIHdlIGV4aGF1c3RlZCBhbGwgb2YgdGhlIGNoaWxkcmVuIFwiZnJvbVwiXG4gICAgICAgIC8vIG5vZGVzLiBUaGVyZWZvcmUsIHdlIHdpbGwganVzdCBhcHBlbmQgdGhlIGN1cnJlbnQgXCJ0b1wiIG5vZGVcbiAgICAgICAgLy8gdG8gdGhlIGVuZFxuICAgICAgICBpZiAoY3VyVG9Ob2RlS2V5ICYmIChtYXRjaGluZ0Zyb21FbCA9IGZyb21Ob2Rlc0xvb2t1cFtjdXJUb05vZGVLZXldKSAmJiBjb21wYXJlTm9kZU5hbWVzKG1hdGNoaW5nRnJvbUVsLCBjdXJUb05vZGVDaGlsZCkpIHtcbiAgICAgICAgICAvLyBNT1JQSFxuICAgICAgICAgIGlmKCFza2lwRnJvbSl7IGFkZENoaWxkKGZyb21FbCwgbWF0Y2hpbmdGcm9tRWwpOyB9XG4gICAgICAgICAgbW9ycGhFbChtYXRjaGluZ0Zyb21FbCwgY3VyVG9Ob2RlQ2hpbGQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBvbkJlZm9yZU5vZGVBZGRlZFJlc3VsdCA9IG9uQmVmb3JlTm9kZUFkZGVkKGN1clRvTm9kZUNoaWxkKTtcbiAgICAgICAgICBpZiAob25CZWZvcmVOb2RlQWRkZWRSZXN1bHQgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICBpZiAob25CZWZvcmVOb2RlQWRkZWRSZXN1bHQpIHtcbiAgICAgICAgICAgICAgY3VyVG9Ob2RlQ2hpbGQgPSBvbkJlZm9yZU5vZGVBZGRlZFJlc3VsdDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGN1clRvTm9kZUNoaWxkLmFjdHVhbGl6ZSkge1xuICAgICAgICAgICAgICBjdXJUb05vZGVDaGlsZCA9IGN1clRvTm9kZUNoaWxkLmFjdHVhbGl6ZShmcm9tRWwub3duZXJEb2N1bWVudCB8fCBkb2MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYWRkQ2hpbGQoZnJvbUVsLCBjdXJUb05vZGVDaGlsZCk7XG4gICAgICAgICAgICBoYW5kbGVOb2RlQWRkZWQoY3VyVG9Ob2RlQ2hpbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGN1clRvTm9kZUNoaWxkID0gdG9OZXh0U2libGluZztcbiAgICAgICAgY3VyRnJvbU5vZGVDaGlsZCA9IGZyb21OZXh0U2libGluZztcbiAgICAgIH1cblxuICAgICAgY2xlYW51cEZyb21FbChmcm9tRWwsIGN1ckZyb21Ob2RlQ2hpbGQsIGN1ckZyb21Ob2RlS2V5KTtcblxuICAgICAgdmFyIHNwZWNpYWxFbEhhbmRsZXIgPSBzcGVjaWFsRWxIYW5kbGVyc1tmcm9tRWwubm9kZU5hbWVdO1xuICAgICAgaWYgKHNwZWNpYWxFbEhhbmRsZXIpIHtcbiAgICAgICAgc3BlY2lhbEVsSGFuZGxlcihmcm9tRWwsIHRvRWwpO1xuICAgICAgfVxuICAgIH0gLy8gRU5EOiBtb3JwaENoaWxkcmVuKC4uLilcblxuICAgIHZhciBtb3JwaGVkTm9kZSA9IGZyb21Ob2RlO1xuICAgIHZhciBtb3JwaGVkTm9kZVR5cGUgPSBtb3JwaGVkTm9kZS5ub2RlVHlwZTtcbiAgICB2YXIgdG9Ob2RlVHlwZSA9IHRvTm9kZS5ub2RlVHlwZTtcblxuICAgIGlmICghY2hpbGRyZW5Pbmx5KSB7XG4gICAgICAvLyBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUgd2UgYXJlIGdpdmVuIHR3byBET00gbm9kZXMgdGhhdCBhcmUgbm90XG4gICAgICAvLyBjb21wYXRpYmxlIChlLmcuIDxkaXY+IC0tPiA8c3Bhbj4gb3IgPGRpdj4gLS0+IFRFWFQpXG4gICAgICBpZiAobW9ycGhlZE5vZGVUeXBlID09PSBFTEVNRU5UX05PREUpIHtcbiAgICAgICAgaWYgKHRvTm9kZVR5cGUgPT09IEVMRU1FTlRfTk9ERSkge1xuICAgICAgICAgIGlmICghY29tcGFyZU5vZGVOYW1lcyhmcm9tTm9kZSwgdG9Ob2RlKSkge1xuICAgICAgICAgICAgb25Ob2RlRGlzY2FyZGVkKGZyb21Ob2RlKTtcbiAgICAgICAgICAgIG1vcnBoZWROb2RlID0gbW92ZUNoaWxkcmVuKGZyb21Ob2RlLCBjcmVhdGVFbGVtZW50TlModG9Ob2RlLm5vZGVOYW1lLCB0b05vZGUubmFtZXNwYWNlVVJJKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIEdvaW5nIGZyb20gYW4gZWxlbWVudCBub2RlIHRvIGEgdGV4dCBub2RlXG4gICAgICAgICAgbW9ycGhlZE5vZGUgPSB0b05vZGU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAobW9ycGhlZE5vZGVUeXBlID09PSBURVhUX05PREUgfHwgbW9ycGhlZE5vZGVUeXBlID09PSBDT01NRU5UX05PREUpIHsgLy8gVGV4dCBvciBjb21tZW50IG5vZGVcbiAgICAgICAgaWYgKHRvTm9kZVR5cGUgPT09IG1vcnBoZWROb2RlVHlwZSkge1xuICAgICAgICAgIGlmIChtb3JwaGVkTm9kZS5ub2RlVmFsdWUgIT09IHRvTm9kZS5ub2RlVmFsdWUpIHtcbiAgICAgICAgICAgIG1vcnBoZWROb2RlLm5vZGVWYWx1ZSA9IHRvTm9kZS5ub2RlVmFsdWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIG1vcnBoZWROb2RlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFRleHQgbm9kZSB0byBzb21ldGhpbmcgZWxzZVxuICAgICAgICAgIG1vcnBoZWROb2RlID0gdG9Ob2RlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1vcnBoZWROb2RlID09PSB0b05vZGUpIHtcbiAgICAgIC8vIFRoZSBcInRvIG5vZGVcIiB3YXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGUgXCJmcm9tIG5vZGVcIiBzbyB3ZSBoYWQgdG9cbiAgICAgIC8vIHRvc3Mgb3V0IHRoZSBcImZyb20gbm9kZVwiIGFuZCB1c2UgdGhlIFwidG8gbm9kZVwiXG4gICAgICBvbk5vZGVEaXNjYXJkZWQoZnJvbU5vZGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodG9Ob2RlLmlzU2FtZU5vZGUgJiYgdG9Ob2RlLmlzU2FtZU5vZGUobW9ycGhlZE5vZGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbW9ycGhFbChtb3JwaGVkTm9kZSwgdG9Ob2RlLCBjaGlsZHJlbk9ubHkpO1xuXG4gICAgICAvLyBXZSBub3cgbmVlZCB0byBsb29wIG92ZXIgYW55IGtleWVkIG5vZGVzIHRoYXQgbWlnaHQgbmVlZCB0byBiZVxuICAgICAgLy8gcmVtb3ZlZC4gV2Ugb25seSBkbyB0aGUgcmVtb3ZhbCBpZiB3ZSBrbm93IHRoYXQgdGhlIGtleWVkIG5vZGVcbiAgICAgIC8vIG5ldmVyIGZvdW5kIGEgbWF0Y2guIFdoZW4gYSBrZXllZCBub2RlIGlzIG1hdGNoZWQgdXAgd2UgcmVtb3ZlXG4gICAgICAvLyBpdCBvdXQgb2YgZnJvbU5vZGVzTG9va3VwIGFuZCB3ZSB1c2UgZnJvbU5vZGVzTG9va3VwIHRvIGRldGVybWluZVxuICAgICAgLy8gaWYgYSBrZXllZCBub2RlIGhhcyBiZWVuIG1hdGNoZWQgdXAgb3Igbm90XG4gICAgICBpZiAoa2V5ZWRSZW1vdmFsTGlzdCkge1xuICAgICAgICBmb3IgKHZhciBpPTAsIGxlbj1rZXllZFJlbW92YWxMaXN0Lmxlbmd0aDsgaTxsZW47IGkrKykge1xuICAgICAgICAgIHZhciBlbFRvUmVtb3ZlID0gZnJvbU5vZGVzTG9va3VwW2tleWVkUmVtb3ZhbExpc3RbaV1dO1xuICAgICAgICAgIGlmIChlbFRvUmVtb3ZlKSB7XG4gICAgICAgICAgICByZW1vdmVOb2RlKGVsVG9SZW1vdmUsIGVsVG9SZW1vdmUucGFyZW50Tm9kZSwgZmFsc2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghY2hpbGRyZW5Pbmx5ICYmIG1vcnBoZWROb2RlICE9PSBmcm9tTm9kZSAmJiBmcm9tTm9kZS5wYXJlbnROb2RlKSB7XG4gICAgICBpZiAobW9ycGhlZE5vZGUuYWN0dWFsaXplKSB7XG4gICAgICAgIG1vcnBoZWROb2RlID0gbW9ycGhlZE5vZGUuYWN0dWFsaXplKGZyb21Ob2RlLm93bmVyRG9jdW1lbnQgfHwgZG9jKTtcbiAgICAgIH1cbiAgICAgIC8vIElmIHdlIGhhZCB0byBzd2FwIG91dCB0aGUgZnJvbSBub2RlIHdpdGggYSBuZXcgbm9kZSBiZWNhdXNlIHRoZSBvbGRcbiAgICAgIC8vIG5vZGUgd2FzIG5vdCBjb21wYXRpYmxlIHdpdGggdGhlIHRhcmdldCBub2RlIHRoZW4gd2UgbmVlZCB0b1xuICAgICAgLy8gcmVwbGFjZSB0aGUgb2xkIERPTSBub2RlIGluIHRoZSBvcmlnaW5hbCBET00gdHJlZS4gVGhpcyBpcyBvbmx5XG4gICAgICAvLyBwb3NzaWJsZSBpZiB0aGUgb3JpZ2luYWwgRE9NIG5vZGUgd2FzIHBhcnQgb2YgYSBET00gdHJlZSB3aGljaFxuICAgICAgLy8gd2Uga25vdyBpcyB0aGUgY2FzZSBpZiBpdCBoYXMgYSBwYXJlbnQgbm9kZS5cbiAgICAgIGZyb21Ob2RlLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG1vcnBoZWROb2RlLCBmcm9tTm9kZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1vcnBoZWROb2RlO1xuICB9O1xufVxuXG52YXIgbW9ycGhkb20gPSBtb3JwaGRvbUZhY3RvcnkobW9ycGhBdHRycyk7XG5cbmV4cG9ydCBkZWZhdWx0IG1vcnBoZG9tO1xuIiwgImltcG9ydCB7XG4gIFBIWF9DT01QT05FTlQsXG4gIFBIWF9ESVNBQkxFX1dJVEgsXG4gIFBIWF9GRUVEQkFDS19GT1IsXG4gIFBIWF9GRUVEQkFDS19HUk9VUCxcbiAgUEhYX1BSVU5FLFxuICBQSFhfUk9PVF9JRCxcbiAgUEhYX1NFU1NJT04sXG4gIFBIWF9TS0lQLFxuICBQSFhfTUFHSUNfSUQsXG4gIFBIWF9TVEFUSUMsXG4gIFBIWF9UUklHR0VSX0FDVElPTixcbiAgUEhYX1VQREFURSxcbiAgUEhYX1NUUkVBTSxcbiAgUEhYX1NUUkVBTV9SRUYsXG4gIFBIWF9WSUVXUE9SVF9UT1AsXG4gIFBIWF9WSUVXUE9SVF9CT1RUT00sXG59IGZyb20gXCIuL2NvbnN0YW50c1wiXG5cbmltcG9ydCB7XG4gIGRldGVjdER1cGxpY2F0ZUlkcyxcbiAgaXNDaWRcbn0gZnJvbSBcIi4vdXRpbHNcIlxuXG5pbXBvcnQgRE9NIGZyb20gXCIuL2RvbVwiXG5pbXBvcnQgRE9NUG9zdE1vcnBoUmVzdG9yZXIgZnJvbSBcIi4vZG9tX3Bvc3RfbW9ycGhfcmVzdG9yZXJcIlxuaW1wb3J0IG1vcnBoZG9tIGZyb20gXCJtb3JwaGRvbVwiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERPTVBhdGNoIHtcbiAgc3RhdGljIHBhdGNoRWwoZnJvbUVsLCB0b0VsLCBhY3RpdmVFbGVtZW50KXtcbiAgICBtb3JwaGRvbShmcm9tRWwsIHRvRWwsIHtcbiAgICAgIGNoaWxkcmVuT25seTogZmFsc2UsXG4gICAgICBvbkJlZm9yZUVsVXBkYXRlZDogKGZyb21FbCwgdG9FbCkgPT4ge1xuICAgICAgICBpZihhY3RpdmVFbGVtZW50ICYmIGFjdGl2ZUVsZW1lbnQuaXNTYW1lTm9kZShmcm9tRWwpICYmIERPTS5pc0Zvcm1JbnB1dChmcm9tRWwpKXtcbiAgICAgICAgICBET00ubWVyZ2VGb2N1c2VkSW5wdXQoZnJvbUVsLCB0b0VsKVxuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHZpZXcsIGNvbnRhaW5lciwgaWQsIGh0bWwsIHN0cmVhbXMsIHRhcmdldENJRCl7XG4gICAgdGhpcy52aWV3ID0gdmlld1xuICAgIHRoaXMubGl2ZVNvY2tldCA9IHZpZXcubGl2ZVNvY2tldFxuICAgIHRoaXMuY29udGFpbmVyID0gY29udGFpbmVyXG4gICAgdGhpcy5pZCA9IGlkXG4gICAgdGhpcy5yb290SUQgPSB2aWV3LnJvb3QuaWRcbiAgICB0aGlzLmh0bWwgPSBodG1sXG4gICAgdGhpcy5zdHJlYW1zID0gc3RyZWFtc1xuICAgIHRoaXMuc3RyZWFtSW5zZXJ0cyA9IHt9XG4gICAgdGhpcy5zdHJlYW1Db21wb25lbnRSZXN0b3JlID0ge31cbiAgICB0aGlzLnRhcmdldENJRCA9IHRhcmdldENJRFxuICAgIHRoaXMuY2lkUGF0Y2ggPSBpc0NpZCh0aGlzLnRhcmdldENJRClcbiAgICB0aGlzLnBlbmRpbmdSZW1vdmVzID0gW11cbiAgICB0aGlzLnBoeFJlbW92ZSA9IHRoaXMubGl2ZVNvY2tldC5iaW5kaW5nKFwicmVtb3ZlXCIpXG4gICAgdGhpcy5jYWxsYmFja3MgPSB7XG4gICAgICBiZWZvcmVhZGRlZDogW10sIGJlZm9yZXVwZGF0ZWQ6IFtdLCBiZWZvcmVwaHhDaGlsZEFkZGVkOiBbXSxcbiAgICAgIGFmdGVyYWRkZWQ6IFtdLCBhZnRlcnVwZGF0ZWQ6IFtdLCBhZnRlcmRpc2NhcmRlZDogW10sIGFmdGVycGh4Q2hpbGRBZGRlZDogW10sXG4gICAgICBhZnRlcnRyYW5zaXRpb25zRGlzY2FyZGVkOiBbXVxuICAgIH1cbiAgfVxuXG4gIGJlZm9yZShraW5kLCBjYWxsYmFjayl7IHRoaXMuY2FsbGJhY2tzW2BiZWZvcmUke2tpbmR9YF0ucHVzaChjYWxsYmFjaykgfVxuICBhZnRlcihraW5kLCBjYWxsYmFjayl7IHRoaXMuY2FsbGJhY2tzW2BhZnRlciR7a2luZH1gXS5wdXNoKGNhbGxiYWNrKSB9XG5cbiAgdHJhY2tCZWZvcmUoa2luZCwgLi4uYXJncyl7XG4gICAgdGhpcy5jYWxsYmFja3NbYGJlZm9yZSR7a2luZH1gXS5mb3JFYWNoKGNhbGxiYWNrID0+IGNhbGxiYWNrKC4uLmFyZ3MpKVxuICB9XG5cbiAgdHJhY2tBZnRlcihraW5kLCAuLi5hcmdzKXtcbiAgICB0aGlzLmNhbGxiYWNrc1tgYWZ0ZXIke2tpbmR9YF0uZm9yRWFjaChjYWxsYmFjayA9PiBjYWxsYmFjayguLi5hcmdzKSlcbiAgfVxuXG4gIG1hcmtQcnVuYWJsZUNvbnRlbnRGb3JSZW1vdmFsKCl7XG4gICAgbGV0IHBoeFVwZGF0ZSA9IHRoaXMubGl2ZVNvY2tldC5iaW5kaW5nKFBIWF9VUERBVEUpXG4gICAgRE9NLmFsbCh0aGlzLmNvbnRhaW5lciwgYFske3BoeFVwZGF0ZX09YXBwZW5kXSA+ICosIFske3BoeFVwZGF0ZX09cHJlcGVuZF0gPiAqYCwgZWwgPT4ge1xuICAgICAgZWwuc2V0QXR0cmlidXRlKFBIWF9QUlVORSwgXCJcIilcbiAgICB9KVxuICB9XG5cbiAgcGVyZm9ybShpc0pvaW5QYXRjaCl7XG4gICAgbGV0IHt2aWV3LCBsaXZlU29ja2V0LCBjb250YWluZXIsIGh0bWx9ID0gdGhpc1xuICAgIGxldCB0YXJnZXRDb250YWluZXIgPSB0aGlzLmlzQ0lEUGF0Y2goKSA/IHRoaXMudGFyZ2V0Q0lEQ29udGFpbmVyKGh0bWwpIDogY29udGFpbmVyXG4gICAgaWYodGhpcy5pc0NJRFBhdGNoKCkgJiYgIXRhcmdldENvbnRhaW5lcil7IHJldHVybiB9XG5cbiAgICBsZXQgZm9jdXNlZCA9IGxpdmVTb2NrZXQuZ2V0QWN0aXZlRWxlbWVudCgpXG4gICAgbGV0IHtzZWxlY3Rpb25TdGFydCwgc2VsZWN0aW9uRW5kfSA9IGZvY3VzZWQgJiYgRE9NLmhhc1NlbGVjdGlvblJhbmdlKGZvY3VzZWQpID8gZm9jdXNlZCA6IHt9XG4gICAgbGV0IHBoeFVwZGF0ZSA9IGxpdmVTb2NrZXQuYmluZGluZyhQSFhfVVBEQVRFKVxuICAgIGxldCBwaHhGZWVkYmFja0ZvciA9IGxpdmVTb2NrZXQuYmluZGluZyhQSFhfRkVFREJBQ0tfRk9SKVxuICAgIGxldCBwaHhGZWVkYmFja0dyb3VwID0gbGl2ZVNvY2tldC5iaW5kaW5nKFBIWF9GRUVEQkFDS19HUk9VUClcbiAgICBsZXQgZGlzYWJsZVdpdGggPSBsaXZlU29ja2V0LmJpbmRpbmcoUEhYX0RJU0FCTEVfV0lUSClcbiAgICBsZXQgcGh4Vmlld3BvcnRUb3AgPSBsaXZlU29ja2V0LmJpbmRpbmcoUEhYX1ZJRVdQT1JUX1RPUClcbiAgICBsZXQgcGh4Vmlld3BvcnRCb3R0b20gPSBsaXZlU29ja2V0LmJpbmRpbmcoUEhYX1ZJRVdQT1JUX0JPVFRPTSlcbiAgICBsZXQgcGh4VHJpZ2dlckV4dGVybmFsID0gbGl2ZVNvY2tldC5iaW5kaW5nKFBIWF9UUklHR0VSX0FDVElPTilcbiAgICBsZXQgYWRkZWQgPSBbXVxuICAgIGxldCBmZWVkYmFja0NvbnRhaW5lcnMgPSBbXVxuICAgIGxldCB1cGRhdGVzID0gW11cbiAgICBsZXQgYXBwZW5kUHJlcGVuZFVwZGF0ZXMgPSBbXVxuXG4gICAgbGV0IGV4dGVybmFsRm9ybVRyaWdnZXJlZCA9IG51bGxcblxuICAgIGZ1bmN0aW9uIG1vcnBoKHRhcmdldENvbnRhaW5lciwgc291cmNlLCB3aXRoQ2hpbGRyZW49ZmFsc2Upe1xuICAgICAgbW9ycGhkb20odGFyZ2V0Q29udGFpbmVyLCBzb3VyY2UsIHtcbiAgICAgICAgLy8gbm9ybWFsbHksIHdlIGFyZSBydW5uaW5nIHdpdGggY2hpbGRyZW5Pbmx5LCBhcyB0aGUgcGF0Y2ggSFRNTCBmb3IgYSBMVlxuICAgICAgICAvLyBkb2VzIG5vdCBpbmNsdWRlIHRoZSBMViBhdHRycyAoZGF0YS1waHgtc2Vzc2lvbiwgZXRjLilcbiAgICAgICAgLy8gd2hlbiB3ZSBhcmUgcGF0Y2hpbmcgYSBsaXZlIGNvbXBvbmVudCwgd2UgZG8gd2FudCB0byBwYXRjaCB0aGUgcm9vdCBlbGVtZW50IGFzIHdlbGw7XG4gICAgICAgIC8vIGFub3RoZXIgY2FzZSBpcyB0aGUgcmVjdXJzaXZlIHBhdGNoIG9mIGEgc3RyZWFtIGl0ZW0gdGhhdCB3YXMga2VwdCBvbiByZXNldCAoLT4gb25CZWZvcmVOb2RlQWRkZWQpXG4gICAgICAgIGNoaWxkcmVuT25seTogdGFyZ2V0Q29udGFpbmVyLmdldEF0dHJpYnV0ZShQSFhfQ09NUE9ORU5UKSA9PT0gbnVsbCAmJiAhd2l0aENoaWxkcmVuLFxuICAgICAgICBnZXROb2RlS2V5OiAobm9kZSkgPT4ge1xuICAgICAgICAgIGlmKERPTS5pc1BoeERlc3Ryb3llZChub2RlKSl7IHJldHVybiBudWxsIH1cbiAgICAgICAgICAvLyBJZiB3ZSBoYXZlIGEgam9pbiBwYXRjaCwgdGhlbiBieSBkZWZpbml0aW9uIHRoZXJlIHdhcyBubyBQSFhfTUFHSUNfSUQuXG4gICAgICAgICAgLy8gVGhpcyBpcyBpbXBvcnRhbnQgdG8gcmVkdWNlIHRoZSBhbW91bnQgb2YgZWxlbWVudHMgbW9ycGhkb20gZGlzY2FyZHMuXG4gICAgICAgICAgaWYoaXNKb2luUGF0Y2gpeyByZXR1cm4gbm9kZS5pZCB9XG4gICAgICAgICAgcmV0dXJuIG5vZGUuaWQgfHwgKG5vZGUuZ2V0QXR0cmlidXRlICYmIG5vZGUuZ2V0QXR0cmlidXRlKFBIWF9NQUdJQ19JRCkpXG4gICAgICAgIH0sXG4gICAgICAgIC8vIHNraXAgaW5kZXhpbmcgZnJvbSBjaGlsZHJlbiB3aGVuIGNvbnRhaW5lciBpcyBzdHJlYW1cbiAgICAgICAgc2tpcEZyb21DaGlsZHJlbjogKGZyb20pID0+IHsgcmV0dXJuIGZyb20uZ2V0QXR0cmlidXRlKHBoeFVwZGF0ZSkgPT09IFBIWF9TVFJFQU0gfSxcbiAgICAgICAgLy8gdGVsbCBtb3JwaGRvbSBob3cgdG8gYWRkIGEgY2hpbGRcbiAgICAgICAgYWRkQ2hpbGQ6IChwYXJlbnQsIGNoaWxkKSA9PiB7XG4gICAgICAgICAgbGV0IHtyZWYsIHN0cmVhbUF0fSA9IHRoaXMuZ2V0U3RyZWFtSW5zZXJ0KGNoaWxkKVxuICAgICAgICAgIGlmKHJlZiA9PT0gdW5kZWZpbmVkKXsgcmV0dXJuIHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZCkgfVxuXG4gICAgICAgICAgdGhpcy5zZXRTdHJlYW1SZWYoY2hpbGQsIHJlZilcblxuICAgICAgICAgIC8vIHN0cmVhbWluZ1xuICAgICAgICAgIGlmKHN0cmVhbUF0ID09PSAwKXtcbiAgICAgICAgICAgIHBhcmVudC5pbnNlcnRBZGphY2VudEVsZW1lbnQoXCJhZnRlcmJlZ2luXCIsIGNoaWxkKVxuICAgICAgICAgIH0gZWxzZSBpZihzdHJlYW1BdCA9PT0gLTEpe1xuICAgICAgICAgICAgcGFyZW50LmFwcGVuZENoaWxkKGNoaWxkKVxuICAgICAgICAgIH0gZWxzZSBpZihzdHJlYW1BdCA+IDApe1xuICAgICAgICAgICAgbGV0IHNpYmxpbmcgPSBBcnJheS5mcm9tKHBhcmVudC5jaGlsZHJlbilbc3RyZWFtQXRdXG4gICAgICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKGNoaWxkLCBzaWJsaW5nKVxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgb25CZWZvcmVOb2RlQWRkZWQ6IChlbCkgPT4ge1xuICAgICAgICAgIERPTS5tYXliZUFkZFByaXZhdGVIb29rcyhlbCwgcGh4Vmlld3BvcnRUb3AsIHBoeFZpZXdwb3J0Qm90dG9tKVxuICAgICAgICAgIHRoaXMudHJhY2tCZWZvcmUoXCJhZGRlZFwiLCBlbClcblxuICAgICAgICAgIGxldCBtb3JwaGVkRWwgPSBlbFxuICAgICAgICAgIC8vIHRoaXMgaXMgYSBzdHJlYW0gaXRlbSB0aGF0IHdhcyBrZXB0IG9uIHJlc2V0LCByZWN1cnNpdmVseSBtb3JwaCBpdFxuICAgICAgICAgIGlmKCFpc0pvaW5QYXRjaCAmJiB0aGlzLnN0cmVhbUNvbXBvbmVudFJlc3RvcmVbZWwuaWRdKXtcbiAgICAgICAgICAgIG1vcnBoZWRFbCA9IHRoaXMuc3RyZWFtQ29tcG9uZW50UmVzdG9yZVtlbC5pZF1cbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbUNvbXBvbmVudFJlc3RvcmVbZWwuaWRdXG4gICAgICAgICAgICBtb3JwaC5jYWxsKHRoaXMsIG1vcnBoZWRFbCwgZWwsIHRydWUpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIG1vcnBoZWRFbFxuICAgICAgICB9LFxuICAgICAgICBvbk5vZGVBZGRlZDogKGVsKSA9PiB7XG4gICAgICAgICAgaWYoZWwuZ2V0QXR0cmlidXRlKXsgdGhpcy5tYXliZVJlT3JkZXJTdHJlYW0oZWwsIHRydWUpIH1cbiAgICAgICAgICBpZihET00uaXNGZWVkYmFja0NvbnRhaW5lcihlbCwgcGh4RmVlZGJhY2tGb3IpKSBmZWVkYmFja0NvbnRhaW5lcnMucHVzaChlbClcblxuICAgICAgICAgIC8vIGhhY2sgdG8gZml4IFNhZmFyaSBoYW5kbGluZyBvZiBpbWcgc3Jjc2V0IGFuZCB2aWRlbyB0YWdzXG4gICAgICAgICAgaWYoZWwgaW5zdGFuY2VvZiBIVE1MSW1hZ2VFbGVtZW50ICYmIGVsLnNyY3NldCl7XG4gICAgICAgICAgICBlbC5zcmNzZXQgPSBlbC5zcmNzZXRcbiAgICAgICAgICB9IGVsc2UgaWYoZWwgaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50ICYmIGVsLmF1dG9wbGF5KXtcbiAgICAgICAgICAgIGVsLnBsYXkoKVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZihET00uaXNOb3dUcmlnZ2VyRm9ybUV4dGVybmFsKGVsLCBwaHhUcmlnZ2VyRXh0ZXJuYWwpKXtcbiAgICAgICAgICAgIGV4dGVybmFsRm9ybVRyaWdnZXJlZCA9IGVsXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gbmVzdGVkIHZpZXcgaGFuZGxpbmdcbiAgICAgICAgICBpZigoRE9NLmlzUGh4Q2hpbGQoZWwpICYmIHZpZXcub3duc0VsZW1lbnQoZWwpKSB8fCBET00uaXNQaHhTdGlja3koZWwpICYmIHZpZXcub3duc0VsZW1lbnQoZWwucGFyZW50Tm9kZSkpe1xuICAgICAgICAgICAgdGhpcy50cmFja0FmdGVyKFwicGh4Q2hpbGRBZGRlZFwiLCBlbClcbiAgICAgICAgICB9XG4gICAgICAgICAgYWRkZWQucHVzaChlbClcbiAgICAgICAgfSxcbiAgICAgICAgb25Ob2RlRGlzY2FyZGVkOiAoZWwpID0+IHRoaXMub25Ob2RlRGlzY2FyZGVkKGVsKSxcbiAgICAgICAgb25CZWZvcmVOb2RlRGlzY2FyZGVkOiAoZWwpID0+IHtcbiAgICAgICAgICBpZihlbC5nZXRBdHRyaWJ1dGUgJiYgZWwuZ2V0QXR0cmlidXRlKFBIWF9QUlVORSkgIT09IG51bGwpeyByZXR1cm4gdHJ1ZSB9XG4gICAgICAgICAgaWYoZWwucGFyZW50RWxlbWVudCAhPT0gbnVsbCAmJiBlbC5pZCAmJlxuICAgICAgICAgICAgRE9NLmlzUGh4VXBkYXRlKGVsLnBhcmVudEVsZW1lbnQsIHBoeFVwZGF0ZSwgW1BIWF9TVFJFQU0sIFwiYXBwZW5kXCIsIFwicHJlcGVuZFwiXSkpe1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmKHRoaXMubWF5YmVQZW5kaW5nUmVtb3ZlKGVsKSl7IHJldHVybiBmYWxzZSB9XG4gICAgICAgICAgaWYodGhpcy5za2lwQ0lEU2libGluZyhlbCkpeyByZXR1cm4gZmFsc2UgfVxuXG4gICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgb25FbFVwZGF0ZWQ6IChlbCkgPT4ge1xuICAgICAgICAgIGlmKERPTS5pc05vd1RyaWdnZXJGb3JtRXh0ZXJuYWwoZWwsIHBoeFRyaWdnZXJFeHRlcm5hbCkpe1xuICAgICAgICAgICAgZXh0ZXJuYWxGb3JtVHJpZ2dlcmVkID0gZWxcbiAgICAgICAgICB9XG4gICAgICAgICAgdXBkYXRlcy5wdXNoKGVsKVxuICAgICAgICAgIHRoaXMubWF5YmVSZU9yZGVyU3RyZWFtKGVsLCBmYWxzZSlcbiAgICAgICAgfSxcbiAgICAgICAgb25CZWZvcmVFbFVwZGF0ZWQ6IChmcm9tRWwsIHRvRWwpID0+IHtcbiAgICAgICAgICBET00ubWF5YmVBZGRQcml2YXRlSG9va3ModG9FbCwgcGh4Vmlld3BvcnRUb3AsIHBoeFZpZXdwb3J0Qm90dG9tKVxuICAgICAgICAgIC8vIG1hcmsgYm90aCBmcm9tIGFuZCB0byBlbHMgYXMgZmVlZGJhY2sgY29udGFpbmVycywgYXMgd2UgZG9uJ3Qga25vdyB5ZXQgd2hpY2ggb25lIHdpbGwgYmUgdXNlZFxuICAgICAgICAgIC8vIGFuZCB3ZSBhbHNvIG5lZWQgdG8gcmVtb3ZlIHRoZSBwaHgtbm8tZmVlZGJhY2sgY2xhc3Mgd2hlbiB0aGUgcGh4LWZlZWRiYWNrLWZvciBhdHRyaWJ1dGUgaXMgcmVtb3ZlZFxuICAgICAgICAgIGlmKERPTS5pc0ZlZWRiYWNrQ29udGFpbmVyKGZyb21FbCwgcGh4RmVlZGJhY2tGb3IpIHx8IERPTS5pc0ZlZWRiYWNrQ29udGFpbmVyKHRvRWwsIHBoeEZlZWRiYWNrRm9yKSl7XG4gICAgICAgICAgICBmZWVkYmFja0NvbnRhaW5lcnMucHVzaChmcm9tRWwpXG4gICAgICAgICAgICBmZWVkYmFja0NvbnRhaW5lcnMucHVzaCh0b0VsKVxuICAgICAgICAgIH1cbiAgICAgICAgICBET00uY2xlYW5DaGlsZE5vZGVzKHRvRWwsIHBoeFVwZGF0ZSlcbiAgICAgICAgICBpZih0aGlzLnNraXBDSURTaWJsaW5nKHRvRWwpKXtcbiAgICAgICAgICAgIC8vIGlmIHRoaXMgaXMgYSBsaXZlIGNvbXBvbmVudCB1c2VkIGluIGEgc3RyZWFtLCB3ZSBtYXkgbmVlZCB0byByZW9yZGVyIGl0XG4gICAgICAgICAgICB0aGlzLm1heWJlUmVPcmRlclN0cmVhbShmcm9tRWwpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYoRE9NLmlzUGh4U3RpY2t5KGZyb21FbCkpeyByZXR1cm4gZmFsc2UgfVxuICAgICAgICAgIGlmKERPTS5pc0lnbm9yZWQoZnJvbUVsLCBwaHhVcGRhdGUpIHx8IChmcm9tRWwuZm9ybSAmJiBmcm9tRWwuZm9ybS5pc1NhbWVOb2RlKGV4dGVybmFsRm9ybVRyaWdnZXJlZCkpKXtcbiAgICAgICAgICAgIHRoaXMudHJhY2tCZWZvcmUoXCJ1cGRhdGVkXCIsIGZyb21FbCwgdG9FbClcbiAgICAgICAgICAgIERPTS5tZXJnZUF0dHJzKGZyb21FbCwgdG9FbCwge2lzSWdub3JlZDogRE9NLmlzSWdub3JlZChmcm9tRWwsIHBoeFVwZGF0ZSl9KVxuICAgICAgICAgICAgdXBkYXRlcy5wdXNoKGZyb21FbClcbiAgICAgICAgICAgIERPTS5hcHBseVN0aWNreU9wZXJhdGlvbnMoZnJvbUVsKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmKGZyb21FbC50eXBlID09PSBcIm51bWJlclwiICYmIChmcm9tRWwudmFsaWRpdHkgJiYgZnJvbUVsLnZhbGlkaXR5LmJhZElucHV0KSl7IHJldHVybiBmYWxzZSB9XG4gICAgICAgICAgaWYoIURPTS5zeW5jUGVuZGluZ1JlZihmcm9tRWwsIHRvRWwsIGRpc2FibGVXaXRoKSl7XG4gICAgICAgICAgICBpZihET00uaXNVcGxvYWRJbnB1dChmcm9tRWwpKXtcbiAgICAgICAgICAgICAgdGhpcy50cmFja0JlZm9yZShcInVwZGF0ZWRcIiwgZnJvbUVsLCB0b0VsKVxuICAgICAgICAgICAgICB1cGRhdGVzLnB1c2goZnJvbUVsKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgRE9NLmFwcGx5U3RpY2t5T3BlcmF0aW9ucyhmcm9tRWwpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBuZXN0ZWQgdmlldyBoYW5kbGluZ1xuICAgICAgICAgIGlmKERPTS5pc1BoeENoaWxkKHRvRWwpKXtcbiAgICAgICAgICAgIGxldCBwcmV2U2Vzc2lvbiA9IGZyb21FbC5nZXRBdHRyaWJ1dGUoUEhYX1NFU1NJT04pXG4gICAgICAgICAgICBET00ubWVyZ2VBdHRycyhmcm9tRWwsIHRvRWwsIHtleGNsdWRlOiBbUEhYX1NUQVRJQ119KVxuICAgICAgICAgICAgaWYocHJldlNlc3Npb24gIT09IFwiXCIpeyBmcm9tRWwuc2V0QXR0cmlidXRlKFBIWF9TRVNTSU9OLCBwcmV2U2Vzc2lvbikgfVxuICAgICAgICAgICAgZnJvbUVsLnNldEF0dHJpYnV0ZShQSFhfUk9PVF9JRCwgdGhpcy5yb290SUQpXG4gICAgICAgICAgICBET00uYXBwbHlTdGlja3lPcGVyYXRpb25zKGZyb21FbClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGlucHV0IGhhbmRsaW5nXG4gICAgICAgICAgRE9NLmNvcHlQcml2YXRlcyh0b0VsLCBmcm9tRWwpXG5cbiAgICAgICAgICBsZXQgaXNGb2N1c2VkRm9ybUVsID0gZm9jdXNlZCAmJiBmcm9tRWwuaXNTYW1lTm9kZShmb2N1c2VkKSAmJiBET00uaXNGb3JtSW5wdXQoZnJvbUVsKVxuICAgICAgICAgIC8vIHNraXAgcGF0Y2hpbmcgZm9jdXNlZCBpbnB1dHMgdW5sZXNzIGZvY3VzIGlzIGEgc2VsZWN0IHRoYXQgaGFzIGNoYW5nZWQgb3B0aW9uc1xuICAgICAgICAgIGxldCBmb2N1c2VkU2VsZWN0Q2hhbmdlZCA9IGlzRm9jdXNlZEZvcm1FbCAmJiB0aGlzLmlzQ2hhbmdlZFNlbGVjdChmcm9tRWwsIHRvRWwpXG4gICAgICAgICAgaWYoaXNGb2N1c2VkRm9ybUVsICYmIGZyb21FbC50eXBlICE9PSBcImhpZGRlblwiICYmICFmb2N1c2VkU2VsZWN0Q2hhbmdlZCl7XG4gICAgICAgICAgICB0aGlzLnRyYWNrQmVmb3JlKFwidXBkYXRlZFwiLCBmcm9tRWwsIHRvRWwpXG4gICAgICAgICAgICBET00ubWVyZ2VGb2N1c2VkSW5wdXQoZnJvbUVsLCB0b0VsKVxuICAgICAgICAgICAgRE9NLnN5bmNBdHRyc1RvUHJvcHMoZnJvbUVsKVxuICAgICAgICAgICAgdXBkYXRlcy5wdXNoKGZyb21FbClcbiAgICAgICAgICAgIERPTS5hcHBseVN0aWNreU9wZXJhdGlvbnMoZnJvbUVsKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGJsdXIgZm9jdXNlZCBzZWxlY3QgaWYgaXQgY2hhbmdlZCBzbyBuYXRpdmUgVUkgaXMgdXBkYXRlZCAoaWUgc2FmYXJpIHdvbid0IHVwZGF0ZSB2aXNpYmxlIG9wdGlvbnMpXG4gICAgICAgICAgICBpZihmb2N1c2VkU2VsZWN0Q2hhbmdlZCl7IGZyb21FbC5ibHVyKCkgfVxuICAgICAgICAgICAgaWYoRE9NLmlzUGh4VXBkYXRlKHRvRWwsIHBoeFVwZGF0ZSwgW1wiYXBwZW5kXCIsIFwicHJlcGVuZFwiXSkpe1xuICAgICAgICAgICAgICBhcHBlbmRQcmVwZW5kVXBkYXRlcy5wdXNoKG5ldyBET01Qb3N0TW9ycGhSZXN0b3Jlcihmcm9tRWwsIHRvRWwsIHRvRWwuZ2V0QXR0cmlidXRlKHBoeFVwZGF0ZSkpKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBET00uc3luY0F0dHJzVG9Qcm9wcyh0b0VsKVxuICAgICAgICAgICAgRE9NLmFwcGx5U3RpY2t5T3BlcmF0aW9ucyh0b0VsKVxuICAgICAgICAgICAgdGhpcy50cmFja0JlZm9yZShcInVwZGF0ZWRcIiwgZnJvbUVsLCB0b0VsKVxuICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuXG4gICAgdGhpcy50cmFja0JlZm9yZShcImFkZGVkXCIsIGNvbnRhaW5lcilcbiAgICB0aGlzLnRyYWNrQmVmb3JlKFwidXBkYXRlZFwiLCBjb250YWluZXIsIGNvbnRhaW5lcilcblxuICAgIGxpdmVTb2NrZXQudGltZShcIm1vcnBoZG9tXCIsICgpID0+IHtcbiAgICAgIHRoaXMuc3RyZWFtcy5mb3JFYWNoKChbcmVmLCBpbnNlcnRzLCBkZWxldGVJZHMsIHJlc2V0XSkgPT4ge1xuICAgICAgICBpbnNlcnRzLmZvckVhY2goKFtrZXksIHN0cmVhbUF0LCBsaW1pdF0pID0+IHtcbiAgICAgICAgICB0aGlzLnN0cmVhbUluc2VydHNba2V5XSA9IHtyZWYsIHN0cmVhbUF0LCBsaW1pdCwgcmVzZXR9XG4gICAgICAgIH0pXG4gICAgICAgIGlmKHJlc2V0ICE9PSB1bmRlZmluZWQpe1xuICAgICAgICAgIERPTS5hbGwoY29udGFpbmVyLCBgWyR7UEhYX1NUUkVBTV9SRUZ9PVwiJHtyZWZ9XCJdYCwgY2hpbGQgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQpXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBkZWxldGVJZHMuZm9yRWFjaChpZCA9PiB7XG4gICAgICAgICAgbGV0IGNoaWxkID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoYFtpZD1cIiR7aWR9XCJdYClcbiAgICAgICAgICBpZihjaGlsZCl7IHRoaXMucmVtb3ZlU3RyZWFtQ2hpbGRFbGVtZW50KGNoaWxkKSB9XG4gICAgICAgIH0pXG4gICAgICB9KVxuXG4gICAgICAvLyBjbGVhciBzdHJlYW0gaXRlbXMgZnJvbSB0aGUgZGVhZCByZW5kZXIgaWYgdGhleSBhcmUgbm90IGluc2VydGVkIGFnYWluXG4gICAgICBpZihpc0pvaW5QYXRjaCl7XG4gICAgICAgIERPTS5hbGwodGhpcy5jb250YWluZXIsIGBbJHtwaHhVcGRhdGV9PSR7UEhYX1NUUkVBTX1dYCwgZWwgPT4ge1xuICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0byBvbmx5IHJlbW92ZSBlbGVtZW50cyBvd25lZCBieSB0aGUgY3VycmVudCB2aWV3XG4gICAgICAgICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9waG9lbml4ZnJhbWV3b3JrL3Bob2VuaXhfbGl2ZV92aWV3L2lzc3Vlcy8zMDQ3XG4gICAgICAgICAgdGhpcy5saXZlU29ja2V0Lm93bmVyKGVsLCAodmlldykgPT4ge1xuICAgICAgICAgICAgaWYodmlldyA9PT0gdGhpcy52aWV3KXtcbiAgICAgICAgICAgICAgQXJyYXkuZnJvbShlbC5jaGlsZHJlbikuZm9yRWFjaChjaGlsZCA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQpXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgbW9ycGguY2FsbCh0aGlzLCB0YXJnZXRDb250YWluZXIsIGh0bWwpXG4gICAgfSlcblxuICAgIGlmKGxpdmVTb2NrZXQuaXNEZWJ1Z0VuYWJsZWQoKSl7XG4gICAgICBkZXRlY3REdXBsaWNhdGVJZHMoKVxuICAgICAgLy8gd2FybiBpZiB0aGVyZSBhcmUgYW55IGlucHV0cyBuYW1lZCBcImlkXCJcbiAgICAgIEFycmF5LmZyb20oZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcImlucHV0W25hbWU9aWRdXCIpKS5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICBpZihub2RlLmZvcm0pe1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJEZXRlY3RlZCBhbiBpbnB1dCB3aXRoIG5hbWU9XFxcImlkXFxcIiBpbnNpZGUgYSBmb3JtISBUaGlzIHdpbGwgY2F1c2UgcHJvYmxlbXMgd2hlbiBwYXRjaGluZyB0aGUgRE9NLlxcblwiLCBub2RlKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmKGFwcGVuZFByZXBlbmRVcGRhdGVzLmxlbmd0aCA+IDApe1xuICAgICAgbGl2ZVNvY2tldC50aW1lKFwicG9zdC1tb3JwaCBhcHBlbmQvcHJlcGVuZCByZXN0b3JhdGlvblwiLCAoKSA9PiB7XG4gICAgICAgIGFwcGVuZFByZXBlbmRVcGRhdGVzLmZvckVhY2godXBkYXRlID0+IHVwZGF0ZS5wZXJmb3JtKCkpXG4gICAgICB9KVxuICAgIH1cblxuICAgIERPTS5tYXliZUhpZGVGZWVkYmFjayh0YXJnZXRDb250YWluZXIsIGZlZWRiYWNrQ29udGFpbmVycywgcGh4RmVlZGJhY2tGb3IsIHBoeEZlZWRiYWNrR3JvdXApXG5cbiAgICBsaXZlU29ja2V0LnNpbGVuY2VFdmVudHMoKCkgPT4gRE9NLnJlc3RvcmVGb2N1cyhmb2N1c2VkLCBzZWxlY3Rpb25TdGFydCwgc2VsZWN0aW9uRW5kKSlcbiAgICBET00uZGlzcGF0Y2hFdmVudChkb2N1bWVudCwgXCJwaHg6dXBkYXRlXCIpXG4gICAgYWRkZWQuZm9yRWFjaChlbCA9PiB0aGlzLnRyYWNrQWZ0ZXIoXCJhZGRlZFwiLCBlbCkpXG4gICAgdXBkYXRlcy5mb3JFYWNoKGVsID0+IHRoaXMudHJhY2tBZnRlcihcInVwZGF0ZWRcIiwgZWwpKVxuXG4gICAgdGhpcy50cmFuc2l0aW9uUGVuZGluZ1JlbW92ZXMoKVxuXG4gICAgaWYoZXh0ZXJuYWxGb3JtVHJpZ2dlcmVkKXtcbiAgICAgIGxpdmVTb2NrZXQudW5sb2FkKClcbiAgICAgIC8vIHVzZSBwcm90b3R5cGUncyBzdWJtaXQgaW4gY2FzZSB0aGVyZSdzIGEgZm9ybSBjb250cm9sIHdpdGggbmFtZSBvciBpZCBvZiBcInN1Ym1pdFwiXG4gICAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSFRNTEZvcm1FbGVtZW50L3N1Ym1pdFxuICAgICAgT2JqZWN0LmdldFByb3RvdHlwZU9mKGV4dGVybmFsRm9ybVRyaWdnZXJlZCkuc3VibWl0LmNhbGwoZXh0ZXJuYWxGb3JtVHJpZ2dlcmVkKVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgb25Ob2RlRGlzY2FyZGVkKGVsKXtcbiAgICAvLyBuZXN0ZWQgdmlldyBoYW5kbGluZ1xuICAgIGlmKERPTS5pc1BoeENoaWxkKGVsKSB8fCBET00uaXNQaHhTdGlja3koZWwpKXsgdGhpcy5saXZlU29ja2V0LmRlc3Ryb3lWaWV3QnlFbChlbCkgfVxuICAgIHRoaXMudHJhY2tBZnRlcihcImRpc2NhcmRlZFwiLCBlbClcbiAgfVxuXG4gIG1heWJlUGVuZGluZ1JlbW92ZShub2RlKXtcbiAgICBpZihub2RlLmdldEF0dHJpYnV0ZSAmJiBub2RlLmdldEF0dHJpYnV0ZSh0aGlzLnBoeFJlbW92ZSkgIT09IG51bGwpe1xuICAgICAgdGhpcy5wZW5kaW5nUmVtb3Zlcy5wdXNoKG5vZGUpXG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cblxuICByZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQpe1xuICAgIC8vIHdlIG5lZWQgdG8gc3RvcmUgdGhlIG5vZGUgaWYgaXQgaXMgYWN0dWFsbHkgcmUtYWRkZWQgaW4gdGhlIHNhbWUgcGF0Y2hcbiAgICAvLyB3ZSBkbyBOT1Qgd2FudCB0byBleGVjdXRlIHBoeC1yZW1vdmUsIHdlIGRvIE5PVCB3YW50IHRvIGNhbGwgb25Ob2RlRGlzY2FyZGVkXG4gICAgaWYodGhpcy5zdHJlYW1JbnNlcnRzW2NoaWxkLmlkXSl7XG4gICAgICB0aGlzLnN0cmVhbUNvbXBvbmVudFJlc3RvcmVbY2hpbGQuaWRdID0gY2hpbGRcbiAgICAgIGNoaWxkLnJlbW92ZSgpXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG9ubHkgcmVtb3ZlIHRoZSBlbGVtZW50IG5vdyBpZiBpdCBoYXMgbm8gcGh4LXJlbW92ZSBiaW5kaW5nXG4gICAgICBpZighdGhpcy5tYXliZVBlbmRpbmdSZW1vdmUoY2hpbGQpKXtcbiAgICAgICAgY2hpbGQucmVtb3ZlKClcbiAgICAgICAgdGhpcy5vbk5vZGVEaXNjYXJkZWQoY2hpbGQpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0U3RyZWFtSW5zZXJ0KGVsKXtcbiAgICBsZXQgaW5zZXJ0ID0gZWwuaWQgPyB0aGlzLnN0cmVhbUluc2VydHNbZWwuaWRdIDoge31cbiAgICByZXR1cm4gaW5zZXJ0IHx8IHt9XG4gIH1cblxuICBzZXRTdHJlYW1SZWYoZWwsIHJlZil7XG4gICAgRE9NLnB1dFN0aWNreShlbCwgUEhYX1NUUkVBTV9SRUYsIGVsID0+IGVsLnNldEF0dHJpYnV0ZShQSFhfU1RSRUFNX1JFRiwgcmVmKSlcbiAgfVxuXG4gIG1heWJlUmVPcmRlclN0cmVhbShlbCwgaXNOZXcpe1xuICAgIGxldCB7cmVmLCBzdHJlYW1BdCwgcmVzZXR9ID0gdGhpcy5nZXRTdHJlYW1JbnNlcnQoZWwpXG4gICAgaWYoc3RyZWFtQXQgPT09IHVuZGVmaW5lZCl7IHJldHVybiB9XG5cbiAgICAvLyB3ZSBuZWVkIHRvIHNldCB0aGUgUEhYX1NUUkVBTV9SRUYgaGVyZSBhcyB3ZWxsIGFzIGFkZENoaWxkIGlzIGludm9rZWQgb25seSBmb3IgcGFyZW50c1xuICAgIHRoaXMuc2V0U3RyZWFtUmVmKGVsLCByZWYpXG5cbiAgICBpZighcmVzZXQgJiYgIWlzTmV3KXtcbiAgICAgIC8vIHdlIG9ubHkgcmVvcmRlciBpZiB0aGUgZWxlbWVudCBpcyBuZXcgb3IgaXQncyBhIHN0cmVhbSByZXNldFxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gY2hlY2sgaWYgdGhlIGVsZW1lbnQgaGFzIGEgcGFyZW50IGVsZW1lbnQ7XG4gICAgLy8gaXQgZG9lc24ndCBpZiB3ZSBhcmUgY3VycmVudGx5IHJlY3Vyc2l2ZWx5IG1vcnBoaW5nIChyZXN0b3JpbmcgYSBzYXZlZCBzdHJlYW0gY2hpbGQpXG4gICAgLy8gYmVjYXVzZSB0aGUgZWxlbWVudCBpcyBub3QgeWV0IGFkZGVkIHRvIHRoZSByZWFsIGRvbTtcbiAgICAvLyByZW9yZGVyaW5nIGRvZXMgbm90IG1ha2Ugc2Vuc2UgaW4gdGhhdCBjYXNlIGFueXdheVxuICAgIGlmKCFlbC5wYXJlbnRFbGVtZW50KXsgcmV0dXJuIH1cblxuICAgIGlmKHN0cmVhbUF0ID09PSAwKXtcbiAgICAgIGVsLnBhcmVudEVsZW1lbnQuaW5zZXJ0QmVmb3JlKGVsLCBlbC5wYXJlbnRFbGVtZW50LmZpcnN0RWxlbWVudENoaWxkKVxuICAgIH0gZWxzZSBpZihzdHJlYW1BdCA+IDApe1xuICAgICAgbGV0IGNoaWxkcmVuID0gQXJyYXkuZnJvbShlbC5wYXJlbnRFbGVtZW50LmNoaWxkcmVuKVxuICAgICAgbGV0IG9sZEluZGV4ID0gY2hpbGRyZW4uaW5kZXhPZihlbClcbiAgICAgIGlmKHN0cmVhbUF0ID49IGNoaWxkcmVuLmxlbmd0aCAtIDEpe1xuICAgICAgICBlbC5wYXJlbnRFbGVtZW50LmFwcGVuZENoaWxkKGVsKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IHNpYmxpbmcgPSBjaGlsZHJlbltzdHJlYW1BdF1cbiAgICAgICAgaWYob2xkSW5kZXggPiBzdHJlYW1BdCl7XG4gICAgICAgICAgZWwucGFyZW50RWxlbWVudC5pbnNlcnRCZWZvcmUoZWwsIHNpYmxpbmcpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZWwucGFyZW50RWxlbWVudC5pbnNlcnRCZWZvcmUoZWwsIHNpYmxpbmcubmV4dEVsZW1lbnRTaWJsaW5nKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5tYXliZUxpbWl0U3RyZWFtKGVsKVxuICB9XG5cbiAgbWF5YmVMaW1pdFN0cmVhbShlbCl7XG4gICAgbGV0IHtsaW1pdH0gPSB0aGlzLmdldFN0cmVhbUluc2VydChlbClcbiAgICBsZXQgY2hpbGRyZW4gPSBsaW1pdCAhPT0gbnVsbCAmJiBBcnJheS5mcm9tKGVsLnBhcmVudEVsZW1lbnQuY2hpbGRyZW4pXG4gICAgaWYobGltaXQgJiYgbGltaXQgPCAwICYmIGNoaWxkcmVuLmxlbmd0aCA+IGxpbWl0ICogLTEpe1xuICAgICAgY2hpbGRyZW4uc2xpY2UoMCwgY2hpbGRyZW4ubGVuZ3RoICsgbGltaXQpLmZvckVhY2goY2hpbGQgPT4gdGhpcy5yZW1vdmVTdHJlYW1DaGlsZEVsZW1lbnQoY2hpbGQpKVxuICAgIH0gZWxzZSBpZihsaW1pdCAmJiBsaW1pdCA+PSAwICYmIGNoaWxkcmVuLmxlbmd0aCA+IGxpbWl0KXtcbiAgICAgIGNoaWxkcmVuLnNsaWNlKGxpbWl0KS5mb3JFYWNoKGNoaWxkID0+IHRoaXMucmVtb3ZlU3RyZWFtQ2hpbGRFbGVtZW50KGNoaWxkKSlcbiAgICB9XG4gIH1cblxuICB0cmFuc2l0aW9uUGVuZGluZ1JlbW92ZXMoKXtcbiAgICBsZXQge3BlbmRpbmdSZW1vdmVzLCBsaXZlU29ja2V0fSA9IHRoaXNcbiAgICBpZihwZW5kaW5nUmVtb3Zlcy5sZW5ndGggPiAwKXtcbiAgICAgIGxpdmVTb2NrZXQudHJhbnNpdGlvblJlbW92ZXMocGVuZGluZ1JlbW92ZXMpXG4gICAgICBsaXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICBwZW5kaW5nUmVtb3Zlcy5mb3JFYWNoKGVsID0+IHtcbiAgICAgICAgICBsZXQgY2hpbGQgPSBET00uZmlyc3RQaHhDaGlsZChlbClcbiAgICAgICAgICBpZihjaGlsZCl7IGxpdmVTb2NrZXQuZGVzdHJveVZpZXdCeUVsKGNoaWxkKSB9XG4gICAgICAgICAgZWwucmVtb3ZlKClcbiAgICAgICAgfSlcbiAgICAgICAgdGhpcy50cmFja0FmdGVyKFwidHJhbnNpdGlvbnNEaXNjYXJkZWRcIiwgcGVuZGluZ1JlbW92ZXMpXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIGlzQ2hhbmdlZFNlbGVjdChmcm9tRWwsIHRvRWwpe1xuICAgIGlmKCEoZnJvbUVsIGluc3RhbmNlb2YgSFRNTFNlbGVjdEVsZW1lbnQpIHx8IGZyb21FbC5tdWx0aXBsZSl7IHJldHVybiBmYWxzZSB9XG4gICAgaWYoZnJvbUVsLm9wdGlvbnMubGVuZ3RoICE9PSB0b0VsLm9wdGlvbnMubGVuZ3RoKXsgcmV0dXJuIHRydWUgfVxuXG4gICAgbGV0IGZyb21TZWxlY3RlZCA9IGZyb21FbC5zZWxlY3RlZE9wdGlvbnNbMF1cbiAgICBsZXQgdG9TZWxlY3RlZCA9IHRvRWwuc2VsZWN0ZWRPcHRpb25zWzBdXG4gICAgaWYoZnJvbVNlbGVjdGVkICYmIGZyb21TZWxlY3RlZC5oYXNBdHRyaWJ1dGUoXCJzZWxlY3RlZFwiKSl7XG4gICAgICB0b1NlbGVjdGVkLnNldEF0dHJpYnV0ZShcInNlbGVjdGVkXCIsIGZyb21TZWxlY3RlZC5nZXRBdHRyaWJ1dGUoXCJzZWxlY3RlZFwiKSlcbiAgICB9XG5cbiAgICAvLyBpbiBnZW5lcmFsIHdlIGhhdmUgdG8gYmUgdmVyeSBjYXJlZnVsIHdpdGggdXNpbmcgaXNFcXVhbE5vZGUgYXMgaXQgZG9lcyBub3QgYSByZWxpYWJsZVxuICAgIC8vIERPTSB0cmVlIGVxdWFsaXR5IGNoZWNrLCBidXQgZm9yIHNlbGVjdGlvbiBhdHRyaWJ1dGVzIGFuZCBvcHRpb25zIGl0IHdvcmtzIGZpbmVcbiAgICByZXR1cm4gIWZyb21FbC5pc0VxdWFsTm9kZSh0b0VsKVxuICB9XG5cbiAgaXNDSURQYXRjaCgpeyByZXR1cm4gdGhpcy5jaWRQYXRjaCB9XG5cbiAgc2tpcENJRFNpYmxpbmcoZWwpe1xuICAgIHJldHVybiBlbC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUgJiYgZWwuaGFzQXR0cmlidXRlKFBIWF9TS0lQKVxuICB9XG5cbiAgdGFyZ2V0Q0lEQ29udGFpbmVyKGh0bWwpe1xuICAgIGlmKCF0aGlzLmlzQ0lEUGF0Y2goKSl7IHJldHVybiB9XG4gICAgbGV0IFtmaXJzdCwgLi4ucmVzdF0gPSBET00uZmluZENvbXBvbmVudE5vZGVMaXN0KHRoaXMuY29udGFpbmVyLCB0aGlzLnRhcmdldENJRClcbiAgICBpZihyZXN0Lmxlbmd0aCA9PT0gMCAmJiBET00uY2hpbGROb2RlTGVuZ3RoKGh0bWwpID09PSAxKXtcbiAgICAgIHJldHVybiBmaXJzdFxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmlyc3QgJiYgZmlyc3QucGFyZW50Tm9kZVxuICAgIH1cbiAgfVxuXG4gIGluZGV4T2YocGFyZW50LCBjaGlsZCl7IHJldHVybiBBcnJheS5mcm9tKHBhcmVudC5jaGlsZHJlbikuaW5kZXhPZihjaGlsZCkgfVxufVxuIiwgImltcG9ydCB7XG4gIENPTVBPTkVOVFMsXG4gIERZTkFNSUNTLFxuICBURU1QTEFURVMsXG4gIEVWRU5UUyxcbiAgUEhYX0NPTVBPTkVOVCxcbiAgUEhYX1NLSVAsXG4gIFBIWF9NQUdJQ19JRCxcbiAgUkVQTFksXG4gIFNUQVRJQyxcbiAgVElUTEUsXG4gIFNUUkVBTSxcbiAgUk9PVCxcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCJcblxuaW1wb3J0IHtcbiAgaXNPYmplY3QsXG4gIGxvZ0Vycm9yLFxuICBpc0NpZCxcbn0gZnJvbSBcIi4vdXRpbHNcIlxuXG5jb25zdCBWT0lEX1RBR1MgPSBuZXcgU2V0KFtcbiAgXCJhcmVhXCIsXG4gIFwiYmFzZVwiLFxuICBcImJyXCIsXG4gIFwiY29sXCIsXG4gIFwiY29tbWFuZFwiLFxuICBcImVtYmVkXCIsXG4gIFwiaHJcIixcbiAgXCJpbWdcIixcbiAgXCJpbnB1dFwiLFxuICBcImtleWdlblwiLFxuICBcImxpbmtcIixcbiAgXCJtZXRhXCIsXG4gIFwicGFyYW1cIixcbiAgXCJzb3VyY2VcIixcbiAgXCJ0cmFja1wiLFxuICBcIndiclwiXG5dKVxuY29uc3QgcXVvdGVDaGFycyA9IG5ldyBTZXQoW1wiJ1wiLCAnXCInXSlcblxuZXhwb3J0IGxldCBtb2RpZnlSb290ID0gKGh0bWwsIGF0dHJzLCBjbGVhcklubmVySFRNTCkgPT4ge1xuICBsZXQgaSA9IDBcbiAgbGV0IGluc2lkZUNvbW1lbnQgPSBmYWxzZVxuICBsZXQgYmVmb3JlVGFnLCBhZnRlclRhZywgdGFnLCB0YWdOYW1lRW5kc0F0LCBpZCwgbmV3SFRNTFxuXG4gIGxldCBsb29rYWhlYWQgPSBodG1sLm1hdGNoKC9eKFxccyooPzo8IS0tLio/LS0+XFxzKikqKTwoW15cXHNcXC8+XSspLylcbiAgaWYobG9va2FoZWFkID09PSBudWxsKSB7IHRocm93IG5ldyBFcnJvcihgbWFsZm9ybWVkIGh0bWwgJHtodG1sfWApIH1cblxuICBpID0gbG9va2FoZWFkWzBdLmxlbmd0aFxuICBiZWZvcmVUYWcgPSBsb29rYWhlYWRbMV1cbiAgdGFnID0gbG9va2FoZWFkWzJdXG4gIHRhZ05hbWVFbmRzQXQgPSBpXG5cbiAgLy8gU2NhbiB0aGUgb3BlbmluZyB0YWcgZm9yIGlkLCBpZiB0aGVyZSBpcyBhbnlcbiAgZm9yKGk7IGkgPCBodG1sLmxlbmd0aDsgaSsrKXtcbiAgICBpZihodG1sLmNoYXJBdChpKSA9PT0gXCI+XCIgKXsgYnJlYWsgfVxuICAgIGlmKGh0bWwuY2hhckF0KGkpID09PSBcIj1cIil7XG4gICAgICBsZXQgaXNJZCA9IGh0bWwuc2xpY2UoaSAtIDMsIGkpID09PSBcIiBpZFwiXG4gICAgICBpKys7XG4gICAgICBsZXQgY2hhciA9IGh0bWwuY2hhckF0KGkpXG4gICAgICBpZiAocXVvdGVDaGFycy5oYXMoY2hhcikpIHtcbiAgICAgICAgbGV0IGF0dHJTdGFydHNBdCA9IGlcbiAgICAgICAgaSsrXG4gICAgICAgIGZvcihpOyBpIDwgaHRtbC5sZW5ndGg7IGkrKyl7XG4gICAgICAgICAgaWYoaHRtbC5jaGFyQXQoaSkgPT09IGNoYXIpeyBicmVhayB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzSWQpIHtcbiAgICAgICAgICBpZCA9IGh0bWwuc2xpY2UoYXR0clN0YXJ0c0F0ICsgMSwgaSlcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbGV0IGNsb3NlQXQgPSBodG1sLmxlbmd0aCAtIDFcbiAgaW5zaWRlQ29tbWVudCA9IGZhbHNlXG4gIHdoaWxlKGNsb3NlQXQgPj0gYmVmb3JlVGFnLmxlbmd0aCArIHRhZy5sZW5ndGgpe1xuICAgIGxldCBjaGFyID0gaHRtbC5jaGFyQXQoY2xvc2VBdClcbiAgICBpZihpbnNpZGVDb21tZW50KXtcbiAgICAgIGlmKGNoYXIgPT09IFwiLVwiICYmIGh0bWwuc2xpY2UoY2xvc2VBdCAtIDMsIGNsb3NlQXQpID09PSBcIjwhLVwiKXtcbiAgICAgICAgaW5zaWRlQ29tbWVudCA9IGZhbHNlXG4gICAgICAgIGNsb3NlQXQgLT0gNFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2xvc2VBdCAtPSAxXG4gICAgICB9XG4gICAgfSBlbHNlIGlmKGNoYXIgPT09IFwiPlwiICYmIGh0bWwuc2xpY2UoY2xvc2VBdCAtIDIsIGNsb3NlQXQpID09PSBcIi0tXCIpe1xuICAgICAgaW5zaWRlQ29tbWVudCA9IHRydWVcbiAgICAgIGNsb3NlQXQgLT0gM1xuICAgIH0gZWxzZSBpZihjaGFyID09PSBcIj5cIil7XG4gICAgICBicmVha1xuICAgIH0gZWxzZSB7XG4gICAgICBjbG9zZUF0IC09IDFcbiAgICB9XG4gIH1cbiAgYWZ0ZXJUYWcgPSBodG1sLnNsaWNlKGNsb3NlQXQgKyAxLCBodG1sLmxlbmd0aClcblxuICBsZXQgYXR0cnNTdHIgPVxuICAgIE9iamVjdC5rZXlzKGF0dHJzKVxuICAgIC5tYXAoYXR0ciA9PiBhdHRyc1thdHRyXSA9PT0gdHJ1ZSA/IGF0dHIgOiBgJHthdHRyfT1cIiR7YXR0cnNbYXR0cl19XCJgKVxuICAgIC5qb2luKFwiIFwiKVxuXG4gIGlmKGNsZWFySW5uZXJIVE1MKXtcbiAgICAvLyBLZWVwIHRoZSBpZCBpZiBhbnlcbiAgICBsZXQgaWRBdHRyU3RyID0gaWQgPyBgIGlkPVwiJHtpZH1cImAgOiBcIlwiO1xuICAgIGlmKFZPSURfVEFHUy5oYXModGFnKSl7XG4gICAgICBuZXdIVE1MID0gYDwke3RhZ30ke2lkQXR0clN0cn0ke2F0dHJzU3RyID09PSBcIlwiID8gXCJcIiA6IFwiIFwifSR7YXR0cnNTdHJ9Lz5gXG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld0hUTUwgPSBgPCR7dGFnfSR7aWRBdHRyU3RyfSR7YXR0cnNTdHIgPT09IFwiXCIgPyBcIlwiIDogXCIgXCJ9JHthdHRyc1N0cn0+PC8ke3RhZ30+YFxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBsZXQgcmVzdCA9IGh0bWwuc2xpY2UodGFnTmFtZUVuZHNBdCwgY2xvc2VBdCArIDEpXG4gICAgbmV3SFRNTCA9IGA8JHt0YWd9JHthdHRyc1N0ciA9PT0gXCJcIiA/IFwiXCIgOiBcIiBcIn0ke2F0dHJzU3RyfSR7cmVzdH1gXG4gIH1cblxuICByZXR1cm4gW25ld0hUTUwsIGJlZm9yZVRhZywgYWZ0ZXJUYWddXG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlbmRlcmVkIHtcbiAgc3RhdGljIGV4dHJhY3QoZGlmZil7XG4gICAgbGV0IHtbUkVQTFldOiByZXBseSwgW0VWRU5UU106IGV2ZW50cywgW1RJVExFXTogdGl0bGV9ID0gZGlmZlxuICAgIGRlbGV0ZSBkaWZmW1JFUExZXVxuICAgIGRlbGV0ZSBkaWZmW0VWRU5UU11cbiAgICBkZWxldGUgZGlmZltUSVRMRV1cbiAgICByZXR1cm4ge2RpZmYsIHRpdGxlLCByZXBseTogcmVwbHkgfHwgbnVsbCwgZXZlbnRzOiBldmVudHMgfHwgW119XG4gIH1cblxuICBjb25zdHJ1Y3Rvcih2aWV3SWQsIHJlbmRlcmVkKXtcbiAgICB0aGlzLnZpZXdJZCA9IHZpZXdJZFxuICAgIHRoaXMucmVuZGVyZWQgPSB7fVxuICAgIHRoaXMubWFnaWNJZCA9IDBcbiAgICB0aGlzLm1lcmdlRGlmZihyZW5kZXJlZClcbiAgfVxuXG4gIHBhcmVudFZpZXdJZCgpeyByZXR1cm4gdGhpcy52aWV3SWQgfVxuXG4gIHRvU3RyaW5nKG9ubHlDaWRzKXtcbiAgICBsZXQgW3N0ciwgc3RyZWFtc10gPSB0aGlzLnJlY3Vyc2l2ZVRvU3RyaW5nKHRoaXMucmVuZGVyZWQsIHRoaXMucmVuZGVyZWRbQ09NUE9ORU5UU10sIG9ubHlDaWRzLCB0cnVlLCB7fSlcbiAgICByZXR1cm4gW3N0ciwgc3RyZWFtc11cbiAgfVxuXG4gIHJlY3Vyc2l2ZVRvU3RyaW5nKHJlbmRlcmVkLCBjb21wb25lbnRzID0gcmVuZGVyZWRbQ09NUE9ORU5UU10sIG9ubHlDaWRzLCBjaGFuZ2VUcmFja2luZywgcm9vdEF0dHJzKXtcbiAgICBvbmx5Q2lkcyA9IG9ubHlDaWRzID8gbmV3IFNldChvbmx5Q2lkcykgOiBudWxsXG4gICAgbGV0IG91dHB1dCA9IHtidWZmZXI6IFwiXCIsIGNvbXBvbmVudHM6IGNvbXBvbmVudHMsIG9ubHlDaWRzOiBvbmx5Q2lkcywgc3RyZWFtczogbmV3IFNldCgpfVxuICAgIHRoaXMudG9PdXRwdXRCdWZmZXIocmVuZGVyZWQsIG51bGwsIG91dHB1dCwgY2hhbmdlVHJhY2tpbmcsIHJvb3RBdHRycylcbiAgICByZXR1cm4gW291dHB1dC5idWZmZXIsIG91dHB1dC5zdHJlYW1zXVxuICB9XG5cbiAgY29tcG9uZW50Q0lEcyhkaWZmKXsgcmV0dXJuIE9iamVjdC5rZXlzKGRpZmZbQ09NUE9ORU5UU10gfHwge30pLm1hcChpID0+IHBhcnNlSW50KGkpKSB9XG5cbiAgaXNDb21wb25lbnRPbmx5RGlmZihkaWZmKXtcbiAgICBpZighZGlmZltDT01QT05FTlRTXSl7IHJldHVybiBmYWxzZSB9XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGRpZmYpLmxlbmd0aCA9PT0gMVxuICB9XG5cbiAgZ2V0Q29tcG9uZW50KGRpZmYsIGNpZCl7IHJldHVybiBkaWZmW0NPTVBPTkVOVFNdW2NpZF0gfVxuXG4gIHJlc2V0UmVuZGVyKGNpZCl7XG4gICAgLy8gd2UgYXJlIHJhY2luZyBhIGNvbXBvbmVudCBkZXN0cm95LCBpdCBjb3VsZCBub3QgZXhpc3QsIHNvXG4gICAgLy8gbWFrZSBzdXJlIHRoYXQgd2UgZG9uJ3QgdHJ5IHRvIHNldCByZXNldCBvbiB1bmRlZmluZWRcbiAgICBpZih0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdW2NpZF0pe1xuICAgICAgdGhpcy5yZW5kZXJlZFtDT01QT05FTlRTXVtjaWRdLnJlc2V0ID0gdHJ1ZVxuICAgIH1cbiAgfVxuXG4gIG1lcmdlRGlmZihkaWZmKXtcbiAgICBsZXQgbmV3YyA9IGRpZmZbQ09NUE9ORU5UU11cbiAgICBsZXQgY2FjaGUgPSB7fVxuICAgIGRlbGV0ZSBkaWZmW0NPTVBPTkVOVFNdXG4gICAgdGhpcy5yZW5kZXJlZCA9IHRoaXMubXV0YWJsZU1lcmdlKHRoaXMucmVuZGVyZWQsIGRpZmYpXG4gICAgdGhpcy5yZW5kZXJlZFtDT01QT05FTlRTXSA9IHRoaXMucmVuZGVyZWRbQ09NUE9ORU5UU10gfHwge31cblxuICAgIGlmKG5ld2Mpe1xuICAgICAgbGV0IG9sZGMgPSB0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdXG5cbiAgICAgIGZvcihsZXQgY2lkIGluIG5ld2Mpe1xuICAgICAgICBuZXdjW2NpZF0gPSB0aGlzLmNhY2hlZEZpbmRDb21wb25lbnQoY2lkLCBuZXdjW2NpZF0sIG9sZGMsIG5ld2MsIGNhY2hlKVxuICAgICAgfVxuXG4gICAgICBmb3IobGV0IGNpZCBpbiBuZXdjKXsgb2xkY1tjaWRdID0gbmV3Y1tjaWRdIH1cbiAgICAgIGRpZmZbQ09NUE9ORU5UU10gPSBuZXdjXG4gICAgfVxuICB9XG5cbiAgY2FjaGVkRmluZENvbXBvbmVudChjaWQsIGNkaWZmLCBvbGRjLCBuZXdjLCBjYWNoZSl7XG4gICAgaWYoY2FjaGVbY2lkXSl7XG4gICAgICByZXR1cm4gY2FjaGVbY2lkXVxuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgbmRpZmYsIHN0YXQsIHNjaWQgPSBjZGlmZltTVEFUSUNdXG5cbiAgICAgIGlmKGlzQ2lkKHNjaWQpKXtcbiAgICAgICAgbGV0IHRkaWZmXG5cbiAgICAgICAgaWYoc2NpZCA+IDApe1xuICAgICAgICAgIHRkaWZmID0gdGhpcy5jYWNoZWRGaW5kQ29tcG9uZW50KHNjaWQsIG5ld2Nbc2NpZF0sIG9sZGMsIG5ld2MsIGNhY2hlKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRkaWZmID0gb2xkY1stc2NpZF1cbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXQgPSB0ZGlmZltTVEFUSUNdXG4gICAgICAgIG5kaWZmID0gdGhpcy5jbG9uZU1lcmdlKHRkaWZmLCBjZGlmZiwgdHJ1ZSlcbiAgICAgICAgbmRpZmZbU1RBVElDXSA9IHN0YXRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5kaWZmID0gY2RpZmZbU1RBVElDXSAhPT0gdW5kZWZpbmVkIHx8IG9sZGNbY2lkXSA9PT0gdW5kZWZpbmVkID9cbiAgICAgICAgICBjZGlmZiA6IHRoaXMuY2xvbmVNZXJnZShvbGRjW2NpZF0sIGNkaWZmLCBmYWxzZSlcbiAgICAgIH1cblxuICAgICAgY2FjaGVbY2lkXSA9IG5kaWZmXG4gICAgICByZXR1cm4gbmRpZmZcbiAgICB9XG4gIH1cblxuICBtdXRhYmxlTWVyZ2UodGFyZ2V0LCBzb3VyY2Upe1xuICAgIGlmKHNvdXJjZVtTVEFUSUNdICE9PSB1bmRlZmluZWQpe1xuICAgICAgcmV0dXJuIHNvdXJjZVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRvTXV0YWJsZU1lcmdlKHRhcmdldCwgc291cmNlKVxuICAgICAgcmV0dXJuIHRhcmdldFxuICAgIH1cbiAgfVxuXG4gIGRvTXV0YWJsZU1lcmdlKHRhcmdldCwgc291cmNlKXtcbiAgICBmb3IobGV0IGtleSBpbiBzb3VyY2Upe1xuICAgICAgbGV0IHZhbCA9IHNvdXJjZVtrZXldXG4gICAgICBsZXQgdGFyZ2V0VmFsID0gdGFyZ2V0W2tleV1cbiAgICAgIGxldCBpc09ialZhbCA9IGlzT2JqZWN0KHZhbClcbiAgICAgIGlmKGlzT2JqVmFsICYmIHZhbFtTVEFUSUNdID09PSB1bmRlZmluZWQgJiYgaXNPYmplY3QodGFyZ2V0VmFsKSl7XG4gICAgICAgIHRoaXMuZG9NdXRhYmxlTWVyZ2UodGFyZ2V0VmFsLCB2YWwpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0YXJnZXRba2V5XSA9IHZhbFxuICAgICAgfVxuICAgIH1cbiAgICBpZih0YXJnZXRbUk9PVF0pe1xuICAgICAgdGFyZ2V0Lm5ld1JlbmRlciA9IHRydWVcbiAgICB9XG4gIH1cblxuICAvLyBNZXJnZXMgY2lkIHRyZWVzIHRvZ2V0aGVyLCBjb3B5aW5nIHN0YXRpY3MgZnJvbSBzb3VyY2UgdHJlZS5cbiAgLy9cbiAgLy8gVGhlIGBwcnVuZU1hZ2ljSWRgIGlzIHBhc3NlZCB0byBjb250cm9sIHBydW5pbmcgdGhlIG1hZ2ljSWQgb2YgdGhlXG4gIC8vIHRhcmdldC4gV2UgbXVzdCBhbHdheXMgcHJ1bmUgdGhlIG1hZ2ljSWQgd2hlbiB3ZSBhcmUgc2hhcmluZyBzdGF0aWNzXG4gIC8vIGZyb20gYW5vdGhlciBjb21wb25lbnQuIElmIG5vdCBwcnVuaW5nLCB3ZSByZXBsaWNhdGUgdGhlIGxvZ2ljIGZyb21cbiAgLy8gbXV0YWJsZU1lcmdlLCB3aGVyZSB3ZSBzZXQgbmV3UmVuZGVyIHRvIHRydWUgaWYgdGhlcmUgaXMgYSByb290XG4gIC8vIChlZmZlY3RpdmVseSBmb3JjaW5nIHRoZSBuZXcgdmVyc2lvbiB0byBiZSByZW5kZXJlZCBpbnN0ZWFkIG9mIHNraXBwZWQpXG4gIC8vXG4gIGNsb25lTWVyZ2UodGFyZ2V0LCBzb3VyY2UsIHBydW5lTWFnaWNJZCl7XG4gICAgbGV0IG1lcmdlZCA9IHsuLi50YXJnZXQsIC4uLnNvdXJjZX1cbiAgICBmb3IobGV0IGtleSBpbiBtZXJnZWQpe1xuICAgICAgbGV0IHZhbCA9IHNvdXJjZVtrZXldXG4gICAgICBsZXQgdGFyZ2V0VmFsID0gdGFyZ2V0W2tleV1cbiAgICAgIGlmKGlzT2JqZWN0KHZhbCkgJiYgdmFsW1NUQVRJQ10gPT09IHVuZGVmaW5lZCAmJiBpc09iamVjdCh0YXJnZXRWYWwpKXtcbiAgICAgICAgbWVyZ2VkW2tleV0gPSB0aGlzLmNsb25lTWVyZ2UodGFyZ2V0VmFsLCB2YWwsIHBydW5lTWFnaWNJZClcbiAgICAgIH0gZWxzZSBpZih2YWwgPT09IHVuZGVmaW5lZCAmJiBpc09iamVjdCh0YXJnZXRWYWwpKXtcbiAgICAgICAgbWVyZ2VkW2tleV0gPSB0aGlzLmNsb25lTWVyZ2UodGFyZ2V0VmFsLCB7fSwgcHJ1bmVNYWdpY0lkKVxuICAgICAgfVxuICAgIH1cbiAgICBpZihwcnVuZU1hZ2ljSWQpe1xuICAgICAgZGVsZXRlIG1lcmdlZC5tYWdpY0lkXG4gICAgICBkZWxldGUgbWVyZ2VkLm5ld1JlbmRlclxuICAgIH0gZWxzZSBpZih0YXJnZXRbUk9PVF0pe1xuICAgICAgbWVyZ2VkLm5ld1JlbmRlciA9IHRydWVcbiAgICB9XG4gICAgcmV0dXJuIG1lcmdlZFxuICB9XG5cbiAgY29tcG9uZW50VG9TdHJpbmcoY2lkKXtcbiAgICBsZXQgW3N0ciwgc3RyZWFtc10gPSB0aGlzLnJlY3Vyc2l2ZUNJRFRvU3RyaW5nKHRoaXMucmVuZGVyZWRbQ09NUE9ORU5UU10sIGNpZCwgbnVsbClcbiAgICBsZXQgW3N0cmlwcGVkSFRNTCwgX2JlZm9yZSwgX2FmdGVyXSA9IG1vZGlmeVJvb3Qoc3RyLCB7fSlcbiAgICByZXR1cm4gW3N0cmlwcGVkSFRNTCwgc3RyZWFtc11cbiAgfVxuXG4gIHBydW5lQ0lEcyhjaWRzKXtcbiAgICBjaWRzLmZvckVhY2goY2lkID0+IGRlbGV0ZSB0aGlzLnJlbmRlcmVkW0NPTVBPTkVOVFNdW2NpZF0pXG4gIH1cblxuICAvLyBwcml2YXRlXG5cbiAgZ2V0KCl7IHJldHVybiB0aGlzLnJlbmRlcmVkIH1cblxuICBpc05ld0ZpbmdlcnByaW50KGRpZmYgPSB7fSl7IHJldHVybiAhIWRpZmZbU1RBVElDXSB9XG5cbiAgdGVtcGxhdGVTdGF0aWMocGFydCwgdGVtcGxhdGVzKXtcbiAgICBpZih0eXBlb2YgKHBhcnQpID09PSBcIm51bWJlclwiKSB7XG4gICAgICByZXR1cm4gdGVtcGxhdGVzW3BhcnRdXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBwYXJ0XG4gICAgfVxuICB9XG5cbiAgbmV4dE1hZ2ljSUQoKXtcbiAgICB0aGlzLm1hZ2ljSWQrK1xuICAgIHJldHVybiBgbSR7dGhpcy5tYWdpY0lkfS0ke3RoaXMucGFyZW50Vmlld0lkKCl9YFxuICB9XG5cbiAgLy8gQ29udmVydHMgcmVuZGVyZWQgdHJlZSB0byBvdXRwdXQgYnVmZmVyLlxuICAvL1xuICAvLyBjaGFuZ2VUcmFja2luZyBjb250cm9scyBpZiB3ZSBjYW4gYXBwbHkgdGhlIFBIWF9TS0lQIG9wdGltaXphdGlvbi5cbiAgLy8gSXQgaXMgZGlzYWJsZWQgZm9yIGNvbXByZWhlbnNpb25zIHNpbmNlIHdlIG11c3QgcmUtcmVuZGVyIHRoZSBlbnRpcmUgY29sbGVjdGlvblxuICAvLyBhbmQgbm8gaW5kaXZpZHVhbCBlbGVtZW50IGlzIHRyYWNrZWQgaW5zaWRlIHRoZSBjb21wcmVoZW5zaW9uLlxuICB0b091dHB1dEJ1ZmZlcihyZW5kZXJlZCwgdGVtcGxhdGVzLCBvdXRwdXQsIGNoYW5nZVRyYWNraW5nLCByb290QXR0cnMgPSB7fSl7XG4gICAgaWYocmVuZGVyZWRbRFlOQU1JQ1NdKXsgcmV0dXJuIHRoaXMuY29tcHJlaGVuc2lvblRvQnVmZmVyKHJlbmRlcmVkLCB0ZW1wbGF0ZXMsIG91dHB1dCkgfVxuICAgIGxldCB7W1NUQVRJQ106IHN0YXRpY3N9ID0gcmVuZGVyZWRcbiAgICBzdGF0aWNzID0gdGhpcy50ZW1wbGF0ZVN0YXRpYyhzdGF0aWNzLCB0ZW1wbGF0ZXMpXG4gICAgbGV0IGlzUm9vdCA9IHJlbmRlcmVkW1JPT1RdXG4gICAgbGV0IHByZXZCdWZmZXIgPSBvdXRwdXQuYnVmZmVyXG4gICAgaWYoaXNSb290KXsgb3V0cHV0LmJ1ZmZlciA9IFwiXCIgfVxuXG4gICAgLy8gdGhpcyBjb25kaXRpb24gaXMgY2FsbGVkIHdoZW4gZmlyc3QgcmVuZGVyaW5nIGFuIG9wdGltaXphYmxlIGZ1bmN0aW9uIGNvbXBvbmVudC5cbiAgICAvLyBMQyBoYXZlIHRoZWlyIG1hZ2ljSWQgcHJldmlvdXNseSBzZXRcbiAgICBpZihjaGFuZ2VUcmFja2luZyAmJiBpc1Jvb3QgJiYgIXJlbmRlcmVkLm1hZ2ljSWQpe1xuICAgICAgcmVuZGVyZWQubmV3UmVuZGVyID0gdHJ1ZVxuICAgICAgcmVuZGVyZWQubWFnaWNJZCA9IHRoaXMubmV4dE1hZ2ljSUQoKVxuICAgIH1cblxuICAgIG91dHB1dC5idWZmZXIgKz0gc3RhdGljc1swXVxuICAgIGZvcihsZXQgaSA9IDE7IGkgPCBzdGF0aWNzLmxlbmd0aDsgaSsrKXtcbiAgICAgIHRoaXMuZHluYW1pY1RvQnVmZmVyKHJlbmRlcmVkW2kgLSAxXSwgdGVtcGxhdGVzLCBvdXRwdXQsIGNoYW5nZVRyYWNraW5nKVxuICAgICAgb3V0cHV0LmJ1ZmZlciArPSBzdGF0aWNzW2ldXG4gICAgfVxuXG4gICAgLy8gQXBwbGllcyB0aGUgcm9vdCB0YWcgXCJza2lwXCIgb3B0aW1pemF0aW9uIGlmIHN1cHBvcnRlZCwgd2hpY2ggY2xlYXJzXG4gICAgLy8gdGhlIHJvb3QgdGFnIGF0dHJpYnV0ZXMgYW5kIGlubmVySFRNTCwgYW5kIG9ubHkgbWFpbnRhaW5zIHRoZSBtYWdpY0lkLlxuICAgIC8vIFdlIGNhbiBvbmx5IHNraXAgd2hlbiBjaGFuZ2VUcmFja2luZyBpcyBzdXBwb3J0ZWQgKG91dHNpZGUgb2YgYSBjb21wcmVoZW5zaW9uKSxcbiAgICAvLyBhbmQgd2hlbiB0aGUgcm9vdCBlbGVtZW50IGhhc24ndCBleHBlcmllbmNlZCBhbiB1bnJlbmRlcmVkIG1lcmdlIChuZXdSZW5kZXIgdHJ1ZSkuXG4gICAgaWYoaXNSb290KXtcbiAgICAgIGxldCBza2lwID0gZmFsc2VcbiAgICAgIGxldCBhdHRyc1xuICAgICAgLy8gV2hlbiBhIExDIGlzIHJlLWFkZGVkIHRvIHRoZSBwYWdlLCB3ZSBuZWVkIHRvIHJlLXJlbmRlciB0aGUgZW50aXJlIExDIHRyZWUsXG4gICAgICAvLyB0aGVyZWZvcmUgY2hhbmdlVHJhY2tpbmcgaXMgZmFsc2U7IGhvd2V2ZXIsIHdlIG5lZWQgdG8ga2VlcCBhbGwgdGhlIG1hZ2ljSWRzXG4gICAgICAvLyBmcm9tIGFueSBmdW5jdGlvbiBjb21wb25lbnQgc28gdGhlIG5leHQgdGltZSB0aGUgTEMgaXMgdXBkYXRlZCwgd2UgY2FuIGFwcGx5XG4gICAgICAvLyB0aGUgc2tpcCBvcHRpbWl6YXRpb25cbiAgICAgIGlmKGNoYW5nZVRyYWNraW5nIHx8IHJlbmRlcmVkLm1hZ2ljSWQpe1xuICAgICAgICBza2lwID0gY2hhbmdlVHJhY2tpbmcgJiYgIXJlbmRlcmVkLm5ld1JlbmRlclxuICAgICAgICBhdHRycyA9IHtbUEhYX01BR0lDX0lEXTogcmVuZGVyZWQubWFnaWNJZCwgLi4ucm9vdEF0dHJzfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXR0cnMgPSByb290QXR0cnNcbiAgICAgIH1cbiAgICAgIGlmKHNraXApeyBhdHRyc1tQSFhfU0tJUF0gPSB0cnVlIH1cbiAgICAgIGxldCBbbmV3Um9vdCwgY29tbWVudEJlZm9yZSwgY29tbWVudEFmdGVyXSA9IG1vZGlmeVJvb3Qob3V0cHV0LmJ1ZmZlciwgYXR0cnMsIHNraXApXG4gICAgICByZW5kZXJlZC5uZXdSZW5kZXIgPSBmYWxzZVxuICAgICAgb3V0cHV0LmJ1ZmZlciA9IHByZXZCdWZmZXIgKyBjb21tZW50QmVmb3JlICsgbmV3Um9vdCArIGNvbW1lbnRBZnRlclxuICAgIH1cbiAgfVxuXG4gIGNvbXByZWhlbnNpb25Ub0J1ZmZlcihyZW5kZXJlZCwgdGVtcGxhdGVzLCBvdXRwdXQpe1xuICAgIGxldCB7W0RZTkFNSUNTXTogZHluYW1pY3MsIFtTVEFUSUNdOiBzdGF0aWNzLCBbU1RSRUFNXTogc3RyZWFtfSA9IHJlbmRlcmVkXG4gICAgbGV0IFtfcmVmLCBfaW5zZXJ0cywgZGVsZXRlSWRzLCByZXNldF0gPSBzdHJlYW0gfHwgW251bGwsIHt9LCBbXSwgbnVsbF1cbiAgICBzdGF0aWNzID0gdGhpcy50ZW1wbGF0ZVN0YXRpYyhzdGF0aWNzLCB0ZW1wbGF0ZXMpXG4gICAgbGV0IGNvbXBUZW1wbGF0ZXMgPSB0ZW1wbGF0ZXMgfHwgcmVuZGVyZWRbVEVNUExBVEVTXVxuICAgIGZvcihsZXQgZCA9IDA7IGQgPCBkeW5hbWljcy5sZW5ndGg7IGQrKyl7XG4gICAgICBsZXQgZHluYW1pYyA9IGR5bmFtaWNzW2RdXG4gICAgICBvdXRwdXQuYnVmZmVyICs9IHN0YXRpY3NbMF1cbiAgICAgIGZvcihsZXQgaSA9IDE7IGkgPCBzdGF0aWNzLmxlbmd0aDsgaSsrKXtcbiAgICAgICAgLy8gSW5zaWRlIGEgY29tcHJlaGVuc2lvbiwgd2UgZG9uJ3QgdHJhY2sgaG93IGR5bmFtaWNzIGNoYW5nZVxuICAgICAgICAvLyBvdmVyIHRpbWUgKGFuZCBmZWF0dXJlcyBsaWtlIHN0cmVhbXMgd291bGQgbWFrZSB0aGF0IGltcG9zc2libGVcbiAgICAgICAgLy8gdW5sZXNzIHdlIG1vdmUgdGhlIHN0cmVhbSBkaWZmaW5nIGF3YXkgZnJvbSBtb3JwaGRvbSksXG4gICAgICAgIC8vIHNvIHdlIGNhbid0IHBlcmZvcm0gcm9vdCBjaGFuZ2UgdHJhY2tpbmcuXG4gICAgICAgIGxldCBjaGFuZ2VUcmFja2luZyA9IGZhbHNlXG4gICAgICAgIHRoaXMuZHluYW1pY1RvQnVmZmVyKGR5bmFtaWNbaSAtIDFdLCBjb21wVGVtcGxhdGVzLCBvdXRwdXQsIGNoYW5nZVRyYWNraW5nKVxuICAgICAgICBvdXRwdXQuYnVmZmVyICs9IHN0YXRpY3NbaV1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZihzdHJlYW0gIT09IHVuZGVmaW5lZCAmJiAocmVuZGVyZWRbRFlOQU1JQ1NdLmxlbmd0aCA+IDAgfHwgZGVsZXRlSWRzLmxlbmd0aCA+IDAgfHwgcmVzZXQpKXtcbiAgICAgIGRlbGV0ZSByZW5kZXJlZFtTVFJFQU1dXG4gICAgICByZW5kZXJlZFtEWU5BTUlDU10gPSBbXVxuICAgICAgb3V0cHV0LnN0cmVhbXMuYWRkKHN0cmVhbSlcbiAgICB9XG4gIH1cblxuICBkeW5hbWljVG9CdWZmZXIocmVuZGVyZWQsIHRlbXBsYXRlcywgb3V0cHV0LCBjaGFuZ2VUcmFja2luZyl7XG4gICAgaWYodHlwZW9mIChyZW5kZXJlZCkgPT09IFwibnVtYmVyXCIpe1xuICAgICAgbGV0IFtzdHIsIHN0cmVhbXNdID0gdGhpcy5yZWN1cnNpdmVDSURUb1N0cmluZyhvdXRwdXQuY29tcG9uZW50cywgcmVuZGVyZWQsIG91dHB1dC5vbmx5Q2lkcylcbiAgICAgIG91dHB1dC5idWZmZXIgKz0gc3RyXG4gICAgICBvdXRwdXQuc3RyZWFtcyA9IG5ldyBTZXQoWy4uLm91dHB1dC5zdHJlYW1zLCAuLi5zdHJlYW1zXSlcbiAgICB9IGVsc2UgaWYoaXNPYmplY3QocmVuZGVyZWQpKXtcbiAgICAgIHRoaXMudG9PdXRwdXRCdWZmZXIocmVuZGVyZWQsIHRlbXBsYXRlcywgb3V0cHV0LCBjaGFuZ2VUcmFja2luZywge30pXG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5idWZmZXIgKz0gcmVuZGVyZWRcbiAgICB9XG4gIH1cblxuICByZWN1cnNpdmVDSURUb1N0cmluZyhjb21wb25lbnRzLCBjaWQsIG9ubHlDaWRzKXtcbiAgICBsZXQgY29tcG9uZW50ID0gY29tcG9uZW50c1tjaWRdIHx8IGxvZ0Vycm9yKGBubyBjb21wb25lbnQgZm9yIENJRCAke2NpZH1gLCBjb21wb25lbnRzKVxuICAgIGxldCBhdHRycyA9IHtbUEhYX0NPTVBPTkVOVF06IGNpZH1cbiAgICBsZXQgc2tpcCA9IG9ubHlDaWRzICYmICFvbmx5Q2lkcy5oYXMoY2lkKVxuICAgIC8vIFR3byBvcHRpbWl6YXRpb24gcGF0aHMgYXBwbHkgaGVyZTpcbiAgICAvL1xuICAgIC8vICAgMS4gVGhlIG9ubHlDaWRzIG9wdGltaXphdGlvbiB3b3JrcyBieSB0aGUgc2VydmVyIGRpZmYgdGVsbGluZyB1cyBvbmx5IHNwZWNpZmljXG4gICAgLy8gICAgIGNpZCdzIGhhdmUgY2hhbmdlZC4gVGhpcyBhbGxvd3MgdXMgdG8gc2tpcCByZW5kZXJpbmcgYW55IGNvbXBvbmVudCB0aGF0IGhhc24ndCBjaGFuZ2VkLFxuICAgIC8vICAgICB3aGljaCB1bHRpbWF0ZWx5IHNldHMgUEhYX1NLSVAgcm9vdCBhdHRyaWJ1dGUgYW5kIGF2b2lkcyByZW5kZXJpbmcgdGhlIGlubmVySFRNTC5cbiAgICAvL1xuICAgIC8vICAgMi4gVGhlIHJvb3QgUEhYX1NLSVAgb3B0aW1pemF0aW9uIGdlbmVyYWxpemVzIHRvIGFsbCBIRUV4IGZ1bmN0aW9uIGNvbXBvbmVudHMsIGFuZFxuICAgIC8vICAgICB3b3JrcyBpbiB0aGUgc2FtZSBQSFhfU0tJUCBhdHRyaWJ1dGUgZmFzaGlvbiBhcyAxLCBidXQgdGhlIG5ld1JlbmRlciB0cmFja2luZyBpcyBkb25lXG4gICAgLy8gICAgIGF0IHRoZSBnZW5lcmFsIGRpZmYgbWVyZ2UgbGV2ZWwuIElmIHdlIG1lcmdlIGEgZGlmZiB3aXRoIG5ldyBkeW5hbWljcywgd2UgbmVjZXNzYXJpbHkgaGF2ZVxuICAgIC8vICAgICBleHBlcmllbmNlZCBhIGNoYW5nZSB3aGljaCBtdXN0IGJlIGEgbmV3UmVuZGVyLCBhbmQgdGh1cyB3ZSBjYW4ndCBza2lwIHRoZSByZW5kZXIuXG4gICAgLy9cbiAgICAvLyBCb3RoIG9wdGltaXphdGlvbiBmbG93cyBhcHBseSBoZXJlLiBuZXdSZW5kZXIgaXMgc2V0IGJhc2VkIG9uIHRoZSBvbmx5Q2lkcyBvcHRpbWl6YXRpb24sIGFuZFxuICAgIC8vIHdlIHRyYWNrIGEgZGV0ZXJtaW5pc3RpYyBtYWdpY0lkIGJhc2VkIG9uIHRoZSBjaWQuXG4gICAgLy9cbiAgICAvLyBjaGFuZ2VUcmFja2luZyBpcyBhYm91dCB0aGUgZW50aXJlIHRyZWVcbiAgICAvLyBuZXdSZW5kZXIgaXMgYWJvdXQgdGhlIGN1cnJlbnQgcm9vdCBpbiB0aGUgdHJlZVxuICAgIC8vXG4gICAgLy8gQnkgZGVmYXVsdCBjaGFuZ2VUcmFja2luZyBpcyBlbmFibGVkLCBidXQgd2Ugc3BlY2lhbCBjYXNlIHRoZSBmbG93IHdoZXJlIHRoZSBjbGllbnQgaXMgcHJ1bmluZ1xuICAgIC8vIGNpZHMgYW5kIHRoZSBzZXJ2ZXIgYWRkcyB0aGUgY29tcG9uZW50IGJhY2suIEluIHN1Y2ggY2FzZXMsIHdlIGV4cGxpY2l0bHkgZGlzYWJsZSBjaGFuZ2VUcmFja2luZ1xuICAgIC8vIHdpdGggcmVzZXRSZW5kZXIgZm9yIHRoaXMgY2lkLCB0aGVuIHJlLWVuYWJsZSBpdCBhZnRlciB0aGUgcmVjdXJzaXZlIGNhbGwgdG8gc2tpcCB0aGUgb3B0aW1pemF0aW9uXG4gICAgLy8gZm9yIHRoZSBlbnRpcmUgY29tcG9uZW50IHRyZWUuXG4gICAgY29tcG9uZW50Lm5ld1JlbmRlciA9ICFza2lwXG4gICAgY29tcG9uZW50Lm1hZ2ljSWQgPSBgYyR7Y2lkfS0ke3RoaXMucGFyZW50Vmlld0lkKCl9YFxuICAgIC8vIGVuYWJsZSBjaGFuZ2UgdHJhY2tpbmcgYXMgbG9uZyBhcyB0aGUgY29tcG9uZW50IGhhc24ndCBiZWVuIHJlc2V0XG4gICAgbGV0IGNoYW5nZVRyYWNraW5nID0gIWNvbXBvbmVudC5yZXNldFxuICAgIGxldCBbaHRtbCwgc3RyZWFtc10gPSB0aGlzLnJlY3Vyc2l2ZVRvU3RyaW5nKGNvbXBvbmVudCwgY29tcG9uZW50cywgb25seUNpZHMsIGNoYW5nZVRyYWNraW5nLCBhdHRycylcbiAgICAvLyBkaXNhYmxlIHJlc2V0IGFmdGVyIHdlJ3ZlIHJlbmRlcmVkXG4gICAgZGVsZXRlIGNvbXBvbmVudC5yZXNldFxuXG4gICAgcmV0dXJuIFtodG1sLCBzdHJlYW1zXVxuICB9XG59XG4iLCAibGV0IHZpZXdIb29rSUQgPSAxXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWaWV3SG9vayB7XG4gIHN0YXRpYyBtYWtlSUQoKXsgcmV0dXJuIHZpZXdIb29rSUQrKyB9XG4gIHN0YXRpYyBlbGVtZW50SUQoZWwpeyByZXR1cm4gZWwucGh4SG9va0lkIH1cblxuICBjb25zdHJ1Y3Rvcih2aWV3LCBlbCwgY2FsbGJhY2tzKXtcbiAgICB0aGlzLl9fdmlldyA9IHZpZXdcbiAgICB0aGlzLmxpdmVTb2NrZXQgPSB2aWV3LmxpdmVTb2NrZXRcbiAgICB0aGlzLl9fY2FsbGJhY2tzID0gY2FsbGJhY2tzXG4gICAgdGhpcy5fX2xpc3RlbmVycyA9IG5ldyBTZXQoKVxuICAgIHRoaXMuX19pc0Rpc2Nvbm5lY3RlZCA9IGZhbHNlXG4gICAgdGhpcy5lbCA9IGVsXG4gICAgdGhpcy5lbC5waHhIb29rSWQgPSB0aGlzLmNvbnN0cnVjdG9yLm1ha2VJRCgpXG4gICAgZm9yKGxldCBrZXkgaW4gdGhpcy5fX2NhbGxiYWNrcyl7IHRoaXNba2V5XSA9IHRoaXMuX19jYWxsYmFja3Nba2V5XSB9XG4gIH1cblxuICBfX21vdW50ZWQoKXsgdGhpcy5tb3VudGVkICYmIHRoaXMubW91bnRlZCgpIH1cbiAgX191cGRhdGVkKCl7IHRoaXMudXBkYXRlZCAmJiB0aGlzLnVwZGF0ZWQoKSB9XG4gIF9fYmVmb3JlVXBkYXRlKCl7IHRoaXMuYmVmb3JlVXBkYXRlICYmIHRoaXMuYmVmb3JlVXBkYXRlKCkgfVxuICBfX2Rlc3Ryb3llZCgpeyB0aGlzLmRlc3Ryb3llZCAmJiB0aGlzLmRlc3Ryb3llZCgpIH1cbiAgX19yZWNvbm5lY3RlZCgpe1xuICAgIGlmKHRoaXMuX19pc0Rpc2Nvbm5lY3RlZCl7XG4gICAgICB0aGlzLl9faXNEaXNjb25uZWN0ZWQgPSBmYWxzZVxuICAgICAgdGhpcy5yZWNvbm5lY3RlZCAmJiB0aGlzLnJlY29ubmVjdGVkKClcbiAgICB9XG4gIH1cbiAgX19kaXNjb25uZWN0ZWQoKXtcbiAgICB0aGlzLl9faXNEaXNjb25uZWN0ZWQgPSB0cnVlXG4gICAgdGhpcy5kaXNjb25uZWN0ZWQgJiYgdGhpcy5kaXNjb25uZWN0ZWQoKVxuICB9XG5cbiAgcHVzaEV2ZW50KGV2ZW50LCBwYXlsb2FkID0ge30sIG9uUmVwbHkgPSBmdW5jdGlvbiAoKXsgfSl7XG4gICAgcmV0dXJuIHRoaXMuX192aWV3LnB1c2hIb29rRXZlbnQodGhpcy5lbCwgbnVsbCwgZXZlbnQsIHBheWxvYWQsIG9uUmVwbHkpXG4gIH1cblxuICBwdXNoRXZlbnRUbyhwaHhUYXJnZXQsIGV2ZW50LCBwYXlsb2FkID0ge30sIG9uUmVwbHkgPSBmdW5jdGlvbiAoKXsgfSl7XG4gICAgcmV0dXJuIHRoaXMuX192aWV3LndpdGhpblRhcmdldHMocGh4VGFyZ2V0LCAodmlldywgdGFyZ2V0Q3R4KSA9PiB7XG4gICAgICByZXR1cm4gdmlldy5wdXNoSG9va0V2ZW50KHRoaXMuZWwsIHRhcmdldEN0eCwgZXZlbnQsIHBheWxvYWQsIG9uUmVwbHkpXG4gICAgfSlcbiAgfVxuXG4gIGhhbmRsZUV2ZW50KGV2ZW50LCBjYWxsYmFjayl7XG4gICAgbGV0IGNhbGxiYWNrUmVmID0gKGN1c3RvbUV2ZW50LCBieXBhc3MpID0+IGJ5cGFzcyA/IGV2ZW50IDogY2FsbGJhY2soY3VzdG9tRXZlbnQuZGV0YWlsKVxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKGBwaHg6JHtldmVudH1gLCBjYWxsYmFja1JlZilcbiAgICB0aGlzLl9fbGlzdGVuZXJzLmFkZChjYWxsYmFja1JlZilcbiAgICByZXR1cm4gY2FsbGJhY2tSZWZcbiAgfVxuXG4gIHJlbW92ZUhhbmRsZUV2ZW50KGNhbGxiYWNrUmVmKXtcbiAgICBsZXQgZXZlbnQgPSBjYWxsYmFja1JlZihudWxsLCB0cnVlKVxuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKGBwaHg6JHtldmVudH1gLCBjYWxsYmFja1JlZilcbiAgICB0aGlzLl9fbGlzdGVuZXJzLmRlbGV0ZShjYWxsYmFja1JlZilcbiAgfVxuXG4gIHVwbG9hZChuYW1lLCBmaWxlcyl7XG4gICAgcmV0dXJuIHRoaXMuX192aWV3LmRpc3BhdGNoVXBsb2FkcyhudWxsLCBuYW1lLCBmaWxlcylcbiAgfVxuXG4gIHVwbG9hZFRvKHBoeFRhcmdldCwgbmFtZSwgZmlsZXMpe1xuICAgIHJldHVybiB0aGlzLl9fdmlldy53aXRoaW5UYXJnZXRzKHBoeFRhcmdldCwgKHZpZXcsIHRhcmdldEN0eCkgPT4ge1xuICAgICAgdmlldy5kaXNwYXRjaFVwbG9hZHModGFyZ2V0Q3R4LCBuYW1lLCBmaWxlcylcbiAgICB9KVxuICB9XG5cbiAgX19jbGVhbnVwX18oKXtcbiAgICB0aGlzLl9fbGlzdGVuZXJzLmZvckVhY2goY2FsbGJhY2tSZWYgPT4gdGhpcy5yZW1vdmVIYW5kbGVFdmVudChjYWxsYmFja1JlZikpXG4gIH1cbn1cbiIsICJpbXBvcnQge1xuICBCRUZPUkVfVU5MT0FEX0xPQURFUl9USU1FT1VULFxuICBDSEVDS0FCTEVfSU5QVVRTLFxuICBDT05TRUNVVElWRV9SRUxPQURTLFxuICBQSFhfQVVUT19SRUNPVkVSLFxuICBQSFhfQ09NUE9ORU5ULFxuICBQSFhfQ09OTkVDVEVEX0NMQVNTLFxuICBQSFhfRElTQUJMRV9XSVRILFxuICBQSFhfRElTQUJMRV9XSVRIX1JFU1RPUkUsXG4gIFBIWF9ESVNBQkxFRCxcbiAgUEhYX0xPQURJTkdfQ0xBU1MsXG4gIFBIWF9FVkVOVF9DTEFTU0VTLFxuICBQSFhfRVJST1JfQ0xBU1MsXG4gIFBIWF9DTElFTlRfRVJST1JfQ0xBU1MsXG4gIFBIWF9TRVJWRVJfRVJST1JfQ0xBU1MsXG4gIFBIWF9GRUVEQkFDS19GT1IsXG4gIFBIWF9GRUVEQkFDS19HUk9VUCxcbiAgUEhYX0hBU19GT0NVU0VELFxuICBQSFhfSEFTX1NVQk1JVFRFRCxcbiAgUEhYX0hPT0ssXG4gIFBIWF9QQUdFX0xPQURJTkcsXG4gIFBIWF9QQVJFTlRfSUQsXG4gIFBIWF9QUk9HUkVTUyxcbiAgUEhYX1JFQURPTkxZLFxuICBQSFhfUkVGLFxuICBQSFhfUkVGX1NSQyxcbiAgUEhYX1JPT1RfSUQsXG4gIFBIWF9TRVNTSU9OLFxuICBQSFhfU1RBVElDLFxuICBQSFhfVFJBQ0tfU1RBVElDLFxuICBQSFhfVFJBQ0tfVVBMT0FEUyxcbiAgUEhYX1VQREFURSxcbiAgUEhYX1VQTE9BRF9SRUYsXG4gIFBIWF9WSUVXX1NFTEVDVE9SLFxuICBQSFhfTUFJTixcbiAgUEhYX01PVU5URUQsXG4gIFBVU0hfVElNRU9VVCxcbiAgUEhYX1ZJRVdQT1JUX1RPUCxcbiAgUEhYX1ZJRVdQT1JUX0JPVFRPTSxcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCJcblxuaW1wb3J0IHtcbiAgY2xvbmUsXG4gIGNsb3Nlc3RQaHhCaW5kaW5nLFxuICBpc0VtcHR5LFxuICBpc0VxdWFsT2JqLFxuICBsb2dFcnJvcixcbiAgbWF5YmUsXG4gIGlzQ2lkLFxufSBmcm9tIFwiLi91dGlsc1wiXG5cbmltcG9ydCBCcm93c2VyIGZyb20gXCIuL2Jyb3dzZXJcIlxuaW1wb3J0IERPTSBmcm9tIFwiLi9kb21cIlxuaW1wb3J0IERPTVBhdGNoIGZyb20gXCIuL2RvbV9wYXRjaFwiXG5pbXBvcnQgTGl2ZVVwbG9hZGVyIGZyb20gXCIuL2xpdmVfdXBsb2FkZXJcIlxuaW1wb3J0IFJlbmRlcmVkIGZyb20gXCIuL3JlbmRlcmVkXCJcbmltcG9ydCBWaWV3SG9vayBmcm9tIFwiLi92aWV3X2hvb2tcIlxuaW1wb3J0IEpTIGZyb20gXCIuL2pzXCJcblxubGV0IHNlcmlhbGl6ZUZvcm0gPSAoZm9ybSwgbWV0YWRhdGEsIG9ubHlOYW1lcyA9IFtdKSA9PiB7XG4gIGNvbnN0IHtzdWJtaXR0ZXIsIC4uLm1ldGF9ID0gbWV0YWRhdGFcblxuICAvLyBXZSBtdXN0IGluamVjdCB0aGUgc3VibWl0dGVyIGluIHRoZSBvcmRlciB0aGF0IGl0IGV4aXN0cyBpbiB0aGUgRE9NXG4gIC8vIHJlbGVhdGl2ZSB0byBvdGhlciBpbnB1dHMuIEZvciBleGFtcGxlLCBmb3IgY2hlY2tib3ggZ3JvdXBzLCB0aGUgb3JkZXIgbXVzdCBiZSBtYWludGFpbmVkLlxuICBsZXQgaW5qZWN0ZWRFbGVtZW50XG4gIGlmKHN1Ym1pdHRlciAmJiBzdWJtaXR0ZXIubmFtZSl7XG4gICAgY29uc3QgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIilcbiAgICBpbnB1dC50eXBlID0gXCJoaWRkZW5cIlxuICAgIC8vIHNldCB0aGUgZm9ybSBhdHRyaWJ1dGUgaWYgdGhlIHN1Ym1pdHRlciBoYXMgb25lO1xuICAgIC8vIHRoaXMgY2FuIGhhcHBlbiBpZiB0aGUgZWxlbWVudCBpcyBvdXRzaWRlIHRoZSBhY3R1YWwgZm9ybSBlbGVtZW50XG4gICAgY29uc3QgZm9ybUlkID0gc3VibWl0dGVyLmdldEF0dHJpYnV0ZShcImZvcm1cIilcbiAgICBpZihmb3JtSWQpe1xuICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKFwiZm9ybVwiLCBmb3JtSWQpXG4gICAgfVxuICAgIGlucHV0Lm5hbWUgPSBzdWJtaXR0ZXIubmFtZVxuICAgIGlucHV0LnZhbHVlID0gc3VibWl0dGVyLnZhbHVlXG4gICAgc3VibWl0dGVyLnBhcmVudEVsZW1lbnQuaW5zZXJ0QmVmb3JlKGlucHV0LCBzdWJtaXR0ZXIpXG4gICAgaW5qZWN0ZWRFbGVtZW50ID0gaW5wdXRcbiAgfVxuXG4gIGNvbnN0IGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKGZvcm0pXG4gIGNvbnN0IHRvUmVtb3ZlID0gW11cblxuICBmb3JtRGF0YS5mb3JFYWNoKCh2YWwsIGtleSwgX2luZGV4KSA9PiB7XG4gICAgaWYodmFsIGluc3RhbmNlb2YgRmlsZSl7IHRvUmVtb3ZlLnB1c2goa2V5KSB9XG4gIH0pXG5cbiAgLy8gQ2xlYW51cCBhZnRlciBidWlsZGluZyBmaWxlRGF0YVxuICB0b1JlbW92ZS5mb3JFYWNoKGtleSA9PiBmb3JtRGF0YS5kZWxldGUoa2V5KSlcblxuICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKClcblxuICBmb3IobGV0IFtrZXksIHZhbF0gb2YgZm9ybURhdGEuZW50cmllcygpKXtcbiAgICBpZihvbmx5TmFtZXMubGVuZ3RoID09PSAwIHx8IG9ubHlOYW1lcy5pbmRleE9mKGtleSkgPj0gMCl7XG4gICAgICBwYXJhbXMuYXBwZW5kKGtleSwgdmFsKVxuICAgIH1cbiAgfVxuXG4gIC8vIHJlbW92ZSB0aGUgaW5qZWN0ZWQgZWxlbWVudCBhZ2FpblxuICAvLyAoaXQgd291bGQgYmUgcmVtb3ZlZCBieSB0aGUgbmV4dCBkb20gcGF0Y2ggYW55d2F5LCBidXQgdGhpcyBpcyBjbGVhbmVyKVxuICBpZihzdWJtaXR0ZXIgJiYgaW5qZWN0ZWRFbGVtZW50KXtcbiAgICBzdWJtaXR0ZXIucGFyZW50RWxlbWVudC5yZW1vdmVDaGlsZChpbmplY3RlZEVsZW1lbnQpXG4gIH1cblxuICBmb3IobGV0IG1ldGFLZXkgaW4gbWV0YSl7IHBhcmFtcy5hcHBlbmQobWV0YUtleSwgbWV0YVttZXRhS2V5XSkgfVxuXG4gIHJldHVybiBwYXJhbXMudG9TdHJpbmcoKVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWaWV3IHtcbiAgY29uc3RydWN0b3IoZWwsIGxpdmVTb2NrZXQsIHBhcmVudFZpZXcsIGZsYXNoLCBsaXZlUmVmZXJlcil7XG4gICAgdGhpcy5pc0RlYWQgPSBmYWxzZVxuICAgIHRoaXMubGl2ZVNvY2tldCA9IGxpdmVTb2NrZXRcbiAgICB0aGlzLmZsYXNoID0gZmxhc2hcbiAgICB0aGlzLnBhcmVudCA9IHBhcmVudFZpZXdcbiAgICB0aGlzLnJvb3QgPSBwYXJlbnRWaWV3ID8gcGFyZW50Vmlldy5yb290IDogdGhpc1xuICAgIHRoaXMuZWwgPSBlbFxuICAgIHRoaXMuaWQgPSB0aGlzLmVsLmlkXG4gICAgdGhpcy5yZWYgPSAwXG4gICAgdGhpcy5jaGlsZEpvaW5zID0gMFxuICAgIHRoaXMubG9hZGVyVGltZXIgPSBudWxsXG4gICAgdGhpcy5wZW5kaW5nRGlmZnMgPSBbXVxuICAgIHRoaXMucGVuZGluZ0Zvcm1zID0gbmV3IFNldCgpXG4gICAgdGhpcy5yZWRpcmVjdCA9IGZhbHNlXG4gICAgdGhpcy5ocmVmID0gbnVsbFxuICAgIHRoaXMuam9pbkNvdW50ID0gdGhpcy5wYXJlbnQgPyB0aGlzLnBhcmVudC5qb2luQ291bnQgLSAxIDogMFxuICAgIHRoaXMuam9pblBlbmRpbmcgPSB0cnVlXG4gICAgdGhpcy5kZXN0cm95ZWQgPSBmYWxzZVxuICAgIHRoaXMuam9pbkNhbGxiYWNrID0gZnVuY3Rpb24ob25Eb25lKXsgb25Eb25lICYmIG9uRG9uZSgpIH1cbiAgICB0aGlzLnN0b3BDYWxsYmFjayA9IGZ1bmN0aW9uKCl7IH1cbiAgICB0aGlzLnBlbmRpbmdKb2luT3BzID0gdGhpcy5wYXJlbnQgPyBudWxsIDogW11cbiAgICB0aGlzLnZpZXdIb29rcyA9IHt9XG4gICAgdGhpcy5mb3JtU3VibWl0cyA9IFtdXG4gICAgdGhpcy5jaGlsZHJlbiA9IHRoaXMucGFyZW50ID8gbnVsbCA6IHt9XG4gICAgdGhpcy5yb290LmNoaWxkcmVuW3RoaXMuaWRdID0ge31cbiAgICB0aGlzLmZvcm1zRm9yUmVjb3ZlcnkgPSB7fVxuICAgIHRoaXMuY2hhbm5lbCA9IHRoaXMubGl2ZVNvY2tldC5jaGFubmVsKGBsdjoke3RoaXMuaWR9YCwgKCkgPT4ge1xuICAgICAgbGV0IHVybCA9IHRoaXMuaHJlZiAmJiB0aGlzLmV4cGFuZFVSTCh0aGlzLmhyZWYpXG4gICAgICByZXR1cm4ge1xuICAgICAgICByZWRpcmVjdDogdGhpcy5yZWRpcmVjdCA/IHVybCA6IHVuZGVmaW5lZCxcbiAgICAgICAgdXJsOiB0aGlzLnJlZGlyZWN0ID8gdW5kZWZpbmVkIDogdXJsIHx8IHVuZGVmaW5lZCxcbiAgICAgICAgcGFyYW1zOiB0aGlzLmNvbm5lY3RQYXJhbXMobGl2ZVJlZmVyZXIpLFxuICAgICAgICBzZXNzaW9uOiB0aGlzLmdldFNlc3Npb24oKSxcbiAgICAgICAgc3RhdGljOiB0aGlzLmdldFN0YXRpYygpLFxuICAgICAgICBmbGFzaDogdGhpcy5mbGFzaCxcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgc2V0SHJlZihocmVmKXsgdGhpcy5ocmVmID0gaHJlZiB9XG5cbiAgc2V0UmVkaXJlY3QoaHJlZil7XG4gICAgdGhpcy5yZWRpcmVjdCA9IHRydWVcbiAgICB0aGlzLmhyZWYgPSBocmVmXG4gIH1cblxuICBpc01haW4oKXsgcmV0dXJuIHRoaXMuZWwuaGFzQXR0cmlidXRlKFBIWF9NQUlOKSB9XG5cbiAgY29ubmVjdFBhcmFtcyhsaXZlUmVmZXJlcil7XG4gICAgbGV0IHBhcmFtcyA9IHRoaXMubGl2ZVNvY2tldC5wYXJhbXModGhpcy5lbClcbiAgICBsZXQgbWFuaWZlc3QgPVxuICAgICAgRE9NLmFsbChkb2N1bWVudCwgYFske3RoaXMuYmluZGluZyhQSFhfVFJBQ0tfU1RBVElDKX1dYClcbiAgICAgICAgLm1hcChub2RlID0+IG5vZGUuc3JjIHx8IG5vZGUuaHJlZikuZmlsdGVyKHVybCA9PiB0eXBlb2YgKHVybCkgPT09IFwic3RyaW5nXCIpXG5cbiAgICBpZihtYW5pZmVzdC5sZW5ndGggPiAwKXsgcGFyYW1zW1wiX3RyYWNrX3N0YXRpY1wiXSA9IG1hbmlmZXN0IH1cbiAgICBwYXJhbXNbXCJfbW91bnRzXCJdID0gdGhpcy5qb2luQ291bnRcbiAgICBwYXJhbXNbXCJfbGl2ZV9yZWZlcmVyXCJdID0gbGl2ZVJlZmVyZXJcblxuICAgIHJldHVybiBwYXJhbXNcbiAgfVxuXG4gIGlzQ29ubmVjdGVkKCl7IHJldHVybiB0aGlzLmNoYW5uZWwuY2FuUHVzaCgpIH1cblxuICBnZXRTZXNzaW9uKCl7IHJldHVybiB0aGlzLmVsLmdldEF0dHJpYnV0ZShQSFhfU0VTU0lPTikgfVxuXG4gIGdldFN0YXRpYygpe1xuICAgIGxldCB2YWwgPSB0aGlzLmVsLmdldEF0dHJpYnV0ZShQSFhfU1RBVElDKVxuICAgIHJldHVybiB2YWwgPT09IFwiXCIgPyBudWxsIDogdmFsXG4gIH1cblxuICBkZXN0cm95KGNhbGxiYWNrID0gZnVuY3Rpb24gKCl7IH0pe1xuICAgIHRoaXMuZGVzdHJveUFsbENoaWxkcmVuKClcbiAgICB0aGlzLmRlc3Ryb3llZCA9IHRydWVcbiAgICBkZWxldGUgdGhpcy5yb290LmNoaWxkcmVuW3RoaXMuaWRdXG4gICAgaWYodGhpcy5wYXJlbnQpeyBkZWxldGUgdGhpcy5yb290LmNoaWxkcmVuW3RoaXMucGFyZW50LmlkXVt0aGlzLmlkXSB9XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMubG9hZGVyVGltZXIpXG4gICAgbGV0IG9uRmluaXNoZWQgPSAoKSA9PiB7XG4gICAgICBjYWxsYmFjaygpXG4gICAgICBmb3IobGV0IGlkIGluIHRoaXMudmlld0hvb2tzKXtcbiAgICAgICAgdGhpcy5kZXN0cm95SG9vayh0aGlzLnZpZXdIb29rc1tpZF0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgRE9NLm1hcmtQaHhDaGlsZERlc3Ryb3llZCh0aGlzLmVsKVxuXG4gICAgdGhpcy5sb2coXCJkZXN0cm95ZWRcIiwgKCkgPT4gW1widGhlIGNoaWxkIGhhcyBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgcGFyZW50XCJdKVxuICAgIHRoaXMuY2hhbm5lbC5sZWF2ZSgpXG4gICAgICAucmVjZWl2ZShcIm9rXCIsIG9uRmluaXNoZWQpXG4gICAgICAucmVjZWl2ZShcImVycm9yXCIsIG9uRmluaXNoZWQpXG4gICAgICAucmVjZWl2ZShcInRpbWVvdXRcIiwgb25GaW5pc2hlZClcbiAgfVxuXG4gIHNldENvbnRhaW5lckNsYXNzZXMoLi4uY2xhc3Nlcyl7XG4gICAgdGhpcy5lbC5jbGFzc0xpc3QucmVtb3ZlKFxuICAgICAgUEhYX0NPTk5FQ1RFRF9DTEFTUyxcbiAgICAgIFBIWF9MT0FESU5HX0NMQVNTLFxuICAgICAgUEhYX0VSUk9SX0NMQVNTLFxuICAgICAgUEhYX0NMSUVOVF9FUlJPUl9DTEFTUyxcbiAgICAgIFBIWF9TRVJWRVJfRVJST1JfQ0xBU1NcbiAgICApXG4gICAgdGhpcy5lbC5jbGFzc0xpc3QuYWRkKC4uLmNsYXNzZXMpXG4gIH1cblxuICBzaG93TG9hZGVyKHRpbWVvdXQpe1xuICAgIGNsZWFyVGltZW91dCh0aGlzLmxvYWRlclRpbWVyKVxuICAgIGlmKHRpbWVvdXQpe1xuICAgICAgdGhpcy5sb2FkZXJUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zaG93TG9hZGVyKCksIHRpbWVvdXQpXG4gICAgfSBlbHNlIHtcbiAgICAgIGZvcihsZXQgaWQgaW4gdGhpcy52aWV3SG9va3MpeyB0aGlzLnZpZXdIb29rc1tpZF0uX19kaXNjb25uZWN0ZWQoKSB9XG4gICAgICB0aGlzLnNldENvbnRhaW5lckNsYXNzZXMoUEhYX0xPQURJTkdfQ0xBU1MpXG4gICAgfVxuICB9XG5cbiAgZXhlY0FsbChiaW5kaW5nKXtcbiAgICBET00uYWxsKHRoaXMuZWwsIGBbJHtiaW5kaW5nfV1gLCBlbCA9PiB0aGlzLmxpdmVTb2NrZXQuZXhlY0pTKGVsLCBlbC5nZXRBdHRyaWJ1dGUoYmluZGluZykpKVxuICB9XG5cbiAgaGlkZUxvYWRlcigpe1xuICAgIGNsZWFyVGltZW91dCh0aGlzLmxvYWRlclRpbWVyKVxuICAgIHRoaXMuc2V0Q29udGFpbmVyQ2xhc3NlcyhQSFhfQ09OTkVDVEVEX0NMQVNTKVxuICAgIHRoaXMuZXhlY0FsbCh0aGlzLmJpbmRpbmcoXCJjb25uZWN0ZWRcIikpXG4gIH1cblxuICB0cmlnZ2VyUmVjb25uZWN0ZWQoKXtcbiAgICBmb3IobGV0IGlkIGluIHRoaXMudmlld0hvb2tzKXsgdGhpcy52aWV3SG9va3NbaWRdLl9fcmVjb25uZWN0ZWQoKSB9XG4gIH1cblxuICBsb2coa2luZCwgbXNnQ2FsbGJhY2spe1xuICAgIHRoaXMubGl2ZVNvY2tldC5sb2codGhpcywga2luZCwgbXNnQ2FsbGJhY2spXG4gIH1cblxuICB0cmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSA9IGZ1bmN0aW9uKCl7fSl7XG4gICAgdGhpcy5saXZlU29ja2V0LnRyYW5zaXRpb24odGltZSwgb25TdGFydCwgb25Eb25lKVxuICB9XG5cbiAgLy8gY2FsbHMgdGhlIGNhbGxiYWNrIHdpdGggdGhlIHZpZXcgYW5kIHRhcmdldCBlbGVtZW50IGZvciB0aGUgZ2l2ZW4gcGh4VGFyZ2V0XG4gIC8vIHRhcmdldHMgY2FuIGJlOlxuICAvLyAgKiBhbiBlbGVtZW50IGl0c2VsZiwgdGhlbiBpdCBpcyBzaW1wbHkgcGFzc2VkIHRvIGxpdmVTb2NrZXQub3duZXI7XG4gIC8vICAqIGEgQ0lEIChDb21wb25lbnQgSUQpLCB0aGVuIHdlIGZpcnN0IHNlYXJjaCB0aGUgY29tcG9uZW50J3MgZWxlbWVudCBpbiB0aGUgRE9NXG4gIC8vICAqIGEgc2VsZWN0b3IsIHRoZW4gd2Ugc2VhcmNoIHRoZSBzZWxlY3RvciBpbiB0aGUgRE9NIGFuZCBjYWxsIHRoZSBjYWxsYmFja1xuICAvLyAgICBmb3IgZWFjaCBlbGVtZW50IGZvdW5kIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgb3duZXIgdmlld1xuICB3aXRoaW5UYXJnZXRzKHBoeFRhcmdldCwgY2FsbGJhY2ssIGRvbSA9IGRvY3VtZW50LCB2aWV3RWwpe1xuICAgIC8vIGluIHRoZSBmb3JtIHJlY292ZXJ5IGNhc2Ugd2Ugc2VhcmNoIGluIGEgdGVtcGxhdGUgZnJhZ21lbnQgaW5zdGVhZCBvZlxuICAgIC8vIHRoZSByZWFsIGRvbSwgdGhlcmVmb3JlIHdlIG9wdGlvbmFsbHkgcGFzcyBkb20gYW5kIHZpZXdFbFxuXG4gICAgaWYocGh4VGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgfHwgcGh4VGFyZ2V0IGluc3RhbmNlb2YgU1ZHRWxlbWVudCl7XG4gICAgICByZXR1cm4gdGhpcy5saXZlU29ja2V0Lm93bmVyKHBoeFRhcmdldCwgdmlldyA9PiBjYWxsYmFjayh2aWV3LCBwaHhUYXJnZXQpKVxuICAgIH1cblxuICAgIGlmKGlzQ2lkKHBoeFRhcmdldCkpe1xuICAgICAgbGV0IHRhcmdldHMgPSBET00uZmluZENvbXBvbmVudE5vZGVMaXN0KHZpZXdFbCB8fCB0aGlzLmVsLCBwaHhUYXJnZXQpXG4gICAgICBpZih0YXJnZXRzLmxlbmd0aCA9PT0gMCl7XG4gICAgICAgIGxvZ0Vycm9yKGBubyBjb21wb25lbnQgZm91bmQgbWF0Y2hpbmcgcGh4LXRhcmdldCBvZiAke3BoeFRhcmdldH1gKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2sodGhpcywgcGFyc2VJbnQocGh4VGFyZ2V0KSlcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHRhcmdldHMgPSBBcnJheS5mcm9tKGRvbS5xdWVyeVNlbGVjdG9yQWxsKHBoeFRhcmdldCkpXG4gICAgICBpZih0YXJnZXRzLmxlbmd0aCA9PT0gMCl7IGxvZ0Vycm9yKGBub3RoaW5nIGZvdW5kIG1hdGNoaW5nIHRoZSBwaHgtdGFyZ2V0IHNlbGVjdG9yIFwiJHtwaHhUYXJnZXR9XCJgKSB9XG4gICAgICB0YXJnZXRzLmZvckVhY2godGFyZ2V0ID0+IHRoaXMubGl2ZVNvY2tldC5vd25lcih0YXJnZXQsIHZpZXcgPT4gY2FsbGJhY2sodmlldywgdGFyZ2V0KSkpXG4gICAgfVxuICB9XG5cbiAgYXBwbHlEaWZmKHR5cGUsIHJhd0RpZmYsIGNhbGxiYWNrKXtcbiAgICB0aGlzLmxvZyh0eXBlLCAoKSA9PiBbXCJcIiwgY2xvbmUocmF3RGlmZildKVxuICAgIGxldCB7ZGlmZiwgcmVwbHksIGV2ZW50cywgdGl0bGV9ID0gUmVuZGVyZWQuZXh0cmFjdChyYXdEaWZmKVxuICAgIGNhbGxiYWNrKHtkaWZmLCByZXBseSwgZXZlbnRzfSlcbiAgICBpZih0eXBlb2YgdGl0bGUgPT09IFwic3RyaW5nXCIpeyB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IERPTS5wdXRUaXRsZSh0aXRsZSkpIH1cbiAgfVxuXG4gIG9uSm9pbihyZXNwKXtcbiAgICBsZXQge3JlbmRlcmVkLCBjb250YWluZXIsIGxpdmV2aWV3X3ZlcnNpb259ID0gcmVzcFxuICAgIGlmKGNvbnRhaW5lcil7XG4gICAgICBsZXQgW3RhZywgYXR0cnNdID0gY29udGFpbmVyXG4gICAgICB0aGlzLmVsID0gRE9NLnJlcGxhY2VSb290Q29udGFpbmVyKHRoaXMuZWwsIHRhZywgYXR0cnMpXG4gICAgfVxuICAgIHRoaXMuY2hpbGRKb2lucyA9IDBcbiAgICB0aGlzLmpvaW5QZW5kaW5nID0gdHJ1ZVxuICAgIHRoaXMuZmxhc2ggPSBudWxsXG4gICAgaWYodGhpcy5yb290ID09PSB0aGlzKXtcbiAgICAgIHRoaXMuZm9ybXNGb3JSZWNvdmVyeSA9IHRoaXMuZ2V0Rm9ybXNGb3JSZWNvdmVyeSgpXG4gICAgfVxuXG4gICAgaWYobGl2ZXZpZXdfdmVyc2lvbiAhPT0gdGhpcy5saXZlU29ja2V0LnZlcnNpb24oKSl7XG4gICAgICBjb25zb2xlLmVycm9yKGBMaXZlVmlldyBhc3NldCB2ZXJzaW9uIG1pc21hdGNoLiBKYXZhU2NyaXB0IHZlcnNpb24gJHt0aGlzLmxpdmVTb2NrZXQudmVyc2lvbigpfSB2cy4gc2VydmVyICR7bGl2ZXZpZXdfdmVyc2lvbn0uIFRvIGF2b2lkIGlzc3VlcywgcGxlYXNlIGVuc3VyZSB0aGF0IHlvdXIgYXNzZXRzIHVzZSB0aGUgc2FtZSB2ZXJzaW9uIGFzIHRoZSBzZXJ2ZXIuYClcbiAgICB9XG5cbiAgICBCcm93c2VyLmRyb3BMb2NhbCh0aGlzLmxpdmVTb2NrZXQubG9jYWxTdG9yYWdlLCB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsIENPTlNFQ1VUSVZFX1JFTE9BRFMpXG4gICAgdGhpcy5hcHBseURpZmYoXCJtb3VudFwiLCByZW5kZXJlZCwgKHtkaWZmLCBldmVudHN9KSA9PiB7XG4gICAgICB0aGlzLnJlbmRlcmVkID0gbmV3IFJlbmRlcmVkKHRoaXMuaWQsIGRpZmYpXG4gICAgICBsZXQgW2h0bWwsIHN0cmVhbXNdID0gdGhpcy5yZW5kZXJDb250YWluZXIobnVsbCwgXCJqb2luXCIpXG4gICAgICB0aGlzLmRyb3BQZW5kaW5nUmVmcygpXG4gICAgICB0aGlzLmpvaW5Db3VudCsrXG5cbiAgICAgIHRoaXMubWF5YmVSZWNvdmVyRm9ybXMoaHRtbCwgKCkgPT4ge1xuICAgICAgICB0aGlzLm9uSm9pbkNvbXBsZXRlKHJlc3AsIGh0bWwsIHN0cmVhbXMsIGV2ZW50cylcbiAgICAgIH0pXG4gICAgfSlcbiAgfVxuXG4gIGRyb3BQZW5kaW5nUmVmcygpe1xuICAgIERPTS5hbGwoZG9jdW1lbnQsIGBbJHtQSFhfUkVGX1NSQ309XCIke3RoaXMuaWR9XCJdWyR7UEhYX1JFRn1dYCwgZWwgPT4ge1xuICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKFBIWF9SRUYpXG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFRl9TUkMpXG4gICAgfSlcbiAgfVxuXG4gIG9uSm9pbkNvbXBsZXRlKHtsaXZlX3BhdGNofSwgaHRtbCwgc3RyZWFtcywgZXZlbnRzKXtcbiAgICAvLyBJbiBvcmRlciB0byBwcm92aWRlIGEgYmV0dGVyIGV4cGVyaWVuY2UsIHdlIHdhbnQgdG8gam9pblxuICAgIC8vIGFsbCBMaXZlVmlld3MgZmlyc3QgYW5kIG9ubHkgdGhlbiBhcHBseSB0aGVpciBwYXRjaGVzLlxuICAgIGlmKHRoaXMuam9pbkNvdW50ID4gMSB8fCAodGhpcy5wYXJlbnQgJiYgIXRoaXMucGFyZW50LmlzSm9pblBlbmRpbmcoKSkpe1xuICAgICAgcmV0dXJuIHRoaXMuYXBwbHlKb2luUGF0Y2gobGl2ZV9wYXRjaCwgaHRtbCwgc3RyZWFtcywgZXZlbnRzKVxuICAgIH1cblxuICAgIC8vIE9uZSBkb3duc2lkZSBvZiB0aGlzIGFwcHJvYWNoIGlzIHRoYXQgd2UgbmVlZCB0byBmaW5kIHBoeENoaWxkcmVuXG4gICAgLy8gaW4gdGhlIGh0bWwgZnJhZ21lbnQsIGluc3RlYWQgb2YgZGlyZWN0bHkgb24gdGhlIERPTS4gVGhlIGZyYWdtZW50XG4gICAgLy8gYWxzbyBkb2VzIG5vdCBpbmNsdWRlIFBIWF9TVEFUSUMsIHNvIHdlIG5lZWQgdG8gY29weSBpdCBvdmVyIGZyb21cbiAgICAvLyB0aGUgRE9NLlxuICAgIGxldCBuZXdDaGlsZHJlbiA9IERPTS5maW5kUGh4Q2hpbGRyZW5JbkZyYWdtZW50KGh0bWwsIHRoaXMuaWQpLmZpbHRlcih0b0VsID0+IHtcbiAgICAgIGxldCBmcm9tRWwgPSB0b0VsLmlkICYmIHRoaXMuZWwucXVlcnlTZWxlY3RvcihgW2lkPVwiJHt0b0VsLmlkfVwiXWApXG4gICAgICBsZXQgcGh4U3RhdGljID0gZnJvbUVsICYmIGZyb21FbC5nZXRBdHRyaWJ1dGUoUEhYX1NUQVRJQylcbiAgICAgIGlmKHBoeFN0YXRpYyl7IHRvRWwuc2V0QXR0cmlidXRlKFBIWF9TVEFUSUMsIHBoeFN0YXRpYykgfVxuICAgICAgLy8gc2V0IFBIWF9ST09UX0lEIHRvIHByZXZlbnQgZXZlbnRzIGZyb20gYmVpbmcgZGlzcGF0Y2hlZCB0byB0aGUgcm9vdCB2aWV3XG4gICAgICAvLyB3aGlsZSB0aGUgY2hpbGQgam9pbiBpcyBzdGlsbCBwZW5kaW5nXG4gICAgICBpZihmcm9tRWwpeyBmcm9tRWwuc2V0QXR0cmlidXRlKFBIWF9ST09UX0lELCB0aGlzLnJvb3QuaWQpIH1cbiAgICAgIHJldHVybiB0aGlzLmpvaW5DaGlsZCh0b0VsKVxuICAgIH0pXG5cbiAgICBpZihuZXdDaGlsZHJlbi5sZW5ndGggPT09IDApe1xuICAgICAgaWYodGhpcy5wYXJlbnQpe1xuICAgICAgICB0aGlzLnJvb3QucGVuZGluZ0pvaW5PcHMucHVzaChbdGhpcywgKCkgPT4gdGhpcy5hcHBseUpvaW5QYXRjaChsaXZlX3BhdGNoLCBodG1sLCBzdHJlYW1zLCBldmVudHMpXSlcbiAgICAgICAgdGhpcy5wYXJlbnQuYWNrSm9pbih0aGlzKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vbkFsbENoaWxkSm9pbnNDb21wbGV0ZSgpXG4gICAgICAgIHRoaXMuYXBwbHlKb2luUGF0Y2gobGl2ZV9wYXRjaCwgaHRtbCwgc3RyZWFtcywgZXZlbnRzKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJvb3QucGVuZGluZ0pvaW5PcHMucHVzaChbdGhpcywgKCkgPT4gdGhpcy5hcHBseUpvaW5QYXRjaChsaXZlX3BhdGNoLCBodG1sLCBzdHJlYW1zLCBldmVudHMpXSlcbiAgICB9XG4gIH1cblxuICBhdHRhY2hUcnVlRG9jRWwoKXtcbiAgICB0aGlzLmVsID0gRE9NLmJ5SWQodGhpcy5pZClcbiAgICB0aGlzLmVsLnNldEF0dHJpYnV0ZShQSFhfUk9PVF9JRCwgdGhpcy5yb290LmlkKVxuICB9XG5cbiAgLy8gdGhpcyBpcyBpbnZva2VkIGZvciBkZWFkIGFuZCBsaXZlIHZpZXdzLCBzbyB3ZSBtdXN0IGZpbHRlciBieVxuICAvLyBieSBvd25lciB0byBlbnN1cmUgd2UgYXJlbid0IGR1cGxpY2F0aW5nIGhvb2tzIGFjcm9zcyBkaXNjb25uZWN0XG4gIC8vIGFuZCBjb25uZWN0ZWQgc3RhdGVzLiBUaGlzIGFsc28gaGFuZGxlcyBjYXNlcyB3aGVyZSBob29rcyBleGlzdFxuICAvLyBpbiBhIHJvb3QgbGF5b3V0IHdpdGggYSBMViBpbiB0aGUgYm9keVxuICBleGVjTmV3TW91bnRlZCgpe1xuICAgIGxldCBwaHhWaWV3cG9ydFRvcCA9IHRoaXMuYmluZGluZyhQSFhfVklFV1BPUlRfVE9QKVxuICAgIGxldCBwaHhWaWV3cG9ydEJvdHRvbSA9IHRoaXMuYmluZGluZyhQSFhfVklFV1BPUlRfQk9UVE9NKVxuICAgIERPTS5hbGwodGhpcy5lbCwgYFske3BoeFZpZXdwb3J0VG9wfV0sIFske3BoeFZpZXdwb3J0Qm90dG9tfV1gLCBob29rRWwgPT4ge1xuICAgICAgaWYodGhpcy5vd25zRWxlbWVudChob29rRWwpKXtcbiAgICAgICAgRE9NLm1heWJlQWRkUHJpdmF0ZUhvb2tzKGhvb2tFbCwgcGh4Vmlld3BvcnRUb3AsIHBoeFZpZXdwb3J0Qm90dG9tKVxuICAgICAgICB0aGlzLm1heWJlQWRkTmV3SG9vayhob29rRWwpXG4gICAgICB9XG4gICAgfSlcbiAgICBET00uYWxsKHRoaXMuZWwsIGBbJHt0aGlzLmJpbmRpbmcoUEhYX0hPT0spfV0sIFtkYXRhLXBoeC0ke1BIWF9IT09LfV1gLCBob29rRWwgPT4ge1xuICAgICAgaWYodGhpcy5vd25zRWxlbWVudChob29rRWwpKXtcbiAgICAgICAgdGhpcy5tYXliZUFkZE5ld0hvb2soaG9va0VsKVxuICAgICAgfVxuICAgIH0pXG4gICAgRE9NLmFsbCh0aGlzLmVsLCBgWyR7dGhpcy5iaW5kaW5nKFBIWF9NT1VOVEVEKX1dYCwgZWwgPT4ge1xuICAgICAgaWYodGhpcy5vd25zRWxlbWVudChlbCkpe1xuICAgICAgICB0aGlzLm1heWJlTW91bnRlZChlbClcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgYXBwbHlKb2luUGF0Y2gobGl2ZV9wYXRjaCwgaHRtbCwgc3RyZWFtcywgZXZlbnRzKXtcbiAgICB0aGlzLmF0dGFjaFRydWVEb2NFbCgpXG4gICAgbGV0IHBhdGNoID0gbmV3IERPTVBhdGNoKHRoaXMsIHRoaXMuZWwsIHRoaXMuaWQsIGh0bWwsIHN0cmVhbXMsIG51bGwpXG4gICAgcGF0Y2gubWFya1BydW5hYmxlQ29udGVudEZvclJlbW92YWwoKVxuICAgIHRoaXMucGVyZm9ybVBhdGNoKHBhdGNoLCBmYWxzZSwgdHJ1ZSlcbiAgICB0aGlzLmpvaW5OZXdDaGlsZHJlbigpXG4gICAgdGhpcy5leGVjTmV3TW91bnRlZCgpXG5cbiAgICB0aGlzLmpvaW5QZW5kaW5nID0gZmFsc2VcbiAgICB0aGlzLmxpdmVTb2NrZXQuZGlzcGF0Y2hFdmVudHMoZXZlbnRzKVxuICAgIHRoaXMuYXBwbHlQZW5kaW5nVXBkYXRlcygpXG5cbiAgICBpZihsaXZlX3BhdGNoKXtcbiAgICAgIGxldCB7a2luZCwgdG99ID0gbGl2ZV9wYXRjaFxuICAgICAgdGhpcy5saXZlU29ja2V0Lmhpc3RvcnlQYXRjaCh0bywga2luZClcbiAgICB9XG4gICAgdGhpcy5oaWRlTG9hZGVyKClcbiAgICBpZih0aGlzLmpvaW5Db3VudCA+IDEpeyB0aGlzLnRyaWdnZXJSZWNvbm5lY3RlZCgpIH1cbiAgICB0aGlzLnN0b3BDYWxsYmFjaygpXG4gIH1cblxuICB0cmlnZ2VyQmVmb3JlVXBkYXRlSG9vayhmcm9tRWwsIHRvRWwpe1xuICAgIHRoaXMubGl2ZVNvY2tldC50cmlnZ2VyRE9NKFwib25CZWZvcmVFbFVwZGF0ZWRcIiwgW2Zyb21FbCwgdG9FbF0pXG4gICAgbGV0IGhvb2sgPSB0aGlzLmdldEhvb2soZnJvbUVsKVxuICAgIGxldCBpc0lnbm9yZWQgPSBob29rICYmIERPTS5pc0lnbm9yZWQoZnJvbUVsLCB0aGlzLmJpbmRpbmcoUEhYX1VQREFURSkpXG4gICAgaWYoaG9vayAmJiAhZnJvbUVsLmlzRXF1YWxOb2RlKHRvRWwpICYmICEoaXNJZ25vcmVkICYmIGlzRXF1YWxPYmooZnJvbUVsLmRhdGFzZXQsIHRvRWwuZGF0YXNldCkpKXtcbiAgICAgIGhvb2suX19iZWZvcmVVcGRhdGUoKVxuICAgICAgcmV0dXJuIGhvb2tcbiAgICB9XG4gIH1cblxuICBtYXliZU1vdW50ZWQoZWwpe1xuICAgIGxldCBwaHhNb3VudGVkID0gZWwuZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhQSFhfTU9VTlRFRCkpXG4gICAgbGV0IGhhc0JlZW5JbnZva2VkID0gcGh4TW91bnRlZCAmJiBET00ucHJpdmF0ZShlbCwgXCJtb3VudGVkXCIpXG4gICAgaWYocGh4TW91bnRlZCAmJiAhaGFzQmVlbkludm9rZWQpe1xuICAgICAgdGhpcy5saXZlU29ja2V0LmV4ZWNKUyhlbCwgcGh4TW91bnRlZClcbiAgICAgIERPTS5wdXRQcml2YXRlKGVsLCBcIm1vdW50ZWRcIiwgdHJ1ZSlcbiAgICB9XG4gIH1cblxuICBtYXliZUFkZE5ld0hvb2soZWwsIGZvcmNlKXtcbiAgICBsZXQgbmV3SG9vayA9IHRoaXMuYWRkSG9vayhlbClcbiAgICBpZihuZXdIb29rKXsgbmV3SG9vay5fX21vdW50ZWQoKSB9XG4gIH1cblxuICBwZXJmb3JtUGF0Y2gocGF0Y2gsIHBydW5lQ2lkcywgaXNKb2luUGF0Y2ggPSBmYWxzZSl7XG4gICAgbGV0IHJlbW92ZWRFbHMgPSBbXVxuICAgIGxldCBwaHhDaGlsZHJlbkFkZGVkID0gZmFsc2VcbiAgICBsZXQgdXBkYXRlZEhvb2tJZHMgPSBuZXcgU2V0KClcblxuICAgIHBhdGNoLmFmdGVyKFwiYWRkZWRcIiwgZWwgPT4ge1xuICAgICAgdGhpcy5saXZlU29ja2V0LnRyaWdnZXJET00oXCJvbk5vZGVBZGRlZFwiLCBbZWxdKVxuICAgICAgbGV0IHBoeFZpZXdwb3J0VG9wID0gdGhpcy5iaW5kaW5nKFBIWF9WSUVXUE9SVF9UT1ApXG4gICAgICBsZXQgcGh4Vmlld3BvcnRCb3R0b20gPSB0aGlzLmJpbmRpbmcoUEhYX1ZJRVdQT1JUX0JPVFRPTSlcbiAgICAgIERPTS5tYXliZUFkZFByaXZhdGVIb29rcyhlbCwgcGh4Vmlld3BvcnRUb3AsIHBoeFZpZXdwb3J0Qm90dG9tKVxuICAgICAgdGhpcy5tYXliZUFkZE5ld0hvb2soZWwpXG4gICAgICBpZihlbC5nZXRBdHRyaWJ1dGUpeyB0aGlzLm1heWJlTW91bnRlZChlbCkgfVxuICAgIH0pXG5cbiAgICBwYXRjaC5hZnRlcihcInBoeENoaWxkQWRkZWRcIiwgZWwgPT4ge1xuICAgICAgaWYoRE9NLmlzUGh4U3RpY2t5KGVsKSl7XG4gICAgICAgIHRoaXMubGl2ZVNvY2tldC5qb2luUm9vdFZpZXdzKClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBoeENoaWxkcmVuQWRkZWQgPSB0cnVlXG4gICAgICB9XG4gICAgfSlcblxuICAgIHBhdGNoLmJlZm9yZShcInVwZGF0ZWRcIiwgKGZyb21FbCwgdG9FbCkgPT4ge1xuICAgICAgbGV0IGhvb2sgPSB0aGlzLnRyaWdnZXJCZWZvcmVVcGRhdGVIb29rKGZyb21FbCwgdG9FbClcbiAgICAgIGlmKGhvb2speyB1cGRhdGVkSG9va0lkcy5hZGQoZnJvbUVsLmlkKSB9XG4gICAgfSlcblxuICAgIHBhdGNoLmFmdGVyKFwidXBkYXRlZFwiLCBlbCA9PiB7XG4gICAgICBpZih1cGRhdGVkSG9va0lkcy5oYXMoZWwuaWQpKXsgdGhpcy5nZXRIb29rKGVsKS5fX3VwZGF0ZWQoKSB9XG4gICAgfSlcblxuICAgIHBhdGNoLmFmdGVyKFwiZGlzY2FyZGVkXCIsIChlbCkgPT4ge1xuICAgICAgaWYoZWwubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKXsgcmVtb3ZlZEVscy5wdXNoKGVsKSB9XG4gICAgfSlcblxuICAgIHBhdGNoLmFmdGVyKFwidHJhbnNpdGlvbnNEaXNjYXJkZWRcIiwgZWxzID0+IHRoaXMuYWZ0ZXJFbGVtZW50c1JlbW92ZWQoZWxzLCBwcnVuZUNpZHMpKVxuICAgIHBhdGNoLnBlcmZvcm0oaXNKb2luUGF0Y2gpXG4gICAgdGhpcy5hZnRlckVsZW1lbnRzUmVtb3ZlZChyZW1vdmVkRWxzLCBwcnVuZUNpZHMpXG5cbiAgICByZXR1cm4gcGh4Q2hpbGRyZW5BZGRlZFxuICB9XG5cbiAgYWZ0ZXJFbGVtZW50c1JlbW92ZWQoZWxlbWVudHMsIHBydW5lQ2lkcyl7XG4gICAgbGV0IGRlc3Ryb3llZENJRHMgPSBbXVxuICAgIGVsZW1lbnRzLmZvckVhY2gocGFyZW50ID0+IHtcbiAgICAgIGxldCBjb21wb25lbnRzID0gRE9NLmFsbChwYXJlbnQsIGBbJHtQSFhfQ09NUE9ORU5UfV1gKVxuICAgICAgbGV0IGhvb2tzID0gRE9NLmFsbChwYXJlbnQsIGBbJHt0aGlzLmJpbmRpbmcoUEhYX0hPT0spfV1gKVxuICAgICAgY29tcG9uZW50cy5jb25jYXQocGFyZW50KS5mb3JFYWNoKGVsID0+IHtcbiAgICAgICAgbGV0IGNpZCA9IHRoaXMuY29tcG9uZW50SUQoZWwpXG4gICAgICAgIGlmKGlzQ2lkKGNpZCkgJiYgZGVzdHJveWVkQ0lEcy5pbmRleE9mKGNpZCkgPT09IC0xKXsgZGVzdHJveWVkQ0lEcy5wdXNoKGNpZCkgfVxuICAgICAgfSlcbiAgICAgIGhvb2tzLmNvbmNhdChwYXJlbnQpLmZvckVhY2goaG9va0VsID0+IHtcbiAgICAgICAgbGV0IGhvb2sgPSB0aGlzLmdldEhvb2soaG9va0VsKVxuICAgICAgICBob29rICYmIHRoaXMuZGVzdHJveUhvb2soaG9vaylcbiAgICAgIH0pXG4gICAgfSlcbiAgICAvLyBXZSBzaG91bGQgbm90IHBydW5lQ2lkcyBvbiBqb2lucy4gT3RoZXJ3aXNlLCBpbiBjYXNlIG9mXG4gICAgLy8gcmVqb2lucywgd2UgbWF5IG5vdGlmeSBjaWRzIHRoYXQgbm8gbG9uZ2VyIGJlbG9uZyB0byB0aGVcbiAgICAvLyBjdXJyZW50IExpdmVWaWV3IHRvIGJlIHJlbW92ZWQuXG4gICAgaWYocHJ1bmVDaWRzKXtcbiAgICAgIHRoaXMubWF5YmVQdXNoQ29tcG9uZW50c0Rlc3Ryb3llZChkZXN0cm95ZWRDSURzKVxuICAgIH1cbiAgfVxuXG4gIGpvaW5OZXdDaGlsZHJlbigpe1xuICAgIERPTS5maW5kUGh4Q2hpbGRyZW4odGhpcy5lbCwgdGhpcy5pZCkuZm9yRWFjaChlbCA9PiB0aGlzLmpvaW5DaGlsZChlbCkpXG4gIH1cblxuICBtYXliZVJlY292ZXJGb3JtcyhodG1sLCBjYWxsYmFjayl7XG4gICAgY29uc3QgcGh4Q2hhbmdlID0gdGhpcy5iaW5kaW5nKFwiY2hhbmdlXCIpXG4gICAgY29uc3Qgb2xkRm9ybXMgPSB0aGlzLnJvb3QuZm9ybXNGb3JSZWNvdmVyeVxuICAgIC8vIFNvIHdoeSBkbyB3ZSBjcmVhdGUgYSB0ZW1wbGF0ZSBlbGVtZW50IGhlcmU/XG4gICAgLy8gT25lIHdheSB0byByZWNvdmVyIGZvcm1zIHdvdWxkIGJlIHRvIGltbWVkaWF0ZWx5IGFwcGx5IHRoZSBtb3VudFxuICAgIC8vIHBhdGNoIGFuZCB0aGVuIGFmdGVyd2FyZHMgcmVjb3ZlciB0aGUgZm9ybXMuIEhvd2V2ZXIsIHRoaXMgd291bGRcbiAgICAvLyBjYXVzZSBhIGZsaWNrZXIsIGJlY2F1c2UgdGhlIG1vdW50IHBhdGNoIHdvdWxkIHJlbW92ZSB0aGUgZm9ybSBjb250ZW50XG4gICAgLy8gdW50aWwgaXQgaXMgcmVzdG9yZWQuIFRoZXJlZm9yZSBMViBkZWNpZGVkIHRvIGRvIGZvcm0gcmVjb3Zlcnkgd2l0aCB0aGVcbiAgICAvLyByYXcgSFRNTCBiZWZvcmUgaXQgaXMgYXBwbGllZCBhbmQgZGVsYXkgdGhlIG1vdW50IHBhdGNoIHVudGlsIHRoZSBmb3JtXG4gICAgLy8gcmVjb3ZlcnkgZXZlbnRzIGFyZSBkb25lLlxuICAgIGxldCB0ZW1wbGF0ZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ0ZW1wbGF0ZVwiKVxuICAgIHRlbXBsYXRlLmlubmVySFRNTCA9IGh0bWxcbiAgICAvLyBiZWNhdXNlIHdlIHdvcmsgd2l0aCBhIHRlbXBsYXRlIGVsZW1lbnQsIHdlIG11c3QgbWFudWFsbHkgY29weSB0aGUgYXR0cmlidXRlc1xuICAgIC8vIG90aGVyd2lzZSB0aGUgb3duZXIgLyB0YXJnZXQgaGVscGVycyBkb24ndCB3b3JrIHByb3Blcmx5XG4gICAgY29uc3Qgcm9vdEVsID0gdGVtcGxhdGUuY29udGVudC5maXJzdEVsZW1lbnRDaGlsZFxuICAgIHJvb3RFbC5pZCA9IHRoaXMuaWRcbiAgICByb290RWwuc2V0QXR0cmlidXRlKFBIWF9ST09UX0lELCB0aGlzLnJvb3QuaWQpXG4gICAgcm9vdEVsLnNldEF0dHJpYnV0ZShQSFhfU0VTU0lPTiwgdGhpcy5nZXRTZXNzaW9uKCkpXG4gICAgcm9vdEVsLnNldEF0dHJpYnV0ZShQSFhfU1RBVElDLCB0aGlzLmdldFN0YXRpYygpKVxuICAgIHJvb3RFbC5zZXRBdHRyaWJ1dGUoUEhYX1BBUkVOVF9JRCwgdGhpcy5wYXJlbnQgPyB0aGlzLnBhcmVudC5pZCA6IG51bGwpXG5cbiAgICAvLyB3ZSBnbyBvdmVyIGFsbCBmb3JtIGVsZW1lbnRzIGluIHRoZSBuZXcgSFRNTCBmb3IgdGhlIExWXG4gICAgLy8gYW5kIGxvb2sgZm9yIG9sZCBmb3JtcyBpbiB0aGUgYGZvcm1zRm9yUmVjb3ZlcnlgIG9iamVjdDtcbiAgICAvLyB0aGUgZm9ybXNGb3JSZWNvdmVyeSBjYW4gYWxzbyBjb250YWluIGZvcm1zIGZyb20gY2hpbGQgdmlld3NcbiAgICBjb25zdCBmb3Jtc1RvUmVjb3ZlciA9XG4gICAgICAvLyB3ZSBnbyBvdmVyIGFsbCBmb3JtcyBpbiB0aGUgbmV3IERPTTsgYmVjYXVzZSB0aGlzIGlzIG9ubHkgdGhlIEhUTUwgZm9yIHRoZSBjdXJyZW50XG4gICAgICAvLyB2aWV3LCB3ZSBjYW4gYmUgc3VyZSB0aGF0IGFsbCBmb3JtcyBhcmUgb3duZWQgYnkgdGhpcyB2aWV3OlxuICAgICAgRE9NLmFsbCh0ZW1wbGF0ZS5jb250ZW50LCBcImZvcm1cIilcbiAgICAgICAgLy8gb25seSByZWNvdmVyIGZvcm1zIHRoYXQgaGF2ZSBhbiBpZCBhbmQgYXJlIGluIHRoZSBvbGQgRE9NXG4gICAgICAgIC5maWx0ZXIobmV3Rm9ybSA9PiBuZXdGb3JtLmlkICYmIG9sZEZvcm1zW25ld0Zvcm0uaWRdKVxuICAgICAgICAvLyBhYmFuZG9uIGZvcm1zIHdlIGFscmVhZHkgdHJpZWQgdG8gcmVjb3ZlciB0byBwcmV2ZW50IGxvb3BpbmcgYSBmYWlsZWQgc3RhdGVcbiAgICAgICAgLmZpbHRlcihuZXdGb3JtID0+ICF0aGlzLnBlbmRpbmdGb3Jtcy5oYXMobmV3Rm9ybS5pZCkpXG4gICAgICAgIC8vIG9ubHkgcmVjb3ZlciBpZiB0aGUgZm9ybSBoYXMgdGhlIHNhbWUgcGh4LWNoYW5nZSB2YWx1ZVxuICAgICAgICAuZmlsdGVyKG5ld0Zvcm0gPT4gb2xkRm9ybXNbbmV3Rm9ybS5pZF0uZ2V0QXR0cmlidXRlKHBoeENoYW5nZSkgPT09IG5ld0Zvcm0uZ2V0QXR0cmlidXRlKHBoeENoYW5nZSkpXG4gICAgICAgIC5tYXAobmV3Rm9ybSA9PiB7XG4gICAgICAgICAgcmV0dXJuIFtvbGRGb3Jtc1tuZXdGb3JtLmlkXSwgbmV3Rm9ybV1cbiAgICAgICAgfSlcblxuICAgIGlmKGZvcm1zVG9SZWNvdmVyLmxlbmd0aCA9PT0gMCl7XG4gICAgICByZXR1cm4gY2FsbGJhY2soKVxuICAgIH1cblxuICAgIGZvcm1zVG9SZWNvdmVyLmZvckVhY2goKFtvbGRGb3JtLCBuZXdGb3JtXSwgaSkgPT4ge1xuICAgICAgdGhpcy5wZW5kaW5nRm9ybXMuYWRkKG5ld0Zvcm0uaWQpXG4gICAgICB0aGlzLnB1c2hGb3JtUmVjb3Zlcnkob2xkRm9ybSwgbmV3Rm9ybSwgdGVtcGxhdGUuY29udGVudCwgKCkgPT4ge1xuICAgICAgICB0aGlzLnBlbmRpbmdGb3Jtcy5kZWxldGUobmV3Rm9ybS5pZClcbiAgICAgICAgLy8gd2Ugb25seSBjYWxsIHRoZSBjYWxsYmFjayBvbmNlIGFsbCBmb3JtcyBoYXZlIGJlZW4gcmVjb3ZlcmVkXG4gICAgICAgIGlmKGkgPT09IGZvcm1zVG9SZWNvdmVyLmxlbmd0aCAtIDEpe1xuICAgICAgICAgIGNhbGxiYWNrKClcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgZ2V0Q2hpbGRCeUlkKGlkKXsgcmV0dXJuIHRoaXMucm9vdC5jaGlsZHJlblt0aGlzLmlkXVtpZF0gfVxuXG4gIGdldERlc2NlbmRlbnRCeUVsKGVsKXtcbiAgICBpZihlbC5pZCA9PT0gdGhpcy5pZCl7XG4gICAgICByZXR1cm4gdGhpc1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5jaGlsZHJlbltlbC5nZXRBdHRyaWJ1dGUoUEhYX1BBUkVOVF9JRCldW2VsLmlkXVxuICAgIH1cbiAgfVxuXG4gIGRlc3Ryb3lEZXNjZW5kZW50KGlkKXtcbiAgICBmb3IobGV0IHBhcmVudElkIGluIHRoaXMucm9vdC5jaGlsZHJlbil7XG4gICAgICBmb3IobGV0IGNoaWxkSWQgaW4gdGhpcy5yb290LmNoaWxkcmVuW3BhcmVudElkXSl7XG4gICAgICAgIGlmKGNoaWxkSWQgPT09IGlkKXsgcmV0dXJuIHRoaXMucm9vdC5jaGlsZHJlbltwYXJlbnRJZF1bY2hpbGRJZF0uZGVzdHJveSgpIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBqb2luQ2hpbGQoZWwpe1xuICAgIGxldCBjaGlsZCA9IHRoaXMuZ2V0Q2hpbGRCeUlkKGVsLmlkKVxuICAgIGlmKCFjaGlsZCl7XG4gICAgICBsZXQgdmlldyA9IG5ldyBWaWV3KGVsLCB0aGlzLmxpdmVTb2NrZXQsIHRoaXMpXG4gICAgICB0aGlzLnJvb3QuY2hpbGRyZW5bdGhpcy5pZF1bdmlldy5pZF0gPSB2aWV3XG4gICAgICB2aWV3LmpvaW4oKVxuICAgICAgdGhpcy5jaGlsZEpvaW5zKytcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG5cbiAgaXNKb2luUGVuZGluZygpeyByZXR1cm4gdGhpcy5qb2luUGVuZGluZyB9XG5cbiAgYWNrSm9pbihfY2hpbGQpe1xuICAgIHRoaXMuY2hpbGRKb2lucy0tXG5cbiAgICBpZih0aGlzLmNoaWxkSm9pbnMgPT09IDApe1xuICAgICAgaWYodGhpcy5wYXJlbnQpe1xuICAgICAgICB0aGlzLnBhcmVudC5hY2tKb2luKHRoaXMpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm9uQWxsQ2hpbGRKb2luc0NvbXBsZXRlKClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBvbkFsbENoaWxkSm9pbnNDb21wbGV0ZSgpe1xuICAgIC8vIHdlIGNhbiBjbGVhciBwZW5kaW5nIGZvcm0gcmVjb3ZlcmllcyBub3cgdGhhdCB3ZSd2ZSBqb2luZWQuXG4gICAgLy8gVGhleSBlaXRoZXIgYWxsIHJlc29sdmVkIG9yIHdlcmUgYWJhbmRvbmVkXG4gICAgdGhpcy5wZW5kaW5nRm9ybXMuY2xlYXIoKVxuICAgIC8vIHdlIGNhbiBhbHNvIGNsZWFyIHRoZSBmb3Jtc0ZvclJlY292ZXJ5IG9iamVjdCB0byBub3Qga2VlcCBvbGQgZm9ybSBlbGVtZW50cyBhcm91bmRcbiAgICB0aGlzLmZvcm1zRm9yUmVjb3ZlcnkgPSB7fVxuICAgIHRoaXMuam9pbkNhbGxiYWNrKCgpID0+IHtcbiAgICAgIHRoaXMucGVuZGluZ0pvaW5PcHMuZm9yRWFjaCgoW3ZpZXcsIG9wXSkgPT4ge1xuICAgICAgICBpZighdmlldy5pc0Rlc3Ryb3llZCgpKXsgb3AoKSB9XG4gICAgICB9KVxuICAgICAgdGhpcy5wZW5kaW5nSm9pbk9wcyA9IFtdXG4gICAgfSlcbiAgfVxuXG4gIHVwZGF0ZShkaWZmLCBldmVudHMpe1xuICAgIGlmKHRoaXMuaXNKb2luUGVuZGluZygpIHx8ICh0aGlzLmxpdmVTb2NrZXQuaGFzUGVuZGluZ0xpbmsoKSAmJiB0aGlzLnJvb3QuaXNNYWluKCkpKXtcbiAgICAgIHJldHVybiB0aGlzLnBlbmRpbmdEaWZmcy5wdXNoKHtkaWZmLCBldmVudHN9KVxuICAgIH1cblxuICAgIHRoaXMucmVuZGVyZWQubWVyZ2VEaWZmKGRpZmYpXG4gICAgbGV0IHBoeENoaWxkcmVuQWRkZWQgPSBmYWxzZVxuXG4gICAgLy8gV2hlbiB0aGUgZGlmZiBvbmx5IGNvbnRhaW5zIGNvbXBvbmVudCBkaWZmcywgdGhlbiB3YWxrIGNvbXBvbmVudHNcbiAgICAvLyBhbmQgcGF0Y2ggb25seSB0aGUgcGFyZW50IGNvbXBvbmVudCBjb250YWluZXJzIGZvdW5kIGluIHRoZSBkaWZmLlxuICAgIC8vIE90aGVyd2lzZSwgcGF0Y2ggZW50aXJlIExWIGNvbnRhaW5lci5cbiAgICBpZih0aGlzLnJlbmRlcmVkLmlzQ29tcG9uZW50T25seURpZmYoZGlmZikpe1xuICAgICAgdGhpcy5saXZlU29ja2V0LnRpbWUoXCJjb21wb25lbnQgcGF0Y2ggY29tcGxldGVcIiwgKCkgPT4ge1xuICAgICAgICBsZXQgcGFyZW50Q2lkcyA9IERPTS5maW5kRXhpc3RpbmdQYXJlbnRDSURzKHRoaXMuZWwsIHRoaXMucmVuZGVyZWQuY29tcG9uZW50Q0lEcyhkaWZmKSlcbiAgICAgICAgcGFyZW50Q2lkcy5mb3JFYWNoKHBhcmVudENJRCA9PiB7XG4gICAgICAgICAgaWYodGhpcy5jb21wb25lbnRQYXRjaCh0aGlzLnJlbmRlcmVkLmdldENvbXBvbmVudChkaWZmLCBwYXJlbnRDSUQpLCBwYXJlbnRDSUQpKXsgcGh4Q2hpbGRyZW5BZGRlZCA9IHRydWUgfVxuICAgICAgICB9KVxuICAgICAgfSlcbiAgICB9IGVsc2UgaWYoIWlzRW1wdHkoZGlmZikpe1xuICAgICAgdGhpcy5saXZlU29ja2V0LnRpbWUoXCJmdWxsIHBhdGNoIGNvbXBsZXRlXCIsICgpID0+IHtcbiAgICAgICAgbGV0IFtodG1sLCBzdHJlYW1zXSA9IHRoaXMucmVuZGVyQ29udGFpbmVyKGRpZmYsIFwidXBkYXRlXCIpXG4gICAgICAgIGxldCBwYXRjaCA9IG5ldyBET01QYXRjaCh0aGlzLCB0aGlzLmVsLCB0aGlzLmlkLCBodG1sLCBzdHJlYW1zLCBudWxsKVxuICAgICAgICBwaHhDaGlsZHJlbkFkZGVkID0gdGhpcy5wZXJmb3JtUGF0Y2gocGF0Y2gsIHRydWUpXG4gICAgICB9KVxuICAgIH1cblxuICAgIHRoaXMubGl2ZVNvY2tldC5kaXNwYXRjaEV2ZW50cyhldmVudHMpXG4gICAgaWYocGh4Q2hpbGRyZW5BZGRlZCl7IHRoaXMuam9pbk5ld0NoaWxkcmVuKCkgfVxuICB9XG5cbiAgcmVuZGVyQ29udGFpbmVyKGRpZmYsIGtpbmQpe1xuICAgIHJldHVybiB0aGlzLmxpdmVTb2NrZXQudGltZShgdG9TdHJpbmcgZGlmZiAoJHtraW5kfSlgLCAoKSA9PiB7XG4gICAgICBsZXQgdGFnID0gdGhpcy5lbC50YWdOYW1lXG4gICAgICAvLyBEb24ndCBza2lwIGFueSBjb21wb25lbnQgaW4gdGhlIGRpZmYgbm9yIGFueSBtYXJrZWQgYXMgcHJ1bmVkXG4gICAgICAvLyAoYXMgdGhleSBtYXkgaGF2ZSBiZWVuIGFkZGVkIGJhY2spXG4gICAgICBsZXQgY2lkcyA9IGRpZmYgPyB0aGlzLnJlbmRlcmVkLmNvbXBvbmVudENJRHMoZGlmZikgOiBudWxsXG4gICAgICBsZXQgW2h0bWwsIHN0cmVhbXNdID0gdGhpcy5yZW5kZXJlZC50b1N0cmluZyhjaWRzKVxuICAgICAgcmV0dXJuIFtgPCR7dGFnfT4ke2h0bWx9PC8ke3RhZ30+YCwgc3RyZWFtc11cbiAgICB9KVxuICB9XG5cbiAgY29tcG9uZW50UGF0Y2goZGlmZiwgY2lkKXtcbiAgICBpZihpc0VtcHR5KGRpZmYpKSByZXR1cm4gZmFsc2VcbiAgICBsZXQgW2h0bWwsIHN0cmVhbXNdID0gdGhpcy5yZW5kZXJlZC5jb21wb25lbnRUb1N0cmluZyhjaWQpXG4gICAgbGV0IHBhdGNoID0gbmV3IERPTVBhdGNoKHRoaXMsIHRoaXMuZWwsIHRoaXMuaWQsIGh0bWwsIHN0cmVhbXMsIGNpZClcbiAgICBsZXQgY2hpbGRyZW5BZGRlZCA9IHRoaXMucGVyZm9ybVBhdGNoKHBhdGNoLCB0cnVlKVxuICAgIHJldHVybiBjaGlsZHJlbkFkZGVkXG4gIH1cblxuICBnZXRIb29rKGVsKXsgcmV0dXJuIHRoaXMudmlld0hvb2tzW1ZpZXdIb29rLmVsZW1lbnRJRChlbCldIH1cblxuICBhZGRIb29rKGVsKXtcbiAgICBpZihWaWV3SG9vay5lbGVtZW50SUQoZWwpIHx8ICFlbC5nZXRBdHRyaWJ1dGUpeyByZXR1cm4gfVxuICAgIGxldCBob29rTmFtZSA9IGVsLmdldEF0dHJpYnV0ZShgZGF0YS1waHgtJHtQSFhfSE9PS31gKSB8fCBlbC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFBIWF9IT09LKSlcbiAgICBpZihob29rTmFtZSAmJiAhdGhpcy5vd25zRWxlbWVudChlbCkpeyByZXR1cm4gfVxuICAgIGxldCBjYWxsYmFja3MgPSB0aGlzLmxpdmVTb2NrZXQuZ2V0SG9va0NhbGxiYWNrcyhob29rTmFtZSlcblxuICAgIGlmKGNhbGxiYWNrcyl7XG4gICAgICBpZighZWwuaWQpeyBsb2dFcnJvcihgbm8gRE9NIElEIGZvciBob29rIFwiJHtob29rTmFtZX1cIi4gSG9va3MgcmVxdWlyZSBhIHVuaXF1ZSBJRCBvbiBlYWNoIGVsZW1lbnQuYCwgZWwpIH1cbiAgICAgIGxldCBob29rID0gbmV3IFZpZXdIb29rKHRoaXMsIGVsLCBjYWxsYmFja3MpXG4gICAgICB0aGlzLnZpZXdIb29rc1tWaWV3SG9vay5lbGVtZW50SUQoaG9vay5lbCldID0gaG9va1xuICAgICAgcmV0dXJuIGhvb2tcbiAgICB9IGVsc2UgaWYoaG9va05hbWUgIT09IG51bGwpe1xuICAgICAgbG9nRXJyb3IoYHVua25vd24gaG9vayBmb3VuZCBmb3IgXCIke2hvb2tOYW1lfVwiYCwgZWwpXG4gICAgfVxuICB9XG5cbiAgZGVzdHJveUhvb2soaG9vayl7XG4gICAgaG9vay5fX2Rlc3Ryb3llZCgpXG4gICAgaG9vay5fX2NsZWFudXBfXygpXG4gICAgZGVsZXRlIHRoaXMudmlld0hvb2tzW1ZpZXdIb29rLmVsZW1lbnRJRChob29rLmVsKV1cbiAgfVxuXG4gIGFwcGx5UGVuZGluZ1VwZGF0ZXMoKXtcbiAgICB0aGlzLnBlbmRpbmdEaWZmcy5mb3JFYWNoKCh7ZGlmZiwgZXZlbnRzfSkgPT4gdGhpcy51cGRhdGUoZGlmZiwgZXZlbnRzKSlcbiAgICB0aGlzLnBlbmRpbmdEaWZmcyA9IFtdXG4gICAgdGhpcy5lYWNoQ2hpbGQoY2hpbGQgPT4gY2hpbGQuYXBwbHlQZW5kaW5nVXBkYXRlcygpKVxuICB9XG5cbiAgZWFjaENoaWxkKGNhbGxiYWNrKXtcbiAgICBsZXQgY2hpbGRyZW4gPSB0aGlzLnJvb3QuY2hpbGRyZW5bdGhpcy5pZF0gfHwge31cbiAgICBmb3IobGV0IGlkIGluIGNoaWxkcmVuKXsgY2FsbGJhY2sodGhpcy5nZXRDaGlsZEJ5SWQoaWQpKSB9XG4gIH1cblxuICBvbkNoYW5uZWwoZXZlbnQsIGNiKXtcbiAgICB0aGlzLmxpdmVTb2NrZXQub25DaGFubmVsKHRoaXMuY2hhbm5lbCwgZXZlbnQsIHJlc3AgPT4ge1xuICAgICAgaWYodGhpcy5pc0pvaW5QZW5kaW5nKCkpe1xuICAgICAgICB0aGlzLnJvb3QucGVuZGluZ0pvaW5PcHMucHVzaChbdGhpcywgKCkgPT4gY2IocmVzcCldKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5saXZlU29ja2V0LnJlcXVlc3RET01VcGRhdGUoKCkgPT4gY2IocmVzcCkpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIGJpbmRDaGFubmVsKCl7XG4gICAgLy8gVGhlIGRpZmYgZXZlbnQgc2hvdWxkIGJlIGhhbmRsZWQgYnkgdGhlIHJlZ3VsYXIgdXBkYXRlIG9wZXJhdGlvbnMuXG4gICAgLy8gQWxsIG90aGVyIG9wZXJhdGlvbnMgYXJlIHF1ZXVlZCB0byBiZSBhcHBsaWVkIG9ubHkgYWZ0ZXIgam9pbi5cbiAgICB0aGlzLmxpdmVTb2NrZXQub25DaGFubmVsKHRoaXMuY2hhbm5lbCwgXCJkaWZmXCIsIChyYXdEaWZmKSA9PiB7XG4gICAgICB0aGlzLmxpdmVTb2NrZXQucmVxdWVzdERPTVVwZGF0ZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuYXBwbHlEaWZmKFwidXBkYXRlXCIsIHJhd0RpZmYsICh7ZGlmZiwgZXZlbnRzfSkgPT4gdGhpcy51cGRhdGUoZGlmZiwgZXZlbnRzKSlcbiAgICAgIH0pXG4gICAgfSlcbiAgICB0aGlzLm9uQ2hhbm5lbChcInJlZGlyZWN0XCIsICh7dG8sIGZsYXNofSkgPT4gdGhpcy5vblJlZGlyZWN0KHt0bywgZmxhc2h9KSlcbiAgICB0aGlzLm9uQ2hhbm5lbChcImxpdmVfcGF0Y2hcIiwgKHJlZGlyKSA9PiB0aGlzLm9uTGl2ZVBhdGNoKHJlZGlyKSlcbiAgICB0aGlzLm9uQ2hhbm5lbChcImxpdmVfcmVkaXJlY3RcIiwgKHJlZGlyKSA9PiB0aGlzLm9uTGl2ZVJlZGlyZWN0KHJlZGlyKSlcbiAgICB0aGlzLmNoYW5uZWwub25FcnJvcihyZWFzb24gPT4gdGhpcy5vbkVycm9yKHJlYXNvbikpXG4gICAgdGhpcy5jaGFubmVsLm9uQ2xvc2UocmVhc29uID0+IHRoaXMub25DbG9zZShyZWFzb24pKVxuICB9XG5cbiAgZGVzdHJveUFsbENoaWxkcmVuKCl7IHRoaXMuZWFjaENoaWxkKGNoaWxkID0+IGNoaWxkLmRlc3Ryb3koKSkgfVxuXG4gIG9uTGl2ZVJlZGlyZWN0KHJlZGlyKXtcbiAgICBsZXQge3RvLCBraW5kLCBmbGFzaH0gPSByZWRpclxuICAgIGxldCB1cmwgPSB0aGlzLmV4cGFuZFVSTCh0bylcbiAgICB0aGlzLmxpdmVTb2NrZXQuaGlzdG9yeVJlZGlyZWN0KHVybCwga2luZCwgZmxhc2gpXG4gIH1cblxuICBvbkxpdmVQYXRjaChyZWRpcil7XG4gICAgbGV0IHt0bywga2luZH0gPSByZWRpclxuICAgIHRoaXMuaHJlZiA9IHRoaXMuZXhwYW5kVVJMKHRvKVxuICAgIHRoaXMubGl2ZVNvY2tldC5oaXN0b3J5UGF0Y2godG8sIGtpbmQpXG4gIH1cblxuICBleHBhbmRVUkwodG8pe1xuICAgIHJldHVybiB0by5zdGFydHNXaXRoKFwiL1wiKSA/IGAke3dpbmRvdy5sb2NhdGlvbi5wcm90b2NvbH0vLyR7d2luZG93LmxvY2F0aW9uLmhvc3R9JHt0b31gIDogdG9cbiAgfVxuXG4gIG9uUmVkaXJlY3Qoe3RvLCBmbGFzaH0peyB0aGlzLmxpdmVTb2NrZXQucmVkaXJlY3QodG8sIGZsYXNoKSB9XG5cbiAgaXNEZXN0cm95ZWQoKXsgcmV0dXJuIHRoaXMuZGVzdHJveWVkIH1cblxuICBqb2luRGVhZCgpeyB0aGlzLmlzRGVhZCA9IHRydWUgfVxuXG4gIGpvaW4oY2FsbGJhY2spe1xuICAgIHRoaXMuc2hvd0xvYWRlcih0aGlzLmxpdmVTb2NrZXQubG9hZGVyVGltZW91dClcbiAgICB0aGlzLmJpbmRDaGFubmVsKClcbiAgICBpZih0aGlzLmlzTWFpbigpKXtcbiAgICAgIHRoaXMuc3RvcENhbGxiYWNrID0gdGhpcy5saXZlU29ja2V0LndpdGhQYWdlTG9hZGluZyh7dG86IHRoaXMuaHJlZiwga2luZDogXCJpbml0aWFsXCJ9KVxuICAgIH1cbiAgICB0aGlzLmpvaW5DYWxsYmFjayA9IChvbkRvbmUpID0+IHtcbiAgICAgIG9uRG9uZSA9IG9uRG9uZSB8fCBmdW5jdGlvbigpe31cbiAgICAgIGNhbGxiYWNrID8gY2FsbGJhY2sodGhpcy5qb2luQ291bnQsIG9uRG9uZSkgOiBvbkRvbmUoKVxuICAgIH1cbiAgICB0aGlzLmxpdmVTb2NrZXQud3JhcFB1c2godGhpcywge3RpbWVvdXQ6IGZhbHNlfSwgKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuY2hhbm5lbC5qb2luKClcbiAgICAgICAgLnJlY2VpdmUoXCJva1wiLCBkYXRhID0+IHtcbiAgICAgICAgICBpZighdGhpcy5pc0Rlc3Ryb3llZCgpKXtcbiAgICAgICAgICAgIHRoaXMubGl2ZVNvY2tldC5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IHRoaXMub25Kb2luKGRhdGEpKVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLnJlY2VpdmUoXCJlcnJvclwiLCByZXNwID0+ICF0aGlzLmlzRGVzdHJveWVkKCkgJiYgdGhpcy5vbkpvaW5FcnJvcihyZXNwKSlcbiAgICAgICAgLnJlY2VpdmUoXCJ0aW1lb3V0XCIsICgpID0+ICF0aGlzLmlzRGVzdHJveWVkKCkgJiYgdGhpcy5vbkpvaW5FcnJvcih7cmVhc29uOiBcInRpbWVvdXRcIn0pKVxuICAgIH0pXG4gIH1cblxuICBvbkpvaW5FcnJvcihyZXNwKXtcbiAgICBpZihyZXNwLnJlYXNvbiA9PT0gXCJyZWxvYWRcIil7XG4gICAgICB0aGlzLmxvZyhcImVycm9yXCIsICgpID0+IFtgZmFpbGVkIG1vdW50IHdpdGggJHtyZXNwLnN0YXR1c30uIEZhbGxpbmcgYmFjayB0byBwYWdlIHJlcXVlc3RgLCByZXNwXSlcbiAgICAgIGlmKHRoaXMuaXNNYWluKCkpeyB0aGlzLm9uUmVkaXJlY3Qoe3RvOiB0aGlzLmhyZWZ9KSB9XG4gICAgICByZXR1cm5cbiAgICB9IGVsc2UgaWYocmVzcC5yZWFzb24gPT09IFwidW5hdXRob3JpemVkXCIgfHwgcmVzcC5yZWFzb24gPT09IFwic3RhbGVcIil7XG4gICAgICB0aGlzLmxvZyhcImVycm9yXCIsICgpID0+IFtcInVuYXV0aG9yaXplZCBsaXZlX3JlZGlyZWN0LiBGYWxsaW5nIGJhY2sgdG8gcGFnZSByZXF1ZXN0XCIsIHJlc3BdKVxuICAgICAgaWYodGhpcy5pc01haW4oKSl7IHRoaXMub25SZWRpcmVjdCh7dG86IHRoaXMuaHJlZn0pIH1cbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBpZihyZXNwLnJlZGlyZWN0IHx8IHJlc3AubGl2ZV9yZWRpcmVjdCl7XG4gICAgICB0aGlzLmpvaW5QZW5kaW5nID0gZmFsc2VcbiAgICAgIHRoaXMuY2hhbm5lbC5sZWF2ZSgpXG4gICAgfVxuICAgIGlmKHJlc3AucmVkaXJlY3QpeyByZXR1cm4gdGhpcy5vblJlZGlyZWN0KHJlc3AucmVkaXJlY3QpIH1cbiAgICBpZihyZXNwLmxpdmVfcmVkaXJlY3QpeyByZXR1cm4gdGhpcy5vbkxpdmVSZWRpcmVjdChyZXNwLmxpdmVfcmVkaXJlY3QpIH1cbiAgICB0aGlzLmRpc3BsYXlFcnJvcihbUEhYX0xPQURJTkdfQ0xBU1MsIFBIWF9FUlJPUl9DTEFTUywgUEhYX1NFUlZFUl9FUlJPUl9DTEFTU10pXG4gICAgdGhpcy5sb2coXCJlcnJvclwiLCAoKSA9PiBbXCJ1bmFibGUgdG8gam9pblwiLCByZXNwXSlcbiAgICBpZih0aGlzLmxpdmVTb2NrZXQuaXNDb25uZWN0ZWQoKSl7IHRoaXMubGl2ZVNvY2tldC5yZWxvYWRXaXRoSml0dGVyKHRoaXMpIH1cbiAgfVxuXG4gIG9uQ2xvc2UocmVhc29uKXtcbiAgICBpZih0aGlzLmlzRGVzdHJveWVkKCkpeyByZXR1cm4gfVxuICAgIGlmKHRoaXMubGl2ZVNvY2tldC5oYXNQZW5kaW5nTGluaygpICYmIHJlYXNvbiAhPT0gXCJsZWF2ZVwiKXtcbiAgICAgIHJldHVybiB0aGlzLmxpdmVTb2NrZXQucmVsb2FkV2l0aEppdHRlcih0aGlzKVxuICAgIH1cbiAgICB0aGlzLmRlc3Ryb3lBbGxDaGlsZHJlbigpXG4gICAgdGhpcy5saXZlU29ja2V0LmRyb3BBY3RpdmVFbGVtZW50KHRoaXMpXG4gICAgLy8gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCBjYW4gYmUgbnVsbCBpbiBJbnRlcm5ldCBFeHBsb3JlciAxMVxuICAgIGlmKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpeyBkb2N1bWVudC5hY3RpdmVFbGVtZW50LmJsdXIoKSB9XG4gICAgaWYodGhpcy5saXZlU29ja2V0LmlzVW5sb2FkZWQoKSl7XG4gICAgICB0aGlzLnNob3dMb2FkZXIoQkVGT1JFX1VOTE9BRF9MT0FERVJfVElNRU9VVClcbiAgICB9XG4gIH1cblxuICBvbkVycm9yKHJlYXNvbil7XG4gICAgdGhpcy5vbkNsb3NlKHJlYXNvbilcbiAgICBpZih0aGlzLmxpdmVTb2NrZXQuaXNDb25uZWN0ZWQoKSl7IHRoaXMubG9nKFwiZXJyb3JcIiwgKCkgPT4gW1widmlldyBjcmFzaGVkXCIsIHJlYXNvbl0pIH1cbiAgICBpZighdGhpcy5saXZlU29ja2V0LmlzVW5sb2FkZWQoKSl7XG4gICAgICBpZih0aGlzLmxpdmVTb2NrZXQuaXNDb25uZWN0ZWQoKSl7XG4gICAgICAgIHRoaXMuZGlzcGxheUVycm9yKFtQSFhfTE9BRElOR19DTEFTUywgUEhYX0VSUk9SX0NMQVNTLCBQSFhfU0VSVkVSX0VSUk9SX0NMQVNTXSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZGlzcGxheUVycm9yKFtQSFhfTE9BRElOR19DTEFTUywgUEhYX0VSUk9SX0NMQVNTLCBQSFhfQ0xJRU5UX0VSUk9SX0NMQVNTXSlcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBkaXNwbGF5RXJyb3IoY2xhc3Nlcyl7XG4gICAgaWYodGhpcy5pc01haW4oKSl7IERPTS5kaXNwYXRjaEV2ZW50KHdpbmRvdywgXCJwaHg6cGFnZS1sb2FkaW5nLXN0YXJ0XCIsIHtkZXRhaWw6IHt0bzogdGhpcy5ocmVmLCBraW5kOiBcImVycm9yXCJ9fSkgfVxuICAgIHRoaXMuc2hvd0xvYWRlcigpXG4gICAgdGhpcy5zZXRDb250YWluZXJDbGFzc2VzKC4uLmNsYXNzZXMpXG4gICAgdGhpcy5leGVjQWxsKHRoaXMuYmluZGluZyhcImRpc2Nvbm5lY3RlZFwiKSlcbiAgfVxuXG4gIHB1c2hXaXRoUmVwbHkocmVmR2VuZXJhdG9yLCBldmVudCwgcGF5bG9hZCwgb25SZXBseSA9IGZ1bmN0aW9uICgpeyB9KXtcbiAgICBpZighdGhpcy5pc0Nvbm5lY3RlZCgpKXsgcmV0dXJuIH1cblxuICAgIGxldCBbcmVmLCBbZWxdLCBvcHRzXSA9IHJlZkdlbmVyYXRvciA/IHJlZkdlbmVyYXRvcigpIDogW251bGwsIFtdLCB7fV1cbiAgICBsZXQgb25Mb2FkaW5nRG9uZSA9IGZ1bmN0aW9uKCl7IH1cbiAgICBpZihvcHRzLnBhZ2VfbG9hZGluZyB8fCAoZWwgJiYgKGVsLmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoUEhYX1BBR0VfTE9BRElORykpICE9PSBudWxsKSkpe1xuICAgICAgb25Mb2FkaW5nRG9uZSA9IHRoaXMubGl2ZVNvY2tldC53aXRoUGFnZUxvYWRpbmcoe2tpbmQ6IFwiZWxlbWVudFwiLCB0YXJnZXQ6IGVsfSlcbiAgICB9XG5cbiAgICBpZih0eXBlb2YgKHBheWxvYWQuY2lkKSAhPT0gXCJudW1iZXJcIil7IGRlbGV0ZSBwYXlsb2FkLmNpZCB9XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMubGl2ZVNvY2tldC53cmFwUHVzaCh0aGlzLCB7dGltZW91dDogdHJ1ZX0sICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hhbm5lbC5wdXNoKGV2ZW50LCBwYXlsb2FkLCBQVVNIX1RJTUVPVVQpLnJlY2VpdmUoXCJva1wiLCByZXNwID0+IHtcbiAgICAgICAgICBsZXQgZmluaXNoID0gKGhvb2tSZXBseSkgPT4ge1xuICAgICAgICAgICAgaWYocmVzcC5yZWRpcmVjdCl7IHRoaXMub25SZWRpcmVjdChyZXNwLnJlZGlyZWN0KSB9XG4gICAgICAgICAgICBpZihyZXNwLmxpdmVfcGF0Y2gpeyB0aGlzLm9uTGl2ZVBhdGNoKHJlc3AubGl2ZV9wYXRjaCkgfVxuICAgICAgICAgICAgaWYocmVzcC5saXZlX3JlZGlyZWN0KXsgdGhpcy5vbkxpdmVSZWRpcmVjdChyZXNwLmxpdmVfcmVkaXJlY3QpIH1cbiAgICAgICAgICAgIG9uTG9hZGluZ0RvbmUoKVxuICAgICAgICAgICAgb25SZXBseShyZXNwLCBob29rUmVwbHkpXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmKHJlc3AuZGlmZil7XG4gICAgICAgICAgICB0aGlzLmxpdmVTb2NrZXQucmVxdWVzdERPTVVwZGF0ZSgoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuYXBwbHlEaWZmKFwidXBkYXRlXCIsIHJlc3AuZGlmZiwgKHtkaWZmLCByZXBseSwgZXZlbnRzfSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmKHJlZiAhPT0gbnVsbCl7IHRoaXMudW5kb1JlZnMocmVmKSB9XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGUoZGlmZiwgZXZlbnRzKVxuICAgICAgICAgICAgICAgIGZpbmlzaChyZXBseSlcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmKHJlZiAhPT0gbnVsbCl7IHRoaXMudW5kb1JlZnMocmVmKSB9XG4gICAgICAgICAgICBmaW5pc2gobnVsbClcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9KVxuICAgIClcbiAgfVxuXG4gIHVuZG9SZWZzKHJlZiwgb25seUVscyl7XG4gICAgb25seUVscyA9IG9ubHlFbHMgPyBuZXcgU2V0KG9ubHlFbHMpIDogbnVsbFxuICAgIGlmKCF0aGlzLmlzQ29ubmVjdGVkKCkpeyByZXR1cm4gfSAvLyBleGl0IGlmIGV4dGVybmFsIGZvcm0gdHJpZ2dlcmVkXG5cbiAgICBET00uYWxsKGRvY3VtZW50LCBgWyR7UEhYX1JFRl9TUkN9PVwiJHt0aGlzLmlkfVwiXVske1BIWF9SRUZ9PVwiJHtyZWZ9XCJdYCwgZWwgPT4ge1xuICAgICAgaWYob25seUVscyAmJiAhb25seUVscy5oYXMoZWwpKXsgcmV0dXJuIH1cblxuICAgICAgZWwuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJwaHg6dW5sb2NrXCIsIHtidWJibGVzOiB0cnVlLCBjYW5jZWxhYmxlOiBmYWxzZX0pKVxuICAgICAgbGV0IGRpc2FibGVkVmFsID0gZWwuZ2V0QXR0cmlidXRlKFBIWF9ESVNBQkxFRClcbiAgICAgIGxldCByZWFkT25seVZhbCA9IGVsLmdldEF0dHJpYnV0ZShQSFhfUkVBRE9OTFkpXG4gICAgICAvLyByZW1vdmUgcmVmc1xuICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKFBIWF9SRUYpXG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFRl9TUkMpXG4gICAgICAvLyByZXN0b3JlIGlucHV0c1xuICAgICAgaWYocmVhZE9ubHlWYWwgIT09IG51bGwpe1xuICAgICAgICBlbC5yZWFkT25seSA9IHJlYWRPbmx5VmFsID09PSBcInRydWVcIiA/IHRydWUgOiBmYWxzZVxuICAgICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX1JFQURPTkxZKVxuICAgICAgfVxuICAgICAgaWYoZGlzYWJsZWRWYWwgIT09IG51bGwpe1xuICAgICAgICBlbC5kaXNhYmxlZCA9IGRpc2FibGVkVmFsID09PSBcInRydWVcIiA/IHRydWUgOiBmYWxzZVxuICAgICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoUEhYX0RJU0FCTEVEKVxuICAgICAgfVxuICAgICAgLy8gcmVtb3ZlIGNsYXNzZXNcbiAgICAgIFBIWF9FVkVOVF9DTEFTU0VTLmZvckVhY2goY2xhc3NOYW1lID0+IERPTS5yZW1vdmVDbGFzcyhlbCwgY2xhc3NOYW1lKSlcbiAgICAgIC8vIHJlc3RvcmUgZGlzYWJsZXNcbiAgICAgIGxldCBkaXNhYmxlUmVzdG9yZSA9IGVsLmdldEF0dHJpYnV0ZShQSFhfRElTQUJMRV9XSVRIX1JFU1RPUkUpXG4gICAgICBpZihkaXNhYmxlUmVzdG9yZSAhPT0gbnVsbCl7XG4gICAgICAgIGVsLmlubmVyVGV4dCA9IGRpc2FibGVSZXN0b3JlXG4gICAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShQSFhfRElTQUJMRV9XSVRIX1JFU1RPUkUpXG4gICAgICB9XG4gICAgICBsZXQgdG9FbCA9IERPTS5wcml2YXRlKGVsLCBQSFhfUkVGKVxuICAgICAgaWYodG9FbCl7XG4gICAgICAgIGxldCBob29rID0gdGhpcy50cmlnZ2VyQmVmb3JlVXBkYXRlSG9vayhlbCwgdG9FbClcbiAgICAgICAgRE9NUGF0Y2gucGF0Y2hFbChlbCwgdG9FbCwgdGhpcy5saXZlU29ja2V0LmdldEFjdGl2ZUVsZW1lbnQoKSlcbiAgICAgICAgaWYoaG9vayl7IGhvb2suX191cGRhdGVkKCkgfVxuICAgICAgICBET00uZGVsZXRlUHJpdmF0ZShlbCwgUEhYX1JFRilcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgcHV0UmVmKGVsZW1lbnRzLCBldmVudCwgb3B0cyA9IHt9KXtcbiAgICBsZXQgbmV3UmVmID0gdGhpcy5yZWYrK1xuICAgIGxldCBkaXNhYmxlV2l0aCA9IHRoaXMuYmluZGluZyhQSFhfRElTQUJMRV9XSVRIKVxuICAgIGlmKG9wdHMubG9hZGluZyl7IGVsZW1lbnRzID0gZWxlbWVudHMuY29uY2F0KERPTS5hbGwoZG9jdW1lbnQsIG9wdHMubG9hZGluZykpfVxuXG4gICAgZm9yKGxldCBlbCBvZiBlbGVtZW50cyl7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoUEhYX1JFRiwgbmV3UmVmKVxuICAgICAgZWwuc2V0QXR0cmlidXRlKFBIWF9SRUZfU1JDLCB0aGlzLmVsLmlkKVxuICAgICAgaWYob3B0cy5zdWJtaXR0ZXIgJiYgIShlbCA9PT0gb3B0cy5zdWJtaXR0ZXIgfHwgZWwgPT09IG9wdHMuZm9ybSkpeyBjb250aW51ZSB9XG5cbiAgICAgIGVsLmNsYXNzTGlzdC5hZGQoYHBoeC0ke2V2ZW50fS1sb2FkaW5nYClcbiAgICAgIGVsLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KGBwaHg6JHtldmVudH0tbG9hZGluZ2AsIHtidWJibGVzOiB0cnVlLCBjYW5jZWxhYmxlOiBmYWxzZX0pKVxuICAgICAgbGV0IGRpc2FibGVUZXh0ID0gZWwuZ2V0QXR0cmlidXRlKGRpc2FibGVXaXRoKVxuICAgICAgaWYoZGlzYWJsZVRleHQgIT09IG51bGwpe1xuICAgICAgICBpZighZWwuZ2V0QXR0cmlidXRlKFBIWF9ESVNBQkxFX1dJVEhfUkVTVE9SRSkpe1xuICAgICAgICAgIGVsLnNldEF0dHJpYnV0ZShQSFhfRElTQUJMRV9XSVRIX1JFU1RPUkUsIGVsLmlubmVyVGV4dClcbiAgICAgICAgfVxuICAgICAgICBpZihkaXNhYmxlVGV4dCAhPT0gXCJcIil7IGVsLmlubmVyVGV4dCA9IGRpc2FibGVUZXh0IH1cbiAgICAgICAgLy8gUEhYX0RJU0FCTEVEIGNvdWxkIGhhdmUgYWxyZWFkeSBiZWVuIHNldCBpbiBkaXNhYmxlRm9ybVxuICAgICAgICBlbC5zZXRBdHRyaWJ1dGUoUEhYX0RJU0FCTEVELCBlbC5nZXRBdHRyaWJ1dGUoUEhYX0RJU0FCTEVEKSB8fCBlbC5kaXNhYmxlZClcbiAgICAgICAgZWwuc2V0QXR0cmlidXRlKFwiZGlzYWJsZWRcIiwgXCJcIilcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIFtuZXdSZWYsIGVsZW1lbnRzLCBvcHRzXVxuICB9XG5cbiAgY29tcG9uZW50SUQoZWwpe1xuICAgIGxldCBjaWQgPSBlbC5nZXRBdHRyaWJ1dGUgJiYgZWwuZ2V0QXR0cmlidXRlKFBIWF9DT01QT05FTlQpXG4gICAgcmV0dXJuIGNpZCA/IHBhcnNlSW50KGNpZCkgOiBudWxsXG4gIH1cblxuICB0YXJnZXRDb21wb25lbnRJRCh0YXJnZXQsIHRhcmdldEN0eCwgb3B0cyA9IHt9KXtcbiAgICBpZihpc0NpZCh0YXJnZXRDdHgpKXsgcmV0dXJuIHRhcmdldEN0eCB9XG5cbiAgICBsZXQgY2lkT3JTZWxlY3RvciA9IG9wdHMudGFyZ2V0IHx8IHRhcmdldC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwidGFyZ2V0XCIpKVxuICAgIGlmKGlzQ2lkKGNpZE9yU2VsZWN0b3IpKXtcbiAgICAgIHJldHVybiBwYXJzZUludChjaWRPclNlbGVjdG9yKVxuICAgIH0gZWxzZSBpZih0YXJnZXRDdHggJiYgKGNpZE9yU2VsZWN0b3IgIT09IG51bGwgfHwgb3B0cy50YXJnZXQpKXtcbiAgICAgIHJldHVybiB0aGlzLmNsb3Nlc3RDb21wb25lbnRJRCh0YXJnZXRDdHgpXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuICB9XG5cbiAgY2xvc2VzdENvbXBvbmVudElEKHRhcmdldEN0eCl7XG4gICAgaWYoaXNDaWQodGFyZ2V0Q3R4KSl7XG4gICAgICByZXR1cm4gdGFyZ2V0Q3R4XG4gICAgfSBlbHNlIGlmKHRhcmdldEN0eCl7XG4gICAgICByZXR1cm4gbWF5YmUodGFyZ2V0Q3R4LmNsb3Nlc3QoYFske1BIWF9DT01QT05FTlR9XWApLCBlbCA9PiB0aGlzLm93bnNFbGVtZW50KGVsKSAmJiB0aGlzLmNvbXBvbmVudElEKGVsKSlcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG4gIH1cblxuICBwdXNoSG9va0V2ZW50KGVsLCB0YXJnZXRDdHgsIGV2ZW50LCBwYXlsb2FkLCBvblJlcGx5KXtcbiAgICBpZighdGhpcy5pc0Nvbm5lY3RlZCgpKXtcbiAgICAgIHRoaXMubG9nKFwiaG9va1wiLCAoKSA9PiBbXCJ1bmFibGUgdG8gcHVzaCBob29rIGV2ZW50LiBMaXZlVmlldyBub3QgY29ubmVjdGVkXCIsIGV2ZW50LCBwYXlsb2FkXSlcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICBsZXQgW3JlZiwgZWxzLCBvcHRzXSA9IHRoaXMucHV0UmVmKFtlbF0sIFwiaG9va1wiKVxuICAgIHRoaXMucHVzaFdpdGhSZXBseSgoKSA9PiBbcmVmLCBlbHMsIG9wdHNdLCBcImV2ZW50XCIsIHtcbiAgICAgIHR5cGU6IFwiaG9va1wiLFxuICAgICAgZXZlbnQ6IGV2ZW50LFxuICAgICAgdmFsdWU6IHBheWxvYWQsXG4gICAgICBjaWQ6IHRoaXMuY2xvc2VzdENvbXBvbmVudElEKHRhcmdldEN0eClcbiAgICB9LCAocmVzcCwgcmVwbHkpID0+IG9uUmVwbHkocmVwbHksIHJlZikpXG5cbiAgICByZXR1cm4gcmVmXG4gIH1cblxuICBleHRyYWN0TWV0YShlbCwgbWV0YSwgdmFsdWUpe1xuICAgIGxldCBwcmVmaXggPSB0aGlzLmJpbmRpbmcoXCJ2YWx1ZS1cIilcbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgZWwuYXR0cmlidXRlcy5sZW5ndGg7IGkrKyl7XG4gICAgICBpZighbWV0YSl7IG1ldGEgPSB7fSB9XG4gICAgICBsZXQgbmFtZSA9IGVsLmF0dHJpYnV0ZXNbaV0ubmFtZVxuICAgICAgaWYobmFtZS5zdGFydHNXaXRoKHByZWZpeCkpeyBtZXRhW25hbWUucmVwbGFjZShwcmVmaXgsIFwiXCIpXSA9IGVsLmdldEF0dHJpYnV0ZShuYW1lKSB9XG4gICAgfVxuICAgIGlmKGVsLnZhbHVlICE9PSB1bmRlZmluZWQgJiYgIShlbCBpbnN0YW5jZW9mIEhUTUxGb3JtRWxlbWVudCkpe1xuICAgICAgaWYoIW1ldGEpeyBtZXRhID0ge30gfVxuICAgICAgbWV0YS52YWx1ZSA9IGVsLnZhbHVlXG5cbiAgICAgIGlmKGVsLnRhZ05hbWUgPT09IFwiSU5QVVRcIiAmJiBDSEVDS0FCTEVfSU5QVVRTLmluZGV4T2YoZWwudHlwZSkgPj0gMCAmJiAhZWwuY2hlY2tlZCl7XG4gICAgICAgIGRlbGV0ZSBtZXRhLnZhbHVlXG4gICAgICB9XG4gICAgfVxuICAgIGlmKHZhbHVlKXtcbiAgICAgIGlmKCFtZXRhKXsgbWV0YSA9IHt9IH1cbiAgICAgIGZvcihsZXQga2V5IGluIHZhbHVlKXsgbWV0YVtrZXldID0gdmFsdWVba2V5XSB9XG4gICAgfVxuICAgIHJldHVybiBtZXRhXG4gIH1cblxuXG4gIHB1c2hFdmVudCh0eXBlLCBlbCwgdGFyZ2V0Q3R4LCBwaHhFdmVudCwgbWV0YSwgb3B0cyA9IHt9LCBvblJlcGx5KXtcbiAgICB0aGlzLnB1c2hXaXRoUmVwbHkoKCkgPT4gdGhpcy5wdXRSZWYoW2VsXSwgdHlwZSwgb3B0cyksIFwiZXZlbnRcIiwge1xuICAgICAgdHlwZTogdHlwZSxcbiAgICAgIGV2ZW50OiBwaHhFdmVudCxcbiAgICAgIHZhbHVlOiB0aGlzLmV4dHJhY3RNZXRhKGVsLCBtZXRhLCBvcHRzLnZhbHVlKSxcbiAgICAgIGNpZDogdGhpcy50YXJnZXRDb21wb25lbnRJRChlbCwgdGFyZ2V0Q3R4LCBvcHRzKVxuICAgIH0sIChyZXNwLCByZXBseSkgPT4gb25SZXBseSAmJiBvblJlcGx5KHJlcGx5KSlcbiAgfVxuXG4gIHB1c2hGaWxlUHJvZ3Jlc3MoZmlsZUVsLCBlbnRyeVJlZiwgcHJvZ3Jlc3MsIG9uUmVwbHkgPSBmdW5jdGlvbiAoKXsgfSl7XG4gICAgdGhpcy5saXZlU29ja2V0LndpdGhpbk93bmVycyhmaWxlRWwuZm9ybSwgKHZpZXcsIHRhcmdldEN0eCkgPT4ge1xuICAgICAgdmlldy5wdXNoV2l0aFJlcGx5KG51bGwsIFwicHJvZ3Jlc3NcIiwge1xuICAgICAgICBldmVudDogZmlsZUVsLmdldEF0dHJpYnV0ZSh2aWV3LmJpbmRpbmcoUEhYX1BST0dSRVNTKSksXG4gICAgICAgIHJlZjogZmlsZUVsLmdldEF0dHJpYnV0ZShQSFhfVVBMT0FEX1JFRiksXG4gICAgICAgIGVudHJ5X3JlZjogZW50cnlSZWYsXG4gICAgICAgIHByb2dyZXNzOiBwcm9ncmVzcyxcbiAgICAgICAgY2lkOiB2aWV3LnRhcmdldENvbXBvbmVudElEKGZpbGVFbC5mb3JtLCB0YXJnZXRDdHgpXG4gICAgICB9LCBvblJlcGx5KVxuICAgIH0pXG4gIH1cblxuICBwdXNoSW5wdXQoaW5wdXRFbCwgdGFyZ2V0Q3R4LCBmb3JjZUNpZCwgcGh4RXZlbnQsIG9wdHMsIGNhbGxiYWNrKXtcbiAgICBsZXQgdXBsb2Fkc1xuICAgIGxldCBjaWQgPSBpc0NpZChmb3JjZUNpZCkgPyBmb3JjZUNpZCA6IHRoaXMudGFyZ2V0Q29tcG9uZW50SUQoaW5wdXRFbC5mb3JtLCB0YXJnZXRDdHgsIG9wdHMpXG4gICAgbGV0IHJlZkdlbmVyYXRvciA9ICgpID0+IHRoaXMucHV0UmVmKFtpbnB1dEVsLCBpbnB1dEVsLmZvcm1dLCBcImNoYW5nZVwiLCBvcHRzKVxuICAgIGxldCBmb3JtRGF0YVxuICAgIGxldCBtZXRhICA9IHRoaXMuZXh0cmFjdE1ldGEoaW5wdXRFbC5mb3JtKVxuICAgIGlmKGlucHV0RWwgaW5zdGFuY2VvZiBIVE1MQnV0dG9uRWxlbWVudCl7IG1ldGEuc3VibWl0dGVyID0gaW5wdXRFbCB9XG4gICAgaWYoaW5wdXRFbC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwiY2hhbmdlXCIpKSl7XG4gICAgICBmb3JtRGF0YSA9IHNlcmlhbGl6ZUZvcm0oaW5wdXRFbC5mb3JtLCB7X3RhcmdldDogb3B0cy5fdGFyZ2V0LCAuLi5tZXRhfSwgW2lucHV0RWwubmFtZV0pXG4gICAgfSBlbHNlIHtcbiAgICAgIGZvcm1EYXRhID0gc2VyaWFsaXplRm9ybShpbnB1dEVsLmZvcm0sIHtfdGFyZ2V0OiBvcHRzLl90YXJnZXQsIC4uLm1ldGF9KVxuICAgIH1cbiAgICBpZihET00uaXNVcGxvYWRJbnB1dChpbnB1dEVsKSAmJiBpbnB1dEVsLmZpbGVzICYmIGlucHV0RWwuZmlsZXMubGVuZ3RoID4gMCl7XG4gICAgICBMaXZlVXBsb2FkZXIudHJhY2tGaWxlcyhpbnB1dEVsLCBBcnJheS5mcm9tKGlucHV0RWwuZmlsZXMpKVxuICAgIH1cbiAgICB1cGxvYWRzID0gTGl2ZVVwbG9hZGVyLnNlcmlhbGl6ZVVwbG9hZHMoaW5wdXRFbClcblxuICAgIGxldCBldmVudCA9IHtcbiAgICAgIHR5cGU6IFwiZm9ybVwiLFxuICAgICAgZXZlbnQ6IHBoeEV2ZW50LFxuICAgICAgdmFsdWU6IGZvcm1EYXRhLFxuICAgICAgdXBsb2FkczogdXBsb2FkcyxcbiAgICAgIGNpZDogY2lkXG4gICAgfVxuICAgIHRoaXMucHVzaFdpdGhSZXBseShyZWZHZW5lcmF0b3IsIFwiZXZlbnRcIiwgZXZlbnQsIHJlc3AgPT4ge1xuICAgICAgRE9NLnNob3dFcnJvcihpbnB1dEVsLCB0aGlzLmxpdmVTb2NrZXQuYmluZGluZyhQSFhfRkVFREJBQ0tfRk9SKSwgdGhpcy5saXZlU29ja2V0LmJpbmRpbmcoUEhYX0ZFRURCQUNLX0dST1VQKSlcbiAgICAgIGlmKERPTS5pc1VwbG9hZElucHV0KGlucHV0RWwpICYmIERPTS5pc0F1dG9VcGxvYWQoaW5wdXRFbCkpe1xuICAgICAgICBpZihMaXZlVXBsb2FkZXIuZmlsZXNBd2FpdGluZ1ByZWZsaWdodChpbnB1dEVsKS5sZW5ndGggPiAwKXtcbiAgICAgICAgICBsZXQgW3JlZiwgX2Vsc10gPSByZWZHZW5lcmF0b3IoKVxuICAgICAgICAgIHRoaXMudW5kb1JlZnMocmVmLCBbaW5wdXRFbC5mb3JtXSlcbiAgICAgICAgICB0aGlzLnVwbG9hZEZpbGVzKGlucHV0RWwuZm9ybSwgdGFyZ2V0Q3R4LCByZWYsIGNpZCwgKF91cGxvYWRzKSA9PiB7XG4gICAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjayhyZXNwKVxuICAgICAgICAgICAgdGhpcy50cmlnZ2VyQXdhaXRpbmdTdWJtaXQoaW5wdXRFbC5mb3JtKVxuICAgICAgICAgICAgdGhpcy51bmRvUmVmcyhyZWYpXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2socmVzcClcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgdHJpZ2dlckF3YWl0aW5nU3VibWl0KGZvcm1FbCl7XG4gICAgbGV0IGF3YWl0aW5nU3VibWl0ID0gdGhpcy5nZXRTY2hlZHVsZWRTdWJtaXQoZm9ybUVsKVxuICAgIGlmKGF3YWl0aW5nU3VibWl0KXtcbiAgICAgIGxldCBbX2VsLCBfcmVmLCBfb3B0cywgY2FsbGJhY2tdID0gYXdhaXRpbmdTdWJtaXRcbiAgICAgIHRoaXMuY2FuY2VsU3VibWl0KGZvcm1FbClcbiAgICAgIGNhbGxiYWNrKClcbiAgICB9XG4gIH1cblxuICBnZXRTY2hlZHVsZWRTdWJtaXQoZm9ybUVsKXtcbiAgICByZXR1cm4gdGhpcy5mb3JtU3VibWl0cy5maW5kKChbZWwsIF9yZWYsIF9vcHRzLCBfY2FsbGJhY2tdKSA9PiBlbC5pc1NhbWVOb2RlKGZvcm1FbCkpXG4gIH1cblxuICBzY2hlZHVsZVN1Ym1pdChmb3JtRWwsIHJlZiwgb3B0cywgY2FsbGJhY2spe1xuICAgIGlmKHRoaXMuZ2V0U2NoZWR1bGVkU3VibWl0KGZvcm1FbCkpeyByZXR1cm4gdHJ1ZSB9XG4gICAgdGhpcy5mb3JtU3VibWl0cy5wdXNoKFtmb3JtRWwsIHJlZiwgb3B0cywgY2FsbGJhY2tdKVxuICB9XG5cbiAgY2FuY2VsU3VibWl0KGZvcm1FbCl7XG4gICAgdGhpcy5mb3JtU3VibWl0cyA9IHRoaXMuZm9ybVN1Ym1pdHMuZmlsdGVyKChbZWwsIHJlZiwgX2NhbGxiYWNrXSkgPT4ge1xuICAgICAgaWYoZWwuaXNTYW1lTm9kZShmb3JtRWwpKXtcbiAgICAgICAgdGhpcy51bmRvUmVmcyhyZWYpXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgZGlzYWJsZUZvcm0oZm9ybUVsLCBvcHRzID0ge30pe1xuICAgIGxldCBmaWx0ZXJJZ25vcmVkID0gZWwgPT4ge1xuICAgICAgbGV0IHVzZXJJZ25vcmVkID0gY2xvc2VzdFBoeEJpbmRpbmcoZWwsIGAke3RoaXMuYmluZGluZyhQSFhfVVBEQVRFKX09aWdub3JlYCwgZWwuZm9ybSlcbiAgICAgIHJldHVybiAhKHVzZXJJZ25vcmVkIHx8IGNsb3Nlc3RQaHhCaW5kaW5nKGVsLCBcImRhdGEtcGh4LXVwZGF0ZT1pZ25vcmVcIiwgZWwuZm9ybSkpXG4gICAgfVxuICAgIGxldCBmaWx0ZXJEaXNhYmxlcyA9IGVsID0+IHtcbiAgICAgIHJldHVybiBlbC5oYXNBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFBIWF9ESVNBQkxFX1dJVEgpKVxuICAgIH1cbiAgICBsZXQgZmlsdGVyQnV0dG9uID0gZWwgPT4gZWwudGFnTmFtZSA9PSBcIkJVVFRPTlwiXG5cbiAgICBsZXQgZmlsdGVySW5wdXQgPSBlbCA9PiBbXCJJTlBVVFwiLCBcIlRFWFRBUkVBXCIsIFwiU0VMRUNUXCJdLmluY2x1ZGVzKGVsLnRhZ05hbWUpXG5cbiAgICBsZXQgZm9ybUVsZW1lbnRzID0gQXJyYXkuZnJvbShmb3JtRWwuZWxlbWVudHMpXG4gICAgbGV0IGRpc2FibGVzID0gZm9ybUVsZW1lbnRzLmZpbHRlcihmaWx0ZXJEaXNhYmxlcylcbiAgICBsZXQgYnV0dG9ucyA9IGZvcm1FbGVtZW50cy5maWx0ZXIoZmlsdGVyQnV0dG9uKS5maWx0ZXIoZmlsdGVySWdub3JlZClcbiAgICBsZXQgaW5wdXRzID0gZm9ybUVsZW1lbnRzLmZpbHRlcihmaWx0ZXJJbnB1dCkuZmlsdGVyKGZpbHRlcklnbm9yZWQpXG5cbiAgICBidXR0b25zLmZvckVhY2goYnV0dG9uID0+IHtcbiAgICAgIGJ1dHRvbi5zZXRBdHRyaWJ1dGUoUEhYX0RJU0FCTEVELCBidXR0b24uZGlzYWJsZWQpXG4gICAgICBidXR0b24uZGlzYWJsZWQgPSB0cnVlXG4gICAgfSlcbiAgICBpbnB1dHMuZm9yRWFjaChpbnB1dCA9PiB7XG4gICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoUEhYX1JFQURPTkxZLCBpbnB1dC5yZWFkT25seSlcbiAgICAgIGlucHV0LnJlYWRPbmx5ID0gdHJ1ZVxuICAgICAgaWYoaW5wdXQuZmlsZXMpe1xuICAgICAgICBpbnB1dC5zZXRBdHRyaWJ1dGUoUEhYX0RJU0FCTEVELCBpbnB1dC5kaXNhYmxlZClcbiAgICAgICAgaW5wdXQuZGlzYWJsZWQgPSB0cnVlXG4gICAgICB9XG4gICAgfSlcbiAgICBmb3JtRWwuc2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhQSFhfUEFHRV9MT0FESU5HKSwgXCJcIilcbiAgICByZXR1cm4gdGhpcy5wdXRSZWYoW2Zvcm1FbF0uY29uY2F0KGRpc2FibGVzKS5jb25jYXQoYnV0dG9ucykuY29uY2F0KGlucHV0cyksIFwic3VibWl0XCIsIG9wdHMpXG4gIH1cblxuICBwdXNoRm9ybVN1Ym1pdChmb3JtRWwsIHRhcmdldEN0eCwgcGh4RXZlbnQsIHN1Ym1pdHRlciwgb3B0cywgb25SZXBseSl7XG4gICAgbGV0IHJlZkdlbmVyYXRvciA9ICgpID0+IHRoaXMuZGlzYWJsZUZvcm0oZm9ybUVsLCB7Li4ub3B0cywgZm9ybTogZm9ybUVsLCBzdWJtaXR0ZXI6IHN1Ym1pdHRlcn0pXG4gICAgbGV0IGNpZCA9IHRoaXMudGFyZ2V0Q29tcG9uZW50SUQoZm9ybUVsLCB0YXJnZXRDdHgpXG4gICAgaWYoTGl2ZVVwbG9hZGVyLmhhc1VwbG9hZHNJblByb2dyZXNzKGZvcm1FbCkpe1xuICAgICAgbGV0IFtyZWYsIF9lbHNdID0gcmVmR2VuZXJhdG9yKClcbiAgICAgIGxldCBwdXNoID0gKCkgPT4gdGhpcy5wdXNoRm9ybVN1Ym1pdChmb3JtRWwsIHRhcmdldEN0eCwgcGh4RXZlbnQsIHN1Ym1pdHRlciwgb3B0cywgb25SZXBseSlcbiAgICAgIHJldHVybiB0aGlzLnNjaGVkdWxlU3VibWl0KGZvcm1FbCwgcmVmLCBvcHRzLCBwdXNoKVxuICAgIH0gZWxzZSBpZihMaXZlVXBsb2FkZXIuaW5wdXRzQXdhaXRpbmdQcmVmbGlnaHQoZm9ybUVsKS5sZW5ndGggPiAwKXtcbiAgICAgIGxldCBbcmVmLCBlbHNdID0gcmVmR2VuZXJhdG9yKClcbiAgICAgIGxldCBwcm94eVJlZkdlbiA9ICgpID0+IFtyZWYsIGVscywgb3B0c11cbiAgICAgIHRoaXMudXBsb2FkRmlsZXMoZm9ybUVsLCB0YXJnZXRDdHgsIHJlZiwgY2lkLCAodXBsb2FkcykgPT4ge1xuICAgICAgICAvLyBpZiB3ZSBzdGlsbCBoYXZpbmcgcGVuZGluZyBwcmVmbGlnaHRzIGl0IG1lYW5zIHdlIGhhdmUgaW52YWxpZCBlbnRyaWVzXG4gICAgICAgIC8vIGFuZCB0aGUgcGh4LXN1Ym1pdCBjYW5ub3QgYmUgY29tcGxldGVkXG4gICAgICAgIGlmKExpdmVVcGxvYWRlci5pbnB1dHNBd2FpdGluZ1ByZWZsaWdodChmb3JtRWwpLmxlbmd0aCA+IDApe1xuICAgICAgICAgIHJldHVybiB0aGlzLnVuZG9SZWZzKHJlZilcbiAgICAgICAgfVxuICAgICAgICBsZXQgbWV0YSA9IHRoaXMuZXh0cmFjdE1ldGEoZm9ybUVsKVxuICAgICAgICBsZXQgZm9ybURhdGEgPSBzZXJpYWxpemVGb3JtKGZvcm1FbCwge3N1Ym1pdHRlciwgLi4ubWV0YX0pXG4gICAgICAgIHRoaXMucHVzaFdpdGhSZXBseShwcm94eVJlZkdlbiwgXCJldmVudFwiLCB7XG4gICAgICAgICAgdHlwZTogXCJmb3JtXCIsXG4gICAgICAgICAgZXZlbnQ6IHBoeEV2ZW50LFxuICAgICAgICAgIHZhbHVlOiBmb3JtRGF0YSxcbiAgICAgICAgICBjaWQ6IGNpZFxuICAgICAgICB9LCBvblJlcGx5KVxuICAgICAgfSlcbiAgICB9IGVsc2UgaWYoIShmb3JtRWwuaGFzQXR0cmlidXRlKFBIWF9SRUYpICYmIGZvcm1FbC5jbGFzc0xpc3QuY29udGFpbnMoXCJwaHgtc3VibWl0LWxvYWRpbmdcIikpKXtcbiAgICAgIGxldCBtZXRhID0gdGhpcy5leHRyYWN0TWV0YShmb3JtRWwpXG4gICAgICBsZXQgZm9ybURhdGEgPSBzZXJpYWxpemVGb3JtKGZvcm1FbCwge3N1Ym1pdHRlciwgLi4ubWV0YX0pXG4gICAgICB0aGlzLnB1c2hXaXRoUmVwbHkocmVmR2VuZXJhdG9yLCBcImV2ZW50XCIsIHtcbiAgICAgICAgdHlwZTogXCJmb3JtXCIsXG4gICAgICAgIGV2ZW50OiBwaHhFdmVudCxcbiAgICAgICAgdmFsdWU6IGZvcm1EYXRhLFxuICAgICAgICBjaWQ6IGNpZFxuICAgICAgfSwgb25SZXBseSlcbiAgICB9XG4gIH1cblxuICB1cGxvYWRGaWxlcyhmb3JtRWwsIHRhcmdldEN0eCwgcmVmLCBjaWQsIG9uQ29tcGxldGUpe1xuICAgIGxldCBqb2luQ291bnRBdFVwbG9hZCA9IHRoaXMuam9pbkNvdW50XG4gICAgbGV0IGlucHV0RWxzID0gTGl2ZVVwbG9hZGVyLmFjdGl2ZUZpbGVJbnB1dHMoZm9ybUVsKVxuICAgIGxldCBudW1GaWxlSW5wdXRzSW5Qcm9ncmVzcyA9IGlucHV0RWxzLmxlbmd0aFxuXG4gICAgLy8gZ2V0IGVhY2ggZmlsZSBpbnB1dFxuICAgIGlucHV0RWxzLmZvckVhY2goaW5wdXRFbCA9PiB7XG4gICAgICBsZXQgdXBsb2FkZXIgPSBuZXcgTGl2ZVVwbG9hZGVyKGlucHV0RWwsIHRoaXMsICgpID0+IHtcbiAgICAgICAgbnVtRmlsZUlucHV0c0luUHJvZ3Jlc3MtLVxuICAgICAgICBpZihudW1GaWxlSW5wdXRzSW5Qcm9ncmVzcyA9PT0gMCl7IG9uQ29tcGxldGUoKSB9XG4gICAgICB9KTtcblxuICAgICAgbGV0IGVudHJpZXMgPSB1cGxvYWRlci5lbnRyaWVzKCkubWFwKGVudHJ5ID0+IGVudHJ5LnRvUHJlZmxpZ2h0UGF5bG9hZCgpKVxuXG4gICAgICBpZihlbnRyaWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBudW1GaWxlSW5wdXRzSW5Qcm9ncmVzcy0tXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBsZXQgcGF5bG9hZCA9IHtcbiAgICAgICAgcmVmOiBpbnB1dEVsLmdldEF0dHJpYnV0ZShQSFhfVVBMT0FEX1JFRiksXG4gICAgICAgIGVudHJpZXM6IGVudHJpZXMsXG4gICAgICAgIGNpZDogdGhpcy50YXJnZXRDb21wb25lbnRJRChpbnB1dEVsLmZvcm0sIHRhcmdldEN0eClcbiAgICAgIH1cblxuICAgICAgdGhpcy5sb2coXCJ1cGxvYWRcIiwgKCkgPT4gW1wic2VuZGluZyBwcmVmbGlnaHQgcmVxdWVzdFwiLCBwYXlsb2FkXSlcblxuICAgICAgdGhpcy5wdXNoV2l0aFJlcGx5KG51bGwsIFwiYWxsb3dfdXBsb2FkXCIsIHBheWxvYWQsIHJlc3AgPT4ge1xuICAgICAgICB0aGlzLmxvZyhcInVwbG9hZFwiLCAoKSA9PiBbXCJnb3QgcHJlZmxpZ2h0IHJlc3BvbnNlXCIsIHJlc3BdKVxuICAgICAgICAvLyB0aGUgcHJlZmxpZ2h0IHdpbGwgcmVqZWN0IGVudHJpZXMgYmV5b25kIHRoZSBtYXggZW50cmllc1xuICAgICAgICAvLyBzbyB3ZSBlcnJvciBhbmQgY2FuY2VsIGVudHJpZXMgb24gdGhlIGNsaWVudCB0aGF0IGFyZSBtaXNzaW5nIGZyb20gdGhlIHJlc3BvbnNlXG4gICAgICAgIHVwbG9hZGVyLmVudHJpZXMoKS5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgICAgICBpZihyZXNwLmVudHJpZXMgJiYgIXJlc3AuZW50cmllc1tlbnRyeS5yZWZdKXtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRmFpbGVkRW50cnlQcmVmbGlnaHQoZW50cnkucmVmLCBcImZhaWxlZCBwcmVmbGlnaHRcIiwgdXBsb2FkZXIpXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAvLyBmb3IgYXV0byB1cGxvYWRzLCB3ZSBtYXkgaGF2ZSBhbiBlbXB0eSBlbnRyaWVzIHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlclxuICAgICAgICAvLyBmb3IgZm9ybSBzdWJtaXRzIHRoYXQgY29udGFpbiBpbnZhbGlkIGVudHJpZXNcbiAgICAgICAgaWYocmVzcC5lcnJvciB8fCBPYmplY3Qua2V5cyhyZXNwLmVudHJpZXMpLmxlbmd0aCA9PT0gMCl7XG4gICAgICAgICAgdGhpcy51bmRvUmVmcyhyZWYpXG4gICAgICAgICAgbGV0IGVycm9ycyA9IHJlc3AuZXJyb3IgfHwgW11cbiAgICAgICAgICBlcnJvcnMubWFwKChbZW50cnlfcmVmLCByZWFzb25dKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZUZhaWxlZEVudHJ5UHJlZmxpZ2h0KGVudHJ5X3JlZiwgcmVhc29uLCB1cGxvYWRlcilcbiAgICAgICAgICB9KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxldCBvbkVycm9yID0gKGNhbGxiYWNrKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNoYW5uZWwub25FcnJvcigoKSA9PiB7XG4gICAgICAgICAgICAgIGlmKHRoaXMuam9pbkNvdW50ID09PSBqb2luQ291bnRBdFVwbG9hZCl7IGNhbGxiYWNrKCkgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9XG4gICAgICAgICAgdXBsb2FkZXIuaW5pdEFkYXB0ZXJVcGxvYWQocmVzcCwgb25FcnJvciwgdGhpcy5saXZlU29ja2V0KVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICBoYW5kbGVGYWlsZWRFbnRyeVByZWZsaWdodCh1cGxvYWRSZWYsIHJlYXNvbiwgdXBsb2FkZXIpe1xuICAgIGlmKHVwbG9hZGVyLmlzQXV0b1VwbG9hZCgpKXtcbiAgICAgIC8vIHVwbG9hZFJlZiBtYXkgYmUgdG9wIGxldmVsIHVwbG9hZCBjb25maWcgcmVmIG9yIGVudHJ5IHJlZlxuICAgICAgbGV0IGVudHJ5ID0gdXBsb2FkZXIuZW50cmllcygpLmZpbmQoZW50cnkgPT4gZW50cnkucmVmID09PSB1cGxvYWRSZWYudG9TdHJpbmcoKSlcbiAgICAgIGlmKGVudHJ5KXsgZW50cnkuY2FuY2VsKCkgfVxuICAgIH0gZWxzZSB7XG4gICAgICB1cGxvYWRlci5lbnRyaWVzKCkubWFwKGVudHJ5ID0+IGVudHJ5LmNhbmNlbCgpKVxuICAgIH1cbiAgICB0aGlzLmxvZyhcInVwbG9hZFwiLCAoKSA9PiBbYGVycm9yIGZvciBlbnRyeSAke3VwbG9hZFJlZn1gLCByZWFzb25dKVxuICB9XG5cbiAgZGlzcGF0Y2hVcGxvYWRzKHRhcmdldEN0eCwgbmFtZSwgZmlsZXNPckJsb2JzKXtcbiAgICBsZXQgdGFyZ2V0RWxlbWVudCA9IHRoaXMudGFyZ2V0Q3R4RWxlbWVudCh0YXJnZXRDdHgpIHx8IHRoaXMuZWxcbiAgICBsZXQgaW5wdXRzID0gRE9NLmZpbmRVcGxvYWRJbnB1dHModGFyZ2V0RWxlbWVudCkuZmlsdGVyKGVsID0+IGVsLm5hbWUgPT09IG5hbWUpXG4gICAgaWYoaW5wdXRzLmxlbmd0aCA9PT0gMCl7IGxvZ0Vycm9yKGBubyBsaXZlIGZpbGUgaW5wdXRzIGZvdW5kIG1hdGNoaW5nIHRoZSBuYW1lIFwiJHtuYW1lfVwiYCkgfVxuICAgIGVsc2UgaWYoaW5wdXRzLmxlbmd0aCA+IDEpeyBsb2dFcnJvcihgZHVwbGljYXRlIGxpdmUgZmlsZSBpbnB1dHMgZm91bmQgbWF0Y2hpbmcgdGhlIG5hbWUgXCIke25hbWV9XCJgKSB9XG4gICAgZWxzZSB7IERPTS5kaXNwYXRjaEV2ZW50KGlucHV0c1swXSwgUEhYX1RSQUNLX1VQTE9BRFMsIHtkZXRhaWw6IHtmaWxlczogZmlsZXNPckJsb2JzfX0pIH1cbiAgfVxuXG4gIHRhcmdldEN0eEVsZW1lbnQodGFyZ2V0Q3R4KSB7XG4gICAgaWYoaXNDaWQodGFyZ2V0Q3R4KSl7XG4gICAgICBsZXQgW3RhcmdldF0gPSBET00uZmluZENvbXBvbmVudE5vZGVMaXN0KHRoaXMuZWwsIHRhcmdldEN0eClcbiAgICAgIHJldHVybiB0YXJnZXRcbiAgICB9IGVsc2UgaWYodGFyZ2V0Q3R4KSB7XG4gICAgICByZXR1cm4gdGFyZ2V0Q3R4XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuICB9XG5cbiAgcHVzaEZvcm1SZWNvdmVyeShvbGRGb3JtLCBuZXdGb3JtLCB0ZW1wbGF0ZURvbSwgY2FsbGJhY2spe1xuICAgIC8vIHdlIGFyZSBvbmx5IHJlY292ZXJpbmcgZm9ybXMgaW5zaWRlIHRoZSBjdXJyZW50IHZpZXcsIHRoZXJlZm9yZSBpdCBpcyBzYWZlIHRvXG4gICAgLy8gc2tpcCB3aXRoaW5Pd25lcnMgaGVyZSBhbmQgYWx3YXlzIHVzZSB0aGlzIHdoZW4gcmVmZXJyaW5nIHRvIHRoZSB2aWV3XG4gICAgY29uc3QgcGh4Q2hhbmdlID0gdGhpcy5iaW5kaW5nKFwiY2hhbmdlXCIpXG4gICAgY29uc3QgcGh4VGFyZ2V0ID0gbmV3Rm9ybS5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwidGFyZ2V0XCIpKSB8fCBuZXdGb3JtXG4gICAgY29uc3QgcGh4RXZlbnQgPSBuZXdGb3JtLmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoUEhYX0FVVE9fUkVDT1ZFUikpIHx8IG5ld0Zvcm0uZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhcImNoYW5nZVwiKSlcbiAgICBjb25zdCBpbnB1dHMgPSBBcnJheS5mcm9tKG9sZEZvcm0uZWxlbWVudHMpLmZpbHRlcihlbCA9PiBET00uaXNGb3JtSW5wdXQoZWwpICYmIGVsLm5hbWUgJiYgIWVsLmhhc0F0dHJpYnV0ZShwaHhDaGFuZ2UpKVxuICAgIGlmKGlucHV0cy5sZW5ndGggPT09IDApeyByZXR1cm4gfVxuXG4gICAgLy8gd2UgbXVzdCBjbGVhciB0cmFja2VkIHVwbG9hZHMgYmVmb3JlIHJlY292ZXJ5IGFzIHRoZXkgbm8gbG9uZ2VyIGhhdmUgdmFsaWQgcmVmc1xuICAgIGlucHV0cy5mb3JFYWNoKGlucHV0ID0+IGlucHV0Lmhhc0F0dHJpYnV0ZShQSFhfVVBMT0FEX1JFRikgJiYgTGl2ZVVwbG9hZGVyLmNsZWFyRmlsZXMoaW5wdXQpKVxuICAgIC8vIHB1c2hJbnB1dCBhc3N1bWVzIHRoYXQgdGhlcmUgaXMgYSBzb3VyY2UgZWxlbWVudCB0aGF0IGluaXRpYXRlZCB0aGUgY2hhbmdlO1xuICAgIC8vIGJlY2F1c2UgdGhpcyBpcyBub3QgdGhlIGNhc2Ugd2hlbiB3ZSByZWNvdmVyIGZvcm1zLCB3ZSBwcm92aWRlIHRoZSBmaXJzdCBpbnB1dCB3ZSBmaW5kXG4gICAgbGV0IGlucHV0ID0gaW5wdXRzLmZpbmQoZWwgPT4gZWwudHlwZSAhPT0gXCJoaWRkZW5cIikgfHwgaW5wdXRzWzBdXG5cbiAgICAvLyBpbiB0aGUgY2FzZSB0aGF0IHRoZXJlIGFyZSBtdWx0aXBsZSB0YXJnZXRzLCB3ZSBjb3VudCB0aGUgbnVtYmVyIG9mIHBlbmRpbmcgcmVjb3ZlcnkgZXZlbnRzXG4gICAgLy8gYW5kIG9ubHkgY2FsbCB0aGUgY2FsbGJhY2sgb25jZSBhbGwgZXZlbnRzIGhhdmUgYmVlbiBwcm9jZXNzZWRcbiAgICBsZXQgcGVuZGluZyA9IDBcbiAgICAvLyB3aXRoaW5UYXJnZXRzKHBoeFRhcmdldCwgY2FsbGJhY2ssIGRvbSwgdmlld0VsKVxuICAgIHRoaXMud2l0aGluVGFyZ2V0cyhwaHhUYXJnZXQsICh0YXJnZXRWaWV3LCB0YXJnZXRDdHgpID0+IHtcbiAgICAgIGNvbnN0IGNpZCA9IHRoaXMudGFyZ2V0Q29tcG9uZW50SUQobmV3Rm9ybSwgdGFyZ2V0Q3R4KVxuICAgICAgcGVuZGluZysrXG4gICAgICB0YXJnZXRWaWV3LnB1c2hJbnB1dChpbnB1dCwgdGFyZ2V0Q3R4LCBjaWQsIHBoeEV2ZW50LCB7X3RhcmdldDogaW5wdXQubmFtZX0sICgpID0+IHtcbiAgICAgICAgcGVuZGluZy0tXG4gICAgICAgIGlmKHBlbmRpbmcgPT09IDApeyBjYWxsYmFjaygpIH1cbiAgICAgIH0pXG4gICAgfSwgdGVtcGxhdGVEb20sIHRlbXBsYXRlRG9tKVxuICB9XG5cbiAgcHVzaExpbmtQYXRjaChocmVmLCB0YXJnZXRFbCwgY2FsbGJhY2spe1xuICAgIGxldCBsaW5rUmVmID0gdGhpcy5saXZlU29ja2V0LnNldFBlbmRpbmdMaW5rKGhyZWYpXG4gICAgbGV0IHJlZkdlbiA9IHRhcmdldEVsID8gKCkgPT4gdGhpcy5wdXRSZWYoW3RhcmdldEVsXSwgXCJjbGlja1wiKSA6IG51bGxcbiAgICBsZXQgZmFsbGJhY2sgPSAoKSA9PiB0aGlzLmxpdmVTb2NrZXQucmVkaXJlY3Qod2luZG93LmxvY2F0aW9uLmhyZWYpXG4gICAgbGV0IHVybCA9IGhyZWYuc3RhcnRzV2l0aChcIi9cIikgPyBgJHtsb2NhdGlvbi5wcm90b2NvbH0vLyR7bG9jYXRpb24uaG9zdH0ke2hyZWZ9YCA6IGhyZWZcblxuICAgIGxldCBwdXNoID0gdGhpcy5wdXNoV2l0aFJlcGx5KHJlZkdlbiwgXCJsaXZlX3BhdGNoXCIsIHt1cmx9LCByZXNwID0+IHtcbiAgICAgIHRoaXMubGl2ZVNvY2tldC5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IHtcbiAgICAgICAgaWYocmVzcC5saW5rX3JlZGlyZWN0KXtcbiAgICAgICAgICB0aGlzLmxpdmVTb2NrZXQucmVwbGFjZU1haW4oaHJlZiwgbnVsbCwgY2FsbGJhY2ssIGxpbmtSZWYpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYodGhpcy5saXZlU29ja2V0LmNvbW1pdFBlbmRpbmdMaW5rKGxpbmtSZWYpKXtcbiAgICAgICAgICAgIHRoaXMuaHJlZiA9IGhyZWZcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5hcHBseVBlbmRpbmdVcGRhdGVzKClcbiAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjayhsaW5rUmVmKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0pXG5cbiAgICBpZihwdXNoKXtcbiAgICAgIHB1c2gucmVjZWl2ZShcInRpbWVvdXRcIiwgZmFsbGJhY2spXG4gICAgfSBlbHNlIHtcbiAgICAgIGZhbGxiYWNrKClcbiAgICB9XG4gIH1cblxuICBnZXRGb3Jtc0ZvclJlY292ZXJ5KCl7XG4gICAgaWYodGhpcy5qb2luQ291bnQgPT09IDApeyByZXR1cm4ge30gfVxuXG4gICAgbGV0IHBoeENoYW5nZSA9IHRoaXMuYmluZGluZyhcImNoYW5nZVwiKVxuXG4gICAgcmV0dXJuIERPTS5hbGwodGhpcy5lbCwgYGZvcm1bJHtwaHhDaGFuZ2V9XWApXG4gICAgICAuZmlsdGVyKGZvcm0gPT4gZm9ybS5pZClcbiAgICAgIC5maWx0ZXIoZm9ybSA9PiBmb3JtLmVsZW1lbnRzLmxlbmd0aCA+IDApXG4gICAgICAuZmlsdGVyKGZvcm0gPT4gZm9ybS5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFBIWF9BVVRPX1JFQ09WRVIpKSAhPT0gXCJpZ25vcmVcIilcbiAgICAgIC5tYXAoZm9ybSA9PiBmb3JtLmNsb25lTm9kZSh0cnVlKSlcbiAgICAgIC5yZWR1Y2UoKGFjYywgZm9ybSkgPT4ge1xuICAgICAgICBhY2NbZm9ybS5pZF0gPSBmb3JtXG4gICAgICAgIHJldHVybiBhY2NcbiAgICAgIH0sIHt9KVxuICB9XG5cbiAgbWF5YmVQdXNoQ29tcG9uZW50c0Rlc3Ryb3llZChkZXN0cm95ZWRDSURzKXtcbiAgICBsZXQgd2lsbERlc3Ryb3lDSURzID0gZGVzdHJveWVkQ0lEcy5maWx0ZXIoY2lkID0+IHtcbiAgICAgIHJldHVybiBET00uZmluZENvbXBvbmVudE5vZGVMaXN0KHRoaXMuZWwsIGNpZCkubGVuZ3RoID09PSAwXG4gICAgfSlcblxuICAgIGlmKHdpbGxEZXN0cm95Q0lEcy5sZW5ndGggPiAwKXtcbiAgICAgIC8vIHdlIG11c3QgcmVzZXQgdGhlIHJlbmRlciBjaGFuZ2UgdHJhY2tpbmcgZm9yIGNpZHMgdGhhdFxuICAgICAgLy8gY291bGQgYmUgYWRkZWQgYmFjayBmcm9tIHRoZSBzZXJ2ZXIgc28gd2UgZG9uJ3Qgc2tpcCB0aGVtXG4gICAgICB3aWxsRGVzdHJveUNJRHMuZm9yRWFjaChjaWQgPT4gdGhpcy5yZW5kZXJlZC5yZXNldFJlbmRlcihjaWQpKVxuXG4gICAgICB0aGlzLnB1c2hXaXRoUmVwbHkobnVsbCwgXCJjaWRzX3dpbGxfZGVzdHJveVwiLCB7Y2lkczogd2lsbERlc3Ryb3lDSURzfSwgKCkgPT4ge1xuICAgICAgICAvLyB3ZSBtdXN0IHdhaXQgZm9yIHBlbmRpbmcgdHJhbnNpdGlvbnMgdG8gY29tcGxldGUgYmVmb3JlIGRldGVybWluaW5nXG4gICAgICAgIC8vIGlmIHRoZSBjaWRzIHdlcmUgYWRkZWQgYmFjayB0byB0aGUgRE9NIGluIHRoZSBtZWFudGltZSAoIzMxMzkpXG4gICAgICAgIHRoaXMubGl2ZVNvY2tldC5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IHtcbiAgICAgICAgICAvLyBTZWUgaWYgYW55IG9mIHRoZSBjaWRzIHdlIHdhbnRlZCB0byBkZXN0cm95IHdlcmUgYWRkZWQgYmFjayxcbiAgICAgICAgICAvLyBpZiB0aGV5IHdlcmUgYWRkZWQgYmFjaywgd2UgZG9uJ3QgYWN0dWFsbHkgZGVzdHJveSB0aGVtLlxuICAgICAgICAgIGxldCBjb21wbGV0ZWx5RGVzdHJveUNJRHMgPSB3aWxsRGVzdHJveUNJRHMuZmlsdGVyKGNpZCA9PiB7XG4gICAgICAgICAgICByZXR1cm4gRE9NLmZpbmRDb21wb25lbnROb2RlTGlzdCh0aGlzLmVsLCBjaWQpLmxlbmd0aCA9PT0gMFxuICAgICAgICAgIH0pXG4gIFxuICAgICAgICAgIGlmKGNvbXBsZXRlbHlEZXN0cm95Q0lEcy5sZW5ndGggPiAwKXtcbiAgICAgICAgICAgIHRoaXMucHVzaFdpdGhSZXBseShudWxsLCBcImNpZHNfZGVzdHJveWVkXCIsIHtjaWRzOiBjb21wbGV0ZWx5RGVzdHJveUNJRHN9LCAocmVzcCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnJlbmRlcmVkLnBydW5lQ0lEcyhyZXNwLmNpZHMpXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgb3duc0VsZW1lbnQoZWwpe1xuICAgIGxldCBwYXJlbnRWaWV3RWwgPSBlbC5jbG9zZXN0KFBIWF9WSUVXX1NFTEVDVE9SKVxuICAgIHJldHVybiBlbC5nZXRBdHRyaWJ1dGUoUEhYX1BBUkVOVF9JRCkgPT09IHRoaXMuaWQgfHxcbiAgICAgIChwYXJlbnRWaWV3RWwgJiYgcGFyZW50Vmlld0VsLmlkID09PSB0aGlzLmlkKSB8fFxuICAgICAgKCFwYXJlbnRWaWV3RWwgJiYgdGhpcy5pc0RlYWQpXG4gIH1cblxuICBzdWJtaXRGb3JtKGZvcm0sIHRhcmdldEN0eCwgcGh4RXZlbnQsIHN1Ym1pdHRlciwgb3B0cyA9IHt9KXtcbiAgICBET00ucHV0UHJpdmF0ZShmb3JtLCBQSFhfSEFTX1NVQk1JVFRFRCwgdHJ1ZSlcbiAgICBjb25zdCBwaHhGZWVkYmFja0ZvciA9IHRoaXMubGl2ZVNvY2tldC5iaW5kaW5nKFBIWF9GRUVEQkFDS19GT1IpXG4gICAgY29uc3QgcGh4RmVlZGJhY2tHcm91cCA9IHRoaXMubGl2ZVNvY2tldC5iaW5kaW5nKFBIWF9GRUVEQkFDS19HUk9VUClcbiAgICBjb25zdCBpbnB1dHMgPSBBcnJheS5mcm9tKGZvcm0uZWxlbWVudHMpXG4gICAgaW5wdXRzLmZvckVhY2goaW5wdXQgPT4gRE9NLnB1dFByaXZhdGUoaW5wdXQsIFBIWF9IQVNfU1VCTUlUVEVELCB0cnVlKSlcbiAgICB0aGlzLmxpdmVTb2NrZXQuYmx1ckFjdGl2ZUVsZW1lbnQodGhpcylcbiAgICB0aGlzLnB1c2hGb3JtU3VibWl0KGZvcm0sIHRhcmdldEN0eCwgcGh4RXZlbnQsIHN1Ym1pdHRlciwgb3B0cywgKCkgPT4ge1xuICAgICAgaW5wdXRzLmZvckVhY2goaW5wdXQgPT4gRE9NLnNob3dFcnJvcihpbnB1dCwgcGh4RmVlZGJhY2tGb3IsIHBoeEZlZWRiYWNrR3JvdXApKVxuICAgICAgdGhpcy5saXZlU29ja2V0LnJlc3RvcmVQcmV2aW91c2x5QWN0aXZlRm9jdXMoKVxuICAgIH0pXG4gIH1cblxuICBiaW5kaW5nKGtpbmQpeyByZXR1cm4gdGhpcy5saXZlU29ja2V0LmJpbmRpbmcoa2luZCkgfVxufVxuIiwgIi8qKiBJbml0aWFsaXplcyB0aGUgTGl2ZVNvY2tldFxuICpcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZW5kUG9pbnQgLSBUaGUgc3RyaW5nIFdlYlNvY2tldCBlbmRwb2ludCwgaWUsIGBcIndzczovL2V4YW1wbGUuY29tL2xpdmVcImAsXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYFwiL2xpdmVcImAgKGluaGVyaXRlZCBob3N0ICYgcHJvdG9jb2wpXG4gKiBAcGFyYW0ge1Bob2VuaXguU29ja2V0fSBzb2NrZXQgLSB0aGUgcmVxdWlyZWQgUGhvZW5peCBTb2NrZXQgY2xhc3MgaW1wb3J0ZWQgZnJvbSBcInBob2VuaXhcIi4gRm9yIGV4YW1wbGU6XG4gKlxuICogICAgIGltcG9ydCB7U29ja2V0fSBmcm9tIFwicGhvZW5peFwiXG4gKiAgICAgaW1wb3J0IHtMaXZlU29ja2V0fSBmcm9tIFwicGhvZW5peF9saXZlX3ZpZXdcIlxuICogICAgIGxldCBsaXZlU29ja2V0ID0gbmV3IExpdmVTb2NrZXQoXCIvbGl2ZVwiLCBTb2NrZXQsIHsuLi59KVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0c10gLSBPcHRpb25hbCBjb25maWd1cmF0aW9uLiBPdXRzaWRlIG9mIGtleXMgbGlzdGVkIGJlbG93LCBhbGxcbiAqIGNvbmZpZ3VyYXRpb24gaXMgcGFzc2VkIGRpcmVjdGx5IHRvIHRoZSBQaG9lbml4IFNvY2tldCBjb25zdHJ1Y3Rvci5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0cy5kZWZhdWx0c10gLSBUaGUgb3B0aW9uYWwgZGVmYXVsdHMgdG8gdXNlIGZvciB2YXJpb3VzIGJpbmRpbmdzLFxuICogc3VjaCBhcyBgcGh4LWRlYm91bmNlYC4gU3VwcG9ydHMgdGhlIGZvbGxvd2luZyBrZXlzOlxuICpcbiAqICAgLSBkZWJvdW5jZSAtIHRoZSBtaWxsaXNlY29uZCBwaHgtZGVib3VuY2UgdGltZS4gRGVmYXVsdHMgMzAwXG4gKiAgIC0gdGhyb3R0bGUgLSB0aGUgbWlsbGlzZWNvbmQgcGh4LXRocm90dGxlIHRpbWUuIERlZmF1bHRzIDMwMFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRzLnBhcmFtc10gLSBUaGUgb3B0aW9uYWwgZnVuY3Rpb24gZm9yIHBhc3NpbmcgY29ubmVjdCBwYXJhbXMuXG4gKiBUaGUgZnVuY3Rpb24gcmVjZWl2ZXMgdGhlIGVsZW1lbnQgYXNzb2NpYXRlZCB3aXRoIGEgZ2l2ZW4gTGl2ZVZpZXcuIEZvciBleGFtcGxlOlxuICpcbiAqICAgICAoZWwpID0+IHt2aWV3OiBlbC5nZXRBdHRyaWJ1dGUoXCJkYXRhLW15LXZpZXctbmFtZVwiLCB0b2tlbjogd2luZG93Lm15VG9rZW59XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcHRzLmJpbmRpbmdQcmVmaXhdIC0gVGhlIG9wdGlvbmFsIHByZWZpeCB0byB1c2UgZm9yIGFsbCBwaHggRE9NIGFubm90YXRpb25zLlxuICogRGVmYXVsdHMgdG8gXCJwaHgtXCIuXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdHMuaG9va3NdIC0gVGhlIG9wdGlvbmFsIG9iamVjdCBmb3IgcmVmZXJlbmNpbmcgTGl2ZVZpZXcgaG9vayBjYWxsYmFja3MuXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdHMudXBsb2FkZXJzXSAtIFRoZSBvcHRpb25hbCBvYmplY3QgZm9yIHJlZmVyZW5jaW5nIExpdmVWaWV3IHVwbG9hZGVyIGNhbGxiYWNrcy5cbiAqIEBwYXJhbSB7aW50ZWdlcn0gW29wdHMubG9hZGVyVGltZW91dF0gLSBUaGUgb3B0aW9uYWwgZGVsYXkgaW4gbWlsbGlzZWNvbmRzIHRvIHdhaXQgYmVmb3JlIGFwcGx5XG4gKiBsb2FkaW5nIHN0YXRlcy5cbiAqIEBwYXJhbSB7aW50ZWdlcn0gW29wdHMubWF4UmVsb2Fkc10gLSBUaGUgbWF4aW11bSByZWxvYWRzIGJlZm9yZSBlbnRlcmluZyBmYWlsc2FmZSBtb2RlLlxuICogQHBhcmFtIHtpbnRlZ2VyfSBbb3B0cy5yZWxvYWRKaXR0ZXJNaW5dIC0gVGhlIG1pbmltdW0gdGltZSBiZXR3ZWVuIG5vcm1hbCByZWxvYWQgYXR0ZW1wdHMuXG4gKiBAcGFyYW0ge2ludGVnZXJ9IFtvcHRzLnJlbG9hZEppdHRlck1heF0gLSBUaGUgbWF4aW11bSB0aW1lIGJldHdlZW4gbm9ybWFsIHJlbG9hZCBhdHRlbXB0cy5cbiAqIEBwYXJhbSB7aW50ZWdlcn0gW29wdHMuZmFpbHNhZmVKaXR0ZXJdIC0gVGhlIHRpbWUgYmV0d2VlbiByZWxvYWQgYXR0ZW1wdHMgaW4gZmFpbHNhZmUgbW9kZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvcHRzLnZpZXdMb2dnZXJdIC0gVGhlIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGxvZyBkZWJ1ZyBpbmZvcm1hdGlvbi4gRm9yIGV4YW1wbGU6XG4gKlxuICogICAgICh2aWV3LCBraW5kLCBtc2csIG9iaikgPT4gY29uc29sZS5sb2coYCR7dmlldy5pZH0gJHtraW5kfTogJHttc2d9IC0gYCwgb2JqKVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0cy5tZXRhZGF0YV0gLSBUaGUgb3B0aW9uYWwgb2JqZWN0IG1hcHBpbmcgZXZlbnQgbmFtZXMgdG8gZnVuY3Rpb25zIGZvclxuICogcG9wdWxhdGluZyBldmVudCBtZXRhZGF0YS4gRm9yIGV4YW1wbGU6XG4gKlxuICogICAgIG1ldGFkYXRhOiB7XG4gKiAgICAgICBjbGljazogKGUsIGVsKSA9PiB7XG4gKiAgICAgICAgIHJldHVybiB7XG4gKiAgICAgICAgICAgY3RybEtleTogZS5jdHJsS2V5LFxuICogICAgICAgICAgIG1ldGFLZXk6IGUubWV0YUtleSxcbiAqICAgICAgICAgICBkZXRhaWw6IGUuZGV0YWlsIHx8IDEsXG4gKiAgICAgICAgIH1cbiAqICAgICAgIH0sXG4gKiAgICAgICBrZXlkb3duOiAoZSwgZWwpID0+IHtcbiAqICAgICAgICAgcmV0dXJuIHtcbiAqICAgICAgICAgICBrZXk6IGUua2V5LFxuICogICAgICAgICAgIGN0cmxLZXk6IGUuY3RybEtleSxcbiAqICAgICAgICAgICBtZXRhS2V5OiBlLm1ldGFLZXksXG4gKiAgICAgICAgICAgc2hpZnRLZXk6IGUuc2hpZnRLZXlcbiAqICAgICAgICAgfVxuICogICAgICAgfVxuICogICAgIH1cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0cy5zZXNzaW9uU3RvcmFnZV0gLSBBbiBvcHRpb25hbCBTdG9yYWdlIGNvbXBhdGlibGUgb2JqZWN0XG4gKiBVc2VmdWwgd2hlbiBMaXZlVmlldyB3b24ndCBoYXZlIGFjY2VzcyB0byBgc2Vzc2lvblN0b3JhZ2VgLiAgRm9yIGV4YW1wbGUsIFRoaXMgY291bGRcbiAqIGhhcHBlbiBpZiBhIHNpdGUgbG9hZHMgYSBjcm9zcy1kb21haW4gTGl2ZVZpZXcgaW4gYW4gaWZyYW1lLiAgRXhhbXBsZSB1c2FnZTpcbiAqXG4gKiAgICAgY2xhc3MgSW5NZW1vcnlTdG9yYWdlIHtcbiAqICAgICAgIGNvbnN0cnVjdG9yKCkgeyB0aGlzLnN0b3JhZ2UgPSB7fSB9XG4gKiAgICAgICBnZXRJdGVtKGtleU5hbWUpIHsgcmV0dXJuIHRoaXMuc3RvcmFnZVtrZXlOYW1lXSB8fCBudWxsIH1cbiAqICAgICAgIHJlbW92ZUl0ZW0oa2V5TmFtZSkgeyBkZWxldGUgdGhpcy5zdG9yYWdlW2tleU5hbWVdIH1cbiAqICAgICAgIHNldEl0ZW0oa2V5TmFtZSwga2V5VmFsdWUpIHsgdGhpcy5zdG9yYWdlW2tleU5hbWVdID0ga2V5VmFsdWUgfVxuICogICAgIH1cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdHMubG9jYWxTdG9yYWdlXSAtIEFuIG9wdGlvbmFsIFN0b3JhZ2UgY29tcGF0aWJsZSBvYmplY3RcbiAqIFVzZWZ1bCBmb3Igd2hlbiBMaXZlVmlldyB3b24ndCBoYXZlIGFjY2VzcyB0byBgbG9jYWxTdG9yYWdlYC5cbiAqIFNlZSBgb3B0cy5zZXNzaW9uU3RvcmFnZWAgZm9yIGV4YW1wbGVzLlxuKi9cblxuaW1wb3J0IHtcbiAgQklORElOR19QUkVGSVgsXG4gIENPTlNFQ1VUSVZFX1JFTE9BRFMsXG4gIERFRkFVTFRTLFxuICBGQUlMU0FGRV9KSVRURVIsXG4gIExPQURFUl9USU1FT1VULFxuICBNQVhfUkVMT0FEUyxcbiAgUEhYX0RFQk9VTkNFLFxuICBQSFhfRFJPUF9UQVJHRVQsXG4gIFBIWF9IQVNfRk9DVVNFRCxcbiAgUEhYX0tFWSxcbiAgUEhYX0xJTktfU1RBVEUsXG4gIFBIWF9MSVZFX0xJTkssXG4gIFBIWF9MVl9ERUJVRyxcbiAgUEhYX0xWX0xBVEVOQ1lfU0lNLFxuICBQSFhfTFZfUFJPRklMRSxcbiAgUEhYX01BSU4sXG4gIFBIWF9QQVJFTlRfSUQsXG4gIFBIWF9WSUVXX1NFTEVDVE9SLFxuICBQSFhfUk9PVF9JRCxcbiAgUEhYX1RIUk9UVExFLFxuICBQSFhfVFJBQ0tfVVBMT0FEUyxcbiAgUEhYX1NFU1NJT04sXG4gIFBIWF9GRUVEQkFDS19GT1IsXG4gIFBIWF9GRUVEQkFDS19HUk9VUCxcbiAgUkVMT0FEX0pJVFRFUl9NSU4sXG4gIFJFTE9BRF9KSVRURVJfTUFYLFxuICBQSFhfUkVGLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIlxuXG5pbXBvcnQge1xuICBjbG9uZSxcbiAgY2xvc2VzdFBoeEJpbmRpbmcsXG4gIGNsb3N1cmUsXG4gIGRlYnVnLFxuICBtYXliZVxufSBmcm9tIFwiLi91dGlsc1wiXG5cbmltcG9ydCBCcm93c2VyIGZyb20gXCIuL2Jyb3dzZXJcIlxuaW1wb3J0IERPTSBmcm9tIFwiLi9kb21cIlxuaW1wb3J0IEhvb2tzIGZyb20gXCIuL2hvb2tzXCJcbmltcG9ydCBMaXZlVXBsb2FkZXIgZnJvbSBcIi4vbGl2ZV91cGxvYWRlclwiXG5pbXBvcnQgVmlldyBmcm9tIFwiLi92aWV3XCJcbmltcG9ydCBKUyBmcm9tIFwiLi9qc1wiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExpdmVTb2NrZXQge1xuICBjb25zdHJ1Y3Rvcih1cmwsIHBoeFNvY2tldCwgb3B0cyA9IHt9KXtcbiAgICB0aGlzLnVubG9hZGVkID0gZmFsc2VcbiAgICBpZighcGh4U29ja2V0IHx8IHBoeFNvY2tldC5jb25zdHJ1Y3Rvci5uYW1lID09PSBcIk9iamVjdFwiKXtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgXG4gICAgICBhIHBob2VuaXggU29ja2V0IG11c3QgYmUgcHJvdmlkZWQgYXMgdGhlIHNlY29uZCBhcmd1bWVudCB0byB0aGUgTGl2ZVNvY2tldCBjb25zdHJ1Y3Rvci4gRm9yIGV4YW1wbGU6XG5cbiAgICAgICAgICBpbXBvcnQge1NvY2tldH0gZnJvbSBcInBob2VuaXhcIlxuICAgICAgICAgIGltcG9ydCB7TGl2ZVNvY2tldH0gZnJvbSBcInBob2VuaXhfbGl2ZV92aWV3XCJcbiAgICAgICAgICBsZXQgbGl2ZVNvY2tldCA9IG5ldyBMaXZlU29ja2V0KFwiL2xpdmVcIiwgU29ja2V0LCB7Li4ufSlcbiAgICAgIGApXG4gICAgfVxuICAgIHRoaXMuc29ja2V0ID0gbmV3IHBoeFNvY2tldCh1cmwsIG9wdHMpXG4gICAgdGhpcy5iaW5kaW5nUHJlZml4ID0gb3B0cy5iaW5kaW5nUHJlZml4IHx8IEJJTkRJTkdfUFJFRklYXG4gICAgdGhpcy5vcHRzID0gb3B0c1xuICAgIHRoaXMucGFyYW1zID0gY2xvc3VyZShvcHRzLnBhcmFtcyB8fCB7fSlcbiAgICB0aGlzLnZpZXdMb2dnZXIgPSBvcHRzLnZpZXdMb2dnZXJcbiAgICB0aGlzLm1ldGFkYXRhQ2FsbGJhY2tzID0gb3B0cy5tZXRhZGF0YSB8fCB7fVxuICAgIHRoaXMuZGVmYXVsdHMgPSBPYmplY3QuYXNzaWduKGNsb25lKERFRkFVTFRTKSwgb3B0cy5kZWZhdWx0cyB8fCB7fSlcbiAgICB0aGlzLmFjdGl2ZUVsZW1lbnQgPSBudWxsXG4gICAgdGhpcy5wcmV2QWN0aXZlID0gbnVsbFxuICAgIHRoaXMuc2lsZW5jZWQgPSBmYWxzZVxuICAgIHRoaXMubWFpbiA9IG51bGxcbiAgICB0aGlzLm91dGdvaW5nTWFpbkVsID0gbnVsbFxuICAgIHRoaXMuY2xpY2tTdGFydGVkQXRUYXJnZXQgPSBudWxsXG4gICAgdGhpcy5saW5rUmVmID0gMVxuICAgIHRoaXMucm9vdHMgPSB7fVxuICAgIHRoaXMuaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmXG4gICAgdGhpcy5wZW5kaW5nTGluayA9IG51bGxcbiAgICB0aGlzLmN1cnJlbnRMb2NhdGlvbiA9IGNsb25lKHdpbmRvdy5sb2NhdGlvbilcbiAgICB0aGlzLmhvb2tzID0gb3B0cy5ob29rcyB8fCB7fVxuICAgIHRoaXMudXBsb2FkZXJzID0gb3B0cy51cGxvYWRlcnMgfHwge31cbiAgICB0aGlzLmxvYWRlclRpbWVvdXQgPSBvcHRzLmxvYWRlclRpbWVvdXQgfHwgTE9BREVSX1RJTUVPVVRcbiAgICB0aGlzLnJlbG9hZFdpdGhKaXR0ZXJUaW1lciA9IG51bGxcbiAgICB0aGlzLm1heFJlbG9hZHMgPSBvcHRzLm1heFJlbG9hZHMgfHwgTUFYX1JFTE9BRFNcbiAgICB0aGlzLnJlbG9hZEppdHRlck1pbiA9IG9wdHMucmVsb2FkSml0dGVyTWluIHx8IFJFTE9BRF9KSVRURVJfTUlOXG4gICAgdGhpcy5yZWxvYWRKaXR0ZXJNYXggPSBvcHRzLnJlbG9hZEppdHRlck1heCB8fCBSRUxPQURfSklUVEVSX01BWFxuICAgIHRoaXMuZmFpbHNhZmVKaXR0ZXIgPSBvcHRzLmZhaWxzYWZlSml0dGVyIHx8IEZBSUxTQUZFX0pJVFRFUlxuICAgIHRoaXMubG9jYWxTdG9yYWdlID0gb3B0cy5sb2NhbFN0b3JhZ2UgfHwgd2luZG93LmxvY2FsU3RvcmFnZVxuICAgIHRoaXMuc2Vzc2lvblN0b3JhZ2UgPSBvcHRzLnNlc3Npb25TdG9yYWdlIHx8IHdpbmRvdy5zZXNzaW9uU3RvcmFnZVxuICAgIHRoaXMuYm91bmRUb3BMZXZlbEV2ZW50cyA9IGZhbHNlXG4gICAgdGhpcy5zZXJ2ZXJDbG9zZVJlZiA9IG51bGxcbiAgICB0aGlzLmRvbUNhbGxiYWNrcyA9IE9iamVjdC5hc3NpZ24oe1xuICAgICAgb25QYXRjaFN0YXJ0OiBjbG9zdXJlKCksXG4gICAgICBvblBhdGNoRW5kOiBjbG9zdXJlKCksXG4gICAgICBvbk5vZGVBZGRlZDogY2xvc3VyZSgpLFxuICAgICAgb25CZWZvcmVFbFVwZGF0ZWQ6IGNsb3N1cmUoKX0sXG4gICAgb3B0cy5kb20gfHwge30pXG4gICAgdGhpcy50cmFuc2l0aW9ucyA9IG5ldyBUcmFuc2l0aW9uU2V0KClcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBhZ2VoaWRlXCIsIF9lID0+IHtcbiAgICAgIHRoaXMudW5sb2FkZWQgPSB0cnVlXG4gICAgfSlcbiAgICB0aGlzLnNvY2tldC5vbk9wZW4oKCkgPT4ge1xuICAgICAgaWYodGhpcy5pc1VubG9hZGVkKCkpe1xuICAgICAgICAvLyByZWxvYWQgcGFnZSBpZiBiZWluZyByZXN0b3JlZCBmcm9tIGJhY2svZm9yd2FyZCBjYWNoZSBhbmQgYnJvd3NlciBkb2VzIG5vdCBlbWl0IFwicGFnZXNob3dcIlxuICAgICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKClcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLy8gcHVibGljXG5cbiAgdmVyc2lvbigpeyByZXR1cm4gTFZfVlNOIH1cblxuICBpc1Byb2ZpbGVFbmFibGVkKCl7IHJldHVybiB0aGlzLnNlc3Npb25TdG9yYWdlLmdldEl0ZW0oUEhYX0xWX1BST0ZJTEUpID09PSBcInRydWVcIiB9XG5cbiAgaXNEZWJ1Z0VuYWJsZWQoKXsgcmV0dXJuIHRoaXMuc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShQSFhfTFZfREVCVUcpID09PSBcInRydWVcIiB9XG5cbiAgaXNEZWJ1Z0Rpc2FibGVkKCl7IHJldHVybiB0aGlzLnNlc3Npb25TdG9yYWdlLmdldEl0ZW0oUEhYX0xWX0RFQlVHKSA9PT0gXCJmYWxzZVwiIH1cblxuICBlbmFibGVEZWJ1ZygpeyB0aGlzLnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oUEhYX0xWX0RFQlVHLCBcInRydWVcIikgfVxuXG4gIGVuYWJsZVByb2ZpbGluZygpeyB0aGlzLnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oUEhYX0xWX1BST0ZJTEUsIFwidHJ1ZVwiKSB9XG5cbiAgZGlzYWJsZURlYnVnKCl7IHRoaXMuc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShQSFhfTFZfREVCVUcsIFwiZmFsc2VcIikgfVxuXG4gIGRpc2FibGVQcm9maWxpbmcoKXsgdGhpcy5zZXNzaW9uU3RvcmFnZS5yZW1vdmVJdGVtKFBIWF9MVl9QUk9GSUxFKSB9XG5cbiAgZW5hYmxlTGF0ZW5jeVNpbSh1cHBlckJvdW5kTXMpe1xuICAgIHRoaXMuZW5hYmxlRGVidWcoKVxuICAgIGNvbnNvbGUubG9nKFwibGF0ZW5jeSBzaW11bGF0b3IgZW5hYmxlZCBmb3IgdGhlIGR1cmF0aW9uIG9mIHRoaXMgYnJvd3NlciBzZXNzaW9uLiBDYWxsIGRpc2FibGVMYXRlbmN5U2ltKCkgdG8gZGlzYWJsZVwiKVxuICAgIHRoaXMuc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShQSFhfTFZfTEFURU5DWV9TSU0sIHVwcGVyQm91bmRNcylcbiAgfVxuXG4gIGRpc2FibGVMYXRlbmN5U2ltKCl7IHRoaXMuc2Vzc2lvblN0b3JhZ2UucmVtb3ZlSXRlbShQSFhfTFZfTEFURU5DWV9TSU0pIH1cblxuICBnZXRMYXRlbmN5U2ltKCl7XG4gICAgbGV0IHN0ciA9IHRoaXMuc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShQSFhfTFZfTEFURU5DWV9TSU0pXG4gICAgcmV0dXJuIHN0ciA/IHBhcnNlSW50KHN0cikgOiBudWxsXG4gIH1cblxuICBnZXRTb2NrZXQoKXsgcmV0dXJuIHRoaXMuc29ja2V0IH1cblxuICBjb25uZWN0KCl7XG4gICAgLy8gZW5hYmxlIGRlYnVnIGJ5IGRlZmF1bHQgaWYgb24gbG9jYWxob3N0IGFuZCBub3QgZXhwbGljaXRseSBkaXNhYmxlZFxuICAgIGlmKHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSA9PT0gXCJsb2NhbGhvc3RcIiAmJiAhdGhpcy5pc0RlYnVnRGlzYWJsZWQoKSl7IHRoaXMuZW5hYmxlRGVidWcoKSB9XG4gICAgbGV0IGRvQ29ubmVjdCA9ICgpID0+IHtcbiAgICAgIGlmKHRoaXMuam9pblJvb3RWaWV3cygpKXtcbiAgICAgICAgdGhpcy5iaW5kVG9wTGV2ZWxFdmVudHMoKVxuICAgICAgICB0aGlzLnNvY2tldC5jb25uZWN0KClcbiAgICAgIH0gZWxzZSBpZih0aGlzLm1haW4pe1xuICAgICAgICB0aGlzLnNvY2tldC5jb25uZWN0KClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYmluZFRvcExldmVsRXZlbnRzKHtkZWFkOiB0cnVlfSlcbiAgICAgIH1cbiAgICAgIHRoaXMuam9pbkRlYWRWaWV3KClcbiAgICB9XG4gICAgaWYoW1wiY29tcGxldGVcIiwgXCJsb2FkZWRcIiwgXCJpbnRlcmFjdGl2ZVwiXS5pbmRleE9mKGRvY3VtZW50LnJlYWR5U3RhdGUpID49IDApe1xuICAgICAgZG9Db25uZWN0KClcbiAgICB9IGVsc2Uge1xuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIkRPTUNvbnRlbnRMb2FkZWRcIiwgKCkgPT4gZG9Db25uZWN0KCkpXG4gICAgfVxuICB9XG5cbiAgZGlzY29ubmVjdChjYWxsYmFjayl7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMucmVsb2FkV2l0aEppdHRlclRpbWVyKVxuICAgIC8vIHJlbW92ZSB0aGUgc29ja2V0IGNsb3NlIGxpc3RlbmVyIHRvIGF2b2lkIHRyeWluZyB0byBoYW5kbGVcbiAgICAvLyBhIHNlcnZlciBjbG9zZSBldmVudCB3aGVuIGl0IGlzIGFjdHVhbGx5IGNhdXNlZCBieSB1cyBkaXNjb25uZWN0aW5nXG4gICAgaWYodGhpcy5zZXJ2ZXJDbG9zZVJlZil7XG4gICAgICB0aGlzLnNvY2tldC5vZmYodGhpcy5zZXJ2ZXJDbG9zZVJlZilcbiAgICAgIHRoaXMuc2VydmVyQ2xvc2VSZWYgPSBudWxsXG4gICAgfVxuICAgIHRoaXMuc29ja2V0LmRpc2Nvbm5lY3QoY2FsbGJhY2spXG4gIH1cblxuICByZXBsYWNlVHJhbnNwb3J0KHRyYW5zcG9ydCl7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMucmVsb2FkV2l0aEppdHRlclRpbWVyKVxuICAgIHRoaXMuc29ja2V0LnJlcGxhY2VUcmFuc3BvcnQodHJhbnNwb3J0KVxuICAgIHRoaXMuY29ubmVjdCgpXG4gIH1cblxuICBleGVjSlMoZWwsIGVuY29kZWRKUywgZXZlbnRUeXBlID0gbnVsbCl7XG4gICAgdGhpcy5vd25lcihlbCwgdmlldyA9PiBKUy5leGVjKGV2ZW50VHlwZSwgZW5jb2RlZEpTLCB2aWV3LCBlbCkpXG4gIH1cblxuICAvLyBwcml2YXRlXG5cbiAgZXhlY0pTSG9va1B1c2goZWwsIHBoeEV2ZW50LCBkYXRhLCBjYWxsYmFjayl7XG4gICAgdGhpcy53aXRoaW5Pd25lcnMoZWwsIHZpZXcgPT4ge1xuICAgICAgSlMuZXhlYyhcImhvb2tcIiwgcGh4RXZlbnQsIHZpZXcsIGVsLCBbXCJwdXNoXCIsIHtkYXRhLCBjYWxsYmFja31dKVxuICAgIH0pXG4gIH1cblxuICB1bmxvYWQoKXtcbiAgICBpZih0aGlzLnVubG9hZGVkKXsgcmV0dXJuIH1cbiAgICBpZih0aGlzLm1haW4gJiYgdGhpcy5pc0Nvbm5lY3RlZCgpKXsgdGhpcy5sb2codGhpcy5tYWluLCBcInNvY2tldFwiLCAoKSA9PiBbXCJkaXNjb25uZWN0IGZvciBwYWdlIG5hdlwiXSkgfVxuICAgIHRoaXMudW5sb2FkZWQgPSB0cnVlXG4gICAgdGhpcy5kZXN0cm95QWxsVmlld3MoKVxuICAgIHRoaXMuZGlzY29ubmVjdCgpXG4gIH1cblxuICB0cmlnZ2VyRE9NKGtpbmQsIGFyZ3MpeyB0aGlzLmRvbUNhbGxiYWNrc1traW5kXSguLi5hcmdzKSB9XG5cbiAgdGltZShuYW1lLCBmdW5jKXtcbiAgICBpZighdGhpcy5pc1Byb2ZpbGVFbmFibGVkKCkgfHwgIWNvbnNvbGUudGltZSl7IHJldHVybiBmdW5jKCkgfVxuICAgIGNvbnNvbGUudGltZShuYW1lKVxuICAgIGxldCByZXN1bHQgPSBmdW5jKClcbiAgICBjb25zb2xlLnRpbWVFbmQobmFtZSlcbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cblxuICBsb2codmlldywga2luZCwgbXNnQ2FsbGJhY2spe1xuICAgIGlmKHRoaXMudmlld0xvZ2dlcil7XG4gICAgICBsZXQgW21zZywgb2JqXSA9IG1zZ0NhbGxiYWNrKClcbiAgICAgIHRoaXMudmlld0xvZ2dlcih2aWV3LCBraW5kLCBtc2csIG9iailcbiAgICB9IGVsc2UgaWYodGhpcy5pc0RlYnVnRW5hYmxlZCgpKXtcbiAgICAgIGxldCBbbXNnLCBvYmpdID0gbXNnQ2FsbGJhY2soKVxuICAgICAgZGVidWcodmlldywga2luZCwgbXNnLCBvYmopXG4gICAgfVxuICB9XG5cbiAgcmVxdWVzdERPTVVwZGF0ZShjYWxsYmFjayl7XG4gICAgdGhpcy50cmFuc2l0aW9ucy5hZnRlcihjYWxsYmFjaylcbiAgfVxuXG4gIHRyYW5zaXRpb24odGltZSwgb25TdGFydCwgb25Eb25lID0gZnVuY3Rpb24oKXt9KXtcbiAgICB0aGlzLnRyYW5zaXRpb25zLmFkZFRyYW5zaXRpb24odGltZSwgb25TdGFydCwgb25Eb25lKVxuICB9XG5cbiAgb25DaGFubmVsKGNoYW5uZWwsIGV2ZW50LCBjYil7XG4gICAgY2hhbm5lbC5vbihldmVudCwgZGF0YSA9PiB7XG4gICAgICBsZXQgbGF0ZW5jeSA9IHRoaXMuZ2V0TGF0ZW5jeVNpbSgpXG4gICAgICBpZighbGF0ZW5jeSl7XG4gICAgICAgIGNiKGRhdGEpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IGNiKGRhdGEpLCBsYXRlbmN5KVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICB3cmFwUHVzaCh2aWV3LCBvcHRzLCBwdXNoKXtcbiAgICBsZXQgbGF0ZW5jeSA9IHRoaXMuZ2V0TGF0ZW5jeVNpbSgpXG4gICAgbGV0IG9sZEpvaW5Db3VudCA9IHZpZXcuam9pbkNvdW50XG4gICAgaWYoIWxhdGVuY3kpe1xuICAgICAgaWYodGhpcy5pc0Nvbm5lY3RlZCgpICYmIG9wdHMudGltZW91dCl7XG4gICAgICAgIHJldHVybiBwdXNoKCkucmVjZWl2ZShcInRpbWVvdXRcIiwgKCkgPT4ge1xuICAgICAgICAgIGlmKHZpZXcuam9pbkNvdW50ID09PSBvbGRKb2luQ291bnQgJiYgIXZpZXcuaXNEZXN0cm95ZWQoKSl7XG4gICAgICAgICAgICB0aGlzLnJlbG9hZFdpdGhKaXR0ZXIodmlldywgKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmxvZyh2aWV3LCBcInRpbWVvdXRcIiwgKCkgPT4gW1wicmVjZWl2ZWQgdGltZW91dCB3aGlsZSBjb21tdW5pY2F0aW5nIHdpdGggc2VydmVyLiBGYWxsaW5nIGJhY2sgdG8gaGFyZCByZWZyZXNoIGZvciByZWNvdmVyeVwiXSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHB1c2goKVxuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBmYWtlUHVzaCA9IHtcbiAgICAgIHJlY2VpdmVzOiBbXSxcbiAgICAgIHJlY2VpdmUoa2luZCwgY2IpeyB0aGlzLnJlY2VpdmVzLnB1c2goW2tpbmQsIGNiXSkgfVxuICAgIH1cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmKHZpZXcuaXNEZXN0cm95ZWQoKSl7IHJldHVybiB9XG4gICAgICBmYWtlUHVzaC5yZWNlaXZlcy5yZWR1Y2UoKGFjYywgW2tpbmQsIGNiXSkgPT4gYWNjLnJlY2VpdmUoa2luZCwgY2IpLCBwdXNoKCkpXG4gICAgfSwgbGF0ZW5jeSlcbiAgICByZXR1cm4gZmFrZVB1c2hcbiAgfVxuXG4gIHJlbG9hZFdpdGhKaXR0ZXIodmlldywgbG9nKXtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5yZWxvYWRXaXRoSml0dGVyVGltZXIpXG4gICAgdGhpcy5kaXNjb25uZWN0KClcbiAgICBsZXQgbWluTXMgPSB0aGlzLnJlbG9hZEppdHRlck1pblxuICAgIGxldCBtYXhNcyA9IHRoaXMucmVsb2FkSml0dGVyTWF4XG4gICAgbGV0IGFmdGVyTXMgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAobWF4TXMgLSBtaW5NcyArIDEpKSArIG1pbk1zXG4gICAgbGV0IHRyaWVzID0gQnJvd3Nlci51cGRhdGVMb2NhbCh0aGlzLmxvY2FsU3RvcmFnZSwgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLCBDT05TRUNVVElWRV9SRUxPQURTLCAwLCBjb3VudCA9PiBjb3VudCArIDEpXG4gICAgaWYodHJpZXMgPiB0aGlzLm1heFJlbG9hZHMpe1xuICAgICAgYWZ0ZXJNcyA9IHRoaXMuZmFpbHNhZmVKaXR0ZXJcbiAgICB9XG4gICAgdGhpcy5yZWxvYWRXaXRoSml0dGVyVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIC8vIGlmIHZpZXcgaGFzIHJlY292ZXJlZCwgc3VjaCBhcyB0cmFuc3BvcnQgcmVwbGFjZWQsIHRoZW4gY2FuY2VsXG4gICAgICBpZih2aWV3LmlzRGVzdHJveWVkKCkgfHwgdmlldy5pc0Nvbm5lY3RlZCgpKXsgcmV0dXJuIH1cbiAgICAgIHZpZXcuZGVzdHJveSgpXG4gICAgICBsb2cgPyBsb2coKSA6IHRoaXMubG9nKHZpZXcsIFwiam9pblwiLCAoKSA9PiBbYGVuY291bnRlcmVkICR7dHJpZXN9IGNvbnNlY3V0aXZlIHJlbG9hZHNgXSlcbiAgICAgIGlmKHRyaWVzID4gdGhpcy5tYXhSZWxvYWRzKXtcbiAgICAgICAgdGhpcy5sb2codmlldywgXCJqb2luXCIsICgpID0+IFtgZXhjZWVkZWQgJHt0aGlzLm1heFJlbG9hZHN9IGNvbnNlY3V0aXZlIHJlbG9hZHMuIEVudGVyaW5nIGZhaWxzYWZlIG1vZGVgXSlcbiAgICAgIH1cbiAgICAgIGlmKHRoaXMuaGFzUGVuZGluZ0xpbmsoKSl7XG4gICAgICAgIHdpbmRvdy5sb2NhdGlvbiA9IHRoaXMucGVuZGluZ0xpbmtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKVxuICAgICAgfVxuICAgIH0sIGFmdGVyTXMpXG4gIH1cblxuICBnZXRIb29rQ2FsbGJhY2tzKG5hbWUpe1xuICAgIHJldHVybiBuYW1lICYmIG5hbWUuc3RhcnRzV2l0aChcIlBob2VuaXguXCIpID8gSG9va3NbbmFtZS5zcGxpdChcIi5cIilbMV1dIDogdGhpcy5ob29rc1tuYW1lXVxuICB9XG5cbiAgaXNVbmxvYWRlZCgpeyByZXR1cm4gdGhpcy51bmxvYWRlZCB9XG5cbiAgaXNDb25uZWN0ZWQoKXsgcmV0dXJuIHRoaXMuc29ja2V0LmlzQ29ubmVjdGVkKCkgfVxuXG4gIGdldEJpbmRpbmdQcmVmaXgoKXsgcmV0dXJuIHRoaXMuYmluZGluZ1ByZWZpeCB9XG5cbiAgYmluZGluZyhraW5kKXsgcmV0dXJuIGAke3RoaXMuZ2V0QmluZGluZ1ByZWZpeCgpfSR7a2luZH1gIH1cblxuICBjaGFubmVsKHRvcGljLCBwYXJhbXMpeyByZXR1cm4gdGhpcy5zb2NrZXQuY2hhbm5lbCh0b3BpYywgcGFyYW1zKSB9XG5cbiAgam9pbkRlYWRWaWV3KCl7XG4gICAgbGV0IGJvZHkgPSBkb2N1bWVudC5ib2R5XG4gICAgaWYoYm9keSAmJiAhdGhpcy5pc1BoeFZpZXcoYm9keSkgJiYgIXRoaXMuaXNQaHhWaWV3KGRvY3VtZW50LmZpcnN0RWxlbWVudENoaWxkKSl7XG4gICAgICBsZXQgdmlldyA9IHRoaXMubmV3Um9vdFZpZXcoYm9keSlcbiAgICAgIHZpZXcuc2V0SHJlZih0aGlzLmdldEhyZWYoKSlcbiAgICAgIHZpZXcuam9pbkRlYWQoKVxuICAgICAgaWYoIXRoaXMubWFpbil7IHRoaXMubWFpbiA9IHZpZXcgfVxuICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB2aWV3LmV4ZWNOZXdNb3VudGVkKCkpXG4gICAgfVxuICB9XG5cbiAgam9pblJvb3RWaWV3cygpe1xuICAgIGxldCByb290c0ZvdW5kID0gZmFsc2VcbiAgICBET00uYWxsKGRvY3VtZW50LCBgJHtQSFhfVklFV19TRUxFQ1RPUn06bm90KFske1BIWF9QQVJFTlRfSUR9XSlgLCByb290RWwgPT4ge1xuICAgICAgaWYoIXRoaXMuZ2V0Um9vdEJ5SWQocm9vdEVsLmlkKSl7XG4gICAgICAgIGxldCB2aWV3ID0gdGhpcy5uZXdSb290Vmlldyhyb290RWwpXG4gICAgICAgIHZpZXcuc2V0SHJlZih0aGlzLmdldEhyZWYoKSlcbiAgICAgICAgdmlldy5qb2luKClcbiAgICAgICAgaWYocm9vdEVsLmhhc0F0dHJpYnV0ZShQSFhfTUFJTikpeyB0aGlzLm1haW4gPSB2aWV3IH1cbiAgICAgIH1cbiAgICAgIHJvb3RzRm91bmQgPSB0cnVlXG4gICAgfSlcbiAgICByZXR1cm4gcm9vdHNGb3VuZFxuICB9XG5cbiAgcmVkaXJlY3QodG8sIGZsYXNoKXtcbiAgICB0aGlzLnVubG9hZCgpXG4gICAgQnJvd3Nlci5yZWRpcmVjdCh0bywgZmxhc2gpXG4gIH1cblxuICByZXBsYWNlTWFpbihocmVmLCBmbGFzaCwgY2FsbGJhY2sgPSBudWxsLCBsaW5rUmVmID0gdGhpcy5zZXRQZW5kaW5nTGluayhocmVmKSl7XG4gICAgbGV0IGxpdmVSZWZlcmVyID0gdGhpcy5jdXJyZW50TG9jYXRpb24uaHJlZlxuICAgIHRoaXMub3V0Z29pbmdNYWluRWwgPSB0aGlzLm91dGdvaW5nTWFpbkVsIHx8IHRoaXMubWFpbi5lbFxuICAgIGxldCBuZXdNYWluRWwgPSBET00uY2xvbmVOb2RlKHRoaXMub3V0Z29pbmdNYWluRWwsIFwiXCIpXG4gICAgdGhpcy5tYWluLnNob3dMb2FkZXIodGhpcy5sb2FkZXJUaW1lb3V0KVxuICAgIHRoaXMubWFpbi5kZXN0cm95KClcblxuICAgIHRoaXMubWFpbiA9IHRoaXMubmV3Um9vdFZpZXcobmV3TWFpbkVsLCBmbGFzaCwgbGl2ZVJlZmVyZXIpXG4gICAgdGhpcy5tYWluLnNldFJlZGlyZWN0KGhyZWYpXG4gICAgdGhpcy50cmFuc2l0aW9uUmVtb3ZlcyhudWxsLCB0cnVlKVxuICAgIHRoaXMubWFpbi5qb2luKChqb2luQ291bnQsIG9uRG9uZSkgPT4ge1xuICAgICAgaWYoam9pbkNvdW50ID09PSAxICYmIHRoaXMuY29tbWl0UGVuZGluZ0xpbmsobGlua1JlZikpe1xuICAgICAgICB0aGlzLnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICAgIERPTS5maW5kUGh4U3RpY2t5KGRvY3VtZW50KS5mb3JFYWNoKGVsID0+IG5ld01haW5FbC5hcHBlbmRDaGlsZChlbCkpXG4gICAgICAgICAgdGhpcy5vdXRnb2luZ01haW5FbC5yZXBsYWNlV2l0aChuZXdNYWluRWwpXG4gICAgICAgICAgdGhpcy5vdXRnb2luZ01haW5FbCA9IG51bGxcbiAgICAgICAgICBjYWxsYmFjayAmJiBjYWxsYmFjayhsaW5rUmVmKVxuICAgICAgICAgIG9uRG9uZSgpXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIHRyYW5zaXRpb25SZW1vdmVzKGVsZW1lbnRzLCBza2lwU3RpY2t5KXtcbiAgICBsZXQgcmVtb3ZlQXR0ciA9IHRoaXMuYmluZGluZyhcInJlbW92ZVwiKVxuICAgIGVsZW1lbnRzID0gZWxlbWVudHMgfHwgRE9NLmFsbChkb2N1bWVudCwgYFske3JlbW92ZUF0dHJ9XWApXG5cbiAgICBpZihza2lwU3RpY2t5KXtcbiAgICAgIGNvbnN0IHN0aWNraWVzID0gRE9NLmZpbmRQaHhTdGlja3koZG9jdW1lbnQpIHx8IFtdXG4gICAgICBlbGVtZW50cyA9IGVsZW1lbnRzLmZpbHRlcihlbCA9PiAhRE9NLmlzQ2hpbGRPZkFueShlbCwgc3RpY2tpZXMpKVxuICAgIH1cbiAgICBlbGVtZW50cy5mb3JFYWNoKGVsID0+IHtcbiAgICAgIHRoaXMuZXhlY0pTKGVsLCBlbC5nZXRBdHRyaWJ1dGUocmVtb3ZlQXR0ciksIFwicmVtb3ZlXCIpXG4gICAgfSlcbiAgfVxuXG4gIGlzUGh4VmlldyhlbCl7IHJldHVybiBlbC5nZXRBdHRyaWJ1dGUgJiYgZWwuZ2V0QXR0cmlidXRlKFBIWF9TRVNTSU9OKSAhPT0gbnVsbCB9XG5cbiAgbmV3Um9vdFZpZXcoZWwsIGZsYXNoLCBsaXZlUmVmZXJlcil7XG4gICAgbGV0IHZpZXcgPSBuZXcgVmlldyhlbCwgdGhpcywgbnVsbCwgZmxhc2gsIGxpdmVSZWZlcmVyKVxuICAgIHRoaXMucm9vdHNbdmlldy5pZF0gPSB2aWV3XG4gICAgcmV0dXJuIHZpZXdcbiAgfVxuXG4gIG93bmVyKGNoaWxkRWwsIGNhbGxiYWNrKXtcbiAgICBsZXQgdmlldyA9IG1heWJlKGNoaWxkRWwuY2xvc2VzdChQSFhfVklFV19TRUxFQ1RPUiksIGVsID0+IHRoaXMuZ2V0Vmlld0J5RWwoZWwpKSB8fCB0aGlzLm1haW5cbiAgICBpZih2aWV3KXsgY2FsbGJhY2sodmlldykgfVxuICB9XG5cbiAgd2l0aGluT3duZXJzKGNoaWxkRWwsIGNhbGxiYWNrKXtcbiAgICB0aGlzLm93bmVyKGNoaWxkRWwsIHZpZXcgPT4gY2FsbGJhY2sodmlldywgY2hpbGRFbCkpXG4gIH1cblxuICBnZXRWaWV3QnlFbChlbCl7XG4gICAgbGV0IHJvb3RJZCA9IGVsLmdldEF0dHJpYnV0ZShQSFhfUk9PVF9JRClcbiAgICByZXR1cm4gbWF5YmUodGhpcy5nZXRSb290QnlJZChyb290SWQpLCByb290ID0+IHJvb3QuZ2V0RGVzY2VuZGVudEJ5RWwoZWwpKVxuICB9XG5cbiAgZ2V0Um9vdEJ5SWQoaWQpeyByZXR1cm4gdGhpcy5yb290c1tpZF0gfVxuXG4gIGRlc3Ryb3lBbGxWaWV3cygpe1xuICAgIGZvcihsZXQgaWQgaW4gdGhpcy5yb290cyl7XG4gICAgICB0aGlzLnJvb3RzW2lkXS5kZXN0cm95KClcbiAgICAgIGRlbGV0ZSB0aGlzLnJvb3RzW2lkXVxuICAgIH1cbiAgICB0aGlzLm1haW4gPSBudWxsXG4gIH1cblxuICBkZXN0cm95Vmlld0J5RWwoZWwpe1xuICAgIGxldCByb290ID0gdGhpcy5nZXRSb290QnlJZChlbC5nZXRBdHRyaWJ1dGUoUEhYX1JPT1RfSUQpKVxuICAgIGlmKHJvb3QgJiYgcm9vdC5pZCA9PT0gZWwuaWQpe1xuICAgICAgcm9vdC5kZXN0cm95KClcbiAgICAgIGRlbGV0ZSB0aGlzLnJvb3RzW3Jvb3QuaWRdXG4gICAgfSBlbHNlIGlmKHJvb3Qpe1xuICAgICAgcm9vdC5kZXN0cm95RGVzY2VuZGVudChlbC5pZClcbiAgICB9XG4gIH1cblxuICBzZXRBY3RpdmVFbGVtZW50KHRhcmdldCl7XG4gICAgaWYodGhpcy5hY3RpdmVFbGVtZW50ID09PSB0YXJnZXQpeyByZXR1cm4gfVxuICAgIHRoaXMuYWN0aXZlRWxlbWVudCA9IHRhcmdldFxuICAgIGxldCBjYW5jZWwgPSAoKSA9PiB7XG4gICAgICBpZih0YXJnZXQgPT09IHRoaXMuYWN0aXZlRWxlbWVudCl7IHRoaXMuYWN0aXZlRWxlbWVudCA9IG51bGwgfVxuICAgICAgdGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIHRoaXMpXG4gICAgICB0YXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsIHRoaXMpXG4gICAgfVxuICAgIHRhcmdldC5hZGRFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCBjYW5jZWwpXG4gICAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCBjYW5jZWwpXG4gIH1cblxuICBnZXRBY3RpdmVFbGVtZW50KCl7XG4gICAgaWYoZG9jdW1lbnQuYWN0aXZlRWxlbWVudCA9PT0gZG9jdW1lbnQuYm9keSl7XG4gICAgICByZXR1cm4gdGhpcy5hY3RpdmVFbGVtZW50IHx8IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnRcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCBjYW4gYmUgbnVsbCBpbiBJbnRlcm5ldCBFeHBsb3JlciAxMVxuICAgICAgcmV0dXJuIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgfHwgZG9jdW1lbnQuYm9keVxuICAgIH1cbiAgfVxuXG4gIGRyb3BBY3RpdmVFbGVtZW50KHZpZXcpe1xuICAgIGlmKHRoaXMucHJldkFjdGl2ZSAmJiB2aWV3Lm93bnNFbGVtZW50KHRoaXMucHJldkFjdGl2ZSkpe1xuICAgICAgdGhpcy5wcmV2QWN0aXZlID0gbnVsbFxuICAgIH1cbiAgfVxuXG4gIHJlc3RvcmVQcmV2aW91c2x5QWN0aXZlRm9jdXMoKXtcbiAgICBpZih0aGlzLnByZXZBY3RpdmUgJiYgdGhpcy5wcmV2QWN0aXZlICE9PSBkb2N1bWVudC5ib2R5KXtcbiAgICAgIHRoaXMucHJldkFjdGl2ZS5mb2N1cygpXG4gICAgfVxuICB9XG5cbiAgYmx1ckFjdGl2ZUVsZW1lbnQoKXtcbiAgICB0aGlzLnByZXZBY3RpdmUgPSB0aGlzLmdldEFjdGl2ZUVsZW1lbnQoKVxuICAgIGlmKHRoaXMucHJldkFjdGl2ZSAhPT0gZG9jdW1lbnQuYm9keSl7IHRoaXMucHJldkFjdGl2ZS5ibHVyKCkgfVxuICB9XG5cbiAgYmluZFRvcExldmVsRXZlbnRzKHtkZWFkfSA9IHt9KXtcbiAgICBpZih0aGlzLmJvdW5kVG9wTGV2ZWxFdmVudHMpeyByZXR1cm4gfVxuXG4gICAgdGhpcy5ib3VuZFRvcExldmVsRXZlbnRzID0gdHJ1ZVxuICAgIC8vIGVudGVyIGZhaWxzYWZlIHJlbG9hZCBpZiBzZXJ2ZXIgaGFzIGdvbmUgYXdheSBpbnRlbnRpb25hbGx5LCBzdWNoIGFzIFwiZGlzY29ubmVjdFwiIGJyb2FkY2FzdFxuICAgIHRoaXMuc2VydmVyQ2xvc2VSZWYgPSB0aGlzLnNvY2tldC5vbkNsb3NlKGV2ZW50ID0+IHtcbiAgICAgIC8vIGZhaWxzYWZlIHJlbG9hZCBpZiBub3JtYWwgY2xvc3VyZSBhbmQgd2Ugc3RpbGwgaGF2ZSBhIG1haW4gTFZcbiAgICAgIGlmKGV2ZW50ICYmIGV2ZW50LmNvZGUgPT09IDEwMDAgJiYgdGhpcy5tYWluKXsgcmV0dXJuIHRoaXMucmVsb2FkV2l0aEppdHRlcih0aGlzLm1haW4pIH1cbiAgICB9KVxuICAgIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIGZ1bmN0aW9uICgpeyB9KSAvLyBlbnN1cmUgYWxsIGNsaWNrIGV2ZW50cyBidWJibGUgZm9yIG1vYmlsZSBTYWZhcmlcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBhZ2VzaG93XCIsIGUgPT4ge1xuICAgICAgaWYoZS5wZXJzaXN0ZWQpeyAvLyByZWxvYWQgcGFnZSBpZiBiZWluZyByZXN0b3JlZCBmcm9tIGJhY2svZm9yd2FyZCBjYWNoZVxuICAgICAgICB0aGlzLmdldFNvY2tldCgpLmRpc2Nvbm5lY3QoKVxuICAgICAgICB0aGlzLndpdGhQYWdlTG9hZGluZyh7dG86IHdpbmRvdy5sb2NhdGlvbi5ocmVmLCBraW5kOiBcInJlZGlyZWN0XCJ9KVxuICAgICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKClcbiAgICAgIH1cbiAgICB9LCB0cnVlKVxuICAgIGlmKCFkZWFkKXsgdGhpcy5iaW5kTmF2KCkgfVxuICAgIHRoaXMuYmluZENsaWNrcygpXG4gICAgaWYoIWRlYWQpeyB0aGlzLmJpbmRGb3JtcygpIH1cbiAgICB0aGlzLmJpbmQoe2tleXVwOiBcImtleXVwXCIsIGtleWRvd246IFwia2V5ZG93blwifSwgKGUsIHR5cGUsIHZpZXcsIHRhcmdldEVsLCBwaHhFdmVudCwgcGh4VGFyZ2V0KSA9PiB7XG4gICAgICBsZXQgbWF0Y2hLZXkgPSB0YXJnZXRFbC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFBIWF9LRVkpKVxuICAgICAgbGV0IHByZXNzZWRLZXkgPSBlLmtleSAmJiBlLmtleS50b0xvd2VyQ2FzZSgpIC8vIGNocm9tZSBjbGlja2VkIGF1dG9jb21wbGV0ZXMgc2VuZCBhIGtleWRvd24gd2l0aG91dCBrZXlcbiAgICAgIGlmKG1hdGNoS2V5ICYmIG1hdGNoS2V5LnRvTG93ZXJDYXNlKCkgIT09IHByZXNzZWRLZXkpeyByZXR1cm4gfVxuXG4gICAgICBsZXQgZGF0YSA9IHtrZXk6IGUua2V5LCAuLi50aGlzLmV2ZW50TWV0YSh0eXBlLCBlLCB0YXJnZXRFbCl9XG4gICAgICBKUy5leGVjKHR5cGUsIHBoeEV2ZW50LCB2aWV3LCB0YXJnZXRFbCwgW1wicHVzaFwiLCB7ZGF0YX1dKVxuICAgIH0pXG4gICAgdGhpcy5iaW5kKHtibHVyOiBcImZvY3Vzb3V0XCIsIGZvY3VzOiBcImZvY3VzaW5cIn0sIChlLCB0eXBlLCB2aWV3LCB0YXJnZXRFbCwgcGh4RXZlbnQsIHBoeFRhcmdldCkgPT4ge1xuICAgICAgaWYoIXBoeFRhcmdldCl7XG4gICAgICAgIGxldCBkYXRhID0ge2tleTogZS5rZXksIC4uLnRoaXMuZXZlbnRNZXRhKHR5cGUsIGUsIHRhcmdldEVsKX1cbiAgICAgICAgSlMuZXhlYyh0eXBlLCBwaHhFdmVudCwgdmlldywgdGFyZ2V0RWwsIFtcInB1c2hcIiwge2RhdGF9XSlcbiAgICAgIH1cbiAgICB9KVxuICAgIHRoaXMuYmluZCh7Ymx1cjogXCJibHVyXCIsIGZvY3VzOiBcImZvY3VzXCJ9LCAoZSwgdHlwZSwgdmlldywgdGFyZ2V0RWwsIHBoeEV2ZW50LCBwaHhUYXJnZXQpID0+IHtcbiAgICAgIC8vIGJsdXIgYW5kIGZvY3VzIGFyZSB0cmlnZ2VyZWQgb24gZG9jdW1lbnQgYW5kIHdpbmRvdy4gRGlzY2FyZCBvbmUgdG8gYXZvaWQgZHVwc1xuICAgICAgaWYocGh4VGFyZ2V0ID09PSBcIndpbmRvd1wiKXtcbiAgICAgICAgbGV0IGRhdGEgPSB0aGlzLmV2ZW50TWV0YSh0eXBlLCBlLCB0YXJnZXRFbClcbiAgICAgICAgSlMuZXhlYyh0eXBlLCBwaHhFdmVudCwgdmlldywgdGFyZ2V0RWwsIFtcInB1c2hcIiwge2RhdGF9XSlcbiAgICAgIH1cbiAgICB9KVxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiZHJhZ292ZXJcIiwgZSA9PiBlLnByZXZlbnREZWZhdWx0KCkpXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJkcm9wXCIsIGUgPT4ge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICBsZXQgZHJvcFRhcmdldElkID0gbWF5YmUoY2xvc2VzdFBoeEJpbmRpbmcoZS50YXJnZXQsIHRoaXMuYmluZGluZyhQSFhfRFJPUF9UQVJHRVQpKSwgdHJ1ZVRhcmdldCA9PiB7XG4gICAgICAgIHJldHVybiB0cnVlVGFyZ2V0LmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoUEhYX0RST1BfVEFSR0VUKSlcbiAgICAgIH0pXG4gICAgICBsZXQgZHJvcFRhcmdldCA9IGRyb3BUYXJnZXRJZCAmJiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChkcm9wVGFyZ2V0SWQpXG4gICAgICBsZXQgZmlsZXMgPSBBcnJheS5mcm9tKGUuZGF0YVRyYW5zZmVyLmZpbGVzIHx8IFtdKVxuICAgICAgaWYoIWRyb3BUYXJnZXQgfHwgZHJvcFRhcmdldC5kaXNhYmxlZCB8fCBmaWxlcy5sZW5ndGggPT09IDAgfHwgIShkcm9wVGFyZ2V0LmZpbGVzIGluc3RhbmNlb2YgRmlsZUxpc3QpKXsgcmV0dXJuIH1cblxuICAgICAgTGl2ZVVwbG9hZGVyLnRyYWNrRmlsZXMoZHJvcFRhcmdldCwgZmlsZXMsIGUuZGF0YVRyYW5zZmVyKVxuICAgICAgZHJvcFRhcmdldC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImlucHV0XCIsIHtidWJibGVzOiB0cnVlfSkpXG4gICAgfSlcbiAgICB0aGlzLm9uKFBIWF9UUkFDS19VUExPQURTLCBlID0+IHtcbiAgICAgIGxldCB1cGxvYWRUYXJnZXQgPSBlLnRhcmdldFxuICAgICAgaWYoIURPTS5pc1VwbG9hZElucHV0KHVwbG9hZFRhcmdldCkpeyByZXR1cm4gfVxuICAgICAgbGV0IGZpbGVzID0gQXJyYXkuZnJvbShlLmRldGFpbC5maWxlcyB8fCBbXSkuZmlsdGVyKGYgPT4gZiBpbnN0YW5jZW9mIEZpbGUgfHwgZiBpbnN0YW5jZW9mIEJsb2IpXG4gICAgICBMaXZlVXBsb2FkZXIudHJhY2tGaWxlcyh1cGxvYWRUYXJnZXQsIGZpbGVzKVxuICAgICAgdXBsb2FkVGFyZ2V0LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwiaW5wdXRcIiwge2J1YmJsZXM6IHRydWV9KSlcbiAgICB9KVxuICB9XG5cbiAgZXZlbnRNZXRhKGV2ZW50TmFtZSwgZSwgdGFyZ2V0RWwpe1xuICAgIGxldCBjYWxsYmFjayA9IHRoaXMubWV0YWRhdGFDYWxsYmFja3NbZXZlbnROYW1lXVxuICAgIHJldHVybiBjYWxsYmFjayA/IGNhbGxiYWNrKGUsIHRhcmdldEVsKSA6IHt9XG4gIH1cblxuICBzZXRQZW5kaW5nTGluayhocmVmKXtcbiAgICB0aGlzLmxpbmtSZWYrK1xuICAgIHRoaXMucGVuZGluZ0xpbmsgPSBocmVmXG4gICAgcmV0dXJuIHRoaXMubGlua1JlZlxuICB9XG5cbiAgY29tbWl0UGVuZGluZ0xpbmsobGlua1JlZil7XG4gICAgaWYodGhpcy5saW5rUmVmICE9PSBsaW5rUmVmKXtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmhyZWYgPSB0aGlzLnBlbmRpbmdMaW5rXG4gICAgICB0aGlzLnBlbmRpbmdMaW5rID0gbnVsbFxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cblxuICBnZXRIcmVmKCl7IHJldHVybiB0aGlzLmhyZWYgfVxuXG4gIGhhc1BlbmRpbmdMaW5rKCl7IHJldHVybiAhIXRoaXMucGVuZGluZ0xpbmsgfVxuXG4gIGJpbmQoZXZlbnRzLCBjYWxsYmFjayl7XG4gICAgZm9yKGxldCBldmVudCBpbiBldmVudHMpe1xuICAgICAgbGV0IGJyb3dzZXJFdmVudE5hbWUgPSBldmVudHNbZXZlbnRdXG5cbiAgICAgIHRoaXMub24oYnJvd3NlckV2ZW50TmFtZSwgZSA9PiB7XG4gICAgICAgIGxldCBiaW5kaW5nID0gdGhpcy5iaW5kaW5nKGV2ZW50KVxuICAgICAgICBsZXQgd2luZG93QmluZGluZyA9IHRoaXMuYmluZGluZyhgd2luZG93LSR7ZXZlbnR9YClcbiAgICAgICAgbGV0IHRhcmdldFBoeEV2ZW50ID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlICYmIGUudGFyZ2V0LmdldEF0dHJpYnV0ZShiaW5kaW5nKVxuICAgICAgICBpZih0YXJnZXRQaHhFdmVudCl7XG4gICAgICAgICAgdGhpcy5kZWJvdW5jZShlLnRhcmdldCwgZSwgYnJvd3NlckV2ZW50TmFtZSwgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy53aXRoaW5Pd25lcnMoZS50YXJnZXQsIHZpZXcgPT4ge1xuICAgICAgICAgICAgICBjYWxsYmFjayhlLCBldmVudCwgdmlldywgZS50YXJnZXQsIHRhcmdldFBoeEV2ZW50LCBudWxsKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIERPTS5hbGwoZG9jdW1lbnQsIGBbJHt3aW5kb3dCaW5kaW5nfV1gLCBlbCA9PiB7XG4gICAgICAgICAgICBsZXQgcGh4RXZlbnQgPSBlbC5nZXRBdHRyaWJ1dGUod2luZG93QmluZGluZylcbiAgICAgICAgICAgIHRoaXMuZGVib3VuY2UoZWwsIGUsIGJyb3dzZXJFdmVudE5hbWUsICgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy53aXRoaW5Pd25lcnMoZWwsIHZpZXcgPT4ge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGUsIGV2ZW50LCB2aWV3LCBlbCwgcGh4RXZlbnQsIFwid2luZG93XCIpXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgYmluZENsaWNrcygpe1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vkb3duXCIsIGUgPT4gdGhpcy5jbGlja1N0YXJ0ZWRBdFRhcmdldCA9IGUudGFyZ2V0KVxuICAgIHRoaXMuYmluZENsaWNrKFwiY2xpY2tcIiwgXCJjbGlja1wiKVxuICB9XG5cbiAgYmluZENsaWNrKGV2ZW50TmFtZSwgYmluZGluZ05hbWUpe1xuICAgIGxldCBjbGljayA9IHRoaXMuYmluZGluZyhiaW5kaW5nTmFtZSlcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGUgPT4ge1xuICAgICAgbGV0IHRhcmdldCA9IG51bGxcbiAgICAgIC8vIGEgc3ludGhldGljIGNsaWNrIGV2ZW50IChkZXRhaWwgMCkgd2lsbCBub3QgaGF2ZSBjYXVzZWQgYSBtb3VzZWRvd24gZXZlbnQsXG4gICAgICAvLyB0aGVyZWZvcmUgdGhlIGNsaWNrU3RhcnRlZEF0VGFyZ2V0IGlzIHN0YWxlXG4gICAgICBpZihlLmRldGFpbCA9PT0gMCkgdGhpcy5jbGlja1N0YXJ0ZWRBdFRhcmdldCA9IGUudGFyZ2V0XG4gICAgICBsZXQgY2xpY2tTdGFydGVkQXRUYXJnZXQgPSB0aGlzLmNsaWNrU3RhcnRlZEF0VGFyZ2V0IHx8IGUudGFyZ2V0XG4gICAgICB0YXJnZXQgPSBjbG9zZXN0UGh4QmluZGluZyhjbGlja1N0YXJ0ZWRBdFRhcmdldCwgY2xpY2spXG4gICAgICB0aGlzLmRpc3BhdGNoQ2xpY2tBd2F5KGUsIGNsaWNrU3RhcnRlZEF0VGFyZ2V0KVxuICAgICAgdGhpcy5jbGlja1N0YXJ0ZWRBdFRhcmdldCA9IG51bGxcbiAgICAgIGxldCBwaHhFdmVudCA9IHRhcmdldCAmJiB0YXJnZXQuZ2V0QXR0cmlidXRlKGNsaWNrKVxuICAgICAgaWYoIXBoeEV2ZW50KXtcbiAgICAgICAgaWYoRE9NLmlzTmV3UGFnZUNsaWNrKGUsIHdpbmRvdy5sb2NhdGlvbikpeyB0aGlzLnVubG9hZCgpIH1cbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGlmKHRhcmdldC5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpID09PSBcIiNcIil7IGUucHJldmVudERlZmF1bHQoKSB9XG5cbiAgICAgIC8vIG5vb3AgaWYgd2UgYXJlIGluIHRoZSBtaWRkbGUgb2YgYXdhaXRpbmcgYW4gYWNrIGZvciB0aGlzIGVsIGFscmVhZHlcbiAgICAgIGlmKHRhcmdldC5oYXNBdHRyaWJ1dGUoUEhYX1JFRikpeyByZXR1cm4gfVxuXG4gICAgICB0aGlzLmRlYm91bmNlKHRhcmdldCwgZSwgXCJjbGlja1wiLCAoKSA9PiB7XG4gICAgICAgIHRoaXMud2l0aGluT3duZXJzKHRhcmdldCwgdmlldyA9PiB7XG4gICAgICAgICAgSlMuZXhlYyhcImNsaWNrXCIsIHBoeEV2ZW50LCB2aWV3LCB0YXJnZXQsIFtcInB1c2hcIiwge2RhdGE6IHRoaXMuZXZlbnRNZXRhKFwiY2xpY2tcIiwgZSwgdGFyZ2V0KX1dKVxuICAgICAgICB9KVxuICAgICAgfSlcbiAgICB9LCBmYWxzZSlcbiAgfVxuXG4gIGRpc3BhdGNoQ2xpY2tBd2F5KGUsIGNsaWNrU3RhcnRlZEF0KXtcbiAgICBsZXQgcGh4Q2xpY2tBd2F5ID0gdGhpcy5iaW5kaW5nKFwiY2xpY2stYXdheVwiKVxuICAgIERPTS5hbGwoZG9jdW1lbnQsIGBbJHtwaHhDbGlja0F3YXl9XWAsIGVsID0+IHtcbiAgICAgIGlmKCEoZWwuaXNTYW1lTm9kZShjbGlja1N0YXJ0ZWRBdCkgfHwgZWwuY29udGFpbnMoY2xpY2tTdGFydGVkQXQpKSl7XG4gICAgICAgIHRoaXMud2l0aGluT3duZXJzKGVsLCB2aWV3ID0+IHtcbiAgICAgICAgICBsZXQgcGh4RXZlbnQgPSBlbC5nZXRBdHRyaWJ1dGUocGh4Q2xpY2tBd2F5KVxuICAgICAgICAgIGlmKEpTLmlzVmlzaWJsZShlbCkgJiYgSlMuaXNJblZpZXdwb3J0KGVsKSl7XG4gICAgICAgICAgICBKUy5leGVjKFwiY2xpY2tcIiwgcGh4RXZlbnQsIHZpZXcsIGVsLCBbXCJwdXNoXCIsIHtkYXRhOiB0aGlzLmV2ZW50TWV0YShcImNsaWNrXCIsIGUsIGUudGFyZ2V0KX1dKVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgYmluZE5hdigpe1xuICAgIGlmKCFCcm93c2VyLmNhblB1c2hTdGF0ZSgpKXsgcmV0dXJuIH1cbiAgICBpZihoaXN0b3J5LnNjcm9sbFJlc3RvcmF0aW9uKXsgaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbiA9IFwibWFudWFsXCIgfVxuICAgIGxldCBzY3JvbGxUaW1lciA9IG51bGxcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInNjcm9sbFwiLCBfZSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQoc2Nyb2xsVGltZXIpXG4gICAgICBzY3JvbGxUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBCcm93c2VyLnVwZGF0ZUN1cnJlbnRTdGF0ZShzdGF0ZSA9PiBPYmplY3QuYXNzaWduKHN0YXRlLCB7c2Nyb2xsOiB3aW5kb3cuc2Nyb2xsWX0pKVxuICAgICAgfSwgMTAwKVxuICAgIH0pXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJwb3BzdGF0ZVwiLCBldmVudCA9PiB7XG4gICAgICBpZighdGhpcy5yZWdpc3Rlck5ld0xvY2F0aW9uKHdpbmRvdy5sb2NhdGlvbikpeyByZXR1cm4gfVxuICAgICAgbGV0IHt0eXBlLCBpZCwgcm9vdCwgc2Nyb2xsfSA9IGV2ZW50LnN0YXRlIHx8IHt9XG4gICAgICBsZXQgaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmXG5cbiAgICAgIERPTS5kaXNwYXRjaEV2ZW50KHdpbmRvdywgXCJwaHg6bmF2aWdhdGVcIiwge2RldGFpbDoge2hyZWYsIHBhdGNoOiB0eXBlID09PSBcInBhdGNoXCIsIHBvcDogdHJ1ZX19KVxuICAgICAgdGhpcy5yZXF1ZXN0RE9NVXBkYXRlKCgpID0+IHtcbiAgICAgICAgaWYodGhpcy5tYWluLmlzQ29ubmVjdGVkKCkgJiYgKHR5cGUgPT09IFwicGF0Y2hcIiAmJiBpZCA9PT0gdGhpcy5tYWluLmlkKSl7XG4gICAgICAgICAgdGhpcy5tYWluLnB1c2hMaW5rUGF0Y2goaHJlZiwgbnVsbCwgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5tYXliZVNjcm9sbChzY3JvbGwpXG4gICAgICAgICAgfSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnJlcGxhY2VNYWluKGhyZWYsIG51bGwsICgpID0+IHtcbiAgICAgICAgICAgIGlmKHJvb3QpeyB0aGlzLnJlcGxhY2VSb290SGlzdG9yeSgpIH1cbiAgICAgICAgICAgIHRoaXMubWF5YmVTY3JvbGwoc2Nyb2xsKVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfSwgZmFsc2UpXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBlID0+IHtcbiAgICAgIGxldCB0YXJnZXQgPSBjbG9zZXN0UGh4QmluZGluZyhlLnRhcmdldCwgUEhYX0xJVkVfTElOSylcbiAgICAgIGxldCB0eXBlID0gdGFyZ2V0ICYmIHRhcmdldC5nZXRBdHRyaWJ1dGUoUEhYX0xJVkVfTElOSylcbiAgICAgIGlmKCF0eXBlIHx8ICF0aGlzLmlzQ29ubmVjdGVkKCkgfHwgIXRoaXMubWFpbiB8fCBET00ud2FudHNOZXdUYWIoZSkpeyByZXR1cm4gfVxuXG4gICAgICAvLyBXaGVuIHdyYXBwaW5nIGFuIFNWRyBlbGVtZW50IGluIGFuIGFuY2hvciB0YWcsIHRoZSBocmVmIGNhbiBiZSBhbiBTVkdBbmltYXRlZFN0cmluZ1xuICAgICAgbGV0IGhyZWYgPSB0YXJnZXQuaHJlZiBpbnN0YW5jZW9mIFNWR0FuaW1hdGVkU3RyaW5nID8gdGFyZ2V0LmhyZWYuYmFzZVZhbCA6IHRhcmdldC5ocmVmXG5cbiAgICAgIGxldCBsaW5rU3RhdGUgPSB0YXJnZXQuZ2V0QXR0cmlidXRlKFBIWF9MSU5LX1NUQVRFKVxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpIC8vIGRvIG5vdCBidWJibGUgY2xpY2sgdG8gcmVndWxhciBwaHgtY2xpY2sgYmluZGluZ3NcbiAgICAgIGlmKHRoaXMucGVuZGluZ0xpbmsgPT09IGhyZWYpeyByZXR1cm4gfVxuXG4gICAgICB0aGlzLnJlcXVlc3RET01VcGRhdGUoKCkgPT4ge1xuICAgICAgICBpZih0eXBlID09PSBcInBhdGNoXCIpe1xuICAgICAgICAgIHRoaXMucHVzaEhpc3RvcnlQYXRjaChocmVmLCBsaW5rU3RhdGUsIHRhcmdldClcbiAgICAgICAgfSBlbHNlIGlmKHR5cGUgPT09IFwicmVkaXJlY3RcIil7XG4gICAgICAgICAgdGhpcy5oaXN0b3J5UmVkaXJlY3QoaHJlZiwgbGlua1N0YXRlKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZXhwZWN0ZWQgJHtQSFhfTElWRV9MSU5LfSB0byBiZSBcInBhdGNoXCIgb3IgXCJyZWRpcmVjdFwiLCBnb3Q6ICR7dHlwZX1gKVxuICAgICAgICB9XG4gICAgICAgIGxldCBwaHhDbGljayA9IHRhcmdldC5nZXRBdHRyaWJ1dGUodGhpcy5iaW5kaW5nKFwiY2xpY2tcIikpXG4gICAgICAgIGlmKHBoeENsaWNrKXtcbiAgICAgICAgICB0aGlzLnJlcXVlc3RET01VcGRhdGUoKCkgPT4gdGhpcy5leGVjSlModGFyZ2V0LCBwaHhDbGljaywgXCJjbGlja1wiKSlcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9LCBmYWxzZSlcbiAgfVxuXG4gIG1heWJlU2Nyb2xsKHNjcm9sbCl7XG4gICAgaWYodHlwZW9mKHNjcm9sbCkgPT09IFwibnVtYmVyXCIpe1xuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgd2luZG93LnNjcm9sbFRvKDAsIHNjcm9sbClcbiAgICAgIH0pIC8vIHRoZSBib2R5IG5lZWRzIHRvIHJlbmRlciBiZWZvcmUgd2Ugc2Nyb2xsLlxuICAgIH1cbiAgfVxuXG4gIGRpc3BhdGNoRXZlbnQoZXZlbnQsIHBheWxvYWQgPSB7fSl7XG4gICAgRE9NLmRpc3BhdGNoRXZlbnQod2luZG93LCBgcGh4OiR7ZXZlbnR9YCwge2RldGFpbDogcGF5bG9hZH0pXG4gIH1cblxuICBkaXNwYXRjaEV2ZW50cyhldmVudHMpe1xuICAgIGV2ZW50cy5mb3JFYWNoKChbZXZlbnQsIHBheWxvYWRdKSA9PiB0aGlzLmRpc3BhdGNoRXZlbnQoZXZlbnQsIHBheWxvYWQpKVxuICB9XG5cbiAgd2l0aFBhZ2VMb2FkaW5nKGluZm8sIGNhbGxiYWNrKXtcbiAgICBET00uZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4OnBhZ2UtbG9hZGluZy1zdGFydFwiLCB7ZGV0YWlsOiBpbmZvfSlcbiAgICBsZXQgZG9uZSA9ICgpID0+IERPTS5kaXNwYXRjaEV2ZW50KHdpbmRvdywgXCJwaHg6cGFnZS1sb2FkaW5nLXN0b3BcIiwge2RldGFpbDogaW5mb30pXG4gICAgcmV0dXJuIGNhbGxiYWNrID8gY2FsbGJhY2soZG9uZSkgOiBkb25lXG4gIH1cblxuICBwdXNoSGlzdG9yeVBhdGNoKGhyZWYsIGxpbmtTdGF0ZSwgdGFyZ2V0RWwpe1xuICAgIGlmKCF0aGlzLmlzQ29ubmVjdGVkKCkgfHwgIXRoaXMubWFpbi5pc01haW4oKSl7IHJldHVybiBCcm93c2VyLnJlZGlyZWN0KGhyZWYpIH1cblxuICAgIHRoaXMud2l0aFBhZ2VMb2FkaW5nKHt0bzogaHJlZiwga2luZDogXCJwYXRjaFwifSwgZG9uZSA9PiB7XG4gICAgICB0aGlzLm1haW4ucHVzaExpbmtQYXRjaChocmVmLCB0YXJnZXRFbCwgbGlua1JlZiA9PiB7XG4gICAgICAgIHRoaXMuaGlzdG9yeVBhdGNoKGhyZWYsIGxpbmtTdGF0ZSwgbGlua1JlZilcbiAgICAgICAgZG9uZSgpXG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICBoaXN0b3J5UGF0Y2goaHJlZiwgbGlua1N0YXRlLCBsaW5rUmVmID0gdGhpcy5zZXRQZW5kaW5nTGluayhocmVmKSl7XG4gICAgaWYoIXRoaXMuY29tbWl0UGVuZGluZ0xpbmsobGlua1JlZikpeyByZXR1cm4gfVxuXG4gICAgQnJvd3Nlci5wdXNoU3RhdGUobGlua1N0YXRlLCB7dHlwZTogXCJwYXRjaFwiLCBpZDogdGhpcy5tYWluLmlkfSwgaHJlZilcbiAgICBET00uZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4Om5hdmlnYXRlXCIsIHtkZXRhaWw6IHtwYXRjaDogdHJ1ZSwgaHJlZiwgcG9wOiBmYWxzZX19KVxuICAgIHRoaXMucmVnaXN0ZXJOZXdMb2NhdGlvbih3aW5kb3cubG9jYXRpb24pXG4gIH1cblxuICBoaXN0b3J5UmVkaXJlY3QoaHJlZiwgbGlua1N0YXRlLCBmbGFzaCl7XG4gICAgaWYoIXRoaXMuaXNDb25uZWN0ZWQoKSB8fCAhdGhpcy5tYWluLmlzTWFpbigpKXsgcmV0dXJuIEJyb3dzZXIucmVkaXJlY3QoaHJlZiwgZmxhc2gpIH1cblxuICAgIC8vIGNvbnZlcnQgdG8gZnVsbCBocmVmIGlmIG9ubHkgcGF0aCBwcmVmaXhcbiAgICBpZigvXlxcLyR8XlxcL1teXFwvXSsuKiQvLnRlc3QoaHJlZikpe1xuICAgICAgbGV0IHtwcm90b2NvbCwgaG9zdH0gPSB3aW5kb3cubG9jYXRpb25cbiAgICAgIGhyZWYgPSBgJHtwcm90b2NvbH0vLyR7aG9zdH0ke2hyZWZ9YFxuICAgIH1cbiAgICBsZXQgc2Nyb2xsID0gd2luZG93LnNjcm9sbFlcbiAgICB0aGlzLndpdGhQYWdlTG9hZGluZyh7dG86IGhyZWYsIGtpbmQ6IFwicmVkaXJlY3RcIn0sIGRvbmUgPT4ge1xuICAgICAgdGhpcy5yZXBsYWNlTWFpbihocmVmLCBmbGFzaCwgKGxpbmtSZWYpID0+IHtcbiAgICAgICAgaWYobGlua1JlZiA9PT0gdGhpcy5saW5rUmVmKXtcbiAgICAgICAgICBCcm93c2VyLnB1c2hTdGF0ZShsaW5rU3RhdGUsIHt0eXBlOiBcInJlZGlyZWN0XCIsIGlkOiB0aGlzLm1haW4uaWQsIHNjcm9sbDogc2Nyb2xsfSwgaHJlZilcbiAgICAgICAgICBET00uZGlzcGF0Y2hFdmVudCh3aW5kb3csIFwicGh4Om5hdmlnYXRlXCIsIHtkZXRhaWw6IHtocmVmLCBwYXRjaDogZmFsc2UsIHBvcDogZmFsc2V9fSlcbiAgICAgICAgICB0aGlzLnJlZ2lzdGVyTmV3TG9jYXRpb24od2luZG93LmxvY2F0aW9uKVxuICAgICAgICB9XG4gICAgICAgIGRvbmUoKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgcmVwbGFjZVJvb3RIaXN0b3J5KCl7XG4gICAgQnJvd3Nlci5wdXNoU3RhdGUoXCJyZXBsYWNlXCIsIHtyb290OiB0cnVlLCB0eXBlOiBcInBhdGNoXCIsIGlkOiB0aGlzLm1haW4uaWR9KVxuICB9XG5cbiAgcmVnaXN0ZXJOZXdMb2NhdGlvbihuZXdMb2NhdGlvbil7XG4gICAgbGV0IHtwYXRobmFtZSwgc2VhcmNofSA9IHRoaXMuY3VycmVudExvY2F0aW9uXG4gICAgaWYocGF0aG5hbWUgKyBzZWFyY2ggPT09IG5ld0xvY2F0aW9uLnBhdGhuYW1lICsgbmV3TG9jYXRpb24uc2VhcmNoKXtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmN1cnJlbnRMb2NhdGlvbiA9IGNsb25lKG5ld0xvY2F0aW9uKVxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cblxuICBiaW5kRm9ybXMoKXtcbiAgICBsZXQgaXRlcmF0aW9ucyA9IDBcbiAgICBsZXQgZXh0ZXJuYWxGb3JtU3VibWl0dGVkID0gZmFsc2VcblxuICAgIC8vIGRpc2FibGUgZm9ybXMgb24gc3VibWl0IHRoYXQgdHJhY2sgcGh4LWNoYW5nZSBidXQgcGVyZm9ybSBleHRlcm5hbCBzdWJtaXRcbiAgICB0aGlzLm9uKFwic3VibWl0XCIsIGUgPT4ge1xuICAgICAgbGV0IHBoeFN1Ym1pdCA9IGUudGFyZ2V0LmdldEF0dHJpYnV0ZSh0aGlzLmJpbmRpbmcoXCJzdWJtaXRcIikpXG4gICAgICBsZXQgcGh4Q2hhbmdlID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhcImNoYW5nZVwiKSlcbiAgICAgIGlmKCFleHRlcm5hbEZvcm1TdWJtaXR0ZWQgJiYgcGh4Q2hhbmdlICYmICFwaHhTdWJtaXQpe1xuICAgICAgICBleHRlcm5hbEZvcm1TdWJtaXR0ZWQgPSB0cnVlXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgICAgICB0aGlzLndpdGhpbk93bmVycyhlLnRhcmdldCwgdmlldyA9PiB7XG4gICAgICAgICAgdmlldy5kaXNhYmxlRm9ybShlLnRhcmdldClcbiAgICAgICAgICAvLyBzYWZhcmkgbmVlZHMgbmV4dCB0aWNrXG4gICAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICBpZihET00uaXNVbmxvYWRhYmxlRm9ybVN1Ym1pdChlKSl7IHRoaXMudW5sb2FkKCkgfVxuICAgICAgICAgICAgZS50YXJnZXQuc3VibWl0KClcbiAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH0sIHRydWUpXG5cbiAgICB0aGlzLm9uKFwic3VibWl0XCIsIGUgPT4ge1xuICAgICAgbGV0IHBoeEV2ZW50ID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKHRoaXMuYmluZGluZyhcInN1Ym1pdFwiKSlcbiAgICAgIGlmKCFwaHhFdmVudCl7XG4gICAgICAgIGlmKERPTS5pc1VubG9hZGFibGVGb3JtU3VibWl0KGUpKXsgdGhpcy51bmxvYWQoKSB9XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICBlLnRhcmdldC5kaXNhYmxlZCA9IHRydWVcbiAgICAgIHRoaXMud2l0aGluT3duZXJzKGUudGFyZ2V0LCB2aWV3ID0+IHtcbiAgICAgICAgSlMuZXhlYyhcInN1Ym1pdFwiLCBwaHhFdmVudCwgdmlldywgZS50YXJnZXQsIFtcInB1c2hcIiwge3N1Ym1pdHRlcjogZS5zdWJtaXR0ZXJ9XSlcbiAgICAgIH0pXG4gICAgfSwgZmFsc2UpXG5cbiAgICBmb3IobGV0IHR5cGUgb2YgW1wiY2hhbmdlXCIsIFwiaW5wdXRcIl0pe1xuICAgICAgdGhpcy5vbih0eXBlLCBlID0+IHtcbiAgICAgICAgbGV0IHBoeENoYW5nZSA9IHRoaXMuYmluZGluZyhcImNoYW5nZVwiKVxuICAgICAgICBsZXQgaW5wdXQgPSBlLnRhcmdldFxuICAgICAgICBsZXQgaW5wdXRFdmVudCA9IGlucHV0LmdldEF0dHJpYnV0ZShwaHhDaGFuZ2UpXG4gICAgICAgIGxldCBmb3JtRXZlbnQgPSBpbnB1dC5mb3JtICYmIGlucHV0LmZvcm0uZ2V0QXR0cmlidXRlKHBoeENoYW5nZSlcbiAgICAgICAgbGV0IHBoeEV2ZW50ID0gaW5wdXRFdmVudCB8fCBmb3JtRXZlbnRcbiAgICAgICAgaWYoIXBoeEV2ZW50KXsgcmV0dXJuIH1cbiAgICAgICAgaWYoaW5wdXQudHlwZSA9PT0gXCJudW1iZXJcIiAmJiBpbnB1dC52YWxpZGl0eSAmJiBpbnB1dC52YWxpZGl0eS5iYWRJbnB1dCl7IHJldHVybiB9XG5cbiAgICAgICAgbGV0IGRpc3BhdGNoZXIgPSBpbnB1dEV2ZW50ID8gaW5wdXQgOiBpbnB1dC5mb3JtXG4gICAgICAgIGxldCBjdXJyZW50SXRlcmF0aW9ucyA9IGl0ZXJhdGlvbnNcbiAgICAgICAgaXRlcmF0aW9ucysrXG4gICAgICAgIGxldCB7YXQ6IGF0LCB0eXBlOiBsYXN0VHlwZX0gPSBET00ucHJpdmF0ZShpbnB1dCwgXCJwcmV2LWl0ZXJhdGlvblwiKSB8fCB7fVxuICAgICAgICAvLyBCcm93c2VycyBzaG91bGQgYWx3YXlzIGZpcmUgYXQgbGVhc3Qgb25lIFwiaW5wdXRcIiBldmVudCBiZWZvcmUgZXZlcnkgXCJjaGFuZ2VcIlxuICAgICAgICAvLyBJZ25vcmUgXCJjaGFuZ2VcIiBldmVudHMsIHVubGVzcyB0aGVyZSB3YXMgbm8gcHJpb3IgXCJpbnB1dFwiIGV2ZW50LlxuICAgICAgICAvLyBUaGlzIGNvdWxkIGhhcHBlbiBpZiB1c2VyIGNvZGUgdHJpZ2dlcnMgYSBcImNoYW5nZVwiIGV2ZW50LCBvciBpZiB0aGUgYnJvd3NlciBpcyBub24tY29uZm9ybWluZy5cbiAgICAgICAgaWYoYXQgPT09IGN1cnJlbnRJdGVyYXRpb25zIC0gMSAmJiB0eXBlID09PSBcImNoYW5nZVwiICYmIGxhc3RUeXBlID09PSBcImlucHV0XCIpeyByZXR1cm4gfVxuXG4gICAgICAgIERPTS5wdXRQcml2YXRlKGlucHV0LCBcInByZXYtaXRlcmF0aW9uXCIsIHthdDogY3VycmVudEl0ZXJhdGlvbnMsIHR5cGU6IHR5cGV9KVxuXG4gICAgICAgIHRoaXMuZGVib3VuY2UoaW5wdXQsIGUsIHR5cGUsICgpID0+IHtcbiAgICAgICAgICB0aGlzLndpdGhpbk93bmVycyhkaXNwYXRjaGVyLCB2aWV3ID0+IHtcbiAgICAgICAgICAgIERPTS5wdXRQcml2YXRlKGlucHV0LCBQSFhfSEFTX0ZPQ1VTRUQsIHRydWUpXG4gICAgICAgICAgICBpZighRE9NLmlzVGV4dHVhbElucHV0KGlucHV0KSl7XG4gICAgICAgICAgICAgIHRoaXMuc2V0QWN0aXZlRWxlbWVudChpbnB1dClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEpTLmV4ZWMoXCJjaGFuZ2VcIiwgcGh4RXZlbnQsIHZpZXcsIGlucHV0LCBbXCJwdXNoXCIsIHtfdGFyZ2V0OiBlLnRhcmdldC5uYW1lLCBkaXNwYXRjaGVyOiBkaXNwYXRjaGVyfV0pXG4gICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICAgIH0sIGZhbHNlKVxuICAgIH1cbiAgICB0aGlzLm9uKFwicmVzZXRcIiwgKGUpID0+IHtcbiAgICAgIGxldCBmb3JtID0gZS50YXJnZXRcbiAgICAgIERPTS5yZXNldEZvcm0oZm9ybSwgdGhpcy5iaW5kaW5nKFBIWF9GRUVEQkFDS19GT1IpLCB0aGlzLmJpbmRpbmcoUEhYX0ZFRURCQUNLX0dST1VQKSlcbiAgICAgIGxldCBpbnB1dCA9IEFycmF5LmZyb20oZm9ybS5lbGVtZW50cykuZmluZChlbCA9PiBlbC50eXBlID09PSBcInJlc2V0XCIpXG4gICAgICBpZihpbnB1dCl7XG4gICAgICAgIC8vIHdhaXQgdW50aWwgbmV4dCB0aWNrIHRvIGdldCB1cGRhdGVkIGlucHV0IHZhbHVlXG4gICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgIGlucHV0LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwiaW5wdXRcIiwge2J1YmJsZXM6IHRydWUsIGNhbmNlbGFibGU6IGZhbHNlfSkpXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIGRlYm91bmNlKGVsLCBldmVudCwgZXZlbnRUeXBlLCBjYWxsYmFjayl7XG4gICAgaWYoZXZlbnRUeXBlID09PSBcImJsdXJcIiB8fCBldmVudFR5cGUgPT09IFwiZm9jdXNvdXRcIil7IHJldHVybiBjYWxsYmFjaygpIH1cblxuICAgIGxldCBwaHhEZWJvdW5jZSA9IHRoaXMuYmluZGluZyhQSFhfREVCT1VOQ0UpXG4gICAgbGV0IHBoeFRocm90dGxlID0gdGhpcy5iaW5kaW5nKFBIWF9USFJPVFRMRSlcbiAgICBsZXQgZGVmYXVsdERlYm91bmNlID0gdGhpcy5kZWZhdWx0cy5kZWJvdW5jZS50b1N0cmluZygpXG4gICAgbGV0IGRlZmF1bHRUaHJvdHRsZSA9IHRoaXMuZGVmYXVsdHMudGhyb3R0bGUudG9TdHJpbmcoKVxuXG4gICAgdGhpcy53aXRoaW5Pd25lcnMoZWwsIHZpZXcgPT4ge1xuICAgICAgbGV0IGFzeW5jRmlsdGVyID0gKCkgPT4gIXZpZXcuaXNEZXN0cm95ZWQoKSAmJiBkb2N1bWVudC5ib2R5LmNvbnRhaW5zKGVsKVxuICAgICAgRE9NLmRlYm91bmNlKGVsLCBldmVudCwgcGh4RGVib3VuY2UsIGRlZmF1bHREZWJvdW5jZSwgcGh4VGhyb3R0bGUsIGRlZmF1bHRUaHJvdHRsZSwgYXN5bmNGaWx0ZXIsICgpID0+IHtcbiAgICAgICAgY2FsbGJhY2soKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgc2lsZW5jZUV2ZW50cyhjYWxsYmFjayl7XG4gICAgdGhpcy5zaWxlbmNlZCA9IHRydWVcbiAgICBjYWxsYmFjaygpXG4gICAgdGhpcy5zaWxlbmNlZCA9IGZhbHNlXG4gIH1cblxuICBvbihldmVudCwgY2FsbGJhY2spe1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBlID0+IHtcbiAgICAgIGlmKCF0aGlzLnNpbGVuY2VkKXsgY2FsbGJhY2soZSkgfVxuICAgIH0pXG4gIH1cbn1cblxuY2xhc3MgVHJhbnNpdGlvblNldCB7XG4gIGNvbnN0cnVjdG9yKCl7XG4gICAgdGhpcy50cmFuc2l0aW9ucyA9IG5ldyBTZXQoKVxuICAgIHRoaXMucGVuZGluZ09wcyA9IFtdXG4gIH1cblxuICByZXNldCgpe1xuICAgIHRoaXMudHJhbnNpdGlvbnMuZm9yRWFjaCh0aW1lciA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpXG4gICAgICB0aGlzLnRyYW5zaXRpb25zLmRlbGV0ZSh0aW1lcilcbiAgICB9KVxuICAgIHRoaXMuZmx1c2hQZW5kaW5nT3BzKClcbiAgfVxuXG4gIGFmdGVyKGNhbGxiYWNrKXtcbiAgICBpZih0aGlzLnNpemUoKSA9PT0gMCl7XG4gICAgICBjYWxsYmFjaygpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHVzaFBlbmRpbmdPcChjYWxsYmFjaylcbiAgICB9XG4gIH1cblxuICBhZGRUcmFuc2l0aW9uKHRpbWUsIG9uU3RhcnQsIG9uRG9uZSl7XG4gICAgb25TdGFydCgpXG4gICAgbGV0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnRyYW5zaXRpb25zLmRlbGV0ZSh0aW1lcilcbiAgICAgIG9uRG9uZSgpXG4gICAgICB0aGlzLmZsdXNoUGVuZGluZ09wcygpXG4gICAgfSwgdGltZSlcbiAgICB0aGlzLnRyYW5zaXRpb25zLmFkZCh0aW1lcilcbiAgfVxuXG4gIHB1c2hQZW5kaW5nT3Aob3ApeyB0aGlzLnBlbmRpbmdPcHMucHVzaChvcCkgfVxuXG4gIHNpemUoKXsgcmV0dXJuIHRoaXMudHJhbnNpdGlvbnMuc2l6ZSB9XG5cbiAgZmx1c2hQZW5kaW5nT3BzKCl7XG4gICAgaWYodGhpcy5zaXplKCkgPiAwKXsgcmV0dXJuIH1cbiAgICBsZXQgb3AgPSB0aGlzLnBlbmRpbmdPcHMuc2hpZnQoKVxuICAgIGlmKG9wKXtcbiAgICAgIG9wKClcbiAgICAgIHRoaXMuZmx1c2hQZW5kaW5nT3BzKClcbiAgICB9XG4gIH1cbn1cbiIsICIvLyBJZiB5b3Ugd2FudCB0byB1c2UgUGhvZW5peCBjaGFubmVscywgcnVuIGBtaXggaGVscCBwaHguZ2VuLmNoYW5uZWxgXG4vLyB0byBnZXQgc3RhcnRlZCBhbmQgdGhlbiB1bmNvbW1lbnQgdGhlIGxpbmUgYmVsb3cuXG4vLyBpbXBvcnQgXCIuL3VzZXJfc29ja2V0LmpzXCJcblxuLy8gWW91IGNhbiBpbmNsdWRlIGRlcGVuZGVuY2llcyBpbiB0d28gd2F5cy5cbi8vXG4vLyBUaGUgc2ltcGxlc3Qgb3B0aW9uIGlzIHRvIHB1dCB0aGVtIGluIGFzc2V0cy92ZW5kb3IgYW5kXG4vLyBpbXBvcnQgdGhlbSB1c2luZyByZWxhdGl2ZSBwYXRoczpcbi8vXG4vLyAgICAgaW1wb3J0IFwiLi4vdmVuZG9yL3NvbWUtcGFja2FnZS5qc1wiXG4vL1xuLy8gQWx0ZXJuYXRpdmVseSwgeW91IGNhbiBgbnBtIGluc3RhbGwgc29tZS1wYWNrYWdlIC0tcHJlZml4IGFzc2V0c2AgYW5kIGltcG9ydFxuLy8gdGhlbSB1c2luZyBhIHBhdGggc3RhcnRpbmcgd2l0aCB0aGUgcGFja2FnZSBuYW1lOlxuLy9cbi8vICAgICBpbXBvcnQgXCJzb21lLXBhY2thZ2VcIlxuLy9cblxuLy8gSW5jbHVkZSBwaG9lbml4X2h0bWwgdG8gaGFuZGxlIG1ldGhvZD1QVVQvREVMRVRFIGluIGZvcm1zIGFuZCBidXR0b25zLlxuaW1wb3J0IFwicGhvZW5peF9odG1sXCJcbi8vIEVzdGFibGlzaCBQaG9lbml4IFNvY2tldCBhbmQgTGl2ZVZpZXcgY29uZmlndXJhdGlvbi5cbmltcG9ydCB7IFNvY2tldCB9IGZyb20gXCJwaG9lbml4XCJcbmltcG9ydCB7IExpdmVTb2NrZXQgfSBmcm9tIFwicGhvZW5peF9saXZlX3ZpZXdcIlxuaW1wb3J0IHRvcGJhciBmcm9tIFwiLi4vdmVuZG9yL3RvcGJhclwiXG5pbXBvcnQgeyBjcmVhdGVMaXZlVG9hc3RIb29rIH0gZnJvbSAnbGl2ZV90b2FzdCdcbi8vIGltcG9ydCBWZWdhTGl0ZSBmcm9tIFwiLi4vdmVuZG9yL3ZlZ2FsaXRlXCJcblxubGV0IGNzcmZUb2tlbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJtZXRhW25hbWU9J2NzcmYtdG9rZW4nXVwiKS5nZXRBdHRyaWJ1dGUoXCJjb250ZW50XCIpXG5sZXQgaG9va3MgPSB7XG4gIExpdmVUb2FzdDogY3JlYXRlTGl2ZVRvYXN0SG9vaygpXG59IC8veyBWZWdhTGl0ZSB9XG5sZXQgbGl2ZVNvY2tldCA9IG5ldyBMaXZlU29ja2V0KFwiL2xpdmVcIiwgU29ja2V0LCB7IHBhcmFtczogeyBfY3NyZl90b2tlbjogY3NyZlRva2VuIH0sIGhvb2tzIH0pXG5cblxuLy8gU2hvdyBwcm9ncmVzcyBiYXIgb24gbGl2ZSBuYXZpZ2F0aW9uIGFuZCBmb3JtIHN1Ym1pdHNcbnRvcGJhci5jb25maWcoeyBiYXJDb2xvcnM6IHsgMDogXCIjMjlkXCIgfSwgc2hhZG93Q29sb3I6IFwicmdiYSgwLCAwLCAwLCAuMylcIiB9KVxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJwaHg6cGFnZS1sb2FkaW5nLXN0YXJ0XCIsIF9pbmZvID0+IHRvcGJhci5zaG93KDMwMCkpXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcInBoeDpwYWdlLWxvYWRpbmctc3RvcFwiLCBfaW5mbyA9PiB0b3BiYXIuaGlkZSgpKVxuXG4vLyBjb25uZWN0IGlmIHRoZXJlIGFyZSBhbnkgTGl2ZVZpZXdzIG9uIHRoZSBwYWdlXG5saXZlU29ja2V0LmNvbm5lY3QoKVxuXG4vLyBleHBvc2UgbGl2ZVNvY2tldCBvbiB3aW5kb3cgZm9yIHdlYiBjb25zb2xlIGRlYnVnIGxvZ3MgYW5kIGxhdGVuY3kgc2ltdWxhdGlvbjpcbi8vID4+IGxpdmVTb2NrZXQuZW5hYmxlRGVidWcoKVxuLy8gPj4gbGl2ZVNvY2tldC5lbmFibGVMYXRlbmN5U2ltKDEwMDApICAvLyBlbmFibGVkIGZvciBkdXJhdGlvbiBvZiBicm93c2VyIHNlc3Npb25cbi8vID4+IGxpdmVTb2NrZXQuZGlzYWJsZUxhdGVuY3lTaW0oKVxud2luZG93LmxpdmVTb2NrZXQgPSBsaXZlU29ja2V0XG5cbiIsICJmdW5jdGlvbiBhZGRVbmlxdWVJdGVtKGFycmF5LCBpdGVtKSB7XG4gICAgYXJyYXkuaW5kZXhPZihpdGVtKSA9PT0gLTEgJiYgYXJyYXkucHVzaChpdGVtKTtcbn1cbmZ1bmN0aW9uIHJlbW92ZUl0ZW0oYXJyLCBpdGVtKSB7XG4gICAgY29uc3QgaW5kZXggPSBhcnIuaW5kZXhPZihpdGVtKTtcbiAgICBpbmRleCA+IC0xICYmIGFyci5zcGxpY2UoaW5kZXgsIDEpO1xufVxuXG5leHBvcnQgeyBhZGRVbmlxdWVJdGVtLCByZW1vdmVJdGVtIH07XG4iLCAiY29uc3QgY2xhbXAgPSAobWluLCBtYXgsIHYpID0+IE1hdGgubWluKE1hdGgubWF4KHYsIG1pbiksIG1heCk7XG5cbmV4cG9ydCB7IGNsYW1wIH07XG4iLCAiY29uc3QgZGVmYXVsdHMgPSB7XG4gICAgZHVyYXRpb246IDAuMyxcbiAgICBkZWxheTogMCxcbiAgICBlbmREZWxheTogMCxcbiAgICByZXBlYXQ6IDAsXG4gICAgZWFzaW5nOiBcImVhc2VcIixcbn07XG5cbmV4cG9ydCB7IGRlZmF1bHRzIH07XG4iLCAiY29uc3QgaXNOdW1iZXIgPSAodmFsdWUpID0+IHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIjtcblxuZXhwb3J0IHsgaXNOdW1iZXIgfTtcbiIsICJpbXBvcnQgeyBpc051bWJlciB9IGZyb20gJy4vaXMtbnVtYmVyLmVzLmpzJztcblxuY29uc3QgaXNFYXNpbmdMaXN0ID0gKGVhc2luZykgPT4gQXJyYXkuaXNBcnJheShlYXNpbmcpICYmICFpc051bWJlcihlYXNpbmdbMF0pO1xuXG5leHBvcnQgeyBpc0Vhc2luZ0xpc3QgfTtcbiIsICJjb25zdCB3cmFwID0gKG1pbiwgbWF4LCB2KSA9PiB7XG4gICAgY29uc3QgcmFuZ2VTaXplID0gbWF4IC0gbWluO1xuICAgIHJldHVybiAoKCgodiAtIG1pbikgJSByYW5nZVNpemUpICsgcmFuZ2VTaXplKSAlIHJhbmdlU2l6ZSkgKyBtaW47XG59O1xuXG5leHBvcnQgeyB3cmFwIH07XG4iLCAiaW1wb3J0IHsgaXNFYXNpbmdMaXN0IH0gZnJvbSAnLi9pcy1lYXNpbmctbGlzdC5lcy5qcyc7XG5pbXBvcnQgeyB3cmFwIH0gZnJvbSAnLi93cmFwLmVzLmpzJztcblxuZnVuY3Rpb24gZ2V0RWFzaW5nRm9yU2VnbWVudChlYXNpbmcsIGkpIHtcbiAgICByZXR1cm4gaXNFYXNpbmdMaXN0KGVhc2luZylcbiAgICAgICAgPyBlYXNpbmdbd3JhcCgwLCBlYXNpbmcubGVuZ3RoLCBpKV1cbiAgICAgICAgOiBlYXNpbmc7XG59XG5cbmV4cG9ydCB7IGdldEVhc2luZ0ZvclNlZ21lbnQgfTtcbiIsICJjb25zdCBtaXggPSAobWluLCBtYXgsIHByb2dyZXNzKSA9PiAtcHJvZ3Jlc3MgKiBtaW4gKyBwcm9ncmVzcyAqIG1heCArIG1pbjtcblxuZXhwb3J0IHsgbWl4IH07XG4iLCAiY29uc3Qgbm9vcCA9ICgpID0+IHsgfTtcbmNvbnN0IG5vb3BSZXR1cm4gPSAodikgPT4gdjtcblxuZXhwb3J0IHsgbm9vcCwgbm9vcFJldHVybiB9O1xuIiwgImNvbnN0IHByb2dyZXNzID0gKG1pbiwgbWF4LCB2YWx1ZSkgPT4gbWF4IC0gbWluID09PSAwID8gMSA6ICh2YWx1ZSAtIG1pbikgLyAobWF4IC0gbWluKTtcblxuZXhwb3J0IHsgcHJvZ3Jlc3MgfTtcbiIsICJpbXBvcnQgeyBtaXggfSBmcm9tICcuL21peC5lcy5qcyc7XG5pbXBvcnQgeyBwcm9ncmVzcyB9IGZyb20gJy4vcHJvZ3Jlc3MuZXMuanMnO1xuXG5mdW5jdGlvbiBmaWxsT2Zmc2V0KG9mZnNldCwgcmVtYWluaW5nKSB7XG4gICAgY29uc3QgbWluID0gb2Zmc2V0W29mZnNldC5sZW5ndGggLSAxXTtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8PSByZW1haW5pbmc7IGkrKykge1xuICAgICAgICBjb25zdCBvZmZzZXRQcm9ncmVzcyA9IHByb2dyZXNzKDAsIHJlbWFpbmluZywgaSk7XG4gICAgICAgIG9mZnNldC5wdXNoKG1peChtaW4sIDEsIG9mZnNldFByb2dyZXNzKSk7XG4gICAgfVxufVxuZnVuY3Rpb24gZGVmYXVsdE9mZnNldChsZW5ndGgpIHtcbiAgICBjb25zdCBvZmZzZXQgPSBbMF07XG4gICAgZmlsbE9mZnNldChvZmZzZXQsIGxlbmd0aCAtIDEpO1xuICAgIHJldHVybiBvZmZzZXQ7XG59XG5cbmV4cG9ydCB7IGRlZmF1bHRPZmZzZXQsIGZpbGxPZmZzZXQgfTtcbiIsICJpbXBvcnQgeyBtaXggfSBmcm9tICcuL21peC5lcy5qcyc7XG5pbXBvcnQgeyBub29wUmV0dXJuIH0gZnJvbSAnLi9ub29wLmVzLmpzJztcbmltcG9ydCB7IGZpbGxPZmZzZXQsIGRlZmF1bHRPZmZzZXQgfSBmcm9tICcuL29mZnNldC5lcy5qcyc7XG5pbXBvcnQgeyBwcm9ncmVzcyB9IGZyb20gJy4vcHJvZ3Jlc3MuZXMuanMnO1xuaW1wb3J0IHsgZ2V0RWFzaW5nRm9yU2VnbWVudCB9IGZyb20gJy4vZWFzaW5nLmVzLmpzJztcbmltcG9ydCB7IGNsYW1wIH0gZnJvbSAnLi9jbGFtcC5lcy5qcyc7XG5cbmZ1bmN0aW9uIGludGVycG9sYXRlKG91dHB1dCwgaW5wdXQgPSBkZWZhdWx0T2Zmc2V0KG91dHB1dC5sZW5ndGgpLCBlYXNpbmcgPSBub29wUmV0dXJuKSB7XG4gICAgY29uc3QgbGVuZ3RoID0gb3V0cHV0Lmxlbmd0aDtcbiAgICAvKipcbiAgICAgKiBJZiB0aGUgaW5wdXQgbGVuZ3RoIGlzIGxvd2VyIHRoYW4gdGhlIG91dHB1dCB3ZVxuICAgICAqIGZpbGwgdGhlIGlucHV0IHRvIG1hdGNoLiBUaGlzIGN1cnJlbnRseSBhc3N1bWVzIHRoZSBpbnB1dFxuICAgICAqIGlzIGFuIGFuaW1hdGlvbiBwcm9ncmVzcyB2YWx1ZSBzbyBpcyBhIGdvb2QgY2FuZGlkYXRlIGZvclxuICAgICAqIG1vdmluZyBvdXRzaWRlIHRoZSBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBjb25zdCByZW1haW5kZXIgPSBsZW5ndGggLSBpbnB1dC5sZW5ndGg7XG4gICAgcmVtYWluZGVyID4gMCAmJiBmaWxsT2Zmc2V0KGlucHV0LCByZW1haW5kZXIpO1xuICAgIHJldHVybiAodCkgPT4ge1xuICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgIGZvciAoOyBpIDwgbGVuZ3RoIC0gMjsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodCA8IGlucHV0W2kgKyAxXSlcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBsZXQgcHJvZ3Jlc3NJblJhbmdlID0gY2xhbXAoMCwgMSwgcHJvZ3Jlc3MoaW5wdXRbaV0sIGlucHV0W2kgKyAxXSwgdCkpO1xuICAgICAgICBjb25zdCBzZWdtZW50RWFzaW5nID0gZ2V0RWFzaW5nRm9yU2VnbWVudChlYXNpbmcsIGkpO1xuICAgICAgICBwcm9ncmVzc0luUmFuZ2UgPSBzZWdtZW50RWFzaW5nKHByb2dyZXNzSW5SYW5nZSk7XG4gICAgICAgIHJldHVybiBtaXgob3V0cHV0W2ldLCBvdXRwdXRbaSArIDFdLCBwcm9ncmVzc0luUmFuZ2UpO1xuICAgIH07XG59XG5cbmV4cG9ydCB7IGludGVycG9sYXRlIH07XG4iLCAiaW1wb3J0IHsgaXNOdW1iZXIgfSBmcm9tICcuL2lzLW51bWJlci5lcy5qcyc7XG5cbmNvbnN0IGlzQ3ViaWNCZXppZXIgPSAoZWFzaW5nKSA9PiBBcnJheS5pc0FycmF5KGVhc2luZykgJiYgaXNOdW1iZXIoZWFzaW5nWzBdKTtcblxuZXhwb3J0IHsgaXNDdWJpY0JlemllciB9O1xuIiwgImNvbnN0IGlzRWFzaW5nR2VuZXJhdG9yID0gKGVhc2luZykgPT4gdHlwZW9mIGVhc2luZyA9PT0gXCJvYmplY3RcIiAmJlxuICAgIEJvb2xlYW4oZWFzaW5nLmNyZWF0ZUFuaW1hdGlvbik7XG5cbmV4cG9ydCB7IGlzRWFzaW5nR2VuZXJhdG9yIH07XG4iLCAiY29uc3QgaXNGdW5jdGlvbiA9ICh2YWx1ZSkgPT4gdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCI7XG5cbmV4cG9ydCB7IGlzRnVuY3Rpb24gfTtcbiIsICJjb25zdCBpc1N0cmluZyA9ICh2YWx1ZSkgPT4gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiO1xuXG5leHBvcnQgeyBpc1N0cmluZyB9O1xuIiwgImNvbnN0IHRpbWUgPSB7XG4gICAgbXM6IChzZWNvbmRzKSA9PiBzZWNvbmRzICogMTAwMCxcbiAgICBzOiAobWlsbGlzZWNvbmRzKSA9PiBtaWxsaXNlY29uZHMgLyAxMDAwLFxufTtcblxuZXhwb3J0IHsgdGltZSB9O1xuIiwgImltcG9ydCB7IG5vb3BSZXR1cm4gfSBmcm9tICdAbW90aW9ub25lL3V0aWxzJztcblxuLypcbiAgQmV6aWVyIGZ1bmN0aW9uIGdlbmVyYXRvclxuXG4gIFRoaXMgaGFzIGJlZW4gbW9kaWZpZWQgZnJvbSBHYVx1MDBFQnRhbiBSZW5hdWRlYXUncyBCZXppZXJFYXNpbmdcbiAgaHR0cHM6Ly9naXRodWIuY29tL2dyZS9iZXppZXItZWFzaW5nL2Jsb2IvbWFzdGVyL3NyYy9pbmRleC5qc1xuICBodHRwczovL2dpdGh1Yi5jb20vZ3JlL2Jlemllci1lYXNpbmcvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICBcbiAgSSd2ZSByZW1vdmVkIHRoZSBuZXd0b25SYXBoc29uSXRlcmF0ZSBhbGdvIGJlY2F1c2UgaW4gYmVuY2htYXJraW5nIGl0XG4gIHdhc24ndCBub3RpY2lhYmx5IGZhc3RlciB0aGFuIGJpbmFyeVN1YmRpdmlzaW9uLCBpbmRlZWQgcmVtb3ZpbmcgaXRcbiAgdXN1YWxseSBpbXByb3ZlZCB0aW1lcywgZGVwZW5kaW5nIG9uIHRoZSBjdXJ2ZS5cblxuICBJIGFsc28gcmVtb3ZlZCB0aGUgbG9va3VwIHRhYmxlLCBhcyBmb3IgdGhlIGFkZGVkIGJ1bmRsZSBzaXplIGFuZCBsb29wIHdlJ3JlXG4gIG9ubHkgY3V0dGluZyB+NCBvciBzbyBzdWJkaXZpc2lvbiBpdGVyYXRpb25zLiBJIGJ1bXBlZCB0aGUgbWF4IGl0ZXJhdGlvbnMgdXBcbiAgdG8gMTIgdG8gY29tcGVuc2F0ZSBhbmQgdGhpcyBzdGlsbCB0ZW5kZWQgdG8gYmUgZmFzdGVyIGZvciBubyBwZXJjZWl2YWJsZVxuICBsb3NzIGluIGFjY3VyYWN5LlxuXG4gIFVzYWdlXG4gICAgY29uc3QgZWFzZU91dCA9IGN1YmljQmV6aWVyKC4xNywuNjcsLjgzLC42Nyk7XG4gICAgY29uc3QgeCA9IGVhc2VPdXQoMC41KTsgLy8gcmV0dXJucyAwLjYyNy4uLlxuKi9cbi8vIFJldHVybnMgeCh0KSBnaXZlbiB0LCB4MSwgYW5kIHgyLCBvciB5KHQpIGdpdmVuIHQsIHkxLCBhbmQgeTIuXG5jb25zdCBjYWxjQmV6aWVyID0gKHQsIGExLCBhMikgPT4gKCgoMS4wIC0gMy4wICogYTIgKyAzLjAgKiBhMSkgKiB0ICsgKDMuMCAqIGEyIC0gNi4wICogYTEpKSAqIHQgKyAzLjAgKiBhMSkgKiB0O1xuY29uc3Qgc3ViZGl2aXNpb25QcmVjaXNpb24gPSAwLjAwMDAwMDE7XG5jb25zdCBzdWJkaXZpc2lvbk1heEl0ZXJhdGlvbnMgPSAxMjtcbmZ1bmN0aW9uIGJpbmFyeVN1YmRpdmlkZSh4LCBsb3dlckJvdW5kLCB1cHBlckJvdW5kLCBtWDEsIG1YMikge1xuICAgIGxldCBjdXJyZW50WDtcbiAgICBsZXQgY3VycmVudFQ7XG4gICAgbGV0IGkgPSAwO1xuICAgIGRvIHtcbiAgICAgICAgY3VycmVudFQgPSBsb3dlckJvdW5kICsgKHVwcGVyQm91bmQgLSBsb3dlckJvdW5kKSAvIDIuMDtcbiAgICAgICAgY3VycmVudFggPSBjYWxjQmV6aWVyKGN1cnJlbnRULCBtWDEsIG1YMikgLSB4O1xuICAgICAgICBpZiAoY3VycmVudFggPiAwLjApIHtcbiAgICAgICAgICAgIHVwcGVyQm91bmQgPSBjdXJyZW50VDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxvd2VyQm91bmQgPSBjdXJyZW50VDtcbiAgICAgICAgfVxuICAgIH0gd2hpbGUgKE1hdGguYWJzKGN1cnJlbnRYKSA+IHN1YmRpdmlzaW9uUHJlY2lzaW9uICYmXG4gICAgICAgICsraSA8IHN1YmRpdmlzaW9uTWF4SXRlcmF0aW9ucyk7XG4gICAgcmV0dXJuIGN1cnJlbnRUO1xufVxuZnVuY3Rpb24gY3ViaWNCZXppZXIobVgxLCBtWTEsIG1YMiwgbVkyKSB7XG4gICAgLy8gSWYgdGhpcyBpcyBhIGxpbmVhciBncmFkaWVudCwgcmV0dXJuIGxpbmVhciBlYXNpbmdcbiAgICBpZiAobVgxID09PSBtWTEgJiYgbVgyID09PSBtWTIpXG4gICAgICAgIHJldHVybiBub29wUmV0dXJuO1xuICAgIGNvbnN0IGdldFRGb3JYID0gKGFYKSA9PiBiaW5hcnlTdWJkaXZpZGUoYVgsIDAsIDEsIG1YMSwgbVgyKTtcbiAgICAvLyBJZiBhbmltYXRpb24gaXMgYXQgc3RhcnQvZW5kLCByZXR1cm4gdCB3aXRob3V0IGVhc2luZ1xuICAgIHJldHVybiAodCkgPT4gdCA9PT0gMCB8fCB0ID09PSAxID8gdCA6IGNhbGNCZXppZXIoZ2V0VEZvclgodCksIG1ZMSwgbVkyKTtcbn1cblxuZXhwb3J0IHsgY3ViaWNCZXppZXIgfTtcbiIsICJpbXBvcnQgeyBjbGFtcCB9IGZyb20gJ0Btb3Rpb25vbmUvdXRpbHMnO1xuXG5jb25zdCBzdGVwcyA9IChzdGVwcywgZGlyZWN0aW9uID0gXCJlbmRcIikgPT4gKHByb2dyZXNzKSA9PiB7XG4gICAgcHJvZ3Jlc3MgPVxuICAgICAgICBkaXJlY3Rpb24gPT09IFwiZW5kXCJcbiAgICAgICAgICAgID8gTWF0aC5taW4ocHJvZ3Jlc3MsIDAuOTk5KVxuICAgICAgICAgICAgOiBNYXRoLm1heChwcm9ncmVzcywgMC4wMDEpO1xuICAgIGNvbnN0IGV4cGFuZGVkID0gcHJvZ3Jlc3MgKiBzdGVwcztcbiAgICBjb25zdCByb3VuZGVkID0gZGlyZWN0aW9uID09PSBcImVuZFwiID8gTWF0aC5mbG9vcihleHBhbmRlZCkgOiBNYXRoLmNlaWwoZXhwYW5kZWQpO1xuICAgIHJldHVybiBjbGFtcCgwLCAxLCByb3VuZGVkIC8gc3RlcHMpO1xufTtcblxuZXhwb3J0IHsgc3RlcHMgfTtcbiIsICJpbXBvcnQgeyBjdWJpY0Jlemllciwgc3RlcHMgfSBmcm9tICdAbW90aW9ub25lL2Vhc2luZyc7XG5pbXBvcnQgeyBpc0Z1bmN0aW9uLCBpc0N1YmljQmV6aWVyLCBub29wUmV0dXJuIH0gZnJvbSAnQG1vdGlvbm9uZS91dGlscyc7XG5cbmNvbnN0IG5hbWVkRWFzaW5ncyA9IHtcbiAgICBlYXNlOiBjdWJpY0JlemllcigwLjI1LCAwLjEsIDAuMjUsIDEuMCksXG4gICAgXCJlYXNlLWluXCI6IGN1YmljQmV6aWVyKDAuNDIsIDAuMCwgMS4wLCAxLjApLFxuICAgIFwiZWFzZS1pbi1vdXRcIjogY3ViaWNCZXppZXIoMC40MiwgMC4wLCAwLjU4LCAxLjApLFxuICAgIFwiZWFzZS1vdXRcIjogY3ViaWNCZXppZXIoMC4wLCAwLjAsIDAuNTgsIDEuMCksXG59O1xuY29uc3QgZnVuY3Rpb25BcmdzUmVnZXggPSAvXFwoKC4qPylcXCkvO1xuZnVuY3Rpb24gZ2V0RWFzaW5nRnVuY3Rpb24oZGVmaW5pdGlvbikge1xuICAgIC8vIElmIGFscmVhZHkgYW4gZWFzaW5nIGZ1bmN0aW9uLCByZXR1cm5cbiAgICBpZiAoaXNGdW5jdGlvbihkZWZpbml0aW9uKSlcbiAgICAgICAgcmV0dXJuIGRlZmluaXRpb247XG4gICAgLy8gSWYgYW4gZWFzaW5nIGN1cnZlIGRlZmluaXRpb24sIHJldHVybiBiZXppZXIgZnVuY3Rpb25cbiAgICBpZiAoaXNDdWJpY0JlemllcihkZWZpbml0aW9uKSlcbiAgICAgICAgcmV0dXJuIGN1YmljQmV6aWVyKC4uLmRlZmluaXRpb24pO1xuICAgIC8vIElmIHdlIGhhdmUgYSBwcmVkZWZpbmVkIGVhc2luZyBmdW5jdGlvbiwgcmV0dXJuXG4gICAgaWYgKG5hbWVkRWFzaW5nc1tkZWZpbml0aW9uXSlcbiAgICAgICAgcmV0dXJuIG5hbWVkRWFzaW5nc1tkZWZpbml0aW9uXTtcbiAgICAvLyBJZiB0aGlzIGlzIGEgc3RlcHMgZnVuY3Rpb24sIGF0dGVtcHQgdG8gY3JlYXRlIGVhc2luZyBjdXJ2ZVxuICAgIGlmIChkZWZpbml0aW9uLnN0YXJ0c1dpdGgoXCJzdGVwc1wiKSkge1xuICAgICAgICBjb25zdCBhcmdzID0gZnVuY3Rpb25BcmdzUmVnZXguZXhlYyhkZWZpbml0aW9uKTtcbiAgICAgICAgaWYgKGFyZ3MpIHtcbiAgICAgICAgICAgIGNvbnN0IGFyZ3NBcnJheSA9IGFyZ3NbMV0uc3BsaXQoXCIsXCIpO1xuICAgICAgICAgICAgcmV0dXJuIHN0ZXBzKHBhcnNlRmxvYXQoYXJnc0FycmF5WzBdKSwgYXJnc0FycmF5WzFdLnRyaW0oKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5vb3BSZXR1cm47XG59XG5cbmV4cG9ydCB7IGdldEVhc2luZ0Z1bmN0aW9uIH07XG4iLCAiaW1wb3J0IHsgbm9vcFJldHVybiwgZGVmYXVsdHMsIGlzRWFzaW5nR2VuZXJhdG9yLCBpc0Vhc2luZ0xpc3QsIGludGVycG9sYXRlIH0gZnJvbSAnQG1vdGlvbm9uZS91dGlscyc7XG5pbXBvcnQgeyBnZXRFYXNpbmdGdW5jdGlvbiB9IGZyb20gJy4vdXRpbHMvZWFzaW5nLmVzLmpzJztcblxuY2xhc3MgQW5pbWF0aW9uIHtcbiAgICBjb25zdHJ1Y3RvcihvdXRwdXQsIGtleWZyYW1lcyA9IFswLCAxXSwgeyBlYXNpbmcsIGR1cmF0aW9uOiBpbml0aWFsRHVyYXRpb24gPSBkZWZhdWx0cy5kdXJhdGlvbiwgZGVsYXkgPSBkZWZhdWx0cy5kZWxheSwgZW5kRGVsYXkgPSBkZWZhdWx0cy5lbmREZWxheSwgcmVwZWF0ID0gZGVmYXVsdHMucmVwZWF0LCBvZmZzZXQsIGRpcmVjdGlvbiA9IFwibm9ybWFsXCIsIGF1dG9wbGF5ID0gdHJ1ZSwgfSA9IHt9KSB7XG4gICAgICAgIHRoaXMuc3RhcnRUaW1lID0gbnVsbDtcbiAgICAgICAgdGhpcy5yYXRlID0gMTtcbiAgICAgICAgdGhpcy50ID0gMDtcbiAgICAgICAgdGhpcy5jYW5jZWxUaW1lc3RhbXAgPSBudWxsO1xuICAgICAgICB0aGlzLmVhc2luZyA9IG5vb3BSZXR1cm47XG4gICAgICAgIHRoaXMuZHVyYXRpb24gPSAwO1xuICAgICAgICB0aGlzLnRvdGFsRHVyYXRpb24gPSAwO1xuICAgICAgICB0aGlzLnJlcGVhdCA9IDA7XG4gICAgICAgIHRoaXMucGxheVN0YXRlID0gXCJpZGxlXCI7XG4gICAgICAgIHRoaXMuZmluaXNoZWQgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlc29sdmUgPSByZXNvbHZlO1xuICAgICAgICAgICAgdGhpcy5yZWplY3QgPSByZWplY3Q7XG4gICAgICAgIH0pO1xuICAgICAgICBlYXNpbmcgPSBlYXNpbmcgfHwgZGVmYXVsdHMuZWFzaW5nO1xuICAgICAgICBpZiAoaXNFYXNpbmdHZW5lcmF0b3IoZWFzaW5nKSkge1xuICAgICAgICAgICAgY29uc3QgY3VzdG9tID0gZWFzaW5nLmNyZWF0ZUFuaW1hdGlvbihrZXlmcmFtZXMpO1xuICAgICAgICAgICAgZWFzaW5nID0gY3VzdG9tLmVhc2luZztcbiAgICAgICAgICAgIGtleWZyYW1lcyA9IGN1c3RvbS5rZXlmcmFtZXMgfHwga2V5ZnJhbWVzO1xuICAgICAgICAgICAgaW5pdGlhbER1cmF0aW9uID0gY3VzdG9tLmR1cmF0aW9uIHx8IGluaXRpYWxEdXJhdGlvbjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlcGVhdCA9IHJlcGVhdDtcbiAgICAgICAgdGhpcy5lYXNpbmcgPSBpc0Vhc2luZ0xpc3QoZWFzaW5nKSA/IG5vb3BSZXR1cm4gOiBnZXRFYXNpbmdGdW5jdGlvbihlYXNpbmcpO1xuICAgICAgICB0aGlzLnVwZGF0ZUR1cmF0aW9uKGluaXRpYWxEdXJhdGlvbik7XG4gICAgICAgIGNvbnN0IGludGVycG9sYXRlJDEgPSBpbnRlcnBvbGF0ZShrZXlmcmFtZXMsIG9mZnNldCwgaXNFYXNpbmdMaXN0KGVhc2luZykgPyBlYXNpbmcubWFwKGdldEVhc2luZ0Z1bmN0aW9uKSA6IG5vb3BSZXR1cm4pO1xuICAgICAgICB0aGlzLnRpY2sgPSAodGltZXN0YW1wKSA9PiB7XG4gICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICAvLyBUT0RPOiBUZW1wb3JhcnkgZml4IGZvciBPcHRpb25zUmVzb2x2ZXIgdHlwaW5nXG4gICAgICAgICAgICBkZWxheSA9IGRlbGF5O1xuICAgICAgICAgICAgbGV0IHQgPSAwO1xuICAgICAgICAgICAgaWYgKHRoaXMucGF1c2VUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0ID0gdGhpcy5wYXVzZVRpbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0ID0gKHRpbWVzdGFtcCAtIHRoaXMuc3RhcnRUaW1lKSAqIHRoaXMucmF0ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudCA9IHQ7XG4gICAgICAgICAgICAvLyBDb252ZXJ0IHRvIHNlY29uZHNcbiAgICAgICAgICAgIHQgLz0gMTAwMDtcbiAgICAgICAgICAgIC8vIFJlYmFzZSBvbiBkZWxheVxuICAgICAgICAgICAgdCA9IE1hdGgubWF4KHQgLSBkZWxheSwgMCk7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIElmIHRoaXMgYW5pbWF0aW9uIGhhcyBmaW5pc2hlZCwgc2V0IHRoZSBjdXJyZW50IHRpbWVcbiAgICAgICAgICAgICAqIHRvIHRoZSB0b3RhbCBkdXJhdGlvbi5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKHRoaXMucGxheVN0YXRlID09PSBcImZpbmlzaGVkXCIgJiYgdGhpcy5wYXVzZVRpbWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHQgPSB0aGlzLnRvdGFsRHVyYXRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEdldCB0aGUgY3VycmVudCBwcm9ncmVzcyAoMC0xKSBvZiB0aGUgYW5pbWF0aW9uLiBJZiB0IGlzID5cbiAgICAgICAgICAgICAqIHRoYW4gZHVyYXRpb24gd2UnbGwgZ2V0IHZhbHVlcyBsaWtlIDIuNSAobWlkd2F5IHRocm91Z2ggdGhlXG4gICAgICAgICAgICAgKiB0aGlyZCBpdGVyYXRpb24pXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IHByb2dyZXNzID0gdCAvIHRoaXMuZHVyYXRpb247XG4gICAgICAgICAgICAvLyBUT0RPIHByb2dyZXNzICs9IGl0ZXJhdGlvblN0YXJ0XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEdldCB0aGUgY3VycmVudCBpdGVyYXRpb24gKDAgaW5kZXhlZCkuIEZvciBpbnN0YW5jZSB0aGUgZmxvb3Igb2ZcbiAgICAgICAgICAgICAqIDIuNSBpcyAyLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBsZXQgY3VycmVudEl0ZXJhdGlvbiA9IE1hdGguZmxvb3IocHJvZ3Jlc3MpO1xuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBHZXQgdGhlIGN1cnJlbnQgcHJvZ3Jlc3Mgb2YgdGhlIGl0ZXJhdGlvbiBieSB0YWtpbmcgdGhlIHJlbWFpbmRlclxuICAgICAgICAgICAgICogc28gMi41IGlzIDAuNSB0aHJvdWdoIGl0ZXJhdGlvbiAyXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGxldCBpdGVyYXRpb25Qcm9ncmVzcyA9IHByb2dyZXNzICUgMS4wO1xuICAgICAgICAgICAgaWYgKCFpdGVyYXRpb25Qcm9ncmVzcyAmJiBwcm9ncmVzcyA+PSAxKSB7XG4gICAgICAgICAgICAgICAgaXRlcmF0aW9uUHJvZ3Jlc3MgPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBJZiBpdGVyYXRpb24gcHJvZ3Jlc3MgaXMgMSB3ZSBjb3VudCB0aGF0IGFzIHRoZSBlbmRcbiAgICAgICAgICAgICAqIG9mIHRoZSBwcmV2aW91cyBpdGVyYXRpb24uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGl0ZXJhdGlvblByb2dyZXNzID09PSAxICYmIGN1cnJlbnRJdGVyYXRpb24tLTtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogUmV2ZXJzZSBwcm9ncmVzcyBpZiB3ZSdyZSBub3QgcnVubmluZyBpbiBcIm5vcm1hbFwiIGRpcmVjdGlvblxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBpdGVyYXRpb25Jc09kZCA9IGN1cnJlbnRJdGVyYXRpb24gJSAyO1xuICAgICAgICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gXCJyZXZlcnNlXCIgfHxcbiAgICAgICAgICAgICAgICAoZGlyZWN0aW9uID09PSBcImFsdGVybmF0ZVwiICYmIGl0ZXJhdGlvbklzT2RkKSB8fFxuICAgICAgICAgICAgICAgIChkaXJlY3Rpb24gPT09IFwiYWx0ZXJuYXRlLXJldmVyc2VcIiAmJiAhaXRlcmF0aW9uSXNPZGQpKSB7XG4gICAgICAgICAgICAgICAgaXRlcmF0aW9uUHJvZ3Jlc3MgPSAxIC0gaXRlcmF0aW9uUHJvZ3Jlc3M7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBwID0gdCA+PSB0aGlzLnRvdGFsRHVyYXRpb24gPyAxIDogTWF0aC5taW4oaXRlcmF0aW9uUHJvZ3Jlc3MsIDEpO1xuICAgICAgICAgICAgY29uc3QgbGF0ZXN0ID0gaW50ZXJwb2xhdGUkMSh0aGlzLmVhc2luZyhwKSk7XG4gICAgICAgICAgICBvdXRwdXQobGF0ZXN0KTtcbiAgICAgICAgICAgIGNvbnN0IGlzQW5pbWF0aW9uRmluaXNoZWQgPSB0aGlzLnBhdXNlVGltZSA9PT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICAgICAgKHRoaXMucGxheVN0YXRlID09PSBcImZpbmlzaGVkXCIgfHwgdCA+PSB0aGlzLnRvdGFsRHVyYXRpb24gKyBlbmREZWxheSk7XG4gICAgICAgICAgICBpZiAoaXNBbmltYXRpb25GaW5pc2hlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMucGxheVN0YXRlID0gXCJmaW5pc2hlZFwiO1xuICAgICAgICAgICAgICAgIChfYSA9IHRoaXMucmVzb2x2ZSkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmNhbGwodGhpcywgbGF0ZXN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMucGxheVN0YXRlICE9PSBcImlkbGVcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuZnJhbWVSZXF1ZXN0SWQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy50aWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGF1dG9wbGF5KVxuICAgICAgICAgICAgdGhpcy5wbGF5KCk7XG4gICAgfVxuICAgIHBsYXkoKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgICB0aGlzLnBsYXlTdGF0ZSA9IFwicnVubmluZ1wiO1xuICAgICAgICBpZiAodGhpcy5wYXVzZVRpbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5zdGFydFRpbWUgPSBub3cgLSB0aGlzLnBhdXNlVGltZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghdGhpcy5zdGFydFRpbWUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhcnRUaW1lID0gbm93O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2FuY2VsVGltZXN0YW1wID0gdGhpcy5zdGFydFRpbWU7XG4gICAgICAgIHRoaXMucGF1c2VUaW1lID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmZyYW1lUmVxdWVzdElkID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMudGljayk7XG4gICAgfVxuICAgIHBhdXNlKCkge1xuICAgICAgICB0aGlzLnBsYXlTdGF0ZSA9IFwicGF1c2VkXCI7XG4gICAgICAgIHRoaXMucGF1c2VUaW1lID0gdGhpcy50O1xuICAgIH1cbiAgICBmaW5pc2goKSB7XG4gICAgICAgIHRoaXMucGxheVN0YXRlID0gXCJmaW5pc2hlZFwiO1xuICAgICAgICB0aGlzLnRpY2soMCk7XG4gICAgfVxuICAgIHN0b3AoKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgdGhpcy5wbGF5U3RhdGUgPSBcImlkbGVcIjtcbiAgICAgICAgaWYgKHRoaXMuZnJhbWVSZXF1ZXN0SWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5mcmFtZVJlcXVlc3RJZCk7XG4gICAgICAgIH1cbiAgICAgICAgKF9hID0gdGhpcy5yZWplY3QpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5jYWxsKHRoaXMsIGZhbHNlKTtcbiAgICB9XG4gICAgY2FuY2VsKCkge1xuICAgICAgICB0aGlzLnN0b3AoKTtcbiAgICAgICAgdGhpcy50aWNrKHRoaXMuY2FuY2VsVGltZXN0YW1wKTtcbiAgICB9XG4gICAgcmV2ZXJzZSgpIHtcbiAgICAgICAgdGhpcy5yYXRlICo9IC0xO1xuICAgIH1cbiAgICBjb21taXRTdHlsZXMoKSB7IH1cbiAgICB1cGRhdGVEdXJhdGlvbihkdXJhdGlvbikge1xuICAgICAgICB0aGlzLmR1cmF0aW9uID0gZHVyYXRpb247XG4gICAgICAgIHRoaXMudG90YWxEdXJhdGlvbiA9IGR1cmF0aW9uICogKHRoaXMucmVwZWF0ICsgMSk7XG4gICAgfVxuICAgIGdldCBjdXJyZW50VGltZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudDtcbiAgICB9XG4gICAgc2V0IGN1cnJlbnRUaW1lKHQpIHtcbiAgICAgICAgaWYgKHRoaXMucGF1c2VUaW1lICE9PSB1bmRlZmluZWQgfHwgdGhpcy5yYXRlID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLnBhdXNlVGltZSA9IHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0VGltZSA9IHBlcmZvcm1hbmNlLm5vdygpIC0gdCAvIHRoaXMucmF0ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgdGhpcy5yYXRlID0gcmF0ZTtcbiAgICB9XG59XG5cbmV4cG9ydCB7IEFuaW1hdGlvbiB9O1xuIiwgInZhciB3YXJuaW5nID0gZnVuY3Rpb24gKCkgeyB9O1xyXG52YXIgaW52YXJpYW50ID0gZnVuY3Rpb24gKCkgeyB9O1xyXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xyXG4gICAgd2FybmluZyA9IGZ1bmN0aW9uIChjaGVjaywgbWVzc2FnZSkge1xyXG4gICAgICAgIGlmICghY2hlY2sgJiYgdHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgaW52YXJpYW50ID0gZnVuY3Rpb24gKGNoZWNrLCBtZXNzYWdlKSB7XHJcbiAgICAgICAgaWYgKCFjaGVjaykge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxufVxuXG5leHBvcnQgeyBpbnZhcmlhbnQsIHdhcm5pbmcgfTtcbiIsICIvKipcbiAqIFRoZSBNb3Rpb25WYWx1ZSB0cmFja3MgdGhlIHN0YXRlIG9mIGEgc2luZ2xlIGFuaW1hdGFibGVcbiAqIHZhbHVlLiBDdXJyZW50bHksIHVwZGF0ZWRBdCBhbmQgY3VycmVudCBhcmUgdW51c2VkLiBUaGVcbiAqIGxvbmcgdGVybSBpZGVhIGlzIHRvIHVzZSB0aGlzIHRvIG1pbmltaXNlIHRoZSBudW1iZXJcbiAqIG9mIERPTSByZWFkcywgYW5kIHRvIGFic3RyYWN0IHRoZSBET00gaW50ZXJhY3Rpb25zIGhlcmUuXG4gKi9cbmNsYXNzIE1vdGlvblZhbHVlIHtcbiAgICBzZXRBbmltYXRpb24oYW5pbWF0aW9uKSB7XG4gICAgICAgIHRoaXMuYW5pbWF0aW9uID0gYW5pbWF0aW9uO1xuICAgICAgICBhbmltYXRpb24gPT09IG51bGwgfHwgYW5pbWF0aW9uID09PSB2b2lkIDAgPyB2b2lkIDAgOiBhbmltYXRpb24uZmluaXNoZWQudGhlbigoKSA9PiB0aGlzLmNsZWFyQW5pbWF0aW9uKCkpLmNhdGNoKCgpID0+IHsgfSk7XG4gICAgfVxuICAgIGNsZWFyQW5pbWF0aW9uKCkge1xuICAgICAgICB0aGlzLmFuaW1hdGlvbiA9IHRoaXMuZ2VuZXJhdG9yID0gdW5kZWZpbmVkO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgTW90aW9uVmFsdWUgfTtcbiIsICJpbXBvcnQgeyBNb3Rpb25WYWx1ZSB9IGZyb20gJ0Btb3Rpb25vbmUvdHlwZXMnO1xuXG5jb25zdCBkYXRhID0gbmV3IFdlYWtNYXAoKTtcbmZ1bmN0aW9uIGdldEFuaW1hdGlvbkRhdGEoZWxlbWVudCkge1xuICAgIGlmICghZGF0YS5oYXMoZWxlbWVudCkpIHtcbiAgICAgICAgZGF0YS5zZXQoZWxlbWVudCwge1xuICAgICAgICAgICAgdHJhbnNmb3JtczogW10sXG4gICAgICAgICAgICB2YWx1ZXM6IG5ldyBNYXAoKSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBkYXRhLmdldChlbGVtZW50KTtcbn1cbmZ1bmN0aW9uIGdldE1vdGlvblZhbHVlKG1vdGlvblZhbHVlcywgbmFtZSkge1xuICAgIGlmICghbW90aW9uVmFsdWVzLmhhcyhuYW1lKSkge1xuICAgICAgICBtb3Rpb25WYWx1ZXMuc2V0KG5hbWUsIG5ldyBNb3Rpb25WYWx1ZSgpKTtcbiAgICB9XG4gICAgcmV0dXJuIG1vdGlvblZhbHVlcy5nZXQobmFtZSk7XG59XG5cbmV4cG9ydCB7IGdldEFuaW1hdGlvbkRhdGEsIGdldE1vdGlvblZhbHVlIH07XG4iLCAiaW1wb3J0IHsgbm9vcFJldHVybiwgYWRkVW5pcXVlSXRlbSB9IGZyb20gJ0Btb3Rpb25vbmUvdXRpbHMnO1xuaW1wb3J0IHsgZ2V0QW5pbWF0aW9uRGF0YSB9IGZyb20gJy4uL2RhdGEuZXMuanMnO1xuXG4vKipcbiAqIEEgbGlzdCBvZiBhbGwgdHJhbnNmb3JtYWJsZSBheGVzLiBXZSdsbCB1c2UgdGhpcyBsaXN0IHRvIGdlbmVyYXRlZCBhIHZlcnNpb25cbiAqIG9mIGVhY2ggYXhlcyBmb3IgZWFjaCB0cmFuc2Zvcm0uXG4gKi9cbmNvbnN0IGF4ZXMgPSBbXCJcIiwgXCJYXCIsIFwiWVwiLCBcIlpcIl07XG4vKipcbiAqIEFuIG9yZGVyZWQgYXJyYXkgb2YgZWFjaCB0cmFuc2Zvcm1hYmxlIHZhbHVlLiBCeSBkZWZhdWx0LCB0cmFuc2Zvcm0gdmFsdWVzXG4gKiB3aWxsIGJlIHNvcnRlZCB0byB0aGlzIG9yZGVyLlxuICovXG5jb25zdCBvcmRlciA9IFtcInRyYW5zbGF0ZVwiLCBcInNjYWxlXCIsIFwicm90YXRlXCIsIFwic2tld1wiXTtcbmNvbnN0IHRyYW5zZm9ybUFsaWFzID0ge1xuICAgIHg6IFwidHJhbnNsYXRlWFwiLFxuICAgIHk6IFwidHJhbnNsYXRlWVwiLFxuICAgIHo6IFwidHJhbnNsYXRlWlwiLFxufTtcbmNvbnN0IHJvdGF0aW9uID0ge1xuICAgIHN5bnRheDogXCI8YW5nbGU+XCIsXG4gICAgaW5pdGlhbFZhbHVlOiBcIjBkZWdcIixcbiAgICB0b0RlZmF1bHRVbml0OiAodikgPT4gdiArIFwiZGVnXCIsXG59O1xuY29uc3QgYmFzZVRyYW5zZm9ybVByb3BlcnRpZXMgPSB7XG4gICAgdHJhbnNsYXRlOiB7XG4gICAgICAgIHN5bnRheDogXCI8bGVuZ3RoLXBlcmNlbnRhZ2U+XCIsXG4gICAgICAgIGluaXRpYWxWYWx1ZTogXCIwcHhcIixcbiAgICAgICAgdG9EZWZhdWx0VW5pdDogKHYpID0+IHYgKyBcInB4XCIsXG4gICAgfSxcbiAgICByb3RhdGU6IHJvdGF0aW9uLFxuICAgIHNjYWxlOiB7XG4gICAgICAgIHN5bnRheDogXCI8bnVtYmVyPlwiLFxuICAgICAgICBpbml0aWFsVmFsdWU6IDEsXG4gICAgICAgIHRvRGVmYXVsdFVuaXQ6IG5vb3BSZXR1cm4sXG4gICAgfSxcbiAgICBza2V3OiByb3RhdGlvbixcbn07XG5jb25zdCB0cmFuc2Zvcm1EZWZpbml0aW9ucyA9IG5ldyBNYXAoKTtcbmNvbnN0IGFzVHJhbnNmb3JtQ3NzVmFyID0gKG5hbWUpID0+IGAtLW1vdGlvbi0ke25hbWV9YDtcbi8qKlxuICogR2VuZXJhdGUgYSBsaXN0IG9mIGV2ZXJ5IHBvc3NpYmxlIHRyYW5zZm9ybSBrZXlcbiAqL1xuY29uc3QgdHJhbnNmb3JtcyA9IFtcInhcIiwgXCJ5XCIsIFwielwiXTtcbm9yZGVyLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICBheGVzLmZvckVhY2goKGF4aXMpID0+IHtcbiAgICAgICAgdHJhbnNmb3Jtcy5wdXNoKG5hbWUgKyBheGlzKTtcbiAgICAgICAgdHJhbnNmb3JtRGVmaW5pdGlvbnMuc2V0KGFzVHJhbnNmb3JtQ3NzVmFyKG5hbWUgKyBheGlzKSwgYmFzZVRyYW5zZm9ybVByb3BlcnRpZXNbbmFtZV0pO1xuICAgIH0pO1xufSk7XG4vKipcbiAqIEEgZnVuY3Rpb24gdG8gdXNlIHdpdGggQXJyYXkuc29ydCB0byBzb3J0IHRyYW5zZm9ybSBrZXlzIGJ5IHRoZWlyIGRlZmF1bHQgb3JkZXIuXG4gKi9cbmNvbnN0IGNvbXBhcmVUcmFuc2Zvcm1PcmRlciA9IChhLCBiKSA9PiB0cmFuc2Zvcm1zLmluZGV4T2YoYSkgLSB0cmFuc2Zvcm1zLmluZGV4T2YoYik7XG4vKipcbiAqIFByb3ZpZGUgYSBxdWljayB3YXkgdG8gY2hlY2sgaWYgYSBzdHJpbmcgaXMgdGhlIG5hbWUgb2YgYSB0cmFuc2Zvcm1cbiAqL1xuY29uc3QgdHJhbnNmb3JtTG9va3VwID0gbmV3IFNldCh0cmFuc2Zvcm1zKTtcbmNvbnN0IGlzVHJhbnNmb3JtID0gKG5hbWUpID0+IHRyYW5zZm9ybUxvb2t1cC5oYXMobmFtZSk7XG5jb25zdCBhZGRUcmFuc2Zvcm1Ub0VsZW1lbnQgPSAoZWxlbWVudCwgbmFtZSkgPT4ge1xuICAgIC8vIE1hcCB4IHRvIHRyYW5zbGF0ZVggZXRjXG4gICAgaWYgKHRyYW5zZm9ybUFsaWFzW25hbWVdKVxuICAgICAgICBuYW1lID0gdHJhbnNmb3JtQWxpYXNbbmFtZV07XG4gICAgY29uc3QgeyB0cmFuc2Zvcm1zIH0gPSBnZXRBbmltYXRpb25EYXRhKGVsZW1lbnQpO1xuICAgIGFkZFVuaXF1ZUl0ZW0odHJhbnNmb3JtcywgbmFtZSk7XG4gICAgLyoqXG4gICAgICogVE9ETzogQW4gb3B0aW1pc2F0aW9uIGhlcmUgY291bGQgYmUgdG8gY2FjaGUgdGhlIHRyYW5zZm9ybSBpbiBlbGVtZW50IGRhdGFcbiAgICAgKiBhbmQgb25seSB1cGRhdGUgaWYgdGhpcyBoYXMgY2hhbmdlZC5cbiAgICAgKi9cbiAgICBlbGVtZW50LnN0eWxlLnRyYW5zZm9ybSA9IGJ1aWxkVHJhbnNmb3JtVGVtcGxhdGUodHJhbnNmb3Jtcyk7XG59O1xuY29uc3QgYnVpbGRUcmFuc2Zvcm1UZW1wbGF0ZSA9ICh0cmFuc2Zvcm1zKSA9PiB0cmFuc2Zvcm1zXG4gICAgLnNvcnQoY29tcGFyZVRyYW5zZm9ybU9yZGVyKVxuICAgIC5yZWR1Y2UodHJhbnNmb3JtTGlzdFRvU3RyaW5nLCBcIlwiKVxuICAgIC50cmltKCk7XG5jb25zdCB0cmFuc2Zvcm1MaXN0VG9TdHJpbmcgPSAodGVtcGxhdGUsIG5hbWUpID0+IGAke3RlbXBsYXRlfSAke25hbWV9KHZhcigke2FzVHJhbnNmb3JtQ3NzVmFyKG5hbWUpfSkpYDtcblxuZXhwb3J0IHsgYWRkVHJhbnNmb3JtVG9FbGVtZW50LCBhc1RyYW5zZm9ybUNzc1ZhciwgYXhlcywgYnVpbGRUcmFuc2Zvcm1UZW1wbGF0ZSwgY29tcGFyZVRyYW5zZm9ybU9yZGVyLCBpc1RyYW5zZm9ybSwgdHJhbnNmb3JtQWxpYXMsIHRyYW5zZm9ybURlZmluaXRpb25zIH07XG4iLCAiaW1wb3J0IHsgdHJhbnNmb3JtRGVmaW5pdGlvbnMgfSBmcm9tICcuL3RyYW5zZm9ybXMuZXMuanMnO1xuXG5jb25zdCBpc0Nzc1ZhciA9IChuYW1lKSA9PiBuYW1lLnN0YXJ0c1dpdGgoXCItLVwiKTtcbmNvbnN0IHJlZ2lzdGVyZWRQcm9wZXJ0aWVzID0gbmV3IFNldCgpO1xuZnVuY3Rpb24gcmVnaXN0ZXJDc3NWYXJpYWJsZShuYW1lKSB7XG4gICAgaWYgKHJlZ2lzdGVyZWRQcm9wZXJ0aWVzLmhhcyhuYW1lKSlcbiAgICAgICAgcmV0dXJuO1xuICAgIHJlZ2lzdGVyZWRQcm9wZXJ0aWVzLmFkZChuYW1lKTtcbiAgICB0cnkge1xuICAgICAgICBjb25zdCB7IHN5bnRheCwgaW5pdGlhbFZhbHVlIH0gPSB0cmFuc2Zvcm1EZWZpbml0aW9ucy5oYXMobmFtZSlcbiAgICAgICAgICAgID8gdHJhbnNmb3JtRGVmaW5pdGlvbnMuZ2V0KG5hbWUpXG4gICAgICAgICAgICA6IHt9O1xuICAgICAgICBDU1MucmVnaXN0ZXJQcm9wZXJ0eSh7XG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgaW5oZXJpdHM6IGZhbHNlLFxuICAgICAgICAgICAgc3ludGF4LFxuICAgICAgICAgICAgaW5pdGlhbFZhbHVlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgY2F0Y2ggKGUpIHsgfVxufVxuXG5leHBvcnQgeyBpc0Nzc1ZhciwgcmVnaXN0ZXJDc3NWYXJpYWJsZSwgcmVnaXN0ZXJlZFByb3BlcnRpZXMgfTtcbiIsICJjb25zdCB0ZXN0QW5pbWF0aW9uID0gKGtleWZyYW1lcywgb3B0aW9ucykgPT4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKS5hbmltYXRlKGtleWZyYW1lcywgb3B0aW9ucyk7XG5jb25zdCBmZWF0dXJlVGVzdHMgPSB7XG4gICAgY3NzUmVnaXN0ZXJQcm9wZXJ0eTogKCkgPT4gdHlwZW9mIENTUyAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuICAgICAgICBPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChDU1MsIFwicmVnaXN0ZXJQcm9wZXJ0eVwiKSxcbiAgICB3YWFwaTogKCkgPT4gT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwoRWxlbWVudC5wcm90b3R5cGUsIFwiYW5pbWF0ZVwiKSxcbiAgICBwYXJ0aWFsS2V5ZnJhbWVzOiAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0ZXN0QW5pbWF0aW9uKHsgb3BhY2l0eTogWzFdIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbiAgICBmaW5pc2hlZDogKCkgPT4gQm9vbGVhbih0ZXN0QW5pbWF0aW9uKHsgb3BhY2l0eTogWzAsIDFdIH0sIHsgZHVyYXRpb246IDAuMDAxIH0pLmZpbmlzaGVkKSxcbiAgICBsaW5lYXJFYXNpbmc6ICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRlc3RBbmltYXRpb24oeyBvcGFjaXR5OiAwIH0sIHsgZWFzaW5nOiBcImxpbmVhcigwLCAxKVwiIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbn07XG5jb25zdCByZXN1bHRzID0ge307XG5jb25zdCBzdXBwb3J0cyA9IHt9O1xuZm9yIChjb25zdCBrZXkgaW4gZmVhdHVyZVRlc3RzKSB7XG4gICAgc3VwcG9ydHNba2V5XSA9ICgpID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdHNba2V5XSA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgcmVzdWx0c1trZXldID0gZmVhdHVyZVRlc3RzW2tleV0oKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdHNba2V5XTtcbiAgICB9O1xufVxuXG5leHBvcnQgeyBzdXBwb3J0cyB9O1xuIiwgImltcG9ydCB7IGlzRnVuY3Rpb24sIGRlZmF1bHRzLCBpc0N1YmljQmV6aWVyLCBwcm9ncmVzcyB9IGZyb20gJ0Btb3Rpb25vbmUvdXRpbHMnO1xuaW1wb3J0IHsgc3VwcG9ydHMgfSBmcm9tICcuL2ZlYXR1cmUtZGV0ZWN0aW9uLmVzLmpzJztcblxuLy8gQ3JlYXRlIGEgbGluZWFyIGVhc2luZyBwb2ludCBmb3IgZXZlcnkgeCBzZWNvbmRcbmNvbnN0IHJlc29sdXRpb24gPSAwLjAxNTtcbmNvbnN0IGdlbmVyYXRlTGluZWFyRWFzaW5nUG9pbnRzID0gKGVhc2luZywgZHVyYXRpb24pID0+IHtcbiAgICBsZXQgcG9pbnRzID0gXCJcIjtcbiAgICBjb25zdCBudW1Qb2ludHMgPSBNYXRoLnJvdW5kKGR1cmF0aW9uIC8gcmVzb2x1dGlvbik7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1Qb2ludHM7IGkrKykge1xuICAgICAgICBwb2ludHMgKz0gZWFzaW5nKHByb2dyZXNzKDAsIG51bVBvaW50cyAtIDEsIGkpKSArIFwiLCBcIjtcbiAgICB9XG4gICAgcmV0dXJuIHBvaW50cy5zdWJzdHJpbmcoMCwgcG9pbnRzLmxlbmd0aCAtIDIpO1xufTtcbmNvbnN0IGNvbnZlcnRFYXNpbmcgPSAoZWFzaW5nLCBkdXJhdGlvbikgPT4ge1xuICAgIGlmIChpc0Z1bmN0aW9uKGVhc2luZykpIHtcbiAgICAgICAgcmV0dXJuIHN1cHBvcnRzLmxpbmVhckVhc2luZygpXG4gICAgICAgICAgICA/IGBsaW5lYXIoJHtnZW5lcmF0ZUxpbmVhckVhc2luZ1BvaW50cyhlYXNpbmcsIGR1cmF0aW9uKX0pYFxuICAgICAgICAgICAgOiBkZWZhdWx0cy5lYXNpbmc7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gaXNDdWJpY0JlemllcihlYXNpbmcpID8gY3ViaWNCZXppZXJBc1N0cmluZyhlYXNpbmcpIDogZWFzaW5nO1xuICAgIH1cbn07XG5jb25zdCBjdWJpY0JlemllckFzU3RyaW5nID0gKFthLCBiLCBjLCBkXSkgPT4gYGN1YmljLWJlemllcigke2F9LCAke2J9LCAke2N9LCAke2R9KWA7XG5cbmV4cG9ydCB7IGNvbnZlcnRFYXNpbmcsIGN1YmljQmV6aWVyQXNTdHJpbmcsIGdlbmVyYXRlTGluZWFyRWFzaW5nUG9pbnRzIH07XG4iLCAiZnVuY3Rpb24gaHlkcmF0ZUtleWZyYW1lcyhrZXlmcmFtZXMsIHJlYWRJbml0aWFsVmFsdWUpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleWZyYW1lcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoa2V5ZnJhbWVzW2ldID09PSBudWxsKSB7XG4gICAgICAgICAgICBrZXlmcmFtZXNbaV0gPSBpID8ga2V5ZnJhbWVzW2kgLSAxXSA6IHJlYWRJbml0aWFsVmFsdWUoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ga2V5ZnJhbWVzO1xufVxuY29uc3Qga2V5ZnJhbWVzTGlzdCA9IChrZXlmcmFtZXMpID0+IEFycmF5LmlzQXJyYXkoa2V5ZnJhbWVzKSA/IGtleWZyYW1lcyA6IFtrZXlmcmFtZXNdO1xuXG5leHBvcnQgeyBoeWRyYXRlS2V5ZnJhbWVzLCBrZXlmcmFtZXNMaXN0IH07XG4iLCAiaW1wb3J0IHsgaXNUcmFuc2Zvcm0sIGFzVHJhbnNmb3JtQ3NzVmFyLCB0cmFuc2Zvcm1BbGlhcyB9IGZyb20gJy4vdHJhbnNmb3Jtcy5lcy5qcyc7XG5cbmZ1bmN0aW9uIGdldFN0eWxlTmFtZShrZXkpIHtcbiAgICBpZiAodHJhbnNmb3JtQWxpYXNba2V5XSlcbiAgICAgICAga2V5ID0gdHJhbnNmb3JtQWxpYXNba2V5XTtcbiAgICByZXR1cm4gaXNUcmFuc2Zvcm0oa2V5KSA/IGFzVHJhbnNmb3JtQ3NzVmFyKGtleSkgOiBrZXk7XG59XG5cbmV4cG9ydCB7IGdldFN0eWxlTmFtZSB9O1xuIiwgImltcG9ydCB7IGlzQ3NzVmFyIH0gZnJvbSAnLi91dGlscy9jc3MtdmFyLmVzLmpzJztcbmltcG9ydCB7IGdldFN0eWxlTmFtZSB9IGZyb20gJy4vdXRpbHMvZ2V0LXN0eWxlLW5hbWUuZXMuanMnO1xuaW1wb3J0IHsgdHJhbnNmb3JtRGVmaW5pdGlvbnMgfSBmcm9tICcuL3V0aWxzL3RyYW5zZm9ybXMuZXMuanMnO1xuXG5jb25zdCBzdHlsZSA9IHtcbiAgICBnZXQ6IChlbGVtZW50LCBuYW1lKSA9PiB7XG4gICAgICAgIG5hbWUgPSBnZXRTdHlsZU5hbWUobmFtZSk7XG4gICAgICAgIGxldCB2YWx1ZSA9IGlzQ3NzVmFyKG5hbWUpXG4gICAgICAgICAgICA/IGVsZW1lbnQuc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKVxuICAgICAgICAgICAgOiBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpW25hbWVdO1xuICAgICAgICBpZiAoIXZhbHVlICYmIHZhbHVlICE9PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBkZWZpbml0aW9uID0gdHJhbnNmb3JtRGVmaW5pdGlvbnMuZ2V0KG5hbWUpO1xuICAgICAgICAgICAgaWYgKGRlZmluaXRpb24pXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBkZWZpbml0aW9uLmluaXRpYWxWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSxcbiAgICBzZXQ6IChlbGVtZW50LCBuYW1lLCB2YWx1ZSkgPT4ge1xuICAgICAgICBuYW1lID0gZ2V0U3R5bGVOYW1lKG5hbWUpO1xuICAgICAgICBpZiAoaXNDc3NWYXIobmFtZSkpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkobmFtZSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZWxlbWVudC5zdHlsZVtuYW1lXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgfSxcbn07XG5cbmV4cG9ydCB7IHN0eWxlIH07XG4iLCAiZnVuY3Rpb24gc3RvcEFuaW1hdGlvbihhbmltYXRpb24sIG5lZWRzQ29tbWl0ID0gdHJ1ZSkge1xuICAgIGlmICghYW5pbWF0aW9uIHx8IGFuaW1hdGlvbi5wbGF5U3RhdGUgPT09IFwiZmluaXNoZWRcIilcbiAgICAgICAgcmV0dXJuO1xuICAgIC8vIFN1cHByZXNzIGVycm9yIHRocm93biBieSBXQUFQSVxuICAgIHRyeSB7XG4gICAgICAgIGlmIChhbmltYXRpb24uc3RvcCkge1xuICAgICAgICAgICAgYW5pbWF0aW9uLnN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG5lZWRzQ29tbWl0ICYmIGFuaW1hdGlvbi5jb21taXRTdHlsZXMoKTtcbiAgICAgICAgICAgIGFuaW1hdGlvbi5jYW5jZWwoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjYXRjaCAoZSkgeyB9XG59XG5cbmV4cG9ydCB7IHN0b3BBbmltYXRpb24gfTtcbiIsICJpbXBvcnQgeyBub29wUmV0dXJuLCBpc1N0cmluZyB9IGZyb20gJ0Btb3Rpb25vbmUvdXRpbHMnO1xuXG5mdW5jdGlvbiBnZXRVbml0Q29udmVydGVyKGtleWZyYW1lcywgZGVmaW5pdGlvbikge1xuICAgIHZhciBfYTtcbiAgICBsZXQgdG9Vbml0ID0gKGRlZmluaXRpb24gPT09IG51bGwgfHwgZGVmaW5pdGlvbiA9PT0gdm9pZCAwID8gdm9pZCAwIDogZGVmaW5pdGlvbi50b0RlZmF1bHRVbml0KSB8fCBub29wUmV0dXJuO1xuICAgIGNvbnN0IGZpbmFsS2V5ZnJhbWUgPSBrZXlmcmFtZXNba2V5ZnJhbWVzLmxlbmd0aCAtIDFdO1xuICAgIGlmIChpc1N0cmluZyhmaW5hbEtleWZyYW1lKSkge1xuICAgICAgICBjb25zdCB1bml0ID0gKChfYSA9IGZpbmFsS2V5ZnJhbWUubWF0Y2goLygtP1tcXGQuXSspKFthLXolXSopLykpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYVsyXSkgfHwgXCJcIjtcbiAgICAgICAgaWYgKHVuaXQpXG4gICAgICAgICAgICB0b1VuaXQgPSAodmFsdWUpID0+IHZhbHVlICsgdW5pdDtcbiAgICB9XG4gICAgcmV0dXJuIHRvVW5pdDtcbn1cblxuZXhwb3J0IHsgZ2V0VW5pdENvbnZlcnRlciB9O1xuIiwgImltcG9ydCB7IGdldEFuaW1hdGlvbkRhdGEsIGdldE1vdGlvblZhbHVlIH0gZnJvbSAnLi9kYXRhLmVzLmpzJztcbmltcG9ydCB7IGlzQ3NzVmFyLCByZWdpc3RlckNzc1ZhcmlhYmxlIH0gZnJvbSAnLi91dGlscy9jc3MtdmFyLmVzLmpzJztcbmltcG9ydCB7IGRlZmF1bHRzLCBpc0Vhc2luZ0dlbmVyYXRvciwgaXNGdW5jdGlvbiwgaXNFYXNpbmdMaXN0LCBpc051bWJlciwgdGltZSwgbm9vcCB9IGZyb20gJ0Btb3Rpb25vbmUvdXRpbHMnO1xuaW1wb3J0IHsgaXNUcmFuc2Zvcm0sIGFkZFRyYW5zZm9ybVRvRWxlbWVudCwgdHJhbnNmb3JtRGVmaW5pdGlvbnMgfSBmcm9tICcuL3V0aWxzL3RyYW5zZm9ybXMuZXMuanMnO1xuaW1wb3J0IHsgY29udmVydEVhc2luZyB9IGZyb20gJy4vdXRpbHMvZWFzaW5nLmVzLmpzJztcbmltcG9ydCB7IHN1cHBvcnRzIH0gZnJvbSAnLi91dGlscy9mZWF0dXJlLWRldGVjdGlvbi5lcy5qcyc7XG5pbXBvcnQgeyBoeWRyYXRlS2V5ZnJhbWVzLCBrZXlmcmFtZXNMaXN0IH0gZnJvbSAnLi91dGlscy9rZXlmcmFtZXMuZXMuanMnO1xuaW1wb3J0IHsgc3R5bGUgfSBmcm9tICcuL3N0eWxlLmVzLmpzJztcbmltcG9ydCB7IGdldFN0eWxlTmFtZSB9IGZyb20gJy4vdXRpbHMvZ2V0LXN0eWxlLW5hbWUuZXMuanMnO1xuaW1wb3J0IHsgc3RvcEFuaW1hdGlvbiB9IGZyb20gJy4vdXRpbHMvc3RvcC1hbmltYXRpb24uZXMuanMnO1xuaW1wb3J0IHsgZ2V0VW5pdENvbnZlcnRlciB9IGZyb20gJy4vdXRpbHMvZ2V0LXVuaXQuZXMuanMnO1xuXG5mdW5jdGlvbiBnZXREZXZUb29sc1JlY29yZCgpIHtcbiAgICByZXR1cm4gd2luZG93Ll9fTU9USU9OX0RFVl9UT09MU19SRUNPUkQ7XG59XG5mdW5jdGlvbiBhbmltYXRlU3R5bGUoZWxlbWVudCwga2V5LCBrZXlmcmFtZXNEZWZpbml0aW9uLCBvcHRpb25zID0ge30sIEFuaW1hdGlvblBvbHlmaWxsKSB7XG4gICAgY29uc3QgcmVjb3JkID0gZ2V0RGV2VG9vbHNSZWNvcmQoKTtcbiAgICBjb25zdCBpc1JlY29yZGluZyA9IG9wdGlvbnMucmVjb3JkICE9PSBmYWxzZSAmJiByZWNvcmQ7XG4gICAgbGV0IGFuaW1hdGlvbjtcbiAgICBsZXQgeyBkdXJhdGlvbiA9IGRlZmF1bHRzLmR1cmF0aW9uLCBkZWxheSA9IGRlZmF1bHRzLmRlbGF5LCBlbmREZWxheSA9IGRlZmF1bHRzLmVuZERlbGF5LCByZXBlYXQgPSBkZWZhdWx0cy5yZXBlYXQsIGVhc2luZyA9IGRlZmF1bHRzLmVhc2luZywgcGVyc2lzdCA9IGZhbHNlLCBkaXJlY3Rpb24sIG9mZnNldCwgYWxsb3dXZWJraXRBY2NlbGVyYXRpb24gPSBmYWxzZSwgYXV0b3BsYXkgPSB0cnVlLCB9ID0gb3B0aW9ucztcbiAgICBjb25zdCBkYXRhID0gZ2V0QW5pbWF0aW9uRGF0YShlbGVtZW50KTtcbiAgICBjb25zdCB2YWx1ZUlzVHJhbnNmb3JtID0gaXNUcmFuc2Zvcm0oa2V5KTtcbiAgICBsZXQgY2FuQW5pbWF0ZU5hdGl2ZWx5ID0gc3VwcG9ydHMud2FhcGkoKTtcbiAgICAvKipcbiAgICAgKiBJZiB0aGlzIGlzIGFuIGluZGl2aWR1YWwgdHJhbnNmb3JtLCB3ZSBuZWVkIHRvIG1hcCBpdHNcbiAgICAgKiBrZXkgdG8gYSBDU1MgdmFyaWFibGUgYW5kIHVwZGF0ZSB0aGUgZWxlbWVudCdzIHRyYW5zZm9ybSBzdHlsZVxuICAgICAqL1xuICAgIHZhbHVlSXNUcmFuc2Zvcm0gJiYgYWRkVHJhbnNmb3JtVG9FbGVtZW50KGVsZW1lbnQsIGtleSk7XG4gICAgY29uc3QgbmFtZSA9IGdldFN0eWxlTmFtZShrZXkpO1xuICAgIGNvbnN0IG1vdGlvblZhbHVlID0gZ2V0TW90aW9uVmFsdWUoZGF0YS52YWx1ZXMsIG5hbWUpO1xuICAgIC8qKlxuICAgICAqIEdldCBkZWZpbml0aW9uIG9mIHZhbHVlLCB0aGlzIHdpbGwgYmUgdXNlZCB0byBjb252ZXJ0IG51bWVyaWNhbFxuICAgICAqIGtleWZyYW1lcyBpbnRvIHRoZSBkZWZhdWx0IHZhbHVlIHR5cGUuXG4gICAgICovXG4gICAgY29uc3QgZGVmaW5pdGlvbiA9IHRyYW5zZm9ybURlZmluaXRpb25zLmdldChuYW1lKTtcbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBjdXJyZW50IGFuaW1hdGlvbiwgaWYgYW55LiBCZWNhdXNlIHRoaXMgd2lsbCB0cmlnZ2VyXG4gICAgICogY29tbWl0U3R5bGVzIChET00gd3JpdGVzKSBhbmQgd2UgbWlnaHQgbGF0ZXIgdHJpZ2dlciBET00gcmVhZHMsXG4gICAgICogdGhpcyBpcyBmaXJlZCBub3cgYW5kIHdlIHJldHVybiBhIGZhY3RvcnkgZnVuY3Rpb24gdG8gY3JlYXRlXG4gICAgICogdGhlIGFjdHVhbCBhbmltYXRpb24gdGhhdCBjYW4gZ2V0IGNhbGxlZCBpbiBiYXRjaCxcbiAgICAgKi9cbiAgICBzdG9wQW5pbWF0aW9uKG1vdGlvblZhbHVlLmFuaW1hdGlvbiwgIShpc0Vhc2luZ0dlbmVyYXRvcihlYXNpbmcpICYmIG1vdGlvblZhbHVlLmdlbmVyYXRvcikgJiZcbiAgICAgICAgb3B0aW9ucy5yZWNvcmQgIT09IGZhbHNlKTtcbiAgICAvKipcbiAgICAgKiBCYXRjaGFibGUgZmFjdG9yeSBmdW5jdGlvbiBjb250YWluaW5nIGFsbCBET00gcmVhZHMuXG4gICAgICovXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVhZEluaXRpYWxWYWx1ZSA9ICgpID0+IHsgdmFyIF9hLCBfYjsgcmV0dXJuIChfYiA9IChfYSA9IHN0eWxlLmdldChlbGVtZW50LCBuYW1lKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogZGVmaW5pdGlvbiA9PT0gbnVsbCB8fCBkZWZpbml0aW9uID09PSB2b2lkIDAgPyB2b2lkIDAgOiBkZWZpbml0aW9uLmluaXRpYWxWYWx1ZSkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogMDsgfTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJlcGxhY2UgbnVsbCB2YWx1ZXMgd2l0aCB0aGUgcHJldmlvdXMga2V5ZnJhbWUgdmFsdWUsIG9yIHJlYWRcbiAgICAgICAgICogaXQgZnJvbSB0aGUgRE9NIGlmIGl0J3MgdGhlIGZpcnN0IGtleWZyYW1lLlxuICAgICAgICAgKi9cbiAgICAgICAgbGV0IGtleWZyYW1lcyA9IGh5ZHJhdGVLZXlmcmFtZXMoa2V5ZnJhbWVzTGlzdChrZXlmcmFtZXNEZWZpbml0aW9uKSwgcmVhZEluaXRpYWxWYWx1ZSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZXRlY3QgdW5pdCB0eXBlIG9mIGtleWZyYW1lcy5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IHRvVW5pdCA9IGdldFVuaXRDb252ZXJ0ZXIoa2V5ZnJhbWVzLCBkZWZpbml0aW9uKTtcbiAgICAgICAgaWYgKGlzRWFzaW5nR2VuZXJhdG9yKGVhc2luZykpIHtcbiAgICAgICAgICAgIGNvbnN0IGN1c3RvbSA9IGVhc2luZy5jcmVhdGVBbmltYXRpb24oa2V5ZnJhbWVzLCBrZXkgIT09IFwib3BhY2l0eVwiLCByZWFkSW5pdGlhbFZhbHVlLCBuYW1lLCBtb3Rpb25WYWx1ZSk7XG4gICAgICAgICAgICBlYXNpbmcgPSBjdXN0b20uZWFzaW5nO1xuICAgICAgICAgICAga2V5ZnJhbWVzID0gY3VzdG9tLmtleWZyYW1lcyB8fCBrZXlmcmFtZXM7XG4gICAgICAgICAgICBkdXJhdGlvbiA9IGN1c3RvbS5kdXJhdGlvbiB8fCBkdXJhdGlvbjtcbiAgICAgICAgfVxuICAgICAgICAvKipcbiAgICAgICAgICogSWYgdGhpcyBpcyBhIENTUyB2YXJpYWJsZSB3ZSBuZWVkIHRvIHJlZ2lzdGVyIGl0IHdpdGggdGhlIGJyb3dzZXJcbiAgICAgICAgICogYmVmb3JlIGl0IGNhbiBiZSBhbmltYXRlZCBuYXRpdmVseS4gV2UgYWxzbyBzZXQgaXQgd2l0aCBzZXRQcm9wZXJ0eVxuICAgICAgICAgKiByYXRoZXIgdGhhbiBkaXJlY3RseSBvbnRvIHRoZSBlbGVtZW50LnN0eWxlIG9iamVjdC5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChpc0Nzc1ZhcihuYW1lKSkge1xuICAgICAgICAgICAgaWYgKHN1cHBvcnRzLmNzc1JlZ2lzdGVyUHJvcGVydHkoKSkge1xuICAgICAgICAgICAgICAgIHJlZ2lzdGVyQ3NzVmFyaWFibGUobmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjYW5BbmltYXRlTmF0aXZlbHkgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvKipcbiAgICAgICAgICogSWYgd2UndmUgYmVlbiBwYXNzZWQgYSBjdXN0b20gZWFzaW5nIGZ1bmN0aW9uLCBhbmQgdGhpcyBicm93c2VyXG4gICAgICAgICAqIGRvZXMgKipub3QqKiBzdXBwb3J0IGxpbmVhcigpIGVhc2luZywgYW5kIHRoZSB2YWx1ZSBpcyBhIHRyYW5zZm9ybVxuICAgICAgICAgKiAoYW5kIHRodXMgYSBwdXJlIG51bWJlcikgd2UgY2FuIHN0aWxsIHN1cHBvcnQgdGhlIGN1c3RvbSBlYXNpbmdcbiAgICAgICAgICogYnkgZmFsbGluZyBiYWNrIHRvIHRoZSBhbmltYXRpb24gcG9seWZpbGwuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAodmFsdWVJc1RyYW5zZm9ybSAmJlxuICAgICAgICAgICAgIXN1cHBvcnRzLmxpbmVhckVhc2luZygpICYmXG4gICAgICAgICAgICAoaXNGdW5jdGlvbihlYXNpbmcpIHx8IChpc0Vhc2luZ0xpc3QoZWFzaW5nKSAmJiBlYXNpbmcuc29tZShpc0Z1bmN0aW9uKSkpKSB7XG4gICAgICAgICAgICBjYW5BbmltYXRlTmF0aXZlbHkgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICAvKipcbiAgICAgICAgICogSWYgd2UgY2FuIGFuaW1hdGUgdGhpcyB2YWx1ZSB3aXRoIFdBQVBJLCBkbyBzby5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChjYW5BbmltYXRlTmF0aXZlbHkpIHtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQ29udmVydCBudW1iZXJzIHRvIGRlZmF1bHQgdmFsdWUgdHlwZXMuIEN1cnJlbnRseSB0aGlzIG9ubHkgc3VwcG9ydHNcbiAgICAgICAgICAgICAqIHRyYW5zZm9ybXMgYnV0IGl0IGNvdWxkIGFsc28gc3VwcG9ydCBvdGhlciB2YWx1ZSB0eXBlcy5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKGRlZmluaXRpb24pIHtcbiAgICAgICAgICAgICAgICBrZXlmcmFtZXMgPSBrZXlmcmFtZXMubWFwKCh2YWx1ZSkgPT4gaXNOdW1iZXIodmFsdWUpID8gZGVmaW5pdGlvbi50b0RlZmF1bHRVbml0KHZhbHVlKSA6IHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogSWYgdGhpcyBicm93c2VyIGRvZXNuJ3Qgc3VwcG9ydCBwYXJ0aWFsL2ltcGxpY2l0IGtleWZyYW1lcyB3ZSBuZWVkIHRvXG4gICAgICAgICAgICAgKiBleHBsaWNpdGx5IHByb3ZpZGUgb25lLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpZiAoa2V5ZnJhbWVzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICAgICAgICAgICghc3VwcG9ydHMucGFydGlhbEtleWZyYW1lcygpIHx8IGlzUmVjb3JkaW5nKSkge1xuICAgICAgICAgICAgICAgIGtleWZyYW1lcy51bnNoaWZ0KHJlYWRJbml0aWFsVmFsdWUoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBhbmltYXRpb25PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIGRlbGF5OiB0aW1lLm1zKGRlbGF5KSxcbiAgICAgICAgICAgICAgICBkdXJhdGlvbjogdGltZS5tcyhkdXJhdGlvbiksXG4gICAgICAgICAgICAgICAgZW5kRGVsYXk6IHRpbWUubXMoZW5kRGVsYXkpLFxuICAgICAgICAgICAgICAgIGVhc2luZzogIWlzRWFzaW5nTGlzdChlYXNpbmcpXG4gICAgICAgICAgICAgICAgICAgID8gY29udmVydEVhc2luZyhlYXNpbmcsIGR1cmF0aW9uKVxuICAgICAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBkaXJlY3Rpb24sXG4gICAgICAgICAgICAgICAgaXRlcmF0aW9uczogcmVwZWF0ICsgMSxcbiAgICAgICAgICAgICAgICBmaWxsOiBcImJvdGhcIixcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhbmltYXRpb24gPSBlbGVtZW50LmFuaW1hdGUoe1xuICAgICAgICAgICAgICAgIFtuYW1lXToga2V5ZnJhbWVzLFxuICAgICAgICAgICAgICAgIG9mZnNldCxcbiAgICAgICAgICAgICAgICBlYXNpbmc6IGlzRWFzaW5nTGlzdChlYXNpbmcpXG4gICAgICAgICAgICAgICAgICAgID8gZWFzaW5nLm1hcCgodGhpc0Vhc2luZykgPT4gY29udmVydEVhc2luZyh0aGlzRWFzaW5nLCBkdXJhdGlvbikpXG4gICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgfSwgYW5pbWF0aW9uT3B0aW9ucyk7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFBvbHlmaWxsIGZpbmlzaGVkIFByb21pc2UgaW4gYnJvd3NlcnMgdGhhdCBkb24ndCBzdXBwb3J0IGl0XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmICghYW5pbWF0aW9uLmZpbmlzaGVkKSB7XG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uLmZpbmlzaGVkID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24ub25maW5pc2ggPSByZXNvbHZlO1xuICAgICAgICAgICAgICAgICAgICBhbmltYXRpb24ub25jYW5jZWwgPSByZWplY3Q7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBrZXlmcmFtZXNba2V5ZnJhbWVzLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgYW5pbWF0aW9uLmZpbmlzaGVkXG4gICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChwZXJzaXN0KVxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgLy8gQXBwbHkgc3R5bGVzIHRvIHRhcmdldFxuICAgICAgICAgICAgICAgIHN0eWxlLnNldChlbGVtZW50LCBuYW1lLCB0YXJnZXQpO1xuICAgICAgICAgICAgICAgIC8vIEVuc3VyZSBmaWxsIG1vZGVzIGRvbid0IHBlcnNpc3RcbiAgICAgICAgICAgICAgICBhbmltYXRpb24uY2FuY2VsKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaChub29wKTtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogVGhpcyBmb3JjZXMgV2Via2l0IHRvIHJ1biBhbmltYXRpb25zIG9uIHRoZSBtYWluIHRocmVhZCBieSBleHBsb2l0aW5nXG4gICAgICAgICAgICAgKiB0aGlzIGNvbmRpdGlvbjpcbiAgICAgICAgICAgICAqIGh0dHBzOi8vdHJhYy53ZWJraXQub3JnL2Jyb3dzZXIvd2Via2l0L3RydW5rL1NvdXJjZS9XZWJDb3JlL3BsYXRmb3JtL2dyYXBoaWNzL2NhL0dyYXBoaWNzTGF5ZXJDQS5jcHA/cmV2PTI4MTIzOCNMMTA5OVxuICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAqIFRoaXMgZml4ZXMgV2Via2l0J3MgdGltaW5nIGJ1Z3MsIGxpa2UgYWNjZWxlcmF0ZWQgYW5pbWF0aW9ucyBmYWxsaW5nXG4gICAgICAgICAgICAgKiBvdXQgb2Ygc3luYyB3aXRoIG1haW4gdGhyZWFkIGFuaW1hdGlvbnMgYW5kIG1hc3NpdmUgZGVsYXlzIGluIHN0YXJ0aW5nXG4gICAgICAgICAgICAgKiBhY2NlbGVyYXRlZCBhbmltYXRpb25zIGluIFdLV2ViVmlldy5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKCFhbGxvd1dlYmtpdEFjY2VsZXJhdGlvbilcbiAgICAgICAgICAgICAgICBhbmltYXRpb24ucGxheWJhY2tSYXRlID0gMS4wMDAwMDE7XG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIElmIHdlIGNhbid0IGFuaW1hdGUgdGhlIHZhbHVlIG5hdGl2ZWx5IHRoZW4gd2UgY2FuIGZhbGxiYWNrIHRvIHRoZSBudW1iZXJzLW9ubHlcbiAgICAgICAgICAgICAqIHBvbHlmaWxsIGZvciB0cmFuc2Zvcm1zLlxuICAgICAgICAgICAgICovXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoQW5pbWF0aW9uUG9seWZpbGwgJiYgdmFsdWVJc1RyYW5zZm9ybSkge1xuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBJZiBhbnkga2V5ZnJhbWUgaXMgYSBzdHJpbmcgKGJlY2F1c2Ugd2UgbWVhc3VyZWQgaXQgZnJvbSB0aGUgRE9NKSwgd2UgbmVlZCB0byBjb252ZXJ0XG4gICAgICAgICAgICAgKiBpdCBpbnRvIGEgbnVtYmVyIGJlZm9yZSBwYXNzaW5nIHRvIHRoZSBBbmltYXRpb24gcG9seWZpbGwuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGtleWZyYW1lcyA9IGtleWZyYW1lcy5tYXAoKHZhbHVlKSA9PiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgPyBwYXJzZUZsb2F0KHZhbHVlKSA6IHZhbHVlKTtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogSWYgd2Ugb25seSBoYXZlIGEgc2luZ2xlIGtleWZyYW1lLCB3ZSBuZWVkIHRvIGNyZWF0ZSBhbiBpbml0aWFsIGtleWZyYW1lIGJ5IHJlYWRpbmdcbiAgICAgICAgICAgICAqIHRoZSBjdXJyZW50IHZhbHVlIGZyb20gdGhlIERPTS5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKGtleWZyYW1lcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICBrZXlmcmFtZXMudW5zaGlmdChwYXJzZUZsb2F0KHJlYWRJbml0aWFsVmFsdWUoKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYW5pbWF0aW9uID0gbmV3IEFuaW1hdGlvblBvbHlmaWxsKChsYXRlc3QpID0+IHtcbiAgICAgICAgICAgICAgICBzdHlsZS5zZXQoZWxlbWVudCwgbmFtZSwgdG9Vbml0ID8gdG9Vbml0KGxhdGVzdCkgOiBsYXRlc3QpO1xuICAgICAgICAgICAgfSwga2V5ZnJhbWVzLCBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMpLCB7IGR1cmF0aW9uLFxuICAgICAgICAgICAgICAgIGVhc2luZyB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB0YXJnZXQgPSBrZXlmcmFtZXNba2V5ZnJhbWVzLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgc3R5bGUuc2V0KGVsZW1lbnQsIG5hbWUsIGRlZmluaXRpb24gJiYgaXNOdW1iZXIodGFyZ2V0KVxuICAgICAgICAgICAgICAgID8gZGVmaW5pdGlvbi50b0RlZmF1bHRVbml0KHRhcmdldClcbiAgICAgICAgICAgICAgICA6IHRhcmdldCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzUmVjb3JkaW5nKSB7XG4gICAgICAgICAgICByZWNvcmQoZWxlbWVudCwga2V5LCBrZXlmcmFtZXMsIHtcbiAgICAgICAgICAgICAgICBkdXJhdGlvbixcbiAgICAgICAgICAgICAgICBkZWxheTogZGVsYXksXG4gICAgICAgICAgICAgICAgZWFzaW5nLFxuICAgICAgICAgICAgICAgIHJlcGVhdCxcbiAgICAgICAgICAgICAgICBvZmZzZXQsXG4gICAgICAgICAgICB9LCBcIm1vdGlvbi1vbmVcIik7XG4gICAgICAgIH1cbiAgICAgICAgbW90aW9uVmFsdWUuc2V0QW5pbWF0aW9uKGFuaW1hdGlvbik7XG4gICAgICAgIGlmIChhbmltYXRpb24gJiYgIWF1dG9wbGF5KVxuICAgICAgICAgICAgYW5pbWF0aW9uLnBhdXNlKCk7XG4gICAgICAgIHJldHVybiBhbmltYXRpb247XG4gICAgfTtcbn1cblxuZXhwb3J0IHsgYW5pbWF0ZVN0eWxlIH07XG4iLCAiY29uc3QgZ2V0T3B0aW9ucyA9IChvcHRpb25zLCBrZXkpID0+IFxuLyoqXG4gKiBUT0RPOiBNYWtlIHRlc3QgZm9yIHRoaXNcbiAqIEFsd2F5cyByZXR1cm4gYSBuZXcgb2JqZWN0IG90aGVyd2lzZSBkZWxheSBpcyBvdmVyd3JpdHRlbiBieSByZXN1bHRzIG9mIHN0YWdnZXJcbiAqIGFuZCB0aGlzIHJlc3VsdHMgaW4gbm8gc3RhZ2dlclxuICovXG5vcHRpb25zW2tleV0gPyBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMpLCBvcHRpb25zW2tleV0pIDogT2JqZWN0LmFzc2lnbih7fSwgb3B0aW9ucyk7XG5cbmV4cG9ydCB7IGdldE9wdGlvbnMgfTtcbiIsICJmdW5jdGlvbiByZXNvbHZlRWxlbWVudHMoZWxlbWVudHMsIHNlbGVjdG9yQ2FjaGUpIHtcbiAgICB2YXIgX2E7XG4gICAgaWYgKHR5cGVvZiBlbGVtZW50cyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICBpZiAoc2VsZWN0b3JDYWNoZSkge1xuICAgICAgICAgICAgKF9hID0gc2VsZWN0b3JDYWNoZVtlbGVtZW50c10pICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6IChzZWxlY3RvckNhY2hlW2VsZW1lbnRzXSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoZWxlbWVudHMpKTtcbiAgICAgICAgICAgIGVsZW1lbnRzID0gc2VsZWN0b3JDYWNoZVtlbGVtZW50c107XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBlbGVtZW50cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoZWxlbWVudHMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKGVsZW1lbnRzIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgICBlbGVtZW50cyA9IFtlbGVtZW50c107XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiBhbiBlbXB0eSBhcnJheVxuICAgICAqL1xuICAgIHJldHVybiBBcnJheS5mcm9tKGVsZW1lbnRzIHx8IFtdKTtcbn1cblxuZXhwb3J0IHsgcmVzb2x2ZUVsZW1lbnRzIH07XG4iLCAiaW1wb3J0IHsgZGVmYXVsdHMsIG5vb3AsIHRpbWUgfSBmcm9tICdAbW90aW9ub25lL3V0aWxzJztcbmltcG9ydCB7IHN0b3BBbmltYXRpb24gfSBmcm9tICcuL3N0b3AtYW5pbWF0aW9uLmVzLmpzJztcblxuY29uc3QgY3JlYXRlQW5pbWF0aW9uID0gKGZhY3RvcnkpID0+IGZhY3RvcnkoKTtcbmNvbnN0IHdpdGhDb250cm9scyA9IChhbmltYXRpb25GYWN0b3J5LCBvcHRpb25zLCBkdXJhdGlvbiA9IGRlZmF1bHRzLmR1cmF0aW9uKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBQcm94eSh7XG4gICAgICAgIGFuaW1hdGlvbnM6IGFuaW1hdGlvbkZhY3RvcnkubWFwKGNyZWF0ZUFuaW1hdGlvbikuZmlsdGVyKEJvb2xlYW4pLFxuICAgICAgICBkdXJhdGlvbixcbiAgICAgICAgb3B0aW9ucyxcbiAgICB9LCBjb250cm9scyk7XG59O1xuLyoqXG4gKiBUT0RPOlxuICogQ3VycmVudGx5IHRoaXMgcmV0dXJucyB0aGUgZmlyc3QgYW5pbWF0aW9uLCBpZGVhbGx5IGl0IHdvdWxkIHJldHVyblxuICogdGhlIGZpcnN0IGFjdGl2ZSBhbmltYXRpb24uXG4gKi9cbmNvbnN0IGdldEFjdGl2ZUFuaW1hdGlvbiA9IChzdGF0ZSkgPT4gc3RhdGUuYW5pbWF0aW9uc1swXTtcbmNvbnN0IGNvbnRyb2xzID0ge1xuICAgIGdldDogKHRhcmdldCwga2V5KSA9PiB7XG4gICAgICAgIGNvbnN0IGFjdGl2ZUFuaW1hdGlvbiA9IGdldEFjdGl2ZUFuaW1hdGlvbih0YXJnZXQpO1xuICAgICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICAgICAgY2FzZSBcImR1cmF0aW9uXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldC5kdXJhdGlvbjtcbiAgICAgICAgICAgIGNhc2UgXCJjdXJyZW50VGltZVwiOlxuICAgICAgICAgICAgICAgIHJldHVybiB0aW1lLnMoKGFjdGl2ZUFuaW1hdGlvbiA9PT0gbnVsbCB8fCBhY3RpdmVBbmltYXRpb24gPT09IHZvaWQgMCA/IHZvaWQgMCA6IGFjdGl2ZUFuaW1hdGlvbltrZXldKSB8fCAwKTtcbiAgICAgICAgICAgIGNhc2UgXCJwbGF5YmFja1JhdGVcIjpcbiAgICAgICAgICAgIGNhc2UgXCJwbGF5U3RhdGVcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gYWN0aXZlQW5pbWF0aW9uID09PSBudWxsIHx8IGFjdGl2ZUFuaW1hdGlvbiA9PT0gdm9pZCAwID8gdm9pZCAwIDogYWN0aXZlQW5pbWF0aW9uW2tleV07XG4gICAgICAgICAgICBjYXNlIFwiZmluaXNoZWRcIjpcbiAgICAgICAgICAgICAgICBpZiAoIXRhcmdldC5maW5pc2hlZCkge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXQuZmluaXNoZWQgPSBQcm9taXNlLmFsbCh0YXJnZXQuYW5pbWF0aW9ucy5tYXAoc2VsZWN0RmluaXNoZWQpKS5jYXRjaChub29wKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldC5maW5pc2hlZDtcbiAgICAgICAgICAgIGNhc2UgXCJzdG9wXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LmFuaW1hdGlvbnMuZm9yRWFjaCgoYW5pbWF0aW9uKSA9PiBzdG9wQW5pbWF0aW9uKGFuaW1hdGlvbikpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjYXNlIFwiZm9yRWFjaE5hdGl2ZVwiOlxuICAgICAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgZm9yIGludGVybmFsIHVzZSBvbmx5LCBmaXJlIGEgY2FsbGJhY2sgZm9yIGVhY2hcbiAgICAgICAgICAgICAgICAgKiB1bmRlcmx5aW5nIGFuaW1hdGlvbi5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICByZXR1cm4gKGNhbGxiYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldC5hbmltYXRpb25zLmZvckVhY2goKGFuaW1hdGlvbikgPT4gY2FsbGJhY2soYW5pbWF0aW9uLCB0YXJnZXQpKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZW9mIChhY3RpdmVBbmltYXRpb24gPT09IG51bGwgfHwgYWN0aXZlQW5pbWF0aW9uID09PSB2b2lkIDAgPyB2b2lkIDAgOiBhY3RpdmVBbmltYXRpb25ba2V5XSkgPT09IFwidW5kZWZpbmVkXCJcbiAgICAgICAgICAgICAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgOiAoKSA9PiB0YXJnZXQuYW5pbWF0aW9ucy5mb3JFYWNoKChhbmltYXRpb24pID0+IGFuaW1hdGlvbltrZXldKCkpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBzZXQ6ICh0YXJnZXQsIGtleSwgdmFsdWUpID0+IHtcbiAgICAgICAgc3dpdGNoIChrZXkpIHtcbiAgICAgICAgICAgIGNhc2UgXCJjdXJyZW50VGltZVwiOlxuICAgICAgICAgICAgICAgIHZhbHVlID0gdGltZS5tcyh2YWx1ZSk7XG4gICAgICAgICAgICAvLyBGYWxsLXRocm91Z2hcbiAgICAgICAgICAgIGNhc2UgXCJwbGF5YmFja1JhdGVcIjpcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRhcmdldC5hbmltYXRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldC5hbmltYXRpb25zW2ldW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG59O1xuY29uc3Qgc2VsZWN0RmluaXNoZWQgPSAoYW5pbWF0aW9uKSA9PiBhbmltYXRpb24uZmluaXNoZWQ7XG5cbmV4cG9ydCB7IGNvbnRyb2xzLCB3aXRoQ29udHJvbHMgfTtcbiIsICJpbXBvcnQgeyBpc051bWJlciwgaXNGdW5jdGlvbiB9IGZyb20gJ0Btb3Rpb25vbmUvdXRpbHMnO1xuaW1wb3J0IHsgZ2V0RWFzaW5nRnVuY3Rpb24gfSBmcm9tICdAbW90aW9ub25lL2FuaW1hdGlvbic7XG5cbmZ1bmN0aW9uIHN0YWdnZXIoZHVyYXRpb24gPSAwLjEsIHsgc3RhcnQgPSAwLCBmcm9tID0gMCwgZWFzaW5nIH0gPSB7fSkge1xuICAgIHJldHVybiAoaSwgdG90YWwpID0+IHtcbiAgICAgICAgY29uc3QgZnJvbUluZGV4ID0gaXNOdW1iZXIoZnJvbSkgPyBmcm9tIDogZ2V0RnJvbUluZGV4KGZyb20sIHRvdGFsKTtcbiAgICAgICAgY29uc3QgZGlzdGFuY2UgPSBNYXRoLmFicyhmcm9tSW5kZXggLSBpKTtcbiAgICAgICAgbGV0IGRlbGF5ID0gZHVyYXRpb24gKiBkaXN0YW5jZTtcbiAgICAgICAgaWYgKGVhc2luZykge1xuICAgICAgICAgICAgY29uc3QgbWF4RGVsYXkgPSB0b3RhbCAqIGR1cmF0aW9uO1xuICAgICAgICAgICAgY29uc3QgZWFzaW5nRnVuY3Rpb24gPSBnZXRFYXNpbmdGdW5jdGlvbihlYXNpbmcpO1xuICAgICAgICAgICAgZGVsYXkgPSBlYXNpbmdGdW5jdGlvbihkZWxheSAvIG1heERlbGF5KSAqIG1heERlbGF5O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdGFydCArIGRlbGF5O1xuICAgIH07XG59XG5mdW5jdGlvbiBnZXRGcm9tSW5kZXgoZnJvbSwgdG90YWwpIHtcbiAgICBpZiAoZnJvbSA9PT0gXCJmaXJzdFwiKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgY29uc3QgbGFzdEluZGV4ID0gdG90YWwgLSAxO1xuICAgICAgICByZXR1cm4gZnJvbSA9PT0gXCJsYXN0XCIgPyBsYXN0SW5kZXggOiBsYXN0SW5kZXggLyAyO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHJlc29sdmVPcHRpb24ob3B0aW9uLCBpLCB0b3RhbCkge1xuICAgIHJldHVybiBpc0Z1bmN0aW9uKG9wdGlvbikgPyBvcHRpb24oaSwgdG90YWwpIDogb3B0aW9uO1xufVxuXG5leHBvcnQgeyBnZXRGcm9tSW5kZXgsIHJlc29sdmVPcHRpb24sIHN0YWdnZXIgfTtcbiIsICJpbXBvcnQgeyBpbnZhcmlhbnQgfSBmcm9tICdoZXktbGlzdGVuJztcbmltcG9ydCB7IGFuaW1hdGVTdHlsZSB9IGZyb20gJy4vYW5pbWF0ZS1zdHlsZS5lcy5qcyc7XG5pbXBvcnQgeyBnZXRPcHRpb25zIH0gZnJvbSAnLi91dGlscy9vcHRpb25zLmVzLmpzJztcbmltcG9ydCB7IHJlc29sdmVFbGVtZW50cyB9IGZyb20gJy4uL3V0aWxzL3Jlc29sdmUtZWxlbWVudHMuZXMuanMnO1xuaW1wb3J0IHsgd2l0aENvbnRyb2xzIH0gZnJvbSAnLi91dGlscy9jb250cm9scy5lcy5qcyc7XG5pbXBvcnQgeyByZXNvbHZlT3B0aW9uIH0gZnJvbSAnLi4vdXRpbHMvc3RhZ2dlci5lcy5qcyc7XG5cbmZ1bmN0aW9uIGNyZWF0ZUFuaW1hdGUoQW5pbWF0ZVBvbHlmaWxsKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIGFuaW1hdGUoZWxlbWVudHMsIGtleWZyYW1lcywgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGVsZW1lbnRzID0gcmVzb2x2ZUVsZW1lbnRzKGVsZW1lbnRzKTtcbiAgICAgICAgY29uc3QgbnVtRWxlbWVudHMgPSBlbGVtZW50cy5sZW5ndGg7XG4gICAgICAgIGludmFyaWFudChCb29sZWFuKG51bUVsZW1lbnRzKSwgXCJObyB2YWxpZCBlbGVtZW50IHByb3ZpZGVkLlwiKTtcbiAgICAgICAgaW52YXJpYW50KEJvb2xlYW4oa2V5ZnJhbWVzKSwgXCJObyBrZXlmcmFtZXMgZGVmaW5lZC5cIik7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGUgYW5kIHN0YXJ0IG5ldyBhbmltYXRpb25zXG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBhbmltYXRpb25GYWN0b3JpZXMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1FbGVtZW50czsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID0gZWxlbWVudHNbaV07XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBrZXlmcmFtZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZU9wdGlvbnMgPSBnZXRPcHRpb25zKG9wdGlvbnMsIGtleSk7XG4gICAgICAgICAgICAgICAgdmFsdWVPcHRpb25zLmRlbGF5ID0gcmVzb2x2ZU9wdGlvbih2YWx1ZU9wdGlvbnMuZGVsYXksIGksIG51bUVsZW1lbnRzKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhbmltYXRpb24gPSBhbmltYXRlU3R5bGUoZWxlbWVudCwga2V5LCBrZXlmcmFtZXNba2V5XSwgdmFsdWVPcHRpb25zLCBBbmltYXRlUG9seWZpbGwpO1xuICAgICAgICAgICAgICAgIGFuaW1hdGlvbkZhY3Rvcmllcy5wdXNoKGFuaW1hdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHdpdGhDb250cm9scyhhbmltYXRpb25GYWN0b3JpZXMsIG9wdGlvbnMsIFxuICAgICAgICAvKipcbiAgICAgICAgICogVE9ETzpcbiAgICAgICAgICogSWYgZWFzaW5nIGlzIHNldCB0byBzcHJpbmcgb3IgZ2xpZGUsIGR1cmF0aW9uIHdpbGwgYmUgZHluYW1pY2FsbHlcbiAgICAgICAgICogZ2VuZXJhdGVkLiBJZGVhbGx5IHdlIHdvdWxkIGR5bmFtaWNhbGx5IGdlbmVyYXRlIHRoaXMgZnJvbVxuICAgICAgICAgKiBhbmltYXRpb24uZWZmZWN0LmdldENvbXB1dGVkVGltaW5nKCkuZHVyYXRpb24gYnV0IHRoaXMgaXNuJ3RcbiAgICAgICAgICogc3VwcG9ydGVkIGluIGlPUzEzIG9yIG91ciBudW1iZXIgcG9seWZpbGwuIFBlcmhhcHMgaXQncyBwb3NzaWJsZVxuICAgICAgICAgKiB0byBQcm94eSBhbmltYXRpb25zIHJldHVybmVkIGZyb20gYW5pbWF0ZVN0eWxlIHRoYXQgaGFzIGR1cmF0aW9uXG4gICAgICAgICAqIGFzIGEgZ2V0dGVyLlxuICAgICAgICAgKi9cbiAgICAgICAgb3B0aW9ucy5kdXJhdGlvbik7XG4gICAgfTtcbn1cblxuZXhwb3J0IHsgY3JlYXRlQW5pbWF0ZSB9O1xuIiwgImltcG9ydCB7IEFuaW1hdGlvbiB9IGZyb20gJ0Btb3Rpb25vbmUvYW5pbWF0aW9uJztcbmltcG9ydCB7IGNyZWF0ZUFuaW1hdGUgfSBmcm9tICcuL2NyZWF0ZS1hbmltYXRlLmVzLmpzJztcblxuY29uc3QgYW5pbWF0ZSA9IGNyZWF0ZUFuaW1hdGUoQW5pbWF0aW9uKTtcblxuZXhwb3J0IHsgYW5pbWF0ZSB9O1xuIiwgImltcG9ydCB7IGFuaW1hdGUgYXMgYW5pbWF0ZSQxLCB3aXRoQ29udHJvbHMgfSBmcm9tICdAbW90aW9ub25lL2RvbSc7XG5pbXBvcnQgeyBpc0Z1bmN0aW9uIH0gZnJvbSAnQG1vdGlvbm9uZS91dGlscyc7XG5pbXBvcnQgeyBBbmltYXRpb24gfSBmcm9tICdAbW90aW9ub25lL2FuaW1hdGlvbic7XG5cbmZ1bmN0aW9uIGFuaW1hdGVQcm9ncmVzcyh0YXJnZXQsIG9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiB3aXRoQ29udHJvbHMoW1xuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbmltYXRpb24gPSBuZXcgQW5pbWF0aW9uKHRhcmdldCwgWzAsIDFdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIGFuaW1hdGlvbi5maW5pc2hlZC5jYXRjaCgoKSA9PiB7IH0pO1xuICAgICAgICAgICAgcmV0dXJuIGFuaW1hdGlvbjtcbiAgICAgICAgfSxcbiAgICBdLCBvcHRpb25zLCBvcHRpb25zLmR1cmF0aW9uKTtcbn1cbmZ1bmN0aW9uIGFuaW1hdGUodGFyZ2V0LCBrZXlmcmFtZXNPck9wdGlvbnMsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBmYWN0b3J5ID0gaXNGdW5jdGlvbih0YXJnZXQpID8gYW5pbWF0ZVByb2dyZXNzIDogYW5pbWF0ZSQxO1xuICAgIHJldHVybiBmYWN0b3J5KHRhcmdldCwga2V5ZnJhbWVzT3JPcHRpb25zLCBvcHRpb25zKTtcbn1cblxuZXhwb3J0IHsgYW5pbWF0ZSwgYW5pbWF0ZVByb2dyZXNzIH07XG4iLCAiaW1wb3J0IHsgYW5pbWF0ZSB9IGZyb20gJ21vdGlvbidcbmltcG9ydCB0eXBlIHsgVmlld0hvb2sgfSBmcm9tICdwaG9lbml4X2xpdmVfdmlldydcblxuZnVuY3Rpb24gaXNIaWRkZW4oZWw6IEhUTUxFbGVtZW50IHwgbnVsbCkge1xuICBpZiAoZWwgPT09IG51bGwpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgcmV0dXJuIGVsLm9mZnNldFBhcmVudCA9PT0gbnVsbFxufVxuXG5mdW5jdGlvbiBpc0ZsYXNoKGVsOiBIVE1MRWxlbWVudCkge1xuICByZXR1cm4gZWwuZGF0YXNldC5jb21wb25lbnQgPT09ICdmbGFzaCdcbn1cblxuLy8gbnVtYmVyIG9mIGZsYXNoZXMgdGhhdCBhcmVuJ3QgaGlkZGVuXG5mdW5jdGlvbiBmbGFzaENvdW50KCkge1xuICBsZXQgbnVtID0gMFxuXG4gIGlmICghaXNIaWRkZW4oZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NlcnZlci1lcnJvcicpKSkge1xuICAgIG51bSArPSAxXG4gIH1cblxuICBpZiAoIWlzSGlkZGVuKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjbGllbnQtZXJyb3InKSkpIHtcbiAgICBudW0gKz0gMVxuICB9XG5cbiAgaWYgKCFpc0hpZGRlbihkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZmxhc2gtaW5mbycpKSkge1xuICAgIG51bSArPSAxXG4gIH1cblxuICBpZiAoIWlzSGlkZGVuKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdmbGFzaC1lcnJvcicpKSkge1xuICAgIG51bSArPSAxXG4gIH1cblxuICByZXR1cm4gbnVtXG59XG5cbi8vIHRpbWUgaW4gbXMgdG8gd2FpdCBiZWZvcmUgcmVtb3ZhbCwgYnV0IGFmdGVyIGFuaW1hdGlvblxuY29uc3QgcmVtb3ZhbFRpbWUgPSA1XG4vLyBhbmltYXRpb24gdGltZSBpbiBtc1xuY29uc3QgYW5pbWF0aW9uVGltZSA9IDU1MFxuLy8gd2hldGhlciBmbGFzaGVzIHNob3VsZCBiZSBjb3VudGVkIGluIG1heEl0ZW1zXG5jb25zdCBtYXhJdGVtc0lnbm9yZXNGbGFzaGVzID0gdHJ1ZVxuLy8gZ2FwIGluIHB4IGJldHdlZW4gdG9hc3RzXG5jb25zdCBnYXAgPSAxNVxuXG5sZXQgbGFzdFRTOiBhbnlbXSA9IFtdXG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIEhUTUxFbGVtZW50IHtcbiAgICBvcmRlcjogbnVtYmVyXG4gICAgdGFyZ2V0RGVzdGluYXRpb246IHN0cmluZ1xuICB9XG59XG5cbmZ1bmN0aW9uIGRvQW5pbWF0aW9ucyhcbiAgdGhpczogVmlld0hvb2ssXG4gIGRlbGF5VGltZTogbnVtYmVyLFxuICBtYXhJdGVtczogbnVtYmVyLFxuICBlbFRvUmVtb3ZlPzogSFRNTEVsZW1lbnRcbikge1xuICBjb25zdCB0cyA9IFtdXG4gIGxldCB0b2FzdHMgPSBBcnJheS5mcm9tKFxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGw8SFRNTEVsZW1lbnQ+KFxuICAgICAgJyN0b2FzdC1ncm91cCBbcGh4LWhvb2s9XCJMaXZlVG9hc3RcIl0nXG4gICAgKVxuICApXG4gICAgLm1hcCh0ID0+IHtcbiAgICAgIGlmIChpc0hpZGRlbih0KSkge1xuICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRcbiAgICAgIH1cbiAgICB9KVxuICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAvLyByZXZlcnNlXG4gICAgLnJldmVyc2UoKVxuXG4gIGlmIChlbFRvUmVtb3ZlKSB7XG4gICAgdG9hc3RzID0gdG9hc3RzLmZpbHRlcih0ID0+IHQgIT09IGVsVG9SZW1vdmUpXG4gIH1cblxuICAvLyBUcmF2ZXJzZSB0aHJvdWdoIGFsbCB0b2FzdHMsIGluIG9yZGVyIHRoZXkgYXBwZWFyIGluIHRoZSBkb20sIGZvciB3aGljaCB0aGV5IGFyZSBOT1QgaGlkZGVuLCBhbmQgYXNzaWduIGVsLm9yZGVyIHRvXG4gIC8vIHRoZWlyIGluZGV4XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdG9hc3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgdG9hc3QgPSB0b2FzdHNbaV0hXG4gICAgaWYgKGlzSGlkZGVuKHRvYXN0KSkge1xuICAgICAgY29udGludWVcbiAgICB9XG4gICAgdG9hc3Qub3JkZXIgPSBpXG5cbiAgICB0c1tpXSA9IHRvYXN0XG4gIH1cblxuICAvLyBub3cgbG9vcCB0aHJvdWdoIHRzIGFuZCBhbmltYXRlIGVhY2ggdG9hc3QgdG8gaXRzIHBvc2l0aW9uXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBtYXggPSBtYXhJdGVtc0lnbm9yZXNGbGFzaGVzID8gbWF4SXRlbXMgKyBmbGFzaENvdW50KCkgOiBtYXhJdGVtc1xuXG4gICAgY29uc3QgdG9hc3QgPSB0c1tpXVxuXG4gICAgbGV0IGRpcmVjdGlvbiA9ICcnXG5cbiAgICBpZiAoXG4gICAgICB0b2FzdC5kYXRhc2V0LmNvcm5lciA9PT0gJ2JvdHRvbV9sZWZ0JyB8fFxuICAgICAgdG9hc3QuZGF0YXNldC5jb3JuZXIgPT09ICdib3R0b21fcmlnaHQnXG4gICAgKSB7XG4gICAgICBkaXJlY3Rpb24gPSAnLSdcbiAgICB9XG5cbiAgICAvLyBDYWxjdWxhdGUgdGhlIHRyYW5zbGF0ZVkgdmFsdWUgd2l0aCBnYXBcbiAgICAvLyBub3cgdGhhdCB0aGV5IGNhbiBiZSBkaWZmZXJlbnQgaGVpZ2h0cywgd2UgbmVlZCB0byBhY3R1YWxseSBjYWx1Y2xhdGUgdGhlIHJlYWwgaGVpZ2h0cyBhbmQgYWRkIHRoZW0gdXAuXG4gICAgbGV0IHZhbCA9IDBcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgdG9hc3Qub3JkZXI7IGorKykge1xuICAgICAgdmFsICs9IHRzW2pdLm9mZnNldEhlaWdodCArIGdhcFxuICAgIH1cblxuICAgIC8vIENhbGN1bGF0ZSBvcGFjaXR5IGJhc2VkIG9uIHBvc2l0aW9uXG4gICAgY29uc3Qgb3BhY2l0eSA9IHRvYXN0Lm9yZGVyID4gbWF4ID8gMCA6IDEgLSAodG9hc3Qub3JkZXIgLSBtYXggKyAxKVxuXG4gICAgLy8gYWxzbyBpZiB0aGlzIGl0ZW0gbW92ZWQgcGFzdCB0aGUgbWF4IGxpbWl0LCBkaXNhYmxlIGNsaWNrIGV2ZW50cyBvbiBpdFxuICAgIGlmICh0b2FzdC5vcmRlciA+PSBtYXgpIHtcbiAgICAgIHRvYXN0LmNsYXNzTGlzdC5yZW1vdmUoJ3BvaW50ZXItZXZlbnRzLWF1dG8nKVxuICAgIH0gZWxzZSB7XG4gICAgICB0b2FzdC5jbGFzc0xpc3QuYWRkKCdwb2ludGVyLWV2ZW50cy1hdXRvJylcbiAgICB9XG5cbiAgICBjb25zdCBrZXlmcmFtZXMgPSB7IHk6IFtgJHtkaXJlY3Rpb259JHt2YWx9cHhgXSwgb3BhY2l0eTogW29wYWNpdHldIH1cblxuICAgIC8vIGlmIGVsZW1lbnQgaXMgZW50ZXJpbmcgZm9yIHRoZSBmaXJzdCB0aW1lLCBzdGFydCBiZWxvdyB0aGUgZm9sZFxuICAgIGlmICh0b2FzdC5vcmRlciA9PT0gMCAmJiBsYXN0VFMuaW5jbHVkZXModG9hc3QpID09PSBmYWxzZSkge1xuICAgICAgY29uc3QgdmFsID0gdG9hc3Qub2Zmc2V0SGVpZ2h0ICsgZ2FwXG4gICAgICBjb25zdCBvcHBvc2l0ZURpcmVjdGlvbiA9IGRpcmVjdGlvbiA9PT0gJy0nID8gJycgOiAnLSdcbiAgICAgIGtleWZyYW1lcy55LnVuc2hpZnQoYCR7b3Bwb3NpdGVEaXJlY3Rpb259JHt2YWx9cHhgKVxuXG4gICAgICBrZXlmcmFtZXMub3BhY2l0eS51bnNoaWZ0KDApXG4gICAgfVxuXG4gICAgdG9hc3QudGFyZ2V0RGVzdGluYXRpb24gPSBgJHtkaXJlY3Rpb259JHt2YWx9cHhgXG5cbiAgICBjb25zdCBkdXJhdGlvbiA9IGFuaW1hdGlvblRpbWUgLyAxMDAwXG5cbiAgICBhbmltYXRlKHRvYXN0LCBrZXlmcmFtZXMsIHtcbiAgICAgIGR1cmF0aW9uLFxuICAgICAgZWFzaW5nOiBbMC4yMiwgMS4wLCAwLjM2LCAxLjBdXG4gICAgfSlcbiAgICB0b2FzdC5vcmRlciArPSAxXG5cbiAgICAvLyBkZWNyZWFzZSB6LWluZGV4XG4gICAgdG9hc3Quc3R5bGUuekluZGV4ID0gKDUwIC0gdG9hc3Qub3JkZXIpLnRvU3RyaW5nKClcblxuICAgIC8vIGlmIHRoaXMgZWxlbWVudCBtb3ZlZCBwYXN0IHRoZSBtYXggaXRlbSBsaW1pdCwgc2VuZCB0aGUgc2lnbmFsIHRvIHJlbW92ZSBpdFxuICAgIC8vIHNob3VsZCB0aGlzIGJlIHNob3J0ZWQgdGhhbiBkZWxheSB0aW1lP1xuICAgIC8vIGFsc28gd2hhdCBhYm91dCBlbGVtZW50cyBtb3ZpbmcgZG93biB3aGVuIHlvdSBjbG9zZSBvbmU/XG4gICAgd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKHRvYXN0Lm9yZGVyID4gbWF4KSB7XG4gICAgICAgIHRoaXMucHVzaEV2ZW50VG8oJyN0b2FzdC1ncm91cCcsICdjbGVhcicsIHsgaWQ6IHRvYXN0LmlkIH0pXG4gICAgICB9XG4gICAgfSwgZGVsYXlUaW1lICsgcmVtb3ZhbFRpbWUpXG5cbiAgICBsYXN0VFMgPSB0c1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGFuaW1hdGVPdXQodGhpczogVmlld0hvb2spIHtcbiAgY29uc3QgdmFsID0gKHRoaXMuZWwub3JkZXIgLSAyKSAqIDEwMCArICh0aGlzLmVsLm9yZGVyIC0gMikgKiBnYXBcblxuICBsZXQgZGlyZWN0aW9uID0gJydcblxuICBpZiAoXG4gICAgdGhpcy5lbC5kYXRhc2V0LmNvcm5lciA9PT0gJ2JvdHRvbV9sZWZ0JyB8fFxuICAgIHRoaXMuZWwuZGF0YXNldC5jb3JuZXIgPT09ICdib3R0b21fcmlnaHQnXG4gICkge1xuICAgIGRpcmVjdGlvbiA9ICctJ1xuICB9XG5cbiAgY29uc3QgYW5pbWF0aW9uID0gYW5pbWF0ZShcbiAgICB0aGlzLmVsLFxuICAgIHsgeTogYCR7ZGlyZWN0aW9ufSR7dmFsfSVgLCBvcGFjaXR5OiAwIH0sXG4gICAge1xuICAgICAgb3BhY2l0eToge1xuICAgICAgICBkdXJhdGlvbjogMC4yLFxuICAgICAgICBlYXNpbmc6ICdlYXNlLW91dCdcbiAgICAgIH0sXG4gICAgICBkdXJhdGlvbjogMC4zLFxuICAgICAgZWFzaW5nOiAnZWFzZS1vdXQnXG4gICAgfVxuICApXG5cbiAgYXdhaXQgYW5pbWF0aW9uLmZpbmlzaGVkXG59XG5cbi8vIENyZWF0ZSB0aGUgUGhvZW5peCBIb29vayBmb3IgbGl2ZV90b2FzdC5cbi8vIFlvdSBjYW4gc2V0IGN1c3RvbSBhbmltYXRpb24gZHVyYXRpb25zLlxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUxpdmVUb2FzdEhvb2soZHVyYXRpb24gPSA2MDAwLCBtYXhJdGVtcyA9IDMpIHtcbiAgcmV0dXJuIHtcbiAgICBkZXN0cm95ZWQodGhpczogVmlld0hvb2spIHtcbiAgICAgIGRvQW5pbWF0aW9ucy5iaW5kKHRoaXMpKGR1cmF0aW9uLCBtYXhJdGVtcylcbiAgICB9LFxuICAgIHVwZGF0ZWQodGhpczogVmlld0hvb2spIHtcbiAgICAgIC8vIGFuaW1hdGUgdG8gdGFyZ2V0RGVzdGluYXRpb24gaW4gMG1zXG4gICAgICBjb25zdCBrZXlmcmFtZXMgPSB7IHk6IFt0aGlzLmVsLnRhcmdldERlc3RpbmF0aW9uXSB9XG4gICAgICBhbmltYXRlKHRoaXMuZWwsIGtleWZyYW1lcywgeyBkdXJhdGlvbjogMCB9KVxuICAgIH0sXG4gICAgbW91bnRlZCh0aGlzOiBWaWV3SG9vaykge1xuICAgICAgLy8gZm9yIHRoZSBzcGVjaWFsIGZsYXNoZXMsIGNoZWNrIGlmIHRoZXkgYXJlIHZpc2libGUsIGFuZCBpZiBub3QsIHJldHVybiBlYXJseSBvdXQgb2YgaGVyZS5cbiAgICAgIGlmIChbJ3NlcnZlci1lcnJvcicsICdjbGllbnQtZXJyb3InXS5pbmNsdWRlcyh0aGlzLmVsLmlkKSkge1xuICAgICAgICBpZiAoaXNIaWRkZW4oZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5lbC5pZCkpKSB7XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2ZsYXNoLWxlYXZlJywgYXN5bmMgZXZlbnQgPT4ge1xuICAgICAgICBpZiAoZXZlbnQudGFyZ2V0ID09PSB0aGlzLmVsKSB7XG4gICAgICAgICAgLy8gYW5pbWF0ZSB0aGlzIGZsYXNoIHNsaWRpbmcgb3V0XG4gICAgICAgICAgZG9BbmltYXRpb25zLmJpbmQodGhpcywgZHVyYXRpb24sIG1heEl0ZW1zLCB0aGlzLmVsKSgpXG4gICAgICAgICAgYXdhaXQgYW5pbWF0ZU91dC5iaW5kKHRoaXMpKClcbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgICAgZG9BbmltYXRpb25zLmJpbmQodGhpcykoZHVyYXRpb24sIG1heEl0ZW1zKVxuXG4gICAgICAvLyBza2lwIHRoZSByZW1vdmFsIGNvZGUgaWYgdGhpcyBpcyBhIGZsYXNoXG4gICAgICBpZiAoaXNGbGFzaCh0aGlzLmVsKSkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgbGV0IGR1cmF0aW9uT3ZlcnJpZGUgPSBkdXJhdGlvblxuICAgICAgaWYgKHRoaXMuZWwuZGF0YXNldC5kdXJhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGR1cmF0aW9uT3ZlcnJpZGUgPSBOdW1iZXIucGFyc2VJbnQodGhpcy5lbC5kYXRhc2V0LmR1cmF0aW9uKVxuICAgICAgfVxuXG4gICAgICB3aW5kb3cuc2V0VGltZW91dChhc3luYyAoKSA9PiB7XG4gICAgICAgIC8vIGFuaW1hdGUgdGhpcyBlbGVtZW50IHNsaWRpbmcgZG93biwgb3BhY2l0eSB0byAwLCB3aXRoIGRlbGF5IHRpbWVcbiAgICAgICAgYXdhaXQgYW5pbWF0ZU91dC5iaW5kKHRoaXMpKClcblxuICAgICAgICB0aGlzLnB1c2hFdmVudFRvKCcjdG9hc3QtZ3JvdXAnLCAnY2xlYXInLCB7IGlkOiB0aGlzLmVsLmlkIH0pXG4gICAgICB9LCBkdXJhdGlvbk92ZXJyaWRlICsgcmVtb3ZhbFRpbWUpXG4gICAgfVxuICB9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBTUEsT0FBQyxTQUFVQSxTQUFRQyxXQUFVO0FBQzNCO0FBR0EsU0FBQyxXQUFZO0FBQ1gsY0FBSSxXQUFXO0FBQ2YsY0FBSSxVQUFVLENBQUMsTUFBTSxPQUFPLFVBQVUsR0FBRztBQUN6QyxtQkFBUyxJQUFJLEdBQUcsSUFBSSxRQUFRLFVBQVUsQ0FBQ0QsUUFBTyx1QkFBdUIsRUFBRSxHQUFHO0FBQ3hFLFlBQUFBLFFBQU8sd0JBQ0xBLFFBQU8sUUFBUSxDQUFDLElBQUksdUJBQXVCO0FBQzdDLFlBQUFBLFFBQU8sdUJBQ0xBLFFBQU8sUUFBUSxDQUFDLElBQUksc0JBQXNCLEtBQzFDQSxRQUFPLFFBQVEsQ0FBQyxJQUFJLDZCQUE2QjtBQUFBLFVBQ3JEO0FBQ0EsY0FBSSxDQUFDQSxRQUFPO0FBQ1YsWUFBQUEsUUFBTyx3QkFBd0IsU0FBVSxVQUFVLFNBQVM7QUFDMUQsa0JBQUksWUFBVyxvQkFBSSxLQUFLLEdBQUUsUUFBUTtBQUNsQyxrQkFBSSxhQUFhLEtBQUssSUFBSSxHQUFHLE1BQU0sV0FBVyxTQUFTO0FBQ3ZELGtCQUFJLEtBQUtBLFFBQU8sV0FBVyxXQUFZO0FBQ3JDLHlCQUFTLFdBQVcsVUFBVTtBQUFBLGNBQ2hDLEdBQUcsVUFBVTtBQUNiLHlCQUFXLFdBQVc7QUFDdEIscUJBQU87QUFBQSxZQUNUO0FBQ0YsY0FBSSxDQUFDQSxRQUFPO0FBQ1YsWUFBQUEsUUFBTyx1QkFBdUIsU0FBVSxJQUFJO0FBQzFDLDJCQUFhLEVBQUU7QUFBQSxZQUNqQjtBQUFBLFFB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U0FBUyxLQUFLLEdBQUcsUUFBUSxRQUFBO1FBQUE7QUFHckQsZUFBTyxXQUFXLFlBQVk7QUFFNUIsZ0JBQU0sV0FBVyxLQUFLLElBQUEsRUFBQTtBQUV0QixlQUFLLFlBQVksZ0JBQWdCLFNBQVMsRUFBRSxJQUFJLEtBQUssR0FBRyxHQUFBLENBQUE7UUFBQSxHQUN2RCxtQkFBbUIsV0FBQTtNQUFBO0lBQUE7RUFBQTs7O0ExQ3BONUIsTUFBSSxZQUFZLFNBQVMsY0FBYyx5QkFBeUIsRUFBRSxhQUFhLFNBQVM7QUFDeEYsTUFBSSxRQUFRO0FBQUEsSUFDVixXQUFXLG9CQUFvQjtBQUFBLEVBQ2pDO0FBQ0EsTUFBSSxhQUFhLElBQUksV0FBVyxTQUFTLFFBQVEsRUFBRSxRQUFRLEVBQUUsYUFBYSxVQUFVLEdBQUcsTUFBTSxDQUFDO0FBSTlGLGdCQUFBQyxRQUFPLE9BQU8sRUFBRSxXQUFXLEVBQUUsR0FBRyxPQUFPLEdBQUcsYUFBYSxvQkFBb0IsQ0FBQztBQUM1RSxTQUFPLGlCQUFpQiwwQkFBMEIsV0FBUyxjQUFBQSxRQUFPLEtBQUssR0FBRyxDQUFDO0FBQzNFLFNBQU8saUJBQWlCLHlCQUF5QixXQUFTLGNBQUFBLFFBQU8sS0FBSyxDQUFDO0FBR3ZFLGFBQVcsUUFBUTtBQU1uQixTQUFPLGFBQWE7IiwKICAibmFtZXMiOiBbIndpbmRvdyIsICJkb2N1bWVudCIsICJzdHlsZSIsICJ0b3BiYXIiLCAiQ3VzdG9tRXZlbnQiLCAiY2xvc3VyZSIsICJkYXRhIiwgImxpdmVTb2NrZXQiLCAiY2xvc3VyZSIsICJkZWZhdWx0cyIsICJkYXRhIiwgInRpbWUiLCAicHJvZ3Jlc3MiLCAiaG9va3MiLCAibm9vcCIsICJ0b3BiYXIiXQp9Cg==