@veltrixsecops/app-sdk 3.2.0 → 3.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +68 -1
  2. package/dist/byol/index.cjs +3802 -0
  3. package/dist/byol/index.cjs.map +1 -0
  4. package/dist/byol/index.d.cts +578 -0
  5. package/dist/byol/index.d.ts +578 -0
  6. package/dist/byol/index.js +2587 -0
  7. package/dist/byol/index.js.map +1 -0
  8. package/dist/chunk-3WK4EVQ3.js +842 -0
  9. package/dist/chunk-3WK4EVQ3.js.map +1 -0
  10. package/dist/{chunk-EOOEHZGC.js → chunk-HIL6RIDG.js} +107 -3
  11. package/dist/chunk-HIL6RIDG.js.map +1 -0
  12. package/dist/{chunk-VWFTOFTI.js → chunk-Y6XBNZGR.js} +8 -2
  13. package/dist/chunk-Y6XBNZGR.js.map +1 -0
  14. package/dist/client/index.cjs +112 -2
  15. package/dist/client/index.cjs.map +1 -1
  16. package/dist/client/index.d.cts +118 -6
  17. package/dist/client/index.d.ts +118 -6
  18. package/dist/client/index.js +13 -1
  19. package/dist/connections/index.cjs +1787 -0
  20. package/dist/connections/index.cjs.map +1 -0
  21. package/dist/connections/index.d.cts +78 -0
  22. package/dist/connections/index.d.ts +78 -0
  23. package/dist/connections/index.js +754 -0
  24. package/dist/connections/index.js.map +1 -0
  25. package/dist/hooks/index.cjs.map +1 -1
  26. package/dist/hooks/index.d.cts +2 -2
  27. package/dist/hooks/index.d.ts +2 -2
  28. package/dist/hooks/index.js +1 -1
  29. package/dist/index.cjs +7 -0
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +3 -3
  32. package/dist/index.d.ts +3 -3
  33. package/dist/index.js +3 -1
  34. package/dist/index.js.map +1 -1
  35. package/dist/opentofu/index.cjs +138 -0
  36. package/dist/opentofu/index.cjs.map +1 -0
  37. package/dist/opentofu/index.d.cts +131 -0
  38. package/dist/opentofu/index.d.ts +131 -0
  39. package/dist/opentofu/index.js +109 -0
  40. package/dist/opentofu/index.js.map +1 -0
  41. package/dist/pipeline/index.cjs +7 -0
  42. package/dist/pipeline/index.cjs.map +1 -1
  43. package/dist/pipeline/index.d.cts +9 -2
  44. package/dist/pipeline/index.d.ts +9 -2
  45. package/dist/pipeline/index.js +3 -1
  46. package/dist/pipeline-beeT8dje.d.cts +408 -0
  47. package/dist/pipeline-beeT8dje.d.ts +408 -0
  48. package/dist/ui/index.cjs +136 -0
  49. package/dist/ui/index.cjs.map +1 -1
  50. package/dist/ui/index.d.cts +109 -1
  51. package/dist/ui/index.d.ts +109 -1
  52. package/dist/ui/index.js +35 -677
  53. package/dist/ui/index.js.map +1 -1
  54. package/dist/{use-app-context-OQlcmq7t.d.cts → use-app-context-Byv_fam0.d.cts} +206 -4
  55. package/dist/{use-app-context-OQlcmq7t.d.ts → use-app-context-Byv_fam0.d.ts} +206 -4
  56. package/opentofu/README.md +114 -0
  57. package/opentofu/modules/aws/main.tf +1008 -0
  58. package/opentofu/modules/aws/outputs.tf +90 -0
  59. package/opentofu/modules/aws/variables.tf +437 -0
  60. package/opentofu/modules/aws/versions.tf +23 -0
  61. package/opentofu/modules/azure/main.tf +920 -0
  62. package/opentofu/modules/azure/outputs.tf +72 -0
  63. package/opentofu/modules/azure/variables.tf +498 -0
  64. package/opentofu/modules/azure/versions.tf +27 -0
  65. package/opentofu/modules/gcp/main.tf +645 -0
  66. package/opentofu/modules/gcp/outputs.tf +73 -0
  67. package/opentofu/modules/gcp/variables.tf +428 -0
  68. package/opentofu/modules/gcp/versions.tf +27 -0
  69. package/opentofu/modules/hetzner/main.tf +432 -0
  70. package/opentofu/modules/hetzner/outputs.tf +72 -0
  71. package/opentofu/modules/hetzner/variables.tf +423 -0
  72. package/opentofu/modules/hetzner/versions.tf +26 -0
  73. package/package.json +33 -1
  74. package/dist/chunk-EOOEHZGC.js.map +0 -1
  75. package/dist/chunk-VWFTOFTI.js.map +0 -1
  76. package/dist/pipeline-A-gSsPRR.d.cts +0 -189
  77. package/dist/pipeline-A-gSsPRR.d.ts +0 -189
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/byol/ByolInfrastructureManager.tsx","../../src/byol/types.ts","../../src/byol/status.ts","../../src/byol/detail/shared.tsx","../../src/byol/api.ts","../../src/byol/ByolInfrastructureDetail.tsx","../../src/byol/placement.ts","../../src/byol/topology.ts","../../src/byol/detail/OverviewTab.tsx","../../src/byol/detail/ResourcesTab.tsx","../../src/byol/detail/ActivityTab.tsx","../../src/byol/detail/AccessTab.tsx","../../src/byol/detail/ConfigurationTab.tsx","../../src/byol/detail/SettingsTab.tsx","../../src/byol/detail/ByolPlanModal.tsx","../../src/byol/diffPlan.ts","../../src/byol/detail/planLines.tsx","../../src/byol/detail/DestroyPlanModal.tsx","../../src/byol/detail/icons.tsx","../../src/byol/ClusterPlacementField.tsx","../../src/byol/tags.ts"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useState } from 'react'\nimport { authFetch } from '../client'\nimport {\n Card,\n CardHeader,\n CardBody,\n Button,\n Input,\n Select,\n Alert,\n FormDialog,\n DataTable,\n FilterBar,\n SortSelect,\n Pagination,\n type DataTableColumn,\n type FilterDefinition,\n type SortOption,\n} from '../ui'\nimport {\n type ByolInfrastructure,\n type ByolInfrastructureManagerProps,\n type Tag,\n type CloudProvider,\n type CloudRegion,\n type CloudAccount,\n type FormState,\n SELF_HOSTED,\n SELF_HOSTED_LABEL,\n DEFAULT_DEPLOYMENT_TYPES,\n NETWORK_MODE_OPTIONS,\n DNS_MODE_OPTIONS,\n BYOC_NETWORK_MODES,\n CONTROL_PLANE_LAYOUT_OPTIONS,\n INSTANCE_TYPE_EXAMPLES,\n BLANK_FORM,\n editFormState,\n} from './types'\nimport { StatusPill, tokens } from './detail/shared'\nimport { errorText, formatDate } from './api'\nimport { ByolInfrastructureDetail } from './ByolInfrastructureDetail'\nimport { ClusterPlacementField } from './ClusterPlacementField'\nimport { validatePlacement } from './placement'\n\n/**\n * Reusable BYOL infrastructure manager: a searchable/filterable list whose rows\n * open a full deployment console (the detail view), a Provider picker (platform\n * cloud providers plus Self-Hosted), an Environment picker fed by the customer's\n * tags, and a cloud region picker shown only for a distributed cloud deployment.\n * The app owns the data (its own DB table + routes); this component owns the UI.\n */\nexport const ByolInfrastructureManager: React.FC<ByolInfrastructureManagerProps> = ({\n apiBase,\n title = 'BYOL Infrastructure',\n deploymentTypes = DEFAULT_DEPLOYMENT_TYPES,\n configBase,\n configLinks,\n versionOptions = [],\n defaultVersionId,\n}) => {\n const [infrastructure, setInfrastructure] = useState<ByolInfrastructure[]>([])\n const [tags, setTags] = useState<Tag[]>([])\n const [cloudProviders, setCloudProviders] = useState<CloudProvider[]>([])\n const [regions, setRegions] = useState<CloudRegion[]>([])\n const [cloudAccounts, setCloudAccounts] = useState<CloudAccount[]>([])\n const [error, setError] = useState<string | null>(null)\n const [isLoading, setIsLoading] = useState(true)\n\n // Master→detail: which infrastructure (if any) is open.\n const [selectedId, setSelectedId] = useState<string | null>(() => {\n if (typeof window === 'undefined') return null\n return new URLSearchParams(window.location.search).get('infra')\n })\n const [reloadSignal, setReloadSignal] = useState(0)\n\n const [search, setSearch] = useState('')\n const [environmentFilter, setEnvironmentFilter] = useState<string | null>(null)\n const [deploymentFilter, setDeploymentFilter] = useState<string | null>(null)\n const [statusFilter, setStatusFilter] = useState<string | null>(null)\n const [sortField, setSortField] = useState('name')\n const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc')\n const [page, setPage] = useState(1)\n const [pageSize, setPageSize] = useState(10)\n\n const [dialogOpen, setDialogOpen] = useState(false)\n const [editing, setEditing] = useState<ByolInfrastructure | null>(null)\n const [form, setForm] = useState<FormState>(BLANK_FORM)\n const [submitting, setSubmitting] = useState(false)\n const [formError, setFormError] = useState<string | null>(null)\n\n const load = useCallback(() => {\n setIsLoading(true)\n setError(null)\n return authFetch(apiBase)\n .then((res) => (res.ok ? res.json() : Promise.reject(new Error(`HTTP ${res.status}`))))\n .then((data: ByolInfrastructure[]) => setInfrastructure(Array.isArray(data) ? data : []))\n .catch((e: Error) => setError(e.message))\n .finally(() => setIsLoading(false))\n }, [apiBase])\n\n useEffect(() => {\n void load()\n }, [load])\n\n // Reference lists: environment tags + platform cloud providers + cloud account\n // connections (for BYOC deployment targets). Best-effort.\n useEffect(() => {\n authFetch('/api/tags')\n .then((res) => (res.ok ? res.json() : []))\n .then((data: Tag[]) => setTags(Array.isArray(data) ? data : []))\n .catch(() => setTags([]))\n authFetch('/api/cloud-providers')\n .then((res) => (res.ok ? res.json() : []))\n .then((data: CloudProvider[]) =>\n setCloudProviders(Array.isArray(data) ? data.filter((c) => c.isActive !== false) : []),\n )\n .catch(() => setCloudProviders([]))\n authFetch('/api/cloud-accounts')\n .then((res) => (res.ok ? res.json() : []))\n .then((data: CloudAccount[]) => setCloudAccounts(Array.isArray(data) ? data : []))\n .catch(() => setCloudAccounts([]))\n }, [])\n\n const isCloud = form.providerId !== '' && form.providerId !== SELF_HOSTED\n const showRegion = isCloud && form.deploymentType === 'distributed'\n // Every cloud deploy can pick a verified account — the tenant's own (customer)\n // for BYOC, or a Veltrix-managed (platform) account for a hosted deploy. BYOC\n // (dedicated/existing) REQUIRES one (whose VPC to use); hosted (shared) is\n // optional (falls back to the default provisioning identity).\n const isByoc = BYOC_NETWORK_MODES.has(form.networkMode)\n const showCloudAccount = isCloud\n // A BYOC (dedicated/existing) target needs a cloud account — but only for a CLOUD\n // deploy. Self-hosted ignores networkMode entirely, so it must never gate Save on\n // an account it doesn't even show a picker for.\n const cloudAccountRequired = isByoc && isCloud\n\n // Load the selected cloud provider's regions when needed for the region picker.\n useEffect(() => {\n if (!isCloud) {\n setRegions([])\n return\n }\n let cancelled = false\n authFetch(`/api/cloud-providers/${form.providerId}/regions`)\n .then((res) => (res.ok ? res.json() : []))\n .then((data: CloudRegion[]) => {\n if (!cancelled) setRegions(Array.isArray(data) ? data.filter((r) => r.isActive !== false) : [])\n })\n .catch(() => {\n if (!cancelled) setRegions([])\n })\n return () => {\n cancelled = true\n }\n }, [isCloud, form.providerId])\n\n const openCreate = () => {\n setEditing(null)\n // A fresh infrastructure defaults its version to the app-supplied \"latest\"\n // (defaultVersionId) when one is available; an existing row's Edit form\n // always reflects its own stored versionId instead (see editFormState).\n setForm({ ...BLANK_FORM, versionId: defaultVersionId ?? '' })\n setFormError(null)\n setDialogOpen(true)\n }\n\n const openEdit = (row: ByolInfrastructure) => {\n setEditing(row)\n setForm(editFormState(row))\n setFormError(null)\n setDialogOpen(true)\n }\n\n const closeDialog = useCallback(() => {\n if (submitting) return\n setDialogOpen(false)\n }, [submitting])\n\n const setField = <K extends keyof FormState>(key: K, value: FormState[K]) =>\n setForm((prev) => ({ ...prev, [key]: value }))\n\n // A cloud account is scoped to a provider — switching providers invalidates any\n // previously selected account (the Cloud account options are recomputed to match\n // the new provider, so keeping the stale id around would let it slip into submit).\n const handleProviderChange = (value: string) =>\n setForm((prev) => ({ ...prev, providerId: value, cloudAccountConnectionId: '' }))\n\n const handleSubmit = async () => {\n if (!form.name.trim()) {\n setFormError('Name is required')\n return\n }\n const indexerCount = Number(form.indexerCount)\n const searchHeadCount = Number(form.searchHeadCount)\n if (form.deploymentType === 'distributed') {\n if (indexerCount < 3) {\n setFormError('Distributed deployments require at least 3 indexers')\n return\n }\n if (searchHeadCount < 2) {\n setFormError('Distributed deployments require at least 2 search heads')\n return\n }\n if (showRegion) {\n const indexerErr = validatePlacement(form.indexerPlacement, indexerCount)\n if (indexerErr) {\n setFormError(`Indexer placement: ${indexerErr}`)\n return\n }\n const searchErr = validatePlacement(form.searchHeadPlacement, searchHeadCount)\n if (searchErr) {\n setFormError(`Search head placement: ${searchErr}`)\n return\n }\n }\n }\n if (cloudAccountRequired && !form.cloudAccountConnectionId) {\n setFormError('Select a verified cloud account for a BYOC deployment target')\n return\n }\n const selfHosted = form.providerId === SELF_HOSTED\n const selectedCloud = cloudProviders.find((c) => c.id === form.providerId)\n const distributed = form.deploymentType === 'distributed'\n // Placement only applies to a distributed cloud deployment (needs AZs/regions);\n // single-instance or self-hosted always collapses to a single site.\n const normalizePlacement = (p: FormState['indexerPlacement']) =>\n distributed && showRegion && p?.mode === 'multi-site' ? p : { mode: 'single' as const }\n setSubmitting(true)\n setFormError(null)\n const payload = {\n name: form.name.trim(),\n deploymentType: form.deploymentType,\n environmentType: form.environmentType,\n hosting_type: selfHosted ? SELF_HOSTED_LABEL : (selectedCloud?.name ?? ''),\n cloudProviderId: selfHosted ? undefined : form.providerId || undefined,\n region: showRegion ? form.region : '',\n indexerCount,\n searchHeadCount,\n networkMode: form.networkMode,\n dnsMode: form.dnsMode,\n cloudAccountConnectionId: showCloudAccount ? form.cloudAccountConnectionId : undefined,\n // Topology authoring — only meaningful for distributed deployments.\n controlPlaneLayout: distributed ? form.controlPlaneLayout : 'dedicated',\n heavyForwarderCount: distributed ? Math.max(1, Number(form.heavyForwarderCount) || 1) : 1,\n // Compute size override; empty → the cloud default (t2.medium-class). Only\n // meaningful for a cloud deployment.\n instanceType: !selfHosted ? form.instanceType.trim() || undefined : undefined,\n indexerPlacement: normalizePlacement(form.indexerPlacement),\n searchHeadPlacement: normalizePlacement(form.searchHeadPlacement),\n versionId: form.versionId || undefined,\n }\n try {\n const res = await authFetch(editing ? `${apiBase}/${editing.id}` : apiBase, {\n method: editing ? 'PUT' : 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n })\n if (!res.ok) throw new Error(await errorText(res))\n setDialogOpen(false)\n await load()\n // If we edited the open infrastructure, refresh the detail view too.\n if (editing) setReloadSignal((n) => n + 1)\n } catch (e) {\n setFormError((e as Error).message)\n } finally {\n setSubmitting(false)\n }\n }\n\n const openDetail = (id: string | null) => {\n setSelectedId(id)\n if (typeof window !== 'undefined' && id === null) {\n const params = new URLSearchParams(window.location.search)\n params.delete('infra')\n params.delete('section')\n const qs = params.toString()\n window.history.replaceState(null, '', qs ? `${window.location.pathname}?${qs}` : window.location.pathname)\n }\n }\n\n const columns: DataTableColumn<ByolInfrastructure>[] = [\n { key: 'name', header: 'Name', render: (row) => <strong>{row.name}</strong> },\n { key: 'deploymentType', header: 'Deployment', render: (row) => row.deploymentType ?? '—' },\n { key: 'environmentType', header: 'Environment', render: (row) => row.environmentType ?? '—' },\n { key: 'hosting_type', header: 'Provider', render: (row) => row.hosting_type ?? '—' },\n { key: 'region', header: 'Region', render: (row) => row.region || '—' },\n { key: 'indexerCount', header: 'Indexers', align: 'right', render: (row) => row.indexerCount ?? '—' },\n { key: 'searchHeadCount', header: 'Search heads', align: 'right', render: (row) => row.searchHeadCount ?? '—' },\n { key: 'status', header: 'Status', render: (row) => <StatusPill status={row.status} /> },\n { key: 'updatedAt', header: 'Updated', render: (row) => formatDate(row.updatedAt) },\n { key: 'chevron', header: '', align: 'right', width: '32px', render: () => <span aria-hidden style={{ color: tokens.faint }}>›</span> },\n ]\n\n const environmentOptions = useMemo(() => tags.map((t) => ({ value: t.name, label: t.name })), [tags])\n const providerOptions = useMemo(\n () => [\n { value: SELF_HOSTED, label: SELF_HOSTED_LABEL },\n ...cloudProviders.map((c) => ({ value: c.id, label: c.name })),\n ],\n [cloudProviders],\n )\n const regionOptions = useMemo(\n () => regions.map((r) => ({ value: r.code, label: `${r.name} (${r.code})` })),\n [regions],\n )\n const selectedProvider = useMemo(\n () => cloudProviders.find((c) => c.id === form.providerId),\n [cloudProviders, form.providerId],\n )\n // Only verified accounts, narrowed to the selected cloud provider (when one is picked).\n const verifiedCloudAccounts = useMemo(\n () =>\n cloudAccounts.filter(\n (a) => a.status === 'VERIFIED' && (!selectedProvider?.code || a.provider === selectedProvider.code),\n ),\n [cloudAccounts, selectedProvider],\n )\n const cloudAccountOptions = useMemo(\n () =>\n verifiedCloudAccounts.map((a) => ({\n value: a.id,\n label: `${a.name} (${a.provider}${a.scope === 'platform' ? ' · Veltrix-managed' : ''})`,\n })),\n [verifiedCloudAccounts],\n )\n\n const statusFilterOptions = useMemo(() => {\n const seen = new Set<string>()\n infrastructure.forEach((i) => seen.add(i.status ?? 'unknown'))\n return Array.from(seen, (value) => ({ value, label: value }))\n }, [infrastructure])\n\n const sortOptions: SortOption[] = [\n { value: 'name', label: 'Name' },\n { value: 'indexerCount', label: 'Indexers' },\n { value: 'searchHeadCount', label: 'Search heads' },\n { value: 'status', label: 'Status' },\n { value: 'updatedAt', label: 'Updated' },\n ]\n const filters: FilterDefinition[] = [\n { key: 'environment', label: 'Environment', options: environmentOptions, value: environmentFilter, onChange: setEnvironmentFilter, alwaysVisible: true },\n { key: 'deployment', label: 'Deployment', options: deploymentTypes, value: deploymentFilter, onChange: setDeploymentFilter },\n { key: 'status', label: 'Status', options: statusFilterOptions, value: statusFilter, onChange: setStatusFilter },\n ]\n\n const filteredSorted = useMemo(() => {\n const term = search.trim().toLowerCase()\n const rows = infrastructure.filter((row) => {\n if (term) {\n const haystack = `${row.name ?? ''} ${row.hosting_type ?? ''} ${row.region ?? ''}`.toLowerCase()\n if (!haystack.includes(term)) return false\n }\n if (environmentFilter && row.environmentType !== environmentFilter) return false\n if (deploymentFilter && row.deploymentType !== deploymentFilter) return false\n if (statusFilter && (row.status ?? 'unknown') !== statusFilter) return false\n return true\n })\n const dir = sortDir === 'asc' ? 1 : -1\n return [...rows].sort((a, b) => {\n switch (sortField) {\n case 'indexerCount':\n return ((a.indexerCount ?? 0) - (b.indexerCount ?? 0)) * dir\n case 'searchHeadCount':\n return ((a.searchHeadCount ?? 0) - (b.searchHeadCount ?? 0)) * dir\n case 'status':\n return (a.status ?? '').localeCompare(b.status ?? '') * dir\n case 'updatedAt':\n return (new Date(a.updatedAt ?? 0).getTime() - new Date(b.updatedAt ?? 0).getTime()) * dir\n case 'name':\n default:\n return (a.name ?? '').localeCompare(b.name ?? '') * dir\n }\n })\n }, [infrastructure, search, environmentFilter, deploymentFilter, statusFilter, sortField, sortDir])\n\n const pageRows = useMemo(\n () => filteredSorted.slice((page - 1) * pageSize, page * pageSize),\n [filteredSorted, page, pageSize],\n )\n\n useEffect(() => {\n setPage(1)\n }, [search, environmentFilter, deploymentFilter, statusFilter, sortField, sortDir])\n\n const selected = selectedId ? infrastructure.find((i) => i.id === selectedId) ?? null : null\n\n // --- Detail view (master→detail swap) ---\n if (selectedId && selected) {\n return (\n <>\n <ByolInfrastructureDetail\n apiBase={apiBase}\n initialInfra={selected}\n configBase={configBase}\n configLinks={configLinks}\n reloadSignal={reloadSignal}\n onBack={() => openDetail(null)}\n onEdit={openEdit}\n onDeleted={() => {\n openDetail(null)\n void load()\n }}\n onChanged={() => void load()}\n />\n <FormDialog\n isOpen={dialogOpen}\n onClose={closeDialog}\n title={editing ? `Edit \"${editing.name}\"` : 'New BYOL infrastructure'}\n description=\"Define the deployment topology for a Bring-Your-Own-License Splunk environment.\"\n onSubmit={handleSubmit}\n submitText={editing ? 'Save changes' : 'Create infrastructure'}\n isSubmitting={submitting}\n submitDisabled={!form.name.trim() || (cloudAccountRequired && !form.cloudAccountConnectionId)}\n error={formError}\n size=\"md\"\n >\n <FormBody\n form={form}\n setField={setField}\n onProviderChange={handleProviderChange}\n deploymentTypes={deploymentTypes}\n environmentOptions={environmentOptions}\n providerOptions={providerOptions}\n regionOptions={regionOptions}\n showRegion={showRegion}\n showCloudAccount={showCloudAccount}\n cloudAccountRequired={cloudAccountRequired}\n cloudAccountOptions={cloudAccountOptions}\n selectedProviderName={selectedProvider?.name}\n providerCode={selectedProvider?.code}\n versionOptions={versionOptions}\n />\n </FormDialog>\n </>\n )\n }\n\n // --- List view ---\n return (\n <Card variant=\"bordered\">\n <CardHeader\n actions={\n <div style={{ display: 'flex', gap: 8 }}>\n <Button variant=\"secondary\" size=\"sm\" onClick={() => void load()} isLoading={isLoading}>\n Refresh\n </Button>\n <Button variant=\"primary\" size=\"sm\" onClick={openCreate}>\n New infrastructure\n </Button>\n </div>\n }\n >\n <h2 style={{ margin: 0, fontSize: 16, fontWeight: 600 }}>{title}</h2>\n </CardHeader>\n <CardBody>\n {error ? (\n <p style={{ color: tokens.danger }}>Failed to load BYOL infrastructure: {error}</p>\n ) : null}\n\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>\n <FilterBar\n search={{ value: search, onChange: setSearch, placeholder: 'Search infrastructure…' }}\n filters={filters}\n />\n <SortSelect\n options={sortOptions}\n value={sortField}\n direction={sortDir}\n onChange={(field, dir) => {\n setSortField(field)\n setSortDir(dir)\n }}\n />\n </div>\n\n <DataTable\n columns={columns}\n data={pageRows}\n rowKey={(row) => row.id}\n isLoading={isLoading}\n onRowClick={(row) => openDetail(row.id)}\n emptyState={{\n title: 'No BYOL infrastructure yet',\n description: 'Create a BYOL deployment to manage its topology, resources and lifecycle here.',\n }}\n />\n <div style={{ marginTop: 12 }}>\n <Pagination\n page={page}\n pageSize={pageSize}\n totalItems={filteredSorted.length}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n pageSizeOptions={[10, 25, 50]}\n />\n </div>\n </CardBody>\n\n <FormDialog\n isOpen={dialogOpen}\n onClose={closeDialog}\n title={editing ? `Edit \"${editing.name}\"` : 'New BYOL infrastructure'}\n description=\"Define the deployment topology for a Bring-Your-Own-License Splunk environment.\"\n onSubmit={handleSubmit}\n submitText={editing ? 'Save changes' : 'Create infrastructure'}\n isSubmitting={submitting}\n submitDisabled={!form.name.trim() || (cloudAccountRequired && !form.cloudAccountConnectionId)}\n error={formError}\n size=\"md\"\n >\n <FormBody\n form={form}\n setField={setField}\n onProviderChange={handleProviderChange}\n deploymentTypes={deploymentTypes}\n environmentOptions={environmentOptions}\n providerOptions={providerOptions}\n regionOptions={regionOptions}\n showRegion={showRegion}\n showCloudAccount={showCloudAccount}\n cloudAccountRequired={cloudAccountRequired}\n cloudAccountOptions={cloudAccountOptions}\n selectedProviderName={selectedProvider?.name}\n versionOptions={versionOptions}\n />\n </FormDialog>\n </Card>\n )\n}\n\n// --- Create/edit form body (shared by both list + detail entry points) -------\n\ninterface FormBodyProps {\n form: FormState\n setField: <K extends keyof FormState>(key: K, value: FormState[K]) => void\n /** Provider-specific onChange (also clears a now-mismatched cloud account selection). */\n onProviderChange: (value: string) => void\n deploymentTypes: Array<{ value: string; label: string }>\n environmentOptions: Array<{ value: string; label: string }>\n providerOptions: Array<{ value: string; label: string }>\n regionOptions: Array<{ value: string; label: string }>\n showRegion: boolean\n /** Whether the current network mode is BYOC (dedicated/existing) and needs a cloud account. */\n showCloudAccount: boolean\n /** Whether an account MUST be picked (BYOC) vs optional (hosted platform account). */\n cloudAccountRequired: boolean\n /** Verified cloud accounts, narrowed to the selected provider when one is picked. */\n cloudAccountOptions: Array<{ value: string; label: string }>\n /** Selected cloud provider's display name, for the \"no verified account\" note. */\n selectedProviderName?: string\n /** Selected cloud provider's code (aws|azure|gcp|hetzner), for cloud-aware zone naming. */\n providerCode?: string\n /** Software version options (app-supplied); the picker is hidden when empty. */\n versionOptions: Array<{ value: string; label: string }>\n}\n\n/** A labelled sub-group of related fields, so the form reads as scannable sections. */\nconst FormSection: React.FC<{ title: string; description?: string; children: React.ReactNode }> = ({\n title,\n description,\n children,\n}) => (\n <div>\n <p style={{ margin: 0, fontSize: 13, fontWeight: 600, color: tokens.text }}>{title}</p>\n {description ? (\n <p style={{ margin: '2px 0 0', fontSize: 12, color: tokens.muted }}>{description}</p>\n ) : null}\n <div style={{ marginTop: 10, display: 'flex', flexDirection: 'column', gap: 12 }}>{children}</div>\n </div>\n)\n\nconst FormBody: React.FC<FormBodyProps> = ({\n form,\n setField,\n onProviderChange,\n deploymentTypes,\n environmentOptions,\n providerOptions,\n regionOptions,\n showRegion,\n showCloudAccount,\n cloudAccountRequired,\n cloudAccountOptions,\n selectedProviderName,\n providerCode,\n versionOptions,\n}) => (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>\n <Input label=\"Name\" value={form.name} onChange={(e) => setField('name', e.target.value)} placeholder=\"e.g. Production cluster\" fullWidth autoFocus />\n <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>\n <Select label=\"Deployment type\" value={form.deploymentType} onChange={(value) => setField('deploymentType', value)} options={deploymentTypes} />\n <Select label=\"Environment\" value={form.environmentType} onChange={(value) => setField('environmentType', value)} options={environmentOptions} />\n </div>\n <div style={{ display: 'grid', gridTemplateColumns: showRegion ? '1fr 1fr' : '1fr', gap: 12 }}>\n <Select label=\"Provider\" value={form.providerId} onChange={onProviderChange} options={providerOptions} />\n {showRegion ? (\n <Select label=\"Region\" value={form.region} onChange={(value) => setField('region', value)} options={regionOptions} />\n ) : null}\n </div>\n\n <FormSection title=\"Deployment target\">\n <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>\n <Select\n label=\"Network\"\n value={form.networkMode}\n onChange={(value) => setField('networkMode', value)}\n options={NETWORK_MODE_OPTIONS}\n />\n <Select label=\"DNS\" value={form.dnsMode} onChange={(value) => setField('dnsMode', value)} options={DNS_MODE_OPTIONS} />\n </div>\n {showCloudAccount ? (\n <>\n <Select\n label={cloudAccountRequired ? 'Cloud account *' : 'Cloud account'}\n value={form.cloudAccountConnectionId}\n onChange={(value) => setField('cloudAccountConnectionId', value)}\n options={cloudAccountOptions}\n placeholder={\n cloudAccountOptions.length\n ? 'Select a verified cloud account…'\n : cloudAccountRequired\n ? 'No verified cloud accounts'\n : 'None — use the default provisioning identity'\n }\n disabled={cloudAccountOptions.length === 0}\n helperText={\n cloudAccountRequired\n ? 'Required for a dedicated or existing-network (BYOC) deployment.'\n : 'Optional — the Veltrix-managed account this hosted deployment provisions through.'\n }\n />\n {cloudAccountRequired && cloudAccountOptions.length === 0 ? (\n <Alert variant=\"warning\" title=\"No verified cloud account available\">\n {selectedProviderName\n ? `No verified ${selectedProviderName} cloud account found. Register and verify a cloud account first in Settings → Cloud Accounts.`\n : 'Register and verify a cloud account first in Settings → Cloud Accounts.'}\n </Alert>\n ) : null}\n </>\n ) : null}\n </FormSection>\n\n <FormSection\n title=\"Topology\"\n description={\n form.deploymentType === 'distributed'\n ? 'Distributed deployments need at least 3 indexers and 2 search heads.'\n : 'Number of indexer and search-head nodes to provision.'\n }\n >\n {versionOptions.length > 0 ? (\n <Select\n label=\"Splunk version\"\n value={form.versionId}\n onChange={(value) => setField('versionId', value)}\n options={versionOptions}\n placeholder=\"Use the app's default version\"\n helperText=\"The Splunk release installed on every node. Leave unset to use the app's default installer.\"\n />\n ) : null}\n <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>\n <Input label=\"Indexers\" type=\"number\" min={1} value={form.indexerCount} onChange={(e) => setField('indexerCount', e.target.value)} fullWidth />\n <Input label=\"Search heads\" type=\"number\" min={1} value={form.searchHeadCount} onChange={(e) => setField('searchHeadCount', e.target.value)} fullWidth />\n </div>\n {form.providerId && form.providerId !== SELF_HOSTED ? (\n <Input\n label=\"Compute size (instance type)\"\n value={form.instanceType}\n onChange={(e) => setField('instanceType', e.target.value)}\n placeholder={INSTANCE_TYPE_EXAMPLES.aws}\n fullWidth\n helperText={`Leave blank for the cloud default (~2 vCPU / 4 GB). Examples: AWS ${INSTANCE_TYPE_EXAMPLES.aws}, Azure ${INSTANCE_TYPE_EXAMPLES.azure}, GCP ${INSTANCE_TYPE_EXAMPLES.gcp}, Hetzner ${INSTANCE_TYPE_EXAMPLES.hetzner}. Applies to every node; you can change it here later.`}\n />\n ) : null}\n {showRegion ? (\n <>\n <ClusterPlacementField\n label=\"Indexer cluster placement\"\n placement={form.indexerPlacement}\n nodeCount={Math.max(1, Number(form.indexerCount) || 1)}\n primaryRegion={form.region}\n providerCode={providerCode}\n regionOptions={regionOptions}\n onChange={(p) => setField('indexerPlacement', p)}\n />\n <ClusterPlacementField\n label=\"Search head cluster placement\"\n placement={form.searchHeadPlacement}\n nodeCount={Math.max(1, Number(form.searchHeadCount) || 1)}\n primaryRegion={form.region}\n providerCode={providerCode}\n regionOptions={regionOptions}\n onChange={(p) => setField('searchHeadPlacement', p)}\n />\n </>\n ) : null}\n </FormSection>\n\n {form.deploymentType === 'distributed' ? (\n <>\n <FormSection\n title=\"Control plane\"\n description=\"How many instances the five management roles run on — fewer instances cut cost, more give isolation and HA.\"\n >\n <Select\n label=\"Consolidation\"\n value={form.controlPlaneLayout}\n onChange={(value) => setField('controlPlaneLayout', value as FormState['controlPlaneLayout'])}\n options={CONTROL_PLANE_LAYOUT_OPTIONS.map((o) => ({ value: o.value, label: `${o.label} — ${o.description}` }))}\n />\n </FormSection>\n\n <FormSection\n title=\"Ingest\"\n description=\"Heavy forwarders for ingest routing. One is provisioned by default; add more for higher throughput.\"\n >\n <Input\n label=\"Heavy forwarders\"\n type=\"number\"\n min={1}\n value={form.heavyForwarderCount}\n onChange={(e) => setField('heavyForwarderCount', e.target.value)}\n fullWidth\n />\n </FormSection>\n </>\n ) : null}\n </div>\n)\n\nexport default ByolInfrastructureManager\n","// =============================================================================\n// Shared types for the BYOL infrastructure manager + detail view.\n// =============================================================================\n\n/** A region association satellite row (indexer / search-head placement). */\nexport interface ByolRegion {\n id: string\n region: string\n}\n\n/**\n * Control-plane consolidation layout. Trades HA/isolation for cost by combining\n * management roles onto fewer instances:\n * - `dedicated` — 5 instances, one role each (LM, CM, SH-deployer, DS, MC).\n * - `consolidated`— ~3 instances; CM and SH-deployer stay isolated, the rest combine.\n * - `single` — 1 manager node running every management role (small / non-HA).\n * Applies to distributed deployments; single-instance deployments ignore it.\n */\nexport type ControlPlaneLayout = 'dedicated' | 'consolidated' | 'single'\n\n/** How a cluster's sites are addressed: availability zones (same region) or regions. */\nexport type PlacementGranularity = 'az' | 'region'\n\n/** One placement target with its share of the cluster's nodes. */\nexport interface PlacementSite {\n /** AZ id (e.g. `us-east-1a`) when granularity is `az`, or a region code (e.g. `us-west-2`) when `region`. */\n site: string\n /** Percent of the cluster's nodes placed on this site. Percents across a cluster's sites sum to 100. */\n percent: number\n}\n\n/**\n * Placement of a single cluster tier. `single` keeps every node in the standard\n * main region/zone; `multi-site` spreads nodes across `sites` by percent.\n * ONLY the indexer and search-head tiers accept multi-site placement — every\n * other tier is always single-site in the main region.\n */\nexport interface ClusterPlacement {\n mode: 'single' | 'multi-site'\n granularity?: PlacementGranularity\n sites?: PlacementSite[]\n}\n\n/** Default single-site placement (all nodes in the main region). */\nexport const SINGLE_SITE_PLACEMENT: ClusterPlacement = { mode: 'single' }\n\n/** Minimum heavy forwarders in a distributed ingest tier. */\nexport const MIN_HEAVY_FORWARDERS = 1\n\nexport interface ByolInfrastructure {\n id: string\n name: string\n deploymentType?: string\n environmentType?: string\n indexerCount?: number\n searchHeadCount?: number\n status?: string\n hosting_type?: string\n cloudProviderId?: string | null\n region?: string | null\n indexerRegions?: ByolRegion[]\n searchHeadRegions?: ByolRegion[]\n /** Deployment target: platform-hosted network, or a customer-owned VPC. Defaults to 'shared'. */\n networkMode?: 'shared' | 'dedicated' | 'existing' | string\n /** DNS strategy for the deployment. Defaults to 'managed'. */\n dnsMode?: 'managed' | 'delegated' | 'private-only' | string\n /** Platform cloud account connection backing a BYOC (dedicated/existing) deployment. */\n cloudAccountConnectionId?: string | null\n /** Control-plane consolidation layout (distributed only). Defaults to 'dedicated'. */\n controlPlaneLayout?: ControlPlaneLayout\n /** Heavy forwarder count in the ingest tier (distributed only). Defaults to 1. */\n heavyForwarderCount?: number\n /** Compute size override for every node (e.g. AWS `t2.medium`); empty = cloud default. */\n instanceType?: string | null\n /** Placement of the indexer cluster — single-site or multi-site by percent. */\n indexerPlacement?: ClusterPlacement\n /** Placement of the search-head cluster — single-site or multi-site by percent. */\n searchHeadPlacement?: ClusterPlacement\n /** Selected software version (app catalog entry id) to install on every node. */\n versionId?: string\n updatedAt?: string\n createdAt?: string\n}\n\n/** A persisted resource row (from GET /byol/:id/resources). */\nexport interface ByolResource {\n id: string\n infrastructureId: string\n tier: string\n kind: string\n name: string\n role: string | null\n region: string | null\n /** Availability zone within `region` for a multi-AZ-placed node; null otherwise. */\n zone?: string | null\n /** Management roles a consolidated control-plane instance runs; null otherwise. */\n roles?: string[] | null\n status: string\n externalRef: string | null\n message: string | null\n planKey: string\n sortOrder: number\n}\n\n/** A deployment step (from GET /byol/:id/deployments → steps). */\nexport interface ByolDeploymentStep {\n id: string\n deploymentId: string\n stepOrder: number\n key: string\n title: string\n status: string\n detail: string | null\n logs: string | null\n startedAt: string | null\n completedAt: string | null\n}\n\n/** A deployment run (from GET /byol/:id/deployments). */\nexport interface ByolDeployment {\n id: string\n infrastructureId: string\n action: string\n status: string\n message: string | null\n startedAt: string\n completedAt: string | null\n steps: ByolDeploymentStep[]\n}\n\n/** Platform tag — the customer's environment tags feed the Environment picker. */\nexport interface Tag {\n id: string\n name: string\n}\n\n/** Platform cloud provider — feeds the \"Provider\" picker (plus Self-Hosted). */\nexport interface CloudProvider {\n id: string\n name: string\n code?: string\n isActive?: boolean\n}\n\nexport interface CloudRegion {\n id: string\n name: string\n code: string\n isActive?: boolean\n}\n\n/**\n * Platform cloud account connection — feeds the \"Cloud account\" picker shown\n * for BYOC (dedicated/existing network) deployment targets. Sourced from\n * `GET /api/cloud-accounts`. Only `VERIFIED` accounts matching the selected\n * cloud provider are offered.\n */\nexport interface CloudAccount {\n id: string\n provider: 'aws' | 'azure' | 'gcp' | 'hetzner' | string\n name: string\n status: 'UNVERIFIED' | 'VERIFIED' | 'ERROR' | string\n authMethod?: string\n /**\n * 'customer' — the tenant's own account (BYOC / dedicated / existing).\n * 'platform' — a Veltrix-managed account a hosted (shared) deployment provisions\n * through. The form offers platform accounts for hosted, customer accounts for BYOC.\n */\n scope?: 'customer' | 'platform' | string\n}\n\nexport interface FormState {\n name: string\n deploymentType: string\n environmentType: string\n /** A cloud provider id, or the SELF_HOSTED sentinel. */\n providerId: string\n region: string\n indexerCount: string\n searchHeadCount: string\n /** Deployment target: 'shared' (Veltrix-hosted), 'dedicated', or 'existing' (BYOC). */\n networkMode: string\n /** DNS strategy: 'managed', 'delegated', or 'private-only'. */\n dnsMode: string\n /** Platform cloud account connection id, required when networkMode is BYOC. */\n cloudAccountConnectionId: string\n /** Control-plane consolidation layout (distributed only). */\n controlPlaneLayout: ControlPlaneLayout\n /** Heavy forwarder count as a form string (distributed only, min 1). */\n heavyForwarderCount: string\n /** Compute size override for every node; empty = cloud default (t2.medium-class). */\n instanceType: string\n /** Placement of the indexer cluster. */\n indexerPlacement: ClusterPlacement\n /** Placement of the search-head cluster. */\n searchHeadPlacement: ClusterPlacement\n /** Selected software version (app catalog entry id); empty = app-default. */\n versionId: string\n}\n\n/**\n * A link surfaced in the detail view's Configuration section. The app supplies\n * these (the SDK stays app-agnostic). When `configTypeId` + `configBase` are\n * present the link resolves to `<configBase>/<configTypeId>`; otherwise `href`\n * is used verbatim.\n */\nexport interface ByolConfigLink {\n key: string\n title: string\n description: string\n configTypeId?: string\n href?: string\n}\n\nexport interface ByolInfrastructureManagerProps {\n /** Base URL of the app's BYOL routes, e.g. `/api/apps/splunk-enterprise/byol`. */\n apiBase: string\n /** Card title. Defaults to \"BYOL Infrastructure\". */\n title?: string\n /** Deployment topology options. Defaults to Single instance + Distributed. */\n deploymentTypes?: Array<{ value: string; label: string }>\n /**\n * Optional base path to this app's configuration canvases, e.g.\n * `/apps/splunk-enterprise/config`. Combined with each link's `configTypeId`\n * to deep-link the detail view's Configuration section.\n */\n configBase?: string\n /** Configuration links to surface in the detail view (app-supplied). */\n configLinks?: ByolConfigLink[]\n /**\n * Software version options for the \"Splunk version\" form picker (app-supplied —\n * the SDK has no notion of Splunk). Omit or pass an empty array to hide the\n * picker entirely (e.g. an app with no version catalog).\n */\n versionOptions?: Array<{ value: string; label: string }>\n /**\n * Version id a NEW infrastructure's form should default to (typically the\n * catalog's \"latest\" entry). Ignored when `versionOptions` is empty. Existing\n * rows always reflect their own stored `versionId`, never this default.\n */\n defaultVersionId?: string\n}\n\n// --- Constants --------------------------------------------------------------\n\n/** Sentinel provider value for a customer-managed (non-cloud) deployment. */\nexport const SELF_HOSTED = 'self-hosted'\nexport const SELF_HOSTED_LABEL = 'Self-Hosted'\n\nexport const DEFAULT_DEPLOYMENT_TYPES = [\n { value: 'single', label: 'Single instance' },\n { value: 'distributed', label: 'Distributed' },\n]\n\n/**\n * Network mode options for the \"Deployment target\" form section. Dedicated is listed\n * first because it is the default: OpenTofu provisions a self-contained VPC. 'shared'\n * requires a platform-managed base network to attach to (not yet provisioned), so it\n * is offered but not the default.\n */\nexport const NETWORK_MODE_OPTIONS = [\n { value: 'dedicated', label: 'Dedicated — your cloud (BYOC)' },\n { value: 'existing', label: 'Existing network — your cloud (BYOC)' },\n { value: 'shared', label: 'Veltrix-hosted (shared)' },\n]\n\n/** DNS mode options for the \"Deployment target\" form section. */\nexport const DNS_MODE_OPTIONS = [\n { value: 'managed', label: 'Managed' },\n { value: 'delegated', label: 'Delegated' },\n { value: 'private-only', label: 'Private only' },\n]\n\n/** Network modes that require a customer-owned (BYOC) cloud account connection. */\nexport const BYOC_NETWORK_MODES = new Set(['dedicated', 'existing'])\n\n/** Control-plane consolidation options for the \"Control plane\" form section. */\nexport const CONTROL_PLANE_LAYOUT_OPTIONS: Array<{\n value: ControlPlaneLayout\n label: string\n description: string\n}> = [\n { value: 'dedicated', label: 'Dedicated', description: '5 servers — one management role each (highest isolation).' },\n { value: 'consolidated', label: 'Consolidated', description: '~3 servers — cluster manager and SH deployer isolated, rest combined.' },\n { value: 'single', label: 'Single node', description: '1 server running every management role (lowest cost, non-HA).' },\n]\n\n/** Placement granularity options for a cluster's \"Placement\" form section. */\nexport const PLACEMENT_GRANULARITY_OPTIONS: Array<{ value: PlacementGranularity; label: string }> = [\n { value: 'az', label: 'Availability zones (same region)' },\n { value: 'region', label: 'Regions (multi-region)' },\n]\n\n/**\n * Map a persisted infrastructure record back into the editable form state, so\n * \"Edit topology\" renders the accurate current values (placement, consolidation,\n * forwarders, instance size, network target, …). Missing fields fall back to the\n * same defaults a new form uses, so a legacy row (created before these fields\n * existed) opens cleanly. Pure — safe to unit test.\n */\nexport function editFormState(row: ByolInfrastructure): FormState {\n const providerId = row.cloudProviderId\n ? row.cloudProviderId\n : row.hosting_type === SELF_HOSTED_LABEL\n ? SELF_HOSTED\n : ''\n return {\n name: row.name ?? '',\n deploymentType: row.deploymentType ?? 'single',\n environmentType: row.environmentType ?? '',\n providerId,\n region: row.region ?? '',\n indexerCount: String(row.indexerCount ?? 1),\n searchHeadCount: String(row.searchHeadCount ?? 1),\n networkMode: row.networkMode ?? 'shared',\n dnsMode: row.dnsMode ?? 'managed',\n cloudAccountConnectionId: row.cloudAccountConnectionId ?? '',\n controlPlaneLayout: row.controlPlaneLayout ?? 'dedicated',\n heavyForwarderCount: String(row.heavyForwarderCount ?? 1),\n instanceType: row.instanceType ?? '',\n indexerPlacement: row.indexerPlacement ?? { mode: 'single' },\n searchHeadPlacement: row.searchHeadPlacement ?? { mode: 'single' },\n versionId: row.versionId ?? '',\n }\n}\n\nexport const BLANK_FORM: FormState = {\n name: '',\n deploymentType: 'single',\n environmentType: '',\n providerId: '',\n region: '',\n indexerCount: '1',\n searchHeadCount: '1',\n // New cloud infra defaults to 'dedicated' — OpenTofu creates its own VPC and the\n // deployment depends on nothing pre-existing. 'shared' attaches to a Veltrix-managed\n // base network that must be provisioned by a separate platform tofu stack; until that\n // stack exists, defaulting to 'shared' produces \"no matching VPC\" at apply time.\n networkMode: 'dedicated',\n dnsMode: 'managed',\n cloudAccountConnectionId: '',\n controlPlaneLayout: 'dedicated',\n heavyForwarderCount: '1',\n instanceType: '',\n indexerPlacement: { mode: 'single' },\n searchHeadPlacement: { mode: 'single' },\n versionId: '',\n}\n\n/**\n * Example compute sizes per cloud (~2 vCPU / 4 GB), shown as form guidance. An\n * empty instanceType uses the module default, which is the first of each here.\n */\nexport const INSTANCE_TYPE_EXAMPLES: Record<string, string> = {\n aws: 't2.medium',\n azure: 'Standard_B2s',\n gcp: 'e2-medium',\n hetzner: 'cx22',\n}\n","// =============================================================================\n// BYOL infrastructure status model — the single place the lifecycle states, their\n// human labels, and their Badge variants are defined. Shared by the list and the\n// detail view so a status renders identically everywhere.\n//\n// Lifecycle: not_started → provisioning → running, with degraded / stopped /\n// failed / destroying as off-happy-path states. `active`/`error` are legacy\n// synonyms emitted by the provisioning hooks (onEvent/onWebhook) and mapped here\n// so old and new values render consistently.\n// =============================================================================\n\nimport type { BadgeVariant } from '../ui'\n\nexport type ByolInfraStatus =\n | 'not_started'\n | 'provisioning'\n | 'running'\n | 'active'\n | 'degraded'\n | 'stopped'\n | 'failed'\n | 'error'\n | 'destroying'\n\nconst VARIANTS: Record<string, BadgeVariant> = {\n not_started: 'default',\n provisioning: 'info',\n running: 'success',\n active: 'success',\n degraded: 'warning',\n stopped: 'warning',\n failed: 'danger',\n error: 'danger',\n destroying: 'info',\n}\n\nconst LABELS: Record<string, string> = {\n not_started: 'Not Started',\n provisioning: 'Provisioning',\n running: 'Running',\n active: 'Running',\n degraded: 'Degraded',\n stopped: 'Stopped',\n failed: 'Failed',\n error: 'Failed',\n destroying: 'Destroying',\n}\n\n/** Badge variant for an infrastructure status (falls back to neutral). */\nexport function statusVariant(status?: string): BadgeVariant {\n return (status && VARIANTS[status]) || 'default'\n}\n\n/** Human label for an infrastructure status (Title-Cases anything unknown). */\nexport function statusLabel(status?: string): string {\n if (!status) return 'Unknown'\n return LABELS[status] || status.replace(/_/g, ' ').replace(/\\b\\w/g, (c) => c.toUpperCase())\n}\n\n/** Whether the environment is actively running (running/active). */\nexport function isRunning(status?: string): boolean {\n return status === 'running' || status === 'active'\n}\n\n/** Whether a deploy has never been requested yet. */\nexport function isNotStarted(status?: string): boolean {\n return !status || status === 'not_started'\n}\n\n// --- Resource statuses (per-resource rows in the Resources tab) --------------\n\nconst RESOURCE_VARIANTS: Record<string, BadgeVariant> = {\n ready: 'success',\n provisioning: 'info',\n attention: 'warning',\n failed: 'danger',\n not_started: 'default',\n}\n\nconst RESOURCE_LABELS: Record<string, string> = {\n ready: 'Ready',\n provisioning: 'Provisioning',\n attention: 'Attention',\n failed: 'Failed',\n not_started: 'Not started',\n}\n\nexport function resourceStatusVariant(status?: string): BadgeVariant {\n return (status && RESOURCE_VARIANTS[status]) || 'default'\n}\n\nexport function resourceStatusLabel(status?: string): string {\n if (!status) return 'Not started'\n return RESOURCE_LABELS[status] || status.replace(/_/g, ' ')\n}\n\n// --- Deployment step statuses (Activity timeline) ---------------------------\n\nconst STEP_VARIANTS: Record<string, BadgeVariant> = {\n done: 'success',\n running: 'info',\n failed: 'danger',\n pending: 'default',\n}\n\nexport function stepStatusVariant(status?: string): BadgeVariant {\n return (status && STEP_VARIANTS[status]) || 'default'\n}\n","import React from 'react'\nimport { Badge } from '../../ui'\nimport { statusVariant, statusLabel, resourceStatusVariant, resourceStatusLabel } from '../status'\nimport type { ByolResource } from '../types'\n\n// Themed tokens — bound to the platform design-system contract in\n// `client/src/styles/tokens.css`. Those `--color-*` variables live on\n// `:root`/`.dark`, cascade into the app subtree, and flip with light/dark, so\n// consuming them here is what makes BYOL follow the active theme automatically.\n//\n// Two rules that the previous version got wrong:\n// 1. The design tokens are *space-separated RGB triples* (e.g. `17 24 39`),\n// meant to be wrapped in `rgb(...)` — not used as bare colours.\n// 2. The real names are `--color-surface[-raised/-sunken]`, `--color-border`,\n// and the `--color-content-*` text family — not `--color-text*` /\n// `--color-surface-secondary`, which never existed (so those silently fell\n// back to hardcoded light hex and never darkened).\n// The triple inside each `var()` fallback keeps the component legible when it\n// renders outside the platform (design tokens undefined → light theme).\n//\n// `primary` is the exception: `--veltrix-app-primary` is a *hex* variable the\n// host injects per app (AppShell brand scope), so it is used directly.\nconst rgbToken = (name: string, fallback: string): string => `rgb(var(${name}, ${fallback}))`\n\nexport const tokens = {\n border: rgbToken('--color-border', '229 231 235'),\n borderStrong: rgbToken('--color-border-strong', '209 213 219'),\n surface: rgbToken('--color-surface-raised', '255 255 255'), // cards / panels / active nav\n surface2: rgbToken('--color-surface', '249 250 251'), // page surface — sidebar / insets\n text: rgbToken('--color-content-primary', '17 24 39'),\n muted: rgbToken('--color-content-secondary', '75 85 99'),\n faint: rgbToken('--color-content-tertiary', '156 163 175'),\n primary: 'var(--veltrix-app-primary, #FF6600)',\n danger: rgbToken('--color-danger', '220 38 38'),\n success: rgbToken('--color-success', '22 163 74'),\n info: rgbToken('--color-info', '14 116 144'),\n warning: rgbToken('--color-warning', '161 98 7'),\n}\n\n/** Overall infrastructure status badge. */\nexport const StatusPill: React.FC<{ status?: string }> = ({ status }) => (\n <Badge variant={statusVariant(status)}>{statusLabel(status)}</Badge>\n)\n\n/** Per-resource status badge. */\nexport const ResourcePill: React.FC<{ status?: string }> = ({ status }) => (\n <Badge variant={resourceStatusVariant(status)} size=\"sm\">\n {resourceStatusLabel(status)}\n </Badge>\n)\n\n/** A labelled key/value pair used across the detail sections. */\nexport const Meta: React.FC<{ label: string; children: React.ReactNode }> = ({ label, children }) => (\n <div>\n <div style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '.05em', color: tokens.faint }}>{label}</div>\n <div style={{ fontWeight: 600, color: tokens.text, marginTop: 2 }}>{children}</div>\n </div>\n)\n\n/** Maps a resource status to a bar colour for the progress meter. */\nfunction barColor(status: string): string {\n switch (status) {\n case 'ready':\n return tokens.success\n case 'provisioning':\n return tokens.info\n case 'attention':\n return tokens.warning\n case 'failed':\n return tokens.danger\n default:\n return tokens.borderStrong\n }\n}\n\n/**\n * Segmented deployment-progress meter: one coloured segment per resource state,\n * plus a \"N / M ready\" readout. Falls back to an empty track when there are no\n * resources yet (never deployed).\n */\nexport const ProgressMeter: React.FC<{ resources: ByolResource[] }> = ({ resources }) => {\n const total = resources.length\n const ready = resources.filter((r) => r.status === 'ready').length\n const counts = new Map<string, number>()\n for (const r of resources) counts.set(r.status, (counts.get(r.status) ?? 0) + 1)\n const order = ['ready', 'provisioning', 'attention', 'failed', 'not_started']\n\n return (\n <div style={{ width: 300, maxWidth: '48vw' }}>\n <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12, color: tokens.muted, marginBottom: 6 }}>\n <span>Deployment progress</span>\n <span style={{ fontVariantNumeric: 'tabular-nums' }}>\n {total === 0 ? 'Not deployed' : `${ready} / ${total} resources ready`}\n </span>\n </div>\n <div style={{ height: 8, borderRadius: 999, background: tokens.surface2, overflow: 'hidden', display: 'flex' }}>\n {total === 0\n ? null\n : order.map((s) => {\n const n = counts.get(s) ?? 0\n if (!n) return null\n return <div key={s} style={{ width: `${(n / total) * 100}%`, background: barColor(s), height: '100%' }} />\n })}\n </div>\n </div>\n )\n}\n\n/** A lightweight titled panel (used where a full Card header is overkill). */\nexport const Panel: React.FC<{ title?: string; actions?: React.ReactNode; children: React.ReactNode }> = ({\n title,\n actions,\n children,\n}) => (\n <div style={{ border: `1px solid ${tokens.border}`, borderRadius: 12, background: tokens.surface, overflow: 'hidden' }}>\n {(title || actions) && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 12,\n padding: '12px 16px',\n borderBottom: `1px solid ${tokens.border}`,\n }}\n >\n {title ? <h3 style={{ margin: 0, fontSize: 14, fontWeight: 600, color: tokens.text }}>{title}</h3> : <span />}\n {actions}\n </div>\n )}\n <div style={{ padding: 16 }}>{children}</div>\n </div>\n)\n","// =============================================================================\n// BYOL fetch + formatting helpers. All calls go through the SDK's authFetch so\n// they carry the tenant's auth against the app's own `/byol` routes.\n// =============================================================================\n\nimport { authFetch } from '../client'\nimport type { ByolInfrastructure, ByolResource, ByolDeployment } from './types'\nimport type { ByolPlan } from './diffPlan'\n\n/** Best-effort extraction of an error message from a failed Response. */\nexport async function errorText(res: Response): Promise<string> {\n return res\n .json()\n .then((b: { error?: string }) => b?.error || `HTTP ${res.status}`)\n .catch(() => `HTTP ${res.status}`)\n}\n\nexport function formatDate(value?: string | null): string {\n if (!value) return '—'\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? '—' : date.toLocaleDateString()\n}\n\nexport function formatDateTime(value?: string | null): string {\n if (!value) return '—'\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? '—' : date.toLocaleString()\n}\n\nasync function json<T>(res: Response): Promise<T> {\n if (!res.ok) throw new Error(await errorText(res))\n return res.json() as Promise<T>\n}\n\n/** Re-fetch a single infrastructure record. */\nexport function getInfra(apiBase: string, id: string): Promise<ByolInfrastructure> {\n return authFetch(`${apiBase}/${id}`).then((r) => json<ByolInfrastructure>(r))\n}\n\nexport function getResources(apiBase: string, id: string): Promise<ByolResource[]> {\n return authFetch(`${apiBase}/${id}/resources`).then((r) => json<ByolResource[]>(r))\n}\n\nexport function getDeployments(apiBase: string, id: string): Promise<ByolDeployment[]> {\n return authFetch(`${apiBase}/${id}/deployments`).then((r) => json<ByolDeployment[]>(r))\n}\n\n/**\n * Dry-run the deployment plan — a side-effect-free diff of the desired topology\n * against the currently persisted resources. Powers the Plan modal shown before\n * Apply. Writes nothing; the subsequent Apply is the existing `deployInfra`.\n */\nexport function getPlan(apiBase: string, id: string): Promise<ByolPlan> {\n return authFetch(`${apiBase}/${id}/plan`).then((r) => json<ByolPlan>(r))\n}\n\n/** Request an end-to-end deploy. Returns the updated infra + the new run. */\nexport function deployInfra(\n apiBase: string,\n id: string,\n): Promise<{ infrastructure: ByolInfrastructure; deployment: ByolDeployment; resources: ByolResource[] }> {\n return authFetch(`${apiBase}/${id}/deploy`, { method: 'POST' }).then((r) =>\n json<{ infrastructure: ByolInfrastructure; deployment: ByolDeployment; resources: ByolResource[] }>(r),\n )\n}\n\n/** Tear down every resource in the plan. */\nexport function destroyInfra(apiBase: string, id: string): Promise<{ infrastructure: ByolInfrastructure }> {\n return authFetch(`${apiBase}/${id}/destroy`, { method: 'POST' }).then((r) =>\n json<{ infrastructure: ByolInfrastructure }>(r),\n )\n}\n\n/** Start / stop / restart a running environment. */\nexport function lifecycleInfra(\n apiBase: string,\n id: string,\n action: 'start' | 'stop' | 'restart',\n): Promise<ByolInfrastructure> {\n return authFetch(`${apiBase}/${id}/${action}`, { method: 'POST' }).then((r) => json<ByolInfrastructure>(r))\n}\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { Button, Spinner, useConfirmDialog } from '../ui'\nimport { buildByolResourcePlan } from './topology'\nimport { isRunning, isNotStarted } from './status'\nimport {\n getInfra,\n getResources,\n getDeployments,\n getPlan,\n deployInfra,\n destroyInfra,\n lifecycleInfra,\n errorText,\n formatDate,\n} from './api'\nimport type { ByolInfrastructure, ByolResource, ByolDeployment, ByolConfigLink } from './types'\nimport { SELF_HOSTED_LABEL } from './types'\nimport type { ByolPlan } from './diffPlan'\nimport { tokens, StatusPill, Meta, ProgressMeter } from './detail/shared'\nimport { OverviewTab } from './detail/OverviewTab'\nimport { ResourcesTab } from './detail/ResourcesTab'\nimport { ActivityTab } from './detail/ActivityTab'\nimport { AccessTab } from './detail/AccessTab'\nimport { ConfigurationTab } from './detail/ConfigurationTab'\nimport { SettingsTab } from './detail/SettingsTab'\nimport { ByolPlanModal } from './detail/ByolPlanModal'\nimport { DestroyPlanModal } from './detail/DestroyPlanModal'\nimport {\n OverviewIcon,\n ResourcesIcon,\n ActivityIcon,\n AccessIcon,\n ConfigurationIcon,\n SettingsIcon,\n type IconProps,\n} from './detail/icons'\n\n/** How often the detail view re-polls while a deployment is in flight. */\nconst PROVISIONING_POLL_MS = 4000\n\ntype Section = 'overview' | 'resources' | 'activity' | 'access' | 'config' | 'settings'\n\n// Inline-SVG icons (font-independent) rather than Unicode glyphs, which failed\n// to render in the platform shell font — see detail/icons.tsx.\nconst SECTIONS: Array<{ key: Section; label: string; Icon: React.FC<IconProps> }> = [\n { key: 'overview', label: 'Overview', Icon: OverviewIcon },\n { key: 'resources', label: 'Resources', Icon: ResourcesIcon },\n { key: 'activity', label: 'Activity', Icon: ActivityIcon },\n { key: 'access', label: 'Access', Icon: AccessIcon },\n { key: 'config', label: 'Configuration', Icon: ConfigurationIcon },\n { key: 'settings', label: 'Settings', Icon: SettingsIcon },\n]\n\nexport interface ByolInfrastructureDetailProps {\n apiBase: string\n /** The row the user clicked — rendered instantly, then refreshed from the API. */\n initialInfra: ByolInfrastructure\n configBase?: string\n configLinks?: ByolConfigLink[]\n onBack: () => void\n onEdit: (infra: ByolInfrastructure) => void\n onDeleted: () => void\n /** Called after any mutation so the parent list can refresh statuses. */\n onChanged: () => void\n /** Bumped by the parent (e.g. after an edit via the shared form) to force a reload. */\n reloadSignal?: number\n}\n\n/** Derive pseudo-resources from topology for the pre-deploy plan view. */\nfunction derivePlan(infra: ByolInfrastructure): ByolResource[] {\n const plan = buildByolResourcePlan({\n deploymentType: infra.deploymentType,\n indexerCount: infra.indexerCount,\n searchHeadCount: infra.searchHeadCount,\n hostingType: infra.hosting_type,\n isCloud: Boolean(infra.cloudProviderId),\n region: infra.region ?? null,\n indexerRegions: (infra.indexerRegions ?? []).map((r) => r.region),\n searchHeadRegions: (infra.searchHeadRegions ?? []).map((r) => r.region),\n })\n return plan.map((p) => ({\n id: p.planKey,\n infrastructureId: infra.id,\n tier: p.tier,\n kind: p.kind,\n name: p.name,\n role: p.role,\n region: p.region,\n status: 'not_started',\n externalRef: null,\n message: null,\n planKey: p.planKey,\n sortOrder: p.sortOrder,\n }))\n}\n\nfunction readSectionFromUrl(): Section | null {\n if (typeof window === 'undefined') return null\n const s = new URLSearchParams(window.location.search).get('section')\n return SECTIONS.some((x) => x.key === s) ? (s as Section) : null\n}\n\nexport const ByolInfrastructureDetail: React.FC<ByolInfrastructureDetailProps> = ({\n apiBase,\n initialInfra,\n configBase,\n configLinks,\n onBack,\n onEdit,\n onDeleted,\n onChanged,\n reloadSignal = 0,\n}) => {\n const [infra, setInfra] = useState<ByolInfrastructure>(initialInfra)\n const [resources, setResources] = useState<ByolResource[]>([])\n const [deployments, setDeployments] = useState<ByolDeployment[]>([])\n const [section, setSection] = useState<Section>(readSectionFromUrl() ?? 'overview')\n const [collapsed, setCollapsed] = useState(false)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n // --- Plan → Apply modal state ---\n const [planOpen, setPlanOpen] = useState(false)\n const [plan, setPlan] = useState<ByolPlan | null>(null)\n const [planLoading, setPlanLoading] = useState(false)\n const [planError, setPlanError] = useState<string | null>(null)\n const [applying, setApplying] = useState(false)\n\n // --- Destroy plan modal state ---\n // Mirrors the Plan → Apply flow above: \"Destroy infrastructure\" opens a modal\n // that previews exactly what will be torn down (every current resource, as a\n // destroy plan) rather than a generic yes/no text confirmation.\n const [destroyOpen, setDestroyOpen] = useState(false)\n const [destroyResources, setDestroyResources] = useState<ByolResource[] | null>(null)\n const [destroyLoading, setDestroyLoading] = useState(false)\n const [destroyError, setDestroyError] = useState<string | null>(null)\n const [destroying, setDestroying] = useState(false)\n\n // Danger-zone confirmation for Delete — the platform's real confirmation dialog\n // (portaled to document.body, themed via the host's brand tokens) when running\n // inside Veltrix; fails closed (no destructive action proceeds) outside it.\n // Replaces the native window.confirm() this view used to call directly. Destroy\n // uses the richer DestroyPlanModal below instead of this text confirmation.\n const { confirm } = useConfirmDialog()\n\n const id = initialInfra.id\n\n // Keep the latest list row available as a fallback without churning `load`.\n const initialRef = useRef(initialInfra)\n initialRef.current = initialInfra\n\n const load = useCallback(async () => {\n setError(null)\n try {\n const [freshInfra, res, deps] = await Promise.all([\n getInfra(apiBase, id).catch(() => initialRef.current),\n getResources(apiBase, id).catch(() => [] as ByolResource[]),\n getDeployments(apiBase, id).catch(() => [] as ByolDeployment[]),\n ])\n setInfra(freshInfra)\n setResources(res)\n setDeployments(deps)\n } catch (e) {\n setError((e as Error).message)\n } finally {\n setLoading(false)\n }\n }, [apiBase, id])\n\n useEffect(() => {\n void load()\n // reloadSignal is an explicit parent-driven refresh trigger.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [load, reloadSignal])\n\n // Reflect the open detail + section in the URL for refresh / deep-link.\n useEffect(() => {\n if (typeof window === 'undefined') return\n const params = new URLSearchParams(window.location.search)\n params.set('infra', id)\n params.set('section', section)\n window.history.replaceState(null, '', `${window.location.pathname}?${params.toString()}`)\n }, [id, section])\n\n const refresh = useCallback(async () => {\n await load()\n onChanged()\n }, [load, onChanged])\n\n // While a deployment (or teardown) is in flight, re-poll so the persisted\n // resource/step rows — and thus the ProgressMeter — animate toward terminal\n // state without the user having to hit Refresh. Cleared on unmount or as soon\n // as the status leaves the transient state.\n const transient = infra.status === 'provisioning' || infra.status === 'destroying'\n useEffect(() => {\n if (!transient) return\n let active = true\n const timer = setInterval(() => {\n if (active) void refresh()\n }, PROVISIONING_POLL_MS)\n return () => {\n active = false\n clearInterval(timer)\n }\n }, [transient, refresh])\n\n const runAction = useCallback(\n async (fn: () => Promise<unknown>) => {\n setBusy(true)\n setError(null)\n try {\n await fn()\n await refresh()\n } catch (e) {\n setError((e as Error).message)\n } finally {\n setBusy(false)\n }\n },\n [refresh],\n )\n\n // Deploy is now a two-phase flow: open the plan modal and fetch the dry-run\n // diff (spinner in the modal); Apply is what actually POSTs /deploy.\n const openPlan = useCallback(() => {\n setPlanOpen(true)\n setPlan(null)\n setPlanError(null)\n setPlanLoading(true)\n getPlan(apiBase, id)\n .then((p) => setPlan(p))\n .catch((e) => setPlanError((e as Error).message))\n .finally(() => setPlanLoading(false))\n }, [apiBase, id])\n\n const closePlan = useCallback(() => {\n if (applying) return\n setPlanOpen(false)\n }, [applying])\n\n const onApply = useCallback(async () => {\n setApplying(true)\n setPlanError(null)\n try {\n await deployInfra(apiBase, id)\n setPlanOpen(false)\n setSection('activity')\n await refresh()\n } catch (e) {\n setPlanError((e as Error).message)\n } finally {\n setApplying(false)\n }\n }, [apiBase, id, refresh])\n\n // Destroy is a two-phase flow, mirroring Deploy: open the destroy-plan modal\n // (a fresh resource fetch so the preview reflects reality even if `resources`\n // is stale), and only POST /destroy when the user confirms inside the modal.\n const openDestroy = useCallback(() => {\n setDestroyOpen(true)\n setDestroyError(null)\n setDestroyResources(null)\n setDestroyLoading(true)\n getResources(apiBase, id)\n .then((res) => setDestroyResources(res))\n // A failed refetch must never block Destroy — fall back to whatever the\n // detail view already has loaded (possibly empty; the modal handles that).\n .catch(() => setDestroyResources(resources))\n .finally(() => setDestroyLoading(false))\n }, [apiBase, id, resources])\n\n const closeDestroy = useCallback(() => {\n if (destroying) return\n setDestroyOpen(false)\n }, [destroying])\n\n const confirmDestroy = useCallback(async () => {\n setDestroying(true)\n setDestroyError(null)\n try {\n await destroyInfra(apiBase, id)\n setDestroyOpen(false)\n setSection('activity')\n await refresh()\n } catch (e) {\n setDestroyError((e as Error).message)\n } finally {\n setDestroying(false)\n }\n }, [apiBase, id, refresh])\n\n const onLifecycle = (action: 'start' | 'stop' | 'restart') => runAction(() => lifecycleInfra(apiBase, id, action))\n const onDelete = async () => {\n const ok = await confirm({\n title: 'Delete infrastructure record',\n message: `Delete \"${infra.name}\"? This cannot be undone.`,\n confirmText: 'Delete',\n cancelText: 'Cancel',\n variant: 'danger',\n })\n if (!ok) return\n setBusy(true)\n setError(null)\n try {\n const res = await import('../client').then(({ authFetch }) => authFetch(`${apiBase}/${id}`, { method: 'DELETE' }))\n if (!res.ok && res.status !== 204) throw new Error(await errorText(res))\n onDeleted()\n } catch (e) {\n setError((e as Error).message)\n setBusy(false)\n }\n }\n\n const status = infra.status\n const notStarted = isNotStarted(status)\n const failed = status === 'failed' || status === 'error'\n const provisioning = status === 'provisioning' || status === 'destroying'\n const running = isRunning(status)\n // A torn-down environment can be stood up again — re-provisioning re-runs the plan\n // against the now-empty state (resources were reset to not_started on teardown).\n const deprovisioned = status === 'deprovisioned' || status === 'decommissioned'\n\n // `deployments` is ordered newest-first (see `listDeployments` — ORDER BY\n // started_at DESC), so [0] is the run that produced the current failed\n // status. A failed *destroy* must retry the teardown, not re-provision —\n // defaults to the deploy retry path when no runs have loaded yet.\n const latestRunAction = deployments[0]?.action\n const failedDestroy = failed && latestRunAction === 'destroy'\n\n // Persisted plan when it exists; otherwise the derived plan (pre-deploy).\n const derived = resources.length === 0\n const displayResources = useMemo(\n () => (derived ? derivePlan(infra) : resources),\n [derived, infra, resources],\n )\n\n const provider = infra.hosting_type || (infra.cloudProviderId ? 'Cloud' : SELF_HOSTED_LABEL)\n\n const primaryAction = (() => {\n if (notStarted) return <Button variant=\"primary\" size=\"sm\" onClick={openPlan} disabled={busy}>Deploy environment</Button>\n if (deprovisioned) return <Button variant=\"primary\" size=\"sm\" onClick={openPlan} disabled={busy}>Re-provision</Button>\n if (failedDestroy) return <Button variant=\"danger\" size=\"sm\" onClick={openDestroy} disabled={busy}>Retry Destroy</Button>\n if (failed) return <Button variant=\"primary\" size=\"sm\" onClick={openPlan} disabled={busy}>Retry deployment</Button>\n if (provisioning) return <Button variant=\"primary\" size=\"sm\" onClick={() => setSection('activity')}>View progress</Button>\n return null\n })()\n\n const content = (() => {\n switch (section) {\n case 'overview':\n return <OverviewTab infra={infra} resources={displayResources} />\n case 'resources':\n return <ResourcesTab resources={displayResources} derived={derived} />\n case 'activity':\n return <ActivityTab deployments={deployments} />\n case 'access':\n return <AccessTab infra={infra} resources={resources} />\n case 'config':\n return <ConfigurationTab links={configLinks ?? []} configBase={configBase} />\n case 'settings':\n return (\n <SettingsTab\n infra={infra}\n busy={busy}\n onEdit={() => onEdit(infra)}\n onDestroy={openDestroy}\n onDelete={onDelete}\n />\n )\n }\n })()\n\n return (\n <div>\n <button\n onClick={onBack}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: 7,\n color: tokens.muted,\n fontSize: 13,\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n padding: 0,\n marginBottom: 12,\n }}\n >\n ‹ Back to infrastructure\n </button>\n\n <div style={{ border: `1px solid ${tokens.border}`, borderRadius: 12, background: tokens.surface, overflow: 'hidden' }}>\n {/* summary header */}\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '18px 24px', alignItems: 'flex-start', justifyContent: 'space-between', padding: 20 }}>\n <div style={{ minWidth: 260, flex: 1 }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>\n <h2 style={{ margin: 0, fontSize: 21, letterSpacing: '-.01em', color: tokens.text }}>{infra.name}</h2>\n <StatusPill status={status} />\n {loading ? <Spinner size=\"sm\" /> : null}\n </div>\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: '12px 20px', marginTop: 12 }}>\n <Meta label=\"Environment\">{infra.environmentType || '—'}</Meta>\n <Meta label=\"Deployment\">{infra.deploymentType ?? '—'}</Meta>\n <Meta label=\"Provider\">{provider}</Meta>\n <Meta label=\"Region\">{infra.region || '—'}</Meta>\n <Meta label=\"Updated\">{formatDate(infra.updatedAt)}</Meta>\n </div>\n <div style={{ marginTop: 14 }}>\n <ProgressMeter resources={displayResources} />\n </div>\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 10 }}>\n {primaryAction}\n <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', justifyContent: 'flex-end' }}>\n {running ? (\n <>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => onLifecycle('stop')} disabled={busy}>Stop</Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => onLifecycle('restart')} disabled={busy}>Restart</Button>\n </>\n ) : null}\n <Button variant=\"ghost\" size=\"sm\" onClick={() => onEdit(infra)} disabled={busy}>Edit topology</Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => void refresh()} disabled={busy}>Refresh</Button>\n </div>\n </div>\n </div>\n\n {error ? (\n <div style={{ padding: '0 20px 12px', color: tokens.danger, fontSize: 13 }}>{error}</div>\n ) : null}\n\n {/* secondary expandable sidebar + content */}\n <div style={{ display: 'flex', borderTop: `1px solid ${tokens.border}`, alignItems: 'stretch' }}>\n <aside\n style={{\n flex: `0 0 ${collapsed ? 56 : 220}px`,\n width: collapsed ? 56 : 220,\n borderRight: `1px solid ${tokens.border}`,\n background: tokens.surface2,\n padding: '14px 12px',\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n transition: 'flex-basis .12s, width .12s',\n }}\n >\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: collapsed ? 'center' : 'space-between', padding: '2px 6px 10px' }}>\n {collapsed ? null : (\n <span style={{ fontSize: 11, letterSpacing: '.1em', textTransform: 'uppercase', color: tokens.faint, fontWeight: 700 }}>\n This infrastructure\n </span>\n )}\n <button\n onClick={() => setCollapsed((c) => !c)}\n title={collapsed ? 'Expand' : 'Collapse'}\n aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}\n style={{\n border: `1px solid ${tokens.border}`,\n background: tokens.surface,\n color: tokens.muted,\n borderRadius: 6,\n width: 24,\n height: 24,\n cursor: 'pointer',\n lineHeight: 1,\n }}\n >\n {collapsed ? '»' : '«'}\n </button>\n </div>\n {SECTIONS.map((s) => {\n const active = s.key === section\n const { Icon } = s\n return (\n <button\n key={s.key}\n onClick={() => setSection(s.key)}\n title={s.label}\n style={{\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: collapsed ? 'center' : 'flex-start',\n gap: 11,\n padding: collapsed ? '9px 0' : '9px 10px',\n borderRadius: 8,\n border: 'none',\n background: active ? tokens.surface : 'transparent',\n color: active ? tokens.primary : tokens.muted,\n fontWeight: 600,\n fontSize: 13,\n cursor: 'pointer',\n textAlign: 'left',\n width: '100%',\n }}\n >\n {active ? (\n <span style={{ position: 'absolute', left: 0, top: 8, bottom: 8, width: 3, borderRadius: '0 3px 3px 0', background: tokens.primary }} />\n ) : null}\n <span style={{ width: 18, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flex: 'none' }}>\n <Icon size={16} />\n </span>\n {collapsed ? null : <span style={{ flex: 1 }}>{s.label}</span>}\n {!collapsed && s.key === 'resources' && displayResources.length > 0 ? (\n <span style={{ fontSize: 11, fontWeight: 600, color: tokens.faint }}>{displayResources.length}</span>\n ) : null}\n {!collapsed && s.key === 'activity' && provisioning ? (\n <span style={{ width: 7, height: 7, borderRadius: '50%', background: tokens.info }} />\n ) : null}\n </button>\n )\n })}\n </aside>\n\n <div style={{ flex: 1, minWidth: 0, padding: '22px 24px' }}>{content}</div>\n </div>\n </div>\n\n <ByolPlanModal\n isOpen={planOpen}\n onClose={closePlan}\n plan={plan}\n loading={planLoading}\n error={planError}\n applying={applying}\n onApply={onApply}\n infraName={infra.name}\n allowApplyWithoutChanges={infra.status === 'failed' || infra.status === 'error' || infra.status === 'not_started'}\n />\n\n <DestroyPlanModal\n isOpen={destroyOpen}\n onClose={closeDestroy}\n resources={destroyResources}\n loading={destroyLoading}\n error={destroyError}\n destroying={destroying}\n onConfirm={confirmDestroy}\n infraName={infra.name}\n />\n </div>\n )\n}\n\nexport default ByolInfrastructureDetail\n","// =============================================================================\n// Cluster placement: percent → integer node allocation.\n//\n// Shared by the topology builder (derives per-node site assignment) and the\n// form (live \"→ N nodes\" preview) so both agree exactly. Only the indexer and\n// search-head tiers use this; every other tier is single-site (main region).\n// =============================================================================\n\nimport type { ClusterPlacement, PlacementSite } from './types'\n\nexport interface SiteAllocation {\n site: string\n count: number\n /** The requested percent for this site (echoed for display / audit). */\n percent: number\n}\n\n/**\n * Allocate `totalNodes` across a cluster's sites by percent.\n *\n * Rules:\n * - Every listed site receives at least one node (a site in the plan must be real).\n * - The remaining nodes are distributed by percent using the largest-remainder\n * method, so the counts sum to exactly `totalNodes`.\n * - Deterministic: ties in the remainder are broken by site order (no RNG).\n *\n * Callers must ensure `sites.length <= totalNodes` (see {@link validatePlacement});\n * when that does not hold this still returns one node per site until it runs out,\n * so it never returns a negative count.\n */\nexport function allocateNodesBySite(totalNodes: number, sites: PlacementSite[]): SiteAllocation[] {\n const n = Math.max(0, Math.floor(totalNodes))\n const list = sites ?? []\n if (list.length === 0) return []\n\n // Floor of one per site, capped at the node budget.\n const base = list.map(() => 0)\n let assigned = 0\n for (let i = 0; i < list.length && assigned < n; i++) {\n base[i] = 1\n assigned++\n }\n\n const remaining = n - assigned\n if (remaining > 0) {\n // Largest-remainder distribution of the remaining nodes by percent.\n const totalPercent = list.reduce((sum, s) => sum + Math.max(0, s.percent), 0) || 1\n const ideal = list.map((s) => (Math.max(0, s.percent) / totalPercent) * remaining)\n const floors = ideal.map((v) => Math.floor(v))\n let leftover = remaining - floors.reduce((a, b) => a + b, 0)\n\n const order = list\n .map((_, i) => ({ i, frac: ideal[i] - floors[i] }))\n .sort((a, b) => b.frac - a.frac || a.i - b.i)\n\n for (let k = 0; k < order.length && leftover > 0; k++) {\n floors[order[k].i]++\n leftover--\n }\n for (let i = 0; i < list.length; i++) base[i] += floors[i]\n }\n\n return list.map((s, i) => ({ site: s.site, count: base[i], percent: s.percent }))\n}\n\n/**\n * Validate a cluster placement against a node count. Returns a human-readable\n * error string, or `null` when the placement is deployable.\n */\nexport function validatePlacement(placement: ClusterPlacement | undefined, totalNodes: number): string | null {\n if (!placement || placement.mode === 'single') return null\n const sites = placement.sites ?? []\n if (sites.length < 2) return 'Multi-site placement needs at least two sites.'\n\n const seen = new Set<string>()\n for (const s of sites) {\n if (!s.site || !s.site.trim()) return 'Every site must be selected.'\n if (seen.has(s.site)) return `Site \"${s.site}\" is listed more than once.`\n seen.add(s.site)\n if (!(s.percent > 0)) return `Site \"${s.site}\" must have a percent greater than zero.`\n }\n\n const sumPercent = sites.reduce((sum, s) => sum + s.percent, 0)\n if (Math.round(sumPercent) !== 100) return `Site percentages must total 100 (currently ${Math.round(sumPercent)}).`\n\n if (sites.length > Math.floor(totalNodes)) {\n return `Too many sites (${sites.length}) for ${totalNodes} node${totalNodes === 1 ? '' : 's'} — each site needs at least one node.`\n }\n return null\n}\n\n/**\n * Resolve the placement actually used for a tier: multi-site placement is only\n * honored for eligible (indexer / search-head) tiers; everything else collapses\n * to single-site so callers can treat the result uniformly.\n */\nexport function effectivePlacement(placement: ClusterPlacement | undefined, eligible: boolean): ClusterPlacement {\n if (!eligible || !placement || placement.mode !== 'multi-site') return { mode: 'single' }\n if (!placement.sites || placement.sites.length < 2) return { mode: 'single' }\n return placement\n}\n","// =============================================================================\n// BYOL resource-plan topology (pure, React-free).\n//\n// Given the shape of a BYOL infrastructure (deployment type, node counts,\n// provider, regions), this derives the FULL set of resources needed to stand up\n// and run an end-to-end Splunk environment — grouped into tiers, in provisioning\n// order. It is the single source of truth for \"what gets deployed\":\n//\n// • the app SERVER imports it (via the React-free root SDK entry) to SEED\n// `splunk_byol_resource` rows when a deployment is requested, and\n// • the app CLIENT renders it as the derived plan BEFORE the first deploy,\n// then swaps to the persisted rows once they exist.\n//\n// Keeping it here (and re-exported from the root entry) is what keeps both sides\n// DRY without the app duplicating the topology rules.\n// =============================================================================\n\nimport type { ClusterPlacement, ControlPlaneLayout } from './types'\nimport { effectivePlacement, allocateNodesBySite } from './placement'\n\n/** Coarse grouping used to lay the plan out by tier in the UI and DB. */\nexport type ByolResourceTier = 'foundation' | 'control-plane' | 'data' | 'search' | 'ingest'\n\n/** Lifecycle state of a single planned/provisioned resource. */\nexport type ByolResourceStatus = 'not_started' | 'provisioning' | 'ready' | 'attention' | 'failed'\n\n/** A stable machine kind for a resource, used for icons + worker correlation. */\nexport type ByolResourceKind =\n | 'network'\n | 'load-balancer'\n | 'dns'\n | 'tls'\n | 'storage'\n | 'secrets'\n | 'license-file'\n | 'license-manager'\n | 'cluster-manager'\n | 'sh-deployer'\n | 'deployment-server'\n | 'monitoring-console'\n | 'indexer'\n | 'search-head'\n | 'hec'\n | 'heavy-forwarder'\n | 'standalone'\n // A single instance running several combined control-plane management roles.\n | 'management-node'\n\n/** One resource in the plan. `planKey` is a stable identity for idempotent seeding. */\nexport interface ByolResourcePlanItem {\n planKey: string\n tier: ByolResourceTier\n kind: ByolResourceKind\n name: string\n role: string\n region: string | null\n /** Availability zone within `region` (multi-AZ placement); null otherwise. */\n zone?: string | null\n /** Machine-readable roles this instance runs — drives control-plane bring-up. */\n roles?: string[]\n}\n\nexport interface ByolTopologyInput {\n deploymentType?: string\n indexerCount?: number\n searchHeadCount?: number\n /** Display provider name, e.g. \"AWS\" or \"Self-Hosted\". */\n hostingType?: string\n /** Whether the deployment targets a cloud provider (vs Self-Hosted). */\n isCloud?: boolean\n /** Primary region + any per-node regions, in preference order. */\n region?: string | null\n indexerRegions?: string[]\n searchHeadRegions?: string[]\n /** Control-plane consolidation layout (distributed only). Defaults to 'dedicated'. */\n controlPlaneLayout?: ControlPlaneLayout\n /** Heavy forwarder count (distributed only). Defaults to 1. */\n heavyForwarderCount?: number\n /** Multi-site placement of the indexer cluster (indexer/search tiers only). */\n indexerPlacement?: ClusterPlacement | null\n /** Multi-site placement of the search-head cluster. */\n searchHeadPlacement?: ClusterPlacement | null\n}\n\n/** A control-plane management role that can be dedicated or combined onto a node. */\ntype ControlPlaneRole =\n | 'license-manager'\n | 'cluster-manager'\n | 'sh-deployer'\n | 'deployment-server'\n | 'monitoring-console'\n\nconst CONTROL_PLANE_ROLE_META: Record<ControlPlaneRole, { kind: ByolResourceKind; name: string; role: string }> = {\n 'license-manager': { kind: 'license-manager', name: 'License Manager', role: 'Serves BYOL license pool' },\n 'cluster-manager': { kind: 'cluster-manager', name: 'Cluster Manager', role: 'Indexer cluster coordinator' },\n 'sh-deployer': { kind: 'sh-deployer', name: 'SH Deployer', role: 'Search head cluster deployer' },\n 'deployment-server': { kind: 'deployment-server', name: 'Deployment Server', role: 'Forwarder app distribution' },\n 'monitoring-console': { kind: 'monitoring-console', name: 'Monitoring Console', role: 'Fleet health & DMC' },\n}\n\n/**\n * Group the five management roles into instances per consolidation layout.\n * The cluster manager and SH deployer stay isolated when consolidating (they\n * coordinate the indexer/search-head clusters and must not co-locate with the\n * peers or each other under HA); only the lighter roles combine.\n */\nfunction controlPlaneGroups(layout: ControlPlaneLayout): ControlPlaneRole[][] {\n switch (layout) {\n case 'single':\n return [['license-manager', 'cluster-manager', 'sh-deployer', 'deployment-server', 'monitoring-console']]\n case 'consolidated':\n return [['cluster-manager'], ['sh-deployer'], ['license-manager', 'deployment-server', 'monitoring-console']]\n case 'dedicated':\n default:\n return [['license-manager'], ['cluster-manager'], ['sh-deployer'], ['deployment-server'], ['monitoring-console']]\n }\n}\n\n/** Build the control-plane instances for a layout (each running one or more roles). */\nfunction buildControlPlane(layout: ControlPlaneLayout, region: string | null): ByolResourcePlanItem[] {\n return controlPlaneGroups(layout).map((roles) => {\n if (roles.length === 1) {\n const meta = CONTROL_PLANE_ROLE_META[roles[0]]\n return { planKey: `control-plane/${roles[0]}`, tier: 'control-plane', kind: meta.kind, name: meta.name, role: meta.role, region, roles: [roles[0]] }\n }\n const label = roles.map((r) => CONTROL_PLANE_ROLE_META[r].name).join(' · ')\n return {\n planKey: 'control-plane/management',\n tier: 'control-plane',\n kind: 'management-node',\n name: roles.length >= 5 ? 'Management node (all roles)' : 'Management node',\n role: label,\n region,\n roles: [...roles],\n }\n })\n}\n\ninterface NodeSite {\n region: string | null\n zone: string | null\n}\n\n/**\n * Resolve the per-node region/zone for a cluster tier. Multi-site placement\n * (indexer/search only) spreads nodes across sites by percent: AZ granularity\n * keeps the main region and varies the zone; region granularity varies the\n * region. Falls back to the legacy per-node region round-robin otherwise.\n */\nfunction assignNodeSites(\n count: number,\n placement: ClusterPlacement | null | undefined,\n primaryRegion: string | null,\n legacyRegions: string[] | undefined,\n): NodeSite[] {\n const eff = effectivePlacement(placement ?? undefined, true)\n if (eff.mode === 'multi-site' && eff.sites && eff.sites.length >= 2) {\n const granularity = eff.granularity ?? 'az'\n const out: NodeSite[] = []\n for (const alloc of allocateNodesBySite(count, eff.sites)) {\n for (let k = 0; k < alloc.count; k++) {\n out.push(granularity === 'az' ? { region: primaryRegion, zone: alloc.site } : { region: alloc.site, zone: null })\n }\n }\n return out\n }\n const out: NodeSite[] = []\n for (let i = 0; i < count; i++) out.push({ region: pickRegion(legacyRegions, i, primaryRegion), zone: null })\n return out\n}\n\nexport const TIER_LABELS: Record<ByolResourceTier, string> = {\n foundation: 'Foundation',\n 'control-plane': 'Control plane',\n data: 'Data tier — indexer cluster',\n search: 'Search tier — search head cluster',\n ingest: 'Ingest & access',\n}\n\n/** Provisioning order the tiers deploy in (also the display order). */\nexport const TIER_ORDER: ByolResourceTier[] = ['foundation', 'control-plane', 'data', 'search', 'ingest']\n\nconst DISTRIBUTED = 'distributed'\n\n/** Pick a region for a node: its own region list, else the primary, else null. */\nfunction pickRegion(regions: string[] | undefined, index: number, fallback: string | null): string | null {\n if (regions && regions.length > 0) return regions[index % regions.length]\n return fallback\n}\n\n/**\n * Build the ordered resource plan for a BYOL infrastructure.\n *\n * A single-instance deployment collapses to an all-in-one Splunk node plus the\n * foundation. A distributed deployment expands to the full topology: control\n * plane (license/cluster managers, deployment server, monitoring console, SH\n * deployer), an N-peer indexer cluster, an M-member search-head cluster, and the\n * ingest path (HEC + heavy forwarders).\n */\nexport function buildByolResourcePlan(input: ByolTopologyInput): ByolResourcePlanItemWithOrder[] {\n const distributed = (input.deploymentType ?? 'single') === DISTRIBUTED\n const primaryRegion = input.region ?? null\n const isCloud = input.isCloud ?? false\n const items: ByolResourcePlanItem[] = []\n\n // --- Foundation ----------------------------------------------------------\n items.push({ planKey: 'foundation/network', tier: 'foundation', kind: 'network', name: 'Network', role: 'VPC · subnets · security groups', region: primaryRegion })\n if (distributed && isCloud) {\n items.push({ planKey: 'foundation/load-balancer', tier: 'foundation', kind: 'load-balancer', name: 'Load balancer', role: 'Search + HEC ingress', region: primaryRegion })\n items.push({ planKey: 'foundation/dns', tier: 'foundation', kind: 'dns', name: 'DNS', role: 'Public + private records', region: 'global' })\n }\n items.push({ planKey: 'foundation/tls', tier: 'foundation', kind: 'tls', name: 'TLS certificates', role: 'Web + inter-node (S2S)', region: null })\n items.push({ planKey: 'foundation/storage', tier: 'foundation', kind: 'storage', name: 'Storage', role: distributed ? 'SmartStore + hot/warm volumes' : 'Index volumes', region: primaryRegion })\n items.push({ planKey: 'foundation/secrets', tier: 'foundation', kind: 'secrets', name: 'Secrets', role: 'Admin password · pass4SymmKey', region: null })\n items.push({ planKey: 'foundation/license-file', tier: 'foundation', kind: 'license-file', name: 'BYOL license file', role: 'Uploaded & validated', region: null })\n\n if (!distributed) {\n // --- Single instance: all-in-one node --------------------------------\n items.push({ planKey: 'data/standalone', tier: 'data', kind: 'standalone', name: 'Splunk instance', role: 'All-in-one (indexer + search head + web)', region: primaryRegion })\n items.push({ planKey: 'ingest/hec', tier: 'ingest', kind: 'hec', name: 'HTTP Event Collector', role: 'Token endpoint', region: primaryRegion })\n return items.map((it, i) => stampOrder(it, i))\n }\n\n // --- Control plane -------------------------------------------------------\n // Always in the main region; consolidation only changes how many instances the\n // management roles run on.\n items.push(...buildControlPlane(input.controlPlaneLayout ?? 'dedicated', primaryRegion))\n\n // --- Data tier: indexer cluster -----------------------------------------\n // Only this tier and the search tier accept multi-site placement; every other\n // tier stays in the main region.\n const indexerCount = Math.max(1, input.indexerCount ?? 1)\n const indexerSites = assignNodeSites(indexerCount, input.indexerPlacement, primaryRegion, input.indexerRegions)\n for (let i = 0; i < indexerCount; i++) {\n items.push({\n planKey: `data/indexer-${i + 1}`,\n tier: 'data',\n kind: 'indexer',\n name: `Indexer peer ${i + 1}`,\n role: 'Cluster peer node',\n region: indexerSites[i].region,\n zone: indexerSites[i].zone,\n })\n }\n\n // --- Search tier: search head cluster -----------------------------------\n const searchHeadCount = Math.max(1, input.searchHeadCount ?? 1)\n const searchHeadSites = assignNodeSites(searchHeadCount, input.searchHeadPlacement, primaryRegion, input.searchHeadRegions)\n for (let i = 0; i < searchHeadCount; i++) {\n items.push({\n planKey: `search/search-head-${i + 1}`,\n tier: 'search',\n kind: 'search-head',\n name: `Search head ${i + 1}`,\n role: i === 0 ? 'SHC captain candidate' : 'SHC member',\n region: searchHeadSites[i].region,\n zone: searchHeadSites[i].zone,\n })\n }\n\n // --- Ingest & access -----------------------------------------------------\n // Ingest is always main-region. Heavy forwarders default to 1; more on demand.\n items.push({ planKey: 'ingest/hec', tier: 'ingest', kind: 'hec', name: 'HTTP Event Collector', role: 'Token endpoint via LB', region: primaryRegion })\n const heavyForwarderCount = Math.max(1, input.heavyForwarderCount ?? 1)\n for (let i = 0; i < heavyForwarderCount; i++) {\n items.push({\n planKey: `ingest/heavy-forwarder-${i + 1}`,\n tier: 'ingest',\n kind: 'heavy-forwarder',\n name: `Heavy Forwarder ${i + 1}`,\n role: 'Ingest routing / props',\n region: primaryRegion,\n })\n }\n\n return items.map((it, i) => stampOrder(it, i))\n}\n\n/** Attach the plan's stable sort order (kept separate so callers can persist it). */\nfunction stampOrder(item: ByolResourcePlanItem, index: number): ByolResourcePlanItem & { sortOrder: number } {\n return { ...item, sortOrder: index }\n}\n\nexport type ByolResourcePlanItemWithOrder = ReturnType<typeof stampOrder>\n\n/**\n * The ordered high-level steps a deployment run advances through. Mirrors the\n * tier order plus the post-deploy phases. Workers report progress against these.\n */\nexport const DEPLOYMENT_STEPS: Array<{ key: string; title: string; detail: string }> = [\n { key: 'plan', title: 'Plan created', detail: 'Resources planned from topology; desired state recorded.' },\n { key: 'foundation', title: 'Provision foundation', detail: 'Network, load balancer, DNS, TLS, storage and secrets.' },\n { key: 'license', title: 'License Manager online · license applied', detail: 'BYOL license validated and pool published.' },\n { key: 'cluster', title: 'Cluster Manager online', detail: 'Indexer cluster policy (RF/SF) published.' },\n { key: 'indexers', title: 'Indexer peers joining cluster', detail: 'Indexer peers boot and register with the cluster manager.' },\n { key: 'search-heads', title: 'Search head cluster forming', detail: 'Deployer pushes the SHC bundle; captain election.' },\n { key: 'services', title: 'Deployment server & monitoring console', detail: 'Ancillary control-plane services come online.' },\n { key: 'post-config', title: 'Post-deploy configuration', detail: 'Apply indexes, HEC tokens and Splunk apps.' },\n { key: 'health', title: 'End-to-end health check', detail: 'Verify search, ingest and replication end to end.' },\n]\n","import React from 'react'\nimport { StatsCard } from '../../ui'\nimport type { ByolInfrastructure, ByolResource } from '../types'\nimport { tokens, Panel } from './shared'\n\nexport interface OverviewTabProps {\n infra: ByolInfrastructure\n resources: ByolResource[]\n}\n\n/** At-a-glance stats + a plain-language summary of what the environment comprises. */\nexport const OverviewTab: React.FC<OverviewTabProps> = ({ infra, resources }) => {\n const distributed = infra.deploymentType === 'distributed'\n const regionCount = new Set(\n resources.map((r) => r.region).filter((r): r is string => Boolean(r) && r !== 'global'),\n ).size\n const readyCount = resources.filter((r) => r.status === 'ready').length\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: 12 }}>\n <StatsCard label=\"Indexer peers\" value={infra.indexerCount ?? '—'} />\n <StatsCard label=\"Search heads\" value={infra.searchHeadCount ?? '—'} />\n <StatsCard label=\"Regions\" value={regionCount || (infra.region ? 1 : '—')} />\n <StatsCard\n label={resources.length ? 'Resources ready' : 'Resources planned'}\n value={resources.length ? `${readyCount} / ${resources.length}` : '—'}\n />\n </div>\n\n <Panel title=\"What gets deployed\">\n <p style={{ margin: 0, fontSize: 13, lineHeight: 1.6, color: tokens.muted }}>\n {distributed ? (\n <>\n A distributed BYOL environment provisions a full Splunk topology: a foundation tier (network, load balancing,\n DNS, TLS, storage/SmartStore, secrets and your license file), a control plane (license manager, cluster\n manager, deployment server, monitoring console and search-head deployer), an{' '}\n {infra.indexerCount}-peer indexer cluster, a {infra.searchHeadCount}-member search-head cluster, and the ingest\n path (HEC + heavy forwarders).\n </>\n ) : (\n <>\n A single-instance BYOL environment provisions the foundation (network, TLS, storage, secrets and your license\n file) plus one all-in-one Splunk node (indexer + search head + web) and an HTTP Event Collector endpoint.\n </>\n )}{' '}\n See the <strong>Resources</strong> tab for the live plan and <strong>Activity</strong> for the run log.\n </p>\n </Panel>\n </div>\n )\n}\n","import React from 'react'\nimport { EmptyState } from '../../ui'\nimport { TIER_ORDER, TIER_LABELS, type ByolResourceTier } from '../topology'\nimport type { ByolResource } from '../types'\nimport { tokens, ResourcePill } from './shared'\n\nconst STRIPE: Record<string, string> = {\n ready: tokens.success,\n provisioning: tokens.info,\n attention: tokens.warning,\n failed: tokens.danger,\n not_started: tokens.borderStrong,\n}\n\nconst LEGEND: Array<{ status: string; label: string }> = [\n { status: 'ready', label: 'Ready' },\n { status: 'provisioning', label: 'Provisioning' },\n { status: 'attention', label: 'Attention' },\n { status: 'failed', label: 'Failed' },\n { status: 'not_started', label: 'Not started' },\n]\n\nconst ResourceCard: React.FC<{ resource: ByolResource }> = ({ resource }) => (\n <div\n style={{\n position: 'relative',\n border: `1px solid ${tokens.border}`,\n borderRadius: 8,\n background: tokens.surface,\n padding: '12px 13px',\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n overflow: 'hidden',\n }}\n >\n <span style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: 3, background: STRIPE[resource.status] ?? STRIPE.not_started }} />\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>\n <span style={{ fontWeight: 600, fontSize: 13, color: tokens.text }}>{resource.name}</span>\n <ResourcePill status={resource.status} />\n </div>\n {resource.role ? <div style={{ fontSize: 11, color: tokens.faint }}>{resource.role}</div> : null}\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8, fontSize: 11, color: tokens.muted }}>\n <span>{resource.zone ? `${resource.region ?? ''} · ${resource.zone}` : resource.region || '—'}</span>\n <span style={{ fontFamily: 'var(--font-mono, ui-monospace, monospace)', color: tokens.faint }}>\n {resource.externalRef || '—'}\n </span>\n </div>\n </div>\n)\n\nexport interface ResourcesTabProps {\n resources: ByolResource[]\n /** True when the plan is derived from topology (never deployed yet). */\n derived: boolean\n}\n\n/**\n * The full end-to-end resource plan, grouped by tier in provisioning order. Each\n * card shows a resource's role, region, status and (once provisioned) its\n * external reference. Before the first deploy this shows the DERIVED plan — what\n * WILL be provisioned — with a hint to deploy.\n */\nexport const ResourcesTab: React.FC<ResourcesTabProps> = ({ resources, derived }) => {\n if (resources.length === 0) {\n return (\n <EmptyState\n title=\"No resources planned\"\n description=\"This infrastructure has no derivable topology yet. Check the deployment type and node counts in Settings.\"\n />\n )\n }\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>\n {derived ? (\n <div\n style={{\n fontSize: 13,\n color: tokens.muted,\n background: tokens.surface2,\n border: `1px solid ${tokens.border}`,\n borderRadius: 8,\n padding: '10px 14px',\n }}\n >\n This is the plan derived from the topology — the resources that <strong>will</strong> be provisioned. Deploy the\n environment to begin creating them.\n </div>\n ) : null}\n\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 14, fontSize: 12, color: tokens.muted }}>\n {LEGEND.map((l) => (\n <span key={l.status} style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>\n <span style={{ width: 8, height: 8, borderRadius: '50%', background: STRIPE[l.status] }} />\n {l.label}\n </span>\n ))}\n </div>\n\n {TIER_ORDER.map((tier) => {\n const inTier = resources.filter((r) => r.tier === (tier as ByolResourceTier))\n if (inTier.length === 0) return null\n const ready = inTier.filter((r) => r.status === 'ready').length\n return (\n <div key={tier}>\n <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, marginBottom: 9 }}>\n <h3\n style={{\n margin: 0,\n fontSize: 12,\n letterSpacing: '.08em',\n textTransform: 'uppercase',\n color: tokens.primary,\n }}\n >\n {TIER_LABELS[tier as ByolResourceTier]}\n </h3>\n <span style={{ fontSize: 12, color: tokens.faint, fontVariantNumeric: 'tabular-nums' }}>\n {inTier.length} {inTier.length === 1 ? 'resource' : 'resources'}\n {!derived ? ` · ${ready} ready` : ''}\n </span>\n </div>\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(232px, 1fr))', gap: 10 }}>\n {inTier.map((r) => (\n <ResourceCard key={r.planKey} resource={r} />\n ))}\n </div>\n </div>\n )\n })}\n </div>\n )\n}\n","import React from 'react'\nimport { EmptyState, Badge } from '../../ui'\nimport { formatDateTime } from '../api'\nimport { stepStatusVariant } from '../status'\nimport type { ByolDeployment, ByolDeploymentStep } from '../types'\nimport { tokens } from './shared'\n\nconst NODE_COLOR: Record<string, string> = {\n done: tokens.success,\n running: tokens.info,\n failed: tokens.danger,\n pending: tokens.borderStrong,\n}\n\nconst StepNode: React.FC<{ step: ByolDeploymentStep; last: boolean }> = ({ step, last }) => (\n <div style={{ position: 'relative', paddingBottom: last ? 0 : 20 }}>\n <span\n style={{\n position: 'absolute',\n left: -24,\n top: 2,\n width: 16,\n height: 16,\n borderRadius: '50%',\n background: NODE_COLOR[step.status] ?? NODE_COLOR.pending,\n border: `3px solid ${tokens.surface}`,\n boxShadow: `0 0 0 1px ${tokens.border}`,\n }}\n />\n <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>\n <span style={{ fontWeight: 600, fontSize: 14, color: tokens.text }}>{step.title}</span>\n <Badge variant={stepStatusVariant(step.status)} size=\"sm\">\n {step.status}\n </Badge>\n <span style={{ fontSize: 12, color: tokens.faint }}>\n {step.completedAt ? formatDateTime(step.completedAt) : step.startedAt ? formatDateTime(step.startedAt) : ''}\n </span>\n </div>\n {step.detail ? <div style={{ fontSize: 13, color: tokens.muted, marginTop: 3 }}>{step.detail}</div> : null}\n {step.logs ? (\n <pre\n style={{\n marginTop: 8,\n background: tokens.surface2,\n border: `1px solid ${tokens.border}`,\n borderRadius: 8,\n padding: '9px 12px',\n fontFamily: 'var(--font-mono, ui-monospace, monospace)',\n fontSize: 11.5,\n color: tokens.muted,\n whiteSpace: 'pre-wrap',\n overflowX: 'auto',\n }}\n >\n {step.logs}\n </pre>\n ) : null}\n </div>\n)\n\nconst RunTimeline: React.FC<{ run: ByolDeployment }> = ({ run }) => (\n <div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14, flexWrap: 'wrap' }}>\n <h3 style={{ margin: 0, fontSize: 14, fontWeight: 600, color: tokens.text, textTransform: 'capitalize' }}>\n {run.action} run\n </h3>\n <Badge variant={run.status === 'succeeded' ? 'success' : run.status === 'failed' ? 'danger' : 'info'} size=\"sm\">\n {run.status}\n </Badge>\n <span style={{ fontSize: 12, color: tokens.faint }}>started {formatDateTime(run.startedAt)}</span>\n </div>\n <div style={{ position: 'relative', paddingLeft: 26 }}>\n <span style={{ position: 'absolute', left: 8, top: 4, bottom: 4, width: 2, background: tokens.border }} />\n {run.steps.map((s, i) => (\n <StepNode key={s.id || s.key} step={s} last={i === run.steps.length - 1} />\n ))}\n </div>\n </div>\n)\n\nexport interface ActivityTabProps {\n deployments: ByolDeployment[]\n}\n\n/** The deployment run log: the latest run as a live timeline, older runs below. */\nexport const ActivityTab: React.FC<ActivityTabProps> = ({ deployments }) => {\n if (deployments.length === 0) {\n return (\n <EmptyState\n title=\"No deployment activity yet\"\n description=\"When you deploy this environment, each provisioning step will stream here.\"\n />\n )\n }\n const [latest, ...previous] = deployments\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 28 }}>\n <RunTimeline run={latest} />\n {previous.length > 0 ? (\n <div>\n <h4 style={{ margin: '0 0 10px', fontSize: 12, letterSpacing: '.06em', textTransform: 'uppercase', color: tokens.faint }}>\n Earlier runs\n </h4>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {previous.map((run) => (\n <div\n key={run.id}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 10,\n padding: '10px 14px',\n border: `1px solid ${tokens.border}`,\n borderRadius: 8,\n background: tokens.surface,\n fontSize: 13,\n }}\n >\n <span style={{ textTransform: 'capitalize', color: tokens.text }}>{run.action}</span>\n <span style={{ color: tokens.faint }}>{formatDateTime(run.startedAt)}</span>\n <Badge variant={run.status === 'succeeded' ? 'success' : run.status === 'failed' ? 'danger' : 'info'} size=\"sm\">\n {run.status}\n </Badge>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n )\n}\n","import React from 'react'\nimport { EmptyState } from '../../ui'\nimport { isRunning } from '../status'\nimport type { ByolInfrastructure, ByolResource } from '../types'\nimport { tokens, Panel } from './shared'\n\nconst mono = 'var(--font-mono, ui-monospace, monospace)'\n\n/**\n * Resolve a usable network host from a resource's external ref. The provisioner\n * reports the managed DNS FQDN (`foundation/dns`) and the load balancer's DNS\n * name (`ingest/hec` → the ALB `dns_name`) as real hostnames; other refs are\n * ARNs, ids, or — before real provisioning has reported anything — placeholders.\n * Only a value that is genuinely a hostname or URL is returned; everything else\n * yields null so the UI never presents a non-reachable string as an endpoint.\n */\nfunction asHost(ref: string | null | undefined): string | null {\n if (!ref) return null\n const v = ref.trim()\n if (/^https?:\\/\\//i.test(v)) {\n try {\n return new URL(v).host\n } catch {\n return null\n }\n }\n // A DNS hostname: dot-separated labels, alphanumerics/hyphens, TLD ≥ 2 chars.\n const HOSTNAME = /^(?=.{1,253}$)([a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z]{2,}$/i\n return HOSTNAME.test(v) ? v : null\n}\n\nconst Row: React.FC<{ label: string; value: string }> = ({ label, value }) => (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: '180px 1fr',\n gap: 16,\n alignItems: 'center',\n padding: '11px 0',\n borderBottom: `1px solid ${tokens.border}`,\n fontSize: 13,\n }}\n >\n <span style={{ color: tokens.muted }}>{label}</span>\n <span style={{ fontFamily: mono, fontSize: 12.5, color: tokens.text, overflowWrap: 'anywhere' }}>{value}</span>\n </div>\n)\n\nexport interface AccessTabProps {\n infra: ByolInfrastructure\n resources: ByolResource[]\n}\n\n/**\n * How to reach the environment once it is running. Every endpoint is derived\n * from the REAL external references the provisioning worker writes onto the\n * resource rows (the managed DNS name, the load balancer, the indexer peers) —\n * nothing is fabricated. Until the worker has reported a reachable endpoint, the\n * tab says so plainly rather than inventing a placeholder host.\n */\nexport const AccessTab: React.FC<AccessTabProps> = ({ infra, resources }) => {\n if (!isRunning(infra.status)) {\n return (\n <EmptyState\n title=\"Endpoints appear once the environment is running\"\n description=\"Deploy the environment; when the search tier is up, its Splunk Web, management and HEC endpoints show here.\"\n />\n )\n }\n\n const refOf = (planKey: string): string | null =>\n resources.find((r) => r.planKey === planKey)?.externalRef ?? null\n\n // Managed DNS FQDN is the friendly host for Splunk Web + management; the ALB\n // DNS name (reported on ingest/hec) is where HEC lives and a fallback host.\n const dnsHost = asHost(refOf('foundation/dns'))\n const albHost = asHost(refOf('ingest/hec'))\n const webHost = dnsHost ?? albHost\n const hecHost = albHost ?? dnsHost\n\n // Forwarder targets: only indexer peers that have reported a real address.\n const indexerTargets = resources\n .filter((r) => r.kind === 'indexer')\n .map((r) => asHost(r.externalRef))\n .filter((h): h is string => Boolean(h))\n .map((h) => `${h}:9997`)\n\n const endpoints: Array<{ label: string; value: string }> = []\n if (webHost) {\n endpoints.push({ label: 'Splunk Web (search)', value: `https://${webHost}` })\n endpoints.push({ label: 'Management API', value: `https://${webHost}:8089` })\n }\n if (hecHost) {\n endpoints.push({ label: 'HTTP Event Collector', value: `https://${hecHost}:8088/services/collector` })\n }\n\n // Running, but the worker hasn't published a reachable endpoint yet (e.g. the\n // load balancer / DNS name is still settling). Be honest — no invented host.\n if (endpoints.length === 0) {\n return (\n <Panel title=\"Endpoints\">\n <p style={{ margin: 0, fontSize: 13, lineHeight: 1.6, color: tokens.muted }}>\n The environment is running, but the provisioner has not reported a reachable endpoint yet.\n Splunk Web, the management API and the HTTP Event Collector URL appear here as soon as the\n load balancer and DNS name are published. Check the <strong>Resources</strong> tab for each\n component&rsquo;s external reference.\n </p>\n </Panel>\n )\n }\n\n const tcpoutGroup = infra.name.toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '') || 'veltrix_splunk'\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>\n <Panel title=\"Endpoints\">\n {endpoints.map((e) => (\n <Row key={e.label} label={e.label} value={e.value} />\n ))}\n </Panel>\n\n <Panel title=\"Point a forwarder at this environment\">\n {indexerTargets.length > 0 ? (\n <>\n <p style={{ margin: '0 0 12px', fontSize: 13, color: tokens.muted }}>\n Add this to a universal forwarder&rsquo;s <span style={{ fontFamily: mono }}>outputs.conf</span>:\n </p>\n <pre\n style={{\n margin: 0,\n background: tokens.surface2,\n border: `1px solid ${tokens.border}`,\n borderRadius: 8,\n padding: '13px 15px',\n fontFamily: mono,\n fontSize: 12,\n color: tokens.text,\n overflowX: 'auto',\n }}\n >\n {`[tcpout]\ndefaultGroup = ${tcpoutGroup}\n\n[tcpout:${tcpoutGroup}]\nserver = ${indexerTargets.join(', ')}\nsslVerifyServerCert = true`}\n </pre>\n </>\n ) : (\n <p style={{ margin: 0, fontSize: 13, color: tokens.muted }}>\n Forwarder targets appear here once the indexer peers report their addresses.\n </p>\n )}\n </Panel>\n </div>\n )\n}\n","import React from 'react'\nimport { EmptyState } from '../../ui'\nimport type { ByolConfigLink } from '../types'\nimport { tokens } from './shared'\n\nexport interface ConfigurationTabProps {\n /** App-supplied configuration links (the SDK stays app-agnostic). */\n links: ByolConfigLink[]\n /** Base path to config canvases, e.g. `/apps/splunk-enterprise/config`. */\n configBase?: string\n}\n\n/** Deep-links to the app's configuration surfaces — configure the running env. */\nexport const ConfigurationTab: React.FC<ConfigurationTabProps> = ({ links, configBase }) => {\n if (!links || links.length === 0) {\n return (\n <EmptyState\n title=\"No configuration surfaces linked\"\n description=\"This app has not surfaced any configuration links for its BYOL environments.\"\n />\n )\n }\n\n const resolve = (link: ByolConfigLink): string | undefined => {\n if (configBase && link.configTypeId) return `${configBase}/${link.configTypeId}`\n return link.href\n }\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>\n <p style={{ margin: 0, fontSize: 13, color: tokens.muted }}>\n Once the environment is running, configure it as code. These open the app&rsquo;s configuration surfaces.\n </p>\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))', gap: 12 }}>\n {links.map((link) => {\n const url = resolve(link)\n const inner = (\n <>\n <h4 style={{ margin: '0 0 4px', fontSize: 13, display: 'flex', justifyContent: 'space-between', color: tokens.text }}>\n {link.title}\n <span style={{ color: tokens.faint }} aria-hidden>\n ↗\n </span>\n </h4>\n <p style={{ margin: 0, fontSize: 12, color: tokens.muted }}>{link.description}</p>\n </>\n )\n const cardStyle: React.CSSProperties = {\n border: `1px solid ${tokens.border}`,\n borderRadius: 8,\n padding: 14,\n background: tokens.surface,\n textDecoration: 'none',\n color: 'inherit',\n display: 'block',\n cursor: url ? 'pointer' : 'default',\n opacity: url ? 1 : 0.7,\n }\n return url ? (\n <a key={link.key} href={url} style={cardStyle}>\n {inner}\n </a>\n ) : (\n <div key={link.key} style={cardStyle} title=\"This link is unavailable here\">\n {inner}\n </div>\n )\n })}\n </div>\n </div>\n )\n}\n","import React from 'react'\nimport { Button } from '../../ui'\nimport { SELF_HOSTED_LABEL, type ByolInfrastructure } from '../types'\nimport { isNotStarted } from '../status'\nimport { tokens, Panel } from './shared'\n\nconst Row: React.FC<{ label: string; value: React.ReactNode }> = ({ label, value }) => (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: '200px 1fr',\n gap: 16,\n padding: '11px 0',\n borderBottom: `1px solid ${tokens.border}`,\n fontSize: 13,\n }}\n >\n <span style={{ color: tokens.muted }}>{label}</span>\n <span style={{ color: tokens.text, fontWeight: 600 }}>{value}</span>\n </div>\n)\n\nexport interface SettingsTabProps {\n infra: ByolInfrastructure\n busy: boolean\n onEdit: () => void\n onDestroy: () => void\n onDelete: () => void\n}\n\n/** Topology summary + the danger zone (destroy / delete). */\nexport const SettingsTab: React.FC<SettingsTabProps> = ({ infra, busy, onEdit, onDestroy, onDelete }) => {\n const provider = infra.hosting_type || (infra.cloudProviderId ? 'Cloud' : SELF_HOSTED_LABEL)\n const neverDeployed = isNotStarted(infra.status)\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>\n <Panel\n title=\"Topology\"\n actions={\n <Button variant=\"ghost\" size=\"sm\" onClick={onEdit} disabled={busy}>\n Edit\n </Button>\n }\n >\n <Row label=\"Name\" value={infra.name} />\n <Row label=\"Deployment type\" value={infra.deploymentType ?? '—'} />\n <Row label=\"Indexers / Search heads\" value={`${infra.indexerCount ?? '—'} / ${infra.searchHeadCount ?? '—'}`} />\n <Row label=\"Provider\" value={provider} />\n <Row label=\"Region\" value={infra.region || '—'} />\n <Row label=\"Environment\" value={infra.environmentType || '—'} />\n </Panel>\n\n <div style={{ border: `1px solid ${tokens.danger}`, borderRadius: 12, padding: '16px 18px' }}>\n <h3 style={{ margin: '0 0 4px', fontSize: 14, color: tokens.danger }}>Danger zone</h3>\n <p style={{ margin: '0 0 12px', fontSize: 13, color: tokens.muted }}>\n {neverDeployed\n ? 'This environment has not been deployed. Deleting removes the record and its plan.'\n : 'Destroy tears down every resource in the plan — instances, storage, network. This cannot be undone.'}\n </p>\n <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>\n {!neverDeployed ? (\n <Button variant=\"ghost\" size=\"sm\" onClick={onDestroy} disabled={busy}>\n Destroy infrastructure\n </Button>\n ) : null}\n <Button variant=\"danger\" size=\"sm\" onClick={onDelete} disabled={busy}>\n Delete record\n </Button>\n </div>\n </div>\n </div>\n )\n}\n","import React from 'react'\nimport { Modal, Button, Badge, Spinner } from '../../ui'\nimport { planHasChanges, type ByolPlan } from '../diffPlan'\nimport { tokens } from './shared'\nimport { PlanGroup } from './planLines'\n\n// =============================================================================\n// ByolPlanModal — a Terraform-style \"Plan\" preview shown before Apply.\n//\n// Renders the side-effect-free plan returned by `GET /byol/:id/plan`: header\n// summary chips (`+N to add · ~M to change · −Z to destroy`), then every\n// resource line grouped by tier in provisioning order, each tagged with a\n// +/~/− action glyph. The footer's primary Apply button triggers the real\n// deploy (the caller wires it to POST /deploy) and is disabled when the plan is\n// a no-op. App-agnostic: no app-specific strings live here.\n// =============================================================================\n\nexport interface ByolPlanModalProps {\n isOpen: boolean\n onClose: () => void\n /** The computed plan, or null while it is still loading. */\n plan: ByolPlan | null\n /** True while the plan is being fetched. */\n loading?: boolean\n /** A plan-fetch or apply error to surface inline. */\n error?: string | null\n /** True while Apply is in flight. */\n applying?: boolean\n /** Invoked by the primary Apply button. */\n onApply: () => void\n /** Optional environment name, shown in the subtitle. */\n infraName?: string\n /**\n * Allow Apply even when the plan has no add/change/destroy — for a redeployable\n * environment (a failed or never-deployed infra) where the user is RE-running\n * the same plan rather than making a change.\n */\n allowApplyWithoutChanges?: boolean\n}\n\n/** A titled, bordered panel matching the modal's card styling. */\nconst InfoPanel: React.FC<{ title: string; children: React.ReactNode }> = ({ title, children }) => (\n <div style={{ border: `1px solid ${tokens.border}`, borderRadius: 8, background: tokens.surface2, overflow: 'hidden' }}>\n <div\n style={{\n padding: '8px 12px',\n borderBottom: `1px solid ${tokens.border}`,\n fontSize: 11,\n letterSpacing: '.08em',\n textTransform: 'uppercase',\n color: tokens.primary,\n fontWeight: 700,\n }}\n >\n {title}\n </div>\n <div style={{ padding: '10px 12px' }}>{children}</div>\n </div>\n)\n\n/** Network panel: the subnet the allocator will carve, or a soft-unavailable note. */\nconst NetworkPanel: React.FC<{ plan: ByolPlan }> = ({ plan }) => {\n if (!plan.network) {\n if (!plan.networkUnavailable) return null\n return (\n <InfoPanel title=\"Network\">\n <div style={{ fontSize: 13, color: tokens.muted }}>\n Subnet allocation preview is temporarily unavailable — the CIDR is reserved when you apply.\n </div>\n </InfoPanel>\n )\n }\n return (\n <InfoPanel title=\"Network\">\n <div style={{ fontSize: 13, color: tokens.text }}>\n Subnet{' '}\n <code style={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace', color: tokens.primary }}>\n {plan.network.subnetCidr}\n </code>{' '}\n will be allocated in{' '}\n <code style={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace', color: tokens.text }}>\n {plan.network.networkRef}\n </code>\n .\n </div>\n </InfoPanel>\n )\n}\n\n/** Tags panel: every canonical cost/tenant tag each resource will carry. */\nconst TagsPanel: React.FC<{ plan: ByolPlan }> = ({ plan }) => {\n const entries = plan.tags ? Object.entries(plan.tags) : []\n if (entries.length === 0) return null\n return (\n <InfoPanel title=\"Tags applied to every resource\">\n <div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '4px 12px', fontSize: 12 }}>\n {entries.map(([key, value]) => (\n <React.Fragment key={key}>\n <span\n style={{\n fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',\n color: tokens.muted,\n whiteSpace: 'nowrap',\n }}\n >\n {key}\n </span>\n <span style={{ color: tokens.text, wordBreak: 'break-all' }}>{value}</span>\n </React.Fragment>\n ))}\n </div>\n </InfoPanel>\n )\n}\n\nconst SummaryChips: React.FC<{ plan: ByolPlan }> = ({ plan }) => {\n const { add, change, destroy } = plan.summary\n return (\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center' }}>\n <Badge variant=\"success\" size=\"sm\">+{add} to add</Badge>\n <Badge variant=\"warning\" size=\"sm\">~{change} to change</Badge>\n <Badge variant=\"danger\" size=\"sm\">−{destroy} to destroy</Badge>\n {plan.summary.noop > 0 ? (\n <span style={{ fontSize: 12, color: tokens.faint }}>{plan.summary.noop} unchanged</span>\n ) : null}\n </div>\n )\n}\n\nconst PlanBody: React.FC<{\n plan: ByolPlan | null\n loading?: boolean\n error?: string | null\n allowApplyWithoutChanges?: boolean\n}> = ({ plan, loading, error, allowApplyWithoutChanges }) => {\n if (loading) {\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '24px 0', color: tokens.muted, fontSize: 13 }}>\n <Spinner size=\"sm\" /> Computing plan…\n </div>\n )\n }\n if (error) {\n return <div style={{ padding: '12px 0', color: tokens.danger, fontSize: 13 }}>{error}</div>\n }\n if (!plan) return null\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>\n <SummaryChips plan={plan} />\n <NetworkPanel plan={plan} />\n <TagsPanel plan={plan} />\n {!planHasChanges(plan.summary) ? (\n <div\n style={{\n fontSize: 13,\n color: tokens.muted,\n background: tokens.surface2,\n border: `1px solid ${tokens.border}`,\n borderRadius: 8,\n padding: '10px 14px',\n }}\n >\n {allowApplyWithoutChanges\n ? 'No plan changes — the previous run did not complete. Apply to re-run the deployment with the same plan.'\n : 'No changes. Infrastructure is up to date.'}\n </div>\n ) : (\n plan.groups.map((group) => <PlanGroup key={group.tier} tier={group.tier} items={group.items} />)\n )}\n </div>\n )\n}\n\n/**\n * The Plan modal. Fetch the plan into `plan` (showing `loading` first), then let\n * the user Apply. Apply is disabled while loading, while applying, and when the\n * plan has no add/change/destroy.\n */\nexport const ByolPlanModal: React.FC<ByolPlanModalProps> = ({\n isOpen,\n onClose,\n plan,\n loading,\n error,\n applying,\n onApply,\n infraName,\n allowApplyWithoutChanges,\n}) => {\n const noChanges = !plan || !planHasChanges(plan.summary)\n const applyDisabled = loading || applying || (noChanges && !allowApplyWithoutChanges)\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n size=\"lg\"\n title=\"Review deployment plan\"\n subtitle={infraName ? `Changes that will be applied to ${infraName}.` : 'Changes that will be applied to this environment.'}\n disableBackdropClose={applying}\n footer={\n <>\n <Button variant=\"ghost\" size=\"sm\" onClick={onClose} disabled={applying}>\n Cancel\n </Button>\n <Button variant=\"primary\" size=\"sm\" onClick={onApply} isLoading={applying} disabled={applyDisabled}>\n Apply\n </Button>\n </>\n }\n >\n <PlanBody plan={plan} loading={loading} error={error} allowApplyWithoutChanges={allowApplyWithoutChanges} />\n </Modal>\n )\n}\n\nexport default ByolPlanModal\n","// =============================================================================\n// BYOL plan diff (pure, React-free).\n//\n// Terraform-style \"what will change\" arithmetic: given the CURRENT persisted\n// resource rows and the DESIRED plan derived from topology, classify every\n// resource by `planKey` into add / change / destroy / noop. This is the exact,\n// non-mutating mirror of the set arithmetic `seedResources` performs when it\n// persists a plan (delete rows not in the plan + upsert the rest) — so a Plan\n// preview and the subsequent Apply agree by construction.\n//\n// It is the single source of truth for the Plan → Apply UX:\n// • the app SERVER computes it for `GET /byol/:id/plan` (a side-effect-free\n// dry-run), returning `buildByolPlan(current, desired)`, and\n// • the SDK renders the returned `ByolPlan` in the Plan modal.\n//\n// Kept React-free (no imports beyond the topology tier order) so it can run on\n// either side. NOTE: like the topology, the app server keeps its OWN copy\n// (apps/<id>/lib/byolPlanDiff.ts) rather than importing this at runtime — an app\n// must not depend on a root/byol SDK export that may be absent in the pinned\n// @veltrixsecops/app-sdk version. Keep the two in sync.\n// =============================================================================\n\nimport { TIER_ORDER } from './topology'\nimport type { ByolTags } from './tags'\n\n/** A single resource's disposition in a plan. */\nexport type PlanAction = 'add' | 'change' | 'destroy' | 'noop'\n\n/** The minimal shape of a CURRENT persisted resource row diffPlan compares. */\nexport interface PlanDiffCurrent {\n planKey: string\n tier: string\n kind: string\n name: string\n role: string | null\n region: string | null\n /** A `failed`/`attention` row is always re-planned as a change. */\n status?: string\n}\n\n/** The minimal shape of a DESIRED topology plan item diffPlan compares. */\nexport interface PlanDiffDesired {\n planKey: string\n tier: string\n kind: string\n name: string\n role: string | null\n region: string | null\n sortOrder?: number\n}\n\n/** The four buckets of a diff, keyed by `planKey`. add/change/noop hold the\n * desired item (the target state); destroy holds the current row being removed. */\nexport interface PlanDiff {\n add: PlanDiffDesired[]\n change: PlanDiffDesired[]\n destroy: PlanDiffCurrent[]\n noop: PlanDiffDesired[]\n}\n\n/** Count of each action — the header summary of the Plan modal. */\nexport interface ByolPlanSummary {\n add: number\n change: number\n destroy: number\n noop: number\n}\n\n/** One resource line in the plan, tagged with its action for the modal. */\nexport interface ByolPlanItem {\n planKey: string\n action: PlanAction\n name: string\n role: string | null\n region: string | null\n kind: string\n}\n\n/** Plan lines grouped by tier, in provisioning order. */\nexport interface ByolPlanGroup {\n tier: string\n items: ByolPlanItem[]\n}\n\n/** The subnet the platform network allocator previewed / reserved for a stack. */\nexport interface ByolPlanNetwork {\n /** Opaque handle to the shared per-(provider,region) Network (VPC/VNet/…). */\n networkRef: string\n /** The /24 subnet CIDR carved for this stack, e.g. `10.20.4.0/24`. */\n subnetCidr: string\n}\n\n/**\n * The full `GET /byol/:id/plan` response contract.\n *\n * The core diff (`summary` + `groups`) is computed by `buildByolPlan`; the app\n * server ENRICHES the response with `network` (a dry-run subnet peek) + `tags`\n * (the canonical tenant/cost tag set). Both are optional so the modal degrades\n * gracefully: `networkUnavailable` flags that the allocator was unreachable, and\n * `network` is simply absent for a self-hosted stack where it does not apply.\n */\nexport interface ByolPlan {\n summary: ByolPlanSummary\n groups: ByolPlanGroup[]\n /** Subnet the allocator would carve for this stack (peek), when applicable. */\n network?: ByolPlanNetwork\n /** Canonical tenant / cost-allocation tags every resource will carry. */\n tags?: ByolTags\n /** Soft flag: the network allocator was unreachable, so `network` is absent. */\n networkUnavailable?: boolean\n}\n\nconst nz = (v: string | null | undefined): string | null => (v == null ? null : v)\n\n/** True when a current row's identifying fields differ from the desired item. */\nfunction differs(current: PlanDiffCurrent, desired: PlanDiffDesired): boolean {\n return (\n current.tier !== desired.tier ||\n current.kind !== desired.kind ||\n current.name !== desired.name ||\n nz(current.role) !== nz(desired.role) ||\n nz(current.region) !== nz(desired.region)\n )\n}\n\n/** A row that failed / needs attention is re-planned (Retry re-provisions it). */\nfunction needsReplan(status?: string): boolean {\n return status === 'failed' || status === 'attention'\n}\n\n/**\n * Diff the desired topology plan against the current persisted rows.\n *\n * • add — desired keys with no current row\n * • change — desired keys whose current row differs (tier/kind/name/role/\n * region) or is failed/attention\n * • destroy — current rows whose key is no longer desired\n * • noop — desired keys whose current row already matches\n *\n * Pure and non-mutating: it never touches its inputs.\n */\nexport function diffPlan(current: PlanDiffCurrent[], desired: PlanDiffDesired[]): PlanDiff {\n const currentByKey = new Map(current.map((c) => [c.planKey, c]))\n const desiredKeys = new Set(desired.map((d) => d.planKey))\n\n const add: PlanDiffDesired[] = []\n const change: PlanDiffDesired[] = []\n const noop: PlanDiffDesired[] = []\n\n for (const item of desired) {\n const existing = currentByKey.get(item.planKey)\n if (!existing) add.push(item)\n else if (differs(existing, item) || needsReplan(existing.status)) change.push(item)\n else noop.push(item)\n }\n\n const destroy = current.filter((c) => !desiredKeys.has(c.planKey))\n\n return { add, change, destroy, noop }\n}\n\n/** Order a tier by its provisioning position (unknown tiers sort last). */\nfunction tierRank(tier: string): number {\n const idx = (TIER_ORDER as readonly string[]).indexOf(tier)\n return idx === -1 ? TIER_ORDER.length : idx\n}\n\n/**\n * Compute the full plan response from current + desired: the action counts plus\n * every resource line grouped by tier in provisioning order. Destroyed rows are\n * appended within their tier (they retain their tier but not a desired order).\n */\nexport function buildByolPlan(current: PlanDiffCurrent[], desired: PlanDiffDesired[]): ByolPlan {\n const diff = diffPlan(current, desired)\n const summary: ByolPlanSummary = {\n add: diff.add.length,\n change: diff.change.length,\n destroy: diff.destroy.length,\n noop: diff.noop.length,\n }\n\n const action = new Map<string, PlanAction>()\n for (const d of diff.add) action.set(d.planKey, 'add')\n for (const d of diff.change) action.set(d.planKey, 'change')\n for (const d of diff.noop) action.set(d.planKey, 'noop')\n\n type Ranked = ByolPlanItem & { tier: string; rank: number }\n const lines: Ranked[] = []\n\n desired.forEach((d, i) => {\n lines.push({\n tier: d.tier,\n rank: d.sortOrder ?? i,\n planKey: d.planKey,\n action: action.get(d.planKey) ?? 'noop',\n name: d.name,\n role: nz(d.role),\n region: nz(d.region),\n kind: d.kind,\n })\n })\n // Destroyed rows have no desired order; place them after the desired items.\n const tail = desired.length\n diff.destroy.forEach((c, i) => {\n lines.push({\n tier: c.tier,\n rank: tail + i,\n planKey: c.planKey,\n action: 'destroy',\n name: c.name,\n role: nz(c.role),\n region: nz(c.region),\n kind: c.kind,\n })\n })\n\n lines.sort((a, b) => tierRank(a.tier) - tierRank(b.tier) || a.rank - b.rank)\n\n const groups: ByolPlanGroup[] = []\n const byTier = new Map<string, ByolPlanGroup>()\n for (const line of lines) {\n let group = byTier.get(line.tier)\n if (!group) {\n group = { tier: line.tier, items: [] }\n byTier.set(line.tier, group)\n groups.push(group)\n }\n group.items.push({\n planKey: line.planKey,\n action: line.action,\n name: line.name,\n role: line.role,\n region: line.region,\n kind: line.kind,\n })\n }\n\n return { summary, groups }\n}\n\n/** Whether a plan has any actionable change (drives the modal's Apply gate). */\nexport function planHasChanges(summary: ByolPlanSummary): boolean {\n return summary.add + summary.change + summary.destroy > 0\n}\n","import React from 'react'\nimport { TIER_LABELS, type ByolResourceTier } from '../topology'\nimport type { PlanAction, ByolPlan } from '../diffPlan'\nimport { tokens } from './shared'\n\n// =============================================================================\n// planLines — the resource-row rendering shared by every Terraform-style plan\n// preview: the Apply-plan modal (`ByolPlanModal`, add/change/destroy/noop) and\n// the Destroy-plan modal (`DestroyPlanModal`, destroy-only). Kept in one place\n// so the two stay pixel-identical and neither duplicates the other's markup.\n// =============================================================================\n\n/** Per-action visual language: glyph + colour + short label. */\nexport const ACTION_META: Record<PlanAction, { glyph: string; color: string; label: string }> = {\n add: { glyph: '+', color: tokens.success, label: 'add' },\n change: { glyph: '~', color: tokens.warning, label: 'change' },\n destroy: { glyph: '−', color: tokens.danger, label: 'destroy' },\n noop: { glyph: '·', color: tokens.faint, label: 'no change' },\n}\n\nexport const tierLabel = (tier: string): string =>\n TIER_LABELS[tier as ByolResourceTier] ?? tier.replace(/-/g, ' ')\n\n/** One resource line in a plan, tagged with its +/~/− action glyph. */\nexport const PlanLine: React.FC<{ item: ByolPlan['groups'][number]['items'][number] }> = ({ item }) => {\n const meta = ACTION_META[item.action]\n return (\n <div\n style={{\n position: 'relative',\n border: `1px solid ${tokens.border}`,\n borderRadius: 8,\n background: tokens.surface,\n padding: '10px 12px 10px 14px',\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n overflow: 'hidden',\n }}\n >\n <span style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: 3, background: meta.color }} />\n <span\n aria-hidden\n title={meta.label}\n style={{\n flex: 'none',\n width: 20,\n height: 20,\n borderRadius: 5,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontWeight: 700,\n fontSize: 14,\n lineHeight: 1,\n color: meta.color,\n background: tokens.surface2,\n }}\n >\n {meta.glyph}\n </span>\n <div style={{ minWidth: 0, flex: 1 }}>\n <div style={{ fontWeight: 600, fontSize: 13, color: tokens.text, textDecoration: item.action === 'destroy' ? 'line-through' : 'none' }}>\n {item.name}\n </div>\n {item.role ? <div style={{ fontSize: 11, color: tokens.faint }}>{item.role}</div> : null}\n </div>\n <span style={{ fontSize: 11, color: tokens.muted, flex: 'none' }}>{item.region || '—'}</span>\n </div>\n )\n}\n\n/** A titled group of plan lines for one provisioning tier. */\nexport const PlanGroup: React.FC<{ tier: string; items: ByolPlan['groups'][number]['items'] }> = ({ tier, items }) => (\n <div>\n <h3\n style={{\n margin: '0 0 8px',\n fontSize: 12,\n letterSpacing: '.08em',\n textTransform: 'uppercase',\n color: tokens.primary,\n }}\n >\n {tierLabel(tier)}\n </h3>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {items.map((item) => (\n <PlanLine key={item.planKey} item={item} />\n ))}\n </div>\n </div>\n)\n","import React, { useMemo } from 'react'\nimport { Alert, Badge, Button, Modal, Spinner } from '../../ui'\nimport { buildByolPlan } from '../diffPlan'\nimport type { ByolResource } from '../types'\nimport { tokens } from './shared'\nimport { PlanGroup } from './planLines'\n\n// =============================================================================\n// DestroyPlanModal — the Destroy-side counterpart of `ByolPlanModal`.\n//\n// \"Destroy infrastructure\" used to show a generic \"Destroy all resources? This\n// cannot be undone.\" text confirmation. That hid exactly what would be torn\n// down. This renders a real Terraform-style destroy plan instead: every CURRENT\n// resource as a destroy (−) line, grouped by tier — built by feeding the\n// current resources through `buildByolPlan(current, [])` (an empty desired set\n// means every resource is classified `destroy`), so it shares the exact plan\n// model AND row rendering (`PlanGroup`/`PlanLine`) the Apply-plan modal uses.\n// Only on confirming the in-modal danger Destroy button does the caller invoke\n// the real `/destroy` action — never a native dialog.\n// =============================================================================\n\nexport interface DestroyPlanModalProps {\n isOpen: boolean\n onClose: () => void\n /** The current persisted resources this destroy will tear down; null while (re)loading. */\n resources: ByolResource[] | null\n /** True while the resource inventory is being (re)loaded. */\n loading?: boolean\n /** A destroy-action error (from the `/destroy` call itself) to surface inline. */\n error?: string | null\n /** True while the destroy request is in flight. */\n destroying?: boolean\n /** Invoked by the primary (danger) Destroy button. */\n onConfirm: () => void\n /** Optional environment name, shown in the subtitle. */\n infraName?: string\n}\n\n/**\n * The Destroy modal. Shows every resource in `resources` as a destroy line\n * grouped by tier. Destroy stays enabled even when the inventory hasn't\n * loaded or is empty — the underlying `/destroy` action doesn't depend on this\n * preview, so an unavailable/empty list must never block the user from tearing\n * an environment down, only inform them the resource list itself was unavailable.\n */\nexport const DestroyPlanModal: React.FC<DestroyPlanModalProps> = ({\n isOpen,\n onClose,\n resources,\n loading,\n error,\n destroying,\n onConfirm,\n infraName,\n}) => {\n const plan = useMemo(() => (resources ? buildByolPlan(resources, []) : null), [resources])\n const destroyCount = plan?.summary.destroy ?? 0\n const confirmDisabled = loading || destroying\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n size=\"lg\"\n title=\"Destroy infrastructure\"\n subtitle={\n infraName\n ? `Every resource for \"${infraName}\" will be torn down.`\n : 'Every resource for this environment will be torn down.'\n }\n disableBackdropClose={destroying}\n footer={\n <>\n <Button variant=\"ghost\" size=\"sm\" onClick={onClose} disabled={destroying}>\n Cancel\n </Button>\n <Button variant=\"danger\" size=\"sm\" onClick={onConfirm} isLoading={destroying} disabled={confirmDisabled}>\n Destroy\n </Button>\n </>\n }\n >\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>\n <Alert variant=\"danger\" title=\"This cannot be undone\">\n Destroying removes every instance, storage volume, and network resource provisioned for this environment.\n </Alert>\n\n {error ? <div style={{ fontSize: 13, color: tokens.danger }}>{error}</div> : null}\n\n {loading ? (\n <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 0', color: tokens.muted, fontSize: 13 }}>\n <Spinner size=\"sm\" /> Loading current resources…\n </div>\n ) : (\n <>\n <Badge variant=\"danger\" size=\"sm\">−{destroyCount} to destroy</Badge>\n {plan && plan.groups.length > 0 ? (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>\n {plan.groups.map((group) => (\n <PlanGroup key={group.tier} tier={group.tier} items={group.items} />\n ))}\n </div>\n ) : (\n <div\n style={{\n fontSize: 13,\n color: tokens.muted,\n background: tokens.surface2,\n border: `1px solid ${tokens.border}`,\n borderRadius: 8,\n padding: '10px 14px',\n }}\n >\n No resource inventory is available for this environment — it will still be destroyed.\n </div>\n )}\n </>\n )}\n </div>\n </Modal>\n )\n}\n\nexport default DestroyPlanModal\n","import React from 'react'\n\n// =============================================================================\n// icons — inline SVG icons for the BYOL infrastructure detail sidebar.\n//\n// These replace the raw Unicode symbol glyphs (◈ ▦ ◷ …) the sidebar used to\n// render. Those glyphs only appeared when the active font happened to contain\n// them; inside the platform shell (Inter) they collapsed to blank/\"tofu\", which\n// is why the section icons \"disappeared\" in production. Inline SVGs are\n// font-independent, render identically everywhere, need no icon dependency, and\n// are CSP-safe (no external asset). They paint with `currentColor`, so each\n// icon automatically tracks its button's colour (active = brand, idle = muted).\n//\n// Paths are the corresponding lucide icons (ISC-licensed), inlined.\n// =============================================================================\n\nexport interface IconProps {\n /** Square edge length in px. */\n size?: number\n /** Extra styles merged onto the <svg> (colour comes from `currentColor`). */\n style?: React.CSSProperties\n}\n\n/** Shared <svg> frame — consistent viewBox, stroke language, and a11y hiding. */\nconst Svg: React.FC<IconProps & { children: React.ReactNode }> = ({ size = 16, style, children }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n focusable={false}\n style={{ display: 'block', flex: 'none', ...style }}\n >\n {children}\n </svg>\n)\n\n/** Overview — dashboard panels. */\nexport const OverviewIcon: React.FC<IconProps> = (p) => (\n <Svg {...p}>\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"9\" rx=\"1\" />\n <rect x=\"14\" y=\"3\" width=\"7\" height=\"5\" rx=\"1\" />\n <rect x=\"14\" y=\"12\" width=\"7\" height=\"9\" rx=\"1\" />\n <rect x=\"3\" y=\"16\" width=\"7\" height=\"5\" rx=\"1\" />\n </Svg>\n)\n\n/** Resources — stacked servers (the provisioned infrastructure). */\nexport const ResourcesIcon: React.FC<IconProps> = (p) => (\n <Svg {...p}>\n <rect x=\"2\" y=\"2\" width=\"20\" height=\"8\" rx=\"2\" />\n <rect x=\"2\" y=\"14\" width=\"20\" height=\"8\" rx=\"2\" />\n <line x1=\"6\" y1=\"6\" x2=\"6.01\" y2=\"6\" />\n <line x1=\"6\" y1=\"18\" x2=\"6.01\" y2=\"18\" />\n </Svg>\n)\n\n/** Activity — the deployment/event pulse. */\nexport const ActivityIcon: React.FC<IconProps> = (p) => (\n <Svg {...p}>\n <path d=\"M22 12h-4l-3 9L9 3l-3 9H2\" />\n </Svg>\n)\n\n/** Access — a key (credentials / who can reach it). */\nexport const AccessIcon: React.FC<IconProps> = (p) => (\n <Svg {...p}>\n <circle cx=\"7.5\" cy=\"15.5\" r=\"5.5\" />\n <path d=\"m21 2-9.6 9.6\" />\n <path d=\"m15.5 7.5 3 3L22 7l-3-3\" />\n </Svg>\n)\n\n/** Configuration — sliders (tunable settings that link out to config pages). */\nexport const ConfigurationIcon: React.FC<IconProps> = (p) => (\n <Svg {...p}>\n <line x1=\"21\" y1=\"4\" x2=\"14\" y2=\"4\" />\n <line x1=\"10\" y1=\"4\" x2=\"3\" y2=\"4\" />\n <line x1=\"21\" y1=\"12\" x2=\"12\" y2=\"12\" />\n <line x1=\"8\" y1=\"12\" x2=\"3\" y2=\"12\" />\n <line x1=\"21\" y1=\"20\" x2=\"16\" y2=\"20\" />\n <line x1=\"12\" y1=\"20\" x2=\"3\" y2=\"20\" />\n <line x1=\"14\" y1=\"2\" x2=\"14\" y2=\"6\" />\n <line x1=\"8\" y1=\"10\" x2=\"8\" y2=\"14\" />\n <line x1=\"16\" y1=\"18\" x2=\"16\" y2=\"22\" />\n </Svg>\n)\n\n/** Settings — a cog (record-level settings + danger zone). */\nexport const SettingsIcon: React.FC<IconProps> = (p) => (\n <Svg {...p}>\n <path d=\"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2Z\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </Svg>\n)\n","import React from 'react'\nimport { Button, Input, Select } from '../ui'\nimport { tokens } from './detail/shared'\nimport {\n type ClusterPlacement,\n type PlacementGranularity,\n type PlacementSite,\n PLACEMENT_GRANULARITY_OPTIONS,\n} from './types'\nimport { allocateNodesBySite, validatePlacement } from './placement'\n\n// =============================================================================\n// Per-cluster placement editor: single-site, or multi-site spread by percent\n// across availability zones (same region) or regions. Used for the indexer and\n// search-head clusters only — every other tier is always in the main region.\n// =============================================================================\n\ninterface ClusterPlacementFieldProps {\n label: string\n placement: ClusterPlacement\n /** Node count for this cluster — drives the live \"→ N nodes\" preview. */\n nodeCount: number\n /** The deployment's main region — the single-site home and the AZ prefix. */\n primaryRegion: string\n /** Cloud provider code (aws|azure|gcp|hetzner) — zone naming differs per cloud. */\n providerCode?: string\n /** Cloud regions offered when spreading by region. */\n regionOptions: Array<{ value: string; label: string }>\n onChange: (placement: ClusterPlacement) => void\n}\n\nconst MODE_OPTIONS = [\n { value: 'single', label: 'Single site — all nodes in the main region' },\n { value: 'multi-site', label: 'Multi-site — spread nodes by percent' },\n]\n\n// Availability-zone naming differs per cloud: AWS `us-east-1a`, GCP `us-central1-a`,\n// Azure numeric zones (1/2/3). Hetzner has no in-location AZs — use region granularity.\nconst AWS_AZ_LETTERS = ['a', 'b', 'c', 'd', 'e', 'f']\nconst GCP_AZ_LETTERS = ['a', 'b', 'c', 'd', 'f']\nconst AZURE_ZONES = ['1', '2', '3']\n\nfunction azOptionsFor(providerCode: string | undefined, region: string): Array<{ value: string; label: string }> {\n const code = (providerCode || 'aws').toLowerCase()\n const base = region || 'region'\n if (code === 'azure') return AZURE_ZONES.map((z) => ({ value: z, label: `Zone ${z}` }))\n if (code === 'gcp') return GCP_AZ_LETTERS.map((l) => ({ value: `${base}-${l}`, label: `${base}-${l}` }))\n return AWS_AZ_LETTERS.map((l) => ({ value: `${base}${l}`, label: `${base}${l}` }))\n}\n\n/** Integer percents summing to 100, with the remainder on the first sites. */\nfunction evenPercents(count: number): number[] {\n if (count <= 0) return []\n const base = Math.floor(100 / count)\n const remainder = 100 - base * count\n return Array.from({ length: count }, (_, i) => base + (i < remainder ? 1 : 0))\n}\n\nfunction defaultSites(\n granularity: PlacementGranularity,\n primaryRegion: string,\n providerCode: string | undefined,\n regionOptions: Array<{ value: string; label: string }>,\n): PlacementSite[] {\n const [p0, p1] = evenPercents(2)\n if (granularity === 'az') {\n const az = azOptionsFor(providerCode, primaryRegion)\n return [\n { site: az[0]?.value ?? `${primaryRegion}a`, percent: p0 },\n { site: az[1]?.value ?? `${primaryRegion}b`, percent: p1 },\n ]\n }\n const regions = regionOptions.map((o) => o.value).filter(Boolean)\n const first = primaryRegion || regions[0] || ''\n const second = regions.find((r) => r !== first) ?? ''\n return [\n { site: first, percent: p0 },\n { site: second, percent: p1 },\n ]\n}\n\nexport const ClusterPlacementField: React.FC<ClusterPlacementFieldProps> = ({\n label,\n placement,\n nodeCount,\n primaryRegion,\n providerCode,\n regionOptions,\n onChange,\n}) => {\n const multi = placement.mode === 'multi-site'\n const granularity: PlacementGranularity = placement.granularity ?? 'az'\n const sites = placement.sites ?? []\n const siteOptions = granularity === 'az' ? azOptionsFor(providerCode, primaryRegion) : regionOptions\n\n const emit = (next: PlacementSite[]) => onChange({ mode: 'multi-site', granularity, sites: next })\n\n const setMode = (mode: string) => {\n if (mode !== 'multi-site') return onChange({ mode: 'single' })\n onChange({\n mode: 'multi-site',\n granularity,\n sites: sites.length >= 2 ? sites : defaultSites(granularity, primaryRegion, providerCode, regionOptions),\n })\n }\n\n const setGranularity = (value: string) => {\n const g = value as PlacementGranularity\n // Sites are granularity-specific (AZ ids vs region codes) — reset to defaults.\n onChange({ mode: 'multi-site', granularity: g, sites: defaultSites(g, primaryRegion, providerCode, regionOptions) })\n }\n\n const updateSite = (i: number, patch: Partial<PlacementSite>) =>\n emit(sites.map((s, idx) => (idx === i ? { ...s, ...patch } : s)))\n\n const addSite = () => {\n const used = new Set(sites.map((s) => s.site))\n const nextSite = siteOptions.map((o) => o.value).find((v) => !used.has(v)) ?? ''\n emit([...sites, { site: nextSite, percent: 0 }])\n }\n\n const removeSite = (i: number) => emit(sites.filter((_, idx) => idx !== i))\n\n const distributeEvenly = () => {\n const percents = evenPercents(sites.length)\n emit(sites.map((s, i) => ({ ...s, percent: percents[i] })))\n }\n\n const allocation = multi ? allocateNodesBySite(nodeCount, sites) : []\n const validationError = multi ? validatePlacement(placement, nodeCount) : null\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>\n <Select label={label} value={placement.mode} onChange={setMode} options={MODE_OPTIONS} />\n\n {multi ? (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: 10,\n padding: 12,\n border: `1px solid ${tokens.border}`,\n borderRadius: 8,\n background: tokens.surface2,\n }}\n >\n <Select\n label=\"Spread across\"\n value={granularity}\n onChange={setGranularity}\n options={[...PLACEMENT_GRANULARITY_OPTIONS]}\n />\n\n <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n {sites.map((site, i) => (\n <div key={i} style={{ display: 'grid', gridTemplateColumns: '1fr 92px auto auto', gap: 8, alignItems: 'end' }}>\n <Select\n label={i === 0 ? (granularity === 'az' ? 'Zone' : 'Region') : undefined}\n value={site.site}\n onChange={(value) => updateSite(i, { site: value })}\n options={siteOptions}\n placeholder=\"Select…\"\n />\n <Input\n label={i === 0 ? 'Share %' : undefined}\n type=\"number\"\n min={0}\n max={100}\n value={String(site.percent)}\n onChange={(e) => updateSite(i, { percent: Number(e.target.value) || 0 })}\n fullWidth\n />\n <span style={{ fontSize: 12, color: tokens.muted, paddingBottom: 10, whiteSpace: 'nowrap' }}>\n → {allocation[i]?.count ?? 0} node{(allocation[i]?.count ?? 0) === 1 ? '' : 's'}\n </span>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => removeSite(i)}\n disabled={sites.length <= 2}\n aria-label={`Remove site ${i + 1}`}\n style={{ marginBottom: 4 }}\n >\n ✕\n </Button>\n </div>\n ))}\n </div>\n\n <div style={{ display: 'flex', gap: 8 }}>\n <Button variant=\"secondary\" size=\"sm\" onClick={addSite} disabled={sites.length >= siteOptions.length}>\n Add site\n </Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={distributeEvenly}>\n Distribute evenly\n </Button>\n </div>\n\n {validationError ? (\n <p style={{ margin: 0, fontSize: 12, color: tokens.danger }}>{validationError}</p>\n ) : (\n <p style={{ margin: 0, fontSize: 12, color: tokens.muted }}>\n {sites.length} sites · {allocation.reduce((n, a) => n + a.count, 0)} of {nodeCount} nodes placed.\n </p>\n )}\n </div>\n ) : null}\n </div>\n )\n}\n","// =============================================================================\n// BYOL tenant / cost-allocation tag builder (pure, React-free).\n//\n// Every Veltrix-provisioned object (the allocated subnet + every environment\n// resource) is stamped with a CANONICAL tag set so cloud spend can be attributed\n// per customer / per app and tenants stay isolated within the shared Network.\n// These keys are the platform-wide contract — billing reconciliation and the\n// least-privilege IAM policy (`Veltrix:ManagedBy=Veltrix`) rely on them, so an\n// app may ADD its own tags but must never rename or drop these.\n//\n// Derived entirely from context the app already holds (customerId, the infra\n// record, appId) — no I/O, no cloud round-trip — so it runs identically on the\n// Plan preview (`GET /byol/:id/plan`) and the Apply commit\n// (`POST /byol/:id/deploy`), keeping the previewed tags and the applied tags\n// equal by construction. Kept React-free so any BYOL app can reuse it server-side.\n//\n// NOTE: like the topology + plan diff, the app server keeps its OWN copy\n// (apps/<id>/lib/byolTags.ts) rather than importing this at runtime — an app must\n// not depend on a byol/root SDK export that may be absent in the pinned\n// @veltrixsecops/app-sdk version. Keep the two in sync.\n// =============================================================================\n\n/** Context a BYOL tag set is derived from — everything the app already holds. */\nexport interface ByolTagInput {\n /** Tenant id — cost attribution + tenant isolation. */\n customerId: string\n /**\n * Human-readable, unique tenant shortname (set in Settings → Organization).\n * Used as the `Veltrix:Customer` value so cloud tags are legible; falls back\n * to `customerId` when the tenant has not set one.\n */\n customerShortName?: string | null\n /** Unique environment id (the infrastructure record id). */\n infrastructureId: string\n /** Human environment name. */\n name: string\n /** Environment class, e.g. prod / staging / dev. */\n environmentType: string\n /** Owning app, e.g. `splunk-enterprise`. */\n appId: string\n /** Billing account / cost center; falls back to `customerId`. */\n costCenter?: string | null\n /** Initiating user / owner; falls back to `customerId`. */\n owner?: string | null\n}\n\n/** An ordered tag map. Insertion order IS the canonical display order. */\nexport type ByolTags = Record<string, string>\n\n/**\n * The canonical tag keys, in the order they are emitted. Exported so callers +\n * tests can assert against the contract without re-deriving it.\n */\nexport const BYOL_TAG_KEYS = [\n 'Veltrix:Customer',\n 'Veltrix:Environment',\n 'Veltrix:EnvName',\n 'Veltrix:EnvType',\n 'Veltrix:App',\n 'Veltrix:ManagedBy',\n 'CostCenter',\n 'Owner',\n] as const\n\n/** The constant value stamped on `Veltrix:ManagedBy` (drives tag-scoped IAM). */\nexport const MANAGED_BY = 'Veltrix'\n\n/** Coerce a tag value to a trimmed string (tags are always strings). */\nfunction s(value: string | null | undefined): string {\n return String(value ?? '').trim()\n}\n\n/**\n * Build the canonical cost-allocation / tenant-isolation tag set for a BYOL\n * environment. Pure: the same input always yields the same ordered map.\n *\n * Veltrix:Customer = customerShortName ?? customerId\n * Veltrix:Environment = infrastructureId (unique env id)\n * Veltrix:EnvName = name\n * Veltrix:EnvType = environmentType (prod / staging / …)\n * Veltrix:App = appId (splunk-enterprise, …)\n * Veltrix:ManagedBy = Veltrix (constant; tag-scoped IAM)\n * CostCenter = costCenter ?? the customer label\n * Owner = owner ?? the customer label\n */\nexport function buildByolTags(input: ByolTagInput): ByolTags {\n const customerId = s(input.customerId)\n // Prefer the human-readable shortname; fall back to the UUID when unset.\n const customerLabel = s(input.customerShortName) || customerId\n const costCenter = s(input.costCenter) || customerLabel\n const owner = s(input.owner) || customerLabel\n\n // Object literal in canonical key order — string keys preserve insertion order.\n return {\n 'Veltrix:Customer': customerLabel,\n 'Veltrix:Environment': s(input.infrastructureId),\n 'Veltrix:EnvName': s(input.name),\n 'Veltrix:EnvType': s(input.environmentType),\n 'Veltrix:App': s(input.appId),\n 'Veltrix:ManagedBy': MANAGED_BY,\n CostCenter: costCenter,\n Owner: owner,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAgB,eAAAA,cAAa,aAAAC,YAAW,WAAAC,UAAS,YAAAC,iBAAgB;;;AC4C1D,IAAM,wBAA0C,EAAE,MAAM,SAAS;AAGjE,IAAM,uBAAuB;AAuM7B,IAAM,cAAc;AACpB,IAAM,oBAAoB;AAE1B,IAAM,2BAA2B;AAAA,EACtC,EAAE,OAAO,UAAU,OAAO,kBAAkB;AAAA,EAC5C,EAAE,OAAO,eAAe,OAAO,cAAc;AAC/C;AAQO,IAAM,uBAAuB;AAAA,EAClC,EAAE,OAAO,aAAa,OAAO,qCAAgC;AAAA,EAC7D,EAAE,OAAO,YAAY,OAAO,4CAAuC;AAAA,EACnE,EAAE,OAAO,UAAU,OAAO,0BAA0B;AACtD;AAGO,IAAM,mBAAmB;AAAA,EAC9B,EAAE,OAAO,WAAW,OAAO,UAAU;AAAA,EACrC,EAAE,OAAO,aAAa,OAAO,YAAY;AAAA,EACzC,EAAE,OAAO,gBAAgB,OAAO,eAAe;AACjD;AAGO,IAAM,qBAAqB,oBAAI,IAAI,CAAC,aAAa,UAAU,CAAC;AAG5D,IAAM,+BAIR;AAAA,EACH,EAAE,OAAO,aAAa,OAAO,aAAa,aAAa,iEAA4D;AAAA,EACnH,EAAE,OAAO,gBAAgB,OAAO,gBAAgB,aAAa,6EAAwE;AAAA,EACrI,EAAE,OAAO,UAAU,OAAO,eAAe,aAAa,gEAAgE;AACxH;AAGO,IAAM,gCAAuF;AAAA,EAClG,EAAE,OAAO,MAAM,OAAO,mCAAmC;AAAA,EACzD,EAAE,OAAO,UAAU,OAAO,yBAAyB;AACrD;AASO,SAAS,cAAc,KAAoC;AAChE,QAAM,aAAa,IAAI,kBACnB,IAAI,kBACJ,IAAI,iBAAiB,oBACnB,cACA;AACN,SAAO;AAAA,IACL,MAAM,IAAI,QAAQ;AAAA,IAClB,gBAAgB,IAAI,kBAAkB;AAAA,IACtC,iBAAiB,IAAI,mBAAmB;AAAA,IACxC;AAAA,IACA,QAAQ,IAAI,UAAU;AAAA,IACtB,cAAc,OAAO,IAAI,gBAAgB,CAAC;AAAA,IAC1C,iBAAiB,OAAO,IAAI,mBAAmB,CAAC;AAAA,IAChD,aAAa,IAAI,eAAe;AAAA,IAChC,SAAS,IAAI,WAAW;AAAA,IACxB,0BAA0B,IAAI,4BAA4B;AAAA,IAC1D,oBAAoB,IAAI,sBAAsB;AAAA,IAC9C,qBAAqB,OAAO,IAAI,uBAAuB,CAAC;AAAA,IACxD,cAAc,IAAI,gBAAgB;AAAA,IAClC,kBAAkB,IAAI,oBAAoB,EAAE,MAAM,SAAS;AAAA,IAC3D,qBAAqB,IAAI,uBAAuB,EAAE,MAAM,SAAS;AAAA,IACjE,WAAW,IAAI,aAAa;AAAA,EAC9B;AACF;AAEO,IAAM,aAAwB;AAAA,EACnC,MAAM;AAAA,EACN,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKjB,aAAa;AAAA,EACb,SAAS;AAAA,EACT,0BAA0B;AAAA,EAC1B,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,cAAc;AAAA,EACd,kBAAkB,EAAE,MAAM,SAAS;AAAA,EACnC,qBAAqB,EAAE,MAAM,SAAS;AAAA,EACtC,WAAW;AACb;AAMO,IAAM,yBAAiD;AAAA,EAC5D,KAAK;AAAA,EACL,OAAO;AAAA,EACP,KAAK;AAAA,EACL,SAAS;AACX;;;AC9UA,IAAM,WAAyC;AAAA,EAC7C,aAAa;AAAA,EACb,cAAc;AAAA,EACd,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,YAAY;AACd;AAEA,IAAM,SAAiC;AAAA,EACrC,aAAa;AAAA,EACb,cAAc;AAAA,EACd,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,YAAY;AACd;AAGO,SAAS,cAAc,QAA+B;AAC3D,SAAQ,UAAU,SAAS,MAAM,KAAM;AACzC;AAGO,SAAS,YAAY,QAAyB;AACnD,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,OAAO,MAAM,KAAK,OAAO,QAAQ,MAAM,GAAG,EAAE,QAAQ,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC;AAC5F;AAGO,SAAS,UAAU,QAA0B;AAClD,SAAO,WAAW,aAAa,WAAW;AAC5C;AAGO,SAAS,aAAa,QAA0B;AACrD,SAAO,CAAC,UAAU,WAAW;AAC/B;AAIA,IAAM,oBAAkD;AAAA,EACtD,OAAO;AAAA,EACP,cAAc;AAAA,EACd,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,aAAa;AACf;AAEA,IAAM,kBAA0C;AAAA,EAC9C,OAAO;AAAA,EACP,cAAc;AAAA,EACd,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,aAAa;AACf;AAEO,SAAS,sBAAsB,QAA+B;AACnE,SAAQ,UAAU,kBAAkB,MAAM,KAAM;AAClD;AAEO,SAAS,oBAAoB,QAAyB;AAC3D,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,gBAAgB,MAAM,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC5D;AAIA,IAAM,gBAA8C;AAAA,EAClD,MAAM;AAAA,EACN,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AACX;AAEO,SAAS,kBAAkB,QAA+B;AAC/D,SAAQ,UAAU,cAAc,MAAM,KAAM;AAC9C;;;AClEE,cAYA,YAZA;AAnBF,IAAM,WAAW,CAAC,MAAc,aAA6B,WAAW,IAAI,KAAK,QAAQ;AAElF,IAAM,SAAS;AAAA,EACpB,QAAQ,SAAS,kBAAkB,aAAa;AAAA,EAChD,cAAc,SAAS,yBAAyB,aAAa;AAAA,EAC7D,SAAS,SAAS,0BAA0B,aAAa;AAAA;AAAA,EACzD,UAAU,SAAS,mBAAmB,aAAa;AAAA;AAAA,EACnD,MAAM,SAAS,2BAA2B,UAAU;AAAA,EACpD,OAAO,SAAS,6BAA6B,UAAU;AAAA,EACvD,OAAO,SAAS,4BAA4B,aAAa;AAAA,EACzD,SAAS;AAAA,EACT,QAAQ,SAAS,kBAAkB,WAAW;AAAA,EAC9C,SAAS,SAAS,mBAAmB,WAAW;AAAA,EAChD,MAAM,SAAS,gBAAgB,YAAY;AAAA,EAC3C,SAAS,SAAS,mBAAmB,UAAU;AACjD;AAGO,IAAM,aAA4C,CAAC,EAAE,OAAO,MACjE,oBAAC,SAAM,SAAS,cAAc,MAAM,GAAI,sBAAY,MAAM,GAAE;AAIvD,IAAM,eAA8C,CAAC,EAAE,OAAO,MACnE,oBAAC,SAAM,SAAS,sBAAsB,MAAM,GAAG,MAAK,MACjD,8BAAoB,MAAM,GAC7B;AAIK,IAAM,OAA+D,CAAC,EAAE,OAAO,SAAS,MAC7F,qBAAC,SACC;AAAA,sBAAC,SAAI,OAAO,EAAE,UAAU,IAAI,eAAe,aAAa,eAAe,SAAS,OAAO,OAAO,MAAM,GAAI,iBAAM;AAAA,EAC9G,oBAAC,SAAI,OAAO,EAAE,YAAY,KAAK,OAAO,OAAO,MAAM,WAAW,EAAE,GAAI,UAAS;AAAA,GAC/E;AAIF,SAAS,SAAS,QAAwB;AACxC,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,OAAO;AAAA,IAChB,KAAK;AACH,aAAO,OAAO;AAAA,IAChB,KAAK;AACH,aAAO,OAAO;AAAA,IAChB,KAAK;AACH,aAAO,OAAO;AAAA,IAChB;AACE,aAAO,OAAO;AAAA,EAClB;AACF;AAOO,IAAM,gBAAyD,CAAC,EAAE,UAAU,MAAM;AACvF,QAAM,QAAQ,UAAU;AACxB,QAAM,QAAQ,UAAU,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,EAAE;AAC5D,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,KAAK,UAAW,QAAO,IAAI,EAAE,SAAS,OAAO,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC;AAC/E,QAAM,QAAQ,CAAC,SAAS,gBAAgB,aAAa,UAAU,aAAa;AAE5E,SACE,qBAAC,SAAI,OAAO,EAAE,OAAO,KAAK,UAAU,OAAO,GACzC;AAAA,yBAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,gBAAgB,iBAAiB,UAAU,IAAI,OAAO,OAAO,OAAO,cAAc,EAAE,GACjH;AAAA,0BAAC,UAAK,iCAAmB;AAAA,MACzB,oBAAC,UAAK,OAAO,EAAE,oBAAoB,eAAe,GAC/C,oBAAU,IAAI,iBAAiB,GAAG,KAAK,MAAM,KAAK,oBACrD;AAAA,OACF;AAAA,IACA,oBAAC,SAAI,OAAO,EAAE,QAAQ,GAAG,cAAc,KAAK,YAAY,OAAO,UAAU,UAAU,UAAU,SAAS,OAAO,GAC1G,oBAAU,IACP,OACA,MAAM,IAAI,CAACC,OAAM;AACf,YAAM,IAAI,OAAO,IAAIA,EAAC,KAAK;AAC3B,UAAI,CAAC,EAAG,QAAO;AACf,aAAO,oBAAC,SAAY,OAAO,EAAE,OAAO,GAAI,IAAI,QAAS,GAAG,KAAK,YAAY,SAASA,EAAC,GAAG,QAAQ,OAAO,KAApFA,EAAuF;AAAA,IAC1G,CAAC,GACP;AAAA,KACF;AAEJ;AAGO,IAAM,QAA4F,CAAC;AAAA,EACxG;AAAA,EACA;AAAA,EACA;AACF,MACE,qBAAC,SAAI,OAAO,EAAE,QAAQ,aAAa,OAAO,MAAM,IAAI,cAAc,IAAI,YAAY,OAAO,SAAS,UAAU,SAAS,GACjH;AAAA,YAAS,YACT;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,KAAK;AAAA,QACL,SAAS;AAAA,QACT,cAAc,aAAa,OAAO,MAAM;AAAA,MAC1C;AAAA,MAEC;AAAA,gBAAQ,oBAAC,QAAG,OAAO,EAAE,QAAQ,GAAG,UAAU,IAAI,YAAY,KAAK,OAAO,OAAO,KAAK,GAAI,iBAAM,IAAQ,oBAAC,UAAK;AAAA,QAC1G;AAAA;AAAA;AAAA,EACH;AAAA,EAEF,oBAAC,SAAI,OAAO,EAAE,SAAS,GAAG,GAAI,UAAS;AAAA,GACzC;;;ACzHF,eAAsB,UAAU,KAAgC;AAC9D,SAAO,IACJ,KAAK,EACL,KAAK,CAAC,MAA0B,GAAG,SAAS,QAAQ,IAAI,MAAM,EAAE,EAChE,MAAM,MAAM,QAAQ,IAAI,MAAM,EAAE;AACrC;AAEO,SAAS,WAAW,OAA+B;AACxD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,SAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,WAAM,KAAK,mBAAmB;AACtE;AAEO,SAAS,eAAe,OAA+B;AAC5D,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,SAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,WAAM,KAAK,eAAe;AAClE;AAEA,eAAe,KAAQ,KAA2B;AAChD,MAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,MAAM,UAAU,GAAG,CAAC;AACjD,SAAO,IAAI,KAAK;AAClB;AAGO,SAAS,SAAS,SAAiB,IAAyC;AACjF,SAAO,UAAU,GAAG,OAAO,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,KAAyB,CAAC,CAAC;AAC9E;AAEO,SAAS,aAAa,SAAiB,IAAqC;AACjF,SAAO,UAAU,GAAG,OAAO,IAAI,EAAE,YAAY,EAAE,KAAK,CAAC,MAAM,KAAqB,CAAC,CAAC;AACpF;AAEO,SAAS,eAAe,SAAiB,IAAuC;AACrF,SAAO,UAAU,GAAG,OAAO,IAAI,EAAE,cAAc,EAAE,KAAK,CAAC,MAAM,KAAuB,CAAC,CAAC;AACxF;AAOO,SAAS,QAAQ,SAAiB,IAA+B;AACtE,SAAO,UAAU,GAAG,OAAO,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,KAAe,CAAC,CAAC;AACzE;AAGO,SAAS,YACd,SACA,IACwG;AACxG,SAAO,UAAU,GAAG,OAAO,IAAI,EAAE,WAAW,EAAE,QAAQ,OAAO,CAAC,EAAE;AAAA,IAAK,CAAC,MACpE,KAAoG,CAAC;AAAA,EACvG;AACF;AAGO,SAAS,aAAa,SAAiB,IAA6D;AACzG,SAAO,UAAU,GAAG,OAAO,IAAI,EAAE,YAAY,EAAE,QAAQ,OAAO,CAAC,EAAE;AAAA,IAAK,CAAC,MACrE,KAA6C,CAAC;AAAA,EAChD;AACF;AAGO,SAAS,eACd,SACA,IACA,QAC6B;AAC7B,SAAO,UAAU,GAAG,OAAO,IAAI,EAAE,IAAI,MAAM,IAAI,EAAE,QAAQ,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,KAAyB,CAAC,CAAC;AAC5G;;;AChFA,SAAgB,aAAa,WAAW,WAAAC,UAAS,QAAQ,gBAAgB;;;AC8BlE,SAAS,oBAAoB,YAAoB,OAA0C;AAChG,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,CAAC;AAC5C,QAAM,OAAO,SAAS,CAAC;AACvB,MAAI,KAAK,WAAW,EAAG,QAAO,CAAC;AAG/B,QAAM,OAAO,KAAK,IAAI,MAAM,CAAC;AAC7B,MAAI,WAAW;AACf,WAAS,IAAI,GAAG,IAAI,KAAK,UAAU,WAAW,GAAG,KAAK;AACpD,SAAK,CAAC,IAAI;AACV;AAAA,EACF;AAEA,QAAM,YAAY,IAAI;AACtB,MAAI,YAAY,GAAG;AAEjB,UAAM,eAAe,KAAK,OAAO,CAAC,KAAKC,OAAM,MAAM,KAAK,IAAI,GAAGA,GAAE,OAAO,GAAG,CAAC,KAAK;AACjF,UAAM,QAAQ,KAAK,IAAI,CAACA,OAAO,KAAK,IAAI,GAAGA,GAAE,OAAO,IAAI,eAAgB,SAAS;AACjF,UAAM,SAAS,MAAM,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;AAC7C,QAAI,WAAW,YAAY,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AAE3D,UAAM,QAAQ,KACX,IAAI,CAAC,GAAG,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,OAAO,CAAC,EAAE,EAAE,EACjD,KAAK,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAE9C,aAAS,IAAI,GAAG,IAAI,MAAM,UAAU,WAAW,GAAG,KAAK;AACrD,aAAO,MAAM,CAAC,EAAE,CAAC;AACjB;AAAA,IACF;AACA,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,IAAK,MAAK,CAAC,KAAK,OAAO,CAAC;AAAA,EAC3D;AAEA,SAAO,KAAK,IAAI,CAACA,IAAG,OAAO,EAAE,MAAMA,GAAE,MAAM,OAAO,KAAK,CAAC,GAAG,SAASA,GAAE,QAAQ,EAAE;AAClF;AAMO,SAAS,kBAAkB,WAAyC,YAAmC;AAC5G,MAAI,CAAC,aAAa,UAAU,SAAS,SAAU,QAAO;AACtD,QAAM,QAAQ,UAAU,SAAS,CAAC;AAClC,MAAI,MAAM,SAAS,EAAG,QAAO;AAE7B,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAWA,MAAK,OAAO;AACrB,QAAI,CAACA,GAAE,QAAQ,CAACA,GAAE,KAAK,KAAK,EAAG,QAAO;AACtC,QAAI,KAAK,IAAIA,GAAE,IAAI,EAAG,QAAO,SAASA,GAAE,IAAI;AAC5C,SAAK,IAAIA,GAAE,IAAI;AACf,QAAI,EAAEA,GAAE,UAAU,GAAI,QAAO,SAASA,GAAE,IAAI;AAAA,EAC9C;AAEA,QAAM,aAAa,MAAM,OAAO,CAAC,KAAKA,OAAM,MAAMA,GAAE,SAAS,CAAC;AAC9D,MAAI,KAAK,MAAM,UAAU,MAAM,IAAK,QAAO,8CAA8C,KAAK,MAAM,UAAU,CAAC;AAE/G,MAAI,MAAM,SAAS,KAAK,MAAM,UAAU,GAAG;AACzC,WAAO,mBAAmB,MAAM,MAAM,SAAS,UAAU,QAAQ,eAAe,IAAI,KAAK,GAAG;AAAA,EAC9F;AACA,SAAO;AACT;AAOO,SAAS,mBAAmB,WAAyC,UAAqC;AAC/G,MAAI,CAAC,YAAY,CAAC,aAAa,UAAU,SAAS,aAAc,QAAO,EAAE,MAAM,SAAS;AACxF,MAAI,CAAC,UAAU,SAAS,UAAU,MAAM,SAAS,EAAG,QAAO,EAAE,MAAM,SAAS;AAC5E,SAAO;AACT;;;ACRA,IAAM,0BAA4G;AAAA,EAChH,mBAAmB,EAAE,MAAM,mBAAmB,MAAM,mBAAmB,MAAM,2BAA2B;AAAA,EACxG,mBAAmB,EAAE,MAAM,mBAAmB,MAAM,mBAAmB,MAAM,8BAA8B;AAAA,EAC3G,eAAe,EAAE,MAAM,eAAe,MAAM,eAAe,MAAM,+BAA+B;AAAA,EAChG,qBAAqB,EAAE,MAAM,qBAAqB,MAAM,qBAAqB,MAAM,6BAA6B;AAAA,EAChH,sBAAsB,EAAE,MAAM,sBAAsB,MAAM,sBAAsB,MAAM,qBAAqB;AAC7G;AAQA,SAAS,mBAAmB,QAAkD;AAC5E,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,CAAC,CAAC,mBAAmB,mBAAmB,eAAe,qBAAqB,oBAAoB,CAAC;AAAA,IAC1G,KAAK;AACH,aAAO,CAAC,CAAC,iBAAiB,GAAG,CAAC,aAAa,GAAG,CAAC,mBAAmB,qBAAqB,oBAAoB,CAAC;AAAA,IAC9G,KAAK;AAAA,IACL;AACE,aAAO,CAAC,CAAC,iBAAiB,GAAG,CAAC,iBAAiB,GAAG,CAAC,aAAa,GAAG,CAAC,mBAAmB,GAAG,CAAC,oBAAoB,CAAC;AAAA,EACpH;AACF;AAGA,SAAS,kBAAkB,QAA4B,QAA+C;AACpG,SAAO,mBAAmB,MAAM,EAAE,IAAI,CAAC,UAAU;AAC/C,QAAI,MAAM,WAAW,GAAG;AACtB,YAAM,OAAO,wBAAwB,MAAM,CAAC,CAAC;AAC7C,aAAO,EAAE,SAAS,iBAAiB,MAAM,CAAC,CAAC,IAAI,MAAM,iBAAiB,MAAM,KAAK,MAAM,MAAM,KAAK,MAAM,MAAM,KAAK,MAAM,QAAQ,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;AAAA,IACrJ;AACA,UAAM,QAAQ,MAAM,IAAI,CAAC,MAAM,wBAAwB,CAAC,EAAE,IAAI,EAAE,KAAK,QAAK;AAC1E,WAAO;AAAA,MACL,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM,MAAM,UAAU,IAAI,gCAAgC;AAAA,MAC1D,MAAM;AAAA,MACN;AAAA,MACA,OAAO,CAAC,GAAG,KAAK;AAAA,IAClB;AAAA,EACF,CAAC;AACH;AAaA,SAAS,gBACP,OACA,WACA,eACA,eACY;AACZ,QAAM,MAAM,mBAAmB,aAAa,QAAW,IAAI;AAC3D,MAAI,IAAI,SAAS,gBAAgB,IAAI,SAAS,IAAI,MAAM,UAAU,GAAG;AACnE,UAAM,cAAc,IAAI,eAAe;AACvC,UAAMC,OAAkB,CAAC;AACzB,eAAW,SAAS,oBAAoB,OAAO,IAAI,KAAK,GAAG;AACzD,eAAS,IAAI,GAAG,IAAI,MAAM,OAAO,KAAK;AACpC,QAAAA,KAAI,KAAK,gBAAgB,OAAO,EAAE,QAAQ,eAAe,MAAM,MAAM,KAAK,IAAI,EAAE,QAAQ,MAAM,MAAM,MAAM,KAAK,CAAC;AAAA,MAClH;AAAA,IACF;AACA,WAAOA;AAAA,EACT;AACA,QAAM,MAAkB,CAAC;AACzB,WAAS,IAAI,GAAG,IAAI,OAAO,IAAK,KAAI,KAAK,EAAE,QAAQ,WAAW,eAAe,GAAG,aAAa,GAAG,MAAM,KAAK,CAAC;AAC5G,SAAO;AACT;AAEO,IAAM,cAAgD;AAAA,EAC3D,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AACV;AAGO,IAAM,aAAiC,CAAC,cAAc,iBAAiB,QAAQ,UAAU,QAAQ;AAExG,IAAM,cAAc;AAGpB,SAAS,WAAW,SAA+B,OAAe,UAAwC;AACxG,MAAI,WAAW,QAAQ,SAAS,EAAG,QAAO,QAAQ,QAAQ,QAAQ,MAAM;AACxE,SAAO;AACT;AAWO,SAAS,sBAAsB,OAA2D;AAC/F,QAAM,eAAe,MAAM,kBAAkB,cAAc;AAC3D,QAAM,gBAAgB,MAAM,UAAU;AACtC,QAAM,UAAU,MAAM,WAAW;AACjC,QAAM,QAAgC,CAAC;AAGvC,QAAM,KAAK,EAAE,SAAS,sBAAsB,MAAM,cAAc,MAAM,WAAW,MAAM,WAAW,MAAM,yCAAmC,QAAQ,cAAc,CAAC;AAClK,MAAI,eAAe,SAAS;AAC1B,UAAM,KAAK,EAAE,SAAS,4BAA4B,MAAM,cAAc,MAAM,iBAAiB,MAAM,iBAAiB,MAAM,wBAAwB,QAAQ,cAAc,CAAC;AACzK,UAAM,KAAK,EAAE,SAAS,kBAAkB,MAAM,cAAc,MAAM,OAAO,MAAM,OAAO,MAAM,4BAA4B,QAAQ,SAAS,CAAC;AAAA,EAC5I;AACA,QAAM,KAAK,EAAE,SAAS,kBAAkB,MAAM,cAAc,MAAM,OAAO,MAAM,oBAAoB,MAAM,0BAA0B,QAAQ,KAAK,CAAC;AACjJ,QAAM,KAAK,EAAE,SAAS,sBAAsB,MAAM,cAAc,MAAM,WAAW,MAAM,WAAW,MAAM,cAAc,kCAAkC,iBAAiB,QAAQ,cAAc,CAAC;AAChM,QAAM,KAAK,EAAE,SAAS,sBAAsB,MAAM,cAAc,MAAM,WAAW,MAAM,WAAW,MAAM,oCAAiC,QAAQ,KAAK,CAAC;AACvJ,QAAM,KAAK,EAAE,SAAS,2BAA2B,MAAM,cAAc,MAAM,gBAAgB,MAAM,qBAAqB,MAAM,wBAAwB,QAAQ,KAAK,CAAC;AAElK,MAAI,CAAC,aAAa;AAEhB,UAAM,KAAK,EAAE,SAAS,mBAAmB,MAAM,QAAQ,MAAM,cAAc,MAAM,mBAAmB,MAAM,4CAA4C,QAAQ,cAAc,CAAC;AAC7K,UAAM,KAAK,EAAE,SAAS,cAAc,MAAM,UAAU,MAAM,OAAO,MAAM,wBAAwB,MAAM,kBAAkB,QAAQ,cAAc,CAAC;AAC9I,WAAO,MAAM,IAAI,CAAC,IAAI,MAAM,WAAW,IAAI,CAAC,CAAC;AAAA,EAC/C;AAKA,QAAM,KAAK,GAAG,kBAAkB,MAAM,sBAAsB,aAAa,aAAa,CAAC;AAKvF,QAAM,eAAe,KAAK,IAAI,GAAG,MAAM,gBAAgB,CAAC;AACxD,QAAM,eAAe,gBAAgB,cAAc,MAAM,kBAAkB,eAAe,MAAM,cAAc;AAC9G,WAAS,IAAI,GAAG,IAAI,cAAc,KAAK;AACrC,UAAM,KAAK;AAAA,MACT,SAAS,gBAAgB,IAAI,CAAC;AAAA,MAC9B,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM,gBAAgB,IAAI,CAAC;AAAA,MAC3B,MAAM;AAAA,MACN,QAAQ,aAAa,CAAC,EAAE;AAAA,MACxB,MAAM,aAAa,CAAC,EAAE;AAAA,IACxB,CAAC;AAAA,EACH;AAGA,QAAM,kBAAkB,KAAK,IAAI,GAAG,MAAM,mBAAmB,CAAC;AAC9D,QAAM,kBAAkB,gBAAgB,iBAAiB,MAAM,qBAAqB,eAAe,MAAM,iBAAiB;AAC1H,WAAS,IAAI,GAAG,IAAI,iBAAiB,KAAK;AACxC,UAAM,KAAK;AAAA,MACT,SAAS,sBAAsB,IAAI,CAAC;AAAA,MACpC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM,eAAe,IAAI,CAAC;AAAA,MAC1B,MAAM,MAAM,IAAI,0BAA0B;AAAA,MAC1C,QAAQ,gBAAgB,CAAC,EAAE;AAAA,MAC3B,MAAM,gBAAgB,CAAC,EAAE;AAAA,IAC3B,CAAC;AAAA,EACH;AAIA,QAAM,KAAK,EAAE,SAAS,cAAc,MAAM,UAAU,MAAM,OAAO,MAAM,wBAAwB,MAAM,yBAAyB,QAAQ,cAAc,CAAC;AACrJ,QAAM,sBAAsB,KAAK,IAAI,GAAG,MAAM,uBAAuB,CAAC;AACtE,WAAS,IAAI,GAAG,IAAI,qBAAqB,KAAK;AAC5C,UAAM,KAAK;AAAA,MACT,SAAS,0BAA0B,IAAI,CAAC;AAAA,MACxC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM,mBAAmB,IAAI,CAAC;AAAA,MAC9B,MAAM;AAAA,MACN,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,SAAO,MAAM,IAAI,CAAC,IAAI,MAAM,WAAW,IAAI,CAAC,CAAC;AAC/C;AAGA,SAAS,WAAW,MAA4B,OAA6D;AAC3G,SAAO,EAAE,GAAG,MAAM,WAAW,MAAM;AACrC;AAQO,IAAM,mBAA0E;AAAA,EACrF,EAAE,KAAK,QAAQ,OAAO,gBAAgB,QAAQ,2DAA2D;AAAA,EACzG,EAAE,KAAK,cAAc,OAAO,wBAAwB,QAAQ,yDAAyD;AAAA,EACrH,EAAE,KAAK,WAAW,OAAO,+CAA4C,QAAQ,6CAA6C;AAAA,EAC1H,EAAE,KAAK,WAAW,OAAO,0BAA0B,QAAQ,4CAA4C;AAAA,EACvG,EAAE,KAAK,YAAY,OAAO,iCAAiC,QAAQ,4DAA4D;AAAA,EAC/H,EAAE,KAAK,gBAAgB,OAAO,+BAA+B,QAAQ,oDAAoD;AAAA,EACzH,EAAE,KAAK,YAAY,OAAO,0CAA0C,QAAQ,gDAAgD;AAAA,EAC5H,EAAE,KAAK,eAAe,OAAO,6BAA6B,QAAQ,6CAA6C;AAAA,EAC/G,EAAE,KAAK,UAAU,OAAO,2BAA2B,QAAQ,oDAAoD;AACjH;;;ACvRM,SAaM,UAZJ,OAAAC,MADF,QAAAC,aAAA;AATC,IAAM,cAA0C,CAAC,EAAE,OAAO,UAAU,MAAM;AAC/E,QAAM,cAAc,MAAM,mBAAmB;AAC7C,QAAM,cAAc,IAAI;AAAA,IACtB,UAAU,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,MAAmB,QAAQ,CAAC,KAAK,MAAM,QAAQ;AAAA,EACxF,EAAE;AACF,QAAM,aAAa,UAAU,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,EAAE;AAEjE,SACE,gBAAAA,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAG,GAC9D;AAAA,oBAAAA,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,qBAAqB,wCAAwC,KAAK,GAAG,GAClG;AAAA,sBAAAD,KAAC,aAAU,OAAM,iBAAgB,OAAO,MAAM,gBAAgB,UAAK;AAAA,MACnE,gBAAAA,KAAC,aAAU,OAAM,gBAAe,OAAO,MAAM,mBAAmB,UAAK;AAAA,MACrE,gBAAAA,KAAC,aAAU,OAAM,WAAU,OAAO,gBAAgB,MAAM,SAAS,IAAI,WAAM;AAAA,MAC3E,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,UAAU,SAAS,oBAAoB;AAAA,UAC9C,OAAO,UAAU,SAAS,GAAG,UAAU,MAAM,UAAU,MAAM,KAAK;AAAA;AAAA,MACpE;AAAA,OACF;AAAA,IAEA,gBAAAA,KAAC,SAAM,OAAM,sBACX,0BAAAC,MAAC,OAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,IAAI,YAAY,KAAK,OAAO,OAAO,MAAM,GACvE;AAAA,oBACC,gBAAAA,MAAA,YAAE;AAAA;AAAA,QAG6E;AAAA,QAC5E,MAAM;AAAA,QAAa;AAAA,QAA0B,MAAM;AAAA,QAAgB;AAAA,SAEtE,IAEA,gBAAAD,KAAA,YAAE,qOAGF;AAAA,MACC;AAAA,MAAI;AAAA,MACC,gBAAAA,KAAC,YAAO,uBAAS;AAAA,MAAS;AAAA,MAA2B,gBAAAA,KAAC,YAAO,sBAAQ;AAAA,MAAS;AAAA,OACxF,GACF;AAAA,KACF;AAEJ;;;ACfI,gBAAAE,MACA,QAAAC,aADA;AA9BJ,IAAM,SAAiC;AAAA,EACrC,OAAO,OAAO;AAAA,EACd,cAAc,OAAO;AAAA,EACrB,WAAW,OAAO;AAAA,EAClB,QAAQ,OAAO;AAAA,EACf,aAAa,OAAO;AACtB;AAEA,IAAM,SAAmD;AAAA,EACvD,EAAE,QAAQ,SAAS,OAAO,QAAQ;AAAA,EAClC,EAAE,QAAQ,gBAAgB,OAAO,eAAe;AAAA,EAChD,EAAE,QAAQ,aAAa,OAAO,YAAY;AAAA,EAC1C,EAAE,QAAQ,UAAU,OAAO,SAAS;AAAA,EACpC,EAAE,QAAQ,eAAe,OAAO,cAAc;AAChD;AAEA,IAAM,eAAqD,CAAC,EAAE,SAAS,MACrE,gBAAAA;AAAA,EAAC;AAAA;AAAA,IACC,OAAO;AAAA,MACL,UAAU;AAAA,MACV,QAAQ,aAAa,OAAO,MAAM;AAAA,MAClC,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,SAAS;AAAA,MACT,SAAS;AAAA,MACT,eAAe;AAAA,MACf,KAAK;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,IAEA;AAAA,sBAAAD,KAAC,UAAK,OAAO,EAAE,UAAU,YAAY,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,OAAO,SAAS,MAAM,KAAK,OAAO,YAAY,GAAG;AAAA,MACxI,gBAAAC,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,gBAAgB,iBAAiB,KAAK,EAAE,GAC3F;AAAA,wBAAAD,KAAC,UAAK,OAAO,EAAE,YAAY,KAAK,UAAU,IAAI,OAAO,OAAO,KAAK,GAAI,mBAAS,MAAK;AAAA,QACnF,gBAAAA,KAAC,gBAAa,QAAQ,SAAS,QAAQ;AAAA,SACzC;AAAA,MACC,SAAS,OAAO,gBAAAA,KAAC,SAAI,OAAO,EAAE,UAAU,IAAI,OAAO,OAAO,MAAM,GAAI,mBAAS,MAAK,IAAS;AAAA,MAC5F,gBAAAC,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,gBAAgB,iBAAiB,KAAK,GAAG,UAAU,IAAI,OAAO,OAAO,MAAM,GAC9H;AAAA,wBAAAD,KAAC,UAAM,mBAAS,OAAO,GAAG,SAAS,UAAU,EAAE,SAAM,SAAS,IAAI,KAAK,SAAS,UAAU,UAAI;AAAA,QAC9F,gBAAAA,KAAC,UAAK,OAAO,EAAE,YAAY,6CAA6C,OAAO,OAAO,MAAM,GACzF,mBAAS,eAAe,UAC3B;AAAA,SACF;AAAA;AAAA;AACF;AAeK,IAAM,eAA4C,CAAC,EAAE,WAAW,QAAQ,MAAM;AACnF,MAAI,UAAU,WAAW,GAAG;AAC1B,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,aAAY;AAAA;AAAA,IACd;AAAA,EAEJ;AAEA,SACE,gBAAAC,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAG,GAC7D;AAAA,cACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,UAAU;AAAA,UACV,OAAO,OAAO;AAAA,UACd,YAAY,OAAO;AAAA,UACnB,QAAQ,aAAa,OAAO,MAAM;AAAA,UAClC,cAAc;AAAA,UACd,SAAS;AAAA,QACX;AAAA,QACD;AAAA;AAAA,UACiE,gBAAAD,KAAC,YAAO,kBAAI;AAAA,UAAS;AAAA;AAAA;AAAA,IAEvF,IACE;AAAA,IAEJ,gBAAAA,KAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,UAAU,QAAQ,KAAK,IAAI,UAAU,IAAI,OAAO,OAAO,MAAM,GACzF,iBAAO,IAAI,CAAC,MACX,gBAAAC,MAAC,UAAoB,OAAO,EAAE,SAAS,eAAe,YAAY,UAAU,KAAK,EAAE,GACjF;AAAA,sBAAAD,KAAC,UAAK,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,cAAc,OAAO,YAAY,OAAO,EAAE,MAAM,EAAE,GAAG;AAAA,MACxF,EAAE;AAAA,SAFM,EAAE,MAGb,CACD,GACH;AAAA,IAEC,WAAW,IAAI,CAAC,SAAS;AACxB,YAAM,SAAS,UAAU,OAAO,CAAC,MAAM,EAAE,SAAU,IAAyB;AAC5E,UAAI,OAAO,WAAW,EAAG,QAAO;AAChC,YAAM,QAAQ,OAAO,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,EAAE;AACzD,aACE,gBAAAC,MAAC,SACC;AAAA,wBAAAA,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,YAAY,KAAK,IAAI,cAAc,EAAE,GAC9E;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,QAAQ;AAAA,gBACR,UAAU;AAAA,gBACV,eAAe;AAAA,gBACf,eAAe;AAAA,gBACf,OAAO,OAAO;AAAA,cAChB;AAAA,cAEC,sBAAY,IAAwB;AAAA;AAAA,UACvC;AAAA,UACA,gBAAAC,MAAC,UAAK,OAAO,EAAE,UAAU,IAAI,OAAO,OAAO,OAAO,oBAAoB,eAAe,GAClF;AAAA,mBAAO;AAAA,YAAO;AAAA,YAAE,OAAO,WAAW,IAAI,aAAa;AAAA,YACnD,CAAC,UAAU,SAAM,KAAK,WAAW;AAAA,aACpC;AAAA,WACF;AAAA,QACA,gBAAAD,KAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,qBAAqB,yCAAyC,KAAK,GAAG,GAClG,iBAAO,IAAI,CAAC,MACX,gBAAAA,KAAC,gBAA6B,UAAU,KAArB,EAAE,OAAsB,CAC5C,GACH;AAAA,WAtBQ,IAuBV;AAAA,IAEJ,CAAC;AAAA,KACH;AAEJ;;;ACrHI,gBAAAE,MAaA,QAAAC,aAbA;AATJ,IAAM,aAAqC;AAAA,EACzC,MAAM,OAAO;AAAA,EACb,SAAS,OAAO;AAAA,EAChB,QAAQ,OAAO;AAAA,EACf,SAAS,OAAO;AAClB;AAEA,IAAM,WAAkE,CAAC,EAAE,MAAM,KAAK,MACpF,gBAAAA,MAAC,SAAI,OAAO,EAAE,UAAU,YAAY,eAAe,OAAO,IAAI,GAAG,GAC/D;AAAA,kBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM;AAAA,QACN,KAAK;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,cAAc;AAAA,QACd,YAAY,WAAW,KAAK,MAAM,KAAK,WAAW;AAAA,QAClD,QAAQ,aAAa,OAAO,OAAO;AAAA,QACnC,WAAW,aAAa,OAAO,MAAM;AAAA,MACvC;AAAA;AAAA,EACF;AAAA,EACA,gBAAAC,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,IAAI,UAAU,OAAO,GAC7E;AAAA,oBAAAD,KAAC,UAAK,OAAO,EAAE,YAAY,KAAK,UAAU,IAAI,OAAO,OAAO,KAAK,GAAI,eAAK,OAAM;AAAA,IAChF,gBAAAA,KAAC,SAAM,SAAS,kBAAkB,KAAK,MAAM,GAAG,MAAK,MAClD,eAAK,QACR;AAAA,IACA,gBAAAA,KAAC,UAAK,OAAO,EAAE,UAAU,IAAI,OAAO,OAAO,MAAM,GAC9C,eAAK,cAAc,eAAe,KAAK,WAAW,IAAI,KAAK,YAAY,eAAe,KAAK,SAAS,IAAI,IAC3G;AAAA,KACF;AAAA,EACC,KAAK,SAAS,gBAAAA,KAAC,SAAI,OAAO,EAAE,UAAU,IAAI,OAAO,OAAO,OAAO,WAAW,EAAE,GAAI,eAAK,QAAO,IAAS;AAAA,EACrG,KAAK,OACJ,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,WAAW;AAAA,QACX,YAAY,OAAO;AAAA,QACnB,QAAQ,aAAa,OAAO,MAAM;AAAA,QAClC,cAAc;AAAA,QACd,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,OAAO,OAAO;AAAA,QACd,YAAY;AAAA,QACZ,WAAW;AAAA,MACb;AAAA,MAEC,eAAK;AAAA;AAAA,EACR,IACE;AAAA,GACN;AAGF,IAAM,cAAiD,CAAC,EAAE,IAAI,MAC5D,gBAAAC,MAAC,SACC;AAAA,kBAAAA,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,IAAI,cAAc,IAAI,UAAU,OAAO,GAC/F;AAAA,oBAAAA,MAAC,QAAG,OAAO,EAAE,QAAQ,GAAG,UAAU,IAAI,YAAY,KAAK,OAAO,OAAO,MAAM,eAAe,aAAa,GACpG;AAAA,UAAI;AAAA,MAAO;AAAA,OACd;AAAA,IACA,gBAAAD,KAAC,SAAM,SAAS,IAAI,WAAW,cAAc,YAAY,IAAI,WAAW,WAAW,WAAW,QAAQ,MAAK,MACxG,cAAI,QACP;AAAA,IACA,gBAAAC,MAAC,UAAK,OAAO,EAAE,UAAU,IAAI,OAAO,OAAO,MAAM,GAAG;AAAA;AAAA,MAAS,eAAe,IAAI,SAAS;AAAA,OAAE;AAAA,KAC7F;AAAA,EACA,gBAAAA,MAAC,SAAI,OAAO,EAAE,UAAU,YAAY,aAAa,GAAG,GAClD;AAAA,oBAAAD,KAAC,UAAK,OAAO,EAAE,UAAU,YAAY,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,OAAO,OAAO,GAAG;AAAA,IACvG,IAAI,MAAM,IAAI,CAACE,IAAG,MACjB,gBAAAF,KAAC,YAA6B,MAAME,IAAG,MAAM,MAAM,IAAI,MAAM,SAAS,KAAvDA,GAAE,MAAMA,GAAE,GAAgD,CAC1E;AAAA,KACH;AAAA,GACF;AAQK,IAAM,cAA0C,CAAC,EAAE,YAAY,MAAM;AAC1E,MAAI,YAAY,WAAW,GAAG;AAC5B,WACE,gBAAAF;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,aAAY;AAAA;AAAA,IACd;AAAA,EAEJ;AACA,QAAM,CAAC,QAAQ,GAAG,QAAQ,IAAI;AAC9B,SACE,gBAAAC,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAG,GAC9D;AAAA,oBAAAD,KAAC,eAAY,KAAK,QAAQ;AAAA,IACzB,SAAS,SAAS,IACjB,gBAAAC,MAAC,SACC;AAAA,sBAAAD,KAAC,QAAG,OAAO,EAAE,QAAQ,YAAY,UAAU,IAAI,eAAe,SAAS,eAAe,aAAa,OAAO,OAAO,MAAM,GAAG,0BAE1H;AAAA,MACA,gBAAAA,KAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,EAAE,GAC5D,mBAAS,IAAI,CAAC,QACb,gBAAAC;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO;AAAA,YACL,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,gBAAgB;AAAA,YAChB,KAAK;AAAA,YACL,SAAS;AAAA,YACT,QAAQ,aAAa,OAAO,MAAM;AAAA,YAClC,cAAc;AAAA,YACd,YAAY,OAAO;AAAA,YACnB,UAAU;AAAA,UACZ;AAAA,UAEA;AAAA,4BAAAD,KAAC,UAAK,OAAO,EAAE,eAAe,cAAc,OAAO,OAAO,KAAK,GAAI,cAAI,QAAO;AAAA,YAC9E,gBAAAA,KAAC,UAAK,OAAO,EAAE,OAAO,OAAO,MAAM,GAAI,yBAAe,IAAI,SAAS,GAAE;AAAA,YACrE,gBAAAA,KAAC,SAAM,SAAS,IAAI,WAAW,cAAc,YAAY,IAAI,WAAW,WAAW,WAAW,QAAQ,MAAK,MACxG,cAAI,QACP;AAAA;AAAA;AAAA,QAjBK,IAAI;AAAA,MAkBX,CACD,GACH;AAAA,OACF,IACE;AAAA,KACN;AAEJ;;;ACnGE,SA2FQ,YAAAG,WAhFN,OAAAC,MAXF,QAAAC,aAAA;AA1BF,IAAM,OAAO;AAUb,SAAS,OAAO,KAA+C;AAC7D,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,IAAI,IAAI,KAAK;AACnB,MAAI,gBAAgB,KAAK,CAAC,GAAG;AAC3B,QAAI;AACF,aAAO,IAAI,IAAI,CAAC,EAAE;AAAA,IACpB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,WAAW;AACjB,SAAO,SAAS,KAAK,CAAC,IAAI,IAAI;AAChC;AAEA,IAAM,MAAkD,CAAC,EAAE,OAAO,MAAM,MACtE,gBAAAA;AAAA,EAAC;AAAA;AAAA,IACC,OAAO;AAAA,MACL,SAAS;AAAA,MACT,qBAAqB;AAAA,MACrB,KAAK;AAAA,MACL,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,cAAc,aAAa,OAAO,MAAM;AAAA,MACxC,UAAU;AAAA,IACZ;AAAA,IAEA;AAAA,sBAAAD,KAAC,UAAK,OAAO,EAAE,OAAO,OAAO,MAAM,GAAI,iBAAM;AAAA,MAC7C,gBAAAA,KAAC,UAAK,OAAO,EAAE,YAAY,MAAM,UAAU,MAAM,OAAO,OAAO,MAAM,cAAc,WAAW,GAAI,iBAAM;AAAA;AAAA;AAC1G;AAeK,IAAM,YAAsC,CAAC,EAAE,OAAO,UAAU,MAAM;AAC3E,MAAI,CAAC,UAAU,MAAM,MAAM,GAAG;AAC5B,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,aAAY;AAAA;AAAA,IACd;AAAA,EAEJ;AAEA,QAAM,QAAQ,CAAC,YACb,UAAU,KAAK,CAAC,MAAM,EAAE,YAAY,OAAO,GAAG,eAAe;AAI/D,QAAM,UAAU,OAAO,MAAM,gBAAgB,CAAC;AAC9C,QAAM,UAAU,OAAO,MAAM,YAAY,CAAC;AAC1C,QAAM,UAAU,WAAW;AAC3B,QAAM,UAAU,WAAW;AAG3B,QAAM,iBAAiB,UACpB,OAAO,CAAC,MAAM,EAAE,SAAS,SAAS,EAClC,IAAI,CAAC,MAAM,OAAO,EAAE,WAAW,CAAC,EAChC,OAAO,CAAC,MAAmB,QAAQ,CAAC,CAAC,EACrC,IAAI,CAAC,MAAM,GAAG,CAAC,OAAO;AAEzB,QAAM,YAAqD,CAAC;AAC5D,MAAI,SAAS;AACX,cAAU,KAAK,EAAE,OAAO,uBAAuB,OAAO,WAAW,OAAO,GAAG,CAAC;AAC5E,cAAU,KAAK,EAAE,OAAO,kBAAkB,OAAO,WAAW,OAAO,QAAQ,CAAC;AAAA,EAC9E;AACA,MAAI,SAAS;AACX,cAAU,KAAK,EAAE,OAAO,wBAAwB,OAAO,WAAW,OAAO,2BAA2B,CAAC;AAAA,EACvG;AAIA,MAAI,UAAU,WAAW,GAAG;AAC1B,WACE,gBAAAA,KAAC,SAAM,OAAM,aACX,0BAAAC,MAAC,OAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,IAAI,YAAY,KAAK,OAAO,OAAO,MAAM,GAAG;AAAA;AAAA,MAGvB,gBAAAD,KAAC,YAAO,uBAAS;AAAA,MAAS;AAAA,OAEhF,GACF;AAAA,EAEJ;AAEA,QAAM,cAAc,MAAM,KAAK,YAAY,EAAE,QAAQ,eAAe,GAAG,EAAE,QAAQ,YAAY,EAAE,KAAK;AAEpG,SACE,gBAAAC,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAG,GAC9D;AAAA,oBAAAD,KAAC,SAAM,OAAM,aACV,oBAAU,IAAI,CAAC,MACd,gBAAAA,KAAC,OAAkB,OAAO,EAAE,OAAO,OAAO,EAAE,SAAlC,EAAE,KAAuC,CACpD,GACH;AAAA,IAEA,gBAAAA,KAAC,SAAM,OAAM,yCACV,yBAAe,SAAS,IACvB,gBAAAC,MAAAF,WAAA,EACE;AAAA,sBAAAE,MAAC,OAAE,OAAO,EAAE,QAAQ,YAAY,UAAU,IAAI,OAAO,OAAO,MAAM,GAAG;AAAA;AAAA,QACzB,gBAAAD,KAAC,UAAK,OAAO,EAAE,YAAY,KAAK,GAAG,0BAAY;AAAA,QAAO;AAAA,SAClG;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,YACL,QAAQ;AAAA,YACR,YAAY,OAAO;AAAA,YACnB,QAAQ,aAAa,OAAO,MAAM;AAAA,YAClC,cAAc;AAAA,YACd,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,OAAO,OAAO;AAAA,YACd,WAAW;AAAA,UACb;AAAA,UAEC;AAAA,iBACE,WAAW;AAAA;AAAA,UAElB,WAAW;AAAA,WACV,eAAe,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,MAExB;AAAA,OACF,IAEA,gBAAAA,KAAC,OAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,IAAI,OAAO,OAAO,MAAM,GAAG,0FAE5D,GAEJ;AAAA,KACF;AAEJ;;;AC5IM,SAqBM,YAAAE,WArBN,OAAAC,MAsBQ,QAAAC,aAtBR;AAHC,IAAM,mBAAoD,CAAC,EAAE,OAAO,WAAW,MAAM;AAC1F,MAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,aAAY;AAAA;AAAA,IACd;AAAA,EAEJ;AAEA,QAAM,UAAU,CAAC,SAA6C;AAC5D,QAAI,cAAc,KAAK,aAAc,QAAO,GAAG,UAAU,IAAI,KAAK,YAAY;AAC9E,WAAO,KAAK;AAAA,EACd;AAEA,SACE,gBAAAC,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAG,GAC9D;AAAA,oBAAAD,KAAC,OAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,IAAI,OAAO,OAAO,MAAM,GAAG,sHAE5D;AAAA,IACA,gBAAAA,KAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,qBAAqB,yCAAyC,KAAK,GAAG,GAClG,gBAAM,IAAI,CAAC,SAAS;AACnB,YAAM,MAAM,QAAQ,IAAI;AACxB,YAAM,QACJ,gBAAAC,MAAAF,WAAA,EACE;AAAA,wBAAAE,MAAC,QAAG,OAAO,EAAE,QAAQ,WAAW,UAAU,IAAI,SAAS,QAAQ,gBAAgB,iBAAiB,OAAO,OAAO,KAAK,GAChH;AAAA,eAAK;AAAA,UACN,gBAAAD,KAAC,UAAK,OAAO,EAAE,OAAO,OAAO,MAAM,GAAG,eAAW,MAAC,oBAElD;AAAA,WACF;AAAA,QACA,gBAAAA,KAAC,OAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,IAAI,OAAO,OAAO,MAAM,GAAI,eAAK,aAAY;AAAA,SAChF;AAEF,YAAM,YAAiC;AAAA,QACrC,QAAQ,aAAa,OAAO,MAAM;AAAA,QAClC,cAAc;AAAA,QACd,SAAS;AAAA,QACT,YAAY,OAAO;AAAA,QACnB,gBAAgB;AAAA,QAChB,OAAO;AAAA,QACP,SAAS;AAAA,QACT,QAAQ,MAAM,YAAY;AAAA,QAC1B,SAAS,MAAM,IAAI;AAAA,MACrB;AACA,aAAO,MACL,gBAAAA,KAAC,OAAiB,MAAM,KAAK,OAAO,WACjC,mBADK,KAAK,GAEb,IAEA,gBAAAA,KAAC,SAAmB,OAAO,WAAW,OAAM,iCACzC,mBADO,KAAK,GAEf;AAAA,IAEJ,CAAC,GACH;AAAA,KACF;AAEJ;;;AChEE,SAUE,OAAAE,MAVF,QAAAC,aAAA;AADF,IAAMC,OAA2D,CAAC,EAAE,OAAO,MAAM,MAC/E,gBAAAD;AAAA,EAAC;AAAA;AAAA,IACC,OAAO;AAAA,MACL,SAAS;AAAA,MACT,qBAAqB;AAAA,MACrB,KAAK;AAAA,MACL,SAAS;AAAA,MACT,cAAc,aAAa,OAAO,MAAM;AAAA,MACxC,UAAU;AAAA,IACZ;AAAA,IAEA;AAAA,sBAAAD,KAAC,UAAK,OAAO,EAAE,OAAO,OAAO,MAAM,GAAI,iBAAM;AAAA,MAC7C,gBAAAA,KAAC,UAAK,OAAO,EAAE,OAAO,OAAO,MAAM,YAAY,IAAI,GAAI,iBAAM;AAAA;AAAA;AAC/D;AAYK,IAAM,cAA0C,CAAC,EAAE,OAAO,MAAM,QAAQ,WAAW,SAAS,MAAM;AACvG,QAAM,WAAW,MAAM,iBAAiB,MAAM,kBAAkB,UAAU;AAC1E,QAAM,gBAAgB,aAAa,MAAM,MAAM;AAE/C,SACE,gBAAAC,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAG,GAC9D;AAAA,oBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,SACE,gBAAAD,KAAC,UAAO,SAAQ,SAAQ,MAAK,MAAK,SAAS,QAAQ,UAAU,MAAM,kBAEnE;AAAA,QAGF;AAAA,0BAAAA,KAACE,MAAA,EAAI,OAAM,QAAO,OAAO,MAAM,MAAM;AAAA,UACrC,gBAAAF,KAACE,MAAA,EAAI,OAAM,mBAAkB,OAAO,MAAM,kBAAkB,UAAK;AAAA,UACjE,gBAAAF,KAACE,MAAA,EAAI,OAAM,2BAA0B,OAAO,GAAG,MAAM,gBAAgB,QAAG,MAAM,MAAM,mBAAmB,QAAG,IAAI;AAAA,UAC9G,gBAAAF,KAACE,MAAA,EAAI,OAAM,YAAW,OAAO,UAAU;AAAA,UACvC,gBAAAF,KAACE,MAAA,EAAI,OAAM,UAAS,OAAO,MAAM,UAAU,UAAK;AAAA,UAChD,gBAAAF,KAACE,MAAA,EAAI,OAAM,eAAc,OAAO,MAAM,mBAAmB,UAAK;AAAA;AAAA;AAAA,IAChE;AAAA,IAEA,gBAAAD,MAAC,SAAI,OAAO,EAAE,QAAQ,aAAa,OAAO,MAAM,IAAI,cAAc,IAAI,SAAS,YAAY,GACzF;AAAA,sBAAAD,KAAC,QAAG,OAAO,EAAE,QAAQ,WAAW,UAAU,IAAI,OAAO,OAAO,OAAO,GAAG,yBAAW;AAAA,MACjF,gBAAAA,KAAC,OAAE,OAAO,EAAE,QAAQ,YAAY,UAAU,IAAI,OAAO,OAAO,MAAM,GAC/D,0BACG,sFACA,4GACN;AAAA,MACA,gBAAAC,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,GAAG,UAAU,OAAO,GACrD;AAAA,SAAC,gBACA,gBAAAD,KAAC,UAAO,SAAQ,SAAQ,MAAK,MAAK,SAAS,WAAW,UAAU,MAAM,oCAEtE,IACE;AAAA,QACJ,gBAAAA,KAAC,UAAO,SAAQ,UAAS,MAAK,MAAK,SAAS,UAAU,UAAU,MAAM,2BAEtE;AAAA,SACF;AAAA,OACF;AAAA,KACF;AAEJ;;;ACzEA,OAAO,WAAW;;;ACgHlB,IAAM,KAAK,CAAC,MAAiD,KAAK,OAAO,OAAO;AAGhF,SAAS,QAAQ,SAA0B,SAAmC;AAC5E,SACE,QAAQ,SAAS,QAAQ,QACzB,QAAQ,SAAS,QAAQ,QACzB,QAAQ,SAAS,QAAQ,QACzB,GAAG,QAAQ,IAAI,MAAM,GAAG,QAAQ,IAAI,KACpC,GAAG,QAAQ,MAAM,MAAM,GAAG,QAAQ,MAAM;AAE5C;AAGA,SAAS,YAAY,QAA0B;AAC7C,SAAO,WAAW,YAAY,WAAW;AAC3C;AAaO,SAAS,SAAS,SAA4B,SAAsC;AACzF,QAAM,eAAe,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;AAC/D,QAAM,cAAc,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;AAEzD,QAAM,MAAyB,CAAC;AAChC,QAAM,SAA4B,CAAC;AACnC,QAAM,OAA0B,CAAC;AAEjC,aAAW,QAAQ,SAAS;AAC1B,UAAM,WAAW,aAAa,IAAI,KAAK,OAAO;AAC9C,QAAI,CAAC,SAAU,KAAI,KAAK,IAAI;AAAA,aACnB,QAAQ,UAAU,IAAI,KAAK,YAAY,SAAS,MAAM,EAAG,QAAO,KAAK,IAAI;AAAA,QAC7E,MAAK,KAAK,IAAI;AAAA,EACrB;AAEA,QAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,OAAO,CAAC;AAEjE,SAAO,EAAE,KAAK,QAAQ,SAAS,KAAK;AACtC;AAGA,SAAS,SAAS,MAAsB;AACtC,QAAM,MAAO,WAAiC,QAAQ,IAAI;AAC1D,SAAO,QAAQ,KAAK,WAAW,SAAS;AAC1C;AAOO,SAAS,cAAc,SAA4B,SAAsC;AAC9F,QAAM,OAAO,SAAS,SAAS,OAAO;AACtC,QAAM,UAA2B;AAAA,IAC/B,KAAK,KAAK,IAAI;AAAA,IACd,QAAQ,KAAK,OAAO;AAAA,IACpB,SAAS,KAAK,QAAQ;AAAA,IACtB,MAAM,KAAK,KAAK;AAAA,EAClB;AAEA,QAAM,SAAS,oBAAI,IAAwB;AAC3C,aAAW,KAAK,KAAK,IAAK,QAAO,IAAI,EAAE,SAAS,KAAK;AACrD,aAAW,KAAK,KAAK,OAAQ,QAAO,IAAI,EAAE,SAAS,QAAQ;AAC3D,aAAW,KAAK,KAAK,KAAM,QAAO,IAAI,EAAE,SAAS,MAAM;AAGvD,QAAM,QAAkB,CAAC;AAEzB,UAAQ,QAAQ,CAAC,GAAG,MAAM;AACxB,UAAM,KAAK;AAAA,MACT,MAAM,EAAE;AAAA,MACR,MAAM,EAAE,aAAa;AAAA,MACrB,SAAS,EAAE;AAAA,MACX,QAAQ,OAAO,IAAI,EAAE,OAAO,KAAK;AAAA,MACjC,MAAM,EAAE;AAAA,MACR,MAAM,GAAG,EAAE,IAAI;AAAA,MACf,QAAQ,GAAG,EAAE,MAAM;AAAA,MACnB,MAAM,EAAE;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AAED,QAAM,OAAO,QAAQ;AACrB,OAAK,QAAQ,QAAQ,CAAC,GAAG,MAAM;AAC7B,UAAM,KAAK;AAAA,MACT,MAAM,EAAE;AAAA,MACR,MAAM,OAAO;AAAA,MACb,SAAS,EAAE;AAAA,MACX,QAAQ;AAAA,MACR,MAAM,EAAE;AAAA,MACR,MAAM,GAAG,EAAE,IAAI;AAAA,MACf,QAAQ,GAAG,EAAE,MAAM;AAAA,MACnB,MAAM,EAAE;AAAA,IACV,CAAC;AAAA,EACH,CAAC;AAED,QAAM,KAAK,CAAC,GAAG,MAAM,SAAS,EAAE,IAAI,IAAI,SAAS,EAAE,IAAI,KAAK,EAAE,OAAO,EAAE,IAAI;AAE3E,QAAM,SAA0B,CAAC;AACjC,QAAM,SAAS,oBAAI,IAA2B;AAC9C,aAAW,QAAQ,OAAO;AACxB,QAAI,QAAQ,OAAO,IAAI,KAAK,IAAI;AAChC,QAAI,CAAC,OAAO;AACV,cAAQ,EAAE,MAAM,KAAK,MAAM,OAAO,CAAC,EAAE;AACrC,aAAO,IAAI,KAAK,MAAM,KAAK;AAC3B,aAAO,KAAK,KAAK;AAAA,IACnB;AACA,UAAM,MAAM,KAAK;AAAA,MACf,SAAS,KAAK;AAAA,MACd,QAAQ,KAAK;AAAA,MACb,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,QAAQ,KAAK;AAAA,MACb,MAAM,KAAK;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,SAAS,OAAO;AAC3B;AAGO,SAAS,eAAe,SAAmC;AAChE,SAAO,QAAQ,MAAM,QAAQ,SAAS,QAAQ,UAAU;AAC1D;;;AC3MM,gBAAAG,MAqBA,QAAAC,aArBA;AA3BC,IAAM,cAAmF;AAAA,EAC9F,KAAK,EAAE,OAAO,KAAK,OAAO,OAAO,SAAS,OAAO,MAAM;AAAA,EACvD,QAAQ,EAAE,OAAO,KAAK,OAAO,OAAO,SAAS,OAAO,SAAS;AAAA,EAC7D,SAAS,EAAE,OAAO,UAAK,OAAO,OAAO,QAAQ,OAAO,UAAU;AAAA,EAC9D,MAAM,EAAE,OAAO,QAAK,OAAO,OAAO,OAAO,OAAO,YAAY;AAC9D;AAEO,IAAM,YAAY,CAAC,SACxB,YAAY,IAAwB,KAAK,KAAK,QAAQ,MAAM,GAAG;AAG1D,IAAM,WAA4E,CAAC,EAAE,KAAK,MAAM;AACrG,QAAM,OAAO,YAAY,KAAK,MAAM;AACpC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,UAAU;AAAA,QACV,QAAQ,aAAa,OAAO,MAAM;AAAA,QAClC,cAAc;AAAA,QACd,YAAY,OAAO;AAAA,QACnB,SAAS;AAAA,QACT,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,KAAK;AAAA,QACL,UAAU;AAAA,MACZ;AAAA,MAEA;AAAA,wBAAAD,KAAC,UAAK,OAAO,EAAE,UAAU,YAAY,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,KAAK,MAAM,GAAG;AAAA,QACrG,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,eAAW;AAAA,YACX,OAAO,KAAK;AAAA,YACZ,OAAO;AAAA,cACL,MAAM;AAAA,cACN,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,cAAc;AAAA,cACd,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,YAAY;AAAA,cACZ,UAAU;AAAA,cACV,YAAY;AAAA,cACZ,OAAO,KAAK;AAAA,cACZ,YAAY,OAAO;AAAA,YACrB;AAAA,YAEC,eAAK;AAAA;AAAA,QACR;AAAA,QACA,gBAAAC,MAAC,SAAI,OAAO,EAAE,UAAU,GAAG,MAAM,EAAE,GACjC;AAAA,0BAAAD,KAAC,SAAI,OAAO,EAAE,YAAY,KAAK,UAAU,IAAI,OAAO,OAAO,MAAM,gBAAgB,KAAK,WAAW,YAAY,iBAAiB,OAAO,GAClI,eAAK,MACR;AAAA,UACC,KAAK,OAAO,gBAAAA,KAAC,SAAI,OAAO,EAAE,UAAU,IAAI,OAAO,OAAO,MAAM,GAAI,eAAK,MAAK,IAAS;AAAA,WACtF;AAAA,QACA,gBAAAA,KAAC,UAAK,OAAO,EAAE,UAAU,IAAI,OAAO,OAAO,OAAO,MAAM,OAAO,GAAI,eAAK,UAAU,UAAI;AAAA;AAAA;AAAA,EACxF;AAEJ;AAGO,IAAM,YAAoF,CAAC,EAAE,MAAM,MAAM,MAC9G,gBAAAC,MAAC,SACC;AAAA,kBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,eAAe;AAAA,QACf,eAAe;AAAA,QACf,OAAO,OAAO;AAAA,MAChB;AAAA,MAEC,oBAAU,IAAI;AAAA;AAAA,EACjB;AAAA,EACA,gBAAAA,KAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,EAAE,GAC5D,gBAAM,IAAI,CAAC,SACV,gBAAAA,KAAC,YAA4B,QAAd,KAAK,OAAqB,CAC1C,GACH;AAAA,GACF;;;AFjDA,SAgKM,YAAAE,WA/JJ,OAAAC,MADF,QAAAC,aAAA;AADF,IAAM,YAAoE,CAAC,EAAE,OAAO,SAAS,MAC3F,gBAAAA,MAAC,SAAI,OAAO,EAAE,QAAQ,aAAa,OAAO,MAAM,IAAI,cAAc,GAAG,YAAY,OAAO,UAAU,UAAU,SAAS,GACnH;AAAA,kBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,SAAS;AAAA,QACT,cAAc,aAAa,OAAO,MAAM;AAAA,QACxC,UAAU;AAAA,QACV,eAAe;AAAA,QACf,eAAe;AAAA,QACf,OAAO,OAAO;AAAA,QACd,YAAY;AAAA,MACd;AAAA,MAEC;AAAA;AAAA,EACH;AAAA,EACA,gBAAAA,KAAC,SAAI,OAAO,EAAE,SAAS,YAAY,GAAI,UAAS;AAAA,GAClD;AAIF,IAAM,eAA6C,CAAC,EAAE,KAAK,MAAM;AAC/D,MAAI,CAAC,KAAK,SAAS;AACjB,QAAI,CAAC,KAAK,mBAAoB,QAAO;AACrC,WACE,gBAAAA,KAAC,aAAU,OAAM,WACf,0BAAAA,KAAC,SAAI,OAAO,EAAE,UAAU,IAAI,OAAO,OAAO,MAAM,GAAG,8GAEnD,GACF;AAAA,EAEJ;AACA,SACE,gBAAAA,KAAC,aAAU,OAAM,WACf,0BAAAC,MAAC,SAAI,OAAO,EAAE,UAAU,IAAI,OAAO,OAAO,KAAK,GAAG;AAAA;AAAA,IACzC;AAAA,IACP,gBAAAD,KAAC,UAAK,OAAO,EAAE,YAAY,kDAAkD,OAAO,OAAO,QAAQ,GAChG,eAAK,QAAQ,YAChB;AAAA,IAAQ;AAAA,IAAI;AAAA,IACS;AAAA,IACrB,gBAAAA,KAAC,UAAK,OAAO,EAAE,YAAY,kDAAkD,OAAO,OAAO,KAAK,GAC7F,eAAK,QAAQ,YAChB;AAAA,IAAO;AAAA,KAET,GACF;AAEJ;AAGA,IAAM,YAA0C,CAAC,EAAE,KAAK,MAAM;AAC5D,QAAM,UAAU,KAAK,OAAO,OAAO,QAAQ,KAAK,IAAI,IAAI,CAAC;AACzD,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SACE,gBAAAA,KAAC,aAAU,OAAM,kCACf,0BAAAA,KAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,qBAAqB,YAAY,KAAK,YAAY,UAAU,GAAG,GAC3F,kBAAQ,IAAI,CAAC,CAAC,KAAK,KAAK,MACvB,gBAAAC,MAAC,MAAM,UAAN,EACC;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,YAAY;AAAA,UACZ,OAAO,OAAO;AAAA,UACd,YAAY;AAAA,QACd;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,IACA,gBAAAA,KAAC,UAAK,OAAO,EAAE,OAAO,OAAO,MAAM,WAAW,YAAY,GAAI,iBAAM;AAAA,OAVjD,GAWrB,CACD,GACH,GACF;AAEJ;AAEA,IAAM,eAA6C,CAAC,EAAE,KAAK,MAAM;AAC/D,QAAM,EAAE,KAAK,QAAQ,QAAQ,IAAI,KAAK;AACtC,SACE,gBAAAC,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,UAAU,QAAQ,KAAK,GAAG,YAAY,SAAS,GAC5E;AAAA,oBAAAA,MAAC,SAAM,SAAQ,WAAU,MAAK,MAAK;AAAA;AAAA,MAAE;AAAA,MAAI;AAAA,OAAO;AAAA,IAChD,gBAAAA,MAAC,SAAM,SAAQ,WAAU,MAAK,MAAK;AAAA;AAAA,MAAE;AAAA,MAAO;AAAA,OAAU;AAAA,IACtD,gBAAAA,MAAC,SAAM,SAAQ,UAAS,MAAK,MAAK;AAAA;AAAA,MAAE;AAAA,MAAQ;AAAA,OAAW;AAAA,IACtD,KAAK,QAAQ,OAAO,IACnB,gBAAAA,MAAC,UAAK,OAAO,EAAE,UAAU,IAAI,OAAO,OAAO,MAAM,GAAI;AAAA,WAAK,QAAQ;AAAA,MAAK;AAAA,OAAU,IAC/E;AAAA,KACN;AAEJ;AAEA,IAAM,WAKD,CAAC,EAAE,MAAM,SAAS,OAAO,yBAAyB,MAAM;AAC3D,MAAI,SAAS;AACX,WACE,gBAAAA,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,IAAI,SAAS,UAAU,OAAO,OAAO,OAAO,UAAU,GAAG,GACjH;AAAA,sBAAAD,KAAC,WAAQ,MAAK,MAAK;AAAA,MAAE;AAAA,OACvB;AAAA,EAEJ;AACA,MAAI,OAAO;AACT,WAAO,gBAAAA,KAAC,SAAI,OAAO,EAAE,SAAS,UAAU,OAAO,OAAO,QAAQ,UAAU,GAAG,GAAI,iBAAM;AAAA,EACvF;AACA,MAAI,CAAC,KAAM,QAAO;AAElB,SACE,gBAAAC,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAG,GAC9D;AAAA,oBAAAD,KAAC,gBAAa,MAAY;AAAA,IAC1B,gBAAAA,KAAC,gBAAa,MAAY;AAAA,IAC1B,gBAAAA,KAAC,aAAU,MAAY;AAAA,IACtB,CAAC,eAAe,KAAK,OAAO,IAC3B,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,UAAU;AAAA,UACV,OAAO,OAAO;AAAA,UACd,YAAY,OAAO;AAAA,UACnB,QAAQ,aAAa,OAAO,MAAM;AAAA,UAClC,cAAc;AAAA,UACd,SAAS;AAAA,QACX;AAAA,QAEC,qCACG,iHACA;AAAA;AAAA,IACN,IAEA,KAAK,OAAO,IAAI,CAAC,UAAU,gBAAAA,KAAC,aAA2B,MAAM,MAAM,MAAM,OAAO,MAAM,SAA3C,MAAM,IAA4C,CAAE;AAAA,KAEnG;AAEJ;AAOO,IAAM,gBAA8C,CAAC;AAAA,EAC1D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,YAAY,CAAC,QAAQ,CAAC,eAAe,KAAK,OAAO;AACvD,QAAM,gBAAgB,WAAW,YAAa,aAAa,CAAC;AAE5D,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MACL,OAAM;AAAA,MACN,UAAU,YAAY,mCAAmC,SAAS,MAAM;AAAA,MACxE,sBAAsB;AAAA,MACtB,QACE,gBAAAC,MAAAF,WAAA,EACE;AAAA,wBAAAC,KAAC,UAAO,SAAQ,SAAQ,MAAK,MAAK,SAAS,SAAS,UAAU,UAAU,oBAExE;AAAA,QACA,gBAAAA,KAAC,UAAO,SAAQ,WAAU,MAAK,MAAK,SAAS,SAAS,WAAW,UAAU,UAAU,eAAe,mBAEpG;AAAA,SACF;AAAA,MAGF,0BAAAA,KAAC,YAAS,MAAY,SAAkB,OAAc,0BAAoD;AAAA;AAAA,EAC5G;AAEJ;;;AGvNA,SAAgB,eAAe;AAwEvB,qBAAAE,WACE,OAAAC,OADF,QAAAC,cAAA;AA3BD,IAAM,mBAAoD,CAAC;AAAA,EAChE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,OAAO,QAAQ,MAAO,YAAY,cAAc,WAAW,CAAC,CAAC,IAAI,MAAO,CAAC,SAAS,CAAC;AACzF,QAAM,eAAe,MAAM,QAAQ,WAAW;AAC9C,QAAM,kBAAkB,WAAW;AAEnC,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MACL,OAAM;AAAA,MACN,UACE,YACI,uBAAuB,SAAS,yBAChC;AAAA,MAEN,sBAAsB;AAAA,MACtB,QACE,gBAAAC,OAAAF,WAAA,EACE;AAAA,wBAAAC,MAAC,UAAO,SAAQ,SAAQ,MAAK,MAAK,SAAS,SAAS,UAAU,YAAY,oBAE1E;AAAA,QACA,gBAAAA,MAAC,UAAO,SAAQ,UAAS,MAAK,MAAK,SAAS,WAAW,WAAW,YAAY,UAAU,iBAAiB,qBAEzG;AAAA,SACF;AAAA,MAGF,0BAAAC,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAG,GAC9D;AAAA,wBAAAD,MAAC,SAAM,SAAQ,UAAS,OAAM,yBAAwB,uHAEtD;AAAA,QAEC,QAAQ,gBAAAA,MAAC,SAAI,OAAO,EAAE,UAAU,IAAI,OAAO,OAAO,OAAO,GAAI,iBAAM,IAAS;AAAA,QAE5E,UACC,gBAAAC,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,IAAI,SAAS,SAAS,OAAO,OAAO,OAAO,UAAU,GAAG,GAChH;AAAA,0BAAAD,MAAC,WAAQ,MAAK,MAAK;AAAA,UAAE;AAAA,WACvB,IAEA,gBAAAC,OAAAF,WAAA,EACE;AAAA,0BAAAE,OAAC,SAAM,SAAQ,UAAS,MAAK,MAAK;AAAA;AAAA,YAAE;AAAA,YAAa;AAAA,aAAW;AAAA,UAC3D,QAAQ,KAAK,OAAO,SAAS,IAC5B,gBAAAD,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAG,GAC7D,eAAK,OAAO,IAAI,CAAC,UAChB,gBAAAA,MAAC,aAA2B,MAAM,MAAM,MAAM,OAAO,MAAM,SAA3C,MAAM,IAA4C,CACnE,GACH,IAEA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,OAAO,OAAO;AAAA,gBACd,YAAY,OAAO;AAAA,gBACnB,QAAQ,aAAa,OAAO,MAAM;AAAA,gBAClC,cAAc;AAAA,gBACd,SAAS;AAAA,cACX;AAAA,cACD;AAAA;AAAA,UAED;AAAA,WAEJ;AAAA,SAEJ;AAAA;AAAA,EACF;AAEJ;;;AChGE,gBAAAE,OAmBA,QAAAC,cAnBA;AADF,IAAM,MAA2D,CAAC,EAAE,OAAO,IAAI,OAAO,SAAS,MAC7F,gBAAAD;AAAA,EAAC;AAAA;AAAA,IACC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,aAAa;AAAA,IACb,eAAc;AAAA,IACd,gBAAe;AAAA,IACf,eAAW;AAAA,IACX,WAAW;AAAA,IACX,OAAO,EAAE,SAAS,SAAS,MAAM,QAAQ,GAAG,MAAM;AAAA,IAEjD;AAAA;AACH;AAIK,IAAM,eAAoC,CAAC,MAChD,gBAAAC,OAAC,OAAK,GAAG,GACP;AAAA,kBAAAD,MAAC,UAAK,GAAE,KAAI,GAAE,KAAI,OAAM,KAAI,QAAO,KAAI,IAAG,KAAI;AAAA,EAC9C,gBAAAA,MAAC,UAAK,GAAE,MAAK,GAAE,KAAI,OAAM,KAAI,QAAO,KAAI,IAAG,KAAI;AAAA,EAC/C,gBAAAA,MAAC,UAAK,GAAE,MAAK,GAAE,MAAK,OAAM,KAAI,QAAO,KAAI,IAAG,KAAI;AAAA,EAChD,gBAAAA,MAAC,UAAK,GAAE,KAAI,GAAE,MAAK,OAAM,KAAI,QAAO,KAAI,IAAG,KAAI;AAAA,GACjD;AAIK,IAAM,gBAAqC,CAAC,MACjD,gBAAAC,OAAC,OAAK,GAAG,GACP;AAAA,kBAAAD,MAAC,UAAK,GAAE,KAAI,GAAE,KAAI,OAAM,MAAK,QAAO,KAAI,IAAG,KAAI;AAAA,EAC/C,gBAAAA,MAAC,UAAK,GAAE,KAAI,GAAE,MAAK,OAAM,MAAK,QAAO,KAAI,IAAG,KAAI;AAAA,EAChD,gBAAAA,MAAC,UAAK,IAAG,KAAI,IAAG,KAAI,IAAG,QAAO,IAAG,KAAI;AAAA,EACrC,gBAAAA,MAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,QAAO,IAAG,MAAK;AAAA,GACzC;AAIK,IAAM,eAAoC,CAAC,MAChD,gBAAAA,MAAC,OAAK,GAAG,GACP,0BAAAA,MAAC,UAAK,GAAE,6BAA4B,GACtC;AAIK,IAAM,aAAkC,CAAC,MAC9C,gBAAAC,OAAC,OAAK,GAAG,GACP;AAAA,kBAAAD,MAAC,YAAO,IAAG,OAAM,IAAG,QAAO,GAAE,OAAM;AAAA,EACnC,gBAAAA,MAAC,UAAK,GAAE,iBAAgB;AAAA,EACxB,gBAAAA,MAAC,UAAK,GAAE,2BAA0B;AAAA,GACpC;AAIK,IAAM,oBAAyC,CAAC,MACrD,gBAAAC,OAAC,OAAK,GAAG,GACP;AAAA,kBAAAD,MAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI;AAAA,EACpC,gBAAAA,MAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,KAAI,IAAG,KAAI;AAAA,EACnC,gBAAAA,MAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,EACtC,gBAAAA,MAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK;AAAA,EACpC,gBAAAA,MAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,EACtC,gBAAAA,MAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK;AAAA,EACrC,gBAAAA,MAAC,UAAK,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI;AAAA,EACpC,gBAAAA,MAAC,UAAK,IAAG,KAAI,IAAG,MAAK,IAAG,KAAI,IAAG,MAAK;AAAA,EACpC,gBAAAA,MAAC,UAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK,IAAG,MAAK;AAAA,GACxC;AAIK,IAAM,eAAoC,CAAC,MAChD,gBAAAC,OAAC,OAAK,GAAG,GACP;AAAA,kBAAAD,MAAC,UAAK,GAAE,yjBAAwjB;AAAA,EAChkB,gBAAAA,MAAC,YAAO,IAAG,MAAK,IAAG,MAAK,GAAE,KAAI;AAAA,GAChC;;;AbkPyB,SA6EX,YAAAE,WA7EW,OAAAC,OAyDf,QAAAC,cAzDe;AA9S3B,IAAM,uBAAuB;AAM7B,IAAM,WAA8E;AAAA,EAClF,EAAE,KAAK,YAAY,OAAO,YAAY,MAAM,aAAa;AAAA,EACzD,EAAE,KAAK,aAAa,OAAO,aAAa,MAAM,cAAc;AAAA,EAC5D,EAAE,KAAK,YAAY,OAAO,YAAY,MAAM,aAAa;AAAA,EACzD,EAAE,KAAK,UAAU,OAAO,UAAU,MAAM,WAAW;AAAA,EACnD,EAAE,KAAK,UAAU,OAAO,iBAAiB,MAAM,kBAAkB;AAAA,EACjE,EAAE,KAAK,YAAY,OAAO,YAAY,MAAM,aAAa;AAC3D;AAkBA,SAAS,WAAW,OAA2C;AAC7D,QAAM,OAAO,sBAAsB;AAAA,IACjC,gBAAgB,MAAM;AAAA,IACtB,cAAc,MAAM;AAAA,IACpB,iBAAiB,MAAM;AAAA,IACvB,aAAa,MAAM;AAAA,IACnB,SAAS,QAAQ,MAAM,eAAe;AAAA,IACtC,QAAQ,MAAM,UAAU;AAAA,IACxB,iBAAiB,MAAM,kBAAkB,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,IAChE,oBAAoB,MAAM,qBAAqB,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,EACxE,CAAC;AACD,SAAO,KAAK,IAAI,CAAC,OAAO;AAAA,IACtB,IAAI,EAAE;AAAA,IACN,kBAAkB,MAAM;AAAA,IACxB,MAAM,EAAE;AAAA,IACR,MAAM,EAAE;AAAA,IACR,MAAM,EAAE;AAAA,IACR,MAAM,EAAE;AAAA,IACR,QAAQ,EAAE;AAAA,IACV,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,SAAS;AAAA,IACT,SAAS,EAAE;AAAA,IACX,WAAW,EAAE;AAAA,EACf,EAAE;AACJ;AAEA,SAAS,qBAAqC;AAC5C,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAMC,KAAI,IAAI,gBAAgB,OAAO,SAAS,MAAM,EAAE,IAAI,SAAS;AACnE,SAAO,SAAS,KAAK,CAAC,MAAM,EAAE,QAAQA,EAAC,IAAKA,KAAgB;AAC9D;AAEO,IAAM,2BAAoE,CAAC;AAAA,EAChF;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AACjB,MAAM;AACJ,QAAM,CAAC,OAAO,QAAQ,IAAI,SAA6B,YAAY;AACnE,QAAM,CAAC,WAAW,YAAY,IAAI,SAAyB,CAAC,CAAC;AAC7D,QAAM,CAAC,aAAa,cAAc,IAAI,SAA2B,CAAC,CAAC;AACnE,QAAM,CAAC,SAAS,UAAU,IAAI,SAAkB,mBAAmB,KAAK,UAAU;AAClF,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,IAAI;AAC3C,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AAGtD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,CAAC,MAAM,OAAO,IAAI,SAA0B,IAAI;AACtD,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,KAAK;AACpD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAwB,IAAI;AAC9D,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAM9C,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,KAAK;AACpD,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAgC,IAAI;AACpF,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAS,KAAK;AAC1D,QAAM,CAAC,cAAc,eAAe,IAAI,SAAwB,IAAI;AACpE,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAOlD,QAAM,EAAE,QAAQ,IAAI,iBAAiB;AAErC,QAAM,KAAK,aAAa;AAGxB,QAAM,aAAa,OAAO,YAAY;AACtC,aAAW,UAAU;AAErB,QAAM,OAAO,YAAY,YAAY;AACnC,aAAS,IAAI;AACb,QAAI;AACF,YAAM,CAAC,YAAY,KAAK,IAAI,IAAI,MAAM,QAAQ,IAAI;AAAA,QAChD,SAAS,SAAS,EAAE,EAAE,MAAM,MAAM,WAAW,OAAO;AAAA,QACpD,aAAa,SAAS,EAAE,EAAE,MAAM,MAAM,CAAC,CAAmB;AAAA,QAC1D,eAAe,SAAS,EAAE,EAAE,MAAM,MAAM,CAAC,CAAqB;AAAA,MAChE,CAAC;AACD,eAAS,UAAU;AACnB,mBAAa,GAAG;AAChB,qBAAe,IAAI;AAAA,IACrB,SAAS,GAAG;AACV,eAAU,EAAY,OAAO;AAAA,IAC/B,UAAE;AACA,iBAAW,KAAK;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,SAAS,EAAE,CAAC;AAEhB,YAAU,MAAM;AACd,SAAK,KAAK;AAAA,EAGZ,GAAG,CAAC,MAAM,YAAY,CAAC;AAGvB,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AACnC,UAAM,SAAS,IAAI,gBAAgB,OAAO,SAAS,MAAM;AACzD,WAAO,IAAI,SAAS,EAAE;AACtB,WAAO,IAAI,WAAW,OAAO;AAC7B,WAAO,QAAQ,aAAa,MAAM,IAAI,GAAG,OAAO,SAAS,QAAQ,IAAI,OAAO,SAAS,CAAC,EAAE;AAAA,EAC1F,GAAG,CAAC,IAAI,OAAO,CAAC;AAEhB,QAAM,UAAU,YAAY,YAAY;AACtC,UAAM,KAAK;AACX,cAAU;AAAA,EACZ,GAAG,CAAC,MAAM,SAAS,CAAC;AAMpB,QAAM,YAAY,MAAM,WAAW,kBAAkB,MAAM,WAAW;AACtE,YAAU,MAAM;AACd,QAAI,CAAC,UAAW;AAChB,QAAI,SAAS;AACb,UAAM,QAAQ,YAAY,MAAM;AAC9B,UAAI,OAAQ,MAAK,QAAQ;AAAA,IAC3B,GAAG,oBAAoB;AACvB,WAAO,MAAM;AACX,eAAS;AACT,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,WAAW,OAAO,CAAC;AAEvB,QAAM,YAAY;AAAA,IAChB,OAAO,OAA+B;AACpC,cAAQ,IAAI;AACZ,eAAS,IAAI;AACb,UAAI;AACF,cAAM,GAAG;AACT,cAAM,QAAQ;AAAA,MAChB,SAAS,GAAG;AACV,iBAAU,EAAY,OAAO;AAAA,MAC/B,UAAE;AACA,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAIA,QAAM,WAAW,YAAY,MAAM;AACjC,gBAAY,IAAI;AAChB,YAAQ,IAAI;AACZ,iBAAa,IAAI;AACjB,mBAAe,IAAI;AACnB,YAAQ,SAAS,EAAE,EAChB,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAC,EACtB,MAAM,CAAC,MAAM,aAAc,EAAY,OAAO,CAAC,EAC/C,QAAQ,MAAM,eAAe,KAAK,CAAC;AAAA,EACxC,GAAG,CAAC,SAAS,EAAE,CAAC;AAEhB,QAAM,YAAY,YAAY,MAAM;AAClC,QAAI,SAAU;AACd,gBAAY,KAAK;AAAA,EACnB,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,UAAU,YAAY,YAAY;AACtC,gBAAY,IAAI;AAChB,iBAAa,IAAI;AACjB,QAAI;AACF,YAAM,YAAY,SAAS,EAAE;AAC7B,kBAAY,KAAK;AACjB,iBAAW,UAAU;AACrB,YAAM,QAAQ;AAAA,IAChB,SAAS,GAAG;AACV,mBAAc,EAAY,OAAO;AAAA,IACnC,UAAE;AACA,kBAAY,KAAK;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,SAAS,IAAI,OAAO,CAAC;AAKzB,QAAM,cAAc,YAAY,MAAM;AACpC,mBAAe,IAAI;AACnB,oBAAgB,IAAI;AACpB,wBAAoB,IAAI;AACxB,sBAAkB,IAAI;AACtB,iBAAa,SAAS,EAAE,EACrB,KAAK,CAAC,QAAQ,oBAAoB,GAAG,CAAC,EAGtC,MAAM,MAAM,oBAAoB,SAAS,CAAC,EAC1C,QAAQ,MAAM,kBAAkB,KAAK,CAAC;AAAA,EAC3C,GAAG,CAAC,SAAS,IAAI,SAAS,CAAC;AAE3B,QAAM,eAAe,YAAY,MAAM;AACrC,QAAI,WAAY;AAChB,mBAAe,KAAK;AAAA,EACtB,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,iBAAiB,YAAY,YAAY;AAC7C,kBAAc,IAAI;AAClB,oBAAgB,IAAI;AACpB,QAAI;AACF,YAAM,aAAa,SAAS,EAAE;AAC9B,qBAAe,KAAK;AACpB,iBAAW,UAAU;AACrB,YAAM,QAAQ;AAAA,IAChB,SAAS,GAAG;AACV,sBAAiB,EAAY,OAAO;AAAA,IACtC,UAAE;AACA,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,SAAS,IAAI,OAAO,CAAC;AAEzB,QAAM,cAAc,CAAC,WAAyC,UAAU,MAAM,eAAe,SAAS,IAAI,MAAM,CAAC;AACjH,QAAM,WAAW,YAAY;AAC3B,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,OAAO;AAAA,MACP,SAAS,WAAW,MAAM,IAAI;AAAA,MAC9B,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,SAAS;AAAA,IACX,CAAC;AACD,QAAI,CAAC,GAAI;AACT,YAAQ,IAAI;AACZ,aAAS,IAAI;AACb,QAAI;AACF,YAAM,MAAM,MAAM,OAAO,oBAAW,EAAE,KAAK,CAAC,EAAE,WAAAC,WAAU,MAAMA,WAAU,GAAG,OAAO,IAAI,EAAE,IAAI,EAAE,QAAQ,SAAS,CAAC,CAAC;AACjH,UAAI,CAAC,IAAI,MAAM,IAAI,WAAW,IAAK,OAAM,IAAI,MAAM,MAAM,UAAU,GAAG,CAAC;AACvE,gBAAU;AAAA,IACZ,SAAS,GAAG;AACV,eAAU,EAAY,OAAO;AAC7B,cAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAEA,QAAM,SAAS,MAAM;AACrB,QAAM,aAAa,aAAa,MAAM;AACtC,QAAM,SAAS,WAAW,YAAY,WAAW;AACjD,QAAM,eAAe,WAAW,kBAAkB,WAAW;AAC7D,QAAM,UAAU,UAAU,MAAM;AAGhC,QAAM,gBAAgB,WAAW,mBAAmB,WAAW;AAM/D,QAAM,kBAAkB,YAAY,CAAC,GAAG;AACxC,QAAM,gBAAgB,UAAU,oBAAoB;AAGpD,QAAM,UAAU,UAAU,WAAW;AACrC,QAAM,mBAAmBC;AAAA,IACvB,MAAO,UAAU,WAAW,KAAK,IAAI;AAAA,IACrC,CAAC,SAAS,OAAO,SAAS;AAAA,EAC5B;AAEA,QAAM,WAAW,MAAM,iBAAiB,MAAM,kBAAkB,UAAU;AAE1E,QAAM,iBAAiB,MAAM;AAC3B,QAAI,WAAY,QAAO,gBAAAJ,MAAC,UAAO,SAAQ,WAAU,MAAK,MAAK,SAAS,UAAU,UAAU,MAAM,gCAAkB;AAChH,QAAI,cAAe,QAAO,gBAAAA,MAAC,UAAO,SAAQ,WAAU,MAAK,MAAK,SAAS,UAAU,UAAU,MAAM,0BAAY;AAC7G,QAAI,cAAe,QAAO,gBAAAA,MAAC,UAAO,SAAQ,UAAS,MAAK,MAAK,SAAS,aAAa,UAAU,MAAM,2BAAa;AAChH,QAAI,OAAQ,QAAO,gBAAAA,MAAC,UAAO,SAAQ,WAAU,MAAK,MAAK,SAAS,UAAU,UAAU,MAAM,8BAAgB;AAC1G,QAAI,aAAc,QAAO,gBAAAA,MAAC,UAAO,SAAQ,WAAU,MAAK,MAAK,SAAS,MAAM,WAAW,UAAU,GAAG,2BAAa;AACjH,WAAO;AAAA,EACT,GAAG;AAEH,QAAM,WAAW,MAAM;AACrB,YAAQ,SAAS;AAAA,MACf,KAAK;AACH,eAAO,gBAAAA,MAAC,eAAY,OAAc,WAAW,kBAAkB;AAAA,MACjE,KAAK;AACH,eAAO,gBAAAA,MAAC,gBAAa,WAAW,kBAAkB,SAAkB;AAAA,MACtE,KAAK;AACH,eAAO,gBAAAA,MAAC,eAAY,aAA0B;AAAA,MAChD,KAAK;AACH,eAAO,gBAAAA,MAAC,aAAU,OAAc,WAAsB;AAAA,MACxD,KAAK;AACH,eAAO,gBAAAA,MAAC,oBAAiB,OAAO,eAAe,CAAC,GAAG,YAAwB;AAAA,MAC7E,KAAK;AACH,eACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,QAAQ,MAAM,OAAO,KAAK;AAAA,YAC1B,WAAW;AAAA,YACX;AAAA;AAAA,QACF;AAAA,IAEN;AAAA,EACF,GAAG;AAEH,SACE,gBAAAC,OAAC,SACC;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,OAAO;AAAA,UACL,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,OAAO,OAAO;AAAA,UACd,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,cAAc;AAAA,QAChB;AAAA,QACD;AAAA;AAAA,IAED;AAAA,IAEA,gBAAAC,OAAC,SAAI,OAAO,EAAE,QAAQ,aAAa,OAAO,MAAM,IAAI,cAAc,IAAI,YAAY,OAAO,SAAS,UAAU,SAAS,GAEnH;AAAA,sBAAAA,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,UAAU,QAAQ,KAAK,aAAa,YAAY,cAAc,gBAAgB,iBAAiB,SAAS,GAAG,GACxI;AAAA,wBAAAA,OAAC,SAAI,OAAO,EAAE,UAAU,KAAK,MAAM,EAAE,GACnC;AAAA,0BAAAA,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,IAAI,UAAU,OAAO,GAC7E;AAAA,4BAAAD,MAAC,QAAG,OAAO,EAAE,QAAQ,GAAG,UAAU,IAAI,eAAe,UAAU,OAAO,OAAO,KAAK,GAAI,gBAAM,MAAK;AAAA,YACjG,gBAAAA,MAAC,cAAW,QAAgB;AAAA,YAC3B,UAAU,gBAAAA,MAAC,WAAQ,MAAK,MAAK,IAAK;AAAA,aACrC;AAAA,UACA,gBAAAC,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,UAAU,QAAQ,KAAK,aAAa,WAAW,GAAG,GAC/E;AAAA,4BAAAD,MAAC,QAAK,OAAM,eAAe,gBAAM,mBAAmB,UAAI;AAAA,YACxD,gBAAAA,MAAC,QAAK,OAAM,cAAc,gBAAM,kBAAkB,UAAI;AAAA,YACtD,gBAAAA,MAAC,QAAK,OAAM,YAAY,oBAAS;AAAA,YACjC,gBAAAA,MAAC,QAAK,OAAM,UAAU,gBAAM,UAAU,UAAI;AAAA,YAC1C,gBAAAA,MAAC,QAAK,OAAM,WAAW,qBAAW,MAAM,SAAS,GAAE;AAAA,aACrD;AAAA,UACA,gBAAAA,MAAC,SAAI,OAAO,EAAE,WAAW,GAAG,GAC1B,0BAAAA,MAAC,iBAAc,WAAW,kBAAkB,GAC9C;AAAA,WACF;AAAA,QACA,gBAAAC,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,YAAY,YAAY,KAAK,GAAG,GACrF;AAAA;AAAA,UACD,gBAAAA,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,GAAG,UAAU,QAAQ,gBAAgB,WAAW,GACjF;AAAA,sBACC,gBAAAA,OAAAF,WAAA,EACE;AAAA,8BAAAC,MAAC,UAAO,SAAQ,SAAQ,MAAK,MAAK,SAAS,MAAM,YAAY,MAAM,GAAG,UAAU,MAAM,kBAAI;AAAA,cAC1F,gBAAAA,MAAC,UAAO,SAAQ,SAAQ,MAAK,MAAK,SAAS,MAAM,YAAY,SAAS,GAAG,UAAU,MAAM,qBAAO;AAAA,eAClG,IACE;AAAA,YACJ,gBAAAA,MAAC,UAAO,SAAQ,SAAQ,MAAK,MAAK,SAAS,MAAM,OAAO,KAAK,GAAG,UAAU,MAAM,2BAAa;AAAA,YAC7F,gBAAAA,MAAC,UAAO,SAAQ,SAAQ,MAAK,MAAK,SAAS,MAAM,KAAK,QAAQ,GAAG,UAAU,MAAM,qBAAO;AAAA,aAC1F;AAAA,WACF;AAAA,SACF;AAAA,MAEC,QACC,gBAAAA,MAAC,SAAI,OAAO,EAAE,SAAS,eAAe,OAAO,OAAO,QAAQ,UAAU,GAAG,GAAI,iBAAM,IACjF;AAAA,MAGJ,gBAAAC,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,WAAW,aAAa,OAAO,MAAM,IAAI,YAAY,UAAU,GAC5F;AAAA,wBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,MAAM,OAAO,YAAY,KAAK,GAAG;AAAA,cACjC,OAAO,YAAY,KAAK;AAAA,cACxB,aAAa,aAAa,OAAO,MAAM;AAAA,cACvC,YAAY,OAAO;AAAA,cACnB,SAAS;AAAA,cACT,SAAS;AAAA,cACT,eAAe;AAAA,cACf,KAAK;AAAA,cACL,YAAY;AAAA,YACd;AAAA,YAEA;AAAA,8BAAAA,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,gBAAgB,YAAY,WAAW,iBAAiB,SAAS,eAAe,GAClI;AAAA,4BAAY,OACX,gBAAAD,MAAC,UAAK,OAAO,EAAE,UAAU,IAAI,eAAe,QAAQ,eAAe,aAAa,OAAO,OAAO,OAAO,YAAY,IAAI,GAAG,iCAExH;AAAA,gBAEF,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,SAAS,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC;AAAA,oBACrC,OAAO,YAAY,WAAW;AAAA,oBAC9B,cAAY,YAAY,mBAAmB;AAAA,oBAC3C,OAAO;AAAA,sBACL,QAAQ,aAAa,OAAO,MAAM;AAAA,sBAClC,YAAY,OAAO;AAAA,sBACnB,OAAO,OAAO;AAAA,sBACd,cAAc;AAAA,sBACd,OAAO;AAAA,sBACP,QAAQ;AAAA,sBACR,QAAQ;AAAA,sBACR,YAAY;AAAA,oBACd;AAAA,oBAEC,sBAAY,SAAM;AAAA;AAAA,gBACrB;AAAA,iBACF;AAAA,cACC,SAAS,IAAI,CAACE,OAAM;AACnB,sBAAM,SAASA,GAAE,QAAQ;AACzB,sBAAM,EAAE,KAAK,IAAIA;AACjB,uBACE,gBAAAD;AAAA,kBAAC;AAAA;AAAA,oBAEC,SAAS,MAAM,WAAWC,GAAE,GAAG;AAAA,oBAC/B,OAAOA,GAAE;AAAA,oBACT,OAAO;AAAA,sBACL,UAAU;AAAA,sBACV,SAAS;AAAA,sBACT,YAAY;AAAA,sBACZ,gBAAgB,YAAY,WAAW;AAAA,sBACvC,KAAK;AAAA,sBACL,SAAS,YAAY,UAAU;AAAA,sBAC/B,cAAc;AAAA,sBACd,QAAQ;AAAA,sBACR,YAAY,SAAS,OAAO,UAAU;AAAA,sBACtC,OAAO,SAAS,OAAO,UAAU,OAAO;AAAA,sBACxC,YAAY;AAAA,sBACZ,UAAU;AAAA,sBACV,QAAQ;AAAA,sBACR,WAAW;AAAA,sBACX,OAAO;AAAA,oBACT;AAAA,oBAEC;AAAA,+BACC,gBAAAF,MAAC,UAAK,OAAO,EAAE,UAAU,YAAY,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,cAAc,eAAe,YAAY,OAAO,QAAQ,GAAG,IACpI;AAAA,sBACJ,gBAAAA,MAAC,UAAK,OAAO,EAAE,OAAO,IAAI,SAAS,eAAe,YAAY,UAAU,gBAAgB,UAAU,MAAM,OAAO,GAC7G,0BAAAA,MAAC,QAAK,MAAM,IAAI,GAClB;AAAA,sBACC,YAAY,OAAO,gBAAAA,MAAC,UAAK,OAAO,EAAE,MAAM,EAAE,GAAI,UAAAE,GAAE,OAAM;AAAA,sBACtD,CAAC,aAAaA,GAAE,QAAQ,eAAe,iBAAiB,SAAS,IAChE,gBAAAF,MAAC,UAAK,OAAO,EAAE,UAAU,IAAI,YAAY,KAAK,OAAO,OAAO,MAAM,GAAI,2BAAiB,QAAO,IAC5F;AAAA,sBACH,CAAC,aAAaE,GAAE,QAAQ,cAAc,eACrC,gBAAAF,MAAC,UAAK,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,cAAc,OAAO,YAAY,OAAO,KAAK,GAAG,IAClF;AAAA;AAAA;AAAA,kBAjCCE,GAAE;AAAA,gBAkCT;AAAA,cAEJ,CAAC;AAAA;AAAA;AAAA,QACH;AAAA,QAEA,gBAAAF,MAAC,SAAI,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,YAAY,GAAI,mBAAQ;AAAA,SACvE;AAAA,OACF;AAAA,IAEA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ;AAAA,QACR,SAAS;AAAA,QACT;AAAA,QACA,SAAS;AAAA,QACT,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,WAAW,MAAM;AAAA,QACjB,0BAA0B,MAAM,WAAW,YAAY,MAAM,WAAW,WAAW,MAAM,WAAW;AAAA;AAAA,IACtG;AAAA,IAEA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW;AAAA,QACX,SAAS;AAAA,QACT,OAAO;AAAA,QACP;AAAA,QACA,WAAW;AAAA,QACX,WAAW,MAAM;AAAA;AAAA,IACnB;AAAA,KACF;AAEJ;;;Ac1ZM,gBAAAK,OAwCU,QAAAC,cAxCV;AAtGN,IAAM,eAAe;AAAA,EACnB,EAAE,OAAO,UAAU,OAAO,kDAA6C;AAAA,EACvE,EAAE,OAAO,cAAc,OAAO,4CAAuC;AACvE;AAIA,IAAM,iBAAiB,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AACpD,IAAM,iBAAiB,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG;AAC/C,IAAM,cAAc,CAAC,KAAK,KAAK,GAAG;AAElC,SAAS,aAAa,cAAkC,QAAyD;AAC/G,QAAM,QAAQ,gBAAgB,OAAO,YAAY;AACjD,QAAM,OAAO,UAAU;AACvB,MAAI,SAAS,QAAS,QAAO,YAAY,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,QAAQ,CAAC,GAAG,EAAE;AACtF,MAAI,SAAS,MAAO,QAAO,eAAe,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,OAAO,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE;AACvG,SAAO,eAAe,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,OAAO,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE;AACnF;AAGA,SAAS,aAAa,OAAyB;AAC7C,MAAI,SAAS,EAAG,QAAO,CAAC;AACxB,QAAM,OAAO,KAAK,MAAM,MAAM,KAAK;AACnC,QAAM,YAAY,MAAM,OAAO;AAC/B,SAAO,MAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,MAAM,QAAQ,IAAI,YAAY,IAAI,EAAE;AAC/E;AAEA,SAAS,aACP,aACA,eACA,cACA,eACiB;AACjB,QAAM,CAAC,IAAI,EAAE,IAAI,aAAa,CAAC;AAC/B,MAAI,gBAAgB,MAAM;AACxB,UAAM,KAAK,aAAa,cAAc,aAAa;AACnD,WAAO;AAAA,MACL,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,GAAG,aAAa,KAAK,SAAS,GAAG;AAAA,MACzD,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,GAAG,aAAa,KAAK,SAAS,GAAG;AAAA,IAC3D;AAAA,EACF;AACA,QAAM,UAAU,cAAc,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,OAAO;AAChE,QAAM,QAAQ,iBAAiB,QAAQ,CAAC,KAAK;AAC7C,QAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,MAAM,KAAK,KAAK;AACnD,SAAO;AAAA,IACL,EAAE,MAAM,OAAO,SAAS,GAAG;AAAA,IAC3B,EAAE,MAAM,QAAQ,SAAS,GAAG;AAAA,EAC9B;AACF;AAEO,IAAM,wBAA8D,CAAC;AAAA,EAC1E;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,QAAQ,UAAU,SAAS;AACjC,QAAM,cAAoC,UAAU,eAAe;AACnE,QAAM,QAAQ,UAAU,SAAS,CAAC;AAClC,QAAM,cAAc,gBAAgB,OAAO,aAAa,cAAc,aAAa,IAAI;AAEvF,QAAM,OAAO,CAAC,SAA0B,SAAS,EAAE,MAAM,cAAc,aAAa,OAAO,KAAK,CAAC;AAEjG,QAAM,UAAU,CAAC,SAAiB;AAChC,QAAI,SAAS,aAAc,QAAO,SAAS,EAAE,MAAM,SAAS,CAAC;AAC7D,aAAS;AAAA,MACP,MAAM;AAAA,MACN;AAAA,MACA,OAAO,MAAM,UAAU,IAAI,QAAQ,aAAa,aAAa,eAAe,cAAc,aAAa;AAAA,IACzG,CAAC;AAAA,EACH;AAEA,QAAM,iBAAiB,CAAC,UAAkB;AACxC,UAAM,IAAI;AAEV,aAAS,EAAE,MAAM,cAAc,aAAa,GAAG,OAAO,aAAa,GAAG,eAAe,cAAc,aAAa,EAAE,CAAC;AAAA,EACrH;AAEA,QAAM,aAAa,CAAC,GAAW,UAC7B,KAAK,MAAM,IAAI,CAACC,IAAG,QAAS,QAAQ,IAAI,EAAE,GAAGA,IAAG,GAAG,MAAM,IAAIA,EAAE,CAAC;AAElE,QAAM,UAAU,MAAM;AACpB,UAAM,OAAO,IAAI,IAAI,MAAM,IAAI,CAACA,OAAMA,GAAE,IAAI,CAAC;AAC7C,UAAM,WAAW,YAAY,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK;AAC9E,SAAK,CAAC,GAAG,OAAO,EAAE,MAAM,UAAU,SAAS,EAAE,CAAC,CAAC;AAAA,EACjD;AAEA,QAAM,aAAa,CAAC,MAAc,KAAK,MAAM,OAAO,CAAC,GAAG,QAAQ,QAAQ,CAAC,CAAC;AAE1E,QAAM,mBAAmB,MAAM;AAC7B,UAAM,WAAW,aAAa,MAAM,MAAM;AAC1C,SAAK,MAAM,IAAI,CAACA,IAAG,OAAO,EAAE,GAAGA,IAAG,SAAS,SAAS,CAAC,EAAE,EAAE,CAAC;AAAA,EAC5D;AAEA,QAAM,aAAa,QAAQ,oBAAoB,WAAW,KAAK,IAAI,CAAC;AACpE,QAAM,kBAAkB,QAAQ,kBAAkB,WAAW,SAAS,IAAI;AAE1E,SACE,gBAAAD,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAG,GAC9D;AAAA,oBAAAD,MAAC,UAAO,OAAc,OAAO,UAAU,MAAM,UAAU,SAAS,SAAS,cAAc;AAAA,IAEtF,QACC,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,SAAS;AAAA,UACT,eAAe;AAAA,UACf,KAAK;AAAA,UACL,SAAS;AAAA,UACT,QAAQ,aAAa,OAAO,MAAM;AAAA,UAClC,cAAc;AAAA,UACd,YAAY,OAAO;AAAA,QACrB;AAAA,QAEA;AAAA,0BAAAD;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,OAAO;AAAA,cACP,UAAU;AAAA,cACV,SAAS,CAAC,GAAG,6BAA6B;AAAA;AAAA,UAC5C;AAAA,UAEA,gBAAAA,MAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,EAAE,GAC5D,gBAAM,IAAI,CAAC,MAAM,MAChB,gBAAAC,OAAC,SAAY,OAAO,EAAE,SAAS,QAAQ,qBAAqB,sBAAsB,KAAK,GAAG,YAAY,MAAM,GAC1G;AAAA,4BAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,MAAM,IAAK,gBAAgB,OAAO,SAAS,WAAY;AAAA,gBAC9D,OAAO,KAAK;AAAA,gBACZ,UAAU,CAAC,UAAU,WAAW,GAAG,EAAE,MAAM,MAAM,CAAC;AAAA,gBAClD,SAAS;AAAA,gBACT,aAAY;AAAA;AAAA,YACd;AAAA,YACA,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO,MAAM,IAAI,YAAY;AAAA,gBAC7B,MAAK;AAAA,gBACL,KAAK;AAAA,gBACL,KAAK;AAAA,gBACL,OAAO,OAAO,KAAK,OAAO;AAAA,gBAC1B,UAAU,CAAC,MAAM,WAAW,GAAG,EAAE,SAAS,OAAO,EAAE,OAAO,KAAK,KAAK,EAAE,CAAC;AAAA,gBACvE,WAAS;AAAA;AAAA,YACX;AAAA,YACA,gBAAAC,OAAC,UAAK,OAAO,EAAE,UAAU,IAAI,OAAO,OAAO,OAAO,eAAe,IAAI,YAAY,SAAS,GAAG;AAAA;AAAA,cACxF,WAAW,CAAC,GAAG,SAAS;AAAA,cAAE;AAAA,eAAO,WAAW,CAAC,GAAG,SAAS,OAAO,IAAI,KAAK;AAAA,eAC9E;AAAA,YACA,gBAAAD;AAAA,cAAC;AAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS,MAAM,WAAW,CAAC;AAAA,gBAC3B,UAAU,MAAM,UAAU;AAAA,gBAC1B,cAAY,eAAe,IAAI,CAAC;AAAA,gBAChC,OAAO,EAAE,cAAc,EAAE;AAAA,gBAC1B;AAAA;AAAA,YAED;AAAA,eA7BQ,CA8BV,CACD,GACH;AAAA,UAEA,gBAAAC,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,EAAE,GACpC;AAAA,4BAAAD,MAAC,UAAO,SAAQ,aAAY,MAAK,MAAK,SAAS,SAAS,UAAU,MAAM,UAAU,YAAY,QAAQ,sBAEtG;AAAA,YACA,gBAAAA,MAAC,UAAO,SAAQ,SAAQ,MAAK,MAAK,SAAS,kBAAkB,+BAE7D;AAAA,aACF;AAAA,UAEC,kBACC,gBAAAA,MAAC,OAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,IAAI,OAAO,OAAO,OAAO,GAAI,2BAAgB,IAE9E,gBAAAC,OAAC,OAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,IAAI,OAAO,OAAO,MAAM,GACtD;AAAA,kBAAM;AAAA,YAAO;AAAA,YAAU,WAAW,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC;AAAA,YAAE;AAAA,YAAK;AAAA,YAAU;AAAA,aACrF;AAAA;AAAA;AAAA,IAEJ,IACE;AAAA,KACN;AAEJ;;;AnBuEoD,SA4G9C,YAAAE,WA5G8C,OAAAC,OA4G9C,QAAAC,cA5G8C;AAtO7C,IAAM,4BAAsE,CAAC;AAAA,EAClF;AAAA,EACA,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACA,iBAAiB,CAAC;AAAA,EAClB;AACF,MAAM;AACJ,QAAM,CAAC,gBAAgB,iBAAiB,IAAIC,UAA+B,CAAC,CAAC;AAC7E,QAAM,CAAC,MAAM,OAAO,IAAIA,UAAgB,CAAC,CAAC;AAC1C,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAA0B,CAAC,CAAC;AACxE,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAwB,CAAC,CAAC;AACxD,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAyB,CAAC,CAAC;AACrE,QAAM,CAAC,OAAO,QAAQ,IAAIA,UAAwB,IAAI;AACtD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,IAAI;AAG/C,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAwB,MAAM;AAChE,QAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,WAAO,IAAI,gBAAgB,OAAO,SAAS,MAAM,EAAE,IAAI,OAAO;AAAA,EAChE,CAAC;AACD,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAS,CAAC;AAElD,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAS,EAAE;AACvC,QAAM,CAAC,mBAAmB,oBAAoB,IAAIA,UAAwB,IAAI;AAC9E,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA,UAAwB,IAAI;AAC5E,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAwB,IAAI;AACpE,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,MAAM;AACjD,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAyB,KAAK;AAC5D,QAAM,CAAC,MAAM,OAAO,IAAIA,UAAS,CAAC;AAClC,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,EAAE;AAE3C,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAS,KAAK;AAClD,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAoC,IAAI;AACtE,QAAM,CAAC,MAAM,OAAO,IAAIA,UAAoB,UAAU;AACtD,QAAM,CAAC,YAAY,aAAa,IAAIA,UAAS,KAAK;AAClD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAwB,IAAI;AAE9D,QAAM,OAAOC,aAAY,MAAM;AAC7B,iBAAa,IAAI;AACjB,aAAS,IAAI;AACb,WAAO,UAAU,OAAO,EACrB,KAAK,CAAC,QAAS,IAAI,KAAK,IAAI,KAAK,IAAI,QAAQ,OAAO,IAAI,MAAM,QAAQ,IAAI,MAAM,EAAE,CAAC,CAAE,EACrF,KAAK,CAAC,SAA+B,kBAAkB,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,EACvF,MAAM,CAAC,MAAa,SAAS,EAAE,OAAO,CAAC,EACvC,QAAQ,MAAM,aAAa,KAAK,CAAC;AAAA,EACtC,GAAG,CAAC,OAAO,CAAC;AAEZ,EAAAC,WAAU,MAAM;AACd,SAAK,KAAK;AAAA,EACZ,GAAG,CAAC,IAAI,CAAC;AAIT,EAAAA,WAAU,MAAM;AACd,cAAU,WAAW,EAClB,KAAK,CAAC,QAAS,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAE,EACxC,KAAK,CAAC,SAAgB,QAAQ,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,EAC9D,MAAM,MAAM,QAAQ,CAAC,CAAC,CAAC;AAC1B,cAAU,sBAAsB,EAC7B,KAAK,CAAC,QAAS,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAE,EACxC;AAAA,MAAK,CAAC,SACL,kBAAkB,MAAM,QAAQ,IAAI,IAAI,KAAK,OAAO,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC,CAAC;AAAA,IACvF,EACC,MAAM,MAAM,kBAAkB,CAAC,CAAC,CAAC;AACpC,cAAU,qBAAqB,EAC5B,KAAK,CAAC,QAAS,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAE,EACxC,KAAK,CAAC,SAAyB,iBAAiB,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,EAChF,MAAM,MAAM,iBAAiB,CAAC,CAAC,CAAC;AAAA,EACrC,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,KAAK,eAAe,MAAM,KAAK,eAAe;AAC9D,QAAM,aAAa,WAAW,KAAK,mBAAmB;AAKtD,QAAM,SAAS,mBAAmB,IAAI,KAAK,WAAW;AACtD,QAAM,mBAAmB;AAIzB,QAAM,uBAAuB,UAAU;AAGvC,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,SAAS;AACZ,iBAAW,CAAC,CAAC;AACb;AAAA,IACF;AACA,QAAI,YAAY;AAChB,cAAU,wBAAwB,KAAK,UAAU,UAAU,EACxD,KAAK,CAAC,QAAS,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAE,EACxC,KAAK,CAAC,SAAwB;AAC7B,UAAI,CAAC,UAAW,YAAW,MAAM,QAAQ,IAAI,IAAI,KAAK,OAAO,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC,CAAC;AAAA,IAChG,CAAC,EACA,MAAM,MAAM;AACX,UAAI,CAAC,UAAW,YAAW,CAAC,CAAC;AAAA,IAC/B,CAAC;AACH,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,SAAS,KAAK,UAAU,CAAC;AAE7B,QAAM,aAAa,MAAM;AACvB,eAAW,IAAI;AAIf,YAAQ,EAAE,GAAG,YAAY,WAAW,oBAAoB,GAAG,CAAC;AAC5D,iBAAa,IAAI;AACjB,kBAAc,IAAI;AAAA,EACpB;AAEA,QAAM,WAAW,CAAC,QAA4B;AAC5C,eAAW,GAAG;AACd,YAAQ,cAAc,GAAG,CAAC;AAC1B,iBAAa,IAAI;AACjB,kBAAc,IAAI;AAAA,EACpB;AAEA,QAAM,cAAcD,aAAY,MAAM;AACpC,QAAI,WAAY;AAChB,kBAAc,KAAK;AAAA,EACrB,GAAG,CAAC,UAAU,CAAC;AAEf,QAAM,WAAW,CAA4B,KAAQ,UACnD,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,EAAE;AAK/C,QAAM,uBAAuB,CAAC,UAC5B,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,YAAY,OAAO,0BAA0B,GAAG,EAAE;AAElF,QAAM,eAAe,YAAY;AAC/B,QAAI,CAAC,KAAK,KAAK,KAAK,GAAG;AACrB,mBAAa,kBAAkB;AAC/B;AAAA,IACF;AACA,UAAM,eAAe,OAAO,KAAK,YAAY;AAC7C,UAAM,kBAAkB,OAAO,KAAK,eAAe;AACnD,QAAI,KAAK,mBAAmB,eAAe;AACzC,UAAI,eAAe,GAAG;AACpB,qBAAa,qDAAqD;AAClE;AAAA,MACF;AACA,UAAI,kBAAkB,GAAG;AACvB,qBAAa,yDAAyD;AACtE;AAAA,MACF;AACA,UAAI,YAAY;AACd,cAAM,aAAa,kBAAkB,KAAK,kBAAkB,YAAY;AACxE,YAAI,YAAY;AACd,uBAAa,sBAAsB,UAAU,EAAE;AAC/C;AAAA,QACF;AACA,cAAM,YAAY,kBAAkB,KAAK,qBAAqB,eAAe;AAC7E,YAAI,WAAW;AACb,uBAAa,0BAA0B,SAAS,EAAE;AAClD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QAAI,wBAAwB,CAAC,KAAK,0BAA0B;AAC1D,mBAAa,8DAA8D;AAC3E;AAAA,IACF;AACA,UAAM,aAAa,KAAK,eAAe;AACvC,UAAM,gBAAgB,eAAe,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,UAAU;AACzE,UAAM,cAAc,KAAK,mBAAmB;AAG5C,UAAM,qBAAqB,CAAC,MAC1B,eAAe,cAAc,GAAG,SAAS,eAAe,IAAI,EAAE,MAAM,SAAkB;AACxF,kBAAc,IAAI;AAClB,iBAAa,IAAI;AACjB,UAAM,UAAU;AAAA,MACd,MAAM,KAAK,KAAK,KAAK;AAAA,MACrB,gBAAgB,KAAK;AAAA,MACrB,iBAAiB,KAAK;AAAA,MACtB,cAAc,aAAa,oBAAqB,eAAe,QAAQ;AAAA,MACvE,iBAAiB,aAAa,SAAY,KAAK,cAAc;AAAA,MAC7D,QAAQ,aAAa,KAAK,SAAS;AAAA,MACnC;AAAA,MACA;AAAA,MACA,aAAa,KAAK;AAAA,MAClB,SAAS,KAAK;AAAA,MACd,0BAA0B,mBAAmB,KAAK,2BAA2B;AAAA;AAAA,MAE7E,oBAAoB,cAAc,KAAK,qBAAqB;AAAA,MAC5D,qBAAqB,cAAc,KAAK,IAAI,GAAG,OAAO,KAAK,mBAAmB,KAAK,CAAC,IAAI;AAAA;AAAA;AAAA,MAGxF,cAAc,CAAC,aAAa,KAAK,aAAa,KAAK,KAAK,SAAY;AAAA,MACpE,kBAAkB,mBAAmB,KAAK,gBAAgB;AAAA,MAC1D,qBAAqB,mBAAmB,KAAK,mBAAmB;AAAA,MAChE,WAAW,KAAK,aAAa;AAAA,IAC/B;AACA,QAAI;AACF,YAAM,MAAM,MAAM,UAAU,UAAU,GAAG,OAAO,IAAI,QAAQ,EAAE,KAAK,SAAS;AAAA,QAC1E,QAAQ,UAAU,QAAQ;AAAA,QAC1B,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B,CAAC;AACD,UAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,MAAM,UAAU,GAAG,CAAC;AACjD,oBAAc,KAAK;AACnB,YAAM,KAAK;AAEX,UAAI,QAAS,iBAAgB,CAAC,MAAM,IAAI,CAAC;AAAA,IAC3C,SAAS,GAAG;AACV,mBAAc,EAAY,OAAO;AAAA,IACnC,UAAE;AACA,oBAAc,KAAK;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,aAAa,CAAC,OAAsB;AACxC,kBAAc,EAAE;AAChB,QAAI,OAAO,WAAW,eAAe,OAAO,MAAM;AAChD,YAAM,SAAS,IAAI,gBAAgB,OAAO,SAAS,MAAM;AACzD,aAAO,OAAO,OAAO;AACrB,aAAO,OAAO,SAAS;AACvB,YAAM,KAAK,OAAO,SAAS;AAC3B,aAAO,QAAQ,aAAa,MAAM,IAAI,KAAK,GAAG,OAAO,SAAS,QAAQ,IAAI,EAAE,KAAK,OAAO,SAAS,QAAQ;AAAA,IAC3G;AAAA,EACF;AAEA,QAAM,UAAiD;AAAA,IACrD,EAAE,KAAK,QAAQ,QAAQ,QAAQ,QAAQ,CAAC,QAAQ,gBAAAH,MAAC,YAAQ,cAAI,MAAK,EAAU;AAAA,IAC5E,EAAE,KAAK,kBAAkB,QAAQ,cAAc,QAAQ,CAAC,QAAQ,IAAI,kBAAkB,SAAI;AAAA,IAC1F,EAAE,KAAK,mBAAmB,QAAQ,eAAe,QAAQ,CAAC,QAAQ,IAAI,mBAAmB,SAAI;AAAA,IAC7F,EAAE,KAAK,gBAAgB,QAAQ,YAAY,QAAQ,CAAC,QAAQ,IAAI,gBAAgB,SAAI;AAAA,IACpF,EAAE,KAAK,UAAU,QAAQ,UAAU,QAAQ,CAAC,QAAQ,IAAI,UAAU,SAAI;AAAA,IACtE,EAAE,KAAK,gBAAgB,QAAQ,YAAY,OAAO,SAAS,QAAQ,CAAC,QAAQ,IAAI,gBAAgB,SAAI;AAAA,IACpG,EAAE,KAAK,mBAAmB,QAAQ,gBAAgB,OAAO,SAAS,QAAQ,CAAC,QAAQ,IAAI,mBAAmB,SAAI;AAAA,IAC9G,EAAE,KAAK,UAAU,QAAQ,UAAU,QAAQ,CAAC,QAAQ,gBAAAA,MAAC,cAAW,QAAQ,IAAI,QAAQ,EAAG;AAAA,IACvF,EAAE,KAAK,aAAa,QAAQ,WAAW,QAAQ,CAAC,QAAQ,WAAW,IAAI,SAAS,EAAE;AAAA,IAClF,EAAE,KAAK,WAAW,QAAQ,IAAI,OAAO,SAAS,OAAO,QAAQ,QAAQ,MAAM,gBAAAA,MAAC,UAAK,eAAW,MAAC,OAAO,EAAE,OAAO,OAAO,MAAM,GAAG,oBAAC,EAAQ;AAAA,EACxI;AAEA,QAAM,qBAAqBK,SAAQ,MAAM,KAAK,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC;AACpG,QAAM,kBAAkBA;AAAA,IACtB,MAAM;AAAA,MACJ,EAAE,OAAO,aAAa,OAAO,kBAAkB;AAAA,MAC/C,GAAG,eAAe,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,OAAO,EAAE,KAAK,EAAE;AAAA,IAC/D;AAAA,IACA,CAAC,cAAc;AAAA,EACjB;AACA,QAAM,gBAAgBA;AAAA,IACpB,MAAM,QAAQ,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,GAAG,EAAE,IAAI,KAAK,EAAE,IAAI,IAAI,EAAE;AAAA,IAC5E,CAAC,OAAO;AAAA,EACV;AACA,QAAM,mBAAmBA;AAAA,IACvB,MAAM,eAAe,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,UAAU;AAAA,IACzD,CAAC,gBAAgB,KAAK,UAAU;AAAA,EAClC;AAEA,QAAM,wBAAwBA;AAAA,IAC5B,MACE,cAAc;AAAA,MACZ,CAAC,MAAM,EAAE,WAAW,eAAe,CAAC,kBAAkB,QAAQ,EAAE,aAAa,iBAAiB;AAAA,IAChG;AAAA,IACF,CAAC,eAAe,gBAAgB;AAAA,EAClC;AACA,QAAM,sBAAsBA;AAAA,IAC1B,MACE,sBAAsB,IAAI,CAAC,OAAO;AAAA,MAChC,OAAO,EAAE;AAAA,MACT,OAAO,GAAG,EAAE,IAAI,KAAK,EAAE,QAAQ,GAAG,EAAE,UAAU,aAAa,0BAAuB,EAAE;AAAA,IACtF,EAAE;AAAA,IACJ,CAAC,qBAAqB;AAAA,EACxB;AAEA,QAAM,sBAAsBA,SAAQ,MAAM;AACxC,UAAM,OAAO,oBAAI,IAAY;AAC7B,mBAAe,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,UAAU,SAAS,CAAC;AAC7D,WAAO,MAAM,KAAK,MAAM,CAAC,WAAW,EAAE,OAAO,OAAO,MAAM,EAAE;AAAA,EAC9D,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,cAA4B;AAAA,IAChC,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,IAC/B,EAAE,OAAO,gBAAgB,OAAO,WAAW;AAAA,IAC3C,EAAE,OAAO,mBAAmB,OAAO,eAAe;AAAA,IAClD,EAAE,OAAO,UAAU,OAAO,SAAS;AAAA,IACnC,EAAE,OAAO,aAAa,OAAO,UAAU;AAAA,EACzC;AACA,QAAM,UAA8B;AAAA,IAClC,EAAE,KAAK,eAAe,OAAO,eAAe,SAAS,oBAAoB,OAAO,mBAAmB,UAAU,sBAAsB,eAAe,KAAK;AAAA,IACvJ,EAAE,KAAK,cAAc,OAAO,cAAc,SAAS,iBAAiB,OAAO,kBAAkB,UAAU,oBAAoB;AAAA,IAC3H,EAAE,KAAK,UAAU,OAAO,UAAU,SAAS,qBAAqB,OAAO,cAAc,UAAU,gBAAgB;AAAA,EACjH;AAEA,QAAM,iBAAiBA,SAAQ,MAAM;AACnC,UAAM,OAAO,OAAO,KAAK,EAAE,YAAY;AACvC,UAAM,OAAO,eAAe,OAAO,CAAC,QAAQ;AAC1C,UAAI,MAAM;AACR,cAAM,WAAW,GAAG,IAAI,QAAQ,EAAE,IAAI,IAAI,gBAAgB,EAAE,IAAI,IAAI,UAAU,EAAE,GAAG,YAAY;AAC/F,YAAI,CAAC,SAAS,SAAS,IAAI,EAAG,QAAO;AAAA,MACvC;AACA,UAAI,qBAAqB,IAAI,oBAAoB,kBAAmB,QAAO;AAC3E,UAAI,oBAAoB,IAAI,mBAAmB,iBAAkB,QAAO;AACxE,UAAI,iBAAiB,IAAI,UAAU,eAAe,aAAc,QAAO;AACvE,aAAO;AAAA,IACT,CAAC;AACD,UAAM,MAAM,YAAY,QAAQ,IAAI;AACpC,WAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM;AAC9B,cAAQ,WAAW;AAAA,QACjB,KAAK;AACH,mBAAS,EAAE,gBAAgB,MAAM,EAAE,gBAAgB,MAAM;AAAA,QAC3D,KAAK;AACH,mBAAS,EAAE,mBAAmB,MAAM,EAAE,mBAAmB,MAAM;AAAA,QACjE,KAAK;AACH,kBAAQ,EAAE,UAAU,IAAI,cAAc,EAAE,UAAU,EAAE,IAAI;AAAA,QAC1D,KAAK;AACH,kBAAQ,IAAI,KAAK,EAAE,aAAa,CAAC,EAAE,QAAQ,IAAI,IAAI,KAAK,EAAE,aAAa,CAAC,EAAE,QAAQ,KAAK;AAAA,QACzF,KAAK;AAAA,QACL;AACE,kBAAQ,EAAE,QAAQ,IAAI,cAAc,EAAE,QAAQ,EAAE,IAAI;AAAA,MACxD;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,gBAAgB,QAAQ,mBAAmB,kBAAkB,cAAc,WAAW,OAAO,CAAC;AAElG,QAAM,WAAWA;AAAA,IACf,MAAM,eAAe,OAAO,OAAO,KAAK,UAAU,OAAO,QAAQ;AAAA,IACjE,CAAC,gBAAgB,MAAM,QAAQ;AAAA,EACjC;AAEA,EAAAD,WAAU,MAAM;AACd,YAAQ,CAAC;AAAA,EACX,GAAG,CAAC,QAAQ,mBAAmB,kBAAkB,cAAc,WAAW,OAAO,CAAC;AAElF,QAAM,WAAW,aAAa,eAAe,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU,KAAK,OAAO;AAGxF,MAAI,cAAc,UAAU;AAC1B,WACE,gBAAAH,OAAAF,WAAA,EACE;AAAA,sBAAAC;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,cAAc;AAAA,UACd;AAAA,UACA;AAAA,UACA;AAAA,UACA,QAAQ,MAAM,WAAW,IAAI;AAAA,UAC7B,QAAQ;AAAA,UACR,WAAW,MAAM;AACf,uBAAW,IAAI;AACf,iBAAK,KAAK;AAAA,UACZ;AAAA,UACA,WAAW,MAAM,KAAK,KAAK;AAAA;AAAA,MAC7B;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,OAAO,UAAU,SAAS,QAAQ,IAAI,MAAM;AAAA,UAC5C,aAAY;AAAA,UACZ,UAAU;AAAA,UACV,YAAY,UAAU,iBAAiB;AAAA,UACvC,cAAc;AAAA,UACd,gBAAgB,CAAC,KAAK,KAAK,KAAK,KAAM,wBAAwB,CAAC,KAAK;AAAA,UACpE,OAAO;AAAA,UACP,MAAK;AAAA,UAEL,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA;AAAA,cACA,kBAAkB;AAAA,cAClB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,sBAAsB,kBAAkB;AAAA,cACxC,cAAc,kBAAkB;AAAA,cAChC;AAAA;AAAA,UACF;AAAA;AAAA,MACF;AAAA,OACF;AAAA,EAEJ;AAGA,SACE,gBAAAC,OAAC,QAAK,SAAQ,YACZ;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,SACE,gBAAAC,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,EAAE,GACpC;AAAA,0BAAAD,MAAC,UAAO,SAAQ,aAAY,MAAK,MAAK,SAAS,MAAM,KAAK,KAAK,GAAG,WAAsB,qBAExF;AAAA,UACA,gBAAAA,MAAC,UAAO,SAAQ,WAAU,MAAK,MAAK,SAAS,YAAY,gCAEzD;AAAA,WACF;AAAA,QAGF,0BAAAA,MAAC,QAAG,OAAO,EAAE,QAAQ,GAAG,UAAU,IAAI,YAAY,IAAI,GAAI,iBAAM;AAAA;AAAA,IAClE;AAAA,IACA,gBAAAC,OAAC,YACE;AAAA,cACC,gBAAAA,OAAC,OAAE,OAAO,EAAE,OAAO,OAAO,OAAO,GAAG;AAAA;AAAA,QAAqC;AAAA,SAAM,IAC7E;AAAA,MAEJ,gBAAAA,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,UAAU,QAAQ,KAAK,GAAG,YAAY,UAAU,gBAAgB,iBAAiB,cAAc,GAAG,GAC/H;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,QAAQ,EAAE,OAAO,QAAQ,UAAU,WAAW,aAAa,8BAAyB;AAAA,YACpF;AAAA;AAAA,QACF;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,SAAS;AAAA,YACT,OAAO;AAAA,YACP,WAAW;AAAA,YACX,UAAU,CAAC,OAAO,QAAQ;AACxB,2BAAa,KAAK;AAClB,yBAAW,GAAG;AAAA,YAChB;AAAA;AAAA,QACF;AAAA,SACF;AAAA,MAEA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,MAAM;AAAA,UACN,QAAQ,CAAC,QAAQ,IAAI;AAAA,UACrB;AAAA,UACA,YAAY,CAAC,QAAQ,WAAW,IAAI,EAAE;AAAA,UACtC,YAAY;AAAA,YACV,OAAO;AAAA,YACP,aAAa;AAAA,UACf;AAAA;AAAA,MACF;AAAA,MACA,gBAAAA,MAAC,SAAI,OAAO,EAAE,WAAW,GAAG,GAC1B,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA,YAAY,eAAe;AAAA,UAC3B,cAAc;AAAA,UACd,kBAAkB;AAAA,UAClB,iBAAiB,CAAC,IAAI,IAAI,EAAE;AAAA;AAAA,MAC9B,GACF;AAAA,OACF;AAAA,IAEA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,OAAO,UAAU,SAAS,QAAQ,IAAI,MAAM;AAAA,QAC5C,aAAY;AAAA,QACZ,UAAU;AAAA,QACV,YAAY,UAAU,iBAAiB;AAAA,QACvC,cAAc;AAAA,QACd,gBAAgB,CAAC,KAAK,KAAK,KAAK,KAAM,wBAAwB,CAAC,KAAK;AAAA,QACpE,OAAO;AAAA,QACP,MAAK;AAAA,QAEL,0BAAAA;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,kBAAkB;AAAA,YAClB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,sBAAsB,kBAAkB;AAAA,YACxC;AAAA;AAAA,QACF;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;AA6BA,IAAM,cAA4F,CAAC;AAAA,EACjG;AAAA,EACA;AAAA,EACA;AACF,MACE,gBAAAC,OAAC,SACC;AAAA,kBAAAD,MAAC,OAAE,OAAO,EAAE,QAAQ,GAAG,UAAU,IAAI,YAAY,KAAK,OAAO,OAAO,KAAK,GAAI,iBAAM;AAAA,EAClF,cACC,gBAAAA,MAAC,OAAE,OAAO,EAAE,QAAQ,WAAW,UAAU,IAAI,OAAO,OAAO,MAAM,GAAI,uBAAY,IAC/E;AAAA,EACJ,gBAAAA,MAAC,SAAI,OAAO,EAAE,WAAW,IAAI,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAG,GAAI,UAAS;AAAA,GAC9F;AAGF,IAAM,WAAoC,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MACE,gBAAAC,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,eAAe,UAAU,KAAK,GAAG,GAC9D;AAAA,kBAAAD,MAAC,SAAM,OAAM,QAAO,OAAO,KAAK,MAAM,UAAU,CAAC,MAAM,SAAS,QAAQ,EAAE,OAAO,KAAK,GAAG,aAAY,2BAA0B,WAAS,MAAC,WAAS,MAAC;AAAA,EACnJ,gBAAAC,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,qBAAqB,WAAW,KAAK,GAAG,GACrE;AAAA,oBAAAD,MAAC,UAAO,OAAM,mBAAkB,OAAO,KAAK,gBAAgB,UAAU,CAAC,UAAU,SAAS,kBAAkB,KAAK,GAAG,SAAS,iBAAiB;AAAA,IAC9I,gBAAAA,MAAC,UAAO,OAAM,eAAc,OAAO,KAAK,iBAAiB,UAAU,CAAC,UAAU,SAAS,mBAAmB,KAAK,GAAG,SAAS,oBAAoB;AAAA,KACjJ;AAAA,EACA,gBAAAC,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,qBAAqB,aAAa,YAAY,OAAO,KAAK,GAAG,GAC1F;AAAA,oBAAAD,MAAC,UAAO,OAAM,YAAW,OAAO,KAAK,YAAY,UAAU,kBAAkB,SAAS,iBAAiB;AAAA,IACtG,aACC,gBAAAA,MAAC,UAAO,OAAM,UAAS,OAAO,KAAK,QAAQ,UAAU,CAAC,UAAU,SAAS,UAAU,KAAK,GAAG,SAAS,eAAe,IACjH;AAAA,KACN;AAAA,EAEA,gBAAAC,OAAC,eAAY,OAAM,qBACjB;AAAA,oBAAAA,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,qBAAqB,WAAW,KAAK,GAAG,GACrE;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,OAAM;AAAA,UACN,OAAO,KAAK;AAAA,UACZ,UAAU,CAAC,UAAU,SAAS,eAAe,KAAK;AAAA,UAClD,SAAS;AAAA;AAAA,MACX;AAAA,MACA,gBAAAA,MAAC,UAAO,OAAM,OAAM,OAAO,KAAK,SAAS,UAAU,CAAC,UAAU,SAAS,WAAW,KAAK,GAAG,SAAS,kBAAkB;AAAA,OACvH;AAAA,IACC,mBACC,gBAAAC,OAAAF,WAAA,EACE;AAAA,sBAAAC;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,uBAAuB,oBAAoB;AAAA,UAClD,OAAO,KAAK;AAAA,UACZ,UAAU,CAAC,UAAU,SAAS,4BAA4B,KAAK;AAAA,UAC/D,SAAS;AAAA,UACT,aACE,oBAAoB,SAChB,0CACA,uBACE,+BACA;AAAA,UAER,UAAU,oBAAoB,WAAW;AAAA,UACzC,YACE,uBACI,oEACA;AAAA;AAAA,MAER;AAAA,MACC,wBAAwB,oBAAoB,WAAW,IACtD,gBAAAA,MAAC,SAAM,SAAQ,WAAU,OAAM,uCAC5B,iCACG,eAAe,oBAAoB,uGACnC,gFACN,IACE;AAAA,OACN,IACE;AAAA,KACN;AAAA,EAEA,gBAAAC;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,aACE,KAAK,mBAAmB,gBACpB,yEACA;AAAA,MAGL;AAAA,uBAAe,SAAS,IACvB,gBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,OAAM;AAAA,YACN,OAAO,KAAK;AAAA,YACZ,UAAU,CAAC,UAAU,SAAS,aAAa,KAAK;AAAA,YAChD,SAAS;AAAA,YACT,aAAY;AAAA,YACZ,YAAW;AAAA;AAAA,QACb,IACE;AAAA,QACJ,gBAAAC,OAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,qBAAqB,WAAW,KAAK,GAAG,GACrE;AAAA,0BAAAD,MAAC,SAAM,OAAM,YAAW,MAAK,UAAS,KAAK,GAAG,OAAO,KAAK,cAAc,UAAU,CAAC,MAAM,SAAS,gBAAgB,EAAE,OAAO,KAAK,GAAG,WAAS,MAAC;AAAA,UAC7I,gBAAAA,MAAC,SAAM,OAAM,gBAAe,MAAK,UAAS,KAAK,GAAG,OAAO,KAAK,iBAAiB,UAAU,CAAC,MAAM,SAAS,mBAAmB,EAAE,OAAO,KAAK,GAAG,WAAS,MAAC;AAAA,WACzJ;AAAA,QACC,KAAK,cAAc,KAAK,eAAe,cACtC,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAM;AAAA,YACN,OAAO,KAAK;AAAA,YACZ,UAAU,CAAC,MAAM,SAAS,gBAAgB,EAAE,OAAO,KAAK;AAAA,YACxD,aAAa,uBAAuB;AAAA,YACpC,WAAS;AAAA,YACT,YAAY,qEAAqE,uBAAuB,GAAG,WAAW,uBAAuB,KAAK,SAAS,uBAAuB,GAAG,aAAa,uBAAuB,OAAO;AAAA;AAAA,QAClO,IACE;AAAA,QACH,aACC,gBAAAC,OAAAF,WAAA,EACE;AAAA,0BAAAC;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,WAAW,KAAK;AAAA,cAChB,WAAW,KAAK,IAAI,GAAG,OAAO,KAAK,YAAY,KAAK,CAAC;AAAA,cACrD,eAAe,KAAK;AAAA,cACpB;AAAA,cACA;AAAA,cACA,UAAU,CAAC,MAAM,SAAS,oBAAoB,CAAC;AAAA;AAAA,UACjD;AAAA,UACA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,WAAW,KAAK;AAAA,cAChB,WAAW,KAAK,IAAI,GAAG,OAAO,KAAK,eAAe,KAAK,CAAC;AAAA,cACxD,eAAe,KAAK;AAAA,cACpB;AAAA,cACA;AAAA,cACA,UAAU,CAAC,MAAM,SAAS,uBAAuB,CAAC;AAAA;AAAA,UACpD;AAAA,WACF,IACE;AAAA;AAAA;AAAA,EACN;AAAA,EAEC,KAAK,mBAAmB,gBACvB,gBAAAC,OAAAF,WAAA,EACE;AAAA,oBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,aAAY;AAAA,QAEZ,0BAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAM;AAAA,YACN,OAAO,KAAK;AAAA,YACZ,UAAU,CAAC,UAAU,SAAS,sBAAsB,KAAwC;AAAA,YAC5F,SAAS,6BAA6B,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,OAAO,GAAG,EAAE,KAAK,WAAM,EAAE,WAAW,GAAG,EAAE;AAAA;AAAA,QAC/G;AAAA;AAAA,IACF;AAAA,IAEA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,aAAY;AAAA,QAEZ,0BAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAM;AAAA,YACN,MAAK;AAAA,YACL,KAAK;AAAA,YACL,OAAO,KAAK;AAAA,YACZ,UAAU,CAAC,MAAM,SAAS,uBAAuB,EAAE,OAAO,KAAK;AAAA,YAC/D,WAAS;AAAA;AAAA,QACX;AAAA;AAAA,IACF;AAAA,KACF,IACE;AAAA,GACN;AAGF,IAAO,oCAAQ;;;AoBrqBR,IAAM,gBAAgB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,aAAa;AAG1B,SAAS,EAAE,OAA0C;AACnD,SAAO,OAAO,SAAS,EAAE,EAAE,KAAK;AAClC;AAeO,SAAS,cAAc,OAA+B;AAC3D,QAAM,aAAa,EAAE,MAAM,UAAU;AAErC,QAAM,gBAAgB,EAAE,MAAM,iBAAiB,KAAK;AACpD,QAAM,aAAa,EAAE,MAAM,UAAU,KAAK;AAC1C,QAAM,QAAQ,EAAE,MAAM,KAAK,KAAK;AAGhC,SAAO;AAAA,IACL,oBAAoB;AAAA,IACpB,uBAAuB,EAAE,MAAM,gBAAgB;AAAA,IAC/C,mBAAmB,EAAE,MAAM,IAAI;AAAA,IAC/B,mBAAmB,EAAE,MAAM,eAAe;AAAA,IAC1C,eAAe,EAAE,MAAM,KAAK;AAAA,IAC5B,qBAAqB;AAAA,IACrB,YAAY;AAAA,IACZ,OAAO;AAAA,EACT;AACF;","names":["useCallback","useEffect","useMemo","useState","s","useMemo","s","out","jsx","jsxs","jsx","jsxs","jsx","jsxs","s","Fragment","jsx","jsxs","Fragment","jsx","jsxs","jsx","jsxs","Row","jsx","jsxs","Fragment","jsx","jsxs","Fragment","jsx","jsxs","jsx","jsxs","Fragment","jsx","jsxs","s","authFetch","useMemo","jsx","jsxs","s","Fragment","jsx","jsxs","useState","useCallback","useEffect","useMemo"]}