__vite_ssr_exportName__("EnvironmentSupervisor", () => { try { return EnvironmentSupervisor } catch {} });
__vite_ssr_exportName__("make", () => { try { return make } catch {} });
const __vite_ssr_import_0__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/shared/src/relayTracing.ts", {"importedNames":["withRelayClientTracing"]});
const __vite_ssr_import_1__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Cause.js");
const __vite_ssr_import_2__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Clock.js");
const __vite_ssr_import_3__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Context.js");
const __vite_ssr_import_4__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Duration.js");
const __vite_ssr_import_5__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Effect.js");
const __vite_ssr_import_6__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Exit.js");
const __vite_ssr_import_7__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Fiber.js");
const __vite_ssr_import_8__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Option.js");
const __vite_ssr_import_9__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Queue.js");
const __vite_ssr_import_10__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Random.js");
const __vite_ssr_import_11__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Ref.js");
const __vite_ssr_import_12__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Scope.js");
const __vite_ssr_import_13__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Stream.js");
const __vite_ssr_import_14__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/SubscriptionRef.js");
const __vite_ssr_import_15__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/Tracer.js");
const __vite_ssr_import_16__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/connection/connectivity.ts");
const __vite_ssr_import_17__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/connection/driver.ts");
const __vite_ssr_import_18__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/connection/model.ts", {"importedNames":["ConnectionTransientError"]});
const __vite_ssr_import_19__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/rpc/session.ts");
const __vite_ssr_import_20__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/errors/safeLog.ts", {"importedNames":["safeErrorLogAttributes"]});
const __vite_ssr_import_21__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/errors/network.ts", {"importedNames":["NETWORK_BLOCKING_HINT"]});
const __vite_ssr_import_22__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/connection/wakeups.ts");
const __vite_ssr_import_23__ = await __vite_ssr_import__("/@fs/home/ubuntu/wt/pr-24263/packages/client-runtime/src/connection/routes.ts", {"importedNames":["connectionRouteId","connectionRouteKind","connectionRoutes","entryWithRoutes"]});
























const RETRY_BASE_DELAY_MS = 1e3;
const RETRY_MAX_DELAY_MS = 3e5;
// A cold server with a large database can take longer than 15 seconds to
// answer, and that is not a reason to drop a working connection.
const CONNECTION_ESTABLISHMENT_TIMEOUT = "15 seconds";
const establishmentTimeout = __vite_ssr_import_4__.fromInputUnsafe(CONNECTION_ESTABLISHMENT_TIMEOUT);
const synchronizationTimeout = __vite_ssr_import_4__.fromInputUnsafe("75 seconds");
const CONNECTION_PROBE_TIMEOUT = "15 seconds";
const QUICK_CONNECTION_PROBE_TIMEOUT = "3 seconds";
const BACKOFF_RESET_AFTER_MS = 3e4;
const BETTER_ROUTE_CHECK_INTERVAL = "60 seconds";
// A better route that answered the check but then failed to connect is not
// tried again for this long, so a flaky LAN cannot bounce the connection.
const BETTER_ROUTE_COOLDOWN_MS = 3e5;
function exitUnlessInterrupted(effect) {
	return __vite_ssr_import_5__.matchCauseEffect(effect, {
		onFailure: (cause) => __vite_ssr_import_1__.hasInterrupts(cause) ? __vite_ssr_import_5__.interrupt : __vite_ssr_import_5__.succeed(__vite_ssr_import_6__.failCause(cause)),
		onSuccess: (value) => __vite_ssr_import_5__.succeed(__vite_ssr_import_6__.succeed(value))
	});
}
function retryDelayMs(failureCount, random) {
	const ceiling = Math.min(RETRY_MAX_DELAY_MS, RETRY_BASE_DELAY_MS * 2 ** (failureCount + 1));
	return Math.round(ceiling / 2 + ceiling / 2 * random);
}
function annotateTarget(target) {
	return __vite_ssr_import_5__.annotateCurrentSpan({
		"environment.id": target.environmentId,
		"environment.label": target.label,
		"environment.target.kind": target._tag
	});
}
function availableState(intent, generation) {
	return {
		desired: false,
		network: intent.network,
		phase: "available",
		stage: null,
		attempt: 0,
		generation,
		lastFailure: null,
		retryAt: null
	};
}
function offlineState(intent, generation, attempt, lastFailure) {
	return {
		desired: true,
		network: intent.network,
		phase: "offline",
		stage: null,
		attempt,
		generation,
		lastFailure,
		retryAt: null
	};
}
function connectingState(intent, generation, attempt, lastFailure, stage = "preparing") {
	return {
		desired: true,
		network: intent.network,
		phase: "connecting",
		stage,
		attempt,
		generation,
		lastFailure,
		retryAt: null
	};
}
function failureFromExit(target, exit, established, stable) {
	if (__vite_ssr_import_6__.isSuccess(exit) || __vite_ssr_import_1__.hasInterruptsOnly(exit.cause)) {
		return {
			_tag: "Interrupted",
			established,
			stable,
			resetRetry: false
		};
	};
	const typedFailure = exit.cause.reasons.find(__vite_ssr_import_1__.isFailReason);
	if (typedFailure) {
		return {
			_tag: "Failure",
			established,
			stable,
			failure: typedFailure.error
		};
	};
	return {
		_tag: "Failure",
		established,
		stable,
		failure: {
			error: new __vite_ssr_import_18__.ConnectionTransientError({
				reason: "transport",
				detail: `${target.label} connection failed unexpectedly.`
			}),
			attemptSpan: __vite_ssr_import_8__.none()
		}
	};
}
class EnvironmentSupervisor extends __vite_ssr_import_3__.Service()("@t3tools/client-runtime/connection/supervisor/EnvironmentSupervisor") {};
const make = __vite_ssr_import_5__.fn("EnvironmentSupervisor.make")(function* (entry, options) {
	const target = entry.target;
	const usesRelay = (0,__vite_ssr_import_23__.connectionRoutes)(entry).some((route) => route.target._tag === "RelayConnectionTarget");
	const setupTimeoutDetail = `${target.label} did not respond during connection setup.${usesRelay ? ` ${__vite_ssr_import_21__.NETWORK_BLOCKING_HINT}` : ""}`;
	yield* annotateTarget(target);
	const connectivity = yield* __vite_ssr_import_16__.Connectivity;
	const driver = yield* __vite_ssr_import_17__.ConnectionDriver;
	const wakeups = yield* __vite_ssr_import_22__.ConnectionWakeups;
	const initialIntent = {
		desired: options?.initiallyDesired ?? false,
		network: yield* connectivity.status
	};
	const intent = yield* __vite_ssr_import_11__.make(initialIntent);
	const signals = yield* __vite_ssr_import_9__.unbounded();
	const resetRetryState = yield* __vite_ssr_import_11__.make(false);
	const probeUnanswered = yield* __vite_ssr_import_11__.make(false);
	const state = yield* __vite_ssr_import_14__.make(!initialIntent.desired ? availableState(initialIntent, 0) : initialIntent.network === "offline" ? offlineState(initialIntent, 0, 0, null) : connectingState(initialIntent, 0, 1, null));
	const session = yield* __vite_ssr_import_14__.make(__vite_ssr_import_8__.none());
	const prepared = yield* __vite_ssr_import_14__.make(__vite_ssr_import_8__.none());
	// Learned routes arrive while a session is live, so the route list is read
	// fresh by each attempt and check instead of being fixed at creation.
	const currentEntry = yield* __vite_ssr_import_11__.make(entry);
	const currentRoutes = __vite_ssr_import_11__.get(currentEntry).pipe(__vite_ssr_import_5__.map((0,__vite_ssr_import_23__.connectionRoutes)));
	const preferredRouteId = yield* __vite_ssr_import_11__.make(__vite_ssr_import_8__.none());
	const routeCooldowns = yield* __vite_ssr_import_11__.make(new Map());
	const attemptEntry = __vite_ssr_import_5__.gen(function* () {
		const latest = yield* __vite_ssr_import_11__.get(currentEntry);
		const routes = (0,__vite_ssr_import_23__.connectionRoutes)(latest);
		const preferred = yield* __vite_ssr_import_11__.getAndSet(preferredRouteId, __vite_ssr_import_8__.none());
		if (__vite_ssr_import_8__.isNone(preferred)) return latest;
		const route = routes.find((candidate) => (0,__vite_ssr_import_23__.connectionRouteId)(candidate.target) === preferred.value);
		return route === undefined ? latest : (0,__vite_ssr_import_23__.entryWithRoutes)(latest, [route, ...routes.filter((candidate) => candidate !== route)]);
	});
	const learnRoutesFrom = __vite_ssr_import_5__.fnUntraced(function* (learn, lease) {
		const config = yield* lease.session.initialConfig.pipe(__vite_ssr_import_5__.option);
		const reported = __vite_ssr_import_8__.getOrUndefined(config)?.directEndpoints;
		if (reported === undefined) return;
		const activeId = (0,__vite_ssr_import_23__.connectionRouteId)(lease.prepared.target);
		const activeRoute = (yield* currentRoutes).find((route) => (0,__vite_ssr_import_23__.connectionRouteId)(route.target) === activeId);
		if (activeRoute === undefined) return;
		const updated = yield* learn({
			activeRoute,
			reported
		});
		if (__vite_ssr_import_8__.isSome(updated)) {
			yield* __vite_ssr_import_11__.set(currentEntry, updated.value);
			yield* requestBetterRouteCheck(lease);
		}
	});
	const routeIndex = (lease) => currentRoutes.pipe(__vite_ssr_import_5__.map((routes) => routes.findIndex((route) => (0,__vite_ssr_import_23__.connectionRouteId)(route.target) === (0,__vite_ssr_import_23__.connectionRouteId)(lease.prepared.target))));
	const checkBetterRoutes = __vite_ssr_import_5__.fnUntraced(function* (lease) {
		const latest = yield* __vite_ssr_import_11__.get(currentEntry);
		const current = yield* routeIndex(lease);
		if (current <= 0) return;
		const now = yield* __vite_ssr_import_2__.monotonicTimeNanos;
		const cooldowns = yield* __vite_ssr_import_11__.get(routeCooldowns);
		const better = (0,__vite_ssr_import_23__.connectionRoutes)(latest).slice(0, current).filter((route) => (cooldowns.get((0,__vite_ssr_import_23__.connectionRouteId)(route.target)) ?? 0n) <= now);
		const passed = yield* __vite_ssr_import_5__.forEach(better, (route) => driver.preflight(latest, route), { concurrency: "unbounded" });
		const index = passed.indexOf(true);
		if (index === -1) return;
		const live = yield* __vite_ssr_import_14__.get(session);
		if (__vite_ssr_import_8__.isNone(live) || live.value !== lease.session) return;
		yield* signal({
			_tag: "BetterRouteAvailable",
			routeId: (0,__vite_ssr_import_23__.connectionRouteId)(better[index].target)
		});
	});
	const betterRouteChecks = yield* __vite_ssr_import_9__.dropping(1);
	const requestBetterRouteCheck = (lease) => routeIndex(lease).pipe(__vite_ssr_import_5__.flatMap((index) => index > 0 ? __vite_ssr_import_9__.offer(betterRouteChecks, lease).pipe(__vite_ssr_import_5__.asVoid) : __vite_ssr_import_5__.void));
	const clearLease = __vite_ssr_import_5__.all([__vite_ssr_import_14__.set(session, __vite_ssr_import_8__.none()), __vite_ssr_import_14__.set(prepared, __vite_ssr_import_8__.none())], { discard: true });
	const setState = __vite_ssr_import_5__.fn("EnvironmentSupervisor.setState")(function* (next) {
		yield* __vite_ssr_import_14__.set(state, next);
	});
	const signal = __vite_ssr_import_5__.fn("EnvironmentSupervisor.signal")(function* (next) {
		yield* __vite_ssr_import_9__.offer(signals, next);
	});
	const logManagedRelayAccountChange = __vite_ssr_import_5__.logInfo("Managed relay account changed; restarting the environment connection.").pipe(__vite_ssr_import_5__.annotateLogs({
		"environment.id": target.environmentId,
		"environment.label": target.label
	}));
	const reportProgress = __vite_ssr_import_5__.fn("EnvironmentSupervisor.reportProgress")(function* (attempt, generation, lastFailure, progress) {
		if ("prepared" in progress) {
			yield* __vite_ssr_import_14__.set(prepared, __vite_ssr_import_8__.some(progress.prepared));
		};
		yield* setState(connectingState(yield* __vite_ssr_import_11__.get(intent), generation, attempt, lastFailure, progress.stage));
	});
	const establishConnection = __vite_ssr_import_5__.fnUntraced(function* (attempt, generation, lastFailure, synchronizedRoutes) {
		return yield* driver.connect(yield* attemptEntry, (progress) => (progress.stage === "synchronizing" ? __vite_ssr_import_11__.update(synchronizedRoutes, (count) => count + 1) : __vite_ssr_import_5__.void).pipe(__vite_ssr_import_5__.andThen(reportProgress(attempt, generation, lastFailure, progress))));
	});
	// Low-cardinality dimensions for time-to-connected dashboards; the error
	// detail stays in the span status, never in an attribute.
	const annotateAttemptOutcome = __vite_ssr_import_5__.fnUntraced(function* (exit) {
		if (__vite_ssr_import_6__.isSuccess(exit)) {
			const leaseTarget = exit.value.prepared.target;
			const route = (yield* currentRoutes).find((candidate) => (0,__vite_ssr_import_23__.connectionRouteId)(candidate.target) === (0,__vite_ssr_import_23__.connectionRouteId)(leaseTarget));
			return yield* __vite_ssr_import_5__.annotateCurrentSpan({
				"connection.outcome": "connected",
				"connection.route": (0,__vite_ssr_import_23__.connectionRouteKind)(route ?? {
					target: leaseTarget,
					profile: __vite_ssr_import_8__.none()
				})
			});
		};
		if (__vite_ssr_import_1__.hasInterruptsOnly(exit.cause)) {
			return yield* __vite_ssr_import_5__.annotateCurrentSpan("connection.outcome", "interrupted");
		};
		const failure = exit.cause.reasons.find(__vite_ssr_import_1__.isFailReason)?.error;
		yield* __vite_ssr_import_5__.annotateCurrentSpan({
			"connection.outcome": "failed",
			"connection.failure.tag": failure?._tag ?? "defect",
			"connection.failure.reason": failure?.reason ?? "defect"
		});
	});
	const traceRelayEstablishment = (effect, attempt, generation, pendingRetry) => {
		// The span must end with the ConnectionAttemptError itself: the exporter
		// can only describe an Error-like failure, and a TracedAttemptFailure
		// wrapper reached it as "[object Object]". The wrapper is added outside.
		let attemptSpan = __vite_ssr_import_8__.none();
		const traced = __vite_ssr_import_5__.gen(function* () {
			attemptSpan = __vite_ssr_import_8__.some(yield* __vite_ssr_import_5__.currentSpan.pipe(__vite_ssr_import_5__.orDie));
			yield* annotateTarget(target);
			yield* __vite_ssr_import_5__.annotateCurrentSpan({
				"connection.attempt": attempt,
				"connection.generation": generation,
				"connection.retry.failure_count": __vite_ssr_import_8__.match(pendingRetry, {
					onNone: () => 0,
					onSome: (retry) => retry.failureCount
				})
			});
			return yield* effect.pipe(__vite_ssr_import_5__.onExit(annotateAttemptOutcome));
		}).pipe(__vite_ssr_import_5__.withSpan("relay.connection.attempt", { root: true }));
		return __vite_ssr_import_8__.match(pendingRetry, {
			onNone: () => traced,
			onSome: (retry) => traced.pipe(__vite_ssr_import_5__.linkSpans(retry.previousAttempt, {
				"connection.retry.delay_ms": retry.delayMs,
				"connection.retry.reason": retry.reason
			}))
		}).pipe(__vite_ssr_import_5__.map((lease) => ({
			attemptSpan,
			lease
		})), __vite_ssr_import_5__.mapError((error) => ({
			error,
			attemptSpan
		})), (0,__vite_ssr_import_0__.withRelayClientTracing));
	};
	const establishTracedConnection = __vite_ssr_import_5__.fnUntraced(function* (attempt, generation, lastFailure, pendingRetry, synchronizedRoutes) {
		if (usesRelay) {
			return yield* traceRelayEstablishment(establishConnection(attempt, generation, lastFailure, synchronizedRoutes), attempt, generation, pendingRetry);
		};
		return yield* establishConnection(attempt, generation, lastFailure, synchronizedRoutes).pipe(__vite_ssr_import_5__.map((lease) => ({
			attemptSpan: __vite_ssr_import_8__.none(),
			lease
		})), __vite_ssr_import_5__.mapError((error) => ({
			error,
			attemptSpan: __vite_ssr_import_8__.none()
		})));
	});
	const waitForEstablishmentInterrupt = __vite_ssr_import_5__.fnUntraced(function* () {
		for (;;) {
			const next = yield* __vite_ssr_import_9__.take(signals);
			switch (next._tag) {
				case "DisconnectRequested":
				case "RetryRequested": return false;
				case "NetworkChanged":
					if (next.network === "offline") {
						return false;
					};
					break;
				case "ConnectRequested":
				case "BetterRouteAvailable": break;
				case "Wakeup":
					if (next.reason === "application-active-reconnect") {
						return true;
					};
					if (next.reason === "credentials-changed" && usesRelay) {
						yield* logManagedRelayAccountChange;
						return false;
					};
					break;
			}
		}
	});
	const isRelayLease = (lease) => lease.prepared.target._tag === "RelayConnectionTarget";
	const connectedLeaseEnd = __vite_ssr_import_5__.fnUntraced(function* (next, lease) {
		if (next._tag === "DisconnectRequested") {
			return "end";
		};
		if (next._tag === "BetterRouteAvailable") {
			yield* __vite_ssr_import_11__.set(preferredRouteId, __vite_ssr_import_8__.some(next.routeId));
			return "reset";
		};
		if (next._tag !== "Wakeup") {
			return undefined;
		};
		if (next.reason === "application-active-reconnect") {
			// Mobile operating systems often kill a suspended socket without a close
			// event. A probe would show a dead socket as "Resuming" until it times
			// out, so a long background resume replaces the session at once.
			return "reset";
		};
		// Only a session over T3 Connect holds the old account's credential.
		if (next.reason === "credentials-changed" && isRelayLease(lease)) {
			yield* logManagedRelayAccountChange;
			return "end";
		};
		return undefined;
	});
	const probeTimeoutFor = (next) => {
		switch (next._tag) {
			case "RetryRequested": return QUICK_CONNECTION_PROBE_TIMEOUT;
			case "NetworkChanged": return next.network === "offline" ? QUICK_CONNECTION_PROBE_TIMEOUT : undefined;
			case "Wakeup":
				if (next.reason === "application-active") {
					return CONNECTION_PROBE_TIMEOUT;
				};
				return next.reason === "application-active-probe" || next.reason === "network-changed" ? QUICK_CONNECTION_PROBE_TIMEOUT : undefined;
			case "ConnectRequested":
			case "DisconnectRequested":
			case "BetterRouteAvailable": return undefined;
		}
	};
	// Returning to the app, an explicit retry, and the network reporting offline
	// all probe the live session instead of replacing it, so a healthy socket is
	// not torn down (the offline report is often wrong, for example for a
	// loopback server).
	const monitorConnectedLease = __vite_ssr_import_5__.fnUntraced(function* (lease) {
		// A probe answers an explicit retry here, so the retry must not also reset
		// the backoff of a later, unrelated failure.
		const takeSignal = __vite_ssr_import_9__.take(signals).pipe(__vite_ssr_import_5__.tap((next) => next._tag === "RetryRequested" ? __vite_ssr_import_11__.set(resetRetryState, false) : __vite_ssr_import_5__.void));
		// Ticks always run: the check skips the preferred route itself, and the
		// route list can grow while connected (learned routes).
		yield* __vite_ssr_import_13__.tick(BETTER_ROUTE_CHECK_INTERVAL).pipe(__vite_ssr_import_13__.drop(1), __vite_ssr_import_13__.runForEach(() => requestBetterRouteCheck(lease)), __vite_ssr_import_5__.forkScoped);
		for (;;) {
			const next = yield* takeSignal;
			const end = yield* connectedLeaseEnd(next, lease);
			if (end !== undefined) {
				return end === "reset";
			};
			if (next._tag === "NetworkChanged" && next.network !== "offline" || next._tag === "Wakeup" && __vite_ssr_import_22__.resetsRetryBackoff(next.reason)) {
				yield* requestBetterRouteCheck(lease);
			};
			const probeTimeout = probeTimeoutFor(next);
			if (probeTimeout === undefined) {
				continue;
			};
			yield* __vite_ssr_import_11__.set(probeUnanswered, true);
			const probe = yield* __vite_ssr_import_5__.forkChild(lease.session.probe);
			let deadline = (yield* __vite_ssr_import_2__.monotonicTimeNanos) + __vite_ssr_import_4__.toNanosUnsafe(probeTimeout);
			for (;;) {
				const remaining = deadline - (yield* __vite_ssr_import_2__.monotonicTimeNanos);
				const probeEvent = yield* __vite_ssr_import_5__.raceAllFirst([
					__vite_ssr_import_7__.await(probe).pipe(__vite_ssr_import_5__.map((exit) => ({
						_tag: "ProbeCompleted",
						exit
					}))),
					takeSignal.pipe(__vite_ssr_import_5__.map((signal) => ({
						_tag: "Signal",
						signal
					}))),
					__vite_ssr_import_5__.sleep(__vite_ssr_import_4__.nanos(remaining > 0n ? remaining : 0n)).pipe(__vite_ssr_import_5__.as({ _tag: "TimedOut" }))
				]);
				if (probeEvent._tag === "TimedOut") {
					yield* __vite_ssr_import_7__.interrupt(probe);
					return yield* new __vite_ssr_import_18__.ConnectionTransientError({
						reason: "timeout",
						detail: `${target.label} did not respond to a connection health check.`
					});
				};
				if (probeEvent._tag === "ProbeCompleted") {
					if (__vite_ssr_import_6__.isSuccess(probeEvent.exit)) {
						yield* __vite_ssr_import_11__.set(probeUnanswered, false);
					};
					yield* probeEvent.exit;
					break;
				};
				const endDuringProbe = yield* connectedLeaseEnd(probeEvent.signal, lease);
				if (endDuringProbe !== undefined) {
					yield* __vite_ssr_import_7__.interrupt(probe);
					return endDuringProbe === "reset";
				};
				const signalTimeout = probeTimeoutFor(probeEvent.signal);
				if (signalTimeout !== undefined) {
					const signalDeadline = (yield* __vite_ssr_import_2__.monotonicTimeNanos) + __vite_ssr_import_4__.toNanosUnsafe(signalTimeout);
					if (signalDeadline < deadline) deadline = signalDeadline;
				}
			}
		}
	});
	const runAttempt = __vite_ssr_import_5__.fnUntraced(function* (attempt, generation, lastFailure, pendingRetry, ignoreOffline) {
		const switchingTo = yield* __vite_ssr_import_11__.get(preferredRouteId);
		yield* __vite_ssr_import_14__.set(prepared, __vite_ssr_import_8__.none());
		const synchronizedRoutes = yield* __vite_ssr_import_11__.make(0);
		const establishment = yield* __vite_ssr_import_5__.raceAllFirst([
			exitUnlessInterrupted(establishTracedConnection(attempt, generation, lastFailure, pendingRetry, synchronizedRoutes)).pipe(__vite_ssr_import_5__.map((exit) => ({
				_tag: "Completed",
				exit
			}))),
			waitForEstablishmentInterrupt().pipe(__vite_ssr_import_5__.map((resetRetry) => ({
				_tag: "Interrupted",
				resetRetry
			}))),
			__vite_ssr_import_5__.gen(function* () {
				const routeCount = (0,__vite_ssr_import_23__.connectionRoutes)(yield* __vite_ssr_import_11__.get(currentEntry)).length;
				const startedAt = yield* __vite_ssr_import_2__.monotonicTimeNanos;
				const setup = __vite_ssr_import_4__.toNanosUnsafe(__vite_ssr_import_4__.times(establishmentTimeout, routeCount));
				while (true) {
					const synchronized = BigInt(yield* __vite_ssr_import_11__.get(synchronizedRoutes));
					const deadline = startedAt + setup + synchronized * __vite_ssr_import_4__.toNanosUnsafe(synchronizationTimeout);
					const remaining = deadline - (yield* __vite_ssr_import_2__.monotonicTimeNanos);
					if (remaining <= 0n) {
						return { _tag: "TimedOut" };
					};
					yield* __vite_ssr_import_5__.sleep(__vite_ssr_import_4__.nanos(remaining));
				}
			})
		]);
		if (establishment._tag === "Interrupted") {
			return {
				_tag: "Interrupted",
				established: false,
				stable: false,
				resetRetry: establishment.resetRetry
			};
		};
		if (establishment._tag === "TimedOut") {
			return {
				_tag: "Failure",
				established: false,
				stable: false,
				failure: {
					error: new __vite_ssr_import_18__.ConnectionTransientError({
						reason: "timeout",
						detail: setupTimeoutDetail
					}),
					attemptSpan: __vite_ssr_import_8__.none()
				}
			};
		};
		if (__vite_ssr_import_6__.isFailure(establishment.exit)) {
			const isUnexpectedDefect = !__vite_ssr_import_1__.hasInterruptsOnly(establishment.exit.cause) && !establishment.exit.cause.reasons.some(__vite_ssr_import_1__.isFailReason);
			const outcome = failureFromExit(target, establishment.exit, false, false);
			if (isUnexpectedDefect) {
				const defect = establishment.exit.cause.reasons.find(__vite_ssr_import_1__.isDieReason)?.defect;
				yield* __vite_ssr_import_5__.logError("Connection attempt failed with an unexpected defect.").pipe(__vite_ssr_import_5__.annotateLogs({
					"environment.id": target.environmentId,
					"environment.label": target.label,
					"cause.reason_count": establishment.exit.cause.reasons.length,
					...(0,__vite_ssr_import_20__.safeErrorLogAttributes)(defect)
				}));
			};
			return outcome;
		};
		const active = establishment.exit.value;
		if (__vite_ssr_import_8__.isSome(switchingTo)) {
			const landed = (0,__vite_ssr_import_23__.connectionRouteId)(active.lease.prepared.target);
			if (landed !== switchingTo.value) {
				const until = (yield* __vite_ssr_import_2__.monotonicTimeNanos) + BigInt(BETTER_ROUTE_COOLDOWN_MS) * 1000000n;
				yield* __vite_ssr_import_11__.update(routeCooldowns, (current) => new Map(current).set(switchingTo.value, until));
			}
		};
		const currentIntent = yield* __vite_ssr_import_11__.get(intent);
		if (!currentIntent.desired || currentIntent.network === "offline" && !ignoreOffline) {
			return {
				_tag: "Interrupted",
				established: false,
				stable: false,
				resetRetry: false
			};
		};
		const connectedAt = yield* __vite_ssr_import_2__.currentTimeMillis;
		yield* __vite_ssr_import_14__.set(prepared, __vite_ssr_import_8__.some(active.lease.prepared));
		yield* __vite_ssr_import_14__.set(session, __vite_ssr_import_8__.some(active.lease.session));
		if (options?.learnRoutes !== undefined) {
			yield* learnRoutesFrom(options.learnRoutes, active.lease).pipe(__vite_ssr_import_5__.forkScoped);
		};
		yield* setState({
			desired: true,
			network: currentIntent.network,
			phase: "connected",
			stage: null,
			attempt,
			generation,
			lastFailure: null,
			retryAt: null
		});
		const connectedExit = yield* __vite_ssr_import_5__.raceFirst(active.lease.session.closed.pipe(__vite_ssr_import_5__.mapError((error) => ({
			error,
			attemptSpan: active.attemptSpan
		}))), monitorConnectedLease(active.lease).pipe(__vite_ssr_import_5__.mapError((error) => ({
			error,
			attemptSpan: active.attemptSpan
		})))).pipe(exitUnlessInterrupted);
		const connectedForMs = (yield* __vite_ssr_import_2__.currentTimeMillis) - connectedAt;
		if (__vite_ssr_import_6__.isSuccess(connectedExit)) {
			return {
				_tag: "Interrupted",
				established: true,
				stable: connectedForMs >= BACKOFF_RESET_AFTER_MS,
				resetRetry: connectedExit.value
			};
		};
		const outcome = failureFromExit(target, connectedExit, true, connectedForMs >= BACKOFF_RESET_AFTER_MS);
		if (outcome._tag === "Failure") {
			yield* __vite_ssr_import_5__.void.pipe(__vite_ssr_import_5__.withSpan("EnvironmentSupervisor.connectionLost", {
				root: true,
				attributes: {
					"environment.id": target.environmentId,
					"environment.label": target.label,
					"environment.target.kind": target._tag,
					"connection.connected_ms": connectedForMs,
					"connection.failure.reason": outcome.failure.error.reason,
					"connection.failure.detail": outcome.failure.error.detail
				}
			}));
		};
		return outcome;
	}, __vite_ssr_import_5__.ensuring(clearLease));
	const waitForRetrySignal = __vite_ssr_import_5__.fnUntraced(function* (delayMs) {
		// @effect-diagnostics-next-line raceFirstWithSleepToTimeout:off - the sleep is the retry delay (false), not a timeout around the signal loop
		return yield* __vite_ssr_import_5__.raceFirst(__vite_ssr_import_5__.sleep(delayMs).pipe(__vite_ssr_import_5__.as(false)), __vite_ssr_import_5__.gen(function* () {
			for (;;) {
				const next = yield* __vite_ssr_import_9__.take(signals);
				switch (next._tag) {
					case "Wakeup": return __vite_ssr_import_22__.resetsRetryBackoff(next.reason);
					case "ConnectRequested":
					case "DisconnectRequested":
					case "RetryRequested":
					case "NetworkChanged": return false;
					case "BetterRouteAvailable": break;
				}
			}
		}));
	});
	const waitForSignal = __vite_ssr_import_9__.take(signals).pipe(__vite_ssr_import_5__.repeat({ while: (next) => next._tag === "BetterRouteAvailable" }), __vite_ssr_import_5__.map((next) => next._tag === "Wakeup" && __vite_ssr_import_22__.resetsRetryBackoff(next.reason)));
	const run = __vite_ssr_import_5__.fnUntraced(function* () {
		let failureCount = 0;
		let generation = 0;
		let latestFailure = null;
		let pendingRetry = __vite_ssr_import_8__.none();
		const resetRetryLadder = () => {
			failureCount = 0;
			pendingRetry = __vite_ssr_import_8__.none();
		};
		let replacing = false;
		for (;;) {
			if (yield* __vite_ssr_import_11__.getAndSet(resetRetryState, false)) {
				failureCount = 0;
				latestFailure = null;
				pendingRetry = __vite_ssr_import_8__.none();
			};
			const currentIntent = yield* __vite_ssr_import_11__.get(intent);
			if (!currentIntent.desired) {
				resetRetryLadder();
				latestFailure = null;
				yield* clearLease;
				yield* setState(availableState(currentIntent, generation));
				yield* waitForSignal;
				continue;
			};
			if (currentIntent.network === "offline" && !replacing) {
				yield* clearLease;
				yield* setState(offlineState(currentIntent, generation, failureCount + 1, latestFailure));
				const applicationActivated = yield* waitForSignal;
				if (applicationActivated) {
					resetRetryLadder();
				};
				continue;
			};
			const attempt = failureCount + 1;
			const nextGeneration = generation + 1;
			const outcome = yield* __vite_ssr_import_5__.scoped(runAttempt(attempt, nextGeneration, latestFailure, pendingRetry, replacing));
			replacing = false;
			const failedProbe = yield* __vite_ssr_import_11__.getAndSet(probeUnanswered, false);
			if (outcome.established) {
				generation = nextGeneration;
				// A session came up, so no earlier failure describes the connection.
				// Losing a live session is not a failed connection either, for example
				// a socket the OS killed while the app was suspended: its replacement
				// reports no failure until it fails itself.
				latestFailure = null;
				if (outcome.stable) {
					resetRetryLadder();
				}
			};
			if (outcome._tag === "Interrupted") {
				if (outcome.resetRetry) {
					resetRetryLadder();
					replacing = true;
				};
				continue;
			};
			const attemptSpan = outcome.failure.attemptSpan;
			const error = outcome.failure.error;
			if (!outcome.established) {
				latestFailure = error;
			};
			if (error._tag === "ConnectionBlockedError") {
				const blockedIntent = yield* __vite_ssr_import_11__.get(intent);
				yield* setState({
					desired: blockedIntent.desired,
					network: blockedIntent.network,
					phase: "blocked",
					stage: null,
					attempt,
					generation,
					lastFailure: error,
					retryAt: null
				});
				const applicationActivated = yield* waitForSignal;
				if (applicationActivated) {
					resetRetryLadder();
				};
				continue;
			};
			if (failedProbe) {
				resetRetryLadder();
				yield* setState(connectingState(yield* __vite_ssr_import_11__.get(intent), generation, 1, latestFailure));
				continue;
			};
			failureCount += 1;
			const delayMs = retryDelayMs(failureCount - 1, yield* __vite_ssr_import_10__.next);
			pendingRetry = __vite_ssr_import_8__.map(attemptSpan, (previousAttempt) => ({
				previousAttempt,
				failureCount,
				delayMs,
				reason: error.reason
			}));
			const failedIntent = yield* __vite_ssr_import_11__.get(intent);
			yield* setState({
				desired: failedIntent.desired,
				network: failedIntent.network,
				phase: "backoff",
				stage: null,
				attempt,
				generation,
				lastFailure: latestFailure,
				retryAt: (yield* __vite_ssr_import_2__.currentTimeMillis) + delayMs
			});
			const applicationActivated = yield* waitForRetrySignal(delayMs);
			if (applicationActivated) {
				resetRetryLadder();
			}
		}
	});
	yield* connectivity.changes.pipe(__vite_ssr_import_13__.runForEach((network) => __vite_ssr_import_11__.modify(intent, (current) => current.network === network ? [false, current] : [true, {
		...current,
		network
	}]).pipe(__vite_ssr_import_5__.flatMap((changed) => changed ? signal({
		_tag: "NetworkChanged",
		network
	}) : __vite_ssr_import_5__.void))), __vite_ssr_import_5__.forkScoped);
	yield* wakeups.changes.pipe(__vite_ssr_import_13__.runForEach((reason) => signal({
		_tag: "Wakeup",
		reason
	})), __vite_ssr_import_5__.forkScoped);
	yield* __vite_ssr_import_9__.take(betterRouteChecks).pipe(__vite_ssr_import_5__.flatMap(checkBetterRoutes), __vite_ssr_import_5__.forever, __vite_ssr_import_5__.forkScoped);
	yield* run().pipe(__vite_ssr_import_5__.forkScoped);
	const connect = __vite_ssr_import_11__.update(intent, (current) => ({
		...current,
		desired: true
	})).pipe(__vite_ssr_import_5__.andThen(signal({ _tag: "ConnectRequested" })), __vite_ssr_import_5__.withSpan("EnvironmentSupervisor.connect"));
	const disconnect = __vite_ssr_import_11__.update(intent, (current) => ({
		...current,
		desired: false
	})).pipe(__vite_ssr_import_5__.andThen(signal({ _tag: "DisconnectRequested" })), __vite_ssr_import_5__.withSpan("EnvironmentSupervisor.disconnect"));
	const retryNow = __vite_ssr_import_11__.set(resetRetryState, true).pipe(__vite_ssr_import_5__.andThen(signal({ _tag: "RetryRequested" })), __vite_ssr_import_5__.withSpan("EnvironmentSupervisor.retryNow"));
	yield* __vite_ssr_import_5__.addFinalizer(() => __vite_ssr_import_9__.shutdown(signals).pipe(__vite_ssr_import_5__.andThen(clearLease)));
	return EnvironmentSupervisor.of({
		target,
		state,
		session,
		prepared,
		connect,
		disconnect,
		retryNow
	});
});
//# sourceMappingSource=vite-generated
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJtYXBwaW5ncyI6IkFBQUEsQ0FBQTs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFRQSxNQUFNLHNCQUFzQjtBQUM1QixNQUFNLHFCQUFxQjs7O0FBRzNCLE1BQU0sbUNBQW1DO0FBQ3pDLE1BQU0sdUJBQXVCLHNCQUFTLGdCQUFnQixnQ0FBZ0M7QUFDdEYsTUFBTSx5QkFBeUIsc0JBQVMsZ0JBQWdCLFlBQVk7QUFDcEUsTUFBTSwyQkFBMkI7QUFDakMsTUFBTSxpQ0FBaUM7QUFDdkMsTUFBTSx5QkFBeUI7QUFDL0IsTUFBTSw4QkFBOEI7OztBQUdwQyxNQUFNLDJCQUEyQjtBQXVEakMsU0FBUyxzQkFDUCxRQUMwQztDQUMxQyxPQUFPLHNCQUFPLGlCQUFpQixRQUFRO0VBQ3JDLFlBQVksVUFDVixzQkFBTSxjQUFjLEtBQUssSUFBSSxzQkFBTyxZQUFZLHNCQUFPLFFBQVEsc0JBQUssVUFBVSxLQUFLLENBQUM7RUFDdEYsWUFBWSxVQUFVLHNCQUFPLFFBQVEsc0JBQUssUUFBUSxLQUFLLENBQUM7Q0FDMUQsQ0FBQztBQUNIO0FBVUEsU0FBUyxhQUFhLGNBQXNCLFFBQXdCO0NBQ2xFLE1BQU0sVUFBVSxLQUFLLElBQUksb0JBQW9CLHNCQUFzQixNQUFNLGVBQWUsRUFBRTtDQUMxRixPQUFPLEtBQUssTUFBTSxVQUFVLElBQUssVUFBVSxJQUFLLE1BQU07QUFDeEQ7QUFFQSxTQUFTLGVBQWUsUUFBMEI7Q0FDaEQsT0FBTyxzQkFBTyxvQkFBb0I7RUFDaEMsa0JBQWtCLE9BQU87RUFDekIscUJBQXFCLE9BQU87RUFDNUIsMkJBQTJCLE9BQU87Q0FDcEMsQ0FBQztBQUNIO0FBRUEsU0FBUyxlQUFlLFFBQTBCLFlBQStDO0NBQy9GLE9BQU87RUFDTCxTQUFTO0VBQ1QsU0FBUyxPQUFPO0VBQ2hCLE9BQU87RUFDUCxPQUFPO0VBQ1AsU0FBUztFQUNUO0VBQ0EsYUFBYTtFQUNiLFNBQVM7Q0FDWDtBQUNGO0FBRUEsU0FBUyxhQUNQLFFBQ0EsWUFDQSxTQUNBLGFBQzJCO0NBQzNCLE9BQU87RUFDTCxTQUFTO0VBQ1QsU0FBUyxPQUFPO0VBQ2hCLE9BQU87RUFDUCxPQUFPO0VBQ1A7RUFDQTtFQUNBO0VBQ0EsU0FBUztDQUNYO0FBQ0Y7QUFFQSxTQUFTLGdCQUNQLFFBQ0EsWUFDQSxTQUNBLGFBQ0EsUUFBNEMsYUFDakI7Q0FDM0IsT0FBTztFQUNMLFNBQVM7RUFDVCxTQUFTLE9BQU87RUFDaEIsT0FBTztFQUNQO0VBQ0E7RUFDQTtFQUNBO0VBQ0EsU0FBUztDQUNYO0FBQ0Y7QUFFQSxTQUFTLGdCQUNQLFFBQ0EsTUFDQSxhQUNBLFFBQ2dCO0NBQ2hCLElBQUksc0JBQUssVUFBVSxJQUFJLEtBQUssc0JBQU0sa0JBQWtCLEtBQUssS0FBSyxHQUFHO0VBQy9ELE9BQU87R0FBRSxNQUFNO0dBQWU7R0FBYTtHQUFRLFlBQVk7RUFBTTtDQUN2RTtDQUNBLE1BQU0sZUFBZSxLQUFLLE1BQU0sUUFBUSxLQUFLLHNCQUFNLFlBQVk7Q0FDL0QsSUFBSSxjQUFjO0VBQ2hCLE9BQU87R0FDTCxNQUFNO0dBQ047R0FDQTtHQUNBLFNBQVMsYUFBYTtFQUN4QjtDQUNGO0NBQ0EsT0FBTztFQUNMLE1BQU07RUFDTjtFQUNBO0VBQ0EsU0FBUztHQUNQLE9BQU8sSUFBSSxnREFBeUI7SUFDbEMsUUFBUTtJQUNSLFFBQVEsR0FBRyxPQUFPLE1BQU07R0FDMUIsQ0FBQztHQUNELGFBQWEsc0JBQU8sS0FBSztFQUMzQjtDQUNGO0FBQ0Y7QUFFTyxNQUFNLDhCQUE4QixzQkFBUSxRQVdqRCxDQUFDLENBQUMscUVBQXFFLENBQUMsQ0FBQyxDQUFDO0FBRXJFLE1BQU0sT0FBTyxzQkFBTyxHQUFHLDRCQUE0QixDQUFDLENBQUMsV0FDMUQsT0FDQSxTQVFBO0NBQ0EsTUFBTSxTQUFTLE1BQU07Q0FDckIsTUFBTSxZQUFZLDRDQUFpQixLQUFLLENBQUMsQ0FBQyxNQUN2QyxVQUFVLE1BQU0sT0FBTyxTQUFTLHVCQUNuQztDQUNBLE1BQU0scUJBQXFCLEdBQUcsT0FBTyxNQUFNLDJDQUN6QyxZQUFZLElBQUksaURBQTBCO0NBRTVDLE9BQU8sZUFBZSxNQUFNO0NBRTVCLE1BQU0sZUFBZSxPQUFPLHVCQUFhO0NBQ3pDLE1BQU0sU0FBUyxPQUFPLHVCQUFpQjtDQUN2QyxNQUFNLFVBQVUsT0FBTyx1QkFBa0I7Q0FDekMsTUFBTSxnQkFBa0M7RUFDdEMsU0FBUyxTQUFTLG9CQUFvQjtFQUN0QyxTQUFTLE9BQU8sYUFBYTtDQUMvQjtDQUNBLE1BQU0sU0FBUyxPQUFPLHVCQUFJLEtBQUssYUFBYTtDQUM1QyxNQUFNLFVBQVUsT0FBTyxzQkFBTSxVQUE0QjtDQUN6RCxNQUFNLGtCQUFrQixPQUFPLHVCQUFJLEtBQUssS0FBSztDQUM3QyxNQUFNLGtCQUFrQixPQUFPLHVCQUFJLEtBQUssS0FBSztDQUM3QyxNQUFNLFFBQVEsT0FBTyx1QkFBZ0IsS0FDbkMsQ0FBQyxjQUFjLFVBQ1gsZUFBZSxlQUFlLENBQUMsSUFDL0IsY0FBYyxZQUFZLFlBQ3hCLGFBQWEsZUFBZSxHQUFHLEdBQUcsSUFBSSxJQUN0QyxnQkFBZ0IsZUFBZSxHQUFHLEdBQUcsSUFBSSxDQUNqRDtDQUNBLE1BQU0sVUFBVSxPQUFPLHVCQUFnQixLQUEyQyxzQkFBTyxLQUFLLENBQUM7Q0FDL0YsTUFBTSxXQUFXLE9BQU8sdUJBQWdCLEtBQXdDLHNCQUFPLEtBQUssQ0FBQzs7O0NBRzdGLE1BQU0sZUFBZSxPQUFPLHVCQUFJLEtBQUssS0FBSztDQUMxQyxNQUFNLGdCQUFnQix1QkFBSSxJQUFJLFlBQVksQ0FBQyxDQUFDLEtBQUssc0JBQU8sT0FBSSx3Q0FBZ0IsQ0FBQztDQUM3RSxNQUFNLG1CQUFtQixPQUFPLHVCQUFJLEtBQUssc0JBQU8sS0FBYSxDQUFDO0NBQzlELE1BQU0saUJBQWlCLE9BQU8sdUJBQUksS0FBa0MsSUFBSSxJQUFJLENBQUM7Q0FFN0UsTUFBTSxlQUFlLHNCQUFPLElBQUksYUFBYTtFQUMzQyxNQUFNLFNBQVMsT0FBTyx1QkFBSSxJQUFJLFlBQVk7RUFDMUMsTUFBTSxTQUFTLDRDQUFpQixNQUFNO0VBQ3RDLE1BQU0sWUFBWSxPQUFPLHVCQUFJLFVBQVUsa0JBQWtCLHNCQUFPLEtBQUssQ0FBQztFQUN0RSxJQUFJLHNCQUFPLE9BQU8sU0FBUyxHQUFHLE9BQU87RUFDckMsTUFBTSxRQUFRLE9BQU8sTUFDbEIsY0FBYyw2Q0FBa0IsVUFBVSxNQUFNLE1BQU0sVUFBVSxLQUNuRTtFQUNBLE9BQU8sVUFBVSxZQUNiLFNBQ0EsMkNBQWdCLFFBQVEsQ0FBQyxPQUFPLEdBQUcsT0FBTyxRQUFRLGNBQWMsY0FBYyxLQUFLLENBQUMsQ0FBQztDQUMzRixDQUFDO0NBRUQsTUFBTSxrQkFBa0Isc0JBQU8sV0FBVyxXQUN4QyxPQUNBLE9BQ0E7RUFDQSxNQUFNLFNBQVMsT0FBTyxNQUFNLFFBQVEsY0FBYyxLQUFLLHNCQUFPLE1BQU07RUFDcEUsTUFBTSxXQUFXLHNCQUFPLGVBQWUsTUFBTSxDQUFDLEVBQUU7RUFDaEQsSUFBSSxhQUFhLFdBQVc7RUFDNUIsTUFBTSxXQUFXLDZDQUFrQixNQUFNLFNBQVMsTUFBTTtFQUN4RCxNQUFNLGVBQWUsT0FBTyxjQUFhLENBQUUsTUFDeEMsVUFBVSw2Q0FBa0IsTUFBTSxNQUFNLE1BQU0sUUFDakQ7RUFDQSxJQUFJLGdCQUFnQixXQUFXO0VBQy9CLE1BQU0sVUFBVSxPQUFPLE1BQU07R0FBRTtHQUFhO0VBQVMsQ0FBQztFQUN0RCxJQUFJLHNCQUFPLE9BQU8sT0FBTyxHQUFHO0dBQzFCLE9BQU8sdUJBQUksSUFBSSxjQUFjLFFBQVEsS0FBSztHQUMxQyxPQUFPLHdCQUF3QixLQUFLO0VBQ3RDO0NBQ0YsQ0FBQztDQUVELE1BQU0sY0FBYyxVQUNsQixjQUFjLEtBQ1osc0JBQU8sS0FBSyxXQUNWLE9BQU8sV0FDSixVQUFVLDZDQUFrQixNQUFNLE1BQU0sTUFBTSw2Q0FBa0IsTUFBTSxTQUFTLE1BQU0sQ0FDeEYsQ0FDRixDQUNGO0NBRUYsTUFBTSxvQkFBb0Isc0JBQU8sV0FBVyxXQUMxQyxPQUNBO0VBQ0EsTUFBTSxTQUFTLE9BQU8sdUJBQUksSUFBSSxZQUFZO0VBQzFDLE1BQU0sVUFBVSxPQUFPLFdBQVcsS0FBSztFQUN2QyxJQUFJLFdBQVcsR0FBRztFQUNsQixNQUFNLE1BQU0sT0FBTyxzQkFBTTtFQUN6QixNQUFNLFlBQVksT0FBTyx1QkFBSSxJQUFJLGNBQWM7RUFDL0MsTUFBTSxTQUFTLDRDQUFpQixNQUFNLENBQUMsQ0FDcEMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxDQUNqQixRQUFRLFdBQVcsVUFBVSxJQUFJLDZDQUFrQixNQUFNLE1BQU0sQ0FBQyxLQUFLLE9BQU8sR0FBRztFQUNsRixNQUFNLFNBQVMsT0FBTyxzQkFBTyxRQUMzQixTQUNDLFVBQTJCLE9BQU8sVUFBVSxRQUFRLEtBQUssR0FDMUQsRUFBRSxhQUFhLFlBQVksQ0FDN0I7RUFDQSxNQUFNLFFBQVEsT0FBTyxRQUFRLElBQUk7RUFDakMsSUFBSSxVQUFVLENBQUMsR0FBRztFQUNsQixNQUFNLE9BQU8sT0FBTyx1QkFBZ0IsSUFBSSxPQUFPO0VBQy9DLElBQUksc0JBQU8sT0FBTyxJQUFJLEtBQUssS0FBSyxVQUFVLE1BQU0sU0FBUztFQUN6RCxPQUFPLE9BQU87R0FDWixNQUFNO0dBQ04sU0FBUyw2Q0FBa0IsT0FBTyxNQUFNLENBQUUsTUFBTTtFQUNsRCxDQUFDO0NBQ0gsQ0FBQztDQUVELE1BQU0sb0JBQW9CLE9BQU8sc0JBQU0sU0FBc0QsQ0FBQztDQUM5RixNQUFNLDJCQUEyQixVQUMvQixXQUFXLEtBQUssQ0FBQyxDQUFDLEtBQ2hCLHNCQUFPLFNBQVMsVUFDZCxRQUFRLElBQUksc0JBQU0sTUFBTSxtQkFBbUIsS0FBSyxDQUFDLENBQUMsS0FBSyxzQkFBTyxNQUFNLElBQUksc0JBQU8sSUFDakYsQ0FDRjtDQUVGLE1BQU0sYUFBYSxzQkFBTyxJQUN4QixDQUFDLHVCQUFnQixJQUFJLFNBQVMsc0JBQU8sS0FBSyxDQUFDLEdBQUcsdUJBQWdCLElBQUksVUFBVSxzQkFBTyxLQUFLLENBQUMsQ0FBQyxHQUMxRixFQUFFLFNBQVMsS0FBSyxDQUNsQjtDQUVBLE1BQU0sV0FBVyxzQkFBTyxHQUFHLGdDQUFnQyxDQUFDLENBQUMsV0FDM0QsTUFDQTtFQUNBLE9BQU8sdUJBQWdCLElBQUksT0FBTyxJQUFJO0NBQ3hDLENBQUM7Q0FFRCxNQUFNLFNBQVMsc0JBQU8sR0FBRyw4QkFBOEIsQ0FBQyxDQUFDLFdBQVcsTUFBd0I7RUFDMUYsT0FBTyxzQkFBTSxNQUFNLFNBQVMsSUFBSTtDQUNsQyxDQUFDO0NBRUQsTUFBTSwrQkFBK0Isc0JBQU8sUUFDMUMsdUVBQ0YsQ0FBQyxDQUFDLEtBQ0Esc0JBQU8sYUFBYTtFQUNsQixrQkFBa0IsT0FBTztFQUN6QixxQkFBcUIsT0FBTztDQUM5QixDQUFDLENBQ0g7Q0FFQSxNQUFNLGlCQUFpQixzQkFBTyxHQUFHLHNDQUFzQyxDQUFDLENBQUMsV0FDdkUsU0FDQSxZQUNBLGFBQ0EsVUFDQTtFQUNBLElBQUksY0FBYyxVQUFVO0dBQzFCLE9BQU8sdUJBQWdCLElBQUksVUFBVSxzQkFBTyxLQUFLLFNBQVMsUUFBUSxDQUFDO0VBQ3JFO0VBQ0EsT0FBTyxTQUNMLGdCQUFnQixPQUFPLHVCQUFJLElBQUksTUFBTSxHQUFHLFlBQVksU0FBUyxhQUFhLFNBQVMsS0FBSyxDQUMxRjtDQUNGLENBQUM7Q0FFRCxNQUFNLHNCQUFzQixzQkFBTyxXQUFXLFdBQzVDLFNBQ0EsWUFDQSxhQUNBLG9CQUNBO0VBQ0EsT0FBTyxPQUFPLE9BQU8sUUFBUSxPQUFPLGVBQWUsY0FDaEQsU0FBUyxVQUFVLGtCQUNoQix1QkFBSSxPQUFPLHFCQUFxQixVQUFVLFFBQVEsQ0FBQyxJQUNuRCxzQkFBTyxLQUFJLENBQ2IsS0FBSyxzQkFBTyxRQUFRLGVBQWUsU0FBUyxZQUFZLGFBQWEsUUFBUSxDQUFDLENBQUMsQ0FDbkY7Q0FDRixDQUFDOzs7Q0FJRCxNQUFNLHlCQUF5QixzQkFBTyxXQUFXLFdBQy9DLE1BQ0E7RUFDQSxJQUFJLHNCQUFLLFVBQVUsSUFBSSxHQUFHO0dBQ3hCLE1BQU0sY0FBYyxLQUFLLE1BQU0sU0FBUztHQUN4QyxNQUFNLFNBQVMsT0FBTyxjQUFhLENBQUUsTUFDbEMsY0FBYyw2Q0FBa0IsVUFBVSxNQUFNLE1BQU0sNkNBQWtCLFdBQVcsQ0FDdEY7R0FDQSxPQUFPLE9BQU8sc0JBQU8sb0JBQW9CO0lBQ3ZDLHNCQUFzQjtJQUN0QixvQkFBb0IsK0NBQ2xCLFNBQVM7S0FBRSxRQUFRO0tBQWEsU0FBUyxzQkFBTyxLQUFLO0lBQUUsQ0FDekQ7R0FDRixDQUFDO0VBQ0g7RUFDQSxJQUFJLHNCQUFNLGtCQUFrQixLQUFLLEtBQUssR0FBRztHQUN2QyxPQUFPLE9BQU8sc0JBQU8sb0JBQW9CLHNCQUFzQixhQUFhO0VBQzlFO0VBQ0EsTUFBTSxVQUFVLEtBQUssTUFBTSxRQUFRLEtBQUssc0JBQU0sWUFBWSxDQUFDLEVBQUU7RUFDN0QsT0FBTyxzQkFBTyxvQkFBb0I7R0FDaEMsc0JBQXNCO0dBQ3RCLDBCQUEwQixTQUFTLFFBQVE7R0FDM0MsNkJBQTZCLFNBQVMsVUFBVTtFQUNsRCxDQUFDO0NBQ0gsQ0FBQztDQUVELE1BQU0sMkJBQ0osUUFLQSxTQUNBLFlBQ0EsaUJBQ0c7Ozs7RUFJSCxJQUFJLGNBQWMsc0JBQU8sS0FBa0I7RUFDM0MsTUFBTSxTQUFTLHNCQUFPLElBQUksYUFBYTtHQUNyQyxjQUFjLHNCQUFPLEtBQUssT0FBTyxzQkFBTyxZQUFZLEtBQUssc0JBQU8sS0FBSyxDQUFDO0dBQ3RFLE9BQU8sZUFBZSxNQUFNO0dBQzVCLE9BQU8sc0JBQU8sb0JBQW9CO0lBQ2hDLHNCQUFzQjtJQUN0Qix5QkFBeUI7SUFDekIsa0NBQWtDLHNCQUFPLE1BQU0sY0FBYztLQUMzRCxjQUFjO0tBQ2QsU0FBUyxVQUFVLE1BQU07SUFDM0IsQ0FBQztHQUNILENBQUM7R0FDRCxPQUFPLE9BQU8sT0FBTyxLQUFLLHNCQUFPLE9BQU8sc0JBQXNCLENBQUM7RUFDakUsQ0FBQyxDQUFDLENBQUMsS0FBSyxzQkFBTyxTQUFTLDRCQUE0QixFQUFFLE1BQU0sS0FBSyxDQUFDLENBQUM7RUFFbkUsT0FBTyxzQkFBTyxNQUFNLGNBQWM7R0FDaEMsY0FBYztHQUNkLFNBQVMsVUFDUCxPQUFPLEtBQ0wsc0JBQU8sVUFBVSxNQUFNLGlCQUFpQjtJQUN0Qyw2QkFBNkIsTUFBTTtJQUNuQywyQkFBMkIsTUFBTTtHQUNuQyxDQUFDLENBQ0g7RUFDSixDQUFDLENBQUMsQ0FBQyxLQUNELHNCQUFPLEtBQUssV0FBVztHQUFFO0dBQWE7RUFBTSxFQUFFLEdBQzlDLHNCQUFPLFVBQVUsV0FBaUM7R0FBRTtHQUFPO0VBQVksRUFBRSxNQUN6RSw2Q0FDRjtDQUNGO0NBRUEsTUFBTSw0QkFBNEIsc0JBQU8sV0FBVyxXQUNsRCxTQUNBLFlBQ0EsYUFDQSxjQUNBLG9CQUNBO0VBQ0EsSUFBSSxXQUFXO0dBQ2IsT0FBTyxPQUFPLHdCQUNaLG9CQUFvQixTQUFTLFlBQVksYUFBYSxrQkFBa0IsR0FDeEUsU0FDQSxZQUNBLFlBQ0Y7RUFDRjtFQUNBLE9BQU8sT0FBTyxvQkFBb0IsU0FBUyxZQUFZLGFBQWEsa0JBQWtCLENBQUMsQ0FBQyxLQUN0RixzQkFBTyxLQUFLLFdBQVc7R0FDckIsYUFBYSxzQkFBTyxLQUFrQjtHQUN0QztFQUNGLEVBQUUsR0FDRixzQkFBTyxVQUFVLFdBQWlDO0dBQ2hEO0dBQ0EsYUFBYSxzQkFBTyxLQUFLO0VBQzNCLEVBQUUsQ0FDSjtDQUNGLENBQUM7Q0FFRCxNQUFNLGdDQUFnQyxzQkFBTyxXQUFXLGFBQWE7RUFDbkUsU0FBUztHQUNQLE1BQU0sT0FBTyxPQUFPLHNCQUFNLEtBQUssT0FBTztHQUN0QyxRQUFRLEtBQUssTUFBYjtJQUNFLEtBQUs7SUFDTCxLQUFLLGtCQUNILE9BQU87SUFDVCxLQUFLO0tBQ0gsSUFBSSxLQUFLLFlBQVksV0FBVztNQUM5QixPQUFPO0tBQ1Q7S0FDQTtJQUNGLEtBQUs7SUFDTCxLQUFLLHdCQUNIO0lBQ0YsS0FBSztLQUNILElBQUksS0FBSyxXQUFXLGdDQUFnQztNQUNsRCxPQUFPO0tBQ1Q7S0FDQSxJQUFJLEtBQUssV0FBVyx5QkFBeUIsV0FBVztNQUN0RCxPQUFPO01BQ1AsT0FBTztLQUNUO0tBQ0E7R0FDSjtFQUNGO0NBQ0YsQ0FBQztDQUVELE1BQU0sZ0JBQWdCLFVBQ3BCLE1BQU0sU0FBUyxPQUFPLFNBQVM7Q0FFakMsTUFBTSxvQkFBb0Isc0JBQU8sV0FBVyxXQUMxQyxNQUNBLE9BQ0E7RUFDQSxJQUFJLEtBQUssU0FBUyx1QkFBdUI7R0FDdkMsT0FBTztFQUNUO0VBQ0EsSUFBSSxLQUFLLFNBQVMsd0JBQXdCO0dBQ3hDLE9BQU8sdUJBQUksSUFBSSxrQkFBa0Isc0JBQU8sS0FBSyxLQUFLLE9BQU8sQ0FBQztHQUMxRCxPQUFPO0VBQ1Q7RUFDQSxJQUFJLEtBQUssU0FBUyxVQUFVO0dBQzFCLE9BQU87RUFDVDtFQUNBLElBQUksS0FBSyxXQUFXLGdDQUFnQzs7OztHQUlsRCxPQUFPO0VBQ1Q7O0VBRUEsSUFBSSxLQUFLLFdBQVcseUJBQXlCLGFBQWEsS0FBSyxHQUFHO0dBQ2hFLE9BQU87R0FDUCxPQUFPO0VBQ1Q7RUFDQSxPQUFPO0NBQ1QsQ0FBQztDQUVELE1BQU0sbUJBQW1CLFNBQXVEO0VBQzlFLFFBQVEsS0FBSyxNQUFiO0dBQ0UsS0FBSyxrQkFDSCxPQUFPO0dBQ1QsS0FBSyxrQkFDSCxPQUFPLEtBQUssWUFBWSxZQUFZLGlDQUFpQztHQUN2RSxLQUFLO0lBQ0gsSUFBSSxLQUFLLFdBQVcsc0JBQXNCO0tBQ3hDLE9BQU87SUFDVDtJQUNBLE9BQU8sS0FBSyxXQUFXLDhCQUE4QixLQUFLLFdBQVcsb0JBQ2pFLGlDQUNBO0dBQ04sS0FBSztHQUNMLEtBQUs7R0FDTCxLQUFLLHdCQUNILE9BQU87RUFDWDtDQUNGOzs7OztDQU1BLE1BQU0sd0JBQXdCLHNCQUFPLFdBQVcsV0FDOUMsT0FDQTs7O0VBR0EsTUFBTSxhQUFhLHNCQUFNLEtBQUssT0FBTyxDQUFDLENBQUMsS0FDckMsc0JBQU8sS0FBSyxTQUNWLEtBQUssU0FBUyxtQkFBbUIsdUJBQUksSUFBSSxpQkFBaUIsS0FBSyxJQUFJLHNCQUFPLElBQzVFLENBQ0Y7OztFQUdBLE9BQU8sdUJBQU8sS0FBSywyQkFBMkIsQ0FBQyxDQUFDLEtBQzlDLHVCQUFPLEtBQUssQ0FBQyxHQUNiLHVCQUFPLGlCQUFpQix3QkFBd0IsS0FBSyxDQUFDLEdBQ3RELHNCQUFPLFVBQ1Q7RUFDQSxTQUFTO0dBQ1AsTUFBTSxPQUFPLE9BQU87R0FDcEIsTUFBTSxNQUFNLE9BQU8sa0JBQWtCLE1BQU0sS0FBSztHQUNoRCxJQUFJLFFBQVEsV0FBVztJQUNyQixPQUFPLFFBQVE7R0FDakI7R0FDQSxJQUNHLEtBQUssU0FBUyxvQkFBb0IsS0FBSyxZQUFZLGFBQ25ELEtBQUssU0FBUyxZQUFZLHVCQUFrQixtQkFBbUIsS0FBSyxNQUFNLEdBQzNFO0lBQ0EsT0FBTyx3QkFBd0IsS0FBSztHQUN0QztHQUNBLE1BQU0sZUFBZSxnQkFBZ0IsSUFBSTtHQUN6QyxJQUFJLGlCQUFpQixXQUFXO0lBQzlCO0dBQ0Y7R0FDQSxPQUFPLHVCQUFJLElBQUksaUJBQWlCLElBQUk7R0FDcEMsTUFBTSxRQUFRLE9BQU8sc0JBQU8sVUFBVSxNQUFNLFFBQVEsS0FBSztHQUN6RCxJQUFJLFlBQVksT0FBTyxzQkFBTSxzQkFBc0Isc0JBQVMsY0FBYyxZQUFZO0dBQ3RGLFNBQVM7SUFDUCxNQUFNLFlBQVksWUFBWSxPQUFPLHNCQUFNO0lBQzNDLE1BQU0sYUFBYSxPQUFPLHNCQUFPLGFBQWE7S0FDNUMsc0JBQU0sTUFBTSxLQUFLLENBQUMsQ0FBQyxLQUNqQixzQkFBTyxLQUFLLFVBQVU7TUFBRSxNQUFNO01BQTJCO0tBQUssRUFBRSxDQUNsRTtLQUNBLFdBQVcsS0FBSyxzQkFBTyxLQUFLLFlBQVk7TUFBRSxNQUFNO01BQW1CO0tBQU8sRUFBRSxDQUFDO0tBQzdFLHNCQUFPLE1BQU0sc0JBQVMsTUFBTSxZQUFZLEtBQUssWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQzVELHNCQUFPLEdBQUcsRUFBRSxNQUFNLFdBQW9CLENBQUMsQ0FDekM7SUFDRixDQUFDO0lBQ0QsSUFBSSxXQUFXLFNBQVMsWUFBWTtLQUNsQyxPQUFPLHNCQUFNLFVBQVUsS0FBSztLQUM1QixPQUFPLE9BQU8sSUFBSSxnREFBeUI7TUFDekMsUUFBUTtNQUNSLFFBQVEsR0FBRyxPQUFPLE1BQU07S0FDMUIsQ0FBQztJQUNIO0lBQ0EsSUFBSSxXQUFXLFNBQVMsa0JBQWtCO0tBQ3hDLElBQUksc0JBQUssVUFBVSxXQUFXLElBQUksR0FBRztNQUNuQyxPQUFPLHVCQUFJLElBQUksaUJBQWlCLEtBQUs7S0FDdkM7S0FDQSxPQUFPLFdBQVc7S0FDbEI7SUFDRjtJQUNBLE1BQU0saUJBQWlCLE9BQU8sa0JBQWtCLFdBQVcsUUFBUSxLQUFLO0lBQ3hFLElBQUksbUJBQW1CLFdBQVc7S0FDaEMsT0FBTyxzQkFBTSxVQUFVLEtBQUs7S0FDNUIsT0FBTyxtQkFBbUI7SUFDNUI7SUFDQSxNQUFNLGdCQUFnQixnQkFBZ0IsV0FBVyxNQUFNO0lBQ3ZELElBQUksa0JBQWtCLFdBQVc7S0FDL0IsTUFBTSxrQkFDSCxPQUFPLHNCQUFNLHNCQUFzQixzQkFBUyxjQUFjLGFBQWE7S0FDMUUsSUFBSSxpQkFBaUIsVUFBVSxXQUFXO0lBQzVDO0dBQ0Y7RUFDRjtDQUNGLENBQUM7Q0FFRCxNQUFNLGFBQWEsc0JBQU8sV0FBVyxXQUNuQyxTQUNBLFlBQ0EsYUFDQSxjQUNBLGVBQ0E7RUFDQSxNQUFNLGNBQWMsT0FBTyx1QkFBSSxJQUFJLGdCQUFnQjtFQUNuRCxPQUFPLHVCQUFnQixJQUFJLFVBQVUsc0JBQU8sS0FBSyxDQUFDO0VBQ2xELE1BQU0scUJBQXFCLE9BQU8sdUJBQUksS0FBSyxDQUFDO0VBQzVDLE1BQU0sZ0JBQWdCLE9BQU8sc0JBQU8sYUFBYTtHQUMvQyxzQkFDRSwwQkFDRSxTQUNBLFlBQ0EsYUFDQSxjQUNBLGtCQUNGLENBQ0YsQ0FBQyxDQUFDLEtBQ0Esc0JBQU8sS0FBSyxVQUE4QjtJQUN4QyxNQUFNO0lBQ047R0FDRixFQUFFLENBQ0o7R0FDQSw4QkFBOEIsQ0FBQyxDQUFDLEtBQzlCLHNCQUFPLEtBQUssZ0JBQW9DO0lBQzlDLE1BQU07SUFDTjtHQUNGLEVBQUUsQ0FDSjtHQUlBLHNCQUFPLElBQUksYUFBYTtJQUN0QixNQUFNLGFBQWEsNENBQWlCLE9BQU8sdUJBQUksSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ2xFLE1BQU0sWUFBWSxPQUFPLHNCQUFNO0lBQy9CLE1BQU0sUUFBUSxzQkFBUyxjQUFjLHNCQUFTLE1BQU0sc0JBQXNCLFVBQVUsQ0FBQztJQUNyRixPQUFPLE1BQU07S0FDWCxNQUFNLGVBQWUsT0FBTyxPQUFPLHVCQUFJLElBQUksa0JBQWtCLENBQUM7S0FDOUQsTUFBTSxXQUNKLFlBQVksUUFBUSxlQUFlLHNCQUFTLGNBQWMsc0JBQXNCO0tBQ2xGLE1BQU0sWUFBWSxZQUFZLE9BQU8sc0JBQU07S0FDM0MsSUFBSSxhQUFhLElBQUk7TUFDbkIsT0FBTyxFQUFFLE1BQU0sV0FBVztLQUM1QjtLQUNBLE9BQU8sc0JBQU8sTUFBTSxzQkFBUyxNQUFNLFNBQVMsQ0FBQztJQUMvQztHQUNGLENBQUM7RUFDSCxDQUFDO0VBRUQsSUFBSSxjQUFjLFNBQVMsZUFBZTtHQUN4QyxPQUFPO0lBQ0wsTUFBTTtJQUNOLGFBQWE7SUFDYixRQUFRO0lBQ1IsWUFBWSxjQUFjO0dBQzVCO0VBQ0Y7RUFDQSxJQUFJLGNBQWMsU0FBUyxZQUFZO0dBQ3JDLE9BQU87SUFDTCxNQUFNO0lBQ04sYUFBYTtJQUNiLFFBQVE7SUFDUixTQUFTO0tBQ1AsT0FBTyxJQUFJLGdEQUF5QjtNQUNsQyxRQUFRO01BQ1IsUUFBUTtLQUNWLENBQUM7S0FDRCxhQUFhLHNCQUFPLEtBQUs7SUFDM0I7R0FDRjtFQUNGO0VBQ0EsSUFBSSxzQkFBSyxVQUFVLGNBQWMsSUFBSSxHQUFHO0dBQ3RDLE1BQU0scUJBQ0osQ0FBQyxzQkFBTSxrQkFBa0IsY0FBYyxLQUFLLEtBQUssS0FDakQsQ0FBQyxjQUFjLEtBQUssTUFBTSxRQUFRLEtBQUssc0JBQU0sWUFBWTtHQUMzRCxNQUFNLFVBQVUsZ0JBQWdCLFFBQVEsY0FBYyxNQUFNLE9BQU8sS0FBSztHQUN4RSxJQUFJLG9CQUFvQjtJQUN0QixNQUFNLFNBQVMsY0FBYyxLQUFLLE1BQU0sUUFBUSxLQUFLLHNCQUFNLFdBQVcsQ0FBQyxFQUFFO0lBQ3pFLE9BQU8sc0JBQU8sU0FBUyxzREFBc0QsQ0FBQyxDQUFDLEtBQzdFLHNCQUFPLGFBQWE7S0FDbEIsa0JBQWtCLE9BQU87S0FDekIscUJBQXFCLE9BQU87S0FDNUIsc0JBQXNCLGNBQWMsS0FBSyxNQUFNLFFBQVE7S0FDdkQsR0FBRyxrREFBdUIsTUFBTTtJQUNsQyxDQUFDLENBQ0g7R0FDRjtHQUNBLE9BQU87RUFDVDtFQUVBLE1BQU0sU0FBUyxjQUFjLEtBQUs7RUFDbEMsSUFBSSxzQkFBTyxPQUFPLFdBQVcsR0FBRztHQUM5QixNQUFNLFNBQVMsNkNBQWtCLE9BQU8sTUFBTSxTQUFTLE1BQU07R0FDN0QsSUFBSSxXQUFXLFlBQVksT0FBTztJQUNoQyxNQUFNLFNBQ0gsT0FBTyxzQkFBTSxzQkFBc0IsT0FBTyx3QkFBd0IsSUFBSTtJQUN6RSxPQUFPLHVCQUFJLE9BQU8saUJBQWlCLFlBQ2pDLElBQUksSUFBSSxPQUFPLENBQUMsQ0FBQyxJQUFJLFlBQVksT0FBTyxLQUFLLENBQy9DO0dBQ0Y7RUFDRjtFQUNBLE1BQU0sZ0JBQWdCLE9BQU8sdUJBQUksSUFBSSxNQUFNO0VBQzNDLElBQUksQ0FBQyxjQUFjLFdBQVksY0FBYyxZQUFZLGFBQWEsQ0FBQyxlQUFnQjtHQUNyRixPQUFPO0lBQ0wsTUFBTTtJQUNOLGFBQWE7SUFDYixRQUFRO0lBQ1IsWUFBWTtHQUNkO0VBQ0Y7RUFFQSxNQUFNLGNBQWMsT0FBTyxzQkFBTTtFQUNqQyxPQUFPLHVCQUFnQixJQUFJLFVBQVUsc0JBQU8sS0FBSyxPQUFPLE1BQU0sUUFBUSxDQUFDO0VBQ3ZFLE9BQU8sdUJBQWdCLElBQUksU0FBUyxzQkFBTyxLQUFLLE9BQU8sTUFBTSxPQUFPLENBQUM7RUFDckUsSUFBSSxTQUFTLGdCQUFnQixXQUFXO0dBQ3RDLE9BQU8sZ0JBQWdCLFFBQVEsYUFBYSxPQUFPLEtBQUssQ0FBQyxDQUFDLEtBQUssc0JBQU8sVUFBVTtFQUNsRjtFQUNBLE9BQU8sU0FBUztHQUNkLFNBQVM7R0FDVCxTQUFTLGNBQWM7R0FDdkIsT0FBTztHQUNQLE9BQU87R0FDUDtHQUNBO0dBQ0EsYUFBYTtHQUNiLFNBQVM7RUFDWCxDQUFDO0VBRUQsTUFBTSxnQkFBZ0IsT0FBTyxzQkFBTyxVQUNsQyxPQUFPLE1BQU0sUUFBUSxPQUFPLEtBQzFCLHNCQUFPLFVBQVUsV0FBaUM7R0FDaEQ7R0FDQSxhQUFhLE9BQU87RUFDdEIsRUFBRSxDQUNKLEdBQ0Esc0JBQXNCLE9BQU8sS0FBSyxDQUFDLENBQUMsS0FDbEMsc0JBQU8sVUFBVSxXQUFpQztHQUNoRDtHQUNBLGFBQWEsT0FBTztFQUN0QixFQUFFLENBQ0osQ0FDRixDQUFDLENBQUMsS0FBSyxxQkFBcUI7RUFDNUIsTUFBTSxrQkFBa0IsT0FBTyxzQkFBTSxxQkFBcUI7RUFDMUQsSUFBSSxzQkFBSyxVQUFVLGFBQWEsR0FBRztHQUNqQyxPQUFPO0lBQ0wsTUFBTTtJQUNOLGFBQWE7SUFDYixRQUFRLGtCQUFrQjtJQUMxQixZQUFZLGNBQWM7R0FDNUI7RUFDRjtFQUNBLE1BQU0sVUFBVSxnQkFDZCxRQUNBLGVBQ0EsTUFDQSxrQkFBa0Isc0JBQ3BCO0VBQ0EsSUFBSSxRQUFRLFNBQVMsV0FBVztHQUM5QixPQUFPLHNCQUFPLEtBQUssS0FDakIsc0JBQU8sU0FBUyx3Q0FBd0M7SUFDdEQsTUFBTTtJQUNOLFlBQVk7S0FDVixrQkFBa0IsT0FBTztLQUN6QixxQkFBcUIsT0FBTztLQUM1QiwyQkFBMkIsT0FBTztLQUNsQywyQkFBMkI7S0FDM0IsNkJBQTZCLFFBQVEsUUFBUSxNQUFNO0tBQ25ELDZCQUE2QixRQUFRLFFBQVEsTUFBTTtJQUNyRDtHQUNGLENBQUMsQ0FDSDtFQUNGO0VBQ0EsT0FBTztDQUNULEdBQUcsc0JBQU8sU0FBUyxVQUFVLENBQUM7Q0FFOUIsTUFBTSxxQkFBcUIsc0JBQU8sV0FBVyxXQUFXLFNBQWlCOztFQUV2RSxPQUFPLE9BQU8sc0JBQU8sVUFDbkIsc0JBQU8sTUFBTSxPQUFPLENBQUMsQ0FBQyxLQUFLLHNCQUFPLEdBQUcsS0FBSyxDQUFDLEdBQzNDLHNCQUFPLElBQUksYUFBYTtHQUN0QixTQUFTO0lBQ1AsTUFBTSxPQUFPLE9BQU8sc0JBQU0sS0FBSyxPQUFPO0lBQ3RDLFFBQVEsS0FBSyxNQUFiO0tBQ0UsS0FBSyxVQUNILE9BQU8sdUJBQWtCLG1CQUFtQixLQUFLLE1BQU07S0FDekQsS0FBSztLQUNMLEtBQUs7S0FDTCxLQUFLO0tBQ0wsS0FBSyxrQkFDSCxPQUFPO0tBQ1QsS0FBSyx3QkFDSDtJQUNKO0dBQ0Y7RUFDRixDQUFDLENBQ0g7Q0FDRixDQUFDO0NBRUQsTUFBTSxnQkFBZ0Isc0JBQU0sS0FBSyxPQUFPLENBQUMsQ0FBQyxLQUN4QyxzQkFBTyxPQUFPLEVBQUUsUUFBUSxTQUFTLEtBQUssU0FBUyx1QkFBdUIsQ0FBQyxHQUN2RSxzQkFBTyxLQUNKLFNBQVMsS0FBSyxTQUFTLFlBQVksdUJBQWtCLG1CQUFtQixLQUFLLE1BQU0sQ0FDdEYsQ0FDRjtDQUVBLE1BQU0sTUFBTSxzQkFBTyxXQUFXLGFBQWE7RUFDekMsSUFBSSxlQUFlO0VBQ25CLElBQUksYUFBYTtFQUNqQixJQUFJLGdCQUErQztFQUNuRCxJQUFJLGVBQWUsc0JBQU8sS0FBd0I7RUFDbEQsTUFBTSx5QkFBeUI7R0FDN0IsZUFBZTtHQUNmLGVBQWUsc0JBQU8sS0FBSztFQUM3QjtFQUNBLElBQUksWUFBWTtFQUVoQixTQUFTO0dBQ1AsSUFBSSxPQUFPLHVCQUFJLFVBQVUsaUJBQWlCLEtBQUssR0FBRztJQUNoRCxlQUFlO0lBQ2YsZ0JBQWdCO0lBQ2hCLGVBQWUsc0JBQU8sS0FBSztHQUM3QjtHQUNBLE1BQU0sZ0JBQWdCLE9BQU8sdUJBQUksSUFBSSxNQUFNO0dBQzNDLElBQUksQ0FBQyxjQUFjLFNBQVM7SUFDMUIsaUJBQWlCO0lBQ2pCLGdCQUFnQjtJQUNoQixPQUFPO0lBQ1AsT0FBTyxTQUFTLGVBQWUsZUFBZSxVQUFVLENBQUM7SUFDekQsT0FBTztJQUNQO0dBQ0Y7R0FDQSxJQUFJLGNBQWMsWUFBWSxhQUFhLENBQUMsV0FBVztJQUNyRCxPQUFPO0lBQ1AsT0FBTyxTQUFTLGFBQWEsZUFBZSxZQUFZLGVBQWUsR0FBRyxhQUFhLENBQUM7SUFDeEYsTUFBTSx1QkFBdUIsT0FBTztJQUNwQyxJQUFJLHNCQUFzQjtLQUN4QixpQkFBaUI7SUFDbkI7SUFDQTtHQUNGO0dBRUEsTUFBTSxVQUFVLGVBQWU7R0FDL0IsTUFBTSxpQkFBaUIsYUFBYTtHQUNwQyxNQUFNLFVBQTBCLE9BQU8sc0JBQU8sT0FDNUMsV0FBVyxTQUFTLGdCQUFnQixlQUFlLGNBQWMsU0FBUyxDQUM1RTtHQUNBLFlBQVk7R0FDWixNQUFNLGNBQWMsT0FBTyx1QkFBSSxVQUFVLGlCQUFpQixLQUFLO0dBQy9ELElBQUksUUFBUSxhQUFhO0lBQ3ZCLGFBQWE7Ozs7O0lBS2IsZ0JBQWdCO0lBQ2hCLElBQUksUUFBUSxRQUFRO0tBQ2xCLGlCQUFpQjtJQUNuQjtHQUNGO0dBQ0EsSUFBSSxRQUFRLFNBQVMsZUFBZTtJQUNsQyxJQUFJLFFBQVEsWUFBWTtLQUN0QixpQkFBaUI7S0FDakIsWUFBWTtJQUNkO0lBQ0E7R0FDRjtHQUVBLE1BQU0sY0FBMEMsUUFBUSxRQUFRO0dBQ2hFLE1BQU0sUUFBZ0MsUUFBUSxRQUFRO0dBQ3RELElBQUksQ0FBQyxRQUFRLGFBQWE7SUFDeEIsZ0JBQWdCO0dBQ2xCO0dBQ0EsSUFBSSxNQUFNLFNBQVMsMEJBQTBCO0lBQzNDLE1BQU0sZ0JBQWdCLE9BQU8sdUJBQUksSUFBSSxNQUFNO0lBQzNDLE9BQU8sU0FBUztLQUNkLFNBQVMsY0FBYztLQUN2QixTQUFTLGNBQWM7S0FDdkIsT0FBTztLQUNQLE9BQU87S0FDUDtLQUNBO0tBQ0EsYUFBYTtLQUNiLFNBQVM7SUFDWCxDQUFDO0lBQ0QsTUFBTSx1QkFBdUIsT0FBTztJQUNwQyxJQUFJLHNCQUFzQjtLQUN4QixpQkFBaUI7SUFDbkI7SUFDQTtHQUNGO0dBRUEsSUFBSSxhQUFhO0lBQ2YsaUJBQWlCO0lBQ2pCLE9BQU8sU0FBUyxnQkFBZ0IsT0FBTyx1QkFBSSxJQUFJLE1BQU0sR0FBRyxZQUFZLEdBQUcsYUFBYSxDQUFDO0lBQ3JGO0dBQ0Y7R0FFQSxnQkFBZ0I7R0FDaEIsTUFBTSxVQUFVLGFBQWEsZUFBZSxHQUFHLE9BQU8sdUJBQU8sSUFBSTtHQUNqRSxlQUFlLHNCQUFPLElBQUksY0FBYyxxQkFBcUI7SUFDM0Q7SUFDQTtJQUNBO0lBQ0EsUUFBUSxNQUFNO0dBQ2hCLEVBQUU7R0FDRixNQUFNLGVBQWUsT0FBTyx1QkFBSSxJQUFJLE1BQU07R0FDMUMsT0FBTyxTQUFTO0lBQ2QsU0FBUyxhQUFhO0lBQ3RCLFNBQVMsYUFBYTtJQUN0QixPQUFPO0lBQ1AsT0FBTztJQUNQO0lBQ0E7SUFDQSxhQUFhO0lBQ2IsVUFBVSxPQUFPLHNCQUFNLHFCQUFxQjtHQUM5QyxDQUFDO0dBQ0QsTUFBTSx1QkFBdUIsT0FBTyxtQkFBbUIsT0FBTztHQUM5RCxJQUFJLHNCQUFzQjtJQUN4QixpQkFBaUI7R0FDbkI7RUFDRjtDQUNGLENBQUM7Q0FFRCxPQUFPLGFBQWEsUUFBUSxLQUMxQix1QkFBTyxZQUFZLFlBQ2pCLHVCQUFJLE9BQU8sU0FBUyxZQUNsQixRQUFRLFlBQVksVUFBVSxDQUFDLE9BQU8sT0FBTyxJQUFLLENBQUMsTUFBTTtFQUFFLEdBQUc7RUFBUztDQUFRLENBQUMsQ0FDbEYsQ0FBQyxDQUFDLEtBQ0Esc0JBQU8sU0FBUyxZQUNkLFVBQVUsT0FBTztFQUFFLE1BQU07RUFBa0I7Q0FBUSxDQUFDLElBQUksc0JBQU8sSUFDakUsQ0FDRixDQUNGLEdBQ0Esc0JBQU8sVUFDVDtDQUNBLE9BQU8sUUFBUSxRQUFRLEtBQ3JCLHVCQUFPLFlBQVksV0FBVyxPQUFPO0VBQUUsTUFBTTtFQUFVO0NBQU8sQ0FBQyxDQUFDLEdBQ2hFLHNCQUFPLFVBQ1Q7Q0FDQSxPQUFPLHNCQUFNLEtBQUssaUJBQWlCLENBQUMsQ0FBQyxLQUNuQyxzQkFBTyxRQUFRLGlCQUFpQixHQUNoQyxzQkFBTyxTQUNQLHNCQUFPLFVBQ1Q7Q0FDQSxPQUFPLElBQUksQ0FBQyxDQUFDLEtBQUssc0JBQU8sVUFBVTtDQUVuQyxNQUFNLFVBQVUsdUJBQUksT0FBTyxTQUFTLGFBQWE7RUFDL0MsR0FBRztFQUNILFNBQVM7Q0FDWCxFQUFFLENBQUMsQ0FBQyxLQUNGLHNCQUFPLFFBQVEsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUMsQ0FBQyxHQUNuRCxzQkFBTyxTQUFTLCtCQUErQixDQUNqRDtDQUVBLE1BQU0sYUFBYSx1QkFBSSxPQUFPLFNBQVMsYUFBYTtFQUNsRCxHQUFHO0VBQ0gsU0FBUztDQUNYLEVBQUUsQ0FBQyxDQUFDLEtBQ0Ysc0JBQU8sUUFBUSxPQUFPLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQyxDQUFDLEdBQ3RELHNCQUFPLFNBQVMsa0NBQWtDLENBQ3BEO0NBRUEsTUFBTSxXQUFXLHVCQUFJLElBQUksaUJBQWlCLElBQUksQ0FBQyxDQUFDLEtBQzlDLHNCQUFPLFFBQVEsT0FBTyxFQUFFLE1BQU0saUJBQWlCLENBQUMsQ0FBQyxHQUNqRCxzQkFBTyxTQUFTLGdDQUFnQyxDQUNsRDtDQUVBLE9BQU8sc0JBQU8sbUJBQW1CLHNCQUFNLFNBQVMsT0FBTyxDQUFDLENBQUMsS0FBSyxzQkFBTyxRQUFRLFVBQVUsQ0FBQyxDQUFDO0NBRXpGLE9BQU8sc0JBQXNCLEdBQUc7RUFDOUI7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7Q0FDRixDQUFDO0FBQ0gsQ0FBQyIsIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6W10sInNvdXJjZXMiOlsic3VwZXJ2aXNvci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB3aXRoUmVsYXlDbGllbnRUcmFjaW5nIH0gZnJvbSBcIkB0M3Rvb2xzL3NoYXJlZC9yZWxheVRyYWNpbmdcIjtcbmltcG9ydCAqIGFzIENhdXNlIGZyb20gXCJlZmZlY3QvQ2F1c2VcIjtcbmltcG9ydCAqIGFzIENsb2NrIGZyb20gXCJlZmZlY3QvQ2xvY2tcIjtcbmltcG9ydCAqIGFzIENvbnRleHQgZnJvbSBcImVmZmVjdC9Db250ZXh0XCI7XG5pbXBvcnQgKiBhcyBEdXJhdGlvbiBmcm9tIFwiZWZmZWN0L0R1cmF0aW9uXCI7XG5pbXBvcnQgKiBhcyBFZmZlY3QgZnJvbSBcImVmZmVjdC9FZmZlY3RcIjtcbmltcG9ydCAqIGFzIEV4aXQgZnJvbSBcImVmZmVjdC9FeGl0XCI7XG5pbXBvcnQgKiBhcyBGaWJlciBmcm9tIFwiZWZmZWN0L0ZpYmVyXCI7XG5pbXBvcnQgKiBhcyBPcHRpb24gZnJvbSBcImVmZmVjdC9PcHRpb25cIjtcbmltcG9ydCAqIGFzIFF1ZXVlIGZyb20gXCJlZmZlY3QvUXVldWVcIjtcbmltcG9ydCAqIGFzIFJhbmRvbSBmcm9tIFwiZWZmZWN0L1JhbmRvbVwiO1xuaW1wb3J0ICogYXMgUmVmIGZyb20gXCJlZmZlY3QvUmVmXCI7XG5pbXBvcnQgKiBhcyBTY29wZSBmcm9tIFwiZWZmZWN0L1Njb3BlXCI7XG5pbXBvcnQgKiBhcyBTdHJlYW0gZnJvbSBcImVmZmVjdC9TdHJlYW1cIjtcbmltcG9ydCAqIGFzIFN1YnNjcmlwdGlvblJlZiBmcm9tIFwiZWZmZWN0L1N1YnNjcmlwdGlvblJlZlwiO1xuaW1wb3J0ICogYXMgVHJhY2VyIGZyb20gXCJlZmZlY3QvVHJhY2VyXCI7XG5cbmltcG9ydCB0eXBlIHsgQ29ubmVjdGlvbkNhdGFsb2dFbnRyeSwgQ29ubmVjdGlvblJvdXRlIH0gZnJvbSBcIi4vY2F0YWxvZy50c1wiO1xuaW1wb3J0ICogYXMgQ29ubmVjdGl2aXR5IGZyb20gXCIuL2Nvbm5lY3Rpdml0eS50c1wiO1xuaW1wb3J0ICogYXMgQ29ubmVjdGlvbkRyaXZlciBmcm9tIFwiLi9kcml2ZXIudHNcIjtcbmltcG9ydCB7XG4gIHR5cGUgQ29ubmVjdGlvbkF0dGVtcHRFcnJvcixcbiAgdHlwZSBDb25uZWN0aW9uVGFyZ2V0LFxuICBDb25uZWN0aW9uVHJhbnNpZW50RXJyb3IsXG4gIHR5cGUgTmV0d29ya1N0YXR1cyxcbiAgdHlwZSBQcmVwYXJlZENvbm5lY3Rpb24sXG4gIHR5cGUgU3VwZXJ2aXNvckNvbm5lY3Rpb25TdGF0ZSxcbn0gZnJvbSBcIi4vbW9kZWwudHNcIjtcbmltcG9ydCAqIGFzIFJwY1Nlc3Npb24gZnJvbSBcIi4uL3JwYy9zZXNzaW9uLnRzXCI7XG5pbXBvcnQgeyBzYWZlRXJyb3JMb2dBdHRyaWJ1dGVzIH0gZnJvbSBcIi4uL2Vycm9ycy9zYWZlTG9nLnRzXCI7XG5pbXBvcnQgeyBORVRXT1JLX0JMT0NLSU5HX0hJTlQgfSBmcm9tIFwiLi4vZXJyb3JzL25ldHdvcmsudHNcIjtcbmltcG9ydCAqIGFzIENvbm5lY3Rpb25XYWtldXBzIGZyb20gXCIuL3dha2V1cHMudHNcIjtcbmltcG9ydCB7XG4gIGNvbm5lY3Rpb25Sb3V0ZUlkLFxuICBjb25uZWN0aW9uUm91dGVLaW5kLFxuICBjb25uZWN0aW9uUm91dGVzLFxuICBlbnRyeVdpdGhSb3V0ZXMsXG4gIHR5cGUgUmVwb3J0ZWRFbmRwb2ludCxcbn0gZnJvbSBcIi4vcm91dGVzLnRzXCI7XG5cbmNvbnN0IFJFVFJZX0JBU0VfREVMQVlfTVMgPSAxXzAwMDtcbmNvbnN0IFJFVFJZX01BWF9ERUxBWV9NUyA9IDMwMF8wMDA7XG4vLyBBIGNvbGQgc2VydmVyIHdpdGggYSBsYXJnZSBkYXRhYmFzZSBjYW4gdGFrZSBsb25nZXIgdGhhbiAxNSBzZWNvbmRzIHRvXG4vLyBhbnN3ZXIsIGFuZCB0aGF0IGlzIG5vdCBhIHJlYXNvbiB0byBkcm9wIGEgd29ya2luZyBjb25uZWN0aW9uLlxuY29uc3QgQ09OTkVDVElPTl9FU1RBQkxJU0hNRU5UX1RJTUVPVVQgPSBcIjE1IHNlY29uZHNcIjtcbmNvbnN0IGVzdGFibGlzaG1lbnRUaW1lb3V0ID0gRHVyYXRpb24uZnJvbUlucHV0VW5zYWZlKENPTk5FQ1RJT05fRVNUQUJMSVNITUVOVF9USU1FT1VUKTtcbmNvbnN0IHN5bmNocm9uaXphdGlvblRpbWVvdXQgPSBEdXJhdGlvbi5mcm9tSW5wdXRVbnNhZmUoXCI3NSBzZWNvbmRzXCIpO1xuY29uc3QgQ09OTkVDVElPTl9QUk9CRV9USU1FT1VUID0gXCIxNSBzZWNvbmRzXCI7XG5jb25zdCBRVUlDS19DT05ORUNUSU9OX1BST0JFX1RJTUVPVVQgPSBcIjMgc2Vjb25kc1wiO1xuY29uc3QgQkFDS09GRl9SRVNFVF9BRlRFUl9NUyA9IDMwXzAwMDtcbmNvbnN0IEJFVFRFUl9ST1VURV9DSEVDS19JTlRFUlZBTCA9IFwiNjAgc2Vjb25kc1wiO1xuLy8gQSBiZXR0ZXIgcm91dGUgdGhhdCBhbnN3ZXJlZCB0aGUgY2hlY2sgYnV0IHRoZW4gZmFpbGVkIHRvIGNvbm5lY3QgaXMgbm90XG4vLyB0cmllZCBhZ2FpbiBmb3IgdGhpcyBsb25nLCBzbyBhIGZsYWt5IExBTiBjYW5ub3QgYm91bmNlIHRoZSBjb25uZWN0aW9uLlxuY29uc3QgQkVUVEVSX1JPVVRFX0NPT0xET1dOX01TID0gMzAwXzAwMDtcblxuaW50ZXJmYWNlIFN1cGVydmlzb3JJbnRlbnQge1xuICByZWFkb25seSBkZXNpcmVkOiBib29sZWFuO1xuICByZWFkb25seSBuZXR3b3JrOiBOZXR3b3JrU3RhdHVzO1xufVxuXG50eXBlIFN1cGVydmlzb3JTaWduYWwgPVxuICB8IHsgcmVhZG9ubHkgX3RhZzogXCJDb25uZWN0UmVxdWVzdGVkXCIgfVxuICB8IHsgcmVhZG9ubHkgX3RhZzogXCJEaXNjb25uZWN0UmVxdWVzdGVkXCIgfVxuICB8IHsgcmVhZG9ubHkgX3RhZzogXCJSZXRyeVJlcXVlc3RlZFwiIH1cbiAgfCB7IHJlYWRvbmx5IF90YWc6IFwiTmV0d29ya0NoYW5nZWRcIjsgcmVhZG9ubHkgbmV0d29yazogTmV0d29ya1N0YXR1cyB9XG4gIHwgeyByZWFkb25seSBfdGFnOiBcIldha2V1cFwiOyByZWFkb25seSByZWFzb246IENvbm5lY3Rpb25XYWtldXBzLkNvbm5lY3Rpb25XYWtldXAgfVxuICB8IHsgcmVhZG9ubHkgX3RhZzogXCJCZXR0ZXJSb3V0ZUF2YWlsYWJsZVwiOyByZWFkb25seSByb3V0ZUlkOiBzdHJpbmcgfTtcblxuaW50ZXJmYWNlIFBlbmRpbmdSZXRyeVRyYWNlIHtcbiAgcmVhZG9ubHkgcHJldmlvdXNBdHRlbXB0OiBUcmFjZXIuU3BhbjtcbiAgcmVhZG9ubHkgZmFpbHVyZUNvdW50OiBudW1iZXI7XG4gIHJlYWRvbmx5IGRlbGF5TXM6IG51bWJlcjtcbiAgcmVhZG9ubHkgcmVhc29uOiBDb25uZWN0aW9uQXR0ZW1wdEVycm9yW1wicmVhc29uXCJdO1xufVxuXG5pbnRlcmZhY2UgVHJhY2VkQXR0ZW1wdEZhaWx1cmUge1xuICByZWFkb25seSBlcnJvcjogQ29ubmVjdGlvbkF0dGVtcHRFcnJvcjtcbiAgcmVhZG9ubHkgYXR0ZW1wdFNwYW46IE9wdGlvbi5PcHRpb248VHJhY2VyLlNwYW4+O1xufVxuXG50eXBlIEF0dGVtcHRPdXRjb21lID1cbiAgfCB7XG4gICAgICByZWFkb25seSBfdGFnOiBcIkludGVycnVwdGVkXCI7XG4gICAgICByZWFkb25seSBlc3RhYmxpc2hlZDogYm9vbGVhbjtcbiAgICAgIHJlYWRvbmx5IHN0YWJsZTogYm9vbGVhbjtcbiAgICAgIHJlYWRvbmx5IHJlc2V0UmV0cnk6IGJvb2xlYW47XG4gICAgfVxuICB8IHtcbiAgICAgIHJlYWRvbmx5IF90YWc6IFwiRmFpbHVyZVwiO1xuICAgICAgcmVhZG9ubHkgZXN0YWJsaXNoZWQ6IGJvb2xlYW47XG4gICAgICByZWFkb25seSBzdGFibGU6IGJvb2xlYW47XG4gICAgICByZWFkb25seSBmYWlsdXJlOiBUcmFjZWRBdHRlbXB0RmFpbHVyZTtcbiAgICB9O1xuXG50eXBlIEVzdGFibGlzaG1lbnRFdmVudCA9XG4gIHwge1xuICAgICAgcmVhZG9ubHkgX3RhZzogXCJDb21wbGV0ZWRcIjtcbiAgICAgIHJlYWRvbmx5IGV4aXQ6IEV4aXQuRXhpdDxcbiAgICAgICAge1xuICAgICAgICAgIHJlYWRvbmx5IGF0dGVtcHRTcGFuOiBPcHRpb24uT3B0aW9uPFRyYWNlci5TcGFuPjtcbiAgICAgICAgICByZWFkb25seSBsZWFzZTogQ29ubmVjdGlvbkRyaXZlci5FbnZpcm9ubWVudENvbm5lY3Rpb25MZWFzZTtcbiAgICAgICAgfSxcbiAgICAgICAgVHJhY2VkQXR0ZW1wdEZhaWx1cmVcbiAgICAgID47XG4gICAgfVxuICB8IHsgcmVhZG9ubHkgX3RhZzogXCJJbnRlcnJ1cHRlZFwiOyByZWFkb25seSByZXNldFJldHJ5OiBib29sZWFuIH1cbiAgfCB7IHJlYWRvbmx5IF90YWc6IFwiVGltZWRPdXRcIiB9O1xuXG5mdW5jdGlvbiBleGl0VW5sZXNzSW50ZXJydXB0ZWQ8QSwgRSwgUj4oXG4gIGVmZmVjdDogRWZmZWN0LkVmZmVjdDxBLCBFLCBSPixcbik6IEVmZmVjdC5FZmZlY3Q8RXhpdC5FeGl0PEEsIEU+LCBuZXZlciwgUj4ge1xuICByZXR1cm4gRWZmZWN0Lm1hdGNoQ2F1c2VFZmZlY3QoZWZmZWN0LCB7XG4gICAgb25GYWlsdXJlOiAoY2F1c2UpID0+XG4gICAgICBDYXVzZS5oYXNJbnRlcnJ1cHRzKGNhdXNlKSA/IEVmZmVjdC5pbnRlcnJ1cHQgOiBFZmZlY3Quc3VjY2VlZChFeGl0LmZhaWxDYXVzZShjYXVzZSkpLFxuICAgIG9uU3VjY2VzczogKHZhbHVlKSA9PiBFZmZlY3Quc3VjY2VlZChFeGl0LnN1Y2NlZWQodmFsdWUpKSxcbiAgfSk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRW52aXJvbm1lbnRTdXBlcnZpc29yT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGluaXRpYWxseURlc2lyZWQ/OiBib29sZWFuO1xuICByZWFkb25seSBsZWFyblJvdXRlcz86IChpbnB1dDoge1xuICAgIHJlYWRvbmx5IGFjdGl2ZVJvdXRlOiBDb25uZWN0aW9uUm91dGU7XG4gICAgcmVhZG9ubHkgcmVwb3J0ZWQ6IFJlYWRvbmx5QXJyYXk8UmVwb3J0ZWRFbmRwb2ludD47XG4gIH0pID0+IEVmZmVjdC5FZmZlY3Q8T3B0aW9uLk9wdGlvbjxDb25uZWN0aW9uQ2F0YWxvZ0VudHJ5Pj47XG59XG5cbmZ1bmN0aW9uIHJldHJ5RGVsYXlNcyhmYWlsdXJlQ291bnQ6IG51bWJlciwgcmFuZG9tOiBudW1iZXIpOiBudW1iZXIge1xuICBjb25zdCBjZWlsaW5nID0gTWF0aC5taW4oUkVUUllfTUFYX0RFTEFZX01TLCBSRVRSWV9CQVNFX0RFTEFZX01TICogMiAqKiAoZmFpbHVyZUNvdW50ICsgMSkpO1xuICByZXR1cm4gTWF0aC5yb3VuZChjZWlsaW5nIC8gMiArIChjZWlsaW5nIC8gMikgKiByYW5kb20pO1xufVxuXG5mdW5jdGlvbiBhbm5vdGF0ZVRhcmdldCh0YXJnZXQ6IENvbm5lY3Rpb25UYXJnZXQpIHtcbiAgcmV0dXJuIEVmZmVjdC5hbm5vdGF0ZUN1cnJlbnRTcGFuKHtcbiAgICBcImVudmlyb25tZW50LmlkXCI6IHRhcmdldC5lbnZpcm9ubWVudElkLFxuICAgIFwiZW52aXJvbm1lbnQubGFiZWxcIjogdGFyZ2V0LmxhYmVsLFxuICAgIFwiZW52aXJvbm1lbnQudGFyZ2V0LmtpbmRcIjogdGFyZ2V0Ll90YWcsXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBhdmFpbGFibGVTdGF0ZShpbnRlbnQ6IFN1cGVydmlzb3JJbnRlbnQsIGdlbmVyYXRpb246IG51bWJlcik6IFN1cGVydmlzb3JDb25uZWN0aW9uU3RhdGUge1xuICByZXR1cm4ge1xuICAgIGRlc2lyZWQ6IGZhbHNlLFxuICAgIG5ldHdvcms6IGludGVudC5uZXR3b3JrLFxuICAgIHBoYXNlOiBcImF2YWlsYWJsZVwiLFxuICAgIHN0YWdlOiBudWxsLFxuICAgIGF0dGVtcHQ6IDAsXG4gICAgZ2VuZXJhdGlvbixcbiAgICBsYXN0RmFpbHVyZTogbnVsbCxcbiAgICByZXRyeUF0OiBudWxsLFxuICB9O1xufVxuXG5mdW5jdGlvbiBvZmZsaW5lU3RhdGUoXG4gIGludGVudDogU3VwZXJ2aXNvckludGVudCxcbiAgZ2VuZXJhdGlvbjogbnVtYmVyLFxuICBhdHRlbXB0OiBudW1iZXIsXG4gIGxhc3RGYWlsdXJlOiBDb25uZWN0aW9uQXR0ZW1wdEVycm9yIHwgbnVsbCxcbik6IFN1cGVydmlzb3JDb25uZWN0aW9uU3RhdGUge1xuICByZXR1cm4ge1xuICAgIGRlc2lyZWQ6IHRydWUsXG4gICAgbmV0d29yazogaW50ZW50Lm5ldHdvcmssXG4gICAgcGhhc2U6IFwib2ZmbGluZVwiLFxuICAgIHN0YWdlOiBudWxsLFxuICAgIGF0dGVtcHQsXG4gICAgZ2VuZXJhdGlvbixcbiAgICBsYXN0RmFpbHVyZSxcbiAgICByZXRyeUF0OiBudWxsLFxuICB9O1xufVxuXG5mdW5jdGlvbiBjb25uZWN0aW5nU3RhdGUoXG4gIGludGVudDogU3VwZXJ2aXNvckludGVudCxcbiAgZ2VuZXJhdGlvbjogbnVtYmVyLFxuICBhdHRlbXB0OiBudW1iZXIsXG4gIGxhc3RGYWlsdXJlOiBDb25uZWN0aW9uQXR0ZW1wdEVycm9yIHwgbnVsbCxcbiAgc3RhZ2U6IFN1cGVydmlzb3JDb25uZWN0aW9uU3RhdGVbXCJzdGFnZVwiXSA9IFwicHJlcGFyaW5nXCIsXG4pOiBTdXBlcnZpc29yQ29ubmVjdGlvblN0YXRlIHtcbiAgcmV0dXJuIHtcbiAgICBkZXNpcmVkOiB0cnVlLFxuICAgIG5ldHdvcms6IGludGVudC5uZXR3b3JrLFxuICAgIHBoYXNlOiBcImNvbm5lY3RpbmdcIixcbiAgICBzdGFnZSxcbiAgICBhdHRlbXB0LFxuICAgIGdlbmVyYXRpb24sXG4gICAgbGFzdEZhaWx1cmUsXG4gICAgcmV0cnlBdDogbnVsbCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZmFpbHVyZUZyb21FeGl0PEE+KFxuICB0YXJnZXQ6IENvbm5lY3Rpb25UYXJnZXQsXG4gIGV4aXQ6IEV4aXQuRXhpdDxBLCBUcmFjZWRBdHRlbXB0RmFpbHVyZT4sXG4gIGVzdGFibGlzaGVkOiBib29sZWFuLFxuICBzdGFibGU6IGJvb2xlYW4sXG4pOiBBdHRlbXB0T3V0Y29tZSB7XG4gIGlmIChFeGl0LmlzU3VjY2VzcyhleGl0KSB8fCBDYXVzZS5oYXNJbnRlcnJ1cHRzT25seShleGl0LmNhdXNlKSkge1xuICAgIHJldHVybiB7IF90YWc6IFwiSW50ZXJydXB0ZWRcIiwgZXN0YWJsaXNoZWQsIHN0YWJsZSwgcmVzZXRSZXRyeTogZmFsc2UgfTtcbiAgfVxuICBjb25zdCB0eXBlZEZhaWx1cmUgPSBleGl0LmNhdXNlLnJlYXNvbnMuZmluZChDYXVzZS5pc0ZhaWxSZWFzb24pO1xuICBpZiAodHlwZWRGYWlsdXJlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIF90YWc6IFwiRmFpbHVyZVwiLFxuICAgICAgZXN0YWJsaXNoZWQsXG4gICAgICBzdGFibGUsXG4gICAgICBmYWlsdXJlOiB0eXBlZEZhaWx1cmUuZXJyb3IsXG4gICAgfTtcbiAgfVxuICByZXR1cm4ge1xuICAgIF90YWc6IFwiRmFpbHVyZVwiLFxuICAgIGVzdGFibGlzaGVkLFxuICAgIHN0YWJsZSxcbiAgICBmYWlsdXJlOiB7XG4gICAgICBlcnJvcjogbmV3IENvbm5lY3Rpb25UcmFuc2llbnRFcnJvcih7XG4gICAgICAgIHJlYXNvbjogXCJ0cmFuc3BvcnRcIixcbiAgICAgICAgZGV0YWlsOiBgJHt0YXJnZXQubGFiZWx9IGNvbm5lY3Rpb24gZmFpbGVkIHVuZXhwZWN0ZWRseS5gLFxuICAgICAgfSksXG4gICAgICBhdHRlbXB0U3BhbjogT3B0aW9uLm5vbmUoKSxcbiAgICB9LFxuICB9O1xufVxuXG5leHBvcnQgY2xhc3MgRW52aXJvbm1lbnRTdXBlcnZpc29yIGV4dGVuZHMgQ29udGV4dC5TZXJ2aWNlPFxuICBFbnZpcm9ubWVudFN1cGVydmlzb3IsXG4gIHtcbiAgICByZWFkb25seSB0YXJnZXQ6IENvbm5lY3Rpb25UYXJnZXQ7XG4gICAgcmVhZG9ubHkgc3RhdGU6IFN1YnNjcmlwdGlvblJlZi5TdWJzY3JpcHRpb25SZWY8U3VwZXJ2aXNvckNvbm5lY3Rpb25TdGF0ZT47XG4gICAgcmVhZG9ubHkgc2Vzc2lvbjogU3Vic2NyaXB0aW9uUmVmLlN1YnNjcmlwdGlvblJlZjxPcHRpb24uT3B0aW9uPFJwY1Nlc3Npb24uUnBjU2Vzc2lvbj4+O1xuICAgIHJlYWRvbmx5IHByZXBhcmVkOiBTdWJzY3JpcHRpb25SZWYuU3Vic2NyaXB0aW9uUmVmPE9wdGlvbi5PcHRpb248UHJlcGFyZWRDb25uZWN0aW9uPj47XG4gICAgcmVhZG9ubHkgY29ubmVjdDogRWZmZWN0LkVmZmVjdDx2b2lkPjtcbiAgICByZWFkb25seSBkaXNjb25uZWN0OiBFZmZlY3QuRWZmZWN0PHZvaWQ+O1xuICAgIHJlYWRvbmx5IHJldHJ5Tm93OiBFZmZlY3QuRWZmZWN0PHZvaWQ+O1xuICB9XG4+KCkoXCJAdDN0b29scy9jbGllbnQtcnVudGltZS9jb25uZWN0aW9uL3N1cGVydmlzb3IvRW52aXJvbm1lbnRTdXBlcnZpc29yXCIpIHt9XG5cbmV4cG9ydCBjb25zdCBtYWtlID0gRWZmZWN0LmZuKFwiRW52aXJvbm1lbnRTdXBlcnZpc29yLm1ha2VcIikoZnVuY3Rpb24qIChcbiAgZW50cnk6IENvbm5lY3Rpb25DYXRhbG9nRW50cnksXG4gIG9wdGlvbnM/OiBFbnZpcm9ubWVudFN1cGVydmlzb3JPcHRpb25zLFxuKTogRWZmZWN0LmZuLlJldHVybjxcbiAgRW52aXJvbm1lbnRTdXBlcnZpc29yW1wiU2VydmljZVwiXSxcbiAgbmV2ZXIsXG4gIHwgQ29ubmVjdGl2aXR5LkNvbm5lY3Rpdml0eVxuICB8IENvbm5lY3Rpb25Ecml2ZXIuQ29ubmVjdGlvbkRyaXZlclxuICB8IFNjb3BlLlNjb3BlXG4gIHwgQ29ubmVjdGlvbldha2V1cHMuQ29ubmVjdGlvbldha2V1cHNcbj4ge1xuICBjb25zdCB0YXJnZXQgPSBlbnRyeS50YXJnZXQ7XG4gIGNvbnN0IHVzZXNSZWxheSA9IGNvbm5lY3Rpb25Sb3V0ZXMoZW50cnkpLnNvbWUoXG4gICAgKHJvdXRlKSA9PiByb3V0ZS50YXJnZXQuX3RhZyA9PT0gXCJSZWxheUNvbm5lY3Rpb25UYXJnZXRcIixcbiAgKTtcbiAgY29uc3Qgc2V0dXBUaW1lb3V0RGV0YWlsID0gYCR7dGFyZ2V0LmxhYmVsfSBkaWQgbm90IHJlc3BvbmQgZHVyaW5nIGNvbm5lY3Rpb24gc2V0dXAuJHtcbiAgICB1c2VzUmVsYXkgPyBgICR7TkVUV09SS19CTE9DS0lOR19ISU5UfWAgOiBcIlwiXG4gIH1gO1xuICB5aWVsZCogYW5ub3RhdGVUYXJnZXQodGFyZ2V0KTtcblxuICBjb25zdCBjb25uZWN0aXZpdHkgPSB5aWVsZCogQ29ubmVjdGl2aXR5LkNvbm5lY3Rpdml0eTtcbiAgY29uc3QgZHJpdmVyID0geWllbGQqIENvbm5lY3Rpb25Ecml2ZXIuQ29ubmVjdGlvbkRyaXZlcjtcbiAgY29uc3Qgd2FrZXVwcyA9IHlpZWxkKiBDb25uZWN0aW9uV2FrZXVwcy5Db25uZWN0aW9uV2FrZXVwcztcbiAgY29uc3QgaW5pdGlhbEludGVudDogU3VwZXJ2aXNvckludGVudCA9IHtcbiAgICBkZXNpcmVkOiBvcHRpb25zPy5pbml0aWFsbHlEZXNpcmVkID8/IGZhbHNlLFxuICAgIG5ldHdvcms6IHlpZWxkKiBjb25uZWN0aXZpdHkuc3RhdHVzLFxuICB9O1xuICBjb25zdCBpbnRlbnQgPSB5aWVsZCogUmVmLm1ha2UoaW5pdGlhbEludGVudCk7XG4gIGNvbnN0IHNpZ25hbHMgPSB5aWVsZCogUXVldWUudW5ib3VuZGVkPFN1cGVydmlzb3JTaWduYWw+KCk7XG4gIGNvbnN0IHJlc2V0UmV0cnlTdGF0ZSA9IHlpZWxkKiBSZWYubWFrZShmYWxzZSk7XG4gIGNvbnN0IHByb2JlVW5hbnN3ZXJlZCA9IHlpZWxkKiBSZWYubWFrZShmYWxzZSk7XG4gIGNvbnN0IHN0YXRlID0geWllbGQqIFN1YnNjcmlwdGlvblJlZi5tYWtlPFN1cGVydmlzb3JDb25uZWN0aW9uU3RhdGU+KFxuICAgICFpbml0aWFsSW50ZW50LmRlc2lyZWRcbiAgICAgID8gYXZhaWxhYmxlU3RhdGUoaW5pdGlhbEludGVudCwgMClcbiAgICAgIDogaW5pdGlhbEludGVudC5uZXR3b3JrID09PSBcIm9mZmxpbmVcIlxuICAgICAgICA/IG9mZmxpbmVTdGF0ZShpbml0aWFsSW50ZW50LCAwLCAwLCBudWxsKVxuICAgICAgICA6IGNvbm5lY3RpbmdTdGF0ZShpbml0aWFsSW50ZW50LCAwLCAxLCBudWxsKSxcbiAgKTtcbiAgY29uc3Qgc2Vzc2lvbiA9IHlpZWxkKiBTdWJzY3JpcHRpb25SZWYubWFrZTxPcHRpb24uT3B0aW9uPFJwY1Nlc3Npb24uUnBjU2Vzc2lvbj4+KE9wdGlvbi5ub25lKCkpO1xuICBjb25zdCBwcmVwYXJlZCA9IHlpZWxkKiBTdWJzY3JpcHRpb25SZWYubWFrZTxPcHRpb24uT3B0aW9uPFByZXBhcmVkQ29ubmVjdGlvbj4+KE9wdGlvbi5ub25lKCkpO1xuICAvLyBMZWFybmVkIHJvdXRlcyBhcnJpdmUgd2hpbGUgYSBzZXNzaW9uIGlzIGxpdmUsIHNvIHRoZSByb3V0ZSBsaXN0IGlzIHJlYWRcbiAgLy8gZnJlc2ggYnkgZWFjaCBhdHRlbXB0IGFuZCBjaGVjayBpbnN0ZWFkIG9mIGJlaW5nIGZpeGVkIGF0IGNyZWF0aW9uLlxuICBjb25zdCBjdXJyZW50RW50cnkgPSB5aWVsZCogUmVmLm1ha2UoZW50cnkpO1xuICBjb25zdCBjdXJyZW50Um91dGVzID0gUmVmLmdldChjdXJyZW50RW50cnkpLnBpcGUoRWZmZWN0Lm1hcChjb25uZWN0aW9uUm91dGVzKSk7XG4gIGNvbnN0IHByZWZlcnJlZFJvdXRlSWQgPSB5aWVsZCogUmVmLm1ha2UoT3B0aW9uLm5vbmU8c3RyaW5nPigpKTtcbiAgY29uc3Qgcm91dGVDb29sZG93bnMgPSB5aWVsZCogUmVmLm1ha2U8UmVhZG9ubHlNYXA8c3RyaW5nLCBiaWdpbnQ+PihuZXcgTWFwKCkpO1xuXG4gIGNvbnN0IGF0dGVtcHRFbnRyeSA9IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBsYXRlc3QgPSB5aWVsZCogUmVmLmdldChjdXJyZW50RW50cnkpO1xuICAgIGNvbnN0IHJvdXRlcyA9IGNvbm5lY3Rpb25Sb3V0ZXMobGF0ZXN0KTtcbiAgICBjb25zdCBwcmVmZXJyZWQgPSB5aWVsZCogUmVmLmdldEFuZFNldChwcmVmZXJyZWRSb3V0ZUlkLCBPcHRpb24ubm9uZSgpKTtcbiAgICBpZiAoT3B0aW9uLmlzTm9uZShwcmVmZXJyZWQpKSByZXR1cm4gbGF0ZXN0O1xuICAgIGNvbnN0IHJvdXRlID0gcm91dGVzLmZpbmQoXG4gICAgICAoY2FuZGlkYXRlKSA9PiBjb25uZWN0aW9uUm91dGVJZChjYW5kaWRhdGUudGFyZ2V0KSA9PT0gcHJlZmVycmVkLnZhbHVlLFxuICAgICk7XG4gICAgcmV0dXJuIHJvdXRlID09PSB1bmRlZmluZWRcbiAgICAgID8gbGF0ZXN0XG4gICAgICA6IGVudHJ5V2l0aFJvdXRlcyhsYXRlc3QsIFtyb3V0ZSwgLi4ucm91dGVzLmZpbHRlcigoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUgIT09IHJvdXRlKV0pO1xuICB9KTtcblxuICBjb25zdCBsZWFyblJvdXRlc0Zyb20gPSBFZmZlY3QuZm5VbnRyYWNlZChmdW5jdGlvbiogKFxuICAgIGxlYXJuOiBOb25OdWxsYWJsZTxFbnZpcm9ubWVudFN1cGVydmlzb3JPcHRpb25zW1wibGVhcm5Sb3V0ZXNcIl0+LFxuICAgIGxlYXNlOiBDb25uZWN0aW9uRHJpdmVyLkVudmlyb25tZW50Q29ubmVjdGlvbkxlYXNlLFxuICApIHtcbiAgICBjb25zdCBjb25maWcgPSB5aWVsZCogbGVhc2Uuc2Vzc2lvbi5pbml0aWFsQ29uZmlnLnBpcGUoRWZmZWN0Lm9wdGlvbik7XG4gICAgY29uc3QgcmVwb3J0ZWQgPSBPcHRpb24uZ2V0T3JVbmRlZmluZWQoY29uZmlnKT8uZGlyZWN0RW5kcG9pbnRzO1xuICAgIGlmIChyZXBvcnRlZCA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgY29uc3QgYWN0aXZlSWQgPSBjb25uZWN0aW9uUm91dGVJZChsZWFzZS5wcmVwYXJlZC50YXJnZXQpO1xuICAgIGNvbnN0IGFjdGl2ZVJvdXRlID0gKHlpZWxkKiBjdXJyZW50Um91dGVzKS5maW5kKFxuICAgICAgKHJvdXRlKSA9PiBjb25uZWN0aW9uUm91dGVJZChyb3V0ZS50YXJnZXQpID09PSBhY3RpdmVJZCxcbiAgICApO1xuICAgIGlmIChhY3RpdmVSb3V0ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgY29uc3QgdXBkYXRlZCA9IHlpZWxkKiBsZWFybih7IGFjdGl2ZVJvdXRlLCByZXBvcnRlZCB9KTtcbiAgICBpZiAoT3B0aW9uLmlzU29tZSh1cGRhdGVkKSkge1xuICAgICAgeWllbGQqIFJlZi5zZXQoY3VycmVudEVudHJ5LCB1cGRhdGVkLnZhbHVlKTtcbiAgICAgIHlpZWxkKiByZXF1ZXN0QmV0dGVyUm91dGVDaGVjayhsZWFzZSk7XG4gICAgfVxuICB9KTtcblxuICBjb25zdCByb3V0ZUluZGV4ID0gKGxlYXNlOiBDb25uZWN0aW9uRHJpdmVyLkVudmlyb25tZW50Q29ubmVjdGlvbkxlYXNlKSA9PlxuICAgIGN1cnJlbnRSb3V0ZXMucGlwZShcbiAgICAgIEVmZmVjdC5tYXAoKHJvdXRlcykgPT5cbiAgICAgICAgcm91dGVzLmZpbmRJbmRleChcbiAgICAgICAgICAocm91dGUpID0+IGNvbm5lY3Rpb25Sb3V0ZUlkKHJvdXRlLnRhcmdldCkgPT09IGNvbm5lY3Rpb25Sb3V0ZUlkKGxlYXNlLnByZXBhcmVkLnRhcmdldCksXG4gICAgICAgICksXG4gICAgICApLFxuICAgICk7XG5cbiAgY29uc3QgY2hlY2tCZXR0ZXJSb3V0ZXMgPSBFZmZlY3QuZm5VbnRyYWNlZChmdW5jdGlvbiogKFxuICAgIGxlYXNlOiBDb25uZWN0aW9uRHJpdmVyLkVudmlyb25tZW50Q29ubmVjdGlvbkxlYXNlLFxuICApIHtcbiAgICBjb25zdCBsYXRlc3QgPSB5aWVsZCogUmVmLmdldChjdXJyZW50RW50cnkpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB5aWVsZCogcm91dGVJbmRleChsZWFzZSk7XG4gICAgaWYgKGN1cnJlbnQgPD0gMCkgcmV0dXJuO1xuICAgIGNvbnN0IG5vdyA9IHlpZWxkKiBDbG9jay5tb25vdG9uaWNUaW1lTmFub3M7XG4gICAgY29uc3QgY29vbGRvd25zID0geWllbGQqIFJlZi5nZXQocm91dGVDb29sZG93bnMpO1xuICAgIGNvbnN0IGJldHRlciA9IGNvbm5lY3Rpb25Sb3V0ZXMobGF0ZXN0KVxuICAgICAgLnNsaWNlKDAsIGN1cnJlbnQpXG4gICAgICAuZmlsdGVyKChyb3V0ZSkgPT4gKGNvb2xkb3ducy5nZXQoY29ubmVjdGlvblJvdXRlSWQocm91dGUudGFyZ2V0KSkgPz8gMG4pIDw9IG5vdyk7XG4gICAgY29uc3QgcGFzc2VkID0geWllbGQqIEVmZmVjdC5mb3JFYWNoKFxuICAgICAgYmV0dGVyLFxuICAgICAgKHJvdXRlOiBDb25uZWN0aW9uUm91dGUpID0+IGRyaXZlci5wcmVmbGlnaHQobGF0ZXN0LCByb3V0ZSksXG4gICAgICB7IGNvbmN1cnJlbmN5OiBcInVuYm91bmRlZFwiIH0sXG4gICAgKTtcbiAgICBjb25zdCBpbmRleCA9IHBhc3NlZC5pbmRleE9mKHRydWUpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHJldHVybjtcbiAgICBjb25zdCBsaXZlID0geWllbGQqIFN1YnNjcmlwdGlvblJlZi5nZXQoc2Vzc2lvbik7XG4gICAgaWYgKE9wdGlvbi5pc05vbmUobGl2ZSkgfHwgbGl2ZS52YWx1ZSAhPT0gbGVhc2Uuc2Vzc2lvbikgcmV0dXJuO1xuICAgIHlpZWxkKiBzaWduYWwoe1xuICAgICAgX3RhZzogXCJCZXR0ZXJSb3V0ZUF2YWlsYWJsZVwiLFxuICAgICAgcm91dGVJZDogY29ubmVjdGlvblJvdXRlSWQoYmV0dGVyW2luZGV4XSEudGFyZ2V0KSxcbiAgICB9KTtcbiAgfSk7XG5cbiAgY29uc3QgYmV0dGVyUm91dGVDaGVja3MgPSB5aWVsZCogUXVldWUuZHJvcHBpbmc8Q29ubmVjdGlvbkRyaXZlci5FbnZpcm9ubWVudENvbm5lY3Rpb25MZWFzZT4oMSk7XG4gIGNvbnN0IHJlcXVlc3RCZXR0ZXJSb3V0ZUNoZWNrID0gKGxlYXNlOiBDb25uZWN0aW9uRHJpdmVyLkVudmlyb25tZW50Q29ubmVjdGlvbkxlYXNlKSA9PlxuICAgIHJvdXRlSW5kZXgobGVhc2UpLnBpcGUoXG4gICAgICBFZmZlY3QuZmxhdE1hcCgoaW5kZXgpID0+XG4gICAgICAgIGluZGV4ID4gMCA/IFF1ZXVlLm9mZmVyKGJldHRlclJvdXRlQ2hlY2tzLCBsZWFzZSkucGlwZShFZmZlY3QuYXNWb2lkKSA6IEVmZmVjdC52b2lkLFxuICAgICAgKSxcbiAgICApO1xuXG4gIGNvbnN0IGNsZWFyTGVhc2UgPSBFZmZlY3QuYWxsKFxuICAgIFtTdWJzY3JpcHRpb25SZWYuc2V0KHNlc3Npb24sIE9wdGlvbi5ub25lKCkpLCBTdWJzY3JpcHRpb25SZWYuc2V0KHByZXBhcmVkLCBPcHRpb24ubm9uZSgpKV0sXG4gICAgeyBkaXNjYXJkOiB0cnVlIH0sXG4gICk7XG5cbiAgY29uc3Qgc2V0U3RhdGUgPSBFZmZlY3QuZm4oXCJFbnZpcm9ubWVudFN1cGVydmlzb3Iuc2V0U3RhdGVcIikoZnVuY3Rpb24qIChcbiAgICBuZXh0OiBTdXBlcnZpc29yQ29ubmVjdGlvblN0YXRlLFxuICApIHtcbiAgICB5aWVsZCogU3Vic2NyaXB0aW9uUmVmLnNldChzdGF0ZSwgbmV4dCk7XG4gIH0pO1xuXG4gIGNvbnN0IHNpZ25hbCA9IEVmZmVjdC5mbihcIkVudmlyb25tZW50U3VwZXJ2aXNvci5zaWduYWxcIikoZnVuY3Rpb24qIChuZXh0OiBTdXBlcnZpc29yU2lnbmFsKSB7XG4gICAgeWllbGQqIFF1ZXVlLm9mZmVyKHNpZ25hbHMsIG5leHQpO1xuICB9KTtcblxuICBjb25zdCBsb2dNYW5hZ2VkUmVsYXlBY2NvdW50Q2hhbmdlID0gRWZmZWN0LmxvZ0luZm8oXG4gICAgXCJNYW5hZ2VkIHJlbGF5IGFjY291bnQgY2hhbmdlZDsgcmVzdGFydGluZyB0aGUgZW52aXJvbm1lbnQgY29ubmVjdGlvbi5cIixcbiAgKS5waXBlKFxuICAgIEVmZmVjdC5hbm5vdGF0ZUxvZ3Moe1xuICAgICAgXCJlbnZpcm9ubWVudC5pZFwiOiB0YXJnZXQuZW52aXJvbm1lbnRJZCxcbiAgICAgIFwiZW52aXJvbm1lbnQubGFiZWxcIjogdGFyZ2V0LmxhYmVsLFxuICAgIH0pLFxuICApO1xuXG4gIGNvbnN0IHJlcG9ydFByb2dyZXNzID0gRWZmZWN0LmZuKFwiRW52aXJvbm1lbnRTdXBlcnZpc29yLnJlcG9ydFByb2dyZXNzXCIpKGZ1bmN0aW9uKiAoXG4gICAgYXR0ZW1wdDogbnVtYmVyLFxuICAgIGdlbmVyYXRpb246IG51bWJlcixcbiAgICBsYXN0RmFpbHVyZTogQ29ubmVjdGlvbkF0dGVtcHRFcnJvciB8IG51bGwsXG4gICAgcHJvZ3Jlc3M6IENvbm5lY3Rpb25Ecml2ZXIuQ29ubmVjdGlvbkRyaXZlclByb2dyZXNzLFxuICApIHtcbiAgICBpZiAoXCJwcmVwYXJlZFwiIGluIHByb2dyZXNzKSB7XG4gICAgICB5aWVsZCogU3Vic2NyaXB0aW9uUmVmLnNldChwcmVwYXJlZCwgT3B0aW9uLnNvbWUocHJvZ3Jlc3MucHJlcGFyZWQpKTtcbiAgICB9XG4gICAgeWllbGQqIHNldFN0YXRlKFxuICAgICAgY29ubmVjdGluZ1N0YXRlKHlpZWxkKiBSZWYuZ2V0KGludGVudCksIGdlbmVyYXRpb24sIGF0dGVtcHQsIGxhc3RGYWlsdXJlLCBwcm9ncmVzcy5zdGFnZSksXG4gICAgKTtcbiAgfSk7XG5cbiAgY29uc3QgZXN0YWJsaXNoQ29ubmVjdGlvbiA9IEVmZmVjdC5mblVudHJhY2VkKGZ1bmN0aW9uKiAoXG4gICAgYXR0ZW1wdDogbnVtYmVyLFxuICAgIGdlbmVyYXRpb246IG51bWJlcixcbiAgICBsYXN0RmFpbHVyZTogQ29ubmVjdGlvbkF0dGVtcHRFcnJvciB8IG51bGwsXG4gICAgc3luY2hyb25pemVkUm91dGVzOiBSZWYuUmVmPG51bWJlcj4sXG4gICkge1xuICAgIHJldHVybiB5aWVsZCogZHJpdmVyLmNvbm5lY3QoeWllbGQqIGF0dGVtcHRFbnRyeSwgKHByb2dyZXNzKSA9PlxuICAgICAgKHByb2dyZXNzLnN0YWdlID09PSBcInN5bmNocm9uaXppbmdcIlxuICAgICAgICA/IFJlZi51cGRhdGUoc3luY2hyb25pemVkUm91dGVzLCAoY291bnQpID0+IGNvdW50ICsgMSlcbiAgICAgICAgOiBFZmZlY3Qudm9pZFxuICAgICAgKS5waXBlKEVmZmVjdC5hbmRUaGVuKHJlcG9ydFByb2dyZXNzKGF0dGVtcHQsIGdlbmVyYXRpb24sIGxhc3RGYWlsdXJlLCBwcm9ncmVzcykpKSxcbiAgICApO1xuICB9KTtcblxuICAvLyBMb3ctY2FyZGluYWxpdHkgZGltZW5zaW9ucyBmb3IgdGltZS10by1jb25uZWN0ZWQgZGFzaGJvYXJkczsgdGhlIGVycm9yXG4gIC8vIGRldGFpbCBzdGF5cyBpbiB0aGUgc3BhbiBzdGF0dXMsIG5ldmVyIGluIGFuIGF0dHJpYnV0ZS5cbiAgY29uc3QgYW5ub3RhdGVBdHRlbXB0T3V0Y29tZSA9IEVmZmVjdC5mblVudHJhY2VkKGZ1bmN0aW9uKiAoXG4gICAgZXhpdDogRXhpdC5FeGl0PENvbm5lY3Rpb25Ecml2ZXIuRW52aXJvbm1lbnRDb25uZWN0aW9uTGVhc2UsIENvbm5lY3Rpb25BdHRlbXB0RXJyb3I+LFxuICApIHtcbiAgICBpZiAoRXhpdC5pc1N1Y2Nlc3MoZXhpdCkpIHtcbiAgICAgIGNvbnN0IGxlYXNlVGFyZ2V0ID0gZXhpdC52YWx1ZS5wcmVwYXJlZC50YXJnZXQ7XG4gICAgICBjb25zdCByb3V0ZSA9ICh5aWVsZCogY3VycmVudFJvdXRlcykuZmluZChcbiAgICAgICAgKGNhbmRpZGF0ZSkgPT4gY29ubmVjdGlvblJvdXRlSWQoY2FuZGlkYXRlLnRhcmdldCkgPT09IGNvbm5lY3Rpb25Sb3V0ZUlkKGxlYXNlVGFyZ2V0KSxcbiAgICAgICk7XG4gICAgICByZXR1cm4geWllbGQqIEVmZmVjdC5hbm5vdGF0ZUN1cnJlbnRTcGFuKHtcbiAgICAgICAgXCJjb25uZWN0aW9uLm91dGNvbWVcIjogXCJjb25uZWN0ZWRcIixcbiAgICAgICAgXCJjb25uZWN0aW9uLnJvdXRlXCI6IGNvbm5lY3Rpb25Sb3V0ZUtpbmQoXG4gICAgICAgICAgcm91dGUgPz8geyB0YXJnZXQ6IGxlYXNlVGFyZ2V0LCBwcm9maWxlOiBPcHRpb24ubm9uZSgpIH0sXG4gICAgICAgICksXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKENhdXNlLmhhc0ludGVycnVwdHNPbmx5KGV4aXQuY2F1c2UpKSB7XG4gICAgICByZXR1cm4geWllbGQqIEVmZmVjdC5hbm5vdGF0ZUN1cnJlbnRTcGFuKFwiY29ubmVjdGlvbi5vdXRjb21lXCIsIFwiaW50ZXJydXB0ZWRcIik7XG4gICAgfVxuICAgIGNvbnN0IGZhaWx1cmUgPSBleGl0LmNhdXNlLnJlYXNvbnMuZmluZChDYXVzZS5pc0ZhaWxSZWFzb24pPy5lcnJvcjtcbiAgICB5aWVsZCogRWZmZWN0LmFubm90YXRlQ3VycmVudFNwYW4oe1xuICAgICAgXCJjb25uZWN0aW9uLm91dGNvbWVcIjogXCJmYWlsZWRcIixcbiAgICAgIFwiY29ubmVjdGlvbi5mYWlsdXJlLnRhZ1wiOiBmYWlsdXJlPy5fdGFnID8/IFwiZGVmZWN0XCIsXG4gICAgICBcImNvbm5lY3Rpb24uZmFpbHVyZS5yZWFzb25cIjogZmFpbHVyZT8ucmVhc29uID8/IFwiZGVmZWN0XCIsXG4gICAgfSk7XG4gIH0pO1xuXG4gIGNvbnN0IHRyYWNlUmVsYXlFc3RhYmxpc2htZW50ID0gKFxuICAgIGVmZmVjdDogRWZmZWN0LkVmZmVjdDxcbiAgICAgIENvbm5lY3Rpb25Ecml2ZXIuRW52aXJvbm1lbnRDb25uZWN0aW9uTGVhc2UsXG4gICAgICBDb25uZWN0aW9uQXR0ZW1wdEVycm9yLFxuICAgICAgU2NvcGUuU2NvcGVcbiAgICA+LFxuICAgIGF0dGVtcHQ6IG51bWJlcixcbiAgICBnZW5lcmF0aW9uOiBudW1iZXIsXG4gICAgcGVuZGluZ1JldHJ5OiBPcHRpb24uT3B0aW9uPFBlbmRpbmdSZXRyeVRyYWNlPixcbiAgKSA9PiB7XG4gICAgLy8gVGhlIHNwYW4gbXVzdCBlbmQgd2l0aCB0aGUgQ29ubmVjdGlvbkF0dGVtcHRFcnJvciBpdHNlbGY6IHRoZSBleHBvcnRlclxuICAgIC8vIGNhbiBvbmx5IGRlc2NyaWJlIGFuIEVycm9yLWxpa2UgZmFpbHVyZSwgYW5kIGEgVHJhY2VkQXR0ZW1wdEZhaWx1cmVcbiAgICAvLyB3cmFwcGVyIHJlYWNoZWQgaXQgYXMgXCJbb2JqZWN0IE9iamVjdF1cIi4gVGhlIHdyYXBwZXIgaXMgYWRkZWQgb3V0c2lkZS5cbiAgICBsZXQgYXR0ZW1wdFNwYW4gPSBPcHRpb24ubm9uZTxUcmFjZXIuU3Bhbj4oKTtcbiAgICBjb25zdCB0cmFjZWQgPSBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICBhdHRlbXB0U3BhbiA9IE9wdGlvbi5zb21lKHlpZWxkKiBFZmZlY3QuY3VycmVudFNwYW4ucGlwZShFZmZlY3Qub3JEaWUpKTtcbiAgICAgIHlpZWxkKiBhbm5vdGF0ZVRhcmdldCh0YXJnZXQpO1xuICAgICAgeWllbGQqIEVmZmVjdC5hbm5vdGF0ZUN1cnJlbnRTcGFuKHtcbiAgICAgICAgXCJjb25uZWN0aW9uLmF0dGVtcHRcIjogYXR0ZW1wdCxcbiAgICAgICAgXCJjb25uZWN0aW9uLmdlbmVyYXRpb25cIjogZ2VuZXJhdGlvbixcbiAgICAgICAgXCJjb25uZWN0aW9uLnJldHJ5LmZhaWx1cmVfY291bnRcIjogT3B0aW9uLm1hdGNoKHBlbmRpbmdSZXRyeSwge1xuICAgICAgICAgIG9uTm9uZTogKCkgPT4gMCxcbiAgICAgICAgICBvblNvbWU6IChyZXRyeSkgPT4gcmV0cnkuZmFpbHVyZUNvdW50LFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHlpZWxkKiBlZmZlY3QucGlwZShFZmZlY3Qub25FeGl0KGFubm90YXRlQXR0ZW1wdE91dGNvbWUpKTtcbiAgICB9KS5waXBlKEVmZmVjdC53aXRoU3BhbihcInJlbGF5LmNvbm5lY3Rpb24uYXR0ZW1wdFwiLCB7IHJvb3Q6IHRydWUgfSkpO1xuXG4gICAgcmV0dXJuIE9wdGlvbi5tYXRjaChwZW5kaW5nUmV0cnksIHtcbiAgICAgIG9uTm9uZTogKCkgPT4gdHJhY2VkLFxuICAgICAgb25Tb21lOiAocmV0cnkpID0+XG4gICAgICAgIHRyYWNlZC5waXBlKFxuICAgICAgICAgIEVmZmVjdC5saW5rU3BhbnMocmV0cnkucHJldmlvdXNBdHRlbXB0LCB7XG4gICAgICAgICAgICBcImNvbm5lY3Rpb24ucmV0cnkuZGVsYXlfbXNcIjogcmV0cnkuZGVsYXlNcyxcbiAgICAgICAgICAgIFwiY29ubmVjdGlvbi5yZXRyeS5yZWFzb25cIjogcmV0cnkucmVhc29uLFxuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgIH0pLnBpcGUoXG4gICAgICBFZmZlY3QubWFwKChsZWFzZSkgPT4gKHsgYXR0ZW1wdFNwYW4sIGxlYXNlIH0pKSxcbiAgICAgIEVmZmVjdC5tYXBFcnJvcigoZXJyb3IpOiBUcmFjZWRBdHRlbXB0RmFpbHVyZSA9PiAoeyBlcnJvciwgYXR0ZW1wdFNwYW4gfSkpLFxuICAgICAgd2l0aFJlbGF5Q2xpZW50VHJhY2luZyxcbiAgICApO1xuICB9O1xuXG4gIGNvbnN0IGVzdGFibGlzaFRyYWNlZENvbm5lY3Rpb24gPSBFZmZlY3QuZm5VbnRyYWNlZChmdW5jdGlvbiogKFxuICAgIGF0dGVtcHQ6IG51bWJlcixcbiAgICBnZW5lcmF0aW9uOiBudW1iZXIsXG4gICAgbGFzdEZhaWx1cmU6IENvbm5lY3Rpb25BdHRlbXB0RXJyb3IgfCBudWxsLFxuICAgIHBlbmRpbmdSZXRyeTogT3B0aW9uLk9wdGlvbjxQZW5kaW5nUmV0cnlUcmFjZT4sXG4gICAgc3luY2hyb25pemVkUm91dGVzOiBSZWYuUmVmPG51bWJlcj4sXG4gICkge1xuICAgIGlmICh1c2VzUmVsYXkpIHtcbiAgICAgIHJldHVybiB5aWVsZCogdHJhY2VSZWxheUVzdGFibGlzaG1lbnQoXG4gICAgICAgIGVzdGFibGlzaENvbm5lY3Rpb24oYXR0ZW1wdCwgZ2VuZXJhdGlvbiwgbGFzdEZhaWx1cmUsIHN5bmNocm9uaXplZFJvdXRlcyksXG4gICAgICAgIGF0dGVtcHQsXG4gICAgICAgIGdlbmVyYXRpb24sXG4gICAgICAgIHBlbmRpbmdSZXRyeSxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB5aWVsZCogZXN0YWJsaXNoQ29ubmVjdGlvbihhdHRlbXB0LCBnZW5lcmF0aW9uLCBsYXN0RmFpbHVyZSwgc3luY2hyb25pemVkUm91dGVzKS5waXBlKFxuICAgICAgRWZmZWN0Lm1hcCgobGVhc2UpID0+ICh7XG4gICAgICAgIGF0dGVtcHRTcGFuOiBPcHRpb24ubm9uZTxUcmFjZXIuU3Bhbj4oKSxcbiAgICAgICAgbGVhc2UsXG4gICAgICB9KSksXG4gICAgICBFZmZlY3QubWFwRXJyb3IoKGVycm9yKTogVHJhY2VkQXR0ZW1wdEZhaWx1cmUgPT4gKHtcbiAgICAgICAgZXJyb3IsXG4gICAgICAgIGF0dGVtcHRTcGFuOiBPcHRpb24ubm9uZSgpLFxuICAgICAgfSkpLFxuICAgICk7XG4gIH0pO1xuXG4gIGNvbnN0IHdhaXRGb3JFc3RhYmxpc2htZW50SW50ZXJydXB0ID0gRWZmZWN0LmZuVW50cmFjZWQoZnVuY3Rpb24qICgpIHtcbiAgICBmb3IgKDs7KSB7XG4gICAgICBjb25zdCBuZXh0ID0geWllbGQqIFF1ZXVlLnRha2Uoc2lnbmFscyk7XG4gICAgICBzd2l0Y2ggKG5leHQuX3RhZykge1xuICAgICAgICBjYXNlIFwiRGlzY29ubmVjdFJlcXVlc3RlZFwiOlxuICAgICAgICBjYXNlIFwiUmV0cnlSZXF1ZXN0ZWRcIjpcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGNhc2UgXCJOZXR3b3JrQ2hhbmdlZFwiOlxuICAgICAgICAgIGlmIChuZXh0Lm5ldHdvcmsgPT09IFwib2ZmbGluZVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiQ29ubmVjdFJlcXVlc3RlZFwiOlxuICAgICAgICBjYXNlIFwiQmV0dGVyUm91dGVBdmFpbGFibGVcIjpcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIldha2V1cFwiOlxuICAgICAgICAgIGlmIChuZXh0LnJlYXNvbiA9PT0gXCJhcHBsaWNhdGlvbi1hY3RpdmUtcmVjb25uZWN0XCIpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobmV4dC5yZWFzb24gPT09IFwiY3JlZGVudGlhbHMtY2hhbmdlZFwiICYmIHVzZXNSZWxheSkge1xuICAgICAgICAgICAgeWllbGQqIGxvZ01hbmFnZWRSZWxheUFjY291bnRDaGFuZ2U7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgY29uc3QgaXNSZWxheUxlYXNlID0gKGxlYXNlOiBDb25uZWN0aW9uRHJpdmVyLkVudmlyb25tZW50Q29ubmVjdGlvbkxlYXNlKSA9PlxuICAgIGxlYXNlLnByZXBhcmVkLnRhcmdldC5fdGFnID09PSBcIlJlbGF5Q29ubmVjdGlvblRhcmdldFwiO1xuXG4gIGNvbnN0IGNvbm5lY3RlZExlYXNlRW5kID0gRWZmZWN0LmZuVW50cmFjZWQoZnVuY3Rpb24qIChcbiAgICBuZXh0OiBTdXBlcnZpc29yU2lnbmFsLFxuICAgIGxlYXNlOiBDb25uZWN0aW9uRHJpdmVyLkVudmlyb25tZW50Q29ubmVjdGlvbkxlYXNlLFxuICApIHtcbiAgICBpZiAobmV4dC5fdGFnID09PSBcIkRpc2Nvbm5lY3RSZXF1ZXN0ZWRcIikge1xuICAgICAgcmV0dXJuIFwiZW5kXCIgYXMgY29uc3Q7XG4gICAgfVxuICAgIGlmIChuZXh0Ll90YWcgPT09IFwiQmV0dGVyUm91dGVBdmFpbGFibGVcIikge1xuICAgICAgeWllbGQqIFJlZi5zZXQocHJlZmVycmVkUm91dGVJZCwgT3B0aW9uLnNvbWUobmV4dC5yb3V0ZUlkKSk7XG4gICAgICByZXR1cm4gXCJyZXNldFwiIGFzIGNvbnN0O1xuICAgIH1cbiAgICBpZiAobmV4dC5fdGFnICE9PSBcIldha2V1cFwiKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBpZiAobmV4dC5yZWFzb24gPT09IFwiYXBwbGljYXRpb24tYWN0aXZlLXJlY29ubmVjdFwiKSB7XG4gICAgICAvLyBNb2JpbGUgb3BlcmF0aW5nIHN5c3RlbXMgb2Z0ZW4ga2lsbCBhIHN1c3BlbmRlZCBzb2NrZXQgd2l0aG91dCBhIGNsb3NlXG4gICAgICAvLyBldmVudC4gQSBwcm9iZSB3b3VsZCBzaG93IGEgZGVhZCBzb2NrZXQgYXMgXCJSZXN1bWluZ1wiIHVudGlsIGl0IHRpbWVzXG4gICAgICAvLyBvdXQsIHNvIGEgbG9uZyBiYWNrZ3JvdW5kIHJlc3VtZSByZXBsYWNlcyB0aGUgc2Vzc2lvbiBhdCBvbmNlLlxuICAgICAgcmV0dXJuIFwicmVzZXRcIiBhcyBjb25zdDtcbiAgICB9XG4gICAgLy8gT25seSBhIHNlc3Npb24gb3ZlciBUMyBDb25uZWN0IGhvbGRzIHRoZSBvbGQgYWNjb3VudCdzIGNyZWRlbnRpYWwuXG4gICAgaWYgKG5leHQucmVhc29uID09PSBcImNyZWRlbnRpYWxzLWNoYW5nZWRcIiAmJiBpc1JlbGF5TGVhc2UobGVhc2UpKSB7XG4gICAgICB5aWVsZCogbG9nTWFuYWdlZFJlbGF5QWNjb3VudENoYW5nZTtcbiAgICAgIHJldHVybiBcImVuZFwiIGFzIGNvbnN0O1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9KTtcblxuICBjb25zdCBwcm9iZVRpbWVvdXRGb3IgPSAobmV4dDogU3VwZXJ2aXNvclNpZ25hbCk6IER1cmF0aW9uLklucHV0IHwgdW5kZWZpbmVkID0+IHtcbiAgICBzd2l0Y2ggKG5leHQuX3RhZykge1xuICAgICAgY2FzZSBcIlJldHJ5UmVxdWVzdGVkXCI6XG4gICAgICAgIHJldHVybiBRVUlDS19DT05ORUNUSU9OX1BST0JFX1RJTUVPVVQ7XG4gICAgICBjYXNlIFwiTmV0d29ya0NoYW5nZWRcIjpcbiAgICAgICAgcmV0dXJuIG5leHQubmV0d29yayA9PT0gXCJvZmZsaW5lXCIgPyBRVUlDS19DT05ORUNUSU9OX1BST0JFX1RJTUVPVVQgOiB1bmRlZmluZWQ7XG4gICAgICBjYXNlIFwiV2FrZXVwXCI6XG4gICAgICAgIGlmIChuZXh0LnJlYXNvbiA9PT0gXCJhcHBsaWNhdGlvbi1hY3RpdmVcIikge1xuICAgICAgICAgIHJldHVybiBDT05ORUNUSU9OX1BST0JFX1RJTUVPVVQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5leHQucmVhc29uID09PSBcImFwcGxpY2F0aW9uLWFjdGl2ZS1wcm9iZVwiIHx8IG5leHQucmVhc29uID09PSBcIm5ldHdvcmstY2hhbmdlZFwiXG4gICAgICAgICAgPyBRVUlDS19DT05ORUNUSU9OX1BST0JFX1RJTUVPVVRcbiAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgIGNhc2UgXCJDb25uZWN0UmVxdWVzdGVkXCI6XG4gICAgICBjYXNlIFwiRGlzY29ubmVjdFJlcXVlc3RlZFwiOlxuICAgICAgY2FzZSBcIkJldHRlclJvdXRlQXZhaWxhYmxlXCI6XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9O1xuXG4gIC8vIFJldHVybmluZyB0byB0aGUgYXBwLCBhbiBleHBsaWNpdCByZXRyeSwgYW5kIHRoZSBuZXR3b3JrIHJlcG9ydGluZyBvZmZsaW5lXG4gIC8vIGFsbCBwcm9iZSB0aGUgbGl2ZSBzZXNzaW9uIGluc3RlYWQgb2YgcmVwbGFjaW5nIGl0LCBzbyBhIGhlYWx0aHkgc29ja2V0IGlzXG4gIC8vIG5vdCB0b3JuIGRvd24gKHRoZSBvZmZsaW5lIHJlcG9ydCBpcyBvZnRlbiB3cm9uZywgZm9yIGV4YW1wbGUgZm9yIGFcbiAgLy8gbG9vcGJhY2sgc2VydmVyKS5cbiAgY29uc3QgbW9uaXRvckNvbm5lY3RlZExlYXNlID0gRWZmZWN0LmZuVW50cmFjZWQoZnVuY3Rpb24qIChcbiAgICBsZWFzZTogQ29ubmVjdGlvbkRyaXZlci5FbnZpcm9ubWVudENvbm5lY3Rpb25MZWFzZSxcbiAgKSB7XG4gICAgLy8gQSBwcm9iZSBhbnN3ZXJzIGFuIGV4cGxpY2l0IHJldHJ5IGhlcmUsIHNvIHRoZSByZXRyeSBtdXN0IG5vdCBhbHNvIHJlc2V0XG4gICAgLy8gdGhlIGJhY2tvZmYgb2YgYSBsYXRlciwgdW5yZWxhdGVkIGZhaWx1cmUuXG4gICAgY29uc3QgdGFrZVNpZ25hbCA9IFF1ZXVlLnRha2Uoc2lnbmFscykucGlwZShcbiAgICAgIEVmZmVjdC50YXAoKG5leHQpID0+XG4gICAgICAgIG5leHQuX3RhZyA9PT0gXCJSZXRyeVJlcXVlc3RlZFwiID8gUmVmLnNldChyZXNldFJldHJ5U3RhdGUsIGZhbHNlKSA6IEVmZmVjdC52b2lkLFxuICAgICAgKSxcbiAgICApO1xuICAgIC8vIFRpY2tzIGFsd2F5cyBydW46IHRoZSBjaGVjayBza2lwcyB0aGUgcHJlZmVycmVkIHJvdXRlIGl0c2VsZiwgYW5kIHRoZVxuICAgIC8vIHJvdXRlIGxpc3QgY2FuIGdyb3cgd2hpbGUgY29ubmVjdGVkIChsZWFybmVkIHJvdXRlcykuXG4gICAgeWllbGQqIFN0cmVhbS50aWNrKEJFVFRFUl9ST1VURV9DSEVDS19JTlRFUlZBTCkucGlwZShcbiAgICAgIFN0cmVhbS5kcm9wKDEpLFxuICAgICAgU3RyZWFtLnJ1bkZvckVhY2goKCkgPT4gcmVxdWVzdEJldHRlclJvdXRlQ2hlY2sobGVhc2UpKSxcbiAgICAgIEVmZmVjdC5mb3JrU2NvcGVkLFxuICAgICk7XG4gICAgZm9yICg7Oykge1xuICAgICAgY29uc3QgbmV4dCA9IHlpZWxkKiB0YWtlU2lnbmFsO1xuICAgICAgY29uc3QgZW5kID0geWllbGQqIGNvbm5lY3RlZExlYXNlRW5kKG5leHQsIGxlYXNlKTtcbiAgICAgIGlmIChlbmQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZW5kID09PSBcInJlc2V0XCI7XG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgIChuZXh0Ll90YWcgPT09IFwiTmV0d29ya0NoYW5nZWRcIiAmJiBuZXh0Lm5ldHdvcmsgIT09IFwib2ZmbGluZVwiKSB8fFxuICAgICAgICAobmV4dC5fdGFnID09PSBcIldha2V1cFwiICYmIENvbm5lY3Rpb25XYWtldXBzLnJlc2V0c1JldHJ5QmFja29mZihuZXh0LnJlYXNvbikpXG4gICAgICApIHtcbiAgICAgICAgeWllbGQqIHJlcXVlc3RCZXR0ZXJSb3V0ZUNoZWNrKGxlYXNlKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHByb2JlVGltZW91dCA9IHByb2JlVGltZW91dEZvcihuZXh0KTtcbiAgICAgIGlmIChwcm9iZVRpbWVvdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHlpZWxkKiBSZWYuc2V0KHByb2JlVW5hbnN3ZXJlZCwgdHJ1ZSk7XG4gICAgICBjb25zdCBwcm9iZSA9IHlpZWxkKiBFZmZlY3QuZm9ya0NoaWxkKGxlYXNlLnNlc3Npb24ucHJvYmUpO1xuICAgICAgbGV0IGRlYWRsaW5lID0gKHlpZWxkKiBDbG9jay5tb25vdG9uaWNUaW1lTmFub3MpICsgRHVyYXRpb24udG9OYW5vc1Vuc2FmZShwcm9iZVRpbWVvdXQpO1xuICAgICAgZm9yICg7Oykge1xuICAgICAgICBjb25zdCByZW1haW5pbmcgPSBkZWFkbGluZSAtICh5aWVsZCogQ2xvY2subW9ub3RvbmljVGltZU5hbm9zKTtcbiAgICAgICAgY29uc3QgcHJvYmVFdmVudCA9IHlpZWxkKiBFZmZlY3QucmFjZUFsbEZpcnN0KFtcbiAgICAgICAgICBGaWJlci5hd2FpdChwcm9iZSkucGlwZShcbiAgICAgICAgICAgIEVmZmVjdC5tYXAoKGV4aXQpID0+ICh7IF90YWc6IFwiUHJvYmVDb21wbGV0ZWRcIiBhcyBjb25zdCwgZXhpdCB9KSksXG4gICAgICAgICAgKSxcbiAgICAgICAgICB0YWtlU2lnbmFsLnBpcGUoRWZmZWN0Lm1hcCgoc2lnbmFsKSA9PiAoeyBfdGFnOiBcIlNpZ25hbFwiIGFzIGNvbnN0LCBzaWduYWwgfSkpKSxcbiAgICAgICAgICBFZmZlY3Quc2xlZXAoRHVyYXRpb24ubmFub3MocmVtYWluaW5nID4gMG4gPyByZW1haW5pbmcgOiAwbikpLnBpcGUoXG4gICAgICAgICAgICBFZmZlY3QuYXMoeyBfdGFnOiBcIlRpbWVkT3V0XCIgYXMgY29uc3QgfSksXG4gICAgICAgICAgKSxcbiAgICAgICAgXSk7XG4gICAgICAgIGlmIChwcm9iZUV2ZW50Ll90YWcgPT09IFwiVGltZWRPdXRcIikge1xuICAgICAgICAgIHlpZWxkKiBGaWJlci5pbnRlcnJ1cHQocHJvYmUpO1xuICAgICAgICAgIHJldHVybiB5aWVsZCogbmV3IENvbm5lY3Rpb25UcmFuc2llbnRFcnJvcih7XG4gICAgICAgICAgICByZWFzb246IFwidGltZW91dFwiLFxuICAgICAgICAgICAgZGV0YWlsOiBgJHt0YXJnZXQubGFiZWx9IGRpZCBub3QgcmVzcG9uZCB0byBhIGNvbm5lY3Rpb24gaGVhbHRoIGNoZWNrLmAsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb2JlRXZlbnQuX3RhZyA9PT0gXCJQcm9iZUNvbXBsZXRlZFwiKSB7XG4gICAgICAgICAgaWYgKEV4aXQuaXNTdWNjZXNzKHByb2JlRXZlbnQuZXhpdCkpIHtcbiAgICAgICAgICAgIHlpZWxkKiBSZWYuc2V0KHByb2JlVW5hbnN3ZXJlZCwgZmFsc2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB5aWVsZCogcHJvYmVFdmVudC5leGl0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGVuZER1cmluZ1Byb2JlID0geWllbGQqIGNvbm5lY3RlZExlYXNlRW5kKHByb2JlRXZlbnQuc2lnbmFsLCBsZWFzZSk7XG4gICAgICAgIGlmIChlbmREdXJpbmdQcm9iZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgeWllbGQqIEZpYmVyLmludGVycnVwdChwcm9iZSk7XG4gICAgICAgICAgcmV0dXJuIGVuZER1cmluZ1Byb2JlID09PSBcInJlc2V0XCI7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2lnbmFsVGltZW91dCA9IHByb2JlVGltZW91dEZvcihwcm9iZUV2ZW50LnNpZ25hbCk7XG4gICAgICAgIGlmIChzaWduYWxUaW1lb3V0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBjb25zdCBzaWduYWxEZWFkbGluZSA9XG4gICAgICAgICAgICAoeWllbGQqIENsb2NrLm1vbm90b25pY1RpbWVOYW5vcykgKyBEdXJhdGlvbi50b05hbm9zVW5zYWZlKHNpZ25hbFRpbWVvdXQpO1xuICAgICAgICAgIGlmIChzaWduYWxEZWFkbGluZSA8IGRlYWRsaW5lKSBkZWFkbGluZSA9IHNpZ25hbERlYWRsaW5lO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBjb25zdCBydW5BdHRlbXB0ID0gRWZmZWN0LmZuVW50cmFjZWQoZnVuY3Rpb24qIChcbiAgICBhdHRlbXB0OiBudW1iZXIsXG4gICAgZ2VuZXJhdGlvbjogbnVtYmVyLFxuICAgIGxhc3RGYWlsdXJlOiBDb25uZWN0aW9uQXR0ZW1wdEVycm9yIHwgbnVsbCxcbiAgICBwZW5kaW5nUmV0cnk6IE9wdGlvbi5PcHRpb248UGVuZGluZ1JldHJ5VHJhY2U+LFxuICAgIGlnbm9yZU9mZmxpbmU6IGJvb2xlYW4sXG4gICkge1xuICAgIGNvbnN0IHN3aXRjaGluZ1RvID0geWllbGQqIFJlZi5nZXQocHJlZmVycmVkUm91dGVJZCk7XG4gICAgeWllbGQqIFN1YnNjcmlwdGlvblJlZi5zZXQocHJlcGFyZWQsIE9wdGlvbi5ub25lKCkpO1xuICAgIGNvbnN0IHN5bmNocm9uaXplZFJvdXRlcyA9IHlpZWxkKiBSZWYubWFrZSgwKTtcbiAgICBjb25zdCBlc3RhYmxpc2htZW50ID0geWllbGQqIEVmZmVjdC5yYWNlQWxsRmlyc3QoW1xuICAgICAgZXhpdFVubGVzc0ludGVycnVwdGVkKFxuICAgICAgICBlc3RhYmxpc2hUcmFjZWRDb25uZWN0aW9uKFxuICAgICAgICAgIGF0dGVtcHQsXG4gICAgICAgICAgZ2VuZXJhdGlvbixcbiAgICAgICAgICBsYXN0RmFpbHVyZSxcbiAgICAgICAgICBwZW5kaW5nUmV0cnksXG4gICAgICAgICAgc3luY2hyb25pemVkUm91dGVzLFxuICAgICAgICApLFxuICAgICAgKS5waXBlKFxuICAgICAgICBFZmZlY3QubWFwKChleGl0KTogRXN0YWJsaXNobWVudEV2ZW50ID0+ICh7XG4gICAgICAgICAgX3RhZzogXCJDb21wbGV0ZWRcIixcbiAgICAgICAgICBleGl0LFxuICAgICAgICB9KSksXG4gICAgICApLFxuICAgICAgd2FpdEZvckVzdGFibGlzaG1lbnRJbnRlcnJ1cHQoKS5waXBlKFxuICAgICAgICBFZmZlY3QubWFwKChyZXNldFJldHJ5KTogRXN0YWJsaXNobWVudEV2ZW50ID0+ICh7XG4gICAgICAgICAgX3RhZzogXCJJbnRlcnJ1cHRlZFwiLFxuICAgICAgICAgIHJlc2V0UmV0cnksXG4gICAgICAgIH0pKSxcbiAgICAgICksXG4gICAgICAvLyBFYWNoIHJvdXRlIG1heSB1c2UgdGhlIGZ1bGwgc2V0dXAgdGltZSBiZWZvcmUgdGhlIG5leHQgaXMgdHJpZWQsIGFuZFxuICAgICAgLy8gZWFjaCByb3V0ZSB0aGF0IHJlYWNoZXMgc3luY2hyb25pemluZyBhZGRzIGl0cyBvd24gc25hcHNob3QgYnVkZ2V0LCBzb1xuICAgICAgLy8gYSByb3V0ZSB0aGF0IGZhaWxzIGxhdGUgZG9lcyBub3QgZWF0IHRoZSBuZXh0IHJvdXRlJ3MgdGltZS5cbiAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3Qgcm91dGVDb3VudCA9IGNvbm5lY3Rpb25Sb3V0ZXMoeWllbGQqIFJlZi5nZXQoY3VycmVudEVudHJ5KSkubGVuZ3RoO1xuICAgICAgICBjb25zdCBzdGFydGVkQXQgPSB5aWVsZCogQ2xvY2subW9ub3RvbmljVGltZU5hbm9zO1xuICAgICAgICBjb25zdCBzZXR1cCA9IER1cmF0aW9uLnRvTmFub3NVbnNhZmUoRHVyYXRpb24udGltZXMoZXN0YWJsaXNobWVudFRpbWVvdXQsIHJvdXRlQ291bnQpKTtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICBjb25zdCBzeW5jaHJvbml6ZWQgPSBCaWdJbnQoeWllbGQqIFJlZi5nZXQoc3luY2hyb25pemVkUm91dGVzKSk7XG4gICAgICAgICAgY29uc3QgZGVhZGxpbmUgPVxuICAgICAgICAgICAgc3RhcnRlZEF0ICsgc2V0dXAgKyBzeW5jaHJvbml6ZWQgKiBEdXJhdGlvbi50b05hbm9zVW5zYWZlKHN5bmNocm9uaXphdGlvblRpbWVvdXQpO1xuICAgICAgICAgIGNvbnN0IHJlbWFpbmluZyA9IGRlYWRsaW5lIC0gKHlpZWxkKiBDbG9jay5tb25vdG9uaWNUaW1lTmFub3MpO1xuICAgICAgICAgIGlmIChyZW1haW5pbmcgPD0gMG4pIHtcbiAgICAgICAgICAgIHJldHVybiB7IF90YWc6IFwiVGltZWRPdXRcIiB9IGFzIGNvbnN0IHNhdGlzZmllcyBFc3RhYmxpc2htZW50RXZlbnQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIHlpZWxkKiBFZmZlY3Quc2xlZXAoRHVyYXRpb24ubmFub3MocmVtYWluaW5nKSk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgIF0pO1xuXG4gICAgaWYgKGVzdGFibGlzaG1lbnQuX3RhZyA9PT0gXCJJbnRlcnJ1cHRlZFwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBfdGFnOiBcIkludGVycnVwdGVkXCIsXG4gICAgICAgIGVzdGFibGlzaGVkOiBmYWxzZSxcbiAgICAgICAgc3RhYmxlOiBmYWxzZSxcbiAgICAgICAgcmVzZXRSZXRyeTogZXN0YWJsaXNobWVudC5yZXNldFJldHJ5LFxuICAgICAgfSBzYXRpc2ZpZXMgQXR0ZW1wdE91dGNvbWU7XG4gICAgfVxuICAgIGlmIChlc3RhYmxpc2htZW50Ll90YWcgPT09IFwiVGltZWRPdXRcIikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgX3RhZzogXCJGYWlsdXJlXCIsXG4gICAgICAgIGVzdGFibGlzaGVkOiBmYWxzZSxcbiAgICAgICAgc3RhYmxlOiBmYWxzZSxcbiAgICAgICAgZmFpbHVyZToge1xuICAgICAgICAgIGVycm9yOiBuZXcgQ29ubmVjdGlvblRyYW5zaWVudEVycm9yKHtcbiAgICAgICAgICAgIHJlYXNvbjogXCJ0aW1lb3V0XCIsXG4gICAgICAgICAgICBkZXRhaWw6IHNldHVwVGltZW91dERldGFpbCxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBhdHRlbXB0U3BhbjogT3B0aW9uLm5vbmUoKSxcbiAgICAgICAgfSxcbiAgICAgIH0gc2F0aXNmaWVzIEF0dGVtcHRPdXRjb21lO1xuICAgIH1cbiAgICBpZiAoRXhpdC5pc0ZhaWx1cmUoZXN0YWJsaXNobWVudC5leGl0KSkge1xuICAgICAgY29uc3QgaXNVbmV4cGVjdGVkRGVmZWN0ID1cbiAgICAgICAgIUNhdXNlLmhhc0ludGVycnVwdHNPbmx5KGVzdGFibGlzaG1lbnQuZXhpdC5jYXVzZSkgJiZcbiAgICAgICAgIWVzdGFibGlzaG1lbnQuZXhpdC5jYXVzZS5yZWFzb25zLnNvbWUoQ2F1c2UuaXNGYWlsUmVhc29uKTtcbiAgICAgIGNvbnN0IG91dGNvbWUgPSBmYWlsdXJlRnJvbUV4aXQodGFyZ2V0LCBlc3RhYmxpc2htZW50LmV4aXQsIGZhbHNlLCBmYWxzZSk7XG4gICAgICBpZiAoaXNVbmV4cGVjdGVkRGVmZWN0KSB7XG4gICAgICAgIGNvbnN0IGRlZmVjdCA9IGVzdGFibGlzaG1lbnQuZXhpdC5jYXVzZS5yZWFzb25zLmZpbmQoQ2F1c2UuaXNEaWVSZWFzb24pPy5kZWZlY3Q7XG4gICAgICAgIHlpZWxkKiBFZmZlY3QubG9nRXJyb3IoXCJDb25uZWN0aW9uIGF0dGVtcHQgZmFpbGVkIHdpdGggYW4gdW5leHBlY3RlZCBkZWZlY3QuXCIpLnBpcGUoXG4gICAgICAgICAgRWZmZWN0LmFubm90YXRlTG9ncyh7XG4gICAgICAgICAgICBcImVudmlyb25tZW50LmlkXCI6IHRhcmdldC5lbnZpcm9ubWVudElkLFxuICAgICAgICAgICAgXCJlbnZpcm9ubWVudC5sYWJlbFwiOiB0YXJnZXQubGFiZWwsXG4gICAgICAgICAgICBcImNhdXNlLnJlYXNvbl9jb3VudFwiOiBlc3RhYmxpc2htZW50LmV4aXQuY2F1c2UucmVhc29ucy5sZW5ndGgsXG4gICAgICAgICAgICAuLi5zYWZlRXJyb3JMb2dBdHRyaWJ1dGVzKGRlZmVjdCksXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gb3V0Y29tZTtcbiAgICB9XG5cbiAgICBjb25zdCBhY3RpdmUgPSBlc3RhYmxpc2htZW50LmV4aXQudmFsdWU7XG4gICAgaWYgKE9wdGlvbi5pc1NvbWUoc3dpdGNoaW5nVG8pKSB7XG4gICAgICBjb25zdCBsYW5kZWQgPSBjb25uZWN0aW9uUm91dGVJZChhY3RpdmUubGVhc2UucHJlcGFyZWQudGFyZ2V0KTtcbiAgICAgIGlmIChsYW5kZWQgIT09IHN3aXRjaGluZ1RvLnZhbHVlKSB7XG4gICAgICAgIGNvbnN0IHVudGlsID1cbiAgICAgICAgICAoeWllbGQqIENsb2NrLm1vbm90b25pY1RpbWVOYW5vcykgKyBCaWdJbnQoQkVUVEVSX1JPVVRFX0NPT0xET1dOX01TKSAqIDFfMDAwXzAwMG47XG4gICAgICAgIHlpZWxkKiBSZWYudXBkYXRlKHJvdXRlQ29vbGRvd25zLCAoY3VycmVudCkgPT5cbiAgICAgICAgICBuZXcgTWFwKGN1cnJlbnQpLnNldChzd2l0Y2hpbmdUby52YWx1ZSwgdW50aWwpLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBjdXJyZW50SW50ZW50ID0geWllbGQqIFJlZi5nZXQoaW50ZW50KTtcbiAgICBpZiAoIWN1cnJlbnRJbnRlbnQuZGVzaXJlZCB8fCAoY3VycmVudEludGVudC5uZXR3b3JrID09PSBcIm9mZmxpbmVcIiAmJiAhaWdub3JlT2ZmbGluZSkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF90YWc6IFwiSW50ZXJydXB0ZWRcIixcbiAgICAgICAgZXN0YWJsaXNoZWQ6IGZhbHNlLFxuICAgICAgICBzdGFibGU6IGZhbHNlLFxuICAgICAgICByZXNldFJldHJ5OiBmYWxzZSxcbiAgICAgIH0gc2F0aXNmaWVzIEF0dGVtcHRPdXRjb21lO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbm5lY3RlZEF0ID0geWllbGQqIENsb2NrLmN1cnJlbnRUaW1lTWlsbGlzO1xuICAgIHlpZWxkKiBTdWJzY3JpcHRpb25SZWYuc2V0KHByZXBhcmVkLCBPcHRpb24uc29tZShhY3RpdmUubGVhc2UucHJlcGFyZWQpKTtcbiAgICB5aWVsZCogU3Vic2NyaXB0aW9uUmVmLnNldChzZXNzaW9uLCBPcHRpb24uc29tZShhY3RpdmUubGVhc2Uuc2Vzc2lvbikpO1xuICAgIGlmIChvcHRpb25zPy5sZWFyblJvdXRlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB5aWVsZCogbGVhcm5Sb3V0ZXNGcm9tKG9wdGlvbnMubGVhcm5Sb3V0ZXMsIGFjdGl2ZS5sZWFzZSkucGlwZShFZmZlY3QuZm9ya1Njb3BlZCk7XG4gICAgfVxuICAgIHlpZWxkKiBzZXRTdGF0ZSh7XG4gICAgICBkZXNpcmVkOiB0cnVlLFxuICAgICAgbmV0d29yazogY3VycmVudEludGVudC5uZXR3b3JrLFxuICAgICAgcGhhc2U6IFwiY29ubmVjdGVkXCIsXG4gICAgICBzdGFnZTogbnVsbCxcbiAgICAgIGF0dGVtcHQsXG4gICAgICBnZW5lcmF0aW9uLFxuICAgICAgbGFzdEZhaWx1cmU6IG51bGwsXG4gICAgICByZXRyeUF0OiBudWxsLFxuICAgIH0pO1xuXG4gICAgY29uc3QgY29ubmVjdGVkRXhpdCA9IHlpZWxkKiBFZmZlY3QucmFjZUZpcnN0KFxuICAgICAgYWN0aXZlLmxlYXNlLnNlc3Npb24uY2xvc2VkLnBpcGUoXG4gICAgICAgIEVmZmVjdC5tYXBFcnJvcigoZXJyb3IpOiBUcmFjZWRBdHRlbXB0RmFpbHVyZSA9PiAoe1xuICAgICAgICAgIGVycm9yLFxuICAgICAgICAgIGF0dGVtcHRTcGFuOiBhY3RpdmUuYXR0ZW1wdFNwYW4sXG4gICAgICAgIH0pKSxcbiAgICAgICksXG4gICAgICBtb25pdG9yQ29ubmVjdGVkTGVhc2UoYWN0aXZlLmxlYXNlKS5waXBlKFxuICAgICAgICBFZmZlY3QubWFwRXJyb3IoKGVycm9yKTogVHJhY2VkQXR0ZW1wdEZhaWx1cmUgPT4gKHtcbiAgICAgICAgICBlcnJvcixcbiAgICAgICAgICBhdHRlbXB0U3BhbjogYWN0aXZlLmF0dGVtcHRTcGFuLFxuICAgICAgICB9KSksXG4gICAgICApLFxuICAgICkucGlwZShleGl0VW5sZXNzSW50ZXJydXB0ZWQpO1xuICAgIGNvbnN0IGNvbm5lY3RlZEZvck1zID0gKHlpZWxkKiBDbG9jay5jdXJyZW50VGltZU1pbGxpcykgLSBjb25uZWN0ZWRBdDtcbiAgICBpZiAoRXhpdC5pc1N1Y2Nlc3MoY29ubmVjdGVkRXhpdCkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF90YWc6IFwiSW50ZXJydXB0ZWRcIixcbiAgICAgICAgZXN0YWJsaXNoZWQ6IHRydWUsXG4gICAgICAgIHN0YWJsZTogY29ubmVjdGVkRm9yTXMgPj0gQkFDS09GRl9SRVNFVF9BRlRFUl9NUyxcbiAgICAgICAgcmVzZXRSZXRyeTogY29ubmVjdGVkRXhpdC52YWx1ZSxcbiAgICAgIH0gc2F0aXNmaWVzIEF0dGVtcHRPdXRjb21lO1xuICAgIH1cbiAgICBjb25zdCBvdXRjb21lID0gZmFpbHVyZUZyb21FeGl0KFxuICAgICAgdGFyZ2V0LFxuICAgICAgY29ubmVjdGVkRXhpdCxcbiAgICAgIHRydWUsXG4gICAgICBjb25uZWN0ZWRGb3JNcyA+PSBCQUNLT0ZGX1JFU0VUX0FGVEVSX01TLFxuICAgICk7XG4gICAgaWYgKG91dGNvbWUuX3RhZyA9PT0gXCJGYWlsdXJlXCIpIHtcbiAgICAgIHlpZWxkKiBFZmZlY3Qudm9pZC5waXBlKFxuICAgICAgICBFZmZlY3Qud2l0aFNwYW4oXCJFbnZpcm9ubWVudFN1cGVydmlzb3IuY29ubmVjdGlvbkxvc3RcIiwge1xuICAgICAgICAgIHJvb3Q6IHRydWUsXG4gICAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgICAgXCJlbnZpcm9ubWVudC5pZFwiOiB0YXJnZXQuZW52aXJvbm1lbnRJZCxcbiAgICAgICAgICAgIFwiZW52aXJvbm1lbnQubGFiZWxcIjogdGFyZ2V0LmxhYmVsLFxuICAgICAgICAgICAgXCJlbnZpcm9ubWVudC50YXJnZXQua2luZFwiOiB0YXJnZXQuX3RhZyxcbiAgICAgICAgICAgIFwiY29ubmVjdGlvbi5jb25uZWN0ZWRfbXNcIjogY29ubmVjdGVkRm9yTXMsXG4gICAgICAgICAgICBcImNvbm5lY3Rpb24uZmFpbHVyZS5yZWFzb25cIjogb3V0Y29tZS5mYWlsdXJlLmVycm9yLnJlYXNvbixcbiAgICAgICAgICAgIFwiY29ubmVjdGlvbi5mYWlsdXJlLmRldGFpbFwiOiBvdXRjb21lLmZhaWx1cmUuZXJyb3IuZGV0YWlsLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIG91dGNvbWU7XG4gIH0sIEVmZmVjdC5lbnN1cmluZyhjbGVhckxlYXNlKSk7XG5cbiAgY29uc3Qgd2FpdEZvclJldHJ5U2lnbmFsID0gRWZmZWN0LmZuVW50cmFjZWQoZnVuY3Rpb24qIChkZWxheU1zOiBudW1iZXIpIHtcbiAgICAvLyBAZWZmZWN0LWRpYWdub3N0aWNzLW5leHQtbGluZSByYWNlRmlyc3RXaXRoU2xlZXBUb1RpbWVvdXQ6b2ZmIC0gdGhlIHNsZWVwIGlzIHRoZSByZXRyeSBkZWxheSAoZmFsc2UpLCBub3QgYSB0aW1lb3V0IGFyb3VuZCB0aGUgc2lnbmFsIGxvb3BcbiAgICByZXR1cm4geWllbGQqIEVmZmVjdC5yYWNlRmlyc3QoXG4gICAgICBFZmZlY3Quc2xlZXAoZGVsYXlNcykucGlwZShFZmZlY3QuYXMoZmFsc2UpKSxcbiAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgIGNvbnN0IG5leHQgPSB5aWVsZCogUXVldWUudGFrZShzaWduYWxzKTtcbiAgICAgICAgICBzd2l0Y2ggKG5leHQuX3RhZykge1xuICAgICAgICAgICAgY2FzZSBcIldha2V1cFwiOlxuICAgICAgICAgICAgICByZXR1cm4gQ29ubmVjdGlvbldha2V1cHMucmVzZXRzUmV0cnlCYWNrb2ZmKG5leHQucmVhc29uKTtcbiAgICAgICAgICAgIGNhc2UgXCJDb25uZWN0UmVxdWVzdGVkXCI6XG4gICAgICAgICAgICBjYXNlIFwiRGlzY29ubmVjdFJlcXVlc3RlZFwiOlxuICAgICAgICAgICAgY2FzZSBcIlJldHJ5UmVxdWVzdGVkXCI6XG4gICAgICAgICAgICBjYXNlIFwiTmV0d29ya0NoYW5nZWRcIjpcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgY2FzZSBcIkJldHRlclJvdXRlQXZhaWxhYmxlXCI6XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgKTtcbiAgfSk7XG5cbiAgY29uc3Qgd2FpdEZvclNpZ25hbCA9IFF1ZXVlLnRha2Uoc2lnbmFscykucGlwZShcbiAgICBFZmZlY3QucmVwZWF0KHsgd2hpbGU6IChuZXh0KSA9PiBuZXh0Ll90YWcgPT09IFwiQmV0dGVyUm91dGVBdmFpbGFibGVcIiB9KSxcbiAgICBFZmZlY3QubWFwKFxuICAgICAgKG5leHQpID0+IG5leHQuX3RhZyA9PT0gXCJXYWtldXBcIiAmJiBDb25uZWN0aW9uV2FrZXVwcy5yZXNldHNSZXRyeUJhY2tvZmYobmV4dC5yZWFzb24pLFxuICAgICksXG4gICk7XG5cbiAgY29uc3QgcnVuID0gRWZmZWN0LmZuVW50cmFjZWQoZnVuY3Rpb24qICgpIHtcbiAgICBsZXQgZmFpbHVyZUNvdW50ID0gMDtcbiAgICBsZXQgZ2VuZXJhdGlvbiA9IDA7XG4gICAgbGV0IGxhdGVzdEZhaWx1cmU6IENvbm5lY3Rpb25BdHRlbXB0RXJyb3IgfCBudWxsID0gbnVsbDtcbiAgICBsZXQgcGVuZGluZ1JldHJ5ID0gT3B0aW9uLm5vbmU8UGVuZGluZ1JldHJ5VHJhY2U+KCk7XG4gICAgY29uc3QgcmVzZXRSZXRyeUxhZGRlciA9ICgpID0+IHtcbiAgICAgIGZhaWx1cmVDb3VudCA9IDA7XG4gICAgICBwZW5kaW5nUmV0cnkgPSBPcHRpb24ubm9uZSgpO1xuICAgIH07XG4gICAgbGV0IHJlcGxhY2luZyA9IGZhbHNlO1xuXG4gICAgZm9yICg7Oykge1xuICAgICAgaWYgKHlpZWxkKiBSZWYuZ2V0QW5kU2V0KHJlc2V0UmV0cnlTdGF0ZSwgZmFsc2UpKSB7XG4gICAgICAgIGZhaWx1cmVDb3VudCA9IDA7XG4gICAgICAgIGxhdGVzdEZhaWx1cmUgPSBudWxsO1xuICAgICAgICBwZW5kaW5nUmV0cnkgPSBPcHRpb24ubm9uZSgpO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEludGVudCA9IHlpZWxkKiBSZWYuZ2V0KGludGVudCk7XG4gICAgICBpZiAoIWN1cnJlbnRJbnRlbnQuZGVzaXJlZCkge1xuICAgICAgICByZXNldFJldHJ5TGFkZGVyKCk7XG4gICAgICAgIGxhdGVzdEZhaWx1cmUgPSBudWxsO1xuICAgICAgICB5aWVsZCogY2xlYXJMZWFzZTtcbiAgICAgICAgeWllbGQqIHNldFN0YXRlKGF2YWlsYWJsZVN0YXRlKGN1cnJlbnRJbnRlbnQsIGdlbmVyYXRpb24pKTtcbiAgICAgICAgeWllbGQqIHdhaXRGb3JTaWduYWw7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKGN1cnJlbnRJbnRlbnQubmV0d29yayA9PT0gXCJvZmZsaW5lXCIgJiYgIXJlcGxhY2luZykge1xuICAgICAgICB5aWVsZCogY2xlYXJMZWFzZTtcbiAgICAgICAgeWllbGQqIHNldFN0YXRlKG9mZmxpbmVTdGF0ZShjdXJyZW50SW50ZW50LCBnZW5lcmF0aW9uLCBmYWlsdXJlQ291bnQgKyAxLCBsYXRlc3RGYWlsdXJlKSk7XG4gICAgICAgIGNvbnN0IGFwcGxpY2F0aW9uQWN0aXZhdGVkID0geWllbGQqIHdhaXRGb3JTaWduYWw7XG4gICAgICAgIGlmIChhcHBsaWNhdGlvbkFjdGl2YXRlZCkge1xuICAgICAgICAgIHJlc2V0UmV0cnlMYWRkZXIoKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYXR0ZW1wdCA9IGZhaWx1cmVDb3VudCArIDE7XG4gICAgICBjb25zdCBuZXh0R2VuZXJhdGlvbiA9IGdlbmVyYXRpb24gKyAxO1xuICAgICAgY29uc3Qgb3V0Y29tZTogQXR0ZW1wdE91dGNvbWUgPSB5aWVsZCogRWZmZWN0LnNjb3BlZChcbiAgICAgICAgcnVuQXR0ZW1wdChhdHRlbXB0LCBuZXh0R2VuZXJhdGlvbiwgbGF0ZXN0RmFpbHVyZSwgcGVuZGluZ1JldHJ5LCByZXBsYWNpbmcpLFxuICAgICAgKTtcbiAgICAgIHJlcGxhY2luZyA9IGZhbHNlO1xuICAgICAgY29uc3QgZmFpbGVkUHJvYmUgPSB5aWVsZCogUmVmLmdldEFuZFNldChwcm9iZVVuYW5zd2VyZWQsIGZhbHNlKTtcbiAgICAgIGlmIChvdXRjb21lLmVzdGFibGlzaGVkKSB7XG4gICAgICAgIGdlbmVyYXRpb24gPSBuZXh0R2VuZXJhdGlvbjtcbiAgICAgICAgLy8gQSBzZXNzaW9uIGNhbWUgdXAsIHNvIG5vIGVhcmxpZXIgZmFpbHVyZSBkZXNjcmliZXMgdGhlIGNvbm5lY3Rpb24uXG4gICAgICAgIC8vIExvc2luZyBhIGxpdmUgc2Vzc2lvbiBpcyBub3QgYSBmYWlsZWQgY29ubmVjdGlvbiBlaXRoZXIsIGZvciBleGFtcGxlXG4gICAgICAgIC8vIGEgc29ja2V0IHRoZSBPUyBraWxsZWQgd2hpbGUgdGhlIGFwcCB3YXMgc3VzcGVuZGVkOiBpdHMgcmVwbGFjZW1lbnRcbiAgICAgICAgLy8gcmVwb3J0cyBubyBmYWlsdXJlIHVudGlsIGl0IGZhaWxzIGl0c2VsZi5cbiAgICAgICAgbGF0ZXN0RmFpbHVyZSA9IG51bGw7XG4gICAgICAgIGlmIChvdXRjb21lLnN0YWJsZSkge1xuICAgICAgICAgIHJlc2V0UmV0cnlMYWRkZXIoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG91dGNvbWUuX3RhZyA9PT0gXCJJbnRlcnJ1cHRlZFwiKSB7XG4gICAgICAgIGlmIChvdXRjb21lLnJlc2V0UmV0cnkpIHtcbiAgICAgICAgICByZXNldFJldHJ5TGFkZGVyKCk7XG4gICAgICAgICAgcmVwbGFjaW5nID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYXR0ZW1wdFNwYW46IE9wdGlvbi5PcHRpb248VHJhY2VyLlNwYW4+ID0gb3V0Y29tZS5mYWlsdXJlLmF0dGVtcHRTcGFuO1xuICAgICAgY29uc3QgZXJyb3I6IENvbm5lY3Rpb25BdHRlbXB0RXJyb3IgPSBvdXRjb21lLmZhaWx1cmUuZXJyb3I7XG4gICAgICBpZiAoIW91dGNvbWUuZXN0YWJsaXNoZWQpIHtcbiAgICAgICAgbGF0ZXN0RmFpbHVyZSA9IGVycm9yO1xuICAgICAgfVxuICAgICAgaWYgKGVycm9yLl90YWcgPT09IFwiQ29ubmVjdGlvbkJsb2NrZWRFcnJvclwiKSB7XG4gICAgICAgIGNvbnN0IGJsb2NrZWRJbnRlbnQgPSB5aWVsZCogUmVmLmdldChpbnRlbnQpO1xuICAgICAgICB5aWVsZCogc2V0U3RhdGUoe1xuICAgICAgICAgIGRlc2lyZWQ6IGJsb2NrZWRJbnRlbnQuZGVzaXJlZCxcbiAgICAgICAgICBuZXR3b3JrOiBibG9ja2VkSW50ZW50Lm5ldHdvcmssXG4gICAgICAgICAgcGhhc2U6IFwiYmxvY2tlZFwiLFxuICAgICAgICAgIHN0YWdlOiBudWxsLFxuICAgICAgICAgIGF0dGVtcHQsXG4gICAgICAgICAgZ2VuZXJhdGlvbixcbiAgICAgICAgICBsYXN0RmFpbHVyZTogZXJyb3IsXG4gICAgICAgICAgcmV0cnlBdDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGFwcGxpY2F0aW9uQWN0aXZhdGVkID0geWllbGQqIHdhaXRGb3JTaWduYWw7XG4gICAgICAgIGlmIChhcHBsaWNhdGlvbkFjdGl2YXRlZCkge1xuICAgICAgICAgIHJlc2V0UmV0cnlMYWRkZXIoKTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGZhaWxlZFByb2JlKSB7XG4gICAgICAgIHJlc2V0UmV0cnlMYWRkZXIoKTtcbiAgICAgICAgeWllbGQqIHNldFN0YXRlKGNvbm5lY3RpbmdTdGF0ZSh5aWVsZCogUmVmLmdldChpbnRlbnQpLCBnZW5lcmF0aW9uLCAxLCBsYXRlc3RGYWlsdXJlKSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBmYWlsdXJlQ291bnQgKz0gMTtcbiAgICAgIGNvbnN0IGRlbGF5TXMgPSByZXRyeURlbGF5TXMoZmFpbHVyZUNvdW50IC0gMSwgeWllbGQqIFJhbmRvbS5uZXh0KTtcbiAgICAgIHBlbmRpbmdSZXRyeSA9IE9wdGlvbi5tYXAoYXR0ZW1wdFNwYW4sIChwcmV2aW91c0F0dGVtcHQpID0+ICh7XG4gICAgICAgIHByZXZpb3VzQXR0ZW1wdCxcbiAgICAgICAgZmFpbHVyZUNvdW50LFxuICAgICAgICBkZWxheU1zLFxuICAgICAgICByZWFzb246IGVycm9yLnJlYXNvbixcbiAgICAgIH0pKTtcbiAgICAgIGNvbnN0IGZhaWxlZEludGVudCA9IHlpZWxkKiBSZWYuZ2V0KGludGVudCk7XG4gICAgICB5aWVsZCogc2V0U3RhdGUoe1xuICAgICAgICBkZXNpcmVkOiBmYWlsZWRJbnRlbnQuZGVzaXJlZCxcbiAgICAgICAgbmV0d29yazogZmFpbGVkSW50ZW50Lm5ldHdvcmssXG4gICAgICAgIHBoYXNlOiBcImJhY2tvZmZcIixcbiAgICAgICAgc3RhZ2U6IG51bGwsXG4gICAgICAgIGF0dGVtcHQsXG4gICAgICAgIGdlbmVyYXRpb24sXG4gICAgICAgIGxhc3RGYWlsdXJlOiBsYXRlc3RGYWlsdXJlLFxuICAgICAgICByZXRyeUF0OiAoeWllbGQqIENsb2NrLmN1cnJlbnRUaW1lTWlsbGlzKSArIGRlbGF5TXMsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGFwcGxpY2F0aW9uQWN0aXZhdGVkID0geWllbGQqIHdhaXRGb3JSZXRyeVNpZ25hbChkZWxheU1zKTtcbiAgICAgIGlmIChhcHBsaWNhdGlvbkFjdGl2YXRlZCkge1xuICAgICAgICByZXNldFJldHJ5TGFkZGVyKCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICB5aWVsZCogY29ubmVjdGl2aXR5LmNoYW5nZXMucGlwZShcbiAgICBTdHJlYW0ucnVuRm9yRWFjaCgobmV0d29yaykgPT5cbiAgICAgIFJlZi5tb2RpZnkoaW50ZW50LCAoY3VycmVudCkgPT5cbiAgICAgICAgY3VycmVudC5uZXR3b3JrID09PSBuZXR3b3JrID8gW2ZhbHNlLCBjdXJyZW50XSA6IChbdHJ1ZSwgeyAuLi5jdXJyZW50LCBuZXR3b3JrIH1dIGFzIGNvbnN0KSxcbiAgICAgICkucGlwZShcbiAgICAgICAgRWZmZWN0LmZsYXRNYXAoKGNoYW5nZWQpID0+XG4gICAgICAgICAgY2hhbmdlZCA/IHNpZ25hbCh7IF90YWc6IFwiTmV0d29ya0NoYW5nZWRcIiwgbmV0d29yayB9KSA6IEVmZmVjdC52b2lkLFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICApLFxuICAgIEVmZmVjdC5mb3JrU2NvcGVkLFxuICApO1xuICB5aWVsZCogd2FrZXVwcy5jaGFuZ2VzLnBpcGUoXG4gICAgU3RyZWFtLnJ1bkZvckVhY2goKHJlYXNvbikgPT4gc2lnbmFsKHsgX3RhZzogXCJXYWtldXBcIiwgcmVhc29uIH0pKSxcbiAgICBFZmZlY3QuZm9ya1Njb3BlZCxcbiAgKTtcbiAgeWllbGQqIFF1ZXVlLnRha2UoYmV0dGVyUm91dGVDaGVja3MpLnBpcGUoXG4gICAgRWZmZWN0LmZsYXRNYXAoY2hlY2tCZXR0ZXJSb3V0ZXMpLFxuICAgIEVmZmVjdC5mb3JldmVyLFxuICAgIEVmZmVjdC5mb3JrU2NvcGVkLFxuICApO1xuICB5aWVsZCogcnVuKCkucGlwZShFZmZlY3QuZm9ya1Njb3BlZCk7XG5cbiAgY29uc3QgY29ubmVjdCA9IFJlZi51cGRhdGUoaW50ZW50LCAoY3VycmVudCkgPT4gKHtcbiAgICAuLi5jdXJyZW50LFxuICAgIGRlc2lyZWQ6IHRydWUsXG4gIH0pKS5waXBlKFxuICAgIEVmZmVjdC5hbmRUaGVuKHNpZ25hbCh7IF90YWc6IFwiQ29ubmVjdFJlcXVlc3RlZFwiIH0pKSxcbiAgICBFZmZlY3Qud2l0aFNwYW4oXCJFbnZpcm9ubWVudFN1cGVydmlzb3IuY29ubmVjdFwiKSxcbiAgKTtcblxuICBjb25zdCBkaXNjb25uZWN0ID0gUmVmLnVwZGF0ZShpbnRlbnQsIChjdXJyZW50KSA9PiAoe1xuICAgIC4uLmN1cnJlbnQsXG4gICAgZGVzaXJlZDogZmFsc2UsXG4gIH0pKS5waXBlKFxuICAgIEVmZmVjdC5hbmRUaGVuKHNpZ25hbCh7IF90YWc6IFwiRGlzY29ubmVjdFJlcXVlc3RlZFwiIH0pKSxcbiAgICBFZmZlY3Qud2l0aFNwYW4oXCJFbnZpcm9ubWVudFN1cGVydmlzb3IuZGlzY29ubmVjdFwiKSxcbiAgKTtcblxuICBjb25zdCByZXRyeU5vdyA9IFJlZi5zZXQocmVzZXRSZXRyeVN0YXRlLCB0cnVlKS5waXBlKFxuICAgIEVmZmVjdC5hbmRUaGVuKHNpZ25hbCh7IF90YWc6IFwiUmV0cnlSZXF1ZXN0ZWRcIiB9KSksXG4gICAgRWZmZWN0LndpdGhTcGFuKFwiRW52aXJvbm1lbnRTdXBlcnZpc29yLnJldHJ5Tm93XCIpLFxuICApO1xuXG4gIHlpZWxkKiBFZmZlY3QuYWRkRmluYWxpemVyKCgpID0+IFF1ZXVlLnNodXRkb3duKHNpZ25hbHMpLnBpcGUoRWZmZWN0LmFuZFRoZW4oY2xlYXJMZWFzZSkpKTtcblxuICByZXR1cm4gRW52aXJvbm1lbnRTdXBlcnZpc29yLm9mKHtcbiAgICB0YXJnZXQsXG4gICAgc3RhdGUsXG4gICAgc2Vzc2lvbixcbiAgICBwcmVwYXJlZCxcbiAgICBjb25uZWN0LFxuICAgIGRpc2Nvbm5lY3QsXG4gICAgcmV0cnlOb3csXG4gIH0pO1xufSk7XG4iXSwiZmlsZSI6Ii9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvY2xpZW50LXJ1bnRpbWUvc3JjL2Nvbm5lY3Rpb24vc3VwZXJ2aXNvci50cyJ9

//# vitestCache=W3siZmlsZSI6IjEiLCJpZCI6IjEiLCJ1cmwiOiIyIiwiaW1wb3J0cyI6IjMiLCJtYXBwaW5ncyI6ZmFsc2UsImRlcHMiOiI0IiwiZHluYW1pY0RlcHMiOiI1Iiwic3RhdGljTW9ja3MiOm51bGx9LCIvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvY2xpZW50LXJ1bnRpbWUvc3JjL2Nvbm5lY3Rpb24vc3VwZXJ2aXNvci50cyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvY2xpZW50LXJ1bnRpbWUvc3JjL2Nvbm5lY3Rpb24vc3VwZXJ2aXNvci50cyIseyJ1cmxzIjoiNiIsImlkcyI6IjcifSxbIjgiLCI5IiwiMTAiLCIxMSIsIjEyIiwiMTMiLCIxNCIsIjE1IiwiMTYiLCIxNyIsIjE4IiwiMTkiLCIyMCIsIjIxIiwiMjIiLCIyMyIsIjI0IiwiMjUiLCIyNiIsIjI3IiwiMjgiLCIyOSIsIjMwIiwiMzEiXSxbXSxbIjgiLCI5IiwiMTAiLCIxMSIsIjEyIiwiMTMiLCIxNCIsIjE1IiwiMTYiLCIxNyIsIjE4IiwiMTkiLCIyMCIsIjIxIiwiMjIiLCIyMyIsIjI0IiwiMjUiLCIyNiIsIjI3IiwiMjgiLCIyOSIsIjMwIiwiMzEiXSx7fSwiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9wYWNrYWdlcy9zaGFyZWQvc3JjL3JlbGF5VHJhY2luZy50cyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvbm9kZV9tb2R1bGVzLy5wbnBtL2VmZmVjdEA0LjAuNS9ub2RlX21vZHVsZXMvZWZmZWN0L2Rpc3QvQ2F1c2UuanMiLCIvQGZzL2hvbWUvdWJ1bnR1L3d0L3ByLTI0MjYzL25vZGVfbW9kdWxlcy8ucG5wbS9lZmZlY3RANC4wLjUvbm9kZV9tb2R1bGVzL2VmZmVjdC9kaXN0L0Nsb2NrLmpzIiwiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9ub2RlX21vZHVsZXMvLnBucG0vZWZmZWN0QDQuMC41L25vZGVfbW9kdWxlcy9lZmZlY3QvZGlzdC9Db250ZXh0LmpzIiwiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9ub2RlX21vZHVsZXMvLnBucG0vZWZmZWN0QDQuMC41L25vZGVfbW9kdWxlcy9lZmZlY3QvZGlzdC9EdXJhdGlvbi5qcyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvbm9kZV9tb2R1bGVzLy5wbnBtL2VmZmVjdEA0LjAuNS9ub2RlX21vZHVsZXMvZWZmZWN0L2Rpc3QvRWZmZWN0LmpzIiwiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9ub2RlX21vZHVsZXMvLnBucG0vZWZmZWN0QDQuMC41L25vZGVfbW9kdWxlcy9lZmZlY3QvZGlzdC9FeGl0LmpzIiwiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9ub2RlX21vZHVsZXMvLnBucG0vZWZmZWN0QDQuMC41L25vZGVfbW9kdWxlcy9lZmZlY3QvZGlzdC9GaWJlci5qcyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvbm9kZV9tb2R1bGVzLy5wbnBtL2VmZmVjdEA0LjAuNS9ub2RlX21vZHVsZXMvZWZmZWN0L2Rpc3QvT3B0aW9uLmpzIiwiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9ub2RlX21vZHVsZXMvLnBucG0vZWZmZWN0QDQuMC41L25vZGVfbW9kdWxlcy9lZmZlY3QvZGlzdC9RdWV1ZS5qcyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvbm9kZV9tb2R1bGVzLy5wbnBtL2VmZmVjdEA0LjAuNS9ub2RlX21vZHVsZXMvZWZmZWN0L2Rpc3QvUmFuZG9tLmpzIiwiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9ub2RlX21vZHVsZXMvLnBucG0vZWZmZWN0QDQuMC41L25vZGVfbW9kdWxlcy9lZmZlY3QvZGlzdC9SZWYuanMiLCIvQGZzL2hvbWUvdWJ1bnR1L3d0L3ByLTI0MjYzL25vZGVfbW9kdWxlcy8ucG5wbS9lZmZlY3RANC4wLjUvbm9kZV9tb2R1bGVzL2VmZmVjdC9kaXN0L1Njb3BlLmpzIiwiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9ub2RlX21vZHVsZXMvLnBucG0vZWZmZWN0QDQuMC41L25vZGVfbW9kdWxlcy9lZmZlY3QvZGlzdC9TdHJlYW0uanMiLCIvQGZzL2hvbWUvdWJ1bnR1L3d0L3ByLTI0MjYzL25vZGVfbW9kdWxlcy8ucG5wbS9lZmZlY3RANC4wLjUvbm9kZV9tb2R1bGVzL2VmZmVjdC9kaXN0L1N1YnNjcmlwdGlvblJlZi5qcyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvbm9kZV9tb2R1bGVzLy5wbnBtL2VmZmVjdEA0LjAuNS9ub2RlX21vZHVsZXMvZWZmZWN0L2Rpc3QvVHJhY2VyLmpzIiwiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9wYWNrYWdlcy9jbGllbnQtcnVudGltZS9zcmMvY29ubmVjdGlvbi9jb25uZWN0aXZpdHkudHMiLCIvQGZzL2hvbWUvdWJ1bnR1L3d0L3ByLTI0MjYzL3BhY2thZ2VzL2NsaWVudC1ydW50aW1lL3NyYy9jb25uZWN0aW9uL2RyaXZlci50cyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvY2xpZW50LXJ1bnRpbWUvc3JjL2Nvbm5lY3Rpb24vbW9kZWwudHMiLCIvQGZzL2hvbWUvdWJ1bnR1L3d0L3ByLTI0MjYzL3BhY2thZ2VzL2NsaWVudC1ydW50aW1lL3NyYy9ycGMvc2Vzc2lvbi50cyIsIi9AZnMvaG9tZS91YnVudHUvd3QvcHItMjQyNjMvcGFja2FnZXMvY2xpZW50LXJ1bnRpbWUvc3JjL2Vycm9ycy9zYWZlTG9nLnRzIiwiL0Bmcy9ob21lL3VidW50dS93dC9wci0yNDI2My9wYWNrYWdlcy9jbGllbnQtcnVudGltZS9zcmMvZXJyb3JzL25ldHdvcmsudHMiLCIvQGZzL2hvbWUvdWJ1bnR1L3d0L3ByLTI0MjYzL3BhY2thZ2VzL2NsaWVudC1ydW50aW1lL3NyYy9jb25uZWN0aW9uL3dha2V1cHMudHMiLCIvQGZzL2hvbWUvdWJ1bnR1L3d0L3ByLTI0MjYzL3BhY2thZ2VzL2NsaWVudC1ydW50aW1lL3NyYy9jb25uZWN0aW9uL3JvdXRlcy50cyJd