@c2l2c/backstage-plugin-dora-metrics 0.3.0 → 0.3.2
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/README.md +74 -3
- package/config.d.ts +8 -1
- package/dist/alpha.d.ts +56 -1
- package/dist/api/DoraMetricsClient.esm.js +12 -2
- package/dist/api/DoraMetricsClient.esm.js.map +1 -1
- package/dist/components/DoraMetricsContent.esm.js +9 -5
- package/dist/components/DoraMetricsContent.esm.js.map +1 -1
- package/dist/components/ui/badge.esm.js +2 -0
- package/dist/components/ui/badge.esm.js.map +1 -1
- package/dist/extensions/entityContent.esm.js +1 -0
- package/dist/extensions/entityContent.esm.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# @c2l2c/backstage-plugin-dora-metrics
|
|
2
2
|
|
|
3
|
+
[](https://github.com/C2L2C/backstage-plugin-dora-metrics/actions/workflows/ci.yml)
|
|
4
|
+
[](https://github.com/C2L2C/backstage-plugin-dora-metrics/actions/workflows/publish.yml)
|
|
5
|
+
[](https://www.npmjs.com/package/@c2l2c/backstage-plugin-dora-metrics)
|
|
6
|
+
|
|
3
7
|
A Backstage frontend plugin that surfaces **DORA metrics per catalog entity** — scoped to the specific service you're viewing, not your whole org.
|
|
4
8
|
|
|
5
9
|
For each catalog service annotated with a GitHub repo, this plugin adds a **DORA Metrics tab** that computes all four key metrics directly from GitHub PRs via OAuth — no extra backend or data pipeline required:
|
|
@@ -80,15 +84,24 @@ app:
|
|
|
80
84
|
collection:
|
|
81
85
|
initialDays: 30
|
|
82
86
|
|
|
83
|
-
# Define the environments / branches to track
|
|
87
|
+
# Define the environments / branches to track.
|
|
88
|
+
# Exactly ONE environment may set isProduction: true.
|
|
84
89
|
environments:
|
|
85
90
|
- name: Production
|
|
86
|
-
branch: main
|
|
91
|
+
branch: main # single branch name
|
|
87
92
|
isProduction: true
|
|
88
|
-
label: hotfix
|
|
93
|
+
label: hotfix # PR label for production failures (used for CFR/MTTR)
|
|
89
94
|
- name: Staging
|
|
90
95
|
branch: staging
|
|
91
96
|
isProduction: false
|
|
97
|
+
- name: Any main
|
|
98
|
+
# Comma-separated list — PRs merged to any of these branches are included
|
|
99
|
+
branch: "main,master"
|
|
100
|
+
isProduction: false
|
|
101
|
+
- name: Release branches
|
|
102
|
+
# JavaScript regex — resolved against the repo's actual branch list at query time
|
|
103
|
+
branch: "^release/.*"
|
|
104
|
+
isProduction: false
|
|
92
105
|
|
|
93
106
|
# Optional: override DORA benchmark targets
|
|
94
107
|
targets:
|
|
@@ -96,8 +109,66 @@ app:
|
|
|
96
109
|
leadTime: 24 # hours (Elite ≤ 24h)
|
|
97
110
|
changeFailureRate: 5 # % (Elite ≤ 5%)
|
|
98
111
|
mttr: 1 # hours (Elite ≤ 1h)
|
|
112
|
+
|
|
113
|
+
# Optional: enable mock data for local development (skips GitHub API calls)
|
|
114
|
+
debug: false
|
|
99
115
|
```
|
|
100
116
|
|
|
117
|
+
### Branch and label patterns
|
|
118
|
+
|
|
119
|
+
Both the `branch` and `label` fields accept the same three formats:
|
|
120
|
+
|
|
121
|
+
| Format | Example | Behaviour |
|
|
122
|
+
|--------|---------|-----------|
|
|
123
|
+
| Single name | `main` / `hotfix` | Exact match |
|
|
124
|
+
| Comma-separated | `main,master` / `hotfix,fix,bug` | Matches any name in the list |
|
|
125
|
+
| JavaScript regex | `^release/.*` / `^hotfix` | Regex test against each value |
|
|
126
|
+
|
|
127
|
+
A string is treated as a regex if it contains any of these characters: `| ^ $ [ ] ( ) { } ? + * \`
|
|
128
|
+
|
|
129
|
+
For `branch`: when multiple branches match, PRs are fetched from all of them and deduplicated by PR number. Regex patterns are resolved against the repo's live branch list via the GitHub Branches API at query time.
|
|
130
|
+
|
|
131
|
+
For `label`: a PR is classified as a hotfix if **any** of its GitHub labels match the pattern.
|
|
132
|
+
|
|
133
|
+
### Environment constraints
|
|
134
|
+
|
|
135
|
+
- You may define any number of environments.
|
|
136
|
+
- **Exactly one** environment may have `isProduction: true`. The plugin throws a configuration error at startup if this constraint is violated.
|
|
137
|
+
- Change Failure Rate, MTTR, and Hotfixes to Production are only calculated for the production environment.
|
|
138
|
+
|
|
139
|
+
### Per-repo overrides via catalog annotations
|
|
140
|
+
|
|
141
|
+
You can override environments and targets on a per-service basis in `catalog-info.yaml` without changing the global config:
|
|
142
|
+
|
|
143
|
+
```yaml
|
|
144
|
+
metadata:
|
|
145
|
+
annotations:
|
|
146
|
+
github.com/project-slug: my-org/my-repo
|
|
147
|
+
|
|
148
|
+
# Override the environments list for this repo only (JSON)
|
|
149
|
+
dora-metrics/environments: |
|
|
150
|
+
[
|
|
151
|
+
{ "name": "Production", "branch": "main", "isProduction": true, "label": "hotfix" },
|
|
152
|
+
{ "name": "Staging", "branch": "staging", "isProduction": false }
|
|
153
|
+
]
|
|
154
|
+
|
|
155
|
+
# Override DORA targets for this repo only (JSON, partial overrides supported)
|
|
156
|
+
dora-metrics/targets: |
|
|
157
|
+
{ "deploymentFrequency": 2, "leadTime": 48 }
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Annotation values are parsed as JSON. Partial `targets` overrides are merged with the global targets — only the keys you specify are replaced.
|
|
161
|
+
|
|
162
|
+
### Example configs
|
|
163
|
+
|
|
164
|
+
Ready-to-use example configs are in the [`examples/`](examples/) directory:
|
|
165
|
+
|
|
166
|
+
| File | Description |
|
|
167
|
+
|------|-------------|
|
|
168
|
+
| [`app-config.regex-branch.yaml`](examples/app-config.regex-branch.yaml) | Production tracked with a regex branch pattern (`^release/.*`) and a comma-separated label pattern |
|
|
169
|
+
| [`app-config.multi-branch.yaml`](examples/app-config.multi-branch.yaml) | Production tracked across `main,master`; staging across `develop,dev`; hotfix label as regex |
|
|
170
|
+
| [`catalog-info.yaml`](examples/catalog-info.yaml) | Per-repo environment and target overrides via `catalog-info.yaml` annotations |
|
|
171
|
+
|
|
101
172
|
---
|
|
102
173
|
|
|
103
174
|
## How it works
|
package/config.d.ts
CHANGED
|
@@ -36,7 +36,14 @@ export interface Config {
|
|
|
36
36
|
* @visibility frontend
|
|
37
37
|
*/
|
|
38
38
|
isProduction?: boolean;
|
|
39
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* Label(s) on PRs that represent production failures (hotfixes).
|
|
41
|
+
* Defaults to "hotfix". Accepts the same three formats as `branch`:
|
|
42
|
+
* - Single label: "hotfix"
|
|
43
|
+
* - Comma-separated: "hotfix,fix,bug"
|
|
44
|
+
* - JavaScript regex: "^(hotfix|fix)$"
|
|
45
|
+
* @visibility frontend
|
|
46
|
+
*/
|
|
40
47
|
label?: string;
|
|
41
48
|
/** Label on PRs that represent planned feature deployments. @visibility frontend */
|
|
42
49
|
featureLabel?: string;
|
package/dist/alpha.d.ts
CHANGED
|
@@ -1,5 +1,60 @@
|
|
|
1
|
+
import * as _backstage_catalog_model from '@backstage/catalog-model';
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import * as _backstage_filter_predicates from '@backstage/filter-predicates';
|
|
1
4
|
import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
|
|
2
5
|
|
|
3
|
-
declare const doraMetricsPlugin: _backstage_frontend_plugin_api.
|
|
6
|
+
declare const doraMetricsPlugin: _backstage_frontend_plugin_api.OverridableFrontendPlugin<{}, {}, {
|
|
7
|
+
"api:dora-metrics/dora-metrics": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
8
|
+
kind: "api";
|
|
9
|
+
name: "dora-metrics";
|
|
10
|
+
config: {};
|
|
11
|
+
configInput: {};
|
|
12
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.AnyApiFactory, "core.api.factory", {}>;
|
|
13
|
+
inputs: {};
|
|
14
|
+
params: <TApi, TImpl extends TApi, TDeps extends { [name in string]: unknown; }>(params: _backstage_frontend_plugin_api.ApiFactory<TApi, TImpl, TDeps>) => _backstage_frontend_plugin_api.ExtensionBlueprintParams<_backstage_frontend_plugin_api.AnyApiFactory>;
|
|
15
|
+
}>;
|
|
16
|
+
"entity-content:dora-metrics": _backstage_frontend_plugin_api.OverridableExtensionDefinition<{
|
|
17
|
+
kind: "entity-content";
|
|
18
|
+
name: undefined;
|
|
19
|
+
config: {
|
|
20
|
+
path: string | undefined;
|
|
21
|
+
title: string | undefined;
|
|
22
|
+
filter: _backstage_filter_predicates.FilterPredicate | undefined;
|
|
23
|
+
group: string | false | undefined;
|
|
24
|
+
icon: string | undefined;
|
|
25
|
+
};
|
|
26
|
+
configInput: {
|
|
27
|
+
filter?: _backstage_filter_predicates.FilterPredicate | undefined;
|
|
28
|
+
title?: string | undefined;
|
|
29
|
+
path?: string | undefined;
|
|
30
|
+
group?: string | false | undefined;
|
|
31
|
+
icon?: string | undefined;
|
|
32
|
+
};
|
|
33
|
+
output: _backstage_frontend_plugin_api.ExtensionDataRef<string, "core.routing.path", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<_backstage_frontend_plugin_api.RouteRef<_backstage_frontend_plugin_api.AnyRouteRefParams>, "core.routing.ref", {
|
|
34
|
+
optional: true;
|
|
35
|
+
}> | _backstage_frontend_plugin_api.ExtensionDataRef<react.JSX.Element, "core.reactElement", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<(entity: _backstage_catalog_model.Entity) => boolean, "catalog.entity-filter-function", {
|
|
36
|
+
optional: true;
|
|
37
|
+
}> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "catalog.entity-filter-expression", {
|
|
38
|
+
optional: true;
|
|
39
|
+
}> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "catalog.entity-content-title", {}> | _backstage_frontend_plugin_api.ExtensionDataRef<string, "catalog.entity-content-group", {
|
|
40
|
+
optional: true;
|
|
41
|
+
}> | _backstage_frontend_plugin_api.ExtensionDataRef<string | react.ReactElement<any, string | react.JSXElementConstructor<any>>, "catalog.entity-content-icon", {
|
|
42
|
+
optional: true;
|
|
43
|
+
}>;
|
|
44
|
+
inputs: {};
|
|
45
|
+
params: {
|
|
46
|
+
defaultPath?: [Error: `Use the 'path' param instead`];
|
|
47
|
+
path: string;
|
|
48
|
+
defaultTitle?: [Error: `Use the 'title' param instead`];
|
|
49
|
+
title: string;
|
|
50
|
+
defaultGroup?: [Error: `Use the 'group' param instead`];
|
|
51
|
+
group?: ("overview" | "documentation" | "development" | "deployment" | "operation" | "observability") | (string & {});
|
|
52
|
+
icon?: string | react.ReactElement;
|
|
53
|
+
loader: () => Promise<JSX.Element>;
|
|
54
|
+
routeRef?: _backstage_frontend_plugin_api.RouteRef;
|
|
55
|
+
filter?: string | _backstage_filter_predicates.FilterPredicate | ((entity: _backstage_catalog_model.Entity) => boolean);
|
|
56
|
+
};
|
|
57
|
+
}>;
|
|
58
|
+
}>;
|
|
4
59
|
|
|
5
60
|
export { doraMetricsPlugin as default };
|
|
@@ -30,6 +30,16 @@ function toPrDetail(pr, durationHours) {
|
|
|
30
30
|
function isRegexPattern(pattern) {
|
|
31
31
|
return /[|^$[\](){}?+*\\]/.test(pattern);
|
|
32
32
|
}
|
|
33
|
+
function matchesLabel(prLabels, labelPattern) {
|
|
34
|
+
if (!labelPattern) return false;
|
|
35
|
+
const names = prLabels.map((l) => l.name);
|
|
36
|
+
if (isRegexPattern(labelPattern)) {
|
|
37
|
+
const regex = new RegExp(labelPattern);
|
|
38
|
+
return names.some((n) => regex.test(n));
|
|
39
|
+
}
|
|
40
|
+
const patterns = labelPattern.split(",").map((l) => l.trim()).filter(Boolean);
|
|
41
|
+
return names.some((n) => patterns.includes(n));
|
|
42
|
+
}
|
|
33
43
|
async function resolveBranches(owner, repo, branchPattern, fetchFn) {
|
|
34
44
|
if (isRegexPattern(branchPattern)) {
|
|
35
45
|
const repoBranches = await fetchFn(
|
|
@@ -163,7 +173,7 @@ class DoraMetricsClient {
|
|
|
163
173
|
};
|
|
164
174
|
}
|
|
165
175
|
const hotfixPRs = mergedPRs.filter(
|
|
166
|
-
(pr) => (pr.labels ?? []
|
|
176
|
+
(pr) => matchesLabel(pr.labels ?? [], env.label)
|
|
167
177
|
);
|
|
168
178
|
const numberOfHotfixes = {
|
|
169
179
|
value: hotfixPRs.length,
|
|
@@ -219,7 +229,7 @@ class DoraMetricsClient {
|
|
|
219
229
|
let changeFailureRate;
|
|
220
230
|
let mttrHours;
|
|
221
231
|
if (env.isProduction) {
|
|
222
|
-
const hotfixPRs = weekPRs.filter((pr) => pr.labels
|
|
232
|
+
const hotfixPRs = weekPRs.filter((pr) => matchesLabel(pr.labels, env.label));
|
|
223
233
|
changeFailureRate = weekPRs.length > 0 ? Math.round(hotfixPRs.length / weekPRs.length * 1e3) / 10 : 0;
|
|
224
234
|
const hotfixDurations = hotfixPRs.map(
|
|
225
235
|
(pr) => (new Date(pr.merged_at).getTime() - new Date(pr.created_at).getTime()) / (1e3 * 60 * 60)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DoraMetricsClient.esm.js","sources":["../../src/api/DoraMetricsClient.ts"],"sourcesContent":["import { ConfigApi, OAuthApi } from '@backstage/core-plugin-api';\nimport {\n DoraEnvironment,\n DoraHistoryPoint,\n DoraMetrics,\n DoraMetricValue,\n DoraMetricsApi,\n DoraRating,\n DoraTargets,\n PrDetail,\n} from './types';\n\ninterface GitHubPR {\n number: number;\n title: string;\n html_url: string;\n created_at: string;\n merged_at: string | null;\n closed_at: string | null;\n labels: Array<{ name: string }>;\n user: { login: string; avatar_url: string } | null;\n}\n\n/**\n * Compute a DORA rating based on the configured target.\n *\n * lowerIsBetter (lead time, CFR, MTTR, hotfix count):\n * elite = value <= target\n * high = value <= target * 2\n * medium = value <= target * 4\n * low = value > target * 4\n *\n * higherIsBetter (deployment frequency):\n * elite = value >= target\n * high = value >= target * 0.7\n * medium = value >= target * 0.4\n * low = value < target * 0.4\n *\n * Special case — target = 0 (hotfix count ideal = 0):\n * elite=0, high≤2, medium≤5, low>5\n */\nfunction computeRating(value: number, target: number, lowerIsBetter: boolean): DoraRating {\n if (lowerIsBetter) {\n if (target === 0) {\n if (value === 0) return 'elite';\n if (value <= 2) return 'high';\n if (value <= 5) return 'medium';\n return 'low';\n }\n if (value <= target) return 'elite';\n if (value <= target * 2) return 'high';\n if (value <= target * 4) return 'medium';\n return 'low';\n }\n if (value >= target) return 'elite';\n if (value >= target * 0.7) return 'high';\n if (value >= target * 0.4) return 'medium';\n return 'low';\n}\n\nfunction toPrDetail(pr: GitHubPR, durationHours: number): PrDetail {\n return {\n number: pr.number,\n title: pr.title,\n url: pr.html_url,\n durationHours: Math.round(durationHours * 10) / 10,\n mergedAt: pr.merged_at!,\n author: pr.user?.login,\n authorAvatar: pr.user?.avatar_url,\n };\n}\n\n/**\n * Determine whether a branch pattern string is a regex (vs a plain name or\n * comma-separated list of names). A string is treated as a regex if it\n * contains any regex meta-character: | ^ $ [ ] ( ) { } ? + * \\\n */\nfunction isRegexPattern(pattern: string): boolean {\n return /[|^$[\\](){}?+*\\\\]/.test(pattern);\n}\n\n/**\n * Resolve a branch pattern to a concrete list of branch names.\n *\n * - Single name \"main\" → [\"main\"]\n * - Comma-sep \"main,master\" → [\"main\", \"master\"]\n * - Regex \"^(main|master)$\"→ fetched from the repo's branch list and filtered\n */\nasync function resolveBranches(\n owner: string,\n repo: string,\n branchPattern: string,\n fetchFn: <T>(url: string) => Promise<T>,\n): Promise<string[]> {\n if (isRegexPattern(branchPattern)) {\n const repoBranches = await fetchFn<Array<{ name: string }>>(\n `https://api.github.com/repos/${owner}/${repo}/branches?per_page=100`,\n );\n const regex = new RegExp(branchPattern);\n return repoBranches.map(b => b.name).filter(name => regex.test(name));\n }\n // Comma-separated or single branch name\n return branchPattern.split(',').map(b => b.trim()).filter(Boolean);\n}\n\nexport class DoraMetricsClient implements DoraMetricsApi {\n private readonly githubAuthApi: OAuthApi;\n private readonly configApi: ConfigApi;\n\n constructor(githubAuthApi: OAuthApi, configApi: ConfigApi) {\n this.githubAuthApi = githubAuthApi;\n this.configApi = configApi;\n }\n\n private getConfig() {\n const appCfg = this.configApi.getConfig('app');\n const cfg = appCfg.getOptionalConfig('doraMetrics');\n\n const rawEnvs = cfg?.getOptionalConfigArray('environments') ?? [];\n const environments: DoraEnvironment[] = rawEnvs.map(e => ({\n name: e.getString('name'),\n branch: e.getString('branch'),\n isProduction: e.getOptionalBoolean('isProduction') ?? false,\n label: e.getOptionalString('label') ?? 'hotfix',\n }));\n\n // Validate: at most one isProduction environment\n const prodEnvs = environments.filter(e => e.isProduction);\n if (prodEnvs.length > 1) {\n throw new Error(\n `DORA metrics config error: only one environment may have isProduction: true, ` +\n `but found ${prodEnvs.length}: ${prodEnvs.map(e => e.name).join(', ')}`,\n );\n }\n\n const initialDays =\n cfg?.getOptionalConfig('collection')?.getOptionalNumber('initialDays') ?? 30;\n\n const targetsCfg = cfg?.getOptionalConfig('targets');\n const targets: DoraTargets = {\n deploymentFrequency: targetsCfg?.getOptionalNumber('deploymentFrequency') ?? 7,\n leadTime: targetsCfg?.getOptionalNumber('leadTime') ?? 24,\n changeFailureRate: targetsCfg?.getOptionalNumber('changeFailureRate') ?? 15,\n mttr: targetsCfg?.getOptionalNumber('mttr') ?? 1,\n };\n\n return { environments, initialDays, targets };\n }\n\n getEnvironments(): DoraEnvironment[] {\n return this.getConfig().environments;\n }\n\n getDefaultDays(): number {\n return this.getConfig().initialDays;\n }\n\n getTargets(): DoraTargets {\n return this.getConfig().targets;\n }\n\n private async fetchWithAuth<T>(url: string, token: string): Promise<T> {\n const response = await fetch(url, {\n headers: {\n Authorization: `token ${token}`,\n Accept: 'application/vnd.github.v3+json',\n },\n });\n\n if (!response.ok) {\n throw new Error(\n `GitHub API request failed: ${response.status} ${response.statusText} — ${url}`,\n );\n }\n\n return response.json() as Promise<T>;\n }\n\n /**\n * Fetch all merged PRs for an environment, resolving branch patterns and\n * deduplicating across multiple branches by PR number.\n */\n private async fetchMergedPRs(\n owner: string,\n repo: string,\n env: DoraEnvironment,\n cutoff: Date,\n token: string,\n ): Promise<GitHubPR[]> {\n const boundFetch = <T>(url: string) => this.fetchWithAuth<T>(url, token);\n\n const branches = await resolveBranches(owner, repo, env.branch, boundFetch);\n\n const allByNumber = new Map<number, GitHubPR>();\n\n await Promise.all(\n branches.map(async branch => {\n const url =\n `https://api.github.com/repos/${owner}/${repo}/pulls` +\n `?state=closed&base=${branch}&per_page=100`;\n const prs = await boundFetch<GitHubPR[]>(url);\n for (const pr of prs) {\n if (pr.merged_at && new Date(pr.merged_at) >= cutoff) {\n // Keep first occurrence (branches may share PRs — shouldn't happen\n // for base-branch-filtered queries, but guard anyway)\n if (!allByNumber.has(pr.number)) {\n allByNumber.set(pr.number, pr);\n }\n }\n }\n }),\n );\n\n return Array.from(allByNumber.values());\n }\n\n async getMetrics(\n projectSlug: string,\n env: DoraEnvironment,\n days: number,\n targetsOverride?: Partial<DoraTargets>,\n ): Promise<DoraMetrics> {\n const token = await this.githubAuthApi.getAccessToken('repo');\n const { targets: configTargets } = this.getConfig();\n const targets: DoraTargets = { ...configTargets, ...targetsOverride };\n\n const [owner, repo] = projectSlug.split('/');\n if (!owner || !repo) {\n throw new Error(`Invalid project slug \"${projectSlug}\". Expected \"owner/repo\".`);\n }\n\n const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n const mergedPRs = await this.fetchMergedPRs(owner, repo, env, cutoff, token);\n\n // --- Deployment Frequency ---\n const deploymentsPerWeek = days > 0 ? (mergedPRs.length / days) * 7 : 0;\n\n const deploymentFrequency: DoraMetricValue = {\n value: Math.round(deploymentsPerWeek * 100) / 100,\n unit: 'per week',\n rating: computeRating(deploymentsPerWeek, targets.deploymentFrequency, false),\n target: targets.deploymentFrequency,\n // All merged PRs sorted newest-first — used in expanded view date table\n slowestPRs: [...mergedPRs]\n .sort((a, b) => new Date(b.merged_at!).getTime() - new Date(a.merged_at!).getTime())\n .map(pr => toPrDetail(pr,\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60)\n )),\n };\n\n // --- Lead Time ---\n const prsWithLeadTime = mergedPRs\n .map(pr => ({\n pr,\n durationHours:\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) /\n (1000 * 60 * 60),\n }))\n .sort((a, b) => b.durationHours - a.durationHours);\n\n const avgLeadTimeHours =\n prsWithLeadTime.length > 0\n ? prsWithLeadTime.reduce((sum, p) => sum + p.durationHours, 0) / prsWithLeadTime.length\n : 0;\n\n const leadTime: DoraMetricValue = {\n value: Math.round(avgLeadTimeHours * 10) / 10,\n unit: 'hours',\n rating: computeRating(avgLeadTimeHours, targets.leadTime, true),\n target: targets.leadTime,\n slowestPRs: prsWithLeadTime\n .slice(0, 10)\n .map(p => toPrDetail(p.pr, p.durationHours)),\n };\n\n // --- Production-only metrics ---\n if (!env.isProduction) {\n return {\n deploymentFrequency,\n leadTime,\n changeFailureRate: null,\n mttr: null,\n numberOfHotfixes: null,\n };\n }\n\n const hotfixPRs = mergedPRs.filter(pr =>\n (pr.labels ?? []).some(l => l.name === env.label),\n );\n\n // Number of Hotfixes — sorted newest-first for the expanded list\n const numberOfHotfixes: DoraMetricValue = {\n value: hotfixPRs.length,\n unit: 'PRs',\n rating: computeRating(hotfixPRs.length, 0, true),\n target: 0,\n slowestPRs: [...hotfixPRs]\n .sort((a, b) => new Date(b.merged_at!).getTime() - new Date(a.merged_at!).getTime())\n .map(pr => toPrDetail(pr,\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60)\n )),\n };\n\n // Change Failure Rate = fix PRs / all merged PRs (DORA standard: always 0–100%)\n const changeFailureRatePct =\n mergedPRs.length > 0 ? (hotfixPRs.length / mergedPRs.length) * 100 : 0;\n\n const changeFailureRate: DoraMetricValue = {\n value: Math.round(changeFailureRatePct * 10) / 10,\n unit: '%',\n rating: computeRating(changeFailureRatePct, targets.changeFailureRate, true),\n target: targets.changeFailureRate,\n };\n\n // MTTR\n const hotfixWithDuration = hotfixPRs\n .map(pr => ({\n pr,\n durationHours:\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) /\n (1000 * 60 * 60),\n }))\n .sort((a, b) => b.durationHours - a.durationHours);\n\n const avgMttrHours =\n hotfixWithDuration.length > 0\n ? hotfixWithDuration.reduce((sum, p) => sum + p.durationHours, 0) /\n hotfixWithDuration.length\n : 0;\n\n const mttr: DoraMetricValue = {\n value: Math.round(avgMttrHours * 10) / 10,\n unit: 'hours',\n rating: computeRating(avgMttrHours, targets.mttr, true),\n target: targets.mttr,\n slowestPRs: hotfixWithDuration\n .slice(0, 10)\n .map(p => toPrDetail(p.pr, p.durationHours)),\n };\n\n return { deploymentFrequency, leadTime, changeFailureRate, mttr, numberOfHotfixes };\n }\n\n async getHistory(\n projectSlug: string,\n env: DoraEnvironment,\n days: number,\n ): Promise<DoraHistoryPoint[]> {\n const token = await this.githubAuthApi.getAccessToken('repo');\n const [owner, repo] = projectSlug.split('/');\n if (!owner || !repo) throw new Error(`Invalid project slug \"${projectSlug}\".`);\n\n const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n const mergedPRs = await this.fetchMergedPRs(owner, repo, env, cutoff, token);\n\n // Scale bucket size so we always get ~7 data points regardless of date range\n const bucketDays = Math.max(1, Math.round(days / 7));\n const numBuckets = Math.max(2, Math.ceil(days / bucketDays));\n const buckets: DoraHistoryPoint[] = [];\n\n for (let w = numBuckets - 1; w >= 0; w--) {\n const weekEnd = new Date(Date.now() - w * bucketDays * 24 * 60 * 60 * 1000);\n const weekStart = new Date(weekEnd.getTime() - bucketDays * 24 * 60 * 60 * 1000);\n\n const weekPRs = mergedPRs.filter(pr => {\n const t = new Date(pr.merged_at!).getTime();\n return t >= weekStart.getTime() && t < weekEnd.getTime();\n });\n\n const leadTimes = weekPRs.map(pr =>\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60),\n );\n const avgLeadTime =\n leadTimes.length > 0 ? leadTimes.reduce((a, b) => a + b, 0) / leadTimes.length : 0;\n\n let changeFailureRate: number | undefined;\n let mttrHours: number | undefined;\n\n if (env.isProduction) {\n const hotfixPRs = weekPRs.filter(pr => pr.labels.some(l => l.name === env.label));\n changeFailureRate =\n weekPRs.length > 0 ? Math.round((hotfixPRs.length / weekPRs.length) * 1000) / 10 : 0;\n const hotfixDurations = hotfixPRs.map(pr =>\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60),\n );\n mttrHours =\n hotfixDurations.length > 0\n ? Math.round((hotfixDurations.reduce((a, b) => a + b, 0) / hotfixDurations.length) * 10) / 10\n : 0;\n }\n\n buckets.push({\n weekLabel: weekStart.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }),\n bucketMidMs: Math.round((weekStart.getTime() + weekEnd.getTime()) / 2),\n deploymentCount: weekPRs.length,\n leadTimeHours: Math.round(avgLeadTime * 10) / 10,\n changeFailureRate,\n mttrHours,\n });\n }\n\n return buckets;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DoraMetricsClient.esm.js","sources":["../../src/api/DoraMetricsClient.ts"],"sourcesContent":["import { ConfigApi, OAuthApi } from '@backstage/core-plugin-api';\nimport {\n DoraEnvironment,\n DoraHistoryPoint,\n DoraMetrics,\n DoraMetricValue,\n DoraMetricsApi,\n DoraRating,\n DoraTargets,\n PrDetail,\n} from './types';\n\ninterface GitHubPR {\n number: number;\n title: string;\n html_url: string;\n created_at: string;\n merged_at: string | null;\n closed_at: string | null;\n labels: Array<{ name: string }>;\n user: { login: string; avatar_url: string } | null;\n}\n\n/**\n * Compute a DORA rating based on the configured target.\n *\n * lowerIsBetter (lead time, CFR, MTTR, hotfix count):\n * elite = value <= target\n * high = value <= target * 2\n * medium = value <= target * 4\n * low = value > target * 4\n *\n * higherIsBetter (deployment frequency):\n * elite = value >= target\n * high = value >= target * 0.7\n * medium = value >= target * 0.4\n * low = value < target * 0.4\n *\n * Special case — target = 0 (hotfix count ideal = 0):\n * elite=0, high≤2, medium≤5, low>5\n */\nfunction computeRating(value: number, target: number, lowerIsBetter: boolean): DoraRating {\n if (lowerIsBetter) {\n if (target === 0) {\n if (value === 0) return 'elite';\n if (value <= 2) return 'high';\n if (value <= 5) return 'medium';\n return 'low';\n }\n if (value <= target) return 'elite';\n if (value <= target * 2) return 'high';\n if (value <= target * 4) return 'medium';\n return 'low';\n }\n if (value >= target) return 'elite';\n if (value >= target * 0.7) return 'high';\n if (value >= target * 0.4) return 'medium';\n return 'low';\n}\n\nfunction toPrDetail(pr: GitHubPR, durationHours: number): PrDetail {\n return {\n number: pr.number,\n title: pr.title,\n url: pr.html_url,\n durationHours: Math.round(durationHours * 10) / 10,\n mergedAt: pr.merged_at!,\n author: pr.user?.login,\n authorAvatar: pr.user?.avatar_url,\n };\n}\n\n/**\n * Determine whether a pattern string is a regex (vs a plain name or\n * comma-separated list of names). A string is treated as a regex if it\n * contains any regex meta-character: | ^ $ [ ] ( ) { } ? + * \\\n */\nfunction isRegexPattern(pattern: string): boolean {\n return /[|^$[\\](){}?+*\\\\]/.test(pattern);\n}\n\n/**\n * Return true if any of the PR's labels match the label pattern.\n *\n * Supports the same three formats as branch patterns:\n * - Single name: \"hotfix\"\n * - Comma-separated: \"hotfix,fix,bug\"\n * - JavaScript regex: \"^(hotfix|fix)$\"\n */\nfunction matchesLabel(prLabels: Array<{ name: string }>, labelPattern: string): boolean {\n if (!labelPattern) return false;\n const names = prLabels.map(l => l.name);\n if (isRegexPattern(labelPattern)) {\n const regex = new RegExp(labelPattern);\n return names.some(n => regex.test(n));\n }\n const patterns = labelPattern.split(',').map(l => l.trim()).filter(Boolean);\n return names.some(n => patterns.includes(n));\n}\n\n/**\n * Resolve a branch pattern to a concrete list of branch names.\n *\n * - Single name \"main\" → [\"main\"]\n * - Comma-sep \"main,master\" → [\"main\", \"master\"]\n * - Regex \"^(main|master)$\"→ fetched from the repo's branch list and filtered\n */\nasync function resolveBranches(\n owner: string,\n repo: string,\n branchPattern: string,\n fetchFn: <T>(url: string) => Promise<T>,\n): Promise<string[]> {\n if (isRegexPattern(branchPattern)) {\n const repoBranches = await fetchFn<Array<{ name: string }>>(\n `https://api.github.com/repos/${owner}/${repo}/branches?per_page=100`,\n );\n const regex = new RegExp(branchPattern);\n return repoBranches.map(b => b.name).filter(name => regex.test(name));\n }\n // Comma-separated or single branch name\n return branchPattern.split(',').map(b => b.trim()).filter(Boolean);\n}\n\nexport class DoraMetricsClient implements DoraMetricsApi {\n private readonly githubAuthApi: OAuthApi;\n private readonly configApi: ConfigApi;\n\n constructor(githubAuthApi: OAuthApi, configApi: ConfigApi) {\n this.githubAuthApi = githubAuthApi;\n this.configApi = configApi;\n }\n\n private getConfig() {\n const appCfg = this.configApi.getConfig('app');\n const cfg = appCfg.getOptionalConfig('doraMetrics');\n\n const rawEnvs = cfg?.getOptionalConfigArray('environments') ?? [];\n const environments: DoraEnvironment[] = rawEnvs.map(e => ({\n name: e.getString('name'),\n branch: e.getString('branch'),\n isProduction: e.getOptionalBoolean('isProduction') ?? false,\n label: e.getOptionalString('label') ?? 'hotfix',\n }));\n\n // Validate: at most one isProduction environment\n const prodEnvs = environments.filter(e => e.isProduction);\n if (prodEnvs.length > 1) {\n throw new Error(\n `DORA metrics config error: only one environment may have isProduction: true, ` +\n `but found ${prodEnvs.length}: ${prodEnvs.map(e => e.name).join(', ')}`,\n );\n }\n\n const initialDays =\n cfg?.getOptionalConfig('collection')?.getOptionalNumber('initialDays') ?? 30;\n\n const targetsCfg = cfg?.getOptionalConfig('targets');\n const targets: DoraTargets = {\n deploymentFrequency: targetsCfg?.getOptionalNumber('deploymentFrequency') ?? 7,\n leadTime: targetsCfg?.getOptionalNumber('leadTime') ?? 24,\n changeFailureRate: targetsCfg?.getOptionalNumber('changeFailureRate') ?? 15,\n mttr: targetsCfg?.getOptionalNumber('mttr') ?? 1,\n };\n\n return { environments, initialDays, targets };\n }\n\n getEnvironments(): DoraEnvironment[] {\n return this.getConfig().environments;\n }\n\n getDefaultDays(): number {\n return this.getConfig().initialDays;\n }\n\n getTargets(): DoraTargets {\n return this.getConfig().targets;\n }\n\n private async fetchWithAuth<T>(url: string, token: string): Promise<T> {\n const response = await fetch(url, {\n headers: {\n Authorization: `token ${token}`,\n Accept: 'application/vnd.github.v3+json',\n },\n });\n\n if (!response.ok) {\n throw new Error(\n `GitHub API request failed: ${response.status} ${response.statusText} — ${url}`,\n );\n }\n\n return response.json() as Promise<T>;\n }\n\n /**\n * Fetch all merged PRs for an environment, resolving branch patterns and\n * deduplicating across multiple branches by PR number.\n */\n private async fetchMergedPRs(\n owner: string,\n repo: string,\n env: DoraEnvironment,\n cutoff: Date,\n token: string,\n ): Promise<GitHubPR[]> {\n const boundFetch = <T>(url: string) => this.fetchWithAuth<T>(url, token);\n\n const branches = await resolveBranches(owner, repo, env.branch, boundFetch);\n\n const allByNumber = new Map<number, GitHubPR>();\n\n await Promise.all(\n branches.map(async branch => {\n const url =\n `https://api.github.com/repos/${owner}/${repo}/pulls` +\n `?state=closed&base=${branch}&per_page=100`;\n const prs = await boundFetch<GitHubPR[]>(url);\n for (const pr of prs) {\n if (pr.merged_at && new Date(pr.merged_at) >= cutoff) {\n // Keep first occurrence (branches may share PRs — shouldn't happen\n // for base-branch-filtered queries, but guard anyway)\n if (!allByNumber.has(pr.number)) {\n allByNumber.set(pr.number, pr);\n }\n }\n }\n }),\n );\n\n return Array.from(allByNumber.values());\n }\n\n async getMetrics(\n projectSlug: string,\n env: DoraEnvironment,\n days: number,\n targetsOverride?: Partial<DoraTargets>,\n ): Promise<DoraMetrics> {\n const token = await this.githubAuthApi.getAccessToken('repo');\n const { targets: configTargets } = this.getConfig();\n const targets: DoraTargets = { ...configTargets, ...targetsOverride };\n\n const [owner, repo] = projectSlug.split('/');\n if (!owner || !repo) {\n throw new Error(`Invalid project slug \"${projectSlug}\". Expected \"owner/repo\".`);\n }\n\n const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n const mergedPRs = await this.fetchMergedPRs(owner, repo, env, cutoff, token);\n\n // --- Deployment Frequency ---\n const deploymentsPerWeek = days > 0 ? (mergedPRs.length / days) * 7 : 0;\n\n const deploymentFrequency: DoraMetricValue = {\n value: Math.round(deploymentsPerWeek * 100) / 100,\n unit: 'per week',\n rating: computeRating(deploymentsPerWeek, targets.deploymentFrequency, false),\n target: targets.deploymentFrequency,\n // All merged PRs sorted newest-first — used in expanded view date table\n slowestPRs: [...mergedPRs]\n .sort((a, b) => new Date(b.merged_at!).getTime() - new Date(a.merged_at!).getTime())\n .map(pr => toPrDetail(pr,\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60)\n )),\n };\n\n // --- Lead Time ---\n const prsWithLeadTime = mergedPRs\n .map(pr => ({\n pr,\n durationHours:\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) /\n (1000 * 60 * 60),\n }))\n .sort((a, b) => b.durationHours - a.durationHours);\n\n const avgLeadTimeHours =\n prsWithLeadTime.length > 0\n ? prsWithLeadTime.reduce((sum, p) => sum + p.durationHours, 0) / prsWithLeadTime.length\n : 0;\n\n const leadTime: DoraMetricValue = {\n value: Math.round(avgLeadTimeHours * 10) / 10,\n unit: 'hours',\n rating: computeRating(avgLeadTimeHours, targets.leadTime, true),\n target: targets.leadTime,\n slowestPRs: prsWithLeadTime\n .slice(0, 10)\n .map(p => toPrDetail(p.pr, p.durationHours)),\n };\n\n // --- Production-only metrics ---\n if (!env.isProduction) {\n return {\n deploymentFrequency,\n leadTime,\n changeFailureRate: null,\n mttr: null,\n numberOfHotfixes: null,\n };\n }\n\n const hotfixPRs = mergedPRs.filter(pr =>\n matchesLabel(pr.labels ?? [], env.label),\n );\n\n // Number of Hotfixes — sorted newest-first for the expanded list\n const numberOfHotfixes: DoraMetricValue = {\n value: hotfixPRs.length,\n unit: 'PRs',\n rating: computeRating(hotfixPRs.length, 0, true),\n target: 0,\n slowestPRs: [...hotfixPRs]\n .sort((a, b) => new Date(b.merged_at!).getTime() - new Date(a.merged_at!).getTime())\n .map(pr => toPrDetail(pr,\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60)\n )),\n };\n\n // Change Failure Rate = fix PRs / all merged PRs (DORA standard: always 0–100%)\n const changeFailureRatePct =\n mergedPRs.length > 0 ? (hotfixPRs.length / mergedPRs.length) * 100 : 0;\n\n const changeFailureRate: DoraMetricValue = {\n value: Math.round(changeFailureRatePct * 10) / 10,\n unit: '%',\n rating: computeRating(changeFailureRatePct, targets.changeFailureRate, true),\n target: targets.changeFailureRate,\n };\n\n // MTTR\n const hotfixWithDuration = hotfixPRs\n .map(pr => ({\n pr,\n durationHours:\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) /\n (1000 * 60 * 60),\n }))\n .sort((a, b) => b.durationHours - a.durationHours);\n\n const avgMttrHours =\n hotfixWithDuration.length > 0\n ? hotfixWithDuration.reduce((sum, p) => sum + p.durationHours, 0) /\n hotfixWithDuration.length\n : 0;\n\n const mttr: DoraMetricValue = {\n value: Math.round(avgMttrHours * 10) / 10,\n unit: 'hours',\n rating: computeRating(avgMttrHours, targets.mttr, true),\n target: targets.mttr,\n slowestPRs: hotfixWithDuration\n .slice(0, 10)\n .map(p => toPrDetail(p.pr, p.durationHours)),\n };\n\n return { deploymentFrequency, leadTime, changeFailureRate, mttr, numberOfHotfixes };\n }\n\n async getHistory(\n projectSlug: string,\n env: DoraEnvironment,\n days: number,\n ): Promise<DoraHistoryPoint[]> {\n const token = await this.githubAuthApi.getAccessToken('repo');\n const [owner, repo] = projectSlug.split('/');\n if (!owner || !repo) throw new Error(`Invalid project slug \"${projectSlug}\".`);\n\n const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000);\n const mergedPRs = await this.fetchMergedPRs(owner, repo, env, cutoff, token);\n\n // Scale bucket size so we always get ~7 data points regardless of date range\n const bucketDays = Math.max(1, Math.round(days / 7));\n const numBuckets = Math.max(2, Math.ceil(days / bucketDays));\n const buckets: DoraHistoryPoint[] = [];\n\n for (let w = numBuckets - 1; w >= 0; w--) {\n const weekEnd = new Date(Date.now() - w * bucketDays * 24 * 60 * 60 * 1000);\n const weekStart = new Date(weekEnd.getTime() - bucketDays * 24 * 60 * 60 * 1000);\n\n const weekPRs = mergedPRs.filter(pr => {\n const t = new Date(pr.merged_at!).getTime();\n return t >= weekStart.getTime() && t < weekEnd.getTime();\n });\n\n const leadTimes = weekPRs.map(pr =>\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60),\n );\n const avgLeadTime =\n leadTimes.length > 0 ? leadTimes.reduce((a, b) => a + b, 0) / leadTimes.length : 0;\n\n let changeFailureRate: number | undefined;\n let mttrHours: number | undefined;\n\n if (env.isProduction) {\n const hotfixPRs = weekPRs.filter(pr => matchesLabel(pr.labels, env.label));\n changeFailureRate =\n weekPRs.length > 0 ? Math.round((hotfixPRs.length / weekPRs.length) * 1000) / 10 : 0;\n const hotfixDurations = hotfixPRs.map(pr =>\n (new Date(pr.merged_at!).getTime() - new Date(pr.created_at).getTime()) / (1000 * 60 * 60),\n );\n mttrHours =\n hotfixDurations.length > 0\n ? Math.round((hotfixDurations.reduce((a, b) => a + b, 0) / hotfixDurations.length) * 10) / 10\n : 0;\n }\n\n buckets.push({\n weekLabel: weekStart.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }),\n bucketMidMs: Math.round((weekStart.getTime() + weekEnd.getTime()) / 2),\n deploymentCount: weekPRs.length,\n leadTimeHours: Math.round(avgLeadTime * 10) / 10,\n changeFailureRate,\n mttrHours,\n });\n }\n\n return buckets;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -762,7 +762,7 @@ function DetailedOverlay({
|
|
|
762
762
|
padding: "8px 12px",
|
|
763
763
|
borderRadius: 8,
|
|
764
764
|
background: isHov ? isDark ? "#18181f" : "#f0f0ff" : isDark ? "#111114" : "#f4f4f6",
|
|
765
|
-
border: `1px solid ${isHov ? sparklineColor
|
|
765
|
+
border: `1px solid ${isHov ? `${sparklineColor}55` : borderColor}`,
|
|
766
766
|
display: "flex",
|
|
767
767
|
flexDirection: "column",
|
|
768
768
|
gap: 5,
|
|
@@ -940,17 +940,21 @@ function DoraMetricsContent() {
|
|
|
940
940
|
const [history, setHistory] = useState(null);
|
|
941
941
|
const [expanded, setExpanded] = useState(null);
|
|
942
942
|
useEffect(() => {
|
|
943
|
+
let cancelled = false;
|
|
943
944
|
if (!projectSlug) {
|
|
944
945
|
setError(new Error(`Entity is missing the "${ANNOTATION_PROJECT_SLUG}" annotation.`));
|
|
945
946
|
setLoading(false);
|
|
946
|
-
return
|
|
947
|
+
return () => {
|
|
948
|
+
cancelled = true;
|
|
949
|
+
};
|
|
947
950
|
}
|
|
948
951
|
if (!selectedEnv) {
|
|
949
952
|
setError(new Error("No environments configured for DORA metrics."));
|
|
950
953
|
setLoading(false);
|
|
951
|
-
return
|
|
954
|
+
return () => {
|
|
955
|
+
cancelled = true;
|
|
956
|
+
};
|
|
952
957
|
}
|
|
953
|
-
let cancelled = false;
|
|
954
958
|
setLoading(true);
|
|
955
959
|
setError(null);
|
|
956
960
|
setHistory(null);
|
|
@@ -972,7 +976,7 @@ function DoraMetricsContent() {
|
|
|
972
976
|
return () => {
|
|
973
977
|
cancelled = true;
|
|
974
978
|
};
|
|
975
|
-
}, [doraApi, projectSlug, selectedEnv?.name, days]);
|
|
979
|
+
}, [doraApi, projectSlug, selectedEnv?.name, days, annotationTargets]);
|
|
976
980
|
if (loading) return /* @__PURE__ */ React.createElement(DoraLoadingOverlay, null);
|
|
977
981
|
if (error) {
|
|
978
982
|
return /* @__PURE__ */ React.createElement(InfoCard, { title: "DORA Metrics" }, /* @__PURE__ */ React.createElement("div", { style: { padding: 24, color: "#f87171" } }, /* @__PURE__ */ React.createElement("span", { style: { fontWeight: 600 } }, "Error: "), error.message));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DoraMetricsContent.esm.js","sources":["../../src/components/DoraMetricsContent.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport { useTheme } from '@material-ui/core/styles';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { InfoCard } from '@backstage/core-components';\nimport { doraMetricsApiRef } from '../api/types';\nimport type { DoraEnvironment, DoraHistoryPoint, DoraMetrics, DoraMetricValue, DoraTargets, PrDetail } from '../api/types';\nimport { RatingBadge } from './ui/badge';\nimport { Card, CardLabel, CardFooter, CardDescription } from './ui/card';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from './ui/select';\nimport { ExternalLink } from 'lucide-react';\n\nconst ANNOTATION_PROJECT_SLUG = 'github.com/project-slug';\n/** Override the global environments list for this specific entity. JSON array of DoraEnvironment objects. */\nconst ANNOTATION_ENVIRONMENTS = 'dora-metrics/environments';\n/** Override the global performance targets for this specific entity. JSON object matching DoraTargets. */\nconst ANNOTATION_TARGETS = 'dora-metrics/targets';\n\n/** Parse entity annotation overrides. Returns undefined for malformed JSON to fail gracefully. */\nfunction parseAnnotationJson<T>(raw: string | undefined): T | undefined {\n if (!raw) return undefined;\n try { return JSON.parse(raw) as T; } catch { return undefined; }\n}\n\nconst DATE_RANGE_OPTIONS = [\n { value: '7', label: 'Last 7 days' },\n { value: '14', label: 'Last 14 days' },\n { value: '30', label: 'Last 30 days' },\n { value: '60', label: 'Last 60 days' },\n { value: '90', label: 'Last 90 days' },\n];\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\nfunction formatDuration(hours: number): string {\n const totalMinutes = Math.round(hours * 60);\n const d = Math.floor(totalMinutes / (24 * 60));\n const h = Math.floor((totalMinutes % (24 * 60)) / 60);\n const m = totalMinutes % 60;\n if (d > 0) return h > 0 ? `${d}d ${h}h` : `${d}d`;\n if (h > 0) return m > 0 ? `${h}h ${m}m` : `${h}h`;\n return `${m}m`;\n}\n\n// Red → Orange → Yellow → Lime → Green gradient (slowest to fastest)\nconst DURATION_GRADIENT = ['#f87171', '#fb923c', '#fbbf24', '#a3e635', '#4ade80'];\n\nfunction durationColor(index: number, total: number): string {\n if (total <= 1) return DURATION_GRADIENT[0];\n const step = (DURATION_GRADIENT.length - 1) / (total - 1);\n return DURATION_GRADIENT[Math.round(index * step)];\n}\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\n// Period-over-period delta — compares last bucket vs second-to-last bucket\nfunction buildDeltaLabel(\n values: number[],\n unit: string,\n lowerIsBetter: boolean,\n): { text: string; tooltip: string; good: boolean } | null {\n if (values.length < 2) return null;\n const curr = values[values.length - 1];\n const prev = values[values.length - 2];\n const diff = curr - prev;\n if (Math.abs(diff) < 0.001) return null;\n const good = lowerIsBetter ? diff < 0 : diff > 0;\n const arrow = diff > 0 ? '↑' : '↓';\n\n const fmt = (v: number) =>\n unit === 'hours' ? formatDuration(v) :\n unit === '%' ? `${Math.round(v * 10) / 10}%` :\n unit === 'per week' ? `${Math.round(v * 10) / 10}/wk` :\n `${Math.round(v * 10) / 10} ${unit}`;\n\n const direction = good ? 'improving' : 'worsening';\n return {\n text: `${arrow} ${fmt(Math.abs(diff))} ${direction}`,\n tooltip: `Latest period: ${fmt(curr)} · Previous period: ${fmt(prev)}\\nEach period = one time bucket (~1/7th of your selected date range)`,\n good,\n };\n}\n\n// ─── Loading overlay ────────────────────────────────────────────────────────\n\nconst LOADING_MESSAGES = [\n 'Establishing routes…',\n 'Syncing catalog…',\n 'Loading plugins…',\n 'Fetching PR data…',\n 'Reading entity graph…',\n];\nconst STAGES = ['FETCH', 'PARSE', 'SCORE', 'RENDER'] as const;\nconst FONT_IMPACT = '\"Impact\",\"Haettenschweiler\",\"Franklin Gothic Heavy\",\"Arial Black\",sans-serif';\nconst FONT_MONO = '\"JetBrains Mono\",\"Fira Code\",\"Consolas\",monospace';\n\nfunction DoraLoadingOverlay() {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n\n const [activeStage, setActiveStage] = useState(0);\n const [msgKey, setMsgKey] = useState(0);\n const [msgIdx, setMsgIdx] = useState(0);\n\n useEffect(() => {\n const st = setInterval(() => setActiveStage(s => (s + 1) % STAGES.length), 800);\n return () => clearInterval(st);\n }, []);\n\n useEffect(() => {\n const mt = setInterval(() => { setMsgIdx(i => (i + 1) % LOADING_MESSAGES.length); setMsgKey(k => k + 1); }, 2200);\n return () => clearInterval(mt);\n }, []);\n\n const textShadow = isDark\n ? '3px 3px 0 #C24E00, 6px 6px 0 #902800, 9px 9px 0 #5A1800, 12px 12px 0 rgba(0,0,0,0.55), 0 0 60px rgba(250,100,0,0.45)'\n : '3px 3px 0 #C24E00, 6px 6px 0 #902800, 9px 9px 0 rgba(80,20,0,0.28), 0 0 32px rgba(250,100,0,0.22)';\n\n const mutedColor = isDark ? '#3f3f46' : '#a1a1aa';\n const subtitleColor = isDark ? '#52525b' : '#71717a';\n const borderColor = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)';\n\n return (\n <>\n {/* Frosted glass backdrop — blurs whatever is behind */}\n <div aria-hidden style={{\n position: 'fixed', inset: 0, zIndex: 900,\n backdropFilter: 'blur(12px)',\n WebkitBackdropFilter: 'blur(12px)',\n background: isDark ? 'rgba(6,6,9,0.65)' : 'rgba(253,252,251,0.70)',\n }} />\n\n {/* Centered card */}\n <div style={{\n position: 'fixed', zIndex: 901,\n top: '50%', left: '50%',\n transform: 'translateX(-50%) translateY(-50%)',\n display: 'flex', flexDirection: 'column', alignItems: 'center',\n padding: '48px 56px 40px',\n borderRadius: 20,\n background: isDark ? 'rgba(9,9,12,0.82)' : 'rgba(255,255,255,0.88)',\n border: `1px solid ${borderColor}`,\n boxShadow: isDark\n ? '0 0 0 1px rgba(250,100,0,0.06), 0 32px 80px rgba(0,0,0,0.65)'\n : '0 32px 80px rgba(0,0,0,0.12)',\n backdropFilter: 'blur(20px)',\n WebkitBackdropFilter: 'blur(20px)',\n animation: 'dlsCardIn 0.35s cubic-bezier(0.34,1.2,0.64,1) both',\n overflow: 'visible',\n }}>\n\n {/* Breathing ambient glow — inside card */}\n <div aria-hidden style={{\n position: 'absolute', width: 500, height: 360,\n left: '50%', top: '50%',\n transform: 'translateX(-50%) translateY(-50%)',\n background: `radial-gradient(ellipse at center, ${isDark ? 'rgba(250,100,0,0.08)' : 'rgba(250,100,0,0.05)'} 0%, transparent 70%)`,\n animation: 'dlsBreath 3.2s ease-in-out infinite',\n pointerEvents: 'none', borderRadius: 20,\n }} />\n\n {/* DORA wordmark */}\n <div style={{ display: 'flex', lineHeight: 1, marginBottom: 6 }}>\n {['D','O','R','A'].map((letter, i) => (\n <span key={i} style={{\n fontFamily: FONT_IMPACT, fontWeight: 900, fontSize: 110,\n color: '#FA6400', letterSpacing: '0.04em', display: 'inline-block',\n transform: 'skewX(-6deg)', textShadow,\n WebkitTextStroke: '0.5px #C24E00',\n animation: `dlsLetterDrop 0.6s cubic-bezier(0.34,1.45,0.64,1) ${i * 0.1}s both`,\n }}>\n {letter}\n </span>\n ))}\n </div>\n\n {/* Subtitle */}\n <span style={{ fontFamily: 'Inter,system-ui,sans-serif', fontSize: 13, fontWeight: 400,\n letterSpacing: '0.06em', color: subtitleColor, marginBottom: 32,\n animation: 'dlsFadeUp 0.4s ease 0.55s both' }}>\n Metrics\n </span>\n\n {/* Pipeline stages */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 0, marginBottom: 20, animation: 'dlsFadeUp 0.4s ease 0.7s both' }}>\n {STAGES.map((stage, i) => {\n const isActive = i === activeStage;\n const isComplete = i < activeStage;\n return (\n <div key={stage} style={{ display: 'flex', alignItems: 'center', gap: 0 }}>\n <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 5, width: 64 }}>\n <div style={{ position: 'relative', width: 12, height: 12 }}>\n {isActive && (\n <div style={{ position: 'absolute', inset: -6, borderRadius: '50%',\n border: '1.5px solid rgba(250,100,0,0.5)', animation: 'dlsPulse 1s ease-out infinite' }} />\n )}\n <div style={{\n width: 12, height: 12, borderRadius: '50%',\n background: (isActive || isComplete) ? '#FA6400' : (isDark ? '#27272a' : '#e4e4e7'),\n border: `2px solid ${(isActive || isComplete) ? '#C24E00' : (isDark ? '#3f3f46' : '#d4d4d8')}`,\n boxShadow: isActive ? '0 0 14px rgba(250,100,0,0.7)' : 'none',\n transition: 'background 0.3s, box-shadow 0.3s',\n }} />\n </div>\n <span style={{ fontFamily: 'Inter,system-ui,sans-serif', fontSize: 8, fontWeight: 700,\n letterSpacing: '0.12em', textTransform: 'uppercase',\n color: isActive ? '#FA6400' : isComplete ? mutedColor : mutedColor,\n transition: 'color 0.3s' }}>\n {stage}\n </span>\n </div>\n {i < STAGES.length - 1 && (\n <div style={{ width: 32, height: 2, marginBottom: 14, position: 'relative', overflow: 'hidden',\n background: isDark ? '#27272a' : '#e4e4e7', borderRadius: 2 }}>\n <div style={{\n position: 'absolute', inset: 0, borderRadius: 2, background: '#FA6400',\n transformOrigin: 'left center',\n transform: `scaleX(${i < activeStage ? 1 : isActive ? 0.5 : 0})`,\n transition: 'transform 0.4s ease',\n }} />\n </div>\n )}\n </div>\n );\n })}\n </div>\n\n {/* Status message */}\n <span key={msgKey} style={{ fontFamily: FONT_MONO, fontSize: 11,\n color: mutedColor, letterSpacing: '0.04em', animation: 'dlsFadeUp 0.3s ease both' }}>\n {LOADING_MESSAGES[msgIdx]}\n </span>\n\n </div>{/* end card */}\n\n <style>{`\n @keyframes dlsLetterDrop {\n from { opacity: 0; transform: skewX(-6deg) translateY(-32px) scale(1.1); }\n 65% { transform: skewX(-6deg) translateY(6px) scale(0.95); }\n to { opacity: 1; transform: skewX(-6deg) translateY(0) scale(1); }\n }\n @keyframes dlsFadeUp {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n @keyframes dlsBreath {\n 0%, 100% { transform: translateX(-50%) translateY(-50%) scale(0.85); opacity: 0.6; }\n 50% { transform: translateX(-50%) translateY(-50%) scale(1.2); opacity: 1; }\n }\n @keyframes dlsPulse {\n from { transform: scale(0.6); opacity: 0.9; }\n to { transform: scale(2.2); opacity: 0; }\n }\n @keyframes dlsCardIn {\n from { opacity: 0; transform: translateX(-50%) translateY(-46%); }\n to { opacity: 1; transform: translateX(-50%) translateY(-50%); }\n }\n `}</style>\n </>\n );\n}\n\n// ─── Compact sparkline (with hover tooltip + date axis) ────────────────────\n\nfunction CompactSparkline({\n values,\n weekLabels,\n color,\n type,\n formatValue,\n height = 36,\n}: {\n values: number[];\n weekLabels: string[];\n color: string;\n type: 'bar' | 'line';\n formatValue: (v: number) => string;\n height?: number;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hoverIdx, setHoverIdx] = useState<number | null>(null);\n\n const VW = 400; // viewBox units\n const mutedBorder = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)';\n const tooltipBg = isDark ? '#1c1c20' : '#ffffff';\n const tooltipBdr = isDark ? '#3f3f46' : '#e4e4e7';\n const tooltipText = isDark ? '#ededef' : '#111114';\n const font = 'Inter,system-ui,sans-serif';\n\n const handleMouseMove = (e: React.MouseEvent<SVGSVGElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const relX = (e.clientX - rect.left) / rect.width;\n setHoverIdx(Math.max(0, Math.min(values.length - 1, Math.round(relX * (values.length - 1)))));\n };\n\n if (type === 'bar') {\n const max = Math.max(...values, 1);\n const gap = 4;\n const barW = (VW - gap * (values.length - 1)) / values.length;\n\n const hoverX = hoverIdx !== null\n ? hoverIdx * (barW + gap) + barW / 2\n : null;\n const tooltipX = hoverX !== null ? Math.min(hoverX - 34, VW - 72) : 0;\n\n return (\n <div>\n <svg viewBox={`0 0 ${VW} ${height}`} width=\"100%\" style={{ display: 'block', overflow: 'visible' }}\n onMouseMove={handleMouseMove} onMouseLeave={() => setHoverIdx(null)}>\n {values.map((v, i) => {\n const h = Math.max(2, (v / max) * (height - 4));\n return (\n <rect key={i} x={i * (barW + gap)} y={height - h} width={barW} height={h} rx={1.5}\n fill={color} opacity={i === hoverIdx ? 1 : 0.3 + (i / values.length) * 0.55} />\n );\n })}\n <line x1={0} y1={height - 0.5} x2={VW} y2={height - 0.5} stroke={mutedBorder} strokeWidth={1} />\n {hoverIdx !== null && hoverX !== null && (\n <>\n <rect x={tooltipX} y={2} width={72} height={22} rx={4} fill={tooltipBg} stroke={tooltipBdr} strokeWidth={1} />\n <text x={tooltipX + 36} y={17} textAnchor=\"middle\" fill={tooltipText} fontSize={9} fontWeight={600} fontFamily={font}>\n {weekLabels[hoverIdx]}: {formatValue(values[hoverIdx])}\n </text>\n </>\n )}\n </svg>\n <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 3 }}>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[0]}</span>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[weekLabels.length - 1]}</span>\n </div>\n </div>\n );\n }\n\n if (values.length < 2) return null;\n const max = Math.max(...values, 0.01);\n const min = Math.min(...values);\n const range = max - min || max || 1;\n const pad = 3;\n const pts = values.map((v, i): [number, number] => [\n (i / (values.length - 1)) * (VW - pad * 2) + pad,\n (height - pad * 2) - ((v - min) / range) * (height - pad * 2 - 2) + pad,\n ]);\n const d = pts.map(([x, y], i) => `${i === 0 ? 'M' : 'L'}${x.toFixed(1)},${y.toFixed(1)}`).join(' ');\n const area = `${d} L${pts[pts.length-1][0]},${height} L${pts[0][0]},${height} Z`;\n const hoverPt = hoverIdx !== null ? pts[hoverIdx] : null;\n const tooltipX2 = hoverPt ? Math.min(hoverPt[0] - 34, VW - 72) : 0;\n\n return (\n <div>\n <svg viewBox={`0 0 ${VW} ${height}`} width=\"100%\" style={{ display: 'block', overflow: 'visible' }}\n onMouseMove={handleMouseMove} onMouseLeave={() => setHoverIdx(null)}>\n <path d={area} fill={color} opacity={0.07} />\n <path d={d} fill=\"none\" stroke={color} strokeWidth={1.5} strokeLinejoin=\"round\" strokeLinecap=\"round\" />\n {pts.map(([x, y], i) => (\n <circle key={i} cx={x} cy={y} r={i === hoverIdx ? 3.5 : i === pts.length - 1 ? 2.5 : 0} fill={color} />\n ))}\n <line x1={0} y1={height - 0.5} x2={VW} y2={height - 0.5} stroke={mutedBorder} strokeWidth={1} />\n {hoverPt && hoverIdx !== null && (\n <>\n <line x1={hoverPt[0]} y1={0} x2={hoverPt[0]} y2={height} stroke={color} strokeWidth={1} strokeDasharray=\"2 2\" opacity={0.4} />\n <rect x={tooltipX2} y={2} width={72} height={22} rx={4} fill={tooltipBg} stroke={tooltipBdr} strokeWidth={1} />\n <text x={tooltipX2 + 36} y={17} textAnchor=\"middle\" fill={tooltipText} fontSize={9} fontWeight={600} fontFamily={font}>\n {weekLabels[hoverIdx]}: {formatValue(values[hoverIdx])}\n </text>\n </>\n )}\n </svg>\n <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 3 }}>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[0]}</span>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[weekLabels.length - 1]}</span>\n </div>\n </div>\n );\n}\n\n// ─── Detailed interactive chart ────────────────────────────────────────────\n\ninterface ChartTooltipState {\n x: number;\n y: number;\n primary: string;\n secondary?: string;\n}\n\nfunction DetailedChart({\n values,\n weekLabels,\n bucketMidMs,\n color,\n type,\n formatValue,\n prs,\n days,\n hoveredPrNumber,\n onPrHover,\n}: {\n values: number[];\n weekLabels: string[];\n bucketMidMs: number[];\n color: string;\n type: 'bar' | 'line';\n formatValue: (v: number) => string;\n prs?: PrDetail[];\n days: number;\n hoveredPrNumber?: number | null;\n onPrHover?: (num: number | null) => void;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hoverIdx, setHoverIdx] = useState<number | null>(null);\n const [tooltip, setTooltip] = useState<ChartTooltipState | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const W = 800, H = 260;\n const PAD = { top: 16, right: 16, bottom: 36, left: 56 };\n const cW = W - PAD.left - PAD.right;\n const cH = H - PAD.top - PAD.bottom;\n\n // Y scale: based on bucket values only so the trend line is clearly readable.\n // PR dots that fall outside this range are rendered clamped to chart area.\n const dataMax = Math.max(...values, 0.01);\n const dataMin = type === 'line' ? Math.min(...values, 0) : 0;\n const dataRange = dataMax - dataMin || dataMax || 1;\n const yScale = (v: number) => cH - ((v - dataMin) / dataRange) * cH;\n\n // Shared timestamp-based x-axis\n const cutoffMs = Date.now() - days * 24 * 60 * 60 * 1000;\n const rangeMs = days * 24 * 60 * 60 * 1000;\n const xTime = (ms: number) => Math.max(0, Math.min(cW, ((ms - cutoffMs) / rangeMs) * cW));\n\n const xIdx = (i: number) => bucketMidMs.length === values.length\n ? xTime(bucketMidMs[i])\n : (values.length > 1 ? (i / (values.length - 1)) * cW : cW / 2);\n\n const pts: [number, number][] = values.map((v, i) => [PAD.left + xIdx(i), PAD.top + yScale(v)]);\n const linePath = pts.map(([x, y], i) => `${i === 0 ? 'M' : 'L'}${x.toFixed(1)},${y.toFixed(1)}`).join(' ');\n const areaPath = pts.length > 1\n ? `${linePath} L${pts[pts.length-1][0]},${PAD.top+cH} L${pts[0][0]},${PAD.top+cH} Z`\n : '';\n\n const gap = 6;\n const barW = values.length > 1 ? (cW - gap * (values.length - 1)) / values.length : cW;\n\n const yTicks = [0, 0.25, 0.5, 0.75, 1].map(t => dataMin + t * dataRange);\n const gridColor = isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)';\n const axisColor = isDark ? '#3f3f46' : '#d4d4d8';\n const labelColor = isDark ? '#52525b' : '#a1a1aa';\n const font = 'Inter,system-ui,sans-serif';\n const gradId = `dg_${color.replace('#','')}`;\n\n // Find the nearest bucket index for a given timestamp\n const nearestBucket = (ms: number): number => {\n if (bucketMidMs.length === 0) return 0;\n let best = 0, bestDist = Infinity;\n bucketMidMs.forEach((mid, i) => {\n const d = Math.abs(ms - mid);\n if (d < bestDist) { bestDist = d; best = i; }\n });\n return best;\n };\n\n const handleSvgMouseMove = (e: React.MouseEvent<SVGSVGElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const relX = (e.clientX - rect.left - PAD.left * (rect.width / W)) / (rect.width * cW / W);\n const idx = Math.max(0, Math.min(values.length - 1, Math.round(relX * (values.length - 1))));\n setHoverIdx(idx);\n const cRect = containerRef.current?.getBoundingClientRect();\n const x = cRect ? e.clientX - cRect.left : 0;\n const y = cRect ? e.clientY - cRect.top : 0;\n setTooltip({ x, y, primary: formatValue(values[idx]), secondary: weekLabels[idx] });\n };\n\n return (\n <div ref={containerRef} style={{ position: 'relative' }}>\n <svg viewBox={`0 0 ${W} ${H}`} width=\"100%\" style={{ display: 'block' }}\n onMouseMove={handleSvgMouseMove}\n onMouseLeave={() => { setHoverIdx(null); setTooltip(null); }}>\n <defs>\n <linearGradient id={gradId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={color} stopOpacity={0.28} />\n <stop offset=\"100%\" stopColor={color} stopOpacity={0} />\n </linearGradient>\n {/* Clip PR dots to the chart area */}\n <clipPath id={`prClip_${gradId}`}>\n <rect x={PAD.left} y={PAD.top - 8} width={cW} height={cH + 16} />\n </clipPath>\n </defs>\n\n {/* Grid + Y-axis */}\n {yTicks.map((v, i) => {\n const y = PAD.top + yScale(v);\n return (\n <g key={i}>\n {i > 0 && <line x1={PAD.left} y1={y} x2={PAD.left+cW} y2={y} stroke={gridColor} strokeWidth={1} strokeDasharray=\"3 4\" />}\n <text x={PAD.left - 6} y={y + 4} textAnchor=\"end\" fill={labelColor} fontSize={10} fontFamily={font}>\n {formatValue(v)}\n </text>\n </g>\n );\n })}\n <line x1={PAD.left} y1={PAD.top+cH} x2={PAD.left+cW} y2={PAD.top+cH} stroke={axisColor} strokeWidth={1} />\n\n {/* Chart body */}\n {type === 'bar' ? (\n values.map((v, i) => {\n const bH = Math.max(2, ((v - dataMin) / dataRange) * cH);\n const x = PAD.left + i * (barW + gap);\n return (\n <rect key={i} x={x} y={PAD.top+cH-bH} width={barW} height={bH} rx={3}\n fill={color} opacity={i === hoverIdx ? 0.95 : 0.4 + (i / Math.max(values.length - 1, 1)) * 0.45} />\n );\n })\n ) : (\n <>\n {areaPath && <path d={areaPath} fill={`url(#${gradId})`} />}\n <path d={linePath} fill=\"none\" stroke={color} strokeWidth={2.5} strokeLinejoin=\"round\" strokeLinecap=\"round\" />\n {pts.map(([x, y], i) => (\n <circle key={i} cx={x} cy={y}\n r={i === hoverIdx ? 5.5 : 4}\n fill={isDark ? '#0f0f12' : '#ffffff'} stroke={color}\n strokeWidth={i === hoverIdx ? 2.5 : 1.5} />\n ))}\n </>\n )}\n\n {/* PR data-point dots — x at bucket midpoint, y at actual duration (clamped to chart) */}\n {prs && type === 'line' && (\n <g clipPath={`url(#prClip_${gradId})`}>\n {prs.map((pr, dotIdx) => {\n const mergedMs = new Date(pr.mergedAt).getTime();\n const bIdx = nearestBucket(mergedMs);\n // Small deterministic jitter within the bucket to avoid overlap\n const jitter = ((pr.number * 17 + dotIdx * 11) % 13 - 6) * 5;\n const px = PAD.left + xIdx(bIdx) + jitter;\n // Clamp y: PR may be faster or slower than bucket avg; always visible\n const rawPy = PAD.top + yScale(pr.durationHours);\n const py = Math.max(PAD.top + 4, Math.min(PAD.top + cH - 4, rawPy));\n const isHov = pr.number === hoveredPrNumber;\n\n // Thin connector from dot to the bucket trend point\n const trendPt = pts[bIdx];\n\n return (\n <g key={pr.number} style={{ cursor: 'pointer' }}\n onMouseEnter={e => {\n e.stopPropagation();\n const cRect = containerRef.current?.getBoundingClientRect();\n const x = cRect ? e.clientX - cRect.left : 0;\n const y = cRect ? e.clientY - cRect.top : 0;\n setTooltip({ x, y,\n primary: `#${pr.number}: ${pr.title}`,\n secondary: `${formatValue(pr.durationHours)} · ${new Date(pr.mergedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}` });\n onPrHover?.(pr.number);\n }}\n onMouseLeave={() => { setTooltip(null); onPrHover?.(null); }}>\n {trendPt && (\n <line x1={px} y1={py} x2={trendPt[0]} y2={trendPt[1]}\n stroke={color} strokeWidth={isHov ? 1 : 0.5}\n strokeDasharray=\"2 3\" opacity={isHov ? 0.5 : 0.2} />\n )}\n <circle cx={px} cy={py} r={isHov ? 11 : 7} fill={color} opacity={isHov ? 0.2 : 0.1} />\n <circle cx={px} cy={py} r={isHov ? 5.5 : 3.5}\n fill={isHov ? color : (isDark ? '#1a1a20' : '#fff')}\n stroke={color} strokeWidth={isHov ? 0 : 1.5}\n opacity={isHov ? 1 : 0.8} />\n </g>\n );\n })}\n </g>\n )}\n\n {/* Hover crosshair */}\n {hoverIdx !== null && type === 'line' && pts[hoverIdx] && (\n <>\n <line x1={pts[hoverIdx][0]} y1={PAD.top} x2={pts[hoverIdx][0]} y2={PAD.top+cH}\n stroke={color} strokeWidth={1} strokeDasharray=\"3 3\" opacity={0.3} />\n <line x1={PAD.left} y1={pts[hoverIdx][1]} x2={PAD.left+cW} y2={pts[hoverIdx][1]}\n stroke={color} strokeWidth={1} strokeDasharray=\"3 3\" opacity={0.2} />\n </>\n )}\n\n {/* X-axis labels */}\n {weekLabels.map((lbl, i) => {\n const total = weekLabels.length;\n const step = Math.max(1, Math.floor(total / 5));\n if (i !== 0 && i !== total - 1 && i % step !== 0) return null;\n const x = type === 'bar'\n ? PAD.left + i * (barW + gap) + barW / 2\n : PAD.left + xIdx(i);\n return (\n <text key={i} x={x} y={H - 8} textAnchor=\"middle\" fill={labelColor} fontSize={10} fontFamily={font}>\n {lbl}\n </text>\n );\n })}\n </svg>\n\n {/* Absolute tooltip — positioned relative to the chart container */}\n {tooltip && (() => {\n const TW = 220;\n const cW2 = containerRef.current?.offsetWidth ?? 800;\n const nearRight = tooltip.x + TW + 12 > cW2;\n return (\n <div style={{\n position: 'absolute',\n left: nearRight ? tooltip.x - TW - 8 : tooltip.x + 8,\n top: tooltip.y - 36,\n zIndex: 9999, pointerEvents: 'none',\n background: isDark ? '#18181b' : '#ffffff',\n border: `1px solid ${isDark ? '#3f3f46' : '#e4e4e7'}`,\n borderRadius: 7, padding: '7px 10px',\n boxShadow: isDark ? '0 6px 20px rgba(0,0,0,0.55)' : '0 6px 20px rgba(0,0,0,0.10)',\n width: TW,\n }}>\n <div style={{ fontSize: 12, fontWeight: 600, color: isDark ? '#ededef' : '#111114',\n fontFamily: font, lineHeight: 1.4 }}>\n {tooltip.primary}\n </div>\n {tooltip.secondary && (\n <div style={{ fontSize: 11, color: isDark ? '#71717a' : '#a1a1aa', fontFamily: font, marginTop: 2 }}>\n {tooltip.secondary}\n </div>\n )}\n </div>\n );\n })()}\n </div>\n );\n}\n\n// ─── Detailed overlay ──────────────────────────────────────────────────────\n\ninterface ExpandedCardData {\n title: string;\n metric: DoraMetricValue;\n description: string;\n lowerIsBetter: boolean;\n sparklineValues: number[];\n sparklineType: 'bar' | 'line';\n sparklineColor: string;\n weekLabels: string[];\n bucketMidMs: number[];\n prs?: PrDetail[];\n /** Override the section header above the PR list (default: \"All deployments\"). */\n prListLabel?: string;\n}\n\nfunction DetailedOverlay({\n data,\n days,\n onClose,\n}: {\n data: ExpandedCardData;\n days: number;\n onClose: () => void;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hoveredPrNumber, setHoveredPrNumber] = useState<number | null>(null);\n const prRowRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [onClose]);\n\n // Auto-scroll to the highlighted PR row when hover comes from the chart\n useEffect(() => {\n if (hoveredPrNumber !== null) {\n const el = prRowRefs.current.get(hoveredPrNumber);\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }, [hoveredPrNumber]);\n\n const { title, metric, description, lowerIsBetter, sparklineValues, sparklineType, sparklineColor, weekLabels, bucketMidMs, prs, prListLabel } = data;\n const isDeployFreq = sparklineType === 'bar';\n const displayValue = metric.unit === 'hours' ? formatDuration(metric.value) : String(metric.value);\n const displayUnit = metric.unit === 'hours' ? '' : metric.unit;\n const formatVal = (v: number) => metric.unit === 'hours' ? formatDuration(v) : `${Math.round(v * 10) / 10}`;\n const borderColor = isDark ? '#27272a' : '#e4e4e7';\n const mutedColor = isDark ? '#52525b' : '#a1a1aa';\n const targetLabel = lowerIsBetter\n ? `Target: < ${metric.unit === 'hours' ? formatDuration(metric.target) : metric.target} ${displayUnit}`\n : `Target: ≥ ${metric.target} ${displayUnit}`;\n\n // Group deployment PRs by date (for the date table)\n const prsByDate = isDeployFreq && prs ? prs.reduce((acc, pr) => {\n const date = new Date(pr.mergedAt).toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' });\n if (!acc[date]) acc[date] = [];\n acc[date].push(pr);\n return acc;\n }, {} as Record<string, PrDetail[]>) : {};\n const sortedDates = Object.keys(prsByDate).sort(\n (a, b) => new Date(prsByDate[b][0].mergedAt).getTime() - new Date(prsByDate[a][0].mergedAt).getTime()\n );\n\n return (\n <>\n {/* Backdrop */}\n <div onClick={onClose} style={{\n position: 'fixed', inset: 0, zIndex: 499,\n background: isDark ? 'rgba(0,0,0,0.6)' : 'rgba(0,0,0,0.3)',\n backdropFilter: 'blur(4px)',\n }} />\n\n {/* Panel */}\n <div style={{\n position: 'fixed',\n top: '50%', left: '50%',\n transform: 'translateX(-50%) translateY(-50%)',\n width: 'min(92vw, 960px)',\n maxHeight: 'calc(100vh - 80px)',\n zIndex: 500,\n background: isDark ? '#09090c' : '#fafafa',\n border: `1px solid ${borderColor}`,\n borderRadius: 14,\n display: 'flex', flexDirection: 'column',\n overflow: 'hidden',\n animation: 'detailExpandIn 0.2s cubic-bezier(0.34,1.2,0.64,1)',\n boxShadow: isDark ? '0 24px 64px rgba(0,0,0,0.7)' : '0 24px 64px rgba(0,0,0,0.18)',\n }}>\n {/* Header */}\n <div style={{\n display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start',\n padding: '20px 24px 16px',\n borderBottom: `1px solid ${borderColor}`,\n flexShrink: 0,\n }}>\n <div>\n <div style={{ fontSize: 10, fontWeight: 700, color: mutedColor, textTransform: 'uppercase', letterSpacing: '0.12em', marginBottom: 8 }}>\n {title} · {weekLabels[0]} – {weekLabels[weekLabels.length - 1]}\n </div>\n <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, flexWrap: 'wrap' }}>\n <span style={{ fontSize: 52, fontWeight: 700, color: theme.palette.text.primary, lineHeight: 1, letterSpacing: '-0.02em' }}>\n {displayValue}\n </span>\n {displayUnit && (\n <span style={{ fontSize: 18, color: mutedColor, fontWeight: 500 }}>{displayUnit}</span>\n )}\n <RatingBadge rating={metric.rating} />\n </div>\n <div style={{ fontSize: 12, color: mutedColor, marginTop: 6 }}>\n {description} · <span style={{ fontStyle: 'italic' }}>{targetLabel}</span>\n </div>\n </div>\n <button type=\"button\" onClick={onClose} style={{\n all: 'unset', cursor: 'pointer', width: 30, height: 30,\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n borderRadius: '50%', background: isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)',\n color: mutedColor, fontSize: 18, fontWeight: 300, transition: 'all 0.12s', flexShrink: 0,\n }}\n onMouseEnter={e => { (e.currentTarget as HTMLElement).style.background = isDark ? 'rgba(255,255,255,0.12)' : 'rgba(0,0,0,0.1)'; }}\n onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)'; }}>\n ✕\n </button>\n </div>\n\n {/* Body — scrollable */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px 24px', display: 'flex', flexDirection: 'column', gap: 20 }}>\n\n {/* Chart */}\n {weekLabels.length >= 2 ? (\n <DetailedChart\n values={sparklineValues} weekLabels={weekLabels}\n bucketMidMs={bucketMidMs}\n color={sparklineColor} type={sparklineType}\n formatValue={formatVal} prs={isDeployFreq ? undefined : prs} days={days}\n hoveredPrNumber={hoveredPrNumber} onPrHover={setHoveredPrNumber}\n />\n ) : (\n <div style={{ color: mutedColor, fontSize: 13, textAlign: 'center', padding: '48px 0' }}>\n Not enough data — select a wider date range.\n </div>\n )}\n\n {/* === Deployment Frequency: PRs grouped by date === */}\n {isDeployFreq && prs && prs.length > 0 && (\n <div>\n <div style={{ fontSize: 10, fontWeight: 700, color: mutedColor, textTransform: 'uppercase',\n letterSpacing: '0.12em', marginBottom: 12,\n borderTop: `1px solid ${borderColor}`, paddingTop: 12 }}>\n {prListLabel ?? 'All deployments'} · {prs.length} PR{prs.length !== 1 ? 's' : ''}\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>\n {sortedDates.map(date => (\n <div key={date}>\n {/* Date header */}\n <div style={{\n fontSize: 11, fontWeight: 700, color: sparklineColor,\n marginBottom: 6, display: 'flex', alignItems: 'center', gap: 8,\n }}>\n <span>{date}</span>\n <span style={{ color: mutedColor, fontWeight: 500 }}>· {prsByDate[date].length} PR{prsByDate[date].length > 1 ? 's' : ''}</span>\n </div>\n {/* PR rows */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: 4, paddingLeft: 12,\n borderLeft: `2px solid ${sparklineColor}22` }}>\n {prsByDate[date].map(pr => (\n <div key={pr.number} style={{\n display: 'flex', flexDirection: 'column', gap: 5,\n padding: '7px 10px', borderRadius: 7,\n background: isDark ? '#0d0d10' : '#f7f7f9',\n border: `1px solid ${borderColor}`,\n transition: 'background 0.12s',\n }}>\n {/* Row 1: number + title + lead time + link */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <span style={{ fontSize: 10, fontWeight: 700, color: mutedColor, flexShrink: 0, minWidth: 36 }}>\n #{pr.number}\n </span>\n <span style={{ fontSize: 12, color: theme.palette.text.primary, flex: 1,\n whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }} title={pr.title}>\n {pr.title}\n </span>\n <span style={{ fontSize: 10, color: mutedColor, flexShrink: 0 }}>\n {formatDuration(pr.durationHours)} lead\n </span>\n <a href={pr.url} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ color: mutedColor, flexShrink: 0 }}>\n <ExternalLink size={11} />\n </a>\n </div>\n {/* Row 2: author badge */}\n {pr.author && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 5 }}>\n {pr.authorAvatar ? (\n <img src={pr.authorAvatar} alt={pr.author}\n style={{ width: 16, height: 16, borderRadius: '50%', flexShrink: 0,\n border: `1px solid ${isDark ? '#3f3f46' : '#e4e4e7'}` }} />\n ) : (\n <div style={{ width: 16, height: 16, borderRadius: '50%', flexShrink: 0,\n background: isDark ? '#27272a' : '#e4e4e7',\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n fontSize: 8, fontWeight: 700, color: mutedColor }}>\n {pr.author[0].toUpperCase()}\n </div>\n )}\n <a href={`https://github.com/${pr.author}`} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ fontSize: 10, fontWeight: 500, color: mutedColor,\n textDecoration: 'none', letterSpacing: '0.01em' }}\n onMouseEnter={e => { (e.currentTarget as HTMLElement).style.color = '#FA6400'; }}\n onMouseLeave={e => { (e.currentTarget as HTMLElement).style.color = mutedColor; }}>\n @{pr.author}\n </a>\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* === Lead Time / MTTR: duration-ranked PR list with hover linking === */}\n {!isDeployFreq && prs && prs.length > 0 && (\n <div>\n <div style={{ fontSize: 10, fontWeight: 700, color: mutedColor, textTransform: 'uppercase',\n letterSpacing: '0.12em', marginBottom: 10,\n borderTop: `1px solid ${borderColor}`, paddingTop: 12 }}>\n {title.toLowerCase().includes('restore') ? 'Slowest Hotfix PRs' : 'Slowest PRs'}\n {' '}· hover a row to highlight on chart\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>\n {prs.map((pr, i) => {\n const col = durationColor(i, prs.length);\n const maxDur = prs[0].durationHours;\n const barPct = maxDur > 0 ? (pr.durationHours / maxDur) * 100 : 0;\n const isHov = pr.number === hoveredPrNumber;\n return (\n <div key={pr.number}\n ref={(el) => {\n if (el) prRowRefs.current.set(pr.number, el);\n else prRowRefs.current.delete(pr.number);\n }}\n onMouseEnter={() => setHoveredPrNumber(pr.number)}\n onMouseLeave={() => setHoveredPrNumber(null)}\n style={{\n padding: '8px 12px', borderRadius: 8,\n background: isHov\n ? (isDark ? '#18181f' : '#f0f0ff')\n : (isDark ? '#111114' : '#f4f4f6'),\n border: `1px solid ${isHov ? sparklineColor + '55' : borderColor}`,\n display: 'flex', flexDirection: 'column', gap: 5,\n transition: 'background 0.12s, border-color 0.12s',\n cursor: 'default',\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 }}>\n <span style={{ fontSize: 10, fontWeight: 700, color: col, flexShrink: 0 }}>#{pr.number}</span>\n <span style={{ fontSize: 12, color: theme.palette.text.primary, flex: 1,\n whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }} title={pr.title}>\n {pr.title}\n </span>\n <span style={{ fontSize: 10, color: mutedColor, flexShrink: 0 }}>\n {new Date(pr.mergedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}\n </span>\n <a href={pr.url} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ color: mutedColor, flexShrink: 0, transition: 'color 0.12s' }}>\n <ExternalLink size={11} />\n </a>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <AnimatedBar widthPct={barPct} color={col} />\n <span style={{ fontSize: 11, fontWeight: 700, color: col, minWidth: 52, textAlign: 'right', flexShrink: 0 }}>\n {formatDuration(pr.durationHours)}\n </span>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n )}\n </div>\n </div>\n <style>{`\n @keyframes detailExpandIn {\n from { opacity: 0; transform: translateX(-50%) translateY(-46%); }\n to { opacity: 1; transform: translateX(-50%) translateY(-50%); }\n }\n `}</style>\n </>\n );\n}\n\n// ─── Animated bar ──────────────────────────────────────────────────────────\n\nfunction AnimatedBar({ widthPct, color }: { widthPct: number; color: string }) {\n const [width, setWidth] = useState(0);\n const ref = useRef<HTMLDivElement>(null);\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n\n useEffect(() => {\n const timer = setTimeout(() => setWidth(widthPct), 80);\n return () => clearTimeout(timer);\n }, [widthPct]);\n\n return (\n <div\n ref={ref}\n style={{\n background: isDark ? '#1a1a1e' : '#f0f0f2',\n borderRadius: 4,\n height: 5,\n overflow: 'hidden',\n flex: 1,\n minWidth: 40,\n }}\n >\n <div\n style={{\n height: '100%',\n width: `${width}%`,\n background: color,\n borderRadius: 4,\n transition: 'width 0.55s cubic-bezier(0.4, 0, 0.2, 1)',\n boxShadow: `0 0 6px ${color}88`,\n }}\n />\n </div>\n );\n}\n\n// ─── Metric cards ──────────────────────────────────────────────────────────\n\nfunction MetricCard({\n title,\n metric,\n description,\n lowerIsBetter = false,\n sparklineData,\n sparklineType = 'line',\n sparklineColor,\n weekLabels,\n onExpand,\n expandLabel,\n}: {\n title: string;\n metric: DoraMetricValue;\n description: string;\n lowerIsBetter?: boolean;\n sparklineData?: number[];\n sparklineType?: 'bar' | 'line';\n sparklineColor?: string;\n weekLabels?: string[];\n onExpand?: () => void;\n /** Persistent label shown in the card footer (instead of the hover-only \"expand ↗\"). */\n expandLabel?: string;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hovered, setHovered] = useState(false);\n\n const displayValue = metric.unit === 'hours' ? formatDuration(metric.value) : metric.value;\n const displayUnit = metric.unit === 'hours' ? '' : metric.unit;\n const targetValue = metric.unit === 'hours' ? formatDuration(metric.target) : metric.target;\n const targetLabel = lowerIsBetter\n ? `Target: < ${targetValue} ${displayUnit}`.trim()\n : `Target: ≥ ${targetValue} ${displayUnit}`.trim();\n\n const hasSparkline = sparklineData && sparklineData.length >= 2 && weekLabels && weekLabels.length >= 2;\n const delta = hasSparkline ? buildDeltaLabel(sparklineData!, metric.unit, lowerIsBetter) : null;\n const formatVal = (v: number) => metric.unit === 'hours' ? formatDuration(v) : `${Math.round(v * 10) / 10}`;\n\n return (\n <Card\n style={{ cursor: onExpand ? 'pointer' : undefined }}\n onClick={onExpand}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n >\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8 }}>\n <CardLabel>{title}</CardLabel>\n {onExpand && (\n <span style={{\n fontSize: 9, fontWeight: 600, color: isDark ? '#3f3f46' : '#d4d4d8',\n opacity: hovered ? 1 : 0, transition: 'opacity 0.15s',\n letterSpacing: '0.05em', textTransform: 'uppercase', flexShrink: 0,\n }}>\n expand ↗\n </span>\n )}\n </div>\n {/* Right-aligned column: delta trend + direction hint stacked */}\n <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 4 }}>\n {delta && (\n <span title={delta.tooltip} style={{\n fontSize: 10, fontWeight: 600, cursor: 'help',\n color: delta.good ? '#4ade80' : '#f87171',\n background: delta.good\n ? (isDark ? 'rgba(74,222,128,0.08)' : 'rgba(74,222,128,0.12)')\n : (isDark ? 'rgba(248,113,113,0.08)' : 'rgba(248,113,113,0.12)'),\n padding: '2px 8px', borderRadius: 4, whiteSpace: 'nowrap',\n }}>\n {delta.text}\n </span>\n )}\n <span style={{\n fontSize: 10, fontWeight: 600,\n color: isDark ? '#3f3f46' : '#d4d4d8',\n whiteSpace: 'nowrap',\n }}>\n {lowerIsBetter ? '↓ lower = better' : '↑ higher = better'}\n </span>\n </div>\n {/* Value row: big number + unit */}\n <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>\n <span style={{ fontSize: 36, fontWeight: 700, color: isDark ? '#f4f4f5' : '#111114', lineHeight: 1 }}>\n {displayValue}\n </span>\n {displayUnit && (\n <span style={{ fontSize: 14, color: isDark ? '#71717a' : '#71717a', fontWeight: 500 }}>\n {displayUnit}\n </span>\n )}\n </div>\n <RatingBadge rating={metric.rating} />\n {hasSparkline && (\n <div style={{ marginTop: 2 }}>\n <CompactSparkline\n values={sparklineData!}\n weekLabels={weekLabels!}\n color={sparklineColor ?? '#FA6400'}\n type={sparklineType}\n formatValue={formatVal}\n />\n </div>\n )}\n <CardDescription>{description}</CardDescription>\n <CardFooter>\n <span style={{ fontWeight: 600, color: isDark ? '#a1a1aa' : '#52525b' }}>\n {targetLabel}\n </span>\n {expandLabel && onExpand && (\n <span style={{\n fontSize: 10, fontWeight: 700,\n color: '#FA6400',\n letterSpacing: '0.04em',\n marginLeft: 'auto',\n }}>\n {expandLabel}\n </span>\n )}\n </CardFooter>\n </Card>\n );\n}\n\nfunction NaCard({ title, description }: { title: string; description: string }) {\n return (\n <Card>\n <CardLabel>{title}</CardLabel>\n <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>\n <span style={{ fontSize: 36, fontWeight: 700, color: '#52525b', lineHeight: 1 }}>N/A</span>\n </div>\n <CardDescription muted>{description}</CardDescription>\n </Card>\n );\n}\n\n// ─── Filter label ──────────────────────────────────────────────────────────\n\nfunction FilterLabel({ children }: { children: React.ReactNode }) {\n const theme = useTheme();\n return (\n <div style={{ fontSize: 11, fontWeight: 600, color: theme.palette.text.primary, marginBottom: 4, textTransform: 'uppercase', letterSpacing: '0.06em' }}>\n {children}\n </div>\n );\n}\n\n// ─── Main component ────────────────────────────────────────────────────────\n\nexport function DoraMetricsContent() {\n const { entity } = useEntity();\n const doraApi = useApi(doraMetricsApiRef);\n const muiTheme = useTheme();\n const textPrimary = muiTheme.palette.text.primary;\n const textSecondary = muiTheme.palette.text.secondary;\n\n const projectSlug = entity.metadata.annotations?.[ANNOTATION_PROJECT_SLUG] ?? '';\n const annotations = entity.metadata.annotations ?? {};\n\n // Per-repo overrides from catalog-info.yaml annotations\n const annotationEnvs = parseAnnotationJson<DoraEnvironment[]>(annotations[ANNOTATION_ENVIRONMENTS]);\n const annotationTargets = parseAnnotationJson<Partial<DoraTargets>>(annotations[ANNOTATION_TARGETS]);\n\n const environments: DoraEnvironment[] = annotationEnvs ?? doraApi.getEnvironments();\n const defaultEnv = environments[0];\n const defaultDays = doraApi.getDefaultDays();\n\n // Use environment name as the selection key (branch can be a multi-value pattern)\n const [selectedEnvName, setSelectedEnvName] = useState<string>(defaultEnv?.name ?? '');\n const [selectedDays, setSelectedDays] = useState<string>(String(defaultDays));\n\n const selectedEnv = environments.find(e => e.name === selectedEnvName) ?? defaultEnv;\n const days = parseInt(selectedDays, 10);\n\n const [metrics, setMetrics] = useState<DoraMetrics | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const [history, setHistory] = useState<DoraHistoryPoint[] | null>(null);\n const [expanded, setExpanded] = useState<ExpandedCardData | null>(null);\n\n useEffect(() => {\n if (!projectSlug) {\n setError(new Error(`Entity is missing the \"${ANNOTATION_PROJECT_SLUG}\" annotation.`));\n setLoading(false);\n return;\n }\n if (!selectedEnv) {\n setError(new Error('No environments configured for DORA metrics.'));\n setLoading(false);\n return;\n }\n\n let cancelled = false;\n setLoading(true);\n setError(null);\n setHistory(null);\n\n doraApi\n .getMetrics(projectSlug, selectedEnv, days, annotationTargets ?? undefined)\n .then(data => {\n if (!cancelled) { setMetrics(data); setLoading(false); }\n })\n .catch((err: Error) => {\n if (!cancelled) { setError(err); setLoading(false); }\n });\n\n doraApi\n .getHistory(projectSlug, selectedEnv, days)\n .then(data => { if (!cancelled) setHistory(data); })\n .catch(() => { /* history is optional — fail silently */ });\n\n return () => { cancelled = true; };\n }, [doraApi, projectSlug, selectedEnv?.name, days]);\n\n if (loading) return <DoraLoadingOverlay />;\n\n if (error) {\n return (\n <InfoCard title=\"DORA Metrics\">\n <div style={{ padding: 24, color: '#f87171' }}>\n <span style={{ fontWeight: 600 }}>Error: </span>{error.message}\n </div>\n </InfoCard>\n );\n }\n\n if (!metrics) return null;\n\n return (\n <InfoCard title=\" \">\n <div style={{ padding: '4px 0', position: 'relative' }}>\n {/* Detailed overlay */}\n {expanded && (\n <DetailedOverlay data={expanded} days={days} onClose={() => setExpanded(null)} />\n )}\n\n {/* Title */}\n <div style={{ marginBottom: 16 }}>\n <div style={{ fontSize: 22, fontWeight: 700, color: textPrimary, letterSpacing: '-0.02em' }}>DORA Metrics</div>\n {selectedEnv && (\n <div style={{ fontSize: 12, color: textSecondary, marginTop: 5 }}>\n Showing metrics for{' '}\n <strong style={{ color: textPrimary }}>{selectedEnv.name}</strong>\n {' '}—{' '}\n <span style={{ fontFamily: 'monospace' }}>{selectedEnv.branch}</span>\n </div>\n )}\n </div>\n\n {/* Filters row — left aligned */}\n <div style={{ display: 'flex', alignItems: 'flex-end', gap: 16, flexWrap: 'wrap', marginBottom: 20 }}>\n {environments.length > 1 && (\n <div>\n <FilterLabel>Environment</FilterLabel>\n <Select value={selectedEnvName} onValueChange={setSelectedEnvName}>\n <SelectTrigger><SelectValue placeholder=\"Select environment\" /></SelectTrigger>\n <SelectContent>\n {environments.map(env => (\n <SelectItem key={env.name} value={env.name}>\n {env.name} ({env.branch})\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n\n <div>\n <FilterLabel>Date Range</FilterLabel>\n <Select value={selectedDays} onValueChange={setSelectedDays}>\n <SelectTrigger><SelectValue placeholder=\"Select date range\" /></SelectTrigger>\n <SelectContent>\n {DATE_RANGE_OPTIONS.map(opt => (\n <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {/* Metric cards — sparklines inline, click to expand */}\n {(() => {\n const wkLabels = history?.map(h => h.weekLabel) ?? [];\n const deployData = history?.map(h => h.deploymentCount) ?? [];\n const leadData = history?.map(h => h.leadTimeHours) ?? [];\n const cfrData = history?.map(h => h.changeFailureRate ?? 0) ?? [];\n const mttrData = history?.map(h => h.mttrHours ?? 0) ?? [];\n\n const bmMs = history?.map(h => h.bucketMidMs) ?? [];\n\n const mkExpand = (\n title: string, metric: DoraMetricValue, description: string,\n lowerIsBetter: boolean, sparklineValues: number[],\n sparklineType: 'bar' | 'line', sparklineColor: string, prs?: PrDetail[],\n prListLabel?: string,\n ) => () => setExpanded({\n title, metric, description, lowerIsBetter,\n sparklineValues, sparklineType, sparklineColor,\n weekLabels: wkLabels, bucketMidMs: bmMs, prs, prListLabel,\n });\n\n return (\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12 }}>\n <MetricCard\n title=\"Deployment Frequency\"\n metric={metrics.deploymentFrequency}\n description=\"How often code is deployed to this branch\"\n sparklineData={deployData}\n sparklineType=\"bar\"\n sparklineColor=\"#FA6400\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Deployment Frequency', metrics.deploymentFrequency,\n 'How often code is deployed to this branch', false, deployData, 'bar', '#FA6400',\n metrics.deploymentFrequency.slowestPRs)}\n />\n <MetricCard\n title=\"Lead Time for Changes\"\n metric={metrics.leadTime}\n description=\"Average time from PR creation to merge\"\n lowerIsBetter\n sparklineData={leadData}\n sparklineType=\"line\"\n sparklineColor=\"#818cf8\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Lead Time for Changes', metrics.leadTime,\n 'Average time from PR creation to merge', true, leadData, 'line', '#818cf8', metrics.leadTime.slowestPRs)}\n />\n {metrics.changeFailureRate !== null ? (\n <MetricCard\n title=\"Change Failure Rate\"\n metric={metrics.changeFailureRate}\n description=\"% of all merged PRs that were hotfixes\"\n lowerIsBetter\n sparklineData={cfrData}\n sparklineType=\"line\"\n sparklineColor=\"#f87171\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Change Failure Rate', metrics.changeFailureRate,\n '% of all merged PRs that were hotfixes', true, cfrData, 'line', '#f87171')}\n />\n ) : (\n <NaCard title=\"Change Failure Rate\" description=\"Only tracked on production branches\" />\n )}\n {metrics.mttr !== null ? (\n <MetricCard\n title=\"Mean Time to Restore\"\n metric={metrics.mttr}\n description=\"Avg time from hotfix PR open to merge\"\n lowerIsBetter\n sparklineData={mttrData}\n sparklineType=\"line\"\n sparklineColor=\"#fbbf24\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Mean Time to Restore', metrics.mttr,\n 'Avg time from hotfix PR open to merge', true, mttrData, 'line', '#fbbf24', metrics.mttr.slowestPRs)}\n />\n ) : (\n <NaCard title=\"Mean Time to Restore\" description=\"Only tracked on production branches\" />\n )}\n {metrics.numberOfHotfixes !== null ? (\n <MetricCard\n title=\"Hotfixes to Production\"\n metric={metrics.numberOfHotfixes}\n description={`PRs labeled '${selectedEnv?.label ?? 'hotfix'}' merged to production`}\n lowerIsBetter\n expandLabel={metrics.numberOfHotfixes.value > 0 ? `View ${metrics.numberOfHotfixes.value} PR${metrics.numberOfHotfixes.value !== 1 ? 's' : ''} →` : undefined}\n onExpand={mkExpand(\n 'Hotfixes to Production',\n metrics.numberOfHotfixes,\n `PRs labeled '${selectedEnv?.label ?? 'hotfix'}' merged to production`,\n true,\n [],\n 'bar',\n '#f87171',\n metrics.numberOfHotfixes.slowestPRs,\n 'All hotfixes',\n )}\n />\n ) : (\n <NaCard title=\"Hotfixes to Production\" description=\"Only tracked on production branches\" />\n )}\n </div>\n );\n })()}\n\n </div>\n </InfoCard>\n );\n}\n"],"names":["max"],"mappings":";;;;;;;;;;;AAkBA,MAAM,uBAAA,GAA0B,yBAAA;AAEhC,MAAM,uBAAA,GAA0B,2BAAA;AAEhC,MAAM,kBAAA,GAAqB,sBAAA;AAG3B,SAAS,oBAAuB,GAAA,EAAwC;AACtE,EAAA,IAAI,CAAC,KAAK,OAAO,MAAA;AACjB,EAAA,IAAI;AAAE,IAAA,OAAO,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,EAAQ,CAAA,CAAA,MAAQ;AAAE,IAAA,OAAO,MAAA;AAAA,EAAW;AACjE;AAEA,MAAM,kBAAA,GAAqB;AAAA,EACzB,EAAE,KAAA,EAAO,GAAA,EAAM,KAAA,EAAO,aAAA,EAAc;AAAA,EACpC,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,cAAA,EAAe;AAAA,EACrC,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,cAAA,EAAe;AAAA,EACrC,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,cAAA,EAAe;AAAA,EACrC,EAAE,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,cAAA;AACxB,CAAA;AAIA,SAAS,eAAe,KAAA,EAAuB;AAC7C,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,EAAE,CAAA;AAC1C,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,YAAA,IAAgB,KAAK,EAAA,CAAG,CAAA;AAC7C,EAAA,MAAM,IAAI,IAAA,CAAK,KAAA,CAAO,YAAA,IAAgB,EAAA,GAAK,MAAO,EAAE,CAAA;AACpD,EAAA,MAAM,IAAI,YAAA,GAAe,EAAA;AACzB,EAAA,IAAI,CAAA,GAAI,CAAA,EAAG,OAAO,CAAA,GAAI,CAAA,GAAI,CAAA,EAAG,CAAC,CAAA,EAAA,EAAK,CAAC,CAAA,CAAA,CAAA,GAAM,CAAA,EAAG,CAAC,CAAA,CAAA,CAAA;AAC9C,EAAA,IAAI,CAAA,GAAI,CAAA,EAAG,OAAO,CAAA,GAAI,CAAA,GAAI,CAAA,EAAG,CAAC,CAAA,EAAA,EAAK,CAAC,CAAA,CAAA,CAAA,GAAM,CAAA,EAAG,CAAC,CAAA,CAAA,CAAA;AAC9C,EAAA,OAAO,GAAG,CAAC,CAAA,CAAA,CAAA;AACb;AAGA,MAAM,oBAAoB,CAAC,SAAA,EAAW,SAAA,EAAW,SAAA,EAAW,WAAW,SAAS,CAAA;AAEhF,SAAS,aAAA,CAAc,OAAe,KAAA,EAAuB;AAC3D,EAAA,IAAI,KAAA,IAAS,CAAA,EAAG,OAAO,iBAAA,CAAkB,CAAC,CAAA;AAC1C,EAAA,MAAM,IAAA,GAAA,CAAQ,iBAAA,CAAkB,MAAA,GAAS,CAAA,KAAM,KAAA,GAAQ,CAAA,CAAA;AACvD,EAAA,OAAO,iBAAA,CAAkB,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,IAAI,CAAC,CAAA;AACnD;AAKA,SAAS,eAAA,CACP,MAAA,EACA,IAAA,EACA,aAAA,EACyD;AACzD,EAAA,IAAI,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,OAAO,IAAA;AAC9B,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAC,CAAA;AACrC,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAC,CAAA;AACrC,EAAA,MAAM,OAAO,IAAA,GAAO,IAAA;AACpB,EAAA,IAAI,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,GAAI,MAAO,OAAO,IAAA;AACnC,EAAA,MAAM,IAAA,GAAO,aAAA,GAAgB,IAAA,GAAO,CAAA,GAAI,IAAA,GAAO,CAAA;AAC/C,EAAA,MAAM,KAAA,GAAQ,IAAA,GAAO,CAAA,GAAI,QAAA,GAAM,QAAA;AAE/B,EAAA,MAAM,MAAM,CAAC,CAAA,KACX,IAAA,KAAS,OAAA,GAAa,eAAe,CAAC,CAAA,GACtC,IAAA,KAAS,GAAA,GAAa,GAAG,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,EAAE,IAAI,EAAE,CAAA,CAAA,CAAA,GAChD,IAAA,KAAS,UAAA,GAAa,GAAG,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,EAAE,IAAI,EAAE,CAAA,GAAA,CAAA,GAC1B,CAAA,EAAG,IAAA,CAAK,MAAM,CAAA,GAAI,EAAE,CAAA,GAAI,EAAE,IAAI,IAAI,CAAA,CAAA;AAE1D,EAAA,MAAM,SAAA,GAAY,OAAO,WAAA,GAAc,WAAA;AACvC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,IAAI,CAAC,CAAC,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA;AAAA,IAClD,OAAA,EAAS,kBAAkB,GAAA,CAAI,IAAI,CAAC,CAAA,uBAAA,EAAuB,GAAA,CAAI,IAAI,CAAC;AAAA,kEAAA,CAAA;AAAA,IACpE;AAAA,GACF;AACF;AAIA,MAAM,gBAAA,GAAmB;AAAA,EACvB,2BAAA;AAAA,EACA,uBAAA;AAAA,EACA,uBAAA;AAAA,EACA,wBAAA;AAAA,EACA;AACF,CAAA;AACA,MAAM,MAAA,GAAS,CAAC,OAAA,EAAS,OAAA,EAAS,SAAS,QAAQ,CAAA;AACnD,MAAM,WAAA,GAAc,8EAAA;AACpB,MAAM,SAAA,GAAc,mDAAA;AAEpB,SAAS,kBAAA,GAAqB;AAC5B,EAAA,MAAM,QAAS,QAAA,EAAS;AACxB,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,IAAA,KAAS,MAAA;AAEtC,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,CAAC,CAAA;AAChD,EAAA,MAAM,CAAC,MAAA,EAAS,SAAS,CAAA,GAAa,SAAS,CAAC,CAAA;AAChD,EAAA,MAAM,CAAC,MAAA,EAAS,SAAS,CAAA,GAAa,SAAS,CAAC,CAAA;AAEhD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,EAAA,GAAK,WAAA,CAAY,MAAM,cAAA,CAAe,CAAA,CAAA,KAAA,CAAM,IAAI,CAAA,IAAK,MAAA,CAAO,MAAM,CAAA,EAAG,GAAG,CAAA;AAC9E,IAAA,OAAO,MAAM,cAAc,EAAE,CAAA;AAAA,EAC/B,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,EAAA,GAAK,YAAY,MAAM;AAAE,MAAA,SAAA,CAAU,CAAA,CAAA,KAAA,CAAM,CAAA,GAAI,CAAA,IAAK,gBAAA,CAAiB,MAAM,CAAA;AAAG,MAAA,SAAA,CAAU,CAAA,CAAA,KAAK,IAAI,CAAC,CAAA;AAAA,IAAG,GAAG,IAAI,CAAA;AAChH,IAAA,OAAO,MAAM,cAAc,EAAE,CAAA;AAAA,EAC/B,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,UAAA,GAAa,SACf,sHAAA,GACA,mGAAA;AAEJ,EAAA,MAAM,UAAA,GAAgB,SAAS,SAAA,GAAY,SAAA;AAC3C,EAAA,MAAM,aAAA,GAAgB,SAAS,SAAA,GAAY,SAAA;AAC3C,EAAA,MAAM,WAAA,GAAgB,SAAS,wBAAA,GAA2B,kBAAA;AAE1D,EAAA,uBACE,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBAEE,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,aAAA,EAAW,MAAC,KAAA,EAAO;AAAA,IACtB,QAAA,EAAU,OAAA;AAAA,IAAS,KAAA,EAAO,CAAA;AAAA,IAAG,MAAA,EAAQ,GAAA;AAAA,IACrC,cAAA,EAAgB,YAAA;AAAA,IAChB,oBAAA,EAAsB,YAAA;AAAA,IACtB,UAAA,EAAY,SAAS,kBAAA,GAAqB;AAAA,GAC5C,EAAG,CAAA,kBAGH,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO;AAAA,IACV,QAAA,EAAU,OAAA;AAAA,IAAS,MAAA,EAAQ,GAAA;AAAA,IAC3B,GAAA,EAAK,KAAA;AAAA,IAAO,IAAA,EAAM,KAAA;AAAA,IAClB,SAAA,EAAW,mCAAA;AAAA,IACX,OAAA,EAAS,MAAA;AAAA,IAAQ,aAAA,EAAe,QAAA;AAAA,IAAU,UAAA,EAAY,QAAA;AAAA,IACtD,OAAA,EAAS,gBAAA;AAAA,IACT,YAAA,EAAc,EAAA;AAAA,IACd,UAAA,EAAY,SAAS,mBAAA,GAAsB,wBAAA;AAAA,IAC3C,MAAA,EAAQ,aAAa,WAAW,CAAA,CAAA;AAAA,IAChC,SAAA,EAAW,SACP,8DAAA,GACA,8BAAA;AAAA,IACJ,cAAA,EAAgB,YAAA;AAAA,IAChB,oBAAA,EAAsB,YAAA;AAAA,IACtB,SAAA,EAAW,oDAAA;AAAA,IACX,QAAA,EAAU;AAAA,GACZ,EAAA,kBAGA,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,aAAA,EAAW,MAAC,KAAA,EAAO;AAAA,IACtB,QAAA,EAAU,UAAA;AAAA,IAAY,KAAA,EAAO,GAAA;AAAA,IAAK,MAAA,EAAQ,GAAA;AAAA,IAC1C,IAAA,EAAM,KAAA;AAAA,IAAO,GAAA,EAAK,KAAA;AAAA,IAClB,SAAA,EAAW,mCAAA;AAAA,IACX,UAAA,EAAY,CAAA,mCAAA,EAAsC,MAAA,GAAS,sBAAA,GAAyB,sBAAsB,CAAA,qBAAA,CAAA;AAAA,IAC1G,SAAA,EAAW,qCAAA;AAAA,IACX,aAAA,EAAe,MAAA;AAAA,IAAQ,YAAA,EAAc;AAAA,GACvC,EAAG,CAAA,kBAGD,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,UAAA,EAAY,CAAA,EAAG,YAAA,EAAc,CAAA,EAAE,EAAA,EAC3D,CAAC,GAAA,EAAI,GAAA,EAAI,GAAA,EAAI,GAAG,CAAA,CAAE,GAAA,CAAI,CAAC,MAAA,EAAQ,CAAA,qBAC9B,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,GAAA,EAAK,CAAA,EAAG,KAAA,EAAO;AAAA,IACnB,UAAA,EAAY,WAAA;AAAA,IAAa,UAAA,EAAY,GAAA;AAAA,IAAK,QAAA,EAAU,GAAA;AAAA,IACpD,KAAA,EAAO,SAAA;AAAA,IAAW,aAAA,EAAe,QAAA;AAAA,IAAU,OAAA,EAAS,cAAA;AAAA,IACpD,SAAA,EAAW,cAAA;AAAA,IAAgB,UAAA;AAAA,IAC3B,gBAAA,EAAkB,eAAA;AAAA,IAClB,SAAA,EAAW,CAAA,kDAAA,EAAqD,CAAA,GAAI,GAAG,CAAA,MAAA;AAAA,OAEtE,MACH,CACD,CACH,CAAA,kBAGA,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO;AAAA,IAAE,UAAA,EAAY,4BAAA;AAAA,IAA8B,QAAA,EAAU,EAAA;AAAA,IAAI,UAAA,EAAY,GAAA;AAAA,IACjF,aAAA,EAAe,QAAA;AAAA,IAAU,KAAA,EAAO,aAAA;AAAA,IAAe,YAAA,EAAc,EAAA;AAAA,IAC7D,SAAA,EAAW;AAAA,GAAiC,EAAA,EAAG,SAEjD,CAAA,kBAGA,KAAA,CAAA,aAAA,CAAC,SAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,UAAA,EAAY,QAAA,EAAU,KAAK,CAAA,EAAG,YAAA,EAAc,IAAI,SAAA,EAAW,+BAAA,MACvF,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,EAAO,CAAA,KAAM;AACxB,IAAA,MAAM,WAAa,CAAA,KAAM,WAAA;AACzB,IAAA,MAAM,aAAa,CAAA,GAAI,WAAA;AACvB,IAAA,2CACG,KAAA,EAAA,EAAI,GAAA,EAAK,OAAO,KAAA,EAAO,EAAE,SAAS,MAAA,EAAQ,UAAA,EAAY,UAAU,GAAA,EAAK,CAAA,sBACpE,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,OAAO,EAAE,OAAA,EAAS,QAAQ,aAAA,EAAe,QAAA,EAAU,UAAA,EAAY,QAAA,EAAU,KAAK,CAAA,EAAG,KAAA,EAAO,IAAG,EAAA,kBAC9F,KAAA,CAAA,aAAA,CAAC,SAAI,KAAA,EAAO,EAAE,UAAU,UAAA,EAAY,KAAA,EAAO,IAAI,MAAA,EAAQ,EAAA,MACpD,QAAA,oBACC,KAAA,CAAA,aAAA,CAAC,SAAI,KAAA,EAAO;AAAA,MAAE,QAAA,EAAU,UAAA;AAAA,MAAY,KAAA,EAAO,EAAA;AAAA,MAAI,YAAA,EAAc,KAAA;AAAA,MAC3D,MAAA,EAAQ,iCAAA;AAAA,MAAmC,SAAA,EAAW;AAAA,KAAgC,EAAG,CAAA,kBAE7F,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO;AAAA,MACV,KAAA,EAAO,EAAA;AAAA,MAAI,MAAA,EAAQ,EAAA;AAAA,MAAI,YAAA,EAAc,KAAA;AAAA,MACrC,UAAA,EAAa,QAAA,IAAY,UAAA,GAAc,SAAA,GAAa,SAAS,SAAA,GAAY,SAAA;AAAA,MACzE,QAAQ,CAAA,UAAA,EAAc,QAAA,IAAY,aAAc,SAAA,GAAa,MAAA,GAAS,YAAY,SAAU,CAAA,CAAA;AAAA,MAC5F,SAAA,EAAW,WAAW,8BAAA,GAAiC,MAAA;AAAA,MACvD,UAAA,EAAY;AAAA,KACd,EAAG,CACL,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO;AAAA,MAAE,UAAA,EAAY,4BAAA;AAAA,MAA8B,QAAA,EAAU,CAAA;AAAA,MAAG,UAAA,EAAY,GAAA;AAAA,MAChF,aAAA,EAAe,QAAA;AAAA,MAAU,aAAA,EAAe,WAAA;AAAA,MACxC,KAAA,EAAO,QAAA,GAAW,SAAA,GAAY,UAAA,GAAa,UAAA,GAAa,UAAA;AAAA,MACxD,UAAA,EAAY;AAAA,KAAa,EAAA,EACxB,KACH,CACF,CAAA,EACC,CAAA,GAAI,OAAO,MAAA,GAAS,CAAA,oBACnB,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO;AAAA,MAAE,KAAA,EAAO,EAAA;AAAA,MAAI,MAAA,EAAQ,CAAA;AAAA,MAAG,YAAA,EAAc,EAAA;AAAA,MAAI,QAAA,EAAU,UAAA;AAAA,MAAY,QAAA,EAAU,QAAA;AAAA,MACpF,UAAA,EAAY,SAAS,SAAA,GAAY,SAAA;AAAA,MAAW,YAAA,EAAc;AAAA,KAAE,EAAA,kBAC5D,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO;AAAA,MACV,QAAA,EAAU,UAAA;AAAA,MAAY,KAAA,EAAO,CAAA;AAAA,MAAG,YAAA,EAAc,CAAA;AAAA,MAAG,UAAA,EAAY,SAAA;AAAA,MAC7D,eAAA,EAAiB,aAAA;AAAA,MACjB,WAAW,CAAA,OAAA,EAAU,CAAA,GAAI,cAAc,CAAA,GAAI,QAAA,GAAW,MAAM,CAAC,CAAA,CAAA,CAAA;AAAA,MAC7D,UAAA,EAAY;AAAA,KACd,EAAG,CACL,CAEJ,CAAA;AAAA,EAEJ,CAAC,CACH,CAAA,sCAGC,MAAA,EAAA,EAAK,GAAA,EAAK,QAAQ,KAAA,EAAO;AAAA,IAAE,UAAA,EAAY,SAAA;AAAA,IAAW,QAAA,EAAU,EAAA;AAAA,IAC3D,KAAA,EAAO,UAAA;AAAA,IAAY,aAAA,EAAe,QAAA;AAAA,IAAU,SAAA,EAAW;AAAA,OACtD,gBAAA,CAAiB,MAAM,CAC1B,CAEF,CAAA,sCAEC,OAAA,EAAA,IAAA,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAAA,CAsBN,CACJ,CAAA;AAEJ;AAIA,SAAS,gBAAA,CAAiB;AAAA,EACxB,MAAA;AAAA,EACA,UAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,WAAA;AAAA,EACA,MAAA,GAAS;AACX,CAAA,EAOG;AACD,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,IAAA,KAAS,MAAA;AACtC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAwB,IAAI,CAAA;AAE5D,EAAA,MAAM,EAAA,GAAK,GAAA;AACX,EAAA,MAAM,WAAA,GAAc,SAAS,wBAAA,GAA2B,kBAAA;AACxD,EAAA,MAAM,SAAA,GAAc,SAAS,SAAA,GAAY,SAAA;AACzC,EAAA,MAAM,UAAA,GAAc,SAAS,SAAA,GAAY,SAAA;AACzC,EAAA,MAAM,WAAA,GAAc,SAAS,SAAA,GAAY,SAAA;AACzC,EAAA,MAAM,IAAA,GAAO,4BAAA;AAEb,EAAA,MAAM,eAAA,GAAkB,CAAC,CAAA,KAAuC;AAC9D,IAAA,MAAM,IAAA,GAAO,CAAA,CAAE,aAAA,CAAc,qBAAA,EAAsB;AACnD,IAAA,MAAM,IAAA,GAAA,CAAQ,CAAA,CAAE,OAAA,GAAU,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAC5C,IAAA,WAAA,CAAY,KAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,OAAO,MAAA,GAAS,CAAA,EAAG,IAAA,CAAK,KAAA,CAAM,QAAQ,MAAA,CAAO,MAAA,GAAS,CAAA,CAAE,CAAC,CAAC,CAAC,CAAA;AAAA,EAC9F,CAAA;AAEA,EAAA,IAAI,SAAS,KAAA,EAAO;AAClB,IAAA,MAAMA,IAAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,QAAQ,CAAC,CAAA;AACjC,IAAA,MAAM,GAAA,GAAM,CAAA;AACZ,IAAA,MAAM,QAAQ,EAAA,GAAK,GAAA,IAAO,MAAA,CAAO,MAAA,GAAS,MAAM,MAAA,CAAO,MAAA;AAEvD,IAAA,MAAM,SAAS,QAAA,KAAa,IAAA,GACxB,YAAY,IAAA,GAAO,GAAA,CAAA,GAAO,OAAO,CAAA,GACjC,IAAA;AACJ,IAAA,MAAM,QAAA,GAAW,WAAW,IAAA,GAAO,IAAA,CAAK,IAAI,MAAA,GAAS,EAAA,EAAI,EAAA,GAAK,EAAE,CAAA,GAAI,CAAA;AAEpE,IAAA,2CACG,KAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QAAI,OAAA,EAAS,CAAA,IAAA,EAAO,EAAE,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AAAA,QAAI,KAAA,EAAM,MAAA;AAAA,QAAO,KAAA,EAAO,EAAE,OAAA,EAAS,OAAA,EAAS,UAAU,SAAA,EAAU;AAAA,QAC/F,WAAA,EAAa,eAAA;AAAA,QAAiB,YAAA,EAAc,MAAM,WAAA,CAAY,IAAI;AAAA,OAAA;AAAA,MACjE,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM;AACpB,QAAA,MAAM,IAAI,IAAA,CAAK,GAAA,CAAI,GAAI,CAAA,GAAIA,IAAAA,IAAQ,SAAS,CAAA,CAAE,CAAA;AAC9C,QAAA,uBACE,KAAA,CAAA,aAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YAAK,GAAA,EAAK,CAAA;AAAA,YAAG,CAAA,EAAG,KAAK,IAAA,GAAO,GAAA,CAAA;AAAA,YAAM,GAAG,MAAA,GAAS,CAAA;AAAA,YAAG,KAAA,EAAO,IAAA;AAAA,YAAM,MAAA,EAAQ,CAAA;AAAA,YAAG,EAAA,EAAI,GAAA;AAAA,YAC5E,IAAA,EAAM,KAAA;AAAA,YAAO,SAAS,CAAA,KAAM,QAAA,GAAW,IAAI,GAAA,GAAO,CAAA,GAAI,OAAO,MAAA,GAAU;AAAA;AAAA,SAAM;AAAA,MAEnF,CAAC,CAAA;AAAA,sBACD,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAI,CAAA,EAAG,IAAI,MAAA,GAAS,GAAA,EAAK,EAAA,EAAI,EAAA,EAAI,IAAI,MAAA,GAAS,GAAA,EAAK,MAAA,EAAQ,WAAA,EAAa,aAAa,CAAA,EAAG,CAAA;AAAA,MAC7F,QAAA,KAAa,QAAQ,MAAA,KAAW,IAAA,8EAE7B,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAG,QAAA,EAAU,CAAA,EAAG,CAAA,EAAG,OAAO,EAAA,EAAI,MAAA,EAAQ,EAAA,EAAI,EAAA,EAAI,CAAA,EAAG,IAAA,EAAM,WAAW,MAAA,EAAQ,UAAA,EAAY,WAAA,EAAa,CAAA,EAAG,CAAA,kBAC5G,KAAA,CAAA,aAAA,CAAC,UAAK,CAAA,EAAG,QAAA,GAAW,IAAI,CAAA,EAAG,EAAA,EAAI,YAAW,QAAA,EAAS,IAAA,EAAM,WAAA,EAAa,QAAA,EAAU,CAAA,EAAG,UAAA,EAAY,KAAK,UAAA,EAAY,IAAA,EAAA,EAC7G,UAAA,CAAW,QAAQ,CAAA,EAAE,IAAA,EAAG,YAAY,MAAA,CAAO,QAAQ,CAAC,CACvD,CACF;AAAA,KAEJ,sCACC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,gBAAgB,eAAA,EAAiB,SAAA,EAAW,GAAE,EAAA,kBAC3E,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO,EAAE,UAAU,CAAA,EAAG,KAAA,EAAO,SAAS,SAAA,GAAY,SAAA,MAAc,UAAA,CAAW,CAAC,CAAE,CAAA,kBACpF,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO,EAAE,UAAU,CAAA,EAAG,KAAA,EAAO,SAAS,SAAA,GAAY,SAAA,MAAc,UAAA,CAAW,UAAA,CAAW,SAAS,CAAC,CAAE,CAC1G,CACF,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,OAAO,IAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,QAAQ,IAAI,CAAA;AACpC,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,GAAG,MAAM,CAAA;AAC9B,EAAA,MAAM,KAAA,GAAQ,GAAA,GAAM,GAAA,IAAO,GAAA,IAAO,CAAA;AAClC,EAAA,MAAM,GAAA,GAAM,CAAA;AACZ,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,GAAA,CAAI,CAAC,GAAG,CAAA,KAAwB;AAAA,IAChD,KAAK,MAAA,CAAO,MAAA,GAAS,CAAA,CAAA,IAAO,EAAA,GAAK,MAAM,CAAA,CAAA,GAAK,GAAA;AAAA,IAC5C,MAAA,GAAS,MAAM,CAAA,GAAA,CAAO,CAAA,GAAI,OAAO,KAAA,IAAU,MAAA,GAAS,GAAA,GAAM,CAAA,GAAI,CAAA,CAAA,GAAK;AAAA,GACrE,CAAA;AACD,EAAA,MAAM,CAAA,GAAI,GAAA,CAAI,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,GAAA,GAAM,GAAG,CAAA,EAAG,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAClG,EAAA,MAAM,IAAA,GAAO,GAAG,CAAC,CAAA,EAAA,EAAK,IAAI,GAAA,CAAI,MAAA,GAAO,CAAC,CAAA,CAAE,CAAC,CAAC,CAAA,CAAA,EAAI,MAAM,KAAK,GAAA,CAAI,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAA,EAAA,CAAA;AAC5E,EAAA,MAAM,OAAA,GAAU,QAAA,KAAa,IAAA,GAAO,GAAA,CAAI,QAAQ,CAAA,GAAI,IAAA;AACpD,EAAA,MAAM,SAAA,GAAY,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,CAAC,CAAA,GAAI,EAAA,EAAI,EAAA,GAAK,EAAE,CAAA,GAAI,CAAA;AAEjE,EAAA,2CACG,KAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MAAI,OAAA,EAAS,CAAA,IAAA,EAAO,EAAE,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AAAA,MAAI,KAAA,EAAM,MAAA;AAAA,MAAO,KAAA,EAAO,EAAE,OAAA,EAAS,OAAA,EAAS,UAAU,SAAA,EAAU;AAAA,MAC/F,WAAA,EAAa,eAAA;AAAA,MAAiB,YAAA,EAAc,MAAM,WAAA,CAAY,IAAI;AAAA,KAAA;AAAA,wCACjE,MAAA,EAAA,EAAK,CAAA,EAAG,MAAM,IAAA,EAAM,KAAA,EAAO,SAAS,IAAA,EAAM,CAAA;AAAA,oBAC3C,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAM,IAAA,EAAK,MAAA,EAAO,MAAA,EAAQ,KAAA,EAAO,WAAA,EAAa,GAAA,EAAK,cAAA,EAAe,OAAA,EAAQ,aAAA,EAAc,OAAA,EAAQ,CAAA;AAAA,IACrG,GAAA,CAAI,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAA,qBAChB,KAAA,CAAA,aAAA,CAAC,QAAA,EAAA,EAAO,GAAA,EAAK,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,CAAA,EAAG,CAAA,KAAM,QAAA,GAAW,GAAA,GAAM,CAAA,KAAM,GAAA,CAAI,MAAA,GAAS,CAAA,GAAI,GAAA,GAAM,CAAA,EAAG,IAAA,EAAM,KAAA,EAAO,CACtG,CAAA;AAAA,oBACD,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAI,CAAA,EAAG,IAAI,MAAA,GAAS,GAAA,EAAK,EAAA,EAAI,EAAA,EAAI,IAAI,MAAA,GAAS,GAAA,EAAK,MAAA,EAAQ,WAAA,EAAa,aAAa,CAAA,EAAG,CAAA;AAAA,IAC7F,OAAA,IAAW,QAAA,KAAa,IAAA,oBACvB,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,sCACG,MAAA,EAAA,EAAK,EAAA,EAAI,OAAA,CAAQ,CAAC,GAAG,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,OAAA,CAAQ,CAAC,CAAA,EAAG,EAAA,EAAI,MAAA,EAAQ,MAAA,EAAQ,KAAA,EAAO,WAAA,EAAa,CAAA,EAAG,eAAA,EAAgB,OAAM,OAAA,EAAS,GAAA,EAAK,CAAA,kBAC5H,KAAA,CAAA,aAAA,CAAC,UAAK,CAAA,EAAG,SAAA,EAAW,CAAA,EAAG,CAAA,EAAG,OAAO,EAAA,EAAI,MAAA,EAAQ,EAAA,EAAI,EAAA,EAAI,CAAA,EAAG,IAAA,EAAM,SAAA,EAAW,MAAA,EAAQ,YAAY,WAAA,EAAa,CAAA,EAAG,CAAA,kBAC7G,KAAA,CAAA,aAAA,CAAC,UAAK,CAAA,EAAG,SAAA,GAAY,EAAA,EAAI,CAAA,EAAG,IAAI,UAAA,EAAW,QAAA,EAAS,IAAA,EAAM,WAAA,EAAa,QAAA,EAAU,CAAA,EAAG,UAAA,EAAY,GAAA,EAAK,YAAY,IAAA,EAAA,EAC9G,UAAA,CAAW,QAAQ,CAAA,EAAE,MAAG,WAAA,CAAY,MAAA,CAAO,QAAQ,CAAC,CACvD,CACF;AAAA,GAEJ,sCACC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,gBAAgB,eAAA,EAAiB,SAAA,EAAW,GAAE,EAAA,kBAC3E,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO,EAAE,UAAU,CAAA,EAAG,KAAA,EAAO,SAAS,SAAA,GAAY,SAAA,MAAc,UAAA,CAAW,CAAC,CAAE,CAAA,kBACpF,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO,EAAE,UAAU,CAAA,EAAG,KAAA,EAAO,SAAS,SAAA,GAAY,SAAA,MAAc,UAAA,CAAW,UAAA,CAAW,SAAS,CAAC,CAAE,CAC1G,CACF,CAAA;AAEJ;AAWA,SAAS,aAAA,CAAc;AAAA,EACrB,MAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,WAAA;AAAA,EACA,GAAA;AAAA,EACA,IAAA;AAAA,EACA,eAAA;AAAA,EACA;AACF,CAAA,EAWG;AACD,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,IAAA,KAAS,MAAA;AACtC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAwB,IAAI,CAAA;AAC5D,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAmC,IAAI,CAAA;AACrE,EAAA,MAAM,YAAA,GAAe,OAAuB,IAAI,CAAA;AAEhD,EAAA,MAAM,CAAA,GAAI,KAAK,CAAA,GAAI,GAAA;AACnB,EAAA,MAAM,GAAA,GAAM,EAAE,GAAA,EAAK,EAAA,EAAI,OAAO,EAAA,EAAI,MAAA,EAAQ,EAAA,EAAI,IAAA,EAAM,EAAA,EAAG;AACvD,EAAA,MAAM,EAAA,GAAK,CAAA,GAAI,GAAA,CAAI,IAAA,GAAO,GAAA,CAAI,KAAA;AAC9B,EAAA,MAAM,EAAA,GAAK,CAAA,GAAI,GAAA,CAAI,GAAA,GAAM,GAAA,CAAI,MAAA;AAI7B,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,GAAG,QAAQ,IAAI,CAAA;AACxC,EAAA,MAAM,OAAA,GAAU,SAAS,MAAA,GAAS,IAAA,CAAK,IAAI,GAAG,MAAA,EAAQ,CAAC,CAAA,GAAI,CAAA;AAC3D,EAAA,MAAM,SAAA,GAAY,OAAA,GAAU,OAAA,IAAW,OAAA,IAAW,CAAA;AAClD,EAAA,MAAM,SAAS,CAAC,CAAA,KAAc,EAAA,GAAA,CAAO,CAAA,GAAI,WAAW,SAAA,GAAa,EAAA;AAGjE,EAAA,MAAM,WAAW,IAAA,CAAK,GAAA,KAAQ,IAAA,GAAO,EAAA,GAAK,KAAK,EAAA,GAAK,GAAA;AACpD,EAAA,MAAM,OAAA,GAAW,IAAA,GAAO,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,GAAA;AACvC,EAAA,MAAM,KAAA,GAAQ,CAAC,EAAA,KAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,EAAA,EAAA,CAAM,EAAA,GAAK,QAAA,IAAY,OAAA,GAAW,EAAE,CAAC,CAAA;AAExF,EAAA,MAAM,IAAA,GAAO,CAAC,CAAA,KAAc,WAAA,CAAY,WAAW,MAAA,CAAO,MAAA,GACtD,MAAM,WAAA,CAAY,CAAC,CAAC,CAAA,GACnB,MAAA,CAAO,SAAS,CAAA,GAAK,CAAA,IAAK,OAAO,MAAA,GAAS,CAAA,CAAA,GAAM,KAAK,EAAA,GAAK,CAAA;AAE/D,EAAA,MAAM,MAA0B,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,EAAG,MAAM,CAAC,GAAA,CAAI,IAAA,GAAO,IAAA,CAAK,CAAC,CAAA,EAAG,GAAA,CAAI,MAAM,MAAA,CAAO,CAAC,CAAC,CAAC,CAAA;AAC9F,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,GAAA,GAAM,GAAG,CAAA,EAAG,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,EAAI,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AACzG,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,MAAA,GAAS,CAAA,GAC1B,CAAA,EAAG,QAAQ,CAAA,EAAA,EAAK,GAAA,CAAI,GAAA,CAAI,MAAA,GAAO,CAAC,CAAA,CAAE,CAAC,CAAC,CAAA,CAAA,EAAI,GAAA,CAAI,GAAA,GAAI,EAAE,CAAA,EAAA,EAAK,GAAA,CAAI,CAAC,CAAA,CAAE,CAAC,CAAC,CAAA,CAAA,EAAI,GAAA,CAAI,GAAA,GAAI,EAAE,CAAA,EAAA,CAAA,GAC9E,EAAA;AAEJ,EAAA,MAAM,GAAA,GAAO,CAAA;AACb,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,GAAS,CAAA,GAAA,CAAK,EAAA,GAAK,OAAO,MAAA,CAAO,MAAA,GAAS,CAAA,CAAA,IAAM,MAAA,CAAO,MAAA,GAAS,EAAA;AAEpF,EAAA,MAAM,MAAA,GAAS,CAAC,CAAA,EAAG,IAAA,EAAM,GAAA,EAAK,IAAA,EAAM,CAAC,CAAA,CAAE,GAAA,CAAI,CAAA,CAAA,KAAK,OAAA,GAAU,CAAA,GAAI,SAAS,CAAA;AACvE,EAAA,MAAM,SAAA,GAAa,SAAS,wBAAA,GAA2B,kBAAA;AACvD,EAAA,MAAM,SAAA,GAAa,SAAS,SAAA,GAAY,SAAA;AACxC,EAAA,MAAM,UAAA,GAAa,SAAS,SAAA,GAAY,SAAA;AACxC,EAAA,MAAM,IAAA,GAAa,4BAAA;AACnB,EAAA,MAAM,SAAa,CAAA,GAAA,EAAM,KAAA,CAAM,OAAA,CAAQ,GAAA,EAAI,EAAE,CAAC,CAAA,CAAA;AAG9C,EAAA,MAAM,aAAA,GAAgB,CAAC,EAAA,KAAuB;AAC5C,IAAA,IAAI,WAAA,CAAY,MAAA,KAAW,CAAA,EAAG,OAAO,CAAA;AACrC,IAAA,IAAI,IAAA,GAAO,GAAG,QAAA,GAAW,QAAA;AACzB,IAAA,WAAA,CAAY,OAAA,CAAQ,CAAC,GAAA,EAAK,CAAA,KAAM;AAC9B,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,EAAA,GAAK,GAAG,CAAA;AAC3B,MAAA,IAAI,IAAI,QAAA,EAAU;AAAE,QAAA,QAAA,GAAW,CAAA;AAAG,QAAA,IAAA,GAAO,CAAA;AAAA,MAAG;AAAA,IAC9C,CAAC,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,kBAAA,GAAqB,CAAC,CAAA,KAAuC;AACjE,IAAA,MAAM,IAAA,GAAO,CAAA,CAAE,aAAA,CAAc,qBAAA,EAAsB;AACnD,IAAA,MAAM,IAAA,GAAA,CAAQ,CAAA,CAAE,OAAA,GAAU,IAAA,CAAK,IAAA,GAAO,GAAA,CAAI,IAAA,IAAQ,IAAA,CAAK,KAAA,GAAQ,CAAA,CAAA,KAAO,IAAA,CAAK,KAAA,GAAQ,EAAA,GAAK,CAAA,CAAA;AACxF,IAAA,MAAM,MAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,IAAA,CAAK,MAAM,IAAA,IAAQ,MAAA,CAAO,MAAA,GAAS,CAAA,CAAE,CAAC,CAAC,CAAA;AAC5F,IAAA,WAAA,CAAY,GAAG,CAAA;AACf,IAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,OAAA,EAAS,qBAAA,EAAsB;AAC1D,IAAA,MAAM,CAAA,GAAI,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,MAAM,IAAA,GAAO,CAAA;AAC3C,IAAA,MAAM,CAAA,GAAI,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,MAAM,GAAA,GAAO,CAAA;AAC3C,IAAA,UAAA,CAAW,EAAE,CAAA,EAAG,CAAA,EAAG,OAAA,EAAS,WAAA,CAAY,MAAA,CAAO,GAAG,CAAC,CAAA,EAAG,SAAA,EAAW,UAAA,CAAW,GAAG,GAAG,CAAA;AAAA,EACpF,CAAA;AAEA,EAAA,uBACE,KAAA,CAAA,aAAA,CAAC,SAAI,GAAA,EAAK,YAAA,EAAc,OAAO,EAAE,QAAA,EAAU,YAAW,EAAA,kBACpD,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MAAI,OAAA,EAAS,CAAA,IAAA,EAAO,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA;AAAA,MAAI,KAAA,EAAM,MAAA;AAAA,MAAO,KAAA,EAAO,EAAE,OAAA,EAAS,OAAA,EAAQ;AAAA,MACpE,WAAA,EAAa,kBAAA;AAAA,MACb,cAAc,MAAM;AAAE,QAAA,WAAA,CAAY,IAAI,CAAA;AAAG,QAAA,UAAA,CAAW,IAAI,CAAA;AAAA,MAAG;AAAA,KAAA;AAAA,oBAC3D,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,gBAAA,EAAA,EAAe,EAAA,EAAI,QAAQ,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,GAAA,EAAI,IAAG,GAAA,EAAA,kBAClD,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,MAAA,EAAO,IAAA,EAAK,SAAA,EAAW,KAAA,EAAO,WAAA,EAAa,IAAA,EAAM,CAAA,kBACvD,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,MAAA,EAAO,MAAA,EAAO,WAAW,KAAA,EAAO,WAAA,EAAa,CAAA,EAAG,CACxD,CAAA,kBAEA,KAAA,CAAA,aAAA,CAAC,cAAS,EAAA,EAAI,CAAA,OAAA,EAAU,MAAM,CAAA,CAAA,EAAA,kBAC5B,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,GAAG,GAAA,CAAI,IAAA,EAAM,CAAA,EAAG,GAAA,CAAI,GAAA,GAAM,CAAA,EAAG,KAAA,EAAO,EAAA,EAAI,MAAA,EAAQ,EAAA,GAAK,EAAA,EAAI,CACjE,CACF,CAAA;AAAA,IAGC,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM;AACpB,MAAA,MAAM,CAAA,GAAI,GAAA,CAAI,GAAA,GAAM,MAAA,CAAO,CAAC,CAAA;AAC5B,MAAA,uBACE,KAAA,CAAA,aAAA,CAAC,OAAE,GAAA,EAAK,CAAA,EAAA,EACL,IAAI,CAAA,oBAAK,KAAA,CAAA,aAAA,CAAC,UAAK,EAAA,EAAI,GAAA,CAAI,MAAM,EAAA,EAAI,CAAA,EAAG,IAAI,GAAA,CAAI,IAAA,GAAK,IAAI,EAAA,EAAI,CAAA,EAAG,MAAA,EAAQ,SAAA,EAAW,WAAA,EAAa,CAAA,EAAG,iBAAgB,KAAA,EAAM,CAAA,sCACrH,MAAA,EAAA,EAAK,CAAA,EAAG,IAAI,IAAA,GAAO,CAAA,EAAG,GAAG,CAAA,GAAI,CAAA,EAAG,YAAW,KAAA,EAAM,IAAA,EAAM,YAAY,QAAA,EAAU,EAAA,EAAI,YAAY,IAAA,EAAA,EAC3F,WAAA,CAAY,CAAC,CAChB,CACF,CAAA;AAAA,IAEJ,CAAC,CAAA;AAAA,oBACD,KAAA,CAAA,aAAA,CAAC,UAAK,EAAA,EAAI,GAAA,CAAI,MAAM,EAAA,EAAI,GAAA,CAAI,MAAI,EAAA,EAAI,EAAA,EAAI,IAAI,IAAA,GAAK,EAAA,EAAI,IAAI,GAAA,CAAI,GAAA,GAAI,IAAI,MAAA,EAAQ,SAAA,EAAW,aAAa,CAAA,EAAG,CAAA;AAAA,IAGvG,SAAS,KAAA,GACR,MAAA,CAAO,GAAA,CAAI,CAAC,GAAG,CAAA,KAAM;AACnB,MAAA,MAAM,KAAK,IAAA,CAAK,GAAA,CAAI,IAAK,CAAA,GAAI,OAAA,IAAW,YAAa,EAAE,CAAA;AACvD,MAAA,MAAM,CAAA,GAAK,GAAA,CAAI,IAAA,GAAO,CAAA,IAAK,IAAA,GAAO,GAAA,CAAA;AAClC,MAAA,uBACE,KAAA,CAAA,aAAA;AAAA,QAAC,MAAA;AAAA,QAAA;AAAA,UAAK,GAAA,EAAK,CAAA;AAAA,UAAG,CAAA;AAAA,UAAM,CAAA,EAAG,GAAA,CAAI,GAAA,GAAI,EAAA,GAAG,EAAA;AAAA,UAAI,KAAA,EAAO,IAAA;AAAA,UAAM,MAAA,EAAQ,EAAA;AAAA,UAAI,EAAA,EAAI,CAAA;AAAA,UACjE,IAAA,EAAM,KAAA;AAAA,UAAO,OAAA,EAAS,CAAA,KAAM,QAAA,GAAW,IAAA,GAAO,GAAA,GAAO,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,CAAC,CAAA,GAAK;AAAA;AAAA,OAAM;AAAA,IAEvG,CAAC,CAAA,mBAED,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,EACG,QAAA,wCAAa,MAAA,EAAA,EAAK,CAAA,EAAG,QAAA,EAAU,IAAA,EAAM,QAAQ,MAAM,CAAA,CAAA,CAAA,EAAK,CAAA,kBACzD,KAAA,CAAA,aAAA,CAAC,UAAK,CAAA,EAAG,QAAA,EAAU,IAAA,EAAK,MAAA,EAAO,QAAQ,KAAA,EAAO,WAAA,EAAa,GAAA,EAAK,cAAA,EAAe,SAAQ,aAAA,EAAc,OAAA,EAAQ,CAAA,EAC5G,GAAA,CAAI,IAAI,CAAC,CAAC,CAAA,EAAG,CAAC,GAAG,CAAA,qBAChB,KAAA,CAAA,aAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QAAO,GAAA,EAAK,CAAA;AAAA,QAAG,EAAA,EAAI,CAAA;AAAA,QAAG,EAAA,EAAI,CAAA;AAAA,QACzB,CAAA,EAAG,CAAA,KAAM,QAAA,GAAW,GAAA,GAAM,CAAA;AAAA,QAC1B,IAAA,EAAM,SAAS,SAAA,GAAY,SAAA;AAAA,QAAW,MAAA,EAAQ,KAAA;AAAA,QAC9C,WAAA,EAAa,CAAA,KAAM,QAAA,GAAW,GAAA,GAAM;AAAA;AAAA,KACvC,CACH,CAAA;AAAA,IAID,GAAA,IAAO,IAAA,KAAS,MAAA,oBACf,KAAA,CAAA,aAAA,CAAC,GAAA,EAAA,EAAE,QAAA,EAAU,CAAA,YAAA,EAAe,MAAM,CAAA,CAAA,CAAA,EAAA,EAC/B,GAAA,CAAI,GAAA,CAAI,CAAC,IAAI,MAAA,KAAW;AACvB,MAAA,MAAM,WAAW,IAAI,IAAA,CAAK,EAAA,CAAG,QAAQ,EAAE,OAAA,EAAQ;AAC/C,MAAA,MAAM,IAAA,GAAO,cAAc,QAAQ,CAAA;AAEnC,MAAA,MAAM,WAAW,EAAA,CAAG,MAAA,GAAS,KAAK,MAAA,GAAS,EAAA,IAAM,KAAK,CAAA,IAAK,CAAA;AAC3D,MAAA,MAAM,EAAA,GAAK,GAAA,CAAI,IAAA,GAAO,IAAA,CAAK,IAAI,CAAA,GAAI,MAAA;AAEnC,MAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,GAAA,GAAM,MAAA,CAAO,GAAG,aAAa,CAAA;AAC/C,MAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,GAAA,CAAI,GAAA,GAAM,EAAA,GAAK,CAAA,EAAG,KAAK,CAAC,CAAA;AAClE,MAAA,MAAM,KAAA,GAAQ,GAAG,MAAA,KAAW,eAAA;AAG5B,MAAA,MAAM,OAAA,GAAU,IAAI,IAAI,CAAA;AAExB,MAAA,uBACE,KAAA,CAAA,aAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UAAE,KAAK,EAAA,CAAG,MAAA;AAAA,UAAQ,KAAA,EAAO,EAAE,MAAA,EAAQ,SAAA,EAAU;AAAA,UAC5C,cAAc,CAAA,CAAA,KAAK;AACjB,YAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,YAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,OAAA,EAAS,qBAAA,EAAsB;AAC1D,YAAA,MAAM,CAAA,GAAI,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,MAAM,IAAA,GAAO,CAAA;AAC3C,YAAA,MAAM,CAAA,GAAI,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,MAAM,GAAA,GAAO,CAAA;AAC3C,YAAA,UAAA,CAAW;AAAA,cAAE,CAAA;AAAA,cAAG,CAAA;AAAA,cACd,SAAS,CAAA,CAAA,EAAI,EAAA,CAAG,MAAM,CAAA,EAAA,EAAK,GAAG,KAAK,CAAA,CAAA;AAAA,cACnC,SAAA,EAAW,GAAG,WAAA,CAAY,EAAA,CAAG,aAAa,CAAC,CAAA,MAAA,EAAM,IAAI,IAAA,CAAK,EAAA,CAAG,QAAQ,CAAA,CAAE,kBAAA,CAAmB,SAAS,EAAE,KAAA,EAAO,SAAS,GAAA,EAAK,SAAA,EAAW,CAAC,CAAA;AAAA,aAAI,CAAA;AAC5I,YAAA,SAAA,GAAY,GAAG,MAAM,CAAA;AAAA,UACvB,CAAA;AAAA,UACA,cAAc,MAAM;AAAE,YAAA,UAAA,CAAW,IAAI,CAAA;AAAG,YAAA,SAAA,GAAY,IAAI,CAAA;AAAA,UAAG;AAAA,SAAA;AAAA,QAC1D,OAAA,oBACC,KAAA,CAAA,aAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YAAK,EAAA,EAAI,EAAA;AAAA,YAAI,EAAA,EAAI,EAAA;AAAA,YAAI,EAAA,EAAI,QAAQ,CAAC,CAAA;AAAA,YAAG,EAAA,EAAI,QAAQ,CAAC,CAAA;AAAA,YACjD,MAAA,EAAQ,KAAA;AAAA,YAAO,WAAA,EAAa,QAAQ,CAAA,GAAI,GAAA;AAAA,YACxC,eAAA,EAAgB,KAAA;AAAA,YAAM,OAAA,EAAS,QAAQ,GAAA,GAAM;AAAA;AAAA,SAAK;AAAA,wBAEtD,KAAA,CAAA,aAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAI,EAAA,EAAI,IAAI,EAAA,EAAI,CAAA,EAAG,KAAA,GAAQ,EAAA,GAAK,GAAG,IAAA,EAAM,KAAA,EAAO,OAAA,EAAS,KAAA,GAAQ,MAAM,GAAA,EAAK,CAAA;AAAA,wBACpF,KAAA,CAAA,aAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YAAO,EAAA,EAAI,EAAA;AAAA,YAAI,EAAA,EAAI,EAAA;AAAA,YAAI,CAAA,EAAG,QAAQ,GAAA,GAAM,GAAA;AAAA,YACvC,IAAA,EAAM,KAAA,GAAQ,KAAA,GAAS,MAAA,GAAS,SAAA,GAAY,MAAA;AAAA,YAC5C,MAAA,EAAQ,KAAA;AAAA,YAAO,WAAA,EAAa,QAAQ,CAAA,GAAI,GAAA;AAAA,YACxC,OAAA,EAAS,QAAQ,CAAA,GAAI;AAAA;AAAA;AAAK,OAC9B;AAAA,IAEJ,CAAC,CACH,CAAA;AAAA,IAID,aAAa,IAAA,IAAQ,IAAA,KAAS,UAAU,GAAA,CAAI,QAAQ,qBACnD,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBACE,KAAA,CAAA,aAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QAAK,EAAA,EAAI,GAAA,CAAI,QAAQ,CAAA,CAAE,CAAC,CAAA;AAAA,QAAG,IAAI,GAAA,CAAI,GAAA;AAAA,QAAK,EAAA,EAAI,GAAA,CAAI,QAAQ,CAAA,CAAE,CAAC,CAAA;AAAA,QAAG,EAAA,EAAI,IAAI,GAAA,GAAI,EAAA;AAAA,QACzE,MAAA,EAAQ,KAAA;AAAA,QAAO,WAAA,EAAa,CAAA;AAAA,QAAG,eAAA,EAAgB,KAAA;AAAA,QAAM,OAAA,EAAS;AAAA;AAAA,KAAK,kBACrE,KAAA,CAAA,aAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QAAK,IAAI,GAAA,CAAI,IAAA;AAAA,QAAM,EAAA,EAAI,GAAA,CAAI,QAAQ,CAAA,CAAE,CAAC,CAAA;AAAA,QAAG,EAAA,EAAI,IAAI,IAAA,GAAK,EAAA;AAAA,QAAI,EAAA,EAAI,GAAA,CAAI,QAAQ,CAAA,CAAE,CAAC,CAAA;AAAA,QAC5E,MAAA,EAAQ,KAAA;AAAA,QAAO,WAAA,EAAa,CAAA;AAAA,QAAG,eAAA,EAAgB,KAAA;AAAA,QAAM,OAAA,EAAS;AAAA;AAAA,KAClE,CAAA;AAAA,IAID,UAAA,CAAW,GAAA,CAAI,CAAC,GAAA,EAAK,CAAA,KAAM;AAC1B,MAAA,MAAM,QAAQ,UAAA,CAAW,MAAA;AACzB,MAAA,MAAM,IAAA,GAAQ,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,KAAA,CAAM,KAAA,GAAQ,CAAC,CAAC,CAAA;AAC/C,MAAA,IAAI,CAAA,KAAM,KAAK,CAAA,KAAM,KAAA,GAAQ,KAAK,CAAA,GAAI,IAAA,KAAS,GAAG,OAAO,IAAA;AACzD,MAAA,MAAM,CAAA,GAAI,IAAA,KAAS,KAAA,GACf,GAAA,CAAI,IAAA,GAAO,CAAA,IAAK,IAAA,GAAO,GAAA,CAAA,GAAO,IAAA,GAAO,CAAA,GACrC,GAAA,CAAI,IAAA,GAAO,KAAK,CAAC,CAAA;AACrB,MAAA,2CACG,MAAA,EAAA,EAAK,GAAA,EAAK,CAAA,EAAG,CAAA,EAAM,GAAG,CAAA,GAAI,CAAA,EAAG,UAAA,EAAW,QAAA,EAAS,MAAM,UAAA,EAAY,QAAA,EAAU,EAAA,EAAI,UAAA,EAAY,QAC3F,GACH,CAAA;AAAA,IAEJ,CAAC;AAAA,GACH,EAGC,YAAY,MAAM;AACjB,IAAA,MAAM,EAAA,GAAK,GAAA;AACX,IAAA,MAAM,GAAA,GAAM,YAAA,CAAa,OAAA,EAAS,WAAA,IAAe,GAAA;AACjD,IAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,CAAA,GAAI,EAAA,GAAK,EAAA,GAAK,GAAA;AACxC,IAAA,uBACE,KAAA,CAAA,aAAA,CAAC,SAAI,KAAA,EAAO;AAAA,MACV,QAAA,EAAU,UAAA;AAAA,MACV,MAAM,SAAA,GAAY,OAAA,CAAQ,IAAI,EAAA,GAAK,CAAA,GAAI,QAAQ,CAAA,GAAI,CAAA;AAAA,MACnD,GAAA,EAAK,QAAQ,CAAA,GAAI,EAAA;AAAA,MACjB,MAAA,EAAQ,IAAA;AAAA,MAAM,aAAA,EAAe,MAAA;AAAA,MAC7B,UAAA,EAAY,SAAS,SAAA,GAAY,SAAA;AAAA,MACjC,MAAA,EAAQ,CAAA,UAAA,EAAa,MAAA,GAAS,SAAA,GAAY,SAAS,CAAA,CAAA;AAAA,MACnD,YAAA,EAAc,CAAA;AAAA,MAAG,OAAA,EAAS,UAAA;AAAA,MAC1B,SAAA,EAAW,SAAS,6BAAA,GAAgC,6BAAA;AAAA,MACpD,KAAA,EAAO;AAAA,KACT,EAAA,kBACE,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO;AAAA,MAAE,QAAA,EAAU,EAAA;AAAA,MAAI,UAAA,EAAY,GAAA;AAAA,MAAK,KAAA,EAAO,SAAS,SAAA,GAAY,SAAA;AAAA,MACvE,UAAA,EAAY,IAAA;AAAA,MAAM,UAAA,EAAY;AAAA,KAAI,EAAA,EACjC,QAAQ,OACX,CAAA,EACC,QAAQ,SAAA,oBACP,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,QAAA,EAAU,IAAI,KAAA,EAAO,MAAA,GAAS,SAAA,GAAY,SAAA,EAAW,UAAA,EAAY,IAAA,EAAM,WAAW,CAAA,EAAE,EAAA,EAC/F,OAAA,CAAQ,SACX,CAEJ,CAAA;AAAA,EAEJ,IACF,CAAA;AAEJ;AAmBA,SAAS,eAAA,CAAgB;AAAA,EACvB,IAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA,EAIG;AACD,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,IAAA,KAAS,MAAA;AACtC,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAI,SAAwB,IAAI,CAAA;AAC1E,EAAA,MAAM,SAAA,GAAY,MAAA,iBAAoC,IAAI,GAAA,EAAK,CAAA;AAE/D,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,KAAqB;AAAE,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,QAAA,EAAU,OAAA,EAAQ;AAAA,IAAG,CAAA;AACzE,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,KAAK,CAAA;AACxC,IAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,KAAK,CAAA;AAAA,EAC1D,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAGZ,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,oBAAoB,IAAA,EAAM;AAC5B,MAAA,MAAM,EAAA,GAAK,SAAA,CAAU,OAAA,CAAQ,GAAA,CAAI,eAAe,CAAA;AAChD,MAAA,IAAI,EAAA,KAAO,cAAA,CAAe,EAAE,UAAU,QAAA,EAAU,KAAA,EAAO,WAAW,CAAA;AAAA,IACpE;AAAA,EACF,CAAA,EAAG,CAAC,eAAe,CAAC,CAAA;AAEpB,EAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAQ,WAAA,EAAa,aAAA,EAAe,eAAA,EAAiB,aAAA,EAAe,cAAA,EAAgB,UAAA,EAAY,WAAA,EAAa,GAAA,EAAK,WAAA,EAAY,GAAI,IAAA;AACjJ,EAAA,MAAM,eAAgB,aAAA,KAAkB,KAAA;AACxC,EAAA,MAAM,YAAA,GAAgB,MAAA,CAAO,IAAA,KAAS,OAAA,GAAU,cAAA,CAAe,OAAO,KAAK,CAAA,GAAI,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA;AAClG,EAAA,MAAM,WAAA,GAAgB,MAAA,CAAO,IAAA,KAAS,OAAA,GAAU,KAAK,MAAA,CAAO,IAAA;AAC5D,EAAA,MAAM,SAAA,GAAgB,CAAC,CAAA,KAAc,MAAA,CAAO,SAAS,OAAA,GAAU,cAAA,CAAe,CAAC,CAAA,GAAI,GAAG,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,EAAE,IAAI,EAAE,CAAA,CAAA;AAC7G,EAAA,MAAM,WAAA,GAAgB,SAAS,SAAA,GAAY,SAAA;AAC3C,EAAA,MAAM,UAAA,GAAgB,SAAS,SAAA,GAAY,SAAA;AAC3C,EAAA,MAAM,cAAgB,aAAA,GAClB,CAAA,UAAA,EAAa,OAAO,IAAA,KAAS,OAAA,GAAU,eAAe,MAAA,CAAO,MAAM,IAAI,MAAA,CAAO,MAAM,IAAI,WAAW,CAAA,CAAA,GACnG,kBAAa,MAAA,CAAO,MAAM,IAAI,WAAW,CAAA,CAAA;AAG7C,EAAA,MAAM,YAAY,YAAA,IAAgB,GAAA,GAAM,IAAI,MAAA,CAAO,CAAC,KAAK,EAAA,KAAO;AAC9D,IAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,EAAA,CAAG,QAAQ,CAAA,CAAE,kBAAA,CAAmB,OAAA,EAAS,EAAE,SAAS,OAAA,EAAS,KAAA,EAAO,OAAA,EAAS,GAAA,EAAK,WAAW,CAAA;AACnH,IAAA,IAAI,CAAC,GAAA,CAAI,IAAI,GAAG,GAAA,CAAI,IAAI,IAAI,EAAC;AAC7B,IAAA,GAAA,CAAI,IAAI,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA;AACjB,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,EAAG,EAAgC,CAAA,GAAI,EAAC;AACxC,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,CAAE,IAAA;AAAA,IACzC,CAAC,GAAG,CAAA,KAAM,IAAI,KAAK,SAAA,CAAU,CAAC,CAAA,CAAE,CAAC,CAAA,CAAE,QAAQ,EAAE,OAAA,EAAQ,GAAI,IAAI,IAAA,CAAK,SAAA,CAAU,CAAC,EAAE,CAAC,CAAA,CAAE,QAAQ,CAAA,CAAE,OAAA;AAAQ,GACtG;AAEA,EAAA,uBACE,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,kBAEE,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,OAAA,EAAS,SAAS,KAAA,EAAO;AAAA,IAC5B,QAAA,EAAU,OAAA;AAAA,IAAS,KAAA,EAAO,CAAA;AAAA,IAAG,MAAA,EAAQ,GAAA;AAAA,IACrC,UAAA,EAAY,SAAS,iBAAA,GAAoB,iBAAA;AAAA,IACzC,cAAA,EAAgB;AAAA,GAClB,EAAG,CAAA,kBAGH,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO;AAAA,IACV,QAAA,EAAU,OAAA;AAAA,IACV,GAAA,EAAK,KAAA;AAAA,IAAO,IAAA,EAAM,KAAA;AAAA,IAClB,SAAA,EAAW,mCAAA;AAAA,IACX,KAAA,EAAO,kBAAA;AAAA,IACP,SAAA,EAAW,oBAAA;AAAA,IACX,MAAA,EAAQ,GAAA;AAAA,IACR,UAAA,EAAY,SAAS,SAAA,GAAY,SAAA;AAAA,IACjC,MAAA,EAAQ,aAAa,WAAW,CAAA,CAAA;AAAA,IAChC,YAAA,EAAc,EAAA;AAAA,IACd,OAAA,EAAS,MAAA;AAAA,IAAQ,aAAA,EAAe,QAAA;AAAA,IAChC,QAAA,EAAU,QAAA;AAAA,IACV,SAAA,EAAW,mDAAA;AAAA,IACX,SAAA,EAAW,SAAS,6BAAA,GAAgC;AAAA,GACtD,EAAA,kBAEE,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO;AAAA,IACV,OAAA,EAAS,MAAA;AAAA,IAAQ,cAAA,EAAgB,eAAA;AAAA,IAAiB,UAAA,EAAY,YAAA;AAAA,IAC9D,OAAA,EAAS,gBAAA;AAAA,IACT,YAAA,EAAc,aAAa,WAAW,CAAA,CAAA;AAAA,IACtC,UAAA,EAAY;AAAA,GACd,EAAA,kBACE,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,OAAO,EAAE,QAAA,EAAU,EAAA,EAAI,UAAA,EAAY,GAAA,EAAK,KAAA,EAAO,YAAY,aAAA,EAAe,WAAA,EAAa,aAAA,EAAe,QAAA,EAAU,YAAA,EAAc,CAAA,MAChI,KAAA,EAAM,QAAA,EAAI,UAAA,CAAW,CAAC,CAAA,EAAE,UAAA,EAAI,WAAW,UAAA,CAAW,MAAA,GAAS,CAAC,CAC/D,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,SAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,UAAA,EAAY,UAAA,EAAY,KAAK,CAAA,EAAG,QAAA,EAAU,MAAA,EAAO,EAAA,kBAC9E,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,OAAO,EAAE,QAAA,EAAU,EAAA,EAAI,UAAA,EAAY,GAAA,EAAK,KAAA,EAAO,MAAM,OAAA,CAAQ,IAAA,CAAK,OAAA,EAAS,UAAA,EAAY,CAAA,EAAG,aAAA,EAAe,WAAU,EAAA,EACtH,YACH,CAAA,EACC,WAAA,oBACC,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,OAAO,EAAE,QAAA,EAAU,EAAA,EAAI,KAAA,EAAO,UAAA,EAAY,UAAA,EAAY,KAAI,EAAA,EAAI,WAAY,CAAA,kBAElF,KAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,MAAA,EAAQ,OAAO,MAAA,EAAQ,CACtC,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,QAAA,EAAU,EAAA,EAAI,KAAA,EAAO,UAAA,EAAY,SAAA,EAAW,CAAA,MACvD,WAAA,EAAY,QAAA,kBAAG,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO,EAAE,SAAA,EAAW,QAAA,EAAS,EAAA,EAAI,WAAY,CACrE,CACF,CAAA,kBACA,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MAAO,IAAA,EAAK,QAAA;AAAA,MAAS,OAAA,EAAS,OAAA;AAAA,MAAS,KAAA,EAAO;AAAA,QAC7C,GAAA,EAAK,OAAA;AAAA,QAAS,MAAA,EAAQ,SAAA;AAAA,QAAW,KAAA,EAAO,EAAA;AAAA,QAAI,MAAA,EAAQ,EAAA;AAAA,QACpD,OAAA,EAAS,MAAA;AAAA,QAAQ,UAAA,EAAY,QAAA;AAAA,QAAU,cAAA,EAAgB,QAAA;AAAA,QACvD,YAAA,EAAc,KAAA;AAAA,QAAO,UAAA,EAAY,SAAS,wBAAA,GAA2B,kBAAA;AAAA,QACrE,KAAA,EAAO,UAAA;AAAA,QAAY,QAAA,EAAU,EAAA;AAAA,QAAI,UAAA,EAAY,GAAA;AAAA,QAAK,UAAA,EAAY,WAAA;AAAA,QAAa,UAAA,EAAY;AAAA,OACzF;AAAA,MACE,cAAc,CAAA,CAAA,KAAK;AAAE,QAAC,CAAA,CAAE,aAAA,CAA8B,KAAA,CAAM,UAAA,GAAa,SAAS,wBAAA,GAA2B,iBAAA;AAAA,MAAmB,CAAA;AAAA,MAChI,cAAc,CAAA,CAAA,KAAK;AAAE,QAAC,CAAA,CAAE,aAAA,CAA8B,KAAA,CAAM,UAAA,GAAa,SAAS,wBAAA,GAA2B,kBAAA;AAAA,MAAoB;AAAA,KAAA;AAAA,IAAG;AAAA,GAGxI,mBAGA,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,OAAO,EAAE,IAAA,EAAM,GAAG,QAAA,EAAU,MAAA,EAAQ,SAAS,WAAA,EAAa,OAAA,EAAS,QAAQ,aAAA,EAAe,QAAA,EAAU,KAAK,EAAA,EAAG,EAAA,EAG9G,UAAA,CAAW,MAAA,IAAU,CAAA,mBACpB,KAAA,CAAA,aAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,MAAA,EAAQ,eAAA;AAAA,MAAiB,UAAA;AAAA,MACzB,WAAA;AAAA,MACA,KAAA,EAAO,cAAA;AAAA,MAAgB,IAAA,EAAM,aAAA;AAAA,MAC7B,WAAA,EAAa,SAAA;AAAA,MAAW,GAAA,EAAK,eAAe,MAAA,GAAY,GAAA;AAAA,MAAK,IAAA;AAAA,MAC7D,eAAA;AAAA,MAAkC,SAAA,EAAW;AAAA;AAAA,GAC/C,mBAEA,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAO,UAAA,EAAY,QAAA,EAAU,EAAA,EAAI,SAAA,EAAW,QAAA,EAAU,OAAA,EAAS,UAAS,EAAA,EAAG,mDAEzF,CAAA,EAID,YAAA,IAAgB,GAAA,IAAO,GAAA,CAAI,MAAA,GAAS,CAAA,oBACnC,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO;AAAA,IAAE,QAAA,EAAU,EAAA;AAAA,IAAI,UAAA,EAAY,GAAA;AAAA,IAAK,KAAA,EAAO,UAAA;AAAA,IAAY,aAAA,EAAe,WAAA;AAAA,IAC7E,aAAA,EAAe,QAAA;AAAA,IAAU,YAAA,EAAc,EAAA;AAAA,IACvC,SAAA,EAAW,aAAa,WAAW,CAAA,CAAA;AAAA,IAAI,UAAA,EAAY;AAAA,GAAG,EAAA,EACrD,WAAA,IAAe,iBAAA,EAAkB,QAAA,EAAI,IAAI,MAAA,EAAO,KAAA,EAAI,GAAA,CAAI,MAAA,KAAW,CAAA,GAAI,GAAA,GAAM,EAChF,CAAA,sCACC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,aAAA,EAAe,QAAA,EAAU,GAAA,EAAK,IAAG,EAAA,EAC7D,WAAA,CAAY,GAAA,CAAI,CAAA,IAAA,yCACd,KAAA,EAAA,EAAI,GAAA,EAAK,IAAA,EAAA,kBAER,KAAA,CAAA,aAAA,CAAC,SAAI,KAAA,EAAO;AAAA,IACV,QAAA,EAAU,EAAA;AAAA,IAAI,UAAA,EAAY,GAAA;AAAA,IAAK,KAAA,EAAO,cAAA;AAAA,IACtC,YAAA,EAAc,CAAA;AAAA,IAAG,OAAA,EAAS,MAAA;AAAA,IAAQ,UAAA,EAAY,QAAA;AAAA,IAAU,GAAA,EAAK;AAAA,GAC/D,EAAA,kBACE,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,IAAA,EAAM,IAAK,CAAA,kBACZ,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO,EAAE,KAAA,EAAO,UAAA,EAAY,UAAA,EAAY,KAAI,EAAA,EAAG,OAAA,EAAG,SAAA,CAAU,IAAI,CAAA,CAAE,MAAA,EAAO,KAAA,EAAI,SAAA,CAAU,IAAI,CAAA,CAAE,MAAA,GAAS,CAAA,GAAI,GAAA,GAAM,EAAG,CAC3H,CAAA,kBAEA,KAAA,CAAA,aAAA,CAAC,SAAI,KAAA,EAAO;AAAA,IAAE,OAAA,EAAS,MAAA;AAAA,IAAQ,aAAA,EAAe,QAAA;AAAA,IAAU,GAAA,EAAK,CAAA;AAAA,IAAG,WAAA,EAAa,EAAA;AAAA,IAC3E,UAAA,EAAY,aAAa,cAAc,CAAA,EAAA;AAAA,GAAK,EAAA,EAC3C,SAAA,CAAU,IAAI,CAAA,CAAE,GAAA,CAAI,CAAA,EAAA,qBACnB,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,EAAA,CAAG,MAAA,EAAQ,KAAA,EAAO;AAAA,IAC1B,OAAA,EAAS,MAAA;AAAA,IAAQ,aAAA,EAAe,QAAA;AAAA,IAAU,GAAA,EAAK,CAAA;AAAA,IAC/C,OAAA,EAAS,UAAA;AAAA,IAAY,YAAA,EAAc,CAAA;AAAA,IACnC,UAAA,EAAY,SAAS,SAAA,GAAY,SAAA;AAAA,IACjC,MAAA,EAAQ,aAAa,WAAW,CAAA,CAAA;AAAA,IAChC,UAAA,EAAY;AAAA,GACd,EAAA,kBAEE,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,UAAA,EAAY,QAAA,EAAU,GAAA,EAAK,CAAA,EAAE,EAAA,kBAC1D,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO,EAAE,QAAA,EAAU,EAAA,EAAI,UAAA,EAAY,GAAA,EAAK,KAAA,EAAO,UAAA,EAAY,YAAY,CAAA,EAAG,QAAA,EAAU,EAAA,EAAG,EAAA,EAAG,KAC5F,EAAA,CAAG,MACP,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO;AAAA,IAAE,QAAA,EAAU,EAAA;AAAA,IAAI,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,OAAA;AAAA,IAAS,IAAA,EAAM,CAAA;AAAA,IACpE,UAAA,EAAY,QAAA;AAAA,IAAU,QAAA,EAAU,QAAA;AAAA,IAAU,YAAA,EAAc;AAAA,GAAW,EAAG,OAAO,EAAA,CAAG,KAAA,EAAA,EAC/E,GAAG,KACN,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO,EAAE,UAAU,EAAA,EAAI,KAAA,EAAO,UAAA,EAAY,UAAA,EAAY,CAAA,EAAE,EAAA,EAC3D,eAAe,EAAA,CAAG,aAAa,CAAA,EAAE,OACpC,CAAA,kBACA,KAAA,CAAA,aAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MAAE,MAAM,EAAA,CAAG,GAAA;AAAA,MAAK,MAAA,EAAO,QAAA;AAAA,MAAS,GAAA,EAAI,qBAAA;AAAA,MACnC,KAAA,EAAO,EAAE,KAAA,EAAO,UAAA,EAAY,YAAY,CAAA;AAAE,KAAA;AAAA,oBAC1C,KAAA,CAAA,aAAA,CAAC,YAAA,EAAA,EAAa,IAAA,EAAM,EAAA,EAAI;AAAA,GAE5B,CAAA,EAEC,EAAA,CAAG,MAAA,oBACF,KAAA,CAAA,aAAA,CAAC,SAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,YAAY,QAAA,EAAU,GAAA,EAAK,CAAA,EAAE,EAAA,EACzD,GAAG,YAAA,mBACF,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MAAI,KAAK,EAAA,CAAG,YAAA;AAAA,MAAc,KAAK,EAAA,CAAG,MAAA;AAAA,MACjC,KAAA,EAAO;AAAA,QAAE,KAAA,EAAO,EAAA;AAAA,QAAI,MAAA,EAAQ,EAAA;AAAA,QAAI,YAAA,EAAc,KAAA;AAAA,QAAO,UAAA,EAAY,CAAA;AAAA,QAC/D,MAAA,EAAQ,CAAA,UAAA,EAAa,MAAA,GAAS,SAAA,GAAY,SAAS,CAAA;AAAA;AAAG;AAAA,GAAG,mBAE7D,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO;AAAA,IAAE,KAAA,EAAO,EAAA;AAAA,IAAI,MAAA,EAAQ,EAAA;AAAA,IAAI,YAAA,EAAc,KAAA;AAAA,IAAO,UAAA,EAAY,CAAA;AAAA,IACpE,UAAA,EAAY,SAAS,SAAA,GAAY,SAAA;AAAA,IACjC,OAAA,EAAS,MAAA;AAAA,IAAQ,UAAA,EAAY,QAAA;AAAA,IAAU,cAAA,EAAgB,QAAA;AAAA,IACvD,QAAA,EAAU,CAAA;AAAA,IAAG,UAAA,EAAY,GAAA;AAAA,IAAK,KAAA,EAAO;AAAA,OACpC,EAAA,CAAG,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAChB,CAAA,kBAEF,KAAA,CAAA,aAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MAAE,IAAA,EAAM,CAAA,mBAAA,EAAsB,EAAA,CAAG,MAAM,CAAA,CAAA;AAAA,MAAI,MAAA,EAAO,QAAA;AAAA,MAAS,GAAA,EAAI,qBAAA;AAAA,MAC9D,KAAA,EAAO;AAAA,QAAE,QAAA,EAAU,EAAA;AAAA,QAAI,UAAA,EAAY,GAAA;AAAA,QAAK,KAAA,EAAO,UAAA;AAAA,QAC7C,cAAA,EAAgB,MAAA;AAAA,QAAQ,aAAA,EAAe;AAAA,OAAS;AAAA,MAClD,cAAc,CAAA,CAAA,KAAK;AAAE,QAAC,CAAA,CAAE,aAAA,CAA8B,KAAA,CAAM,KAAA,GAAQ,SAAA;AAAA,MAAW,CAAA;AAAA,MAC/E,cAAc,CAAA,CAAA,KAAK;AAAE,QAAC,CAAA,CAAE,aAAA,CAA8B,KAAA,CAAM,KAAA,GAAQ,UAAA;AAAA,MAAY;AAAA,KAAA;AAAA,IAAG,GAAA;AAAA,IACjF,EAAA,CAAG;AAAA,GAET,CAEJ,CACD,CACH,CACF,CACD,CACH,CACF,CAAA,EAID,CAAC,YAAA,IAAgB,GAAA,IAAO,IAAI,MAAA,GAAS,CAAA,wCACnC,KAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,SAAI,KAAA,EAAO;AAAA,IAAE,QAAA,EAAU,EAAA;AAAA,IAAI,UAAA,EAAY,GAAA;AAAA,IAAK,KAAA,EAAO,UAAA;AAAA,IAAY,aAAA,EAAe,WAAA;AAAA,IAC7E,aAAA,EAAe,QAAA;AAAA,IAAU,YAAA,EAAc,EAAA;AAAA,IACvC,SAAA,EAAW,aAAa,WAAW,CAAA,CAAA;AAAA,IAAI,UAAA,EAAY;AAAA,GAAG,EAAA,EACrD,KAAA,CAAM,WAAA,EAAY,CAAE,QAAA,CAAS,SAAS,CAAA,GAAI,oBAAA,GAAuB,aAAA,EACjE,GAAA,EAAI,wCACP,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,aAAA,EAAe,QAAA,EAAU,GAAA,EAAK,CAAA,EAAE,EAAA,EAC5D,GAAA,CAAI,GAAA,CAAI,CAAC,EAAA,EAAI,CAAA,KAAM;AAClB,IAAA,MAAM,GAAA,GAAS,aAAA,CAAc,CAAA,EAAG,GAAA,CAAI,MAAM,CAAA;AAC1C,IAAA,MAAM,MAAA,GAAS,GAAA,CAAI,CAAC,CAAA,CAAE,aAAA;AACtB,IAAA,MAAM,SAAS,MAAA,GAAS,CAAA,GAAK,EAAA,CAAG,aAAA,GAAgB,SAAU,GAAA,GAAM,CAAA;AAChE,IAAA,MAAM,KAAA,GAAS,GAAG,MAAA,KAAW,eAAA;AAC7B,IAAA,uBACE,KAAA,CAAA,aAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QAAI,KAAK,EAAA,CAAG,MAAA;AAAA,QACX,GAAA,EAAK,CAAC,EAAA,KAAO;AACX,UAAA,IAAI,IAAI,SAAA,CAAU,OAAA,CAAQ,GAAA,CAAI,EAAA,CAAG,QAAQ,EAAE,CAAA;AAAA,eACtC,SAAA,CAAU,OAAA,CAAQ,MAAA,CAAO,EAAA,CAAG,MAAM,CAAA;AAAA,QACzC,CAAA;AAAA,QACA,YAAA,EAAc,MAAM,kBAAA,CAAmB,EAAA,CAAG,MAAM,CAAA;AAAA,QAChD,YAAA,EAAc,MAAM,kBAAA,CAAmB,IAAI,CAAA;AAAA,QAC3C,KAAA,EAAO;AAAA,UACL,OAAA,EAAS,UAAA;AAAA,UAAY,YAAA,EAAc,CAAA;AAAA,UACnC,YAAY,KAAA,GACP,MAAA,GAAS,SAAA,GAAY,SAAA,GACrB,SAAS,SAAA,GAAY,SAAA;AAAA,UAC1B,MAAA,EAAQ,CAAA,UAAA,EAAa,KAAA,GAAQ,cAAA,GAAiB,OAAO,WAAW,CAAA,CAAA;AAAA,UAChE,OAAA,EAAS,MAAA;AAAA,UAAQ,aAAA,EAAe,QAAA;AAAA,UAAU,GAAA,EAAK,CAAA;AAAA,UAC/C,UAAA,EAAY,sCAAA;AAAA,UACZ,MAAA,EAAQ;AAAA;AACV,OAAA;AAAA,sBACA,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,SAAS,MAAA,EAAQ,UAAA,EAAY,QAAA,EAAU,GAAA,EAAK,CAAA,EAAG,QAAA,EAAU,CAAA,EAAE,EAAA,sCACtE,MAAA,EAAA,EAAK,KAAA,EAAO,EAAE,QAAA,EAAU,EAAA,EAAI,UAAA,EAAY,GAAA,EAAK,KAAA,EAAO,KAAK,UAAA,EAAY,CAAA,EAAE,EAAA,EAAG,GAAA,EAAE,EAAA,CAAG,MAAO,CAAA,kBACvF,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO;AAAA,QAAE,QAAA,EAAU,EAAA;AAAA,QAAI,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,OAAA;AAAA,QAAS,IAAA,EAAM,CAAA;AAAA,QACpE,UAAA,EAAY,QAAA;AAAA,QAAU,QAAA,EAAU,QAAA;AAAA,QAAU,YAAA,EAAc;AAAA,OAAW,EAAG,KAAA,EAAO,EAAA,CAAG,KAAA,EAAA,EAC/E,GAAG,KACN,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO,EAAE,QAAA,EAAU,EAAA,EAAI,OAAO,UAAA,EAAY,UAAA,EAAY,CAAA,EAAE,EAAA,EAC3D,IAAI,IAAA,CAAK,EAAA,CAAG,QAAQ,EAAE,kBAAA,CAAmB,OAAA,EAAS,EAAE,KAAA,EAAO,OAAA,EAAS,GAAA,EAAK,SAAA,EAAW,CACvF,CAAA,kBACA,KAAA,CAAA,aAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UAAE,MAAM,EAAA,CAAG,GAAA;AAAA,UAAK,MAAA,EAAO,QAAA;AAAA,UAAS,GAAA,EAAI,qBAAA;AAAA,UACnC,OAAO,EAAE,KAAA,EAAO,YAAY,UAAA,EAAY,CAAA,EAAG,YAAY,aAAA;AAAc,SAAA;AAAA,wBACrE,KAAA,CAAA,aAAA,CAAC,YAAA,EAAA,EAAa,IAAA,EAAM,EAAA,EAAI;AAAA,OAE5B,CAAA;AAAA,0CACC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,QAAQ,UAAA,EAAY,QAAA,EAAU,GAAA,EAAK,CAAA,sBACxD,KAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,UAAU,MAAA,EAAQ,KAAA,EAAO,KAAK,CAAA,kBAC3C,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO,EAAE,QAAA,EAAU,EAAA,EAAI,YAAY,GAAA,EAAK,KAAA,EAAO,KAAK,QAAA,EAAU,EAAA,EAAI,SAAA,EAAW,OAAA,EAAS,YAAY,CAAA,EAAE,EAAA,EACvG,eAAe,EAAA,CAAG,aAAa,CAClC,CACF;AAAA,KACF;AAAA,EAEJ,CAAC,CACH,CACF,CAEJ,CACF,CAAA,sCACC,OAAA,EAAA,IAAA,EAAO;AAAA;AAAA;AAAA;AAAA;AAAA,MAAA,CAKN,CACJ,CAAA;AAEJ;AAIA,SAAS,WAAA,CAAY,EAAE,QAAA,EAAU,KAAA,EAAM,EAAwC;AAC7E,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,CAAC,CAAA;AACpC,EAAA,MAAM,GAAA,GAAM,OAAuB,IAAI,CAAA;AACvC,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,IAAA,KAAS,MAAA;AAEtC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,QAAQ,UAAA,CAAW,MAAM,QAAA,CAAS,QAAQ,GAAG,EAAE,CAAA;AACrD,IAAA,OAAO,MAAM,aAAa,KAAK,CAAA;AAAA,EACjC,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,KAAA,EAAO;AAAA,QACL,UAAA,EAAY,SAAS,SAAA,GAAY,SAAA;AAAA,QACjC,YAAA,EAAc,CAAA;AAAA,QACd,MAAA,EAAQ,CAAA;AAAA,QACR,QAAA,EAAU,QAAA;AAAA,QACV,IAAA,EAAM,CAAA;AAAA,QACN,QAAA,EAAU;AAAA;AACZ,KAAA;AAAA,oBAEA,KAAA,CAAA,aAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO;AAAA,UACL,MAAA,EAAQ,MAAA;AAAA,UACR,KAAA,EAAO,GAAG,KAAK,CAAA,CAAA,CAAA;AAAA,UACf,UAAA,EAAY,KAAA;AAAA,UACZ,YAAA,EAAc,CAAA;AAAA,UACd,UAAA,EAAY,0CAAA;AAAA,UACZ,SAAA,EAAW,WAAW,KAAK,CAAA,EAAA;AAAA;AAC7B;AAAA;AACF,GACF;AAEJ;AAIA,SAAS,UAAA,CAAW;AAAA,EAClB,KAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA,GAAgB,KAAA;AAAA,EAChB,aAAA;AAAA,EACA,aAAA,GAAgB,MAAA;AAAA,EAChB,cAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA,EAYG;AACD,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,IAAA,KAAS,MAAA;AACtC,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,KAAK,CAAA;AAE5C,EAAA,MAAM,YAAA,GAAe,OAAO,IAAA,KAAS,OAAA,GAAU,eAAe,MAAA,CAAO,KAAK,IAAI,MAAA,CAAO,KAAA;AACrF,EAAA,MAAM,WAAA,GAAe,MAAA,CAAO,IAAA,KAAS,OAAA,GAAU,KAAK,MAAA,CAAO,IAAA;AAC3D,EAAA,MAAM,WAAA,GAAe,OAAO,IAAA,KAAS,OAAA,GAAU,eAAe,MAAA,CAAO,MAAM,IAAI,MAAA,CAAO,MAAA;AACtF,EAAA,MAAM,WAAA,GAAe,aAAA,GACjB,CAAA,UAAA,EAAa,WAAW,IAAI,WAAW,CAAA,CAAA,CAAG,IAAA,EAAK,GAC/C,CAAA,eAAA,EAAa,WAAW,CAAA,CAAA,EAAI,WAAW,GAAG,IAAA,EAAK;AAEnD,EAAA,MAAM,eAAe,aAAA,IAAiB,aAAA,CAAc,UAAU,CAAA,IAAK,UAAA,IAAc,WAAW,MAAA,IAAU,CAAA;AACtG,EAAA,MAAM,QAAQ,YAAA,GAAe,eAAA,CAAgB,eAAgB,MAAA,CAAO,IAAA,EAAM,aAAa,CAAA,GAAI,IAAA;AAC3F,EAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KAAc,MAAA,CAAO,SAAS,OAAA,GAAU,cAAA,CAAe,CAAC,CAAA,GAAI,GAAG,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,EAAE,IAAI,EAAE,CAAA,CAAA;AAEzG,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,EAAE,MAAA,EAAQ,QAAA,GAAW,YAAY,MAAA,EAAU;AAAA,MAClD,OAAA,EAAS,QAAA;AAAA,MACT,YAAA,EAAc,MAAM,UAAA,CAAW,IAAI,CAAA;AAAA,MACnC,YAAA,EAAc,MAAM,UAAA,CAAW,KAAK;AAAA,KAAA;AAAA,oBAEpC,KAAA,CAAA,aAAA,CAAC,SAAI,KAAA,EAAO,EAAE,SAAS,MAAA,EAAQ,cAAA,EAAgB,iBAAiB,UAAA,EAAY,YAAA,EAAc,KAAK,CAAA,EAAE,EAAA,sCAC9F,SAAA,EAAA,IAAA,EAAW,KAAM,GACjB,QAAA,oBACC,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO;AAAA,MACX,QAAA,EAAU,CAAA;AAAA,MAAG,UAAA,EAAY,GAAA;AAAA,MAAK,KAAA,EAAO,SAAS,SAAA,GAAY,SAAA;AAAA,MAC1D,OAAA,EAAS,UAAU,CAAA,GAAI,CAAA;AAAA,MAAG,UAAA,EAAY,eAAA;AAAA,MACtC,aAAA,EAAe,QAAA;AAAA,MAAU,aAAA,EAAe,WAAA;AAAA,MAAa,UAAA,EAAY;AAAA,KACnE,EAAA,EAAG,eAEH,CAEJ,CAAA;AAAA,wCAEC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,eAAe,QAAA,EAAU,UAAA,EAAY,YAAY,GAAA,EAAK,CAAA,MAClF,KAAA,oBACC,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO,KAAA,CAAM,SAAS,KAAA,EAAO;AAAA,MACjC,QAAA,EAAU,EAAA;AAAA,MAAI,UAAA,EAAY,GAAA;AAAA,MAAK,MAAA,EAAQ,MAAA;AAAA,MACvC,KAAA,EAAO,KAAA,CAAM,IAAA,GAAO,SAAA,GAAY,SAAA;AAAA,MAChC,YAAY,KAAA,CAAM,IAAA,GACb,SAAS,uBAAA,GAA0B,uBAAA,GACnC,SAAS,wBAAA,GAA2B,wBAAA;AAAA,MACzC,OAAA,EAAS,SAAA;AAAA,MAAW,YAAA,EAAc,CAAA;AAAA,MAAG,UAAA,EAAY;AAAA,SAEhD,KAAA,CAAM,IACT,CAAA,kBAEF,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO;AAAA,MACX,QAAA,EAAU,EAAA;AAAA,MAAI,UAAA,EAAY,GAAA;AAAA,MAC1B,KAAA,EAAO,SAAS,SAAA,GAAY,SAAA;AAAA,MAC5B,UAAA,EAAY;AAAA,KACd,EAAA,EACG,aAAA,GAAgB,uBAAA,GAAqB,wBACxC,CACF,CAAA;AAAA,wCAEC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,YAAY,UAAA,EAAY,GAAA,EAAK,GAAE,EAAA,kBAC5D,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO,EAAE,UAAU,EAAA,EAAI,UAAA,EAAY,KAAK,KAAA,EAAO,MAAA,GAAS,YAAY,SAAA,EAAW,UAAA,EAAY,GAAE,EAAA,EAChG,YACH,GACC,WAAA,oBACC,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO,EAAE,UAAU,EAAA,EAAI,KAAA,EAAO,SAAS,SAAA,GAAY,SAAA,EAAW,YAAY,GAAA,EAAI,EAAA,EACjF,WACH,CAEJ,CAAA;AAAA,oBACA,KAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAQ,CAAA;AAAA,IACnC,gCACC,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,OAAO,EAAE,SAAA,EAAW,GAAE,EAAA,kBACzB,KAAA,CAAA,aAAA;AAAA,MAAC,gBAAA;AAAA,MAAA;AAAA,QACC,MAAA,EAAQ,aAAA;AAAA,QACR,UAAA;AAAA,QACA,OAAO,cAAA,IAAkB,SAAA;AAAA,QACzB,IAAA,EAAM,aAAA;AAAA,QACN,WAAA,EAAa;AAAA;AAAA,KAEjB,CAAA;AAAA,oBAEF,KAAA,CAAA,aAAA,CAAC,uBAAiB,WAAY,CAAA;AAAA,wCAC7B,UAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO,EAAE,YAAY,GAAA,EAAK,KAAA,EAAO,SAAS,SAAA,GAAY,SAAA,MACzD,WACH,CAAA,EACC,eAAe,QAAA,oBACd,KAAA,CAAA,aAAA,CAAC,UAAK,KAAA,EAAO;AAAA,MACX,QAAA,EAAU,EAAA;AAAA,MAAI,UAAA,EAAY,GAAA;AAAA,MAC1B,KAAA,EAAO,SAAA;AAAA,MACP,aAAA,EAAe,QAAA;AAAA,MACf,UAAA,EAAY;AAAA,KACd,EAAA,EACG,WACH,CAEJ;AAAA,GACF;AAEJ;AAEA,SAAS,MAAA,CAAO,EAAE,KAAA,EAAO,WAAA,EAAY,EAA2C;AAC9E,EAAA,2CACG,IAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,SAAA,EAAA,IAAA,EAAW,KAAM,mBAClB,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,SAAS,MAAA,EAAQ,UAAA,EAAY,YAAY,GAAA,EAAK,CAAA,sBAC1D,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO,EAAE,UAAU,EAAA,EAAI,UAAA,EAAY,GAAA,EAAK,KAAA,EAAO,WAAW,UAAA,EAAY,CAAA,EAAE,EAAA,EAAG,KAAG,CACtF,CAAA,kBACA,KAAA,CAAA,aAAA,CAAC,mBAAgB,KAAA,EAAK,IAAA,EAAA,EAAE,WAAY,CACtC,CAAA;AAEJ;AAIA,SAAS,WAAA,CAAY,EAAE,QAAA,EAAS,EAAkC;AAChE,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,uBACE,KAAA,CAAA,aAAA,CAAC,SAAI,KAAA,EAAO,EAAE,UAAU,EAAA,EAAI,UAAA,EAAY,KAAK,KAAA,EAAO,KAAA,CAAM,QAAQ,IAAA,CAAK,OAAA,EAAS,cAAc,CAAA,EAAG,aAAA,EAAe,aAAa,aAAA,EAAe,QAAA,MACzI,QACH,CAAA;AAEJ;AAIO,SAAS,kBAAA,GAAqB;AACnC,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,SAAA,EAAU;AAC7B,EAAA,MAAM,OAAA,GAAU,OAAO,iBAAiB,CAAA;AACxC,EAAA,MAAM,WAAW,QAAA,EAAS;AAC1B,EAAA,MAAM,WAAA,GAAc,QAAA,CAAS,OAAA,CAAQ,IAAA,CAAK,OAAA;AAC1C,EAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,OAAA,CAAQ,IAAA,CAAK,SAAA;AAE5C,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,uBAAuB,CAAA,IAAK,EAAA;AAC9E,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,QAAA,CAAS,WAAA,IAAe,EAAC;AAGpD,EAAA,MAAM,cAAA,GAAiB,mBAAA,CAAuC,WAAA,CAAY,uBAAuB,CAAC,CAAA;AAClG,EAAA,MAAM,iBAAA,GAAoB,mBAAA,CAA0C,WAAA,CAAY,kBAAkB,CAAC,CAAA;AAEnG,EAAA,MAAM,YAAA,GAAkC,cAAA,IAAkB,OAAA,CAAQ,eAAA,EAAgB;AAClF,EAAA,MAAM,UAAA,GAAa,aAAa,CAAC,CAAA;AACjC,EAAA,MAAM,WAAA,GAAc,QAAQ,cAAA,EAAe;AAG3C,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,IAAI,QAAA,CAAiB,UAAA,EAAY,QAAQ,EAAE,CAAA;AACrF,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,IAAI,QAAA,CAAiB,MAAA,CAAO,WAAW,CAAC,CAAA;AAE5E,EAAA,MAAM,cAAc,YAAA,CAAa,IAAA,CAAK,OAAK,CAAA,CAAE,IAAA,KAAS,eAAe,CAAA,IAAK,UAAA;AAC1E,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,YAAA,EAAc,EAAE,CAAA;AAEtC,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAA6B,IAAI,CAAA;AAC/D,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,IAAI,CAAA;AAC3C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAErD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAoC,IAAI,CAAA;AACtE,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAkC,IAAI,CAAA;AAEtE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,QAAA,CAAS,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,uBAAuB,eAAe,CAAC,CAAA;AACpF,MAAA,UAAA,CAAW,KAAK,CAAA;AAChB,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,WAAA,EAAa;AAChB,MAAA,QAAA,CAAS,IAAI,KAAA,CAAM,8CAA8C,CAAC,CAAA;AAClE,MAAA,UAAA,CAAW,KAAK,CAAA;AAChB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,UAAA,CAAW,IAAI,CAAA;AAEf,IAAA,OAAA,CACG,UAAA,CAAW,aAAa,WAAA,EAAa,IAAA,EAAM,qBAAqB,MAAS,CAAA,CACzE,KAAK,CAAA,IAAA,KAAQ;AACZ,MAAA,IAAI,CAAC,SAAA,EAAW;AAAE,QAAA,UAAA,CAAW,IAAI,CAAA;AAAG,QAAA,UAAA,CAAW,KAAK,CAAA;AAAA,MAAG;AAAA,IACzD,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,GAAA,KAAe;AACrB,MAAA,IAAI,CAAC,SAAA,EAAW;AAAE,QAAA,QAAA,CAAS,GAAG,CAAA;AAAG,QAAA,UAAA,CAAW,KAAK,CAAA;AAAA,MAAG;AAAA,IACtD,CAAC,CAAA;AAEH,IAAA,OAAA,CACG,WAAW,WAAA,EAAa,WAAA,EAAa,IAAI,CAAA,CACzC,KAAK,CAAA,IAAA,KAAQ;AAAE,MAAA,IAAI,CAAC,SAAA,EAAW,UAAA,CAAW,IAAI,CAAA;AAAA,IAAG,CAAC,CAAA,CAClD,KAAA,CAAM,MAAM;AAAA,IAA4C,CAAC,CAAA;AAE5D,IAAA,OAAO,MAAM;AAAE,MAAA,SAAA,GAAY,IAAA;AAAA,IAAM,CAAA;AAAA,EACnC,GAAG,CAAC,OAAA,EAAS,aAAa,WAAA,EAAa,IAAA,EAAM,IAAI,CAAC,CAAA;AAElD,EAAA,IAAI,OAAA,EAAS,uBAAO,KAAA,CAAA,aAAA,CAAC,kBAAA,EAAA,IAAmB,CAAA;AAExC,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,uBACE,KAAA,CAAA,aAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,cAAA,EAAA,kBACd,KAAA,CAAA,aAAA,CAAC,SAAI,KAAA,EAAO,EAAE,OAAA,EAAS,EAAA,EAAI,KAAA,EAAO,SAAA,sBAChC,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAO,EAAE,UAAA,EAAY,GAAA,MAAO,SAAO,CAAA,EAAQ,KAAA,CAAM,OACzD,CACF,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AAErB,EAAA,uBACE,KAAA,CAAA,aAAA,CAAC,YAAS,KAAA,EAAM,GAAA,EAAA,sCACb,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,OAAA,EAAS,UAAU,UAAA,EAAW,EAAA,EAElD,4BACC,KAAA,CAAA,aAAA,CAAC,eAAA,EAAA,EAAgB,MAAM,QAAA,EAAU,IAAA,EAAY,SAAS,MAAM,WAAA,CAAY,IAAI,CAAA,EAAG,CAAA,sCAIhF,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,YAAA,EAAc,EAAA,sBAC1B,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,OAAO,EAAE,QAAA,EAAU,IAAI,UAAA,EAAY,GAAA,EAAK,OAAO,WAAA,EAAa,aAAA,EAAe,WAAU,EAAA,EAAG,cAAY,GACxG,WAAA,oBACC,KAAA,CAAA,aAAA,CAAC,SAAI,KAAA,EAAO,EAAE,UAAU,EAAA,EAAI,KAAA,EAAO,eAAe,SAAA,EAAW,CAAA,MAAK,qBAAA,EAC5C,GAAA,sCACnB,QAAA,EAAA,EAAO,KAAA,EAAO,EAAE,KAAA,EAAO,WAAA,MAAgB,WAAA,CAAY,IAAK,GACxD,GAAA,EAAI,QAAA,EAAE,qBACP,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,OAAO,EAAE,UAAA,EAAY,aAAY,EAAA,EAAI,WAAA,CAAY,MAAO,CAChE,CAEJ,mBAGA,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,OAAO,EAAE,OAAA,EAAS,QAAQ,UAAA,EAAY,UAAA,EAAY,KAAK,EAAA,EAAI,QAAA,EAAU,QAAQ,YAAA,EAAc,EAAA,MAC7F,YAAA,CAAa,MAAA,GAAS,qBACrB,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,IAAA,sCACE,WAAA,EAAA,IAAA,EAAY,aAAW,mBACxB,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAO,OAAO,eAAA,EAAiB,aAAA,EAAe,sCAC7C,KAAA,CAAA,aAAA,CAAC,aAAA,EAAA,IAAA,sCAAe,WAAA,EAAA,EAAY,WAAA,EAAY,sBAAqB,CAAE,CAAA,sCAC9D,aAAA,EAAA,IAAA,EACE,YAAA,CAAa,IAAI,CAAA,GAAA,qBAChB,KAAA,CAAA,aAAA,CAAC,cAAW,GAAA,EAAK,GAAA,CAAI,MAAM,KAAA,EAAO,GAAA,CAAI,QACnC,GAAA,CAAI,IAAA,EAAK,MAAG,GAAA,CAAI,MAAA,EAAO,GAC1B,CACD,CACH,CACF,CACF,CAAA,sCAGD,KAAA,EAAA,IAAA,kBACC,KAAA,CAAA,aAAA,CAAC,mBAAY,YAAU,CAAA,sCACtB,MAAA,EAAA,EAAO,KAAA,EAAO,cAAc,aAAA,EAAe,eAAA,EAAA,sCACzC,aAAA,EAAA,IAAA,kBAAc,KAAA,CAAA,aAAA,CAAC,eAAY,WAAA,EAAY,mBAAA,EAAoB,CAAE,CAAA,kBAC9D,KAAA,CAAA,aAAA,CAAC,qBACE,kBAAA,CAAmB,GAAA,CAAI,yBACtB,KAAA,CAAA,aAAA,CAAC,UAAA,EAAA,EAAW,KAAK,GAAA,CAAI,KAAA,EAAO,OAAO,GAAA,CAAI,KAAA,EAAA,EAAQ,IAAI,KAAM,CAC1D,CACH,CACF,CACF,CACF,CAAA,EAAA,CAGE,MAAM;AACN,IAAA,MAAM,WAAa,OAAA,EAAS,GAAA,CAAI,OAAK,CAAA,CAAE,SAAS,KAAK,EAAC;AACtD,IAAA,MAAM,aAAa,OAAA,EAAS,GAAA,CAAI,OAAK,CAAA,CAAE,eAAe,KAAK,EAAC;AAC5D,IAAA,MAAM,WAAa,OAAA,EAAS,GAAA,CAAI,OAAK,CAAA,CAAE,aAAa,KAAK,EAAC;AAC1D,IAAA,MAAM,OAAA,GAAa,SAAS,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,iBAAA,IAAqB,CAAC,KAAK,EAAC;AACnE,IAAA,MAAM,QAAA,GAAa,SAAS,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,SAAA,IAAa,CAAC,KAAK,EAAC;AAE3D,IAAA,MAAM,OAAO,OAAA,EAAS,GAAA,CAAI,OAAK,CAAA,CAAE,WAAW,KAAK,EAAC;AAElD,IAAA,MAAM,QAAA,GAAW,CACf,KAAA,EAAe,MAAA,EAAyB,WAAA,EACxC,aAAA,EAAwB,eAAA,EACxB,aAAA,EAA+B,cAAA,EAAwB,GAAA,EACvD,WAAA,KACG,MAAM,WAAA,CAAY;AAAA,MACrB,KAAA;AAAA,MAAO,MAAA;AAAA,MAAQ,WAAA;AAAA,MAAa,aAAA;AAAA,MAC5B,eAAA;AAAA,MAAiB,aAAA;AAAA,MAAe,cAAA;AAAA,MAChC,UAAA,EAAY,QAAA;AAAA,MAAU,WAAA,EAAa,IAAA;AAAA,MAAM,GAAA;AAAA,MAAK;AAAA,KAC/C,CAAA;AAED,IAAA,uBACE,KAAA,CAAA,aAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,EAAE,OAAA,EAAS,QAAQ,QAAA,EAAU,MAAA,EAAQ,GAAA,EAAK,EAAA,EAAG,EAAA,kBACvD,KAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,sBAAA;AAAA,QACN,QAAQ,OAAA,CAAQ,mBAAA;AAAA,QAChB,WAAA,EAAY,2CAAA;AAAA,QACZ,aAAA,EAAe,UAAA;AAAA,QACf,aAAA,EAAc,KAAA;AAAA,QACd,cAAA,EAAe,SAAA;AAAA,QACf,UAAA,EAAY,QAAA;AAAA,QACZ,QAAA,EAAU,QAAA;AAAA,UAAS,sBAAA;AAAA,UAAwB,OAAA,CAAQ,mBAAA;AAAA,UACjD,2CAAA;AAAA,UAA6C,KAAA;AAAA,UAAO,UAAA;AAAA,UAAY,KAAA;AAAA,UAAO,SAAA;AAAA,UACvE,QAAQ,mBAAA,CAAoB;AAAA;AAAU;AAAA,KAC1C,kBACA,KAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,uBAAA;AAAA,QACN,QAAQ,OAAA,CAAQ,QAAA;AAAA,QAChB,WAAA,EAAY,wCAAA;AAAA,QACZ,aAAA,EAAa,IAAA;AAAA,QACb,aAAA,EAAe,QAAA;AAAA,QACf,aAAA,EAAc,MAAA;AAAA,QACd,cAAA,EAAe,SAAA;AAAA,QACf,UAAA,EAAY,QAAA;AAAA,QACZ,QAAA,EAAU,QAAA;AAAA,UAAS,uBAAA;AAAA,UAAyB,OAAA,CAAQ,QAAA;AAAA,UAClD,wCAAA;AAAA,UAA0C,IAAA;AAAA,UAAM,QAAA;AAAA,UAAU,MAAA;AAAA,UAAQ,SAAA;AAAA,UAAW,QAAQ,QAAA,CAAS;AAAA;AAAU;AAAA,KAC5G,EACC,OAAA,CAAQ,iBAAA,KAAsB,IAAA,mBAC7B,KAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,qBAAA;AAAA,QACN,QAAQ,OAAA,CAAQ,iBAAA;AAAA,QAChB,WAAA,EAAY,wCAAA;AAAA,QACZ,aAAA,EAAa,IAAA;AAAA,QACb,aAAA,EAAe,OAAA;AAAA,QACf,aAAA,EAAc,MAAA;AAAA,QACd,cAAA,EAAe,SAAA;AAAA,QACf,UAAA,EAAY,QAAA;AAAA,QACZ,QAAA,EAAU,QAAA;AAAA,UAAS,qBAAA;AAAA,UAAuB,OAAA,CAAQ,iBAAA;AAAA,UAChD,wCAAA;AAAA,UAA0C,IAAA;AAAA,UAAM,OAAA;AAAA,UAAS,MAAA;AAAA,UAAQ;AAAA;AAAS;AAAA,KAC9E,mBAEA,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAO,KAAA,EAAM,qBAAA,EAAsB,aAAY,qCAAA,EAAsC,CAAA,EAEvF,OAAA,CAAQ,IAAA,KAAS,IAAA,mBAChB,KAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,sBAAA;AAAA,QACN,QAAQ,OAAA,CAAQ,IAAA;AAAA,QAChB,WAAA,EAAY,uCAAA;AAAA,QACZ,aAAA,EAAa,IAAA;AAAA,QACb,aAAA,EAAe,QAAA;AAAA,QACf,aAAA,EAAc,MAAA;AAAA,QACd,cAAA,EAAe,SAAA;AAAA,QACf,UAAA,EAAY,QAAA;AAAA,QACZ,QAAA,EAAU,QAAA;AAAA,UAAS,sBAAA;AAAA,UAAwB,OAAA,CAAQ,IAAA;AAAA,UACjD,uCAAA;AAAA,UAAyC,IAAA;AAAA,UAAM,QAAA;AAAA,UAAU,MAAA;AAAA,UAAQ,SAAA;AAAA,UAAW,QAAQ,IAAA,CAAK;AAAA;AAAU;AAAA,KACvG,mBAEA,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAO,KAAA,EAAM,sBAAA,EAAuB,aAAY,qCAAA,EAAsC,CAAA,EAExF,OAAA,CAAQ,gBAAA,KAAqB,IAAA,mBAC5B,KAAA,CAAA,aAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAM,wBAAA;AAAA,QACN,QAAQ,OAAA,CAAQ,gBAAA;AAAA,QAChB,WAAA,EAAa,CAAA,aAAA,EAAgB,WAAA,EAAa,KAAA,IAAS,QAAQ,CAAA,sBAAA,CAAA;AAAA,QAC3D,aAAA,EAAa,IAAA;AAAA,QACb,aAAa,OAAA,CAAQ,gBAAA,CAAiB,KAAA,GAAQ,CAAA,GAAI,QAAQ,OAAA,CAAQ,gBAAA,CAAiB,KAAK,CAAA,GAAA,EAAM,QAAQ,gBAAA,CAAiB,KAAA,KAAU,CAAA,GAAI,GAAA,GAAM,EAAE,CAAA,OAAA,CAAA,GAAO,MAAA;AAAA,QACpJ,QAAA,EAAU,QAAA;AAAA,UACR,wBAAA;AAAA,UACA,OAAA,CAAQ,gBAAA;AAAA,UACR,CAAA,aAAA,EAAgB,WAAA,EAAa,KAAA,IAAS,QAAQ,CAAA,sBAAA,CAAA;AAAA,UAC9C,IAAA;AAAA,UACA,EAAC;AAAA,UACD,KAAA;AAAA,UACA,SAAA;AAAA,UACA,QAAQ,gBAAA,CAAiB,UAAA;AAAA,UACzB;AAAA;AACF;AAAA,wBAGF,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAO,OAAM,wBAAA,EAAyB,WAAA,EAAY,uCAAsC,CAE7F,CAAA;AAAA,EAEJ,CAAA,GAEF,CACF,CAAA;AAEJ;;;;"}
|
|
1
|
+
{"version":3,"file":"DoraMetricsContent.esm.js","sources":["../../src/components/DoraMetricsContent.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport { useTheme } from '@material-ui/core/styles';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { InfoCard } from '@backstage/core-components';\nimport { doraMetricsApiRef } from '../api/types';\nimport type { DoraEnvironment, DoraHistoryPoint, DoraMetrics, DoraMetricValue, DoraTargets, PrDetail } from '../api/types';\nimport { RatingBadge } from './ui/badge';\nimport { Card, CardLabel, CardFooter, CardDescription } from './ui/card';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from './ui/select';\nimport { ExternalLink } from 'lucide-react';\n\nconst ANNOTATION_PROJECT_SLUG = 'github.com/project-slug';\n/** Override the global environments list for this specific entity. JSON array of DoraEnvironment objects. */\nconst ANNOTATION_ENVIRONMENTS = 'dora-metrics/environments';\n/** Override the global performance targets for this specific entity. JSON object matching DoraTargets. */\nconst ANNOTATION_TARGETS = 'dora-metrics/targets';\n\n/** Parse entity annotation overrides. Returns undefined for malformed JSON to fail gracefully. */\nfunction parseAnnotationJson<T>(raw: string | undefined): T | undefined {\n if (!raw) return undefined;\n try { return JSON.parse(raw) as T; } catch { return undefined; }\n}\n\nconst DATE_RANGE_OPTIONS = [\n { value: '7', label: 'Last 7 days' },\n { value: '14', label: 'Last 14 days' },\n { value: '30', label: 'Last 30 days' },\n { value: '60', label: 'Last 60 days' },\n { value: '90', label: 'Last 90 days' },\n];\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\nfunction formatDuration(hours: number): string {\n const totalMinutes = Math.round(hours * 60);\n const d = Math.floor(totalMinutes / (24 * 60));\n const h = Math.floor((totalMinutes % (24 * 60)) / 60);\n const m = totalMinutes % 60;\n if (d > 0) return h > 0 ? `${d}d ${h}h` : `${d}d`;\n if (h > 0) return m > 0 ? `${h}h ${m}m` : `${h}h`;\n return `${m}m`;\n}\n\n// Red → Orange → Yellow → Lime → Green gradient (slowest to fastest)\nconst DURATION_GRADIENT = ['#f87171', '#fb923c', '#fbbf24', '#a3e635', '#4ade80'];\n\nfunction durationColor(index: number, total: number): string {\n if (total <= 1) return DURATION_GRADIENT[0];\n const step = (DURATION_GRADIENT.length - 1) / (total - 1);\n return DURATION_GRADIENT[Math.round(index * step)];\n}\n\n// ─── Helpers ───────────────────────────────────────────────────────────────\n\n// Period-over-period delta — compares last bucket vs second-to-last bucket\nfunction buildDeltaLabel(\n values: number[],\n unit: string,\n lowerIsBetter: boolean,\n): { text: string; tooltip: string; good: boolean } | null {\n if (values.length < 2) return null;\n const curr = values[values.length - 1];\n const prev = values[values.length - 2];\n const diff = curr - prev;\n if (Math.abs(diff) < 0.001) return null;\n const good = lowerIsBetter ? diff < 0 : diff > 0;\n const arrow = diff > 0 ? '↑' : '↓';\n\n const fmt = (v: number) =>\n unit === 'hours' ? formatDuration(v) :\n unit === '%' ? `${Math.round(v * 10) / 10}%` :\n unit === 'per week' ? `${Math.round(v * 10) / 10}/wk` :\n `${Math.round(v * 10) / 10} ${unit}`;\n\n const direction = good ? 'improving' : 'worsening';\n return {\n text: `${arrow} ${fmt(Math.abs(diff))} ${direction}`,\n tooltip: `Latest period: ${fmt(curr)} · Previous period: ${fmt(prev)}\\nEach period = one time bucket (~1/7th of your selected date range)`,\n good,\n };\n}\n\n// ─── Loading overlay ────────────────────────────────────────────────────────\n\nconst LOADING_MESSAGES = [\n 'Establishing routes…',\n 'Syncing catalog…',\n 'Loading plugins…',\n 'Fetching PR data…',\n 'Reading entity graph…',\n];\nconst STAGES = ['FETCH', 'PARSE', 'SCORE', 'RENDER'] as const;\nconst FONT_IMPACT = '\"Impact\",\"Haettenschweiler\",\"Franklin Gothic Heavy\",\"Arial Black\",sans-serif';\nconst FONT_MONO = '\"JetBrains Mono\",\"Fira Code\",\"Consolas\",monospace';\n\nfunction DoraLoadingOverlay() {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n\n const [activeStage, setActiveStage] = useState(0);\n const [msgKey, setMsgKey] = useState(0);\n const [msgIdx, setMsgIdx] = useState(0);\n\n useEffect(() => {\n const st = setInterval(() => setActiveStage(s => (s + 1) % STAGES.length), 800);\n return () => clearInterval(st);\n }, []);\n\n useEffect(() => {\n const mt = setInterval(() => { setMsgIdx(i => (i + 1) % LOADING_MESSAGES.length); setMsgKey(k => k + 1); }, 2200);\n return () => clearInterval(mt);\n }, []);\n\n const textShadow = isDark\n ? '3px 3px 0 #C24E00, 6px 6px 0 #902800, 9px 9px 0 #5A1800, 12px 12px 0 rgba(0,0,0,0.55), 0 0 60px rgba(250,100,0,0.45)'\n : '3px 3px 0 #C24E00, 6px 6px 0 #902800, 9px 9px 0 rgba(80,20,0,0.28), 0 0 32px rgba(250,100,0,0.22)';\n\n const mutedColor = isDark ? '#3f3f46' : '#a1a1aa';\n const subtitleColor = isDark ? '#52525b' : '#71717a';\n const borderColor = isDark ? 'rgba(255,255,255,0.07)' : 'rgba(0,0,0,0.08)';\n\n return (\n <>\n {/* Frosted glass backdrop — blurs whatever is behind */}\n <div aria-hidden style={{\n position: 'fixed', inset: 0, zIndex: 900,\n backdropFilter: 'blur(12px)',\n WebkitBackdropFilter: 'blur(12px)',\n background: isDark ? 'rgba(6,6,9,0.65)' : 'rgba(253,252,251,0.70)',\n }} />\n\n {/* Centered card */}\n <div style={{\n position: 'fixed', zIndex: 901,\n top: '50%', left: '50%',\n transform: 'translateX(-50%) translateY(-50%)',\n display: 'flex', flexDirection: 'column', alignItems: 'center',\n padding: '48px 56px 40px',\n borderRadius: 20,\n background: isDark ? 'rgba(9,9,12,0.82)' : 'rgba(255,255,255,0.88)',\n border: `1px solid ${borderColor}`,\n boxShadow: isDark\n ? '0 0 0 1px rgba(250,100,0,0.06), 0 32px 80px rgba(0,0,0,0.65)'\n : '0 32px 80px rgba(0,0,0,0.12)',\n backdropFilter: 'blur(20px)',\n WebkitBackdropFilter: 'blur(20px)',\n animation: 'dlsCardIn 0.35s cubic-bezier(0.34,1.2,0.64,1) both',\n overflow: 'visible',\n }}>\n\n {/* Breathing ambient glow — inside card */}\n <div aria-hidden style={{\n position: 'absolute', width: 500, height: 360,\n left: '50%', top: '50%',\n transform: 'translateX(-50%) translateY(-50%)',\n background: `radial-gradient(ellipse at center, ${isDark ? 'rgba(250,100,0,0.08)' : 'rgba(250,100,0,0.05)'} 0%, transparent 70%)`,\n animation: 'dlsBreath 3.2s ease-in-out infinite',\n pointerEvents: 'none', borderRadius: 20,\n }} />\n\n {/* DORA wordmark */}\n <div style={{ display: 'flex', lineHeight: 1, marginBottom: 6 }}>\n {['D','O','R','A'].map((letter, i) => (\n <span key={i} style={{\n fontFamily: FONT_IMPACT, fontWeight: 900, fontSize: 110,\n color: '#FA6400', letterSpacing: '0.04em', display: 'inline-block',\n transform: 'skewX(-6deg)', textShadow,\n WebkitTextStroke: '0.5px #C24E00',\n animation: `dlsLetterDrop 0.6s cubic-bezier(0.34,1.45,0.64,1) ${i * 0.1}s both`,\n }}>\n {letter}\n </span>\n ))}\n </div>\n\n {/* Subtitle */}\n <span style={{ fontFamily: 'Inter,system-ui,sans-serif', fontSize: 13, fontWeight: 400,\n letterSpacing: '0.06em', color: subtitleColor, marginBottom: 32,\n animation: 'dlsFadeUp 0.4s ease 0.55s both' }}>\n Metrics\n </span>\n\n {/* Pipeline stages */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 0, marginBottom: 20, animation: 'dlsFadeUp 0.4s ease 0.7s both' }}>\n {STAGES.map((stage, i) => {\n const isActive = i === activeStage;\n const isComplete = i < activeStage;\n return (\n <div key={stage} style={{ display: 'flex', alignItems: 'center', gap: 0 }}>\n <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 5, width: 64 }}>\n <div style={{ position: 'relative', width: 12, height: 12 }}>\n {isActive && (\n <div style={{ position: 'absolute', inset: -6, borderRadius: '50%',\n border: '1.5px solid rgba(250,100,0,0.5)', animation: 'dlsPulse 1s ease-out infinite' }} />\n )}\n <div style={{\n width: 12, height: 12, borderRadius: '50%',\n background: (isActive || isComplete) ? '#FA6400' : (isDark ? '#27272a' : '#e4e4e7'),\n border: `2px solid ${(isActive || isComplete) ? '#C24E00' : (isDark ? '#3f3f46' : '#d4d4d8')}`,\n boxShadow: isActive ? '0 0 14px rgba(250,100,0,0.7)' : 'none',\n transition: 'background 0.3s, box-shadow 0.3s',\n }} />\n </div>\n <span style={{ fontFamily: 'Inter,system-ui,sans-serif', fontSize: 8, fontWeight: 700,\n letterSpacing: '0.12em', textTransform: 'uppercase',\n color: isActive ? '#FA6400' : isComplete ? mutedColor : mutedColor,\n transition: 'color 0.3s' }}>\n {stage}\n </span>\n </div>\n {i < STAGES.length - 1 && (\n <div style={{ width: 32, height: 2, marginBottom: 14, position: 'relative', overflow: 'hidden',\n background: isDark ? '#27272a' : '#e4e4e7', borderRadius: 2 }}>\n <div style={{\n position: 'absolute', inset: 0, borderRadius: 2, background: '#FA6400',\n transformOrigin: 'left center',\n transform: `scaleX(${i < activeStage ? 1 : isActive ? 0.5 : 0})`,\n transition: 'transform 0.4s ease',\n }} />\n </div>\n )}\n </div>\n );\n })}\n </div>\n\n {/* Status message */}\n <span key={msgKey} style={{ fontFamily: FONT_MONO, fontSize: 11,\n color: mutedColor, letterSpacing: '0.04em', animation: 'dlsFadeUp 0.3s ease both' }}>\n {LOADING_MESSAGES[msgIdx]}\n </span>\n\n </div>{/* end card */}\n\n <style>{`\n @keyframes dlsLetterDrop {\n from { opacity: 0; transform: skewX(-6deg) translateY(-32px) scale(1.1); }\n 65% { transform: skewX(-6deg) translateY(6px) scale(0.95); }\n to { opacity: 1; transform: skewX(-6deg) translateY(0) scale(1); }\n }\n @keyframes dlsFadeUp {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n @keyframes dlsBreath {\n 0%, 100% { transform: translateX(-50%) translateY(-50%) scale(0.85); opacity: 0.6; }\n 50% { transform: translateX(-50%) translateY(-50%) scale(1.2); opacity: 1; }\n }\n @keyframes dlsPulse {\n from { transform: scale(0.6); opacity: 0.9; }\n to { transform: scale(2.2); opacity: 0; }\n }\n @keyframes dlsCardIn {\n from { opacity: 0; transform: translateX(-50%) translateY(-46%); }\n to { opacity: 1; transform: translateX(-50%) translateY(-50%); }\n }\n `}</style>\n </>\n );\n}\n\n// ─── Compact sparkline (with hover tooltip + date axis) ────────────────────\n\nfunction CompactSparkline({\n values,\n weekLabels,\n color,\n type,\n formatValue,\n height = 36,\n}: {\n values: number[];\n weekLabels: string[];\n color: string;\n type: 'bar' | 'line';\n formatValue: (v: number) => string;\n height?: number;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hoverIdx, setHoverIdx] = useState<number | null>(null);\n\n const VW = 400; // viewBox units\n const mutedBorder = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)';\n const tooltipBg = isDark ? '#1c1c20' : '#ffffff';\n const tooltipBdr = isDark ? '#3f3f46' : '#e4e4e7';\n const tooltipText = isDark ? '#ededef' : '#111114';\n const font = 'Inter,system-ui,sans-serif';\n\n const handleMouseMove = (e: React.MouseEvent<SVGSVGElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const relX = (e.clientX - rect.left) / rect.width;\n setHoverIdx(Math.max(0, Math.min(values.length - 1, Math.round(relX * (values.length - 1)))));\n };\n\n if (type === 'bar') {\n const max = Math.max(...values, 1);\n const gap = 4;\n const barW = (VW - gap * (values.length - 1)) / values.length;\n\n const hoverX = hoverIdx !== null\n ? hoverIdx * (barW + gap) + barW / 2\n : null;\n const tooltipX = hoverX !== null ? Math.min(hoverX - 34, VW - 72) : 0;\n\n return (\n <div>\n <svg viewBox={`0 0 ${VW} ${height}`} width=\"100%\" style={{ display: 'block', overflow: 'visible' }}\n onMouseMove={handleMouseMove} onMouseLeave={() => setHoverIdx(null)}>\n {values.map((v, i) => {\n const h = Math.max(2, (v / max) * (height - 4));\n return (\n <rect key={i} x={i * (barW + gap)} y={height - h} width={barW} height={h} rx={1.5}\n fill={color} opacity={i === hoverIdx ? 1 : 0.3 + (i / values.length) * 0.55} />\n );\n })}\n <line x1={0} y1={height - 0.5} x2={VW} y2={height - 0.5} stroke={mutedBorder} strokeWidth={1} />\n {hoverIdx !== null && hoverX !== null && (\n <>\n <rect x={tooltipX} y={2} width={72} height={22} rx={4} fill={tooltipBg} stroke={tooltipBdr} strokeWidth={1} />\n <text x={tooltipX + 36} y={17} textAnchor=\"middle\" fill={tooltipText} fontSize={9} fontWeight={600} fontFamily={font}>\n {weekLabels[hoverIdx]}: {formatValue(values[hoverIdx])}\n </text>\n </>\n )}\n </svg>\n <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 3 }}>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[0]}</span>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[weekLabels.length - 1]}</span>\n </div>\n </div>\n );\n }\n\n if (values.length < 2) return null;\n const max = Math.max(...values, 0.01);\n const min = Math.min(...values);\n const range = max - min || max || 1;\n const pad = 3;\n const pts = values.map((v, i): [number, number] => [\n (i / (values.length - 1)) * (VW - pad * 2) + pad,\n (height - pad * 2) - ((v - min) / range) * (height - pad * 2 - 2) + pad,\n ]);\n const d = pts.map(([x, y], i) => `${i === 0 ? 'M' : 'L'}${x.toFixed(1)},${y.toFixed(1)}`).join(' ');\n const area = `${d} L${pts[pts.length-1][0]},${height} L${pts[0][0]},${height} Z`;\n const hoverPt = hoverIdx !== null ? pts[hoverIdx] : null;\n const tooltipX2 = hoverPt ? Math.min(hoverPt[0] - 34, VW - 72) : 0;\n\n return (\n <div>\n <svg viewBox={`0 0 ${VW} ${height}`} width=\"100%\" style={{ display: 'block', overflow: 'visible' }}\n onMouseMove={handleMouseMove} onMouseLeave={() => setHoverIdx(null)}>\n <path d={area} fill={color} opacity={0.07} />\n <path d={d} fill=\"none\" stroke={color} strokeWidth={1.5} strokeLinejoin=\"round\" strokeLinecap=\"round\" />\n {pts.map(([x, y], i) => (\n <circle key={i} cx={x} cy={y} r={i === hoverIdx ? 3.5 : i === pts.length - 1 ? 2.5 : 0} fill={color} />\n ))}\n <line x1={0} y1={height - 0.5} x2={VW} y2={height - 0.5} stroke={mutedBorder} strokeWidth={1} />\n {hoverPt && hoverIdx !== null && (\n <>\n <line x1={hoverPt[0]} y1={0} x2={hoverPt[0]} y2={height} stroke={color} strokeWidth={1} strokeDasharray=\"2 2\" opacity={0.4} />\n <rect x={tooltipX2} y={2} width={72} height={22} rx={4} fill={tooltipBg} stroke={tooltipBdr} strokeWidth={1} />\n <text x={tooltipX2 + 36} y={17} textAnchor=\"middle\" fill={tooltipText} fontSize={9} fontWeight={600} fontFamily={font}>\n {weekLabels[hoverIdx]}: {formatValue(values[hoverIdx])}\n </text>\n </>\n )}\n </svg>\n <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 3 }}>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[0]}</span>\n <span style={{ fontSize: 9, color: isDark ? '#3f3f46' : '#a1a1aa' }}>{weekLabels[weekLabels.length - 1]}</span>\n </div>\n </div>\n );\n}\n\n// ─── Detailed interactive chart ────────────────────────────────────────────\n\ninterface ChartTooltipState {\n x: number;\n y: number;\n primary: string;\n secondary?: string;\n}\n\nfunction DetailedChart({\n values,\n weekLabels,\n bucketMidMs,\n color,\n type,\n formatValue,\n prs,\n days,\n hoveredPrNumber,\n onPrHover,\n}: {\n values: number[];\n weekLabels: string[];\n bucketMidMs: number[];\n color: string;\n type: 'bar' | 'line';\n formatValue: (v: number) => string;\n prs?: PrDetail[];\n days: number;\n hoveredPrNumber?: number | null;\n onPrHover?: (num: number | null) => void;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hoverIdx, setHoverIdx] = useState<number | null>(null);\n const [tooltip, setTooltip] = useState<ChartTooltipState | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const W = 800, H = 260;\n const PAD = { top: 16, right: 16, bottom: 36, left: 56 };\n const cW = W - PAD.left - PAD.right;\n const cH = H - PAD.top - PAD.bottom;\n\n // Y scale: based on bucket values only so the trend line is clearly readable.\n // PR dots that fall outside this range are rendered clamped to chart area.\n const dataMax = Math.max(...values, 0.01);\n const dataMin = type === 'line' ? Math.min(...values, 0) : 0;\n const dataRange = dataMax - dataMin || dataMax || 1;\n const yScale = (v: number) => cH - ((v - dataMin) / dataRange) * cH;\n\n // Shared timestamp-based x-axis\n const cutoffMs = Date.now() - days * 24 * 60 * 60 * 1000;\n const rangeMs = days * 24 * 60 * 60 * 1000;\n const xTime = (ms: number) => Math.max(0, Math.min(cW, ((ms - cutoffMs) / rangeMs) * cW));\n\n const xIdx = (i: number) => bucketMidMs.length === values.length\n ? xTime(bucketMidMs[i])\n : (values.length > 1 ? (i / (values.length - 1)) * cW : cW / 2);\n\n const pts: [number, number][] = values.map((v, i) => [PAD.left + xIdx(i), PAD.top + yScale(v)]);\n const linePath = pts.map(([x, y], i) => `${i === 0 ? 'M' : 'L'}${x.toFixed(1)},${y.toFixed(1)}`).join(' ');\n const areaPath = pts.length > 1\n ? `${linePath} L${pts[pts.length-1][0]},${PAD.top+cH} L${pts[0][0]},${PAD.top+cH} Z`\n : '';\n\n const gap = 6;\n const barW = values.length > 1 ? (cW - gap * (values.length - 1)) / values.length : cW;\n\n const yTicks = [0, 0.25, 0.5, 0.75, 1].map(t => dataMin + t * dataRange);\n const gridColor = isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.05)';\n const axisColor = isDark ? '#3f3f46' : '#d4d4d8';\n const labelColor = isDark ? '#52525b' : '#a1a1aa';\n const font = 'Inter,system-ui,sans-serif';\n const gradId = `dg_${color.replace('#','')}`;\n\n // Find the nearest bucket index for a given timestamp\n const nearestBucket = (ms: number): number => {\n if (bucketMidMs.length === 0) return 0;\n let best = 0, bestDist = Infinity;\n bucketMidMs.forEach((mid, i) => {\n const d = Math.abs(ms - mid);\n if (d < bestDist) { bestDist = d; best = i; }\n });\n return best;\n };\n\n const handleSvgMouseMove = (e: React.MouseEvent<SVGSVGElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const relX = (e.clientX - rect.left - PAD.left * (rect.width / W)) / (rect.width * cW / W);\n const idx = Math.max(0, Math.min(values.length - 1, Math.round(relX * (values.length - 1))));\n setHoverIdx(idx);\n const cRect = containerRef.current?.getBoundingClientRect();\n const x = cRect ? e.clientX - cRect.left : 0;\n const y = cRect ? e.clientY - cRect.top : 0;\n setTooltip({ x, y, primary: formatValue(values[idx]), secondary: weekLabels[idx] });\n };\n\n return (\n <div ref={containerRef} style={{ position: 'relative' }}>\n <svg viewBox={`0 0 ${W} ${H}`} width=\"100%\" style={{ display: 'block' }}\n onMouseMove={handleSvgMouseMove}\n onMouseLeave={() => { setHoverIdx(null); setTooltip(null); }}>\n <defs>\n <linearGradient id={gradId} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={color} stopOpacity={0.28} />\n <stop offset=\"100%\" stopColor={color} stopOpacity={0} />\n </linearGradient>\n {/* Clip PR dots to the chart area */}\n <clipPath id={`prClip_${gradId}`}>\n <rect x={PAD.left} y={PAD.top - 8} width={cW} height={cH + 16} />\n </clipPath>\n </defs>\n\n {/* Grid + Y-axis */}\n {yTicks.map((v, i) => {\n const y = PAD.top + yScale(v);\n return (\n <g key={i}>\n {i > 0 && <line x1={PAD.left} y1={y} x2={PAD.left+cW} y2={y} stroke={gridColor} strokeWidth={1} strokeDasharray=\"3 4\" />}\n <text x={PAD.left - 6} y={y + 4} textAnchor=\"end\" fill={labelColor} fontSize={10} fontFamily={font}>\n {formatValue(v)}\n </text>\n </g>\n );\n })}\n <line x1={PAD.left} y1={PAD.top+cH} x2={PAD.left+cW} y2={PAD.top+cH} stroke={axisColor} strokeWidth={1} />\n\n {/* Chart body */}\n {type === 'bar' ? (\n values.map((v, i) => {\n const bH = Math.max(2, ((v - dataMin) / dataRange) * cH);\n const x = PAD.left + i * (barW + gap);\n return (\n <rect key={i} x={x} y={PAD.top+cH-bH} width={barW} height={bH} rx={3}\n fill={color} opacity={i === hoverIdx ? 0.95 : 0.4 + (i / Math.max(values.length - 1, 1)) * 0.45} />\n );\n })\n ) : (\n <>\n {areaPath && <path d={areaPath} fill={`url(#${gradId})`} />}\n <path d={linePath} fill=\"none\" stroke={color} strokeWidth={2.5} strokeLinejoin=\"round\" strokeLinecap=\"round\" />\n {pts.map(([x, y], i) => (\n <circle key={i} cx={x} cy={y}\n r={i === hoverIdx ? 5.5 : 4}\n fill={isDark ? '#0f0f12' : '#ffffff'} stroke={color}\n strokeWidth={i === hoverIdx ? 2.5 : 1.5} />\n ))}\n </>\n )}\n\n {/* PR data-point dots — x at bucket midpoint, y at actual duration (clamped to chart) */}\n {prs && type === 'line' && (\n <g clipPath={`url(#prClip_${gradId})`}>\n {prs.map((pr, dotIdx) => {\n const mergedMs = new Date(pr.mergedAt).getTime();\n const bIdx = nearestBucket(mergedMs);\n // Small deterministic jitter within the bucket to avoid overlap\n const jitter = ((pr.number * 17 + dotIdx * 11) % 13 - 6) * 5;\n const px = PAD.left + xIdx(bIdx) + jitter;\n // Clamp y: PR may be faster or slower than bucket avg; always visible\n const rawPy = PAD.top + yScale(pr.durationHours);\n const py = Math.max(PAD.top + 4, Math.min(PAD.top + cH - 4, rawPy));\n const isHov = pr.number === hoveredPrNumber;\n\n // Thin connector from dot to the bucket trend point\n const trendPt = pts[bIdx];\n\n return (\n <g key={pr.number} style={{ cursor: 'pointer' }}\n onMouseEnter={e => {\n e.stopPropagation();\n const cRect = containerRef.current?.getBoundingClientRect();\n const x = cRect ? e.clientX - cRect.left : 0;\n const y = cRect ? e.clientY - cRect.top : 0;\n setTooltip({ x, y,\n primary: `#${pr.number}: ${pr.title}`,\n secondary: `${formatValue(pr.durationHours)} · ${new Date(pr.mergedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}` });\n onPrHover?.(pr.number);\n }}\n onMouseLeave={() => { setTooltip(null); onPrHover?.(null); }}>\n {trendPt && (\n <line x1={px} y1={py} x2={trendPt[0]} y2={trendPt[1]}\n stroke={color} strokeWidth={isHov ? 1 : 0.5}\n strokeDasharray=\"2 3\" opacity={isHov ? 0.5 : 0.2} />\n )}\n <circle cx={px} cy={py} r={isHov ? 11 : 7} fill={color} opacity={isHov ? 0.2 : 0.1} />\n <circle cx={px} cy={py} r={isHov ? 5.5 : 3.5}\n fill={isHov ? color : (isDark ? '#1a1a20' : '#fff')}\n stroke={color} strokeWidth={isHov ? 0 : 1.5}\n opacity={isHov ? 1 : 0.8} />\n </g>\n );\n })}\n </g>\n )}\n\n {/* Hover crosshair */}\n {hoverIdx !== null && type === 'line' && pts[hoverIdx] && (\n <>\n <line x1={pts[hoverIdx][0]} y1={PAD.top} x2={pts[hoverIdx][0]} y2={PAD.top+cH}\n stroke={color} strokeWidth={1} strokeDasharray=\"3 3\" opacity={0.3} />\n <line x1={PAD.left} y1={pts[hoverIdx][1]} x2={PAD.left+cW} y2={pts[hoverIdx][1]}\n stroke={color} strokeWidth={1} strokeDasharray=\"3 3\" opacity={0.2} />\n </>\n )}\n\n {/* X-axis labels */}\n {weekLabels.map((lbl, i) => {\n const total = weekLabels.length;\n const step = Math.max(1, Math.floor(total / 5));\n if (i !== 0 && i !== total - 1 && i % step !== 0) return null;\n const x = type === 'bar'\n ? PAD.left + i * (barW + gap) + barW / 2\n : PAD.left + xIdx(i);\n return (\n <text key={i} x={x} y={H - 8} textAnchor=\"middle\" fill={labelColor} fontSize={10} fontFamily={font}>\n {lbl}\n </text>\n );\n })}\n </svg>\n\n {/* Absolute tooltip — positioned relative to the chart container */}\n {tooltip && (() => {\n const TW = 220;\n const cW2 = containerRef.current?.offsetWidth ?? 800;\n const nearRight = tooltip.x + TW + 12 > cW2;\n return (\n <div style={{\n position: 'absolute',\n left: nearRight ? tooltip.x - TW - 8 : tooltip.x + 8,\n top: tooltip.y - 36,\n zIndex: 9999, pointerEvents: 'none',\n background: isDark ? '#18181b' : '#ffffff',\n border: `1px solid ${isDark ? '#3f3f46' : '#e4e4e7'}`,\n borderRadius: 7, padding: '7px 10px',\n boxShadow: isDark ? '0 6px 20px rgba(0,0,0,0.55)' : '0 6px 20px rgba(0,0,0,0.10)',\n width: TW,\n }}>\n <div style={{ fontSize: 12, fontWeight: 600, color: isDark ? '#ededef' : '#111114',\n fontFamily: font, lineHeight: 1.4 }}>\n {tooltip.primary}\n </div>\n {tooltip.secondary && (\n <div style={{ fontSize: 11, color: isDark ? '#71717a' : '#a1a1aa', fontFamily: font, marginTop: 2 }}>\n {tooltip.secondary}\n </div>\n )}\n </div>\n );\n })()}\n </div>\n );\n}\n\n// ─── Detailed overlay ──────────────────────────────────────────────────────\n\ninterface ExpandedCardData {\n title: string;\n metric: DoraMetricValue;\n description: string;\n lowerIsBetter: boolean;\n sparklineValues: number[];\n sparklineType: 'bar' | 'line';\n sparklineColor: string;\n weekLabels: string[];\n bucketMidMs: number[];\n prs?: PrDetail[];\n /** Override the section header above the PR list (default: \"All deployments\"). */\n prListLabel?: string;\n}\n\nfunction DetailedOverlay({\n data,\n days,\n onClose,\n}: {\n data: ExpandedCardData;\n days: number;\n onClose: () => void;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hoveredPrNumber, setHoveredPrNumber] = useState<number | null>(null);\n const prRowRefs = useRef<Map<number, HTMLDivElement>>(new Map());\n\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [onClose]);\n\n // Auto-scroll to the highlighted PR row when hover comes from the chart\n useEffect(() => {\n if (hoveredPrNumber !== null) {\n const el = prRowRefs.current.get(hoveredPrNumber);\n if (el) el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }\n }, [hoveredPrNumber]);\n\n const { title, metric, description, lowerIsBetter, sparklineValues, sparklineType, sparklineColor, weekLabels, bucketMidMs, prs, prListLabel } = data;\n const isDeployFreq = sparklineType === 'bar';\n const displayValue = metric.unit === 'hours' ? formatDuration(metric.value) : String(metric.value);\n const displayUnit = metric.unit === 'hours' ? '' : metric.unit;\n const formatVal = (v: number) => metric.unit === 'hours' ? formatDuration(v) : `${Math.round(v * 10) / 10}`;\n const borderColor = isDark ? '#27272a' : '#e4e4e7';\n const mutedColor = isDark ? '#52525b' : '#a1a1aa';\n const targetLabel = lowerIsBetter\n ? `Target: < ${metric.unit === 'hours' ? formatDuration(metric.target) : metric.target} ${displayUnit}`\n : `Target: ≥ ${metric.target} ${displayUnit}`;\n\n // Group deployment PRs by date (for the date table)\n const prsByDate = isDeployFreq && prs ? prs.reduce((acc, pr) => {\n const date = new Date(pr.mergedAt).toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' });\n if (!acc[date]) acc[date] = [];\n acc[date].push(pr);\n return acc;\n }, {} as Record<string, PrDetail[]>) : {};\n const sortedDates = Object.keys(prsByDate).sort(\n (a, b) => new Date(prsByDate[b][0].mergedAt).getTime() - new Date(prsByDate[a][0].mergedAt).getTime()\n );\n\n return (\n <>\n {/* Backdrop */}\n <div onClick={onClose} style={{\n position: 'fixed', inset: 0, zIndex: 499,\n background: isDark ? 'rgba(0,0,0,0.6)' : 'rgba(0,0,0,0.3)',\n backdropFilter: 'blur(4px)',\n }} />\n\n {/* Panel */}\n <div style={{\n position: 'fixed',\n top: '50%', left: '50%',\n transform: 'translateX(-50%) translateY(-50%)',\n width: 'min(92vw, 960px)',\n maxHeight: 'calc(100vh - 80px)',\n zIndex: 500,\n background: isDark ? '#09090c' : '#fafafa',\n border: `1px solid ${borderColor}`,\n borderRadius: 14,\n display: 'flex', flexDirection: 'column',\n overflow: 'hidden',\n animation: 'detailExpandIn 0.2s cubic-bezier(0.34,1.2,0.64,1)',\n boxShadow: isDark ? '0 24px 64px rgba(0,0,0,0.7)' : '0 24px 64px rgba(0,0,0,0.18)',\n }}>\n {/* Header */}\n <div style={{\n display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start',\n padding: '20px 24px 16px',\n borderBottom: `1px solid ${borderColor}`,\n flexShrink: 0,\n }}>\n <div>\n <div style={{ fontSize: 10, fontWeight: 700, color: mutedColor, textTransform: 'uppercase', letterSpacing: '0.12em', marginBottom: 8 }}>\n {title} · {weekLabels[0]} – {weekLabels[weekLabels.length - 1]}\n </div>\n <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, flexWrap: 'wrap' }}>\n <span style={{ fontSize: 52, fontWeight: 700, color: theme.palette.text.primary, lineHeight: 1, letterSpacing: '-0.02em' }}>\n {displayValue}\n </span>\n {displayUnit && (\n <span style={{ fontSize: 18, color: mutedColor, fontWeight: 500 }}>{displayUnit}</span>\n )}\n <RatingBadge rating={metric.rating} />\n </div>\n <div style={{ fontSize: 12, color: mutedColor, marginTop: 6 }}>\n {description} · <span style={{ fontStyle: 'italic' }}>{targetLabel}</span>\n </div>\n </div>\n <button type=\"button\" onClick={onClose} style={{\n all: 'unset', cursor: 'pointer', width: 30, height: 30,\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n borderRadius: '50%', background: isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)',\n color: mutedColor, fontSize: 18, fontWeight: 300, transition: 'all 0.12s', flexShrink: 0,\n }}\n onMouseEnter={e => { (e.currentTarget as HTMLElement).style.background = isDark ? 'rgba(255,255,255,0.12)' : 'rgba(0,0,0,0.1)'; }}\n onMouseLeave={e => { (e.currentTarget as HTMLElement).style.background = isDark ? 'rgba(255,255,255,0.06)' : 'rgba(0,0,0,0.06)'; }}>\n ✕\n </button>\n </div>\n\n {/* Body — scrollable */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px 24px', display: 'flex', flexDirection: 'column', gap: 20 }}>\n\n {/* Chart */}\n {weekLabels.length >= 2 ? (\n <DetailedChart\n values={sparklineValues} weekLabels={weekLabels}\n bucketMidMs={bucketMidMs}\n color={sparklineColor} type={sparklineType}\n formatValue={formatVal} prs={isDeployFreq ? undefined : prs} days={days}\n hoveredPrNumber={hoveredPrNumber} onPrHover={setHoveredPrNumber}\n />\n ) : (\n <div style={{ color: mutedColor, fontSize: 13, textAlign: 'center', padding: '48px 0' }}>\n Not enough data — select a wider date range.\n </div>\n )}\n\n {/* === Deployment Frequency: PRs grouped by date === */}\n {isDeployFreq && prs && prs.length > 0 && (\n <div>\n <div style={{ fontSize: 10, fontWeight: 700, color: mutedColor, textTransform: 'uppercase',\n letterSpacing: '0.12em', marginBottom: 12,\n borderTop: `1px solid ${borderColor}`, paddingTop: 12 }}>\n {prListLabel ?? 'All deployments'} · {prs.length} PR{prs.length !== 1 ? 's' : ''}\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>\n {sortedDates.map(date => (\n <div key={date}>\n {/* Date header */}\n <div style={{\n fontSize: 11, fontWeight: 700, color: sparklineColor,\n marginBottom: 6, display: 'flex', alignItems: 'center', gap: 8,\n }}>\n <span>{date}</span>\n <span style={{ color: mutedColor, fontWeight: 500 }}>· {prsByDate[date].length} PR{prsByDate[date].length > 1 ? 's' : ''}</span>\n </div>\n {/* PR rows */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: 4, paddingLeft: 12,\n borderLeft: `2px solid ${sparklineColor}22` }}>\n {prsByDate[date].map(pr => (\n <div key={pr.number} style={{\n display: 'flex', flexDirection: 'column', gap: 5,\n padding: '7px 10px', borderRadius: 7,\n background: isDark ? '#0d0d10' : '#f7f7f9',\n border: `1px solid ${borderColor}`,\n transition: 'background 0.12s',\n }}>\n {/* Row 1: number + title + lead time + link */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <span style={{ fontSize: 10, fontWeight: 700, color: mutedColor, flexShrink: 0, minWidth: 36 }}>\n #{pr.number}\n </span>\n <span style={{ fontSize: 12, color: theme.palette.text.primary, flex: 1,\n whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }} title={pr.title}>\n {pr.title}\n </span>\n <span style={{ fontSize: 10, color: mutedColor, flexShrink: 0 }}>\n {formatDuration(pr.durationHours)} lead\n </span>\n <a href={pr.url} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ color: mutedColor, flexShrink: 0 }}>\n <ExternalLink size={11} />\n </a>\n </div>\n {/* Row 2: author badge */}\n {pr.author && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 5 }}>\n {pr.authorAvatar ? (\n <img src={pr.authorAvatar} alt={pr.author}\n style={{ width: 16, height: 16, borderRadius: '50%', flexShrink: 0,\n border: `1px solid ${isDark ? '#3f3f46' : '#e4e4e7'}` }} />\n ) : (\n <div style={{ width: 16, height: 16, borderRadius: '50%', flexShrink: 0,\n background: isDark ? '#27272a' : '#e4e4e7',\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n fontSize: 8, fontWeight: 700, color: mutedColor }}>\n {pr.author[0].toUpperCase()}\n </div>\n )}\n <a href={`https://github.com/${pr.author}`} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ fontSize: 10, fontWeight: 500, color: mutedColor,\n textDecoration: 'none', letterSpacing: '0.01em' }}\n onMouseEnter={e => { (e.currentTarget as HTMLElement).style.color = '#FA6400'; }}\n onMouseLeave={e => { (e.currentTarget as HTMLElement).style.color = mutedColor; }}>\n @{pr.author}\n </a>\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* === Lead Time / MTTR: duration-ranked PR list with hover linking === */}\n {!isDeployFreq && prs && prs.length > 0 && (\n <div>\n <div style={{ fontSize: 10, fontWeight: 700, color: mutedColor, textTransform: 'uppercase',\n letterSpacing: '0.12em', marginBottom: 10,\n borderTop: `1px solid ${borderColor}`, paddingTop: 12 }}>\n {title.toLowerCase().includes('restore') ? 'Slowest Hotfix PRs' : 'Slowest PRs'}\n {' '}· hover a row to highlight on chart\n </div>\n <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>\n {prs.map((pr, i) => {\n const col = durationColor(i, prs.length);\n const maxDur = prs[0].durationHours;\n const barPct = maxDur > 0 ? (pr.durationHours / maxDur) * 100 : 0;\n const isHov = pr.number === hoveredPrNumber;\n return (\n <div key={pr.number}\n ref={(el) => {\n if (el) prRowRefs.current.set(pr.number, el);\n else prRowRefs.current.delete(pr.number);\n }}\n onMouseEnter={() => setHoveredPrNumber(pr.number)}\n onMouseLeave={() => setHoveredPrNumber(null)}\n style={{\n padding: '8px 12px', borderRadius: 8,\n background: isHov\n ? (isDark ? '#18181f' : '#f0f0ff')\n : (isDark ? '#111114' : '#f4f4f6'),\n border: `1px solid ${isHov ? `${sparklineColor}55` : borderColor}`,\n display: 'flex', flexDirection: 'column', gap: 5,\n transition: 'background 0.12s, border-color 0.12s',\n cursor: 'default',\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: 6, minWidth: 0 }}>\n <span style={{ fontSize: 10, fontWeight: 700, color: col, flexShrink: 0 }}>#{pr.number}</span>\n <span style={{ fontSize: 12, color: theme.palette.text.primary, flex: 1,\n whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }} title={pr.title}>\n {pr.title}\n </span>\n <span style={{ fontSize: 10, color: mutedColor, flexShrink: 0 }}>\n {new Date(pr.mergedAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}\n </span>\n <a href={pr.url} target=\"_blank\" rel=\"noopener noreferrer\"\n style={{ color: mutedColor, flexShrink: 0, transition: 'color 0.12s' }}>\n <ExternalLink size={11} />\n </a>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n <AnimatedBar widthPct={barPct} color={col} />\n <span style={{ fontSize: 11, fontWeight: 700, color: col, minWidth: 52, textAlign: 'right', flexShrink: 0 }}>\n {formatDuration(pr.durationHours)}\n </span>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n )}\n </div>\n </div>\n <style>{`\n @keyframes detailExpandIn {\n from { opacity: 0; transform: translateX(-50%) translateY(-46%); }\n to { opacity: 1; transform: translateX(-50%) translateY(-50%); }\n }\n `}</style>\n </>\n );\n}\n\n// ─── Animated bar ──────────────────────────────────────────────────────────\n\nfunction AnimatedBar({ widthPct, color }: { widthPct: number; color: string }) {\n const [width, setWidth] = useState(0);\n const ref = useRef<HTMLDivElement>(null);\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n\n useEffect(() => {\n const timer = setTimeout(() => setWidth(widthPct), 80);\n return () => clearTimeout(timer);\n }, [widthPct]);\n\n return (\n <div\n ref={ref}\n style={{\n background: isDark ? '#1a1a1e' : '#f0f0f2',\n borderRadius: 4,\n height: 5,\n overflow: 'hidden',\n flex: 1,\n minWidth: 40,\n }}\n >\n <div\n style={{\n height: '100%',\n width: `${width}%`,\n background: color,\n borderRadius: 4,\n transition: 'width 0.55s cubic-bezier(0.4, 0, 0.2, 1)',\n boxShadow: `0 0 6px ${color}88`,\n }}\n />\n </div>\n );\n}\n\n// ─── Metric cards ──────────────────────────────────────────────────────────\n\nfunction MetricCard({\n title,\n metric,\n description,\n lowerIsBetter = false,\n sparklineData,\n sparklineType = 'line',\n sparklineColor,\n weekLabels,\n onExpand,\n expandLabel,\n}: {\n title: string;\n metric: DoraMetricValue;\n description: string;\n lowerIsBetter?: boolean;\n sparklineData?: number[];\n sparklineType?: 'bar' | 'line';\n sparklineColor?: string;\n weekLabels?: string[];\n onExpand?: () => void;\n /** Persistent label shown in the card footer (instead of the hover-only \"expand ↗\"). */\n expandLabel?: string;\n}) {\n const theme = useTheme();\n const isDark = theme.palette.type === 'dark';\n const [hovered, setHovered] = useState(false);\n\n const displayValue = metric.unit === 'hours' ? formatDuration(metric.value) : metric.value;\n const displayUnit = metric.unit === 'hours' ? '' : metric.unit;\n const targetValue = metric.unit === 'hours' ? formatDuration(metric.target) : metric.target;\n const targetLabel = lowerIsBetter\n ? `Target: < ${targetValue} ${displayUnit}`.trim()\n : `Target: ≥ ${targetValue} ${displayUnit}`.trim();\n\n const hasSparkline = sparklineData && sparklineData.length >= 2 && weekLabels && weekLabels.length >= 2;\n const delta = hasSparkline ? buildDeltaLabel(sparklineData!, metric.unit, lowerIsBetter) : null;\n const formatVal = (v: number) => metric.unit === 'hours' ? formatDuration(v) : `${Math.round(v * 10) / 10}`;\n\n return (\n <Card\n style={{ cursor: onExpand ? 'pointer' : undefined }}\n onClick={onExpand}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n >\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8 }}>\n <CardLabel>{title}</CardLabel>\n {onExpand && (\n <span style={{\n fontSize: 9, fontWeight: 600, color: isDark ? '#3f3f46' : '#d4d4d8',\n opacity: hovered ? 1 : 0, transition: 'opacity 0.15s',\n letterSpacing: '0.05em', textTransform: 'uppercase', flexShrink: 0,\n }}>\n expand ↗\n </span>\n )}\n </div>\n {/* Right-aligned column: delta trend + direction hint stacked */}\n <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 4 }}>\n {delta && (\n <span title={delta.tooltip} style={{\n fontSize: 10, fontWeight: 600, cursor: 'help',\n color: delta.good ? '#4ade80' : '#f87171',\n background: delta.good\n ? (isDark ? 'rgba(74,222,128,0.08)' : 'rgba(74,222,128,0.12)')\n : (isDark ? 'rgba(248,113,113,0.08)' : 'rgba(248,113,113,0.12)'),\n padding: '2px 8px', borderRadius: 4, whiteSpace: 'nowrap',\n }}>\n {delta.text}\n </span>\n )}\n <span style={{\n fontSize: 10, fontWeight: 600,\n color: isDark ? '#3f3f46' : '#d4d4d8',\n whiteSpace: 'nowrap',\n }}>\n {lowerIsBetter ? '↓ lower = better' : '↑ higher = better'}\n </span>\n </div>\n {/* Value row: big number + unit */}\n <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>\n <span style={{ fontSize: 36, fontWeight: 700, color: isDark ? '#f4f4f5' : '#111114', lineHeight: 1 }}>\n {displayValue}\n </span>\n {displayUnit && (\n <span style={{ fontSize: 14, color: isDark ? '#71717a' : '#71717a', fontWeight: 500 }}>\n {displayUnit}\n </span>\n )}\n </div>\n <RatingBadge rating={metric.rating} />\n {hasSparkline && (\n <div style={{ marginTop: 2 }}>\n <CompactSparkline\n values={sparklineData!}\n weekLabels={weekLabels!}\n color={sparklineColor ?? '#FA6400'}\n type={sparklineType}\n formatValue={formatVal}\n />\n </div>\n )}\n <CardDescription>{description}</CardDescription>\n <CardFooter>\n <span style={{ fontWeight: 600, color: isDark ? '#a1a1aa' : '#52525b' }}>\n {targetLabel}\n </span>\n {expandLabel && onExpand && (\n <span style={{\n fontSize: 10, fontWeight: 700,\n color: '#FA6400',\n letterSpacing: '0.04em',\n marginLeft: 'auto',\n }}>\n {expandLabel}\n </span>\n )}\n </CardFooter>\n </Card>\n );\n}\n\nfunction NaCard({ title, description }: { title: string; description: string }) {\n return (\n <Card>\n <CardLabel>{title}</CardLabel>\n <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>\n <span style={{ fontSize: 36, fontWeight: 700, color: '#52525b', lineHeight: 1 }}>N/A</span>\n </div>\n <CardDescription muted>{description}</CardDescription>\n </Card>\n );\n}\n\n// ─── Filter label ──────────────────────────────────────────────────────────\n\nfunction FilterLabel({ children }: { children: React.ReactNode }) {\n const theme = useTheme();\n return (\n <div style={{ fontSize: 11, fontWeight: 600, color: theme.palette.text.primary, marginBottom: 4, textTransform: 'uppercase', letterSpacing: '0.06em' }}>\n {children}\n </div>\n );\n}\n\n// ─── Main component ────────────────────────────────────────────────────────\n\nexport function DoraMetricsContent() {\n const { entity } = useEntity();\n const doraApi = useApi(doraMetricsApiRef);\n const muiTheme = useTheme();\n const textPrimary = muiTheme.palette.text.primary;\n const textSecondary = muiTheme.palette.text.secondary;\n\n const projectSlug = entity.metadata.annotations?.[ANNOTATION_PROJECT_SLUG] ?? '';\n const annotations = entity.metadata.annotations ?? {};\n\n // Per-repo overrides from catalog-info.yaml annotations\n const annotationEnvs = parseAnnotationJson<DoraEnvironment[]>(annotations[ANNOTATION_ENVIRONMENTS]);\n const annotationTargets = parseAnnotationJson<Partial<DoraTargets>>(annotations[ANNOTATION_TARGETS]);\n\n const environments: DoraEnvironment[] = annotationEnvs ?? doraApi.getEnvironments();\n const defaultEnv = environments[0];\n const defaultDays = doraApi.getDefaultDays();\n\n // Use environment name as the selection key (branch can be a multi-value pattern)\n const [selectedEnvName, setSelectedEnvName] = useState<string>(defaultEnv?.name ?? '');\n const [selectedDays, setSelectedDays] = useState<string>(String(defaultDays));\n\n const selectedEnv = environments.find(e => e.name === selectedEnvName) ?? defaultEnv;\n const days = parseInt(selectedDays, 10);\n\n const [metrics, setMetrics] = useState<DoraMetrics | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const [history, setHistory] = useState<DoraHistoryPoint[] | null>(null);\n const [expanded, setExpanded] = useState<ExpandedCardData | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n\n if (!projectSlug) {\n setError(new Error(`Entity is missing the \"${ANNOTATION_PROJECT_SLUG}\" annotation.`));\n setLoading(false);\n return () => { cancelled = true; };\n }\n if (!selectedEnv) {\n setError(new Error('No environments configured for DORA metrics.'));\n setLoading(false);\n return () => { cancelled = true; };\n }\n\n setLoading(true);\n setError(null);\n setHistory(null);\n\n doraApi\n .getMetrics(projectSlug, selectedEnv, days, annotationTargets ?? undefined)\n .then(data => {\n if (!cancelled) { setMetrics(data); setLoading(false); }\n })\n .catch((err: Error) => {\n if (!cancelled) { setError(err); setLoading(false); }\n });\n\n doraApi\n .getHistory(projectSlug, selectedEnv, days)\n .then(data => { if (!cancelled) setHistory(data); })\n .catch(() => { /* history is optional — fail silently */ });\n\n return () => { cancelled = true; };\n // selectedEnv?.name is intentional — avoids re-render loops from object identity changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [doraApi, projectSlug, selectedEnv?.name, days, annotationTargets]);\n\n if (loading) return <DoraLoadingOverlay />;\n\n if (error) {\n return (\n <InfoCard title=\"DORA Metrics\">\n <div style={{ padding: 24, color: '#f87171' }}>\n <span style={{ fontWeight: 600 }}>Error: </span>{error.message}\n </div>\n </InfoCard>\n );\n }\n\n if (!metrics) return null;\n\n return (\n <InfoCard title=\" \">\n <div style={{ padding: '4px 0', position: 'relative' }}>\n {/* Detailed overlay */}\n {expanded && (\n <DetailedOverlay data={expanded} days={days} onClose={() => setExpanded(null)} />\n )}\n\n {/* Title */}\n <div style={{ marginBottom: 16 }}>\n <div style={{ fontSize: 22, fontWeight: 700, color: textPrimary, letterSpacing: '-0.02em' }}>DORA Metrics</div>\n {selectedEnv && (\n <div style={{ fontSize: 12, color: textSecondary, marginTop: 5 }}>\n Showing metrics for{' '}\n <strong style={{ color: textPrimary }}>{selectedEnv.name}</strong>\n {' '}—{' '}\n <span style={{ fontFamily: 'monospace' }}>{selectedEnv.branch}</span>\n </div>\n )}\n </div>\n\n {/* Filters row — left aligned */}\n <div style={{ display: 'flex', alignItems: 'flex-end', gap: 16, flexWrap: 'wrap', marginBottom: 20 }}>\n {environments.length > 1 && (\n <div>\n <FilterLabel>Environment</FilterLabel>\n <Select value={selectedEnvName} onValueChange={setSelectedEnvName}>\n <SelectTrigger><SelectValue placeholder=\"Select environment\" /></SelectTrigger>\n <SelectContent>\n {environments.map(env => (\n <SelectItem key={env.name} value={env.name}>\n {env.name} ({env.branch})\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n\n <div>\n <FilterLabel>Date Range</FilterLabel>\n <Select value={selectedDays} onValueChange={setSelectedDays}>\n <SelectTrigger><SelectValue placeholder=\"Select date range\" /></SelectTrigger>\n <SelectContent>\n {DATE_RANGE_OPTIONS.map(opt => (\n <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {/* Metric cards — sparklines inline, click to expand */}\n {(() => {\n const wkLabels = history?.map(h => h.weekLabel) ?? [];\n const deployData = history?.map(h => h.deploymentCount) ?? [];\n const leadData = history?.map(h => h.leadTimeHours) ?? [];\n const cfrData = history?.map(h => h.changeFailureRate ?? 0) ?? [];\n const mttrData = history?.map(h => h.mttrHours ?? 0) ?? [];\n\n const bmMs = history?.map(h => h.bucketMidMs) ?? [];\n\n const mkExpand = (\n title: string, metric: DoraMetricValue, description: string,\n lowerIsBetter: boolean, sparklineValues: number[],\n sparklineType: 'bar' | 'line', sparklineColor: string, prs?: PrDetail[],\n prListLabel?: string,\n ) => () => setExpanded({\n title, metric, description, lowerIsBetter,\n sparklineValues, sparklineType, sparklineColor,\n weekLabels: wkLabels, bucketMidMs: bmMs, prs, prListLabel,\n });\n\n return (\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12 }}>\n <MetricCard\n title=\"Deployment Frequency\"\n metric={metrics.deploymentFrequency}\n description=\"How often code is deployed to this branch\"\n sparklineData={deployData}\n sparklineType=\"bar\"\n sparklineColor=\"#FA6400\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Deployment Frequency', metrics.deploymentFrequency,\n 'How often code is deployed to this branch', false, deployData, 'bar', '#FA6400',\n metrics.deploymentFrequency.slowestPRs)}\n />\n <MetricCard\n title=\"Lead Time for Changes\"\n metric={metrics.leadTime}\n description=\"Average time from PR creation to merge\"\n lowerIsBetter\n sparklineData={leadData}\n sparklineType=\"line\"\n sparklineColor=\"#818cf8\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Lead Time for Changes', metrics.leadTime,\n 'Average time from PR creation to merge', true, leadData, 'line', '#818cf8', metrics.leadTime.slowestPRs)}\n />\n {metrics.changeFailureRate !== null ? (\n <MetricCard\n title=\"Change Failure Rate\"\n metric={metrics.changeFailureRate}\n description=\"% of all merged PRs that were hotfixes\"\n lowerIsBetter\n sparklineData={cfrData}\n sparklineType=\"line\"\n sparklineColor=\"#f87171\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Change Failure Rate', metrics.changeFailureRate,\n '% of all merged PRs that were hotfixes', true, cfrData, 'line', '#f87171')}\n />\n ) : (\n <NaCard title=\"Change Failure Rate\" description=\"Only tracked on production branches\" />\n )}\n {metrics.mttr !== null ? (\n <MetricCard\n title=\"Mean Time to Restore\"\n metric={metrics.mttr}\n description=\"Avg time from hotfix PR open to merge\"\n lowerIsBetter\n sparklineData={mttrData}\n sparklineType=\"line\"\n sparklineColor=\"#fbbf24\"\n weekLabels={wkLabels}\n onExpand={mkExpand('Mean Time to Restore', metrics.mttr,\n 'Avg time from hotfix PR open to merge', true, mttrData, 'line', '#fbbf24', metrics.mttr.slowestPRs)}\n />\n ) : (\n <NaCard title=\"Mean Time to Restore\" description=\"Only tracked on production branches\" />\n )}\n {metrics.numberOfHotfixes !== null ? (\n <MetricCard\n title=\"Hotfixes to Production\"\n metric={metrics.numberOfHotfixes}\n description={`PRs labeled '${selectedEnv?.label ?? 'hotfix'}' merged to production`}\n lowerIsBetter\n expandLabel={metrics.numberOfHotfixes.value > 0 ? `View ${metrics.numberOfHotfixes.value} PR${metrics.numberOfHotfixes.value !== 1 ? 's' : ''} →` : undefined}\n onExpand={mkExpand(\n 'Hotfixes to Production',\n metrics.numberOfHotfixes,\n `PRs labeled '${selectedEnv?.label ?? 'hotfix'}' merged to production`,\n true,\n [],\n 'bar',\n '#f87171',\n metrics.numberOfHotfixes.slowestPRs,\n 'All hotfixes',\n )}\n />\n ) : (\n <NaCard title=\"Hotfixes to Production\" description=\"Only tracked on production branches\" />\n )}\n </div>\n );\n })()}\n\n </div>\n </InfoCard>\n );\n}\n"],"names":["max"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"badge.esm.js","sources":["../../../src/components/ui/badge.tsx"],"sourcesContent":["import type { DoraRating } from '../../api/types';\n\nconst RATING_STYLES: Record<DoraRating, { background: string; color: string; border: string }> = {\n elite: { background: '#14532d', color: '#86efac', border: '#166534' },\n high: { background: '#1e3a5f', color: '#93c5fd', border: '#1d4ed8' },\n medium:{ background: '#451a03', color: '#fdba74', border: '#92400e' },\n low: { background: '#450a0a', color: '#fca5a5', border: '#991b1b' },\n};\n\nexport function RatingBadge({ rating }: { rating: DoraRating }) {\n const s = RATING_STYLES[rating];\n return (\n <span\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n padding: '2px 8px',\n borderRadius: 9999,\n background: s.background,\n color: s.color,\n border: `1px solid ${s.border}`,\n fontSize: 11,\n fontWeight: 600,\n letterSpacing: '0.06em',\n textTransform: 'uppercase',\n }}\n >\n {rating}\n </span>\n );\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"badge.esm.js","sources":["../../../src/components/ui/badge.tsx"],"sourcesContent":["import React from 'react';\nimport type { DoraRating } from '../../api/types';\n\nconst RATING_STYLES: Record<DoraRating, { background: string; color: string; border: string }> = {\n elite: { background: '#14532d', color: '#86efac', border: '#166534' },\n high: { background: '#1e3a5f', color: '#93c5fd', border: '#1d4ed8' },\n medium:{ background: '#451a03', color: '#fdba74', border: '#92400e' },\n low: { background: '#450a0a', color: '#fca5a5', border: '#991b1b' },\n};\n\nexport function RatingBadge({ rating }: { rating: DoraRating }) {\n const s = RATING_STYLES[rating];\n return (\n <span\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n padding: '2px 8px',\n borderRadius: 9999,\n background: s.background,\n color: s.color,\n border: `1px solid ${s.border}`,\n fontSize: 11,\n fontWeight: 600,\n letterSpacing: '0.06em',\n textTransform: 'uppercase',\n }}\n >\n {rating}\n </span>\n );\n}\n"],"names":[],"mappings":";;AAGA,MAAM,aAAA,GAA2F;AAAA,EAC/F,OAAO,EAAE,UAAA,EAAY,WAAW,KAAA,EAAO,SAAA,EAAW,QAAQ,SAAA,EAAU;AAAA,EACpE,MAAO,EAAE,UAAA,EAAY,WAAW,KAAA,EAAO,SAAA,EAAW,QAAQ,SAAA,EAAU;AAAA,EACpE,QAAO,EAAE,UAAA,EAAY,WAAW,KAAA,EAAO,SAAA,EAAW,QAAQ,SAAA,EAAU;AAAA,EACpE,KAAO,EAAE,UAAA,EAAY,WAAW,KAAA,EAAO,SAAA,EAAW,QAAQ,SAAA;AAC5D,CAAA;AAEO,SAAS,WAAA,CAAY,EAAE,MAAA,EAAO,EAA2B;AAC9D,EAAA,MAAM,CAAA,GAAI,cAAc,MAAM,CAAA;AAC9B,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO;AAAA,QACL,OAAA,EAAS,aAAA;AAAA,QACT,UAAA,EAAY,QAAA;AAAA,QACZ,OAAA,EAAS,SAAA;AAAA,QACT,YAAA,EAAc,IAAA;AAAA,QACd,YAAY,CAAA,CAAE,UAAA;AAAA,QACd,OAAO,CAAA,CAAE,KAAA;AAAA,QACT,MAAA,EAAQ,CAAA,UAAA,EAAa,CAAA,CAAE,MAAM,CAAA,CAAA;AAAA,QAC7B,QAAA,EAAU,EAAA;AAAA,QACV,UAAA,EAAY,GAAA;AAAA,QACZ,aAAA,EAAe,QAAA;AAAA,QACf,aAAA,EAAe;AAAA;AACjB,KAAA;AAAA,IAEC;AAAA,GACH;AAEJ;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entityContent.esm.js","sources":["../../src/extensions/entityContent.tsx"],"sourcesContent":["import { EntityContentBlueprint } from '@backstage/plugin-catalog-react/alpha';\n\nexport const doraMetricsEntityContentExtension = EntityContentBlueprint.make({\n params: {\n path: 'dora-metrics',\n title: 'DORA Metrics',\n filter: entity =>\n entity.spec?.type === 'service' ||\n Boolean(entity.metadata.annotations?.['github.com/project-slug']),\n loader: () =>\n import('../components/DoraMetricsContent').then(m => (\n <m.DoraMetricsContent />\n )),\n },\n});\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"entityContent.esm.js","sources":["../../src/extensions/entityContent.tsx"],"sourcesContent":["import React from 'react';\nimport { EntityContentBlueprint } from '@backstage/plugin-catalog-react/alpha';\n\nexport const doraMetricsEntityContentExtension = EntityContentBlueprint.make({\n params: {\n path: 'dora-metrics',\n title: 'DORA Metrics',\n filter: entity =>\n entity.spec?.type === 'service' ||\n Boolean(entity.metadata.annotations?.['github.com/project-slug']),\n loader: () =>\n import('../components/DoraMetricsContent').then(m => (\n <m.DoraMetricsContent />\n )),\n },\n});\n"],"names":[],"mappings":";;;AAGO,MAAM,iCAAA,GAAoC,uBAAuB,IAAA,CAAK;AAAA,EAC3E,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,cAAA;AAAA,IACN,KAAA,EAAO,cAAA;AAAA,IACP,MAAA,EAAQ,CAAA,MAAA,KACN,MAAA,CAAO,IAAA,EAAM,IAAA,KAAS,SAAA,IACtB,OAAA,CAAQ,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,yBAAyB,CAAC,CAAA;AAAA,IAClE,MAAA,EAAQ,MACN,OAAO,yCAAkC,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,qBAC9C,KAAA,CAAA,aAAA,CAAC,CAAA,CAAE,kBAAA,EAAF,IAAqB,CACvB;AAAA;AAEP,CAAC;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export { default as doraMetricsPlugin } from './alpha.js';
|
|
2
2
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
3
3
|
import { OAuthApi, ConfigApi } from '@backstage/core-plugin-api';
|
|
4
|
-
import
|
|
4
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
|
+
import '@backstage/catalog-model';
|
|
6
|
+
import 'react';
|
|
7
|
+
import '@backstage/filter-predicates';
|
|
5
8
|
import '@backstage/frontend-plugin-api';
|
|
6
9
|
|
|
7
10
|
type DoraRating = 'elite' | 'high' | 'medium' | 'low';
|
|
@@ -91,7 +94,7 @@ declare class MockDoraMetricsClient implements DoraMetricsApi {
|
|
|
91
94
|
getHistory(_projectSlug: string, env: DoraEnvironment, _days: number): Promise<DoraHistoryPoint[]>;
|
|
92
95
|
}
|
|
93
96
|
|
|
94
|
-
declare function DoraMetricsContent():
|
|
97
|
+
declare function DoraMetricsContent(): react_jsx_runtime.JSX.Element | null;
|
|
95
98
|
|
|
96
99
|
export { DoraMetricsClient, DoraMetricsContent, MockDoraMetricsClient, doraMetricsApiRef };
|
|
97
100
|
export type { DoraEnvironment, DoraMetricValue, DoraMetrics, DoraMetricsApi, DoraRating, DoraTargets, PrDetail };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c2l2c/backstage-plugin-dora-metrics",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "A Backstage frontend plugin that displays DORA metrics (Deployment Frequency, Lead Time, Change Failure Rate, MTTR) for catalog entities via the GitHub API.",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
@@ -54,17 +54,23 @@
|
|
|
54
54
|
"@backstage/config": "^1.3.2",
|
|
55
55
|
"@backstage/core-components": "^0.18.7",
|
|
56
56
|
"@backstage/core-plugin-api": "^1.12.3",
|
|
57
|
-
"@backstage/frontend-plugin-api": "^0.
|
|
57
|
+
"@backstage/frontend-plugin-api": "^0.15.1",
|
|
58
58
|
"@backstage/plugin-catalog-react": "^2.0.0",
|
|
59
|
+
"@material-ui/core": "^4.12.4",
|
|
59
60
|
"@radix-ui/react-select": "^2.2.6",
|
|
60
|
-
"lucide-react": "^
|
|
61
|
+
"lucide-react": "^1.7.0"
|
|
61
62
|
},
|
|
62
63
|
"devDependencies": {
|
|
63
|
-
"@backstage/cli": "^0.
|
|
64
|
+
"@backstage/cli": "^0.36.0",
|
|
65
|
+
"@backstage/cli-defaults": "^0.1.0",
|
|
66
|
+
"@types/react": "^18",
|
|
64
67
|
"jest": "^30",
|
|
65
68
|
"jest-environment-jsdom": "^30"
|
|
66
69
|
},
|
|
67
70
|
"peerDependencies": {
|
|
68
71
|
"react": "^17.0.0 || ^18.0.0"
|
|
72
|
+
},
|
|
73
|
+
"engines": {
|
|
74
|
+
"node": ">=20"
|
|
69
75
|
}
|
|
70
76
|
}
|