const require_chunk = require("./chunk-9hOWP6kD.cjs");
const require_FluidProvider = require("./FluidProvider-D2ZXrmtu.cjs");
const require_FluidThemeProvider = require("./FluidThemeProvider-DMfCMPLp.cjs");
const require_use_account = require("./use-account-C596ARpR.cjs");
const require_hook_types = require("./hook-types-B8cS7ta0.cjs");
const require_query_keys = require("./query-keys-p6qddudR.cjs");
const require_registries = require("./registries-DgzzKX8_.cjs");
const require_use_store = require("./use-store-Dl3HEHrF.cjs");
const require_AppNavigationContext = require("./AppNavigationContext-D1Xx1-jH.cjs");
const require_authoring = require("./authoring-HytiVeJw.cjs");
let react = require("react");
react = require_chunk.__toESM(react);
let _tanstack_react_query = require("@tanstack/react-query");
let react_jsx_runtime = require("react/jsx-runtime");
react_jsx_runtime = require_chunk.__toESM(react_jsx_runtime);
let react_dom = require("react-dom");
react_dom = require_chunk.__toESM(react_dom);
//#region src/hooks/use-fluid-app.ts
/**
* Base query key for full app data (rendered manifest endpoint).
* Kept for backwards compatibility — the runtime key used by the hook
* includes a company prefix via {@link useCompanyScopedQueryKey}.
*/
const APP_DATA_QUERY_KEY = ["fluid", "app"];
/**
* Fetch the raw rendered manifest via the portal-tenant BFF adapter.
* Shared by `useFluidApp` and `useFluidProfile` to avoid drift.
*/
async function fetchRawManifest(api) {
	return require_hook_types.toRawManifest(await api.fetchManifest());
}
/**
* Module-level persister instance (browser only).
* Created once when the module loads so all calls to useFluidApp share
* the same IndexedDB connection. Applied at the query level so it works
* regardless of which QueryClient the app provides.
*/
const appDataPersister = typeof window !== "undefined" && !{}.env?.DEV ? require_FluidProvider.createPersister() : void 0;
/**
* Hook to fetch the full portal app data from the rendered-manifest endpoint.
*
* Returns a `RepAppData` object containing:
* - `screens` — all screen definitions with normalized component trees
* - `profile.themes` — fully-transformed ThemeDefinition[] (handles legacy + new formats)
* - `profile.activeThemeId` — the currently active theme ID
* - `profile.navigation.navigation_items` — sorted, recursive navigation tree
*
* Uses IndexedDB persistence so subsequent page loads hydrate instantly
* from cache while revalidating in the background. The raw API response
* (plain JSON) is cached; Color objects are recreated from cache via
* `select` on every restore — this is fast (CPU only, no network).
*
* @example
* ```tsx
* function App() {
*   const { data: appData, isLoading } = useFluidApp();
*
*   if (isLoading) return <Spinner />;
*
*   return (
*     <AppShell
*       appData={appData}
*       navigation={appData.profile.navigation.navigation_items}
*     />
*   );
* }
* ```
*/
function useFluidApp(options) {
	const appDefinitionApi = require_FluidThemeProvider.useAppDefinitionApi();
	const { scopeKey } = require_hook_types.useCompanyScopedQueryKey();
	return (0, _tanstack_react_query.useQuery)({
		queryKey: scopeKey(APP_DATA_QUERY_KEY),
		queryFn: () => fetchRawManifest(appDefinitionApi),
		select: require_hook_types.transformManifestToRepAppData,
		...appDataPersister && { persister: appDataPersister.persisterFn },
		...options?.enabled !== void 0 && { enabled: options.enabled }
	});
}
//#endregion
//#region src/hooks/use-logout.ts
/**
* useLogout Hook
*
* Provides a complete logout function that:
* 1. Clears all client-side state (query cache, IndexedDB, sessionStorage)
* 2. Navigates to GET /logout — Rails clears the session and redirects to the Hub
*/
/**
* Hook that returns a `logout` function which clears the server session
* via `DELETE /logout` and all cached/persisted client state.
*
* @example
* ```tsx
* const logout = useLogout({ redirectUrl: "/login" });
* <button onClick={logout}>Log out</button>
* ```
*
* @example
* ```tsx
* const logout = useLogout({
*   onLogout: () => navigate("/signed-out"),
* });
* ```
*/
function useLogout({ redirectUrl, onLogout } = {}) {
	const queryClient = (0, _tanstack_react_query.useQueryClient)();
	return (0, react.useCallback)(async () => {
		await queryClient.cancelQueries();
		queryClient.clear();
		try {
			await require_FluidProvider.deleteDatabase();
		} catch (error) {
			console.error("[useLogout] Failed to clear IndexedDB cache:", error);
		}
		try {
			sessionStorage.clear();
		} catch {}
		if (redirectUrl) window.location.href = redirectUrl;
		else if (onLogout) onLogout();
		else window.location.href = "/logout";
	}, [
		queryClient,
		redirectUrl,
		onLogout
	]);
}
//#endregion
//#region src/config/env.ts
/**
* Read Vite environment variables at runtime.
*
* Isolated into its own module so that Jest tests can mock it
* (import.meta is a syntax-level construct that CJS/Jest cannot parse).
*/
function getViteEnv(key) {
	return {}.env?.[key];
}
//#endregion
//#region src/config/defaults.ts
/**
* Creates a FluidSDKConfig with sensible defaults.
*
* Default behavior:
* - baseUrl: reads from `VITE_API_URL` env var, falls back to `""` (same-origin relative)
* - Auth: relies on session cookies sent via `credentials: 'include'`
*
* Pass overrides to customize any field:
* ```ts
* const config = createDefaultFluidConfig({ baseUrl: "https://my-api.example.com" });
* ```
*/
function createDefaultFluidConfig(overrides) {
	return {
		baseUrl: getViteEnv("VITE_API_URL") ?? "",
		smartyEmbeddedKey: getViteEnv("NEXT_PUBLIC_SMARTY_EMBEDDED_KEY"),
		googleMapsApiKey: getViteEnv("NEXT_PUBLIC_GOOGLE_MAPS_API_KEY"),
		...overrides
	};
}
//#endregion
//#region ../../platform/widget-runtime/src/errors.ts
var WidgetRuntimeError = class extends Error {
	code;
	packageId;
	version;
	cause;
	constructor(details) {
		super(details.message);
		this.name = "WidgetRuntimeError";
		this.code = details.code;
		this.packageId = details.packageId;
		this.version = details.version;
		this.cause = details.cause;
	}
};
function toWidgetRuntimeError(error, fallback) {
	if (error instanceof WidgetRuntimeError) return error;
	return new WidgetRuntimeError({
		...fallback,
		cause: error
	});
}
//#endregion
//#region ../../platform/widget-runtime/src/fluid-widgets.ts
const globalMarker$1 = Symbol.for("fluid.widget-runtime.FluidWidgetsGlobal");
const cleanupRegistrationMarker = Symbol.for("fluid.widget-runtime.FluidWidgetsGlobal.cleanupRegistration");
function ensureFluidWidgetsGlobal() {
	const existing = window.FluidWidgets;
	if (isFluidWidgetsGlobal(existing)) return existing;
	const registrationsByPackageKey = /* @__PURE__ */ new Map();
	const subscribers = /* @__PURE__ */ new Set();
	const fluidWidgets = {
		[globalMarker$1]: true,
		[cleanupRegistrationMarker](registration, previousRegistration) {
			const registrationKey = createPackageRegistrationKey(registration.packageId, registration.version);
			if (registrationsByPackageKey.get(registrationKey) !== registration) return;
			if (previousRegistration === void 0) {
				registrationsByPackageKey.delete(registrationKey);
				return;
			}
			registrationsByPackageKey.set(registrationKey, previousRegistration);
		},
		registerPackage(registration) {
			const registrationKey = createPackageRegistrationKey(registration.packageId, registration.version);
			const previousRegistration = registrationsByPackageKey.get(registrationKey);
			registrationsByPackageKey.set(registrationKey, registration);
			notify({
				kind: "register",
				registration,
				previousRegistration
			});
		},
		getPackageRegistration(packageId, version) {
			return registrationsByPackageKey.get(createPackageRegistrationKey(packageId, version));
		},
		getRegisteredWidgets() {
			return Array.from(registrationsByPackageKey.values()).flatMap((registration) => registration.widgets.map((widget) => ({
				...widget,
				packageId: registration.packageId,
				version: registration.version
			})));
		},
		getRegistry() {
			const registry = /* @__PURE__ */ new Map();
			for (const registration of registrationsByPackageKey.values()) for (const widget of registration.widgets) {
				const globalWidget = {
					...widget,
					packageId: registration.packageId,
					version: registration.version
				};
				registry.set(createGlobalWidgetRegistryKey(registration.packageId, registration.version, widget.type), globalWidget);
			}
			return registry;
		},
		clear(packageId, version) {
			if (packageId === void 0) {
				registrationsByPackageKey.clear();
				notify({ kind: "clear" });
				return;
			}
			let cleared = false;
			for (const [key, registration] of registrationsByPackageKey) if (registration.packageId === packageId && (version === void 0 || registration.version === version)) {
				registrationsByPackageKey.delete(key);
				cleared = true;
			}
			if (cleared) notify({
				kind: "clear",
				packageId,
				version
			});
		},
		subscribe(listener) {
			subscribers.add(listener);
			return () => {
				subscribers.delete(listener);
			};
		}
	};
	window.FluidWidgets = fluidWidgets;
	return fluidWidgets;
	function notify(event) {
		for (const subscriber of Array.from(subscribers)) subscriber(event);
	}
}
function cleanupUnexpectedFluidWidgetsRegistration(registration, previousRegistration) {
	const fluidWidgets = window.FluidWidgets;
	if (!isFluidWidgetsGlobal(fluidWidgets)) return;
	fluidWidgets[cleanupRegistrationMarker](registration, previousRegistration);
}
function isFluidWidgetsGlobal(value) {
	return value !== void 0 && value[globalMarker$1] === true;
}
function createPackageRegistrationKey(packageId, version) {
	return JSON.stringify([packageId, version]);
}
function createGlobalWidgetRegistryKey(packageId, version, type) {
	return JSON.stringify([
		packageId,
		version,
		type
	]);
}
const DEFAULT_WIDGET_CONTAINER = "block";
const widgetPackageTypes$1 = new Set([
	"fluid",
	"company",
	"droplet",
	"partner",
	"internal"
]);
const widgetContainers$1 = new Set([
	"inline",
	"block",
	"card",
	"fullscreen"
]);
const widgetResizableValues$1 = new Set([
	"horizontal",
	"vertical",
	"both"
]);
function readNonEmptyString(value) {
	return typeof value === "string" && value.length > 0 ? value : void 0;
}
function hasControlCharacter(value) {
	for (let index = 0; index < value.length; index++) {
		const code = value.charCodeAt(index);
		if (code <= 31 || code >= 127 && code <= 159) return true;
	}
	return false;
}
function isWidgetPackageType(value) {
	return typeof value === "string" && widgetPackageTypes$1.has(value);
}
function normalizeWidgetPackageType(value) {
	return isWidgetPackageType(value) ? value : null;
}
function isWidgetRuntimeContainer(value) {
	return typeof value === "string" && widgetContainers$1.has(value);
}
function normalizeWidgetRuntimeContainer(value) {
	return isWidgetRuntimeContainer(value) ? value : DEFAULT_WIDGET_CONTAINER;
}
function isWidgetRuntimeResizableString(value) {
	return typeof value === "string" && widgetResizableValues$1.has(value);
}
function normalizeWidgetRuntimeResizable(value) {
	if (typeof value === "boolean") return value;
	if (isWidgetRuntimeResizableString(value)) return value;
	if (!isRecord$1(value)) return false;
	const horizontal = value.horizontal === true;
	const vertical = value.vertical === true;
	if (horizontal && vertical) return "both";
	if (horizontal) return "horizontal";
	if (vertical) return "vertical";
	return false;
}
function isRecord$1(value) {
	return typeof value === "object" && value !== null && !Array.isArray(value);
}
//#endregion
//#region ../../platform/widget-runtime/src/validation.ts
const widgetPackageTypes = new Set([
	"fluid",
	"company",
	"droplet",
	"partner",
	"internal"
]);
const widgetContainers = new Set([
	"inline",
	"block",
	"card",
	"fullscreen"
]);
const widgetResizableValues = new Set([
	"horizontal",
	"vertical",
	"both"
]);
function validateWidgetPackageDescriptor(descriptor) {
	if (!isObjectRecord(descriptor)) throwInvalidDescriptor("Widget package descriptor must be an object");
	if (descriptor.manifestVersion !== 1) throwInvalidDescriptor(`Unsupported widget package manifestVersion: ${String(descriptor.manifestVersion)}`, descriptor);
	assertNonEmptyString(descriptor.packageId, "packageId", descriptor);
	assertNonEmptyString(descriptor.version, "version", descriptor);
	assertNonEmptyString(descriptor.remoteEntryUrl, "remoteEntryUrl", descriptor);
	assertValidUrl(descriptor.remoteEntryUrl, "remoteEntryUrl", descriptor);
	if (!widgetPackageTypes.has(descriptor.packageType)) throwInvalidDescriptor(`Unsupported widget packageType: ${String(descriptor.packageType)}`, descriptor);
	if (!Array.isArray(descriptor.cssUrls)) throwInvalidDescriptor("Widget package cssUrls must be an array", descriptor);
	for (const cssUrl of descriptor.cssUrls) {
		if (typeof cssUrl !== "string" || cssUrl.length === 0) throwInvalidDescriptor("Widget package cssUrls must contain only non-empty strings", descriptor);
		assertValidUrl(cssUrl, "cssUrls[]", descriptor);
	}
	if (!Array.isArray(descriptor.widgets) || descriptor.widgets.length === 0) throwInvalidDescriptor("Widget package widgets must be a non-empty array", descriptor);
	const seenTypes = /* @__PURE__ */ new Set();
	for (const widget of descriptor.widgets) {
		validateWidgetDescriptor(widget, descriptor);
		if (seenTypes.has(widget.type)) throwInvalidDescriptor(`Widget package descriptor contains duplicate widget type: ${widget.type}`, descriptor);
		seenTypes.add(widget.type);
	}
}
function validateWidgetPackageRegistration(registration, descriptor) {
	if (!registration) throw new WidgetRuntimeError({
		code: "REGISTRATION_MISSING",
		message: `Remote widget package ${descriptor.packageId}@${descriptor.version} did not call window.FluidWidgets.registerPackage`,
		packageId: descriptor.packageId,
		version: descriptor.version
	});
	if (!isObjectRecord(registration)) throwInvalidRegistration("Widget package registration must be an object", descriptor);
	if (registration.packageId !== descriptor.packageId) throw new WidgetRuntimeError({
		code: "REGISTRATION_MISMATCH",
		message: `Remote widget package registered packageId ${String(registration.packageId)} but descriptor expected ${descriptor.packageId}`,
		packageId: descriptor.packageId,
		version: descriptor.version
	});
	if (registration.version !== descriptor.version) throw new WidgetRuntimeError({
		code: "REGISTRATION_MISMATCH",
		message: `Remote widget package ${descriptor.packageId} registered version ${String(registration.version)} but descriptor expected ${descriptor.version}`,
		packageId: descriptor.packageId,
		version: descriptor.version
	});
	if (!Array.isArray(registration.widgets)) throwInvalidRegistration("Widget package registration widgets must be an array", descriptor);
	const descriptorWidgetsByType = new Map(descriptor.widgets.map((widget) => [widget.type, widget]));
	const registeredTypes = /* @__PURE__ */ new Set();
	for (const widget of registration.widgets) {
		validateRuntimeWidgetRegistration(widget, descriptor, descriptorWidgetsByType);
		if (registeredTypes.has(widget.type)) throwInvalidRegistration(`Widget package registration contains duplicate widget type: ${widget.type}`, descriptor);
		registeredTypes.add(widget.type);
	}
	for (const descriptorWidget of descriptor.widgets) if (!registeredTypes.has(descriptorWidget.type)) throwInvalidRegistration(`Widget package registration is missing widget type: ${descriptorWidget.type}`, descriptor);
}
function validateWidgetDescriptor(widget, descriptor) {
	if (!isObjectRecord(widget)) throwInvalidDescriptor("Widget descriptor must be an object", descriptor);
	assertNonEmptyString(widget.type, "widgets[].type", descriptor);
	assertNonEmptyString(widget.name, "widgets[].name", descriptor);
	assertNonEmptyString(widget.displayName, "widgets[].displayName", descriptor);
	assertNonEmptyString(widget.description, "widgets[].description", descriptor);
	assertNonEmptyString(widget.icon, "widgets[].icon", descriptor);
	assertNonEmptyString(widget.category, "widgets[].category", descriptor);
	assertNonEmptyString(widget.minSdkVersion, "widgets[].minSdkVersion", descriptor);
	if (!isObjectRecord(widget.propertySchema)) throwInvalidDescriptor("Widget propertySchema must be an object", descriptor);
	validatePropertySchemaWidgetType(widget.propertySchema, widget.type, descriptor, "INVALID_DESCRIPTOR");
	if (!isObjectRecord(widget.defaultProps)) throwInvalidDescriptor("Widget defaultProps must be an object", descriptor);
	if (!widgetContainers.has(widget.container)) throwInvalidDescriptor(`Unsupported widget container: ${String(widget.container)}`, descriptor);
	validateResizable(widget.resizable, descriptor);
}
function validateRuntimeWidgetRegistration(widget, descriptor, descriptorWidgetsByType) {
	if (!isObjectRecord(widget)) throwInvalidRegistration("Registered widget must be an object", descriptor);
	assertNonEmptyString(widget.type, "registered widgets[].type", descriptor);
	const descriptorWidget = descriptorWidgetsByType.get(widget.type);
	if (!descriptorWidget) throwInvalidRegistration(`Widget package registration contains unknown widget type: ${widget.type}`, descriptor);
	if (!isWidgetComponent(widget.component)) throwInvalidRegistration(`Registered widget ${widget.type} must include a React component`, descriptor);
	if (!isObjectRecord(widget.propertySchema)) throwInvalidRegistration(`Registered widget ${widget.type} propertySchema must be an object`, descriptor);
	validatePropertySchemaWidgetType(widget.propertySchema, widget.type, descriptor, "INVALID_REGISTRATION");
	if (!isObjectRecord(widget.defaultProps)) throwInvalidRegistration(`Registered widget ${widget.type} defaultProps must be an object`, descriptor);
	validateOptionalRuntimeMetadataStrings(widget, descriptor);
	if (widget.container !== void 0 && !widgetContainers.has(widget.container)) throwInvalidRegistration(`Registered widget ${widget.type} has unsupported container: ${String(widget.container)}`, descriptor);
	if (widget.resizable !== void 0) validateResizable(widget.resizable, descriptor, "INVALID_REGISTRATION");
	validatePropertySchemaWidgetType(descriptorWidget.propertySchema, widget.type, descriptor, "INVALID_DESCRIPTOR");
}
function validateOptionalRuntimeMetadataStrings(widget, descriptor) {
	for (const field of [
		"name",
		"displayName",
		"description",
		"icon",
		"category",
		"minSdkVersion"
	]) {
		const value = widget[field];
		if (value === void 0) continue;
		if (typeof value !== "string" || value.length === 0) throwInvalidRegistration(`Registered widget ${widget.type} ${field} must be a non-empty string when present`, descriptor);
	}
}
function validatePropertySchemaWidgetType(propertySchema, widgetType, descriptor, code) {
	if (propertySchema.widgetType !== void 0 && propertySchema.widgetType !== widgetType) throwValidationError(code, `Widget type ${widgetType} must match propertySchema.widgetType ${propertySchema.widgetType}`, descriptor);
}
function validateResizable(resizable, descriptor, code = "INVALID_DESCRIPTOR") {
	if (!(typeof resizable === "boolean" || typeof resizable === "string" && widgetResizableValues.has(resizable))) throwValidationError(code, `Unsupported widget resizable value: ${String(resizable)}`, descriptor);
}
function throwValidationError(code, message, descriptor) {
	if (code === "INVALID_REGISTRATION") throwInvalidRegistration(message, descriptor);
	throwInvalidDescriptor(message, descriptor);
}
function assertNonEmptyString(value, field, descriptor) {
	if (typeof value !== "string" || value.length === 0) throwInvalidDescriptor(`Widget package ${field} must be a non-empty string`, descriptor);
}
function assertValidUrl(url, field, descriptor) {
	if (url.trim() !== url || containsUnsafeUrlCharacter(url) || hasAmbiguousHttpScheme$1(url)) throwInvalidDescriptor(`Widget package ${field} contains invalid URL: ${url}`, descriptor);
	if (/^[a-zA-Z][a-zA-Z\d+.-]*:/.exec(url)) {
		let parsedUrl;
		try {
			parsedUrl = new URL(url);
		} catch {
			throwInvalidDescriptor(`Widget package ${field} contains invalid URL: ${url}`, descriptor);
		}
		if (parsedUrl.protocol !== "https:" && !isTrustedLocalHttpUrl(parsedUrl, url)) throwInvalidDescriptor(`Widget package ${field} must be an https absolute URL, a trusted local http URL, or a relative URL: ${url}`, descriptor);
		return;
	}
	if (url.slice(0, 2) === "//") throwInvalidDescriptor(`Widget package ${field} must be an https absolute URL, a trusted local http URL, or a relative URL: ${url}`, descriptor);
	try {
		new URL(url, getValidationBaseUrl());
	} catch {
		throwInvalidDescriptor(`Widget package ${field} contains invalid URL: ${url}`, descriptor);
	}
}
function isTrustedLocalHttpUrl(url, rawUrl) {
	if (url.protocol !== "http:") return false;
	const hostname = extractRawHostname(rawUrl).toLowerCase();
	return hostname === "localhost" || hostname === "[::1]" || hostname === "::1" || isLoopbackIpv4Hostname(hostname);
}
function extractRawHostname(rawUrl) {
	const authorityStart = rawUrl.indexOf("://") + 3;
	const authorityEnd = findAuthorityEnd(rawUrl, authorityStart);
	const authority = rawUrl.slice(authorityStart, authorityEnd);
	const hostAndPort = authority.slice(authority.lastIndexOf("@") + 1);
	if (hostAndPort.charAt(0) === "[") {
		const bracketEnd = hostAndPort.indexOf("]");
		return bracketEnd === -1 ? hostAndPort : hostAndPort.slice(0, bracketEnd + 1);
	}
	const portStart = hostAndPort.indexOf(":");
	return portStart === -1 ? hostAndPort : hostAndPort.slice(0, portStart);
}
function findAuthorityEnd(rawUrl, authorityStart) {
	let authorityEnd = rawUrl.length;
	for (const delimiter of [
		"/",
		"?",
		"#"
	]) {
		const delimiterIndex = rawUrl.indexOf(delimiter, authorityStart);
		if (delimiterIndex !== -1 && delimiterIndex < authorityEnd) authorityEnd = delimiterIndex;
	}
	return authorityEnd;
}
function isLoopbackIpv4Hostname(hostname) {
	const octets = hostname.split(".");
	if (octets.length !== 4 || octets[0] !== "127") return false;
	return octets.every(isBoundedIpv4Octet);
}
function isBoundedIpv4Octet(octet) {
	if (!/^\d{1,3}$/.test(octet)) return false;
	if (octet.length > 1 && octet.charAt(0) === "0") return false;
	const value = Number(octet);
	return value >= 0 && value <= 255;
}
function containsUnsafeUrlCharacter(url) {
	return hasControlCharacter(url) || url.includes("\\");
}
function hasAmbiguousHttpScheme$1(url) {
	return /^https?:(?!\/\/)/i.test(url);
}
function getValidationBaseUrl() {
	if (typeof window === "undefined") return "http://localhost";
	return window.location.href;
}
function throwInvalidDescriptor(message, descriptor) {
	throw new WidgetRuntimeError({
		code: "INVALID_DESCRIPTOR",
		message,
		packageId: descriptor?.packageId,
		version: descriptor?.version
	});
}
function throwInvalidRegistration(message, descriptor) {
	throw new WidgetRuntimeError({
		code: "INVALID_REGISTRATION",
		message,
		packageId: descriptor.packageId,
		version: descriptor.version
	});
}
function isObjectRecord(value) {
	return typeof value === "object" && value !== null && !Array.isArray(value);
}
function isWidgetComponent(value) {
	if (typeof value === "function") return true;
	return isObjectRecord(value) && typeof value["$$typeof"] === "symbol";
}
//#endregion
//#region ../../platform/widget-runtime/src/loader.ts
const defaultTimeoutMs = 15e3;
/**
* Shared remote script queue for the page.
*
* Classic remote scripts register through the shared `window.FluidWidgets`
* callback, so the loader intentionally appends only one remote entry script at
* a time across all loader instances. Each queued load waits for the previous
* load to settle, even when the previous load fails, which keeps registration
* attribution deterministic and prevents overlapping classic-script remotes
* from racing their global registrations.
*/
let remoteScriptLoadQueue;
const pendingRemoteRegistrationsByPackageKey = /* @__PURE__ */ new Map();
const observedRegistrationsByPendingLoad = /* @__PURE__ */ new WeakMap();
function createWidgetRuntimeLoader(options = {}) {
	const timeoutMs = options.timeoutMs ?? defaultTimeoutMs;
	const ignorePreRegisteredPackages = options.ignorePreRegisteredPackages === true;
	const fluidWidgets = ensureFluidWidgetsGlobal();
	const packagesByKey = /* @__PURE__ */ new Map();
	const pendingPackagesByKey = /* @__PURE__ */ new Map();
	const packageGenerationsByKey = /* @__PURE__ */ new Map();
	const cssByKey = /* @__PURE__ */ new Map();
	const widgetsByKey = /* @__PURE__ */ new Map();
	let isApplyingLocalGlobalClear = false;
	fluidWidgets.subscribe((event) => {
		if (isApplyingLocalGlobalClear || event.kind !== "clear") return;
		if (event.packageId === void 0) {
			invalidateCacheKeys(new Set([...packagesByKey.keys(), ...pendingPackagesByKey.keys()]));
			return;
		}
		invalidateCacheKeys(collectMatchingCacheKeys(event.packageId, event.version));
	});
	async function loadPackage(descriptor) {
		try {
			validateWidgetPackageDescriptor(descriptor);
			const cacheKey = createPackageCacheKey(descriptor.packageId, descriptor.version);
			const cachedPackage = packagesByKey.get(cacheKey);
			if (cachedPackage) return createSuccess(cachedPackage);
			const pendingPackage = pendingPackagesByKey.get(cacheKey);
			if (pendingPackage) return await pendingPackage.promise;
			const globalRegistration = fluidWidgets.getPackageRegistration(descriptor.packageId, descriptor.version);
			if (globalRegistration && !ignorePreRegisteredPackages) return createSuccess(cachePreRegisteredPackage(descriptor, cacheKey, createCssLoadRef(cacheKey, getPackageGeneration(cacheKey)), globalRegistration));
			const generation = getPackageGeneration(cacheKey);
			const pendingLoad = {
				cacheKey,
				cssLoadRef: createCssLoadRef(cacheKey, generation),
				generation,
				packageId: descriptor.packageId,
				remoteEntryUrlKey: normalizeAssetUrl(descriptor.remoteEntryUrl, descriptor),
				version: descriptor.version,
				getCurrentGeneration: () => getPackageGeneration(cacheKey)
			};
			addPendingRemoteRegistration(pendingLoad);
			const promise = loadPackageUncached(descriptor, pendingLoad);
			const pendingPackageEntry = {
				load: pendingLoad,
				promise
			};
			promise.then(() => {
				removePendingRemoteRegistration(pendingLoad);
				if (pendingPackagesByKey.get(cacheKey) === pendingPackageEntry) pendingPackagesByKey.delete(cacheKey);
			}, () => {
				removePendingRemoteRegistration(pendingLoad);
				if (pendingPackagesByKey.get(cacheKey) === pendingPackageEntry) pendingPackagesByKey.delete(cacheKey);
			});
			pendingPackagesByKey.set(cacheKey, pendingPackageEntry);
			return await pendingPackageEntry.promise;
		} catch (error) {
			const descriptorIdentity = getDescriptorIdentity(descriptor);
			const runtimeError = toWidgetRuntimeError(error, {
				code: "SCRIPT_LOAD_FAILED",
				message: "Failed to load widget package",
				packageId: descriptorIdentity.packageId,
				version: descriptorIdentity.version
			});
			if (options.throwOnError === true) throw runtimeError;
			return {
				ok: false,
				packageId: descriptorIdentity.packageId ?? "",
				version: descriptorIdentity.version ?? "",
				error: runtimeError
			};
		}
	}
	async function loadPackageUncached(descriptor, pendingLoad) {
		let scriptElement;
		try {
			installCssUrls(descriptor, pendingLoad.cssLoadRef);
			const scriptLoadResult = await loadRemoteEntryScript(descriptor, timeoutMs, options.cacheBust, () => {
				throwIfStalePackageLoad(pendingLoad);
			}, () => isFreshPackageLoad(pendingLoad), pendingLoad, ignorePreRegisteredPackages);
			scriptElement = scriptLoadResult.scriptElement;
			throwIfStalePackageLoad(pendingLoad);
			const registration = ignorePreRegisteredPackages ? scriptLoadResult.registration : fluidWidgets.getPackageRegistration(descriptor.packageId, descriptor.version) ?? scriptLoadResult.registration;
			const cached = cachePackageRegistrationWithRemoteCleanup(descriptor, pendingLoad.cacheKey, pendingLoad.cssLoadRef, registration, scriptLoadResult, scriptElement);
			throwIfStalePackageLoad(pendingLoad);
			return createSuccess(cached);
		} catch (error) {
			scriptElement?.remove();
			removeCssForLoad(pendingLoad.cssLoadRef);
			throw error;
		}
	}
	async function loadPackages(descriptors) {
		return await Promise.all(descriptors.map(loadPackage));
	}
	function getRegisteredWidgets() {
		return Array.from(widgetsByKey.values());
	}
	function getRegistry() {
		return new Map(widgetsByKey);
	}
	function cachePreRegisteredPackage(descriptor, cacheKey, cssLoadRef, registration) {
		try {
			installCssUrls(descriptor, cssLoadRef);
			return cachePackageRegistration(descriptor, cacheKey, cssLoadRef, registration);
		} catch (error) {
			removeCssForLoad(cssLoadRef);
			throw error;
		}
	}
	function cachePackageRegistrationWithRemoteCleanup(descriptor, cacheKey, cssLoadRef, registration, scriptLoadResult, scriptElement) {
		try {
			return cachePackageRegistration(descriptor, cacheKey, cssLoadRef, registration, scriptElement);
		} catch (error) {
			if (scriptLoadResult.registration !== void 0 && registration === scriptLoadResult.registration) cleanupUnexpectedFluidWidgetsRegistration(scriptLoadResult.registration, scriptLoadResult.previousRegistration);
			throw error;
		}
	}
	function cachePackageRegistration(descriptor, cacheKey, cssLoadRef, registration, scriptElement) {
		validateWidgetPackageRegistration(registration, descriptor);
		const widgets = mergeRegisteredWidgets(descriptor, registration);
		const cached = {
			cacheKey,
			cssLoadRef,
			packageId: descriptor.packageId,
			version: descriptor.version,
			scriptElement,
			widgets
		};
		packagesByKey.set(cacheKey, cached);
		for (const widget of widgets) widgetsByKey.set(createWidgetRegistryKey(widget.packageId, widget.version, widget.type), widget);
		return cached;
	}
	function invalidatePackage(packageId, version) {
		isApplyingLocalGlobalClear = true;
		try {
			fluidWidgets.clear(packageId, version);
		} finally {
			isApplyingLocalGlobalClear = false;
		}
		invalidateCacheKeys(collectMatchingCacheKeys(packageId, version));
	}
	function clear() {
		isApplyingLocalGlobalClear = true;
		try {
			fluidWidgets.clear();
		} finally {
			isApplyingLocalGlobalClear = false;
		}
		invalidateCacheKeys(new Set([...packagesByKey.keys(), ...pendingPackagesByKey.keys()]));
	}
	function collectMatchingCacheKeys(packageId, version) {
		const cacheKeys = /* @__PURE__ */ new Set();
		for (const cachedPackage of packagesByKey.values()) if (matchesPackage(cachedPackage, packageId, version)) cacheKeys.add(cachedPackage.cacheKey);
		for (const pendingPackage of pendingPackagesByKey.values()) if (matchesPackage(pendingPackage.load, packageId, version)) cacheKeys.add(pendingPackage.load.cacheKey);
		return cacheKeys;
	}
	function invalidateCacheKeys(cacheKeys) {
		for (const cacheKey of cacheKeys) invalidatePackageCacheKey(cacheKey);
	}
	function installCssUrls(descriptor, cssLoadRef) {
		const normalizedCssUrls = descriptor.cssUrls.map((cssUrl) => ({ key: normalizeAssetUrl(cssUrl, descriptor) }));
		const keys = [];
		for (const { key } of normalizedCssUrls) {
			const existing = cssByKey.get(key);
			if (existing) {
				existing.packageRefs.add(cssLoadRef);
				keys.push(key);
				continue;
			}
			const linkElement = document.createElement("link");
			linkElement.rel = "stylesheet";
			linkElement.href = key;
			linkElement.dataset.fluidWidgetRuntimeCss = "true";
			linkElement.dataset.fluidWidgetRuntimeCssKey = key;
			document.head.appendChild(linkElement);
			cssByKey.set(key, {
				key,
				element: linkElement,
				packageRefs: new Set([cssLoadRef])
			});
			keys.push(key);
		}
		return keys;
	}
	function invalidatePackageCacheKey(cacheKey) {
		bumpPackageGeneration(cacheKey);
		const pendingPackage = pendingPackagesByKey.get(cacheKey);
		if (pendingPackage) {
			removeCssForLoad(pendingPackage.load.cssLoadRef);
			pendingPackagesByKey.delete(cacheKey);
		}
		removePackage(cacheKey);
	}
	function removePackage(cacheKey) {
		const cachedPackage = packagesByKey.get(cacheKey);
		if (!cachedPackage) return;
		cachedPackage.scriptElement?.remove();
		for (const widget of cachedPackage.widgets) widgetsByKey.delete(createWidgetRegistryKey(widget.packageId, widget.version, widget.type));
		removeCssForLoad(cachedPackage.cssLoadRef);
		packagesByKey.delete(cacheKey);
	}
	function removeCssForLoad(cssLoadRef) {
		for (const entry of Array.from(cssByKey.values())) {
			entry.packageRefs.delete(cssLoadRef);
			if (entry.packageRefs.size === 0) {
				entry.element.remove();
				cssByKey.delete(entry.key);
			}
		}
	}
	function getPackageGeneration(cacheKey) {
		return packageGenerationsByKey.get(cacheKey) ?? 0;
	}
	function bumpPackageGeneration(cacheKey) {
		packageGenerationsByKey.set(cacheKey, getPackageGeneration(cacheKey) + 1);
	}
	function isFreshPackageLoad(pendingLoad) {
		return getPackageGeneration(pendingLoad.cacheKey) === pendingLoad.generation;
	}
	function throwIfStalePackageLoad(pendingLoad) {
		if (isFreshPackageLoad(pendingLoad)) return;
		throw new WidgetRuntimeError({
			code: "SCRIPT_LOAD_FAILED",
			message: `Widget package load ${pendingLoad.packageId}@${pendingLoad.version} was invalidated before it completed`,
			packageId: pendingLoad.packageId,
			version: pendingLoad.version
		});
	}
	function matchesPackage(cachedPackage, packageId, version) {
		if (cachedPackage.packageId !== packageId) return false;
		return version === void 0 || cachedPackage.version === version;
	}
	return {
		loadPackage,
		loadPackages,
		getRegisteredWidgets,
		getRegistry,
		invalidatePackage,
		clear
	};
}
function mergeRegisteredWidgets(descriptor, registration) {
	const registrationWidgetsByType = new Map(registration.widgets.map((widget) => [widget.type, widget]));
	return descriptor.widgets.map((descriptorWidget) => {
		const registeredWidget = registrationWidgetsByType.get(descriptorWidget.type);
		if (!registeredWidget) throw new WidgetRuntimeError({
			code: "INVALID_REGISTRATION",
			message: `Widget package registration is missing widget type: ${descriptorWidget.type}`,
			packageId: descriptor.packageId,
			version: descriptor.version
		});
		return {
			...descriptorWidget,
			...pickRuntimeMetadataOverrides(registeredWidget),
			packageId: descriptor.packageId,
			packageType: descriptor.packageType,
			version: descriptor.version,
			propertySchema: registeredWidget.propertySchema,
			defaultProps: registeredWidget.defaultProps,
			component: registeredWidget.component
		};
	});
}
function pickRuntimeMetadataOverrides(widget) {
	return {
		...widget.name !== void 0 ? { name: widget.name } : {},
		...widget.displayName !== void 0 ? { displayName: widget.displayName } : {},
		...widget.description !== void 0 ? { description: widget.description } : {},
		...widget.icon !== void 0 ? { icon: widget.icon } : {},
		...widget.category !== void 0 ? { category: widget.category } : {},
		...widget.container !== void 0 ? { container: widget.container } : {},
		...widget.minSdkVersion !== void 0 ? { minSdkVersion: widget.minSdkVersion } : {},
		...widget.resizable !== void 0 ? { resizable: widget.resizable } : {}
	};
}
function loadRemoteEntryScript(descriptor, timeoutMs, cacheBust, assertFreshPackageLoad, isFreshPackageLoad, pendingLoad, ignorePreRegisteredPackages) {
	return enqueueRemoteEntryScriptLoad(async () => {
		assertFreshPackageLoad();
		const registration = ensureFluidWidgetsGlobal().getPackageRegistration(descriptor.packageId, descriptor.version);
		const observedRegistration = observedRegistrationsByPendingLoad.get(pendingLoad);
		if (registration && observedRegistration?.registration === registration) return observedRegistration;
		if (registration && !ignorePreRegisteredPackages) return {
			previousRegistration: void 0,
			registration
		};
		return await loadRemoteEntryScriptImmediately(descriptor, timeoutMs, cacheBust, isFreshPackageLoad, pendingLoad);
	});
}
async function loadRemoteEntryScriptImmediately(descriptor, timeoutMs, cacheBust, isFreshPackageLoad, pendingLoad) {
	const fluidWidgets = ensureFluidWidgetsGlobal();
	let previousRegistration;
	let registration;
	const unsubscribe = fluidWidgets.subscribe((event) => {
		if (event.kind !== "register") return;
		if (event.registration.packageId === descriptor.packageId && event.registration.version === descriptor.version) {
			if (isFreshPackageLoad()) {
				previousRegistration = event.previousRegistration;
				registration = event.registration;
				observeRegistrationForPendingLoad(pendingLoad, event);
				return;
			}
			if (observeFreshPendingRegistrationForScript(event, pendingLoad)) return;
			cleanupUnexpectedFluidWidgetsRegistration(event.registration, event.previousRegistration);
			return;
		}
		const pendingSharedRemoteLoads = getPendingRemoteRegistrationsForScript(event.registration, pendingLoad.remoteEntryUrlKey);
		if (pendingSharedRemoteLoads.length === 0) return;
		const freshSharedRemoteLoads = pendingSharedRemoteLoads.filter(isFreshPendingPackageLoad);
		if (freshSharedRemoteLoads.length > 0) {
			for (const freshPendingLoad of freshSharedRemoteLoads) observeRegistrationForPendingLoad(freshPendingLoad, event);
			return;
		}
		cleanupUnexpectedFluidWidgetsRegistration(event.registration, event.previousRegistration);
	});
	const scriptElement = document.createElement("script");
	let timeoutId;
	try {
		await new Promise((resolve, reject) => {
			timeoutId = window.setTimeout(() => {
				reject(new WidgetRuntimeError({
					code: "SCRIPT_TIMEOUT",
					message: `Timed out loading widget package ${descriptor.packageId}@${descriptor.version}`,
					packageId: descriptor.packageId,
					version: descriptor.version
				}));
			}, timeoutMs);
			scriptElement.async = true;
			scriptElement.src = withCacheBust(descriptor.remoteEntryUrl, cacheBust);
			scriptElement.dataset.fluidWidgetRuntimeScript = "true";
			scriptElement.dataset.fluidWidgetRuntimePackageId = descriptor.packageId;
			scriptElement.dataset.fluidWidgetRuntimeVersion = descriptor.version;
			scriptElement.addEventListener("load", () => {
				resolve();
			}, { once: true });
			scriptElement.addEventListener("error", () => {
				reject(new WidgetRuntimeError({
					code: "SCRIPT_LOAD_FAILED",
					message: `Failed to load widget package script ${descriptor.remoteEntryUrl}`,
					packageId: descriptor.packageId,
					version: descriptor.version
				}));
			}, { once: true });
			document.head.appendChild(scriptElement);
		});
	} catch (error) {
		scriptElement.remove();
		throw error;
	} finally {
		unsubscribe();
		if (timeoutId !== void 0) window.clearTimeout(timeoutId);
	}
	return {
		previousRegistration,
		registration,
		scriptElement
	};
}
function getDescriptorIdentity(descriptor) {
	if (typeof descriptor !== "object" || descriptor === null) return {};
	return {
		packageId: typeof descriptor.packageId === "string" ? descriptor.packageId : void 0,
		version: typeof descriptor.version === "string" ? descriptor.version : void 0
	};
}
function createSuccess(cachedPackage) {
	return {
		ok: true,
		packageId: cachedPackage.packageId,
		version: cachedPackage.version,
		widgets: cachedPackage.widgets
	};
}
function createPackageCacheKey(packageId, version) {
	return JSON.stringify([packageId, version]);
}
function createCssLoadRef(cacheKey, generation) {
	return JSON.stringify([cacheKey, generation]);
}
function createWidgetRegistryKey(packageId, version, type) {
	return JSON.stringify([
		packageId,
		version,
		type
	]);
}
function addPendingRemoteRegistration(pendingLoad) {
	const packageKey = createPackageCacheKey(pendingLoad.packageId, pendingLoad.version);
	const pendingLoads = pendingRemoteRegistrationsByPackageKey.get(packageKey);
	if (pendingLoads) {
		pendingLoads.add(pendingLoad);
		return;
	}
	pendingRemoteRegistrationsByPackageKey.set(packageKey, new Set([pendingLoad]));
}
function removePendingRemoteRegistration(pendingLoad) {
	const packageKey = createPackageCacheKey(pendingLoad.packageId, pendingLoad.version);
	const pendingLoads = pendingRemoteRegistrationsByPackageKey.get(packageKey);
	if (!pendingLoads) return;
	pendingLoads.delete(pendingLoad);
	observedRegistrationsByPendingLoad.delete(pendingLoad);
	if (pendingLoads.size === 0) pendingRemoteRegistrationsByPackageKey.delete(packageKey);
}
function getPendingRemoteRegistrationsForScript(registration, remoteEntryUrlKey) {
	const pendingLoads = pendingRemoteRegistrationsByPackageKey.get(createPackageCacheKey(registration.packageId, registration.version));
	if (!pendingLoads) return [];
	return Array.from(pendingLoads).filter((pendingLoad) => pendingLoad.remoteEntryUrlKey === remoteEntryUrlKey);
}
function observeFreshPendingRegistrationForScript(event, pendingLoad) {
	const freshPendingLoads = getPendingRemoteRegistrationsForScript(event.registration, pendingLoad.remoteEntryUrlKey).filter(isFreshPendingPackageLoad);
	if (freshPendingLoads.length === 0) return false;
	for (const freshPendingLoad of freshPendingLoads) observeRegistrationForPendingLoad(freshPendingLoad, event);
	return true;
}
function observeRegistrationForPendingLoad(pendingLoad, event) {
	observedRegistrationsByPendingLoad.set(pendingLoad, {
		previousRegistration: event.previousRegistration,
		registration: event.registration
	});
}
function isFreshPendingPackageLoad(pendingLoad) {
	return pendingLoad.getCurrentGeneration() === pendingLoad.generation;
}
function enqueueRemoteEntryScriptLoad(task) {
	const previousLoad = remoteScriptLoadQueue;
	const resultPromise = previousLoad === void 0 ? task() : previousLoad.then(task, task);
	const currentLoad = resultPromise.then(() => void 0, () => void 0);
	remoteScriptLoadQueue = currentLoad;
	currentLoad.then(() => {
		if (remoteScriptLoadQueue === currentLoad) remoteScriptLoadQueue = void 0;
	});
	return resultPromise;
}
function normalizeAssetUrl(url, descriptor) {
	try {
		return new URL(url, window.location.href).href;
	} catch {
		throw new WidgetRuntimeError({
			code: "INVALID_DESCRIPTOR",
			message: `Widget package cssUrls contains invalid URL: ${url}`,
			packageId: descriptor.packageId,
			version: descriptor.version
		});
	}
}
function withCacheBust(url, cacheBust) {
	if (cacheBust === void 0 || cacheBust === false) return url;
	const cacheBustValue = typeof cacheBust === "function" ? cacheBust() : cacheBust === true ? String(Date.now()) : cacheBust;
	const nextUrl = new URL(url, window.location.href);
	nextUrl.searchParams.set("fluidWidgetRuntimeCacheBust", cacheBustValue);
	return nextUrl.href;
}
//#endregion
//#region ../../platform/widget-runtime/src/globals.ts
const globalMarker = Symbol.for("fluid.widget-runtime.FluidSharedGlobals");
const pendingPackageFactoryErrorPrefix = "[Fluid Widget Runtime] Failed to register deferred widget package:";
function installFluidWidgetRuntimeHostGlobals(shared = {}) {
	ensureFluidWidgetsGlobal();
	const existing = window.FluidShared;
	if (isFluidSharedGlobal(existing)) {
		if (existing.PortalSdk === void 0 && shared.PortalSdk !== void 0) existing.PortalSdk = shared.PortalSdk;
		drainPendingFluidWidgetPackages();
		return existing;
	}
	const widgetRuntime = {
		createWidgetRuntimeLoader,
		installFluidWidgetRuntimeHostGlobals,
		manifestVersion: 1,
		...shared.WidgetRuntime
	};
	const fluidShared = {
		[globalMarker]: true,
		React: shared.React ?? react,
		ReactDOM: shared.ReactDOM ?? react_dom,
		ReactJsxRuntime: shared.ReactJsxRuntime ?? react_jsx_runtime,
		WidgetRuntime: widgetRuntime,
		...shared.PortalSdk === void 0 ? {} : { PortalSdk: shared.PortalSdk }
	};
	window.FluidShared = fluidShared;
	drainPendingFluidWidgetPackages();
	return fluidShared;
}
function drainPendingFluidWidgetPackages() {
	const queue = window.FluidWidgetPackageQueue;
	if (!Array.isArray(queue) || window.FluidShared === void 0) return;
	const hasPortalSdk = window.FluidShared.PortalSdk !== void 0;
	const deferredFactories = [];
	while (queue.length > 0) {
		const factory = queue.shift();
		if (typeof factory !== "function") continue;
		if (factory["__fluidRequiresPortalSdk"] === true && !hasPortalSdk) {
			deferredFactories.push(factory);
			continue;
		}
		try {
			factory();
		} catch (err) {
			console.error(pendingPackageFactoryErrorPrefix, err);
		}
	}
	queue.push(...deferredFactories);
}
function isFluidSharedGlobal(value) {
	return value !== void 0 && value[globalMarker] === true;
}
//#endregion
//#region ../../platform/widget-runtime/src/components/WidgetRuntimeErrorBoundary.tsx
var WidgetRuntimeErrorBoundary = class extends react.Component {
	state = { error: null };
	static getDerivedStateFromError(error) {
		return { error };
	}
	componentDidCatch(error, errorInfo) {
		this.props.onError?.(error, errorInfo);
	}
	render() {
		const { error } = this.state;
		if (!error) return this.props.children;
		const reset = () => {
			this.setState({ error: null });
		};
		if (typeof this.props.fallback === "function") return this.props.fallback({
			error,
			reset
		});
		if (this.props.fallback !== void 0) return this.props.fallback;
		return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultWidgetRuntimeErrorFallback, {
			error,
			reset
		});
	}
};
function DefaultWidgetRuntimeErrorFallback({ error, reset }) {
	return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
		role: "alert",
		children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: error instanceof WidgetRuntimeError ? "Widget runtime failed" : "Widget failed to render" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
			type: "button",
			onClick: reset,
			children: "Try again"
		})]
	});
}
//#endregion
//#region src/utils/build-widget-registry.ts
function buildWidgetRegistry(manifests) {
	if (manifests.length === 0) return require_FluidProvider.DEFAULT_SDK_WIDGET_REGISTRY;
	const customEntries = Object.fromEntries(manifests.filter((manifest) => {
		const isBuiltIn = isBuiltInWidgetType(manifest.type);
		if (isBuiltIn) warnBuiltInWidgetCollision("manifest", manifest.type);
		return !isBuiltIn;
	}).map((manifest) => [manifest.type, manifest.component]));
	return {
		...require_FluidProvider.DEFAULT_SDK_WIDGET_REGISTRY,
		...customEntries
	};
}
function mergeRegisteredWidgetsIntoRegistry(registry, registeredWidgets, warningSink = defaultWidgetRegistryWarningSink) {
	if (registeredWidgets.length === 0) return registry;
	const duplicateRuntimeWidgetTypes = getDuplicateWidgetTypes(registeredWidgets);
	const remoteEntries = Object.fromEntries(registeredWidgets.filter((widget) => {
		if (isBuiltInWidgetType(widget.type)) {
			warnBuiltInWidgetCollision("runtime registration", widget.type, warningSink);
			return false;
		}
		if (duplicateRuntimeWidgetTypes.has(widget.type)) {
			warnDuplicateRuntimeWidgetType(widget.type, warningSink);
			return false;
		}
		if (isExistingRegistryWidgetType(registry, widget.type)) {
			warnExistingRegistryWidgetCollision(widget.type, warningSink);
			return false;
		}
		return true;
	}).map((widget) => [widget.type, wrapRuntimeWidgetComponent(widget)]));
	return {
		...registry,
		...remoteEntries
	};
}
function getDuplicateWidgetTypes(widgets) {
	const counts = /* @__PURE__ */ new Map();
	for (const widget of widgets) counts.set(widget.type, (counts.get(widget.type) ?? 0) + 1);
	return new Set(Array.from(counts.entries()).filter(([, count]) => count > 1).map(([type]) => type));
}
function wrapRuntimeWidgetComponent(widget) {
	const RuntimeWidgetComponent = widget.component;
	function RuntimeWidgetWithBoundary(props) {
		return (0, react.createElement)(WidgetRuntimeErrorBoundary, null, (0, react.createElement)(RuntimeWidgetComponent, props));
	}
	RuntimeWidgetWithBoundary.displayName = `WidgetRuntimeErrorBoundary(${widget.type})`;
	return RuntimeWidgetWithBoundary;
}
function isBuiltInWidgetType(widgetType) {
	return Object.prototype.hasOwnProperty.call(require_FluidProvider.DEFAULT_SDK_WIDGET_REGISTRY, widgetType);
}
function isExistingRegistryWidgetType(registry, widgetType) {
	return Object.prototype.hasOwnProperty.call(registry, widgetType);
}
function defaultWidgetRegistryWarningSink(message) {
	console.warn(message);
}
function warnBuiltInWidgetCollision(source, widgetType, warningSink = defaultWidgetRegistryWarningSink) {
	warningSink(`[portal-sdk] Ignoring ${source} for built-in widget type "${widgetType}". Built-in widgets cannot be overridden.`);
}
function warnDuplicateRuntimeWidgetType(widgetType, warningSink = defaultWidgetRegistryWarningSink) {
	warningSink(`[portal-sdk] Ignoring runtime widget type "${widgetType}" because multiple packages registered the same SDK-facing type.`);
}
function warnExistingRegistryWidgetCollision(widgetType, warningSink = defaultWidgetRegistryWarningSink) {
	warningSink(`[portal-sdk] Ignoring runtime widget type "${widgetType}" because the SDK registry already contains that type.`);
}
//#endregion
//#region src/hooks/use-fluid-profile.ts
/**
* Base query key for profile data.
* Kept for backwards compatibility — the runtime key used by the hook
* includes a company prefix via {@link useCompanyScopedQueryKey}.
*
* @deprecated Use {@link APP_DATA_QUERY_KEY} with `useFluidApp` instead.
*/
const PROFILE_QUERY_KEY = ["fluid", "profile"];
/**
* Hook to fetch the portal profile (themes, navigation, screens).
*
* Internally fetches from the fluidos API (same data source as
* {@link useFluidApp}) and selects the `profile` slice, so no
* legacy `/api/rep_app/manifest` call is made.
*
* @deprecated Use `useFluidApp()` instead — it returns the full
* `RepAppData` including `profile`, `screens`, and more.
*
* @example
* ```tsx
* function Navigation() {
*   const { data: profile, isLoading } = useFluidProfile();
*
*   if (isLoading) return <Spinner />;
*
*   return (
*     <nav>
*       {profile?.navigation.navigation_items.map(item => (
*         <NavItem key={item.id} item={item} />
*       ))}
*     </nav>
*   );
* }
* ```
*/
function useFluidProfile() {
	const appDefinitionApi = require_FluidThemeProvider.useAppDefinitionApi();
	const { scopeKey } = require_hook_types.useCompanyScopedQueryKey();
	return (0, _tanstack_react_query.useQuery)({
		queryKey: scopeKey(APP_DATA_QUERY_KEY),
		queryFn: () => fetchRawManifest(appDefinitionApi),
		select: (raw) => {
			return require_hook_types.transformManifestToRepAppData(raw).profile;
		}
	});
}
//#endregion
//#region src/hooks/use-company-switch.ts
/**
* Hook that handles company switching for the portal.
*
* Calls PUT /api/authentication/company/{id}/switch, clears the TanStack
* Query cache and IndexedDB persisted cache, then reloads the page so all
* queries re-fetch with the new company context.
*
* The server updates the session cookie automatically via the switch
* endpoint response; no client-side token storage is needed.
*/
function useCompanySwitch(_options) {
	const client = require_query_keys.usePortalTenantClient();
	const queryClient = (0, _tanstack_react_query.useQueryClient)();
	const switchingRef = (0, react.useRef)(false);
	const { mutate, isPending, isError, error } = (0, _tanstack_react_query.useMutation)({
		mutationFn: (companyId) => client.put(`/api/authentication/company/${companyId}/switch`),
		onSuccess: async () => {
			queryClient.clear();
			try {
				await require_FluidProvider.deleteDatabase("company-switch");
			} catch {}
			window.location.reload();
		},
		onError: () => {
			switchingRef.current = false;
		}
	});
	return {
		switchCompany: (0, react.useCallback)((companyId) => {
			if (switchingRef.current) return;
			switchingRef.current = true;
			mutate(companyId);
		}, [mutate]),
		isPending,
		isError,
		error
	};
}
//#endregion
//#region src/widgets/runtime-sdk.ts
var runtime_sdk_exports = /* @__PURE__ */ require_chunk.__exportAll({
	APP_DATA_QUERY_KEY: () => APP_DATA_QUERY_KEY,
	APP_DEFINITION_QUERY_KEY: () => require_hook_types.APP_DEFINITION_QUERY_KEY,
	AppNavigationProvider: () => require_AppNavigationContext.AppNavigationProvider,
	PROFILE_QUERY_KEY: () => PROFILE_QUERY_KEY,
	PROPERTY_FIELD_TYPES: () => require_registries.PROPERTY_FIELD_TYPES,
	applyPropertyValues: () => require_registries.applyPropertyValues,
	buildThemeDefinition: () => require_FluidThemeProvider.buildThemeDefinition,
	createCompanyQueryKey: () => require_hook_types.createCompanyQueryKey,
	defineWidget: () => require_authoring.defineWidget,
	defineWidgetPackage: () => require_authoring.defineWidgetPackage,
	extractPropertyValues: () => require_registries.extractPropertyValues,
	getActiveThemeId: () => require_FluidThemeProvider.getActiveThemeId,
	getProperty: () => require_hook_types.getProperty,
	groupPropertyFields: () => require_registries.groupPropertyFields,
	hasData: () => require_hook_types.hasData,
	isErrorResult: () => require_hook_types.isErrorResult,
	isIdle: () => require_hook_types.isIdle,
	isLoading: () => require_hook_types.isLoading,
	isPropertyFieldType: () => require_registries.isPropertyFieldType,
	isSourceWidgetPackage: () => require_authoring.isSourceWidgetPackage,
	normalizeComponentTree: () => require_hook_types.normalizeComponentTree,
	selectProperty: () => require_hook_types.selectProperty,
	sourceWidgetPackagesToManifests: () => require_authoring.sourceWidgetPackagesToManifests,
	toNavigationItem: () => require_hook_types.toNavigationItem,
	toRawManifest: () => require_hook_types.toRawManifest,
	toScreenDefinition: () => require_hook_types.toScreenDefinition,
	transformManifestToRepAppData: () => require_hook_types.transformManifestToRepAppData,
	transformThemes: () => require_FluidThemeProvider.transformThemes,
	useAccount: () => require_use_account.useAccount,
	useAppDefinition: () => require_hook_types.useAppDefinition,
	useAppDefinitionApi: () => require_FluidThemeProvider.useAppDefinitionApi,
	useAppNavigation: () => require_AppNavigationContext.useAppNavigation,
	useCompanyScopedQueryKey: () => require_hook_types.useCompanyScopedQueryKey,
	useCompanySwitch: () => useCompanySwitch,
	useFluidApp: () => useFluidApp,
	useFluidProfile: () => useFluidProfile,
	useFluidTheme: () => require_hook_types.useFluidTheme,
	useLogout: () => useLogout,
	usePortalTenantClient: () => require_query_keys.usePortalTenantClient,
	useStore: () => require_use_store.useStore
});
//#endregion
//#region src/utils/widget-package-manifest-url.ts
const DEFAULT_WIDGET_PACKAGE_MANIFEST_URL = "/api/app/widget-packages";
const VITE_DEV_WIDGET_PACKAGE_MANIFEST_URL = "/__widget-packages__";
const VITE_DEV_MODULE_PATH_SEGMENTS = [
	"/@fs/",
	"/src/",
	"/node_modules/.vite/",
	"/@id/"
];
function resolveDefaultWidgetPackageManifestUrl(moduleUrl, options = {}) {
	const parsedModuleUrl = parseModuleUrl(moduleUrl);
	if (!parsedModuleUrl) return false;
	if (options.isViteDev && isViteDevModulePath(parsedModuleUrl.pathname)) return new URL(VITE_DEV_WIDGET_PACKAGE_MANIFEST_URL, parsedModuleUrl.origin).href;
	return DEFAULT_WIDGET_PACKAGE_MANIFEST_URL;
}
function parseModuleUrl(moduleUrl) {
	if (!moduleUrl) return null;
	try {
		return new URL(moduleUrl);
	} catch {
		return null;
	}
}
function isViteDevModulePath(pathname) {
	return VITE_DEV_MODULE_PATH_SEGMENTS.some((segment) => pathname.includes(segment));
}
function getDefaultWidgetPackageManifestUrl() {
	return resolveDefaultWidgetPackageManifestUrl(require("url").pathToFileURL(__filename).href, { isViteDev: isViteDevRuntime() });
}
function isViteDevRuntime() {
	return {}.env?.DEV === true;
}
//#endregion
//#region src/utils/load-widget-packages.ts
const WIDGET_PACKAGE_DESCRIPTOR_MANIFEST_VERSION = 1;
const WIDGET_PACKAGE_DESCRIPTOR_FETCH_TIMEOUT_MS = 5e3;
function installAndReadFluidWidgetsRegistry() {
	if (typeof window === "undefined") return [];
	return installAndReadFluidWidgetsGlobal().getRegisteredWidgets();
}
function subscribeToFluidWidgetsRegistry(listener) {
	if (typeof window === "undefined") return {
		registeredWidgets: [],
		unsubscribe: () => void 0
	};
	const fluidWidgets = installAndReadFluidWidgetsGlobal();
	const unsubscribe = fluidWidgets.subscribe((event) => {
		listener(fluidWidgets.getRegisteredWidgets(), event);
	});
	return {
		registeredWidgets: fluidWidgets.getRegisteredWidgets(),
		unsubscribe
	};
}
function installAndReadFluidWidgetsGlobal() {
	installFluidWidgetRuntimeHostGlobals({
		React: react,
		ReactDOM: react_dom,
		ReactJsxRuntime: react_jsx_runtime,
		PortalSdk: runtime_sdk_exports
	});
	return ensureFluidWidgetsGlobal();
}
async function fetchWidgetPackageDescriptors(descriptorEndpointUrl = DEFAULT_WIDGET_PACKAGE_MANIFEST_URL, options = {}) {
	const abortSignal = createTimeoutAbortSignal(WIDGET_PACKAGE_DESCRIPTOR_FETCH_TIMEOUT_MS);
	try {
		const response = await fetch(descriptorEndpointUrl, {
			credentials: options.credentials ?? "same-origin",
			signal: abortSignal.signal
		});
		if (!response.ok) throw new Error(`[portal] Failed to fetch widget package descriptors from ${descriptorEndpointUrl}: ${response.status} ${response.statusText}`);
		return parseWidgetPackageDescriptorResponse(await response.json(), descriptorEndpointUrl, options);
	} finally {
		abortSignal.cleanup();
	}
}
function parseWidgetPackageDescriptorResponse(data, descriptorEndpointUrl = DEFAULT_WIDGET_PACKAGE_MANIFEST_URL, options = {}) {
	const descriptorEndpointBaseUrl = normalizeDescriptorEndpointUrl(descriptorEndpointUrl);
	if (!descriptorEndpointBaseUrl) return [];
	const entries = getWidgetPackageDescriptorEntries(data);
	if (!entries) return [];
	const assetOriginPolicy = createRuntimeAssetOriginPolicy(descriptorEndpointBaseUrl, options.allowedOrigins ?? [], options.trustCatalogAssetOrigins === true);
	const descriptors = [];
	for (const entry of entries) {
		const descriptor = normalizeWidgetPackageDescriptor(entry, descriptorEndpointBaseUrl, assetOriginPolicy);
		if (descriptor) descriptors.push(descriptor);
	}
	return descriptors;
}
async function loadWidgetPackages(widgetPackages, options = {}) {
	if (widgetPackages.length === 0) return {
		registeredWidgets: [],
		hasFailures: false
	};
	if (options.ignoreExistingGlobalRegistrations) installAndReadFluidWidgetsGlobal();
	else installAndReadFluidWidgetsRegistry();
	const loader = createWidgetRuntimeLoader({ ignorePreRegisteredPackages: options.ignoreExistingGlobalRegistrations === true });
	const runtimeWidgetPackages = widgetPackages;
	const results = await loader.loadPackages(runtimeWidgetPackages);
	let hasFailures = false;
	for (const result of results) if (!result.ok) {
		hasFailures = true;
		console.error(`[portal] Failed to load widget package ${result.packageId}@${result.version}:`, result.error);
	}
	return {
		registeredWidgets: loader.getRegisteredWidgets(),
		hasFailures
	};
}
function createTimeoutAbortSignal(timeoutMs) {
	if (typeof AbortSignal.timeout === "function") return {
		signal: AbortSignal.timeout(timeoutMs),
		cleanup: () => void 0
	};
	const controller = new AbortController();
	const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
	return {
		signal: controller.signal,
		cleanup: () => clearTimeout(timeoutId)
	};
}
function getWidgetPackageDescriptorEntries(data) {
	if (Array.isArray(data)) return data;
	if (!isRecord(data)) return null;
	const wrappedEntries = getArrayProperty(data, "packages") ?? getArrayProperty(data, "packageDescriptors") ?? getArrayProperty(data, "widgetPackages");
	if (wrappedEntries) return wrappedEntries;
	return looksLikeWidgetPackageEntry(data) ? [data] : null;
}
function normalizeWidgetPackageDescriptor(entry, descriptorEndpointUrl, assetOriginPolicy) {
	const candidate = createWidgetPackageDescriptorCandidate(entry);
	if (candidate.kind === "skipped") return null;
	if (candidate.kind === "invalid") {
		warnRejectedMalformedWidgetPackageEntry(entry, candidate.reason, descriptorEndpointUrl);
		return null;
	}
	const remoteEntryUrl = normalizeRuntimeAssetUrl(candidate.descriptor.remoteEntryUrl, descriptorEndpointUrl, assetOriginPolicy);
	if (!remoteEntryUrl.ok) {
		warnRejectedWidgetPackageDescriptor(candidate.descriptor, "remoteEntryUrl", remoteEntryUrl.failure, descriptorEndpointUrl);
		return null;
	}
	const cssUrls = [];
	for (const cssUrl of candidate.descriptor.cssUrls) {
		const normalizedCssUrl = normalizeRuntimeAssetUrl(cssUrl, descriptorEndpointUrl, assetOriginPolicy);
		if (!normalizedCssUrl.ok) {
			warnRejectedWidgetPackageDescriptor(candidate.descriptor, "cssUrls", normalizedCssUrl.failure, descriptorEndpointUrl);
			return null;
		}
		cssUrls.push(normalizedCssUrl.url);
	}
	const descriptor = {
		...candidate.descriptor,
		remoteEntryUrl: remoteEntryUrl.url,
		cssUrls
	};
	const validationError = validateDescriptorCandidate(descriptor);
	if (validationError) {
		warnRejectedMalformedWidgetPackageEntry(entry, validationError, descriptorEndpointUrl);
		return null;
	}
	return descriptor;
}
function createWidgetPackageDescriptorCandidate(entry) {
	if (!isRecord(entry)) return {
		kind: "invalid",
		reason: "entry must be an object"
	};
	const manifest = isRecord(entry.manifest) ? entry.manifest : void 0;
	if (entry.disabled === true || entry.enabled === false) return { kind: "skipped" };
	if (isRuntimeWidgetPackageDescriptorAttempt(entry)) return createStrictRuntimeWidgetPackageDescriptorCandidate(entry);
	if (isCatalogWidgetPackageEntry(entry, manifest)) return createCatalogWidgetPackageDescriptorCandidate(entry, manifest);
	return createRuntimeWidgetPackageDescriptorCandidate(entry, manifest);
}
function createStrictRuntimeWidgetPackageDescriptorCandidate(entry) {
	return createDescriptorCandidate({
		manifestVersion: normalizeManifestVersion(entry.manifestVersion, { defaultWhenMissing: false }),
		packageId: readNonEmptyString(entry.packageId),
		packageType: normalizeWidgetPackageType(entry.packageType),
		version: readNonEmptyString(entry.version),
		remoteEntryUrl: readNonEmptyString(entry.remoteEntryUrl),
		cssUrls: normalizeRuntimeCssUrls(entry.cssUrls),
		widgets: normalizeRuntimeWidgets(entry.widgets),
		packageTypeError: "packageType must be one of fluid, company, droplet, partner, or internal",
		widgetsError: "manifest.widgets/widgets must be a non-empty array"
	});
}
function createRuntimeWidgetPackageDescriptorCandidate(entry, manifest) {
	const packageId = readNonEmptyString(entry.packageId) ?? readNonEmptyString(manifest?.packageId);
	const version = readNonEmptyString(entry.version) ?? readNonEmptyString(manifest?.version);
	const remoteEntryUrl = readNonEmptyString(entry.remoteEntryUrl) ?? readNonEmptyString(manifest?.remoteEntryUrl);
	const packageType = normalizeWidgetPackageType(entry.packageType) ?? normalizeWidgetPackageType(manifest?.packageType);
	return createDescriptorCandidate({
		manifestVersion: normalizeManifestVersion(entry.manifestVersion ?? manifest?.manifestVersion, { defaultWhenMissing: false }),
		packageId,
		packageType,
		version,
		remoteEntryUrl,
		cssUrls: normalizeRuntimeCssUrls(entry.cssUrls ?? manifest?.cssUrls),
		widgets: normalizeRuntimeWidgets(manifest?.widgets ?? entry.widgets),
		packageTypeError: "packageType must be one of fluid, company, droplet, partner, or internal",
		widgetsError: "manifest.widgets/widgets must be a non-empty array"
	});
}
function createCatalogWidgetPackageDescriptorCandidate(entry, manifest) {
	const packageId = readNonEmptyString(entry.packageId) ?? readNonEmptyString(manifest?.packageId);
	const version = readNonEmptyString(entry.version) ?? readNonEmptyString(manifest?.version);
	const remoteEntryUrl = readNonEmptyString(entry.scriptUrl) ?? readNonEmptyString(entry.remoteEntryUrl) ?? readNonEmptyString(manifest?.scriptUrl) ?? readNonEmptyString(manifest?.remoteEntryUrl);
	const packageType = normalizeWidgetPackageType(entry.source) ?? normalizeWidgetPackageType(entry.packageType) ?? normalizeWidgetPackageType(manifest?.source) ?? normalizeWidgetPackageType(manifest?.packageType) ?? "company";
	const manifestVersion = normalizeManifestVersion(entry.manifestVersion ?? manifest?.manifestVersion, { defaultWhenMissing: true });
	const cssUrls = normalizeCssUrls(entry.cssUrls ?? manifest?.cssUrls);
	const rawWidgets = manifest?.widgets ?? entry.widgets;
	return createDescriptorCandidate({
		manifestVersion,
		packageId,
		packageType,
		version,
		remoteEntryUrl,
		cssUrls,
		widgets: Array.isArray(rawWidgets) ? normalizeCatalogWidgets(rawWidgets, packageId) : null,
		packageTypeError: "packageType/source must be one of fluid, company, droplet, partner, internal, or omitted for company catalog packages",
		widgetsError: "manifest.widgets/widgets must contain at least one valid widget"
	});
}
function createDescriptorCandidate(fields) {
	if (!fields.manifestVersion) return {
		kind: "invalid",
		reason: "unsupported manifestVersion"
	};
	if (!fields.packageId) return {
		kind: "invalid",
		reason: "packageId must be a non-empty string"
	};
	if (!fields.version) return {
		kind: "invalid",
		reason: "version must be a non-empty string"
	};
	if (!fields.packageType) return {
		kind: "invalid",
		reason: fields.packageTypeError
	};
	if (!fields.remoteEntryUrl) return {
		kind: "invalid",
		reason: "remoteEntryUrl/scriptUrl must be a non-empty string"
	};
	if (!fields.cssUrls) return {
		kind: "invalid",
		reason: "cssUrls must be an array of strings"
	};
	if (!fields.widgets || fields.widgets.length === 0) return {
		kind: "invalid",
		reason: fields.widgetsError
	};
	return {
		kind: "valid",
		descriptor: {
			manifestVersion: fields.manifestVersion,
			packageId: fields.packageId,
			packageType: fields.packageType,
			version: fields.version,
			remoteEntryUrl: fields.remoteEntryUrl,
			cssUrls: fields.cssUrls,
			widgets: fields.widgets
		}
	};
}
function validateDescriptorCandidate(descriptor) {
	try {
		validateWidgetPackageDescriptor(descriptor);
		return null;
	} catch (error) {
		return error instanceof Error ? error.message : String(error);
	}
}
function isRuntimeWidgetPackageDescriptorAttempt(entry) {
	return entry.manifestVersion !== void 0 && entry.packageId !== void 0 && entry.packageType !== void 0 && entry.version !== void 0 && entry.remoteEntryUrl !== void 0 && entry.cssUrls !== void 0 && entry.widgets !== void 0;
}
function isCatalogWidgetPackageEntry(entry, manifest) {
	return entry.source !== void 0 || entry.scriptUrl !== void 0 || entry.manifestUrl !== void 0 || manifest?.source !== void 0 || manifest?.scriptUrl !== void 0 || manifest?.manifestUrl !== void 0 || manifest?.widgets !== void 0;
}
function normalizeManifestVersion(value, options) {
	if (value === WIDGET_PACKAGE_DESCRIPTOR_MANIFEST_VERSION) return WIDGET_PACKAGE_DESCRIPTOR_MANIFEST_VERSION;
	if (value === void 0 && options.defaultWhenMissing) return WIDGET_PACKAGE_DESCRIPTOR_MANIFEST_VERSION;
	return null;
}
function normalizeCssUrls(value) {
	return normalizeCssUrlList(value, { undefinedValue: [] });
}
function normalizeRuntimeCssUrls(value) {
	return normalizeCssUrlList(value, { undefinedValue: null });
}
function normalizeCssUrlList(value, options) {
	if (value === void 0) return options.undefinedValue;
	if (!Array.isArray(value)) return null;
	const cssUrls = [];
	for (const cssUrl of value) {
		const normalizedCssUrl = readNonEmptyString(cssUrl);
		if (!normalizedCssUrl) return null;
		cssUrls.push(normalizedCssUrl);
	}
	return cssUrls;
}
function normalizeRuntimeWidgets(value) {
	if (!Array.isArray(value)) return null;
	return value;
}
function normalizeCatalogWidgets(value, packageId) {
	const widgets = [];
	value.forEach((widget, index) => {
		const normalizedWidget = normalizeWidgetDescriptor(widget, {
			fallbackType: packageId === void 0 ? void 0 : `${packageId}-widget-${index + 1}`,
			overwritePropertySchemaWidgetType: true
		});
		if (normalizedWidget) widgets.push(normalizedWidget);
	});
	return widgets;
}
function normalizeWidgetDescriptor(widget, options = {}) {
	if (!isRecord(widget)) return null;
	const type = readNonEmptyString(widget.type) ?? readNonEmptyString(widget.name) ?? options.fallbackType;
	if (!type) return null;
	const name = readNonEmptyString(widget.name) ?? type;
	const displayName = readNonEmptyString(widget.displayName) ?? name;
	return {
		type,
		name,
		displayName,
		description: readNonEmptyString(widget.description) ?? `Custom widget ${displayName}`,
		icon: readNonEmptyString(widget.icon) ?? "box",
		category: readNonEmptyString(widget.category) ?? "components",
		propertySchema: normalizePropertySchema(widget.propertySchema, type, { overwriteWidgetType: options.overwritePropertySchemaWidgetType === true }),
		defaultProps: isRecord(widget.defaultProps) ? widget.defaultProps : {},
		container: normalizeContainer(widget.container),
		minSdkVersion: readNonEmptyString(widget.minSdkVersion) ?? "0.0.0",
		resizable: normalizeResizable(widget.resizable)
	};
}
function normalizePropertySchema(value, widgetType, options = { overwriteWidgetType: false }) {
	if (!isRecord(value)) return { widgetType };
	if (options.overwriteWidgetType || value.widgetType === void 0) return {
		...value,
		widgetType
	};
	return value;
}
function normalizeContainer(value) {
	return normalizeWidgetRuntimeContainer(value);
}
function normalizeResizable(value) {
	return normalizeWidgetRuntimeResizable(value);
}
function normalizeRuntimeAssetUrl(url, baseUrl, assetOriginPolicy) {
	if (hasUnsafeRawRuntimeAssetUrlSyntax(url)) return {
		ok: false,
		failure: {
			inputUrl: url,
			reason: "invalid-url"
		}
	};
	try {
		const parsedUrl = new URL(url, baseUrl);
		if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") return {
			ok: false,
			failure: {
				inputUrl: url,
				resolvedUrl: parsedUrl.href,
				reason: "unsupported-protocol"
			}
		};
		if (assetOriginPolicy.allowedOrigins.has(parsedUrl.origin)) return {
			ok: true,
			url: parsedUrl.href
		};
		if (assetOriginPolicy.allowSharedWidgetArtifactBucket && parsedUrl.href.startsWith("https://storage.googleapis.com/portal-widgets/")) return {
			ok: true,
			url: parsedUrl.href
		};
		return {
			ok: false,
			failure: {
				inputUrl: url,
				resolvedUrl: parsedUrl.href,
				reason: "untrusted-origin"
			}
		};
	} catch {
		return {
			ok: false,
			failure: {
				inputUrl: url,
				reason: "invalid-url"
			}
		};
	}
}
function warnRejectedWidgetPackageDescriptor(descriptor, assetField, failure, descriptorEndpointUrl) {
	console.warn(`[portal] Dropping widget package descriptor ${descriptor.packageId}@${descriptor.version} from ${descriptorEndpointUrl.href}: ${assetField} "${failure.inputUrl}" ${formatRuntimeAssetUrlFailure(failure)}.`);
}
function warnRejectedMalformedWidgetPackageEntry(entry, reason, descriptorEndpointUrl) {
	console.warn(`[portal] Dropping widget package catalog entry ${formatWidgetPackageEntryIdentity(entry)} from ${descriptorEndpointUrl.href}: ${reason}.`);
}
function formatWidgetPackageEntryIdentity(entry) {
	if (!isRecord(entry)) return "<unknown>";
	const packageId = readNonEmptyString(entry.packageId);
	const version = readNonEmptyString(entry.version);
	if (packageId && version) return `${packageId}@${version}`;
	if (packageId) return packageId;
	return "<unknown>";
}
function formatRuntimeAssetUrlFailure(failure) {
	const resolvedUrl = failure.resolvedUrl ? ` (resolved as ${failure.resolvedUrl})` : "";
	switch (failure.reason) {
		case "invalid-url": return "is not a valid URL";
		case "unsupported-protocol": return `uses an unsupported protocol${resolvedUrl}`;
		case "untrusted-origin": return `resolved to an untrusted origin${resolvedUrl}`;
	}
}
function createRuntimeAssetOriginPolicy(descriptorEndpointUrl, allowedOrigins, trustCatalogAssetOrigins) {
	const origins = /* @__PURE__ */ new Set();
	if (!trustCatalogAssetOrigins) origins.add(descriptorEndpointUrl.origin);
	for (const origin of allowedOrigins) {
		const normalizedOrigin = normalizeAllowedOrigin(origin);
		if (normalizedOrigin) origins.add(normalizedOrigin);
		else console.warn(`[portal] Ignoring invalid widget package allowed origin "${origin}". Expected an http(s) absolute URL origin.`);
	}
	return {
		allowSharedWidgetArtifactBucket: trustCatalogAssetOrigins,
		allowedOrigins: origins
	};
}
function hasUnsafeRawRuntimeAssetUrlSyntax(url) {
	return url.trim() !== url || hasControlCharacter(url) || url.includes("\\") || url.startsWith("//") || hasAmbiguousHttpScheme(url);
}
function hasAmbiguousHttpScheme(url) {
	return /^https?:(?!\/\/)/i.test(url);
}
function normalizeAllowedOrigin(origin) {
	try {
		const parsedOrigin = new URL(origin);
		if (parsedOrigin.protocol !== "http:" && parsedOrigin.protocol !== "https:") return null;
		return parsedOrigin.origin;
	} catch {
		return null;
	}
}
function normalizeDescriptorEndpointUrl(url) {
	try {
		return new URL(url, getWindowLocationHref());
	} catch {
		return null;
	}
}
function getWindowLocationHref() {
	return typeof window === "undefined" ? void 0 : window.location.href;
}
function looksLikeWidgetPackageEntry(value) {
	return value.packageId !== void 0 || value.remoteEntryUrl !== void 0 || value.scriptUrl !== void 0 || value.manifest !== void 0 || value.widgets !== void 0;
}
function getArrayProperty(value, key) {
	const property = value[key];
	return Array.isArray(property) ? property : void 0;
}
function isRecord(value) {
	return typeof value === "object" && value !== null && !Array.isArray(value);
}
//#endregion
//#region src/utils/widget-package-utils.ts
function resolveHostedWidgetPackageManifestUrl(descriptorEndpointUrl, baseUrl) {
	try {
		return new URL(descriptorEndpointUrl, baseUrl).href;
	} catch {
		return descriptorEndpointUrl;
	}
}
function dedupeWidgetPackagesByPackageIdAndVersion(widgetPackages) {
	const widgetPackagesByIdAndVersion = /* @__PURE__ */ new Map();
	for (const widgetPackage of widgetPackages) {
		const key = JSON.stringify([widgetPackage.packageId, widgetPackage.version]);
		if (!widgetPackagesByIdAndVersion.has(key)) widgetPackagesByIdAndVersion.set(key, widgetPackage);
	}
	return Array.from(widgetPackagesByIdAndVersion.values());
}
//#endregion
Object.defineProperty(exports, "APP_DATA_QUERY_KEY", {
	enumerable: true,
	get: function() {
		return APP_DATA_QUERY_KEY;
	}
});
Object.defineProperty(exports, "DEFAULT_WIDGET_PACKAGE_MANIFEST_URL", {
	enumerable: true,
	get: function() {
		return DEFAULT_WIDGET_PACKAGE_MANIFEST_URL;
	}
});
Object.defineProperty(exports, "PROFILE_QUERY_KEY", {
	enumerable: true,
	get: function() {
		return PROFILE_QUERY_KEY;
	}
});
Object.defineProperty(exports, "buildWidgetRegistry", {
	enumerable: true,
	get: function() {
		return buildWidgetRegistry;
	}
});
Object.defineProperty(exports, "createDefaultFluidConfig", {
	enumerable: true,
	get: function() {
		return createDefaultFluidConfig;
	}
});
Object.defineProperty(exports, "dedupeWidgetPackagesByPackageIdAndVersion", {
	enumerable: true,
	get: function() {
		return dedupeWidgetPackagesByPackageIdAndVersion;
	}
});
Object.defineProperty(exports, "fetchWidgetPackageDescriptors", {
	enumerable: true,
	get: function() {
		return fetchWidgetPackageDescriptors;
	}
});
Object.defineProperty(exports, "getDefaultWidgetPackageManifestUrl", {
	enumerable: true,
	get: function() {
		return getDefaultWidgetPackageManifestUrl;
	}
});
Object.defineProperty(exports, "installAndReadFluidWidgetsRegistry", {
	enumerable: true,
	get: function() {
		return installAndReadFluidWidgetsRegistry;
	}
});
Object.defineProperty(exports, "loadWidgetPackages", {
	enumerable: true,
	get: function() {
		return loadWidgetPackages;
	}
});
Object.defineProperty(exports, "mergeRegisteredWidgetsIntoRegistry", {
	enumerable: true,
	get: function() {
		return mergeRegisteredWidgetsIntoRegistry;
	}
});
Object.defineProperty(exports, "resolveHostedWidgetPackageManifestUrl", {
	enumerable: true,
	get: function() {
		return resolveHostedWidgetPackageManifestUrl;
	}
});
Object.defineProperty(exports, "subscribeToFluidWidgetsRegistry", {
	enumerable: true,
	get: function() {
		return subscribeToFluidWidgetsRegistry;
	}
});
Object.defineProperty(exports, "useCompanySwitch", {
	enumerable: true,
	get: function() {
		return useCompanySwitch;
	}
});
Object.defineProperty(exports, "useFluidApp", {
	enumerable: true,
	get: function() {
		return useFluidApp;
	}
});
Object.defineProperty(exports, "useFluidProfile", {
	enumerable: true,
	get: function() {
		return useFluidProfile;
	}
});
Object.defineProperty(exports, "useLogout", {
	enumerable: true,
	get: function() {
		return useLogout;
	}
});

//# sourceMappingURL=widget-package-utils-CygmmEmW.cjs.map