@anyshift/backstage-plugin-anyshift 0.1.0-beta.14 → 0.1.0-beta.16
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.
- package/CHANGELOG.md +12 -0
- package/dist/api/AnyshiftApi.esm.js +2 -0
- package/dist/api/AnyshiftApi.esm.js.map +1 -1
- package/dist/components/cloud/CloudResourceContent.esm.js +6 -3
- package/dist/components/cloud/CloudResourceContent.esm.js.map +1 -1
- package/dist/components/entity/AnyshiftEntityContent.esm.js +48 -6
- package/dist/components/entity/AnyshiftEntityContent.esm.js.map +1 -1
- package/dist/components/entity/SectionPresenters.esm.js +10 -4
- package/dist/components/entity/SectionPresenters.esm.js.map +1 -1
- package/dist/components/entity/entityIdentity.esm.js +11 -1
- package/dist/components/entity/entityIdentity.esm.js.map +1 -1
- package/dist/components/entity/relatedCatalogEntities.esm.js +60 -0
- package/dist/components/entity/relatedCatalogEntities.esm.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/package.json.esm.js +10 -10
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.1.0-beta.16
|
|
6
|
+
|
|
7
|
+
- Retry unresolved cloud-change evidence with the provider-native ARN while keeping the stable
|
|
8
|
+
catalog identity and existing entity URLs unchanged.
|
|
9
|
+
|
|
10
|
+
## 0.1.0-beta.15
|
|
11
|
+
|
|
12
|
+
- Resolve Affected footprint entries against one Backstage catalog snapshot and link only entities
|
|
13
|
+
that are proven to exist.
|
|
14
|
+
- Repair stale runtime-namespace links, de-duplicate logical names, and keep unresolved graph
|
|
15
|
+
evidence visible as plain text instead of dead links.
|
|
16
|
+
|
|
5
17
|
## 0.1.0-beta.14
|
|
6
18
|
|
|
7
19
|
- Expose available APM HTTP methods and templated paths from service `CALLS_TO` edges through a compact architecture-diagram affordance and source-grouped evidence inspector.
|
|
@@ -54,6 +54,8 @@ class AnyshiftClient {
|
|
|
54
54
|
}
|
|
55
55
|
async cloudResourceBrief(resource, options = {}) {
|
|
56
56
|
const params = new URLSearchParams({ resource });
|
|
57
|
+
if (options.fallbackResource)
|
|
58
|
+
params.set("fallbackResource", options.fallbackResource);
|
|
57
59
|
if (options.since) params.set("since", options.since);
|
|
58
60
|
if (options.cursor) params.set("cursor", options.cursor);
|
|
59
61
|
if (options.diff !== void 0) params.set("diff", String(options.diff));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnyshiftApi.esm.js","sources":["../../src/api/AnyshiftApi.ts"],"sourcesContent":["import {\n createApiRef,\n type DiscoveryApi,\n type FetchApi,\n} from '@backstage/frontend-plugin-api';\nimport type {\n BriefSectionName,\n BriefSectionResponse,\n AnyshiftCapabilities,\n AskAnyshiftRequest,\n AskAnyshiftResponse,\n CatalogSummary,\n CatalogSyncReport,\n CloudResourceBrief,\n DatadogSignals,\n EstateInsights,\n QueryResult,\n ServiceBrief,\n} from './types';\n\nexport interface AnyshiftApi {\n ask(request: AskAnyshiftRequest): Promise<AskAnyshiftResponse>;\n capabilities(): Promise<AnyshiftCapabilities>;\n brief(\n kind: string,\n target: string,\n options?: BriefRequestOptions,\n ): Promise<ServiceBrief>;\n briefSection(\n kind: string,\n target: string,\n section: BriefSectionName,\n options?: BriefRequestOptions,\n ): Promise<BriefSectionResponse>;\n insights(options?: { refresh?: boolean }): Promise<EstateInsights>;\n datadogSignals(options?: { refresh?: boolean }): Promise<DatadogSignals>;\n cloudResourceBrief(\n resource: string,\n options?: CloudResourceBriefRequestOptions,\n ): Promise<CloudResourceBrief>;\n inventory(\n type: string,\n options?: { limit?: number; offset?: number },\n ): Promise<CatalogSummary>;\n query(sql: string): Promise<QueryResult>;\n reconcileCatalog(): Promise<CatalogSyncAccepted>;\n}\n\nexport interface BriefRequestOptions {\n namespace?: string;\n refresh?: boolean;\n configurationEndpoints?: string;\n configurationDependencies?: string;\n configurationTarget?: string;\n}\n\nexport interface CloudResourceBriefRequestOptions {\n since?: string;\n cursor?: string;\n diff?: boolean;\n refresh?: boolean;\n}\n\nexport interface CatalogSyncAccepted {\n accepted: true;\n acceptedAt: string;\n previous?: CatalogSyncReport;\n}\n\nexport const anyshiftApiRef = createApiRef<AnyshiftApi>({\n id: 'plugin.anyshift.service',\n});\n\nexport class AnyshiftRequestError extends Error {\n constructor(\n readonly status: number,\n readonly code: string,\n message: string,\n readonly retryAfterSeconds?: number,\n ) {\n super(message);\n this.name = 'AnyshiftRequestError';\n }\n}\n\nexport class AnyshiftClient implements AnyshiftApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: { discoveryApi: DiscoveryApi; fetchApi: FetchApi }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi;\n }\n\n async ask(request: AskAnyshiftRequest): Promise<AskAnyshiftResponse> {\n return this.request('/ask', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(request),\n });\n }\n\n async capabilities(): Promise<AnyshiftCapabilities> {\n return this.get('/capabilities');\n }\n\n async brief(\n kind: string,\n target: string,\n options: BriefRequestOptions = {},\n ): Promise<ServiceBrief> {\n return this.get(\n `/brief/${encodeURIComponent(kind)}/${encodeURIComponent(\n target,\n )}${briefQuery(options)}`,\n );\n }\n\n async briefSection(\n kind: string,\n target: string,\n section: BriefSectionName,\n options: BriefRequestOptions = {},\n ): Promise<BriefSectionResponse> {\n return this.get(\n `/brief/${encodeURIComponent(kind)}/${encodeURIComponent(\n target,\n )}/sections/${encodeURIComponent(section)}${briefQuery(options)}`,\n );\n }\n\n async insights(options: { refresh?: boolean } = {}): Promise<EstateInsights> {\n return this.get(`/insights${options.refresh ? '?refresh=1' : ''}`);\n }\n\n async datadogSignals(\n options: { refresh?: boolean } = {},\n ): Promise<DatadogSignals> {\n return this.get(`/signals/datadog${options.refresh ? '?refresh=1' : ''}`);\n }\n\n async cloudResourceBrief(\n resource: string,\n options: CloudResourceBriefRequestOptions = {},\n ): Promise<CloudResourceBrief> {\n const params = new URLSearchParams({ resource });\n if (options.since) params.set('since', options.since);\n if (options.cursor) params.set('cursor', options.cursor);\n if (options.diff !== undefined) params.set('diff', String(options.diff));\n if (options.refresh) params.set('refresh', '1');\n return this.get(`/cloud/resources/brief?${params}`);\n }\n\n async inventory(\n type: string,\n options: { limit?: number; offset?: number } = {},\n ): Promise<CatalogSummary> {\n const params = new URLSearchParams({ type });\n if (options.limit !== undefined) params.set('limit', String(options.limit));\n if (options.offset !== undefined)\n params.set('offset', String(options.offset));\n return this.get(`/inventory?${params}`);\n }\n\n async query(sql: string): Promise<QueryResult> {\n return this.request('/query', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ sql }),\n });\n }\n\n async reconcileCatalog(): Promise<CatalogSyncAccepted> {\n return this.request('/anyshift/reconcile', { method: 'POST' }, 'catalog');\n }\n\n private async get<T>(path: string): Promise<T> {\n return this.request(path, { method: 'GET' });\n }\n\n private async request<T>(\n path: string,\n init: RequestInit,\n pluginId = 'anyshift',\n ): Promise<T> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n const response = await this.fetchApi.fetch(`${baseUrl}${path}`, init);\n const text = await response.text();\n let payload: unknown;\n try {\n payload = text ? JSON.parse(text) : {};\n } catch {\n payload = {};\n }\n if (!response.ok) {\n const error = errorEnvelope(payload);\n throw new AnyshiftRequestError(\n response.status,\n error.code,\n error.message ?? `Anyshift request failed (${response.status})`,\n error.retryAfterSeconds,\n );\n }\n return payload as T;\n }\n}\n\nfunction errorEnvelope(payload: unknown): {\n code: string;\n message?: string;\n retryAfterSeconds?: number;\n} {\n const error =\n payload && typeof payload === 'object' && 'error' in payload\n ? (payload as { error?: unknown }).error\n : undefined;\n if (!error || typeof error !== 'object') {\n return { code: 'request_failed' };\n }\n\n const { code, message, retryAfterSeconds } = error as {\n code?: unknown;\n message?: unknown;\n retryAfterSeconds?: unknown;\n };\n return {\n code: typeof code === 'string' ? code : 'request_failed',\n message: typeof message === 'string' && message ? message : undefined,\n retryAfterSeconds:\n typeof retryAfterSeconds === 'number' &&\n Number.isFinite(retryAfterSeconds)\n ? retryAfterSeconds\n : undefined,\n };\n}\n\nfunction briefQuery(options: BriefRequestOptions): string {\n const params = new URLSearchParams();\n if (options.namespace) params.set('namespace', options.namespace);\n if (options.refresh) params.set('refresh', '1');\n if (options.configurationEndpoints)\n params.set('configurationEndpoints', options.configurationEndpoints);\n if (options.configurationDependencies)\n params.set('configurationDependencies', options.configurationDependencies);\n if (options.configurationTarget)\n params.set('configurationTarget', options.configurationTarget);\n const query = params.toString();\n return query ? `?${query}` : '';\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AnyshiftApi.esm.js","sources":["../../src/api/AnyshiftApi.ts"],"sourcesContent":["import {\n createApiRef,\n type DiscoveryApi,\n type FetchApi,\n} from '@backstage/frontend-plugin-api';\nimport type {\n BriefSectionName,\n BriefSectionResponse,\n AnyshiftCapabilities,\n AskAnyshiftRequest,\n AskAnyshiftResponse,\n CatalogSummary,\n CatalogSyncReport,\n CloudResourceBrief,\n DatadogSignals,\n EstateInsights,\n QueryResult,\n ServiceBrief,\n} from './types';\n\nexport interface AnyshiftApi {\n ask(request: AskAnyshiftRequest): Promise<AskAnyshiftResponse>;\n capabilities(): Promise<AnyshiftCapabilities>;\n brief(\n kind: string,\n target: string,\n options?: BriefRequestOptions,\n ): Promise<ServiceBrief>;\n briefSection(\n kind: string,\n target: string,\n section: BriefSectionName,\n options?: BriefRequestOptions,\n ): Promise<BriefSectionResponse>;\n insights(options?: { refresh?: boolean }): Promise<EstateInsights>;\n datadogSignals(options?: { refresh?: boolean }): Promise<DatadogSignals>;\n cloudResourceBrief(\n resource: string,\n options?: CloudResourceBriefRequestOptions,\n ): Promise<CloudResourceBrief>;\n inventory(\n type: string,\n options?: { limit?: number; offset?: number },\n ): Promise<CatalogSummary>;\n query(sql: string): Promise<QueryResult>;\n reconcileCatalog(): Promise<CatalogSyncAccepted>;\n}\n\nexport interface BriefRequestOptions {\n namespace?: string;\n refresh?: boolean;\n configurationEndpoints?: string;\n configurationDependencies?: string;\n configurationTarget?: string;\n}\n\nexport interface CloudResourceBriefRequestOptions {\n fallbackResource?: string;\n since?: string;\n cursor?: string;\n diff?: boolean;\n refresh?: boolean;\n}\n\nexport interface CatalogSyncAccepted {\n accepted: true;\n acceptedAt: string;\n previous?: CatalogSyncReport;\n}\n\nexport const anyshiftApiRef = createApiRef<AnyshiftApi>({\n id: 'plugin.anyshift.service',\n});\n\nexport class AnyshiftRequestError extends Error {\n constructor(\n readonly status: number,\n readonly code: string,\n message: string,\n readonly retryAfterSeconds?: number,\n ) {\n super(message);\n this.name = 'AnyshiftRequestError';\n }\n}\n\nexport class AnyshiftClient implements AnyshiftApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: { discoveryApi: DiscoveryApi; fetchApi: FetchApi }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi;\n }\n\n async ask(request: AskAnyshiftRequest): Promise<AskAnyshiftResponse> {\n return this.request('/ask', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(request),\n });\n }\n\n async capabilities(): Promise<AnyshiftCapabilities> {\n return this.get('/capabilities');\n }\n\n async brief(\n kind: string,\n target: string,\n options: BriefRequestOptions = {},\n ): Promise<ServiceBrief> {\n return this.get(\n `/brief/${encodeURIComponent(kind)}/${encodeURIComponent(\n target,\n )}${briefQuery(options)}`,\n );\n }\n\n async briefSection(\n kind: string,\n target: string,\n section: BriefSectionName,\n options: BriefRequestOptions = {},\n ): Promise<BriefSectionResponse> {\n return this.get(\n `/brief/${encodeURIComponent(kind)}/${encodeURIComponent(\n target,\n )}/sections/${encodeURIComponent(section)}${briefQuery(options)}`,\n );\n }\n\n async insights(options: { refresh?: boolean } = {}): Promise<EstateInsights> {\n return this.get(`/insights${options.refresh ? '?refresh=1' : ''}`);\n }\n\n async datadogSignals(\n options: { refresh?: boolean } = {},\n ): Promise<DatadogSignals> {\n return this.get(`/signals/datadog${options.refresh ? '?refresh=1' : ''}`);\n }\n\n async cloudResourceBrief(\n resource: string,\n options: CloudResourceBriefRequestOptions = {},\n ): Promise<CloudResourceBrief> {\n const params = new URLSearchParams({ resource });\n if (options.fallbackResource)\n params.set('fallbackResource', options.fallbackResource);\n if (options.since) params.set('since', options.since);\n if (options.cursor) params.set('cursor', options.cursor);\n if (options.diff !== undefined) params.set('diff', String(options.diff));\n if (options.refresh) params.set('refresh', '1');\n return this.get(`/cloud/resources/brief?${params}`);\n }\n\n async inventory(\n type: string,\n options: { limit?: number; offset?: number } = {},\n ): Promise<CatalogSummary> {\n const params = new URLSearchParams({ type });\n if (options.limit !== undefined) params.set('limit', String(options.limit));\n if (options.offset !== undefined)\n params.set('offset', String(options.offset));\n return this.get(`/inventory?${params}`);\n }\n\n async query(sql: string): Promise<QueryResult> {\n return this.request('/query', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ sql }),\n });\n }\n\n async reconcileCatalog(): Promise<CatalogSyncAccepted> {\n return this.request('/anyshift/reconcile', { method: 'POST' }, 'catalog');\n }\n\n private async get<T>(path: string): Promise<T> {\n return this.request(path, { method: 'GET' });\n }\n\n private async request<T>(\n path: string,\n init: RequestInit,\n pluginId = 'anyshift',\n ): Promise<T> {\n const baseUrl = await this.discoveryApi.getBaseUrl(pluginId);\n const response = await this.fetchApi.fetch(`${baseUrl}${path}`, init);\n const text = await response.text();\n let payload: unknown;\n try {\n payload = text ? JSON.parse(text) : {};\n } catch {\n payload = {};\n }\n if (!response.ok) {\n const error = errorEnvelope(payload);\n throw new AnyshiftRequestError(\n response.status,\n error.code,\n error.message ?? `Anyshift request failed (${response.status})`,\n error.retryAfterSeconds,\n );\n }\n return payload as T;\n }\n}\n\nfunction errorEnvelope(payload: unknown): {\n code: string;\n message?: string;\n retryAfterSeconds?: number;\n} {\n const error =\n payload && typeof payload === 'object' && 'error' in payload\n ? (payload as { error?: unknown }).error\n : undefined;\n if (!error || typeof error !== 'object') {\n return { code: 'request_failed' };\n }\n\n const { code, message, retryAfterSeconds } = error as {\n code?: unknown;\n message?: unknown;\n retryAfterSeconds?: unknown;\n };\n return {\n code: typeof code === 'string' ? code : 'request_failed',\n message: typeof message === 'string' && message ? message : undefined,\n retryAfterSeconds:\n typeof retryAfterSeconds === 'number' &&\n Number.isFinite(retryAfterSeconds)\n ? retryAfterSeconds\n : undefined,\n };\n}\n\nfunction briefQuery(options: BriefRequestOptions): string {\n const params = new URLSearchParams();\n if (options.namespace) params.set('namespace', options.namespace);\n if (options.refresh) params.set('refresh', '1');\n if (options.configurationEndpoints)\n params.set('configurationEndpoints', options.configurationEndpoints);\n if (options.configurationDependencies)\n params.set('configurationDependencies', options.configurationDependencies);\n if (options.configurationTarget)\n params.set('configurationTarget', options.configurationTarget);\n const query = params.toString();\n return query ? `?${query}` : '';\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ import { useEntity } from '@backstage/plugin-catalog-react';
|
|
|
9
9
|
import { anyshiftApiRef } from '../../api/AnyshiftApi.esm.js';
|
|
10
10
|
import { AskAnyshiftCard } from '../ask/AskAnyshiftCard.esm.js';
|
|
11
11
|
import { askScopeForEntity } from '../ask/askScope.esm.js';
|
|
12
|
-
import { cloudResourceIdentity } from '../entity/entityIdentity.esm.js';
|
|
12
|
+
import { cloudResourceIdentity, cloudResourceFallbackIdentity } from '../entity/entityIdentity.esm.js';
|
|
13
13
|
import { CloudImpactSection } from './CloudImpactSection.esm.js';
|
|
14
14
|
import { CloudDependenciesSection, CloudDependentsSection } from './CloudRelationshipSections.esm.js';
|
|
15
15
|
|
|
@@ -19,6 +19,7 @@ const CloudResourceEvidenceContent = ({ includeAsk = false }) => {
|
|
|
19
19
|
const { entity } = useEntity();
|
|
20
20
|
const api = useApi(anyshiftApiRef);
|
|
21
21
|
const resourceId = cloudResourceIdentity(entity);
|
|
22
|
+
const fallbackResource = cloudResourceFallbackIdentity(entity);
|
|
22
23
|
const [loadedBrief, setLoadedBrief] = useState();
|
|
23
24
|
const brief = loadedBrief && loadedBrief.resourceId === resourceId ? loadedBrief.value : void 0;
|
|
24
25
|
const [error, setError] = useState();
|
|
@@ -56,6 +57,7 @@ const CloudResourceEvidenceContent = ({ includeAsk = false }) => {
|
|
|
56
57
|
setError(void 0);
|
|
57
58
|
try {
|
|
58
59
|
const next = await api.cloudResourceBrief(resourceId, {
|
|
60
|
+
...fallbackResource ? { fallbackResource } : {},
|
|
59
61
|
since: "24h",
|
|
60
62
|
diff: true,
|
|
61
63
|
...refresh ? { refresh: true } : {}
|
|
@@ -79,7 +81,7 @@ const CloudResourceEvidenceContent = ({ includeAsk = false }) => {
|
|
|
79
81
|
}
|
|
80
82
|
}
|
|
81
83
|
},
|
|
82
|
-
[api, resourceId]
|
|
84
|
+
[api, fallbackResource, resourceId]
|
|
83
85
|
);
|
|
84
86
|
useEffect(() => {
|
|
85
87
|
void load();
|
|
@@ -104,6 +106,7 @@ const CloudResourceEvidenceContent = ({ includeAsk = false }) => {
|
|
|
104
106
|
setPaginationError(void 0);
|
|
105
107
|
try {
|
|
106
108
|
const next = await api.cloudResourceBrief(resourceId, {
|
|
109
|
+
...fallbackResource ? { fallbackResource } : {},
|
|
107
110
|
since: brief.since,
|
|
108
111
|
diff: true,
|
|
109
112
|
cursor
|
|
@@ -150,7 +153,7 @@ const CloudResourceEvidenceContent = ({ includeAsk = false }) => {
|
|
|
150
153
|
setLoadingMore(false);
|
|
151
154
|
}
|
|
152
155
|
}
|
|
153
|
-
}, [api, brief, resourceId]);
|
|
156
|
+
}, [api, brief, fallbackResource, resourceId]);
|
|
154
157
|
if (!resourceId) {
|
|
155
158
|
return /* @__PURE__ */ jsx(Alert, { severity: "info", children: "This catalog entity has no stable Anyshift resource ID or cloud ARN." });
|
|
156
159
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CloudResourceContent.esm.js","sources":["../../../src/components/cloud/CloudResourceContent.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport {\n Button,\n Chip,\n CircularProgress,\n Grid,\n Typography,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport { InfoCard, Link, Progress } from '@backstage/core-components';\nimport { useApi } from '@backstage/frontend-plugin-api';\nimport type { Entity } from '@backstage/catalog-model';\nimport {\n ANYSHIFT_CLOUD_ACCOUNT_ANNOTATION,\n ANYSHIFT_CLOUD_PROVIDER_ANNOTATION,\n ANYSHIFT_CLOUD_REGION_ANNOTATION,\n ANYSHIFT_RESOURCE_TYPE_ANNOTATION,\n type BriefSection,\n type CloudEventsEvidence,\n type CloudResourceBrief,\n type IacDriftEvidence,\n type IacEvidence,\n} from '@anyshift/backstage-plugin-anyshift-common';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { anyshiftApiRef } from '../../api/AnyshiftApi';\nimport { AskAnyshiftCard } from '../ask/AskAnyshiftCard';\nimport { askScopeForEntity } from '../ask/askScope';\nimport type { AnyshiftCapabilities, AskScope } from '../../api/types';\nimport { cloudResourceIdentity } from '../entity/entityIdentity';\nimport { CloudImpactSection } from './CloudImpactSection';\nimport {\n CloudDependenciesSection,\n CloudDependentsSection,\n} from './CloudRelationshipSections';\n\nexport const CloudResourceContent = () => <CloudResourceEvidenceContent />;\n\nexport const CloudAnyshiftEntityContent = () => (\n <CloudResourceEvidenceContent includeAsk />\n);\n\nconst CloudResourceEvidenceContent = ({ includeAsk = false }) => {\n const { entity } = useEntity();\n const api = useApi(anyshiftApiRef);\n const resourceId = cloudResourceIdentity(entity);\n const [loadedBrief, setLoadedBrief] = useState<{\n resourceId: string;\n value: CloudResourceBrief;\n }>();\n const brief =\n loadedBrief && loadedBrief.resourceId === resourceId\n ? loadedBrief.value\n : undefined;\n const [error, setError] = useState<string>();\n const [refreshing, setRefreshing] = useState(false);\n const [loadingMore, setLoadingMore] = useState(false);\n const [paginationError, setPaginationError] = useState<string>();\n const [capabilities, setCapabilities] = useState<AnyshiftCapabilities>({\n askEnabled: false,\n queryEnabled: false,\n });\n const operations = useRef({ identity: 0, primary: 0, pagination: 0 });\n const askScope = useMemo(\n () => (includeAsk ? askScopeForEntity(entity) : undefined),\n [entity, includeAsk],\n );\n\n useLayoutEffect(() => {\n operations.current.identity += 1;\n operations.current.primary += 1;\n operations.current.pagination += 1;\n setLoadedBrief(undefined);\n setError(undefined);\n setRefreshing(false);\n setLoadingMore(false);\n setPaginationError(undefined);\n }, [resourceId]);\n\n const load = useCallback(\n async (refresh = false) => {\n if (!resourceId) return;\n const identity = operations.current.identity;\n const primary = ++operations.current.primary;\n ++operations.current.pagination;\n setRefreshing(refresh);\n setLoadingMore(false);\n setPaginationError(undefined);\n setError(undefined);\n try {\n const next = await api.cloudResourceBrief(resourceId, {\n since: '24h',\n diff: true,\n ...(refresh ? { refresh: true } : {}),\n });\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary\n ) {\n ++operations.current.pagination;\n setLoadingMore(false);\n setLoadedBrief({ resourceId, value: next });\n }\n } catch (loadError) {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary\n ) {\n ++operations.current.pagination;\n setLoadingMore(false);\n setError(\n loadError instanceof Error\n ? loadError.message\n : 'Unable to load cloud evidence',\n );\n }\n } finally {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary\n ) {\n setRefreshing(false);\n }\n }\n },\n [api, resourceId],\n );\n\n useEffect(() => {\n void load();\n }, [load]);\n\n useEffect(() => {\n if (!includeAsk) return undefined;\n let active = true;\n api\n .capabilities()\n .then(next => active && setCapabilities(next))\n .catch(\n () =>\n active && setCapabilities({ askEnabled: false, queryEnabled: false }),\n );\n return () => {\n active = false;\n };\n }, [api, includeAsk]);\n\n const loadMore = useCallback(async () => {\n const cursor = brief?.changes.data?.page.nextCursor;\n if (!resourceId || !cursor) return;\n const identity = operations.current.identity;\n const primary = operations.current.primary;\n const pagination = ++operations.current.pagination;\n setLoadingMore(true);\n setPaginationError(undefined);\n try {\n const next = await api.cloudResourceBrief(resourceId, {\n since: brief.since,\n diff: true,\n cursor,\n });\n if (\n operations.current.identity !== identity ||\n operations.current.primary !== primary ||\n operations.current.pagination !== pagination\n ) {\n return;\n }\n if (next.changes.state === 'error') {\n setPaginationError(\n next.changes.message || 'Unable to load more cloud changes',\n );\n return;\n }\n if (next.changes.state === 'data' && next.changes.data) {\n setPaginationError(undefined);\n }\n setLoadedBrief(current => {\n if (\n !current ||\n current.resourceId !== resourceId ||\n !current.value.changes.data ||\n next.changes.state !== 'data' ||\n !next.changes.data\n ) {\n return current;\n }\n return {\n resourceId,\n value: {\n ...current.value,\n refreshedAt: next.refreshedAt,\n changes: {\n state: 'data',\n data: mergeCloudEventsEvidence(\n current.value.changes.data,\n next.changes.data,\n ),\n },\n },\n };\n });\n } catch (loadError) {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary &&\n operations.current.pagination === pagination\n ) {\n setPaginationError(\n loadError instanceof Error\n ? loadError.message\n : 'Unable to load more cloud changes',\n );\n }\n } finally {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary &&\n operations.current.pagination === pagination\n ) {\n setLoadingMore(false);\n }\n }\n }, [api, brief, resourceId]);\n\n if (!resourceId) {\n return (\n <Alert severity=\"info\">\n This catalog entity has no stable Anyshift resource ID or cloud ARN.\n </Alert>\n );\n }\n if (error && !brief) {\n return (\n <Alert severity=\"error\">\n {error} <Button onClick={() => void load(true)}>Retry</Button>\n </Alert>\n );\n }\n if (!brief) return <Progress />;\n\n return (\n <CloudResourceBriefView\n entity={entity}\n brief={brief}\n refreshing={refreshing}\n onRefresh={() => void load(true)}\n loadingMore={loadingMore}\n onLoadMore={() => void loadMore()}\n error={error}\n paginationError={paginationError}\n askEnabled={includeAsk && capabilities.askEnabled && Boolean(askScope)}\n askScope={askScope}\n />\n );\n};\n\nexport function mergeCloudEventsEvidence(\n current: CloudEventsEvidence,\n next: CloudEventsEvidence,\n): CloudEventsEvidence {\n return {\n ...next,\n availability: mergeCloudEventAvailability(\n current.availability,\n next.availability,\n ),\n warnings: [...new Set([...current.warnings, ...next.warnings])],\n items: [...current.items, ...next.items],\n };\n}\n\nfunction mergeCloudEventAvailability(\n current: Record<string, string>,\n next: Record<string, string>,\n): Record<string, string> {\n const availability: Record<string, string> = {};\n for (const field of new Set([\n ...Object.keys(current),\n ...Object.keys(next),\n ])) {\n availability[field] = leastCompleteAvailability(\n current[field],\n next[field],\n );\n }\n return availability;\n}\n\nfunction leastCompleteAvailability(\n current: string | undefined,\n next: string | undefined,\n): string {\n const normalizedCurrent = normalizeAvailability(current);\n const normalizedNext = normalizeAvailability(next);\n return AVAILABILITY_RANK[normalizedCurrent] <=\n AVAILABILITY_RANK[normalizedNext]\n ? normalizedCurrent\n : normalizedNext;\n}\n\nconst AVAILABILITY_RANK: Record<string, number> = {\n unavailable: 0,\n partial: 1,\n available: 2,\n};\n\nfunction normalizeAvailability(value: string | undefined): string {\n return value && value in AVAILABILITY_RANK ? value : 'unavailable';\n}\n\nexport const CloudResourceBriefView = ({\n entity,\n brief,\n refreshing,\n onRefresh,\n loadingMore,\n onLoadMore,\n error,\n paginationError,\n askEnabled = false,\n askScope,\n}: {\n entity: Entity;\n brief: CloudResourceBrief;\n refreshing?: boolean;\n onRefresh: () => void;\n loadingMore?: boolean;\n onLoadMore?: () => void;\n error?: string;\n paginationError?: string;\n askEnabled?: boolean;\n askScope?: AskScope;\n}) => {\n const annotations = entity.metadata.annotations ?? {};\n const consoleLink = entity.metadata.links?.find(link =>\n link.url.startsWith('https://console.aws.amazon.com/'),\n );\n\n return (\n <Grid container spacing={3}>\n {error && (\n <Grid item xs={12}>\n <Alert severity=\"error\">{error}</Alert>\n </Grid>\n )}\n <Grid item xs={12}>\n <InfoCard\n title=\"Cloud evidence\"\n action={\n <Button\n size=\"small\"\n onClick={onRefresh}\n startIcon={\n refreshing ? <CircularProgress size={14} /> : undefined\n }\n >\n Refresh\n </Button>\n }\n >\n <Typography color=\"textSecondary\">\n Read-only Anyshift evidence · last refreshed{' '}\n {formatCloudTimestamp(brief.refreshedAt)} · window {brief.since}\n </Typography>\n </InfoCard>\n </Grid>\n\n <Grid item xs={12}>\n <InfoCard title=\"Cloud identity\">\n <Definition\n label=\"Provider\"\n value={annotations[ANYSHIFT_CLOUD_PROVIDER_ANNOTATION]}\n />\n <Definition\n label=\"Resource type\"\n value={\n annotations[ANYSHIFT_RESOURCE_TYPE_ANNOTATION] ||\n String(entity.spec?.type || '')\n }\n />\n <Definition\n label=\"Region\"\n value={annotations[ANYSHIFT_CLOUD_REGION_ANNOTATION] || 'Global'}\n />\n <Definition\n label=\"Account\"\n value={annotations[ANYSHIFT_CLOUD_ACCOUNT_ANNOTATION]}\n />\n <Definition label=\"Stable resource ID\" value={brief.resourceId} />\n {consoleLink && <Link to={consoleLink.url}>Open in AWS Console</Link>}\n </InfoCard>\n </Grid>\n <Grid item xs={12} md={6}>\n <CloudDependenciesSection entity={entity} />\n </Grid>\n <Grid item xs={12} md={6}>\n <CloudDependentsSection entity={entity} />\n </Grid>\n <Grid item xs={12}>\n <CloudImpactSection section={brief.impact} onRetry={onRefresh} />\n </Grid>\n <Grid item xs={12}>\n <ChangesSection\n section={brief.changes}\n loadingMore={loadingMore}\n onLoadMore={onLoadMore}\n paginationError={paginationError}\n />\n </Grid>\n <Grid item xs={12} md={6}>\n <ProvenanceSection section={brief.provenance} />\n </Grid>\n <Grid item xs={12} md={6}>\n <DriftSection section={brief.drift} />\n </Grid>\n {askEnabled && (\n <Grid item xs={12}>\n <AskAnyshiftCard context=\"entity\" scope={askScope} />\n </Grid>\n )}\n </Grid>\n );\n};\n\nconst ChangesSection = ({\n section,\n loadingMore,\n onLoadMore,\n paginationError,\n}: {\n section: BriefSection<CloudEventsEvidence>;\n loadingMore?: boolean;\n onLoadMore?: () => void;\n paginationError?: string;\n}) => {\n const { hasEvidenceLimitations, actionableWarnings } =\n partitionCloudEventWarnings(\n section.data?.warnings,\n section.data?.items.length ?? 0,\n );\n\n if (section.state === 'empty') {\n return (\n <InfoCard title=\"Recent cloud changes\">\n <Typography color=\"textSecondary\">\n {section.message || 'No cloud changes were found in this window.'}\n </Typography>\n </InfoCard>\n );\n }\n\n return (\n <InfoCard title=\"Recent cloud changes\">\n <SectionState section={section}>\n {paginationError && (\n <Alert severity=\"error\" style={{ marginBottom: 8 }}>\n {paginationError}\n </Alert>\n )}\n {hasEvidenceLimitations && (\n <Typography\n aria-label=\"Cloud event evidence limitations\"\n variant=\"caption\"\n color=\"textSecondary\"\n display=\"block\"\n style={{ marginBottom: 8 }}\n >\n Event source is derived from graph relationships, and event status\n may be incomplete.\n </Typography>\n )}\n {actionableWarnings.map(warning => (\n <Alert severity=\"warning\" key={warning} style={{ marginBottom: 8 }}>\n {humanize(warning)}\n </Alert>\n ))}\n {section.data?.items?.length ? (\n section.data.items.map(event => (\n <div key={event.id} style={{ marginBottom: 20 }}>\n <Typography variant=\"subtitle1\">\n {event.summary || humanize(event.type)}\n </Typography>\n <Typography color=\"textSecondary\">\n {formatCloudTimestamp(event.timestamp)} · {event.category} ·{' '}\n {event.evidence.source} · {event.evidence.status}\n {event.actor?.name || event.actor?.id\n ? ` · ${event.actor.name || event.actor.id}`\n : ''}\n </Typography>\n {event.change.fields.length > 0 && (\n <details>\n <summary>View sanitized field changes</summary>\n <ul>\n {event.change.fields.map(field => {\n const detail = event.change.details.find(\n candidate => candidate.field === field,\n );\n return (\n <li key={field}>\n <code>{field}</code>\n {detail\n ? `: ${detail.before ?? '∅'} → ${\n detail.after ?? '∅'\n }`\n : ''}\n </li>\n );\n })}\n </ul>\n </details>\n )}\n </div>\n ))\n ) : (\n <Typography color=\"textSecondary\">\n No cloud changes were found in this window.\n </Typography>\n )}\n {section.data?.page.hasMore && onLoadMore && (\n <Button\n size=\"small\"\n onClick={onLoadMore}\n disabled={loadingMore}\n startIcon={loadingMore ? <CircularProgress size={14} /> : undefined}\n >\n Load more changes\n </Button>\n )}\n </SectionState>\n </InfoCard>\n );\n};\n\nconst QUIET_EVIDENCE_LIMITATIONS = new Set([\n 'event_source_derived',\n 'event_status_incomplete',\n]);\nconst IDENTITY_COMPLETENESS_WARNINGS = new Set([\n 'target_identity_incomplete',\n 'actor_identity_incomplete',\n]);\n\nfunction partitionCloudEventWarnings(\n warnings: string[] | undefined,\n eventCount: number,\n) {\n const allWarnings = warnings ?? [];\n return {\n hasEvidenceLimitations: allWarnings.some(warning =>\n QUIET_EVIDENCE_LIMITATIONS.has(warning),\n ),\n actionableWarnings: allWarnings.filter(\n warning =>\n !QUIET_EVIDENCE_LIMITATIONS.has(warning) &&\n (eventCount > 0 || !IDENTITY_COMPLETENESS_WARNINGS.has(warning)),\n ),\n };\n}\n\nconst ProvenanceSection = ({\n section,\n}: {\n section: BriefSection<IacEvidence>;\n}) => {\n if (section.state === 'empty') {\n return (\n <InfoCard title=\"IaC provenance\">\n <Typography color=\"textSecondary\">\n {section.message ||\n 'No Terraform provenance is linked to this resource.'}\n </Typography>\n </InfoCard>\n );\n }\n return (\n <InfoCard title=\"IaC provenance\">\n <SectionState section={section}>\n {section.data?.resources?.length ? (\n section.data.resources.map(resource => (\n <div key={resource.terraform.hashedID} style={{ marginBottom: 16 }}>\n <Typography variant=\"subtitle1\">\n {resource.terraform.address}\n </Typography>\n <Chip size=\"small\" label={humanize(resource.status)} />\n <Definition\n label=\"File\"\n value={resource.terraform.fileRef ?? ''}\n />\n <Definition\n label=\"State links\"\n value={String(resource.states.length)}\n />\n <Definition\n label=\"Cloud links\"\n value={String(resource.clouds.length)}\n />\n {resource.terraform.githubUrl && (\n <Link to={resource.terraform.githubUrl}>Open source</Link>\n )}\n </div>\n ))\n ) : (\n <Typography color=\"textSecondary\">\n No Terraform provenance is linked to this resource.\n </Typography>\n )}\n </SectionState>\n </InfoCard>\n );\n};\n\nconst DriftSection = ({\n section,\n}: {\n section: BriefSection<IacDriftEvidence>;\n}) => {\n if (section.state === 'empty') {\n return (\n <InfoCard title=\"IaC drift evidence\">\n <Typography color=\"textSecondary\">\n {section.message || 'No comparable Terraform evidence is available.'}\n </Typography>\n </InfoCard>\n );\n }\n return (\n <InfoCard title=\"IaC drift evidence\">\n <SectionState section={section}>\n {section.data?.items?.length ? (\n section.data.items.map(item => (\n <div key={item.terraform.hashedID} style={{ marginBottom: 16 }}>\n <Typography variant=\"subtitle1\">\n {item.terraform.address}\n </Typography>\n <Chip\n size=\"small\"\n color={item.status === 'drifted' ? 'secondary' : 'default'}\n label={humanize(item.status)}\n />\n <Typography color=\"textSecondary\">\n {item.status === 'unknown'\n ? `Unknown is not drift: ${humanize(item.reason)}.`\n : `${item.comparedFields} supported fields compared.`}\n </Typography>\n {item.differences.length > 0 && (\n <details>\n <summary>View sanitized differences</summary>\n <ul>\n {item.differences.map(difference => (\n <li key={difference.field}>\n <code>{difference.field}</code>:{' '}\n {difference.lastApplied ?? '∅'} →{' '}\n {difference.observed ?? '∅'}\n </li>\n ))}\n </ul>\n </details>\n )}\n </div>\n ))\n ) : (\n <Typography color=\"textSecondary\">\n No comparable Terraform evidence is available.\n </Typography>\n )}\n </SectionState>\n </InfoCard>\n );\n};\n\nconst SectionState = ({\n section,\n children,\n}: {\n section: BriefSection;\n children: ReactNode;\n}) => {\n if (section.state === 'error') {\n return <Alert severity=\"error\">{section.message}</Alert>;\n }\n if (section.state === 'unsupported') {\n return <Alert severity=\"info\">{section.message}</Alert>;\n }\n if (section.state === 'empty') {\n return <Typography color=\"textSecondary\">{section.message}</Typography>;\n }\n return <>{children}</>;\n};\n\nconst Definition = ({ label, value }: { label: string; value?: string }) => (\n <Typography paragraph>\n <strong>{label}:</strong> {value || 'Not available'}\n </Typography>\n);\n\nfunction humanize(value: string): string {\n return value.replaceAll('_', ' ');\n}\n\nexport function formatCloudTimestamp(value: string): string {\n const directTimestamp = Date.parse(value);\n if (!Number.isNaN(directTimestamp)) {\n return new Date(directTimestamp).toLocaleString();\n }\n\n const withoutBracketedZone = value.replace(/\\[[^\\]]+\\]$/, '');\n const normalizedTimestamp = Date.parse(withoutBracketedZone);\n return Number.isNaN(normalizedTimestamp)\n ? value\n : new Date(normalizedTimestamp).toLocaleString();\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AA2CO,MAAM,oBAAA,GAAuB,sBAAM,GAAA,CAAC,4BAAA,EAAA,EAA6B;AAEjE,MAAM,0BAAA,GAA6B,sBACxC,GAAA,CAAC,4BAAA,EAAA,EAA6B,YAAU,IAAA,EAAC;AAG3C,MAAM,4BAAA,GAA+B,CAAC,EAAE,UAAA,GAAa,OAAM,KAAM;AAC/D,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAC7B,EAAA,MAAM,GAAA,GAAM,OAAO,cAAc,CAAA;AACjC,EAAA,MAAM,UAAA,GAAa,sBAAsB,MAAM,CAAA;AAC/C,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,QAAA,EAGnC;AACH,EAAA,MAAM,QACJ,WAAA,IAAe,WAAA,CAAY,UAAA,KAAe,UAAA,GACtC,YAAY,KAAA,GACZ,MAAA;AACN,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAA,EAAiB;AAC3C,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,KAAK,CAAA;AAClD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,KAAK,CAAA;AACpD,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAI,QAAA,EAAiB;AAC/D,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,QAAA,CAA+B;AAAA,IACrE,UAAA,EAAY,KAAA;AAAA,IACZ,YAAA,EAAc;AAAA,GACf,CAAA;AACD,EAAA,MAAM,UAAA,GAAa,OAAO,EAAE,QAAA,EAAU,GAAG,OAAA,EAAS,CAAA,EAAG,UAAA,EAAY,CAAA,EAAG,CAAA;AACpE,EAAA,MAAM,QAAA,GAAW,OAAA;AAAA,IACf,MAAO,UAAA,GAAa,iBAAA,CAAkB,MAAM,CAAA,GAAI,MAAA;AAAA,IAChD,CAAC,QAAQ,UAAU;AAAA,GACrB;AAEA,EAAA,eAAA,CAAgB,MAAM;AACpB,IAAA,UAAA,CAAW,QAAQ,QAAA,IAAY,CAAA;AAC/B,IAAA,UAAA,CAAW,QAAQ,OAAA,IAAW,CAAA;AAC9B,IAAA,UAAA,CAAW,QAAQ,UAAA,IAAc,CAAA;AACjC,IAAA,cAAA,CAAe,MAAS,CAAA;AACxB,IAAA,QAAA,CAAS,MAAS,CAAA;AAClB,IAAA,aAAA,CAAc,KAAK,CAAA;AACnB,IAAA,cAAA,CAAe,KAAK,CAAA;AACpB,IAAA,kBAAA,CAAmB,MAAS,CAAA;AAAA,EAC9B,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAA,MAAM,IAAA,GAAO,WAAA;AAAA,IACX,OAAO,UAAU,KAAA,KAAU;AACzB,MAAA,IAAI,CAAC,UAAA,EAAY;AACjB,MAAA,MAAM,QAAA,GAAW,WAAW,OAAA,CAAQ,QAAA;AACpC,MAAA,MAAM,OAAA,GAAU,EAAE,UAAA,CAAW,OAAA,CAAQ,OAAA;AACrC,MAAA,EAAE,WAAW,OAAA,CAAQ,UAAA;AACrB,MAAA,aAAA,CAAc,OAAO,CAAA;AACrB,MAAA,cAAA,CAAe,KAAK,CAAA;AACpB,MAAA,kBAAA,CAAmB,MAAS,CAAA;AAC5B,MAAA,QAAA,CAAS,MAAS,CAAA;AAClB,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,kBAAA,CAAmB,UAAA,EAAY;AAAA,UACpD,KAAA,EAAO,KAAA;AAAA,UACP,IAAA,EAAM,IAAA;AAAA,UACN,GAAI,OAAA,GAAU,EAAE,OAAA,EAAS,IAAA,KAAS;AAAC,SACpC,CAAA;AACD,QAAA,IACE,WAAW,OAAA,CAAQ,QAAA,KAAa,YAChC,UAAA,CAAW,OAAA,CAAQ,YAAY,OAAA,EAC/B;AACA,UAAA,EAAE,WAAW,OAAA,CAAQ,UAAA;AACrB,UAAA,cAAA,CAAe,KAAK,CAAA;AACpB,UAAA,cAAA,CAAe,EAAE,UAAA,EAAY,KAAA,EAAO,IAAA,EAAM,CAAA;AAAA,QAC5C;AAAA,MACF,SAAS,SAAA,EAAW;AAClB,QAAA,IACE,WAAW,OAAA,CAAQ,QAAA,KAAa,YAChC,UAAA,CAAW,OAAA,CAAQ,YAAY,OAAA,EAC/B;AACA,UAAA,EAAE,WAAW,OAAA,CAAQ,UAAA;AACrB,UAAA,cAAA,CAAe,KAAK,CAAA;AACpB,UAAA,QAAA;AAAA,YACE,SAAA,YAAqB,KAAA,GACjB,SAAA,CAAU,OAAA,GACV;AAAA,WACN;AAAA,QACF;AAAA,MACF,CAAA,SAAE;AACA,QAAA,IACE,WAAW,OAAA,CAAQ,QAAA,KAAa,YAChC,UAAA,CAAW,OAAA,CAAQ,YAAY,OAAA,EAC/B;AACA,UAAA,aAAA,CAAc,KAAK,CAAA;AAAA,QACrB;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IACA,CAAC,KAAK,UAAU;AAAA,GAClB;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,KAAK,IAAA,EAAK;AAAA,EACZ,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAY,OAAO,MAAA;AACxB,IAAA,IAAI,MAAA,GAAS,IAAA;AACb,IAAA,GAAA,CACG,YAAA,GACA,IAAA,CAAK,CAAA,IAAA,KAAQ,UAAU,eAAA,CAAgB,IAAI,CAAC,CAAA,CAC5C,KAAA;AAAA,MACC,MACE,UAAU,eAAA,CAAgB,EAAE,YAAY,KAAA,EAAO,YAAA,EAAc,OAAO;AAAA,KACxE;AACF,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,GAAS,KAAA;AAAA,IACX,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,GAAA,EAAK,UAAU,CAAC,CAAA;AAEpB,EAAA,MAAM,QAAA,GAAW,YAAY,YAAY;AACvC,IAAA,MAAM,MAAA,GAAS,KAAA,EAAO,OAAA,CAAQ,IAAA,EAAM,IAAA,CAAK,UAAA;AACzC,IAAA,IAAI,CAAC,UAAA,IAAc,CAAC,MAAA,EAAQ;AAC5B,IAAA,MAAM,QAAA,GAAW,WAAW,OAAA,CAAQ,QAAA;AACpC,IAAA,MAAM,OAAA,GAAU,WAAW,OAAA,CAAQ,OAAA;AACnC,IAAA,MAAM,UAAA,GAAa,EAAE,UAAA,CAAW,OAAA,CAAQ,UAAA;AACxC,IAAA,cAAA,CAAe,IAAI,CAAA;AACnB,IAAA,kBAAA,CAAmB,MAAS,CAAA;AAC5B,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,kBAAA,CAAmB,UAAA,EAAY;AAAA,QACpD,OAAO,KAAA,CAAM,KAAA;AAAA,QACb,IAAA,EAAM,IAAA;AAAA,QACN;AAAA,OACD,CAAA;AACD,MAAA,IACE,UAAA,CAAW,OAAA,CAAQ,QAAA,KAAa,QAAA,IAChC,UAAA,CAAW,OAAA,CAAQ,OAAA,KAAY,OAAA,IAC/B,UAAA,CAAW,OAAA,CAAQ,UAAA,KAAe,UAAA,EAClC;AACA,QAAA;AAAA,MACF;AACA,MAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,KAAA,KAAU,OAAA,EAAS;AAClC,QAAA,kBAAA;AAAA,UACE,IAAA,CAAK,QAAQ,OAAA,IAAW;AAAA,SAC1B;AACA,QAAA;AAAA,MACF;AACA,MAAA,IAAI,KAAK,OAAA,CAAQ,KAAA,KAAU,MAAA,IAAU,IAAA,CAAK,QAAQ,IAAA,EAAM;AACtD,QAAA,kBAAA,CAAmB,KAAA,CAAS,CAAA;AAAA,MAC9B;AACA,MAAA,cAAA,CAAe,CAAA,OAAA,KAAW;AACxB,QAAA,IACE,CAAC,OAAA,IACD,OAAA,CAAQ,UAAA,KAAe,UAAA,IACvB,CAAC,OAAA,CAAQ,KAAA,CAAM,OAAA,CAAQ,IAAA,IACvB,KAAK,OAAA,CAAQ,KAAA,KAAU,UACvB,CAAC,IAAA,CAAK,QAAQ,IAAA,EACd;AACA,UAAA,OAAO,OAAA;AAAA,QACT;AACA,QAAA,OAAO;AAAA,UACL,UAAA;AAAA,UACA,KAAA,EAAO;AAAA,YACL,GAAG,OAAA,CAAQ,KAAA;AAAA,YACX,aAAa,IAAA,CAAK,WAAA;AAAA,YAClB,OAAA,EAAS;AAAA,cACP,KAAA,EAAO,MAAA;AAAA,cACP,IAAA,EAAM,wBAAA;AAAA,gBACJ,OAAA,CAAQ,MAAM,OAAA,CAAQ,IAAA;AAAA,gBACtB,KAAK,OAAA,CAAQ;AAAA;AACf;AACF;AACF,SACF;AAAA,MACF,CAAC,CAAA;AAAA,IACH,SAAS,SAAA,EAAW;AAClB,MAAA,IACE,UAAA,CAAW,OAAA,CAAQ,QAAA,KAAa,QAAA,IAChC,UAAA,CAAW,OAAA,CAAQ,OAAA,KAAY,OAAA,IAC/B,UAAA,CAAW,OAAA,CAAQ,UAAA,KAAe,UAAA,EAClC;AACA,QAAA,kBAAA;AAAA,UACE,SAAA,YAAqB,KAAA,GACjB,SAAA,CAAU,OAAA,GACV;AAAA,SACN;AAAA,MACF;AAAA,IACF,CAAA,SAAE;AACA,MAAA,IACE,UAAA,CAAW,OAAA,CAAQ,QAAA,KAAa,QAAA,IAChC,UAAA,CAAW,OAAA,CAAQ,OAAA,KAAY,OAAA,IAC/B,UAAA,CAAW,OAAA,CAAQ,UAAA,KAAe,UAAA,EAClC;AACA,QAAA,cAAA,CAAe,KAAK,CAAA;AAAA,MACtB;AAAA,IACF;AAAA,EACF,CAAA,EAAG,CAAC,GAAA,EAAK,KAAA,EAAO,UAAU,CAAC,CAAA;AAE3B,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,MAAA,EAAO,QAAA,EAAA,sEAAA,EAEvB,CAAA;AAAA,EAEJ;AACA,EAAA,IAAI,KAAA,IAAS,CAAC,KAAA,EAAO;AACnB,IAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,OAAA,EACb,QAAA,EAAA;AAAA,MAAA,KAAA;AAAA,MAAM,GAAA;AAAA,sBAAC,GAAA,CAAC,UAAO,OAAA,EAAS,MAAM,KAAK,IAAA,CAAK,IAAI,GAAG,QAAA,EAAA,OAAA,EAAK;AAAA,KAAA,EACvD,CAAA;AAAA,EAEJ;AACA,EAAA,IAAI,CAAC,KAAA,EAAO,uBAAO,GAAA,CAAC,QAAA,EAAA,EAAS,CAAA;AAE7B,EAAA,uBACE,GAAA;AAAA,IAAC,sBAAA;AAAA,IAAA;AAAA,MACC,MAAA;AAAA,MACA,KAAA;AAAA,MACA,UAAA;AAAA,MACA,SAAA,EAAW,MAAM,KAAK,IAAA,CAAK,IAAI,CAAA;AAAA,MAC/B,WAAA;AAAA,MACA,UAAA,EAAY,MAAM,KAAK,QAAA,EAAS;AAAA,MAChC,KAAA;AAAA,MACA,eAAA;AAAA,MACA,UAAA,EAAY,UAAA,IAAc,YAAA,CAAa,UAAA,IAAc,QAAQ,QAAQ,CAAA;AAAA,MACrE;AAAA;AAAA,GACF;AAEJ,CAAA;AAEO,SAAS,wBAAA,CACd,SACA,IAAA,EACqB;AACrB,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,YAAA,EAAc,2BAAA;AAAA,MACZ,OAAA,CAAQ,YAAA;AAAA,MACR,IAAA,CAAK;AAAA,KACP;AAAA,IACA,QAAA,EAAU,CAAC,mBAAG,IAAI,GAAA,CAAI,CAAC,GAAG,OAAA,CAAQ,QAAA,EAAU,GAAG,IAAA,CAAK,QAAQ,CAAC,CAAC,CAAA;AAAA,IAC9D,OAAO,CAAC,GAAG,QAAQ,KAAA,EAAO,GAAG,KAAK,KAAK;AAAA,GACzC;AACF;AAEA,SAAS,2BAAA,CACP,SACA,IAAA,EACwB;AACxB,EAAA,MAAM,eAAuC,EAAC;AAC9C,EAAA,KAAA,MAAW,KAAA,wBAAa,GAAA,CAAI;AAAA,IAC1B,GAAG,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AAAA,IACtB,GAAG,MAAA,CAAO,IAAA,CAAK,IAAI;AAAA,GACpB,CAAA,EAAG;AACF,IAAA,YAAA,CAAa,KAAK,CAAA,GAAI,yBAAA;AAAA,MACpB,QAAQ,KAAK,CAAA;AAAA,MACb,KAAK,KAAK;AAAA,KACZ;AAAA,EACF;AACA,EAAA,OAAO,YAAA;AACT;AAEA,SAAS,yBAAA,CACP,SACA,IAAA,EACQ;AACR,EAAA,MAAM,iBAAA,GAAoB,sBAAsB,OAAO,CAAA;AACvD,EAAA,MAAM,cAAA,GAAiB,sBAAsB,IAAI,CAAA;AACjD,EAAA,OAAO,kBAAkB,iBAAiB,CAAA,IACxC,iBAAA,CAAkB,cAAc,IAC9B,iBAAA,GACA,cAAA;AACN;AAEA,MAAM,iBAAA,GAA4C;AAAA,EAChD,WAAA,EAAa,CAAA;AAAA,EACb,OAAA,EAAS,CAAA;AAAA,EACT,SAAA,EAAW;AACb,CAAA;AAEA,SAAS,sBAAsB,KAAA,EAAmC;AAChE,EAAA,OAAO,KAAA,IAAS,KAAA,IAAS,iBAAA,GAAoB,KAAA,GAAQ,aAAA;AACvD;AAEO,MAAM,yBAAyB,CAAC;AAAA,EACrC,MAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,KAAA;AAAA,EACA,eAAA;AAAA,EACA,UAAA,GAAa,KAAA;AAAA,EACb;AACF,CAAA,KAWM;AACJ,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AACpD,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,KAAA,EAAO,IAAA;AAAA,IAAK,CAAA,IAAA,KAC9C,IAAA,CAAK,GAAA,CAAI,UAAA,CAAW,iCAAiC;AAAA,GACvD;AAEA,EAAA,uBACE,IAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAS,IAAA,EAAC,SAAS,CAAA,EACtB,QAAA,EAAA;AAAA,IAAA,KAAA,oBACC,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EACb,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,OAAA,EAAS,QAAA,EAAA,KAAA,EAAM,CAAA,EACjC,CAAA;AAAA,oBAEF,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,IAAI,EAAA,EACb,QAAA,kBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,gBAAA;AAAA,QACN,MAAA,kBACE,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,OAAA;AAAA,YACL,OAAA,EAAS,SAAA;AAAA,YACT,WACE,UAAA,mBAAa,GAAA,CAAC,gBAAA,EAAA,EAAiB,IAAA,EAAM,IAAI,CAAA,GAAK,MAAA;AAAA,YAEjD,QAAA,EAAA;AAAA;AAAA,SAED;AAAA,QAGF,QAAA,kBAAA,IAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EAAgB,QAAA,EAAA;AAAA,UAAA,iDAAA;AAAA,UACa,GAAA;AAAA,UAC5C,oBAAA,CAAqB,MAAM,WAAW,CAAA;AAAA,UAAE,eAAA;AAAA,UAAW,KAAA,CAAM;AAAA,SAAA,EAC5D;AAAA;AAAA,KACF,EACF,CAAA;AAAA,oBAEA,GAAA,CAAC,QAAK,IAAA,EAAI,IAAA,EAAC,IAAI,EAAA,EACb,QAAA,kBAAA,IAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,gBAAA,EACd,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,UAAA;AAAA,UACN,KAAA,EAAO,YAAY,kCAAkC;AAAA;AAAA,OACvD;AAAA,sBACA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,eAAA;AAAA,UACN,KAAA,EACE,YAAY,iCAAiC,CAAA,IAC7C,OAAO,MAAA,CAAO,IAAA,EAAM,QAAQ,EAAE;AAAA;AAAA,OAElC;AAAA,sBACA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,QAAA;AAAA,UACN,KAAA,EAAO,WAAA,CAAY,gCAAgC,CAAA,IAAK;AAAA;AAAA,OAC1D;AAAA,sBACA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,SAAA;AAAA,UACN,KAAA,EAAO,YAAY,iCAAiC;AAAA;AAAA,OACtD;AAAA,0BACC,UAAA,EAAA,EAAW,KAAA,EAAM,oBAAA,EAAqB,KAAA,EAAO,MAAM,UAAA,EAAY,CAAA;AAAA,MAC/D,+BAAe,GAAA,CAAC,IAAA,EAAA,EAAK,EAAA,EAAI,WAAA,CAAY,KAAK,QAAA,EAAA,qBAAA,EAAmB;AAAA,KAAA,EAChE,CAAA,EACF,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,wBAAA,EAAA,EAAyB,MAAA,EAAgB,CAAA,EAC5C,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,sBAAA,EAAA,EAAuB,MAAA,EAAgB,CAAA,EAC1C,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EACb,QAAA,kBAAA,GAAA,CAAC,kBAAA,EAAA,EAAmB,OAAA,EAAS,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,WAAW,CAAA,EACjE,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,IAAI,EAAA,EACb,QAAA,kBAAA,GAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACC,SAAS,KAAA,CAAM,OAAA;AAAA,QACf,WAAA;AAAA,QACA,UAAA;AAAA,QACA;AAAA;AAAA,KACF,EACF,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,iBAAA,EAAA,EAAkB,OAAA,EAAS,KAAA,CAAM,YAAY,CAAA,EAChD,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,YAAA,EAAA,EAAa,OAAA,EAAS,KAAA,CAAM,OAAO,CAAA,EACtC,CAAA;AAAA,IACC,UAAA,oBACC,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EACb,QAAA,kBAAA,GAAA,CAAC,eAAA,EAAA,EAAgB,OAAA,EAAQ,QAAA,EAAS,KAAA,EAAO,UAAU,CAAA,EACrD;AAAA,GAAA,EAEJ,CAAA;AAEJ;AAEA,MAAM,iBAAiB,CAAC;AAAA,EACtB,OAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAA,KAKM;AACJ,EAAA,MAAM,EAAE,sBAAA,EAAwB,kBAAA,EAAmB,GACjD,2BAAA;AAAA,IACE,QAAQ,IAAA,EAAM,QAAA;AAAA,IACd,OAAA,CAAQ,IAAA,EAAM,KAAA,CAAM,MAAA,IAAU;AAAA,GAChC;AAEF,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,sBAAA,EACd,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA,OAAA,CAAQ,OAAA,IAAW,6CAAA,EACtB,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,2BACG,QAAA,EAAA,EAAS,KAAA,EAAM,sBAAA,EACd,QAAA,kBAAA,IAAA,CAAC,gBAAa,OAAA,EACX,QAAA,EAAA;AAAA,IAAA,eAAA,oBACC,GAAA,CAAC,SAAM,QAAA,EAAS,OAAA,EAAQ,OAAO,EAAE,YAAA,EAAc,CAAA,EAAE,EAC9C,QAAA,EAAA,eAAA,EACH,CAAA;AAAA,IAED,sBAAA,oBACC,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,YAAA,EAAW,kCAAA;AAAA,QACX,OAAA,EAAQ,SAAA;AAAA,QACR,KAAA,EAAM,eAAA;AAAA,QACN,OAAA,EAAQ,OAAA;AAAA,QACR,KAAA,EAAO,EAAE,YAAA,EAAc,CAAA,EAAE;AAAA,QAC1B,QAAA,EAAA;AAAA;AAAA,KAGD;AAAA,IAED,mBAAmB,GAAA,CAAI,CAAA,OAAA,qBACtB,GAAA,CAAC,KAAA,EAAA,EAAM,UAAS,SAAA,EAAwB,KAAA,EAAO,EAAE,YAAA,EAAc,GAAE,EAC9D,QAAA,EAAA,QAAA,CAAS,OAAO,CAAA,EAAA,EADY,OAE/B,CACD,CAAA;AAAA,IACA,OAAA,CAAQ,IAAA,EAAM,KAAA,EAAO,MAAA,GACpB,QAAQ,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,CAAA,KAAA,0BACpB,KAAA,EAAA,EAAmB,KAAA,EAAO,EAAE,YAAA,EAAc,IAAG,EAC5C,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,SAAQ,WAAA,EACjB,QAAA,EAAA,KAAA,CAAM,WAAW,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA,EACvC,CAAA;AAAA,sBACA,IAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA;AAAA,QAAA,oBAAA,CAAqB,MAAM,SAAS,CAAA;AAAA,QAAE,QAAA;AAAA,QAAI,KAAA,CAAM,QAAA;AAAA,QAAS,OAAA;AAAA,QAAG,GAAA;AAAA,QAC5D,MAAM,QAAA,CAAS,MAAA;AAAA,QAAO,QAAA;AAAA,QAAI,MAAM,QAAA,CAAS,MAAA;AAAA,QACzC,KAAA,CAAM,KAAA,EAAO,IAAA,IAAQ,KAAA,CAAM,KAAA,EAAO,EAAA,GAC/B,CAAA,MAAA,EAAM,KAAA,CAAM,KAAA,CAAM,IAAA,IAAQ,KAAA,CAAM,KAAA,CAAM,EAAE,CAAA,CAAA,GACxC;AAAA,OAAA,EACN,CAAA;AAAA,MACC,MAAM,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAA,yBAC3B,SAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,aAAQ,QAAA,EAAA,8BAAA,EAA4B,CAAA;AAAA,4BACpC,IAAA,EAAA,EACE,QAAA,EAAA,KAAA,CAAM,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,KAAA,KAAS;AAChC,UAAA,MAAM,MAAA,GAAS,KAAA,CAAM,MAAA,CAAO,OAAA,CAAQ,IAAA;AAAA,YAClC,CAAA,SAAA,KAAa,UAAU,KAAA,KAAU;AAAA,WACnC;AACA,UAAA,4BACG,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,UAAM,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,YACZ,MAAA,GACG,KAAK,MAAA,CAAO,MAAA,IAAU,QAAG,CAAA,QAAA,EACvB,MAAA,CAAO,KAAA,IAAS,QAClB,CAAA,CAAA,GACA;AAAA,WAAA,EAAA,EANG,KAOT,CAAA;AAAA,QAEJ,CAAC,CAAA,EACH;AAAA,OAAA,EACF;AAAA,KAAA,EAAA,EA/BM,KAAA,CAAM,EAiChB,CACD,CAAA,uBAEA,UAAA,EAAA,EAAW,KAAA,EAAM,iBAAgB,QAAA,EAAA,6CAAA,EAElC,CAAA;AAAA,IAED,OAAA,CAAQ,IAAA,EAAM,IAAA,CAAK,OAAA,IAAW,UAAA,oBAC7B,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,OAAA;AAAA,QACL,OAAA,EAAS,UAAA;AAAA,QACT,QAAA,EAAU,WAAA;AAAA,QACV,WAAW,WAAA,mBAAc,GAAA,CAAC,gBAAA,EAAA,EAAiB,IAAA,EAAM,IAAI,CAAA,GAAK,MAAA;AAAA,QAC3D,QAAA,EAAA;AAAA;AAAA;AAED,GAAA,EAEJ,CAAA,EACF,CAAA;AAEJ,CAAA;AAEA,MAAM,0BAAA,uBAAiC,GAAA,CAAI;AAAA,EACzC,sBAAA;AAAA,EACA;AACF,CAAC,CAAA;AACD,MAAM,8BAAA,uBAAqC,GAAA,CAAI;AAAA,EAC7C,4BAAA;AAAA,EACA;AACF,CAAC,CAAA;AAED,SAAS,2BAAA,CACP,UACA,UAAA,EACA;AACA,EAAA,MAAM,WAAA,GAAc,YAAY,EAAC;AACjC,EAAA,OAAO;AAAA,IACL,wBAAwB,WAAA,CAAY,IAAA;AAAA,MAAK,CAAA,OAAA,KACvC,0BAAA,CAA2B,GAAA,CAAI,OAAO;AAAA,KACxC;AAAA,IACA,oBAAoB,WAAA,CAAY,MAAA;AAAA,MAC9B,CAAA,OAAA,KACE,CAAC,0BAAA,CAA2B,GAAA,CAAI,OAAO,CAAA,KACtC,UAAA,GAAa,CAAA,IAAK,CAAC,8BAAA,CAA+B,GAAA,CAAI,OAAO,CAAA;AAAA;AAClE,GACF;AACF;AAEA,MAAM,oBAAoB,CAAC;AAAA,EACzB;AACF,CAAA,KAEM;AACJ,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,gBAAA,EACd,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA,OAAA,CAAQ,OAAA,IACP,qDAAA,EACJ,CAAA,EACF,CAAA;AAAA,EAEJ;AACA,EAAA,uBACE,GAAA,CAAC,YAAS,KAAA,EAAM,gBAAA,EACd,8BAAC,YAAA,EAAA,EAAa,OAAA,EACX,QAAA,EAAA,OAAA,CAAQ,IAAA,EAAM,SAAA,EAAW,MAAA,GACxB,QAAQ,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,QAAA,qBACzB,IAAA,CAAC,SAAsC,KAAA,EAAO,EAAE,YAAA,EAAc,EAAA,EAAG,EAC/D,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,WAAA,EACjB,QAAA,EAAA,QAAA,CAAS,UAAU,OAAA,EACtB,CAAA;AAAA,oBACA,GAAA,CAAC,QAAK,IAAA,EAAK,OAAA,EAAQ,OAAO,QAAA,CAAS,QAAA,CAAS,MAAM,CAAA,EAAG,CAAA;AAAA,oBACrD,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,MAAA;AAAA,QACN,KAAA,EAAO,QAAA,CAAS,SAAA,CAAU,OAAA,IAAW;AAAA;AAAA,KACvC;AAAA,oBACA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,aAAA;AAAA,QACN,KAAA,EAAO,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,MAAM;AAAA;AAAA,KACtC;AAAA,oBACA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,aAAA;AAAA,QACN,KAAA,EAAO,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,MAAM;AAAA;AAAA,KACtC;AAAA,IACC,QAAA,CAAS,UAAU,SAAA,oBAClB,GAAA,CAAC,QAAK,EAAA,EAAI,QAAA,CAAS,SAAA,CAAU,SAAA,EAAW,QAAA,EAAA,aAAA,EAAW;AAAA,GAAA,EAAA,EAlB7C,QAAA,CAAS,SAAA,CAAU,QAoB7B,CACD,CAAA,mBAED,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EAAgB,QAAA,EAAA,qDAAA,EAElC,CAAA,EAEJ,CAAA,EACF,CAAA;AAEJ,CAAA;AAEA,MAAM,eAAe,CAAC;AAAA,EACpB;AACF,CAAA,KAEM;AACJ,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,oBAAA,EACd,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA,OAAA,CAAQ,OAAA,IAAW,gDAAA,EACtB,CAAA,EACF,CAAA;AAAA,EAEJ;AACA,EAAA,uBACE,GAAA,CAAC,YAAS,KAAA,EAAM,oBAAA,EACd,8BAAC,YAAA,EAAA,EAAa,OAAA,EACX,QAAA,EAAA,OAAA,CAAQ,IAAA,EAAM,KAAA,EAAO,MAAA,GACpB,QAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,IAAA,qBACrB,IAAA,CAAC,SAAkC,KAAA,EAAO,EAAE,YAAA,EAAc,EAAA,EAAG,EAC3D,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,WAAA,EACjB,QAAA,EAAA,IAAA,CAAK,UAAU,OAAA,EAClB,CAAA;AAAA,oBACA,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,OAAA;AAAA,QACL,KAAA,EAAO,IAAA,CAAK,MAAA,KAAW,SAAA,GAAY,WAAA,GAAc,SAAA;AAAA,QACjD,KAAA,EAAO,QAAA,CAAS,IAAA,CAAK,MAAM;AAAA;AAAA,KAC7B;AAAA,wBACC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA,IAAA,CAAK,WAAW,SAAA,GACb,CAAA,sBAAA,EAAyB,QAAA,CAAS,IAAA,CAAK,MAAM,CAAC,CAAA,CAAA,CAAA,GAC9C,CAAA,EAAG,IAAA,CAAK,cAAc,CAAA,2BAAA,CAAA,EAC5B,CAAA;AAAA,IACC,IAAA,CAAK,WAAA,CAAY,MAAA,GAAS,CAAA,yBACxB,SAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,aAAQ,QAAA,EAAA,4BAAA,EAA0B,CAAA;AAAA,0BAClC,IAAA,EAAA,EACE,QAAA,EAAA,IAAA,CAAK,YAAY,GAAA,CAAI,CAAA,UAAA,0BACnB,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,MAAA,EAAA,EAAM,qBAAW,KAAA,EAAM,CAAA;AAAA,QAAO,GAAA;AAAA,QAAE,GAAA;AAAA,QAChC,WAAW,WAAA,IAAe,QAAA;AAAA,QAAI,SAAA;AAAA,QAAG,GAAA;AAAA,QACjC,WAAW,QAAA,IAAY;AAAA,OAAA,EAAA,EAHjB,UAAA,CAAW,KAIpB,CACD,CAAA,EACH;AAAA,KAAA,EACF;AAAA,GAAA,EAAA,EA1BM,IAAA,CAAK,SAAA,CAAU,QA4BzB,CACD,CAAA,mBAED,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EAAgB,QAAA,EAAA,gDAAA,EAElC,CAAA,EAEJ,CAAA,EACF,CAAA;AAEJ,CAAA;AAEA,MAAM,eAAe,CAAC;AAAA,EACpB,OAAA;AAAA,EACA;AACF,CAAA,KAGM;AACJ,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,OAAA,EAAS,kBAAQ,OAAA,EAAQ,CAAA;AAAA,EAClD;AACA,EAAA,IAAI,OAAA,CAAQ,UAAU,aAAA,EAAe;AACnC,IAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,MAAA,EAAQ,kBAAQ,OAAA,EAAQ,CAAA;AAAA,EACjD;AACA,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBAAO,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EAAiB,kBAAQ,OAAA,EAAQ,CAAA;AAAA,EAC5D;AACA,EAAA,uCAAU,QAAA,EAAS,CAAA;AACrB,CAAA;AAEA,MAAM,UAAA,GAAa,CAAC,EAAE,KAAA,EAAO,OAAM,qBACjC,IAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAS,IAAA,EACnB,QAAA,EAAA;AAAA,kBAAA,IAAA,CAAC,QAAA,EAAA,EAAQ,QAAA,EAAA;AAAA,IAAA,KAAA;AAAA,IAAM;AAAA,GAAA,EAAC,CAAA;AAAA,EAAS,GAAA;AAAA,EAAE,KAAA,IAAS;AAAA,CAAA,EACtC,CAAA;AAGF,SAAS,SAAS,KAAA,EAAuB;AACvC,EAAA,OAAO,KAAA,CAAM,UAAA,CAAW,GAAA,EAAK,GAAG,CAAA;AAClC;AAEO,SAAS,qBAAqB,KAAA,EAAuB;AAC1D,EAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AACxC,EAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,eAAe,CAAA,EAAG;AAClC,IAAA,OAAO,IAAI,IAAA,CAAK,eAAe,CAAA,CAAE,cAAA,EAAe;AAAA,EAClD;AAEA,EAAA,MAAM,oBAAA,GAAuB,KAAA,CAAM,OAAA,CAAQ,aAAA,EAAe,EAAE,CAAA;AAC5D,EAAA,MAAM,mBAAA,GAAsB,IAAA,CAAK,KAAA,CAAM,oBAAoB,CAAA;AAC3D,EAAA,OAAO,MAAA,CAAO,MAAM,mBAAmB,CAAA,GACnC,QACA,IAAI,IAAA,CAAK,mBAAmB,CAAA,CAAE,cAAA,EAAe;AACnD;;;;"}
|
|
1
|
+
{"version":3,"file":"CloudResourceContent.esm.js","sources":["../../../src/components/cloud/CloudResourceContent.tsx"],"sourcesContent":["import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport {\n Button,\n Chip,\n CircularProgress,\n Grid,\n Typography,\n} from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport { InfoCard, Link, Progress } from '@backstage/core-components';\nimport { useApi } from '@backstage/frontend-plugin-api';\nimport type { Entity } from '@backstage/catalog-model';\nimport {\n ANYSHIFT_CLOUD_ACCOUNT_ANNOTATION,\n ANYSHIFT_CLOUD_PROVIDER_ANNOTATION,\n ANYSHIFT_CLOUD_REGION_ANNOTATION,\n ANYSHIFT_RESOURCE_TYPE_ANNOTATION,\n type BriefSection,\n type CloudEventsEvidence,\n type CloudResourceBrief,\n type IacDriftEvidence,\n type IacEvidence,\n} from '@anyshift/backstage-plugin-anyshift-common';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { anyshiftApiRef } from '../../api/AnyshiftApi';\nimport { AskAnyshiftCard } from '../ask/AskAnyshiftCard';\nimport { askScopeForEntity } from '../ask/askScope';\nimport type { AnyshiftCapabilities, AskScope } from '../../api/types';\nimport {\n cloudResourceFallbackIdentity,\n cloudResourceIdentity,\n} from '../entity/entityIdentity';\nimport { CloudImpactSection } from './CloudImpactSection';\nimport {\n CloudDependenciesSection,\n CloudDependentsSection,\n} from './CloudRelationshipSections';\n\nexport const CloudResourceContent = () => <CloudResourceEvidenceContent />;\n\nexport const CloudAnyshiftEntityContent = () => (\n <CloudResourceEvidenceContent includeAsk />\n);\n\nconst CloudResourceEvidenceContent = ({ includeAsk = false }) => {\n const { entity } = useEntity();\n const api = useApi(anyshiftApiRef);\n const resourceId = cloudResourceIdentity(entity);\n const fallbackResource = cloudResourceFallbackIdentity(entity);\n const [loadedBrief, setLoadedBrief] = useState<{\n resourceId: string;\n value: CloudResourceBrief;\n }>();\n const brief =\n loadedBrief && loadedBrief.resourceId === resourceId\n ? loadedBrief.value\n : undefined;\n const [error, setError] = useState<string>();\n const [refreshing, setRefreshing] = useState(false);\n const [loadingMore, setLoadingMore] = useState(false);\n const [paginationError, setPaginationError] = useState<string>();\n const [capabilities, setCapabilities] = useState<AnyshiftCapabilities>({\n askEnabled: false,\n queryEnabled: false,\n });\n const operations = useRef({ identity: 0, primary: 0, pagination: 0 });\n const askScope = useMemo(\n () => (includeAsk ? askScopeForEntity(entity) : undefined),\n [entity, includeAsk],\n );\n\n useLayoutEffect(() => {\n operations.current.identity += 1;\n operations.current.primary += 1;\n operations.current.pagination += 1;\n setLoadedBrief(undefined);\n setError(undefined);\n setRefreshing(false);\n setLoadingMore(false);\n setPaginationError(undefined);\n }, [resourceId]);\n\n const load = useCallback(\n async (refresh = false) => {\n if (!resourceId) return;\n const identity = operations.current.identity;\n const primary = ++operations.current.primary;\n ++operations.current.pagination;\n setRefreshing(refresh);\n setLoadingMore(false);\n setPaginationError(undefined);\n setError(undefined);\n try {\n const next = await api.cloudResourceBrief(resourceId, {\n ...(fallbackResource ? { fallbackResource } : {}),\n since: '24h',\n diff: true,\n ...(refresh ? { refresh: true } : {}),\n });\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary\n ) {\n ++operations.current.pagination;\n setLoadingMore(false);\n setLoadedBrief({ resourceId, value: next });\n }\n } catch (loadError) {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary\n ) {\n ++operations.current.pagination;\n setLoadingMore(false);\n setError(\n loadError instanceof Error\n ? loadError.message\n : 'Unable to load cloud evidence',\n );\n }\n } finally {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary\n ) {\n setRefreshing(false);\n }\n }\n },\n [api, fallbackResource, resourceId],\n );\n\n useEffect(() => {\n void load();\n }, [load]);\n\n useEffect(() => {\n if (!includeAsk) return undefined;\n let active = true;\n api\n .capabilities()\n .then(next => active && setCapabilities(next))\n .catch(\n () =>\n active && setCapabilities({ askEnabled: false, queryEnabled: false }),\n );\n return () => {\n active = false;\n };\n }, [api, includeAsk]);\n\n const loadMore = useCallback(async () => {\n const cursor = brief?.changes.data?.page.nextCursor;\n if (!resourceId || !cursor) return;\n const identity = operations.current.identity;\n const primary = operations.current.primary;\n const pagination = ++operations.current.pagination;\n setLoadingMore(true);\n setPaginationError(undefined);\n try {\n const next = await api.cloudResourceBrief(resourceId, {\n ...(fallbackResource ? { fallbackResource } : {}),\n since: brief.since,\n diff: true,\n cursor,\n });\n if (\n operations.current.identity !== identity ||\n operations.current.primary !== primary ||\n operations.current.pagination !== pagination\n ) {\n return;\n }\n if (next.changes.state === 'error') {\n setPaginationError(\n next.changes.message || 'Unable to load more cloud changes',\n );\n return;\n }\n if (next.changes.state === 'data' && next.changes.data) {\n setPaginationError(undefined);\n }\n setLoadedBrief(current => {\n if (\n !current ||\n current.resourceId !== resourceId ||\n !current.value.changes.data ||\n next.changes.state !== 'data' ||\n !next.changes.data\n ) {\n return current;\n }\n return {\n resourceId,\n value: {\n ...current.value,\n refreshedAt: next.refreshedAt,\n changes: {\n state: 'data',\n data: mergeCloudEventsEvidence(\n current.value.changes.data,\n next.changes.data,\n ),\n },\n },\n };\n });\n } catch (loadError) {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary &&\n operations.current.pagination === pagination\n ) {\n setPaginationError(\n loadError instanceof Error\n ? loadError.message\n : 'Unable to load more cloud changes',\n );\n }\n } finally {\n if (\n operations.current.identity === identity &&\n operations.current.primary === primary &&\n operations.current.pagination === pagination\n ) {\n setLoadingMore(false);\n }\n }\n }, [api, brief, fallbackResource, resourceId]);\n\n if (!resourceId) {\n return (\n <Alert severity=\"info\">\n This catalog entity has no stable Anyshift resource ID or cloud ARN.\n </Alert>\n );\n }\n if (error && !brief) {\n return (\n <Alert severity=\"error\">\n {error} <Button onClick={() => void load(true)}>Retry</Button>\n </Alert>\n );\n }\n if (!brief) return <Progress />;\n\n return (\n <CloudResourceBriefView\n entity={entity}\n brief={brief}\n refreshing={refreshing}\n onRefresh={() => void load(true)}\n loadingMore={loadingMore}\n onLoadMore={() => void loadMore()}\n error={error}\n paginationError={paginationError}\n askEnabled={includeAsk && capabilities.askEnabled && Boolean(askScope)}\n askScope={askScope}\n />\n );\n};\n\nexport function mergeCloudEventsEvidence(\n current: CloudEventsEvidence,\n next: CloudEventsEvidence,\n): CloudEventsEvidence {\n return {\n ...next,\n availability: mergeCloudEventAvailability(\n current.availability,\n next.availability,\n ),\n warnings: [...new Set([...current.warnings, ...next.warnings])],\n items: [...current.items, ...next.items],\n };\n}\n\nfunction mergeCloudEventAvailability(\n current: Record<string, string>,\n next: Record<string, string>,\n): Record<string, string> {\n const availability: Record<string, string> = {};\n for (const field of new Set([\n ...Object.keys(current),\n ...Object.keys(next),\n ])) {\n availability[field] = leastCompleteAvailability(\n current[field],\n next[field],\n );\n }\n return availability;\n}\n\nfunction leastCompleteAvailability(\n current: string | undefined,\n next: string | undefined,\n): string {\n const normalizedCurrent = normalizeAvailability(current);\n const normalizedNext = normalizeAvailability(next);\n return AVAILABILITY_RANK[normalizedCurrent] <=\n AVAILABILITY_RANK[normalizedNext]\n ? normalizedCurrent\n : normalizedNext;\n}\n\nconst AVAILABILITY_RANK: Record<string, number> = {\n unavailable: 0,\n partial: 1,\n available: 2,\n};\n\nfunction normalizeAvailability(value: string | undefined): string {\n return value && value in AVAILABILITY_RANK ? value : 'unavailable';\n}\n\nexport const CloudResourceBriefView = ({\n entity,\n brief,\n refreshing,\n onRefresh,\n loadingMore,\n onLoadMore,\n error,\n paginationError,\n askEnabled = false,\n askScope,\n}: {\n entity: Entity;\n brief: CloudResourceBrief;\n refreshing?: boolean;\n onRefresh: () => void;\n loadingMore?: boolean;\n onLoadMore?: () => void;\n error?: string;\n paginationError?: string;\n askEnabled?: boolean;\n askScope?: AskScope;\n}) => {\n const annotations = entity.metadata.annotations ?? {};\n const consoleLink = entity.metadata.links?.find(link =>\n link.url.startsWith('https://console.aws.amazon.com/'),\n );\n\n return (\n <Grid container spacing={3}>\n {error && (\n <Grid item xs={12}>\n <Alert severity=\"error\">{error}</Alert>\n </Grid>\n )}\n <Grid item xs={12}>\n <InfoCard\n title=\"Cloud evidence\"\n action={\n <Button\n size=\"small\"\n onClick={onRefresh}\n startIcon={\n refreshing ? <CircularProgress size={14} /> : undefined\n }\n >\n Refresh\n </Button>\n }\n >\n <Typography color=\"textSecondary\">\n Read-only Anyshift evidence · last refreshed{' '}\n {formatCloudTimestamp(brief.refreshedAt)} · window {brief.since}\n </Typography>\n </InfoCard>\n </Grid>\n\n <Grid item xs={12}>\n <InfoCard title=\"Cloud identity\">\n <Definition\n label=\"Provider\"\n value={annotations[ANYSHIFT_CLOUD_PROVIDER_ANNOTATION]}\n />\n <Definition\n label=\"Resource type\"\n value={\n annotations[ANYSHIFT_RESOURCE_TYPE_ANNOTATION] ||\n String(entity.spec?.type || '')\n }\n />\n <Definition\n label=\"Region\"\n value={annotations[ANYSHIFT_CLOUD_REGION_ANNOTATION] || 'Global'}\n />\n <Definition\n label=\"Account\"\n value={annotations[ANYSHIFT_CLOUD_ACCOUNT_ANNOTATION]}\n />\n <Definition label=\"Stable resource ID\" value={brief.resourceId} />\n {consoleLink && <Link to={consoleLink.url}>Open in AWS Console</Link>}\n </InfoCard>\n </Grid>\n <Grid item xs={12} md={6}>\n <CloudDependenciesSection entity={entity} />\n </Grid>\n <Grid item xs={12} md={6}>\n <CloudDependentsSection entity={entity} />\n </Grid>\n <Grid item xs={12}>\n <CloudImpactSection section={brief.impact} onRetry={onRefresh} />\n </Grid>\n <Grid item xs={12}>\n <ChangesSection\n section={brief.changes}\n loadingMore={loadingMore}\n onLoadMore={onLoadMore}\n paginationError={paginationError}\n />\n </Grid>\n <Grid item xs={12} md={6}>\n <ProvenanceSection section={brief.provenance} />\n </Grid>\n <Grid item xs={12} md={6}>\n <DriftSection section={brief.drift} />\n </Grid>\n {askEnabled && (\n <Grid item xs={12}>\n <AskAnyshiftCard context=\"entity\" scope={askScope} />\n </Grid>\n )}\n </Grid>\n );\n};\n\nconst ChangesSection = ({\n section,\n loadingMore,\n onLoadMore,\n paginationError,\n}: {\n section: BriefSection<CloudEventsEvidence>;\n loadingMore?: boolean;\n onLoadMore?: () => void;\n paginationError?: string;\n}) => {\n const { hasEvidenceLimitations, actionableWarnings } =\n partitionCloudEventWarnings(\n section.data?.warnings,\n section.data?.items.length ?? 0,\n );\n\n if (section.state === 'empty') {\n return (\n <InfoCard title=\"Recent cloud changes\">\n <Typography color=\"textSecondary\">\n {section.message || 'No cloud changes were found in this window.'}\n </Typography>\n </InfoCard>\n );\n }\n\n return (\n <InfoCard title=\"Recent cloud changes\">\n <SectionState section={section}>\n {paginationError && (\n <Alert severity=\"error\" style={{ marginBottom: 8 }}>\n {paginationError}\n </Alert>\n )}\n {hasEvidenceLimitations && (\n <Typography\n aria-label=\"Cloud event evidence limitations\"\n variant=\"caption\"\n color=\"textSecondary\"\n display=\"block\"\n style={{ marginBottom: 8 }}\n >\n Event source is derived from graph relationships, and event status\n may be incomplete.\n </Typography>\n )}\n {actionableWarnings.map(warning => (\n <Alert severity=\"warning\" key={warning} style={{ marginBottom: 8 }}>\n {humanize(warning)}\n </Alert>\n ))}\n {section.data?.items?.length ? (\n section.data.items.map(event => (\n <div key={event.id} style={{ marginBottom: 20 }}>\n <Typography variant=\"subtitle1\">\n {event.summary || humanize(event.type)}\n </Typography>\n <Typography color=\"textSecondary\">\n {formatCloudTimestamp(event.timestamp)} · {event.category} ·{' '}\n {event.evidence.source} · {event.evidence.status}\n {event.actor?.name || event.actor?.id\n ? ` · ${event.actor.name || event.actor.id}`\n : ''}\n </Typography>\n {event.change.fields.length > 0 && (\n <details>\n <summary>View sanitized field changes</summary>\n <ul>\n {event.change.fields.map(field => {\n const detail = event.change.details.find(\n candidate => candidate.field === field,\n );\n return (\n <li key={field}>\n <code>{field}</code>\n {detail\n ? `: ${detail.before ?? '∅'} → ${\n detail.after ?? '∅'\n }`\n : ''}\n </li>\n );\n })}\n </ul>\n </details>\n )}\n </div>\n ))\n ) : (\n <Typography color=\"textSecondary\">\n No cloud changes were found in this window.\n </Typography>\n )}\n {section.data?.page.hasMore && onLoadMore && (\n <Button\n size=\"small\"\n onClick={onLoadMore}\n disabled={loadingMore}\n startIcon={loadingMore ? <CircularProgress size={14} /> : undefined}\n >\n Load more changes\n </Button>\n )}\n </SectionState>\n </InfoCard>\n );\n};\n\nconst QUIET_EVIDENCE_LIMITATIONS = new Set([\n 'event_source_derived',\n 'event_status_incomplete',\n]);\nconst IDENTITY_COMPLETENESS_WARNINGS = new Set([\n 'target_identity_incomplete',\n 'actor_identity_incomplete',\n]);\n\nfunction partitionCloudEventWarnings(\n warnings: string[] | undefined,\n eventCount: number,\n) {\n const allWarnings = warnings ?? [];\n return {\n hasEvidenceLimitations: allWarnings.some(warning =>\n QUIET_EVIDENCE_LIMITATIONS.has(warning),\n ),\n actionableWarnings: allWarnings.filter(\n warning =>\n !QUIET_EVIDENCE_LIMITATIONS.has(warning) &&\n (eventCount > 0 || !IDENTITY_COMPLETENESS_WARNINGS.has(warning)),\n ),\n };\n}\n\nconst ProvenanceSection = ({\n section,\n}: {\n section: BriefSection<IacEvidence>;\n}) => {\n if (section.state === 'empty') {\n return (\n <InfoCard title=\"IaC provenance\">\n <Typography color=\"textSecondary\">\n {section.message ||\n 'No Terraform provenance is linked to this resource.'}\n </Typography>\n </InfoCard>\n );\n }\n return (\n <InfoCard title=\"IaC provenance\">\n <SectionState section={section}>\n {section.data?.resources?.length ? (\n section.data.resources.map(resource => (\n <div key={resource.terraform.hashedID} style={{ marginBottom: 16 }}>\n <Typography variant=\"subtitle1\">\n {resource.terraform.address}\n </Typography>\n <Chip size=\"small\" label={humanize(resource.status)} />\n <Definition\n label=\"File\"\n value={resource.terraform.fileRef ?? ''}\n />\n <Definition\n label=\"State links\"\n value={String(resource.states.length)}\n />\n <Definition\n label=\"Cloud links\"\n value={String(resource.clouds.length)}\n />\n {resource.terraform.githubUrl && (\n <Link to={resource.terraform.githubUrl}>Open source</Link>\n )}\n </div>\n ))\n ) : (\n <Typography color=\"textSecondary\">\n No Terraform provenance is linked to this resource.\n </Typography>\n )}\n </SectionState>\n </InfoCard>\n );\n};\n\nconst DriftSection = ({\n section,\n}: {\n section: BriefSection<IacDriftEvidence>;\n}) => {\n if (section.state === 'empty') {\n return (\n <InfoCard title=\"IaC drift evidence\">\n <Typography color=\"textSecondary\">\n {section.message || 'No comparable Terraform evidence is available.'}\n </Typography>\n </InfoCard>\n );\n }\n return (\n <InfoCard title=\"IaC drift evidence\">\n <SectionState section={section}>\n {section.data?.items?.length ? (\n section.data.items.map(item => (\n <div key={item.terraform.hashedID} style={{ marginBottom: 16 }}>\n <Typography variant=\"subtitle1\">\n {item.terraform.address}\n </Typography>\n <Chip\n size=\"small\"\n color={item.status === 'drifted' ? 'secondary' : 'default'}\n label={humanize(item.status)}\n />\n <Typography color=\"textSecondary\">\n {item.status === 'unknown'\n ? `Unknown is not drift: ${humanize(item.reason)}.`\n : `${item.comparedFields} supported fields compared.`}\n </Typography>\n {item.differences.length > 0 && (\n <details>\n <summary>View sanitized differences</summary>\n <ul>\n {item.differences.map(difference => (\n <li key={difference.field}>\n <code>{difference.field}</code>:{' '}\n {difference.lastApplied ?? '∅'} →{' '}\n {difference.observed ?? '∅'}\n </li>\n ))}\n </ul>\n </details>\n )}\n </div>\n ))\n ) : (\n <Typography color=\"textSecondary\">\n No comparable Terraform evidence is available.\n </Typography>\n )}\n </SectionState>\n </InfoCard>\n );\n};\n\nconst SectionState = ({\n section,\n children,\n}: {\n section: BriefSection;\n children: ReactNode;\n}) => {\n if (section.state === 'error') {\n return <Alert severity=\"error\">{section.message}</Alert>;\n }\n if (section.state === 'unsupported') {\n return <Alert severity=\"info\">{section.message}</Alert>;\n }\n if (section.state === 'empty') {\n return <Typography color=\"textSecondary\">{section.message}</Typography>;\n }\n return <>{children}</>;\n};\n\nconst Definition = ({ label, value }: { label: string; value?: string }) => (\n <Typography paragraph>\n <strong>{label}:</strong> {value || 'Not available'}\n </Typography>\n);\n\nfunction humanize(value: string): string {\n return value.replaceAll('_', ' ');\n}\n\nexport function formatCloudTimestamp(value: string): string {\n const directTimestamp = Date.parse(value);\n if (!Number.isNaN(directTimestamp)) {\n return new Date(directTimestamp).toLocaleString();\n }\n\n const withoutBracketedZone = value.replace(/\\[[^\\]]+\\]$/, '');\n const normalizedTimestamp = Date.parse(withoutBracketedZone);\n return Number.isNaN(normalizedTimestamp)\n ? value\n : new Date(normalizedTimestamp).toLocaleString();\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AA8CO,MAAM,oBAAA,GAAuB,sBAAM,GAAA,CAAC,4BAAA,EAAA,EAA6B;AAEjE,MAAM,0BAAA,GAA6B,sBACxC,GAAA,CAAC,4BAAA,EAAA,EAA6B,YAAU,IAAA,EAAC;AAG3C,MAAM,4BAAA,GAA+B,CAAC,EAAE,UAAA,GAAa,OAAM,KAAM;AAC/D,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAC7B,EAAA,MAAM,GAAA,GAAM,OAAO,cAAc,CAAA;AACjC,EAAA,MAAM,UAAA,GAAa,sBAAsB,MAAM,CAAA;AAC/C,EAAA,MAAM,gBAAA,GAAmB,8BAA8B,MAAM,CAAA;AAC7D,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,QAAA,EAGnC;AACH,EAAA,MAAM,QACJ,WAAA,IAAe,WAAA,CAAY,UAAA,KAAe,UAAA,GACtC,YAAY,KAAA,GACZ,MAAA;AACN,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,QAAA,EAAiB;AAC3C,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,KAAK,CAAA;AAClD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,KAAK,CAAA;AACpD,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAI,QAAA,EAAiB;AAC/D,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,QAAA,CAA+B;AAAA,IACrE,UAAA,EAAY,KAAA;AAAA,IACZ,YAAA,EAAc;AAAA,GACf,CAAA;AACD,EAAA,MAAM,UAAA,GAAa,OAAO,EAAE,QAAA,EAAU,GAAG,OAAA,EAAS,CAAA,EAAG,UAAA,EAAY,CAAA,EAAG,CAAA;AACpE,EAAA,MAAM,QAAA,GAAW,OAAA;AAAA,IACf,MAAO,UAAA,GAAa,iBAAA,CAAkB,MAAM,CAAA,GAAI,MAAA;AAAA,IAChD,CAAC,QAAQ,UAAU;AAAA,GACrB;AAEA,EAAA,eAAA,CAAgB,MAAM;AACpB,IAAA,UAAA,CAAW,QAAQ,QAAA,IAAY,CAAA;AAC/B,IAAA,UAAA,CAAW,QAAQ,OAAA,IAAW,CAAA;AAC9B,IAAA,UAAA,CAAW,QAAQ,UAAA,IAAc,CAAA;AACjC,IAAA,cAAA,CAAe,MAAS,CAAA;AACxB,IAAA,QAAA,CAAS,MAAS,CAAA;AAClB,IAAA,aAAA,CAAc,KAAK,CAAA;AACnB,IAAA,cAAA,CAAe,KAAK,CAAA;AACpB,IAAA,kBAAA,CAAmB,MAAS,CAAA;AAAA,EAC9B,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAEf,EAAA,MAAM,IAAA,GAAO,WAAA;AAAA,IACX,OAAO,UAAU,KAAA,KAAU;AACzB,MAAA,IAAI,CAAC,UAAA,EAAY;AACjB,MAAA,MAAM,QAAA,GAAW,WAAW,OAAA,CAAQ,QAAA;AACpC,MAAA,MAAM,OAAA,GAAU,EAAE,UAAA,CAAW,OAAA,CAAQ,OAAA;AACrC,MAAA,EAAE,WAAW,OAAA,CAAQ,UAAA;AACrB,MAAA,aAAA,CAAc,OAAO,CAAA;AACrB,MAAA,cAAA,CAAe,KAAK,CAAA;AACpB,MAAA,kBAAA,CAAmB,MAAS,CAAA;AAC5B,MAAA,QAAA,CAAS,MAAS,CAAA;AAClB,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,kBAAA,CAAmB,UAAA,EAAY;AAAA,UACpD,GAAI,gBAAA,GAAmB,EAAE,gBAAA,KAAqB,EAAC;AAAA,UAC/C,KAAA,EAAO,KAAA;AAAA,UACP,IAAA,EAAM,IAAA;AAAA,UACN,GAAI,OAAA,GAAU,EAAE,OAAA,EAAS,IAAA,KAAS;AAAC,SACpC,CAAA;AACD,QAAA,IACE,WAAW,OAAA,CAAQ,QAAA,KAAa,YAChC,UAAA,CAAW,OAAA,CAAQ,YAAY,OAAA,EAC/B;AACA,UAAA,EAAE,WAAW,OAAA,CAAQ,UAAA;AACrB,UAAA,cAAA,CAAe,KAAK,CAAA;AACpB,UAAA,cAAA,CAAe,EAAE,UAAA,EAAY,KAAA,EAAO,IAAA,EAAM,CAAA;AAAA,QAC5C;AAAA,MACF,SAAS,SAAA,EAAW;AAClB,QAAA,IACE,WAAW,OAAA,CAAQ,QAAA,KAAa,YAChC,UAAA,CAAW,OAAA,CAAQ,YAAY,OAAA,EAC/B;AACA,UAAA,EAAE,WAAW,OAAA,CAAQ,UAAA;AACrB,UAAA,cAAA,CAAe,KAAK,CAAA;AACpB,UAAA,QAAA;AAAA,YACE,SAAA,YAAqB,KAAA,GACjB,SAAA,CAAU,OAAA,GACV;AAAA,WACN;AAAA,QACF;AAAA,MACF,CAAA,SAAE;AACA,QAAA,IACE,WAAW,OAAA,CAAQ,QAAA,KAAa,YAChC,UAAA,CAAW,OAAA,CAAQ,YAAY,OAAA,EAC/B;AACA,UAAA,aAAA,CAAc,KAAK,CAAA;AAAA,QACrB;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IACA,CAAC,GAAA,EAAK,gBAAA,EAAkB,UAAU;AAAA,GACpC;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,KAAK,IAAA,EAAK;AAAA,EACZ,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAY,OAAO,MAAA;AACxB,IAAA,IAAI,MAAA,GAAS,IAAA;AACb,IAAA,GAAA,CACG,YAAA,GACA,IAAA,CAAK,CAAA,IAAA,KAAQ,UAAU,eAAA,CAAgB,IAAI,CAAC,CAAA,CAC5C,KAAA;AAAA,MACC,MACE,UAAU,eAAA,CAAgB,EAAE,YAAY,KAAA,EAAO,YAAA,EAAc,OAAO;AAAA,KACxE;AACF,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,GAAS,KAAA;AAAA,IACX,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,GAAA,EAAK,UAAU,CAAC,CAAA;AAEpB,EAAA,MAAM,QAAA,GAAW,YAAY,YAAY;AACvC,IAAA,MAAM,MAAA,GAAS,KAAA,EAAO,OAAA,CAAQ,IAAA,EAAM,IAAA,CAAK,UAAA;AACzC,IAAA,IAAI,CAAC,UAAA,IAAc,CAAC,MAAA,EAAQ;AAC5B,IAAA,MAAM,QAAA,GAAW,WAAW,OAAA,CAAQ,QAAA;AACpC,IAAA,MAAM,OAAA,GAAU,WAAW,OAAA,CAAQ,OAAA;AACnC,IAAA,MAAM,UAAA,GAAa,EAAE,UAAA,CAAW,OAAA,CAAQ,UAAA;AACxC,IAAA,cAAA,CAAe,IAAI,CAAA;AACnB,IAAA,kBAAA,CAAmB,MAAS,CAAA;AAC5B,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,kBAAA,CAAmB,UAAA,EAAY;AAAA,QACpD,GAAI,gBAAA,GAAmB,EAAE,gBAAA,KAAqB,EAAC;AAAA,QAC/C,OAAO,KAAA,CAAM,KAAA;AAAA,QACb,IAAA,EAAM,IAAA;AAAA,QACN;AAAA,OACD,CAAA;AACD,MAAA,IACE,UAAA,CAAW,OAAA,CAAQ,QAAA,KAAa,QAAA,IAChC,UAAA,CAAW,OAAA,CAAQ,OAAA,KAAY,OAAA,IAC/B,UAAA,CAAW,OAAA,CAAQ,UAAA,KAAe,UAAA,EAClC;AACA,QAAA;AAAA,MACF;AACA,MAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,KAAA,KAAU,OAAA,EAAS;AAClC,QAAA,kBAAA;AAAA,UACE,IAAA,CAAK,QAAQ,OAAA,IAAW;AAAA,SAC1B;AACA,QAAA;AAAA,MACF;AACA,MAAA,IAAI,KAAK,OAAA,CAAQ,KAAA,KAAU,MAAA,IAAU,IAAA,CAAK,QAAQ,IAAA,EAAM;AACtD,QAAA,kBAAA,CAAmB,KAAA,CAAS,CAAA;AAAA,MAC9B;AACA,MAAA,cAAA,CAAe,CAAA,OAAA,KAAW;AACxB,QAAA,IACE,CAAC,OAAA,IACD,OAAA,CAAQ,UAAA,KAAe,UAAA,IACvB,CAAC,OAAA,CAAQ,KAAA,CAAM,OAAA,CAAQ,IAAA,IACvB,KAAK,OAAA,CAAQ,KAAA,KAAU,UACvB,CAAC,IAAA,CAAK,QAAQ,IAAA,EACd;AACA,UAAA,OAAO,OAAA;AAAA,QACT;AACA,QAAA,OAAO;AAAA,UACL,UAAA;AAAA,UACA,KAAA,EAAO;AAAA,YACL,GAAG,OAAA,CAAQ,KAAA;AAAA,YACX,aAAa,IAAA,CAAK,WAAA;AAAA,YAClB,OAAA,EAAS;AAAA,cACP,KAAA,EAAO,MAAA;AAAA,cACP,IAAA,EAAM,wBAAA;AAAA,gBACJ,OAAA,CAAQ,MAAM,OAAA,CAAQ,IAAA;AAAA,gBACtB,KAAK,OAAA,CAAQ;AAAA;AACf;AACF;AACF,SACF;AAAA,MACF,CAAC,CAAA;AAAA,IACH,SAAS,SAAA,EAAW;AAClB,MAAA,IACE,UAAA,CAAW,OAAA,CAAQ,QAAA,KAAa,QAAA,IAChC,UAAA,CAAW,OAAA,CAAQ,OAAA,KAAY,OAAA,IAC/B,UAAA,CAAW,OAAA,CAAQ,UAAA,KAAe,UAAA,EAClC;AACA,QAAA,kBAAA;AAAA,UACE,SAAA,YAAqB,KAAA,GACjB,SAAA,CAAU,OAAA,GACV;AAAA,SACN;AAAA,MACF;AAAA,IACF,CAAA,SAAE;AACA,MAAA,IACE,UAAA,CAAW,OAAA,CAAQ,QAAA,KAAa,QAAA,IAChC,UAAA,CAAW,OAAA,CAAQ,OAAA,KAAY,OAAA,IAC/B,UAAA,CAAW,OAAA,CAAQ,UAAA,KAAe,UAAA,EAClC;AACA,QAAA,cAAA,CAAe,KAAK,CAAA;AAAA,MACtB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,GAAA,EAAK,KAAA,EAAO,gBAAA,EAAkB,UAAU,CAAC,CAAA;AAE7C,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,MAAA,EAAO,QAAA,EAAA,sEAAA,EAEvB,CAAA;AAAA,EAEJ;AACA,EAAA,IAAI,KAAA,IAAS,CAAC,KAAA,EAAO;AACnB,IAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,OAAA,EACb,QAAA,EAAA;AAAA,MAAA,KAAA;AAAA,MAAM,GAAA;AAAA,sBAAC,GAAA,CAAC,UAAO,OAAA,EAAS,MAAM,KAAK,IAAA,CAAK,IAAI,GAAG,QAAA,EAAA,OAAA,EAAK;AAAA,KAAA,EACvD,CAAA;AAAA,EAEJ;AACA,EAAA,IAAI,CAAC,KAAA,EAAO,uBAAO,GAAA,CAAC,QAAA,EAAA,EAAS,CAAA;AAE7B,EAAA,uBACE,GAAA;AAAA,IAAC,sBAAA;AAAA,IAAA;AAAA,MACC,MAAA;AAAA,MACA,KAAA;AAAA,MACA,UAAA;AAAA,MACA,SAAA,EAAW,MAAM,KAAK,IAAA,CAAK,IAAI,CAAA;AAAA,MAC/B,WAAA;AAAA,MACA,UAAA,EAAY,MAAM,KAAK,QAAA,EAAS;AAAA,MAChC,KAAA;AAAA,MACA,eAAA;AAAA,MACA,UAAA,EAAY,UAAA,IAAc,YAAA,CAAa,UAAA,IAAc,QAAQ,QAAQ,CAAA;AAAA,MACrE;AAAA;AAAA,GACF;AAEJ,CAAA;AAEO,SAAS,wBAAA,CACd,SACA,IAAA,EACqB;AACrB,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,YAAA,EAAc,2BAAA;AAAA,MACZ,OAAA,CAAQ,YAAA;AAAA,MACR,IAAA,CAAK;AAAA,KACP;AAAA,IACA,QAAA,EAAU,CAAC,mBAAG,IAAI,GAAA,CAAI,CAAC,GAAG,OAAA,CAAQ,QAAA,EAAU,GAAG,IAAA,CAAK,QAAQ,CAAC,CAAC,CAAA;AAAA,IAC9D,OAAO,CAAC,GAAG,QAAQ,KAAA,EAAO,GAAG,KAAK,KAAK;AAAA,GACzC;AACF;AAEA,SAAS,2BAAA,CACP,SACA,IAAA,EACwB;AACxB,EAAA,MAAM,eAAuC,EAAC;AAC9C,EAAA,KAAA,MAAW,KAAA,wBAAa,GAAA,CAAI;AAAA,IAC1B,GAAG,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AAAA,IACtB,GAAG,MAAA,CAAO,IAAA,CAAK,IAAI;AAAA,GACpB,CAAA,EAAG;AACF,IAAA,YAAA,CAAa,KAAK,CAAA,GAAI,yBAAA;AAAA,MACpB,QAAQ,KAAK,CAAA;AAAA,MACb,KAAK,KAAK;AAAA,KACZ;AAAA,EACF;AACA,EAAA,OAAO,YAAA;AACT;AAEA,SAAS,yBAAA,CACP,SACA,IAAA,EACQ;AACR,EAAA,MAAM,iBAAA,GAAoB,sBAAsB,OAAO,CAAA;AACvD,EAAA,MAAM,cAAA,GAAiB,sBAAsB,IAAI,CAAA;AACjD,EAAA,OAAO,kBAAkB,iBAAiB,CAAA,IACxC,iBAAA,CAAkB,cAAc,IAC9B,iBAAA,GACA,cAAA;AACN;AAEA,MAAM,iBAAA,GAA4C;AAAA,EAChD,WAAA,EAAa,CAAA;AAAA,EACb,OAAA,EAAS,CAAA;AAAA,EACT,SAAA,EAAW;AACb,CAAA;AAEA,SAAS,sBAAsB,KAAA,EAAmC;AAChE,EAAA,OAAO,KAAA,IAAS,KAAA,IAAS,iBAAA,GAAoB,KAAA,GAAQ,aAAA;AACvD;AAEO,MAAM,yBAAyB,CAAC;AAAA,EACrC,MAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,KAAA;AAAA,EACA,eAAA;AAAA,EACA,UAAA,GAAa,KAAA;AAAA,EACb;AACF,CAAA,KAWM;AACJ,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AACpD,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,KAAA,EAAO,IAAA;AAAA,IAAK,CAAA,IAAA,KAC9C,IAAA,CAAK,GAAA,CAAI,UAAA,CAAW,iCAAiC;AAAA,GACvD;AAEA,EAAA,uBACE,IAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAS,IAAA,EAAC,SAAS,CAAA,EACtB,QAAA,EAAA;AAAA,IAAA,KAAA,oBACC,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EACb,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,OAAA,EAAS,QAAA,EAAA,KAAA,EAAM,CAAA,EACjC,CAAA;AAAA,oBAEF,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,IAAI,EAAA,EACb,QAAA,kBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,gBAAA;AAAA,QACN,MAAA,kBACE,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,OAAA;AAAA,YACL,OAAA,EAAS,SAAA;AAAA,YACT,WACE,UAAA,mBAAa,GAAA,CAAC,gBAAA,EAAA,EAAiB,IAAA,EAAM,IAAI,CAAA,GAAK,MAAA;AAAA,YAEjD,QAAA,EAAA;AAAA;AAAA,SAED;AAAA,QAGF,QAAA,kBAAA,IAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EAAgB,QAAA,EAAA;AAAA,UAAA,iDAAA;AAAA,UACa,GAAA;AAAA,UAC5C,oBAAA,CAAqB,MAAM,WAAW,CAAA;AAAA,UAAE,eAAA;AAAA,UAAW,KAAA,CAAM;AAAA,SAAA,EAC5D;AAAA;AAAA,KACF,EACF,CAAA;AAAA,oBAEA,GAAA,CAAC,QAAK,IAAA,EAAI,IAAA,EAAC,IAAI,EAAA,EACb,QAAA,kBAAA,IAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,gBAAA,EACd,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,UAAA;AAAA,UACN,KAAA,EAAO,YAAY,kCAAkC;AAAA;AAAA,OACvD;AAAA,sBACA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,eAAA;AAAA,UACN,KAAA,EACE,YAAY,iCAAiC,CAAA,IAC7C,OAAO,MAAA,CAAO,IAAA,EAAM,QAAQ,EAAE;AAAA;AAAA,OAElC;AAAA,sBACA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,QAAA;AAAA,UACN,KAAA,EAAO,WAAA,CAAY,gCAAgC,CAAA,IAAK;AAAA;AAAA,OAC1D;AAAA,sBACA,GAAA;AAAA,QAAC,UAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAM,SAAA;AAAA,UACN,KAAA,EAAO,YAAY,iCAAiC;AAAA;AAAA,OACtD;AAAA,0BACC,UAAA,EAAA,EAAW,KAAA,EAAM,oBAAA,EAAqB,KAAA,EAAO,MAAM,UAAA,EAAY,CAAA;AAAA,MAC/D,+BAAe,GAAA,CAAC,IAAA,EAAA,EAAK,EAAA,EAAI,WAAA,CAAY,KAAK,QAAA,EAAA,qBAAA,EAAmB;AAAA,KAAA,EAChE,CAAA,EACF,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,wBAAA,EAAA,EAAyB,MAAA,EAAgB,CAAA,EAC5C,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,sBAAA,EAAA,EAAuB,MAAA,EAAgB,CAAA,EAC1C,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EACb,QAAA,kBAAA,GAAA,CAAC,kBAAA,EAAA,EAAmB,OAAA,EAAS,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,WAAW,CAAA,EACjE,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,IAAI,EAAA,EACb,QAAA,kBAAA,GAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACC,SAAS,KAAA,CAAM,OAAA;AAAA,QACf,WAAA;AAAA,QACA,UAAA;AAAA,QACA;AAAA;AAAA,KACF,EACF,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,iBAAA,EAAA,EAAkB,OAAA,EAAS,KAAA,CAAM,YAAY,CAAA,EAChD,CAAA;AAAA,oBACA,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EACrB,QAAA,kBAAA,GAAA,CAAC,YAAA,EAAA,EAAa,OAAA,EAAS,KAAA,CAAM,OAAO,CAAA,EACtC,CAAA;AAAA,IACC,UAAA,oBACC,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAI,IAAA,EAAC,EAAA,EAAI,EAAA,EACb,QAAA,kBAAA,GAAA,CAAC,eAAA,EAAA,EAAgB,OAAA,EAAQ,QAAA,EAAS,KAAA,EAAO,UAAU,CAAA,EACrD;AAAA,GAAA,EAEJ,CAAA;AAEJ;AAEA,MAAM,iBAAiB,CAAC;AAAA,EACtB,OAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAA,KAKM;AACJ,EAAA,MAAM,EAAE,sBAAA,EAAwB,kBAAA,EAAmB,GACjD,2BAAA;AAAA,IACE,QAAQ,IAAA,EAAM,QAAA;AAAA,IACd,OAAA,CAAQ,IAAA,EAAM,KAAA,CAAM,MAAA,IAAU;AAAA,GAChC;AAEF,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,sBAAA,EACd,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA,OAAA,CAAQ,OAAA,IAAW,6CAAA,EACtB,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,2BACG,QAAA,EAAA,EAAS,KAAA,EAAM,sBAAA,EACd,QAAA,kBAAA,IAAA,CAAC,gBAAa,OAAA,EACX,QAAA,EAAA;AAAA,IAAA,eAAA,oBACC,GAAA,CAAC,SAAM,QAAA,EAAS,OAAA,EAAQ,OAAO,EAAE,YAAA,EAAc,CAAA,EAAE,EAC9C,QAAA,EAAA,eAAA,EACH,CAAA;AAAA,IAED,sBAAA,oBACC,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,YAAA,EAAW,kCAAA;AAAA,QACX,OAAA,EAAQ,SAAA;AAAA,QACR,KAAA,EAAM,eAAA;AAAA,QACN,OAAA,EAAQ,OAAA;AAAA,QACR,KAAA,EAAO,EAAE,YAAA,EAAc,CAAA,EAAE;AAAA,QAC1B,QAAA,EAAA;AAAA;AAAA,KAGD;AAAA,IAED,mBAAmB,GAAA,CAAI,CAAA,OAAA,qBACtB,GAAA,CAAC,KAAA,EAAA,EAAM,UAAS,SAAA,EAAwB,KAAA,EAAO,EAAE,YAAA,EAAc,GAAE,EAC9D,QAAA,EAAA,QAAA,CAAS,OAAO,CAAA,EAAA,EADY,OAE/B,CACD,CAAA;AAAA,IACA,OAAA,CAAQ,IAAA,EAAM,KAAA,EAAO,MAAA,GACpB,QAAQ,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,CAAA,KAAA,0BACpB,KAAA,EAAA,EAAmB,KAAA,EAAO,EAAE,YAAA,EAAc,IAAG,EAC5C,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,SAAQ,WAAA,EACjB,QAAA,EAAA,KAAA,CAAM,WAAW,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA,EACvC,CAAA;AAAA,sBACA,IAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA;AAAA,QAAA,oBAAA,CAAqB,MAAM,SAAS,CAAA;AAAA,QAAE,QAAA;AAAA,QAAI,KAAA,CAAM,QAAA;AAAA,QAAS,OAAA;AAAA,QAAG,GAAA;AAAA,QAC5D,MAAM,QAAA,CAAS,MAAA;AAAA,QAAO,QAAA;AAAA,QAAI,MAAM,QAAA,CAAS,MAAA;AAAA,QACzC,KAAA,CAAM,KAAA,EAAO,IAAA,IAAQ,KAAA,CAAM,KAAA,EAAO,EAAA,GAC/B,CAAA,MAAA,EAAM,KAAA,CAAM,KAAA,CAAM,IAAA,IAAQ,KAAA,CAAM,KAAA,CAAM,EAAE,CAAA,CAAA,GACxC;AAAA,OAAA,EACN,CAAA;AAAA,MACC,MAAM,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAA,yBAC3B,SAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,aAAQ,QAAA,EAAA,8BAAA,EAA4B,CAAA;AAAA,4BACpC,IAAA,EAAA,EACE,QAAA,EAAA,KAAA,CAAM,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,KAAA,KAAS;AAChC,UAAA,MAAM,MAAA,GAAS,KAAA,CAAM,MAAA,CAAO,OAAA,CAAQ,IAAA;AAAA,YAClC,CAAA,SAAA,KAAa,UAAU,KAAA,KAAU;AAAA,WACnC;AACA,UAAA,4BACG,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,UAAM,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,YACZ,MAAA,GACG,KAAK,MAAA,CAAO,MAAA,IAAU,QAAG,CAAA,QAAA,EACvB,MAAA,CAAO,KAAA,IAAS,QAClB,CAAA,CAAA,GACA;AAAA,WAAA,EAAA,EANG,KAOT,CAAA;AAAA,QAEJ,CAAC,CAAA,EACH;AAAA,OAAA,EACF;AAAA,KAAA,EAAA,EA/BM,KAAA,CAAM,EAiChB,CACD,CAAA,uBAEA,UAAA,EAAA,EAAW,KAAA,EAAM,iBAAgB,QAAA,EAAA,6CAAA,EAElC,CAAA;AAAA,IAED,OAAA,CAAQ,IAAA,EAAM,IAAA,CAAK,OAAA,IAAW,UAAA,oBAC7B,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,OAAA;AAAA,QACL,OAAA,EAAS,UAAA;AAAA,QACT,QAAA,EAAU,WAAA;AAAA,QACV,WAAW,WAAA,mBAAc,GAAA,CAAC,gBAAA,EAAA,EAAiB,IAAA,EAAM,IAAI,CAAA,GAAK,MAAA;AAAA,QAC3D,QAAA,EAAA;AAAA;AAAA;AAED,GAAA,EAEJ,CAAA,EACF,CAAA;AAEJ,CAAA;AAEA,MAAM,0BAAA,uBAAiC,GAAA,CAAI;AAAA,EACzC,sBAAA;AAAA,EACA;AACF,CAAC,CAAA;AACD,MAAM,8BAAA,uBAAqC,GAAA,CAAI;AAAA,EAC7C,4BAAA;AAAA,EACA;AACF,CAAC,CAAA;AAED,SAAS,2BAAA,CACP,UACA,UAAA,EACA;AACA,EAAA,MAAM,WAAA,GAAc,YAAY,EAAC;AACjC,EAAA,OAAO;AAAA,IACL,wBAAwB,WAAA,CAAY,IAAA;AAAA,MAAK,CAAA,OAAA,KACvC,0BAAA,CAA2B,GAAA,CAAI,OAAO;AAAA,KACxC;AAAA,IACA,oBAAoB,WAAA,CAAY,MAAA;AAAA,MAC9B,CAAA,OAAA,KACE,CAAC,0BAAA,CAA2B,GAAA,CAAI,OAAO,CAAA,KACtC,UAAA,GAAa,CAAA,IAAK,CAAC,8BAAA,CAA+B,GAAA,CAAI,OAAO,CAAA;AAAA;AAClE,GACF;AACF;AAEA,MAAM,oBAAoB,CAAC;AAAA,EACzB;AACF,CAAA,KAEM;AACJ,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,gBAAA,EACd,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA,OAAA,CAAQ,OAAA,IACP,qDAAA,EACJ,CAAA,EACF,CAAA;AAAA,EAEJ;AACA,EAAA,uBACE,GAAA,CAAC,YAAS,KAAA,EAAM,gBAAA,EACd,8BAAC,YAAA,EAAA,EAAa,OAAA,EACX,QAAA,EAAA,OAAA,CAAQ,IAAA,EAAM,SAAA,EAAW,MAAA,GACxB,QAAQ,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,QAAA,qBACzB,IAAA,CAAC,SAAsC,KAAA,EAAO,EAAE,YAAA,EAAc,EAAA,EAAG,EAC/D,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,WAAA,EACjB,QAAA,EAAA,QAAA,CAAS,UAAU,OAAA,EACtB,CAAA;AAAA,oBACA,GAAA,CAAC,QAAK,IAAA,EAAK,OAAA,EAAQ,OAAO,QAAA,CAAS,QAAA,CAAS,MAAM,CAAA,EAAG,CAAA;AAAA,oBACrD,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,MAAA;AAAA,QACN,KAAA,EAAO,QAAA,CAAS,SAAA,CAAU,OAAA,IAAW;AAAA;AAAA,KACvC;AAAA,oBACA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,aAAA;AAAA,QACN,KAAA,EAAO,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,MAAM;AAAA;AAAA,KACtC;AAAA,oBACA,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,aAAA;AAAA,QACN,KAAA,EAAO,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,MAAM;AAAA;AAAA,KACtC;AAAA,IACC,QAAA,CAAS,UAAU,SAAA,oBAClB,GAAA,CAAC,QAAK,EAAA,EAAI,QAAA,CAAS,SAAA,CAAU,SAAA,EAAW,QAAA,EAAA,aAAA,EAAW;AAAA,GAAA,EAAA,EAlB7C,QAAA,CAAS,SAAA,CAAU,QAoB7B,CACD,CAAA,mBAED,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EAAgB,QAAA,EAAA,qDAAA,EAElC,CAAA,EAEJ,CAAA,EACF,CAAA;AAEJ,CAAA;AAEA,MAAM,eAAe,CAAC;AAAA,EACpB;AACF,CAAA,KAEM;AACJ,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,oBAAA,EACd,QAAA,kBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA,OAAA,CAAQ,OAAA,IAAW,gDAAA,EACtB,CAAA,EACF,CAAA;AAAA,EAEJ;AACA,EAAA,uBACE,GAAA,CAAC,YAAS,KAAA,EAAM,oBAAA,EACd,8BAAC,YAAA,EAAA,EAAa,OAAA,EACX,QAAA,EAAA,OAAA,CAAQ,IAAA,EAAM,KAAA,EAAO,MAAA,GACpB,QAAQ,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,IAAA,qBACrB,IAAA,CAAC,SAAkC,KAAA,EAAO,EAAE,YAAA,EAAc,EAAA,EAAG,EAC3D,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,WAAA,EACjB,QAAA,EAAA,IAAA,CAAK,UAAU,OAAA,EAClB,CAAA;AAAA,oBACA,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,OAAA;AAAA,QACL,KAAA,EAAO,IAAA,CAAK,MAAA,KAAW,SAAA,GAAY,WAAA,GAAc,SAAA;AAAA,QACjD,KAAA,EAAO,QAAA,CAAS,IAAA,CAAK,MAAM;AAAA;AAAA,KAC7B;AAAA,wBACC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EACf,QAAA,EAAA,IAAA,CAAK,WAAW,SAAA,GACb,CAAA,sBAAA,EAAyB,QAAA,CAAS,IAAA,CAAK,MAAM,CAAC,CAAA,CAAA,CAAA,GAC9C,CAAA,EAAG,IAAA,CAAK,cAAc,CAAA,2BAAA,CAAA,EAC5B,CAAA;AAAA,IACC,IAAA,CAAK,WAAA,CAAY,MAAA,GAAS,CAAA,yBACxB,SAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,aAAQ,QAAA,EAAA,4BAAA,EAA0B,CAAA;AAAA,0BAClC,IAAA,EAAA,EACE,QAAA,EAAA,IAAA,CAAK,YAAY,GAAA,CAAI,CAAA,UAAA,0BACnB,IAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,MAAA,EAAA,EAAM,qBAAW,KAAA,EAAM,CAAA;AAAA,QAAO,GAAA;AAAA,QAAE,GAAA;AAAA,QAChC,WAAW,WAAA,IAAe,QAAA;AAAA,QAAI,SAAA;AAAA,QAAG,GAAA;AAAA,QACjC,WAAW,QAAA,IAAY;AAAA,OAAA,EAAA,EAHjB,UAAA,CAAW,KAIpB,CACD,CAAA,EACH;AAAA,KAAA,EACF;AAAA,GAAA,EAAA,EA1BM,IAAA,CAAK,SAAA,CAAU,QA4BzB,CACD,CAAA,mBAED,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EAAgB,QAAA,EAAA,gDAAA,EAElC,CAAA,EAEJ,CAAA,EACF,CAAA;AAEJ,CAAA;AAEA,MAAM,eAAe,CAAC;AAAA,EACpB,OAAA;AAAA,EACA;AACF,CAAA,KAGM;AACJ,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,OAAA,EAAS,kBAAQ,OAAA,EAAQ,CAAA;AAAA,EAClD;AACA,EAAA,IAAI,OAAA,CAAQ,UAAU,aAAA,EAAe;AACnC,IAAA,uBAAO,GAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,MAAA,EAAQ,kBAAQ,OAAA,EAAQ,CAAA;AAAA,EACjD;AACA,EAAA,IAAI,OAAA,CAAQ,UAAU,OAAA,EAAS;AAC7B,IAAA,uBAAO,GAAA,CAAC,UAAA,EAAA,EAAW,KAAA,EAAM,eAAA,EAAiB,kBAAQ,OAAA,EAAQ,CAAA;AAAA,EAC5D;AACA,EAAA,uCAAU,QAAA,EAAS,CAAA;AACrB,CAAA;AAEA,MAAM,UAAA,GAAa,CAAC,EAAE,KAAA,EAAO,OAAM,qBACjC,IAAA,CAAC,UAAA,EAAA,EAAW,SAAA,EAAS,IAAA,EACnB,QAAA,EAAA;AAAA,kBAAA,IAAA,CAAC,QAAA,EAAA,EAAQ,QAAA,EAAA;AAAA,IAAA,KAAA;AAAA,IAAM;AAAA,GAAA,EAAC,CAAA;AAAA,EAAS,GAAA;AAAA,EAAE,KAAA,IAAS;AAAA,CAAA,EACtC,CAAA;AAGF,SAAS,SAAS,KAAA,EAAuB;AACvC,EAAA,OAAO,KAAA,CAAM,UAAA,CAAW,GAAA,EAAK,GAAG,CAAA;AAClC;AAEO,SAAS,qBAAqB,KAAA,EAAuB;AAC1D,EAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AACxC,EAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,eAAe,CAAA,EAAG;AAClC,IAAA,OAAO,IAAI,IAAA,CAAK,eAAe,CAAA,CAAE,cAAA,EAAe;AAAA,EAClD;AAEA,EAAA,MAAM,oBAAA,GAAuB,KAAA,CAAM,OAAA,CAAQ,aAAA,EAAe,EAAE,CAAA;AAC5D,EAAA,MAAM,mBAAA,GAAsB,IAAA,CAAK,KAAA,CAAM,oBAAoB,CAAA;AAC3D,EAAA,OAAO,MAAA,CAAO,MAAM,mBAAmB,CAAA,GACnC,QACA,IAAI,IAAA,CAAK,mBAAmB,CAAA,CAAE,cAAA,EAAe;AACnD;;;;"}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
2
|
+
import { useState, useRef, useCallback, useEffect, useMemo } from 'react';
|
|
3
3
|
import { Typography, Box, Chip, Button, CircularProgress, Grid } from '@material-ui/core';
|
|
4
4
|
import { Progress } from '@backstage/core-components';
|
|
5
|
-
import { useApi } from '@backstage/frontend-plugin-api';
|
|
5
|
+
import { useApi, useApiHolder } from '@backstage/frontend-plugin-api';
|
|
6
6
|
import { ANYSHIFT_KIND_ANNOTATION, ANYSHIFT_CONFIGURATION_ENDPOINTS_ANNOTATION, ANYSHIFT_CONFIGURATION_DEPENDENCIES_ANNOTATION, ANYSHIFT_RUNTIME_RESOURCE_ID_ANNOTATION } from '@anyshift/backstage-plugin-anyshift-common';
|
|
7
|
-
import { useEntity } from '@backstage/plugin-catalog-react';
|
|
7
|
+
import { useEntity, catalogApiRef } from '@backstage/plugin-catalog-react';
|
|
8
8
|
import { anyshiftApiRef } from '../../api/AnyshiftApi.esm.js';
|
|
9
9
|
import { AskAnyshiftCard } from '../ask/AskAnyshiftCard.esm.js';
|
|
10
10
|
import { askScopeForEntity } from '../ask/askScope.esm.js';
|
|
11
11
|
import { CloudAnyshiftEntityContent } from '../cloud/CloudResourceContent.esm.js';
|
|
12
12
|
import { isCloudResourceEntity, entityTarget } from './entityIdentity.esm.js';
|
|
13
|
+
import { resolveRelatedCatalogEntities } from './relatedCatalogEntities.esm.js';
|
|
13
14
|
import { OverviewSection, WhyNowSection, DatadogSignalSection, ArchitectureSection, DependencySection, BriefRail, TimelineSection } from './BriefSections.esm.js';
|
|
14
15
|
|
|
15
16
|
const AnyshiftEntityContent = () => {
|
|
@@ -19,6 +20,7 @@ const AnyshiftEntityContent = () => {
|
|
|
19
20
|
const ServiceAnyshiftEntityContent = () => {
|
|
20
21
|
const { entity } = useEntity();
|
|
21
22
|
const api = useApi(anyshiftApiRef);
|
|
23
|
+
const catalogApi = useApiHolder().get(catalogApiRef);
|
|
22
24
|
const annotations = entity.metadata.annotations ?? {};
|
|
23
25
|
const target = entityTarget(entity);
|
|
24
26
|
const kind = annotations[ANYSHIFT_KIND_ANNOTATION] || "workload";
|
|
@@ -27,6 +29,7 @@ const ServiceAnyshiftEntityContent = () => {
|
|
|
27
29
|
const configurationDependencies = annotations[ANYSHIFT_CONFIGURATION_DEPENDENCIES_ANNOTATION];
|
|
28
30
|
const configurationTarget = annotations[ANYSHIFT_RUNTIME_RESOURCE_ID_ANNOTATION];
|
|
29
31
|
const [brief, setBrief] = useState();
|
|
32
|
+
const [catalogEntities, setCatalogEntities] = useState([]);
|
|
30
33
|
const [capabilities, setCapabilities] = useState({
|
|
31
34
|
askEnabled: false,
|
|
32
35
|
queryEnabled: false
|
|
@@ -115,6 +118,26 @@ const ServiceAnyshiftEntityContent = () => {
|
|
|
115
118
|
active.current = false;
|
|
116
119
|
};
|
|
117
120
|
}, [load]);
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
let cancelled = false;
|
|
123
|
+
if (!catalogApi) {
|
|
124
|
+
setCatalogEntities([]);
|
|
125
|
+
return () => {
|
|
126
|
+
cancelled = true;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
catalogApi.getEntities({
|
|
130
|
+
filter: [{ kind: "Component" }, { kind: "Resource" }],
|
|
131
|
+
fields: ["kind", "metadata.name", "metadata.namespace"]
|
|
132
|
+
}).then((response) => {
|
|
133
|
+
if (!cancelled) setCatalogEntities(response.items);
|
|
134
|
+
}).catch(() => {
|
|
135
|
+
if (!cancelled) setCatalogEntities([]);
|
|
136
|
+
});
|
|
137
|
+
return () => {
|
|
138
|
+
cancelled = true;
|
|
139
|
+
};
|
|
140
|
+
}, [catalogApi]);
|
|
118
141
|
useEffect(() => {
|
|
119
142
|
api.capabilities().then((next) => {
|
|
120
143
|
if (active.current) setCapabilities(next);
|
|
@@ -124,12 +147,31 @@ const ServiceAnyshiftEntityContent = () => {
|
|
|
124
147
|
}
|
|
125
148
|
});
|
|
126
149
|
}, [api]);
|
|
127
|
-
|
|
128
|
-
|
|
150
|
+
const resolvedBrief = useMemo(() => {
|
|
151
|
+
if (!brief || brief.impact.state !== "data" || !brief.impact.data)
|
|
152
|
+
return brief;
|
|
153
|
+
const impactData = brief.impact.data;
|
|
154
|
+
return {
|
|
155
|
+
...brief,
|
|
156
|
+
impact: {
|
|
157
|
+
...brief.impact,
|
|
158
|
+
data: {
|
|
159
|
+
...impactData,
|
|
160
|
+
relatedEntities: resolveRelatedCatalogEntities(
|
|
161
|
+
impactData.relatedEntities,
|
|
162
|
+
catalogEntities
|
|
163
|
+
)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}, [brief, catalogEntities]);
|
|
168
|
+
if (error && !resolvedBrief)
|
|
169
|
+
return /* @__PURE__ */ jsx(Typography, { color: "error", children: error });
|
|
170
|
+
if (!resolvedBrief) return /* @__PURE__ */ jsx(Progress, {});
|
|
129
171
|
return /* @__PURE__ */ jsx(
|
|
130
172
|
ServiceBriefView,
|
|
131
173
|
{
|
|
132
|
-
brief,
|
|
174
|
+
brief: resolvedBrief,
|
|
133
175
|
onRetry: retrySection,
|
|
134
176
|
refreshing,
|
|
135
177
|
onRefresh: () => void load(true),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnyshiftEntityContent.esm.js","sources":["../../../src/components/entity/AnyshiftEntityContent.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n Box,\n Button,\n Chip,\n CircularProgress,\n Grid,\n Typography,\n} from '@material-ui/core';\nimport { Progress } from '@backstage/core-components';\nimport { useApi } from '@backstage/frontend-plugin-api';\nimport {\n ANYSHIFT_CONFIGURATION_DEPENDENCIES_ANNOTATION,\n ANYSHIFT_CONFIGURATION_ENDPOINTS_ANNOTATION,\n ANYSHIFT_KIND_ANNOTATION,\n ANYSHIFT_RUNTIME_RESOURCE_ID_ANNOTATION,\n} from '@anyshift/backstage-plugin-anyshift-common';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { anyshiftApiRef } from '../../api/AnyshiftApi';\nimport type {\n AnyshiftCapabilities,\n AskScope,\n BriefSectionName,\n ServiceBrief,\n} from '../../api/types';\nimport { AskAnyshiftCard } from '../ask/AskAnyshiftCard';\nimport { askScopeForEntity } from '../ask/askScope';\nimport { CloudAnyshiftEntityContent } from '../cloud/CloudResourceContent';\nimport { entityTarget, isCloudResourceEntity } from './entityIdentity';\nimport {\n ArchitectureSection,\n BriefRail,\n DatadogSignalSection,\n DependencySection,\n OverviewSection,\n TimelineSection,\n WhyNowSection,\n} from './BriefSections';\n\nexport const AnyshiftEntityContent = () => {\n const { entity } = useEntity();\n return isCloudResourceEntity(entity) ? (\n <CloudAnyshiftEntityContent />\n ) : (\n <ServiceAnyshiftEntityContent />\n );\n};\n\nexport const ServiceAnyshiftEntityContent = () => {\n const { entity } = useEntity();\n const api = useApi(anyshiftApiRef);\n const annotations = entity.metadata.annotations ?? {};\n const target = entityTarget(entity);\n const kind = annotations[ANYSHIFT_KIND_ANNOTATION] || 'workload';\n const namespace = entity.metadata.namespace;\n const configurationEndpoints =\n annotations[ANYSHIFT_CONFIGURATION_ENDPOINTS_ANNOTATION];\n const configurationDependencies =\n annotations[ANYSHIFT_CONFIGURATION_DEPENDENCIES_ANNOTATION];\n const configurationTarget =\n annotations[ANYSHIFT_RUNTIME_RESOURCE_ID_ANNOTATION];\n const [brief, setBrief] = useState<ServiceBrief>();\n const [capabilities, setCapabilities] = useState<AnyshiftCapabilities>({\n askEnabled: false,\n queryEnabled: false,\n });\n const [error, setError] = useState<string>();\n const [refreshingAll, setRefreshingAll] = useState(false);\n const [refreshing, setRefreshing] = useState<Set<BriefSectionName>>(\n new Set(),\n );\n const active = useRef(true);\n\n const load = useCallback(\n async (refresh = false) => {\n setError(undefined);\n if (refresh) setRefreshingAll(true);\n try {\n const next = await api.brief(kind, target, {\n namespace,\n refresh,\n configurationEndpoints,\n configurationDependencies,\n configurationTarget,\n });\n if (active.current) setBrief(next);\n } catch (cause) {\n if (active.current)\n setError(cause instanceof Error ? cause.message : String(cause));\n } finally {\n if (active.current) setRefreshingAll(false);\n }\n },\n [\n api,\n configurationDependencies,\n configurationEndpoints,\n configurationTarget,\n kind,\n namespace,\n target,\n ],\n );\n\n const retrySection = useCallback(\n async (section: BriefSectionName) => {\n setRefreshing(current => new Set(current).add(section));\n try {\n const response = await api.briefSection(kind, target, section, {\n namespace,\n refresh: true,\n configurationEndpoints,\n configurationDependencies,\n configurationTarget,\n });\n if (active.current) {\n setBrief(current =>\n current\n ? {\n ...current,\n [section]: response.value,\n refreshedAt: response.refreshedAt,\n ...(response.observedService\n ? { observedService: response.observedService }\n : {}),\n }\n : current,\n );\n }\n } finally {\n if (active.current) {\n setRefreshing(current => {\n const next = new Set(current);\n next.delete(section);\n return next;\n });\n }\n }\n },\n [\n api,\n configurationDependencies,\n configurationEndpoints,\n configurationTarget,\n kind,\n namespace,\n target,\n ],\n );\n\n useEffect(() => {\n active.current = true;\n void load();\n return () => {\n active.current = false;\n };\n }, [load]);\n\n useEffect(() => {\n api\n .capabilities()\n .then(next => {\n if (active.current) setCapabilities(next);\n })\n .catch(() => {\n if (active.current) {\n setCapabilities({ askEnabled: false, queryEnabled: false });\n }\n });\n }, [api]);\n\n if (error && !brief) return <Typography color=\"error\">{error}</Typography>;\n if (!brief) return <Progress />;\n return (\n <ServiceBriefView\n brief={brief}\n onRetry={retrySection}\n refreshing={refreshing}\n onRefresh={() => void load(true)}\n refreshingAll={refreshingAll}\n refreshError={error}\n askEnabled={capabilities.askEnabled}\n askScope={askScopeForEntity(entity)}\n />\n );\n};\n\nexport const ServiceBriefView = ({\n brief,\n onRetry,\n refreshing = new Set(),\n onRefresh = () => {},\n refreshingAll = false,\n refreshError,\n askEnabled = false,\n askScope,\n}: {\n brief: ServiceBrief;\n onRetry: (section: BriefSectionName) => void;\n refreshing?: ReadonlySet<BriefSectionName>;\n onRefresh?: () => void;\n refreshingAll?: boolean;\n refreshError?: string;\n askEnabled?: boolean;\n askScope?: AskScope;\n}) => (\n <>\n <Box\n mb={3}\n px={2.5}\n py={2}\n borderLeft={4}\n borderColor=\"primary.main\"\n bgcolor=\"background.paper\"\n >\n <Box display=\"flex\" justifyContent=\"space-between\" gridGap={16}>\n <Box>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Anyshift evidence trace\n </Typography>\n <Box display=\"flex\" flexWrap=\"wrap\" alignItems=\"center\" gridGap={8}>\n <Chip size=\"small\" label={`Workload · ${brief.target}`} />\n <Typography aria-hidden=\"true\" color=\"primary\">\n →\n </Typography>\n <Chip\n size=\"small\"\n color=\"primary\"\n label={`Observed service · ${\n brief.observedService || 'Not resolved'\n }`}\n />\n </Box>\n <Typography variant=\"caption\" color=\"textSecondary\">\n Runtime namespace: {brief.namespace || 'Not set'} · Refreshed{' '}\n {formatTimestamp(brief.refreshedAt)}\n </Typography>\n </Box>\n <Button\n type=\"button\"\n variant=\"outlined\"\n size=\"small\"\n onClick={onRefresh}\n disabled={refreshingAll}\n startIcon={refreshingAll ? <CircularProgress size={14} /> : undefined}\n >\n {refreshingAll ? 'Refreshing…' : 'Refresh brief'}\n </Button>\n </Box>\n {refreshError && (\n <Typography color=\"error\" variant=\"caption\">\n Refresh failed: {refreshError}. Existing evidence is still shown.\n </Typography>\n )}\n </Box>\n\n <Grid container spacing={3} alignItems=\"stretch\">\n <Grid item xs={12}>\n <OverviewSection\n section={brief.overview}\n onRetry={onRetry}\n refreshing={refreshing.has('overview')}\n />\n </Grid>\n <Grid item xs={12}>\n <WhyNowSection\n section={brief.whyNow}\n onRetry={onRetry}\n refreshing={refreshing.has('whyNow')}\n />\n </Grid>\n {askEnabled && (\n <Grid item xs={12}>\n <AskAnyshiftCard context=\"entity\" scope={askScope} />\n </Grid>\n )}\n <Grid item xs={12}>\n <DatadogSignalSection\n section={brief.observability}\n onRetry={onRetry}\n refreshing={refreshing.has('observability')}\n />\n </Grid>\n <Grid item xs={12}>\n <ArchitectureSection\n section={brief.architecture}\n onRetry={onRetry}\n refreshing={refreshing.has('architecture')}\n />\n </Grid>\n <Grid item xs={12} md={8}>\n <DependencySection\n section={brief.topology}\n onRetry={onRetry}\n refreshing={refreshing.has('topology')}\n />\n </Grid>\n <Grid item xs={12} md={4}>\n <BriefRail brief={brief} onRetry={onRetry} refreshing={refreshing} />\n </Grid>\n <Grid item xs={12}>\n <TimelineSection\n section={brief.timeline}\n onRetry={onRetry}\n refreshing={refreshing.has('timeline')}\n />\n </Grid>\n </Grid>\n </>\n);\n\nfunction formatTimestamp(value: string): string {\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? value : new Date(parsed).toLocaleString();\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AnyshiftEntityContent.esm.js","sources":["../../../src/components/entity/AnyshiftEntityContent.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Box,\n Button,\n Chip,\n CircularProgress,\n Grid,\n Typography,\n} from '@material-ui/core';\nimport { Progress } from '@backstage/core-components';\nimport { useApi, useApiHolder } from '@backstage/frontend-plugin-api';\nimport type { Entity } from '@backstage/catalog-model';\nimport {\n ANYSHIFT_CONFIGURATION_DEPENDENCIES_ANNOTATION,\n ANYSHIFT_CONFIGURATION_ENDPOINTS_ANNOTATION,\n ANYSHIFT_KIND_ANNOTATION,\n ANYSHIFT_RUNTIME_RESOURCE_ID_ANNOTATION,\n} from '@anyshift/backstage-plugin-anyshift-common';\nimport { catalogApiRef, useEntity } from '@backstage/plugin-catalog-react';\nimport { anyshiftApiRef } from '../../api/AnyshiftApi';\nimport type {\n AnyshiftCapabilities,\n AskScope,\n BriefSectionName,\n ServiceBrief,\n} from '../../api/types';\nimport { AskAnyshiftCard } from '../ask/AskAnyshiftCard';\nimport { askScopeForEntity } from '../ask/askScope';\nimport { CloudAnyshiftEntityContent } from '../cloud/CloudResourceContent';\nimport { entityTarget, isCloudResourceEntity } from './entityIdentity';\nimport { resolveRelatedCatalogEntities } from './relatedCatalogEntities';\nimport {\n ArchitectureSection,\n BriefRail,\n DatadogSignalSection,\n DependencySection,\n OverviewSection,\n TimelineSection,\n WhyNowSection,\n} from './BriefSections';\n\nexport const AnyshiftEntityContent = () => {\n const { entity } = useEntity();\n return isCloudResourceEntity(entity) ? (\n <CloudAnyshiftEntityContent />\n ) : (\n <ServiceAnyshiftEntityContent />\n );\n};\n\nexport const ServiceAnyshiftEntityContent = () => {\n const { entity } = useEntity();\n const api = useApi(anyshiftApiRef);\n const catalogApi = useApiHolder().get(catalogApiRef);\n const annotations = entity.metadata.annotations ?? {};\n const target = entityTarget(entity);\n const kind = annotations[ANYSHIFT_KIND_ANNOTATION] || 'workload';\n const namespace = entity.metadata.namespace;\n const configurationEndpoints =\n annotations[ANYSHIFT_CONFIGURATION_ENDPOINTS_ANNOTATION];\n const configurationDependencies =\n annotations[ANYSHIFT_CONFIGURATION_DEPENDENCIES_ANNOTATION];\n const configurationTarget =\n annotations[ANYSHIFT_RUNTIME_RESOURCE_ID_ANNOTATION];\n const [brief, setBrief] = useState<ServiceBrief>();\n const [catalogEntities, setCatalogEntities] = useState<Entity[]>([]);\n const [capabilities, setCapabilities] = useState<AnyshiftCapabilities>({\n askEnabled: false,\n queryEnabled: false,\n });\n const [error, setError] = useState<string>();\n const [refreshingAll, setRefreshingAll] = useState(false);\n const [refreshing, setRefreshing] = useState<Set<BriefSectionName>>(\n new Set(),\n );\n const active = useRef(true);\n\n const load = useCallback(\n async (refresh = false) => {\n setError(undefined);\n if (refresh) setRefreshingAll(true);\n try {\n const next = await api.brief(kind, target, {\n namespace,\n refresh,\n configurationEndpoints,\n configurationDependencies,\n configurationTarget,\n });\n if (active.current) setBrief(next);\n } catch (cause) {\n if (active.current)\n setError(cause instanceof Error ? cause.message : String(cause));\n } finally {\n if (active.current) setRefreshingAll(false);\n }\n },\n [\n api,\n configurationDependencies,\n configurationEndpoints,\n configurationTarget,\n kind,\n namespace,\n target,\n ],\n );\n\n const retrySection = useCallback(\n async (section: BriefSectionName) => {\n setRefreshing(current => new Set(current).add(section));\n try {\n const response = await api.briefSection(kind, target, section, {\n namespace,\n refresh: true,\n configurationEndpoints,\n configurationDependencies,\n configurationTarget,\n });\n if (active.current) {\n setBrief(current =>\n current\n ? {\n ...current,\n [section]: response.value,\n refreshedAt: response.refreshedAt,\n ...(response.observedService\n ? { observedService: response.observedService }\n : {}),\n }\n : current,\n );\n }\n } finally {\n if (active.current) {\n setRefreshing(current => {\n const next = new Set(current);\n next.delete(section);\n return next;\n });\n }\n }\n },\n [\n api,\n configurationDependencies,\n configurationEndpoints,\n configurationTarget,\n kind,\n namespace,\n target,\n ],\n );\n\n useEffect(() => {\n active.current = true;\n void load();\n return () => {\n active.current = false;\n };\n }, [load]);\n\n useEffect(() => {\n let cancelled = false;\n if (!catalogApi) {\n setCatalogEntities([]);\n return () => {\n cancelled = true;\n };\n }\n catalogApi\n .getEntities({\n filter: [{ kind: 'Component' }, { kind: 'Resource' }],\n fields: ['kind', 'metadata.name', 'metadata.namespace'],\n })\n .then(response => {\n if (!cancelled) setCatalogEntities(response.items);\n })\n .catch(() => {\n if (!cancelled) setCatalogEntities([]);\n });\n return () => {\n cancelled = true;\n };\n }, [catalogApi]);\n\n useEffect(() => {\n api\n .capabilities()\n .then(next => {\n if (active.current) setCapabilities(next);\n })\n .catch(() => {\n if (active.current) {\n setCapabilities({ askEnabled: false, queryEnabled: false });\n }\n });\n }, [api]);\n\n const resolvedBrief = useMemo<ServiceBrief | undefined>(() => {\n if (!brief || brief.impact.state !== 'data' || !brief.impact.data)\n return brief;\n const impactData = brief.impact.data;\n return {\n ...brief,\n impact: {\n ...brief.impact,\n data: {\n ...impactData,\n relatedEntities: resolveRelatedCatalogEntities(\n impactData.relatedEntities,\n catalogEntities,\n ),\n },\n },\n };\n }, [brief, catalogEntities]);\n\n if (error && !resolvedBrief)\n return <Typography color=\"error\">{error}</Typography>;\n if (!resolvedBrief) return <Progress />;\n return (\n <ServiceBriefView\n brief={resolvedBrief}\n onRetry={retrySection}\n refreshing={refreshing}\n onRefresh={() => void load(true)}\n refreshingAll={refreshingAll}\n refreshError={error}\n askEnabled={capabilities.askEnabled}\n askScope={askScopeForEntity(entity)}\n />\n );\n};\n\nexport const ServiceBriefView = ({\n brief,\n onRetry,\n refreshing = new Set(),\n onRefresh = () => {},\n refreshingAll = false,\n refreshError,\n askEnabled = false,\n askScope,\n}: {\n brief: ServiceBrief;\n onRetry: (section: BriefSectionName) => void;\n refreshing?: ReadonlySet<BriefSectionName>;\n onRefresh?: () => void;\n refreshingAll?: boolean;\n refreshError?: string;\n askEnabled?: boolean;\n askScope?: AskScope;\n}) => (\n <>\n <Box\n mb={3}\n px={2.5}\n py={2}\n borderLeft={4}\n borderColor=\"primary.main\"\n bgcolor=\"background.paper\"\n >\n <Box display=\"flex\" justifyContent=\"space-between\" gridGap={16}>\n <Box>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Anyshift evidence trace\n </Typography>\n <Box display=\"flex\" flexWrap=\"wrap\" alignItems=\"center\" gridGap={8}>\n <Chip size=\"small\" label={`Workload · ${brief.target}`} />\n <Typography aria-hidden=\"true\" color=\"primary\">\n →\n </Typography>\n <Chip\n size=\"small\"\n color=\"primary\"\n label={`Observed service · ${\n brief.observedService || 'Not resolved'\n }`}\n />\n </Box>\n <Typography variant=\"caption\" color=\"textSecondary\">\n Runtime namespace: {brief.namespace || 'Not set'} · Refreshed{' '}\n {formatTimestamp(brief.refreshedAt)}\n </Typography>\n </Box>\n <Button\n type=\"button\"\n variant=\"outlined\"\n size=\"small\"\n onClick={onRefresh}\n disabled={refreshingAll}\n startIcon={refreshingAll ? <CircularProgress size={14} /> : undefined}\n >\n {refreshingAll ? 'Refreshing…' : 'Refresh brief'}\n </Button>\n </Box>\n {refreshError && (\n <Typography color=\"error\" variant=\"caption\">\n Refresh failed: {refreshError}. Existing evidence is still shown.\n </Typography>\n )}\n </Box>\n\n <Grid container spacing={3} alignItems=\"stretch\">\n <Grid item xs={12}>\n <OverviewSection\n section={brief.overview}\n onRetry={onRetry}\n refreshing={refreshing.has('overview')}\n />\n </Grid>\n <Grid item xs={12}>\n <WhyNowSection\n section={brief.whyNow}\n onRetry={onRetry}\n refreshing={refreshing.has('whyNow')}\n />\n </Grid>\n {askEnabled && (\n <Grid item xs={12}>\n <AskAnyshiftCard context=\"entity\" scope={askScope} />\n </Grid>\n )}\n <Grid item xs={12}>\n <DatadogSignalSection\n section={brief.observability}\n onRetry={onRetry}\n refreshing={refreshing.has('observability')}\n />\n </Grid>\n <Grid item xs={12}>\n <ArchitectureSection\n section={brief.architecture}\n onRetry={onRetry}\n refreshing={refreshing.has('architecture')}\n />\n </Grid>\n <Grid item xs={12} md={8}>\n <DependencySection\n section={brief.topology}\n onRetry={onRetry}\n refreshing={refreshing.has('topology')}\n />\n </Grid>\n <Grid item xs={12} md={4}>\n <BriefRail brief={brief} onRetry={onRetry} refreshing={refreshing} />\n </Grid>\n <Grid item xs={12}>\n <TimelineSection\n section={brief.timeline}\n onRetry={onRetry}\n refreshing={refreshing.has('timeline')}\n />\n </Grid>\n </Grid>\n </>\n);\n\nfunction formatTimestamp(value: string): string {\n const parsed = Date.parse(value);\n return Number.isNaN(parsed) ? value : new Date(parsed).toLocaleString();\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -188,14 +188,20 @@ const AffectedFootprintPresenter = ({
|
|
|
188
188
|
] }),
|
|
189
189
|
data.relatedEntities.length > 0 && /* @__PURE__ */ jsxs(Box, { mt: 2, children: [
|
|
190
190
|
/* @__PURE__ */ jsx(Typography, { variant: "overline", color: "textSecondary", children: "Related catalog entities" }),
|
|
191
|
-
/* @__PURE__ */ jsx(Box, { display: "flex", flexDirection: "column", gridGap: 4, children: data.relatedEntities.map((entity) => /* @__PURE__ */ jsx(
|
|
191
|
+
/* @__PURE__ */ jsx(Box, { display: "flex", flexDirection: "column", gridGap: 4, children: data.relatedEntities.map((entity, index) => /* @__PURE__ */ jsx(Box, { children: entity.entityRef ? /* @__PURE__ */ jsx(
|
|
192
192
|
EntityRefLink,
|
|
193
193
|
{
|
|
194
194
|
entityRef: entity.entityRef,
|
|
195
195
|
title: entity.name
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
|
|
196
|
+
}
|
|
197
|
+
) : /* @__PURE__ */ jsx(
|
|
198
|
+
Typography,
|
|
199
|
+
{
|
|
200
|
+
variant: "body2",
|
|
201
|
+
"aria-label": `${entity.name} (${entity.category})`,
|
|
202
|
+
children: entity.name
|
|
203
|
+
}
|
|
204
|
+
) }, `${entity.category}:${entity.name}:${index}`)) })
|
|
199
205
|
] }),
|
|
200
206
|
/* @__PURE__ */ jsx(Warnings, { warnings: data.warnings })
|
|
201
207
|
] });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SectionPresenters.esm.js","sources":["../../../src/components/entity/SectionPresenters.tsx"],"sourcesContent":["import {\n Box,\n Button,\n ButtonGroup,\n Chip,\n Divider,\n Grid,\n Typography,\n} from '@material-ui/core';\nimport type { ReactNode } from 'react';\nimport { useState } from 'react';\nimport { EntityRefLink } from '@backstage/plugin-catalog-react';\nimport type {\n EntityImpact,\n SafeguardResult,\n WhyNowAssessment,\n} from '../../api/types';\nimport { ArchitectureDiagram } from './MermaidArchitecture';\nimport { architectureGraphFrom } from './architectureGraph';\nimport { EvidenceDisclosure } from './EvidenceDisclosure';\nimport {\n eventFrom,\n factsFrom,\n firstRecordFrom,\n isRecord,\n readText,\n recordsFrom,\n statusFrom,\n type Fact,\n type StatusSummary,\n} from './sectionData';\n\nconst SAFEGUARD_LABELS: Record<SafeguardResult['capability'], string> = {\n pdb: 'Pod disruption budget',\n scaling: 'Scaling',\n priority: 'Priority',\n storage: 'Storage',\n};\n\nconst OVERVIEW_SIGNALS = [\n ['callerCount', 'Direct callers'],\n ['calleeCount', 'Direct callees'],\n ['downstreamServiceCount', 'Downstream services'],\n ['datastoreCount', 'Datastores'],\n ['externalCount', 'External systems'],\n ['eventCount24h', 'Changes · 24h'],\n] as const;\n\nexport const OverviewPresenter = ({ data }: { data: unknown }) => {\n const value = isRecord(data) ? data : {};\n return (\n <>\n <Grid container spacing={2} aria-label=\"Service signals\">\n {OVERVIEW_SIGNALS.map(([key, label]) => (\n <Grid item xs={6} sm={4} md={2} key={key}>\n <Typography variant=\"h5\">\n {typeof value[key] === 'number' ? String(value[key]) : 'N/A'}\n </Typography>\n <Typography variant=\"caption\" color=\"textSecondary\">\n {label}\n </Typography>\n </Grid>\n ))}\n <Grid item xs={6} sm={4} md={2}>\n <Typography variant=\"subtitle1\">\n {readableStatus(value.sloStatus)}\n </Typography>\n <Typography variant=\"caption\" color=\"textSecondary\">\n Service level\n </Typography>\n </Grid>\n <Grid item xs={6} sm={4} md={2}>\n <Typography variant=\"subtitle1\">\n {typeof value.activeAlertCount === 'number'\n ? `${value.activeAlertCount} active`\n : 'N/A'}\n </Typography>\n <Typography variant=\"caption\" color=\"textSecondary\">\n Alerts\n </Typography>\n </Grid>\n </Grid>\n <EvidenceDisclosure data={data} />\n </>\n );\n};\n\nexport const DependencyFootprintPresenter = ({ data }: { data: unknown }) => {\n const root = isRecord(data) ? data : {};\n const serviceTree = isRecord(root.serviceTree) ? root.serviceTree : {};\n const tree = isRecord(serviceTree.target) ? serviceTree.target : {};\n const calls = isRecord(root.calls) ? root.calls : {};\n const direct = isRecord(calls.target) ? calls.target : {};\n const callers = textArray(direct.callers);\n const callees = textArray(direct.callees);\n const configuration = isRecord(root.configuration) ? root.configuration : {};\n const configuredNodes = new Map(\n recordsFrom(configuration.nodes).flatMap(node => {\n const id = readText(node, ['id']);\n const name = readText(node, ['name']);\n return id && name ? [[id, name] as const] : [];\n }),\n );\n const configuredEdges = recordsFrom(configuration.edges);\n const configuredCallers = configuredEdges.flatMap(edge => {\n const from = readText(edge, ['from']);\n const to = readText(edge, ['to']);\n return from && to && !to.startsWith('configured:')\n ? [configuredNodes.get(from) ?? from]\n : [];\n });\n const configuredCallees = configuredEdges.flatMap(edge => {\n const to = readText(edge, ['to']);\n return to?.startsWith('configured:')\n ? [configuredNodes.get(to) ?? to.slice('configured:'.length)]\n : [];\n });\n const footprint = [\n metricLabel(tree.serviceCount, 'service', 'services'),\n metricLabel(tree.datastoreCount, 'datastore', 'datastores'),\n metricLabel(tree.externalCount, 'external', 'externals'),\n ].filter((value): value is string => Boolean(value));\n\n return (\n <>\n {tree.hasCycle === true && (\n <Box mb={2}>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n label=\"Dependency cycle detected\"\n />\n </Box>\n )}\n <Grid container spacing={3}>\n <Grid item xs={12} md={6}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Called by\n </Typography>\n <NamedResources names={callers} />\n {callers.length === 0 && <Muted>Not resolved</Muted>}\n </Grid>\n <Grid item xs={12} md={6}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Calls\n </Typography>\n <NamedResources names={callees} />\n {callees.length === 0 && <Muted>Not resolved</Muted>}\n </Grid>\n </Grid>\n {footprint.length > 0 && (\n <Box display=\"flex\" flexWrap=\"wrap\" gridGap={8} mt={2}>\n {footprint.map(item => (\n <Chip key={item} size=\"small\" variant=\"outlined\" label={item} />\n ))}\n </Box>\n )}\n {(configuredCallers.length > 0 || configuredCallees.length > 0) && (\n <Box mt={2}>\n <Chip size=\"small\" color=\"primary\" label=\"Configured evidence\" />\n <Grid container spacing={3}>\n <Grid item xs={12} md={6}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Configured callers\n </Typography>\n <NamedResources names={configuredCallers} />\n </Grid>\n <Grid item xs={12} md={6}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Configured dependencies\n </Typography>\n <NamedResources names={configuredCallees} />\n </Grid>\n </Grid>\n </Box>\n )}\n <EvidenceDisclosure data={data} />\n </>\n );\n};\n\nexport const OperationalPosturePresenter = ({ data }: { data: unknown }) => {\n const root = isRecord(data) ? data : {};\n const slo = isRecord(root.slo) ? root.slo : {};\n const sloTarget = isRecord(slo.target) ? slo.target : {};\n const alerts = isRecord(root.alerts) ? root.alerts : {};\n const deployImpact = isRecord(root.deployImpact) ? root.deployImpact : {};\n const gitops = isRecord(root.gitops) ? root.gitops : {};\n const owner = isRecord(gitops.owner) ? gitops.owner : {};\n const alertCause = isRecord(root.alertCause) ? root.alertCause : {};\n const changes = Array.isArray(alertCause.changes)\n ? alertCause.changes.length\n : undefined;\n const findings = [\n {\n label: sloTarget.status\n ? `${readableStatus(sloTarget.status)} SLO`\n : 'SLO not resolved',\n detail: readText(sloTarget, ['name']),\n },\n {\n label:\n alerts.total === 0\n ? 'No active alerts'\n : typeof alerts.total === 'number'\n ? `${alerts.total} active alerts`\n : 'Alerts not resolved',\n },\n {\n label:\n typeof deployImpact.rollouts === 'number'\n ? `${deployImpact.rollouts} rollouts · ${\n typeof deployImpact.total === 'number'\n ? deployImpact.total\n : 'N/A'\n } correlated failures`\n : 'Deployment impact not resolved',\n },\n {\n label: owner.application ? String(owner.application) : 'No GitOps owner',\n },\n {\n label:\n changes === undefined\n ? 'Recent cause not resolved'\n : `${changes} recent correlated ${\n changes === 1 ? 'change' : 'changes'\n }`,\n },\n ];\n\n return (\n <>\n <Box component=\"ul\" m={0} p={0} aria-label=\"Operational findings\">\n {findings.map((finding, index) => (\n <Box component=\"li\" key={finding.label} style={{ listStyle: 'none' }}>\n {index > 0 && <Divider />}\n <Box py={1}>\n <Typography variant=\"subtitle2\">{finding.label}</Typography>\n {finding.detail && <Muted>{finding.detail}</Muted>}\n </Box>\n </Box>\n ))}\n </Box>\n <EvidenceDisclosure data={data} />\n </>\n );\n};\n\nconst WHY_NOW_LABELS: Record<WhyNowAssessment['verdict'], string> = {\n deployment_correlated: 'Deployment correlated',\n runtime_cause_suspected: 'Runtime cause suspected',\n active_alerts: 'Active alerts',\n clear: 'No active alerts',\n insufficient_evidence: 'Insufficient evidence',\n};\n\nexport const WhyNowPresenter = ({ data }: { data: WhyNowAssessment }) => (\n <>\n <Box display=\"flex\" flexWrap=\"wrap\" alignItems=\"center\" gridGap={8} mb={1}>\n <Chip\n size=\"small\"\n color={data.verdict === 'clear' ? 'primary' : 'default'}\n label={WHY_NOW_LABELS[data.verdict]}\n />\n <Typography variant=\"subtitle1\">{data.headline}</Typography>\n </Box>\n <Grid container spacing={2}>\n <Grid item xs={12} md={4}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Current condition\n </Typography>\n <Typography variant=\"body2\">\n {typeof data.activeAlerts === 'number'\n ? `${data.activeAlerts} active ${\n data.activeAlerts === 1 ? 'alert' : 'alerts'\n }`\n : 'Alert evidence unavailable'}\n </Typography>\n {data.firingMonitors.length > 0 && (\n <NamedResources names={data.firingMonitors} />\n )}\n </Grid>\n <Grid item xs={12} md={4}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Runtime suspects · {data.evidence.runtimeWindow}\n </Typography>\n {data.suspectedChanges.length > 0 ? (\n <Box component=\"ul\" m={0} pl={2}>\n {data.suspectedChanges.map((change, index) => (\n <li key={`${change.timestamp || change.type}-${index}`}>\n <Typography variant=\"body2\">\n {change.summary || 'No graph summary was provided.'}\n </Typography>\n <Muted>{readableStatus(change.type)}</Muted>\n </li>\n ))}\n </Box>\n ) : (\n <Muted>No recent runtime suspect was resolved.</Muted>\n )}\n </Grid>\n <Grid item xs={12} md={4}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Deployment correlation · {data.evidence.deploymentWindow}\n </Typography>\n <Typography variant=\"body2\">\n {typeof data.deployment.rollouts === 'number'\n ? `${data.deployment.rollouts} ${\n data.deployment.rollouts === 1 ? 'rollout' : 'rollouts'\n } · ${\n typeof data.deployment.correlatedFailures === 'number'\n ? data.deployment.correlatedFailures\n : 'N/A'\n } correlated failures`\n : 'Deployment evidence unavailable'}\n </Typography>\n </Grid>\n </Grid>\n <Warnings warnings={data.warnings} />\n </>\n);\n\nconst IMPACT_METRICS = [\n ['affectedWorkloads', 'Affected workloads'],\n ['downstreamServices', 'Downstream services'],\n ['datastores', 'Datastores'],\n ['externalDependencies', 'External dependencies'],\n] as const;\n\nexport const AffectedFootprintPresenter = ({\n data,\n}: {\n data: EntityImpact;\n}) => (\n <>\n <Grid container spacing={2}>\n {IMPACT_METRICS.map(([key, label]) => (\n <Grid item xs={6} key={key}>\n <Typography variant=\"h5\">\n {typeof data[key] === 'number' ? data[key] : 'N/A'}\n </Typography>\n <Typography variant=\"caption\" color=\"textSecondary\">\n {label}\n </Typography>\n </Grid>\n ))}\n </Grid>\n <Box display=\"flex\" flexWrap=\"wrap\" gridGap={8} mt={2}>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n label={`${data.monitorCount ?? 'N/A'} monitors`}\n />\n <Chip\n size=\"small\"\n variant=\"outlined\"\n label={`${data.sloCount ?? 'N/A'} SLOs`}\n />\n </Box>\n {data.relatedEntities.length > 0 && (\n <Box mt={2}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Related catalog entities\n </Typography>\n <Box display=\"flex\" flexDirection=\"column\" gridGap={4}>\n {data.relatedEntities.map(entity => (\n <EntityRefLink\n key={entity.entityRef}\n entityRef={entity.entityRef}\n title={entity.name}\n />\n ))}\n </Box>\n </Box>\n )}\n <Warnings warnings={data.warnings} />\n </>\n);\n\nexport const ImpactPresenter = ({\n data,\n showEvidence = true,\n summaryMetric,\n}: {\n data: unknown;\n showEvidence?: boolean;\n summaryMetric?: false | { label: string; total: number };\n}) => {\n const affected = namedRecords(data);\n const total = numberFrom(data, ['total', 'count', 'affectedCount']);\n const status = statusFrom(data);\n const defaultTotal =\n total ?? (affected.length > 0 ? affected.length : undefined);\n const visibleSummary =\n summaryMetric === false\n ? undefined\n : summaryMetric ??\n (defaultTotal !== undefined\n ? { label: 'Affected resources', total: defaultTotal }\n : undefined);\n\n return (\n <>\n {visibleSummary && (\n <Box mb={2}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n {visibleSummary.label}\n </Typography>\n <Typography variant=\"h5\">{visibleSummary.total}</Typography>\n </Box>\n )}\n {status && <StatusChip status={status} />}\n <GenericFacts data={data} omit={['total', 'count', 'affectedCount']} />\n <NamedResources names={affected} />\n {showEvidence && <EvidenceDisclosure data={data} />}\n </>\n );\n};\n\nexport const LatestChangePresenter = ({ data }: { data: unknown }) => {\n const record = firstRecordFrom(data);\n const event = eventFrom(record);\n if (!record) {\n return <PresenterFallback data={data} />;\n }\n\n return (\n <>\n <EventHeading event={event} />\n <FactGrid facts={event.facts} />\n <EvidenceDisclosure data={data} />\n </>\n );\n};\n\nexport const SafeguardsPresenter = ({ data }: { data: SafeguardResult[] }) => (\n <>\n <Box component=\"ul\" m={0} p={0} aria-label=\"Service safeguards\">\n {data.map((item, index) => (\n <Box component=\"li\" key={item.capability} style={{ listStyle: 'none' }}>\n {index > 0 && <Divider />}\n <Box width=\"100%\" py={1}>\n <Typography variant=\"subtitle2\">\n {SAFEGUARD_LABELS[item.capability]}\n </Typography>\n <SafeguardState item={item} />\n </Box>\n </Box>\n ))}\n </Box>\n <EvidenceDisclosure data={data} />\n </>\n);\n\nexport const TimelinePresenter = ({\n data,\n fallbackLabel = 'Change recorded',\n showEvidence = true,\n}: {\n data: unknown;\n fallbackLabel?: string;\n showEvidence?: boolean;\n}) => {\n const records = recordsFrom(data).slice(0, 10);\n if (records.length === 0) return <PresenterFallback data={data} />;\n\n return (\n <>\n <Box component=\"ol\" m={0} pl={3}>\n {records.map((record, index) => {\n const event = eventFrom(record);\n return (\n <Box component=\"li\" key={eventKey(record, index)} pb={2}>\n <EventHeading event={event} fallbackLabel={fallbackLabel} />\n {event.summary && (\n <Typography variant=\"body2\">{event.summary}</Typography>\n )}\n </Box>\n );\n })}\n </Box>\n {showEvidence && <EvidenceDisclosure data={data} />}\n </>\n );\n};\n\nexport const ArchitecturePresenter = ({ data }: { data: unknown }) => {\n const graph = architectureGraphFrom(data);\n const [view, setView] = useState<'context' | 'runtime'>('context');\n if (graph.nodes.length === 0) {\n return <PresenterFallback data={data} />;\n }\n\n return (\n <>\n <Box display=\"flex\" justifyContent=\"flex-end\" mb={1}>\n <ButtonGroup size=\"small\" aria-label=\"Service map depth\">\n <Button\n type=\"button\"\n aria-pressed={view === 'context'}\n color={view === 'context' ? 'primary' : 'default'}\n onClick={() => setView('context')}\n >\n Service context\n </Button>\n <Button\n type=\"button\"\n aria-pressed={view === 'runtime'}\n color={view === 'runtime' ? 'primary' : 'default'}\n onClick={() => setView('runtime')}\n >\n Runtime detail\n </Button>\n </ButtonGroup>\n </Box>\n <ArchitectureDiagram graph={graph} view={view} />\n <EvidenceDisclosure data={data} />\n </>\n );\n};\n\nexport const GenericFacts = ({\n data,\n omit = [],\n}: {\n data: unknown;\n omit?: string[];\n}) => {\n const omitted = new Set(omit);\n const facts = factsFrom(data).filter(fact => !omitted.has(factKey(fact)));\n if (facts.length === 0) {\n return (\n <Typography variant=\"body2\" color=\"textSecondary\">\n No readable summary is available.\n </Typography>\n );\n }\n return <FactGrid facts={facts} />;\n};\n\nconst PresenterFallback = ({ data }: { data: unknown }) => (\n <>\n <GenericFacts data={data} />\n <EvidenceDisclosure data={data} />\n </>\n);\n\nconst SafeguardState = ({ item }: { item: SafeguardResult }) => {\n if (item.section.state === 'error') {\n return <Typography color=\"error\">{item.section.message}</Typography>;\n }\n if (item.section.state === 'empty' || item.section.state === 'unsupported') {\n return (\n <Typography variant=\"body2\" color=\"textSecondary\">\n {item.section.message || 'No evidence returned.'}\n </Typography>\n );\n }\n\n const names = namedRecords(item.section.data);\n return (\n <Box mt={0.5}>\n {statusFrom(item.section.data) && (\n <StatusChip status={statusFrom(item.section.data)!} />\n )}\n <GenericFacts data={item.section.data} />\n <NamedResources names={names} />\n </Box>\n );\n};\n\nconst EventHeading = ({\n event,\n fallbackLabel = 'Change recorded',\n}: {\n event: ReturnType<typeof eventFrom>;\n fallbackLabel?: string;\n}) => (\n <Box>\n <Box display=\"flex\" flexWrap=\"wrap\" alignItems=\"center\" gridGap={8}>\n <Typography variant=\"subtitle2\">{event.type || fallbackLabel}</Typography>\n {event.status && <StatusChip status={event.status} />}\n </Box>\n {event.target && <Typography variant=\"body2\">{event.target}</Typography>}\n {event.timestamp && (\n <Typography variant=\"caption\" color=\"textSecondary\">\n {formatTimestamp(event.timestamp)}\n </Typography>\n )}\n </Box>\n);\n\nconst StatusChip = ({ status }: { status: StatusSummary }) => (\n <Chip\n size=\"small\"\n variant=\"outlined\"\n color={\n status.tone === 'success'\n ? 'primary'\n : status.tone === 'warning' || status.tone === 'error'\n ? 'secondary'\n : 'default'\n }\n label={status.label}\n />\n);\n\nconst FactGrid = ({ facts }: { facts: Fact[] }) => (\n <Grid component=\"dl\" container spacing={1} style={{ margin: 0 }}>\n {facts.map(fact => (\n <Grid\n item\n xs={fact.label === 'Summary' ? 12 : 6}\n sm={fact.label === 'Summary' ? 12 : 4}\n key={`${fact.label}-${fact.value}`}\n >\n <Typography component=\"dt\" variant=\"caption\" color=\"textSecondary\">\n {fact.label}\n </Typography>\n <Typography component=\"dd\" variant=\"body2\" style={{ margin: 0 }}>\n {fact.value}\n </Typography>\n </Grid>\n ))}\n </Grid>\n);\n\nconst NamedResources = ({ names }: { names: string[] }) =>\n names.length > 0 ? (\n <Box display=\"flex\" flexWrap=\"wrap\" gridGap={6} mt={1}>\n {names.slice(0, 20).map(name => (\n <Chip key={name} size=\"small\" label={name} />\n ))}\n </Box>\n ) : null;\n\nfunction namedRecords(value: unknown): string[] {\n return [\n ...new Set(\n recordsFrom(value)\n .map(record => readText(record, ['name', 'target', 'resource', 'id']))\n .filter((name): name is string => Boolean(name)),\n ),\n ].slice(0, 20);\n}\n\nfunction numberFrom(value: unknown, keys: string[]): number | undefined {\n if (!isRecord(value)) return undefined;\n for (const key of keys) {\n if (typeof value[key] === 'number') return value[key];\n }\n return undefined;\n}\n\nfunction factKey(fact: Fact): string {\n return fact.label.replace(/\\s+/g, '').toLocaleLowerCase();\n}\n\nfunction eventKey(record: Record<string, unknown>, index: number): string {\n const identity =\n readText(record, ['id', 'ts', 'timestamp', 'time']) ?? 'event';\n return `${identity}-${index}`;\n}\n\nfunction formatTimestamp(value: string): string {\n const timestamp = Date.parse(value);\n return Number.isNaN(timestamp) ? value : new Date(timestamp).toLocaleString();\n}\n\nconst Muted = ({ children }: { children: ReactNode }) => (\n <Typography variant=\"body2\" color=\"textSecondary\">\n {children}\n </Typography>\n);\n\nconst Warnings = ({ warnings }: { warnings: string[] }) =>\n warnings.length > 0 ? (\n <Box mt={2}>\n {warnings.map(warning => (\n <Typography key={warning} variant=\"caption\" color=\"textSecondary\">\n {warning}\n </Typography>\n ))}\n </Box>\n ) : null;\n\nfunction textArray(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === 'string')\n : [];\n}\n\nfunction metricLabel(\n value: unknown,\n singular: string,\n plural: string,\n): string | undefined {\n return typeof value === 'number'\n ? `${value} ${value === 1 ? singular : plural}`\n : undefined;\n}\n\nfunction readableStatus(value: unknown): string {\n if (typeof value !== 'string' || !value) return 'Not resolved';\n return value.charAt(0).toUpperCase() + value.slice(1).replace(/_/g, ' ');\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SectionPresenters.esm.js","sources":["../../../src/components/entity/SectionPresenters.tsx"],"sourcesContent":["import {\n Box,\n Button,\n ButtonGroup,\n Chip,\n Divider,\n Grid,\n Typography,\n} from '@material-ui/core';\nimport type { ReactNode } from 'react';\nimport { useState } from 'react';\nimport { EntityRefLink } from '@backstage/plugin-catalog-react';\nimport type {\n EntityImpact,\n SafeguardResult,\n WhyNowAssessment,\n} from '../../api/types';\nimport { ArchitectureDiagram } from './MermaidArchitecture';\nimport { architectureGraphFrom } from './architectureGraph';\nimport { EvidenceDisclosure } from './EvidenceDisclosure';\nimport {\n eventFrom,\n factsFrom,\n firstRecordFrom,\n isRecord,\n readText,\n recordsFrom,\n statusFrom,\n type Fact,\n type StatusSummary,\n} from './sectionData';\n\nconst SAFEGUARD_LABELS: Record<SafeguardResult['capability'], string> = {\n pdb: 'Pod disruption budget',\n scaling: 'Scaling',\n priority: 'Priority',\n storage: 'Storage',\n};\n\nconst OVERVIEW_SIGNALS = [\n ['callerCount', 'Direct callers'],\n ['calleeCount', 'Direct callees'],\n ['downstreamServiceCount', 'Downstream services'],\n ['datastoreCount', 'Datastores'],\n ['externalCount', 'External systems'],\n ['eventCount24h', 'Changes · 24h'],\n] as const;\n\nexport const OverviewPresenter = ({ data }: { data: unknown }) => {\n const value = isRecord(data) ? data : {};\n return (\n <>\n <Grid container spacing={2} aria-label=\"Service signals\">\n {OVERVIEW_SIGNALS.map(([key, label]) => (\n <Grid item xs={6} sm={4} md={2} key={key}>\n <Typography variant=\"h5\">\n {typeof value[key] === 'number' ? String(value[key]) : 'N/A'}\n </Typography>\n <Typography variant=\"caption\" color=\"textSecondary\">\n {label}\n </Typography>\n </Grid>\n ))}\n <Grid item xs={6} sm={4} md={2}>\n <Typography variant=\"subtitle1\">\n {readableStatus(value.sloStatus)}\n </Typography>\n <Typography variant=\"caption\" color=\"textSecondary\">\n Service level\n </Typography>\n </Grid>\n <Grid item xs={6} sm={4} md={2}>\n <Typography variant=\"subtitle1\">\n {typeof value.activeAlertCount === 'number'\n ? `${value.activeAlertCount} active`\n : 'N/A'}\n </Typography>\n <Typography variant=\"caption\" color=\"textSecondary\">\n Alerts\n </Typography>\n </Grid>\n </Grid>\n <EvidenceDisclosure data={data} />\n </>\n );\n};\n\nexport const DependencyFootprintPresenter = ({ data }: { data: unknown }) => {\n const root = isRecord(data) ? data : {};\n const serviceTree = isRecord(root.serviceTree) ? root.serviceTree : {};\n const tree = isRecord(serviceTree.target) ? serviceTree.target : {};\n const calls = isRecord(root.calls) ? root.calls : {};\n const direct = isRecord(calls.target) ? calls.target : {};\n const callers = textArray(direct.callers);\n const callees = textArray(direct.callees);\n const configuration = isRecord(root.configuration) ? root.configuration : {};\n const configuredNodes = new Map(\n recordsFrom(configuration.nodes).flatMap(node => {\n const id = readText(node, ['id']);\n const name = readText(node, ['name']);\n return id && name ? [[id, name] as const] : [];\n }),\n );\n const configuredEdges = recordsFrom(configuration.edges);\n const configuredCallers = configuredEdges.flatMap(edge => {\n const from = readText(edge, ['from']);\n const to = readText(edge, ['to']);\n return from && to && !to.startsWith('configured:')\n ? [configuredNodes.get(from) ?? from]\n : [];\n });\n const configuredCallees = configuredEdges.flatMap(edge => {\n const to = readText(edge, ['to']);\n return to?.startsWith('configured:')\n ? [configuredNodes.get(to) ?? to.slice('configured:'.length)]\n : [];\n });\n const footprint = [\n metricLabel(tree.serviceCount, 'service', 'services'),\n metricLabel(tree.datastoreCount, 'datastore', 'datastores'),\n metricLabel(tree.externalCount, 'external', 'externals'),\n ].filter((value): value is string => Boolean(value));\n\n return (\n <>\n {tree.hasCycle === true && (\n <Box mb={2}>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n label=\"Dependency cycle detected\"\n />\n </Box>\n )}\n <Grid container spacing={3}>\n <Grid item xs={12} md={6}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Called by\n </Typography>\n <NamedResources names={callers} />\n {callers.length === 0 && <Muted>Not resolved</Muted>}\n </Grid>\n <Grid item xs={12} md={6}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Calls\n </Typography>\n <NamedResources names={callees} />\n {callees.length === 0 && <Muted>Not resolved</Muted>}\n </Grid>\n </Grid>\n {footprint.length > 0 && (\n <Box display=\"flex\" flexWrap=\"wrap\" gridGap={8} mt={2}>\n {footprint.map(item => (\n <Chip key={item} size=\"small\" variant=\"outlined\" label={item} />\n ))}\n </Box>\n )}\n {(configuredCallers.length > 0 || configuredCallees.length > 0) && (\n <Box mt={2}>\n <Chip size=\"small\" color=\"primary\" label=\"Configured evidence\" />\n <Grid container spacing={3}>\n <Grid item xs={12} md={6}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Configured callers\n </Typography>\n <NamedResources names={configuredCallers} />\n </Grid>\n <Grid item xs={12} md={6}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Configured dependencies\n </Typography>\n <NamedResources names={configuredCallees} />\n </Grid>\n </Grid>\n </Box>\n )}\n <EvidenceDisclosure data={data} />\n </>\n );\n};\n\nexport const OperationalPosturePresenter = ({ data }: { data: unknown }) => {\n const root = isRecord(data) ? data : {};\n const slo = isRecord(root.slo) ? root.slo : {};\n const sloTarget = isRecord(slo.target) ? slo.target : {};\n const alerts = isRecord(root.alerts) ? root.alerts : {};\n const deployImpact = isRecord(root.deployImpact) ? root.deployImpact : {};\n const gitops = isRecord(root.gitops) ? root.gitops : {};\n const owner = isRecord(gitops.owner) ? gitops.owner : {};\n const alertCause = isRecord(root.alertCause) ? root.alertCause : {};\n const changes = Array.isArray(alertCause.changes)\n ? alertCause.changes.length\n : undefined;\n const findings = [\n {\n label: sloTarget.status\n ? `${readableStatus(sloTarget.status)} SLO`\n : 'SLO not resolved',\n detail: readText(sloTarget, ['name']),\n },\n {\n label:\n alerts.total === 0\n ? 'No active alerts'\n : typeof alerts.total === 'number'\n ? `${alerts.total} active alerts`\n : 'Alerts not resolved',\n },\n {\n label:\n typeof deployImpact.rollouts === 'number'\n ? `${deployImpact.rollouts} rollouts · ${\n typeof deployImpact.total === 'number'\n ? deployImpact.total\n : 'N/A'\n } correlated failures`\n : 'Deployment impact not resolved',\n },\n {\n label: owner.application ? String(owner.application) : 'No GitOps owner',\n },\n {\n label:\n changes === undefined\n ? 'Recent cause not resolved'\n : `${changes} recent correlated ${\n changes === 1 ? 'change' : 'changes'\n }`,\n },\n ];\n\n return (\n <>\n <Box component=\"ul\" m={0} p={0} aria-label=\"Operational findings\">\n {findings.map((finding, index) => (\n <Box component=\"li\" key={finding.label} style={{ listStyle: 'none' }}>\n {index > 0 && <Divider />}\n <Box py={1}>\n <Typography variant=\"subtitle2\">{finding.label}</Typography>\n {finding.detail && <Muted>{finding.detail}</Muted>}\n </Box>\n </Box>\n ))}\n </Box>\n <EvidenceDisclosure data={data} />\n </>\n );\n};\n\nconst WHY_NOW_LABELS: Record<WhyNowAssessment['verdict'], string> = {\n deployment_correlated: 'Deployment correlated',\n runtime_cause_suspected: 'Runtime cause suspected',\n active_alerts: 'Active alerts',\n clear: 'No active alerts',\n insufficient_evidence: 'Insufficient evidence',\n};\n\nexport const WhyNowPresenter = ({ data }: { data: WhyNowAssessment }) => (\n <>\n <Box display=\"flex\" flexWrap=\"wrap\" alignItems=\"center\" gridGap={8} mb={1}>\n <Chip\n size=\"small\"\n color={data.verdict === 'clear' ? 'primary' : 'default'}\n label={WHY_NOW_LABELS[data.verdict]}\n />\n <Typography variant=\"subtitle1\">{data.headline}</Typography>\n </Box>\n <Grid container spacing={2}>\n <Grid item xs={12} md={4}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Current condition\n </Typography>\n <Typography variant=\"body2\">\n {typeof data.activeAlerts === 'number'\n ? `${data.activeAlerts} active ${\n data.activeAlerts === 1 ? 'alert' : 'alerts'\n }`\n : 'Alert evidence unavailable'}\n </Typography>\n {data.firingMonitors.length > 0 && (\n <NamedResources names={data.firingMonitors} />\n )}\n </Grid>\n <Grid item xs={12} md={4}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Runtime suspects · {data.evidence.runtimeWindow}\n </Typography>\n {data.suspectedChanges.length > 0 ? (\n <Box component=\"ul\" m={0} pl={2}>\n {data.suspectedChanges.map((change, index) => (\n <li key={`${change.timestamp || change.type}-${index}`}>\n <Typography variant=\"body2\">\n {change.summary || 'No graph summary was provided.'}\n </Typography>\n <Muted>{readableStatus(change.type)}</Muted>\n </li>\n ))}\n </Box>\n ) : (\n <Muted>No recent runtime suspect was resolved.</Muted>\n )}\n </Grid>\n <Grid item xs={12} md={4}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Deployment correlation · {data.evidence.deploymentWindow}\n </Typography>\n <Typography variant=\"body2\">\n {typeof data.deployment.rollouts === 'number'\n ? `${data.deployment.rollouts} ${\n data.deployment.rollouts === 1 ? 'rollout' : 'rollouts'\n } · ${\n typeof data.deployment.correlatedFailures === 'number'\n ? data.deployment.correlatedFailures\n : 'N/A'\n } correlated failures`\n : 'Deployment evidence unavailable'}\n </Typography>\n </Grid>\n </Grid>\n <Warnings warnings={data.warnings} />\n </>\n);\n\nconst IMPACT_METRICS = [\n ['affectedWorkloads', 'Affected workloads'],\n ['downstreamServices', 'Downstream services'],\n ['datastores', 'Datastores'],\n ['externalDependencies', 'External dependencies'],\n] as const;\n\nexport const AffectedFootprintPresenter = ({\n data,\n}: {\n data: EntityImpact;\n}) => (\n <>\n <Grid container spacing={2}>\n {IMPACT_METRICS.map(([key, label]) => (\n <Grid item xs={6} key={key}>\n <Typography variant=\"h5\">\n {typeof data[key] === 'number' ? data[key] : 'N/A'}\n </Typography>\n <Typography variant=\"caption\" color=\"textSecondary\">\n {label}\n </Typography>\n </Grid>\n ))}\n </Grid>\n <Box display=\"flex\" flexWrap=\"wrap\" gridGap={8} mt={2}>\n <Chip\n size=\"small\"\n variant=\"outlined\"\n label={`${data.monitorCount ?? 'N/A'} monitors`}\n />\n <Chip\n size=\"small\"\n variant=\"outlined\"\n label={`${data.sloCount ?? 'N/A'} SLOs`}\n />\n </Box>\n {data.relatedEntities.length > 0 && (\n <Box mt={2}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n Related catalog entities\n </Typography>\n <Box display=\"flex\" flexDirection=\"column\" gridGap={4}>\n {data.relatedEntities.map((entity, index) => (\n <Box key={`${entity.category}:${entity.name}:${index}`}>\n {entity.entityRef ? (\n <EntityRefLink\n entityRef={entity.entityRef}\n title={entity.name}\n />\n ) : (\n <Typography\n variant=\"body2\"\n aria-label={`${entity.name} (${entity.category})`}\n >\n {entity.name}\n </Typography>\n )}\n </Box>\n ))}\n </Box>\n </Box>\n )}\n <Warnings warnings={data.warnings} />\n </>\n);\n\nexport const ImpactPresenter = ({\n data,\n showEvidence = true,\n summaryMetric,\n}: {\n data: unknown;\n showEvidence?: boolean;\n summaryMetric?: false | { label: string; total: number };\n}) => {\n const affected = namedRecords(data);\n const total = numberFrom(data, ['total', 'count', 'affectedCount']);\n const status = statusFrom(data);\n const defaultTotal =\n total ?? (affected.length > 0 ? affected.length : undefined);\n const visibleSummary =\n summaryMetric === false\n ? undefined\n : summaryMetric ??\n (defaultTotal !== undefined\n ? { label: 'Affected resources', total: defaultTotal }\n : undefined);\n\n return (\n <>\n {visibleSummary && (\n <Box mb={2}>\n <Typography variant=\"overline\" color=\"textSecondary\">\n {visibleSummary.label}\n </Typography>\n <Typography variant=\"h5\">{visibleSummary.total}</Typography>\n </Box>\n )}\n {status && <StatusChip status={status} />}\n <GenericFacts data={data} omit={['total', 'count', 'affectedCount']} />\n <NamedResources names={affected} />\n {showEvidence && <EvidenceDisclosure data={data} />}\n </>\n );\n};\n\nexport const LatestChangePresenter = ({ data }: { data: unknown }) => {\n const record = firstRecordFrom(data);\n const event = eventFrom(record);\n if (!record) {\n return <PresenterFallback data={data} />;\n }\n\n return (\n <>\n <EventHeading event={event} />\n <FactGrid facts={event.facts} />\n <EvidenceDisclosure data={data} />\n </>\n );\n};\n\nexport const SafeguardsPresenter = ({ data }: { data: SafeguardResult[] }) => (\n <>\n <Box component=\"ul\" m={0} p={0} aria-label=\"Service safeguards\">\n {data.map((item, index) => (\n <Box component=\"li\" key={item.capability} style={{ listStyle: 'none' }}>\n {index > 0 && <Divider />}\n <Box width=\"100%\" py={1}>\n <Typography variant=\"subtitle2\">\n {SAFEGUARD_LABELS[item.capability]}\n </Typography>\n <SafeguardState item={item} />\n </Box>\n </Box>\n ))}\n </Box>\n <EvidenceDisclosure data={data} />\n </>\n);\n\nexport const TimelinePresenter = ({\n data,\n fallbackLabel = 'Change recorded',\n showEvidence = true,\n}: {\n data: unknown;\n fallbackLabel?: string;\n showEvidence?: boolean;\n}) => {\n const records = recordsFrom(data).slice(0, 10);\n if (records.length === 0) return <PresenterFallback data={data} />;\n\n return (\n <>\n <Box component=\"ol\" m={0} pl={3}>\n {records.map((record, index) => {\n const event = eventFrom(record);\n return (\n <Box component=\"li\" key={eventKey(record, index)} pb={2}>\n <EventHeading event={event} fallbackLabel={fallbackLabel} />\n {event.summary && (\n <Typography variant=\"body2\">{event.summary}</Typography>\n )}\n </Box>\n );\n })}\n </Box>\n {showEvidence && <EvidenceDisclosure data={data} />}\n </>\n );\n};\n\nexport const ArchitecturePresenter = ({ data }: { data: unknown }) => {\n const graph = architectureGraphFrom(data);\n const [view, setView] = useState<'context' | 'runtime'>('context');\n if (graph.nodes.length === 0) {\n return <PresenterFallback data={data} />;\n }\n\n return (\n <>\n <Box display=\"flex\" justifyContent=\"flex-end\" mb={1}>\n <ButtonGroup size=\"small\" aria-label=\"Service map depth\">\n <Button\n type=\"button\"\n aria-pressed={view === 'context'}\n color={view === 'context' ? 'primary' : 'default'}\n onClick={() => setView('context')}\n >\n Service context\n </Button>\n <Button\n type=\"button\"\n aria-pressed={view === 'runtime'}\n color={view === 'runtime' ? 'primary' : 'default'}\n onClick={() => setView('runtime')}\n >\n Runtime detail\n </Button>\n </ButtonGroup>\n </Box>\n <ArchitectureDiagram graph={graph} view={view} />\n <EvidenceDisclosure data={data} />\n </>\n );\n};\n\nexport const GenericFacts = ({\n data,\n omit = [],\n}: {\n data: unknown;\n omit?: string[];\n}) => {\n const omitted = new Set(omit);\n const facts = factsFrom(data).filter(fact => !omitted.has(factKey(fact)));\n if (facts.length === 0) {\n return (\n <Typography variant=\"body2\" color=\"textSecondary\">\n No readable summary is available.\n </Typography>\n );\n }\n return <FactGrid facts={facts} />;\n};\n\nconst PresenterFallback = ({ data }: { data: unknown }) => (\n <>\n <GenericFacts data={data} />\n <EvidenceDisclosure data={data} />\n </>\n);\n\nconst SafeguardState = ({ item }: { item: SafeguardResult }) => {\n if (item.section.state === 'error') {\n return <Typography color=\"error\">{item.section.message}</Typography>;\n }\n if (item.section.state === 'empty' || item.section.state === 'unsupported') {\n return (\n <Typography variant=\"body2\" color=\"textSecondary\">\n {item.section.message || 'No evidence returned.'}\n </Typography>\n );\n }\n\n const names = namedRecords(item.section.data);\n return (\n <Box mt={0.5}>\n {statusFrom(item.section.data) && (\n <StatusChip status={statusFrom(item.section.data)!} />\n )}\n <GenericFacts data={item.section.data} />\n <NamedResources names={names} />\n </Box>\n );\n};\n\nconst EventHeading = ({\n event,\n fallbackLabel = 'Change recorded',\n}: {\n event: ReturnType<typeof eventFrom>;\n fallbackLabel?: string;\n}) => (\n <Box>\n <Box display=\"flex\" flexWrap=\"wrap\" alignItems=\"center\" gridGap={8}>\n <Typography variant=\"subtitle2\">{event.type || fallbackLabel}</Typography>\n {event.status && <StatusChip status={event.status} />}\n </Box>\n {event.target && <Typography variant=\"body2\">{event.target}</Typography>}\n {event.timestamp && (\n <Typography variant=\"caption\" color=\"textSecondary\">\n {formatTimestamp(event.timestamp)}\n </Typography>\n )}\n </Box>\n);\n\nconst StatusChip = ({ status }: { status: StatusSummary }) => (\n <Chip\n size=\"small\"\n variant=\"outlined\"\n color={\n status.tone === 'success'\n ? 'primary'\n : status.tone === 'warning' || status.tone === 'error'\n ? 'secondary'\n : 'default'\n }\n label={status.label}\n />\n);\n\nconst FactGrid = ({ facts }: { facts: Fact[] }) => (\n <Grid component=\"dl\" container spacing={1} style={{ margin: 0 }}>\n {facts.map(fact => (\n <Grid\n item\n xs={fact.label === 'Summary' ? 12 : 6}\n sm={fact.label === 'Summary' ? 12 : 4}\n key={`${fact.label}-${fact.value}`}\n >\n <Typography component=\"dt\" variant=\"caption\" color=\"textSecondary\">\n {fact.label}\n </Typography>\n <Typography component=\"dd\" variant=\"body2\" style={{ margin: 0 }}>\n {fact.value}\n </Typography>\n </Grid>\n ))}\n </Grid>\n);\n\nconst NamedResources = ({ names }: { names: string[] }) =>\n names.length > 0 ? (\n <Box display=\"flex\" flexWrap=\"wrap\" gridGap={6} mt={1}>\n {names.slice(0, 20).map(name => (\n <Chip key={name} size=\"small\" label={name} />\n ))}\n </Box>\n ) : null;\n\nfunction namedRecords(value: unknown): string[] {\n return [\n ...new Set(\n recordsFrom(value)\n .map(record => readText(record, ['name', 'target', 'resource', 'id']))\n .filter((name): name is string => Boolean(name)),\n ),\n ].slice(0, 20);\n}\n\nfunction numberFrom(value: unknown, keys: string[]): number | undefined {\n if (!isRecord(value)) return undefined;\n for (const key of keys) {\n if (typeof value[key] === 'number') return value[key];\n }\n return undefined;\n}\n\nfunction factKey(fact: Fact): string {\n return fact.label.replace(/\\s+/g, '').toLocaleLowerCase();\n}\n\nfunction eventKey(record: Record<string, unknown>, index: number): string {\n const identity =\n readText(record, ['id', 'ts', 'timestamp', 'time']) ?? 'event';\n return `${identity}-${index}`;\n}\n\nfunction formatTimestamp(value: string): string {\n const timestamp = Date.parse(value);\n return Number.isNaN(timestamp) ? value : new Date(timestamp).toLocaleString();\n}\n\nconst Muted = ({ children }: { children: ReactNode }) => (\n <Typography variant=\"body2\" color=\"textSecondary\">\n {children}\n </Typography>\n);\n\nconst Warnings = ({ warnings }: { warnings: string[] }) =>\n warnings.length > 0 ? (\n <Box mt={2}>\n {warnings.map(warning => (\n <Typography key={warning} variant=\"caption\" color=\"textSecondary\">\n {warning}\n </Typography>\n ))}\n </Box>\n ) : null;\n\nfunction textArray(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === 'string')\n : [];\n}\n\nfunction metricLabel(\n value: unknown,\n singular: string,\n plural: string,\n): string | undefined {\n return typeof value === 'number'\n ? `${value} ${value === 1 ? singular : plural}`\n : undefined;\n}\n\nfunction readableStatus(value: unknown): string {\n if (typeof value !== 'string' || !value) return 'Not resolved';\n return value.charAt(0).toUpperCase() + value.slice(1).replace(/_/g, ' ');\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,16 @@ function cloudResourceIdentity(entity) {
|
|
|
9
9
|
const annotations = entity.metadata.annotations ?? {};
|
|
10
10
|
return annotationValue(annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION]) ?? annotationValue(annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION]);
|
|
11
11
|
}
|
|
12
|
+
function cloudResourceFallbackIdentity(entity) {
|
|
13
|
+
const annotations = entity.metadata.annotations ?? {};
|
|
14
|
+
const resourceId = annotationValue(
|
|
15
|
+
annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION]
|
|
16
|
+
);
|
|
17
|
+
const arn = annotationValue(
|
|
18
|
+
annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION]
|
|
19
|
+
);
|
|
20
|
+
return arn && arn !== resourceId ? arn : void 0;
|
|
21
|
+
}
|
|
12
22
|
function cloudResourceAskTarget(entity) {
|
|
13
23
|
const annotations = entity.metadata.annotations ?? {};
|
|
14
24
|
return annotationValue(annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION]) ?? annotationValue(annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION]);
|
|
@@ -26,5 +36,5 @@ function annotationValue(value) {
|
|
|
26
36
|
return trimmed || void 0;
|
|
27
37
|
}
|
|
28
38
|
|
|
29
|
-
export { cloudResourceAskTarget, cloudResourceIdentity, entityTarget, isCloudResourceEntity };
|
|
39
|
+
export { cloudResourceAskTarget, cloudResourceFallbackIdentity, cloudResourceIdentity, entityTarget, isCloudResourceEntity };
|
|
30
40
|
//# sourceMappingURL=entityIdentity.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entityIdentity.esm.js","sources":["../../../src/components/entity/entityIdentity.ts"],"sourcesContent":["import type { Entity } from '@backstage/catalog-model';\nimport {\n ANYSHIFT_CLOUD_PROVIDER_ANNOTATION,\n ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION,\n ANYSHIFT_RESOURCE_ID_ANNOTATION,\n ANYSHIFT_TARGET_ANNOTATION,\n GITHUB_PROJECT_SLUG_ANNOTATION,\n} from '@anyshift/backstage-plugin-anyshift-common';\n\nexport function isCloudResourceEntity(entity: Entity): boolean {\n return (\n entity.kind.toLocaleLowerCase('en-US') === 'resource' &&\n Boolean(\n entity.metadata.annotations?.[ANYSHIFT_CLOUD_PROVIDER_ANNOTATION]?.trim(),\n )\n );\n}\n\nexport function cloudResourceIdentity(entity: Entity): string | undefined {\n const annotations = entity.metadata.annotations ?? {};\n return (\n annotationValue(annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION]) ??\n annotationValue(annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION])\n );\n}\n\nexport function cloudResourceAskTarget(entity: Entity): string | undefined {\n const annotations = entity.metadata.annotations ?? {};\n return (\n annotationValue(annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION]) ??\n annotationValue(annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION])\n );\n}\n\nexport function entityTarget(entity: Entity): string {\n const annotations = entity.metadata.annotations ?? {};\n const explicit = annotationValue(annotations[ANYSHIFT_TARGET_ANNOTATION]);\n if (explicit) return explicit;\n\n const slug = annotationValue(annotations[GITHUB_PROJECT_SLUG_ANNOTATION]);\n const repository = slug?.split('/').filter(Boolean).at(-1);\n return repository || entity.metadata.name;\n}\n\nfunction annotationValue(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed || undefined;\n}\n"],"names":[],"mappings":";;AASO,SAAS,sBAAsB,MAAA,EAAyB;AAC7D,EAAA,OACE,MAAA,CAAO,IAAA,CAAK,iBAAA,CAAkB,OAAO,MAAM,UAAA,IAC3C,OAAA;AAAA,IACE,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,kCAAkC,GAAG,IAAA;AAAK,GAC1E;AAEJ;AAEO,SAAS,sBAAsB,MAAA,EAAoC;AACxE,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AACpD,EAAA,OACE,eAAA,CAAgB,YAAY,+BAA+B,CAAC,KAC5D,eAAA,CAAgB,WAAA,CAAY,sCAAsC,CAAC,CAAA;AAEvE;AAEO,SAAS,uBAAuB,MAAA,EAAoC;AACzE,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AACpD,EAAA,OACE,eAAA,CAAgB,YAAY,sCAAsC,CAAC,KACnE,eAAA,CAAgB,WAAA,CAAY,+BAA+B,CAAC,CAAA;AAEhE;AAEO,SAAS,aAAa,MAAA,EAAwB;AACnD,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AACpD,EAAA,MAAM,QAAA,GAAW,eAAA,CAAgB,WAAA,CAAY,0BAA0B,CAAC,CAAA;AACxE,EAAA,IAAI,UAAU,OAAO,QAAA;AAErB,EAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,WAAA,CAAY,8BAA8B,CAAC,CAAA;AACxE,EAAA,MAAM,UAAA,GAAa,MAAM,KAAA,CAAM,GAAG,EAAE,MAAA,CAAO,OAAO,CAAA,CAAE,EAAA,CAAG,EAAE,CAAA;AACzD,EAAA,OAAO,UAAA,IAAc,OAAO,QAAA,CAAS,IAAA;AACvC;AAEA,SAAS,gBAAgB,KAAA,EAA+C;AACtE,EAAA,MAAM,OAAA,GAAU,OAAO,IAAA,EAAK;AAC5B,EAAA,OAAO,OAAA,IAAW,MAAA;AACpB;;;;"}
|
|
1
|
+
{"version":3,"file":"entityIdentity.esm.js","sources":["../../../src/components/entity/entityIdentity.ts"],"sourcesContent":["import type { Entity } from '@backstage/catalog-model';\nimport {\n ANYSHIFT_CLOUD_PROVIDER_ANNOTATION,\n ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION,\n ANYSHIFT_RESOURCE_ID_ANNOTATION,\n ANYSHIFT_TARGET_ANNOTATION,\n GITHUB_PROJECT_SLUG_ANNOTATION,\n} from '@anyshift/backstage-plugin-anyshift-common';\n\nexport function isCloudResourceEntity(entity: Entity): boolean {\n return (\n entity.kind.toLocaleLowerCase('en-US') === 'resource' &&\n Boolean(\n entity.metadata.annotations?.[ANYSHIFT_CLOUD_PROVIDER_ANNOTATION]?.trim(),\n )\n );\n}\n\nexport function cloudResourceIdentity(entity: Entity): string | undefined {\n const annotations = entity.metadata.annotations ?? {};\n return (\n annotationValue(annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION]) ??\n annotationValue(annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION])\n );\n}\n\nexport function cloudResourceFallbackIdentity(\n entity: Entity,\n): string | undefined {\n const annotations = entity.metadata.annotations ?? {};\n const resourceId = annotationValue(\n annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION],\n );\n const arn = annotationValue(\n annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION],\n );\n return arn && arn !== resourceId ? arn : undefined;\n}\n\nexport function cloudResourceAskTarget(entity: Entity): string | undefined {\n const annotations = entity.metadata.annotations ?? {};\n return (\n annotationValue(annotations[ANYSHIFT_CLOUD_RESOURCE_ARN_ANNOTATION]) ??\n annotationValue(annotations[ANYSHIFT_RESOURCE_ID_ANNOTATION])\n );\n}\n\nexport function entityTarget(entity: Entity): string {\n const annotations = entity.metadata.annotations ?? {};\n const explicit = annotationValue(annotations[ANYSHIFT_TARGET_ANNOTATION]);\n if (explicit) return explicit;\n\n const slug = annotationValue(annotations[GITHUB_PROJECT_SLUG_ANNOTATION]);\n const repository = slug?.split('/').filter(Boolean).at(-1);\n return repository || entity.metadata.name;\n}\n\nfunction annotationValue(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed || undefined;\n}\n"],"names":[],"mappings":";;AASO,SAAS,sBAAsB,MAAA,EAAyB;AAC7D,EAAA,OACE,MAAA,CAAO,IAAA,CAAK,iBAAA,CAAkB,OAAO,MAAM,UAAA,IAC3C,OAAA;AAAA,IACE,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,kCAAkC,GAAG,IAAA;AAAK,GAC1E;AAEJ;AAEO,SAAS,sBAAsB,MAAA,EAAoC;AACxE,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AACpD,EAAA,OACE,eAAA,CAAgB,YAAY,+BAA+B,CAAC,KAC5D,eAAA,CAAgB,WAAA,CAAY,sCAAsC,CAAC,CAAA;AAEvE;AAEO,SAAS,8BACd,MAAA,EACoB;AACpB,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AACpD,EAAA,MAAM,UAAA,GAAa,eAAA;AAAA,IACjB,YAAY,+BAA+B;AAAA,GAC7C;AACA,EAAA,MAAM,GAAA,GAAM,eAAA;AAAA,IACV,YAAY,sCAAsC;AAAA,GACpD;AACA,EAAA,OAAO,GAAA,IAAO,GAAA,KAAQ,UAAA,GAAa,GAAA,GAAM,MAAA;AAC3C;AAEO,SAAS,uBAAuB,MAAA,EAAoC;AACzE,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AACpD,EAAA,OACE,eAAA,CAAgB,YAAY,sCAAsC,CAAC,KACnE,eAAA,CAAgB,WAAA,CAAY,+BAA+B,CAAC,CAAA;AAEhE;AAEO,SAAS,aAAa,MAAA,EAAwB;AACnD,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AACpD,EAAA,MAAM,QAAA,GAAW,eAAA,CAAgB,WAAA,CAAY,0BAA0B,CAAC,CAAA;AACxE,EAAA,IAAI,UAAU,OAAO,QAAA;AAErB,EAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,WAAA,CAAY,8BAA8B,CAAC,CAAA;AACxE,EAAA,MAAM,UAAA,GAAa,MAAM,KAAA,CAAM,GAAG,EAAE,MAAA,CAAO,OAAO,CAAA,CAAE,EAAA,CAAG,EAAE,CAAA;AACzD,EAAA,OAAO,UAAA,IAAc,OAAO,QAAA,CAAS,IAAA;AACvC;AAEA,SAAS,gBAAgB,KAAA,EAA+C;AACtE,EAAA,MAAM,OAAA,GAAU,OAAO,IAAA,EAAK;AAC5B,EAAA,OAAO,OAAA,IAAW,MAAA;AACpB;;;;"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { stringifyEntityRef, parseEntityRef } from '@backstage/catalog-model';
|
|
2
|
+
|
|
3
|
+
const normalizeEntityName = (value) => value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 63).replace(/-+$/g, "");
|
|
4
|
+
const canonicalEntityRef = (value) => {
|
|
5
|
+
try {
|
|
6
|
+
return stringifyEntityRef(parseEntityRef(value));
|
|
7
|
+
} catch {
|
|
8
|
+
return void 0;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const addCandidate = (index, name, entityRef) => {
|
|
12
|
+
const key = normalizeEntityName(name);
|
|
13
|
+
if (!key) return;
|
|
14
|
+
const refs = index.get(key) ?? [];
|
|
15
|
+
if (!refs.includes(entityRef)) refs.push(entityRef);
|
|
16
|
+
index.set(key, refs);
|
|
17
|
+
};
|
|
18
|
+
const resolveRelatedCatalogEntities = (relatedEntities, catalogEntities) => {
|
|
19
|
+
const catalogRefs = /* @__PURE__ */ new Set();
|
|
20
|
+
const componentsByName = /* @__PURE__ */ new Map();
|
|
21
|
+
const resourcesByName = /* @__PURE__ */ new Map();
|
|
22
|
+
for (const entity of catalogEntities) {
|
|
23
|
+
const kind = entity.kind.toLowerCase();
|
|
24
|
+
if (kind !== "component" && kind !== "resource") continue;
|
|
25
|
+
const entityRef = stringifyEntityRef(entity);
|
|
26
|
+
catalogRefs.add(entityRef);
|
|
27
|
+
addCandidate(
|
|
28
|
+
kind === "component" ? componentsByName : resourcesByName,
|
|
29
|
+
entity.metadata.name,
|
|
30
|
+
entityRef
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
const seenNames = /* @__PURE__ */ new Set();
|
|
34
|
+
const resolved = [];
|
|
35
|
+
for (const related of relatedEntities) {
|
|
36
|
+
const logicalName = normalizeEntityName(related.name);
|
|
37
|
+
if (seenNames.has(logicalName)) continue;
|
|
38
|
+
seenNames.add(logicalName);
|
|
39
|
+
const legacyRef = related.entityRef ? canonicalEntityRef(related.entityRef) : void 0;
|
|
40
|
+
let entityRef = legacyRef && catalogRefs.has(legacyRef) ? legacyRef : void 0;
|
|
41
|
+
if (!entityRef) {
|
|
42
|
+
const componentMatches = componentsByName.get(logicalName) ?? [];
|
|
43
|
+
if (componentMatches.length === 1) {
|
|
44
|
+
[entityRef] = componentMatches;
|
|
45
|
+
} else if (componentMatches.length === 0) {
|
|
46
|
+
const resourceMatches = resourcesByName.get(logicalName) ?? [];
|
|
47
|
+
if (resourceMatches.length === 1) [entityRef] = resourceMatches;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
resolved.push({
|
|
51
|
+
name: related.name,
|
|
52
|
+
category: related.category,
|
|
53
|
+
...entityRef ? { entityRef } : {}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return resolved;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export { resolveRelatedCatalogEntities };
|
|
60
|
+
//# sourceMappingURL=relatedCatalogEntities.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relatedCatalogEntities.esm.js","sources":["../../../src/components/entity/relatedCatalogEntities.ts"],"sourcesContent":["import {\n parseEntityRef,\n stringifyEntityRef,\n type Entity,\n} from '@backstage/catalog-model';\nimport type { EntityImpactRelatedEntity } from '../../api/types';\n\nconst normalizeEntityName = (value: string): string =>\n value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 63)\n .replace(/-+$/g, '');\n\nconst canonicalEntityRef = (value: string): string | undefined => {\n try {\n return stringifyEntityRef(parseEntityRef(value));\n } catch {\n return undefined;\n }\n};\n\nconst addCandidate = (\n index: Map<string, string[]>,\n name: string,\n entityRef: string,\n) => {\n const key = normalizeEntityName(name);\n if (!key) return;\n const refs = index.get(key) ?? [];\n if (!refs.includes(entityRef)) refs.push(entityRef);\n index.set(key, refs);\n};\n\nexport const resolveRelatedCatalogEntities = (\n relatedEntities: EntityImpactRelatedEntity[],\n catalogEntities: Entity[],\n): EntityImpactRelatedEntity[] => {\n const catalogRefs = new Set<string>();\n const componentsByName = new Map<string, string[]>();\n const resourcesByName = new Map<string, string[]>();\n\n for (const entity of catalogEntities) {\n const kind = entity.kind.toLowerCase();\n if (kind !== 'component' && kind !== 'resource') continue;\n const entityRef = stringifyEntityRef(entity);\n catalogRefs.add(entityRef);\n addCandidate(\n kind === 'component' ? componentsByName : resourcesByName,\n entity.metadata.name,\n entityRef,\n );\n }\n\n const seenNames = new Set<string>();\n const resolved: EntityImpactRelatedEntity[] = [];\n\n for (const related of relatedEntities) {\n const logicalName = normalizeEntityName(related.name);\n if (seenNames.has(logicalName)) continue;\n seenNames.add(logicalName);\n\n const legacyRef = related.entityRef\n ? canonicalEntityRef(related.entityRef)\n : undefined;\n let entityRef =\n legacyRef && catalogRefs.has(legacyRef) ? legacyRef : undefined;\n\n if (!entityRef) {\n const componentMatches = componentsByName.get(logicalName) ?? [];\n if (componentMatches.length === 1) {\n [entityRef] = componentMatches;\n } else if (componentMatches.length === 0) {\n const resourceMatches = resourcesByName.get(logicalName) ?? [];\n if (resourceMatches.length === 1) [entityRef] = resourceMatches;\n }\n }\n\n resolved.push({\n name: related.name,\n category: related.category,\n ...(entityRef ? { entityRef } : {}),\n });\n }\n\n return resolved;\n};\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
package/dist/package.json.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
var name = "@anyshift/backstage-plugin-anyshift";
|
|
2
|
-
var version = "0.1.0-beta.
|
|
2
|
+
var version = "0.1.0-beta.16";
|
|
3
3
|
var description = "Read-only Anyshift infrastructure context for Backstage";
|
|
4
4
|
var main = "src/index.ts";
|
|
5
5
|
var types = "src/index.ts";
|
|
@@ -46,27 +46,27 @@ var scripts = {
|
|
|
46
46
|
var dependencies = {
|
|
47
47
|
"@anyshift/backstage-plugin-anyshift-common": "workspace:^",
|
|
48
48
|
"@backstage/catalog-model": "^1.9.0",
|
|
49
|
-
"@backstage/core-components": "^0.18.
|
|
50
|
-
"@backstage/frontend-plugin-api": "^0.17.
|
|
51
|
-
"@backstage/plugin-catalog-react": "^3.
|
|
52
|
-
"@backstage/plugin-permission-react": "^0.5.
|
|
49
|
+
"@backstage/core-components": "^0.18.12",
|
|
50
|
+
"@backstage/frontend-plugin-api": "^0.17.3",
|
|
51
|
+
"@backstage/plugin-catalog-react": "^3.2.0",
|
|
52
|
+
"@backstage/plugin-permission-react": "^0.5.3",
|
|
53
53
|
"@backstage/theme": "^0.7.3",
|
|
54
54
|
"@material-ui/core": "^4.12.2",
|
|
55
55
|
"@material-ui/icons": "^4.9.1",
|
|
56
56
|
"@material-ui/lab": "^4.0.0-alpha.61",
|
|
57
|
-
mermaid: "^11.
|
|
57
|
+
mermaid: "^11.16.1"
|
|
58
58
|
};
|
|
59
59
|
var peerDependencies = {
|
|
60
60
|
react: "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
61
61
|
"react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
62
|
-
"react-router-dom": "^6.0.0"
|
|
62
|
+
"react-router-dom": "^6.0.0 || ^7.0.0"
|
|
63
63
|
};
|
|
64
64
|
var devDependencies = {
|
|
65
|
-
"@backstage/cli": "^0.36.
|
|
66
|
-
"@backstage/test-utils": "^1.7.
|
|
65
|
+
"@backstage/cli": "^0.36.4",
|
|
66
|
+
"@backstage/test-utils": "^1.7.20",
|
|
67
67
|
"@testing-library/jest-dom": "^6.0.0",
|
|
68
68
|
"@testing-library/react": "^14.0.0",
|
|
69
|
-
"@testing-library/user-event": "^14.
|
|
69
|
+
"@testing-library/user-event": "^14.6.3",
|
|
70
70
|
msw: "^1.0.0"
|
|
71
71
|
};
|
|
72
72
|
var files = [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anyshift/backstage-plugin-anyshift",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.16",
|
|
4
4
|
"description": "Read-only Anyshift infrastructure context for Backstage",
|
|
5
5
|
"main": "dist/index.esm.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -45,29 +45,29 @@
|
|
|
45
45
|
"clean": "backstage-cli package clean"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@anyshift/backstage-plugin-anyshift-common": "^0.1.0-beta.
|
|
48
|
+
"@anyshift/backstage-plugin-anyshift-common": "^0.1.0-beta.14",
|
|
49
49
|
"@backstage/catalog-model": "^1.9.0",
|
|
50
|
-
"@backstage/core-components": "^0.18.
|
|
51
|
-
"@backstage/frontend-plugin-api": "^0.17.
|
|
52
|
-
"@backstage/plugin-catalog-react": "^3.
|
|
53
|
-
"@backstage/plugin-permission-react": "^0.5.
|
|
50
|
+
"@backstage/core-components": "^0.18.12",
|
|
51
|
+
"@backstage/frontend-plugin-api": "^0.17.3",
|
|
52
|
+
"@backstage/plugin-catalog-react": "^3.2.0",
|
|
53
|
+
"@backstage/plugin-permission-react": "^0.5.3",
|
|
54
54
|
"@backstage/theme": "^0.7.3",
|
|
55
55
|
"@material-ui/core": "^4.12.2",
|
|
56
56
|
"@material-ui/icons": "^4.9.1",
|
|
57
57
|
"@material-ui/lab": "^4.0.0-alpha.61",
|
|
58
|
-
"mermaid": "^11.
|
|
58
|
+
"mermaid": "^11.16.1"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"react": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
62
62
|
"react-dom": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
63
|
-
"react-router-dom": "^6.0.0"
|
|
63
|
+
"react-router-dom": "^6.0.0 || ^7.0.0"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@backstage/cli": "^0.36.
|
|
67
|
-
"@backstage/test-utils": "^1.7.
|
|
66
|
+
"@backstage/cli": "^0.36.4",
|
|
67
|
+
"@backstage/test-utils": "^1.7.20",
|
|
68
68
|
"@testing-library/jest-dom": "^6.0.0",
|
|
69
69
|
"@testing-library/react": "^14.0.0",
|
|
70
|
-
"@testing-library/user-event": "^14.
|
|
70
|
+
"@testing-library/user-event": "^14.6.3",
|
|
71
71
|
"msw": "^1.0.0"
|
|
72
72
|
},
|
|
73
73
|
"files": [
|