XspecT 0.5.1__py3-none-any.whl → 0.5.2__py3-none-any.whl
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.
Potentially problematic release.
This version of XspecT might be problematic. Click here for more details.
- xspect/classify.py +51 -38
- xspect/definitions.py +50 -10
- xspect/download_models.py +10 -2
- xspect/file_io.py +115 -48
- xspect/filter_sequences.py +36 -66
- xspect/main.py +41 -10
- xspect/mlst_feature/mlst_helper.py +3 -0
- xspect/mlst_feature/pub_mlst_handler.py +43 -1
- xspect/model_management.py +84 -14
- xspect/models/probabilistic_filter_mlst_model.py +75 -37
- xspect/models/probabilistic_filter_model.py +194 -12
- xspect/models/probabilistic_filter_svm_model.py +99 -6
- xspect/models/probabilistic_single_filter_model.py +66 -5
- xspect/models/result.py +77 -10
- xspect/ncbi.py +45 -10
- xspect/train.py +2 -1
- xspect/web.py +68 -12
- xspect/xspect-web/dist/assets/index-Ceo58xui.css +1 -0
- xspect/xspect-web/dist/assets/{index-CMG4V7fZ.js → index-Dt_UlbgE.js} +82 -77
- xspect/xspect-web/dist/index.html +2 -2
- xspect/xspect-web/src/App.tsx +4 -2
- xspect/xspect-web/src/api.tsx +23 -1
- xspect/xspect-web/src/components/filter-form.tsx +16 -3
- xspect/xspect-web/src/components/filtering-result.tsx +65 -0
- xspect/xspect-web/src/components/result.tsx +2 -2
- xspect/xspect-web/src/types.tsx +5 -0
- {xspect-0.5.1.dist-info → xspect-0.5.2.dist-info}/METADATA +1 -1
- {xspect-0.5.1.dist-info → xspect-0.5.2.dist-info}/RECORD +32 -31
- {xspect-0.5.1.dist-info → xspect-0.5.2.dist-info}/WHEEL +1 -1
- xspect/xspect-web/dist/assets/index-jIKg1HIy.css +0 -1
- {xspect-0.5.1.dist-info → xspect-0.5.2.dist-info}/entry_points.txt +0 -0
- {xspect-0.5.1.dist-info → xspect-0.5.2.dist-info}/licenses/LICENSE +0 -0
- {xspect-0.5.1.dist-info → xspect-0.5.2.dist-info}/top_level.txt +0 -0
xspect/models/result.py
CHANGED
|
@@ -14,9 +14,22 @@ class ModelResult:
|
|
|
14
14
|
hits: dict[str, dict[str, int]],
|
|
15
15
|
num_kmers: dict[str, int],
|
|
16
16
|
sparse_sampling_step: int = 1,
|
|
17
|
-
prediction: str = None,
|
|
18
|
-
input_source: str = None,
|
|
17
|
+
prediction: str | None = None,
|
|
18
|
+
input_source: str | None = None,
|
|
19
19
|
):
|
|
20
|
+
"""
|
|
21
|
+
Initialize the ModelResult object.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
model_slug (str): The slug of the model.
|
|
25
|
+
hits (dict[str, dict[str, int]]): A dictionary where keys are subsequence names
|
|
26
|
+
and values are dictionaries with labels as keys and hit counts as values.
|
|
27
|
+
num_kmers (dict[str, int]): A dictionary where keys are subsequence names
|
|
28
|
+
and values are the total number of k-mers for that subsequence.
|
|
29
|
+
sparse_sampling_step (int): The step size for sparse sampling, default is 1.
|
|
30
|
+
prediction (str | None): The prediction made by the model, default is None.
|
|
31
|
+
input_source (str | None): The source of the input data, default is None.
|
|
32
|
+
"""
|
|
20
33
|
if "total" in hits:
|
|
21
34
|
raise ValueError(
|
|
22
35
|
"'total' is a reserved key and cannot be used as a subsequence"
|
|
@@ -29,7 +42,16 @@ class ModelResult:
|
|
|
29
42
|
self.input_source = input_source
|
|
30
43
|
|
|
31
44
|
def get_scores(self) -> dict:
|
|
32
|
-
"""
|
|
45
|
+
"""
|
|
46
|
+
Return the scores of the model.
|
|
47
|
+
|
|
48
|
+
The scores are calculated as the number of hits divided by the total number of k-mers
|
|
49
|
+
for each subsequence and label. The scores are rounded to two decimal places.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
dict: A dictionary where keys are subsequence names and values are dictionaries
|
|
53
|
+
with labels as keys and scores as values. Also includes a 'total' key for overall scores.
|
|
54
|
+
"""
|
|
33
55
|
scores = {
|
|
34
56
|
subsequence: {
|
|
35
57
|
label: round(hits / self.num_kmers[subsequence], 2)
|
|
@@ -50,20 +72,37 @@ class ModelResult:
|
|
|
50
72
|
return scores
|
|
51
73
|
|
|
52
74
|
def get_total_hits(self) -> dict[str, int]:
|
|
53
|
-
"""
|
|
75
|
+
"""
|
|
76
|
+
Return the total hits of the model.
|
|
77
|
+
|
|
78
|
+
The total hits are calculated by summing the hits for each label across all subsequences.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
dict: A dictionary where keys are labels and values are the total number of hits for that label.
|
|
82
|
+
"""
|
|
54
83
|
total_hits = {label: 0 for label in list(self.hits.values())[0]}
|
|
55
|
-
for _,
|
|
56
|
-
for label, hits in
|
|
84
|
+
for _, subsequence_hits in self.hits.items():
|
|
85
|
+
for label, hits in subsequence_hits.items():
|
|
57
86
|
total_hits[label] += hits
|
|
58
87
|
return total_hits
|
|
59
88
|
|
|
60
89
|
def get_filter_mask(self, label: str, filter_threshold: float) -> dict[str, bool]:
|
|
61
|
-
"""
|
|
90
|
+
"""
|
|
91
|
+
Return a mask for filtered subsequences.
|
|
62
92
|
|
|
63
93
|
The mask is a dictionary with subsequence names as keys and boolean values
|
|
64
94
|
indicating whether the subsequence is above the filter threshold for the given label.
|
|
65
95
|
A value of -1 for filter_threshold indicates that the subsequence with the maximum score
|
|
66
96
|
for the given label should be returned.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
label (str): The label for which to filter the subsequences.
|
|
100
|
+
filter_threshold (float): The threshold for filtering subsequences. Must be between 0 and 1,
|
|
101
|
+
or -1 to return the subsequence with the maximum score for the label.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
dict[str, bool]: A dictionary where keys are subsequence names and values are booleans
|
|
105
|
+
indicating whether the subsequence meets the filter criteria for the given label.
|
|
67
106
|
"""
|
|
68
107
|
if filter_threshold < 0 and not filter_threshold == -1 or filter_threshold > 1:
|
|
69
108
|
raise ValueError("The filter threshold must be between 0 and 1.")
|
|
@@ -84,7 +123,19 @@ class ModelResult:
|
|
|
84
123
|
def get_filtered_subsequence_labels(
|
|
85
124
|
self, label: str, filter_threshold: float = 0.7
|
|
86
125
|
) -> list[str]:
|
|
87
|
-
"""
|
|
126
|
+
"""
|
|
127
|
+
Return the labels of filtered subsequences.
|
|
128
|
+
|
|
129
|
+
This method filters subsequences based on the scores for a given label and a filter threshold.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
label (str): The label for which to filter the subsequences.
|
|
133
|
+
filter_threshold (float): The threshold for filtering subsequences. Must be between 0 and 1,
|
|
134
|
+
or -1 to return the subsequence with the maximum score for the label.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
list[str]: A list of subsequence names that meet the filter criteria for the given label.
|
|
138
|
+
"""
|
|
88
139
|
return [
|
|
89
140
|
subsequence
|
|
90
141
|
for subsequence, mask in self.get_filter_mask(
|
|
@@ -94,7 +145,15 @@ class ModelResult:
|
|
|
94
145
|
]
|
|
95
146
|
|
|
96
147
|
def to_dict(self) -> dict:
|
|
97
|
-
"""
|
|
148
|
+
"""
|
|
149
|
+
Return the result as a dictionary.
|
|
150
|
+
|
|
151
|
+
This method converts the ModelResult object into a dictionary format suitable for serialization.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
dict: A dictionary representation of the ModelResult object, including model slug,
|
|
155
|
+
sparse sampling step, hits, scores, number of k-mers, input source, and prediction if available.
|
|
156
|
+
"""
|
|
98
157
|
res = {
|
|
99
158
|
"model_slug": self.model_slug,
|
|
100
159
|
"sparse_sampling_step": self.sparse_sampling_step,
|
|
@@ -110,6 +169,14 @@ class ModelResult:
|
|
|
110
169
|
return res
|
|
111
170
|
|
|
112
171
|
def save(self, path: Path) -> None:
|
|
113
|
-
"""
|
|
172
|
+
"""
|
|
173
|
+
Save the result as a JSON file.
|
|
174
|
+
|
|
175
|
+
This method serializes the ModelResult object to a JSON file at the specified path.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
path (Path): The path where the JSON file will be saved.
|
|
179
|
+
"""
|
|
180
|
+
path.parent.mkdir(exist_ok=True, parents=True)
|
|
114
181
|
with open(path, "w", encoding="utf-8") as f:
|
|
115
182
|
f.write(dumps(self.to_dict(), indent=4))
|
xspect/ncbi.py
CHANGED
|
@@ -27,26 +27,35 @@ class AssemblySource(Enum):
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
class NCBIHandler:
|
|
30
|
-
"""
|
|
30
|
+
"""
|
|
31
|
+
This class uses the NCBI Datasets API to get data about taxa and their assemblies.
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
It provides methods to get taxon IDs, species, names, accessions, and download assemblies.
|
|
34
|
+
It also enforces rate limiting to comply with NCBI's API usage policies.
|
|
34
35
|
"""
|
|
35
36
|
|
|
36
37
|
def __init__(
|
|
37
38
|
self,
|
|
38
39
|
api_key: str | None = None,
|
|
39
40
|
):
|
|
40
|
-
"""
|
|
41
|
+
"""
|
|
42
|
+
Initialise the NCBI handler.
|
|
43
|
+
|
|
44
|
+
This method sets up the base URL for the NCBI Datasets API and initializes the rate limiting parameters.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
api_key (str | None): The NCBI API key. If None, the handler will use the public API without an API key.
|
|
48
|
+
"""
|
|
41
49
|
self.api_key = api_key
|
|
42
50
|
self.base_url = "https://api.ncbi.nlm.nih.gov/datasets/v2"
|
|
43
|
-
self.last_request_time = 0
|
|
51
|
+
self.last_request_time = 0.0
|
|
44
52
|
self.min_interval = (
|
|
45
53
|
1 / 10 if api_key else 1 / 5
|
|
46
54
|
) # NCBI allows 10 requests per second with if an API key, otherwise 5 requests per second
|
|
47
55
|
|
|
48
|
-
def _enforce_rate_limit(self):
|
|
49
|
-
"""
|
|
56
|
+
def _enforce_rate_limit(self) -> None:
|
|
57
|
+
"""
|
|
58
|
+
Enforce rate limiting for the NCBI Datasets API.
|
|
50
59
|
|
|
51
60
|
This method ensures that the requests to the API are limited to 5 requests per second
|
|
52
61
|
without an API key and 10 requests per second with an API key.
|
|
@@ -59,7 +68,11 @@ class NCBIHandler:
|
|
|
59
68
|
self.last_request_time = now
|
|
60
69
|
|
|
61
70
|
def _make_request(self, endpoint: str, timeout: int = 15) -> dict:
|
|
62
|
-
"""
|
|
71
|
+
"""
|
|
72
|
+
Make a request to the NCBI Datasets API.
|
|
73
|
+
|
|
74
|
+
This method constructs the full URL for the API endpoint, adds the necessary headers (including the API key if provided),
|
|
75
|
+
and makes a GET request to the API. It also enforces rate limiting before making the request.
|
|
63
76
|
|
|
64
77
|
Args:
|
|
65
78
|
endpoint (str): The endpoint to make the request to.
|
|
@@ -239,7 +252,20 @@ class NCBIHandler:
|
|
|
239
252
|
def get_highest_quality_accessions(
|
|
240
253
|
self, taxon_id: int, assembly_source: AssemblySource, count: int
|
|
241
254
|
) -> list[str]:
|
|
242
|
-
"""
|
|
255
|
+
"""
|
|
256
|
+
Get the highest quality accessions for a given taxon id (based on the assembly level).
|
|
257
|
+
|
|
258
|
+
This function iterates through the assembly levels in order of quality and retrieves accessions
|
|
259
|
+
until the specified count is reached. It ensures that the accessions are unique and sorted by quality.
|
|
260
|
+
|
|
261
|
+
Args:
|
|
262
|
+
taxon_id (int): The taxon id to get the accessions for.
|
|
263
|
+
assembly_source (AssemblySource): The assembly source to get the accessions for.
|
|
264
|
+
count (int): The number of accessions to get.
|
|
265
|
+
|
|
266
|
+
Returns:
|
|
267
|
+
list[str]: A list containing the highest quality accessions.
|
|
268
|
+
"""
|
|
243
269
|
accessions = []
|
|
244
270
|
for assembly_level in list(AssemblyLevel):
|
|
245
271
|
accessions += self.get_accessions(
|
|
@@ -253,7 +279,16 @@ class NCBIHandler:
|
|
|
253
279
|
return list(set(accessions))[:count] # Remove duplicates and limit to count
|
|
254
280
|
|
|
255
281
|
def download_assemblies(self, accessions: list[str], output_dir: Path) -> None:
|
|
256
|
-
"""
|
|
282
|
+
"""
|
|
283
|
+
Download assemblies for a list of accessions.
|
|
284
|
+
|
|
285
|
+
This function makes a request to the NCBI Datasets API to download the assemblies for the given accessions.
|
|
286
|
+
It saves the downloaded assemblies as a zip file in the specified output directory.
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
accessions (list[str]): A list of accessions to download.
|
|
290
|
+
output_dir (Path): The directory where the downloaded assemblies will be saved.
|
|
291
|
+
"""
|
|
257
292
|
endpoint = f"/genome/accession/{','.join(accessions)}/download?include_annotation_type=GENOME_FASTA"
|
|
258
293
|
|
|
259
294
|
self._enforce_rate_limit()
|
xspect/train.py
CHANGED
|
@@ -187,7 +187,8 @@ def train_from_ncbi(
|
|
|
187
187
|
author_email: str | None = None,
|
|
188
188
|
ncbi_api_key: str | None = None,
|
|
189
189
|
):
|
|
190
|
-
"""
|
|
190
|
+
"""
|
|
191
|
+
Train a model using NCBI assembly data for a given genus.
|
|
191
192
|
|
|
192
193
|
This function trains a probabilistic filter model using the assembly data from NCBI.
|
|
193
194
|
The training data is downloaded and processed, and the model is saved to the
|
xspect/web.py
CHANGED
|
@@ -5,7 +5,7 @@ import json
|
|
|
5
5
|
from shutil import copyfileobj
|
|
6
6
|
import importlib.resources as pkg_resources
|
|
7
7
|
from fastapi import APIRouter, FastAPI, HTTPException, UploadFile, BackgroundTasks
|
|
8
|
-
from fastapi.responses import RedirectResponse
|
|
8
|
+
from fastapi.responses import FileResponse, RedirectResponse
|
|
9
9
|
from xspect.definitions import get_xspect_runs_path, get_xspect_upload_path
|
|
10
10
|
from xspect.download_models import download_test_models
|
|
11
11
|
import xspect.model_management as mm
|
|
@@ -85,36 +85,92 @@ def classify_post(
|
|
|
85
85
|
)
|
|
86
86
|
|
|
87
87
|
|
|
88
|
-
router.post("/filter")
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
@router.post("/filter")
|
|
91
89
|
def filter_post(
|
|
92
90
|
filter_type: str,
|
|
93
|
-
|
|
91
|
+
genus: str,
|
|
94
92
|
input_file: str,
|
|
95
93
|
threshold: float,
|
|
96
|
-
|
|
94
|
+
background_tasks: BackgroundTasks,
|
|
95
|
+
filter_species: str | None = None,
|
|
96
|
+
step: int = 1,
|
|
97
97
|
):
|
|
98
98
|
"""Filter sequences."""
|
|
99
99
|
input_path = get_xspect_upload_path() / input_file
|
|
100
|
-
|
|
100
|
+
|
|
101
|
+
uuid = str(uuid4())
|
|
102
|
+
filter_output_path = get_xspect_runs_path() / f"filtered_{uuid}.fasta"
|
|
103
|
+
classification_output_path = get_xspect_runs_path() / f"result_{uuid}.json"
|
|
101
104
|
|
|
102
105
|
if not input_path.exists():
|
|
103
106
|
raise FileNotFoundError(f"File {input_path} does not exist.")
|
|
104
107
|
|
|
105
108
|
if filter_type == "Genus":
|
|
106
|
-
|
|
107
|
-
|
|
109
|
+
background_tasks.add_task(
|
|
110
|
+
filter_sequences.filter_genus,
|
|
111
|
+
genus,
|
|
112
|
+
input_path,
|
|
113
|
+
filter_output_path,
|
|
114
|
+
threshold,
|
|
115
|
+
classification_output_path,
|
|
116
|
+
step,
|
|
117
|
+
)
|
|
118
|
+
return {"message": "Genus filtering started.", "uuid": uuid}
|
|
108
119
|
|
|
109
120
|
elif filter_type == "Species":
|
|
110
|
-
|
|
111
|
-
|
|
121
|
+
if not filter_species:
|
|
122
|
+
raise ValueError("filter_species must be provided for species filtering.")
|
|
123
|
+
background_tasks.add_task(
|
|
124
|
+
filter_sequences.filter_species,
|
|
125
|
+
genus,
|
|
126
|
+
filter_species,
|
|
127
|
+
input_path,
|
|
128
|
+
filter_output_path,
|
|
129
|
+
threshold,
|
|
130
|
+
classification_output_path,
|
|
131
|
+
step,
|
|
112
132
|
)
|
|
113
|
-
return {"message": "Species
|
|
133
|
+
return {"message": "Species filtering started.", "uuid": uuid}
|
|
114
134
|
|
|
115
135
|
raise NotImplementedError(f"Filter type {filter_type} is not implemented.")
|
|
116
136
|
|
|
117
137
|
|
|
138
|
+
@router.get("/filtering-result")
|
|
139
|
+
def get_filtering_result(uuid: str):
|
|
140
|
+
"""Get filtering result."""
|
|
141
|
+
result_path = get_xspect_runs_path() / f"result_{uuid}.json"
|
|
142
|
+
filtered_path = get_xspect_runs_path() / f"filtered_{uuid}.fasta"
|
|
143
|
+
if not result_path.exists():
|
|
144
|
+
raise HTTPException(
|
|
145
|
+
status_code=404, detail="No result found for the specified uuid."
|
|
146
|
+
)
|
|
147
|
+
if not filtered_path.exists():
|
|
148
|
+
return {
|
|
149
|
+
"message": "Filtering completed, but no sequences met the criteria.",
|
|
150
|
+
"uuid": uuid,
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
"message": "Filtering completed successfully.",
|
|
154
|
+
"uuid": uuid,
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@router.get("/download-filtered")
|
|
159
|
+
def download_filtered(uuid: str):
|
|
160
|
+
"""Download filtered sequences."""
|
|
161
|
+
filtered_path = get_xspect_runs_path() / f"filtered_{uuid}.fasta"
|
|
162
|
+
if not filtered_path.exists():
|
|
163
|
+
raise HTTPException(
|
|
164
|
+
status_code=404,
|
|
165
|
+
detail="No filtered sequences found for the specified uuid.",
|
|
166
|
+
)
|
|
167
|
+
return FileResponse(
|
|
168
|
+
filtered_path,
|
|
169
|
+
media_type="application/octet-stream",
|
|
170
|
+
filename=filtered_path.name,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
|
|
118
174
|
@router.post("/train")
|
|
119
175
|
def train(genus: str, background_tasks: BackgroundTasks, svm_steps: int = 1):
|
|
120
176
|
"""Train NCBI model."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tailwindcss v4.1.4 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-space-x-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-500:oklch(63.7% .237 25.331);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-lg:32rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5/2.25);--text-6xl:3.75rem;--text-6xl--line-height:1;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-widest:.1em;--leading-snug:1.375;--radius-xs:.125rem;--animate-spin:spin 1s linear infinite;--aspect-video:16/9;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-border:var(--border)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab,red,red)){*{outline-color:color-mix(in oklab,var(--ring)50%,transparent)}}body{background-color:var(--background);color:var(--foreground)}}@layer components;@layer utilities{.\@container\/card-header{container:card-header/inline-size}.pointer-events-none{pointer-events:none}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing)*0)}.top-0{top:calc(var(--spacing)*0)}.top-1\/2{top:50%}.top-4{top:calc(var(--spacing)*4)}.top-\[1px\]{top:1px}.top-\[50\%\]{top:50%}.top-\[60\%\]{top:60%}.top-full{top:100%}.right-2{right:calc(var(--spacing)*2)}.right-4{right:calc(var(--spacing)*4)}.left-0{left:calc(var(--spacing)*0)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-\[50\%\]{left:50%}.isolate{isolation:isolate}.z-50{z-index:50}.z-\[1\]{z-index:1}.col-start-2{grid-column-start:2}.row-span-2{grid-row:span 2/span 2}.row-start-1{grid-row-start:1}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-2{margin:calc(var(--spacing)*2)}.-mx-1{margin-inline:calc(var(--spacing)*-1)}.mx-auto{margin-inline:auto}.my-0\.5{margin-block:calc(var(--spacing)*.5)}.my-1{margin-block:calc(var(--spacing)*1)}.my-3{margin-block:calc(var(--spacing)*3)}.my-4{margin-block:calc(var(--spacing)*4)}.mt-1\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-4{margin-top:calc(var(--spacing)*4)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-2{margin-left:calc(var(--spacing)*2)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.inline-flex{display:inline-flex}.table{display:table}.table-caption{display:table-caption}.table-cell{display:table-cell}.table-row{display:table-row}.aspect-square{aspect-ratio:1}.aspect-video{aspect-ratio:var(--aspect-video)}.size-2{width:calc(var(--spacing)*2);height:calc(var(--spacing)*2)}.size-3{width:calc(var(--spacing)*3);height:calc(var(--spacing)*3)}.size-3\.5{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-7{width:calc(var(--spacing)*7);height:calc(var(--spacing)*7)}.size-9{width:calc(var(--spacing)*9);height:calc(var(--spacing)*9)}.size-10{width:calc(var(--spacing)*10);height:calc(var(--spacing)*10)}.size-full{width:100%;height:100%}.h-1\.5{height:calc(var(--spacing)*1.5)}.h-2{height:calc(var(--spacing)*2)}.h-2\.5{height:calc(var(--spacing)*2.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-24{height:calc(var(--spacing)*24)}.h-\[1\.15rem\]{height:1.15rem}.h-\[calc\(100\%-1px\)\]{height:calc(100% - 1px)}.h-\[var\(--radix-navigation-menu-viewport-height\)\]{height:var(--radix-navigation-menu-viewport-height)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-full{height:100%}.h-px{height:1px}.max-h-\(--radix-dropdown-menu-content-available-height\){max-height:var(--radix-dropdown-menu-content-available-height)}.max-h-\(--radix-select-content-available-height\){max-height:var(--radix-select-content-available-height)}.max-h-\[300px\]{max-height:300px}.max-h-\[1000px\]{max-height:1000px}.min-h-screen{min-height:100vh}.w-0{width:calc(var(--spacing)*0)}.w-1{width:calc(var(--spacing)*1)}.w-1\/2{width:50%}.w-2{width:calc(var(--spacing)*2)}.w-2\.5{width:calc(var(--spacing)*2.5)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-8{width:calc(var(--spacing)*8)}.w-56{width:calc(var(--spacing)*56)}.w-72{width:calc(var(--spacing)*72)}.w-fit{width:fit-content}.w-full{width:100%}.w-max{width:max-content}.max-w-\[calc\(100\%-2rem\)\]{max-width:calc(100% - 2rem)}.max-w-max{max-width:max-content}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.caption-bottom{caption-side:bottom}.origin-\(--radix-dropdown-menu-content-transform-origin\){transform-origin:var(--radix-dropdown-menu-content-transform-origin)}.origin-\(--radix-popover-content-transform-origin\){transform-origin:var(--radix-popover-content-transform-origin)}.origin-\(--radix-select-content-transform-origin\){transform-origin:var(--radix-select-content-transform-origin)}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-\[-50\%\]{--tw-translate-x:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-0\.5{--tw-translate-y:calc(var(--spacing)*.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-y-\[-50\%\]{--tw-translate-y:-50%;translate:var(--tw-translate-x)var(--tw-translate-y)}.rotate-45{rotate:45deg}.rotate-\[-90deg\]{rotate:-90deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.touch-none{touch-action:none}.scroll-my-1{scroll-margin-block:calc(var(--spacing)*1)}.scroll-py-1{scroll-padding-block:calc(var(--spacing)*1)}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.auto-rows-min{grid-auto-rows:min-content}.grid-rows-\[auto_auto\]{grid-template-rows:auto auto}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-2\.5{gap:calc(var(--spacing)*2.5)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*.5)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*6)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*6)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*2)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-x-reverse)))}:where(.space-x-4>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing)*4)*var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-x-reverse)))}.self-start{align-self:flex-start}.justify-self-end{justify-self:flex-end}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\[2px\]{border-radius:2px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.rounded-sm{border-radius:calc(var(--radius) - 4px)}.rounded-xl{border-radius:calc(var(--radius) + 4px)}.rounded-xs{border-radius:var(--radius-xs)}.rounded-tl-sm{border-top-left-radius:calc(var(--radius) - 4px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-\[1\.5px\]{border-style:var(--tw-border-style);border-width:1.5px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\(--color-border\){border-color:var(--color-border)}.border-border\/50{border-color:var(--border)}@supports (color:color-mix(in lab,red,red)){.border-border\/50{border-color:color-mix(in oklab,var(--border)50%,transparent)}}.border-input{border-color:var(--input)}.border-primary{border-color:var(--primary)}.border-transparent{border-color:#0000}.bg-\(--color-bg\){background-color:var(--color-bg)}.bg-accent\/50{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.bg-accent\/50{background-color:color-mix(in oklab,var(--accent)50%,transparent)}}.bg-background{background-color:var(--background)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black)50%,transparent)}}.bg-border{background-color:var(--border)}.bg-card{background-color:var(--card)}.bg-destructive{background-color:var(--destructive)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-muted,.bg-muted\/50{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.bg-muted\/50{background-color:color-mix(in oklab,var(--muted)50%,transparent)}}.bg-popover{background-color:var(--popover)}.bg-primary,.bg-primary\/20{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.bg-primary\/20{background-color:color-mix(in oklab,var(--primary)20%,transparent)}}.bg-primary\/50{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.bg-primary\/50{background-color:color-mix(in oklab,var(--primary)50%,transparent)}}.bg-secondary{background-color:var(--secondary)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.fill-current{fill:currentColor}.object-cover{object-fit:cover}.p-0{padding:calc(var(--spacing)*0)}.p-1{padding:calc(var(--spacing)*1)}.p-1\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-2\.5{padding:calc(var(--spacing)*2.5)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-6{padding:calc(var(--spacing)*6)}.p-\[3px\]{padding:3px}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-6{padding-block:calc(var(--spacing)*6)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-3{padding-top:calc(var(--spacing)*3)}.pr-2{padding-right:calc(var(--spacing)*2)}.pr-2\.5{padding-right:calc(var(--spacing)*2.5)}.pr-8{padding-right:calc(var(--spacing)*8)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pb-4{padding-bottom:calc(var(--spacing)*4)}.pl-2{padding-left:calc(var(--spacing)*2)}.pl-8{padding-left:calc(var(--spacing)*8)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-4xl{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.leading-none{--tw-leading:1;line-height:1}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.whitespace-nowrap{white-space:nowrap}.text-card-foreground{color:var(--card-foreground)}.text-destructive{color:var(--destructive)}.text-foreground{color:var(--foreground)}.text-gray-700{color:var(--color-gray-700)}.text-muted-foreground{color:var(--muted-foreground)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-primary\/20{color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.text-primary\/20{color:color-mix(in oklab,var(--primary)20%,transparent)}}.text-red-500{color:var(--color-red-500)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-white{color:var(--color-white)}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-0{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-ring\/50{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab,red,red)){.ring-ring\/50{--tw-ring-color:color-mix(in oklab,var(--ring)50%,transparent)}}.ring-offset-background{--tw-ring-offset-color:var(--background)}.outline-hidden{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.outline-hidden{outline-offset:2px;outline:2px solid #0000}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[clip-path\]{transition-property:clip-path;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[color\,box-shadow\]{transition-property:color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[stroke-dashoffset\]{transition-property:stroke-dashoffset;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.ease-linear{--tw-ease:linear;transition-timing-function:linear}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.group-data-\[disabled\=true\]\:pointer-events-none:is(:where(.group)[data-disabled=true] *){pointer-events:none}.group-data-\[disabled\=true\]\:opacity-50:is(:where(.group)[data-disabled=true] *){opacity:.5}.group-data-\[state\=open\]\:rotate-180:is(:where(.group)[data-state=open] *){rotate:180deg}.group-data-\[viewport\=false\]\/navigation-menu\:top-full:is(:where(.group\/navigation-menu)[data-viewport=false] *){top:100%}.group-data-\[viewport\=false\]\/navigation-menu\:mt-1\.5:is(:where(.group\/navigation-menu)[data-viewport=false] *){margin-top:calc(var(--spacing)*1.5)}.group-data-\[viewport\=false\]\/navigation-menu\:overflow-hidden:is(:where(.group\/navigation-menu)[data-viewport=false] *){overflow:hidden}.group-data-\[viewport\=false\]\/navigation-menu\:rounded-md:is(:where(.group\/navigation-menu)[data-viewport=false] *){border-radius:calc(var(--radius) - 2px)}.group-data-\[viewport\=false\]\/navigation-menu\:border:is(:where(.group\/navigation-menu)[data-viewport=false] *){border-style:var(--tw-border-style);border-width:1px}.group-data-\[viewport\=false\]\/navigation-menu\:bg-popover:is(:where(.group\/navigation-menu)[data-viewport=false] *){background-color:var(--popover)}.group-data-\[viewport\=false\]\/navigation-menu\:text-popover-foreground:is(:where(.group\/navigation-menu)[data-viewport=false] *){color:var(--popover-foreground)}.group-data-\[viewport\=false\]\/navigation-menu\:shadow:is(:where(.group\/navigation-menu)[data-viewport=false] *){--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.group-data-\[viewport\=false\]\/navigation-menu\:duration-200:is(:where(.group\/navigation-menu)[data-viewport=false] *){--tw-duration:.2s;transition-duration:.2s}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\:opacity-50:is(:where(.peer):disabled~*){opacity:.5}.selection\:bg-primary ::selection{background-color:var(--primary)}.selection\:bg-primary::selection{background-color:var(--primary)}.selection\:text-primary-foreground ::selection{color:var(--primary-foreground)}.selection\:text-primary-foreground::selection{color:var(--primary-foreground)}.file\:inline-flex::file-selector-button{display:inline-flex}.file\:h-7::file-selector-button{height:calc(var(--spacing)*7)}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--foreground)}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media (hover:hover){.hover\:bg-accent:hover,.hover\:bg-accent\/30:hover{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-accent\/30:hover{background-color:color-mix(in oklab,var(--accent)30%,transparent)}}.hover\:bg-destructive\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab,var(--destructive)90%,transparent)}}.hover\:bg-muted\/50:hover{background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab,var(--muted)50%,transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab,var(--primary)90%,transparent)}}.hover\:bg-secondary\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab,var(--secondary)80%,transparent)}}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-gray-900:hover{color:var(--color-gray-900)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:ring-4:hover{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(4px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus\:bg-accent:focus{background-color:var(--accent)}.focus\:text-accent-foreground:focus{color:var(--accent-foreground)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-ring:focus{--tw-ring-color:var(--ring)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}.focus\:outline-hidden:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus\:outline-hidden:focus{outline-offset:2px;outline:2px solid #0000}}.focus-visible\:border-ring:focus-visible,.focus-visible\:border-ring\/50:focus-visible{border-color:var(--ring)}@supports (color:color-mix(in lab,red,red)){.focus-visible\:border-ring\/50:focus-visible{border-color:color-mix(in oklab,var(--ring)50%,transparent)}}.focus-visible\:ring-4:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(4px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-\[3px\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(3px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:color-mix(in oklab,var(--destructive)20%,transparent)}}.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab,red,red)){.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:color-mix(in oklab,var(--ring)50%,transparent)}}.focus-visible\:outline-hidden:focus-visible{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus-visible\:outline-hidden:focus-visible{outline-offset:2px;outline:2px solid #0000}}.focus-visible\:outline-1:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.focus-visible\:outline-ring:focus-visible{outline-color:var(--ring)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.has-data-\[slot\=card-action\]\:grid-cols-\[1fr_auto\]:has([data-slot=card-action]){grid-template-columns:1fr auto}.has-\[\>svg\]\:px-2\.5:has(>svg){padding-inline:calc(var(--spacing)*2.5)}.has-\[\>svg\]\:px-3:has(>svg){padding-inline:calc(var(--spacing)*3)}.has-\[\>svg\]\:px-4:has(>svg){padding-inline:calc(var(--spacing)*4)}.aria-invalid\:border-destructive[aria-invalid=true]{border-color:var(--destructive)}.aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:color-mix(in oklab,var(--destructive)20%,transparent)}}.data-\[active\=true\]\:bg-accent\/50[data-active=true]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.data-\[active\=true\]\:bg-accent\/50[data-active=true]{background-color:color-mix(in oklab,var(--accent)50%,transparent)}}.data-\[active\=true\]\:text-accent-foreground[data-active=true]{color:var(--accent-foreground)}@media (hover:hover){.data-\[active\=true\]\:hover\:bg-accent[data-active=true]:hover{background-color:var(--accent)}}.data-\[active\=true\]\:focus\:bg-accent[data-active=true]:focus{background-color:var(--accent)}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[disabled\=true\]\:pointer-events-none[data-disabled=true]{pointer-events:none}.data-\[disabled\=true\]\:opacity-50[data-disabled=true]{opacity:.5}.data-\[dragging\]\:border-primary[data-dragging]{border-color:var(--primary)}.data-\[error\=true\]\:text-destructive[data-error=true]{color:var(--destructive)}.data-\[inset\]\:pl-8[data-inset]{padding-left:calc(var(--spacing)*8)}.data-\[invalid\]\:border-destructive[data-invalid]{border-color:var(--destructive)}.data-\[invalid\]\:ring-destructive\/20[data-invalid]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.data-\[invalid\]\:ring-destructive\/20[data-invalid]{--tw-ring-color:color-mix(in oklab,var(--destructive)20%,transparent)}}.data-\[motion\=from-end\]\:slide-in-from-right-52[data-motion=from-end]{--tw-enter-translate-x:calc(52*var(--spacing))}.data-\[motion\=from-start\]\:slide-in-from-left-52[data-motion=from-start]{--tw-enter-translate-x:calc(52*var(--spacing)*-1)}.data-\[motion\=to-end\]\:slide-out-to-right-52[data-motion=to-end]{--tw-exit-translate-x:calc(52*var(--spacing))}.data-\[motion\=to-start\]\:slide-out-to-left-52[data-motion=to-start]{--tw-exit-translate-x:calc(52*var(--spacing)*-1)}.data-\[motion\^\=from-\]\:animate-in[data-motion^=from-]{animation:enter var(--tw-duration,.15s)var(--tw-ease,ease)}.data-\[motion\^\=from-\]\:fade-in[data-motion^=from-]{--tw-enter-opacity:0}.data-\[motion\^\=to-\]\:animate-out[data-motion^=to-]{animation:exit var(--tw-duration,.15s)var(--tw-ease,ease)}.data-\[motion\^\=to-\]\:fade-out[data-motion^=to-]{--tw-exit-opacity:0}.data-\[orientation\=horizontal\]\:h-1\.5[data-orientation=horizontal]{height:calc(var(--spacing)*1.5)}.data-\[orientation\=horizontal\]\:h-full[data-orientation=horizontal]{height:100%}.data-\[orientation\=horizontal\]\:h-px[data-orientation=horizontal]{height:1px}.data-\[orientation\=horizontal\]\:w-full[data-orientation=horizontal]{width:100%}.data-\[orientation\=vertical\]\:h-full[data-orientation=vertical]{height:100%}.data-\[orientation\=vertical\]\:min-h-44[data-orientation=vertical]{min-height:calc(var(--spacing)*44)}.data-\[orientation\=vertical\]\:w-1\.5[data-orientation=vertical]{width:calc(var(--spacing)*1.5)}.data-\[orientation\=vertical\]\:w-auto[data-orientation=vertical]{width:auto}.data-\[orientation\=vertical\]\:w-full[data-orientation=vertical]{width:100%}.data-\[orientation\=vertical\]\:w-px[data-orientation=vertical]{width:1px}.data-\[orientation\=vertical\]\:flex-col[data-orientation=vertical]{flex-direction:column}.data-\[placeholder\]\:text-muted-foreground[data-placeholder]{color:var(--muted-foreground)}.data-\[selected\=true\]\:bg-accent[data-selected=true]{background-color:var(--accent)}.data-\[selected\=true\]\:text-accent-foreground[data-selected=true]{color:var(--accent-foreground)}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:calc(2*var(--spacing)*-1)}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=left\]\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:calc(2*var(--spacing))}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x:calc(var(--spacing)*1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=right\]\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:calc(2*var(--spacing)*-1)}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y:calc(var(--spacing)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:calc(2*var(--spacing))}.data-\[size\=default\]\:h-9[data-size=default]{height:calc(var(--spacing)*9)}.data-\[size\=sm\]\:h-8[data-size=sm]{height:calc(var(--spacing)*8)}:is(.\*\*\:data-\[slot\=command-input-wrapper\]\:h-12 *)[data-slot=command-input-wrapper]{height:calc(var(--spacing)*12)}:is(.\*\*\:data-\[slot\=navigation-menu-link\]\:focus\:ring-0 *)[data-slot=navigation-menu-link]:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(0px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}:is(.\*\*\:data-\[slot\=navigation-menu-link\]\:focus\:outline-none *)[data-slot=navigation-menu-link]:focus{--tw-outline-style:none;outline-style:none}:is(.\*\:data-\[slot\=select-value\]\:line-clamp-1>*)[data-slot=select-value]{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}:is(.\*\:data-\[slot\=select-value\]\:flex>*)[data-slot=select-value]{display:flex}:is(.\*\:data-\[slot\=select-value\]\:items-center>*)[data-slot=select-value]{align-items:center}:is(.\*\:data-\[slot\=select-value\]\:gap-2>*)[data-slot=select-value]{gap:calc(var(--spacing)*2)}.data-\[state\=active\]\:animate-in[data-state=active]{animation:enter var(--tw-duration,.15s)var(--tw-ease,ease)}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:var(--background)}.data-\[state\=active\]\:shadow-sm[data-state=active]{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.data-\[state\=active\]\:fade-in-0[data-state=active]{--tw-enter-opacity:0}.data-\[state\=active\]\:slide-in-from-top-2[data-state=active]{--tw-enter-translate-y:calc(2*var(--spacing)*-1)}.data-\[state\=checked\]\:translate-x-\[calc\(100\%-2px\)\][data-state=checked]{--tw-translate-x: calc(100% - 2px) ;translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:var(--primary)}.data-\[state\=closed\]\:animate-accordion-up[data-state=closed]{animation:accordion-up var(--tw-duration,.2s)ease-out}.data-\[state\=closed\]\:animate-out[data-state=closed]{animation:exit var(--tw-duration,.15s)var(--tw-ease,ease)}.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity:0}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale:.95}.group-data-\[viewport\=false\]\/navigation-menu\:data-\[state\=closed\]\:animate-out:is(:where(.group\/navigation-menu)[data-viewport=false] *)[data-state=closed]{animation:exit var(--tw-duration,.15s)var(--tw-ease,ease)}.group-data-\[viewport\=false\]\/navigation-menu\:data-\[state\=closed\]\:fade-out-0:is(:where(.group\/navigation-menu)[data-viewport=false] *)[data-state=closed]{--tw-exit-opacity:0}.group-data-\[viewport\=false\]\/navigation-menu\:data-\[state\=closed\]\:zoom-out-95:is(:where(.group\/navigation-menu)[data-viewport=false] *)[data-state=closed]{--tw-exit-scale:.95}.data-\[state\=hidden\]\:animate-out[data-state=hidden]{animation:exit var(--tw-duration,.15s)var(--tw-ease,ease)}.data-\[state\=hidden\]\:fade-out[data-state=hidden]{--tw-exit-opacity:0}.data-\[state\=inactive\]\:animate-out[data-state=inactive]{animation:exit var(--tw-duration,.15s)var(--tw-ease,ease)}.data-\[state\=inactive\]\:fade-out-0[data-state=inactive]{--tw-exit-opacity:0}.data-\[state\=inactive\]\:slide-out-to-top-2[data-state=inactive]{--tw-exit-translate-y:calc(2*var(--spacing)*-1)}.data-\[state\=open\]\:animate-accordion-down[data-state=open]{animation:accordion-down var(--tw-duration,.2s)ease-out}.data-\[state\=open\]\:animate-in[data-state=open]{animation:enter var(--tw-duration,.15s)var(--tw-ease,ease)}.data-\[state\=open\]\:bg-accent[data-state=open],.data-\[state\=open\]\:bg-accent\/50[data-state=open]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.data-\[state\=open\]\:bg-accent\/50[data-state=open]{background-color:color-mix(in oklab,var(--accent)50%,transparent)}}.data-\[state\=open\]\:text-accent-foreground[data-state=open]{color:var(--accent-foreground)}.data-\[state\=open\]\:text-muted-foreground[data-state=open]{color:var(--muted-foreground)}.data-\[state\=open\]\:fade-in-0[data-state=open]{--tw-enter-opacity:0}.data-\[state\=open\]\:zoom-in-90[data-state=open]{--tw-enter-scale:.9}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale:.95}.group-data-\[viewport\=false\]\/navigation-menu\:data-\[state\=open\]\:animate-in:is(:where(.group\/navigation-menu)[data-viewport=false] *)[data-state=open]{animation:enter var(--tw-duration,.15s)var(--tw-ease,ease)}.group-data-\[viewport\=false\]\/navigation-menu\:data-\[state\=open\]\:fade-in-0:is(:where(.group\/navigation-menu)[data-viewport=false] *)[data-state=open]{--tw-enter-opacity:0}.group-data-\[viewport\=false\]\/navigation-menu\:data-\[state\=open\]\:zoom-in-95:is(:where(.group\/navigation-menu)[data-viewport=false] *)[data-state=open]{--tw-enter-scale:.95}@media (hover:hover){.data-\[state\=open\]\:hover\:bg-accent[data-state=open]:hover{background-color:var(--accent)}}.data-\[state\=open\]\:focus\:bg-accent[data-state=open]:focus{background-color:var(--accent)}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:var(--muted)}.data-\[state\=unchecked\]\:translate-x-0[data-state=unchecked]{--tw-translate-x:calc(var(--spacing)*0);translate:var(--tw-translate-x)var(--tw-translate-y)}.data-\[state\=unchecked\]\:bg-input[data-state=unchecked]{background-color:var(--input)}.data-\[state\=visible\]\:animate-in[data-state=visible]{animation:enter var(--tw-duration,.15s)var(--tw-ease,ease)}.data-\[state\=visible\]\:fade-in[data-state=visible]{--tw-enter-opacity:0}.data-\[variant\=destructive\]\:text-destructive[data-variant=destructive]{color:var(--destructive)}.data-\[variant\=destructive\]\:focus\:bg-destructive\/10[data-variant=destructive]:focus{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.data-\[variant\=destructive\]\:focus\:bg-destructive\/10[data-variant=destructive]:focus{background-color:color-mix(in oklab,var(--destructive)10%,transparent)}}.data-\[variant\=destructive\]\:focus\:text-destructive[data-variant=destructive]:focus{color:var(--destructive)}@media (min-width:40rem){.sm\:max-w-lg{max-width:var(--container-lg)}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}.sm\:text-left{text-align:left}}@media (min-width:48rem){.md\:absolute{position:absolute}.md\:w-\[var\(--radix-navigation-menu-viewport-width\)\]{width:var(--radix-navigation-menu-viewport-width)}.md\:w-auto{width:auto}.md\:text-6xl{font-size:var(--text-6xl);line-height:var(--tw-leading,var(--text-6xl--line-height))}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.dark\:border-input:is(.dark *){border-color:var(--input)}.dark\:bg-destructive\/60:is(.dark *){background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-destructive\/60:is(.dark *){background-color:color-mix(in oklab,var(--destructive)60%,transparent)}}.dark\:bg-input\/30:is(.dark *){background-color:var(--input)}@supports (color:color-mix(in lab,red,red)){.dark\:bg-input\/30:is(.dark *){background-color:color-mix(in oklab,var(--input)30%,transparent)}}.dark\:text-muted-foreground:is(.dark *){color:var(--muted-foreground)}@media (hover:hover){.dark\:hover\:bg-accent\/50:is(.dark *):hover{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-accent\/50:is(.dark *):hover{background-color:color-mix(in oklab,var(--accent)50%,transparent)}}.dark\:hover\:bg-input\/50:is(.dark *):hover{background-color:var(--input)}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-input\/50:is(.dark *):hover{background-color:color-mix(in oklab,var(--input)50%,transparent)}}}.dark\:focus-visible\:ring-destructive\/40:is(.dark *):focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.dark\:focus-visible\:ring-destructive\/40:is(.dark *):focus-visible{--tw-ring-color:color-mix(in oklab,var(--destructive)40%,transparent)}}.dark\:aria-invalid\:ring-destructive\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.dark\:aria-invalid\:ring-destructive\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:color-mix(in oklab,var(--destructive)40%,transparent)}}.dark\:data-\[state\=active\]\:border-input:is(.dark *)[data-state=active]{border-color:var(--input)}.dark\:data-\[state\=active\]\:bg-input\/30:is(.dark *)[data-state=active]{background-color:var(--input)}@supports (color:color-mix(in lab,red,red)){.dark\:data-\[state\=active\]\:bg-input\/30:is(.dark *)[data-state=active]{background-color:color-mix(in oklab,var(--input)30%,transparent)}}.dark\:data-\[state\=active\]\:text-foreground:is(.dark *)[data-state=active]{color:var(--foreground)}.dark\:data-\[state\=checked\]\:bg-primary-foreground:is(.dark *)[data-state=checked]{background-color:var(--primary-foreground)}.dark\:data-\[state\=unchecked\]\:bg-foreground:is(.dark *)[data-state=unchecked]{background-color:var(--foreground)}.dark\:data-\[state\=unchecked\]\:bg-input\/80:is(.dark *)[data-state=unchecked]{background-color:var(--input)}@supports (color:color-mix(in lab,red,red)){.dark\:data-\[state\=unchecked\]\:bg-input\/80:is(.dark *)[data-state=unchecked]{background-color:color-mix(in oklab,var(--input)80%,transparent)}}.dark\:data-\[variant\=destructive\]\:focus\:bg-destructive\/20:is(.dark *)[data-variant=destructive]:focus{background-color:var(--destructive)}@supports (color:color-mix(in lab,red,red)){.dark\:data-\[variant\=destructive\]\:focus\:bg-destructive\/20:is(.dark *)[data-variant=destructive]:focus{background-color:color-mix(in oklab,var(--destructive)20%,transparent)}}.\[\&_\.recharts-cartesian-axis-tick_text\]\:fill-muted-foreground .recharts-cartesian-axis-tick text{fill:var(--muted-foreground)}.\[\&_\.recharts-cartesian-grid_line\[stroke\=\'\#ccc\'\]\]\:stroke-border\/50 .recharts-cartesian-grid line[stroke="#ccc"]{stroke:var(--border)}@supports (color:color-mix(in lab,red,red)){.\[\&_\.recharts-cartesian-grid_line\[stroke\=\'\#ccc\'\]\]\:stroke-border\/50 .recharts-cartesian-grid line[stroke="#ccc"]{stroke:color-mix(in oklab,var(--border)50%,transparent)}}.\[\&_\.recharts-curve\.recharts-tooltip-cursor\]\:stroke-border .recharts-curve.recharts-tooltip-cursor{stroke:var(--border)}.\[\&_\.recharts-dot\[stroke\=\'\#fff\'\]\]\:stroke-transparent .recharts-dot[stroke="#fff"]{stroke:#0000}.\[\&_\.recharts-layer\]\:outline-hidden .recharts-layer{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.\[\&_\.recharts-layer\]\:outline-hidden .recharts-layer{outline-offset:2px;outline:2px solid #0000}}.\[\&_\.recharts-polar-grid_\[stroke\=\'\#ccc\'\]\]\:stroke-border .recharts-polar-grid [stroke="#ccc"]{stroke:var(--border)}.\[\&_\.recharts-radial-bar-background-sector\]\:fill-muted .recharts-radial-bar-background-sector,.\[\&_\.recharts-rectangle\.recharts-tooltip-cursor\]\:fill-muted .recharts-rectangle.recharts-tooltip-cursor{fill:var(--muted)}.\[\&_\.recharts-reference-line_\[stroke\=\'\#ccc\'\]\]\:stroke-border .recharts-reference-line [stroke="#ccc"]{stroke:var(--border)}.\[\&_\.recharts-sector\]\:outline-hidden .recharts-sector{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.\[\&_\.recharts-sector\]\:outline-hidden .recharts-sector{outline-offset:2px;outline:2px solid #0000}}.\[\&_\.recharts-sector\[stroke\=\'\#fff\'\]\]\:stroke-transparent .recharts-sector[stroke="#fff"]{stroke:#0000}.\[\&_\.recharts-surface\]\:outline-hidden .recharts-surface{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.\[\&_\.recharts-surface\]\:outline-hidden .recharts-surface{outline-offset:2px;outline:2px solid #0000}}.\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading]{padding-inline:calc(var(--spacing)*2)}.\[\&_\[cmdk-group-heading\]\]\:py-1\.5 [cmdk-group-heading]{padding-block:calc(var(--spacing)*1.5)}.\[\&_\[cmdk-group-heading\]\]\:text-xs [cmdk-group-heading]{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.\[\&_\[cmdk-group-heading\]\]\:font-medium [cmdk-group-heading]{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.\[\&_\[cmdk-group-heading\]\]\:text-muted-foreground [cmdk-group-heading]{color:var(--muted-foreground)}.\[\&_\[cmdk-group\]\]\:px-2 [cmdk-group]{padding-inline:calc(var(--spacing)*2)}.\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 [cmdk-group]:not([hidden])~[cmdk-group]{padding-top:calc(var(--spacing)*0)}.\[\&_\[cmdk-input-wrapper\]_svg\]\:h-5 [cmdk-input-wrapper] svg{height:calc(var(--spacing)*5)}.\[\&_\[cmdk-input-wrapper\]_svg\]\:w-5 [cmdk-input-wrapper] svg{width:calc(var(--spacing)*5)}.\[\&_\[cmdk-input\]\]\:h-12 [cmdk-input]{height:calc(var(--spacing)*12)}.\[\&_\[cmdk-item\]\]\:px-2 [cmdk-item]{padding-inline:calc(var(--spacing)*2)}.\[\&_\[cmdk-item\]\]\:py-3 [cmdk-item]{padding-block:calc(var(--spacing)*3)}.\[\&_\[cmdk-item\]_svg\]\:h-5 [cmdk-item] svg{height:calc(var(--spacing)*5)}.\[\&_\[cmdk-item\]_svg\]\:w-5 [cmdk-item] svg{width:calc(var(--spacing)*5)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\[\&_svg\:not\(\[class\*\=\'text-\'\]\)\]\:text-muted-foreground svg:not([class*=text-]){color:var(--muted-foreground)}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:calc(var(--spacing)*0)}.\[\.border-b\]\:pb-6.border-b{padding-bottom:calc(var(--spacing)*6)}.\[\.border-t\]\:pt-6.border-t{padding-top:calc(var(--spacing)*6)}:is(.\*\:\[span\]\:last\:flex>*):is(span):last-child{display:flex}:is(.\*\:\[span\]\:last\:items-center>*):is(span):last-child{align-items:center}:is(.\*\:\[span\]\:last\:gap-2>*):is(span):last-child{gap:calc(var(--spacing)*2)}:is(.data-\[variant\=destructive\]\:\*\:\[svg\]\:\!text-destructive[data-variant=destructive]>*):is(svg){color:var(--destructive)!important}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y:2px;translate:var(--tw-translate-x)var(--tw-translate-y)}.\[\&\>svg\]\:size-10>svg{width:calc(var(--spacing)*10);height:calc(var(--spacing)*10)}.\[\&\>svg\]\:h-2\.5>svg{height:calc(var(--spacing)*2.5)}.\[\&\>svg\]\:h-3>svg{height:calc(var(--spacing)*3)}.\[\&\>svg\]\:w-2\.5>svg{width:calc(var(--spacing)*2.5)}.\[\&\>svg\]\:w-3>svg{width:calc(var(--spacing)*3)}.\[\&\>svg\]\:text-muted-foreground>svg{color:var(--muted-foreground)}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.\[\&\[data-state\=open\]\>svg\]\:rotate-180[data-state=open]>svg{rotate:180deg}}:root{--radius:.3rem;--background:oklch(1 0 0);--foreground:oklch(.141 .005 285.823);--card:oklch(1 0 0);--card-foreground:oklch(.141 .005 285.823);--popover:oklch(1 0 0);--popover-foreground:oklch(.141 .005 285.823);--primary:oklch(.623 .214 259.815);--primary-foreground:oklch(.97 .014 254.604);--secondary:oklch(.967 .001 286.375);--secondary-foreground:oklch(.21 .006 285.885);--muted:oklch(.967 .001 286.375);--muted-foreground:oklch(.552 .016 285.938);--accent:oklch(.967 .001 286.375);--accent-foreground:oklch(.21 .006 285.885);--destructive:oklch(.577 .245 27.325);--border:oklch(.92 .004 286.32);--input:oklch(.92 .004 286.32);--ring:oklch(.623 .214 259.815);--chart-1:oklch(.646 .222 41.116);--chart-2:oklch(.6 .118 184.704);--chart-3:oklch(.398 .07 227.392);--chart-4:oklch(.828 .189 84.429);--chart-5:oklch(.769 .188 70.08);--sidebar:oklch(.985 0 0);--sidebar-foreground:oklch(.141 .005 285.823);--sidebar-primary:oklch(.623 .214 259.815);--sidebar-primary-foreground:oklch(.97 .014 254.604);--sidebar-accent:oklch(.967 .001 286.375);--sidebar-accent-foreground:oklch(.21 .006 285.885);--sidebar-border:oklch(.92 .004 286.32);--sidebar-ring:oklch(.623 .214 259.815)}.dark{--background:oklch(.141 .005 285.823);--foreground:oklch(.985 0 0);--card:oklch(.21 .006 285.885);--card-foreground:oklch(.985 0 0);--popover:oklch(.21 .006 285.885);--popover-foreground:oklch(.985 0 0);--primary:oklch(.546 .245 262.881);--primary-foreground:oklch(.379 .146 265.522);--secondary:oklch(.274 .006 286.033);--secondary-foreground:oklch(.985 0 0);--muted:oklch(.274 .006 286.033);--muted-foreground:oklch(.705 .015 286.067);--accent:oklch(.274 .006 286.033);--accent-foreground:oklch(.985 0 0);--destructive:oklch(.704 .191 22.216);--border:oklch(1 0 0/10%);--input:oklch(1 0 0/15%);--ring:oklch(.488 .243 264.376);--chart-1:oklch(.488 .243 264.376);--chart-2:oklch(.696 .17 162.48);--chart-3:oklch(.769 .188 70.08);--chart-4:oklch(.627 .265 303.9);--chart-5:oklch(.645 .246 16.439);--sidebar:oklch(.21 .006 285.885);--sidebar-foreground:oklch(.985 0 0);--sidebar-primary:oklch(.546 .245 262.881);--sidebar-primary-foreground:oklch(.379 .146 265.522);--sidebar-accent:oklch(.274 .006 286.033);--sidebar-accent-foreground:oklch(.985 0 0);--sidebar-border:oklch(1 0 0/10%);--sidebar-ring:oklch(.488 .243 264.376)}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0))}}@keyframes accordion-down{0%{height:0}to{height:var(--radix-accordion-content-height,var(--bits-accordion-content-height,auto))}}@keyframes accordion-up{0%{height:var(--radix-accordion-content-height,var(--bits-accordion-content-height,auto))}to{height:0}}
|