Spaces:
Running
on
T4
Running
on
T4
Upload folder using huggingface_hub
Browse files- .gitignore +3 -2
- README.md +211 -19
- prepare_feed_deploy.py +32 -80
- pyproject.toml +80 -2
- src/README.md +19 -0
- src/backend/__init__.py +0 -0
- src/backend/cache.py +26 -0
- src/backend/colpali.py +281 -0
- src/backend/stopwords.py +18 -0
- src/backend/testquery.py +3013 -0
- src/backend/vespa_app.py +496 -0
- src/frontend/__init__.py +0 -0
- src/frontend/app.py +644 -0
- src/frontend/layout.py +171 -0
- src/globals.css +293 -0
- src/icons.py +1 -0
- src/main.py +420 -0
- src/output.css +2893 -0
- src/requirements.txt +540 -0
- src/static/img/vespa-colpali.png +0 -0
- src/static/js/highlightjs-theme.js +23 -0
- src/tailwind.config.js +243 -0
- src/tailwindcss +3 -0
- uv.lock +5 -5
.gitignore
CHANGED
@@ -8,7 +8,8 @@ template/
|
|
8 |
*.json
|
9 |
output/
|
10 |
pdfs/
|
11 |
-
|
12 |
-
static/
|
|
|
13 |
embeddings/
|
14 |
hf_dataset/
|
|
|
8 |
*.json
|
9 |
output/
|
10 |
pdfs/
|
11 |
+
colpalidemo/
|
12 |
+
src/static/full_images/
|
13 |
+
src/static/sim_maps/
|
14 |
embeddings/
|
15 |
hf_dataset/
|
README.md
CHANGED
@@ -1,19 +1,211 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!-- Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -->
|
2 |
+
|
3 |
+
<picture>
|
4 |
+
<source media="(prefers-color-scheme: dark)" srcset="https://assets.vespa.ai/logos/Vespa-logo-green-RGB.svg">
|
5 |
+
<source media="(prefers-color-scheme: light)" srcset="https://assets.vespa.ai/logos/Vespa-logo-dark-RGB.svg">
|
6 |
+
<img alt="#Vespa" width="200" src="https://assets.vespa.ai/logos/Vespa-logo-dark-RGB.svg" style="margin-bottom: 25px;">
|
7 |
+
</picture>
|
8 |
+
|
9 |
+
# π Visual Retrieval ColPali π
|
10 |
+
|
11 |
+
This readme contains the code for a web app including a frontend that can be set up as a user facing interface.
|
12 |
+
|
13 |
+
## Why?
|
14 |
+
|
15 |
+
To enable _you_ to showcase the power of ColPali and Vespa to your users, and to provide a starting point for your own projects.
|
16 |
+
|
17 |
+
> "But I only know Python, how can I create a web app that's not Gradio or Streamlit?" π€
|
18 |
+
|
19 |
+
No worries! This project uses [FastHTML](https://fastht.ml/) to create a beautiful web app - and it's all Python! π
|
20 |
+
|
21 |
+
Also, π
|
22 |
+
|
23 |
+
<a href="https://imgflip.com/i/98mhch"><img src="https://i.imgflip.com/98mhch.jpg" title="made at imgflip.com" alt="Funny meme about json output in demo"/></a>
|
24 |
+
|
25 |
+
As a prerequisite, you should run [this notebook](https://pyvespa.readthedocs.io/en/latest/examples/visual_pdf_rag_with_vespa_colpali_cloud.ipynb) to prepare the data and deploy the Vespa application.
|
26 |
+
|
27 |
+
## Setting up your .env variables
|
28 |
+
|
29 |
+
The following variables are required in your `.env` file for the application to be able to connect to the Vespa application and the Gemini API:
|
30 |
+
|
31 |
+
You can rename the `.env.example` file to `.env` and fill in the required values.
|
32 |
+
The other variables are optional, if you want to use mTLS authentication against the Vespa application.
|
33 |
+
|
34 |
+
```bash
|
35 |
+
VESPA_APP_TOKEN_URL=https://abcde.z.vespa-app.cloud
|
36 |
+
VESPA_CLOUD_SECRET_TOKEN=vespa_cloud_xxxxxxxx
|
37 |
+
GEMINI_API_KEY=asdf
|
38 |
+
```
|
39 |
+
|
40 |
+
If you want to deploy the application to Huggingface, you also need to set a `HF_TOKEN` variable, with write permissions.
|
41 |
+
This is personal, and must be created at [huggingface](https://huggingface.co/settings/tokens).
|
42 |
+
|
43 |
+
```bash
|
44 |
+
HF_TOKEN=hf_xxxxxxxxxx
|
45 |
+
```
|
46 |
+
|
47 |
+
## Setting up python environment
|
48 |
+
|
49 |
+
This application should work on Python 3.8 and above.
|
50 |
+
|
51 |
+
You can install the dependencies with `pip`, but we recommend using `uv`.
|
52 |
+
Skip to [Installing dependencies using `uv`](#installing-dependencies-using-uv) if you want to use `uv`.
|
53 |
+
|
54 |
+
### Installing dependencies using `pip`
|
55 |
+
|
56 |
+
You can install the dependencies with `pip`:
|
57 |
+
|
58 |
+
```bash
|
59 |
+
pip install -r src/requirements.txt
|
60 |
+
```
|
61 |
+
|
62 |
+
### Installing dependencies using `uv`
|
63 |
+
|
64 |
+
We recommend installing the amazing `uv` to manage your python environment:
|
65 |
+
See also [installation - uv docs](https://docs.astral.sh/uv/getting-started/installation/) for other installation options.
|
66 |
+
|
67 |
+
```bash
|
68 |
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
69 |
+
```
|
70 |
+
|
71 |
+
Then, create a virtual environment:
|
72 |
+
|
73 |
+
```bash
|
74 |
+
uv venv
|
75 |
+
```
|
76 |
+
|
77 |
+
Activate the virtual environment:
|
78 |
+
|
79 |
+
```bash
|
80 |
+
source .venv/bin/activate
|
81 |
+
```
|
82 |
+
|
83 |
+
Sync your virtual environment with the dependencies:
|
84 |
+
|
85 |
+
```bash
|
86 |
+
uv sync --extra dev
|
87 |
+
```
|
88 |
+
|
89 |
+
## Running the application locally
|
90 |
+
|
91 |
+
To run the application locally, you can change into the `src` directory and run:
|
92 |
+
|
93 |
+
```bash
|
94 |
+
python main.py
|
95 |
+
```
|
96 |
+
|
97 |
+
This will start a local server, and you can access the application at `http://localhost:7860`.
|
98 |
+
|
99 |
+
## Deploy to huggingface π€ spaces
|
100 |
+
|
101 |
+
### Compiling dependencies
|
102 |
+
|
103 |
+
Before a deploy, make sure to run this to compile the `uv` lock file to `requirements.txt` if you have made changes to the dependencies:
|
104 |
+
|
105 |
+
```bash
|
106 |
+
uv pip compile pyproject.toml -o src/requirements.txt
|
107 |
+
```
|
108 |
+
|
109 |
+
This will make sure that the dependencies in your `pyproject.toml` are compiled to the `requirements.txt` file, which is used by the huggingface space.
|
110 |
+
|
111 |
+
### Deploying to huggingface
|
112 |
+
|
113 |
+
Note that you need to set `HF_TOKEN` environment variable first.
|
114 |
+
This is personal, and must be created at [huggingface](https://huggingface.co/settings/tokens).
|
115 |
+
Make sure the token has `write` access.
|
116 |
+
Be aware that this will not delete existing files, only modify or add,
|
117 |
+
see [huggingface-cli](https://huggingface.co/docs/huggingface_hub/en/guides/upload#upload-from-the-cli) for more
|
118 |
+
information.
|
119 |
+
|
120 |
+
#### Update your space configuration
|
121 |
+
|
122 |
+
The `src/README.md` file contains the configuration for the space.
|
123 |
+
Feel free to update this file to match your own configuration - name, description, etc.
|
124 |
+
|
125 |
+
Note that we can actually use the `gradio` SDK of spaces, to serve FastHTML apps as well, as long as we serve the app on port `7860`.
|
126 |
+
See [Custom python spaces](https://huggingface.co/docs/hub/en/spaces-sdks-python) for more information.
|
127 |
+
|
128 |
+
#### Upload the files
|
129 |
+
|
130 |
+
To deploy, run
|
131 |
+
|
132 |
+
(Replace `vespa-engine/colpali-vespa-visual-retrieval` with your own huggingface user/repo name, does not need to exist beforehand)
|
133 |
+
|
134 |
+
```bash
|
135 |
+
huggingface-cli upload vespa-engine/colpali-vespa-visual-retrieval src . --repo-type=space
|
136 |
+
```
|
137 |
+
|
138 |
+
Note that we upload only the `src` directory.
|
139 |
+
|
140 |
+
## Development
|
141 |
+
|
142 |
+
This section applies if you want to make changes to the web app.
|
143 |
+
|
144 |
+
### Adding dependencies
|
145 |
+
|
146 |
+
To add dependencies, you can add them to the `pyproject.toml` file and run:
|
147 |
+
|
148 |
+
```bash
|
149 |
+
uv compile
|
150 |
+
```
|
151 |
+
|
152 |
+
and then sync the dependencies:
|
153 |
+
|
154 |
+
```bash
|
155 |
+
uv sync --extra dev
|
156 |
+
```
|
157 |
+
|
158 |
+
### Making changes to CSS
|
159 |
+
|
160 |
+
To make changes to output.css apply, run
|
161 |
+
|
162 |
+
```bash
|
163 |
+
shad4fast watch # watches all files passed through the tailwind.config.js content section
|
164 |
+
|
165 |
+
shad4fast build # minifies the current output.css file to reduce bundle size in production.
|
166 |
+
```
|
167 |
+
|
168 |
+
### Instructions on creating and feeding the full dataset
|
169 |
+
|
170 |
+
This section is only relevant if you want to create and feed the full dataset to Vespa.
|
171 |
+
The notebook referenced in the beginning of this readme should be sufficient if you just want to spin up a scaled down version of the demo.
|
172 |
+
|
173 |
+
#### Prepare data and Vespa application
|
174 |
+
|
175 |
+
First, install `uv`:
|
176 |
+
|
177 |
+
```bash
|
178 |
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
179 |
+
```
|
180 |
+
|
181 |
+
Then, run:
|
182 |
+
|
183 |
+
```bash
|
184 |
+
uv sync --extra dev --extra feed
|
185 |
+
```
|
186 |
+
|
187 |
+
#### Converting to notebook
|
188 |
+
|
189 |
+
If you want to run the `prepare_feed_deploy.py` as a notebook, you can convert it using `jupytext`:
|
190 |
+
|
191 |
+
Convert the `prepare_feed_deploy.py` to notebook to:
|
192 |
+
|
193 |
+
```bash
|
194 |
+
jupytext --to notebook prepare_feed_deploy.py
|
195 |
+
```
|
196 |
+
|
197 |
+
And launch a Jupyter instance with:
|
198 |
+
|
199 |
+
```bash
|
200 |
+
uv run --with jupyter jupyter lab
|
201 |
+
```
|
202 |
+
|
203 |
+
## Credits
|
204 |
+
|
205 |
+
Huge thanks to the amazing projects that made it a joy to create this demo ππ
|
206 |
+
|
207 |
+
- Freeing us from python dependency hell - [uv](https://astral.sh/uv/)
|
208 |
+
- Allowing us to build **beautiful** full stack web apps in Python [FastHTML](https://fastht.ml/)
|
209 |
+
- Introducing the ColPali architecture - [ColPali](https://huggingface.co/vidore/colpali-v1.2)
|
210 |
+
- Adding `shadcn` components to FastHTML - [Shad4Fast](https://www.shad4fasthtml.com/)
|
211 |
+
|
prepare_feed_deploy.py
CHANGED
@@ -1,4 +1,3 @@
|
|
1 |
-
# %% [markdown]
|
2 |
# # Visual PDF Retrieval - demo application
|
3 |
#
|
4 |
# In this notebook, we will prepare the Vespa backend application for our visual retrieval demo.
|
@@ -23,11 +22,10 @@
|
|
23 |
# We have tried to make it easy for others to run this notebook, to create your own PDF Enterprise Search application using Vespa.
|
24 |
#
|
25 |
|
26 |
-
# %% [markdown]
|
27 |
# ## 0. Setup and Configuration
|
28 |
#
|
29 |
|
30 |
-
#
|
31 |
import os
|
32 |
import asyncio
|
33 |
import json
|
@@ -80,8 +78,8 @@ load_dotenv()
|
|
80 |
|
81 |
# Avoid warning from huggingface tokenizers
|
82 |
os.environ["TOKENIZERS_PARALLELISM"] = "false"
|
|
|
83 |
|
84 |
-
# %% [markdown]
|
85 |
# ### Create a free trial in Vespa Cloud
|
86 |
#
|
87 |
# Create a tenant from [here](https://vespa.ai/free-trial/).
|
@@ -89,49 +87,39 @@ os.environ["TOKENIZERS_PARALLELISM"] = "false"
|
|
89 |
# Take note of your tenant name.
|
90 |
#
|
91 |
|
92 |
-
# %%
|
93 |
VESPA_TENANT_NAME = "vespa-team"
|
94 |
|
95 |
-
# %% [markdown]
|
96 |
# Here, set your desired application name. (Will be created in later steps)
|
97 |
# Note that you can not have hyphen `-` or underscore `_` in the application name.
|
98 |
#
|
99 |
|
100 |
-
# %%
|
101 |
VESPA_APPLICATION_NAME = "colpalidemo"
|
102 |
VESPA_SCHEMA_NAME = "pdf_page"
|
103 |
|
104 |
-
# %% [markdown]
|
105 |
# Next, you need to create some tokens for feeding data, and querying the application.
|
106 |
# We recommend separate tokens for feeding and querying, (the former with write permission, and the latter with read permission).
|
107 |
# The tokens can be created from the [Vespa Cloud console](https://console.vespa-cloud.com/) in the 'Account' -> 'Tokens' section.
|
108 |
#
|
109 |
|
110 |
-
# %%
|
111 |
VESPA_TOKEN_ID_WRITE = "colpalidemo_write"
|
112 |
-
VESPA_TOKEN_ID_READ = "colpalidemo_read"
|
113 |
|
114 |
-
# %% [markdown]
|
115 |
# We also need to set the value of the write token to be able to feed data to the Vespa application.
|
116 |
#
|
117 |
|
118 |
-
# %%
|
119 |
VESPA_CLOUD_SECRET_TOKEN = os.getenv("VESPA_CLOUD_SECRET_TOKEN") or input(
|
120 |
"Enter Vespa cloud secret token: "
|
121 |
)
|
122 |
|
123 |
-
# %% [markdown]
|
124 |
# We will also use the Gemini API to create sample queries for our images.
|
125 |
# You can also use other VLM's to create these queries.
|
126 |
# Create a Gemini API key from [here](https://aistudio.google.com/app/apikey).
|
127 |
#
|
128 |
|
129 |
-
# %%
|
130 |
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") or input(
|
131 |
"Enter Google Generative AI API key: "
|
132 |
)
|
133 |
|
134 |
-
#
|
135 |
MODEL_NAME = "vidore/colpali-v1.2"
|
136 |
|
137 |
# Configure Google Generative AI
|
@@ -149,8 +137,8 @@ model = ColPali.from_pretrained(
|
|
149 |
).eval()
|
150 |
|
151 |
processor = ColPaliProcessor.from_pretrained(MODEL_NAME)
|
|
|
152 |
|
153 |
-
# %% [markdown]
|
154 |
# ## 1. Download PDFs
|
155 |
#
|
156 |
# We are going to use public reports from the Norwegian Government Pension Fund Global (also known as the Oil Fund).
|
@@ -163,12 +151,11 @@ processor = ColPaliProcessor.from_pretrained(MODEL_NAME)
|
|
163 |
# ![Sample2](./static/img/gfpg-sample-2.png)
|
164 |
#
|
165 |
|
166 |
-
# %% [markdown]
|
167 |
# As we can see, a lot of the information is in the form of tables, charts and numbers.
|
168 |
# These are not easily extractable using pdf-readers or OCR tools.
|
169 |
#
|
170 |
|
171 |
-
#
|
172 |
import requests
|
173 |
|
174 |
url = "https://www.nbim.no/en/publications/reports/"
|
@@ -194,14 +181,14 @@ for year_div in soup.find_all("div", id=lambda x: x and x.startswith("year-")):
|
|
194 |
links.append(full_url)
|
195 |
url_to_year[full_url] = year
|
196 |
links, url_to_year
|
|
|
197 |
|
198 |
-
# %%
|
199 |
# Limit the number of PDFs to download
|
200 |
NUM_PDFS = 2 # Set to None to download all PDFs
|
201 |
links = links[:NUM_PDFS] if NUM_PDFS else links
|
202 |
links
|
203 |
|
204 |
-
#
|
205 |
from nest_asyncio import apply
|
206 |
from typing import List
|
207 |
|
@@ -272,16 +259,15 @@ async def download_pdfs(links: List[str]) -> List[dict]:
|
|
272 |
os.makedirs("pdfs", exist_ok=True)
|
273 |
# Now run the download_pdfs function with the URL
|
274 |
pdfs = asyncio.run(download_pdfs(links))
|
|
|
275 |
|
276 |
-
# %%
|
277 |
pdfs
|
278 |
|
279 |
-
# %% [markdown]
|
280 |
# ## 2. Convert PDFs to Images
|
281 |
#
|
282 |
|
283 |
|
284 |
-
#
|
285 |
def get_pdf_images(pdf_path):
|
286 |
reader = PdfReader(pdf_path)
|
287 |
page_texts = []
|
@@ -313,11 +299,11 @@ for pdf in tqdm(pdfs):
|
|
313 |
"page_no": page_no,
|
314 |
}
|
315 |
)
|
|
|
316 |
|
317 |
-
# %%
|
318 |
len(pdf_pages)
|
319 |
|
320 |
-
#
|
321 |
from collections import Counter
|
322 |
|
323 |
# Print the length of the text fields - mean, max and min
|
@@ -327,8 +313,8 @@ print(f"Max text length: {np.max(text_lengths)}")
|
|
327 |
print(f"Min text length: {np.min(text_lengths)}")
|
328 |
print(f"Median text length: {np.median(text_lengths)}")
|
329 |
print(f"Number of text with length == 0: {Counter(text_lengths)[0]}")
|
|
|
330 |
|
331 |
-
# %% [markdown]
|
332 |
# ## 3. Generate Queries
|
333 |
#
|
334 |
# In this step, we want to generate queries for each page image.
|
@@ -342,7 +328,7 @@ print(f"Number of text with length == 0: {Counter(text_lengths)[0]}")
|
|
342 |
# We will use the Gemini API to generate these queries, with `gemini-1.5-flash-8b` as the model.
|
343 |
#
|
344 |
|
345 |
-
#
|
346 |
from pydantic import BaseModel
|
347 |
|
348 |
|
@@ -394,7 +380,7 @@ Only return JSON. Don't return any extra explanation text. """
|
|
394 |
|
395 |
prompt_text, pydantic_model = get_retrieval_prompt()
|
396 |
|
397 |
-
#
|
398 |
gemini_model = genai.GenerativeModel("gemini-1.5-flash-8b")
|
399 |
|
400 |
|
@@ -420,18 +406,17 @@ def generate_queries(image, prompt_text, pydantic_model):
|
|
420 |
return queries
|
421 |
|
422 |
|
423 |
-
#
|
|
|
424 |
for pdf in tqdm(pdf_pages):
|
425 |
image = pdf.get("image")
|
426 |
pdf["queries"] = generate_queries(image, prompt_text, pydantic_model)
|
427 |
|
428 |
-
# %%
|
429 |
pdf_pages[46]["image"]
|
430 |
|
431 |
-
# %%
|
432 |
pdf_pages[46]["queries"]
|
433 |
|
434 |
-
#
|
435 |
# Generate queries async - keeping for now as we probably need when applying to the full dataset
|
436 |
# import asyncio
|
437 |
# from tenacity import retry, stop_after_attempt, wait_exponential
|
@@ -482,7 +467,7 @@ pdf_pages[46]["queries"]
|
|
482 |
|
483 |
# pdf_pages = asyncio.run(enrich_pdfs())
|
484 |
|
485 |
-
#
|
486 |
# write title, url, page_no, text, queries, not image to JSON
|
487 |
with open("output/pdf_pages.json", "w") as f:
|
488 |
to_write = [{k: v for k, v in pdf.items() if k != "image"} for pdf in pdf_pages]
|
@@ -492,15 +477,14 @@ with open("output/pdf_pages.json", "w") as f:
|
|
492 |
# saved_pdf_pages = json.load(f)
|
493 |
# for pdf, saved_pdf in zip(pdf_pages, saved_pdf_pages):
|
494 |
# pdf.update(saved_pdf)
|
|
|
495 |
|
496 |
-
# %% [markdown]
|
497 |
# ## 4. Generate embeddings
|
498 |
#
|
499 |
# Now that we have the queries, we can use the ColPali model to generate embeddings for each page image.
|
500 |
#
|
501 |
|
502 |
|
503 |
-
# %%
|
504 |
def generate_embeddings(images, model, processor, batch_size=2) -> np.ndarray:
|
505 |
"""
|
506 |
Generate embeddings for a list of images.
|
@@ -539,22 +523,18 @@ def generate_embeddings(images, model, processor, batch_size=2) -> np.ndarray:
|
|
539 |
return all_embeddings
|
540 |
|
541 |
|
542 |
-
# %%
|
543 |
# Generate embeddings for all images
|
544 |
images = [pdf["image"] for pdf in pdf_pages]
|
545 |
embeddings = generate_embeddings(images, model, processor)
|
546 |
|
547 |
-
# %%
|
548 |
embeddings.shape
|
549 |
|
550 |
-
# %% [markdown]
|
551 |
# ## 5. Prepare Data on Vespa Format
|
552 |
#
|
553 |
# Now, that we have all the data we need, all that remains is to make sure it is in the right format for Vespa.
|
554 |
#
|
555 |
|
556 |
|
557 |
-
# %%
|
558 |
def float_to_binary_embedding(float_query_embedding: dict) -> dict:
|
559 |
"""Utility function to convert float query embeddings to binary query embeddings."""
|
560 |
binary_query_embeddings = {}
|
@@ -566,7 +546,6 @@ def float_to_binary_embedding(float_query_embedding: dict) -> dict:
|
|
566 |
return binary_query_embeddings
|
567 |
|
568 |
|
569 |
-
# %%
|
570 |
vespa_feed = []
|
571 |
for pdf, embedding in zip(pdf_pages, embeddings):
|
572 |
url = pdf["url"]
|
@@ -604,7 +583,7 @@ for pdf, embedding in zip(pdf_pages, embeddings):
|
|
604 |
}
|
605 |
vespa_feed.append(page)
|
606 |
|
607 |
-
#
|
608 |
# We will prepare the Vespa feed data, including the embeddings and the generated queries
|
609 |
|
610 |
|
@@ -618,20 +597,19 @@ with open("output/vespa_feed.json", "w") as f:
|
|
618 |
vespa_feed_to_save.append({"put": put_id, "fields": page["fields"]})
|
619 |
json.dump(vespa_feed_to_save, f)
|
620 |
|
621 |
-
#
|
622 |
# import json
|
623 |
|
624 |
# with open("output/vespa_feed.json", "r") as f:
|
625 |
# vespa_feed = json.load(f)
|
|
|
626 |
|
627 |
-
# %%
|
628 |
len(vespa_feed)
|
629 |
|
630 |
-
# %% [markdown]
|
631 |
# ## 5. Prepare Vespa Application
|
632 |
#
|
633 |
|
634 |
-
#
|
635 |
# Define the Vespa schema
|
636 |
colpali_schema = Schema(
|
637 |
name=VESPA_SCHEMA_NAME,
|
@@ -678,32 +656,15 @@ colpali_schema = Schema(
|
|
678 |
Field(
|
679 |
name="questions",
|
680 |
type="array<string>",
|
681 |
-
indexing=["summary", "
|
682 |
-
|
683 |
-
stemming="best",
|
684 |
),
|
685 |
Field(
|
686 |
name="queries",
|
687 |
type="array<string>",
|
688 |
-
indexing=["summary", "
|
689 |
-
|
690 |
-
stemming="best",
|
691 |
),
|
692 |
-
# Add synthetic fields for the questions and queries
|
693 |
-
# Field(
|
694 |
-
# name="questions_exact",
|
695 |
-
# type="array<string>",
|
696 |
-
# indexing=["input questions", "index", "attribute"],
|
697 |
-
# match=["word"],
|
698 |
-
# is_document_field=False,
|
699 |
-
# ),
|
700 |
-
# Field(
|
701 |
-
# name="queries_exact",
|
702 |
-
# type="array<string>",
|
703 |
-
# indexing=["input queries", "index"],
|
704 |
-
# match=["word"],
|
705 |
-
# is_document_field=False,
|
706 |
-
# ),
|
707 |
]
|
708 |
),
|
709 |
fieldsets=[
|
@@ -868,7 +829,7 @@ colpali_retrieval_profile = RankProfile(
|
|
868 |
colpali_schema.add_rank_profile(colpali_retrieval_profile)
|
869 |
colpali_schema.add_rank_profile(with_quantized_similarity(colpali_retrieval_profile))
|
870 |
|
871 |
-
#
|
872 |
from vespa.configuration.services import (
|
873 |
services,
|
874 |
container,
|
@@ -908,11 +869,6 @@ service_config = ServicesConfiguration(
|
|
908 |
id="token_write",
|
909 |
permissions="read,write",
|
910 |
),
|
911 |
-
client(
|
912 |
-
token(id=f"{VESPA_TOKEN_ID_READ}"),
|
913 |
-
id="token_read",
|
914 |
-
permissions="read",
|
915 |
-
),
|
916 |
),
|
917 |
config(
|
918 |
vt("tag")(
|
@@ -944,8 +900,8 @@ service_config = ServicesConfiguration(
|
|
944 |
version="1.0",
|
945 |
),
|
946 |
)
|
|
|
947 |
|
948 |
-
# %%
|
949 |
# Create the Vespa application package
|
950 |
vespa_application_package = ApplicationPackage(
|
951 |
name=VESPA_APPLICATION_NAME,
|
@@ -953,16 +909,14 @@ vespa_application_package = ApplicationPackage(
|
|
953 |
services_config=service_config,
|
954 |
)
|
955 |
|
956 |
-
# %% [markdown]
|
957 |
# ## 6. Deploy Vespa Application
|
958 |
#
|
959 |
|
960 |
-
# %%
|
961 |
VESPA_TEAM_API_KEY = os.getenv("VESPA_TEAM_API_KEY") or input(
|
962 |
"Enter Vespa team API key: "
|
963 |
)
|
964 |
|
965 |
-
#
|
966 |
vespa_cloud = VespaCloud(
|
967 |
tenant=VESPA_TENANT_NAME,
|
968 |
application=VESPA_APPLICATION_NAME,
|
@@ -976,23 +930,21 @@ vespa_cloud.deploy()
|
|
976 |
# Output the endpoint URL
|
977 |
endpoint_url = vespa_cloud.get_token_endpoint()
|
978 |
print(f"Application deployed. Token endpoint URL: {endpoint_url}")
|
|
|
979 |
|
980 |
-
# %% [markdown]
|
981 |
# Make sure to take note of the token endpoint_url.
|
982 |
# You need to put this in your `.env` file - `VESPA_APP_URL=https://abcd.vespa-app.cloud` - to access the Vespa application from your web application.
|
983 |
#
|
984 |
|
985 |
-
# %% [markdown]
|
986 |
# ## 8. Feed Data to Vespa
|
987 |
#
|
988 |
|
989 |
-
# %%
|
990 |
# Instantiate Vespa connection using token
|
991 |
app = Vespa(url=endpoint_url, vespa_cloud_secret_token=VESPA_CLOUD_SECRET_TOKEN)
|
992 |
app.get_application_status()
|
993 |
|
994 |
|
995 |
-
#
|
996 |
def callback(response: VespaResponse, id: str):
|
997 |
if not response.is_successful():
|
998 |
print(
|
|
|
|
|
1 |
# # Visual PDF Retrieval - demo application
|
2 |
#
|
3 |
# In this notebook, we will prepare the Vespa backend application for our visual retrieval demo.
|
|
|
22 |
# We have tried to make it easy for others to run this notebook, to create your own PDF Enterprise Search application using Vespa.
|
23 |
#
|
24 |
|
|
|
25 |
# ## 0. Setup and Configuration
|
26 |
#
|
27 |
|
28 |
+
# +
|
29 |
import os
|
30 |
import asyncio
|
31 |
import json
|
|
|
78 |
|
79 |
# Avoid warning from huggingface tokenizers
|
80 |
os.environ["TOKENIZERS_PARALLELISM"] = "false"
|
81 |
+
# -
|
82 |
|
|
|
83 |
# ### Create a free trial in Vespa Cloud
|
84 |
#
|
85 |
# Create a tenant from [here](https://vespa.ai/free-trial/).
|
|
|
87 |
# Take note of your tenant name.
|
88 |
#
|
89 |
|
|
|
90 |
VESPA_TENANT_NAME = "vespa-team"
|
91 |
|
|
|
92 |
# Here, set your desired application name. (Will be created in later steps)
|
93 |
# Note that you can not have hyphen `-` or underscore `_` in the application name.
|
94 |
#
|
95 |
|
|
|
96 |
VESPA_APPLICATION_NAME = "colpalidemo"
|
97 |
VESPA_SCHEMA_NAME = "pdf_page"
|
98 |
|
|
|
99 |
# Next, you need to create some tokens for feeding data, and querying the application.
|
100 |
# We recommend separate tokens for feeding and querying, (the former with write permission, and the latter with read permission).
|
101 |
# The tokens can be created from the [Vespa Cloud console](https://console.vespa-cloud.com/) in the 'Account' -> 'Tokens' section.
|
102 |
#
|
103 |
|
|
|
104 |
VESPA_TOKEN_ID_WRITE = "colpalidemo_write"
|
|
|
105 |
|
|
|
106 |
# We also need to set the value of the write token to be able to feed data to the Vespa application.
|
107 |
#
|
108 |
|
|
|
109 |
VESPA_CLOUD_SECRET_TOKEN = os.getenv("VESPA_CLOUD_SECRET_TOKEN") or input(
|
110 |
"Enter Vespa cloud secret token: "
|
111 |
)
|
112 |
|
|
|
113 |
# We will also use the Gemini API to create sample queries for our images.
|
114 |
# You can also use other VLM's to create these queries.
|
115 |
# Create a Gemini API key from [here](https://aistudio.google.com/app/apikey).
|
116 |
#
|
117 |
|
|
|
118 |
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") or input(
|
119 |
"Enter Google Generative AI API key: "
|
120 |
)
|
121 |
|
122 |
+
# +
|
123 |
MODEL_NAME = "vidore/colpali-v1.2"
|
124 |
|
125 |
# Configure Google Generative AI
|
|
|
137 |
).eval()
|
138 |
|
139 |
processor = ColPaliProcessor.from_pretrained(MODEL_NAME)
|
140 |
+
# -
|
141 |
|
|
|
142 |
# ## 1. Download PDFs
|
143 |
#
|
144 |
# We are going to use public reports from the Norwegian Government Pension Fund Global (also known as the Oil Fund).
|
|
|
151 |
# ![Sample2](./static/img/gfpg-sample-2.png)
|
152 |
#
|
153 |
|
|
|
154 |
# As we can see, a lot of the information is in the form of tables, charts and numbers.
|
155 |
# These are not easily extractable using pdf-readers or OCR tools.
|
156 |
#
|
157 |
|
158 |
+
# +
|
159 |
import requests
|
160 |
|
161 |
url = "https://www.nbim.no/en/publications/reports/"
|
|
|
181 |
links.append(full_url)
|
182 |
url_to_year[full_url] = year
|
183 |
links, url_to_year
|
184 |
+
# -
|
185 |
|
|
|
186 |
# Limit the number of PDFs to download
|
187 |
NUM_PDFS = 2 # Set to None to download all PDFs
|
188 |
links = links[:NUM_PDFS] if NUM_PDFS else links
|
189 |
links
|
190 |
|
191 |
+
# +
|
192 |
from nest_asyncio import apply
|
193 |
from typing import List
|
194 |
|
|
|
259 |
os.makedirs("pdfs", exist_ok=True)
|
260 |
# Now run the download_pdfs function with the URL
|
261 |
pdfs = asyncio.run(download_pdfs(links))
|
262 |
+
# -
|
263 |
|
|
|
264 |
pdfs
|
265 |
|
|
|
266 |
# ## 2. Convert PDFs to Images
|
267 |
#
|
268 |
|
269 |
|
270 |
+
# +
|
271 |
def get_pdf_images(pdf_path):
|
272 |
reader = PdfReader(pdf_path)
|
273 |
page_texts = []
|
|
|
299 |
"page_no": page_no,
|
300 |
}
|
301 |
)
|
302 |
+
# -
|
303 |
|
|
|
304 |
len(pdf_pages)
|
305 |
|
306 |
+
# +
|
307 |
from collections import Counter
|
308 |
|
309 |
# Print the length of the text fields - mean, max and min
|
|
|
313 |
print(f"Min text length: {np.min(text_lengths)}")
|
314 |
print(f"Median text length: {np.median(text_lengths)}")
|
315 |
print(f"Number of text with length == 0: {Counter(text_lengths)[0]}")
|
316 |
+
# -
|
317 |
|
|
|
318 |
# ## 3. Generate Queries
|
319 |
#
|
320 |
# In this step, we want to generate queries for each page image.
|
|
|
328 |
# We will use the Gemini API to generate these queries, with `gemini-1.5-flash-8b` as the model.
|
329 |
#
|
330 |
|
331 |
+
# +
|
332 |
from pydantic import BaseModel
|
333 |
|
334 |
|
|
|
380 |
|
381 |
prompt_text, pydantic_model = get_retrieval_prompt()
|
382 |
|
383 |
+
# +
|
384 |
gemini_model = genai.GenerativeModel("gemini-1.5-flash-8b")
|
385 |
|
386 |
|
|
|
406 |
return queries
|
407 |
|
408 |
|
409 |
+
# -
|
410 |
+
|
411 |
for pdf in tqdm(pdf_pages):
|
412 |
image = pdf.get("image")
|
413 |
pdf["queries"] = generate_queries(image, prompt_text, pydantic_model)
|
414 |
|
|
|
415 |
pdf_pages[46]["image"]
|
416 |
|
|
|
417 |
pdf_pages[46]["queries"]
|
418 |
|
419 |
+
# +
|
420 |
# Generate queries async - keeping for now as we probably need when applying to the full dataset
|
421 |
# import asyncio
|
422 |
# from tenacity import retry, stop_after_attempt, wait_exponential
|
|
|
467 |
|
468 |
# pdf_pages = asyncio.run(enrich_pdfs())
|
469 |
|
470 |
+
# +
|
471 |
# write title, url, page_no, text, queries, not image to JSON
|
472 |
with open("output/pdf_pages.json", "w") as f:
|
473 |
to_write = [{k: v for k, v in pdf.items() if k != "image"} for pdf in pdf_pages]
|
|
|
477 |
# saved_pdf_pages = json.load(f)
|
478 |
# for pdf, saved_pdf in zip(pdf_pages, saved_pdf_pages):
|
479 |
# pdf.update(saved_pdf)
|
480 |
+
# -
|
481 |
|
|
|
482 |
# ## 4. Generate embeddings
|
483 |
#
|
484 |
# Now that we have the queries, we can use the ColPali model to generate embeddings for each page image.
|
485 |
#
|
486 |
|
487 |
|
|
|
488 |
def generate_embeddings(images, model, processor, batch_size=2) -> np.ndarray:
|
489 |
"""
|
490 |
Generate embeddings for a list of images.
|
|
|
523 |
return all_embeddings
|
524 |
|
525 |
|
|
|
526 |
# Generate embeddings for all images
|
527 |
images = [pdf["image"] for pdf in pdf_pages]
|
528 |
embeddings = generate_embeddings(images, model, processor)
|
529 |
|
|
|
530 |
embeddings.shape
|
531 |
|
|
|
532 |
# ## 5. Prepare Data on Vespa Format
|
533 |
#
|
534 |
# Now, that we have all the data we need, all that remains is to make sure it is in the right format for Vespa.
|
535 |
#
|
536 |
|
537 |
|
|
|
538 |
def float_to_binary_embedding(float_query_embedding: dict) -> dict:
|
539 |
"""Utility function to convert float query embeddings to binary query embeddings."""
|
540 |
binary_query_embeddings = {}
|
|
|
546 |
return binary_query_embeddings
|
547 |
|
548 |
|
|
|
549 |
vespa_feed = []
|
550 |
for pdf, embedding in zip(pdf_pages, embeddings):
|
551 |
url = pdf["url"]
|
|
|
583 |
}
|
584 |
vespa_feed.append(page)
|
585 |
|
586 |
+
# +
|
587 |
# We will prepare the Vespa feed data, including the embeddings and the generated queries
|
588 |
|
589 |
|
|
|
597 |
vespa_feed_to_save.append({"put": put_id, "fields": page["fields"]})
|
598 |
json.dump(vespa_feed_to_save, f)
|
599 |
|
600 |
+
# +
|
601 |
# import json
|
602 |
|
603 |
# with open("output/vespa_feed.json", "r") as f:
|
604 |
# vespa_feed = json.load(f)
|
605 |
+
# -
|
606 |
|
|
|
607 |
len(vespa_feed)
|
608 |
|
|
|
609 |
# ## 5. Prepare Vespa Application
|
610 |
#
|
611 |
|
612 |
+
# +
|
613 |
# Define the Vespa schema
|
614 |
colpali_schema = Schema(
|
615 |
name=VESPA_SCHEMA_NAME,
|
|
|
656 |
Field(
|
657 |
name="questions",
|
658 |
type="array<string>",
|
659 |
+
indexing=["summary", "attribute"],
|
660 |
+
summary=Summary(fields=["matched-elements-only"]),
|
|
|
661 |
),
|
662 |
Field(
|
663 |
name="queries",
|
664 |
type="array<string>",
|
665 |
+
indexing=["summary", "attribute"],
|
666 |
+
summary=Summary(fields=["matched-elements-only"]),
|
|
|
667 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
668 |
]
|
669 |
),
|
670 |
fieldsets=[
|
|
|
829 |
colpali_schema.add_rank_profile(colpali_retrieval_profile)
|
830 |
colpali_schema.add_rank_profile(with_quantized_similarity(colpali_retrieval_profile))
|
831 |
|
832 |
+
# +
|
833 |
from vespa.configuration.services import (
|
834 |
services,
|
835 |
container,
|
|
|
869 |
id="token_write",
|
870 |
permissions="read,write",
|
871 |
),
|
|
|
|
|
|
|
|
|
|
|
872 |
),
|
873 |
config(
|
874 |
vt("tag")(
|
|
|
900 |
version="1.0",
|
901 |
),
|
902 |
)
|
903 |
+
# -
|
904 |
|
|
|
905 |
# Create the Vespa application package
|
906 |
vespa_application_package = ApplicationPackage(
|
907 |
name=VESPA_APPLICATION_NAME,
|
|
|
909 |
services_config=service_config,
|
910 |
)
|
911 |
|
|
|
912 |
# ## 6. Deploy Vespa Application
|
913 |
#
|
914 |
|
|
|
915 |
VESPA_TEAM_API_KEY = os.getenv("VESPA_TEAM_API_KEY") or input(
|
916 |
"Enter Vespa team API key: "
|
917 |
)
|
918 |
|
919 |
+
# +
|
920 |
vespa_cloud = VespaCloud(
|
921 |
tenant=VESPA_TENANT_NAME,
|
922 |
application=VESPA_APPLICATION_NAME,
|
|
|
930 |
# Output the endpoint URL
|
931 |
endpoint_url = vespa_cloud.get_token_endpoint()
|
932 |
print(f"Application deployed. Token endpoint URL: {endpoint_url}")
|
933 |
+
# -
|
934 |
|
|
|
935 |
# Make sure to take note of the token endpoint_url.
|
936 |
# You need to put this in your `.env` file - `VESPA_APP_URL=https://abcd.vespa-app.cloud` - to access the Vespa application from your web application.
|
937 |
#
|
938 |
|
|
|
939 |
# ## 8. Feed Data to Vespa
|
940 |
#
|
941 |
|
|
|
942 |
# Instantiate Vespa connection using token
|
943 |
app = Vespa(url=endpoint_url, vespa_cloud_secret_token=VESPA_CLOUD_SECRET_TOKEN)
|
944 |
app.get_application_status()
|
945 |
|
946 |
|
947 |
+
# +
|
948 |
def callback(response: VespaResponse, id: str):
|
949 |
if not response.is_successful():
|
950 |
print(
|
pyproject.toml
CHANGED
@@ -3,7 +3,7 @@ name = "visual-retrieval-colpali"
|
|
3 |
version = "0.1.0"
|
4 |
description = "Visual retrieval with ColPali"
|
5 |
readme = "README.md"
|
6 |
-
requires-python = ">=3.10"
|
7 |
license = { text = "Apache-2.0" }
|
8 |
dependencies = [
|
9 |
"python-fasthtml",
|
@@ -37,4 +37,82 @@ feed = [
|
|
37 |
"beautifulsoup4",
|
38 |
"pdf2image",
|
39 |
"google-generativeai"
|
40 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
version = "0.1.0"
|
4 |
description = "Visual retrieval with ColPali"
|
5 |
readme = "README.md"
|
6 |
+
requires-python = ">=3.10, <3.13"
|
7 |
license = { text = "Apache-2.0" }
|
8 |
dependencies = [
|
9 |
"python-fasthtml",
|
|
|
37 |
"beautifulsoup4",
|
38 |
"pdf2image",
|
39 |
"google-generativeai"
|
40 |
+
]
|
41 |
+
[tool.ruff]
|
42 |
+
# Exclude a variety of commonly ignored directories.
|
43 |
+
exclude = [
|
44 |
+
".bzr",
|
45 |
+
".direnv",
|
46 |
+
".eggs",
|
47 |
+
".git",
|
48 |
+
".git-rewrite",
|
49 |
+
".hg",
|
50 |
+
".ipynb_checkpoints",
|
51 |
+
".mypy_cache",
|
52 |
+
".nox",
|
53 |
+
".pants.d",
|
54 |
+
".pyenv",
|
55 |
+
".pytest_cache",
|
56 |
+
".pytype",
|
57 |
+
".ruff_cache",
|
58 |
+
".svn",
|
59 |
+
".tox",
|
60 |
+
".venv",
|
61 |
+
".vscode",
|
62 |
+
"__pypackages__",
|
63 |
+
"_build",
|
64 |
+
"buck-out",
|
65 |
+
"build",
|
66 |
+
"dist",
|
67 |
+
"node_modules",
|
68 |
+
"site-packages",
|
69 |
+
"venv",
|
70 |
+
]
|
71 |
+
|
72 |
+
# Same as Black.
|
73 |
+
line-length = 88
|
74 |
+
indent-width = 4
|
75 |
+
|
76 |
+
# Assume Python 3.8
|
77 |
+
target-version = "py38"
|
78 |
+
|
79 |
+
[tool.ruff.lint]
|
80 |
+
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
|
81 |
+
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
|
82 |
+
# McCabe complexity (`C901`) by default.
|
83 |
+
select = ["E4", "E7", "E9", "F"]
|
84 |
+
ignore = []
|
85 |
+
|
86 |
+
# Allow fix for all enabled rules (when `--fix`) is provided.
|
87 |
+
fixable = ["ALL"]
|
88 |
+
unfixable = []
|
89 |
+
|
90 |
+
# Allow unused variables when underscore-prefixed.
|
91 |
+
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
92 |
+
|
93 |
+
[tool.ruff.format]
|
94 |
+
# Like Black, use double quotes for strings.
|
95 |
+
quote-style = "double"
|
96 |
+
|
97 |
+
# Like Black, indent with spaces, rather than tabs.
|
98 |
+
indent-style = "space"
|
99 |
+
|
100 |
+
# Like Black, respect magic trailing commas.
|
101 |
+
skip-magic-trailing-comma = false
|
102 |
+
|
103 |
+
# Like Black, automatically detect the appropriate line ending.
|
104 |
+
line-ending = "auto"
|
105 |
+
|
106 |
+
# Enable auto-formatting of code examples in docstrings. Markdown,
|
107 |
+
# reStructuredText code/literal blocks and doctests are all supported.
|
108 |
+
#
|
109 |
+
# This is currently disabled by default, but it is planned for this
|
110 |
+
# to be opt-out in the future.
|
111 |
+
docstring-code-format = false
|
112 |
+
|
113 |
+
# Set the line length limit used when formatting code snippets in
|
114 |
+
# docstrings.
|
115 |
+
#
|
116 |
+
# This only has an effect when the `docstring-code-format` setting is
|
117 |
+
# enabled.
|
118 |
+
docstring-code-line-length = "dynamic"
|
src/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
---
|
2 |
+
title: ColPali π€ Vespa - Visual Retrieval
|
3 |
+
short_description: Visual Retrieval with ColPali and Vespa
|
4 |
+
emoji: π
|
5 |
+
colorFrom: purple
|
6 |
+
colorTo: blue
|
7 |
+
sdk: gradio
|
8 |
+
sdk_version: 4.44.0
|
9 |
+
app_file: main.py
|
10 |
+
pinned: false
|
11 |
+
license: apache-2.0
|
12 |
+
suggested_hardware: t4-small
|
13 |
+
models:
|
14 |
+
- vidore/colpaligemma-3b-pt-448-base
|
15 |
+
- vidore/colpali-v1.2
|
16 |
+
preload_from_hub:
|
17 |
+
- vidore/colpaligemma-3b-pt-448-base config.json,model-00001-of-00002.safetensors,model-00002-of-00002.safetensors,model.safetensors.index.json,preprocessor_config.json,special_tokens_map.json,tokenizer.json,tokenizer_config.json 12c59eb7e23bc4c26876f7be7c17760d5d3a1ffa
|
18 |
+
- vidore/colpali-v1.2 adapter_config.json,adapter_model.safetensors,preprocessor_config.json,special_tokens_map.json,tokenizer.json,tokenizer_config.json 9912ce6f8a462d8cf2269f5606eabbd2784e764f
|
19 |
+
---
|
src/backend/__init__.py
ADDED
File without changes
|
src/backend/cache.py
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from collections import OrderedDict
|
2 |
+
|
3 |
+
|
4 |
+
# Initialize LRU Cache
|
5 |
+
class LRUCache:
|
6 |
+
def __init__(self, max_size=20):
|
7 |
+
self.max_size = max_size
|
8 |
+
self.cache = OrderedDict()
|
9 |
+
|
10 |
+
def get(self, key):
|
11 |
+
if key in self.cache:
|
12 |
+
self.cache.move_to_end(key)
|
13 |
+
return self.cache[key]
|
14 |
+
return None
|
15 |
+
|
16 |
+
def set(self, key, value):
|
17 |
+
if key in self.cache:
|
18 |
+
self.cache.move_to_end(key)
|
19 |
+
else:
|
20 |
+
if len(self.cache) >= self.max_size:
|
21 |
+
self.cache.popitem(last=False)
|
22 |
+
self.cache[key] = value
|
23 |
+
|
24 |
+
def delete(self, key):
|
25 |
+
if key in self.cache:
|
26 |
+
del self.cache[key]
|
src/backend/colpali.py
ADDED
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch
|
2 |
+
from PIL import Image
|
3 |
+
import numpy as np
|
4 |
+
from typing import Generator, Tuple, List, Union, Dict
|
5 |
+
from pathlib import Path
|
6 |
+
import base64
|
7 |
+
from io import BytesIO
|
8 |
+
import re
|
9 |
+
import io
|
10 |
+
import matplotlib.cm as cm
|
11 |
+
|
12 |
+
from colpali_engine.models import ColPali, ColPaliProcessor
|
13 |
+
from colpali_engine.utils.torch_utils import get_torch_device
|
14 |
+
from vidore_benchmark.interpretability.torch_utils import (
|
15 |
+
normalize_similarity_map_per_query_token,
|
16 |
+
)
|
17 |
+
from functools import lru_cache
|
18 |
+
import logging
|
19 |
+
|
20 |
+
|
21 |
+
class SimMapGenerator:
|
22 |
+
"""
|
23 |
+
Generates similarity maps based on query embeddings and image patches using the ColPali model.
|
24 |
+
"""
|
25 |
+
|
26 |
+
colormap = cm.get_cmap("viridis") # Preload colormap for efficiency
|
27 |
+
|
28 |
+
def __init__(
|
29 |
+
self,
|
30 |
+
logger: logging.Logger,
|
31 |
+
model_name: str = "vidore/colpali-v1.2",
|
32 |
+
n_patch: int = 32,
|
33 |
+
):
|
34 |
+
"""
|
35 |
+
Initializes the SimMapGenerator class with a specified model and patch dimension.
|
36 |
+
|
37 |
+
Args:
|
38 |
+
model_name (str): The model name for loading the ColPali model.
|
39 |
+
n_patch (int): The number of patches per dimension.
|
40 |
+
"""
|
41 |
+
self.model_name = model_name
|
42 |
+
self.n_patch = n_patch
|
43 |
+
self.device = get_torch_device("auto")
|
44 |
+
self.logger = logger
|
45 |
+
self.logger.info(f"Using device: {self.device}")
|
46 |
+
self.model, self.processor = self.load_model()
|
47 |
+
|
48 |
+
def load_model(self) -> Tuple[ColPali, ColPaliProcessor]:
|
49 |
+
"""
|
50 |
+
Loads the ColPali model and processor.
|
51 |
+
|
52 |
+
Returns:
|
53 |
+
Tuple[ColPali, ColPaliProcessor]: Loaded model and processor.
|
54 |
+
"""
|
55 |
+
model = ColPali.from_pretrained(
|
56 |
+
self.model_name,
|
57 |
+
torch_dtype=torch.bfloat16, # Note that the embeddings created during feed were float32 -> binarized, yet setting this seem to produce the most similar results both locally (mps) and HF (Cuda)
|
58 |
+
device_map=self.device,
|
59 |
+
).eval()
|
60 |
+
|
61 |
+
processor = ColPaliProcessor.from_pretrained(self.model_name)
|
62 |
+
return model, processor
|
63 |
+
|
64 |
+
def gen_similarity_maps(
|
65 |
+
self,
|
66 |
+
query: str,
|
67 |
+
query_embs: torch.Tensor,
|
68 |
+
token_idx_map: Dict[int, str],
|
69 |
+
images: List[Union[Path, str]],
|
70 |
+
vespa_sim_maps: List[Dict],
|
71 |
+
) -> Generator[Tuple[int, str, str], None, None]:
|
72 |
+
"""
|
73 |
+
Generates similarity maps for the provided images and query, and returns base64-encoded blended images.
|
74 |
+
|
75 |
+
Args:
|
76 |
+
query (str): The query string.
|
77 |
+
query_embs (torch.Tensor): Query embeddings tensor.
|
78 |
+
token_idx_map (dict): Mapping from indices to tokens.
|
79 |
+
images (List[Union[Path, str]]): List of image paths or base64-encoded strings.
|
80 |
+
vespa_sim_maps (List[Dict]): List of Vespa similarity maps.
|
81 |
+
|
82 |
+
Yields:
|
83 |
+
Tuple[int, str, str]: A tuple containing the image index, selected token, and base64-encoded image.
|
84 |
+
"""
|
85 |
+
processed_images, original_images, original_sizes = [], [], []
|
86 |
+
for img in images:
|
87 |
+
img_pil = self._load_image(img)
|
88 |
+
original_images.append(img_pil.copy())
|
89 |
+
original_sizes.append(img_pil.size)
|
90 |
+
processed_images.append(img_pil)
|
91 |
+
|
92 |
+
vespa_sim_map_tensor = self._prepare_similarity_map_tensor(
|
93 |
+
query_embs, vespa_sim_maps
|
94 |
+
)
|
95 |
+
similarity_map_normalized = normalize_similarity_map_per_query_token(
|
96 |
+
vespa_sim_map_tensor
|
97 |
+
)
|
98 |
+
|
99 |
+
for idx, img in enumerate(original_images):
|
100 |
+
for token_idx, token in token_idx_map.items():
|
101 |
+
if self.should_filter_token(token):
|
102 |
+
continue
|
103 |
+
|
104 |
+
sim_map = similarity_map_normalized[idx, token_idx, :, :]
|
105 |
+
blended_img_base64 = self._blend_image(
|
106 |
+
img, sim_map, original_sizes[idx]
|
107 |
+
)
|
108 |
+
yield idx, token, token_idx, blended_img_base64
|
109 |
+
|
110 |
+
def _load_image(self, img: Union[Path, str]) -> Image:
|
111 |
+
"""
|
112 |
+
Loads an image from a file path or a base64-encoded string.
|
113 |
+
|
114 |
+
Args:
|
115 |
+
img (Union[Path, str]): The image to load.
|
116 |
+
|
117 |
+
Returns:
|
118 |
+
Image: The loaded PIL image.
|
119 |
+
"""
|
120 |
+
try:
|
121 |
+
if isinstance(img, Path):
|
122 |
+
return Image.open(img).convert("RGB")
|
123 |
+
elif isinstance(img, str):
|
124 |
+
return Image.open(BytesIO(base64.b64decode(img))).convert("RGB")
|
125 |
+
except Exception as e:
|
126 |
+
raise ValueError(f"Failed to load image: {e}")
|
127 |
+
|
128 |
+
def _prepare_similarity_map_tensor(
|
129 |
+
self, query_embs: torch.Tensor, vespa_sim_maps: List[Dict]
|
130 |
+
) -> torch.Tensor:
|
131 |
+
"""
|
132 |
+
Prepares a similarity map tensor from Vespa similarity maps.
|
133 |
+
|
134 |
+
Args:
|
135 |
+
query_embs (torch.Tensor): Query embeddings tensor.
|
136 |
+
vespa_sim_maps (List[Dict]): List of Vespa similarity maps.
|
137 |
+
|
138 |
+
Returns:
|
139 |
+
torch.Tensor: The prepared similarity map tensor.
|
140 |
+
"""
|
141 |
+
vespa_sim_map_tensor = torch.zeros(
|
142 |
+
(len(vespa_sim_maps), query_embs.size(1), self.n_patch, self.n_patch)
|
143 |
+
)
|
144 |
+
for idx, vespa_sim_map in enumerate(vespa_sim_maps):
|
145 |
+
for cell in vespa_sim_map["quantized"]["cells"]:
|
146 |
+
patch = int(cell["address"]["patch"])
|
147 |
+
query_token = int(cell["address"]["querytoken"])
|
148 |
+
value = cell["value"]
|
149 |
+
if hasattr(self.processor, "image_seq_length"):
|
150 |
+
image_seq_length = self.processor.image_seq_length
|
151 |
+
else:
|
152 |
+
image_seq_length = 1024
|
153 |
+
|
154 |
+
if patch >= image_seq_length:
|
155 |
+
continue
|
156 |
+
vespa_sim_map_tensor[
|
157 |
+
idx,
|
158 |
+
query_token,
|
159 |
+
patch // self.n_patch,
|
160 |
+
patch % self.n_patch,
|
161 |
+
] = value
|
162 |
+
return vespa_sim_map_tensor
|
163 |
+
|
164 |
+
def _blend_image(
|
165 |
+
self, img: Image, sim_map: torch.Tensor, original_size: Tuple[int, int]
|
166 |
+
) -> str:
|
167 |
+
"""
|
168 |
+
Blends an image with a similarity map and encodes it to base64.
|
169 |
+
|
170 |
+
Args:
|
171 |
+
img (Image): The original image.
|
172 |
+
sim_map (torch.Tensor): The similarity map tensor.
|
173 |
+
original_size (Tuple[int, int]): The original size of the image.
|
174 |
+
|
175 |
+
Returns:
|
176 |
+
str: The base64-encoded blended image.
|
177 |
+
"""
|
178 |
+
SCALING_FACTOR = 8
|
179 |
+
sim_map_resolution = (
|
180 |
+
max(32, int(original_size[0] / SCALING_FACTOR)),
|
181 |
+
max(32, int(original_size[1] / SCALING_FACTOR)),
|
182 |
+
)
|
183 |
+
|
184 |
+
sim_map_np = sim_map.cpu().float().numpy()
|
185 |
+
sim_map_img = Image.fromarray(sim_map_np).resize(
|
186 |
+
sim_map_resolution, resample=Image.BICUBIC
|
187 |
+
)
|
188 |
+
sim_map_resized_np = np.array(sim_map_img, dtype=np.float32)
|
189 |
+
sim_map_normalized = self._normalize_sim_map(sim_map_resized_np)
|
190 |
+
|
191 |
+
heatmap = self.colormap(sim_map_normalized)
|
192 |
+
heatmap_img = Image.fromarray((heatmap * 255).astype(np.uint8)).convert("RGBA")
|
193 |
+
|
194 |
+
buffer = io.BytesIO()
|
195 |
+
heatmap_img.save(buffer, format="PNG")
|
196 |
+
return base64.b64encode(buffer.getvalue()).decode("utf-8")
|
197 |
+
|
198 |
+
@staticmethod
|
199 |
+
def _normalize_sim_map(sim_map: np.ndarray) -> np.ndarray:
|
200 |
+
"""
|
201 |
+
Normalizes a similarity map to range [0, 1].
|
202 |
+
|
203 |
+
Args:
|
204 |
+
sim_map (np.ndarray): The similarity map.
|
205 |
+
|
206 |
+
Returns:
|
207 |
+
np.ndarray: The normalized similarity map.
|
208 |
+
"""
|
209 |
+
sim_map_min, sim_map_max = sim_map.min(), sim_map.max()
|
210 |
+
if sim_map_max - sim_map_min > 1e-6:
|
211 |
+
return (sim_map - sim_map_min) / (sim_map_max - sim_map_min)
|
212 |
+
return np.zeros_like(sim_map)
|
213 |
+
|
214 |
+
@staticmethod
|
215 |
+
def should_filter_token(token: str) -> bool:
|
216 |
+
"""
|
217 |
+
Determines if a token should be filtered out based on predefined patterns.
|
218 |
+
|
219 |
+
The function filters out tokens that:
|
220 |
+
|
221 |
+
- Start with '<' (e.g., '<bos>')
|
222 |
+
- Consist entirely of whitespace
|
223 |
+
- Are purely punctuation (excluding tokens that contain digits or start with 'β')
|
224 |
+
- Start with an underscore '_'
|
225 |
+
- Exactly match the word 'Question'
|
226 |
+
- Are exactly the single character 'β'
|
227 |
+
|
228 |
+
Output of test:
|
229 |
+
Token: '2' | False
|
230 |
+
Token: '0' | False
|
231 |
+
Token: '2' | False
|
232 |
+
Token: '3' | False
|
233 |
+
Token: 'β2' | False
|
234 |
+
Token: 'βhi' | False
|
235 |
+
Token: 'norwegian' | False
|
236 |
+
Token: 'unlisted' | False
|
237 |
+
Token: '<bos>' | True
|
238 |
+
Token: 'Question' | True
|
239 |
+
Token: ':' | True
|
240 |
+
Token: '<pad>' | True
|
241 |
+
Token: '\n' | True
|
242 |
+
Token: 'β' | True
|
243 |
+
Token: '?' | True
|
244 |
+
Token: ')' | True
|
245 |
+
Token: '%' | True
|
246 |
+
Token: '/)' | True
|
247 |
+
|
248 |
+
|
249 |
+
Args:
|
250 |
+
token (str): The token to check.
|
251 |
+
|
252 |
+
Returns:
|
253 |
+
bool: True if the token should be filtered out, False otherwise.
|
254 |
+
"""
|
255 |
+
pattern = re.compile(
|
256 |
+
r"^<.*$|^\s+$|^(?!.*\d)(?!β)[^\w\s]+$|^_.*$|^Question$|^β$"
|
257 |
+
)
|
258 |
+
return bool(pattern.match(token))
|
259 |
+
|
260 |
+
@lru_cache(maxsize=128)
|
261 |
+
def get_query_embeddings_and_token_map(
|
262 |
+
self, query: str
|
263 |
+
) -> Tuple[torch.Tensor, dict]:
|
264 |
+
"""
|
265 |
+
Retrieves query embeddings and a token index map.
|
266 |
+
|
267 |
+
Args:
|
268 |
+
query (str): The query string.
|
269 |
+
|
270 |
+
Returns:
|
271 |
+
Tuple[torch.Tensor, dict]: Query embeddings and token index map.
|
272 |
+
"""
|
273 |
+
inputs = self.processor.process_queries([query]).to(self.model.device)
|
274 |
+
with torch.no_grad():
|
275 |
+
q_emb = self.model(**inputs).to("cpu")[0]
|
276 |
+
|
277 |
+
query_tokens = self.processor.tokenizer.tokenize(
|
278 |
+
self.processor.decode(inputs.input_ids[0])
|
279 |
+
)
|
280 |
+
idx_to_token = {idx: token for idx, token in enumerate(query_tokens)}
|
281 |
+
return q_emb, idx_to_token
|
src/backend/stopwords.py
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import spacy
|
2 |
+
import os
|
3 |
+
|
4 |
+
# Download the model if it is not already present
|
5 |
+
if not spacy.util.is_package("en_core_web_sm"):
|
6 |
+
spacy.cli.download("en_core_web_sm")
|
7 |
+
nlp = spacy.load("en_core_web_sm")
|
8 |
+
|
9 |
+
|
10 |
+
# It would be possible to remove bolding for stopwords without removing them from the query,
|
11 |
+
# but that would require a java plugin which we didn't want to complicate this sample app with.
|
12 |
+
def filter(text):
|
13 |
+
doc = nlp(text)
|
14 |
+
tokens = [token.text for token in doc if not token.is_stop]
|
15 |
+
if len(tokens) == 0:
|
16 |
+
# if we remove all the words we don't have a query at all, so use the original
|
17 |
+
return text
|
18 |
+
return " ".join(tokens)
|
src/backend/testquery.py
ADDED
@@ -0,0 +1,3013 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch
|
2 |
+
|
3 |
+
token_to_idx = {
|
4 |
+
"<bos>": 0,
|
5 |
+
"Question": 1,
|
6 |
+
":": 2,
|
7 |
+
"βPercentage": 3,
|
8 |
+
"βof": 4,
|
9 |
+
"βnon": 5,
|
10 |
+
"-": 6,
|
11 |
+
"fresh": 7,
|
12 |
+
"βwater": 8,
|
13 |
+
"βas": 9,
|
14 |
+
"βsource": 10,
|
15 |
+
"?": 11,
|
16 |
+
"<pad>": 21,
|
17 |
+
"\n": 22,
|
18 |
+
}
|
19 |
+
idx_to_token = {v: k for k, v in token_to_idx.items()}
|
20 |
+
q_embs = torch.tensor(
|
21 |
+
[
|
22 |
+
[
|
23 |
+
1.6547e-01,
|
24 |
+
-1.8838e-02,
|
25 |
+
1.0150e-01,
|
26 |
+
-2.2643e-02,
|
27 |
+
5.0652e-02,
|
28 |
+
3.2039e-02,
|
29 |
+
6.8322e-02,
|
30 |
+
2.7134e-02,
|
31 |
+
7.2197e-03,
|
32 |
+
-4.2341e-02,
|
33 |
+
-5.8006e-02,
|
34 |
+
-1.1389e-01,
|
35 |
+
7.0041e-02,
|
36 |
+
-6.8021e-02,
|
37 |
+
2.4681e-02,
|
38 |
+
5.3306e-02,
|
39 |
+
4.1714e-02,
|
40 |
+
6.2021e-02,
|
41 |
+
1.3488e-01,
|
42 |
+
3.4943e-02,
|
43 |
+
3.8032e-02,
|
44 |
+
-3.2724e-02,
|
45 |
+
-1.2960e-01,
|
46 |
+
1.1453e-02,
|
47 |
+
-2.6477e-02,
|
48 |
+
3.5219e-02,
|
49 |
+
-7.6606e-02,
|
50 |
+
2.2387e-01,
|
51 |
+
-3.4888e-02,
|
52 |
+
-4.0333e-02,
|
53 |
+
1.4128e-01,
|
54 |
+
4.2248e-02,
|
55 |
+
-1.2664e-01,
|
56 |
+
-7.8376e-02,
|
57 |
+
-2.0356e-02,
|
58 |
+
4.2198e-02,
|
59 |
+
-7.0776e-02,
|
60 |
+
1.3965e-02,
|
61 |
+
4.2442e-03,
|
62 |
+
7.1987e-02,
|
63 |
+
8.5172e-04,
|
64 |
+
-6.4878e-02,
|
65 |
+
-1.8954e-01,
|
66 |
+
-8.6171e-02,
|
67 |
+
9.1983e-02,
|
68 |
+
-9.3358e-02,
|
69 |
+
2.2704e-01,
|
70 |
+
1.3102e-02,
|
71 |
+
6.5327e-02,
|
72 |
+
2.4815e-02,
|
73 |
+
-1.4533e-01,
|
74 |
+
5.8823e-02,
|
75 |
+
-6.1434e-02,
|
76 |
+
5.2004e-02,
|
77 |
+
-8.4065e-02,
|
78 |
+
1.6298e-01,
|
79 |
+
8.1965e-02,
|
80 |
+
2.6553e-02,
|
81 |
+
-1.2377e-01,
|
82 |
+
-5.3495e-02,
|
83 |
+
-3.4537e-02,
|
84 |
+
5.1438e-02,
|
85 |
+
8.2665e-03,
|
86 |
+
7.9407e-02,
|
87 |
+
5.8799e-02,
|
88 |
+
-3.5538e-02,
|
89 |
+
1.9870e-01,
|
90 |
+
6.2459e-02,
|
91 |
+
1.6154e-01,
|
92 |
+
7.2921e-02,
|
93 |
+
-9.7275e-02,
|
94 |
+
3.0933e-02,
|
95 |
+
-1.0579e-02,
|
96 |
+
-1.4484e-01,
|
97 |
+
-4.8761e-02,
|
98 |
+
-5.3119e-02,
|
99 |
+
6.2644e-02,
|
100 |
+
2.2985e-02,
|
101 |
+
-2.1209e-01,
|
102 |
+
9.0963e-02,
|
103 |
+
-2.6955e-02,
|
104 |
+
-7.7520e-02,
|
105 |
+
1.2072e-01,
|
106 |
+
-1.9626e-02,
|
107 |
+
5.8813e-02,
|
108 |
+
-1.2730e-01,
|
109 |
+
1.5610e-01,
|
110 |
+
-1.6914e-01,
|
111 |
+
6.5033e-02,
|
112 |
+
8.5765e-02,
|
113 |
+
1.2701e-01,
|
114 |
+
6.5633e-02,
|
115 |
+
-1.0309e-01,
|
116 |
+
-8.0259e-02,
|
117 |
+
4.5913e-02,
|
118 |
+
-3.3277e-02,
|
119 |
+
1.9227e-01,
|
120 |
+
-2.3351e-02,
|
121 |
+
-8.0545e-02,
|
122 |
+
-9.8760e-03,
|
123 |
+
-4.1836e-02,
|
124 |
+
1.2041e-01,
|
125 |
+
8.1419e-02,
|
126 |
+
1.4848e-01,
|
127 |
+
7.2537e-02,
|
128 |
+
-4.7115e-03,
|
129 |
+
4.1489e-02,
|
130 |
+
4.3031e-02,
|
131 |
+
-1.3515e-01,
|
132 |
+
1.0383e-01,
|
133 |
+
-9.4411e-02,
|
134 |
+
2.8965e-02,
|
135 |
+
1.9185e-01,
|
136 |
+
-1.4600e-02,
|
137 |
+
-8.0910e-02,
|
138 |
+
-2.9022e-02,
|
139 |
+
-4.4347e-02,
|
140 |
+
-8.8980e-03,
|
141 |
+
2.8737e-03,
|
142 |
+
4.2124e-02,
|
143 |
+
-1.6609e-02,
|
144 |
+
4.2994e-02,
|
145 |
+
-7.2814e-02,
|
146 |
+
-2.9573e-02,
|
147 |
+
-1.2666e-01,
|
148 |
+
-4.3703e-02,
|
149 |
+
-7.2094e-02,
|
150 |
+
-2.7486e-02,
|
151 |
+
],
|
152 |
+
[
|
153 |
+
-9.8454e-02,
|
154 |
+
-1.2954e-01,
|
155 |
+
6.5702e-02,
|
156 |
+
-9.0006e-03,
|
157 |
+
-1.0934e-01,
|
158 |
+
3.2155e-02,
|
159 |
+
-1.1444e-01,
|
160 |
+
-1.0309e-01,
|
161 |
+
5.7024e-02,
|
162 |
+
1.0124e-01,
|
163 |
+
2.0721e-02,
|
164 |
+
-5.2608e-03,
|
165 |
+
6.9916e-02,
|
166 |
+
1.8036e-02,
|
167 |
+
3.1653e-02,
|
168 |
+
2.1923e-02,
|
169 |
+
-9.2523e-02,
|
170 |
+
-1.8215e-02,
|
171 |
+
1.2974e-01,
|
172 |
+
-2.9632e-02,
|
173 |
+
-1.3854e-01,
|
174 |
+
2.5710e-02,
|
175 |
+
-1.1727e-03,
|
176 |
+
1.0245e-01,
|
177 |
+
-2.0731e-01,
|
178 |
+
4.3669e-02,
|
179 |
+
-7.0196e-02,
|
180 |
+
-1.6697e-01,
|
181 |
+
6.6050e-02,
|
182 |
+
9.9776e-02,
|
183 |
+
-1.2227e-01,
|
184 |
+
9.4000e-02,
|
185 |
+
1.1945e-01,
|
186 |
+
2.4611e-02,
|
187 |
+
-1.4073e-01,
|
188 |
+
9.3476e-02,
|
189 |
+
2.1170e-01,
|
190 |
+
-7.4522e-02,
|
191 |
+
-5.3362e-02,
|
192 |
+
-4.1198e-03,
|
193 |
+
8.3880e-02,
|
194 |
+
2.6590e-02,
|
195 |
+
-4.8489e-02,
|
196 |
+
-3.1279e-02,
|
197 |
+
-9.3401e-03,
|
198 |
+
-1.5945e-01,
|
199 |
+
-6.6368e-02,
|
200 |
+
7.5715e-02,
|
201 |
+
5.6884e-02,
|
202 |
+
1.2861e-01,
|
203 |
+
1.0073e-02,
|
204 |
+
-1.7185e-02,
|
205 |
+
1.1545e-01,
|
206 |
+
2.8725e-02,
|
207 |
+
-9.4969e-02,
|
208 |
+
-4.5517e-02,
|
209 |
+
3.1253e-02,
|
210 |
+
2.1135e-02,
|
211 |
+
-1.4505e-02,
|
212 |
+
9.0893e-02,
|
213 |
+
-6.2680e-02,
|
214 |
+
-7.2855e-02,
|
215 |
+
-1.1275e-01,
|
216 |
+
-1.8433e-01,
|
217 |
+
1.4693e-01,
|
218 |
+
4.0366e-02,
|
219 |
+
6.6879e-02,
|
220 |
+
-8.5653e-03,
|
221 |
+
1.0663e-01,
|
222 |
+
-1.2342e-01,
|
223 |
+
2.5350e-01,
|
224 |
+
-3.2227e-02,
|
225 |
+
9.9404e-02,
|
226 |
+
3.7340e-02,
|
227 |
+
4.5462e-04,
|
228 |
+
-2.3015e-01,
|
229 |
+
4.9006e-02,
|
230 |
+
1.0079e-01,
|
231 |
+
-4.7179e-02,
|
232 |
+
6.7642e-02,
|
233 |
+
-1.0833e-01,
|
234 |
+
1.0030e-01,
|
235 |
+
1.2838e-01,
|
236 |
+
-9.2911e-03,
|
237 |
+
1.2342e-01,
|
238 |
+
-4.8455e-02,
|
239 |
+
5.3904e-03,
|
240 |
+
4.5178e-02,
|
241 |
+
3.8961e-02,
|
242 |
+
1.3383e-01,
|
243 |
+
-1.2236e-02,
|
244 |
+
8.2026e-03,
|
245 |
+
4.3735e-03,
|
246 |
+
-7.1725e-02,
|
247 |
+
6.4360e-02,
|
248 |
+
1.0004e-01,
|
249 |
+
6.6840e-02,
|
250 |
+
6.5649e-02,
|
251 |
+
-1.3978e-02,
|
252 |
+
1.2810e-01,
|
253 |
+
4.4325e-03,
|
254 |
+
1.1136e-01,
|
255 |
+
-1.7329e-01,
|
256 |
+
-3.4472e-02,
|
257 |
+
-1.4066e-01,
|
258 |
+
1.5641e-02,
|
259 |
+
-3.3600e-02,
|
260 |
+
-7.6192e-02,
|
261 |
+
5.3085e-02,
|
262 |
+
-7.2859e-03,
|
263 |
+
2.8798e-02,
|
264 |
+
-3.3748e-02,
|
265 |
+
-7.7591e-02,
|
266 |
+
-4.0927e-02,
|
267 |
+
-3.6577e-02,
|
268 |
+
1.4012e-02,
|
269 |
+
-8.1780e-02,
|
270 |
+
-4.6315e-03,
|
271 |
+
-1.6508e-02,
|
272 |
+
-2.4506e-02,
|
273 |
+
1.5122e-01,
|
274 |
+
7.8270e-02,
|
275 |
+
8.6502e-02,
|
276 |
+
-2.4651e-02,
|
277 |
+
-1.0286e-01,
|
278 |
+
-1.2171e-02,
|
279 |
+
-7.9000e-02,
|
280 |
+
1.1161e-01,
|
281 |
+
],
|
282 |
+
[
|
283 |
+
6.4320e-02,
|
284 |
+
-2.6815e-02,
|
285 |
+
1.2390e-01,
|
286 |
+
8.6642e-02,
|
287 |
+
5.3320e-02,
|
288 |
+
9.1074e-02,
|
289 |
+
-8.9753e-02,
|
290 |
+
1.6141e-02,
|
291 |
+
-5.0281e-02,
|
292 |
+
1.0177e-01,
|
293 |
+
4.5343e-02,
|
294 |
+
9.1281e-02,
|
295 |
+
-8.2592e-03,
|
296 |
+
-1.4100e-02,
|
297 |
+
-4.7048e-02,
|
298 |
+
-8.6034e-02,
|
299 |
+
-1.1608e-01,
|
300 |
+
-8.4754e-02,
|
301 |
+
1.0302e-01,
|
302 |
+
-1.2210e-02,
|
303 |
+
8.5147e-02,
|
304 |
+
1.3103e-01,
|
305 |
+
-3.3592e-03,
|
306 |
+
-1.4328e-02,
|
307 |
+
-4.6128e-03,
|
308 |
+
2.1401e-02,
|
309 |
+
-1.7464e-01,
|
310 |
+
-3.9111e-02,
|
311 |
+
2.0886e-02,
|
312 |
+
8.9284e-02,
|
313 |
+
1.3262e-01,
|
314 |
+
7.0918e-02,
|
315 |
+
-1.3693e-02,
|
316 |
+
-9.7673e-02,
|
317 |
+
-5.3411e-02,
|
318 |
+
-6.7563e-02,
|
319 |
+
2.3017e-02,
|
320 |
+
-3.4614e-02,
|
321 |
+
3.6464e-02,
|
322 |
+
-4.6408e-02,
|
323 |
+
1.4866e-01,
|
324 |
+
-2.1191e-01,
|
325 |
+
-6.4368e-02,
|
326 |
+
-3.0555e-02,
|
327 |
+
7.2177e-02,
|
328 |
+
2.4685e-02,
|
329 |
+
8.6115e-02,
|
330 |
+
-5.8688e-02,
|
331 |
+
-2.8230e-03,
|
332 |
+
1.1166e-01,
|
333 |
+
1.8380e-01,
|
334 |
+
3.6462e-02,
|
335 |
+
-1.4943e-02,
|
336 |
+
-1.4276e-01,
|
337 |
+
1.0795e-01,
|
338 |
+
1.9204e-02,
|
339 |
+
-6.5320e-02,
|
340 |
+
1.0561e-01,
|
341 |
+
-1.3642e-01,
|
342 |
+
-4.3444e-02,
|
343 |
+
-6.4725e-02,
|
344 |
+
-1.3094e-01,
|
345 |
+
1.9447e-02,
|
346 |
+
-1.3199e-01,
|
347 |
+
8.7880e-02,
|
348 |
+
5.8078e-02,
|
349 |
+
-2.5612e-02,
|
350 |
+
7.7620e-02,
|
351 |
+
-2.5044e-02,
|
352 |
+
1.0772e-02,
|
353 |
+
6.5417e-02,
|
354 |
+
8.2137e-02,
|
355 |
+
-2.8482e-02,
|
356 |
+
5.5003e-02,
|
357 |
+
-1.1163e-01,
|
358 |
+
1.7200e-03,
|
359 |
+
-1.0106e-01,
|
360 |
+
-1.8413e-02,
|
361 |
+
1.2838e-01,
|
362 |
+
-1.2991e-01,
|
363 |
+
-1.8546e-02,
|
364 |
+
1.0517e-01,
|
365 |
+
1.0279e-01,
|
366 |
+
-8.1887e-02,
|
367 |
+
1.0885e-01,
|
368 |
+
-1.0635e-01,
|
369 |
+
1.2035e-01,
|
370 |
+
1.1769e-01,
|
371 |
+
-2.8768e-02,
|
372 |
+
-3.3413e-02,
|
373 |
+
1.3779e-01,
|
374 |
+
1.4403e-02,
|
375 |
+
2.3429e-02,
|
376 |
+
-1.2761e-01,
|
377 |
+
7.2160e-02,
|
378 |
+
-1.0512e-01,
|
379 |
+
-1.7202e-02,
|
380 |
+
5.3549e-02,
|
381 |
+
5.5205e-02,
|
382 |
+
9.2863e-02,
|
383 |
+
-2.3728e-02,
|
384 |
+
-5.1368e-02,
|
385 |
+
-3.7719e-02,
|
386 |
+
-4.7308e-02,
|
387 |
+
-2.2489e-02,
|
388 |
+
4.5195e-02,
|
389 |
+
1.0398e-01,
|
390 |
+
-2.2197e-02,
|
391 |
+
-1.7208e-01,
|
392 |
+
7.4649e-02,
|
393 |
+
-7.7925e-02,
|
394 |
+
-6.4237e-02,
|
395 |
+
2.8195e-02,
|
396 |
+
2.2692e-01,
|
397 |
+
-9.7749e-02,
|
398 |
+
2.4283e-01,
|
399 |
+
-4.0124e-02,
|
400 |
+
1.8797e-02,
|
401 |
+
-6.1516e-02,
|
402 |
+
6.5331e-03,
|
403 |
+
1.3717e-01,
|
404 |
+
9.9761e-02,
|
405 |
+
5.4705e-02,
|
406 |
+
3.5325e-02,
|
407 |
+
1.9071e-01,
|
408 |
+
-6.1137e-02,
|
409 |
+
1.6656e-01,
|
410 |
+
3.4067e-02,
|
411 |
+
],
|
412 |
+
[
|
413 |
+
1.0896e-01,
|
414 |
+
-9.4366e-03,
|
415 |
+
1.2956e-01,
|
416 |
+
7.8127e-02,
|
417 |
+
5.5422e-02,
|
418 |
+
3.9155e-02,
|
419 |
+
-5.8379e-03,
|
420 |
+
-4.4257e-02,
|
421 |
+
-7.5182e-02,
|
422 |
+
1.0452e-01,
|
423 |
+
4.4595e-02,
|
424 |
+
2.0972e-02,
|
425 |
+
1.1071e-01,
|
426 |
+
7.4710e-02,
|
427 |
+
-7.5500e-02,
|
428 |
+
-5.3393e-02,
|
429 |
+
-1.5478e-02,
|
430 |
+
-5.4455e-03,
|
431 |
+
5.6779e-02,
|
432 |
+
-6.3919e-02,
|
433 |
+
5.1792e-02,
|
434 |
+
1.2070e-01,
|
435 |
+
-5.3707e-02,
|
436 |
+
4.5715e-02,
|
437 |
+
-9.3062e-02,
|
438 |
+
3.0224e-02,
|
439 |
+
-1.5892e-01,
|
440 |
+
-2.1702e-02,
|
441 |
+
1.7942e-03,
|
442 |
+
1.4574e-01,
|
443 |
+
2.0721e-01,
|
444 |
+
-2.8224e-02,
|
445 |
+
-5.8104e-02,
|
446 |
+
-1.1645e-01,
|
447 |
+
-1.1515e-01,
|
448 |
+
-1.5202e-01,
|
449 |
+
-3.9751e-02,
|
450 |
+
6.0342e-02,
|
451 |
+
7.8182e-02,
|
452 |
+
-2.1132e-02,
|
453 |
+
9.6468e-02,
|
454 |
+
-5.3148e-02,
|
455 |
+
-3.0343e-02,
|
456 |
+
7.9363e-02,
|
457 |
+
1.0752e-01,
|
458 |
+
3.1086e-02,
|
459 |
+
1.9322e-02,
|
460 |
+
-1.1134e-01,
|
461 |
+
1.6342e-02,
|
462 |
+
3.0358e-02,
|
463 |
+
1.8543e-01,
|
464 |
+
5.5353e-02,
|
465 |
+
-8.6656e-02,
|
466 |
+
-1.5650e-01,
|
467 |
+
1.2087e-01,
|
468 |
+
-3.7852e-02,
|
469 |
+
-6.9116e-02,
|
470 |
+
5.9981e-03,
|
471 |
+
1.9205e-02,
|
472 |
+
-1.0314e-01,
|
473 |
+
-6.8082e-02,
|
474 |
+
-1.3078e-01,
|
475 |
+
3.8448e-02,
|
476 |
+
-9.2233e-02,
|
477 |
+
1.0965e-01,
|
478 |
+
6.6332e-02,
|
479 |
+
-2.5805e-02,
|
480 |
+
1.2299e-01,
|
481 |
+
2.8629e-02,
|
482 |
+
-4.4949e-02,
|
483 |
+
4.5560e-02,
|
484 |
+
1.0507e-01,
|
485 |
+
-1.0271e-01,
|
486 |
+
1.6237e-02,
|
487 |
+
-1.4555e-01,
|
488 |
+
-4.5335e-02,
|
489 |
+
-1.3477e-01,
|
490 |
+
1.0230e-02,
|
491 |
+
1.2380e-01,
|
492 |
+
-1.0681e-01,
|
493 |
+
1.4412e-02,
|
494 |
+
1.2396e-01,
|
495 |
+
8.5290e-02,
|
496 |
+
-2.5138e-02,
|
497 |
+
1.0191e-01,
|
498 |
+
-1.3413e-01,
|
499 |
+
8.5871e-02,
|
500 |
+
1.3389e-01,
|
501 |
+
-3.6357e-02,
|
502 |
+
-3.9740e-02,
|
503 |
+
2.1128e-01,
|
504 |
+
1.0263e-02,
|
505 |
+
2.5547e-02,
|
506 |
+
-7.0139e-02,
|
507 |
+
1.0178e-01,
|
508 |
+
-1.2729e-01,
|
509 |
+
-1.0717e-01,
|
510 |
+
-4.9394e-02,
|
511 |
+
7.7645e-02,
|
512 |
+
7.4589e-02,
|
513 |
+
-8.2835e-02,
|
514 |
+
-4.2227e-02,
|
515 |
+
-3.6417e-02,
|
516 |
+
-2.2900e-02,
|
517 |
+
-2.1010e-02,
|
518 |
+
2.7898e-02,
|
519 |
+
2.7314e-02,
|
520 |
+
2.2172e-02,
|
521 |
+
-7.1122e-02,
|
522 |
+
5.1570e-02,
|
523 |
+
2.1860e-02,
|
524 |
+
-3.5103e-03,
|
525 |
+
-5.4524e-02,
|
526 |
+
1.7485e-01,
|
527 |
+
-8.3810e-02,
|
528 |
+
2.3868e-01,
|
529 |
+
5.9468e-02,
|
530 |
+
-2.6706e-02,
|
531 |
+
-2.6617e-02,
|
532 |
+
3.3851e-02,
|
533 |
+
6.3651e-02,
|
534 |
+
1.0611e-01,
|
535 |
+
9.6252e-02,
|
536 |
+
-6.8701e-02,
|
537 |
+
1.8108e-01,
|
538 |
+
-1.0178e-01,
|
539 |
+
1.6935e-01,
|
540 |
+
5.9301e-02,
|
541 |
+
],
|
542 |
+
[
|
543 |
+
1.3364e-01,
|
544 |
+
6.6797e-02,
|
545 |
+
1.0182e-01,
|
546 |
+
6.1569e-02,
|
547 |
+
-1.4169e-04,
|
548 |
+
1.1567e-01,
|
549 |
+
-3.1255e-03,
|
550 |
+
-8.9336e-02,
|
551 |
+
5.3206e-03,
|
552 |
+
1.7179e-01,
|
553 |
+
1.3974e-01,
|
554 |
+
-6.5797e-02,
|
555 |
+
1.2566e-01,
|
556 |
+
6.1290e-02,
|
557 |
+
-1.3671e-01,
|
558 |
+
-1.1113e-01,
|
559 |
+
1.6596e-01,
|
560 |
+
6.2694e-02,
|
561 |
+
-1.6573e-02,
|
562 |
+
-1.8648e-02,
|
563 |
+
2.1086e-02,
|
564 |
+
9.6320e-03,
|
565 |
+
-1.0017e-01,
|
566 |
+
2.3561e-02,
|
567 |
+
-6.2797e-02,
|
568 |
+
2.1202e-02,
|
569 |
+
-1.3333e-01,
|
570 |
+
1.4728e-01,
|
571 |
+
1.9824e-03,
|
572 |
+
1.6832e-01,
|
573 |
+
1.7138e-01,
|
574 |
+
4.6578e-02,
|
575 |
+
-1.2989e-01,
|
576 |
+
3.2167e-02,
|
577 |
+
-7.7753e-02,
|
578 |
+
-1.1548e-01,
|
579 |
+
4.3367e-02,
|
580 |
+
-4.5640e-02,
|
581 |
+
4.3583e-02,
|
582 |
+
-8.9393e-03,
|
583 |
+
5.3231e-02,
|
584 |
+
-4.8284e-02,
|
585 |
+
3.1841e-04,
|
586 |
+
6.6374e-02,
|
587 |
+
7.7363e-02,
|
588 |
+
4.0000e-02,
|
589 |
+
1.5414e-02,
|
590 |
+
-9.6156e-02,
|
591 |
+
1.1389e-01,
|
592 |
+
7.1118e-02,
|
593 |
+
3.0042e-02,
|
594 |
+
5.9752e-02,
|
595 |
+
-6.4565e-02,
|
596 |
+
-1.2914e-01,
|
597 |
+
1.1048e-01,
|
598 |
+
1.2409e-02,
|
599 |
+
-9.9385e-02,
|
600 |
+
1.8671e-02,
|
601 |
+
2.1383e-02,
|
602 |
+
3.7012e-03,
|
603 |
+
-1.1497e-01,
|
604 |
+
-6.8653e-02,
|
605 |
+
3.0582e-02,
|
606 |
+
-1.1567e-01,
|
607 |
+
1.4165e-01,
|
608 |
+
3.7493e-02,
|
609 |
+
-6.0779e-02,
|
610 |
+
1.0989e-01,
|
611 |
+
8.6001e-02,
|
612 |
+
-5.6139e-02,
|
613 |
+
2.0710e-02,
|
614 |
+
9.8577e-02,
|
615 |
+
-9.9427e-02,
|
616 |
+
5.8372e-02,
|
617 |
+
-1.3443e-01,
|
618 |
+
-1.3021e-02,
|
619 |
+
-1.3802e-01,
|
620 |
+
7.6053e-02,
|
621 |
+
1.2181e-01,
|
622 |
+
-8.7719e-02,
|
623 |
+
1.0967e-02,
|
624 |
+
1.3160e-01,
|
625 |
+
4.7032e-02,
|
626 |
+
-6.3351e-02,
|
627 |
+
7.1883e-02,
|
628 |
+
-9.7565e-02,
|
629 |
+
1.4424e-01,
|
630 |
+
1.2353e-01,
|
631 |
+
-6.1527e-02,
|
632 |
+
2.4263e-02,
|
633 |
+
2.9356e-01,
|
634 |
+
6.2813e-02,
|
635 |
+
-4.5265e-03,
|
636 |
+
-1.0213e-01,
|
637 |
+
1.4227e-02,
|
638 |
+
-7.9267e-02,
|
639 |
+
-1.0845e-01,
|
640 |
+
-2.0014e-02,
|
641 |
+
2.8542e-02,
|
642 |
+
9.7207e-02,
|
643 |
+
-2.5234e-02,
|
644 |
+
-7.3668e-02,
|
645 |
+
-3.0084e-02,
|
646 |
+
-1.2958e-02,
|
647 |
+
-3.9597e-02,
|
648 |
+
-7.2243e-02,
|
649 |
+
5.3054e-02,
|
650 |
+
3.1470e-03,
|
651 |
+
-1.9800e-02,
|
652 |
+
1.3476e-01,
|
653 |
+
-1.6873e-02,
|
654 |
+
5.2286e-02,
|
655 |
+
2.0254e-02,
|
656 |
+
1.0554e-01,
|
657 |
+
-3.0395e-02,
|
658 |
+
8.6349e-02,
|
659 |
+
7.6580e-02,
|
660 |
+
-3.0139e-02,
|
661 |
+
-4.8131e-02,
|
662 |
+
-4.5770e-02,
|
663 |
+
1.5154e-01,
|
664 |
+
1.1276e-01,
|
665 |
+
5.7244e-02,
|
666 |
+
8.0574e-02,
|
667 |
+
1.5610e-01,
|
668 |
+
-1.5523e-01,
|
669 |
+
1.0428e-01,
|
670 |
+
5.7947e-02,
|
671 |
+
],
|
672 |
+
[
|
673 |
+
7.0440e-02,
|
674 |
+
1.4300e-01,
|
675 |
+
6.0559e-02,
|
676 |
+
1.9177e-02,
|
677 |
+
-9.0313e-02,
|
678 |
+
1.7104e-01,
|
679 |
+
-5.1137e-02,
|
680 |
+
-1.0229e-01,
|
681 |
+
-2.8831e-02,
|
682 |
+
1.5385e-01,
|
683 |
+
-8.4017e-03,
|
684 |
+
-4.9185e-03,
|
685 |
+
1.0820e-01,
|
686 |
+
1.0022e-01,
|
687 |
+
-1.9284e-01,
|
688 |
+
-2.7293e-02,
|
689 |
+
4.9526e-02,
|
690 |
+
5.5152e-02,
|
691 |
+
-6.7003e-02,
|
692 |
+
-7.0313e-03,
|
693 |
+
-3.3208e-02,
|
694 |
+
1.3815e-02,
|
695 |
+
-6.0694e-02,
|
696 |
+
6.2041e-02,
|
697 |
+
-3.2288e-02,
|
698 |
+
1.1629e-01,
|
699 |
+
-7.5270e-02,
|
700 |
+
2.1824e-01,
|
701 |
+
-2.5215e-03,
|
702 |
+
1.8179e-01,
|
703 |
+
1.5514e-01,
|
704 |
+
1.0494e-01,
|
705 |
+
-1.2390e-01,
|
706 |
+
-1.2241e-03,
|
707 |
+
6.1079e-04,
|
708 |
+
-5.8730e-02,
|
709 |
+
6.1313e-02,
|
710 |
+
-7.8853e-02,
|
711 |
+
6.0292e-02,
|
712 |
+
-9.1497e-04,
|
713 |
+
7.9087e-02,
|
714 |
+
-1.8246e-02,
|
715 |
+
5.0215e-03,
|
716 |
+
3.5083e-02,
|
717 |
+
5.9616e-02,
|
718 |
+
5.9520e-02,
|
719 |
+
6.0224e-02,
|
720 |
+
-1.3079e-01,
|
721 |
+
1.6500e-01,
|
722 |
+
4.4308e-03,
|
723 |
+
4.2712e-02,
|
724 |
+
5.5916e-02,
|
725 |
+
-5.4616e-02,
|
726 |
+
-8.5617e-02,
|
727 |
+
1.1235e-01,
|
728 |
+
6.5911e-03,
|
729 |
+
-6.1463e-02,
|
730 |
+
3.7832e-02,
|
731 |
+
3.4189e-02,
|
732 |
+
-1.1295e-02,
|
733 |
+
-8.0972e-02,
|
734 |
+
-1.0051e-02,
|
735 |
+
-2.6856e-02,
|
736 |
+
-7.9570e-02,
|
737 |
+
1.2776e-01,
|
738 |
+
6.5826e-02,
|
739 |
+
-3.1759e-02,
|
740 |
+
9.6016e-02,
|
741 |
+
6.7249e-02,
|
742 |
+
-4.5115e-02,
|
743 |
+
6.3695e-03,
|
744 |
+
1.2092e-01,
|
745 |
+
-1.3821e-01,
|
746 |
+
-9.7066e-02,
|
747 |
+
-1.5063e-02,
|
748 |
+
2.4618e-02,
|
749 |
+
-1.9589e-01,
|
750 |
+
5.8625e-02,
|
751 |
+
1.7886e-01,
|
752 |
+
-6.3740e-02,
|
753 |
+
-1.7241e-02,
|
754 |
+
7.3394e-02,
|
755 |
+
5.8903e-02,
|
756 |
+
-1.6557e-02,
|
757 |
+
-1.9226e-02,
|
758 |
+
-1.0912e-01,
|
759 |
+
8.7902e-02,
|
760 |
+
6.4426e-02,
|
761 |
+
4.8019e-02,
|
762 |
+
8.1223e-02,
|
763 |
+
2.9888e-01,
|
764 |
+
8.7458e-02,
|
765 |
+
4.4167e-02,
|
766 |
+
-1.3228e-01,
|
767 |
+
5.9629e-02,
|
768 |
+
-1.0696e-01,
|
769 |
+
-1.4102e-01,
|
770 |
+
-5.2509e-02,
|
771 |
+
-1.9981e-02,
|
772 |
+
1.6788e-01,
|
773 |
+
9.7499e-02,
|
774 |
+
-5.4125e-02,
|
775 |
+
-8.2383e-02,
|
776 |
+
-6.3908e-02,
|
777 |
+
-6.8830e-02,
|
778 |
+
-1.2622e-01,
|
779 |
+
3.1651e-02,
|
780 |
+
4.4592e-02,
|
781 |
+
-1.3325e-02,
|
782 |
+
1.1260e-01,
|
783 |
+
-3.9567e-02,
|
784 |
+
6.9631e-03,
|
785 |
+
1.4943e-01,
|
786 |
+
8.6930e-02,
|
787 |
+
-3.6171e-03,
|
788 |
+
-5.6886e-02,
|
789 |
+
-8.3102e-03,
|
790 |
+
-2.6001e-02,
|
791 |
+
-1.5187e-02,
|
792 |
+
-1.8835e-02,
|
793 |
+
2.3583e-02,
|
794 |
+
9.5520e-02,
|
795 |
+
-3.4944e-02,
|
796 |
+
4.5537e-02,
|
797 |
+
6.1444e-02,
|
798 |
+
-1.7165e-01,
|
799 |
+
1.0230e-01,
|
800 |
+
2.0319e-02,
|
801 |
+
],
|
802 |
+
[
|
803 |
+
7.7065e-02,
|
804 |
+
1.4466e-01,
|
805 |
+
1.0796e-01,
|
806 |
+
9.7362e-03,
|
807 |
+
-9.3062e-02,
|
808 |
+
2.0065e-01,
|
809 |
+
-9.3982e-03,
|
810 |
+
-1.2871e-01,
|
811 |
+
-4.6724e-02,
|
812 |
+
1.6573e-01,
|
813 |
+
-1.7444e-02,
|
814 |
+
-3.1211e-02,
|
815 |
+
9.7404e-02,
|
816 |
+
9.6222e-02,
|
817 |
+
-1.4772e-01,
|
818 |
+
-5.6838e-02,
|
819 |
+
9.6276e-02,
|
820 |
+
7.7819e-02,
|
821 |
+
-1.1884e-01,
|
822 |
+
-4.5898e-02,
|
823 |
+
-7.3665e-02,
|
824 |
+
2.1005e-02,
|
825 |
+
-2.8032e-02,
|
826 |
+
7.0900e-02,
|
827 |
+
-7.7625e-02,
|
828 |
+
7.0269e-02,
|
829 |
+
-7.0747e-02,
|
830 |
+
2.5605e-01,
|
831 |
+
1.9427e-04,
|
832 |
+
1.4614e-01,
|
833 |
+
1.6723e-01,
|
834 |
+
1.0016e-01,
|
835 |
+
-7.8961e-02,
|
836 |
+
1.3307e-02,
|
837 |
+
-1.1207e-02,
|
838 |
+
-7.1492e-02,
|
839 |
+
7.5561e-02,
|
840 |
+
-1.3290e-02,
|
841 |
+
4.4527e-02,
|
842 |
+
-2.4224e-02,
|
843 |
+
8.7846e-02,
|
844 |
+
4.7492e-02,
|
845 |
+
-7.0398e-02,
|
846 |
+
-2.6663e-02,
|
847 |
+
4.9730e-02,
|
848 |
+
6.6743e-02,
|
849 |
+
3.1060e-02,
|
850 |
+
-7.8352e-02,
|
851 |
+
1.0100e-01,
|
852 |
+
6.4963e-02,
|
853 |
+
1.6746e-02,
|
854 |
+
3.0324e-02,
|
855 |
+
-2.6583e-02,
|
856 |
+
-7.8028e-02,
|
857 |
+
7.0180e-02,
|
858 |
+
3.8924e-02,
|
859 |
+
-8.5861e-02,
|
860 |
+
-3.3792e-02,
|
861 |
+
6.1542e-02,
|
862 |
+
1.6180e-02,
|
863 |
+
-7.7865e-02,
|
864 |
+
3.9551e-02,
|
865 |
+
2.9772e-02,
|
866 |
+
-7.0824e-02,
|
867 |
+
1.5235e-01,
|
868 |
+
4.8718e-02,
|
869 |
+
1.5973e-03,
|
870 |
+
8.7719e-02,
|
871 |
+
7.7414e-02,
|
872 |
+
-6.4385e-02,
|
873 |
+
-6.4330e-02,
|
874 |
+
1.3965e-01,
|
875 |
+
-1.6355e-01,
|
876 |
+
-6.5261e-02,
|
877 |
+
-6.2693e-02,
|
878 |
+
4.9435e-02,
|
879 |
+
-1.5245e-01,
|
880 |
+
6.6557e-02,
|
881 |
+
1.5213e-01,
|
882 |
+
-8.2073e-02,
|
883 |
+
1.4664e-02,
|
884 |
+
8.4507e-02,
|
885 |
+
3.0684e-02,
|
886 |
+
-8.7932e-02,
|
887 |
+
1.9927e-02,
|
888 |
+
-7.1788e-02,
|
889 |
+
9.4965e-02,
|
890 |
+
3.9220e-02,
|
891 |
+
4.5944e-02,
|
892 |
+
8.7249e-02,
|
893 |
+
3.3315e-01,
|
894 |
+
5.9872e-02,
|
895 |
+
2.6362e-02,
|
896 |
+
-1.7888e-01,
|
897 |
+
-1.6042e-02,
|
898 |
+
-9.4593e-02,
|
899 |
+
-1.7915e-01,
|
900 |
+
-2.9888e-02,
|
901 |
+
-4.3776e-02,
|
902 |
+
1.1388e-01,
|
903 |
+
2.3778e-02,
|
904 |
+
-4.0233e-02,
|
905 |
+
-4.7893e-02,
|
906 |
+
-4.4371e-02,
|
907 |
+
-2.7491e-02,
|
908 |
+
-9.6716e-02,
|
909 |
+
-2.0120e-02,
|
910 |
+
5.6864e-02,
|
911 |
+
1.8953e-02,
|
912 |
+
1.2741e-01,
|
913 |
+
-5.3045e-02,
|
914 |
+
3.2240e-02,
|
915 |
+
1.4479e-01,
|
916 |
+
9.5315e-02,
|
917 |
+
-2.7717e-02,
|
918 |
+
-5.7349e-02,
|
919 |
+
3.3824e-03,
|
920 |
+
-3.5642e-02,
|
921 |
+
-1.6905e-02,
|
922 |
+
-4.5765e-02,
|
923 |
+
1.1481e-02,
|
924 |
+
4.2545e-02,
|
925 |
+
1.2632e-02,
|
926 |
+
4.5401e-02,
|
927 |
+
7.7769e-02,
|
928 |
+
-1.7107e-01,
|
929 |
+
7.7265e-02,
|
930 |
+
1.3922e-02,
|
931 |
+
],
|
932 |
+
[
|
933 |
+
-2.5666e-02,
|
934 |
+
9.8268e-02,
|
935 |
+
2.1571e-01,
|
936 |
+
6.8094e-02,
|
937 |
+
-1.0440e-01,
|
938 |
+
1.4299e-01,
|
939 |
+
6.5751e-02,
|
940 |
+
-5.0693e-02,
|
941 |
+
-5.3796e-02,
|
942 |
+
1.5239e-01,
|
943 |
+
2.9566e-02,
|
944 |
+
-7.9492e-02,
|
945 |
+
9.3274e-02,
|
946 |
+
7.6112e-02,
|
947 |
+
-1.8187e-02,
|
948 |
+
-1.1190e-01,
|
949 |
+
9.7962e-02,
|
950 |
+
-2.8204e-02,
|
951 |
+
-8.1216e-02,
|
952 |
+
-5.5618e-02,
|
953 |
+
-6.2378e-02,
|
954 |
+
4.4238e-02,
|
955 |
+
-1.6572e-02,
|
956 |
+
-3.4035e-02,
|
957 |
+
-8.8068e-02,
|
958 |
+
1.4164e-02,
|
959 |
+
-2.6908e-02,
|
960 |
+
1.9650e-01,
|
961 |
+
6.8845e-03,
|
962 |
+
8.7550e-02,
|
963 |
+
1.7410e-01,
|
964 |
+
1.0088e-01,
|
965 |
+
-1.1340e-02,
|
966 |
+
3.2057e-04,
|
967 |
+
-5.5130e-02,
|
968 |
+
-2.5234e-02,
|
969 |
+
8.2460e-02,
|
970 |
+
-6.0768e-02,
|
971 |
+
1.2448e-01,
|
972 |
+
6.8736e-02,
|
973 |
+
4.6176e-02,
|
974 |
+
1.0866e-01,
|
975 |
+
4.9560e-02,
|
976 |
+
-5.8322e-02,
|
977 |
+
4.4106e-02,
|
978 |
+
2.0739e-02,
|
979 |
+
-9.0032e-02,
|
980 |
+
-5.8815e-02,
|
981 |
+
7.8127e-03,
|
982 |
+
1.7999e-01,
|
983 |
+
1.2519e-01,
|
984 |
+
7.1377e-02,
|
985 |
+
9.3219e-02,
|
986 |
+
-1.3311e-01,
|
987 |
+
6.0305e-02,
|
988 |
+
5.9400e-02,
|
989 |
+
-1.6119e-01,
|
990 |
+
5.4173e-02,
|
991 |
+
-5.8663e-02,
|
992 |
+
-4.8149e-02,
|
993 |
+
1.6295e-02,
|
994 |
+
-6.9787e-02,
|
995 |
+
5.7512e-03,
|
996 |
+
-8.9745e-03,
|
997 |
+
1.3492e-01,
|
998 |
+
3.0659e-02,
|
999 |
+
-6.8611e-02,
|
1000 |
+
2.1200e-02,
|
1001 |
+
8.5522e-02,
|
1002 |
+
-4.3482e-02,
|
1003 |
+
-8.4601e-02,
|
1004 |
+
1.4191e-01,
|
1005 |
+
-1.5514e-01,
|
1006 |
+
-5.8989e-03,
|
1007 |
+
-4.5591e-02,
|
1008 |
+
6.4905e-02,
|
1009 |
+
-1.3198e-01,
|
1010 |
+
1.3764e-01,
|
1011 |
+
9.5549e-02,
|
1012 |
+
-9.4689e-02,
|
1013 |
+
-1.9705e-02,
|
1014 |
+
2.1147e-01,
|
1015 |
+
-9.8519e-03,
|
1016 |
+
-7.7839e-02,
|
1017 |
+
6.1447e-02,
|
1018 |
+
-6.4708e-02,
|
1019 |
+
3.1579e-03,
|
1020 |
+
7.6588e-02,
|
1021 |
+
-1.2452e-01,
|
1022 |
+
-6.1076e-02,
|
1023 |
+
2.5150e-01,
|
1024 |
+
2.3101e-02,
|
1025 |
+
-1.3632e-02,
|
1026 |
+
-8.5695e-02,
|
1027 |
+
-8.5841e-02,
|
1028 |
+
-1.3152e-01,
|
1029 |
+
-1.5294e-01,
|
1030 |
+
-4.4509e-03,
|
1031 |
+
8.6619e-02,
|
1032 |
+
-1.0974e-02,
|
1033 |
+
-3.9592e-02,
|
1034 |
+
-3.0472e-02,
|
1035 |
+
-1.4011e-01,
|
1036 |
+
8.6485e-03,
|
1037 |
+
-1.3633e-02,
|
1038 |
+
-1.7940e-02,
|
1039 |
+
3.3016e-02,
|
1040 |
+
-5.7245e-02,
|
1041 |
+
1.0200e-01,
|
1042 |
+
1.2807e-01,
|
1043 |
+
1.5249e-02,
|
1044 |
+
-1.2197e-02,
|
1045 |
+
-1.6867e-02,
|
1046 |
+
3.4516e-02,
|
1047 |
+
-9.0908e-02,
|
1048 |
+
-2.6167e-02,
|
1049 |
+
2.2975e-01,
|
1050 |
+
4.2693e-02,
|
1051 |
+
2.5415e-03,
|
1052 |
+
7.1921e-03,
|
1053 |
+
1.2855e-01,
|
1054 |
+
5.5747e-03,
|
1055 |
+
-2.7843e-02,
|
1056 |
+
2.4283e-02,
|
1057 |
+
-1.3484e-02,
|
1058 |
+
-1.5948e-01,
|
1059 |
+
2.1127e-02,
|
1060 |
+
3.8017e-02,
|
1061 |
+
],
|
1062 |
+
[
|
1063 |
+
5.8410e-02,
|
1064 |
+
3.7501e-02,
|
1065 |
+
1.7189e-01,
|
1066 |
+
4.5894e-02,
|
1067 |
+
-6.7739e-02,
|
1068 |
+
1.1421e-01,
|
1069 |
+
4.6982e-02,
|
1070 |
+
-1.2963e-01,
|
1071 |
+
-4.2804e-02,
|
1072 |
+
1.2137e-01,
|
1073 |
+
1.0761e-01,
|
1074 |
+
-7.2615e-02,
|
1075 |
+
1.1811e-01,
|
1076 |
+
1.1291e-01,
|
1077 |
+
-1.6041e-01,
|
1078 |
+
-6.6820e-02,
|
1079 |
+
1.9071e-01,
|
1080 |
+
-3.6201e-02,
|
1081 |
+
-1.0659e-01,
|
1082 |
+
-3.3226e-02,
|
1083 |
+
-2.6535e-02,
|
1084 |
+
7.8536e-02,
|
1085 |
+
-3.2975e-02,
|
1086 |
+
1.3015e-02,
|
1087 |
+
-1.0903e-01,
|
1088 |
+
-1.2502e-02,
|
1089 |
+
-7.0142e-02,
|
1090 |
+
1.6872e-01,
|
1091 |
+
-3.7569e-02,
|
1092 |
+
2.2090e-01,
|
1093 |
+
1.5620e-01,
|
1094 |
+
9.5620e-02,
|
1095 |
+
-7.9306e-02,
|
1096 |
+
7.8558e-02,
|
1097 |
+
-6.6709e-02,
|
1098 |
+
-6.6446e-02,
|
1099 |
+
3.1198e-02,
|
1100 |
+
-4.8808e-02,
|
1101 |
+
6.7798e-02,
|
1102 |
+
-4.9524e-02,
|
1103 |
+
1.2496e-01,
|
1104 |
+
3.1661e-02,
|
1105 |
+
4.0690e-02,
|
1106 |
+
-1.1341e-02,
|
1107 |
+
2.9852e-03,
|
1108 |
+
3.6166e-02,
|
1109 |
+
-1.1723e-01,
|
1110 |
+
-8.2746e-02,
|
1111 |
+
1.2874e-01,
|
1112 |
+
1.0894e-01,
|
1113 |
+
7.6219e-02,
|
1114 |
+
5.5564e-02,
|
1115 |
+
4.3571e-02,
|
1116 |
+
-1.4745e-01,
|
1117 |
+
5.1090e-02,
|
1118 |
+
-6.8233e-04,
|
1119 |
+
-1.7107e-01,
|
1120 |
+
-2.5612e-02,
|
1121 |
+
1.9185e-02,
|
1122 |
+
3.4466e-03,
|
1123 |
+
-2.5362e-02,
|
1124 |
+
-3.4807e-02,
|
1125 |
+
8.1003e-02,
|
1126 |
+
-2.1582e-02,
|
1127 |
+
1.1581e-01,
|
1128 |
+
-5.5891e-04,
|
1129 |
+
4.2455e-02,
|
1130 |
+
6.3277e-02,
|
1131 |
+
7.9868e-02,
|
1132 |
+
-2.0369e-02,
|
1133 |
+
-7.6229e-02,
|
1134 |
+
1.2525e-01,
|
1135 |
+
-1.4795e-01,
|
1136 |
+
5.8798e-03,
|
1137 |
+
-2.8584e-02,
|
1138 |
+
-3.2508e-04,
|
1139 |
+
-5.5666e-02,
|
1140 |
+
7.1217e-02,
|
1141 |
+
1.3122e-01,
|
1142 |
+
-1.8671e-02,
|
1143 |
+
-6.6402e-02,
|
1144 |
+
8.1978e-02,
|
1145 |
+
-5.5194e-02,
|
1146 |
+
-1.7259e-02,
|
1147 |
+
7.1373e-02,
|
1148 |
+
-2.4721e-02,
|
1149 |
+
1.0176e-01,
|
1150 |
+
1.7447e-02,
|
1151 |
+
-8.2872e-02,
|
1152 |
+
4.7707e-02,
|
1153 |
+
2.9338e-01,
|
1154 |
+
3.0481e-02,
|
1155 |
+
1.3437e-02,
|
1156 |
+
-1.1888e-01,
|
1157 |
+
-6.1243e-02,
|
1158 |
+
-8.7197e-02,
|
1159 |
+
-1.1085e-01,
|
1160 |
+
3.2847e-03,
|
1161 |
+
1.0611e-02,
|
1162 |
+
1.2908e-01,
|
1163 |
+
-2.9064e-02,
|
1164 |
+
4.5522e-03,
|
1165 |
+
-7.8045e-02,
|
1166 |
+
-1.4551e-02,
|
1167 |
+
-3.3958e-02,
|
1168 |
+
-1.3626e-01,
|
1169 |
+
1.0859e-01,
|
1170 |
+
-7.3438e-03,
|
1171 |
+
9.5942e-02,
|
1172 |
+
1.4176e-01,
|
1173 |
+
7.3675e-02,
|
1174 |
+
-2.3085e-03,
|
1175 |
+
-1.1689e-02,
|
1176 |
+
6.1119e-02,
|
1177 |
+
-9.3085e-02,
|
1178 |
+
-1.9003e-03,
|
1179 |
+
1.9013e-01,
|
1180 |
+
-2.5321e-02,
|
1181 |
+
-7.0616e-02,
|
1182 |
+
-3.7145e-02,
|
1183 |
+
1.2449e-01,
|
1184 |
+
5.3496e-02,
|
1185 |
+
6.4021e-02,
|
1186 |
+
2.2668e-02,
|
1187 |
+
7.3348e-02,
|
1188 |
+
-1.7717e-01,
|
1189 |
+
8.7206e-02,
|
1190 |
+
-9.0490e-03,
|
1191 |
+
],
|
1192 |
+
[
|
1193 |
+
1.0227e-01,
|
1194 |
+
4.4796e-02,
|
1195 |
+
4.0916e-02,
|
1196 |
+
1.2557e-01,
|
1197 |
+
6.2699e-02,
|
1198 |
+
8.8194e-02,
|
1199 |
+
1.0194e-02,
|
1200 |
+
-1.8886e-01,
|
1201 |
+
-2.6260e-02,
|
1202 |
+
1.8107e-01,
|
1203 |
+
1.1127e-01,
|
1204 |
+
-4.9960e-03,
|
1205 |
+
8.2291e-02,
|
1206 |
+
6.0932e-02,
|
1207 |
+
-1.3735e-01,
|
1208 |
+
-8.1350e-02,
|
1209 |
+
1.2948e-01,
|
1210 |
+
1.0171e-01,
|
1211 |
+
-7.5950e-02,
|
1212 |
+
4.7169e-02,
|
1213 |
+
3.5525e-03,
|
1214 |
+
-1.4790e-02,
|
1215 |
+
-3.9063e-02,
|
1216 |
+
-1.9754e-02,
|
1217 |
+
-4.6450e-02,
|
1218 |
+
4.9071e-03,
|
1219 |
+
-3.5914e-02,
|
1220 |
+
1.7644e-01,
|
1221 |
+
4.1860e-02,
|
1222 |
+
1.0857e-01,
|
1223 |
+
8.5257e-02,
|
1224 |
+
1.0368e-01,
|
1225 |
+
-1.7223e-01,
|
1226 |
+
4.6316e-02,
|
1227 |
+
-3.9480e-02,
|
1228 |
+
-9.5817e-02,
|
1229 |
+
1.5301e-03,
|
1230 |
+
-4.5519e-02,
|
1231 |
+
1.2380e-01,
|
1232 |
+
-3.0402e-02,
|
1233 |
+
4.9047e-02,
|
1234 |
+
3.4955e-02,
|
1235 |
+
-1.3018e-02,
|
1236 |
+
7.4193e-02,
|
1237 |
+
-3.0426e-02,
|
1238 |
+
1.8414e-02,
|
1239 |
+
-1.6606e-02,
|
1240 |
+
-1.6301e-01,
|
1241 |
+
1.5784e-01,
|
1242 |
+
1.3759e-01,
|
1243 |
+
3.1906e-02,
|
1244 |
+
2.9389e-02,
|
1245 |
+
-9.4501e-02,
|
1246 |
+
-1.9930e-01,
|
1247 |
+
1.3336e-01,
|
1248 |
+
3.0685e-02,
|
1249 |
+
-7.3809e-02,
|
1250 |
+
6.2165e-02,
|
1251 |
+
7.3050e-02,
|
1252 |
+
3.2870e-02,
|
1253 |
+
-1.2857e-01,
|
1254 |
+
-7.5806e-04,
|
1255 |
+
1.3985e-01,
|
1256 |
+
-5.5108e-02,
|
1257 |
+
9.2220e-02,
|
1258 |
+
7.2490e-02,
|
1259 |
+
-2.6251e-02,
|
1260 |
+
3.4508e-02,
|
1261 |
+
-3.1215e-02,
|
1262 |
+
-8.1111e-02,
|
1263 |
+
1.4316e-02,
|
1264 |
+
1.2390e-01,
|
1265 |
+
-9.6291e-03,
|
1266 |
+
6.4214e-02,
|
1267 |
+
-9.6013e-02,
|
1268 |
+
7.5809e-02,
|
1269 |
+
-1.5899e-01,
|
1270 |
+
8.6961e-02,
|
1271 |
+
1.5239e-03,
|
1272 |
+
-5.6370e-02,
|
1273 |
+
-4.3367e-02,
|
1274 |
+
1.5813e-02,
|
1275 |
+
9.7189e-04,
|
1276 |
+
-5.2946e-02,
|
1277 |
+
4.5950e-02,
|
1278 |
+
-1.0028e-01,
|
1279 |
+
1.1108e-01,
|
1280 |
+
9.0491e-03,
|
1281 |
+
-3.5540e-02,
|
1282 |
+
-1.2020e-02,
|
1283 |
+
2.2980e-01,
|
1284 |
+
2.7125e-02,
|
1285 |
+
-2.4191e-02,
|
1286 |
+
-1.1363e-01,
|
1287 |
+
-1.0109e-01,
|
1288 |
+
-1.4781e-01,
|
1289 |
+
-4.7656e-02,
|
1290 |
+
3.9481e-02,
|
1291 |
+
5.4198e-02,
|
1292 |
+
8.2908e-02,
|
1293 |
+
1.4034e-02,
|
1294 |
+
-1.8492e-02,
|
1295 |
+
-6.8612e-02,
|
1296 |
+
-4.8741e-02,
|
1297 |
+
1.1223e-02,
|
1298 |
+
3.9220e-02,
|
1299 |
+
5.4551e-04,
|
1300 |
+
6.5554e-02,
|
1301 |
+
4.3087e-02,
|
1302 |
+
1.4678e-01,
|
1303 |
+
-4.4496e-02,
|
1304 |
+
6.2379e-02,
|
1305 |
+
4.7876e-02,
|
1306 |
+
7.0156e-02,
|
1307 |
+
-6.4684e-02,
|
1308 |
+
6.1076e-02,
|
1309 |
+
1.4685e-01,
|
1310 |
+
-6.3639e-02,
|
1311 |
+
-8.7487e-02,
|
1312 |
+
-1.3756e-02,
|
1313 |
+
1.2724e-01,
|
1314 |
+
1.7404e-01,
|
1315 |
+
6.7980e-02,
|
1316 |
+
6.8036e-02,
|
1317 |
+
1.9786e-01,
|
1318 |
+
-9.2910e-02,
|
1319 |
+
1.9158e-01,
|
1320 |
+
4.2686e-02,
|
1321 |
+
],
|
1322 |
+
[
|
1323 |
+
4.7626e-02,
|
1324 |
+
9.3338e-02,
|
1325 |
+
9.8020e-02,
|
1326 |
+
9.2408e-02,
|
1327 |
+
1.8267e-02,
|
1328 |
+
1.9572e-02,
|
1329 |
+
1.1056e-01,
|
1330 |
+
-1.2639e-01,
|
1331 |
+
-3.1999e-02,
|
1332 |
+
1.3731e-01,
|
1333 |
+
1.4826e-01,
|
1334 |
+
-6.7136e-02,
|
1335 |
+
8.9095e-02,
|
1336 |
+
1.9683e-01,
|
1337 |
+
-6.5839e-02,
|
1338 |
+
-1.0708e-01,
|
1339 |
+
1.4414e-01,
|
1340 |
+
4.7389e-02,
|
1341 |
+
-7.9921e-02,
|
1342 |
+
2.7793e-02,
|
1343 |
+
9.7240e-02,
|
1344 |
+
3.8000e-03,
|
1345 |
+
-4.2359e-02,
|
1346 |
+
5.9870e-02,
|
1347 |
+
-8.2957e-02,
|
1348 |
+
-2.1429e-02,
|
1349 |
+
-5.1302e-02,
|
1350 |
+
7.6202e-02,
|
1351 |
+
3.5426e-02,
|
1352 |
+
8.1509e-02,
|
1353 |
+
1.0849e-01,
|
1354 |
+
2.1857e-01,
|
1355 |
+
-9.1445e-02,
|
1356 |
+
1.1869e-01,
|
1357 |
+
-1.1225e-02,
|
1358 |
+
-1.6530e-01,
|
1359 |
+
2.9216e-02,
|
1360 |
+
-7.2792e-02,
|
1361 |
+
2.9544e-02,
|
1362 |
+
5.3102e-02,
|
1363 |
+
2.7746e-02,
|
1364 |
+
1.8145e-01,
|
1365 |
+
4.4050e-02,
|
1366 |
+
8.2549e-02,
|
1367 |
+
2.3603e-02,
|
1368 |
+
1.1494e-02,
|
1369 |
+
-9.1516e-02,
|
1370 |
+
-6.2333e-02,
|
1371 |
+
1.0970e-01,
|
1372 |
+
1.4544e-01,
|
1373 |
+
-2.3549e-02,
|
1374 |
+
3.8348e-02,
|
1375 |
+
-8.8504e-03,
|
1376 |
+
-1.6986e-01,
|
1377 |
+
5.3215e-02,
|
1378 |
+
4.0085e-02,
|
1379 |
+
-1.4667e-01,
|
1380 |
+
8.6047e-02,
|
1381 |
+
4.7751e-02,
|
1382 |
+
-9.0753e-03,
|
1383 |
+
-8.0938e-02,
|
1384 |
+
7.1735e-02,
|
1385 |
+
1.1711e-01,
|
1386 |
+
-4.2525e-02,
|
1387 |
+
9.4244e-02,
|
1388 |
+
6.2260e-02,
|
1389 |
+
-8.4798e-02,
|
1390 |
+
-6.2766e-02,
|
1391 |
+
6.1025e-02,
|
1392 |
+
-7.7480e-02,
|
1393 |
+
-5.3010e-02,
|
1394 |
+
1.0182e-01,
|
1395 |
+
-7.1081e-03,
|
1396 |
+
1.4029e-01,
|
1397 |
+
-8.2788e-02,
|
1398 |
+
3.0182e-02,
|
1399 |
+
-1.4279e-01,
|
1400 |
+
4.7882e-02,
|
1401 |
+
3.2736e-02,
|
1402 |
+
1.0058e-02,
|
1403 |
+
-1.2673e-02,
|
1404 |
+
3.2723e-02,
|
1405 |
+
5.7034e-02,
|
1406 |
+
-2.0343e-02,
|
1407 |
+
-6.3037e-03,
|
1408 |
+
6.8914e-03,
|
1409 |
+
2.8643e-02,
|
1410 |
+
8.2739e-02,
|
1411 |
+
-2.5124e-02,
|
1412 |
+
-7.0611e-02,
|
1413 |
+
2.7142e-01,
|
1414 |
+
-1.6370e-02,
|
1415 |
+
1.1240e-02,
|
1416 |
+
-1.5776e-01,
|
1417 |
+
-8.8755e-02,
|
1418 |
+
-1.2389e-01,
|
1419 |
+
-2.5785e-02,
|
1420 |
+
-3.1258e-02,
|
1421 |
+
2.2023e-02,
|
1422 |
+
8.5497e-02,
|
1423 |
+
6.8360e-02,
|
1424 |
+
9.6662e-03,
|
1425 |
+
-1.2843e-01,
|
1426 |
+
-7.4122e-02,
|
1427 |
+
7.1105e-02,
|
1428 |
+
5.8334e-02,
|
1429 |
+
-1.8609e-02,
|
1430 |
+
7.2775e-02,
|
1431 |
+
-1.1696e-03,
|
1432 |
+
1.3165e-01,
|
1433 |
+
-4.7326e-02,
|
1434 |
+
6.8737e-02,
|
1435 |
+
-2.3211e-02,
|
1436 |
+
5.5425e-02,
|
1437 |
+
-6.8077e-02,
|
1438 |
+
-7.3743e-04,
|
1439 |
+
1.6215e-01,
|
1440 |
+
-4.9965e-02,
|
1441 |
+
-6.8493e-02,
|
1442 |
+
-6.8358e-03,
|
1443 |
+
9.9518e-02,
|
1444 |
+
1.5627e-01,
|
1445 |
+
1.3100e-01,
|
1446 |
+
9.0073e-03,
|
1447 |
+
1.8023e-01,
|
1448 |
+
-2.7992e-02,
|
1449 |
+
1.3087e-01,
|
1450 |
+
7.5672e-02,
|
1451 |
+
],
|
1452 |
+
[
|
1453 |
+
9.0390e-03,
|
1454 |
+
1.3137e-01,
|
1455 |
+
4.6586e-02,
|
1456 |
+
1.1836e-01,
|
1457 |
+
1.1406e-01,
|
1458 |
+
-7.3655e-02,
|
1459 |
+
-1.4340e-02,
|
1460 |
+
-1.4285e-01,
|
1461 |
+
2.0426e-02,
|
1462 |
+
1.3532e-01,
|
1463 |
+
1.3353e-01,
|
1464 |
+
-4.7242e-02,
|
1465 |
+
2.6449e-02,
|
1466 |
+
2.0707e-02,
|
1467 |
+
-7.5049e-02,
|
1468 |
+
-4.4098e-02,
|
1469 |
+
1.4599e-01,
|
1470 |
+
1.1299e-01,
|
1471 |
+
-2.2097e-02,
|
1472 |
+
8.4679e-02,
|
1473 |
+
5.8946e-02,
|
1474 |
+
2.1213e-02,
|
1475 |
+
-5.8343e-03,
|
1476 |
+
-4.5902e-02,
|
1477 |
+
-6.1018e-02,
|
1478 |
+
4.4368e-02,
|
1479 |
+
-5.7242e-02,
|
1480 |
+
1.4734e-01,
|
1481 |
+
-2.6191e-02,
|
1482 |
+
8.6116e-02,
|
1483 |
+
4.6004e-02,
|
1484 |
+
9.4532e-02,
|
1485 |
+
-1.7424e-01,
|
1486 |
+
1.3697e-01,
|
1487 |
+
4.6544e-02,
|
1488 |
+
-1.1718e-01,
|
1489 |
+
8.2567e-02,
|
1490 |
+
-3.1494e-02,
|
1491 |
+
6.2073e-02,
|
1492 |
+
-4.6328e-02,
|
1493 |
+
1.0782e-02,
|
1494 |
+
6.6071e-02,
|
1495 |
+
9.6953e-03,
|
1496 |
+
2.0415e-02,
|
1497 |
+
-7.0939e-02,
|
1498 |
+
-3.1883e-02,
|
1499 |
+
-4.9926e-02,
|
1500 |
+
-1.2694e-01,
|
1501 |
+
1.6351e-01,
|
1502 |
+
1.1670e-01,
|
1503 |
+
3.8149e-02,
|
1504 |
+
7.2657e-02,
|
1505 |
+
-1.3930e-01,
|
1506 |
+
-1.6682e-01,
|
1507 |
+
1.2471e-01,
|
1508 |
+
1.9094e-02,
|
1509 |
+
-6.1618e-02,
|
1510 |
+
5.8628e-02,
|
1511 |
+
1.8804e-03,
|
1512 |
+
-9.8104e-03,
|
1513 |
+
-1.8998e-01,
|
1514 |
+
1.4179e-02,
|
1515 |
+
1.4856e-01,
|
1516 |
+
-4.2194e-02,
|
1517 |
+
5.0934e-02,
|
1518 |
+
7.4201e-02,
|
1519 |
+
1.5546e-02,
|
1520 |
+
2.3192e-02,
|
1521 |
+
-5.5886e-02,
|
1522 |
+
-4.3618e-02,
|
1523 |
+
3.6677e-02,
|
1524 |
+
1.2750e-01,
|
1525 |
+
2.1240e-02,
|
1526 |
+
9.5849e-02,
|
1527 |
+
-1.2006e-01,
|
1528 |
+
6.0424e-02,
|
1529 |
+
-1.6516e-01,
|
1530 |
+
7.8015e-02,
|
1531 |
+
-7.6026e-02,
|
1532 |
+
-1.6711e-02,
|
1533 |
+
-3.3572e-02,
|
1534 |
+
4.3704e-02,
|
1535 |
+
1.2728e-02,
|
1536 |
+
-6.9630e-02,
|
1537 |
+
4.1065e-02,
|
1538 |
+
-8.6589e-02,
|
1539 |
+
1.1581e-01,
|
1540 |
+
2.2666e-02,
|
1541 |
+
-5.1476e-02,
|
1542 |
+
2.2756e-02,
|
1543 |
+
1.9309e-01,
|
1544 |
+
7.0417e-02,
|
1545 |
+
8.9253e-03,
|
1546 |
+
-1.3546e-01,
|
1547 |
+
-7.7783e-02,
|
1548 |
+
-1.5058e-01,
|
1549 |
+
-4.7874e-02,
|
1550 |
+
3.3498e-02,
|
1551 |
+
6.4585e-02,
|
1552 |
+
7.8633e-02,
|
1553 |
+
1.0162e-01,
|
1554 |
+
4.5821e-02,
|
1555 |
+
-2.8424e-02,
|
1556 |
+
4.4524e-02,
|
1557 |
+
4.6649e-02,
|
1558 |
+
4.5805e-02,
|
1559 |
+
8.9723e-02,
|
1560 |
+
3.7597e-02,
|
1561 |
+
-6.8016e-03,
|
1562 |
+
1.1727e-01,
|
1563 |
+
-6.6387e-02,
|
1564 |
+
3.4958e-02,
|
1565 |
+
4.0205e-02,
|
1566 |
+
7.5854e-02,
|
1567 |
+
-5.1322e-02,
|
1568 |
+
6.0060e-02,
|
1569 |
+
1.4631e-01,
|
1570 |
+
-1.1550e-01,
|
1571 |
+
-1.5388e-01,
|
1572 |
+
6.0975e-03,
|
1573 |
+
1.2013e-01,
|
1574 |
+
2.1669e-01,
|
1575 |
+
4.8245e-02,
|
1576 |
+
8.4634e-02,
|
1577 |
+
1.4934e-01,
|
1578 |
+
-1.2099e-01,
|
1579 |
+
1.6673e-01,
|
1580 |
+
6.2539e-02,
|
1581 |
+
],
|
1582 |
+
[
|
1583 |
+
1.6222e-01,
|
1584 |
+
7.5644e-03,
|
1585 |
+
1.0667e-01,
|
1586 |
+
8.3084e-02,
|
1587 |
+
5.1888e-02,
|
1588 |
+
8.7477e-02,
|
1589 |
+
-1.1550e-01,
|
1590 |
+
-4.7037e-02,
|
1591 |
+
-3.9418e-02,
|
1592 |
+
8.0987e-02,
|
1593 |
+
1.2812e-01,
|
1594 |
+
-6.6527e-02,
|
1595 |
+
6.5405e-02,
|
1596 |
+
5.2723e-03,
|
1597 |
+
-6.2940e-02,
|
1598 |
+
-5.8805e-02,
|
1599 |
+
2.8526e-02,
|
1600 |
+
4.0631e-02,
|
1601 |
+
9.8513e-02,
|
1602 |
+
-2.8448e-02,
|
1603 |
+
9.2361e-02,
|
1604 |
+
6.9724e-02,
|
1605 |
+
-1.1792e-01,
|
1606 |
+
-1.4806e-02,
|
1607 |
+
-6.6172e-02,
|
1608 |
+
5.9468e-02,
|
1609 |
+
-1.8325e-01,
|
1610 |
+
3.2851e-02,
|
1611 |
+
-2.7042e-02,
|
1612 |
+
1.7569e-01,
|
1613 |
+
1.9061e-01,
|
1614 |
+
4.1868e-02,
|
1615 |
+
-1.4116e-01,
|
1616 |
+
-1.6780e-02,
|
1617 |
+
-6.2881e-02,
|
1618 |
+
-9.4655e-02,
|
1619 |
+
5.1488e-02,
|
1620 |
+
-3.6501e-03,
|
1621 |
+
5.6754e-02,
|
1622 |
+
-6.3285e-03,
|
1623 |
+
9.2234e-02,
|
1624 |
+
-1.0761e-01,
|
1625 |
+
-5.5392e-02,
|
1626 |
+
7.5249e-02,
|
1627 |
+
8.7539e-02,
|
1628 |
+
4.3377e-02,
|
1629 |
+
3.2473e-03,
|
1630 |
+
-1.0990e-01,
|
1631 |
+
5.2611e-02,
|
1632 |
+
3.4955e-02,
|
1633 |
+
1.1722e-01,
|
1634 |
+
4.0339e-02,
|
1635 |
+
-9.6605e-02,
|
1636 |
+
-9.3660e-02,
|
1637 |
+
9.6494e-02,
|
1638 |
+
-1.4790e-02,
|
1639 |
+
-5.7770e-02,
|
1640 |
+
4.3192e-02,
|
1641 |
+
-8.1741e-02,
|
1642 |
+
-4.0909e-02,
|
1643 |
+
-9.5212e-02,
|
1644 |
+
-1.2459e-01,
|
1645 |
+
3.6241e-02,
|
1646 |
+
-1.2878e-01,
|
1647 |
+
1.1544e-01,
|
1648 |
+
3.6392e-03,
|
1649 |
+
-7.7986e-03,
|
1650 |
+
8.2339e-02,
|
1651 |
+
1.4319e-01,
|
1652 |
+
-5.8374e-02,
|
1653 |
+
1.2483e-01,
|
1654 |
+
5.6826e-02,
|
1655 |
+
-6.2649e-02,
|
1656 |
+
4.5884e-02,
|
1657 |
+
-1.8261e-01,
|
1658 |
+
-9.1633e-02,
|
1659 |
+
-1.9414e-01,
|
1660 |
+
2.8376e-02,
|
1661 |
+
9.5654e-02,
|
1662 |
+
-1.3532e-01,
|
1663 |
+
2.1669e-03,
|
1664 |
+
7.9960e-02,
|
1665 |
+
5.0917e-02,
|
1666 |
+
-5.4874e-02,
|
1667 |
+
7.6823e-02,
|
1668 |
+
-1.3932e-01,
|
1669 |
+
1.2431e-01,
|
1670 |
+
1.3001e-01,
|
1671 |
+
-6.0069e-02,
|
1672 |
+
2.6470e-02,
|
1673 |
+
2.2378e-01,
|
1674 |
+
2.7335e-02,
|
1675 |
+
1.6487e-02,
|
1676 |
+
-9.6473e-02,
|
1677 |
+
8.3110e-02,
|
1678 |
+
-8.8776e-02,
|
1679 |
+
-6.2299e-02,
|
1680 |
+
4.0821e-02,
|
1681 |
+
6.5279e-02,
|
1682 |
+
8.4030e-02,
|
1683 |
+
-4.9298e-02,
|
1684 |
+
-3.7441e-02,
|
1685 |
+
-4.9233e-02,
|
1686 |
+
-1.9428e-03,
|
1687 |
+
-1.9763e-02,
|
1688 |
+
-9.1249e-02,
|
1689 |
+
1.1593e-01,
|
1690 |
+
6.6291e-03,
|
1691 |
+
-1.0686e-01,
|
1692 |
+
5.9383e-02,
|
1693 |
+
-3.1088e-02,
|
1694 |
+
-1.9844e-03,
|
1695 |
+
2.5891e-02,
|
1696 |
+
1.3471e-01,
|
1697 |
+
-3.5624e-02,
|
1698 |
+
1.2647e-01,
|
1699 |
+
6.7167e-02,
|
1700 |
+
-1.8682e-02,
|
1701 |
+
-2.4806e-02,
|
1702 |
+
-1.1453e-02,
|
1703 |
+
9.6992e-02,
|
1704 |
+
1.2253e-01,
|
1705 |
+
5.6707e-02,
|
1706 |
+
1.0860e-02,
|
1707 |
+
2.4775e-01,
|
1708 |
+
-8.8641e-02,
|
1709 |
+
1.1375e-01,
|
1710 |
+
6.9383e-02,
|
1711 |
+
],
|
1712 |
+
[
|
1713 |
+
1.4724e-01,
|
1714 |
+
3.7511e-02,
|
1715 |
+
1.1238e-01,
|
1716 |
+
6.3809e-02,
|
1717 |
+
1.8174e-03,
|
1718 |
+
8.4854e-02,
|
1719 |
+
-7.8965e-02,
|
1720 |
+
-3.1542e-02,
|
1721 |
+
-3.7643e-02,
|
1722 |
+
1.0136e-01,
|
1723 |
+
1.5837e-01,
|
1724 |
+
-7.5701e-02,
|
1725 |
+
1.0313e-01,
|
1726 |
+
2.2795e-02,
|
1727 |
+
-1.1227e-01,
|
1728 |
+
-4.3783e-02,
|
1729 |
+
4.6561e-02,
|
1730 |
+
4.1225e-02,
|
1731 |
+
7.4273e-02,
|
1732 |
+
-4.8200e-02,
|
1733 |
+
2.7666e-02,
|
1734 |
+
5.1417e-02,
|
1735 |
+
-1.3928e-01,
|
1736 |
+
2.0020e-02,
|
1737 |
+
-9.3673e-02,
|
1738 |
+
5.1440e-02,
|
1739 |
+
-2.0076e-01,
|
1740 |
+
1.0715e-01,
|
1741 |
+
-3.0323e-02,
|
1742 |
+
1.7241e-01,
|
1743 |
+
1.9730e-01,
|
1744 |
+
7.7685e-02,
|
1745 |
+
-1.5949e-01,
|
1746 |
+
4.8495e-02,
|
1747 |
+
-8.0068e-02,
|
1748 |
+
-7.1965e-02,
|
1749 |
+
8.7222e-02,
|
1750 |
+
-4.8383e-02,
|
1751 |
+
7.0627e-02,
|
1752 |
+
3.9791e-03,
|
1753 |
+
7.0469e-02,
|
1754 |
+
-8.6697e-02,
|
1755 |
+
-3.7149e-02,
|
1756 |
+
7.9965e-02,
|
1757 |
+
8.8967e-02,
|
1758 |
+
5.3325e-02,
|
1759 |
+
-5.6073e-03,
|
1760 |
+
-1.1336e-01,
|
1761 |
+
1.0338e-01,
|
1762 |
+
2.3824e-02,
|
1763 |
+
6.9393e-02,
|
1764 |
+
6.1018e-02,
|
1765 |
+
-7.2880e-02,
|
1766 |
+
-6.6328e-02,
|
1767 |
+
8.9040e-02,
|
1768 |
+
-8.8268e-03,
|
1769 |
+
-7.5720e-02,
|
1770 |
+
3.7544e-02,
|
1771 |
+
-8.3740e-02,
|
1772 |
+
-4.7977e-02,
|
1773 |
+
-1.2425e-01,
|
1774 |
+
-1.0304e-01,
|
1775 |
+
-3.7850e-03,
|
1776 |
+
-1.1540e-01,
|
1777 |
+
1.0803e-01,
|
1778 |
+
2.5964e-02,
|
1779 |
+
-1.0915e-02,
|
1780 |
+
1.1758e-01,
|
1781 |
+
1.6561e-01,
|
1782 |
+
-4.5171e-02,
|
1783 |
+
1.1272e-01,
|
1784 |
+
6.0721e-02,
|
1785 |
+
-9.6027e-02,
|
1786 |
+
6.0908e-02,
|
1787 |
+
-1.6545e-01,
|
1788 |
+
-6.5444e-02,
|
1789 |
+
-1.6802e-01,
|
1790 |
+
2.5850e-02,
|
1791 |
+
1.2434e-01,
|
1792 |
+
-1.2358e-01,
|
1793 |
+
-5.2647e-04,
|
1794 |
+
1.2329e-01,
|
1795 |
+
6.3928e-02,
|
1796 |
+
-5.5478e-02,
|
1797 |
+
5.4642e-02,
|
1798 |
+
-1.0372e-01,
|
1799 |
+
1.0955e-01,
|
1800 |
+
1.1810e-01,
|
1801 |
+
-7.7028e-02,
|
1802 |
+
5.0302e-02,
|
1803 |
+
2.7576e-01,
|
1804 |
+
6.4704e-02,
|
1805 |
+
3.7824e-03,
|
1806 |
+
-8.3016e-02,
|
1807 |
+
6.7355e-02,
|
1808 |
+
-4.9660e-02,
|
1809 |
+
-1.2677e-01,
|
1810 |
+
3.4498e-02,
|
1811 |
+
2.7027e-02,
|
1812 |
+
9.1476e-02,
|
1813 |
+
-5.1170e-02,
|
1814 |
+
-3.4786e-02,
|
1815 |
+
-4.4356e-02,
|
1816 |
+
6.2440e-03,
|
1817 |
+
-3.5473e-02,
|
1818 |
+
-1.1076e-01,
|
1819 |
+
1.0014e-01,
|
1820 |
+
-1.5927e-02,
|
1821 |
+
-7.9539e-02,
|
1822 |
+
1.1542e-01,
|
1823 |
+
-3.6775e-03,
|
1824 |
+
2.5437e-02,
|
1825 |
+
2.1185e-02,
|
1826 |
+
1.0472e-01,
|
1827 |
+
-4.8937e-03,
|
1828 |
+
4.5876e-02,
|
1829 |
+
5.3122e-02,
|
1830 |
+
-1.9815e-02,
|
1831 |
+
-1.8126e-02,
|
1832 |
+
-2.3358e-02,
|
1833 |
+
1.2271e-01,
|
1834 |
+
9.8860e-02,
|
1835 |
+
4.5235e-02,
|
1836 |
+
6.2841e-02,
|
1837 |
+
1.6294e-01,
|
1838 |
+
-1.0909e-01,
|
1839 |
+
7.2012e-02,
|
1840 |
+
5.3389e-02,
|
1841 |
+
],
|
1842 |
+
[
|
1843 |
+
1.2605e-01,
|
1844 |
+
5.1723e-02,
|
1845 |
+
1.2152e-01,
|
1846 |
+
5.8291e-02,
|
1847 |
+
-3.8019e-02,
|
1848 |
+
8.8117e-02,
|
1849 |
+
-4.1927e-02,
|
1850 |
+
-2.3022e-02,
|
1851 |
+
-3.1158e-02,
|
1852 |
+
1.2518e-01,
|
1853 |
+
1.4279e-01,
|
1854 |
+
-7.1922e-02,
|
1855 |
+
1.0867e-01,
|
1856 |
+
3.3116e-02,
|
1857 |
+
-1.3669e-01,
|
1858 |
+
-3.2413e-02,
|
1859 |
+
9.0301e-02,
|
1860 |
+
5.9203e-02,
|
1861 |
+
-7.5021e-03,
|
1862 |
+
-6.9837e-02,
|
1863 |
+
-1.2463e-03,
|
1864 |
+
1.8891e-02,
|
1865 |
+
-1.1878e-01,
|
1866 |
+
6.1658e-02,
|
1867 |
+
-1.2649e-01,
|
1868 |
+
4.2450e-02,
|
1869 |
+
-1.6298e-01,
|
1870 |
+
1.5450e-01,
|
1871 |
+
-2.6732e-02,
|
1872 |
+
1.7891e-01,
|
1873 |
+
2.1083e-01,
|
1874 |
+
1.0432e-01,
|
1875 |
+
-1.3396e-01,
|
1876 |
+
6.9416e-02,
|
1877 |
+
-7.3193e-02,
|
1878 |
+
-6.8281e-02,
|
1879 |
+
9.9454e-02,
|
1880 |
+
-4.4528e-02,
|
1881 |
+
7.7992e-02,
|
1882 |
+
-2.6336e-03,
|
1883 |
+
6.9279e-02,
|
1884 |
+
-3.8836e-02,
|
1885 |
+
-2.8872e-02,
|
1886 |
+
5.6951e-02,
|
1887 |
+
8.7154e-02,
|
1888 |
+
6.1652e-02,
|
1889 |
+
-1.8049e-02,
|
1890 |
+
-1.2096e-01,
|
1891 |
+
1.3820e-01,
|
1892 |
+
5.1705e-02,
|
1893 |
+
3.4052e-02,
|
1894 |
+
1.1524e-01,
|
1895 |
+
-4.1216e-02,
|
1896 |
+
-8.5670e-02,
|
1897 |
+
7.1571e-02,
|
1898 |
+
-1.6001e-02,
|
1899 |
+
-8.8427e-02,
|
1900 |
+
3.1357e-02,
|
1901 |
+
-5.4897e-02,
|
1902 |
+
-3.1463e-02,
|
1903 |
+
-1.2070e-01,
|
1904 |
+
-5.7460e-02,
|
1905 |
+
-2.1424e-02,
|
1906 |
+
-1.2160e-01,
|
1907 |
+
1.0026e-01,
|
1908 |
+
4.7475e-02,
|
1909 |
+
-1.4578e-02,
|
1910 |
+
1.3247e-01,
|
1911 |
+
1.5272e-01,
|
1912 |
+
-2.9788e-02,
|
1913 |
+
8.2947e-02,
|
1914 |
+
7.9830e-02,
|
1915 |
+
-1.1615e-01,
|
1916 |
+
7.2949e-02,
|
1917 |
+
-1.2386e-01,
|
1918 |
+
-5.3969e-02,
|
1919 |
+
-1.3578e-01,
|
1920 |
+
4.0461e-02,
|
1921 |
+
1.2467e-01,
|
1922 |
+
-9.4575e-02,
|
1923 |
+
6.2182e-04,
|
1924 |
+
1.3108e-01,
|
1925 |
+
6.5035e-02,
|
1926 |
+
-5.7784e-02,
|
1927 |
+
4.2513e-02,
|
1928 |
+
-7.8118e-02,
|
1929 |
+
1.1274e-01,
|
1930 |
+
8.9333e-02,
|
1931 |
+
-4.9991e-02,
|
1932 |
+
7.4639e-02,
|
1933 |
+
3.0876e-01,
|
1934 |
+
7.3974e-02,
|
1935 |
+
-1.4039e-02,
|
1936 |
+
-7.4526e-02,
|
1937 |
+
6.5200e-02,
|
1938 |
+
-3.6421e-02,
|
1939 |
+
-1.6730e-01,
|
1940 |
+
4.1713e-02,
|
1941 |
+
-1.5316e-02,
|
1942 |
+
1.0056e-01,
|
1943 |
+
-5.0370e-02,
|
1944 |
+
-4.4531e-02,
|
1945 |
+
-5.0233e-02,
|
1946 |
+
3.2636e-02,
|
1947 |
+
-1.7609e-02,
|
1948 |
+
-1.1354e-01,
|
1949 |
+
8.1922e-02,
|
1950 |
+
-2.0907e-02,
|
1951 |
+
-1.3264e-02,
|
1952 |
+
1.5115e-01,
|
1953 |
+
1.2777e-02,
|
1954 |
+
3.8261e-02,
|
1955 |
+
2.1829e-02,
|
1956 |
+
5.5874e-02,
|
1957 |
+
6.8772e-03,
|
1958 |
+
-2.7772e-02,
|
1959 |
+
6.7979e-02,
|
1960 |
+
-3.9099e-02,
|
1961 |
+
-2.8619e-02,
|
1962 |
+
-5.6936e-02,
|
1963 |
+
1.3366e-01,
|
1964 |
+
9.4269e-02,
|
1965 |
+
4.4852e-02,
|
1966 |
+
7.6881e-02,
|
1967 |
+
9.6787e-02,
|
1968 |
+
-1.2885e-01,
|
1969 |
+
7.9722e-02,
|
1970 |
+
6.4991e-02,
|
1971 |
+
],
|
1972 |
+
[
|
1973 |
+
1.0575e-01,
|
1974 |
+
6.4565e-02,
|
1975 |
+
1.2479e-01,
|
1976 |
+
5.5616e-02,
|
1977 |
+
-5.5869e-02,
|
1978 |
+
8.9005e-02,
|
1979 |
+
-1.9612e-02,
|
1980 |
+
-3.3032e-02,
|
1981 |
+
-3.9719e-02,
|
1982 |
+
1.3884e-01,
|
1983 |
+
1.2010e-01,
|
1984 |
+
-6.3224e-02,
|
1985 |
+
1.0893e-01,
|
1986 |
+
4.4172e-02,
|
1987 |
+
-1.4283e-01,
|
1988 |
+
-3.8972e-02,
|
1989 |
+
1.1470e-01,
|
1990 |
+
7.7830e-02,
|
1991 |
+
-4.6450e-02,
|
1992 |
+
-8.7246e-02,
|
1993 |
+
-5.7215e-03,
|
1994 |
+
1.7476e-02,
|
1995 |
+
-9.0388e-02,
|
1996 |
+
7.4607e-02,
|
1997 |
+
-1.3105e-01,
|
1998 |
+
2.9371e-02,
|
1999 |
+
-1.2681e-01,
|
2000 |
+
1.6014e-01,
|
2001 |
+
-1.3655e-02,
|
2002 |
+
1.8492e-01,
|
2003 |
+
1.9841e-01,
|
2004 |
+
1.0942e-01,
|
2005 |
+
-1.1261e-01,
|
2006 |
+
6.8326e-02,
|
2007 |
+
-5.1130e-02,
|
2008 |
+
-7.1296e-02,
|
2009 |
+
9.3895e-02,
|
2010 |
+
-3.1097e-02,
|
2011 |
+
8.7043e-02,
|
2012 |
+
-1.2087e-02,
|
2013 |
+
7.3054e-02,
|
2014 |
+
-1.0602e-02,
|
2015 |
+
-3.6347e-02,
|
2016 |
+
3.1324e-02,
|
2017 |
+
7.5686e-02,
|
2018 |
+
5.3221e-02,
|
2019 |
+
-3.1793e-02,
|
2020 |
+
-1.3818e-01,
|
2021 |
+
1.4972e-01,
|
2022 |
+
9.0217e-02,
|
2023 |
+
2.6365e-02,
|
2024 |
+
1.1733e-01,
|
2025 |
+
-2.6107e-02,
|
2026 |
+
-1.1933e-01,
|
2027 |
+
6.5575e-02,
|
2028 |
+
-1.6907e-02,
|
2029 |
+
-1.0186e-01,
|
2030 |
+
3.3719e-02,
|
2031 |
+
-3.4021e-02,
|
2032 |
+
-1.0597e-02,
|
2033 |
+
-1.0478e-01,
|
2034 |
+
-3.4765e-02,
|
2035 |
+
-3.0666e-03,
|
2036 |
+
-1.2035e-01,
|
2037 |
+
1.1053e-01,
|
2038 |
+
5.2212e-02,
|
2039 |
+
-1.8638e-02,
|
2040 |
+
1.2226e-01,
|
2041 |
+
1.3614e-01,
|
2042 |
+
-4.3806e-02,
|
2043 |
+
4.7251e-02,
|
2044 |
+
9.2144e-02,
|
2045 |
+
-1.2505e-01,
|
2046 |
+
8.3020e-02,
|
2047 |
+
-1.1203e-01,
|
2048 |
+
-4.9654e-02,
|
2049 |
+
-1.1939e-01,
|
2050 |
+
4.4126e-02,
|
2051 |
+
1.1188e-01,
|
2052 |
+
-7.8910e-02,
|
2053 |
+
-4.1917e-03,
|
2054 |
+
1.3279e-01,
|
2055 |
+
5.0291e-02,
|
2056 |
+
-6.1770e-02,
|
2057 |
+
5.1914e-02,
|
2058 |
+
-6.8796e-02,
|
2059 |
+
1.2148e-01,
|
2060 |
+
7.6837e-02,
|
2061 |
+
-4.0098e-02,
|
2062 |
+
8.3547e-02,
|
2063 |
+
3.0367e-01,
|
2064 |
+
6.9357e-02,
|
2065 |
+
-2.5710e-02,
|
2066 |
+
-7.2644e-02,
|
2067 |
+
5.2612e-02,
|
2068 |
+
-5.3110e-02,
|
2069 |
+
-1.7360e-01,
|
2070 |
+
5.2791e-02,
|
2071 |
+
-1.6490e-02,
|
2072 |
+
9.9930e-02,
|
2073 |
+
-4.8174e-02,
|
2074 |
+
-3.0230e-02,
|
2075 |
+
-6.0898e-02,
|
2076 |
+
3.4064e-02,
|
2077 |
+
8.2446e-03,
|
2078 |
+
-1.0747e-01,
|
2079 |
+
6.9406e-02,
|
2080 |
+
-9.2400e-03,
|
2081 |
+
2.1804e-02,
|
2082 |
+
1.5491e-01,
|
2083 |
+
2.0964e-02,
|
2084 |
+
3.4691e-02,
|
2085 |
+
3.5648e-02,
|
2086 |
+
4.4363e-02,
|
2087 |
+
-3.2605e-03,
|
2088 |
+
-5.9988e-02,
|
2089 |
+
9.3354e-02,
|
2090 |
+
-7.4183e-02,
|
2091 |
+
-3.5824e-02,
|
2092 |
+
-7.1163e-02,
|
2093 |
+
1.4776e-01,
|
2094 |
+
1.0179e-01,
|
2095 |
+
4.1685e-02,
|
2096 |
+
6.7698e-02,
|
2097 |
+
8.4053e-02,
|
2098 |
+
-1.4797e-01,
|
2099 |
+
9.9115e-02,
|
2100 |
+
7.2061e-02,
|
2101 |
+
],
|
2102 |
+
[
|
2103 |
+
8.3987e-02,
|
2104 |
+
6.9951e-02,
|
2105 |
+
1.3728e-01,
|
2106 |
+
6.4616e-02,
|
2107 |
+
-5.5591e-02,
|
2108 |
+
8.8007e-02,
|
2109 |
+
-1.7926e-02,
|
2110 |
+
-4.8462e-02,
|
2111 |
+
-4.8522e-02,
|
2112 |
+
1.5932e-01,
|
2113 |
+
1.0766e-01,
|
2114 |
+
-4.9589e-02,
|
2115 |
+
1.0511e-01,
|
2116 |
+
4.4010e-02,
|
2117 |
+
-1.3653e-01,
|
2118 |
+
-4.1380e-02,
|
2119 |
+
1.3629e-01,
|
2120 |
+
9.2007e-02,
|
2121 |
+
-5.2961e-02,
|
2122 |
+
-7.1865e-02,
|
2123 |
+
-2.8329e-03,
|
2124 |
+
1.3417e-02,
|
2125 |
+
-5.2565e-02,
|
2126 |
+
6.2258e-02,
|
2127 |
+
-1.2135e-01,
|
2128 |
+
2.7531e-02,
|
2129 |
+
-9.4902e-02,
|
2130 |
+
1.6567e-01,
|
2131 |
+
-1.6613e-02,
|
2132 |
+
1.8443e-01,
|
2133 |
+
1.6290e-01,
|
2134 |
+
1.1109e-01,
|
2135 |
+
-1.1476e-01,
|
2136 |
+
6.5613e-02,
|
2137 |
+
-1.7283e-02,
|
2138 |
+
-8.7120e-02,
|
2139 |
+
1.0862e-01,
|
2140 |
+
-2.5325e-02,
|
2141 |
+
8.9025e-02,
|
2142 |
+
-1.8290e-02,
|
2143 |
+
7.2979e-02,
|
2144 |
+
1.1878e-04,
|
2145 |
+
-4.1007e-02,
|
2146 |
+
1.9679e-02,
|
2147 |
+
6.1887e-02,
|
2148 |
+
4.0949e-02,
|
2149 |
+
-3.6016e-02,
|
2150 |
+
-1.5569e-01,
|
2151 |
+
1.4839e-01,
|
2152 |
+
1.1372e-01,
|
2153 |
+
1.8360e-02,
|
2154 |
+
9.3030e-02,
|
2155 |
+
-1.8070e-02,
|
2156 |
+
-1.5578e-01,
|
2157 |
+
6.1180e-02,
|
2158 |
+
-1.9569e-02,
|
2159 |
+
-1.1221e-01,
|
2160 |
+
4.0037e-02,
|
2161 |
+
-2.3712e-02,
|
2162 |
+
-1.0311e-02,
|
2163 |
+
-1.0530e-01,
|
2164 |
+
-1.2916e-02,
|
2165 |
+
3.1546e-02,
|
2166 |
+
-1.1647e-01,
|
2167 |
+
1.2109e-01,
|
2168 |
+
5.8714e-02,
|
2169 |
+
-1.9454e-02,
|
2170 |
+
9.9438e-02,
|
2171 |
+
1.1088e-01,
|
2172 |
+
-7.4443e-02,
|
2173 |
+
1.6456e-02,
|
2174 |
+
8.7619e-02,
|
2175 |
+
-1.1460e-01,
|
2176 |
+
9.7142e-02,
|
2177 |
+
-1.1083e-01,
|
2178 |
+
-5.2367e-02,
|
2179 |
+
-1.2157e-01,
|
2180 |
+
4.6784e-02,
|
2181 |
+
8.5968e-02,
|
2182 |
+
-7.2488e-02,
|
2183 |
+
-1.2658e-02,
|
2184 |
+
1.4136e-01,
|
2185 |
+
1.7934e-02,
|
2186 |
+
-6.4075e-02,
|
2187 |
+
5.3809e-02,
|
2188 |
+
-5.8649e-02,
|
2189 |
+
1.2410e-01,
|
2190 |
+
6.7307e-02,
|
2191 |
+
-5.3157e-02,
|
2192 |
+
8.5616e-02,
|
2193 |
+
2.8266e-01,
|
2194 |
+
6.4775e-02,
|
2195 |
+
-2.9330e-02,
|
2196 |
+
-8.7733e-02,
|
2197 |
+
1.3974e-02,
|
2198 |
+
-7.9092e-02,
|
2199 |
+
-1.6691e-01,
|
2200 |
+
5.9037e-02,
|
2201 |
+
4.1784e-03,
|
2202 |
+
9.8219e-02,
|
2203 |
+
-3.6970e-02,
|
2204 |
+
8.6754e-03,
|
2205 |
+
-5.5234e-02,
|
2206 |
+
3.4627e-02,
|
2207 |
+
3.5126e-02,
|
2208 |
+
-9.5508e-02,
|
2209 |
+
6.4539e-02,
|
2210 |
+
-9.1506e-04,
|
2211 |
+
2.9144e-02,
|
2212 |
+
1.3975e-01,
|
2213 |
+
1.5472e-02,
|
2214 |
+
3.9015e-02,
|
2215 |
+
4.6270e-02,
|
2216 |
+
5.4053e-02,
|
2217 |
+
-1.2525e-02,
|
2218 |
+
-6.6168e-02,
|
2219 |
+
1.2463e-01,
|
2220 |
+
-1.0793e-01,
|
2221 |
+
-4.0659e-02,
|
2222 |
+
-8.1224e-02,
|
2223 |
+
1.5702e-01,
|
2224 |
+
1.2323e-01,
|
2225 |
+
3.3473e-02,
|
2226 |
+
6.1162e-02,
|
2227 |
+
8.3375e-02,
|
2228 |
+
-1.7863e-01,
|
2229 |
+
1.1536e-01,
|
2230 |
+
6.9906e-02,
|
2231 |
+
],
|
2232 |
+
[
|
2233 |
+
6.2508e-02,
|
2234 |
+
8.5713e-02,
|
2235 |
+
1.3566e-01,
|
2236 |
+
8.5148e-02,
|
2237 |
+
-2.2642e-02,
|
2238 |
+
5.8889e-02,
|
2239 |
+
-3.3654e-02,
|
2240 |
+
-6.6948e-02,
|
2241 |
+
-5.1541e-02,
|
2242 |
+
1.7082e-01,
|
2243 |
+
1.1639e-01,
|
2244 |
+
-3.9750e-02,
|
2245 |
+
8.5338e-02,
|
2246 |
+
2.8182e-02,
|
2247 |
+
-1.1108e-01,
|
2248 |
+
-3.5316e-02,
|
2249 |
+
1.4888e-01,
|
2250 |
+
1.0210e-01,
|
2251 |
+
-3.4537e-02,
|
2252 |
+
-1.1950e-02,
|
2253 |
+
5.0482e-03,
|
2254 |
+
1.8051e-02,
|
2255 |
+
-2.2067e-02,
|
2256 |
+
1.8682e-02,
|
2257 |
+
-9.7924e-02,
|
2258 |
+
2.6326e-02,
|
2259 |
+
-7.6128e-02,
|
2260 |
+
1.7675e-01,
|
2261 |
+
-1.6092e-02,
|
2262 |
+
1.6355e-01,
|
2263 |
+
1.1133e-01,
|
2264 |
+
1.1036e-01,
|
2265 |
+
-1.4070e-01,
|
2266 |
+
6.9723e-02,
|
2267 |
+
2.0482e-02,
|
2268 |
+
-1.0421e-01,
|
2269 |
+
1.2920e-01,
|
2270 |
+
-3.1272e-02,
|
2271 |
+
7.6070e-02,
|
2272 |
+
-3.1384e-02,
|
2273 |
+
6.7374e-02,
|
2274 |
+
-8.3764e-05,
|
2275 |
+
-2.1820e-02,
|
2276 |
+
1.4192e-02,
|
2277 |
+
2.3975e-02,
|
2278 |
+
2.3384e-02,
|
2279 |
+
-2.3589e-02,
|
2280 |
+
-1.7196e-01,
|
2281 |
+
1.4986e-01,
|
2282 |
+
1.1465e-01,
|
2283 |
+
2.0120e-02,
|
2284 |
+
4.8034e-02,
|
2285 |
+
-3.9982e-02,
|
2286 |
+
-1.8704e-01,
|
2287 |
+
6.2222e-02,
|
2288 |
+
-1.4799e-02,
|
2289 |
+
-1.0783e-01,
|
2290 |
+
5.4098e-02,
|
2291 |
+
-1.2046e-02,
|
2292 |
+
-1.5444e-02,
|
2293 |
+
-1.4001e-01,
|
2294 |
+
1.5944e-02,
|
2295 |
+
7.9476e-02,
|
2296 |
+
-9.7107e-02,
|
2297 |
+
1.0629e-01,
|
2298 |
+
7.1731e-02,
|
2299 |
+
-8.1614e-03,
|
2300 |
+
6.2800e-02,
|
2301 |
+
5.5151e-02,
|
2302 |
+
-1.0514e-01,
|
2303 |
+
1.7916e-02,
|
2304 |
+
8.1229e-02,
|
2305 |
+
-7.8761e-02,
|
2306 |
+
1.1222e-01,
|
2307 |
+
-1.1032e-01,
|
2308 |
+
-4.8039e-02,
|
2309 |
+
-1.5340e-01,
|
2310 |
+
6.0481e-02,
|
2311 |
+
3.2276e-02,
|
2312 |
+
-6.2797e-02,
|
2313 |
+
-3.3934e-02,
|
2314 |
+
1.3062e-01,
|
2315 |
+
-6.3068e-03,
|
2316 |
+
-6.5936e-02,
|
2317 |
+
4.2361e-02,
|
2318 |
+
-4.6102e-02,
|
2319 |
+
1.2669e-01,
|
2320 |
+
6.1909e-02,
|
2321 |
+
-5.7771e-02,
|
2322 |
+
7.8385e-02,
|
2323 |
+
2.4836e-01,
|
2324 |
+
7.5433e-02,
|
2325 |
+
-2.0151e-02,
|
2326 |
+
-1.2117e-01,
|
2327 |
+
-4.1874e-02,
|
2328 |
+
-1.1751e-01,
|
2329 |
+
-1.4471e-01,
|
2330 |
+
6.3096e-02,
|
2331 |
+
2.9419e-02,
|
2332 |
+
1.0021e-01,
|
2333 |
+
-1.2180e-02,
|
2334 |
+
5.0896e-02,
|
2335 |
+
-4.0094e-02,
|
2336 |
+
4.1059e-02,
|
2337 |
+
8.0853e-02,
|
2338 |
+
-7.4614e-02,
|
2339 |
+
7.5243e-02,
|
2340 |
+
1.4928e-02,
|
2341 |
+
1.1477e-02,
|
2342 |
+
1.2385e-01,
|
2343 |
+
-1.4719e-02,
|
2344 |
+
5.3751e-02,
|
2345 |
+
5.2591e-02,
|
2346 |
+
7.2013e-02,
|
2347 |
+
-1.6333e-02,
|
2348 |
+
-5.0256e-02,
|
2349 |
+
1.4199e-01,
|
2350 |
+
-1.3433e-01,
|
2351 |
+
-7.1574e-02,
|
2352 |
+
-7.4449e-02,
|
2353 |
+
1.6136e-01,
|
2354 |
+
1.5659e-01,
|
2355 |
+
2.1466e-02,
|
2356 |
+
6.9775e-02,
|
2357 |
+
1.0352e-01,
|
2358 |
+
-1.9641e-01,
|
2359 |
+
1.3156e-01,
|
2360 |
+
5.5903e-02,
|
2361 |
+
],
|
2362 |
+
[
|
2363 |
+
4.4988e-02,
|
2364 |
+
1.0390e-01,
|
2365 |
+
1.1266e-01,
|
2366 |
+
1.1661e-01,
|
2367 |
+
2.1212e-02,
|
2368 |
+
1.4641e-02,
|
2369 |
+
-3.1484e-02,
|
2370 |
+
-8.3443e-02,
|
2371 |
+
-4.4991e-02,
|
2372 |
+
1.5687e-01,
|
2373 |
+
1.3158e-01,
|
2374 |
+
-3.3434e-02,
|
2375 |
+
6.5104e-02,
|
2376 |
+
2.0808e-02,
|
2377 |
+
-7.0680e-02,
|
2378 |
+
-4.2508e-02,
|
2379 |
+
1.4304e-01,
|
2380 |
+
9.8483e-02,
|
2381 |
+
-2.6904e-02,
|
2382 |
+
3.2902e-02,
|
2383 |
+
1.1152e-02,
|
2384 |
+
2.1118e-02,
|
2385 |
+
-1.4842e-02,
|
2386 |
+
-2.2356e-02,
|
2387 |
+
-8.6942e-02,
|
2388 |
+
2.6609e-02,
|
2389 |
+
-6.2533e-02,
|
2390 |
+
1.7495e-01,
|
2391 |
+
-1.0246e-02,
|
2392 |
+
1.2697e-01,
|
2393 |
+
7.9345e-02,
|
2394 |
+
1.0189e-01,
|
2395 |
+
-1.7178e-01,
|
2396 |
+
7.5006e-02,
|
2397 |
+
4.5051e-02,
|
2398 |
+
-1.0753e-01,
|
2399 |
+
1.2829e-01,
|
2400 |
+
-3.3422e-02,
|
2401 |
+
7.8522e-02,
|
2402 |
+
-4.5604e-02,
|
2403 |
+
5.2822e-02,
|
2404 |
+
8.3934e-03,
|
2405 |
+
-1.4676e-02,
|
2406 |
+
1.0482e-02,
|
2407 |
+
-6.9389e-03,
|
2408 |
+
2.2131e-03,
|
2409 |
+
-2.0089e-02,
|
2410 |
+
-1.7261e-01,
|
2411 |
+
1.5468e-01,
|
2412 |
+
1.1537e-01,
|
2413 |
+
2.7489e-02,
|
2414 |
+
2.9948e-02,
|
2415 |
+
-7.4234e-02,
|
2416 |
+
-1.9946e-01,
|
2417 |
+
7.4632e-02,
|
2418 |
+
2.2249e-03,
|
2419 |
+
-9.7061e-02,
|
2420 |
+
6.4988e-02,
|
2421 |
+
-1.1239e-02,
|
2422 |
+
-2.6152e-02,
|
2423 |
+
-1.6496e-01,
|
2424 |
+
3.0305e-02,
|
2425 |
+
1.0491e-01,
|
2426 |
+
-6.7692e-02,
|
2427 |
+
7.3323e-02,
|
2428 |
+
7.0258e-02,
|
2429 |
+
1.2020e-02,
|
2430 |
+
4.1457e-02,
|
2431 |
+
3.7126e-03,
|
2432 |
+
-1.0465e-01,
|
2433 |
+
2.7035e-02,
|
2434 |
+
8.1376e-02,
|
2435 |
+
-4.0890e-02,
|
2436 |
+
1.0791e-01,
|
2437 |
+
-1.2141e-01,
|
2438 |
+
-1.6070e-02,
|
2439 |
+
-1.7111e-01,
|
2440 |
+
7.4218e-02,
|
2441 |
+
-2.4698e-02,
|
2442 |
+
-3.7496e-02,
|
2443 |
+
-4.5666e-02,
|
2444 |
+
1.0478e-01,
|
2445 |
+
-1.7289e-03,
|
2446 |
+
-7.1823e-02,
|
2447 |
+
2.7480e-02,
|
2448 |
+
-5.5305e-02,
|
2449 |
+
1.2323e-01,
|
2450 |
+
5.3008e-02,
|
2451 |
+
-5.6903e-02,
|
2452 |
+
6.6087e-02,
|
2453 |
+
2.1523e-01,
|
2454 |
+
8.2657e-02,
|
2455 |
+
-9.3275e-03,
|
2456 |
+
-1.3791e-01,
|
2457 |
+
-6.7856e-02,
|
2458 |
+
-1.4959e-01,
|
2459 |
+
-1.1916e-01,
|
2460 |
+
6.2014e-02,
|
2461 |
+
3.8735e-02,
|
2462 |
+
9.7171e-02,
|
2463 |
+
2.6820e-02,
|
2464 |
+
7.4336e-02,
|
2465 |
+
-2.9922e-02,
|
2466 |
+
5.3645e-02,
|
2467 |
+
1.0981e-01,
|
2468 |
+
-3.7215e-02,
|
2469 |
+
9.4254e-02,
|
2470 |
+
4.2902e-02,
|
2471 |
+
-2.0969e-03,
|
2472 |
+
1.1838e-01,
|
2473 |
+
-5.4015e-02,
|
2474 |
+
5.3799e-02,
|
2475 |
+
4.8568e-02,
|
2476 |
+
8.0494e-02,
|
2477 |
+
-2.1410e-02,
|
2478 |
+
-2.0629e-02,
|
2479 |
+
1.3477e-01,
|
2480 |
+
-1.4177e-01,
|
2481 |
+
-1.1144e-01,
|
2482 |
+
-5.1781e-02,
|
2483 |
+
1.5780e-01,
|
2484 |
+
1.9357e-01,
|
2485 |
+
2.5627e-02,
|
2486 |
+
7.5402e-02,
|
2487 |
+
1.1982e-01,
|
2488 |
+
-1.8961e-01,
|
2489 |
+
1.4646e-01,
|
2490 |
+
4.2665e-02,
|
2491 |
+
],
|
2492 |
+
[
|
2493 |
+
5.1689e-02,
|
2494 |
+
1.0737e-01,
|
2495 |
+
1.1035e-01,
|
2496 |
+
1.1308e-01,
|
2497 |
+
2.0363e-02,
|
2498 |
+
1.9703e-02,
|
2499 |
+
-3.2107e-02,
|
2500 |
+
-9.0838e-02,
|
2501 |
+
-3.7066e-02,
|
2502 |
+
1.5839e-01,
|
2503 |
+
1.3202e-01,
|
2504 |
+
-3.9661e-02,
|
2505 |
+
6.3263e-02,
|
2506 |
+
1.4509e-02,
|
2507 |
+
-6.0145e-02,
|
2508 |
+
-4.1459e-02,
|
2509 |
+
1.4670e-01,
|
2510 |
+
9.4701e-02,
|
2511 |
+
-2.7710e-02,
|
2512 |
+
3.4281e-02,
|
2513 |
+
1.2373e-02,
|
2514 |
+
2.0087e-02,
|
2515 |
+
-2.0821e-02,
|
2516 |
+
-1.6274e-02,
|
2517 |
+
-7.9908e-02,
|
2518 |
+
2.6209e-02,
|
2519 |
+
-7.0731e-02,
|
2520 |
+
1.7365e-01,
|
2521 |
+
-8.5357e-03,
|
2522 |
+
1.2784e-01,
|
2523 |
+
7.9591e-02,
|
2524 |
+
9.7291e-02,
|
2525 |
+
-1.6958e-01,
|
2526 |
+
7.5774e-02,
|
2527 |
+
4.4993e-02,
|
2528 |
+
-1.0499e-01,
|
2529 |
+
1.2133e-01,
|
2530 |
+
-4.2564e-02,
|
2531 |
+
7.7296e-02,
|
2532 |
+
-3.9049e-02,
|
2533 |
+
5.4639e-02,
|
2534 |
+
3.7831e-03,
|
2535 |
+
-1.2108e-02,
|
2536 |
+
1.7782e-02,
|
2537 |
+
-1.8517e-03,
|
2538 |
+
1.1160e-02,
|
2539 |
+
-1.9819e-02,
|
2540 |
+
-1.7390e-01,
|
2541 |
+
1.5853e-01,
|
2542 |
+
1.1225e-01,
|
2543 |
+
2.6839e-02,
|
2544 |
+
3.1746e-02,
|
2545 |
+
-8.1013e-02,
|
2546 |
+
-1.9950e-01,
|
2547 |
+
7.7933e-02,
|
2548 |
+
4.3883e-03,
|
2549 |
+
-9.1775e-02,
|
2550 |
+
6.3761e-02,
|
2551 |
+
-2.0220e-02,
|
2552 |
+
-2.0873e-02,
|
2553 |
+
-1.6981e-01,
|
2554 |
+
3.2587e-02,
|
2555 |
+
1.0188e-01,
|
2556 |
+
-7.2338e-02,
|
2557 |
+
7.9739e-02,
|
2558 |
+
7.2336e-02,
|
2559 |
+
1.2712e-02,
|
2560 |
+
4.6304e-02,
|
2561 |
+
1.1977e-02,
|
2562 |
+
-9.9069e-02,
|
2563 |
+
3.2361e-02,
|
2564 |
+
7.4647e-02,
|
2565 |
+
-3.2075e-02,
|
2566 |
+
1.0834e-01,
|
2567 |
+
-1.2421e-01,
|
2568 |
+
-1.4408e-02,
|
2569 |
+
-1.7591e-01,
|
2570 |
+
7.6520e-02,
|
2571 |
+
-2.1893e-02,
|
2572 |
+
-4.0591e-02,
|
2573 |
+
-3.9790e-02,
|
2574 |
+
1.0072e-01,
|
2575 |
+
2.1907e-03,
|
2576 |
+
-7.5756e-02,
|
2577 |
+
3.4002e-02,
|
2578 |
+
-6.2571e-02,
|
2579 |
+
1.2714e-01,
|
2580 |
+
5.2011e-02,
|
2581 |
+
-5.6154e-02,
|
2582 |
+
6.2876e-02,
|
2583 |
+
2.0992e-01,
|
2584 |
+
8.9547e-02,
|
2585 |
+
-1.2875e-02,
|
2586 |
+
-1.3528e-01,
|
2587 |
+
-6.6275e-02,
|
2588 |
+
-1.4322e-01,
|
2589 |
+
-1.0560e-01,
|
2590 |
+
5.9555e-02,
|
2591 |
+
4.4426e-02,
|
2592 |
+
1.0047e-01,
|
2593 |
+
3.3182e-02,
|
2594 |
+
7.2001e-02,
|
2595 |
+
-3.6514e-02,
|
2596 |
+
5.0708e-02,
|
2597 |
+
1.0564e-01,
|
2598 |
+
-4.1174e-02,
|
2599 |
+
1.0378e-01,
|
2600 |
+
4.2651e-02,
|
2601 |
+
-2.6353e-03,
|
2602 |
+
1.1964e-01,
|
2603 |
+
-6.2808e-02,
|
2604 |
+
5.9555e-02,
|
2605 |
+
5.4234e-02,
|
2606 |
+
8.3802e-02,
|
2607 |
+
-1.2534e-02,
|
2608 |
+
-1.7949e-02,
|
2609 |
+
1.3403e-01,
|
2610 |
+
-1.3682e-01,
|
2611 |
+
-1.1048e-01,
|
2612 |
+
-5.1154e-02,
|
2613 |
+
1.5967e-01,
|
2614 |
+
1.9743e-01,
|
2615 |
+
3.2240e-02,
|
2616 |
+
7.4049e-02,
|
2617 |
+
1.2060e-01,
|
2618 |
+
-1.9087e-01,
|
2619 |
+
1.3942e-01,
|
2620 |
+
4.1168e-02,
|
2621 |
+
],
|
2622 |
+
[
|
2623 |
+
7.2669e-02,
|
2624 |
+
1.0343e-01,
|
2625 |
+
1.1966e-01,
|
2626 |
+
9.3777e-02,
|
2627 |
+
-4.3358e-03,
|
2628 |
+
5.0720e-02,
|
2629 |
+
-3.8923e-02,
|
2630 |
+
-9.1626e-02,
|
2631 |
+
-3.0056e-02,
|
2632 |
+
1.6863e-01,
|
2633 |
+
1.2676e-01,
|
2634 |
+
-5.3184e-02,
|
2635 |
+
7.4056e-02,
|
2636 |
+
1.5517e-02,
|
2637 |
+
-7.5657e-02,
|
2638 |
+
-3.7712e-02,
|
2639 |
+
1.5280e-01,
|
2640 |
+
9.0719e-02,
|
2641 |
+
-3.1311e-02,
|
2642 |
+
1.7038e-02,
|
2643 |
+
1.0062e-02,
|
2644 |
+
1.4759e-02,
|
2645 |
+
-3.4438e-02,
|
2646 |
+
1.5206e-02,
|
2647 |
+
-7.7897e-02,
|
2648 |
+
2.7431e-02,
|
2649 |
+
-9.0602e-02,
|
2650 |
+
1.7164e-01,
|
2651 |
+
-9.9721e-03,
|
2652 |
+
1.4776e-01,
|
2653 |
+
1.0475e-01,
|
2654 |
+
9.0160e-02,
|
2655 |
+
-1.5270e-01,
|
2656 |
+
7.4838e-02,
|
2657 |
+
2.4463e-02,
|
2658 |
+
-1.0180e-01,
|
2659 |
+
1.1501e-01,
|
2660 |
+
-5.0178e-02,
|
2661 |
+
7.2532e-02,
|
2662 |
+
-1.8656e-02,
|
2663 |
+
6.9202e-02,
|
2664 |
+
-9.6694e-03,
|
2665 |
+
-1.8219e-02,
|
2666 |
+
3.5159e-02,
|
2667 |
+
2.5262e-02,
|
2668 |
+
3.4003e-02,
|
2669 |
+
-1.4053e-02,
|
2670 |
+
-1.7146e-01,
|
2671 |
+
1.6299e-01,
|
2672 |
+
1.0628e-01,
|
2673 |
+
2.3901e-02,
|
2674 |
+
4.2174e-02,
|
2675 |
+
-7.0690e-02,
|
2676 |
+
-1.8996e-01,
|
2677 |
+
7.4249e-02,
|
2678 |
+
-2.3634e-03,
|
2679 |
+
-8.9371e-02,
|
2680 |
+
5.7919e-02,
|
2681 |
+
-3.2949e-02,
|
2682 |
+
-2.4951e-03,
|
2683 |
+
-1.6144e-01,
|
2684 |
+
3.1264e-02,
|
2685 |
+
8.4885e-02,
|
2686 |
+
-9.7903e-02,
|
2687 |
+
1.0806e-01,
|
2688 |
+
7.3583e-02,
|
2689 |
+
1.4389e-03,
|
2690 |
+
6.4343e-02,
|
2691 |
+
5.4305e-02,
|
2692 |
+
-9.2823e-02,
|
2693 |
+
3.4699e-02,
|
2694 |
+
6.5887e-02,
|
2695 |
+
-4.1142e-02,
|
2696 |
+
1.1057e-01,
|
2697 |
+
-1.2077e-01,
|
2698 |
+
-3.4178e-02,
|
2699 |
+
-1.7040e-01,
|
2700 |
+
7.2546e-02,
|
2701 |
+
1.9399e-02,
|
2702 |
+
-6.3051e-02,
|
2703 |
+
-3.0156e-02,
|
2704 |
+
1.1501e-01,
|
2705 |
+
3.9456e-03,
|
2706 |
+
-7.8346e-02,
|
2707 |
+
5.0548e-02,
|
2708 |
+
-6.3681e-02,
|
2709 |
+
1.3261e-01,
|
2710 |
+
6.1531e-02,
|
2711 |
+
-5.1743e-02,
|
2712 |
+
6.4762e-02,
|
2713 |
+
2.3264e-01,
|
2714 |
+
9.4896e-02,
|
2715 |
+
-2.0536e-02,
|
2716 |
+
-1.1807e-01,
|
2717 |
+
-4.9545e-02,
|
2718 |
+
-1.1460e-01,
|
2719 |
+
-1.0079e-01,
|
2720 |
+
5.7836e-02,
|
2721 |
+
4.4144e-02,
|
2722 |
+
1.1039e-01,
|
2723 |
+
2.1311e-02,
|
2724 |
+
4.8694e-02,
|
2725 |
+
-4.7126e-02,
|
2726 |
+
3.7200e-02,
|
2727 |
+
8.3108e-02,
|
2728 |
+
-7.0069e-02,
|
2729 |
+
9.7451e-02,
|
2730 |
+
2.0983e-02,
|
2731 |
+
-4.1628e-04,
|
2732 |
+
1.2463e-01,
|
2733 |
+
-5.0752e-02,
|
2734 |
+
7.0680e-02,
|
2735 |
+
6.3588e-02,
|
2736 |
+
8.6767e-02,
|
2737 |
+
6.3361e-04,
|
2738 |
+
-2.5236e-02,
|
2739 |
+
1.3658e-01,
|
2740 |
+
-1.1925e-01,
|
2741 |
+
-8.3861e-02,
|
2742 |
+
-6.3728e-02,
|
2743 |
+
1.6767e-01,
|
2744 |
+
1.7967e-01,
|
2745 |
+
3.3894e-02,
|
2746 |
+
7.2830e-02,
|
2747 |
+
1.1590e-01,
|
2748 |
+
-1.9359e-01,
|
2749 |
+
1.2254e-01,
|
2750 |
+
4.7767e-02,
|
2751 |
+
],
|
2752 |
+
[
|
2753 |
+
8.4189e-02,
|
2754 |
+
9.3299e-02,
|
2755 |
+
1.1532e-01,
|
2756 |
+
8.4670e-02,
|
2757 |
+
-9.7533e-03,
|
2758 |
+
6.4423e-02,
|
2759 |
+
-4.3742e-02,
|
2760 |
+
-9.0334e-02,
|
2761 |
+
-1.9307e-02,
|
2762 |
+
1.7434e-01,
|
2763 |
+
1.2522e-01,
|
2764 |
+
-6.4064e-02,
|
2765 |
+
7.7841e-02,
|
2766 |
+
2.5594e-02,
|
2767 |
+
-9.4764e-02,
|
2768 |
+
-3.8088e-02,
|
2769 |
+
1.5148e-01,
|
2770 |
+
8.7002e-02,
|
2771 |
+
-3.8634e-02,
|
2772 |
+
1.6073e-02,
|
2773 |
+
1.0152e-02,
|
2774 |
+
8.9035e-03,
|
2775 |
+
-3.9583e-02,
|
2776 |
+
3.3614e-02,
|
2777 |
+
-7.4457e-02,
|
2778 |
+
2.6379e-02,
|
2779 |
+
-9.8885e-02,
|
2780 |
+
1.6510e-01,
|
2781 |
+
-1.1651e-02,
|
2782 |
+
1.5700e-01,
|
2783 |
+
1.3055e-01,
|
2784 |
+
7.7680e-02,
|
2785 |
+
-1.3690e-01,
|
2786 |
+
7.0143e-02,
|
2787 |
+
5.4565e-03,
|
2788 |
+
-1.0524e-01,
|
2789 |
+
1.1096e-01,
|
2790 |
+
-4.6091e-02,
|
2791 |
+
6.8167e-02,
|
2792 |
+
-5.6453e-03,
|
2793 |
+
7.2094e-02,
|
2794 |
+
-1.8229e-02,
|
2795 |
+
-2.5539e-02,
|
2796 |
+
3.9328e-02,
|
2797 |
+
4.3699e-02,
|
2798 |
+
4.4686e-02,
|
2799 |
+
-1.2072e-02,
|
2800 |
+
-1.6738e-01,
|
2801 |
+
1.6301e-01,
|
2802 |
+
1.0474e-01,
|
2803 |
+
1.4918e-02,
|
2804 |
+
5.4164e-02,
|
2805 |
+
-7.2489e-02,
|
2806 |
+
-1.7993e-01,
|
2807 |
+
7.7292e-02,
|
2808 |
+
-2.8187e-03,
|
2809 |
+
-8.9506e-02,
|
2810 |
+
5.6049e-02,
|
2811 |
+
-3.1474e-02,
|
2812 |
+
4.7455e-03,
|
2813 |
+
-1.5338e-01,
|
2814 |
+
2.2827e-02,
|
2815 |
+
6.7546e-02,
|
2816 |
+
-1.1578e-01,
|
2817 |
+
1.2026e-01,
|
2818 |
+
8.2049e-02,
|
2819 |
+
-1.1262e-02,
|
2820 |
+
7.4682e-02,
|
2821 |
+
7.3023e-02,
|
2822 |
+
-8.6490e-02,
|
2823 |
+
3.1955e-02,
|
2824 |
+
6.6658e-02,
|
2825 |
+
-4.6417e-02,
|
2826 |
+
1.0408e-01,
|
2827 |
+
-1.1210e-01,
|
2828 |
+
-3.3793e-02,
|
2829 |
+
-1.6235e-01,
|
2830 |
+
7.3353e-02,
|
2831 |
+
4.5024e-02,
|
2832 |
+
-7.6526e-02,
|
2833 |
+
-3.0443e-02,
|
2834 |
+
1.2222e-01,
|
2835 |
+
1.1513e-02,
|
2836 |
+
-8.5835e-02,
|
2837 |
+
5.6084e-02,
|
2838 |
+
-6.5380e-02,
|
2839 |
+
1.3535e-01,
|
2840 |
+
7.2861e-02,
|
2841 |
+
-4.8121e-02,
|
2842 |
+
6.6781e-02,
|
2843 |
+
2.5041e-01,
|
2844 |
+
9.3076e-02,
|
2845 |
+
-2.0334e-02,
|
2846 |
+
-1.0416e-01,
|
2847 |
+
-3.9805e-02,
|
2848 |
+
-1.0051e-01,
|
2849 |
+
-9.2133e-02,
|
2850 |
+
6.3271e-02,
|
2851 |
+
3.4768e-02,
|
2852 |
+
1.1286e-01,
|
2853 |
+
1.3493e-02,
|
2854 |
+
3.0643e-02,
|
2855 |
+
-5.5867e-02,
|
2856 |
+
2.4630e-02,
|
2857 |
+
7.8038e-02,
|
2858 |
+
-7.5769e-02,
|
2859 |
+
9.0636e-02,
|
2860 |
+
1.8840e-02,
|
2861 |
+
1.3688e-02,
|
2862 |
+
1.2780e-01,
|
2863 |
+
-4.3306e-02,
|
2864 |
+
7.6513e-02,
|
2865 |
+
5.6990e-02,
|
2866 |
+
8.7927e-02,
|
2867 |
+
1.6438e-03,
|
2868 |
+
-1.0833e-02,
|
2869 |
+
1.3722e-01,
|
2870 |
+
-9.4365e-02,
|
2871 |
+
-7.4534e-02,
|
2872 |
+
-6.2697e-02,
|
2873 |
+
1.6868e-01,
|
2874 |
+
1.6850e-01,
|
2875 |
+
4.3229e-02,
|
2876 |
+
7.4762e-02,
|
2877 |
+
1.1225e-01,
|
2878 |
+
-1.9559e-01,
|
2879 |
+
1.1981e-01,
|
2880 |
+
5.0025e-02,
|
2881 |
+
],
|
2882 |
+
[
|
2883 |
+
1.0233e-01,
|
2884 |
+
6.7397e-02,
|
2885 |
+
1.0132e-01,
|
2886 |
+
1.1631e-01,
|
2887 |
+
4.3957e-02,
|
2888 |
+
5.7017e-02,
|
2889 |
+
-4.0769e-02,
|
2890 |
+
-1.2329e-01,
|
2891 |
+
-6.1235e-03,
|
2892 |
+
1.3821e-01,
|
2893 |
+
1.3135e-01,
|
2894 |
+
-7.2640e-02,
|
2895 |
+
6.7380e-02,
|
2896 |
+
4.7518e-02,
|
2897 |
+
-1.0261e-01,
|
2898 |
+
-8.4497e-02,
|
2899 |
+
1.1074e-01,
|
2900 |
+
7.9965e-02,
|
2901 |
+
4.3208e-03,
|
2902 |
+
-7.9881e-03,
|
2903 |
+
3.0558e-02,
|
2904 |
+
3.8130e-02,
|
2905 |
+
-7.0863e-02,
|
2906 |
+
2.6484e-02,
|
2907 |
+
-8.1795e-02,
|
2908 |
+
3.9067e-02,
|
2909 |
+
-1.5670e-01,
|
2910 |
+
1.2963e-01,
|
2911 |
+
4.3868e-03,
|
2912 |
+
1.3081e-01,
|
2913 |
+
1.7308e-01,
|
2914 |
+
5.3891e-02,
|
2915 |
+
-1.2683e-01,
|
2916 |
+
6.0787e-02,
|
2917 |
+
-7.8336e-02,
|
2918 |
+
-1.0347e-01,
|
2919 |
+
5.8472e-02,
|
2920 |
+
-2.7212e-02,
|
2921 |
+
7.1385e-02,
|
2922 |
+
-6.8297e-03,
|
2923 |
+
8.7485e-02,
|
2924 |
+
-7.1364e-02,
|
2925 |
+
-1.9182e-02,
|
2926 |
+
8.7217e-02,
|
2927 |
+
8.2944e-02,
|
2928 |
+
3.4400e-02,
|
2929 |
+
-8.5778e-03,
|
2930 |
+
-1.1191e-01,
|
2931 |
+
1.4871e-01,
|
2932 |
+
1.0602e-01,
|
2933 |
+
5.5060e-02,
|
2934 |
+
4.0554e-02,
|
2935 |
+
-1.0835e-01,
|
2936 |
+
-1.4749e-01,
|
2937 |
+
1.1336e-01,
|
2938 |
+
8.1897e-03,
|
2939 |
+
-5.1693e-02,
|
2940 |
+
4.9600e-02,
|
2941 |
+
-3.6377e-02,
|
2942 |
+
-1.6864e-03,
|
2943 |
+
-1.4149e-01,
|
2944 |
+
-3.8906e-02,
|
2945 |
+
5.3481e-02,
|
2946 |
+
-1.1160e-01,
|
2947 |
+
1.3861e-01,
|
2948 |
+
6.3040e-02,
|
2949 |
+
-2.2296e-02,
|
2950 |
+
8.1680e-02,
|
2951 |
+
7.9567e-02,
|
2952 |
+
-6.1083e-02,
|
2953 |
+
6.7573e-02,
|
2954 |
+
9.8196e-02,
|
2955 |
+
-7.0956e-02,
|
2956 |
+
8.7717e-02,
|
2957 |
+
-1.3439e-01,
|
2958 |
+
-4.4087e-02,
|
2959 |
+
-1.7677e-01,
|
2960 |
+
5.1971e-02,
|
2961 |
+
1.1013e-01,
|
2962 |
+
-1.2838e-01,
|
2963 |
+
-1.8450e-02,
|
2964 |
+
9.7373e-02,
|
2965 |
+
1.5415e-02,
|
2966 |
+
-6.8535e-02,
|
2967 |
+
5.8374e-02,
|
2968 |
+
-1.0450e-01,
|
2969 |
+
1.3363e-01,
|
2970 |
+
1.2089e-01,
|
2971 |
+
-4.1817e-02,
|
2972 |
+
3.1015e-02,
|
2973 |
+
2.7185e-01,
|
2974 |
+
6.9890e-02,
|
2975 |
+
-3.8259e-03,
|
2976 |
+
-7.7094e-02,
|
2977 |
+
2.4651e-02,
|
2978 |
+
-1.0086e-01,
|
2979 |
+
-8.4380e-02,
|
2980 |
+
4.9062e-02,
|
2981 |
+
4.7470e-02,
|
2982 |
+
1.0739e-01,
|
2983 |
+
-2.4693e-03,
|
2984 |
+
-5.9990e-02,
|
2985 |
+
-6.2990e-02,
|
2986 |
+
1.2398e-03,
|
2987 |
+
4.8100e-03,
|
2988 |
+
-6.0338e-02,
|
2989 |
+
6.4579e-02,
|
2990 |
+
4.2505e-04,
|
2991 |
+
-2.9926e-02,
|
2992 |
+
1.3627e-01,
|
2993 |
+
-3.0724e-02,
|
2994 |
+
4.2972e-02,
|
2995 |
+
4.6971e-02,
|
2996 |
+
1.2441e-01,
|
2997 |
+
-2.4336e-02,
|
2998 |
+
6.9954e-02,
|
2999 |
+
1.0403e-01,
|
3000 |
+
-3.2450e-02,
|
3001 |
+
-4.3154e-02,
|
3002 |
+
-4.9959e-02,
|
3003 |
+
1.5666e-01,
|
3004 |
+
1.3688e-01,
|
3005 |
+
5.3450e-02,
|
3006 |
+
7.9968e-02,
|
3007 |
+
1.3858e-01,
|
3008 |
+
-1.6817e-01,
|
3009 |
+
1.2637e-01,
|
3010 |
+
7.3937e-02,
|
3011 |
+
],
|
3012 |
+
]
|
3013 |
+
)
|
src/backend/vespa_app.py
ADDED
@@ -0,0 +1,496 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import time
|
3 |
+
from typing import Any, Dict, Tuple
|
4 |
+
import asyncio
|
5 |
+
import numpy as np
|
6 |
+
import torch
|
7 |
+
from dotenv import load_dotenv
|
8 |
+
from vespa.application import Vespa
|
9 |
+
from vespa.io import VespaQueryResponse
|
10 |
+
from .colpali import SimMapGenerator
|
11 |
+
import backend.stopwords
|
12 |
+
import logging
|
13 |
+
|
14 |
+
|
15 |
+
class VespaQueryClient:
|
16 |
+
MAX_QUERY_TERMS = 64
|
17 |
+
VESPA_SCHEMA_NAME = "pdf_page"
|
18 |
+
SELECT_FIELDS = "id,title,url,blur_image,page_number,snippet,text"
|
19 |
+
|
20 |
+
def __init__(self, logger: logging.Logger):
|
21 |
+
"""
|
22 |
+
Initialize the VespaQueryClient by loading environment variables and establishing a connection to the Vespa application.
|
23 |
+
"""
|
24 |
+
load_dotenv()
|
25 |
+
self.logger = logger
|
26 |
+
|
27 |
+
if os.environ.get("USE_MTLS") == "true":
|
28 |
+
self.logger.info("Connected using mTLS")
|
29 |
+
mtls_key = os.environ.get("VESPA_CLOUD_MTLS_KEY")
|
30 |
+
mtls_cert = os.environ.get("VESPA_CLOUD_MTLS_CERT")
|
31 |
+
|
32 |
+
self.vespa_app_url = os.environ.get("VESPA_APP_MTLS_URL")
|
33 |
+
if not self.vespa_app_url:
|
34 |
+
raise ValueError(
|
35 |
+
"Please set the VESPA_APP_MTLS_URL environment variable"
|
36 |
+
)
|
37 |
+
|
38 |
+
if not mtls_cert or not mtls_key:
|
39 |
+
raise ValueError(
|
40 |
+
"USE_MTLS was true, but VESPA_CLOUD_MTLS_KEY and VESPA_CLOUD_MTLS_CERT were not set"
|
41 |
+
)
|
42 |
+
|
43 |
+
# write the key and cert to a file
|
44 |
+
mtls_key_path = "/tmp/vespa-data-plane-private-key.pem"
|
45 |
+
with open(mtls_key_path, "w") as f:
|
46 |
+
f.write(mtls_key)
|
47 |
+
|
48 |
+
mtls_cert_path = "/tmp/vespa-data-plane-public-cert.pem"
|
49 |
+
with open(mtls_cert_path, "w") as f:
|
50 |
+
f.write(mtls_cert)
|
51 |
+
|
52 |
+
# Instantiate Vespa connection
|
53 |
+
self.app = Vespa(
|
54 |
+
url=self.vespa_app_url, key=mtls_key_path, cert=mtls_cert_path
|
55 |
+
)
|
56 |
+
else:
|
57 |
+
self.logger.info("Connected using token")
|
58 |
+
self.vespa_app_url = os.environ.get("VESPA_APP_TOKEN_URL")
|
59 |
+
if not self.vespa_app_url:
|
60 |
+
raise ValueError(
|
61 |
+
"Please set the VESPA_APP_TOKEN_URL environment variable"
|
62 |
+
)
|
63 |
+
|
64 |
+
self.vespa_cloud_secret_token = os.environ.get("VESPA_CLOUD_SECRET_TOKEN")
|
65 |
+
|
66 |
+
if not self.vespa_cloud_secret_token:
|
67 |
+
raise ValueError(
|
68 |
+
"Please set the VESPA_CLOUD_SECRET_TOKEN environment variable"
|
69 |
+
)
|
70 |
+
|
71 |
+
# Instantiate Vespa connection
|
72 |
+
self.app = Vespa(
|
73 |
+
url=self.vespa_app_url,
|
74 |
+
vespa_cloud_secret_token=self.vespa_cloud_secret_token,
|
75 |
+
)
|
76 |
+
|
77 |
+
self.app.wait_for_application_up()
|
78 |
+
self.logger.info(f"Connected to Vespa at {self.vespa_app_url}")
|
79 |
+
|
80 |
+
def get_fields(self, sim_map: bool = False):
|
81 |
+
if not sim_map:
|
82 |
+
return self.SELECT_FIELDS
|
83 |
+
else:
|
84 |
+
return "summaryfeatures"
|
85 |
+
|
86 |
+
def format_query_results(
|
87 |
+
self, query: str, response: VespaQueryResponse, hits: int = 5
|
88 |
+
) -> dict:
|
89 |
+
"""
|
90 |
+
Format the Vespa query results.
|
91 |
+
|
92 |
+
Args:
|
93 |
+
query (str): The query text.
|
94 |
+
response (VespaQueryResponse): The response from Vespa.
|
95 |
+
hits (int, optional): Number of hits to display. Defaults to 5.
|
96 |
+
|
97 |
+
Returns:
|
98 |
+
dict: The JSON content of the response.
|
99 |
+
"""
|
100 |
+
query_time = response.json.get("timing", {}).get("searchtime", -1)
|
101 |
+
query_time = round(query_time, 2)
|
102 |
+
count = response.json.get("root", {}).get("fields", {}).get("totalCount", 0)
|
103 |
+
result_text = f"Query text: '{query}', query time {query_time}s, count={count}, top results:\n"
|
104 |
+
self.logger.debug(result_text)
|
105 |
+
return response.json
|
106 |
+
|
107 |
+
async def query_vespa_default(
|
108 |
+
self,
|
109 |
+
query: str,
|
110 |
+
q_emb: torch.Tensor,
|
111 |
+
hits: int = 3,
|
112 |
+
timeout: str = "10s",
|
113 |
+
sim_map: bool = False,
|
114 |
+
**kwargs,
|
115 |
+
) -> dict:
|
116 |
+
"""
|
117 |
+
Query Vespa using the default ranking profile.
|
118 |
+
|
119 |
+
Args:
|
120 |
+
query (str): The query text.
|
121 |
+
q_emb (torch.Tensor): Query embeddings.
|
122 |
+
hits (int, optional): Number of hits to retrieve. Defaults to 3.
|
123 |
+
timeout (str, optional): Query timeout. Defaults to "10s".
|
124 |
+
|
125 |
+
Returns:
|
126 |
+
dict: The formatted query results.
|
127 |
+
"""
|
128 |
+
async with self.app.asyncio(connections=1) as session:
|
129 |
+
query_embedding = self.format_q_embs(q_emb)
|
130 |
+
|
131 |
+
start = time.perf_counter()
|
132 |
+
response: VespaQueryResponse = await session.query(
|
133 |
+
body={
|
134 |
+
"yql": (
|
135 |
+
f"select {self.get_fields(sim_map=sim_map)} from {self.VESPA_SCHEMA_NAME} where userQuery();"
|
136 |
+
),
|
137 |
+
"ranking": self.get_rank_profile("default", sim_map),
|
138 |
+
"query": query,
|
139 |
+
"timeout": timeout,
|
140 |
+
"hits": hits,
|
141 |
+
"input.query(qt)": query_embedding,
|
142 |
+
"presentation.timing": True,
|
143 |
+
**kwargs,
|
144 |
+
},
|
145 |
+
)
|
146 |
+
assert response.is_successful(), response.json
|
147 |
+
stop = time.perf_counter()
|
148 |
+
self.logger.debug(
|
149 |
+
f"Query time + data transfer took: {stop - start} s, Vespa reported searchtime was "
|
150 |
+
f"{response.json.get('timing', {}).get('searchtime', -1)} s"
|
151 |
+
)
|
152 |
+
return self.format_query_results(query, response)
|
153 |
+
|
154 |
+
async def query_vespa_bm25(
|
155 |
+
self,
|
156 |
+
query: str,
|
157 |
+
q_emb: torch.Tensor,
|
158 |
+
hits: int = 3,
|
159 |
+
timeout: str = "10s",
|
160 |
+
sim_map: bool = False,
|
161 |
+
**kwargs,
|
162 |
+
) -> dict:
|
163 |
+
"""
|
164 |
+
Query Vespa using the BM25 ranking profile.
|
165 |
+
|
166 |
+
Args:
|
167 |
+
query (str): The query text.
|
168 |
+
q_emb (torch.Tensor): Query embeddings.
|
169 |
+
hits (int, optional): Number of hits to retrieve. Defaults to 3.
|
170 |
+
timeout (str, optional): Query timeout. Defaults to "10s".
|
171 |
+
|
172 |
+
Returns:
|
173 |
+
dict: The formatted query results.
|
174 |
+
"""
|
175 |
+
async with self.app.asyncio(connections=1) as session:
|
176 |
+
query_embedding = self.format_q_embs(q_emb)
|
177 |
+
|
178 |
+
start = time.perf_counter()
|
179 |
+
response: VespaQueryResponse = await session.query(
|
180 |
+
body={
|
181 |
+
"yql": (
|
182 |
+
f"select {self.get_fields(sim_map=sim_map)} from {self.VESPA_SCHEMA_NAME} where userQuery();"
|
183 |
+
),
|
184 |
+
"ranking": self.get_rank_profile("bm25", sim_map),
|
185 |
+
"query": query,
|
186 |
+
"timeout": timeout,
|
187 |
+
"hits": hits,
|
188 |
+
"input.query(qt)": query_embedding,
|
189 |
+
"presentation.timing": True,
|
190 |
+
**kwargs,
|
191 |
+
},
|
192 |
+
)
|
193 |
+
assert response.is_successful(), response.json
|
194 |
+
stop = time.perf_counter()
|
195 |
+
self.logger.debug(
|
196 |
+
f"Query time + data transfer took: {stop - start} s, Vespa reported searchtime was "
|
197 |
+
f"{response.json.get('timing', {}).get('searchtime', -1)} s"
|
198 |
+
)
|
199 |
+
return self.format_query_results(query, response)
|
200 |
+
|
201 |
+
def float_to_binary_embedding(self, float_query_embedding: dict) -> dict:
|
202 |
+
"""
|
203 |
+
Convert float query embeddings to binary embeddings.
|
204 |
+
|
205 |
+
Args:
|
206 |
+
float_query_embedding (dict): Dictionary of float embeddings.
|
207 |
+
|
208 |
+
Returns:
|
209 |
+
dict: Dictionary of binary embeddings.
|
210 |
+
"""
|
211 |
+
binary_query_embeddings = {}
|
212 |
+
for key, vector in float_query_embedding.items():
|
213 |
+
binary_vector = (
|
214 |
+
np.packbits(np.where(np.array(vector) > 0, 1, 0))
|
215 |
+
.astype(np.int8)
|
216 |
+
.tolist()
|
217 |
+
)
|
218 |
+
binary_query_embeddings[key] = binary_vector
|
219 |
+
if len(binary_query_embeddings) >= self.MAX_QUERY_TERMS:
|
220 |
+
self.logger.warning(
|
221 |
+
f"Warning: Query has more than {self.MAX_QUERY_TERMS} terms. Truncating."
|
222 |
+
)
|
223 |
+
break
|
224 |
+
return binary_query_embeddings
|
225 |
+
|
226 |
+
def create_nn_query_strings(
|
227 |
+
self, binary_query_embeddings: dict, target_hits_per_query_tensor: int = 20
|
228 |
+
) -> Tuple[str, dict]:
|
229 |
+
"""
|
230 |
+
Create nearest neighbor query strings for Vespa.
|
231 |
+
|
232 |
+
Args:
|
233 |
+
binary_query_embeddings (dict): Binary query embeddings.
|
234 |
+
target_hits_per_query_tensor (int, optional): Target hits per query tensor. Defaults to 20.
|
235 |
+
|
236 |
+
Returns:
|
237 |
+
Tuple[str, dict]: Nearest neighbor query string and query tensor dictionary.
|
238 |
+
"""
|
239 |
+
nn_query_dict = {}
|
240 |
+
for i in range(len(binary_query_embeddings)):
|
241 |
+
nn_query_dict[f"input.query(rq{i})"] = binary_query_embeddings[i]
|
242 |
+
nn = " OR ".join(
|
243 |
+
[
|
244 |
+
f"({{targetHits:{target_hits_per_query_tensor}}}nearestNeighbor(embedding,rq{i}))"
|
245 |
+
for i in range(len(binary_query_embeddings))
|
246 |
+
]
|
247 |
+
)
|
248 |
+
return nn, nn_query_dict
|
249 |
+
|
250 |
+
def format_q_embs(self, q_embs: torch.Tensor) -> dict:
|
251 |
+
"""
|
252 |
+
Convert query embeddings to a dictionary of lists.
|
253 |
+
|
254 |
+
Args:
|
255 |
+
q_embs (torch.Tensor): Query embeddings tensor.
|
256 |
+
|
257 |
+
Returns:
|
258 |
+
dict: Dictionary where each key is an index and value is the embedding list.
|
259 |
+
"""
|
260 |
+
return {idx: emb.tolist() for idx, emb in enumerate(q_embs)}
|
261 |
+
|
262 |
+
async def get_result_from_query(
|
263 |
+
self,
|
264 |
+
query: str,
|
265 |
+
q_embs: torch.Tensor,
|
266 |
+
ranking: str,
|
267 |
+
idx_to_token: dict,
|
268 |
+
) -> Dict[str, Any]:
|
269 |
+
"""
|
270 |
+
Get query results from Vespa based on the ranking method.
|
271 |
+
|
272 |
+
Args:
|
273 |
+
query (str): The query text.
|
274 |
+
q_embs (torch.Tensor): Query embeddings.
|
275 |
+
ranking (str): The ranking method to use.
|
276 |
+
idx_to_token (dict): Index to token mapping.
|
277 |
+
|
278 |
+
Returns:
|
279 |
+
Dict[str, Any]: The query results.
|
280 |
+
"""
|
281 |
+
|
282 |
+
# Remove stopwords from the query to avoid visual emphasis on irrelevant words (e.g., "the", "and", "of")
|
283 |
+
query = backend.stopwords.filter(query)
|
284 |
+
|
285 |
+
rank_method = ranking.split("_")[0]
|
286 |
+
sim_map: bool = len(ranking.split("_")) > 1 and ranking.split("_")[1] == "sim"
|
287 |
+
if rank_method == "nn+colpali":
|
288 |
+
result = await self.query_vespa_nearest_neighbor(
|
289 |
+
query, q_embs, sim_map=sim_map
|
290 |
+
)
|
291 |
+
elif rank_method == "bm25+colpali":
|
292 |
+
result = await self.query_vespa_default(query, q_embs, sim_map=sim_map)
|
293 |
+
elif rank_method == "bm25":
|
294 |
+
result = await self.query_vespa_bm25(query, q_embs, sim_map=sim_map)
|
295 |
+
else:
|
296 |
+
raise ValueError(f"Unsupported ranking: {rank_method}")
|
297 |
+
if "root" not in result or "children" not in result["root"]:
|
298 |
+
result["root"] = {"children": []}
|
299 |
+
return result
|
300 |
+
for single_result in result["root"]["children"]:
|
301 |
+
self.logger.debug(single_result["fields"].keys())
|
302 |
+
return result
|
303 |
+
|
304 |
+
def get_sim_maps_from_query(
|
305 |
+
self, query: str, q_embs: torch.Tensor, ranking: str, idx_to_token: dict
|
306 |
+
):
|
307 |
+
"""
|
308 |
+
Get similarity maps from Vespa based on the ranking method.
|
309 |
+
|
310 |
+
Args:
|
311 |
+
query (str): The query text.
|
312 |
+
q_embs (torch.Tensor): Query embeddings.
|
313 |
+
ranking (str): The ranking method to use.
|
314 |
+
idx_to_token (dict): Index to token mapping.
|
315 |
+
|
316 |
+
Returns:
|
317 |
+
Dict[str, Any]: The query results.
|
318 |
+
"""
|
319 |
+
# Get the result by calling asyncio.run
|
320 |
+
result = asyncio.run(
|
321 |
+
self.get_result_from_query(query, q_embs, ranking, idx_to_token)
|
322 |
+
)
|
323 |
+
vespa_sim_maps = []
|
324 |
+
for single_result in result["root"]["children"]:
|
325 |
+
vespa_sim_map = single_result["fields"].get("summaryfeatures", None)
|
326 |
+
if vespa_sim_map is not None:
|
327 |
+
vespa_sim_maps.append(vespa_sim_map)
|
328 |
+
else:
|
329 |
+
raise ValueError("No sim_map found in Vespa response")
|
330 |
+
return vespa_sim_maps
|
331 |
+
|
332 |
+
async def get_full_image_from_vespa(self, doc_id: str) -> str:
|
333 |
+
"""
|
334 |
+
Retrieve the full image from Vespa for a given document ID.
|
335 |
+
|
336 |
+
Args:
|
337 |
+
doc_id (str): The document ID.
|
338 |
+
|
339 |
+
Returns:
|
340 |
+
str: The full image data.
|
341 |
+
"""
|
342 |
+
async with self.app.asyncio(connections=1) as session:
|
343 |
+
start = time.perf_counter()
|
344 |
+
response: VespaQueryResponse = await session.query(
|
345 |
+
body={
|
346 |
+
"yql": f'select full_image from {self.VESPA_SCHEMA_NAME} where id contains "{doc_id}"',
|
347 |
+
"ranking": "unranked",
|
348 |
+
"presentation.timing": True,
|
349 |
+
},
|
350 |
+
)
|
351 |
+
assert response.is_successful(), response.json
|
352 |
+
stop = time.perf_counter()
|
353 |
+
self.logger.debug(
|
354 |
+
f"Getting image from Vespa took: {stop - start} s, Vespa reported searchtime was "
|
355 |
+
f"{response.json.get('timing', {}).get('searchtime', -1)} s"
|
356 |
+
)
|
357 |
+
return response.json["root"]["children"][0]["fields"]["full_image"]
|
358 |
+
|
359 |
+
def get_results_children(self, result: VespaQueryResponse) -> list:
|
360 |
+
return result["root"]["children"]
|
361 |
+
|
362 |
+
def results_to_search_results(
|
363 |
+
self, result: VespaQueryResponse, idx_to_token: dict
|
364 |
+
) -> list:
|
365 |
+
# Initialize sim_map_ fields in the result
|
366 |
+
fields_to_add = [
|
367 |
+
f"sim_map_{token}_{idx}"
|
368 |
+
for idx, token in idx_to_token.items()
|
369 |
+
if not SimMapGenerator.should_filter_token(token)
|
370 |
+
]
|
371 |
+
for child in result["root"]["children"]:
|
372 |
+
for sim_map_key in fields_to_add:
|
373 |
+
child["fields"][sim_map_key] = None
|
374 |
+
return self.get_results_children(result)
|
375 |
+
|
376 |
+
async def get_suggestions(self, query: str) -> list:
|
377 |
+
async with self.app.asyncio(connections=1) as session:
|
378 |
+
start = time.perf_counter()
|
379 |
+
yql = f'select questions from {self.VESPA_SCHEMA_NAME} where questions matches (".*{query}.*")'
|
380 |
+
response: VespaQueryResponse = await session.query(
|
381 |
+
body={
|
382 |
+
"yql": yql,
|
383 |
+
"query": query,
|
384 |
+
"ranking": "unranked",
|
385 |
+
"presentation.timing": True,
|
386 |
+
"presentation.summary": "suggestions",
|
387 |
+
},
|
388 |
+
)
|
389 |
+
assert response.is_successful(), response.json
|
390 |
+
stop = time.perf_counter()
|
391 |
+
self.logger.debug(
|
392 |
+
f"Getting suggestions from Vespa took: {stop - start} s, Vespa reported searchtime was "
|
393 |
+
f"{response.json.get('timing', {}).get('searchtime', -1)} s"
|
394 |
+
)
|
395 |
+
search_results = (
|
396 |
+
response.json["root"]["children"]
|
397 |
+
if "root" in response.json and "children" in response.json["root"]
|
398 |
+
else []
|
399 |
+
)
|
400 |
+
questions = [
|
401 |
+
result["fields"]["questions"]
|
402 |
+
for result in search_results
|
403 |
+
if "questions" in result["fields"]
|
404 |
+
]
|
405 |
+
for q in questions:
|
406 |
+
print(q)
|
407 |
+
unique_questions = set([item for sublist in questions for item in sublist])
|
408 |
+
|
409 |
+
# remove an artifact from our data generation
|
410 |
+
if "string" in unique_questions:
|
411 |
+
unique_questions.remove("string")
|
412 |
+
|
413 |
+
return list(unique_questions)
|
414 |
+
|
415 |
+
def get_rank_profile(self, ranking: str, sim_map: bool) -> str:
|
416 |
+
if sim_map:
|
417 |
+
return f"{ranking}_sim"
|
418 |
+
else:
|
419 |
+
return ranking
|
420 |
+
|
421 |
+
async def query_vespa_nearest_neighbor(
|
422 |
+
self,
|
423 |
+
query: str,
|
424 |
+
q_emb: torch.Tensor,
|
425 |
+
target_hits_per_query_tensor: int = 20,
|
426 |
+
hits: int = 3,
|
427 |
+
timeout: str = "10s",
|
428 |
+
sim_map: bool = False,
|
429 |
+
**kwargs,
|
430 |
+
) -> dict:
|
431 |
+
"""
|
432 |
+
Query Vespa using nearest neighbor search with mixed tensors for MaxSim calculations.
|
433 |
+
|
434 |
+
Args:
|
435 |
+
query (str): The query text.
|
436 |
+
q_emb (torch.Tensor): Query embeddings.
|
437 |
+
target_hits_per_query_tensor (int, optional): Target hits per query tensor. Defaults to 20.
|
438 |
+
hits (int, optional): Number of hits to retrieve. Defaults to 3.
|
439 |
+
timeout (str, optional): Query timeout. Defaults to "10s".
|
440 |
+
|
441 |
+
Returns:
|
442 |
+
dict: The formatted query results.
|
443 |
+
"""
|
444 |
+
async with self.app.asyncio(connections=1) as session:
|
445 |
+
float_query_embedding = self.format_q_embs(q_emb)
|
446 |
+
binary_query_embeddings = self.float_to_binary_embedding(
|
447 |
+
float_query_embedding
|
448 |
+
)
|
449 |
+
|
450 |
+
# Mixed tensors for MaxSim calculations
|
451 |
+
query_tensors = {
|
452 |
+
"input.query(qtb)": binary_query_embeddings,
|
453 |
+
"input.query(qt)": float_query_embedding,
|
454 |
+
}
|
455 |
+
nn_string, nn_query_dict = self.create_nn_query_strings(
|
456 |
+
binary_query_embeddings, target_hits_per_query_tensor
|
457 |
+
)
|
458 |
+
query_tensors.update(nn_query_dict)
|
459 |
+
response: VespaQueryResponse = await session.query(
|
460 |
+
body={
|
461 |
+
**query_tensors,
|
462 |
+
"presentation.timing": True,
|
463 |
+
"yql": (
|
464 |
+
f"select {self.get_fields(sim_map=sim_map)} from {self.VESPA_SCHEMA_NAME} where {nn_string} or userQuery()"
|
465 |
+
),
|
466 |
+
"ranking.profile": self.get_rank_profile(
|
467 |
+
"retrieval-and-rerank", sim_map
|
468 |
+
),
|
469 |
+
"timeout": timeout,
|
470 |
+
"hits": hits,
|
471 |
+
"query": query,
|
472 |
+
**kwargs,
|
473 |
+
},
|
474 |
+
)
|
475 |
+
assert response.is_successful(), response.json
|
476 |
+
return self.format_query_results(query, response)
|
477 |
+
|
478 |
+
async def keepalive(self) -> bool:
|
479 |
+
"""
|
480 |
+
Query Vespa to keep the connection alive.
|
481 |
+
|
482 |
+
Returns:
|
483 |
+
bool: True if the connection is alive.
|
484 |
+
"""
|
485 |
+
async with self.app.asyncio(connections=1) as session:
|
486 |
+
response: VespaQueryResponse = await session.query(
|
487 |
+
body={
|
488 |
+
"yql": f"select title from {self.VESPA_SCHEMA_NAME} where true limit 1;",
|
489 |
+
"ranking": "unranked",
|
490 |
+
"query": "keepalive",
|
491 |
+
"timeout": "3s",
|
492 |
+
"hits": 1,
|
493 |
+
},
|
494 |
+
)
|
495 |
+
assert response.is_successful(), response.json
|
496 |
+
return True
|
src/frontend/__init__.py
ADDED
File without changes
|
src/frontend/app.py
ADDED
@@ -0,0 +1,644 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Optional
|
2 |
+
from urllib.parse import quote_plus
|
3 |
+
|
4 |
+
from fasthtml.components import H1, H2, H3, Br, Div, Form, Img, NotStr, P, Span, Strong
|
5 |
+
from fasthtml.xtend import A, Script
|
6 |
+
from lucide_fasthtml import Lucide
|
7 |
+
from shad4fast import Badge, Button, Input, Label, RadioGroup, RadioGroupItem, Separator
|
8 |
+
|
9 |
+
# JavaScript to check the input value and enable/disable the search button and radio buttons
|
10 |
+
check_input_script = Script(
|
11 |
+
"""
|
12 |
+
window.onload = function() {
|
13 |
+
const input = document.getElementById('search-input');
|
14 |
+
const button = document.querySelector('[data-button="search-button"]');
|
15 |
+
const radioGroupItems = document.querySelectorAll('button[data-ref="radio-item"]'); // Get all radio buttons
|
16 |
+
|
17 |
+
function checkInputValue() {
|
18 |
+
const isInputEmpty = input.value.trim() === "";
|
19 |
+
button.disabled = isInputEmpty; // Disable the submit button
|
20 |
+
radioGroupItems.forEach(item => {
|
21 |
+
item.disabled = isInputEmpty; // Disable/enable the radio buttons
|
22 |
+
});
|
23 |
+
}
|
24 |
+
|
25 |
+
input.addEventListener('input', checkInputValue); // Listen for input changes
|
26 |
+
checkInputValue(); // Initial check when the page loads
|
27 |
+
};
|
28 |
+
"""
|
29 |
+
)
|
30 |
+
|
31 |
+
# JavaScript to handle the image swapping, reset button, and active class toggling
|
32 |
+
image_swapping = Script(
|
33 |
+
"""
|
34 |
+
document.addEventListener('click', function (e) {
|
35 |
+
if (e.target.classList.contains('sim-map-button') || e.target.classList.contains('reset-button')) {
|
36 |
+
const imgContainer = e.target.closest('.relative');
|
37 |
+
const overlayContainer = imgContainer.querySelector('.overlay-container');
|
38 |
+
const newSrc = e.target.getAttribute('data-image-src');
|
39 |
+
|
40 |
+
// If it's a reset button, remove the overlay image
|
41 |
+
if (e.target.classList.contains('reset-button')) {
|
42 |
+
overlayContainer.innerHTML = ''; // Clear the overlay container, showing only the full image
|
43 |
+
} else {
|
44 |
+
// Create a new overlay image
|
45 |
+
const img = document.createElement('img');
|
46 |
+
img.src = newSrc;
|
47 |
+
img.classList.add('overlay-image', 'absolute', 'top-0', 'left-0', 'w-full', 'h-full');
|
48 |
+
overlayContainer.innerHTML = ''; // Clear any previous overlay
|
49 |
+
overlayContainer.appendChild(img); // Add the new overlay image
|
50 |
+
}
|
51 |
+
|
52 |
+
// Toggle active class on buttons
|
53 |
+
const activeButton = document.querySelector('.sim-map-button.active');
|
54 |
+
if (activeButton) {
|
55 |
+
activeButton.classList.remove('active');
|
56 |
+
}
|
57 |
+
if (e.target.classList.contains('sim-map-button')) {
|
58 |
+
e.target.classList.add('active');
|
59 |
+
}
|
60 |
+
}
|
61 |
+
});
|
62 |
+
"""
|
63 |
+
)
|
64 |
+
|
65 |
+
toggle_text_content = Script(
|
66 |
+
"""
|
67 |
+
function toggleTextContent(idx) {
|
68 |
+
const textColumn = document.getElementById(`text-column-${idx}`);
|
69 |
+
const imageTextColumns = document.getElementById(`image-text-columns-${idx}`);
|
70 |
+
const toggleButton = document.getElementById(`toggle-button-${idx}`);
|
71 |
+
|
72 |
+
if (textColumn.classList.contains('md-grid-text-column')) {
|
73 |
+
// Hide the text column
|
74 |
+
textColumn.classList.remove('md-grid-text-column');
|
75 |
+
imageTextColumns.classList.remove('grid-image-text-columns');
|
76 |
+
toggleButton.innerText = `Show Text`;
|
77 |
+
} else {
|
78 |
+
// Show the text column
|
79 |
+
textColumn.classList.add('md-grid-text-column');
|
80 |
+
imageTextColumns.classList.add('grid-image-text-columns');
|
81 |
+
toggleButton.innerText = `Hide Text`;
|
82 |
+
}
|
83 |
+
}
|
84 |
+
"""
|
85 |
+
)
|
86 |
+
|
87 |
+
autocomplete_script = Script(
|
88 |
+
"""
|
89 |
+
document.addEventListener('DOMContentLoaded', function() {
|
90 |
+
const input = document.querySelector('#search-input');
|
91 |
+
const awesomplete = new Awesomplete(input, { minChars: 1, maxItems: 5 });
|
92 |
+
|
93 |
+
input.addEventListener('input', function() {
|
94 |
+
if (this.value.length >= 1) {
|
95 |
+
// Use template literals to insert the input value dynamically in the query parameter
|
96 |
+
fetch(`/suggestions?query=${encodeURIComponent(this.value)}`)
|
97 |
+
.then(response => response.json())
|
98 |
+
.then(data => {
|
99 |
+
// Update the Awesomplete list dynamically with fetched suggestions
|
100 |
+
awesomplete.list = data.suggestions;
|
101 |
+
})
|
102 |
+
.catch(err => console.error('Error fetching suggestions:', err));
|
103 |
+
}
|
104 |
+
});
|
105 |
+
});
|
106 |
+
"""
|
107 |
+
)
|
108 |
+
|
109 |
+
dynamic_elements_scrollbars = Script(
|
110 |
+
"""
|
111 |
+
(function () {
|
112 |
+
const { applyOverlayScrollbars, getScrollbarTheme } = OverlayScrollbarsManager;
|
113 |
+
|
114 |
+
function applyScrollbarsToDynamicElements() {
|
115 |
+
const scrollbarTheme = getScrollbarTheme();
|
116 |
+
|
117 |
+
// Apply scrollbars to dynamically loaded result-text-full and result-text-snippet elements
|
118 |
+
const resultTextFullElements = document.querySelectorAll('[id^="result-text-full"]');
|
119 |
+
const resultTextSnippetElements = document.querySelectorAll('[id^="result-text-snippet"]');
|
120 |
+
|
121 |
+
resultTextFullElements.forEach(element => {
|
122 |
+
applyOverlayScrollbars(element, scrollbarTheme);
|
123 |
+
});
|
124 |
+
|
125 |
+
resultTextSnippetElements.forEach(element => {
|
126 |
+
applyOverlayScrollbars(element, scrollbarTheme);
|
127 |
+
});
|
128 |
+
}
|
129 |
+
|
130 |
+
// Apply scrollbars after dynamic content is loaded (e.g., after search results)
|
131 |
+
applyScrollbarsToDynamicElements();
|
132 |
+
|
133 |
+
// Observe changes in the 'dark' class to adjust the theme dynamically if needed
|
134 |
+
const observer = new MutationObserver(applyScrollbarsToDynamicElements);
|
135 |
+
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
|
136 |
+
})();
|
137 |
+
"""
|
138 |
+
)
|
139 |
+
|
140 |
+
submit_form_on_radio_change = Script(
|
141 |
+
"""
|
142 |
+
document.addEventListener('click', function (e) {
|
143 |
+
// if target has data-ref="radio-item" and type is button
|
144 |
+
if (e.target.getAttribute('data-ref') === 'radio-item' && e.target.type === 'button') {
|
145 |
+
console.log('Radio button clicked');
|
146 |
+
const form = e.target.closest('form');
|
147 |
+
form.submit();
|
148 |
+
}
|
149 |
+
});
|
150 |
+
"""
|
151 |
+
)
|
152 |
+
|
153 |
+
|
154 |
+
def SearchBox(with_border=False, query_value="", ranking_value="nn+colpali"):
|
155 |
+
grid_cls = "grid gap-2 items-center p-3 bg-muted w-full"
|
156 |
+
|
157 |
+
if with_border:
|
158 |
+
grid_cls = "grid gap-2 p-3 rounded-md border border-input bg-muted w-full ring-offset-background focus-within:outline-none focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-within:border-input"
|
159 |
+
|
160 |
+
return Form(
|
161 |
+
Div(
|
162 |
+
Lucide(
|
163 |
+
icon="search", cls="absolute left-2 top-2 text-muted-foreground z-10"
|
164 |
+
),
|
165 |
+
Input(
|
166 |
+
placeholder="Enter your search query...",
|
167 |
+
name="query",
|
168 |
+
value=query_value,
|
169 |
+
id="search-input",
|
170 |
+
cls="text-base pl-10 border-transparent ring-offset-transparent ring-0 focus-visible:ring-transparent bg-white dark:bg-background awesomplete",
|
171 |
+
data_list="#suggestions",
|
172 |
+
style="font-size: 1rem",
|
173 |
+
autofocus=True,
|
174 |
+
),
|
175 |
+
cls="relative",
|
176 |
+
),
|
177 |
+
Div(
|
178 |
+
Div(
|
179 |
+
Span("Ranking by:", cls="text-muted-foreground text-xs font-semibold"),
|
180 |
+
RadioGroup(
|
181 |
+
Div(
|
182 |
+
RadioGroupItem(value="nn+colpali", id="nn+colpali"),
|
183 |
+
Label("ColPali", htmlFor="ColPali"),
|
184 |
+
cls="flex items-center space-x-2",
|
185 |
+
),
|
186 |
+
Div(
|
187 |
+
RadioGroupItem(value="bm25", id="bm25"),
|
188 |
+
Label("BM25", htmlFor="BM25"),
|
189 |
+
cls="flex items-center space-x-2",
|
190 |
+
),
|
191 |
+
Div(
|
192 |
+
RadioGroupItem(value="bm25+colpali", id="bm25+colpali"),
|
193 |
+
Label("Hybrid ColPali + BM25", htmlFor="Hybrid ColPali + BM25"),
|
194 |
+
cls="flex items-center space-x-2",
|
195 |
+
),
|
196 |
+
name="ranking",
|
197 |
+
default_value=ranking_value,
|
198 |
+
cls="grid-flow-col gap-x-5 text-muted-foreground",
|
199 |
+
# Submit form when radio button is clicked
|
200 |
+
),
|
201 |
+
cls="grid grid-flow-col items-center gap-x-3 border border-input px-3 rounded-sm",
|
202 |
+
),
|
203 |
+
Button(
|
204 |
+
Lucide(icon="arrow-right", size="21"),
|
205 |
+
size="sm",
|
206 |
+
type="submit",
|
207 |
+
data_button="search-button",
|
208 |
+
disabled=True,
|
209 |
+
),
|
210 |
+
cls="flex justify-between",
|
211 |
+
),
|
212 |
+
check_input_script,
|
213 |
+
autocomplete_script,
|
214 |
+
submit_form_on_radio_change,
|
215 |
+
action=f"/search?query={quote_plus(query_value)}&ranking={quote_plus(ranking_value)}",
|
216 |
+
method="GET",
|
217 |
+
hx_get="/fetch_results", # As the component is a form, input components query and ranking are sent as query parameters automatically, see https://htmx.org/docs/#parameters
|
218 |
+
hx_trigger="load",
|
219 |
+
hx_target="#search-results",
|
220 |
+
hx_swap="outerHTML",
|
221 |
+
hx_indicator="#loading-indicator",
|
222 |
+
cls=grid_cls,
|
223 |
+
)
|
224 |
+
|
225 |
+
|
226 |
+
def SampleQueries():
|
227 |
+
sample_queries = [
|
228 |
+
"Total amount of fixed salaries paid in 2023?",
|
229 |
+
"Proportion of female new hires 2021-2023?",
|
230 |
+
"Number of internship applications trend 2021-2023",
|
231 |
+
"Gender balance at level 4 or above in NY office 2023?",
|
232 |
+
"What percentage of the funds unlisted real estate investments were in Switzerland 2023?",
|
233 |
+
"child jumping over puddle",
|
234 |
+
"hula hoop kid",
|
235 |
+
]
|
236 |
+
|
237 |
+
query_badges = []
|
238 |
+
for query in sample_queries:
|
239 |
+
query_badges.append(
|
240 |
+
A(
|
241 |
+
Badge(
|
242 |
+
Div(
|
243 |
+
Lucide(
|
244 |
+
icon="text-search", size="18", cls="text-muted-foreground"
|
245 |
+
),
|
246 |
+
Span(query, cls="text-base font-normal"),
|
247 |
+
cls="flex gap-2 items-center",
|
248 |
+
),
|
249 |
+
variant="outline",
|
250 |
+
cls="text-base font-normal text-muted-foreground hover:border-black dark:hover:border-white",
|
251 |
+
),
|
252 |
+
href=f"/search?query={quote_plus(query)}",
|
253 |
+
cls="no-underline",
|
254 |
+
)
|
255 |
+
)
|
256 |
+
|
257 |
+
return Div(*query_badges, cls="grid gap-2 justify-items-center")
|
258 |
+
|
259 |
+
|
260 |
+
def Hero():
|
261 |
+
return Div(
|
262 |
+
H1(
|
263 |
+
"Vespa.ai + ColPali",
|
264 |
+
cls="text-5xl md:text-7xl font-bold tracking-wide md:tracking-wider bg-clip-text text-transparent bg-gradient-to-r from-black to-slate-700 dark:from-white dark:to-slate-300 animate-fade-in",
|
265 |
+
),
|
266 |
+
P(
|
267 |
+
"Efficient Document Retrieval with Vision Language Models",
|
268 |
+
cls="text-lg md:text-2xl text-muted-foreground md:tracking-wide",
|
269 |
+
),
|
270 |
+
cls="grid gap-5 text-center",
|
271 |
+
)
|
272 |
+
|
273 |
+
|
274 |
+
def Home():
|
275 |
+
return Div(
|
276 |
+
Div(
|
277 |
+
Hero(),
|
278 |
+
SearchBox(with_border=True),
|
279 |
+
SampleQueries(),
|
280 |
+
cls="grid gap-8 content-start mt-[13vh]",
|
281 |
+
),
|
282 |
+
cls="grid w-full h-full max-w-screen-md gap-4 mx-auto",
|
283 |
+
)
|
284 |
+
|
285 |
+
|
286 |
+
def AboutThisDemo():
|
287 |
+
return Div(
|
288 |
+
Div(
|
289 |
+
Div(
|
290 |
+
H1(
|
291 |
+
"Vespa.ai + ColPali",
|
292 |
+
cls="text-5xl font-bold tracking-wide md:tracking-wider",
|
293 |
+
),
|
294 |
+
P(
|
295 |
+
"Efficient Document Retrieval with Vision Language Models",
|
296 |
+
cls="text-lg text-muted-foreground md:tracking-wide",
|
297 |
+
),
|
298 |
+
Div(
|
299 |
+
Img(
|
300 |
+
src="/static/img/vespa-colpali.png",
|
301 |
+
alt="Vespa and ColPali",
|
302 |
+
cls="object-contain h-[377px]",
|
303 |
+
),
|
304 |
+
cls="grid justify-center",
|
305 |
+
),
|
306 |
+
Div(
|
307 |
+
P(
|
308 |
+
"This is a demo application showcasing the integration of Vespa.ai and ColPali for visual retrieval of documents.",
|
309 |
+
cls="text-base",
|
310 |
+
),
|
311 |
+
P(
|
312 |
+
"The application uses a combination of neural networks and traditional search algorithms to retrieve relevant documents based on visual and textual queries.",
|
313 |
+
cls="text-base",
|
314 |
+
),
|
315 |
+
cls="grid gap-2 text-center",
|
316 |
+
),
|
317 |
+
cls="grid gap-5 text-center",
|
318 |
+
),
|
319 |
+
cls="grid gap-8 content-start mt-[8vh]",
|
320 |
+
),
|
321 |
+
cls="grid w-full h-full max-w-screen-md gap-4 mx-auto",
|
322 |
+
)
|
323 |
+
|
324 |
+
|
325 |
+
def Search(request, search_results=[]):
|
326 |
+
query_value = request.query_params.get("query", "").strip()
|
327 |
+
ranking_value = request.query_params.get("ranking", "nn+colpali")
|
328 |
+
return Div(
|
329 |
+
Div(
|
330 |
+
Div(
|
331 |
+
SearchBox(query_value=query_value, ranking_value=ranking_value),
|
332 |
+
Div(
|
333 |
+
LoadingMessage(),
|
334 |
+
id="search-results", # This will be replaced by the search results
|
335 |
+
),
|
336 |
+
cls="grid",
|
337 |
+
),
|
338 |
+
cls="grid",
|
339 |
+
),
|
340 |
+
)
|
341 |
+
|
342 |
+
|
343 |
+
def LoadingMessage(display_text="Retrieving search results"):
|
344 |
+
return Div(
|
345 |
+
Lucide(icon="loader-circle", cls="size-5 mr-1.5 animate-spin"),
|
346 |
+
Span(display_text, cls="text-base text-center"),
|
347 |
+
cls="p-10 text-muted-foreground flex items-center justify-center",
|
348 |
+
id="loading-indicator",
|
349 |
+
)
|
350 |
+
|
351 |
+
|
352 |
+
def LoadingSkeleton():
|
353 |
+
return Div(
|
354 |
+
Div(cls="h-5 bg-muted"),
|
355 |
+
Div(cls="h-5 bg-muted"),
|
356 |
+
Div(cls="h-5 bg-muted"),
|
357 |
+
cls="grid gap-2 animate-pulse",
|
358 |
+
)
|
359 |
+
|
360 |
+
|
361 |
+
def SimMapButtonReady(query_id, idx, token, token_idx, img_src):
|
362 |
+
return Button(
|
363 |
+
token.replace("\u2581", ""),
|
364 |
+
size="sm",
|
365 |
+
data_image_src=img_src,
|
366 |
+
id=f"sim-map-button-{query_id}-{idx}-{token_idx}-{token}",
|
367 |
+
cls="sim-map-button pointer-events-auto font-mono text-xs h-5 rounded-none px-2",
|
368 |
+
)
|
369 |
+
|
370 |
+
|
371 |
+
def SimMapButtonPoll(query_id, idx, token, token_idx):
|
372 |
+
return Button(
|
373 |
+
Lucide(icon="loader-circle", size="15", cls="animate-spin"),
|
374 |
+
size="sm",
|
375 |
+
disabled=True,
|
376 |
+
hx_get=f"/get_sim_map?query_id={query_id}&idx={idx}&token={token}&token_idx={token_idx}",
|
377 |
+
hx_trigger="every 0.5s",
|
378 |
+
hx_swap="outerHTML",
|
379 |
+
cls="pointer-events-auto text-xs h-5 rounded-none px-2",
|
380 |
+
)
|
381 |
+
|
382 |
+
|
383 |
+
def SearchInfo(search_time, total_count):
|
384 |
+
return (
|
385 |
+
Div(
|
386 |
+
Span(
|
387 |
+
"Retrieved ",
|
388 |
+
Strong(total_count),
|
389 |
+
Span(" results"),
|
390 |
+
Span(" in "),
|
391 |
+
Strong(f"{search_time:.3f}"), # 3 significant digits
|
392 |
+
Span(" seconds."),
|
393 |
+
),
|
394 |
+
cls="grid bg-background border-t text-sm text-center p-3",
|
395 |
+
),
|
396 |
+
)
|
397 |
+
|
398 |
+
|
399 |
+
def SearchResult(
|
400 |
+
results: list,
|
401 |
+
query: str,
|
402 |
+
query_id: Optional[str] = None,
|
403 |
+
search_time: float = 0,
|
404 |
+
total_count: int = 0,
|
405 |
+
):
|
406 |
+
if not results:
|
407 |
+
return Div(
|
408 |
+
P(
|
409 |
+
"No results found for your query.",
|
410 |
+
cls="text-muted-foreground text-base text-center",
|
411 |
+
),
|
412 |
+
cls="grid p-10",
|
413 |
+
)
|
414 |
+
|
415 |
+
doc_ids = []
|
416 |
+
# Otherwise, display the search results
|
417 |
+
result_items = []
|
418 |
+
for idx, result in enumerate(results):
|
419 |
+
fields = result["fields"] # Extract the 'fields' part of each result
|
420 |
+
doc_id = fields["id"]
|
421 |
+
doc_ids.append(doc_id)
|
422 |
+
blur_image_base64 = f"data:image/jpeg;base64,{fields['blur_image']}"
|
423 |
+
|
424 |
+
sim_map_fields = {
|
425 |
+
key: value
|
426 |
+
for key, value in fields.items()
|
427 |
+
if key.startswith(
|
428 |
+
"sim_map_"
|
429 |
+
) # filtering is done before creating with 'should_filter_token'-function
|
430 |
+
}
|
431 |
+
|
432 |
+
# Generate buttons for the sim_map fields
|
433 |
+
sim_map_buttons = []
|
434 |
+
for key, value in sim_map_fields.items():
|
435 |
+
token = key.split("_")[-2]
|
436 |
+
token_idx = int(key.split("_")[-1])
|
437 |
+
if value is not None:
|
438 |
+
sim_map_base64 = f"data:image/jpeg;base64,{value}"
|
439 |
+
sim_map_buttons.append(
|
440 |
+
SimMapButtonReady(
|
441 |
+
query_id=query_id,
|
442 |
+
idx=idx,
|
443 |
+
token=token,
|
444 |
+
token_idx=token_idx,
|
445 |
+
img_src=sim_map_base64,
|
446 |
+
)
|
447 |
+
)
|
448 |
+
else:
|
449 |
+
sim_map_buttons.append(
|
450 |
+
SimMapButtonPoll(
|
451 |
+
query_id=query_id,
|
452 |
+
idx=idx,
|
453 |
+
token=token,
|
454 |
+
token_idx=token_idx,
|
455 |
+
)
|
456 |
+
)
|
457 |
+
|
458 |
+
# Add "Reset Image" button to restore the full image
|
459 |
+
reset_button = Button(
|
460 |
+
"Reset",
|
461 |
+
variant="outline",
|
462 |
+
size="sm",
|
463 |
+
data_image_src=blur_image_base64,
|
464 |
+
cls="reset-button pointer-events-auto font-mono text-xs h-5 rounded-none px-2",
|
465 |
+
)
|
466 |
+
|
467 |
+
tokens_icon = Lucide(icon="images", size="15")
|
468 |
+
|
469 |
+
# Add "Tokens" button - this has no action, just a placeholder
|
470 |
+
tokens_button = Button(
|
471 |
+
tokens_icon,
|
472 |
+
"Tokens",
|
473 |
+
size="sm",
|
474 |
+
cls="tokens-button flex gap-[3px] font-bold pointer-events-none font-mono text-xs h-5 rounded-none px-2",
|
475 |
+
)
|
476 |
+
|
477 |
+
result_items.append(
|
478 |
+
Div(
|
479 |
+
Div(
|
480 |
+
Div(
|
481 |
+
Lucide(icon="file-text"),
|
482 |
+
H2(fields["title"], cls="text-xl md:text-2xl font-semibold"),
|
483 |
+
Separator(orientation="vertical"),
|
484 |
+
Badge(
|
485 |
+
f"Relevance score: {result['relevance']:.4f}",
|
486 |
+
cls="flex gap-1.5 items-center justify-center",
|
487 |
+
),
|
488 |
+
cls="flex items-center gap-2",
|
489 |
+
),
|
490 |
+
Div(
|
491 |
+
Button(
|
492 |
+
"Hide Text",
|
493 |
+
size="sm",
|
494 |
+
id=f"toggle-button-{idx}",
|
495 |
+
onclick=f"toggleTextContent({idx})",
|
496 |
+
cls="hidden md:block",
|
497 |
+
),
|
498 |
+
),
|
499 |
+
cls="flex flex-wrap items-center justify-between bg-background px-3 py-4",
|
500 |
+
),
|
501 |
+
Div(
|
502 |
+
Div(
|
503 |
+
Div(
|
504 |
+
tokens_button,
|
505 |
+
*sim_map_buttons,
|
506 |
+
reset_button,
|
507 |
+
cls="flex flex-wrap gap-px w-full pointer-events-none",
|
508 |
+
),
|
509 |
+
Div(
|
510 |
+
Div(
|
511 |
+
Div(
|
512 |
+
Img(
|
513 |
+
src=blur_image_base64,
|
514 |
+
hx_get=f"/full_image?doc_id={doc_id}",
|
515 |
+
style="backdrop-filter: blur(5px);",
|
516 |
+
hx_trigger="load",
|
517 |
+
hx_swap="outerHTML",
|
518 |
+
alt=fields["title"],
|
519 |
+
cls="result-image w-full h-full object-contain",
|
520 |
+
),
|
521 |
+
Div(
|
522 |
+
cls="overlay-container absolute top-0 left-0 w-full h-full pointer-events-none"
|
523 |
+
),
|
524 |
+
cls="relative w-full h-full",
|
525 |
+
),
|
526 |
+
cls="grid bg-muted p-2",
|
527 |
+
),
|
528 |
+
cls="block",
|
529 |
+
),
|
530 |
+
id=f"image-column-{idx}",
|
531 |
+
cls="image-column relative bg-background px-3 py-5 grid-image-column",
|
532 |
+
),
|
533 |
+
Div(
|
534 |
+
Div(
|
535 |
+
A(
|
536 |
+
Lucide(icon="external-link", size="18"),
|
537 |
+
f"PDF Source (Page {fields['page_number'] + 1})",
|
538 |
+
href=f"{fields['url']}#page={fields['page_number'] + 1}",
|
539 |
+
target="_blank",
|
540 |
+
cls="flex items-center gap-1.5 font-mono bold text-sm",
|
541 |
+
),
|
542 |
+
cls="flex items-center justify-end",
|
543 |
+
),
|
544 |
+
Div(
|
545 |
+
Div(
|
546 |
+
Div(
|
547 |
+
Div(
|
548 |
+
Div(
|
549 |
+
H3(
|
550 |
+
"Dynamic summary",
|
551 |
+
cls="text-base font-semibold",
|
552 |
+
),
|
553 |
+
P(
|
554 |
+
NotStr(fields.get("snippet", "")),
|
555 |
+
cls="text-highlight text-muted-foreground",
|
556 |
+
),
|
557 |
+
cls="grid grid-rows-[auto_0px] content-start gap-y-3",
|
558 |
+
),
|
559 |
+
id=f"result-text-snippet-{idx}",
|
560 |
+
cls="grid gap-y-3 p-8 border border-dashed",
|
561 |
+
),
|
562 |
+
Div(
|
563 |
+
Div(
|
564 |
+
Div(
|
565 |
+
H3(
|
566 |
+
"Full text",
|
567 |
+
cls="text-base font-semibold",
|
568 |
+
),
|
569 |
+
Div(
|
570 |
+
P(
|
571 |
+
NotStr(fields.get("text", "")),
|
572 |
+
cls="text-highlight text-muted-foreground",
|
573 |
+
),
|
574 |
+
Br(),
|
575 |
+
),
|
576 |
+
cls="grid grid-rows-[auto_0px] content-start gap-y-3",
|
577 |
+
),
|
578 |
+
id=f"result-text-full-{idx}",
|
579 |
+
cls="grid gap-y-3 p-8 border border-dashed",
|
580 |
+
),
|
581 |
+
Div(
|
582 |
+
cls="absolute inset-x-0 bottom-0 bg-gradient-to-t from-[#fcfcfd] dark:from-[#1c2024] pt-[7%]"
|
583 |
+
),
|
584 |
+
cls="relative grid",
|
585 |
+
),
|
586 |
+
cls="grid grid-rows-[1fr_1fr] xl:grid-rows-[1fr_2fr] gap-y-8 p-8 text-sm",
|
587 |
+
),
|
588 |
+
cls="grid bg-background",
|
589 |
+
),
|
590 |
+
cls="grid bg-muted p-2",
|
591 |
+
),
|
592 |
+
id=f"text-column-{idx}",
|
593 |
+
cls="text-column relative bg-background px-3 py-5 hidden md-grid-text-column",
|
594 |
+
),
|
595 |
+
id=f"image-text-columns-{idx}",
|
596 |
+
cls="relative grid grid-cols-1 border-t grid-image-text-columns",
|
597 |
+
),
|
598 |
+
cls="grid grid-cols-1 grid-rows-[auto_auto_1fr]",
|
599 |
+
),
|
600 |
+
)
|
601 |
+
|
602 |
+
return [
|
603 |
+
Div(
|
604 |
+
SearchInfo(search_time, total_count),
|
605 |
+
*result_items,
|
606 |
+
image_swapping,
|
607 |
+
toggle_text_content,
|
608 |
+
dynamic_elements_scrollbars,
|
609 |
+
id="search-results",
|
610 |
+
cls="grid grid-cols-1 gap-px bg-border min-h-0",
|
611 |
+
),
|
612 |
+
Div(
|
613 |
+
ChatResult(query_id=query_id, query=query, doc_ids=doc_ids),
|
614 |
+
hx_swap_oob="true",
|
615 |
+
id="chat_messages",
|
616 |
+
),
|
617 |
+
]
|
618 |
+
|
619 |
+
|
620 |
+
def ChatResult(query_id: str, query: str, doc_ids: Optional[list] = None):
|
621 |
+
messages = Div(LoadingSkeleton())
|
622 |
+
|
623 |
+
if doc_ids:
|
624 |
+
messages = Div(
|
625 |
+
LoadingSkeleton(),
|
626 |
+
hx_ext="sse",
|
627 |
+
sse_connect=f"/get-message?query_id={query_id}&doc_ids={','.join(doc_ids)}&query={quote_plus(query)}",
|
628 |
+
sse_swap="message",
|
629 |
+
sse_close="close",
|
630 |
+
hx_swap="innerHTML",
|
631 |
+
)
|
632 |
+
|
633 |
+
return Div(
|
634 |
+
Div("AI-response (Gemini-8B)", cls="text-xl font-semibold p-5"),
|
635 |
+
Div(
|
636 |
+
Div(
|
637 |
+
messages,
|
638 |
+
),
|
639 |
+
id="chat-messages",
|
640 |
+
cls="overflow-auto min-h-0 grid items-end px-5",
|
641 |
+
),
|
642 |
+
id="chat_messages",
|
643 |
+
cls="h-full grid grid-rows-[auto_1fr_auto] min-h-0 gap-3",
|
644 |
+
)
|
src/frontend/layout.py
ADDED
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from fasthtml.components import Body, Div, Header, Img, Nav, Title
|
2 |
+
from fasthtml.xtend import A, Script
|
3 |
+
from lucide_fasthtml import Lucide
|
4 |
+
from shad4fast import Button, Separator
|
5 |
+
|
6 |
+
layout_script = Script(
|
7 |
+
"""
|
8 |
+
document.addEventListener("DOMContentLoaded", function () {
|
9 |
+
const main = document.querySelector('main');
|
10 |
+
const aside = document.querySelector('aside');
|
11 |
+
const body = document.body;
|
12 |
+
|
13 |
+
if (main && aside && main.nextElementSibling === aside) {
|
14 |
+
// If we have both main and aside, adjust the layout for larger screens
|
15 |
+
body.classList.remove('grid-cols-1'); // Remove single-column layout
|
16 |
+
body.classList.add('md:grid-cols-[minmax(0,_45fr)_minmax(0,_15fr)]'); // Two-column layout on larger screens
|
17 |
+
} else if (main) {
|
18 |
+
// If only main, keep it full width
|
19 |
+
body.classList.add('grid-cols-1');
|
20 |
+
}
|
21 |
+
});
|
22 |
+
"""
|
23 |
+
)
|
24 |
+
|
25 |
+
overlay_scrollbars_manager = Script(
|
26 |
+
"""
|
27 |
+
(function () {
|
28 |
+
const { OverlayScrollbars } = OverlayScrollbarsGlobal;
|
29 |
+
|
30 |
+
function getPreferredTheme() {
|
31 |
+
return localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
32 |
+
? 'dark'
|
33 |
+
: 'light';
|
34 |
+
}
|
35 |
+
|
36 |
+
function applyOverlayScrollbars(element, scrollbarTheme) {
|
37 |
+
// Destroy existing OverlayScrollbars instance if it exists
|
38 |
+
const instance = OverlayScrollbars(element);
|
39 |
+
if (instance) {
|
40 |
+
instance.destroy();
|
41 |
+
}
|
42 |
+
|
43 |
+
// Reinitialize OverlayScrollbars with the correct theme and settings
|
44 |
+
OverlayScrollbars(element, {
|
45 |
+
overflow: {
|
46 |
+
x: 'hidden',
|
47 |
+
y: 'scroll'
|
48 |
+
},
|
49 |
+
scrollbars: {
|
50 |
+
theme: scrollbarTheme,
|
51 |
+
visibility: 'auto',
|
52 |
+
autoHide: 'leave',
|
53 |
+
autoHideDelay: 800
|
54 |
+
}
|
55 |
+
});
|
56 |
+
}
|
57 |
+
|
58 |
+
// Function to get the current scrollbar theme (light or dark)
|
59 |
+
function getScrollbarTheme() {
|
60 |
+
const isDarkMode = getPreferredTheme() === 'dark';
|
61 |
+
return isDarkMode ? 'os-theme-light' : 'os-theme-dark'; // Light theme in dark mode, dark theme in light mode
|
62 |
+
}
|
63 |
+
|
64 |
+
// Expose the common functions globally for reuse
|
65 |
+
window.OverlayScrollbarsManager = {
|
66 |
+
applyOverlayScrollbars: applyOverlayScrollbars,
|
67 |
+
getScrollbarTheme: getScrollbarTheme
|
68 |
+
};
|
69 |
+
})();
|
70 |
+
"""
|
71 |
+
)
|
72 |
+
|
73 |
+
static_elements_scrollbars = Script(
|
74 |
+
"""
|
75 |
+
(function () {
|
76 |
+
const { applyOverlayScrollbars, getScrollbarTheme } = OverlayScrollbarsManager;
|
77 |
+
|
78 |
+
function applyScrollbarsToStaticElements() {
|
79 |
+
const mainElement = document.querySelector('main');
|
80 |
+
const chatMessagesElement = document.querySelector('#chat-messages');
|
81 |
+
|
82 |
+
const scrollbarTheme = getScrollbarTheme();
|
83 |
+
|
84 |
+
if (mainElement) {
|
85 |
+
applyOverlayScrollbars(mainElement, scrollbarTheme);
|
86 |
+
}
|
87 |
+
|
88 |
+
if (chatMessagesElement) {
|
89 |
+
applyOverlayScrollbars(chatMessagesElement, scrollbarTheme);
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
// Apply the scrollbars on page load
|
94 |
+
applyScrollbarsToStaticElements();
|
95 |
+
|
96 |
+
// Observe changes in the 'dark' class on the <html> element to adjust the theme dynamically
|
97 |
+
const observer = new MutationObserver(applyScrollbarsToStaticElements);
|
98 |
+
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
|
99 |
+
})();
|
100 |
+
"""
|
101 |
+
)
|
102 |
+
|
103 |
+
|
104 |
+
def Logo():
|
105 |
+
return Div(
|
106 |
+
Img(
|
107 |
+
src="https://assets.vespa.ai/logos/vespa-logo-black.svg",
|
108 |
+
alt="Vespa Logo",
|
109 |
+
cls="h-full dark:hidden",
|
110 |
+
),
|
111 |
+
Img(
|
112 |
+
src="https://assets.vespa.ai/logos/vespa-logo-white.svg",
|
113 |
+
alt="Vespa Logo Dark Mode",
|
114 |
+
cls="h-full hidden dark:block",
|
115 |
+
),
|
116 |
+
cls="h-[27px]",
|
117 |
+
)
|
118 |
+
|
119 |
+
|
120 |
+
def ThemeToggle(variant="ghost", cls=None, **kwargs):
|
121 |
+
return Button(
|
122 |
+
Lucide("sun", cls="dark:flex hidden"),
|
123 |
+
Lucide("moon", cls="dark:hidden"),
|
124 |
+
variant=variant,
|
125 |
+
size="icon",
|
126 |
+
cls=f"theme-toggle {cls}",
|
127 |
+
**kwargs,
|
128 |
+
)
|
129 |
+
|
130 |
+
|
131 |
+
def Links():
|
132 |
+
return Nav(
|
133 |
+
A(
|
134 |
+
Button("About this demo?", variant="link"),
|
135 |
+
href="/about-this-demo",
|
136 |
+
),
|
137 |
+
Separator(orientation="vertical"),
|
138 |
+
A(
|
139 |
+
Button(Lucide(icon="github"), size="icon", variant="ghost"),
|
140 |
+
href="https://github.com/vespa-engine/vespa",
|
141 |
+
target="_blank",
|
142 |
+
),
|
143 |
+
A(
|
144 |
+
Button(Lucide(icon="slack"), size="icon", variant="ghost"),
|
145 |
+
href="https://slack.vespa.ai",
|
146 |
+
target="_blank",
|
147 |
+
),
|
148 |
+
Separator(orientation="vertical"),
|
149 |
+
ThemeToggle(),
|
150 |
+
cls="flex items-center space-x-2",
|
151 |
+
)
|
152 |
+
|
153 |
+
|
154 |
+
def Layout(*c, is_home=False, **kwargs):
|
155 |
+
return (
|
156 |
+
Title("Visual Retrieval ColPali"),
|
157 |
+
Body(
|
158 |
+
Header(
|
159 |
+
A(Logo(), href="/"),
|
160 |
+
Links(),
|
161 |
+
cls="min-h-[55px] h-[55px] w-full flex items-center justify-between px-4",
|
162 |
+
),
|
163 |
+
*c,
|
164 |
+
**kwargs,
|
165 |
+
data_is_home=str(is_home).lower(),
|
166 |
+
cls="grid grid-rows-[minmax(0,55px)_minmax(0,1fr)] min-h-0",
|
167 |
+
),
|
168 |
+
layout_script,
|
169 |
+
overlay_scrollbars_manager,
|
170 |
+
static_elements_scrollbars,
|
171 |
+
)
|
src/globals.css
ADDED
@@ -0,0 +1,293 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@tailwind base;
|
2 |
+
@tailwind components;
|
3 |
+
@tailwind utilities;
|
4 |
+
|
5 |
+
|
6 |
+
@layer base {
|
7 |
+
:root {
|
8 |
+
--background: 240 20% 99%; /* 1 */
|
9 |
+
--foreground: 210 13% 13%; /* 12 */
|
10 |
+
--card: 240 20% 99%; /* 1 */
|
11 |
+
--card-foreground: 210 13% 13%; /* 12 */
|
12 |
+
--popover: 240 20% 99%; /* 1 */
|
13 |
+
--popover-foreground: 210 13% 13%; /* 12 */
|
14 |
+
--primary: 210 13% 13%; /* 12 */
|
15 |
+
--primary-foreground: 240 20% 98%; /* 2 */
|
16 |
+
--secondary: 240 11% 95%; /* 3 */
|
17 |
+
--secondary-foreground: 210 13% 13%; /* 12 */
|
18 |
+
--muted: 240 11% 95%; /* 3 */
|
19 |
+
--muted-foreground: 220 6% 40%; /* 11 */
|
20 |
+
--accent: 240 11% 95%; /* 3 */
|
21 |
+
--accent-foreground: 210 13% 13%; /* 12 */
|
22 |
+
--destructive: 358 75% 59%; /* 9 - red */
|
23 |
+
--destructive-foreground: 240 20% 98%; /* 2 */
|
24 |
+
--border: 240 10% 86%; /* 6 */
|
25 |
+
--input: 240 10% 86%; /* 6 */
|
26 |
+
--ring: 210 13% 13%; /* 12 */
|
27 |
+
--chart-1: 10 78% 54%; /* 9 - tomato */
|
28 |
+
--chart-2: 173 80% 36%; /* 9 - teal */
|
29 |
+
--chart-3: 206 100% 50%; /* 9 - blue */
|
30 |
+
--chart-4: 42 100% 62%; /* 9 - amber */
|
31 |
+
--chart-5: 23 93% 53%; /* 9 - orange */
|
32 |
+
}
|
33 |
+
|
34 |
+
.dark {
|
35 |
+
--background: 240 6% 7%; /* 1 */
|
36 |
+
--foreground: 220 9% 94%; /* 12 */
|
37 |
+
--card: 240 6% 7%; /* 1 */
|
38 |
+
--card-foreground: 220 9% 94%; /* 12 */
|
39 |
+
--popover: 240 6% 7%; /* 1 */
|
40 |
+
--popover-foreground: 220 9% 94%; /* 12 */
|
41 |
+
--primary: 220 9% 94%; /* 12 */
|
42 |
+
--primary-foreground: 220 6% 10%; /* 2 */
|
43 |
+
--secondary: 225 6% 14%; /* 3 */
|
44 |
+
--secondary-foreground: 220 9% 94%; /* 12 */
|
45 |
+
--muted: 225 6% 14%; /* 3 */
|
46 |
+
--muted-foreground: 216 7% 71%; /* 11 */
|
47 |
+
--accent: 225 6% 14%; /* 3 */
|
48 |
+
--accent-foreground: 220 9% 94%; /* 12 */
|
49 |
+
--destructive: 358 75% 59%; /* 9 - red */
|
50 |
+
--destructive-foreground: 220 9% 94%; /* 12 */
|
51 |
+
--border: 213 8% 23%; /* 6 */
|
52 |
+
--input: 213 8% 23%; /* 6 */
|
53 |
+
--ring: 220 9% 94%; /* 12 */
|
54 |
+
--chart-1: 10 78% 54%; /* 9 - tomato */
|
55 |
+
--chart-2: 173 80% 36%; /* 9 - teal */
|
56 |
+
--chart-3: 206 100% 50%; /* 9 - blue */
|
57 |
+
--chart-4: 42 100% 62%; /* 9 - amber */
|
58 |
+
--chart-5: 23 93% 53%; /* 9 - orange */
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
@layer base {
|
63 |
+
:root:has(.no-bg-scroll) {
|
64 |
+
overflow: hidden;
|
65 |
+
}
|
66 |
+
|
67 |
+
* {
|
68 |
+
@apply border-border;
|
69 |
+
}
|
70 |
+
|
71 |
+
body {
|
72 |
+
@apply bg-background text-foreground antialiased min-h-screen;
|
73 |
+
font-feature-settings: "rlig" 1, "calt" 1;
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
@layer utilities {
|
78 |
+
|
79 |
+
/* Hide scrollbar for Chrome, Safari and Opera */
|
80 |
+
.no-scrollbar::-webkit-scrollbar {
|
81 |
+
display: none;
|
82 |
+
}
|
83 |
+
|
84 |
+
/* Hide scrollbar for IE, Edge and Firefox */
|
85 |
+
.no-scrollbar {
|
86 |
+
-webkit-overflow-scrolling: touch;
|
87 |
+
-ms-overflow-style: none;
|
88 |
+
/* IE and Edge */
|
89 |
+
scrollbar-width: none;
|
90 |
+
/* Firefox */
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
@keyframes slideInFromTop {
|
95 |
+
from {
|
96 |
+
transform: translateY(-100%);
|
97 |
+
}
|
98 |
+
|
99 |
+
to {
|
100 |
+
transform: translateY(0);
|
101 |
+
}
|
102 |
+
}
|
103 |
+
|
104 |
+
@keyframes slideInFromBottom {
|
105 |
+
from {
|
106 |
+
transform: translateY(100%);
|
107 |
+
}
|
108 |
+
|
109 |
+
to {
|
110 |
+
transform: translateY(0);
|
111 |
+
}
|
112 |
+
}
|
113 |
+
|
114 |
+
.toast {
|
115 |
+
animation-duration: 0.2s;
|
116 |
+
animation-fill-mode: forwards;
|
117 |
+
}
|
118 |
+
|
119 |
+
@media (max-width: 640px) {
|
120 |
+
.toast {
|
121 |
+
animation-name: slideInFromTop;
|
122 |
+
}
|
123 |
+
}
|
124 |
+
|
125 |
+
@media (min-width: 641px) {
|
126 |
+
.toast {
|
127 |
+
animation-name: slideInFromBottom;
|
128 |
+
}
|
129 |
+
}
|
130 |
+
|
131 |
+
@keyframes fade-in {
|
132 |
+
from {
|
133 |
+
opacity: 0;
|
134 |
+
}
|
135 |
+
to {
|
136 |
+
opacity: 1;
|
137 |
+
}
|
138 |
+
}
|
139 |
+
|
140 |
+
@keyframes slide-up {
|
141 |
+
from {
|
142 |
+
transform: translateY(20px);
|
143 |
+
opacity: 0;
|
144 |
+
}
|
145 |
+
to {
|
146 |
+
transform: translateY(0);
|
147 |
+
opacity: 1;
|
148 |
+
}
|
149 |
+
}
|
150 |
+
|
151 |
+
.animate-fade-in {
|
152 |
+
animation: fade-in 1s ease-out forwards;
|
153 |
+
}
|
154 |
+
|
155 |
+
.animate-slide-up {
|
156 |
+
animation: slide-up 1s ease-out forwards;
|
157 |
+
}
|
158 |
+
|
159 |
+
.sim-map-button.active {
|
160 |
+
background-color: #61D790;
|
161 |
+
color: #2E2F27;
|
162 |
+
|
163 |
+
&:hover {
|
164 |
+
background-color: #61D790;
|
165 |
+
}
|
166 |
+
}
|
167 |
+
|
168 |
+
.text-highlight strong {
|
169 |
+
color: black;
|
170 |
+
|
171 |
+
.dark & {
|
172 |
+
color: white;
|
173 |
+
}
|
174 |
+
}
|
175 |
+
|
176 |
+
.tokens-button {
|
177 |
+
background-color: #B7E2F1;
|
178 |
+
color: #2E2F27;
|
179 |
+
}
|
180 |
+
|
181 |
+
.overlay-image {
|
182 |
+
opacity: 0.5;
|
183 |
+
position: absolute;
|
184 |
+
top: 0;
|
185 |
+
left: 0;
|
186 |
+
width: 100%;
|
187 |
+
height: 100%;
|
188 |
+
z-index: 10;
|
189 |
+
}
|
190 |
+
|
191 |
+
header {
|
192 |
+
grid-column: 1/-1;
|
193 |
+
}
|
194 |
+
|
195 |
+
body {
|
196 |
+
&[data-is-home="true"] {
|
197 |
+
background: radial-gradient(circle at 50% 100%, #fcfcfd, #fcfcfd, #fdfdfe, #fdfdfe, #fefefe, #fefefe, #ffffff, #ffffff);
|
198 |
+
|
199 |
+
.dark & {
|
200 |
+
background: radial-gradient(circle at 50% 50%, #272a2d, #242629, #212326, #1e1f22, #1b1c1e, #18181b, #151517, #111113);
|
201 |
+
}
|
202 |
+
}
|
203 |
+
}
|
204 |
+
|
205 |
+
main {
|
206 |
+
overflow: auto;
|
207 |
+
}
|
208 |
+
|
209 |
+
aside {
|
210 |
+
overflow: auto;
|
211 |
+
}
|
212 |
+
|
213 |
+
.scroll-container {
|
214 |
+
padding-right: 10px;
|
215 |
+
}
|
216 |
+
|
217 |
+
.question-message {
|
218 |
+
background-color: #61D790;
|
219 |
+
color: #2E2F27;
|
220 |
+
}
|
221 |
+
|
222 |
+
.grid-image-text-columns {
|
223 |
+
@apply md:grid-cols-2 md:col-span-2
|
224 |
+
}
|
225 |
+
|
226 |
+
.grid-image-column {
|
227 |
+
@apply grid grid-rows-subgrid row-span-2 content-start;
|
228 |
+
}
|
229 |
+
|
230 |
+
.md-grid-text-column {
|
231 |
+
@apply md:grid md:grid-rows-subgrid md:row-span-2 md:content-start;
|
232 |
+
}
|
233 |
+
|
234 |
+
#search-input[aria-expanded="true"] {
|
235 |
+
border-top: 1px solid hsl(var(--input));
|
236 |
+
border-left: 1px solid hsl(var(--input));
|
237 |
+
border-right: 1px solid hsl(var(--input));
|
238 |
+
border-bottom: none;
|
239 |
+
border-bottom-left-radius: 0;
|
240 |
+
border-bottom-right-radius: 0;
|
241 |
+
}
|
242 |
+
|
243 |
+
.awesomplete {
|
244 |
+
width: 100%;
|
245 |
+
}
|
246 |
+
|
247 |
+
.awesomplete > ul {
|
248 |
+
@apply text-sm space-y-1;
|
249 |
+
margin: 0;
|
250 |
+
border-top: none;
|
251 |
+
border-left: 1px solid hsl(var(--input));
|
252 |
+
border-right: 1px solid hsl(var(--input));
|
253 |
+
border-bottom: 1px solid hsl(var(--input));
|
254 |
+
border-radius: 0 0 calc(var(--radius) - 2px) calc(var(--radius) - 2px);
|
255 |
+
background: white;
|
256 |
+
|
257 |
+
.dark & {
|
258 |
+
background: hsl(var(--background));
|
259 |
+
}
|
260 |
+
|
261 |
+
box-shadow: none;
|
262 |
+
text-shadow: none;
|
263 |
+
}
|
264 |
+
|
265 |
+
.awesomplete > ul:before {
|
266 |
+
display: none;
|
267 |
+
}
|
268 |
+
|
269 |
+
.awesomplete > ul > li:hover {
|
270 |
+
background-color: #B7E2F1;
|
271 |
+
color: #2E2F27;
|
272 |
+
}
|
273 |
+
|
274 |
+
.awesomplete > ul > li[aria-selected="true"] {
|
275 |
+
background-color: #B7E2F1;
|
276 |
+
color: #2E2F27;
|
277 |
+
}
|
278 |
+
|
279 |
+
.awesomplete mark {
|
280 |
+
background-color: #61D790;
|
281 |
+
color: #2E2F27;
|
282 |
+
}
|
283 |
+
|
284 |
+
.awesomplete li:hover mark {
|
285 |
+
background-color: #61D790;
|
286 |
+
color: #2E2F27;
|
287 |
+
}
|
288 |
+
|
289 |
+
.awesomplete li[aria-selected="true"] mark {
|
290 |
+
background-color: #61D790;
|
291 |
+
color: #2E2F27;
|
292 |
+
}
|
293 |
+
|
src/icons.py
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
ICONS = {"chevrons-right": "<path d=\"m6 17 5-5-5-5\"></path><path d=\"m13 17 5-5-5-5\"></path>", "moon": "<path d=\"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z\"></path>", "sun": "<circle cx=\"12\" cy=\"12\" r=\"4\"></circle><path d=\"M12 2v2\"></path><path d=\"M12 20v2\"></path><path d=\"m4.93 4.93 1.41 1.41\"></path><path d=\"m17.66 17.66 1.41 1.41\"></path><path d=\"M2 12h2\"></path><path d=\"M20 12h2\"></path><path d=\"m6.34 17.66-1.41 1.41\"></path><path d=\"m19.07 4.93-1.41 1.41\"></path>", "github": "<path d=\"M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4\"></path><path d=\"M9 18c-4.51 2-5-2-7-2\"></path>", "slack": "<rect height=\"8\" rx=\"1.5\" width=\"3\" x=\"13\" y=\"2\"></rect><path d=\"M19 8.5V10h1.5A1.5 1.5 0 1 0 19 8.5\"></path><rect height=\"8\" rx=\"1.5\" width=\"3\" x=\"8\" y=\"14\"></rect><path d=\"M5 15.5V14H3.5A1.5 1.5 0 1 0 5 15.5\"></path><rect height=\"3\" rx=\"1.5\" width=\"8\" x=\"14\" y=\"13\"></rect><path d=\"M15.5 19H14v1.5a1.5 1.5 0 1 0 1.5-1.5\"></path><rect height=\"3\" rx=\"1.5\" width=\"8\" x=\"2\" y=\"8\"></rect><path d=\"M8.5 5H10V3.5A1.5 1.5 0 1 0 8.5 5\"></path>", "settings": "<path d=\"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\"></path><circle cx=\"12\" cy=\"12\" r=\"3\"></circle>", "arrow-right": "<path d=\"M5 12h14\"></path><path d=\"m12 5 7 7-7 7\"></path>", "search": "<circle cx=\"11\" cy=\"11\" r=\"8\"></circle><path d=\"m21 21-4.3-4.3\"></path>", "file-search": "<path d=\"M14 2v4a2 2 0 0 0 2 2h4\"></path><path d=\"M4.268 21a2 2 0 0 0 1.727 1H18a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v3\"></path><path d=\"m9 18-1.5-1.5\"></path><circle cx=\"5\" cy=\"14\" r=\"3\"></circle>", "message-circle-question": "<path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\"></path><path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\"></path><path d=\"M12 17h.01\"></path>", "text-search": "<path d=\"M21 6H3\"></path><path d=\"M10 12H3\"></path><path d=\"M10 18H3\"></path><circle cx=\"17\" cy=\"15\" r=\"3\"></circle><path d=\"m21 19-1.9-1.9\"></path>", "maximize": "<path d=\"M8 3H5a2 2 0 0 0-2 2v3\"></path><path d=\"M21 8V5a2 2 0 0 0-2-2h-3\"></path><path d=\"M3 16v3a2 2 0 0 0 2 2h3\"></path><path d=\"M16 21h3a2 2 0 0 0 2-2v-3\"></path>", "expand": "<path d=\"m21 21-6-6m6 6v-4.8m0 4.8h-4.8\"></path><path d=\"M3 16.2V21m0 0h4.8M3 21l6-6\"></path><path d=\"M21 7.8V3m0 0h-4.8M21 3l-6 6\"></path><path d=\"M3 7.8V3m0 0h4.8M3 3l6 6\"></path>", "fullscreen": "<path d=\"M3 7V5a2 2 0 0 1 2-2h2\"></path><path d=\"M17 3h2a2 2 0 0 1 2 2v2\"></path><path d=\"M21 17v2a2 2 0 0 1-2 2h-2\"></path><path d=\"M7 21H5a2 2 0 0 1-2-2v-2\"></path><rect height=\"8\" rx=\"1\" width=\"10\" x=\"7\" y=\"8\"></rect>", "images": "<path d=\"M18 22H4a2 2 0 0 1-2-2V6\"></path><path d=\"m22 13-1.296-1.296a2.41 2.41 0 0 0-3.408 0L11 18\"></path><circle cx=\"12\" cy=\"8\" r=\"2\"></circle><rect height=\"16\" rx=\"2\" width=\"16\" x=\"6\" y=\"2\"></rect>", "circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle>", "loader-circle": "<path d=\"M21 12a9 9 0 1 1-6.219-8.56\"></path>", "file-text": "<path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\"></path><path d=\"M14 2v4a2 2 0 0 0 2 2h4\"></path><path d=\"M10 9H8\"></path><path d=\"M16 13H8\"></path><path d=\"M16 17H8\"></path>", "file-question": "<path d=\"M12 17h.01\"></path><path d=\"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z\"></path><path d=\"M9.1 9a3 3 0 0 1 5.82 1c0 2-3 3-3 3\"></path>", "external-link": "<path d=\"M15 3h6v6\"></path><path d=\"M10 14 21 3\"></path><path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"></path>"}
|
src/main.py
ADDED
@@ -0,0 +1,420 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import asyncio
|
2 |
+
import base64
|
3 |
+
import os
|
4 |
+
import time
|
5 |
+
import uuid
|
6 |
+
import logging
|
7 |
+
import sys
|
8 |
+
from concurrent.futures import ThreadPoolExecutor
|
9 |
+
from pathlib import Path
|
10 |
+
|
11 |
+
import google.generativeai as genai
|
12 |
+
from fastcore.parallel import threaded
|
13 |
+
from fasthtml.common import (
|
14 |
+
Aside,
|
15 |
+
Div,
|
16 |
+
FileResponse,
|
17 |
+
HighlightJS,
|
18 |
+
Img,
|
19 |
+
JSONResponse,
|
20 |
+
Link,
|
21 |
+
Main,
|
22 |
+
P,
|
23 |
+
RedirectResponse,
|
24 |
+
Script,
|
25 |
+
StreamingResponse,
|
26 |
+
fast_app,
|
27 |
+
serve,
|
28 |
+
)
|
29 |
+
from PIL import Image
|
30 |
+
from shad4fast import ShadHead
|
31 |
+
from vespa.application import Vespa
|
32 |
+
|
33 |
+
from backend.colpali import SimMapGenerator
|
34 |
+
from backend.vespa_app import VespaQueryClient
|
35 |
+
from frontend.app import (
|
36 |
+
AboutThisDemo,
|
37 |
+
ChatResult,
|
38 |
+
Home,
|
39 |
+
Search,
|
40 |
+
SearchBox,
|
41 |
+
SearchResult,
|
42 |
+
SimMapButtonPoll,
|
43 |
+
SimMapButtonReady,
|
44 |
+
)
|
45 |
+
from frontend.layout import Layout
|
46 |
+
|
47 |
+
highlight_js_theme_link = Link(id="highlight-theme", rel="stylesheet", href="")
|
48 |
+
highlight_js_theme = Script(src="/static/js/highlightjs-theme.js")
|
49 |
+
highlight_js = HighlightJS(
|
50 |
+
langs=["python", "javascript", "java", "json", "xml"],
|
51 |
+
dark="github-dark",
|
52 |
+
light="github",
|
53 |
+
)
|
54 |
+
|
55 |
+
overlayscrollbars_link = Link(
|
56 |
+
rel="stylesheet",
|
57 |
+
href="https://cdnjs.cloudflare.com/ajax/libs/overlayscrollbars/2.10.0/styles/overlayscrollbars.min.css",
|
58 |
+
type="text/css",
|
59 |
+
)
|
60 |
+
overlayscrollbars_js = Script(
|
61 |
+
src="https://cdnjs.cloudflare.com/ajax/libs/overlayscrollbars/2.10.0/browser/overlayscrollbars.browser.es5.min.js"
|
62 |
+
)
|
63 |
+
awesomplete_link = Link(
|
64 |
+
rel="stylesheet",
|
65 |
+
href="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.7/awesomplete.min.css",
|
66 |
+
type="text/css",
|
67 |
+
)
|
68 |
+
awesomplete_js = Script(
|
69 |
+
src="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.7/awesomplete.min.js"
|
70 |
+
)
|
71 |
+
sselink = Script(src="https://unpkg.com/htmx-ext-sse@2.2.1/sse.js")
|
72 |
+
|
73 |
+
# Get log level from environment variable, default to INFO
|
74 |
+
LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper()
|
75 |
+
# Configure logger
|
76 |
+
logger = logging.getLogger("vespa_app")
|
77 |
+
handler = logging.StreamHandler(sys.stdout)
|
78 |
+
handler.setFormatter(
|
79 |
+
logging.Formatter(
|
80 |
+
"%(levelname)s: \t %(asctime)s \t %(message)s",
|
81 |
+
datefmt="%Y-%m-%d %H:%M:%S",
|
82 |
+
)
|
83 |
+
)
|
84 |
+
logger.addHandler(handler)
|
85 |
+
logger.setLevel(getattr(logging, LOG_LEVEL))
|
86 |
+
|
87 |
+
app, rt = fast_app(
|
88 |
+
htmlkw={"cls": "grid h-full"},
|
89 |
+
pico=False,
|
90 |
+
hdrs=(
|
91 |
+
highlight_js,
|
92 |
+
highlight_js_theme_link,
|
93 |
+
highlight_js_theme,
|
94 |
+
overlayscrollbars_link,
|
95 |
+
overlayscrollbars_js,
|
96 |
+
awesomplete_link,
|
97 |
+
awesomplete_js,
|
98 |
+
sselink,
|
99 |
+
ShadHead(tw_cdn=False, theme_handle=True),
|
100 |
+
),
|
101 |
+
)
|
102 |
+
vespa_app: Vespa = VespaQueryClient(logger=logger)
|
103 |
+
thread_pool = ThreadPoolExecutor()
|
104 |
+
# Gemini config
|
105 |
+
|
106 |
+
genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
|
107 |
+
GEMINI_SYSTEM_PROMPT = """If the user query is a question, try your best to answer it based on the provided images.
|
108 |
+
If the user query can not be interpreted as a question, or if the answer to the query can not be inferred from the images,
|
109 |
+
answer with the exact phrase "I am sorry, I can't find enough relevant information on these pages to answer your question.".
|
110 |
+
Your response should be HTML formatted, but only simple tags, such as <b>. <p>, <i>, <br> <ul> and <li> are allowed. No HTML tables.
|
111 |
+
This means that newlines will be replaced with <br> tags, bold text will be enclosed in <b> tags, and so on.
|
112 |
+
Do NOT include backticks (`) in your response. Only simple HTML tags and text.
|
113 |
+
"""
|
114 |
+
gemini_model = genai.GenerativeModel(
|
115 |
+
"gemini-1.5-flash-8b", system_instruction=GEMINI_SYSTEM_PROMPT
|
116 |
+
)
|
117 |
+
STATIC_DIR = Path("static")
|
118 |
+
IMG_DIR = STATIC_DIR / "full_images"
|
119 |
+
SIM_MAP_DIR = STATIC_DIR / "sim_maps"
|
120 |
+
os.makedirs(IMG_DIR, exist_ok=True)
|
121 |
+
os.makedirs(SIM_MAP_DIR, exist_ok=True)
|
122 |
+
|
123 |
+
|
124 |
+
@app.on_event("startup")
|
125 |
+
def load_model_on_startup():
|
126 |
+
app.sim_map_generator = SimMapGenerator(logger=logger)
|
127 |
+
return
|
128 |
+
|
129 |
+
|
130 |
+
@app.on_event("startup")
|
131 |
+
async def keepalive():
|
132 |
+
asyncio.create_task(poll_vespa_keepalive())
|
133 |
+
return
|
134 |
+
|
135 |
+
|
136 |
+
def generate_query_id(query, ranking_value):
|
137 |
+
hash_input = (query + ranking_value).encode("utf-8")
|
138 |
+
return hash(hash_input)
|
139 |
+
|
140 |
+
|
141 |
+
@rt("/static/{filepath:path}")
|
142 |
+
def serve_static(filepath: str):
|
143 |
+
return FileResponse(STATIC_DIR / filepath)
|
144 |
+
|
145 |
+
|
146 |
+
@rt("/")
|
147 |
+
def get(session):
|
148 |
+
if "session_id" not in session:
|
149 |
+
session["session_id"] = str(uuid.uuid4())
|
150 |
+
return Layout(Main(Home()), is_home=True)
|
151 |
+
|
152 |
+
|
153 |
+
@rt("/about-this-demo")
|
154 |
+
def get():
|
155 |
+
return Layout(Main(AboutThisDemo()))
|
156 |
+
|
157 |
+
|
158 |
+
@rt("/search")
|
159 |
+
def get(request, query: str = "", ranking: str = "nn+colpali"):
|
160 |
+
logger.info(f"/search: Fetching results for query: {query}, ranking: {ranking}")
|
161 |
+
|
162 |
+
# Always render the SearchBox first
|
163 |
+
if not query:
|
164 |
+
# Show SearchBox and a message for missing query
|
165 |
+
return Layout(
|
166 |
+
Main(
|
167 |
+
Div(
|
168 |
+
SearchBox(query_value=query, ranking_value=ranking),
|
169 |
+
Div(
|
170 |
+
P(
|
171 |
+
"No query provided. Please enter a query.",
|
172 |
+
cls="text-center text-muted-foreground",
|
173 |
+
),
|
174 |
+
cls="p-10",
|
175 |
+
),
|
176 |
+
cls="grid",
|
177 |
+
)
|
178 |
+
)
|
179 |
+
)
|
180 |
+
# Generate a unique query_id based on the query and ranking value
|
181 |
+
query_id = generate_query_id(query, ranking)
|
182 |
+
# Show the loading message if a query is provided
|
183 |
+
return Layout(
|
184 |
+
Main(Search(request), data_overlayscrollbars_initialize=True, cls="border-t"),
|
185 |
+
Aside(
|
186 |
+
ChatResult(query_id=query_id, query=query),
|
187 |
+
cls="border-t border-l hidden md:block",
|
188 |
+
),
|
189 |
+
) # Show SearchBox and Loading message initially
|
190 |
+
|
191 |
+
|
192 |
+
@rt("/fetch_results")
|
193 |
+
async def get(session, request, query: str, ranking: str):
|
194 |
+
if "hx-request" not in request.headers:
|
195 |
+
return RedirectResponse("/search")
|
196 |
+
|
197 |
+
# Get the hash of the query and ranking value
|
198 |
+
query_id = generate_query_id(query, ranking)
|
199 |
+
logger.info(f"Query id in /fetch_results: {query_id}")
|
200 |
+
# Run the embedding and query against Vespa app
|
201 |
+
start_inference = time.perf_counter()
|
202 |
+
q_embs, idx_to_token = app.sim_map_generator.get_query_embeddings_and_token_map(
|
203 |
+
query
|
204 |
+
)
|
205 |
+
end_inference = time.perf_counter()
|
206 |
+
logger.info(
|
207 |
+
f"Inference time for query_id: {query_id} \t {end_inference - start_inference:.2f} seconds"
|
208 |
+
)
|
209 |
+
|
210 |
+
start = time.perf_counter()
|
211 |
+
# Fetch real search results from Vespa
|
212 |
+
result = await vespa_app.get_result_from_query(
|
213 |
+
query=query,
|
214 |
+
q_embs=q_embs,
|
215 |
+
ranking=ranking,
|
216 |
+
idx_to_token=idx_to_token,
|
217 |
+
)
|
218 |
+
end = time.perf_counter()
|
219 |
+
logger.info(
|
220 |
+
f"Search results fetched in {end - start:.2f} seconds. Vespa search time: {result['timing']['searchtime']}"
|
221 |
+
)
|
222 |
+
search_time = result["timing"]["searchtime"]
|
223 |
+
# Safely get total_count with a default of 0
|
224 |
+
total_count = result.get("root", {}).get("fields", {}).get("totalCount", 0)
|
225 |
+
|
226 |
+
search_results = vespa_app.results_to_search_results(result, idx_to_token)
|
227 |
+
|
228 |
+
get_and_store_sim_maps(
|
229 |
+
query_id=query_id,
|
230 |
+
query=query,
|
231 |
+
q_embs=q_embs,
|
232 |
+
ranking=ranking,
|
233 |
+
idx_to_token=idx_to_token,
|
234 |
+
doc_ids=[result["fields"]["id"] for result in search_results],
|
235 |
+
)
|
236 |
+
return SearchResult(search_results, query, query_id, search_time, total_count)
|
237 |
+
|
238 |
+
|
239 |
+
def get_results_children(result):
|
240 |
+
search_results = (
|
241 |
+
result["root"]["children"]
|
242 |
+
if "root" in result and "children" in result["root"]
|
243 |
+
else []
|
244 |
+
)
|
245 |
+
return search_results
|
246 |
+
|
247 |
+
|
248 |
+
async def poll_vespa_keepalive():
|
249 |
+
while True:
|
250 |
+
await asyncio.sleep(5)
|
251 |
+
await vespa_app.keepalive()
|
252 |
+
logger.debug(f"Vespa keepalive: {time.time()}")
|
253 |
+
|
254 |
+
|
255 |
+
@threaded
|
256 |
+
def get_and_store_sim_maps(
|
257 |
+
query_id, query: str, q_embs, ranking, idx_to_token, doc_ids
|
258 |
+
):
|
259 |
+
ranking_sim = ranking + "_sim"
|
260 |
+
vespa_sim_maps = vespa_app.get_sim_maps_from_query(
|
261 |
+
query=query,
|
262 |
+
q_embs=q_embs,
|
263 |
+
ranking=ranking_sim,
|
264 |
+
idx_to_token=idx_to_token,
|
265 |
+
)
|
266 |
+
img_paths = [IMG_DIR / f"{doc_id}.jpg" for doc_id in doc_ids]
|
267 |
+
# All images should be downloaded, but best to wait 5 secs
|
268 |
+
max_wait = 5
|
269 |
+
start_time = time.time()
|
270 |
+
while (
|
271 |
+
not all([os.path.exists(img_path) for img_path in img_paths])
|
272 |
+
and time.time() - start_time < max_wait
|
273 |
+
):
|
274 |
+
time.sleep(0.2)
|
275 |
+
if not all([os.path.exists(img_path) for img_path in img_paths]):
|
276 |
+
logger.warning(f"Images not ready in 5 seconds for query_id: {query_id}")
|
277 |
+
return False
|
278 |
+
sim_map_generator = app.sim_map_generator.gen_similarity_maps(
|
279 |
+
query=query,
|
280 |
+
query_embs=q_embs,
|
281 |
+
token_idx_map=idx_to_token,
|
282 |
+
images=img_paths,
|
283 |
+
vespa_sim_maps=vespa_sim_maps,
|
284 |
+
)
|
285 |
+
for idx, token, token_idx, blended_img_base64 in sim_map_generator:
|
286 |
+
with open(SIM_MAP_DIR / f"{query_id}_{idx}_{token_idx}.png", "wb") as f:
|
287 |
+
f.write(base64.b64decode(blended_img_base64))
|
288 |
+
logger.debug(
|
289 |
+
f"Sim map saved to disk for query_id: {query_id}, idx: {idx}, token: {token}"
|
290 |
+
)
|
291 |
+
return True
|
292 |
+
|
293 |
+
|
294 |
+
@app.get("/get_sim_map")
|
295 |
+
async def get_sim_map(query_id: str, idx: int, token: str, token_idx: int):
|
296 |
+
"""
|
297 |
+
Endpoint that each of the sim map button polls to get the sim map image
|
298 |
+
when it is ready. If it is not ready, returns a SimMapButtonPoll, that
|
299 |
+
continues to poll every 1 second.
|
300 |
+
"""
|
301 |
+
sim_map_path = SIM_MAP_DIR / f"{query_id}_{idx}_{token_idx}.png"
|
302 |
+
if not os.path.exists(sim_map_path):
|
303 |
+
logger.debug(
|
304 |
+
f"Sim map not ready for query_id: {query_id}, idx: {idx}, token: {token}"
|
305 |
+
)
|
306 |
+
return SimMapButtonPoll(
|
307 |
+
query_id=query_id, idx=idx, token=token, token_idx=token_idx
|
308 |
+
)
|
309 |
+
else:
|
310 |
+
return SimMapButtonReady(
|
311 |
+
query_id=query_id,
|
312 |
+
idx=idx,
|
313 |
+
token=token,
|
314 |
+
token_idx=token_idx,
|
315 |
+
img_src=sim_map_path,
|
316 |
+
)
|
317 |
+
|
318 |
+
|
319 |
+
@app.get("/full_image")
|
320 |
+
async def full_image(doc_id: str):
|
321 |
+
"""
|
322 |
+
Endpoint to get the full quality image for a given result id.
|
323 |
+
"""
|
324 |
+
img_path = IMG_DIR / f"{doc_id}.jpg"
|
325 |
+
if not os.path.exists(img_path):
|
326 |
+
image_data = await vespa_app.get_full_image_from_vespa(doc_id)
|
327 |
+
# image data is base 64 encoded string. Save it to disk as jpg.
|
328 |
+
with open(img_path, "wb") as f:
|
329 |
+
f.write(base64.b64decode(image_data))
|
330 |
+
logger.debug(f"Full image saved to disk for doc_id: {doc_id}")
|
331 |
+
else:
|
332 |
+
with open(img_path, "rb") as f:
|
333 |
+
image_data = base64.b64encode(f.read()).decode("utf-8")
|
334 |
+
return Img(
|
335 |
+
src=f"data:image/jpeg;base64,{image_data}",
|
336 |
+
alt="something",
|
337 |
+
cls="result-image w-full h-full object-contain",
|
338 |
+
)
|
339 |
+
|
340 |
+
|
341 |
+
@rt("/suggestions")
|
342 |
+
async def get_suggestions(query: str = ""):
|
343 |
+
"""Endpoint to get suggestions as user types in the search box"""
|
344 |
+
query = query.lower().strip()
|
345 |
+
|
346 |
+
if query:
|
347 |
+
suggestions = await vespa_app.get_suggestions(query)
|
348 |
+
if len(suggestions) > 0:
|
349 |
+
return JSONResponse({"suggestions": suggestions})
|
350 |
+
|
351 |
+
return JSONResponse({"suggestions": []})
|
352 |
+
|
353 |
+
|
354 |
+
async def message_generator(query_id: str, query: str, doc_ids: list):
|
355 |
+
"""Generator function to yield SSE messages for chat response"""
|
356 |
+
images = []
|
357 |
+
num_images = 3 # Number of images before firing chat request
|
358 |
+
max_wait = 10 # seconds
|
359 |
+
start_time = time.time()
|
360 |
+
# Check if full images are ready on disk
|
361 |
+
while (
|
362 |
+
len(images) < min(num_images, len(doc_ids))
|
363 |
+
and time.time() - start_time < max_wait
|
364 |
+
):
|
365 |
+
images = []
|
366 |
+
for idx in range(num_images):
|
367 |
+
image_filename = IMG_DIR / f"{doc_ids[idx]}.jpg"
|
368 |
+
if not os.path.exists(image_filename):
|
369 |
+
logger.debug(
|
370 |
+
f"Message generator: Full image not ready for query_id: {query_id}, idx: {idx}"
|
371 |
+
)
|
372 |
+
continue
|
373 |
+
else:
|
374 |
+
logger.debug(
|
375 |
+
f"Message generator: image ready for query_id: {query_id}, idx: {idx}"
|
376 |
+
)
|
377 |
+
images.append(Image.open(image_filename))
|
378 |
+
if len(images) < num_images:
|
379 |
+
await asyncio.sleep(0.2)
|
380 |
+
|
381 |
+
# yield message with number of images ready
|
382 |
+
yield f"event: message\ndata: Generating response based on {len(images)} images...\n\n"
|
383 |
+
if not images:
|
384 |
+
yield "event: message\ndata: Failed to send images to Gemini-8B!\n\n"
|
385 |
+
yield "event: close\ndata: \n\n"
|
386 |
+
return
|
387 |
+
|
388 |
+
# If newlines are present in the response, the connection will be closed.
|
389 |
+
def replace_newline_with_br(text):
|
390 |
+
return text.replace("\n", "<br>")
|
391 |
+
|
392 |
+
response_text = ""
|
393 |
+
async for chunk in await gemini_model.generate_content_async(
|
394 |
+
images + ["\n\n Query: ", query], stream=True
|
395 |
+
):
|
396 |
+
if chunk.text:
|
397 |
+
response_text += chunk.text
|
398 |
+
response_text = replace_newline_with_br(response_text)
|
399 |
+
yield f"event: message\ndata: {response_text}\n\n"
|
400 |
+
await asyncio.sleep(0.1)
|
401 |
+
yield "event: close\ndata: \n\n"
|
402 |
+
|
403 |
+
|
404 |
+
@app.get("/get-message")
|
405 |
+
async def get_message(query_id: str, query: str, doc_ids: str):
|
406 |
+
return StreamingResponse(
|
407 |
+
message_generator(query_id=query_id, query=query, doc_ids=doc_ids.split(",")),
|
408 |
+
media_type="text/event-stream",
|
409 |
+
)
|
410 |
+
|
411 |
+
|
412 |
+
@rt("/app")
|
413 |
+
def get():
|
414 |
+
return Layout(Main(Div(P(f"Connected to Vespa at {vespa_app.url}"), cls="p-4")))
|
415 |
+
|
416 |
+
|
417 |
+
if __name__ == "__main__":
|
418 |
+
HOT_RELOAD = os.getenv("HOT_RELOAD", "False").lower() == "true"
|
419 |
+
logger.info(f"Starting app with hot reload: {HOT_RELOAD}")
|
420 |
+
serve(port=7860, reload=HOT_RELOAD)
|
src/output.css
ADDED
@@ -0,0 +1,2893 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
*, ::before, ::after {
|
2 |
+
--tw-border-spacing-x: 0;
|
3 |
+
--tw-border-spacing-y: 0;
|
4 |
+
--tw-translate-x: 0;
|
5 |
+
--tw-translate-y: 0;
|
6 |
+
--tw-rotate: 0;
|
7 |
+
--tw-skew-x: 0;
|
8 |
+
--tw-skew-y: 0;
|
9 |
+
--tw-scale-x: 1;
|
10 |
+
--tw-scale-y: 1;
|
11 |
+
--tw-pan-x: ;
|
12 |
+
--tw-pan-y: ;
|
13 |
+
--tw-pinch-zoom: ;
|
14 |
+
--tw-scroll-snap-strictness: proximity;
|
15 |
+
--tw-gradient-from-position: ;
|
16 |
+
--tw-gradient-via-position: ;
|
17 |
+
--tw-gradient-to-position: ;
|
18 |
+
--tw-ordinal: ;
|
19 |
+
--tw-slashed-zero: ;
|
20 |
+
--tw-numeric-figure: ;
|
21 |
+
--tw-numeric-spacing: ;
|
22 |
+
--tw-numeric-fraction: ;
|
23 |
+
--tw-ring-inset: ;
|
24 |
+
--tw-ring-offset-width: 0px;
|
25 |
+
--tw-ring-offset-color: #fff;
|
26 |
+
--tw-ring-color: rgb(59 130 246 / 0.5);
|
27 |
+
--tw-ring-offset-shadow: 0 0 #0000;
|
28 |
+
--tw-ring-shadow: 0 0 #0000;
|
29 |
+
--tw-shadow: 0 0 #0000;
|
30 |
+
--tw-shadow-colored: 0 0 #0000;
|
31 |
+
--tw-blur: ;
|
32 |
+
--tw-brightness: ;
|
33 |
+
--tw-contrast: ;
|
34 |
+
--tw-grayscale: ;
|
35 |
+
--tw-hue-rotate: ;
|
36 |
+
--tw-invert: ;
|
37 |
+
--tw-saturate: ;
|
38 |
+
--tw-sepia: ;
|
39 |
+
--tw-drop-shadow: ;
|
40 |
+
--tw-backdrop-blur: ;
|
41 |
+
--tw-backdrop-brightness: ;
|
42 |
+
--tw-backdrop-contrast: ;
|
43 |
+
--tw-backdrop-grayscale: ;
|
44 |
+
--tw-backdrop-hue-rotate: ;
|
45 |
+
--tw-backdrop-invert: ;
|
46 |
+
--tw-backdrop-opacity: ;
|
47 |
+
--tw-backdrop-saturate: ;
|
48 |
+
--tw-backdrop-sepia: ;
|
49 |
+
--tw-contain-size: ;
|
50 |
+
--tw-contain-layout: ;
|
51 |
+
--tw-contain-paint: ;
|
52 |
+
--tw-contain-style: ;
|
53 |
+
}
|
54 |
+
|
55 |
+
::backdrop {
|
56 |
+
--tw-border-spacing-x: 0;
|
57 |
+
--tw-border-spacing-y: 0;
|
58 |
+
--tw-translate-x: 0;
|
59 |
+
--tw-translate-y: 0;
|
60 |
+
--tw-rotate: 0;
|
61 |
+
--tw-skew-x: 0;
|
62 |
+
--tw-skew-y: 0;
|
63 |
+
--tw-scale-x: 1;
|
64 |
+
--tw-scale-y: 1;
|
65 |
+
--tw-pan-x: ;
|
66 |
+
--tw-pan-y: ;
|
67 |
+
--tw-pinch-zoom: ;
|
68 |
+
--tw-scroll-snap-strictness: proximity;
|
69 |
+
--tw-gradient-from-position: ;
|
70 |
+
--tw-gradient-via-position: ;
|
71 |
+
--tw-gradient-to-position: ;
|
72 |
+
--tw-ordinal: ;
|
73 |
+
--tw-slashed-zero: ;
|
74 |
+
--tw-numeric-figure: ;
|
75 |
+
--tw-numeric-spacing: ;
|
76 |
+
--tw-numeric-fraction: ;
|
77 |
+
--tw-ring-inset: ;
|
78 |
+
--tw-ring-offset-width: 0px;
|
79 |
+
--tw-ring-offset-color: #fff;
|
80 |
+
--tw-ring-color: rgb(59 130 246 / 0.5);
|
81 |
+
--tw-ring-offset-shadow: 0 0 #0000;
|
82 |
+
--tw-ring-shadow: 0 0 #0000;
|
83 |
+
--tw-shadow: 0 0 #0000;
|
84 |
+
--tw-shadow-colored: 0 0 #0000;
|
85 |
+
--tw-blur: ;
|
86 |
+
--tw-brightness: ;
|
87 |
+
--tw-contrast: ;
|
88 |
+
--tw-grayscale: ;
|
89 |
+
--tw-hue-rotate: ;
|
90 |
+
--tw-invert: ;
|
91 |
+
--tw-saturate: ;
|
92 |
+
--tw-sepia: ;
|
93 |
+
--tw-drop-shadow: ;
|
94 |
+
--tw-backdrop-blur: ;
|
95 |
+
--tw-backdrop-brightness: ;
|
96 |
+
--tw-backdrop-contrast: ;
|
97 |
+
--tw-backdrop-grayscale: ;
|
98 |
+
--tw-backdrop-hue-rotate: ;
|
99 |
+
--tw-backdrop-invert: ;
|
100 |
+
--tw-backdrop-opacity: ;
|
101 |
+
--tw-backdrop-saturate: ;
|
102 |
+
--tw-backdrop-sepia: ;
|
103 |
+
--tw-contain-size: ;
|
104 |
+
--tw-contain-layout: ;
|
105 |
+
--tw-contain-paint: ;
|
106 |
+
--tw-contain-style: ;
|
107 |
+
}
|
108 |
+
|
109 |
+
/*
|
110 |
+
! tailwindcss v3.4.13 | MIT License | https://tailwindcss.com
|
111 |
+
*/
|
112 |
+
|
113 |
+
/*
|
114 |
+
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
|
115 |
+
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
|
116 |
+
*/
|
117 |
+
|
118 |
+
*,
|
119 |
+
::before,
|
120 |
+
::after {
|
121 |
+
box-sizing: border-box;
|
122 |
+
/* 1 */
|
123 |
+
border-width: 0;
|
124 |
+
/* 2 */
|
125 |
+
border-style: solid;
|
126 |
+
/* 2 */
|
127 |
+
border-color: #e5e7eb;
|
128 |
+
/* 2 */
|
129 |
+
}
|
130 |
+
|
131 |
+
::before,
|
132 |
+
::after {
|
133 |
+
--tw-content: '';
|
134 |
+
}
|
135 |
+
|
136 |
+
/*
|
137 |
+
1. Use a consistent sensible line-height in all browsers.
|
138 |
+
2. Prevent adjustments of font size after orientation changes in iOS.
|
139 |
+
3. Use a more readable tab size.
|
140 |
+
4. Use the user's configured `sans` font-family by default.
|
141 |
+
5. Use the user's configured `sans` font-feature-settings by default.
|
142 |
+
6. Use the user's configured `sans` font-variation-settings by default.
|
143 |
+
7. Disable tap highlights on iOS
|
144 |
+
*/
|
145 |
+
|
146 |
+
html,
|
147 |
+
:host {
|
148 |
+
line-height: 1.5;
|
149 |
+
/* 1 */
|
150 |
+
-webkit-text-size-adjust: 100%;
|
151 |
+
/* 2 */
|
152 |
+
-moz-tab-size: 4;
|
153 |
+
/* 3 */
|
154 |
+
-o-tab-size: 4;
|
155 |
+
tab-size: 4;
|
156 |
+
/* 3 */
|
157 |
+
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
158 |
+
/* 4 */
|
159 |
+
font-feature-settings: normal;
|
160 |
+
/* 5 */
|
161 |
+
font-variation-settings: normal;
|
162 |
+
/* 6 */
|
163 |
+
-webkit-tap-highlight-color: transparent;
|
164 |
+
/* 7 */
|
165 |
+
}
|
166 |
+
|
167 |
+
/*
|
168 |
+
1. Remove the margin in all browsers.
|
169 |
+
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
|
170 |
+
*/
|
171 |
+
|
172 |
+
body {
|
173 |
+
margin: 0;
|
174 |
+
/* 1 */
|
175 |
+
line-height: inherit;
|
176 |
+
/* 2 */
|
177 |
+
}
|
178 |
+
|
179 |
+
/*
|
180 |
+
1. Add the correct height in Firefox.
|
181 |
+
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
|
182 |
+
3. Ensure horizontal rules are visible by default.
|
183 |
+
*/
|
184 |
+
|
185 |
+
hr {
|
186 |
+
height: 0;
|
187 |
+
/* 1 */
|
188 |
+
color: inherit;
|
189 |
+
/* 2 */
|
190 |
+
border-top-width: 1px;
|
191 |
+
/* 3 */
|
192 |
+
}
|
193 |
+
|
194 |
+
/*
|
195 |
+
Add the correct text decoration in Chrome, Edge, and Safari.
|
196 |
+
*/
|
197 |
+
|
198 |
+
abbr:where([title]) {
|
199 |
+
-webkit-text-decoration: underline dotted;
|
200 |
+
text-decoration: underline dotted;
|
201 |
+
}
|
202 |
+
|
203 |
+
/*
|
204 |
+
Remove the default font size and weight for headings.
|
205 |
+
*/
|
206 |
+
|
207 |
+
h1,
|
208 |
+
h2,
|
209 |
+
h3,
|
210 |
+
h4,
|
211 |
+
h5,
|
212 |
+
h6 {
|
213 |
+
font-size: inherit;
|
214 |
+
font-weight: inherit;
|
215 |
+
}
|
216 |
+
|
217 |
+
/*
|
218 |
+
Reset links to optimize for opt-in styling instead of opt-out.
|
219 |
+
*/
|
220 |
+
|
221 |
+
a {
|
222 |
+
color: inherit;
|
223 |
+
text-decoration: inherit;
|
224 |
+
}
|
225 |
+
|
226 |
+
/*
|
227 |
+
Add the correct font weight in Edge and Safari.
|
228 |
+
*/
|
229 |
+
|
230 |
+
b,
|
231 |
+
strong {
|
232 |
+
font-weight: bolder;
|
233 |
+
}
|
234 |
+
|
235 |
+
/*
|
236 |
+
1. Use the user's configured `mono` font-family by default.
|
237 |
+
2. Use the user's configured `mono` font-feature-settings by default.
|
238 |
+
3. Use the user's configured `mono` font-variation-settings by default.
|
239 |
+
4. Correct the odd `em` font sizing in all browsers.
|
240 |
+
*/
|
241 |
+
|
242 |
+
code,
|
243 |
+
kbd,
|
244 |
+
samp,
|
245 |
+
pre {
|
246 |
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
247 |
+
/* 1 */
|
248 |
+
font-feature-settings: normal;
|
249 |
+
/* 2 */
|
250 |
+
font-variation-settings: normal;
|
251 |
+
/* 3 */
|
252 |
+
font-size: 1em;
|
253 |
+
/* 4 */
|
254 |
+
}
|
255 |
+
|
256 |
+
/*
|
257 |
+
Add the correct font size in all browsers.
|
258 |
+
*/
|
259 |
+
|
260 |
+
small {
|
261 |
+
font-size: 80%;
|
262 |
+
}
|
263 |
+
|
264 |
+
/*
|
265 |
+
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
|
266 |
+
*/
|
267 |
+
|
268 |
+
sub,
|
269 |
+
sup {
|
270 |
+
font-size: 75%;
|
271 |
+
line-height: 0;
|
272 |
+
position: relative;
|
273 |
+
vertical-align: baseline;
|
274 |
+
}
|
275 |
+
|
276 |
+
sub {
|
277 |
+
bottom: -0.25em;
|
278 |
+
}
|
279 |
+
|
280 |
+
sup {
|
281 |
+
top: -0.5em;
|
282 |
+
}
|
283 |
+
|
284 |
+
/*
|
285 |
+
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
|
286 |
+
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
|
287 |
+
3. Remove gaps between table borders by default.
|
288 |
+
*/
|
289 |
+
|
290 |
+
table {
|
291 |
+
text-indent: 0;
|
292 |
+
/* 1 */
|
293 |
+
border-color: inherit;
|
294 |
+
/* 2 */
|
295 |
+
border-collapse: collapse;
|
296 |
+
/* 3 */
|
297 |
+
}
|
298 |
+
|
299 |
+
/*
|
300 |
+
1. Change the font styles in all browsers.
|
301 |
+
2. Remove the margin in Firefox and Safari.
|
302 |
+
3. Remove default padding in all browsers.
|
303 |
+
*/
|
304 |
+
|
305 |
+
button,
|
306 |
+
input,
|
307 |
+
optgroup,
|
308 |
+
select,
|
309 |
+
textarea {
|
310 |
+
font-family: inherit;
|
311 |
+
/* 1 */
|
312 |
+
font-feature-settings: inherit;
|
313 |
+
/* 1 */
|
314 |
+
font-variation-settings: inherit;
|
315 |
+
/* 1 */
|
316 |
+
font-size: 100%;
|
317 |
+
/* 1 */
|
318 |
+
font-weight: inherit;
|
319 |
+
/* 1 */
|
320 |
+
line-height: inherit;
|
321 |
+
/* 1 */
|
322 |
+
letter-spacing: inherit;
|
323 |
+
/* 1 */
|
324 |
+
color: inherit;
|
325 |
+
/* 1 */
|
326 |
+
margin: 0;
|
327 |
+
/* 2 */
|
328 |
+
padding: 0;
|
329 |
+
/* 3 */
|
330 |
+
}
|
331 |
+
|
332 |
+
/*
|
333 |
+
Remove the inheritance of text transform in Edge and Firefox.
|
334 |
+
*/
|
335 |
+
|
336 |
+
button,
|
337 |
+
select {
|
338 |
+
text-transform: none;
|
339 |
+
}
|
340 |
+
|
341 |
+
/*
|
342 |
+
1. Correct the inability to style clickable types in iOS and Safari.
|
343 |
+
2. Remove default button styles.
|
344 |
+
*/
|
345 |
+
|
346 |
+
button,
|
347 |
+
input:where([type='button']),
|
348 |
+
input:where([type='reset']),
|
349 |
+
input:where([type='submit']) {
|
350 |
+
-webkit-appearance: button;
|
351 |
+
/* 1 */
|
352 |
+
background-color: transparent;
|
353 |
+
/* 2 */
|
354 |
+
background-image: none;
|
355 |
+
/* 2 */
|
356 |
+
}
|
357 |
+
|
358 |
+
/*
|
359 |
+
Use the modern Firefox focus style for all focusable elements.
|
360 |
+
*/
|
361 |
+
|
362 |
+
:-moz-focusring {
|
363 |
+
outline: auto;
|
364 |
+
}
|
365 |
+
|
366 |
+
/*
|
367 |
+
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
|
368 |
+
*/
|
369 |
+
|
370 |
+
:-moz-ui-invalid {
|
371 |
+
box-shadow: none;
|
372 |
+
}
|
373 |
+
|
374 |
+
/*
|
375 |
+
Add the correct vertical alignment in Chrome and Firefox.
|
376 |
+
*/
|
377 |
+
|
378 |
+
progress {
|
379 |
+
vertical-align: baseline;
|
380 |
+
}
|
381 |
+
|
382 |
+
/*
|
383 |
+
Correct the cursor style of increment and decrement buttons in Safari.
|
384 |
+
*/
|
385 |
+
|
386 |
+
::-webkit-inner-spin-button,
|
387 |
+
::-webkit-outer-spin-button {
|
388 |
+
height: auto;
|
389 |
+
}
|
390 |
+
|
391 |
+
/*
|
392 |
+
1. Correct the odd appearance in Chrome and Safari.
|
393 |
+
2. Correct the outline style in Safari.
|
394 |
+
*/
|
395 |
+
|
396 |
+
[type='search'] {
|
397 |
+
-webkit-appearance: textfield;
|
398 |
+
/* 1 */
|
399 |
+
outline-offset: -2px;
|
400 |
+
/* 2 */
|
401 |
+
}
|
402 |
+
|
403 |
+
/*
|
404 |
+
Remove the inner padding in Chrome and Safari on macOS.
|
405 |
+
*/
|
406 |
+
|
407 |
+
::-webkit-search-decoration {
|
408 |
+
-webkit-appearance: none;
|
409 |
+
}
|
410 |
+
|
411 |
+
/*
|
412 |
+
1. Correct the inability to style clickable types in iOS and Safari.
|
413 |
+
2. Change font properties to `inherit` in Safari.
|
414 |
+
*/
|
415 |
+
|
416 |
+
::-webkit-file-upload-button {
|
417 |
+
-webkit-appearance: button;
|
418 |
+
/* 1 */
|
419 |
+
font: inherit;
|
420 |
+
/* 2 */
|
421 |
+
}
|
422 |
+
|
423 |
+
/*
|
424 |
+
Add the correct display in Chrome and Safari.
|
425 |
+
*/
|
426 |
+
|
427 |
+
summary {
|
428 |
+
display: list-item;
|
429 |
+
}
|
430 |
+
|
431 |
+
/*
|
432 |
+
Removes the default spacing and border for appropriate elements.
|
433 |
+
*/
|
434 |
+
|
435 |
+
blockquote,
|
436 |
+
dl,
|
437 |
+
dd,
|
438 |
+
h1,
|
439 |
+
h2,
|
440 |
+
h3,
|
441 |
+
h4,
|
442 |
+
h5,
|
443 |
+
h6,
|
444 |
+
hr,
|
445 |
+
figure,
|
446 |
+
p,
|
447 |
+
pre {
|
448 |
+
margin: 0;
|
449 |
+
}
|
450 |
+
|
451 |
+
fieldset {
|
452 |
+
margin: 0;
|
453 |
+
padding: 0;
|
454 |
+
}
|
455 |
+
|
456 |
+
legend {
|
457 |
+
padding: 0;
|
458 |
+
}
|
459 |
+
|
460 |
+
ol,
|
461 |
+
ul,
|
462 |
+
menu {
|
463 |
+
list-style: none;
|
464 |
+
margin: 0;
|
465 |
+
padding: 0;
|
466 |
+
}
|
467 |
+
|
468 |
+
/*
|
469 |
+
Reset default styling for dialogs.
|
470 |
+
*/
|
471 |
+
|
472 |
+
dialog {
|
473 |
+
padding: 0;
|
474 |
+
}
|
475 |
+
|
476 |
+
/*
|
477 |
+
Prevent resizing textareas horizontally by default.
|
478 |
+
*/
|
479 |
+
|
480 |
+
textarea {
|
481 |
+
resize: vertical;
|
482 |
+
}
|
483 |
+
|
484 |
+
/*
|
485 |
+
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
|
486 |
+
2. Set the default placeholder color to the user's configured gray 400 color.
|
487 |
+
*/
|
488 |
+
|
489 |
+
input::-moz-placeholder, textarea::-moz-placeholder {
|
490 |
+
opacity: 1;
|
491 |
+
/* 1 */
|
492 |
+
color: #9ca3af;
|
493 |
+
/* 2 */
|
494 |
+
}
|
495 |
+
|
496 |
+
input::placeholder,
|
497 |
+
textarea::placeholder {
|
498 |
+
opacity: 1;
|
499 |
+
/* 1 */
|
500 |
+
color: #9ca3af;
|
501 |
+
/* 2 */
|
502 |
+
}
|
503 |
+
|
504 |
+
/*
|
505 |
+
Set the default cursor for buttons.
|
506 |
+
*/
|
507 |
+
|
508 |
+
button,
|
509 |
+
[role="button"] {
|
510 |
+
cursor: pointer;
|
511 |
+
}
|
512 |
+
|
513 |
+
/*
|
514 |
+
Make sure disabled buttons don't get the pointer cursor.
|
515 |
+
*/
|
516 |
+
|
517 |
+
:disabled {
|
518 |
+
cursor: default;
|
519 |
+
}
|
520 |
+
|
521 |
+
/*
|
522 |
+
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
|
523 |
+
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
|
524 |
+
This can trigger a poorly considered lint error in some tools but is included by design.
|
525 |
+
*/
|
526 |
+
|
527 |
+
img,
|
528 |
+
svg,
|
529 |
+
video,
|
530 |
+
canvas,
|
531 |
+
audio,
|
532 |
+
iframe,
|
533 |
+
embed,
|
534 |
+
object {
|
535 |
+
display: block;
|
536 |
+
/* 1 */
|
537 |
+
vertical-align: middle;
|
538 |
+
/* 2 */
|
539 |
+
}
|
540 |
+
|
541 |
+
/*
|
542 |
+
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
|
543 |
+
*/
|
544 |
+
|
545 |
+
img,
|
546 |
+
video {
|
547 |
+
max-width: 100%;
|
548 |
+
height: auto;
|
549 |
+
}
|
550 |
+
|
551 |
+
/* Make elements with the HTML hidden attribute stay hidden by default */
|
552 |
+
|
553 |
+
[hidden] {
|
554 |
+
display: none;
|
555 |
+
}
|
556 |
+
|
557 |
+
:root {
|
558 |
+
--background: 240 20% 99%;
|
559 |
+
/* 1 */
|
560 |
+
--foreground: 210 13% 13%;
|
561 |
+
/* 12 */
|
562 |
+
--card: 240 20% 99%;
|
563 |
+
/* 1 */
|
564 |
+
--card-foreground: 210 13% 13%;
|
565 |
+
/* 12 */
|
566 |
+
--popover: 240 20% 99%;
|
567 |
+
/* 1 */
|
568 |
+
--popover-foreground: 210 13% 13%;
|
569 |
+
/* 12 */
|
570 |
+
--primary: 210 13% 13%;
|
571 |
+
/* 12 */
|
572 |
+
--primary-foreground: 240 20% 98%;
|
573 |
+
/* 2 */
|
574 |
+
--secondary: 240 11% 95%;
|
575 |
+
/* 3 */
|
576 |
+
--secondary-foreground: 210 13% 13%;
|
577 |
+
/* 12 */
|
578 |
+
--muted: 240 11% 95%;
|
579 |
+
/* 3 */
|
580 |
+
--muted-foreground: 220 6% 40%;
|
581 |
+
/* 11 */
|
582 |
+
--accent: 240 11% 95%;
|
583 |
+
/* 3 */
|
584 |
+
--accent-foreground: 210 13% 13%;
|
585 |
+
/* 12 */
|
586 |
+
--destructive: 358 75% 59%;
|
587 |
+
/* 9 - red */
|
588 |
+
--destructive-foreground: 240 20% 98%;
|
589 |
+
/* 2 */
|
590 |
+
--border: 240 10% 86%;
|
591 |
+
/* 6 */
|
592 |
+
--input: 240 10% 86%;
|
593 |
+
/* 6 */
|
594 |
+
--ring: 210 13% 13%;
|
595 |
+
/* 12 */
|
596 |
+
--chart-1: 10 78% 54%;
|
597 |
+
/* 9 - tomato */
|
598 |
+
--chart-2: 173 80% 36%;
|
599 |
+
/* 9 - teal */
|
600 |
+
--chart-3: 206 100% 50%;
|
601 |
+
/* 9 - blue */
|
602 |
+
--chart-4: 42 100% 62%;
|
603 |
+
/* 9 - amber */
|
604 |
+
--chart-5: 23 93% 53%;
|
605 |
+
/* 9 - orange */
|
606 |
+
}
|
607 |
+
|
608 |
+
.dark {
|
609 |
+
--background: 240 6% 7%;
|
610 |
+
/* 1 */
|
611 |
+
--foreground: 220 9% 94%;
|
612 |
+
/* 12 */
|
613 |
+
--card: 240 6% 7%;
|
614 |
+
/* 1 */
|
615 |
+
--card-foreground: 220 9% 94%;
|
616 |
+
/* 12 */
|
617 |
+
--popover: 240 6% 7%;
|
618 |
+
/* 1 */
|
619 |
+
--popover-foreground: 220 9% 94%;
|
620 |
+
/* 12 */
|
621 |
+
--primary: 220 9% 94%;
|
622 |
+
/* 12 */
|
623 |
+
--primary-foreground: 220 6% 10%;
|
624 |
+
/* 2 */
|
625 |
+
--secondary: 225 6% 14%;
|
626 |
+
/* 3 */
|
627 |
+
--secondary-foreground: 220 9% 94%;
|
628 |
+
/* 12 */
|
629 |
+
--muted: 225 6% 14%;
|
630 |
+
/* 3 */
|
631 |
+
--muted-foreground: 216 7% 71%;
|
632 |
+
/* 11 */
|
633 |
+
--accent: 225 6% 14%;
|
634 |
+
/* 3 */
|
635 |
+
--accent-foreground: 220 9% 94%;
|
636 |
+
/* 12 */
|
637 |
+
--destructive: 358 75% 59%;
|
638 |
+
/* 9 - red */
|
639 |
+
--destructive-foreground: 220 9% 94%;
|
640 |
+
/* 12 */
|
641 |
+
--border: 213 8% 23%;
|
642 |
+
/* 6 */
|
643 |
+
--input: 213 8% 23%;
|
644 |
+
/* 6 */
|
645 |
+
--ring: 220 9% 94%;
|
646 |
+
/* 12 */
|
647 |
+
--chart-1: 10 78% 54%;
|
648 |
+
/* 9 - tomato */
|
649 |
+
--chart-2: 173 80% 36%;
|
650 |
+
/* 9 - teal */
|
651 |
+
--chart-3: 206 100% 50%;
|
652 |
+
/* 9 - blue */
|
653 |
+
--chart-4: 42 100% 62%;
|
654 |
+
/* 9 - amber */
|
655 |
+
--chart-5: 23 93% 53%;
|
656 |
+
/* 9 - orange */
|
657 |
+
}
|
658 |
+
|
659 |
+
:root:has(.no-bg-scroll) {
|
660 |
+
overflow: hidden;
|
661 |
+
}
|
662 |
+
|
663 |
+
* {
|
664 |
+
border-color: hsl(var(--border));
|
665 |
+
}
|
666 |
+
|
667 |
+
body {
|
668 |
+
min-height: 100vh;
|
669 |
+
background-color: hsl(var(--background));
|
670 |
+
color: hsl(var(--foreground));
|
671 |
+
-webkit-font-smoothing: antialiased;
|
672 |
+
-moz-osx-font-smoothing: grayscale;
|
673 |
+
font-feature-settings: "rlig" 1, "calt" 1;
|
674 |
+
}
|
675 |
+
|
676 |
+
.container {
|
677 |
+
width: 100%;
|
678 |
+
margin-right: auto;
|
679 |
+
margin-left: auto;
|
680 |
+
padding-right: 2rem;
|
681 |
+
padding-left: 2rem;
|
682 |
+
}
|
683 |
+
|
684 |
+
@media (min-width: 1400px) {
|
685 |
+
.container {
|
686 |
+
max-width: 1400px;
|
687 |
+
}
|
688 |
+
}
|
689 |
+
|
690 |
+
.sr-only {
|
691 |
+
position: absolute;
|
692 |
+
width: 1px;
|
693 |
+
height: 1px;
|
694 |
+
padding: 0;
|
695 |
+
margin: -1px;
|
696 |
+
overflow: hidden;
|
697 |
+
clip: rect(0, 0, 0, 0);
|
698 |
+
white-space: nowrap;
|
699 |
+
border-width: 0;
|
700 |
+
}
|
701 |
+
|
702 |
+
.pointer-events-none {
|
703 |
+
pointer-events: none;
|
704 |
+
}
|
705 |
+
|
706 |
+
.pointer-events-auto {
|
707 |
+
pointer-events: auto;
|
708 |
+
}
|
709 |
+
|
710 |
+
.static {
|
711 |
+
position: static;
|
712 |
+
}
|
713 |
+
|
714 |
+
.fixed {
|
715 |
+
position: fixed;
|
716 |
+
}
|
717 |
+
|
718 |
+
.absolute {
|
719 |
+
position: absolute;
|
720 |
+
}
|
721 |
+
|
722 |
+
.relative {
|
723 |
+
position: relative;
|
724 |
+
}
|
725 |
+
|
726 |
+
.inset-0 {
|
727 |
+
inset: 0px;
|
728 |
+
}
|
729 |
+
|
730 |
+
.inset-x-0 {
|
731 |
+
left: 0px;
|
732 |
+
right: 0px;
|
733 |
+
}
|
734 |
+
|
735 |
+
.inset-y-0 {
|
736 |
+
top: 0px;
|
737 |
+
bottom: 0px;
|
738 |
+
}
|
739 |
+
|
740 |
+
.-bottom-12 {
|
741 |
+
bottom: -3rem;
|
742 |
+
}
|
743 |
+
|
744 |
+
.-left-12 {
|
745 |
+
left: -3rem;
|
746 |
+
}
|
747 |
+
|
748 |
+
.-right-12 {
|
749 |
+
right: -3rem;
|
750 |
+
}
|
751 |
+
|
752 |
+
.-top-12 {
|
753 |
+
top: -3rem;
|
754 |
+
}
|
755 |
+
|
756 |
+
.bottom-0 {
|
757 |
+
bottom: 0px;
|
758 |
+
}
|
759 |
+
|
760 |
+
.left-0 {
|
761 |
+
left: 0px;
|
762 |
+
}
|
763 |
+
|
764 |
+
.left-1\/2 {
|
765 |
+
left: 50%;
|
766 |
+
}
|
767 |
+
|
768 |
+
.left-2 {
|
769 |
+
left: 0.5rem;
|
770 |
+
}
|
771 |
+
|
772 |
+
.left-\[50\%\] {
|
773 |
+
left: 50%;
|
774 |
+
}
|
775 |
+
|
776 |
+
.right-0 {
|
777 |
+
right: 0px;
|
778 |
+
}
|
779 |
+
|
780 |
+
.right-2 {
|
781 |
+
right: 0.5rem;
|
782 |
+
}
|
783 |
+
|
784 |
+
.right-4 {
|
785 |
+
right: 1rem;
|
786 |
+
}
|
787 |
+
|
788 |
+
.top-0 {
|
789 |
+
top: 0px;
|
790 |
+
}
|
791 |
+
|
792 |
+
.top-1\/2 {
|
793 |
+
top: 50%;
|
794 |
+
}
|
795 |
+
|
796 |
+
.top-2 {
|
797 |
+
top: 0.5rem;
|
798 |
+
}
|
799 |
+
|
800 |
+
.top-4 {
|
801 |
+
top: 1rem;
|
802 |
+
}
|
803 |
+
|
804 |
+
.top-\[50\%\] {
|
805 |
+
top: 50%;
|
806 |
+
}
|
807 |
+
|
808 |
+
.z-10 {
|
809 |
+
z-index: 10;
|
810 |
+
}
|
811 |
+
|
812 |
+
.z-50 {
|
813 |
+
z-index: 50;
|
814 |
+
}
|
815 |
+
|
816 |
+
.z-\[100\] {
|
817 |
+
z-index: 100;
|
818 |
+
}
|
819 |
+
|
820 |
+
.-mx-1 {
|
821 |
+
margin-left: -0.25rem;
|
822 |
+
margin-right: -0.25rem;
|
823 |
+
}
|
824 |
+
|
825 |
+
.mx-auto {
|
826 |
+
margin-left: auto;
|
827 |
+
margin-right: auto;
|
828 |
+
}
|
829 |
+
|
830 |
+
.my-1 {
|
831 |
+
margin-top: 0.25rem;
|
832 |
+
margin-bottom: 0.25rem;
|
833 |
+
}
|
834 |
+
|
835 |
+
.-ml-4 {
|
836 |
+
margin-left: -1rem;
|
837 |
+
}
|
838 |
+
|
839 |
+
.-mt-4 {
|
840 |
+
margin-top: -1rem;
|
841 |
+
}
|
842 |
+
|
843 |
+
.mb-1 {
|
844 |
+
margin-bottom: 0.25rem;
|
845 |
+
}
|
846 |
+
|
847 |
+
.mr-1\.5 {
|
848 |
+
margin-right: 0.375rem;
|
849 |
+
}
|
850 |
+
|
851 |
+
.mt-2 {
|
852 |
+
margin-top: 0.5rem;
|
853 |
+
}
|
854 |
+
|
855 |
+
.mt-\[13vh\] {
|
856 |
+
margin-top: 13vh;
|
857 |
+
}
|
858 |
+
|
859 |
+
.mt-\[8vh\] {
|
860 |
+
margin-top: 8vh;
|
861 |
+
}
|
862 |
+
|
863 |
+
.block {
|
864 |
+
display: block;
|
865 |
+
}
|
866 |
+
|
867 |
+
.flex {
|
868 |
+
display: flex;
|
869 |
+
}
|
870 |
+
|
871 |
+
.inline-flex {
|
872 |
+
display: inline-flex;
|
873 |
+
}
|
874 |
+
|
875 |
+
.table {
|
876 |
+
display: table;
|
877 |
+
}
|
878 |
+
|
879 |
+
.grid {
|
880 |
+
display: grid;
|
881 |
+
}
|
882 |
+
|
883 |
+
.contents {
|
884 |
+
display: contents;
|
885 |
+
}
|
886 |
+
|
887 |
+
.hidden {
|
888 |
+
display: none;
|
889 |
+
}
|
890 |
+
|
891 |
+
.aspect-square {
|
892 |
+
aspect-ratio: 1 / 1;
|
893 |
+
}
|
894 |
+
|
895 |
+
.size-4 {
|
896 |
+
width: 1rem;
|
897 |
+
height: 1rem;
|
898 |
+
}
|
899 |
+
|
900 |
+
.size-5 {
|
901 |
+
width: 1.25rem;
|
902 |
+
height: 1.25rem;
|
903 |
+
}
|
904 |
+
|
905 |
+
.h-10 {
|
906 |
+
height: 2.5rem;
|
907 |
+
}
|
908 |
+
|
909 |
+
.h-11 {
|
910 |
+
height: 2.75rem;
|
911 |
+
}
|
912 |
+
|
913 |
+
.h-12 {
|
914 |
+
height: 3rem;
|
915 |
+
}
|
916 |
+
|
917 |
+
.h-2 {
|
918 |
+
height: 0.5rem;
|
919 |
+
}
|
920 |
+
|
921 |
+
.h-2\.5 {
|
922 |
+
height: 0.625rem;
|
923 |
+
}
|
924 |
+
|
925 |
+
.h-3\.5 {
|
926 |
+
height: 0.875rem;
|
927 |
+
}
|
928 |
+
|
929 |
+
.h-4 {
|
930 |
+
height: 1rem;
|
931 |
+
}
|
932 |
+
|
933 |
+
.h-5 {
|
934 |
+
height: 1.25rem;
|
935 |
+
}
|
936 |
+
|
937 |
+
.h-6 {
|
938 |
+
height: 1.5rem;
|
939 |
+
}
|
940 |
+
|
941 |
+
.h-8 {
|
942 |
+
height: 2rem;
|
943 |
+
}
|
944 |
+
|
945 |
+
.h-9 {
|
946 |
+
height: 2.25rem;
|
947 |
+
}
|
948 |
+
|
949 |
+
.h-\[1\.5px\] {
|
950 |
+
height: 1.5px;
|
951 |
+
}
|
952 |
+
|
953 |
+
.h-\[27px\] {
|
954 |
+
height: 27px;
|
955 |
+
}
|
956 |
+
|
957 |
+
.h-\[377px\] {
|
958 |
+
height: 377px;
|
959 |
+
}
|
960 |
+
|
961 |
+
.h-\[55px\] {
|
962 |
+
height: 55px;
|
963 |
+
}
|
964 |
+
|
965 |
+
.h-\[var\(--radix-select-trigger-height\)\] {
|
966 |
+
height: var(--radix-select-trigger-height);
|
967 |
+
}
|
968 |
+
|
969 |
+
.h-full {
|
970 |
+
height: 100%;
|
971 |
+
}
|
972 |
+
|
973 |
+
.h-px {
|
974 |
+
height: 1px;
|
975 |
+
}
|
976 |
+
|
977 |
+
.max-h-96 {
|
978 |
+
max-height: 24rem;
|
979 |
+
}
|
980 |
+
|
981 |
+
.max-h-screen {
|
982 |
+
max-height: 100vh;
|
983 |
+
}
|
984 |
+
|
985 |
+
.min-h-0 {
|
986 |
+
min-height: 0px;
|
987 |
+
}
|
988 |
+
|
989 |
+
.min-h-\[55px\] {
|
990 |
+
min-height: 55px;
|
991 |
+
}
|
992 |
+
|
993 |
+
.min-h-\[80px\] {
|
994 |
+
min-height: 80px;
|
995 |
+
}
|
996 |
+
|
997 |
+
.min-h-screen {
|
998 |
+
min-height: 100vh;
|
999 |
+
}
|
1000 |
+
|
1001 |
+
.w-10 {
|
1002 |
+
width: 2.5rem;
|
1003 |
+
}
|
1004 |
+
|
1005 |
+
.w-11 {
|
1006 |
+
width: 2.75rem;
|
1007 |
+
}
|
1008 |
+
|
1009 |
+
.w-2\.5 {
|
1010 |
+
width: 0.625rem;
|
1011 |
+
}
|
1012 |
+
|
1013 |
+
.w-3\.5 {
|
1014 |
+
width: 0.875rem;
|
1015 |
+
}
|
1016 |
+
|
1017 |
+
.w-3\/4 {
|
1018 |
+
width: 75%;
|
1019 |
+
}
|
1020 |
+
|
1021 |
+
.w-4 {
|
1022 |
+
width: 1rem;
|
1023 |
+
}
|
1024 |
+
|
1025 |
+
.w-5 {
|
1026 |
+
width: 1.25rem;
|
1027 |
+
}
|
1028 |
+
|
1029 |
+
.w-8 {
|
1030 |
+
width: 2rem;
|
1031 |
+
}
|
1032 |
+
|
1033 |
+
.w-\[1\.5px\] {
|
1034 |
+
width: 1.5px;
|
1035 |
+
}
|
1036 |
+
|
1037 |
+
.w-full {
|
1038 |
+
width: 100%;
|
1039 |
+
}
|
1040 |
+
|
1041 |
+
.min-w-0 {
|
1042 |
+
min-width: 0px;
|
1043 |
+
}
|
1044 |
+
|
1045 |
+
.min-w-\[8rem\] {
|
1046 |
+
min-width: 8rem;
|
1047 |
+
}
|
1048 |
+
|
1049 |
+
.min-w-\[var\(--radix-select-trigger-width\)\] {
|
1050 |
+
min-width: var(--radix-select-trigger-width);
|
1051 |
+
}
|
1052 |
+
|
1053 |
+
.max-w-lg {
|
1054 |
+
max-width: 32rem;
|
1055 |
+
}
|
1056 |
+
|
1057 |
+
.max-w-screen-md {
|
1058 |
+
max-width: 768px;
|
1059 |
+
}
|
1060 |
+
|
1061 |
+
.flex-1 {
|
1062 |
+
flex: 1 1 0%;
|
1063 |
+
}
|
1064 |
+
|
1065 |
+
.shrink-0 {
|
1066 |
+
flex-shrink: 0;
|
1067 |
+
}
|
1068 |
+
|
1069 |
+
.grow {
|
1070 |
+
flex-grow: 1;
|
1071 |
+
}
|
1072 |
+
|
1073 |
+
.grow-0 {
|
1074 |
+
flex-grow: 0;
|
1075 |
+
}
|
1076 |
+
|
1077 |
+
.basis-full {
|
1078 |
+
flex-basis: 100%;
|
1079 |
+
}
|
1080 |
+
|
1081 |
+
.caption-bottom {
|
1082 |
+
caption-side: bottom;
|
1083 |
+
}
|
1084 |
+
|
1085 |
+
.-translate-x-1\/2 {
|
1086 |
+
--tw-translate-x: -50%;
|
1087 |
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
1088 |
+
}
|
1089 |
+
|
1090 |
+
.-translate-y-1\/2 {
|
1091 |
+
--tw-translate-y: -50%;
|
1092 |
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
1093 |
+
}
|
1094 |
+
|
1095 |
+
.translate-x-\[-50\%\] {
|
1096 |
+
--tw-translate-x: -50%;
|
1097 |
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
1098 |
+
}
|
1099 |
+
|
1100 |
+
.translate-y-\[-50\%\] {
|
1101 |
+
--tw-translate-y: -50%;
|
1102 |
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
1103 |
+
}
|
1104 |
+
|
1105 |
+
.rotate-90 {
|
1106 |
+
--tw-rotate: 90deg;
|
1107 |
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
1108 |
+
}
|
1109 |
+
|
1110 |
+
.transform {
|
1111 |
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
1112 |
+
}
|
1113 |
+
|
1114 |
+
@keyframes pulse {
|
1115 |
+
50% {
|
1116 |
+
opacity: .5;
|
1117 |
+
}
|
1118 |
+
}
|
1119 |
+
|
1120 |
+
.animate-pulse {
|
1121 |
+
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
1122 |
+
}
|
1123 |
+
|
1124 |
+
@keyframes spin {
|
1125 |
+
to {
|
1126 |
+
transform: rotate(360deg);
|
1127 |
+
}
|
1128 |
+
}
|
1129 |
+
|
1130 |
+
.animate-spin {
|
1131 |
+
animation: spin 1s linear infinite;
|
1132 |
+
}
|
1133 |
+
|
1134 |
+
.cursor-default {
|
1135 |
+
cursor: default;
|
1136 |
+
}
|
1137 |
+
|
1138 |
+
.cursor-pointer {
|
1139 |
+
cursor: pointer;
|
1140 |
+
}
|
1141 |
+
|
1142 |
+
.touch-none {
|
1143 |
+
touch-action: none;
|
1144 |
+
}
|
1145 |
+
|
1146 |
+
.select-none {
|
1147 |
+
-webkit-user-select: none;
|
1148 |
+
-moz-user-select: none;
|
1149 |
+
user-select: none;
|
1150 |
+
}
|
1151 |
+
|
1152 |
+
.resize {
|
1153 |
+
resize: both;
|
1154 |
+
}
|
1155 |
+
|
1156 |
+
.grid-flow-col {
|
1157 |
+
grid-auto-flow: column;
|
1158 |
+
}
|
1159 |
+
|
1160 |
+
.grid-cols-1 {
|
1161 |
+
grid-template-columns: repeat(1, minmax(0, 1fr));
|
1162 |
+
}
|
1163 |
+
|
1164 |
+
.grid-rows-\[1fr_1fr\] {
|
1165 |
+
grid-template-rows: 1fr 1fr;
|
1166 |
+
}
|
1167 |
+
|
1168 |
+
.grid-rows-\[auto_0px\] {
|
1169 |
+
grid-template-rows: auto 0px;
|
1170 |
+
}
|
1171 |
+
|
1172 |
+
.grid-rows-\[auto_1fr\] {
|
1173 |
+
grid-template-rows: auto 1fr;
|
1174 |
+
}
|
1175 |
+
|
1176 |
+
.grid-rows-\[auto_1fr_auto\] {
|
1177 |
+
grid-template-rows: auto 1fr auto;
|
1178 |
+
}
|
1179 |
+
|
1180 |
+
.grid-rows-\[minmax\(0\2c 55px\)_minmax\(0\2c 1fr\)\] {
|
1181 |
+
grid-template-rows: minmax(0,55px) minmax(0,1fr);
|
1182 |
+
}
|
1183 |
+
|
1184 |
+
.grid-rows-\[auto_auto_1fr\] {
|
1185 |
+
grid-template-rows: auto auto 1fr;
|
1186 |
+
}
|
1187 |
+
|
1188 |
+
.flex-col {
|
1189 |
+
flex-direction: column;
|
1190 |
+
}
|
1191 |
+
|
1192 |
+
.flex-col-reverse {
|
1193 |
+
flex-direction: column-reverse;
|
1194 |
+
}
|
1195 |
+
|
1196 |
+
.flex-wrap {
|
1197 |
+
flex-wrap: wrap;
|
1198 |
+
}
|
1199 |
+
|
1200 |
+
.content-start {
|
1201 |
+
align-content: flex-start;
|
1202 |
+
}
|
1203 |
+
|
1204 |
+
.items-end {
|
1205 |
+
align-items: flex-end;
|
1206 |
+
}
|
1207 |
+
|
1208 |
+
.items-center {
|
1209 |
+
align-items: center;
|
1210 |
+
}
|
1211 |
+
|
1212 |
+
.justify-end {
|
1213 |
+
justify-content: flex-end;
|
1214 |
+
}
|
1215 |
+
|
1216 |
+
.justify-center {
|
1217 |
+
justify-content: center;
|
1218 |
+
}
|
1219 |
+
|
1220 |
+
.justify-between {
|
1221 |
+
justify-content: space-between;
|
1222 |
+
}
|
1223 |
+
|
1224 |
+
.justify-items-center {
|
1225 |
+
justify-items: center;
|
1226 |
+
}
|
1227 |
+
|
1228 |
+
.gap-1\.5 {
|
1229 |
+
gap: 0.375rem;
|
1230 |
+
}
|
1231 |
+
|
1232 |
+
.gap-2 {
|
1233 |
+
gap: 0.5rem;
|
1234 |
+
}
|
1235 |
+
|
1236 |
+
.gap-3 {
|
1237 |
+
gap: 0.75rem;
|
1238 |
+
}
|
1239 |
+
|
1240 |
+
.gap-4 {
|
1241 |
+
gap: 1rem;
|
1242 |
+
}
|
1243 |
+
|
1244 |
+
.gap-5 {
|
1245 |
+
gap: 1.25rem;
|
1246 |
+
}
|
1247 |
+
|
1248 |
+
.gap-8 {
|
1249 |
+
gap: 2rem;
|
1250 |
+
}
|
1251 |
+
|
1252 |
+
.gap-\[3px\] {
|
1253 |
+
gap: 3px;
|
1254 |
+
}
|
1255 |
+
|
1256 |
+
.gap-px {
|
1257 |
+
gap: 1px;
|
1258 |
+
}
|
1259 |
+
|
1260 |
+
.gap-x-3 {
|
1261 |
+
-moz-column-gap: 0.75rem;
|
1262 |
+
column-gap: 0.75rem;
|
1263 |
+
}
|
1264 |
+
|
1265 |
+
.gap-x-5 {
|
1266 |
+
-moz-column-gap: 1.25rem;
|
1267 |
+
column-gap: 1.25rem;
|
1268 |
+
}
|
1269 |
+
|
1270 |
+
.gap-y-3 {
|
1271 |
+
row-gap: 0.75rem;
|
1272 |
+
}
|
1273 |
+
|
1274 |
+
.gap-y-8 {
|
1275 |
+
row-gap: 2rem;
|
1276 |
+
}
|
1277 |
+
|
1278 |
+
.space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
1279 |
+
--tw-space-x-reverse: 0;
|
1280 |
+
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
1281 |
+
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
1282 |
+
}
|
1283 |
+
|
1284 |
+
.space-x-4 > :not([hidden]) ~ :not([hidden]) {
|
1285 |
+
--tw-space-x-reverse: 0;
|
1286 |
+
margin-right: calc(1rem * var(--tw-space-x-reverse));
|
1287 |
+
margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));
|
1288 |
+
}
|
1289 |
+
|
1290 |
+
.space-y-1\.5 > :not([hidden]) ~ :not([hidden]) {
|
1291 |
+
--tw-space-y-reverse: 0;
|
1292 |
+
margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse)));
|
1293 |
+
margin-bottom: calc(0.375rem * var(--tw-space-y-reverse));
|
1294 |
+
}
|
1295 |
+
|
1296 |
+
.space-y-2 > :not([hidden]) ~ :not([hidden]) {
|
1297 |
+
--tw-space-y-reverse: 0;
|
1298 |
+
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
|
1299 |
+
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
|
1300 |
+
}
|
1301 |
+
|
1302 |
+
.space-x-1 > :not([hidden]) ~ :not([hidden]) {
|
1303 |
+
--tw-space-x-reverse: 0;
|
1304 |
+
margin-right: calc(0.25rem * var(--tw-space-x-reverse));
|
1305 |
+
margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse)));
|
1306 |
+
}
|
1307 |
+
|
1308 |
+
.self-stretch {
|
1309 |
+
align-self: stretch;
|
1310 |
+
}
|
1311 |
+
|
1312 |
+
.overflow-auto {
|
1313 |
+
overflow: auto;
|
1314 |
+
}
|
1315 |
+
|
1316 |
+
.overflow-hidden {
|
1317 |
+
overflow: hidden;
|
1318 |
+
}
|
1319 |
+
|
1320 |
+
.whitespace-nowrap {
|
1321 |
+
white-space: nowrap;
|
1322 |
+
}
|
1323 |
+
|
1324 |
+
.\!rounded-full {
|
1325 |
+
border-radius: 9999px !important;
|
1326 |
+
}
|
1327 |
+
|
1328 |
+
.rounded-\[inherit\] {
|
1329 |
+
border-radius: inherit;
|
1330 |
+
}
|
1331 |
+
|
1332 |
+
.rounded-full {
|
1333 |
+
border-radius: 9999px;
|
1334 |
+
}
|
1335 |
+
|
1336 |
+
.rounded-lg {
|
1337 |
+
border-radius: var(--radius);
|
1338 |
+
}
|
1339 |
+
|
1340 |
+
.rounded-md {
|
1341 |
+
border-radius: calc(var(--radius) - 2px);
|
1342 |
+
}
|
1343 |
+
|
1344 |
+
.rounded-none {
|
1345 |
+
border-radius: 0px;
|
1346 |
+
}
|
1347 |
+
|
1348 |
+
.rounded-sm {
|
1349 |
+
border-radius: calc(var(--radius) - 4px);
|
1350 |
+
}
|
1351 |
+
|
1352 |
+
.border {
|
1353 |
+
border-width: 1px;
|
1354 |
+
}
|
1355 |
+
|
1356 |
+
.border-2 {
|
1357 |
+
border-width: 2px;
|
1358 |
+
}
|
1359 |
+
|
1360 |
+
.border-b {
|
1361 |
+
border-bottom-width: 1px;
|
1362 |
+
}
|
1363 |
+
|
1364 |
+
.border-l {
|
1365 |
+
border-left-width: 1px;
|
1366 |
+
}
|
1367 |
+
|
1368 |
+
.border-r {
|
1369 |
+
border-right-width: 1px;
|
1370 |
+
}
|
1371 |
+
|
1372 |
+
.border-t {
|
1373 |
+
border-top-width: 1px;
|
1374 |
+
}
|
1375 |
+
|
1376 |
+
.border-dashed {
|
1377 |
+
border-style: dashed;
|
1378 |
+
}
|
1379 |
+
|
1380 |
+
.border-destructive {
|
1381 |
+
border-color: hsl(var(--destructive));
|
1382 |
+
}
|
1383 |
+
|
1384 |
+
.border-destructive\/50 {
|
1385 |
+
border-color: hsl(var(--destructive) / 0.5);
|
1386 |
+
}
|
1387 |
+
|
1388 |
+
.border-input {
|
1389 |
+
border-color: hsl(var(--input));
|
1390 |
+
}
|
1391 |
+
|
1392 |
+
.border-primary {
|
1393 |
+
border-color: hsl(var(--primary));
|
1394 |
+
}
|
1395 |
+
|
1396 |
+
.border-transparent {
|
1397 |
+
border-color: transparent;
|
1398 |
+
}
|
1399 |
+
|
1400 |
+
.border-l-transparent {
|
1401 |
+
border-left-color: transparent;
|
1402 |
+
}
|
1403 |
+
|
1404 |
+
.border-t-transparent {
|
1405 |
+
border-top-color: transparent;
|
1406 |
+
}
|
1407 |
+
|
1408 |
+
.bg-background {
|
1409 |
+
background-color: hsl(var(--background));
|
1410 |
+
}
|
1411 |
+
|
1412 |
+
.bg-black\/80 {
|
1413 |
+
background-color: rgb(0 0 0 / 0.8);
|
1414 |
+
}
|
1415 |
+
|
1416 |
+
.bg-blue-500 {
|
1417 |
+
--tw-bg-opacity: 1;
|
1418 |
+
background-color: rgb(59 130 246 / var(--tw-bg-opacity));
|
1419 |
+
}
|
1420 |
+
|
1421 |
+
.bg-border {
|
1422 |
+
background-color: hsl(var(--border));
|
1423 |
+
}
|
1424 |
+
|
1425 |
+
.bg-card {
|
1426 |
+
background-color: hsl(var(--card));
|
1427 |
+
}
|
1428 |
+
|
1429 |
+
.bg-destructive {
|
1430 |
+
background-color: hsl(var(--destructive));
|
1431 |
+
}
|
1432 |
+
|
1433 |
+
.bg-input {
|
1434 |
+
background-color: hsl(var(--input));
|
1435 |
+
}
|
1436 |
+
|
1437 |
+
.bg-muted {
|
1438 |
+
background-color: hsl(var(--muted));
|
1439 |
+
}
|
1440 |
+
|
1441 |
+
.bg-muted\/50 {
|
1442 |
+
background-color: hsl(var(--muted) / 0.5);
|
1443 |
+
}
|
1444 |
+
|
1445 |
+
.bg-popover {
|
1446 |
+
background-color: hsl(var(--popover));
|
1447 |
+
}
|
1448 |
+
|
1449 |
+
.bg-primary {
|
1450 |
+
background-color: hsl(var(--primary));
|
1451 |
+
}
|
1452 |
+
|
1453 |
+
.bg-red-300 {
|
1454 |
+
--tw-bg-opacity: 1;
|
1455 |
+
background-color: rgb(252 165 165 / var(--tw-bg-opacity));
|
1456 |
+
}
|
1457 |
+
|
1458 |
+
.bg-red-500 {
|
1459 |
+
--tw-bg-opacity: 1;
|
1460 |
+
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
1461 |
+
}
|
1462 |
+
|
1463 |
+
.bg-secondary {
|
1464 |
+
background-color: hsl(var(--secondary));
|
1465 |
+
}
|
1466 |
+
|
1467 |
+
.bg-white {
|
1468 |
+
--tw-bg-opacity: 1;
|
1469 |
+
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
1470 |
+
}
|
1471 |
+
|
1472 |
+
.bg-gradient-to-r {
|
1473 |
+
background-image: linear-gradient(to right, var(--tw-gradient-stops));
|
1474 |
+
}
|
1475 |
+
|
1476 |
+
.bg-gradient-to-t {
|
1477 |
+
background-image: linear-gradient(to top, var(--tw-gradient-stops));
|
1478 |
+
}
|
1479 |
+
|
1480 |
+
.from-\[\#fcfcfd\] {
|
1481 |
+
--tw-gradient-from: #fcfcfd var(--tw-gradient-from-position);
|
1482 |
+
--tw-gradient-to: rgb(252 252 253 / 0) var(--tw-gradient-to-position);
|
1483 |
+
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
|
1484 |
+
}
|
1485 |
+
|
1486 |
+
.from-black {
|
1487 |
+
--tw-gradient-from: #000 var(--tw-gradient-from-position);
|
1488 |
+
--tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);
|
1489 |
+
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
|
1490 |
+
}
|
1491 |
+
|
1492 |
+
.to-slate-700 {
|
1493 |
+
--tw-gradient-to: #334155 var(--tw-gradient-to-position);
|
1494 |
+
}
|
1495 |
+
|
1496 |
+
.bg-clip-text {
|
1497 |
+
-webkit-background-clip: text;
|
1498 |
+
background-clip: text;
|
1499 |
+
}
|
1500 |
+
|
1501 |
+
.fill-current {
|
1502 |
+
fill: currentColor;
|
1503 |
+
}
|
1504 |
+
|
1505 |
+
.object-contain {
|
1506 |
+
-o-object-fit: contain;
|
1507 |
+
object-fit: contain;
|
1508 |
+
}
|
1509 |
+
|
1510 |
+
.p-1 {
|
1511 |
+
padding: 0.25rem;
|
1512 |
+
}
|
1513 |
+
|
1514 |
+
.p-10 {
|
1515 |
+
padding: 2.5rem;
|
1516 |
+
}
|
1517 |
+
|
1518 |
+
.p-2 {
|
1519 |
+
padding: 0.5rem;
|
1520 |
+
}
|
1521 |
+
|
1522 |
+
.p-3 {
|
1523 |
+
padding: 0.75rem;
|
1524 |
+
}
|
1525 |
+
|
1526 |
+
.p-4 {
|
1527 |
+
padding: 1rem;
|
1528 |
+
}
|
1529 |
+
|
1530 |
+
.p-5 {
|
1531 |
+
padding: 1.25rem;
|
1532 |
+
}
|
1533 |
+
|
1534 |
+
.p-6 {
|
1535 |
+
padding: 1.5rem;
|
1536 |
+
}
|
1537 |
+
|
1538 |
+
.p-8 {
|
1539 |
+
padding: 2rem;
|
1540 |
+
}
|
1541 |
+
|
1542 |
+
.p-\[1px\] {
|
1543 |
+
padding: 1px;
|
1544 |
+
}
|
1545 |
+
|
1546 |
+
.px-2 {
|
1547 |
+
padding-left: 0.5rem;
|
1548 |
+
padding-right: 0.5rem;
|
1549 |
+
}
|
1550 |
+
|
1551 |
+
.px-2\.5 {
|
1552 |
+
padding-left: 0.625rem;
|
1553 |
+
padding-right: 0.625rem;
|
1554 |
+
}
|
1555 |
+
|
1556 |
+
.px-3 {
|
1557 |
+
padding-left: 0.75rem;
|
1558 |
+
padding-right: 0.75rem;
|
1559 |
+
}
|
1560 |
+
|
1561 |
+
.px-4 {
|
1562 |
+
padding-left: 1rem;
|
1563 |
+
padding-right: 1rem;
|
1564 |
+
}
|
1565 |
+
|
1566 |
+
.px-5 {
|
1567 |
+
padding-left: 1.25rem;
|
1568 |
+
padding-right: 1.25rem;
|
1569 |
+
}
|
1570 |
+
|
1571 |
+
.px-8 {
|
1572 |
+
padding-left: 2rem;
|
1573 |
+
padding-right: 2rem;
|
1574 |
+
}
|
1575 |
+
|
1576 |
+
.py-0\.5 {
|
1577 |
+
padding-top: 0.125rem;
|
1578 |
+
padding-bottom: 0.125rem;
|
1579 |
+
}
|
1580 |
+
|
1581 |
+
.py-1 {
|
1582 |
+
padding-top: 0.25rem;
|
1583 |
+
padding-bottom: 0.25rem;
|
1584 |
+
}
|
1585 |
+
|
1586 |
+
.py-1\.5 {
|
1587 |
+
padding-top: 0.375rem;
|
1588 |
+
padding-bottom: 0.375rem;
|
1589 |
+
}
|
1590 |
+
|
1591 |
+
.py-2 {
|
1592 |
+
padding-top: 0.5rem;
|
1593 |
+
padding-bottom: 0.5rem;
|
1594 |
+
}
|
1595 |
+
|
1596 |
+
.py-4 {
|
1597 |
+
padding-top: 1rem;
|
1598 |
+
padding-bottom: 1rem;
|
1599 |
+
}
|
1600 |
+
|
1601 |
+
.py-5 {
|
1602 |
+
padding-top: 1.25rem;
|
1603 |
+
padding-bottom: 1.25rem;
|
1604 |
+
}
|
1605 |
+
|
1606 |
+
.pl-10 {
|
1607 |
+
padding-left: 2.5rem;
|
1608 |
+
}
|
1609 |
+
|
1610 |
+
.pl-4 {
|
1611 |
+
padding-left: 1rem;
|
1612 |
+
}
|
1613 |
+
|
1614 |
+
.pl-8 {
|
1615 |
+
padding-left: 2rem;
|
1616 |
+
}
|
1617 |
+
|
1618 |
+
.pr-2 {
|
1619 |
+
padding-right: 0.5rem;
|
1620 |
+
}
|
1621 |
+
|
1622 |
+
.pr-8 {
|
1623 |
+
padding-right: 2rem;
|
1624 |
+
}
|
1625 |
+
|
1626 |
+
.pt-0 {
|
1627 |
+
padding-top: 0px;
|
1628 |
+
}
|
1629 |
+
|
1630 |
+
.pt-4 {
|
1631 |
+
padding-top: 1rem;
|
1632 |
+
}
|
1633 |
+
|
1634 |
+
.pt-\[7\%\] {
|
1635 |
+
padding-top: 7%;
|
1636 |
+
}
|
1637 |
+
|
1638 |
+
.text-left {
|
1639 |
+
text-align: left;
|
1640 |
+
}
|
1641 |
+
|
1642 |
+
.text-center {
|
1643 |
+
text-align: center;
|
1644 |
+
}
|
1645 |
+
|
1646 |
+
.align-middle {
|
1647 |
+
vertical-align: middle;
|
1648 |
+
}
|
1649 |
+
|
1650 |
+
.font-mono {
|
1651 |
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
1652 |
+
}
|
1653 |
+
|
1654 |
+
.text-2xl {
|
1655 |
+
font-size: 1.5rem;
|
1656 |
+
line-height: 2rem;
|
1657 |
+
}
|
1658 |
+
|
1659 |
+
.text-3xl {
|
1660 |
+
font-size: 1.875rem;
|
1661 |
+
line-height: 2.25rem;
|
1662 |
+
}
|
1663 |
+
|
1664 |
+
.text-5xl {
|
1665 |
+
font-size: 3rem;
|
1666 |
+
line-height: 1;
|
1667 |
+
}
|
1668 |
+
|
1669 |
+
.text-base {
|
1670 |
+
font-size: 1rem;
|
1671 |
+
line-height: 1.5rem;
|
1672 |
+
}
|
1673 |
+
|
1674 |
+
.text-lg {
|
1675 |
+
font-size: 1.125rem;
|
1676 |
+
line-height: 1.75rem;
|
1677 |
+
}
|
1678 |
+
|
1679 |
+
.text-sm {
|
1680 |
+
font-size: 0.875rem;
|
1681 |
+
line-height: 1.25rem;
|
1682 |
+
}
|
1683 |
+
|
1684 |
+
.text-xl {
|
1685 |
+
font-size: 1.25rem;
|
1686 |
+
line-height: 1.75rem;
|
1687 |
+
}
|
1688 |
+
|
1689 |
+
.text-xs {
|
1690 |
+
font-size: 0.75rem;
|
1691 |
+
line-height: 1rem;
|
1692 |
+
}
|
1693 |
+
|
1694 |
+
.font-bold {
|
1695 |
+
font-weight: 700;
|
1696 |
+
}
|
1697 |
+
|
1698 |
+
.font-medium {
|
1699 |
+
font-weight: 500;
|
1700 |
+
}
|
1701 |
+
|
1702 |
+
.font-normal {
|
1703 |
+
font-weight: 400;
|
1704 |
+
}
|
1705 |
+
|
1706 |
+
.font-semibold {
|
1707 |
+
font-weight: 600;
|
1708 |
+
}
|
1709 |
+
|
1710 |
+
.leading-none {
|
1711 |
+
line-height: 1;
|
1712 |
+
}
|
1713 |
+
|
1714 |
+
.tracking-tight {
|
1715 |
+
letter-spacing: -0.025em;
|
1716 |
+
}
|
1717 |
+
|
1718 |
+
.tracking-wide {
|
1719 |
+
letter-spacing: 0.025em;
|
1720 |
+
}
|
1721 |
+
|
1722 |
+
.text-card-foreground {
|
1723 |
+
color: hsl(var(--card-foreground));
|
1724 |
+
}
|
1725 |
+
|
1726 |
+
.text-current {
|
1727 |
+
color: currentColor;
|
1728 |
+
}
|
1729 |
+
|
1730 |
+
.text-destructive {
|
1731 |
+
color: hsl(var(--destructive));
|
1732 |
+
}
|
1733 |
+
|
1734 |
+
.text-destructive-foreground {
|
1735 |
+
color: hsl(var(--destructive-foreground));
|
1736 |
+
}
|
1737 |
+
|
1738 |
+
.text-foreground {
|
1739 |
+
color: hsl(var(--foreground));
|
1740 |
+
}
|
1741 |
+
|
1742 |
+
.text-foreground\/50 {
|
1743 |
+
color: hsl(var(--foreground) / 0.5);
|
1744 |
+
}
|
1745 |
+
|
1746 |
+
.text-gray-800 {
|
1747 |
+
--tw-text-opacity: 1;
|
1748 |
+
color: rgb(31 41 55 / var(--tw-text-opacity));
|
1749 |
+
}
|
1750 |
+
|
1751 |
+
.text-gray-900 {
|
1752 |
+
--tw-text-opacity: 1;
|
1753 |
+
color: rgb(17 24 39 / var(--tw-text-opacity));
|
1754 |
+
}
|
1755 |
+
|
1756 |
+
.text-muted-foreground {
|
1757 |
+
color: hsl(var(--muted-foreground));
|
1758 |
+
}
|
1759 |
+
|
1760 |
+
.text-popover-foreground {
|
1761 |
+
color: hsl(var(--popover-foreground));
|
1762 |
+
}
|
1763 |
+
|
1764 |
+
.text-primary {
|
1765 |
+
color: hsl(var(--primary));
|
1766 |
+
}
|
1767 |
+
|
1768 |
+
.text-primary-foreground {
|
1769 |
+
color: hsl(var(--primary-foreground));
|
1770 |
+
}
|
1771 |
+
|
1772 |
+
.text-secondary-foreground {
|
1773 |
+
color: hsl(var(--secondary-foreground));
|
1774 |
+
}
|
1775 |
+
|
1776 |
+
.text-transparent {
|
1777 |
+
color: transparent;
|
1778 |
+
}
|
1779 |
+
|
1780 |
+
.no-underline {
|
1781 |
+
text-decoration-line: none;
|
1782 |
+
}
|
1783 |
+
|
1784 |
+
.underline-offset-4 {
|
1785 |
+
text-underline-offset: 4px;
|
1786 |
+
}
|
1787 |
+
|
1788 |
+
.antialiased {
|
1789 |
+
-webkit-font-smoothing: antialiased;
|
1790 |
+
-moz-osx-font-smoothing: grayscale;
|
1791 |
+
}
|
1792 |
+
|
1793 |
+
.opacity-0 {
|
1794 |
+
opacity: 0;
|
1795 |
+
}
|
1796 |
+
|
1797 |
+
.opacity-50 {
|
1798 |
+
opacity: 0.5;
|
1799 |
+
}
|
1800 |
+
|
1801 |
+
.opacity-70 {
|
1802 |
+
opacity: 0.7;
|
1803 |
+
}
|
1804 |
+
|
1805 |
+
.opacity-90 {
|
1806 |
+
opacity: 0.9;
|
1807 |
+
}
|
1808 |
+
|
1809 |
+
.shadow-lg {
|
1810 |
+
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
1811 |
+
--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
|
1812 |
+
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
1813 |
+
}
|
1814 |
+
|
1815 |
+
.shadow-md {
|
1816 |
+
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
1817 |
+
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
|
1818 |
+
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
1819 |
+
}
|
1820 |
+
|
1821 |
+
.shadow-sm {
|
1822 |
+
--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
1823 |
+
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
|
1824 |
+
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
1825 |
+
}
|
1826 |
+
|
1827 |
+
.outline-none {
|
1828 |
+
outline: 2px solid transparent;
|
1829 |
+
outline-offset: 2px;
|
1830 |
+
}
|
1831 |
+
|
1832 |
+
.outline {
|
1833 |
+
outline-style: solid;
|
1834 |
+
}
|
1835 |
+
|
1836 |
+
.ring {
|
1837 |
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
1838 |
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
1839 |
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
1840 |
+
}
|
1841 |
+
|
1842 |
+
.ring-0 {
|
1843 |
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
1844 |
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
1845 |
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
1846 |
+
}
|
1847 |
+
|
1848 |
+
.ring-offset-background {
|
1849 |
+
--tw-ring-offset-color: hsl(var(--background));
|
1850 |
+
}
|
1851 |
+
|
1852 |
+
.ring-offset-transparent {
|
1853 |
+
--tw-ring-offset-color: transparent;
|
1854 |
+
}
|
1855 |
+
|
1856 |
+
.blur {
|
1857 |
+
--tw-blur: blur(8px);
|
1858 |
+
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);
|
1859 |
+
}
|
1860 |
+
|
1861 |
+
.filter {
|
1862 |
+
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);
|
1863 |
+
}
|
1864 |
+
|
1865 |
+
.backdrop-filter {
|
1866 |
+
-webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
|
1867 |
+
backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
|
1868 |
+
}
|
1869 |
+
|
1870 |
+
.transition {
|
1871 |
+
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter;
|
1872 |
+
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
|
1873 |
+
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter;
|
1874 |
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
1875 |
+
transition-duration: 150ms;
|
1876 |
+
}
|
1877 |
+
|
1878 |
+
.transition-all {
|
1879 |
+
transition-property: all;
|
1880 |
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
1881 |
+
transition-duration: 150ms;
|
1882 |
+
}
|
1883 |
+
|
1884 |
+
.transition-colors {
|
1885 |
+
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
|
1886 |
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
1887 |
+
transition-duration: 150ms;
|
1888 |
+
}
|
1889 |
+
|
1890 |
+
.transition-opacity {
|
1891 |
+
transition-property: opacity;
|
1892 |
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
1893 |
+
transition-duration: 150ms;
|
1894 |
+
}
|
1895 |
+
|
1896 |
+
.transition-transform {
|
1897 |
+
transition-property: transform;
|
1898 |
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
1899 |
+
transition-duration: 150ms;
|
1900 |
+
}
|
1901 |
+
|
1902 |
+
.duration-200 {
|
1903 |
+
transition-duration: 200ms;
|
1904 |
+
}
|
1905 |
+
|
1906 |
+
.duration-300 {
|
1907 |
+
transition-duration: 300ms;
|
1908 |
+
}
|
1909 |
+
|
1910 |
+
.ease-in-out {
|
1911 |
+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
1912 |
+
}
|
1913 |
+
|
1914 |
+
.ease-out {
|
1915 |
+
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
1916 |
+
}
|
1917 |
+
|
1918 |
+
@keyframes enter {
|
1919 |
+
from {
|
1920 |
+
opacity: var(--tw-enter-opacity, 1);
|
1921 |
+
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));
|
1922 |
+
}
|
1923 |
+
}
|
1924 |
+
|
1925 |
+
@keyframes exit {
|
1926 |
+
to {
|
1927 |
+
opacity: var(--tw-exit-opacity, 1);
|
1928 |
+
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));
|
1929 |
+
}
|
1930 |
+
}
|
1931 |
+
|
1932 |
+
.animate-in {
|
1933 |
+
animation-name: enter;
|
1934 |
+
animation-duration: 150ms;
|
1935 |
+
--tw-enter-opacity: initial;
|
1936 |
+
--tw-enter-scale: initial;
|
1937 |
+
--tw-enter-rotate: initial;
|
1938 |
+
--tw-enter-translate-x: initial;
|
1939 |
+
--tw-enter-translate-y: initial;
|
1940 |
+
}
|
1941 |
+
|
1942 |
+
.animate-out {
|
1943 |
+
animation-name: exit;
|
1944 |
+
animation-duration: 150ms;
|
1945 |
+
--tw-exit-opacity: initial;
|
1946 |
+
--tw-exit-scale: initial;
|
1947 |
+
--tw-exit-rotate: initial;
|
1948 |
+
--tw-exit-translate-x: initial;
|
1949 |
+
--tw-exit-translate-y: initial;
|
1950 |
+
}
|
1951 |
+
|
1952 |
+
.fade-in {
|
1953 |
+
--tw-enter-opacity: 0;
|
1954 |
+
}
|
1955 |
+
|
1956 |
+
.fade-out {
|
1957 |
+
--tw-exit-opacity: 0;
|
1958 |
+
}
|
1959 |
+
|
1960 |
+
.zoom-in {
|
1961 |
+
--tw-enter-scale: 0;
|
1962 |
+
}
|
1963 |
+
|
1964 |
+
.zoom-out {
|
1965 |
+
--tw-exit-scale: 0;
|
1966 |
+
}
|
1967 |
+
|
1968 |
+
.spin-in {
|
1969 |
+
--tw-enter-rotate: 30deg;
|
1970 |
+
}
|
1971 |
+
|
1972 |
+
.spin-out {
|
1973 |
+
--tw-exit-rotate: 30deg;
|
1974 |
+
}
|
1975 |
+
|
1976 |
+
.slide-in-from-bottom {
|
1977 |
+
--tw-enter-translate-y: 100%;
|
1978 |
+
}
|
1979 |
+
|
1980 |
+
.slide-in-from-left {
|
1981 |
+
--tw-enter-translate-x: -100%;
|
1982 |
+
}
|
1983 |
+
|
1984 |
+
.slide-in-from-right {
|
1985 |
+
--tw-enter-translate-x: 100%;
|
1986 |
+
}
|
1987 |
+
|
1988 |
+
.slide-in-from-top {
|
1989 |
+
--tw-enter-translate-y: -100%;
|
1990 |
+
}
|
1991 |
+
|
1992 |
+
.slide-out-to-bottom {
|
1993 |
+
--tw-exit-translate-y: 100%;
|
1994 |
+
}
|
1995 |
+
|
1996 |
+
.slide-out-to-left {
|
1997 |
+
--tw-exit-translate-x: -100%;
|
1998 |
+
}
|
1999 |
+
|
2000 |
+
.slide-out-to-right {
|
2001 |
+
--tw-exit-translate-x: 100%;
|
2002 |
+
}
|
2003 |
+
|
2004 |
+
.slide-out-to-top {
|
2005 |
+
--tw-exit-translate-y: -100%;
|
2006 |
+
}
|
2007 |
+
|
2008 |
+
.duration-200 {
|
2009 |
+
animation-duration: 200ms;
|
2010 |
+
}
|
2011 |
+
|
2012 |
+
.duration-300 {
|
2013 |
+
animation-duration: 300ms;
|
2014 |
+
}
|
2015 |
+
|
2016 |
+
.ease-in-out {
|
2017 |
+
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
2018 |
+
}
|
2019 |
+
|
2020 |
+
.ease-out {
|
2021 |
+
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
|
2022 |
+
}
|
2023 |
+
|
2024 |
+
.running {
|
2025 |
+
animation-play-state: running;
|
2026 |
+
}
|
2027 |
+
|
2028 |
+
.paused {
|
2029 |
+
animation-play-state: paused;
|
2030 |
+
}
|
2031 |
+
|
2032 |
+
/* Hide scrollbar for Chrome, Safari and Opera */
|
2033 |
+
|
2034 |
+
.no-scrollbar::-webkit-scrollbar {
|
2035 |
+
display: none;
|
2036 |
+
}
|
2037 |
+
|
2038 |
+
/* Hide scrollbar for IE, Edge and Firefox */
|
2039 |
+
|
2040 |
+
.no-scrollbar {
|
2041 |
+
-webkit-overflow-scrolling: touch;
|
2042 |
+
-ms-overflow-style: none;
|
2043 |
+
/* IE and Edge */
|
2044 |
+
scrollbar-width: none;
|
2045 |
+
/* Firefox */
|
2046 |
+
}
|
2047 |
+
|
2048 |
+
@keyframes slideInFromTop {
|
2049 |
+
from {
|
2050 |
+
transform: translateY(-100%);
|
2051 |
+
}
|
2052 |
+
|
2053 |
+
to {
|
2054 |
+
transform: translateY(0);
|
2055 |
+
}
|
2056 |
+
}
|
2057 |
+
|
2058 |
+
@keyframes slideInFromBottom {
|
2059 |
+
from {
|
2060 |
+
transform: translateY(100%);
|
2061 |
+
}
|
2062 |
+
|
2063 |
+
to {
|
2064 |
+
transform: translateY(0);
|
2065 |
+
}
|
2066 |
+
}
|
2067 |
+
|
2068 |
+
.toast {
|
2069 |
+
animation-duration: 0.2s;
|
2070 |
+
animation-fill-mode: forwards;
|
2071 |
+
}
|
2072 |
+
|
2073 |
+
@media (max-width: 640px) {
|
2074 |
+
.toast {
|
2075 |
+
animation-name: slideInFromTop;
|
2076 |
+
}
|
2077 |
+
}
|
2078 |
+
|
2079 |
+
@media (min-width: 641px) {
|
2080 |
+
.toast {
|
2081 |
+
animation-name: slideInFromBottom;
|
2082 |
+
}
|
2083 |
+
}
|
2084 |
+
|
2085 |
+
@keyframes fade-in {
|
2086 |
+
from {
|
2087 |
+
opacity: 0;
|
2088 |
+
}
|
2089 |
+
|
2090 |
+
to {
|
2091 |
+
opacity: 1;
|
2092 |
+
}
|
2093 |
+
}
|
2094 |
+
|
2095 |
+
@keyframes slide-up {
|
2096 |
+
from {
|
2097 |
+
transform: translateY(20px);
|
2098 |
+
opacity: 0;
|
2099 |
+
}
|
2100 |
+
|
2101 |
+
to {
|
2102 |
+
transform: translateY(0);
|
2103 |
+
opacity: 1;
|
2104 |
+
}
|
2105 |
+
}
|
2106 |
+
|
2107 |
+
.animate-fade-in {
|
2108 |
+
animation: fade-in 1s ease-out forwards;
|
2109 |
+
}
|
2110 |
+
|
2111 |
+
.animate-slide-up {
|
2112 |
+
animation: slide-up 1s ease-out forwards;
|
2113 |
+
}
|
2114 |
+
|
2115 |
+
.sim-map-button.active {
|
2116 |
+
background-color: #61D790;
|
2117 |
+
color: #2E2F27;
|
2118 |
+
&:hover {
|
2119 |
+
background-color: #61D790;
|
2120 |
+
}
|
2121 |
+
}
|
2122 |
+
|
2123 |
+
.text-highlight strong {
|
2124 |
+
color: black;
|
2125 |
+
.dark & {
|
2126 |
+
color: white;
|
2127 |
+
}
|
2128 |
+
}
|
2129 |
+
|
2130 |
+
.tokens-button {
|
2131 |
+
background-color: #B7E2F1;
|
2132 |
+
color: #2E2F27;
|
2133 |
+
}
|
2134 |
+
|
2135 |
+
.overlay-image {
|
2136 |
+
opacity: 0.5;
|
2137 |
+
position: absolute;
|
2138 |
+
top: 0;
|
2139 |
+
left: 0;
|
2140 |
+
width: 100%;
|
2141 |
+
height: 100%;
|
2142 |
+
z-index: 10;
|
2143 |
+
}
|
2144 |
+
|
2145 |
+
header {
|
2146 |
+
grid-column: 1/-1;
|
2147 |
+
}
|
2148 |
+
|
2149 |
+
body {
|
2150 |
+
&[data-is-home="true"] {
|
2151 |
+
background: radial-gradient(circle at 50% 100%, #fcfcfd, #fcfcfd, #fdfdfe, #fdfdfe, #fefefe, #fefefe, #ffffff, #ffffff);
|
2152 |
+
.dark & {
|
2153 |
+
background: radial-gradient(circle at 50% 50%, #272a2d, #242629, #212326, #1e1f22, #1b1c1e, #18181b, #151517, #111113);
|
2154 |
+
}
|
2155 |
+
}
|
2156 |
+
}
|
2157 |
+
|
2158 |
+
main {
|
2159 |
+
overflow: auto;
|
2160 |
+
}
|
2161 |
+
|
2162 |
+
aside {
|
2163 |
+
overflow: auto;
|
2164 |
+
}
|
2165 |
+
|
2166 |
+
.scroll-container {
|
2167 |
+
padding-right: 10px;
|
2168 |
+
}
|
2169 |
+
|
2170 |
+
.question-message {
|
2171 |
+
background-color: #61D790;
|
2172 |
+
color: #2E2F27;
|
2173 |
+
}
|
2174 |
+
|
2175 |
+
@media (min-width: 768px) {
|
2176 |
+
.grid-image-text-columns {
|
2177 |
+
grid-column: span 2 / span 2;
|
2178 |
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
2179 |
+
}
|
2180 |
+
}
|
2181 |
+
|
2182 |
+
.grid-image-column {
|
2183 |
+
grid-row: span 2 / span 2;
|
2184 |
+
display: grid;
|
2185 |
+
grid-template-rows: subgrid;
|
2186 |
+
align-content: flex-start;
|
2187 |
+
}
|
2188 |
+
|
2189 |
+
@media (min-width: 768px) {
|
2190 |
+
.md-grid-text-column {
|
2191 |
+
grid-row: span 2 / span 2;
|
2192 |
+
display: grid;
|
2193 |
+
grid-template-rows: subgrid;
|
2194 |
+
align-content: flex-start;
|
2195 |
+
}
|
2196 |
+
}
|
2197 |
+
|
2198 |
+
#search-input[aria-expanded="true"] {
|
2199 |
+
border-top: 1px solid hsl(var(--input));
|
2200 |
+
border-left: 1px solid hsl(var(--input));
|
2201 |
+
border-right: 1px solid hsl(var(--input));
|
2202 |
+
border-bottom: none;
|
2203 |
+
border-bottom-left-radius: 0;
|
2204 |
+
border-bottom-right-radius: 0;
|
2205 |
+
}
|
2206 |
+
|
2207 |
+
.awesomplete {
|
2208 |
+
width: 100%;
|
2209 |
+
}
|
2210 |
+
|
2211 |
+
.awesomplete > ul > :not([hidden]) ~ :not([hidden]) {
|
2212 |
+
--tw-space-y-reverse: 0;
|
2213 |
+
margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));
|
2214 |
+
margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
|
2215 |
+
}
|
2216 |
+
|
2217 |
+
.awesomplete > ul {
|
2218 |
+
font-size: 0.875rem;
|
2219 |
+
line-height: 1.25rem;
|
2220 |
+
margin: 0;
|
2221 |
+
border-top: none;
|
2222 |
+
border-left: 1px solid hsl(var(--input));
|
2223 |
+
border-right: 1px solid hsl(var(--input));
|
2224 |
+
border-bottom: 1px solid hsl(var(--input));
|
2225 |
+
border-radius: 0 0 calc(var(--radius) - 2px) calc(var(--radius) - 2px);
|
2226 |
+
background: white;
|
2227 |
+
.dark & {
|
2228 |
+
background: hsl(var(--background));
|
2229 |
+
}
|
2230 |
+
box-shadow: none;
|
2231 |
+
text-shadow: none;
|
2232 |
+
}
|
2233 |
+
|
2234 |
+
.awesomplete > ul:before {
|
2235 |
+
display: none;
|
2236 |
+
}
|
2237 |
+
|
2238 |
+
.awesomplete > ul > li:hover {
|
2239 |
+
background-color: #B7E2F1;
|
2240 |
+
color: #2E2F27;
|
2241 |
+
}
|
2242 |
+
|
2243 |
+
.awesomplete > ul > li[aria-selected="true"] {
|
2244 |
+
background-color: #B7E2F1;
|
2245 |
+
color: #2E2F27;
|
2246 |
+
}
|
2247 |
+
|
2248 |
+
.awesomplete mark {
|
2249 |
+
background-color: #61D790;
|
2250 |
+
color: #2E2F27;
|
2251 |
+
}
|
2252 |
+
|
2253 |
+
.awesomplete li:hover mark {
|
2254 |
+
background-color: #61D790;
|
2255 |
+
color: #2E2F27;
|
2256 |
+
}
|
2257 |
+
|
2258 |
+
.awesomplete li[aria-selected="true"] mark {
|
2259 |
+
background-color: #61D790;
|
2260 |
+
color: #2E2F27;
|
2261 |
+
}
|
2262 |
+
|
2263 |
+
:root:has(.data-\[state\=open\]\:no-bg-scroll[data-state="open"]) {
|
2264 |
+
overflow: hidden;
|
2265 |
+
}
|
2266 |
+
|
2267 |
+
:root:has(.group[data-state="open"] .group-data-\[state\=open\]\:no-bg-scroll) {
|
2268 |
+
overflow: hidden;
|
2269 |
+
}
|
2270 |
+
|
2271 |
+
.file\:border-0::file-selector-button {
|
2272 |
+
border-width: 0px;
|
2273 |
+
}
|
2274 |
+
|
2275 |
+
.file\:bg-transparent::file-selector-button {
|
2276 |
+
background-color: transparent;
|
2277 |
+
}
|
2278 |
+
|
2279 |
+
.file\:text-sm::file-selector-button {
|
2280 |
+
font-size: 0.875rem;
|
2281 |
+
line-height: 1.25rem;
|
2282 |
+
}
|
2283 |
+
|
2284 |
+
.file\:font-medium::file-selector-button {
|
2285 |
+
font-weight: 500;
|
2286 |
+
}
|
2287 |
+
|
2288 |
+
.placeholder\:text-muted-foreground::-moz-placeholder {
|
2289 |
+
color: hsl(var(--muted-foreground));
|
2290 |
+
}
|
2291 |
+
|
2292 |
+
.placeholder\:text-muted-foreground::placeholder {
|
2293 |
+
color: hsl(var(--muted-foreground));
|
2294 |
+
}
|
2295 |
+
|
2296 |
+
.focus-within\:border-input:focus-within {
|
2297 |
+
border-color: hsl(var(--input));
|
2298 |
+
}
|
2299 |
+
|
2300 |
+
.focus-within\:outline-none:focus-within {
|
2301 |
+
outline: 2px solid transparent;
|
2302 |
+
outline-offset: 2px;
|
2303 |
+
}
|
2304 |
+
|
2305 |
+
.focus-within\:ring-2:focus-within {
|
2306 |
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
2307 |
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
2308 |
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
2309 |
+
}
|
2310 |
+
|
2311 |
+
.focus-within\:ring-ring:focus-within {
|
2312 |
+
--tw-ring-color: hsl(var(--ring));
|
2313 |
+
}
|
2314 |
+
|
2315 |
+
.focus-within\:ring-offset-2:focus-within {
|
2316 |
+
--tw-ring-offset-width: 2px;
|
2317 |
+
}
|
2318 |
+
|
2319 |
+
.hover\:border-black:hover {
|
2320 |
+
--tw-border-opacity: 1;
|
2321 |
+
border-color: rgb(0 0 0 / var(--tw-border-opacity));
|
2322 |
+
}
|
2323 |
+
|
2324 |
+
.hover\:bg-accent:hover {
|
2325 |
+
background-color: hsl(var(--accent));
|
2326 |
+
}
|
2327 |
+
|
2328 |
+
.hover\:bg-destructive\/80:hover {
|
2329 |
+
background-color: hsl(var(--destructive) / 0.8);
|
2330 |
+
}
|
2331 |
+
|
2332 |
+
.hover\:bg-destructive\/90:hover {
|
2333 |
+
background-color: hsl(var(--destructive) / 0.9);
|
2334 |
+
}
|
2335 |
+
|
2336 |
+
.hover\:bg-muted\/50:hover {
|
2337 |
+
background-color: hsl(var(--muted) / 0.5);
|
2338 |
+
}
|
2339 |
+
|
2340 |
+
.hover\:bg-primary\/80:hover {
|
2341 |
+
background-color: hsl(var(--primary) / 0.8);
|
2342 |
+
}
|
2343 |
+
|
2344 |
+
.hover\:bg-primary\/90:hover {
|
2345 |
+
background-color: hsl(var(--primary) / 0.9);
|
2346 |
+
}
|
2347 |
+
|
2348 |
+
.hover\:bg-secondary\/80:hover {
|
2349 |
+
background-color: hsl(var(--secondary) / 0.8);
|
2350 |
+
}
|
2351 |
+
|
2352 |
+
.hover\:text-accent-foreground:hover {
|
2353 |
+
color: hsl(var(--accent-foreground));
|
2354 |
+
}
|
2355 |
+
|
2356 |
+
.hover\:text-foreground:hover {
|
2357 |
+
color: hsl(var(--foreground));
|
2358 |
+
}
|
2359 |
+
|
2360 |
+
.hover\:underline:hover {
|
2361 |
+
text-decoration-line: underline;
|
2362 |
+
}
|
2363 |
+
|
2364 |
+
.hover\:opacity-100:hover {
|
2365 |
+
opacity: 1;
|
2366 |
+
}
|
2367 |
+
|
2368 |
+
.focus\:bg-accent:focus {
|
2369 |
+
background-color: hsl(var(--accent));
|
2370 |
+
}
|
2371 |
+
|
2372 |
+
.focus\:text-accent-foreground:focus {
|
2373 |
+
color: hsl(var(--accent-foreground));
|
2374 |
+
}
|
2375 |
+
|
2376 |
+
.focus\:opacity-100:focus {
|
2377 |
+
opacity: 1;
|
2378 |
+
}
|
2379 |
+
|
2380 |
+
.focus\:outline-none:focus {
|
2381 |
+
outline: 2px solid transparent;
|
2382 |
+
outline-offset: 2px;
|
2383 |
+
}
|
2384 |
+
|
2385 |
+
.focus\:ring-2:focus {
|
2386 |
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
2387 |
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
2388 |
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
2389 |
+
}
|
2390 |
+
|
2391 |
+
.focus\:ring-ring:focus {
|
2392 |
+
--tw-ring-color: hsl(var(--ring));
|
2393 |
+
}
|
2394 |
+
|
2395 |
+
.focus\:ring-offset-2:focus {
|
2396 |
+
--tw-ring-offset-width: 2px;
|
2397 |
+
}
|
2398 |
+
|
2399 |
+
.focus-visible\:outline-none:focus-visible {
|
2400 |
+
outline: 2px solid transparent;
|
2401 |
+
outline-offset: 2px;
|
2402 |
+
}
|
2403 |
+
|
2404 |
+
.focus-visible\:ring-2:focus-visible {
|
2405 |
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
2406 |
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
2407 |
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
2408 |
+
}
|
2409 |
+
|
2410 |
+
.focus-visible\:ring-ring:focus-visible {
|
2411 |
+
--tw-ring-color: hsl(var(--ring));
|
2412 |
+
}
|
2413 |
+
|
2414 |
+
.focus-visible\:ring-transparent:focus-visible {
|
2415 |
+
--tw-ring-color: transparent;
|
2416 |
+
}
|
2417 |
+
|
2418 |
+
.focus-visible\:ring-offset-2:focus-visible {
|
2419 |
+
--tw-ring-offset-width: 2px;
|
2420 |
+
}
|
2421 |
+
|
2422 |
+
.active\:ring:active {
|
2423 |
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
2424 |
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
2425 |
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
2426 |
+
}
|
2427 |
+
|
2428 |
+
.disabled\:pointer-events-none:disabled {
|
2429 |
+
pointer-events: none;
|
2430 |
+
}
|
2431 |
+
|
2432 |
+
.disabled\:cursor-not-allowed:disabled {
|
2433 |
+
cursor: not-allowed;
|
2434 |
+
}
|
2435 |
+
|
2436 |
+
.disabled\:opacity-50:disabled {
|
2437 |
+
opacity: 0.5;
|
2438 |
+
}
|
2439 |
+
|
2440 |
+
.group:hover .group-hover\:opacity-100 {
|
2441 |
+
opacity: 1;
|
2442 |
+
}
|
2443 |
+
|
2444 |
+
.group.destructive .group-\[\.destructive\]\:text-red-300 {
|
2445 |
+
--tw-text-opacity: 1;
|
2446 |
+
color: rgb(252 165 165 / var(--tw-text-opacity));
|
2447 |
+
}
|
2448 |
+
|
2449 |
+
.group.destructive .group-\[\.destructive\]\:hover\:text-red-50:hover {
|
2450 |
+
--tw-text-opacity: 1;
|
2451 |
+
color: rgb(254 242 242 / var(--tw-text-opacity));
|
2452 |
+
}
|
2453 |
+
|
2454 |
+
.group.destructive .group-\[\.destructive\]\:focus\:ring-red-400:focus {
|
2455 |
+
--tw-ring-opacity: 1;
|
2456 |
+
--tw-ring-color: rgb(248 113 113 / var(--tw-ring-opacity));
|
2457 |
+
}
|
2458 |
+
|
2459 |
+
.group.destructive .group-\[\.destructive\]\:focus\:ring-offset-red-600:focus {
|
2460 |
+
--tw-ring-offset-color: #dc2626;
|
2461 |
+
}
|
2462 |
+
|
2463 |
+
.peer:checked ~ .peer-checked\:bg-primary {
|
2464 |
+
background-color: hsl(var(--primary));
|
2465 |
+
}
|
2466 |
+
|
2467 |
+
.peer:checked ~ .peer-checked\:text-primary-foreground {
|
2468 |
+
color: hsl(var(--primary-foreground));
|
2469 |
+
}
|
2470 |
+
|
2471 |
+
.peer:disabled ~ .peer-disabled\:cursor-not-allowed {
|
2472 |
+
cursor: not-allowed;
|
2473 |
+
}
|
2474 |
+
|
2475 |
+
.peer:disabled ~ .peer-disabled\:opacity-50 {
|
2476 |
+
opacity: 0.5;
|
2477 |
+
}
|
2478 |
+
|
2479 |
+
.peer:disabled ~ .peer-disabled\:opacity-70 {
|
2480 |
+
opacity: 0.7;
|
2481 |
+
}
|
2482 |
+
|
2483 |
+
.data-\[disabled\]\:pointer-events-none[data-disabled] {
|
2484 |
+
pointer-events: none;
|
2485 |
+
}
|
2486 |
+
|
2487 |
+
.data-\[side\=bottom\]\:translate-y-1[data-side="bottom"] {
|
2488 |
+
--tw-translate-y: 0.25rem;
|
2489 |
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
2490 |
+
}
|
2491 |
+
|
2492 |
+
.data-\[side\=left\]\:-translate-x-1[data-side="left"] {
|
2493 |
+
--tw-translate-x: -0.25rem;
|
2494 |
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
2495 |
+
}
|
2496 |
+
|
2497 |
+
.data-\[side\=right\]\:translate-x-1[data-side="right"] {
|
2498 |
+
--tw-translate-x: 0.25rem;
|
2499 |
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
2500 |
+
}
|
2501 |
+
|
2502 |
+
.data-\[side\=top\]\:-translate-y-1[data-side="top"] {
|
2503 |
+
--tw-translate-y: -0.25rem;
|
2504 |
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
2505 |
+
}
|
2506 |
+
|
2507 |
+
.data-\[state\=active\]\:bg-background[data-state="active"] {
|
2508 |
+
background-color: hsl(var(--background));
|
2509 |
+
}
|
2510 |
+
|
2511 |
+
.data-\[state\=selected\]\:bg-muted[data-state="selected"] {
|
2512 |
+
background-color: hsl(var(--muted));
|
2513 |
+
}
|
2514 |
+
|
2515 |
+
.data-\[state\=active\]\:text-foreground[data-state="active"] {
|
2516 |
+
color: hsl(var(--foreground));
|
2517 |
+
}
|
2518 |
+
|
2519 |
+
.data-\[disabled\]\:opacity-50[data-disabled] {
|
2520 |
+
opacity: 0.5;
|
2521 |
+
}
|
2522 |
+
|
2523 |
+
.data-\[state\=active\]\:shadow-sm[data-state="active"] {
|
2524 |
+
--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
2525 |
+
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
|
2526 |
+
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
2527 |
+
}
|
2528 |
+
|
2529 |
+
.data-\[state\=open\]\:animate-in[data-state="open"] {
|
2530 |
+
animation-name: enter;
|
2531 |
+
animation-duration: 150ms;
|
2532 |
+
--tw-enter-opacity: initial;
|
2533 |
+
--tw-enter-scale: initial;
|
2534 |
+
--tw-enter-rotate: initial;
|
2535 |
+
--tw-enter-translate-x: initial;
|
2536 |
+
--tw-enter-translate-y: initial;
|
2537 |
+
}
|
2538 |
+
|
2539 |
+
.data-\[state\=closed\]\:animate-out[data-state="closed"] {
|
2540 |
+
animation-name: exit;
|
2541 |
+
animation-duration: 150ms;
|
2542 |
+
--tw-exit-opacity: initial;
|
2543 |
+
--tw-exit-scale: initial;
|
2544 |
+
--tw-exit-rotate: initial;
|
2545 |
+
--tw-exit-translate-x: initial;
|
2546 |
+
--tw-exit-translate-y: initial;
|
2547 |
+
}
|
2548 |
+
|
2549 |
+
.data-\[state\=closed\]\:fade-out-0[data-state="closed"] {
|
2550 |
+
--tw-exit-opacity: 0;
|
2551 |
+
}
|
2552 |
+
|
2553 |
+
.data-\[state\=open\]\:fade-in-0[data-state="open"] {
|
2554 |
+
--tw-enter-opacity: 0;
|
2555 |
+
}
|
2556 |
+
|
2557 |
+
.data-\[state\=closed\]\:zoom-out-95[data-state="closed"] {
|
2558 |
+
--tw-exit-scale: .95;
|
2559 |
+
}
|
2560 |
+
|
2561 |
+
.data-\[state\=open\]\:zoom-in-95[data-state="open"] {
|
2562 |
+
--tw-enter-scale: .95;
|
2563 |
+
}
|
2564 |
+
|
2565 |
+
.data-\[side\=bottom\]\:slide-in-from-top-2[data-side="bottom"] {
|
2566 |
+
--tw-enter-translate-y: -0.5rem;
|
2567 |
+
}
|
2568 |
+
|
2569 |
+
.data-\[side\=left\]\:slide-in-from-right-2[data-side="left"] {
|
2570 |
+
--tw-enter-translate-x: 0.5rem;
|
2571 |
+
}
|
2572 |
+
|
2573 |
+
.data-\[side\=right\]\:slide-in-from-left-2[data-side="right"] {
|
2574 |
+
--tw-enter-translate-x: -0.5rem;
|
2575 |
+
}
|
2576 |
+
|
2577 |
+
.data-\[side\=top\]\:slide-in-from-bottom-2[data-side="top"] {
|
2578 |
+
--tw-enter-translate-y: 0.5rem;
|
2579 |
+
}
|
2580 |
+
|
2581 |
+
.group[data-checked="true"] .group-data-\[checked\=true\]\:flex {
|
2582 |
+
display: flex;
|
2583 |
+
}
|
2584 |
+
|
2585 |
+
.group[data-state="checked"] .group-data-\[state\=checked\]\:flex {
|
2586 |
+
display: flex;
|
2587 |
+
}
|
2588 |
+
|
2589 |
+
.group[data-state="open"] .group-data-\[state\=open\]\:bg-accent {
|
2590 |
+
background-color: hsl(var(--accent));
|
2591 |
+
}
|
2592 |
+
|
2593 |
+
.group[data-state="open"] .group-data-\[state\=open\]\:text-muted-foreground {
|
2594 |
+
color: hsl(var(--muted-foreground));
|
2595 |
+
}
|
2596 |
+
|
2597 |
+
.group[data-state="closed"] .group-data-\[state\=closed\]\:duration-300 {
|
2598 |
+
transition-duration: 300ms;
|
2599 |
+
}
|
2600 |
+
|
2601 |
+
.group[data-state="open"] .group-data-\[state\=open\]\:duration-500 {
|
2602 |
+
transition-duration: 500ms;
|
2603 |
+
}
|
2604 |
+
|
2605 |
+
.group[data-state="open"] .group-data-\[state\=open\]\:animate-in {
|
2606 |
+
animation-name: enter;
|
2607 |
+
animation-duration: 150ms;
|
2608 |
+
--tw-enter-opacity: initial;
|
2609 |
+
--tw-enter-scale: initial;
|
2610 |
+
--tw-enter-rotate: initial;
|
2611 |
+
--tw-enter-translate-x: initial;
|
2612 |
+
--tw-enter-translate-y: initial;
|
2613 |
+
}
|
2614 |
+
|
2615 |
+
.group[data-state="closed"] .group-data-\[state\=closed\]\:animate-out {
|
2616 |
+
animation-name: exit;
|
2617 |
+
animation-duration: 150ms;
|
2618 |
+
--tw-exit-opacity: initial;
|
2619 |
+
--tw-exit-scale: initial;
|
2620 |
+
--tw-exit-rotate: initial;
|
2621 |
+
--tw-exit-translate-x: initial;
|
2622 |
+
--tw-exit-translate-y: initial;
|
2623 |
+
}
|
2624 |
+
|
2625 |
+
.group[data-state="closed"] .group-data-\[state\=closed\]\:fade-out-0 {
|
2626 |
+
--tw-exit-opacity: 0;
|
2627 |
+
}
|
2628 |
+
|
2629 |
+
.group[data-state="open"] .group-data-\[state\=open\]\:fade-in-0 {
|
2630 |
+
--tw-enter-opacity: 0;
|
2631 |
+
}
|
2632 |
+
|
2633 |
+
.group[data-state="closed"] .group-data-\[state\=closed\]\:zoom-out-95 {
|
2634 |
+
--tw-exit-scale: .95;
|
2635 |
+
}
|
2636 |
+
|
2637 |
+
.group[data-state="open"] .group-data-\[state\=open\]\:zoom-in-95 {
|
2638 |
+
--tw-enter-scale: .95;
|
2639 |
+
}
|
2640 |
+
|
2641 |
+
.group[data-state="closed"] .group-data-\[state\=closed\]\:slide-out-to-bottom {
|
2642 |
+
--tw-exit-translate-y: 100%;
|
2643 |
+
}
|
2644 |
+
|
2645 |
+
.group[data-state="closed"] .group-data-\[state\=closed\]\:slide-out-to-left {
|
2646 |
+
--tw-exit-translate-x: -100%;
|
2647 |
+
}
|
2648 |
+
|
2649 |
+
.group[data-state="closed"] .group-data-\[state\=closed\]\:slide-out-to-left-1\/2 {
|
2650 |
+
--tw-exit-translate-x: -50%;
|
2651 |
+
}
|
2652 |
+
|
2653 |
+
.group[data-state="closed"] .group-data-\[state\=closed\]\:slide-out-to-right {
|
2654 |
+
--tw-exit-translate-x: 100%;
|
2655 |
+
}
|
2656 |
+
|
2657 |
+
.group[data-state="closed"] .group-data-\[state\=closed\]\:slide-out-to-top {
|
2658 |
+
--tw-exit-translate-y: -100%;
|
2659 |
+
}
|
2660 |
+
|
2661 |
+
.group[data-state="closed"] .group-data-\[state\=closed\]\:slide-out-to-top-\[48\%\] {
|
2662 |
+
--tw-exit-translate-y: -48%;
|
2663 |
+
}
|
2664 |
+
|
2665 |
+
.group[data-state="open"] .group-data-\[state\=open\]\:slide-in-from-bottom {
|
2666 |
+
--tw-enter-translate-y: 100%;
|
2667 |
+
}
|
2668 |
+
|
2669 |
+
.group[data-state="open"] .group-data-\[state\=open\]\:slide-in-from-left {
|
2670 |
+
--tw-enter-translate-x: -100%;
|
2671 |
+
}
|
2672 |
+
|
2673 |
+
.group[data-state="open"] .group-data-\[state\=open\]\:slide-in-from-left-1\/2 {
|
2674 |
+
--tw-enter-translate-x: -50%;
|
2675 |
+
}
|
2676 |
+
|
2677 |
+
.group[data-state="open"] .group-data-\[state\=open\]\:slide-in-from-right {
|
2678 |
+
--tw-enter-translate-x: 100%;
|
2679 |
+
}
|
2680 |
+
|
2681 |
+
.group[data-state="open"] .group-data-\[state\=open\]\:slide-in-from-top {
|
2682 |
+
--tw-enter-translate-y: -100%;
|
2683 |
+
}
|
2684 |
+
|
2685 |
+
.group[data-state="open"] .group-data-\[state\=open\]\:slide-in-from-top-\[48\%\] {
|
2686 |
+
--tw-enter-translate-y: -48%;
|
2687 |
+
}
|
2688 |
+
|
2689 |
+
.group[data-state="closed"] .group-data-\[state\=closed\]\:duration-300 {
|
2690 |
+
animation-duration: 300ms;
|
2691 |
+
}
|
2692 |
+
|
2693 |
+
.group[data-state="open"] .group-data-\[state\=open\]\:duration-500 {
|
2694 |
+
animation-duration: 500ms;
|
2695 |
+
}
|
2696 |
+
|
2697 |
+
@media (min-width: 640px) {
|
2698 |
+
.sm\:bottom-0 {
|
2699 |
+
bottom: 0px;
|
2700 |
+
}
|
2701 |
+
|
2702 |
+
.sm\:right-0 {
|
2703 |
+
right: 0px;
|
2704 |
+
}
|
2705 |
+
|
2706 |
+
.sm\:top-auto {
|
2707 |
+
top: auto;
|
2708 |
+
}
|
2709 |
+
|
2710 |
+
.sm\:flex {
|
2711 |
+
display: flex;
|
2712 |
+
}
|
2713 |
+
|
2714 |
+
.sm\:max-w-sm {
|
2715 |
+
max-width: 24rem;
|
2716 |
+
}
|
2717 |
+
|
2718 |
+
.sm\:flex-row {
|
2719 |
+
flex-direction: row;
|
2720 |
+
}
|
2721 |
+
|
2722 |
+
.sm\:flex-col {
|
2723 |
+
flex-direction: column;
|
2724 |
+
}
|
2725 |
+
|
2726 |
+
.sm\:justify-end {
|
2727 |
+
justify-content: flex-end;
|
2728 |
+
}
|
2729 |
+
|
2730 |
+
.sm\:space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
2731 |
+
--tw-space-x-reverse: 0;
|
2732 |
+
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
2733 |
+
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
2734 |
+
}
|
2735 |
+
|
2736 |
+
.sm\:rounded-lg {
|
2737 |
+
border-radius: var(--radius);
|
2738 |
+
}
|
2739 |
+
|
2740 |
+
.sm\:text-left {
|
2741 |
+
text-align: left;
|
2742 |
+
}
|
2743 |
+
}
|
2744 |
+
|
2745 |
+
@media (min-width: 768px) {
|
2746 |
+
.md\:block {
|
2747 |
+
display: block;
|
2748 |
+
}
|
2749 |
+
|
2750 |
+
.md\:max-w-\[420px\] {
|
2751 |
+
max-width: 420px;
|
2752 |
+
}
|
2753 |
+
|
2754 |
+
.md\:grid-cols-\[minmax\(0\2c _45fr\)_minmax\(0\2c _15fr\)\] {
|
2755 |
+
grid-template-columns: minmax(0, 45fr) minmax(0, 15fr);
|
2756 |
+
}
|
2757 |
+
|
2758 |
+
.md\:text-2xl {
|
2759 |
+
font-size: 1.5rem;
|
2760 |
+
line-height: 2rem;
|
2761 |
+
}
|
2762 |
+
|
2763 |
+
.md\:text-7xl {
|
2764 |
+
font-size: 4.5rem;
|
2765 |
+
line-height: 1;
|
2766 |
+
}
|
2767 |
+
|
2768 |
+
.md\:tracking-wide {
|
2769 |
+
letter-spacing: 0.025em;
|
2770 |
+
}
|
2771 |
+
|
2772 |
+
.md\:tracking-wider {
|
2773 |
+
letter-spacing: 0.05em;
|
2774 |
+
}
|
2775 |
+
}
|
2776 |
+
|
2777 |
+
@media (min-width: 1280px) {
|
2778 |
+
.xl\:grid-rows-\[1fr_2fr\] {
|
2779 |
+
grid-template-rows: 1fr 2fr;
|
2780 |
+
}
|
2781 |
+
}
|
2782 |
+
|
2783 |
+
.dark\:block:where(.dark, .dark *) {
|
2784 |
+
display: block;
|
2785 |
+
}
|
2786 |
+
|
2787 |
+
.dark\:flex:where(.dark, .dark *) {
|
2788 |
+
display: flex;
|
2789 |
+
}
|
2790 |
+
|
2791 |
+
.dark\:hidden:where(.dark, .dark *) {
|
2792 |
+
display: none;
|
2793 |
+
}
|
2794 |
+
|
2795 |
+
.dark\:border-destructive:where(.dark, .dark *) {
|
2796 |
+
border-color: hsl(var(--destructive));
|
2797 |
+
}
|
2798 |
+
|
2799 |
+
.dark\:bg-background:where(.dark, .dark *) {
|
2800 |
+
background-color: hsl(var(--background));
|
2801 |
+
}
|
2802 |
+
|
2803 |
+
.dark\:from-\[\#1c2024\]:where(.dark, .dark *) {
|
2804 |
+
--tw-gradient-from: #1c2024 var(--tw-gradient-from-position);
|
2805 |
+
--tw-gradient-to: rgb(28 32 36 / 0) var(--tw-gradient-to-position);
|
2806 |
+
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
|
2807 |
+
}
|
2808 |
+
|
2809 |
+
.dark\:from-white:where(.dark, .dark *) {
|
2810 |
+
--tw-gradient-from: #fff var(--tw-gradient-from-position);
|
2811 |
+
--tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);
|
2812 |
+
--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
|
2813 |
+
}
|
2814 |
+
|
2815 |
+
.dark\:to-slate-300:where(.dark, .dark *) {
|
2816 |
+
--tw-gradient-to: #cbd5e1 var(--tw-gradient-to-position);
|
2817 |
+
}
|
2818 |
+
|
2819 |
+
.dark\:hover\:border-white:hover:where(.dark, .dark *) {
|
2820 |
+
--tw-border-opacity: 1;
|
2821 |
+
border-color: rgb(255 255 255 / var(--tw-border-opacity));
|
2822 |
+
}
|
2823 |
+
|
2824 |
+
.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]) {
|
2825 |
+
padding-right: 0px;
|
2826 |
+
}
|
2827 |
+
|
2828 |
+
.\[\&\>span\]\:line-clamp-1>span {
|
2829 |
+
overflow: hidden;
|
2830 |
+
display: -webkit-box;
|
2831 |
+
-webkit-box-orient: vertical;
|
2832 |
+
-webkit-line-clamp: 1;
|
2833 |
+
}
|
2834 |
+
|
2835 |
+
.\[\&\>span\]\:translate-x-0>span {
|
2836 |
+
--tw-translate-x: 0px;
|
2837 |
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
2838 |
+
}
|
2839 |
+
|
2840 |
+
.peer:checked ~ .peer-checked\:\[\&\>span\]\:flex>span {
|
2841 |
+
display: flex;
|
2842 |
+
}
|
2843 |
+
|
2844 |
+
.peer:checked ~ .peer-checked\:\[\&\>span\]\:translate-x-5>span {
|
2845 |
+
--tw-translate-x: 1.25rem;
|
2846 |
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
2847 |
+
}
|
2848 |
+
|
2849 |
+
.\[\&\>svg\+div\]\:translate-y-\[-3px\]>svg+div {
|
2850 |
+
--tw-translate-y: -3px;
|
2851 |
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
2852 |
+
}
|
2853 |
+
|
2854 |
+
.\[\&\>svg\]\:absolute>svg {
|
2855 |
+
position: absolute;
|
2856 |
+
}
|
2857 |
+
|
2858 |
+
.\[\&\>svg\]\:left-4>svg {
|
2859 |
+
left: 1rem;
|
2860 |
+
}
|
2861 |
+
|
2862 |
+
.\[\&\>svg\]\:top-4>svg {
|
2863 |
+
top: 1rem;
|
2864 |
+
}
|
2865 |
+
|
2866 |
+
.\[\&\>svg\]\:text-destructive>svg {
|
2867 |
+
color: hsl(var(--destructive));
|
2868 |
+
}
|
2869 |
+
|
2870 |
+
.\[\&\>svg\]\:text-foreground>svg {
|
2871 |
+
color: hsl(var(--foreground));
|
2872 |
+
}
|
2873 |
+
|
2874 |
+
.\[\&\>svg\~\*\]\:pl-7>svg~* {
|
2875 |
+
padding-left: 1.75rem;
|
2876 |
+
}
|
2877 |
+
|
2878 |
+
.\[\&\>tr\]\:last\:border-b-0:last-child>tr {
|
2879 |
+
border-bottom-width: 0px;
|
2880 |
+
}
|
2881 |
+
|
2882 |
+
.\[\&_p\]\:leading-relaxed p {
|
2883 |
+
line-height: 1.625;
|
2884 |
+
}
|
2885 |
+
|
2886 |
+
.\[\&_tr\:last-child\]\:border-0 tr:last-child {
|
2887 |
+
border-width: 0px;
|
2888 |
+
}
|
2889 |
+
|
2890 |
+
.\[\&_tr\]\:border-b tr {
|
2891 |
+
border-bottom-width: 1px;
|
2892 |
+
}
|
2893 |
+
|
src/requirements.txt
ADDED
@@ -0,0 +1,540 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# This file was autogenerated by uv via the following command:
|
2 |
+
# uv pip compile pyproject.toml -o src/requirements.txt
|
3 |
+
accelerate==0.34.2
|
4 |
+
# via peft
|
5 |
+
aiohappyeyeballs==2.4.3
|
6 |
+
# via aiohttp
|
7 |
+
aiohttp==3.10.9
|
8 |
+
# via
|
9 |
+
# datasets
|
10 |
+
# fsspec
|
11 |
+
# pyvespa
|
12 |
+
aiosignal==1.3.1
|
13 |
+
# via aiohttp
|
14 |
+
annotated-types==0.7.0
|
15 |
+
# via pydantic
|
16 |
+
anyio==4.6.0
|
17 |
+
# via
|
18 |
+
# httpx
|
19 |
+
# starlette
|
20 |
+
# watchfiles
|
21 |
+
async-timeout==4.0.3
|
22 |
+
# via aiohttp
|
23 |
+
attrs==24.2.0
|
24 |
+
# via aiohttp
|
25 |
+
beautifulsoup4==4.12.3
|
26 |
+
# via python-fasthtml
|
27 |
+
blis==0.7.11
|
28 |
+
# via thinc
|
29 |
+
cachetools==5.5.0
|
30 |
+
# via google-auth
|
31 |
+
catalogue==2.0.10
|
32 |
+
# via
|
33 |
+
# spacy
|
34 |
+
# srsly
|
35 |
+
# thinc
|
36 |
+
certifi==2024.8.30
|
37 |
+
# via
|
38 |
+
# httpcore
|
39 |
+
# httpx
|
40 |
+
# requests
|
41 |
+
cffi==1.17.1
|
42 |
+
# via cryptography
|
43 |
+
charset-normalizer==3.3.2
|
44 |
+
# via requests
|
45 |
+
click==8.1.7
|
46 |
+
# via
|
47 |
+
# typer
|
48 |
+
# uvicorn
|
49 |
+
cloudpathlib==0.20.0
|
50 |
+
# via weasel
|
51 |
+
colpali-engine==0.3.1
|
52 |
+
# via
|
53 |
+
# visual-retrieval-colpali (pyproject.toml)
|
54 |
+
# vidore-benchmark
|
55 |
+
confection==0.1.5
|
56 |
+
# via
|
57 |
+
# thinc
|
58 |
+
# weasel
|
59 |
+
contourpy==1.3.0
|
60 |
+
# via matplotlib
|
61 |
+
cryptography==43.0.1
|
62 |
+
# via pyvespa
|
63 |
+
cycler==0.12.1
|
64 |
+
# via matplotlib
|
65 |
+
cymem==2.0.8
|
66 |
+
# via
|
67 |
+
# preshed
|
68 |
+
# spacy
|
69 |
+
# thinc
|
70 |
+
datasets==2.21.0
|
71 |
+
# via
|
72 |
+
# mteb
|
73 |
+
# vidore-benchmark
|
74 |
+
dill==0.3.8
|
75 |
+
# via
|
76 |
+
# datasets
|
77 |
+
# multiprocess
|
78 |
+
docker==7.1.0
|
79 |
+
# via pyvespa
|
80 |
+
einops==0.8.0
|
81 |
+
# via
|
82 |
+
# visual-retrieval-colpali (pyproject.toml)
|
83 |
+
# vidore-benchmark
|
84 |
+
eval-type-backport==0.2.0
|
85 |
+
# via mteb
|
86 |
+
exceptiongroup==1.2.2
|
87 |
+
# via anyio
|
88 |
+
fastcore==1.7.11
|
89 |
+
# via
|
90 |
+
# fastlite
|
91 |
+
# python-fasthtml
|
92 |
+
# pyvespa
|
93 |
+
# sqlite-minutils
|
94 |
+
fastlite==0.0.11
|
95 |
+
# via python-fasthtml
|
96 |
+
filelock==3.16.1
|
97 |
+
# via
|
98 |
+
# datasets
|
99 |
+
# huggingface-hub
|
100 |
+
# torch
|
101 |
+
# transformers
|
102 |
+
fonttools==4.54.1
|
103 |
+
# via matplotlib
|
104 |
+
frozenlist==1.4.1
|
105 |
+
# via
|
106 |
+
# aiohttp
|
107 |
+
# aiosignal
|
108 |
+
fsspec==2024.6.1
|
109 |
+
# via
|
110 |
+
# datasets
|
111 |
+
# huggingface-hub
|
112 |
+
# torch
|
113 |
+
google-ai-generativelanguage==0.6.10
|
114 |
+
# via google-generativeai
|
115 |
+
google-api-core==2.21.0
|
116 |
+
# via
|
117 |
+
# google-ai-generativelanguage
|
118 |
+
# google-api-python-client
|
119 |
+
# google-generativeai
|
120 |
+
google-api-python-client==2.149.0
|
121 |
+
# via google-generativeai
|
122 |
+
google-auth==2.35.0
|
123 |
+
# via
|
124 |
+
# google-ai-generativelanguage
|
125 |
+
# google-api-core
|
126 |
+
# google-api-python-client
|
127 |
+
# google-auth-httplib2
|
128 |
+
# google-generativeai
|
129 |
+
google-auth-httplib2==0.2.0
|
130 |
+
# via google-api-python-client
|
131 |
+
google-generativeai==0.8.3
|
132 |
+
# via visual-retrieval-colpali (pyproject.toml)
|
133 |
+
googleapis-common-protos==1.65.0
|
134 |
+
# via
|
135 |
+
# google-api-core
|
136 |
+
# grpcio-status
|
137 |
+
gputil==1.4.0
|
138 |
+
# via
|
139 |
+
# colpali-engine
|
140 |
+
# vidore-benchmark
|
141 |
+
grpcio==1.67.0
|
142 |
+
# via
|
143 |
+
# google-api-core
|
144 |
+
# grpcio-status
|
145 |
+
grpcio-status==1.67.0
|
146 |
+
# via google-api-core
|
147 |
+
h11==0.14.0
|
148 |
+
# via
|
149 |
+
# httpcore
|
150 |
+
# uvicorn
|
151 |
+
h2==4.1.0
|
152 |
+
# via httpx
|
153 |
+
hpack==4.0.0
|
154 |
+
# via h2
|
155 |
+
httpcore==1.0.6
|
156 |
+
# via httpx
|
157 |
+
httplib2==0.22.0
|
158 |
+
# via
|
159 |
+
# google-api-python-client
|
160 |
+
# google-auth-httplib2
|
161 |
+
httptools==0.6.1
|
162 |
+
# via uvicorn
|
163 |
+
httpx==0.27.2
|
164 |
+
# via
|
165 |
+
# python-fasthtml
|
166 |
+
# pyvespa
|
167 |
+
huggingface-hub==0.25.1
|
168 |
+
# via
|
169 |
+
# visual-retrieval-colpali (pyproject.toml)
|
170 |
+
# accelerate
|
171 |
+
# datasets
|
172 |
+
# peft
|
173 |
+
# sentence-transformers
|
174 |
+
# tokenizers
|
175 |
+
# transformers
|
176 |
+
hyperframe==6.0.1
|
177 |
+
# via h2
|
178 |
+
idna==3.10
|
179 |
+
# via
|
180 |
+
# anyio
|
181 |
+
# httpx
|
182 |
+
# requests
|
183 |
+
# yarl
|
184 |
+
itsdangerous==2.2.0
|
185 |
+
# via python-fasthtml
|
186 |
+
jinja2==3.1.4
|
187 |
+
# via
|
188 |
+
# pyvespa
|
189 |
+
# spacy
|
190 |
+
# torch
|
191 |
+
joblib==1.4.2
|
192 |
+
# via scikit-learn
|
193 |
+
kiwisolver==1.4.7
|
194 |
+
# via matplotlib
|
195 |
+
langcodes==3.4.1
|
196 |
+
# via spacy
|
197 |
+
language-data==1.2.0
|
198 |
+
# via langcodes
|
199 |
+
loguru==0.7.2
|
200 |
+
# via vidore-benchmark
|
201 |
+
lucide-fasthtml==0.0.9
|
202 |
+
# via shad4fast
|
203 |
+
lxml==5.3.0
|
204 |
+
# via
|
205 |
+
# lucide-fasthtml
|
206 |
+
# pyvespa
|
207 |
+
marisa-trie==1.2.1
|
208 |
+
# via language-data
|
209 |
+
markdown-it-py==3.0.0
|
210 |
+
# via rich
|
211 |
+
markupsafe==2.1.5
|
212 |
+
# via jinja2
|
213 |
+
matplotlib==3.9.2
|
214 |
+
# via
|
215 |
+
# seaborn
|
216 |
+
# vidore-benchmark
|
217 |
+
mdurl==0.1.2
|
218 |
+
# via markdown-it-py
|
219 |
+
mpmath==1.3.0
|
220 |
+
# via sympy
|
221 |
+
mteb==1.15.3
|
222 |
+
# via vidore-benchmark
|
223 |
+
multidict==6.1.0
|
224 |
+
# via
|
225 |
+
# aiohttp
|
226 |
+
# yarl
|
227 |
+
multiprocess==0.70.16
|
228 |
+
# via datasets
|
229 |
+
murmurhash==1.0.10
|
230 |
+
# via
|
231 |
+
# preshed
|
232 |
+
# spacy
|
233 |
+
# thinc
|
234 |
+
networkx==3.3
|
235 |
+
# via torch
|
236 |
+
numpy==1.26.4
|
237 |
+
# via
|
238 |
+
# accelerate
|
239 |
+
# blis
|
240 |
+
# colpali-engine
|
241 |
+
# contourpy
|
242 |
+
# datasets
|
243 |
+
# matplotlib
|
244 |
+
# mteb
|
245 |
+
# pandas
|
246 |
+
# peft
|
247 |
+
# pyarrow
|
248 |
+
# scikit-learn
|
249 |
+
# scipy
|
250 |
+
# seaborn
|
251 |
+
# spacy
|
252 |
+
# thinc
|
253 |
+
# transformers
|
254 |
+
# vidore-benchmark
|
255 |
+
oauthlib==3.2.2
|
256 |
+
# via python-fasthtml
|
257 |
+
packaging==24.1
|
258 |
+
# via
|
259 |
+
# accelerate
|
260 |
+
# datasets
|
261 |
+
# fastcore
|
262 |
+
# huggingface-hub
|
263 |
+
# matplotlib
|
264 |
+
# peft
|
265 |
+
# spacy
|
266 |
+
# thinc
|
267 |
+
# transformers
|
268 |
+
# weasel
|
269 |
+
pandas==2.2.3
|
270 |
+
# via
|
271 |
+
# datasets
|
272 |
+
# seaborn
|
273 |
+
pdf2image==1.17.0
|
274 |
+
# via vidore-benchmark
|
275 |
+
peft==0.11.1
|
276 |
+
# via
|
277 |
+
# colpali-engine
|
278 |
+
# vidore-benchmark
|
279 |
+
pillow==10.4.0
|
280 |
+
# via
|
281 |
+
# colpali-engine
|
282 |
+
# matplotlib
|
283 |
+
# pdf2image
|
284 |
+
# sentence-transformers
|
285 |
+
# vidore-benchmark
|
286 |
+
pip==24.3.1
|
287 |
+
# via visual-retrieval-colpali (pyproject.toml)
|
288 |
+
polars==1.9.0
|
289 |
+
# via mteb
|
290 |
+
preshed==3.0.9
|
291 |
+
# via
|
292 |
+
# spacy
|
293 |
+
# thinc
|
294 |
+
proto-plus==1.24.0
|
295 |
+
# via
|
296 |
+
# google-ai-generativelanguage
|
297 |
+
# google-api-core
|
298 |
+
protobuf==5.28.3
|
299 |
+
# via
|
300 |
+
# google-ai-generativelanguage
|
301 |
+
# google-api-core
|
302 |
+
# google-generativeai
|
303 |
+
# googleapis-common-protos
|
304 |
+
# grpcio-status
|
305 |
+
# proto-plus
|
306 |
+
psutil==6.0.0
|
307 |
+
# via
|
308 |
+
# accelerate
|
309 |
+
# peft
|
310 |
+
pyarrow==17.0.0
|
311 |
+
# via datasets
|
312 |
+
pyasn1==0.6.1
|
313 |
+
# via
|
314 |
+
# pyasn1-modules
|
315 |
+
# rsa
|
316 |
+
pyasn1-modules==0.4.1
|
317 |
+
# via google-auth
|
318 |
+
pycparser==2.22
|
319 |
+
# via cffi
|
320 |
+
pydantic==2.9.2
|
321 |
+
# via
|
322 |
+
# confection
|
323 |
+
# google-generativeai
|
324 |
+
# mteb
|
325 |
+
# spacy
|
326 |
+
# thinc
|
327 |
+
# weasel
|
328 |
+
pydantic-core==2.23.4
|
329 |
+
# via pydantic
|
330 |
+
pygments==2.18.0
|
331 |
+
# via rich
|
332 |
+
pyparsing==3.1.4
|
333 |
+
# via
|
334 |
+
# httplib2
|
335 |
+
# matplotlib
|
336 |
+
pypdf==5.0.1
|
337 |
+
# via visual-retrieval-colpali (pyproject.toml)
|
338 |
+
python-dateutil==2.9.0.post0
|
339 |
+
# via
|
340 |
+
# matplotlib
|
341 |
+
# pandas
|
342 |
+
# python-fasthtml
|
343 |
+
# pyvespa
|
344 |
+
python-dotenv==1.0.1
|
345 |
+
# via
|
346 |
+
# visual-retrieval-colpali (pyproject.toml)
|
347 |
+
# uvicorn
|
348 |
+
# vidore-benchmark
|
349 |
+
python-fasthtml==0.6.9
|
350 |
+
# via
|
351 |
+
# visual-retrieval-colpali (pyproject.toml)
|
352 |
+
# lucide-fasthtml
|
353 |
+
# shad4fast
|
354 |
+
python-multipart==0.0.12
|
355 |
+
# via python-fasthtml
|
356 |
+
pytrec-eval-terrier==0.5.6
|
357 |
+
# via mteb
|
358 |
+
pytz==2024.2
|
359 |
+
# via pandas
|
360 |
+
pyvespa==0.50.0
|
361 |
+
# via visual-retrieval-colpali (pyproject.toml)
|
362 |
+
pyyaml==6.0.2
|
363 |
+
# via
|
364 |
+
# accelerate
|
365 |
+
# datasets
|
366 |
+
# huggingface-hub
|
367 |
+
# peft
|
368 |
+
# transformers
|
369 |
+
# uvicorn
|
370 |
+
regex==2024.9.11
|
371 |
+
# via transformers
|
372 |
+
requests==2.32.3
|
373 |
+
# via
|
374 |
+
# colpali-engine
|
375 |
+
# datasets
|
376 |
+
# docker
|
377 |
+
# google-api-core
|
378 |
+
# huggingface-hub
|
379 |
+
# lucide-fasthtml
|
380 |
+
# mteb
|
381 |
+
# pyvespa
|
382 |
+
# requests-toolbelt
|
383 |
+
# spacy
|
384 |
+
# transformers
|
385 |
+
# weasel
|
386 |
+
requests-toolbelt==1.0.0
|
387 |
+
# via pyvespa
|
388 |
+
rich==13.9.2
|
389 |
+
# via
|
390 |
+
# mteb
|
391 |
+
# typer
|
392 |
+
rsa==4.9
|
393 |
+
# via google-auth
|
394 |
+
safetensors==0.4.5
|
395 |
+
# via
|
396 |
+
# accelerate
|
397 |
+
# peft
|
398 |
+
# transformers
|
399 |
+
scikit-learn==1.5.2
|
400 |
+
# via
|
401 |
+
# mteb
|
402 |
+
# sentence-transformers
|
403 |
+
scipy==1.14.1
|
404 |
+
# via
|
405 |
+
# mteb
|
406 |
+
# scikit-learn
|
407 |
+
# sentence-transformers
|
408 |
+
seaborn==0.13.2
|
409 |
+
# via vidore-benchmark
|
410 |
+
sentence-transformers==3.1.1
|
411 |
+
# via
|
412 |
+
# mteb
|
413 |
+
# vidore-benchmark
|
414 |
+
sentencepiece==0.2.0
|
415 |
+
# via vidore-benchmark
|
416 |
+
setuptools==75.1.0
|
417 |
+
# via
|
418 |
+
# visual-retrieval-colpali (pyproject.toml)
|
419 |
+
# marisa-trie
|
420 |
+
# spacy
|
421 |
+
# thinc
|
422 |
+
shad4fast==1.2.1
|
423 |
+
# via visual-retrieval-colpali (pyproject.toml)
|
424 |
+
shellingham==1.5.4
|
425 |
+
# via typer
|
426 |
+
six==1.16.0
|
427 |
+
# via python-dateutil
|
428 |
+
smart-open==7.0.5
|
429 |
+
# via weasel
|
430 |
+
sniffio==1.3.1
|
431 |
+
# via
|
432 |
+
# anyio
|
433 |
+
# httpx
|
434 |
+
soupsieve==2.6
|
435 |
+
# via beautifulsoup4
|
436 |
+
spacy==3.7.5
|
437 |
+
# via visual-retrieval-colpali (pyproject.toml)
|
438 |
+
spacy-legacy==3.0.12
|
439 |
+
# via spacy
|
440 |
+
spacy-loggers==1.0.5
|
441 |
+
# via spacy
|
442 |
+
sqlite-minutils==3.37.0.post3
|
443 |
+
# via fastlite
|
444 |
+
srsly==2.4.8
|
445 |
+
# via
|
446 |
+
# confection
|
447 |
+
# spacy
|
448 |
+
# thinc
|
449 |
+
# weasel
|
450 |
+
starlette==0.39.2
|
451 |
+
# via python-fasthtml
|
452 |
+
sympy==1.13.3
|
453 |
+
# via torch
|
454 |
+
tenacity==9.0.0
|
455 |
+
# via pyvespa
|
456 |
+
thinc==8.2.5
|
457 |
+
# via spacy
|
458 |
+
threadpoolctl==3.5.0
|
459 |
+
# via scikit-learn
|
460 |
+
tokenizers==0.20.0
|
461 |
+
# via transformers
|
462 |
+
torch==2.4.1
|
463 |
+
# via
|
464 |
+
# visual-retrieval-colpali (pyproject.toml)
|
465 |
+
# accelerate
|
466 |
+
# colpali-engine
|
467 |
+
# mteb
|
468 |
+
# peft
|
469 |
+
# sentence-transformers
|
470 |
+
# vidore-benchmark
|
471 |
+
tqdm==4.66.5
|
472 |
+
# via
|
473 |
+
# datasets
|
474 |
+
# google-generativeai
|
475 |
+
# huggingface-hub
|
476 |
+
# mteb
|
477 |
+
# peft
|
478 |
+
# sentence-transformers
|
479 |
+
# spacy
|
480 |
+
# transformers
|
481 |
+
transformers==4.45.1
|
482 |
+
# via
|
483 |
+
# colpali-engine
|
484 |
+
# peft
|
485 |
+
# sentence-transformers
|
486 |
+
# vidore-benchmark
|
487 |
+
typer==0.12.5
|
488 |
+
# via
|
489 |
+
# spacy
|
490 |
+
# vidore-benchmark
|
491 |
+
# weasel
|
492 |
+
typing-extensions==4.12.2
|
493 |
+
# via
|
494 |
+
# anyio
|
495 |
+
# cloudpathlib
|
496 |
+
# google-generativeai
|
497 |
+
# huggingface-hub
|
498 |
+
# mteb
|
499 |
+
# multidict
|
500 |
+
# pydantic
|
501 |
+
# pydantic-core
|
502 |
+
# pypdf
|
503 |
+
# pyvespa
|
504 |
+
# rich
|
505 |
+
# torch
|
506 |
+
# typer
|
507 |
+
# uvicorn
|
508 |
+
tzdata==2024.2
|
509 |
+
# via pandas
|
510 |
+
uritemplate==4.1.1
|
511 |
+
# via google-api-python-client
|
512 |
+
urllib3==2.2.3
|
513 |
+
# via
|
514 |
+
# docker
|
515 |
+
# requests
|
516 |
+
uvicorn==0.31.0
|
517 |
+
# via python-fasthtml
|
518 |
+
uvloop==0.20.0
|
519 |
+
# via uvicorn
|
520 |
+
vespacli==8.391.23
|
521 |
+
# via visual-retrieval-colpali (pyproject.toml)
|
522 |
+
vidore-benchmark==4.0.0
|
523 |
+
# via visual-retrieval-colpali (pyproject.toml)
|
524 |
+
wasabi==1.1.3
|
525 |
+
# via
|
526 |
+
# spacy
|
527 |
+
# thinc
|
528 |
+
# weasel
|
529 |
+
watchfiles==0.24.0
|
530 |
+
# via uvicorn
|
531 |
+
weasel==0.4.1
|
532 |
+
# via spacy
|
533 |
+
websockets==13.1
|
534 |
+
# via uvicorn
|
535 |
+
wrapt==1.16.0
|
536 |
+
# via smart-open
|
537 |
+
xxhash==3.5.0
|
538 |
+
# via datasets
|
539 |
+
yarl==1.13.1
|
540 |
+
# via aiohttp
|
src/static/img/vespa-colpali.png
ADDED
src/static/js/highlightjs-theme.js
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
(function () {
|
2 |
+
function getPreferredTheme() {
|
3 |
+
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
4 |
+
return 'dark';
|
5 |
+
}
|
6 |
+
return 'light';
|
7 |
+
}
|
8 |
+
|
9 |
+
function syncHighlightTheme() {
|
10 |
+
const link = document.getElementById('highlight-theme');
|
11 |
+
const preferredTheme = getPreferredTheme();
|
12 |
+
link.href = preferredTheme === 'dark' ?
|
13 |
+
'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.4.0/styles/github-dark.min.css' :
|
14 |
+
'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.4.0/styles/github.min.css';
|
15 |
+
}
|
16 |
+
|
17 |
+
// Apply the correct theme immediately
|
18 |
+
syncHighlightTheme();
|
19 |
+
|
20 |
+
// Observe changes in the 'dark' class on the <html> element
|
21 |
+
const observer = new MutationObserver(syncHighlightTheme);
|
22 |
+
observer.observe(document.documentElement, {attributes: true, attributeFilter: ['class']});
|
23 |
+
})();
|
src/tailwind.config.js
ADDED
@@ -0,0 +1,243 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
function filterDefault(values) {
|
2 |
+
return Object.fromEntries(
|
3 |
+
Object.entries(values).filter(([key]) => key !== "DEFAULT"),
|
4 |
+
);
|
5 |
+
}
|
6 |
+
|
7 |
+
/** @type {import('tailwindcss').Config} */
|
8 |
+
export default {
|
9 |
+
darkMode: ["selector"],
|
10 |
+
content: [
|
11 |
+
"./**/*.py",
|
12 |
+
"./.venv/lib/python3.12/site-packages/shad4fast/**/*.{py,js}",
|
13 |
+
],
|
14 |
+
theme: {
|
15 |
+
container: {
|
16 |
+
center: true,
|
17 |
+
padding: "2rem",
|
18 |
+
screens: {
|
19 |
+
"2xl": "1400px",
|
20 |
+
},
|
21 |
+
},
|
22 |
+
extend: {
|
23 |
+
animation: {
|
24 |
+
"accordion-down": "accordion-down 0.2s ease-out",
|
25 |
+
"accordion-up": "accordion-up 0.2s ease-out",
|
26 |
+
},
|
27 |
+
animationDelay: ({theme}) => ({
|
28 |
+
...theme("transitionDelay"),
|
29 |
+
}),
|
30 |
+
animationDuration: ({theme}) => ({
|
31 |
+
0: "0ms",
|
32 |
+
...theme("transitionDuration"),
|
33 |
+
}),
|
34 |
+
animationTimingFunction: ({theme}) => ({
|
35 |
+
...theme("transitionTimingFunction"),
|
36 |
+
}),
|
37 |
+
animationFillMode: {
|
38 |
+
none: "none",
|
39 |
+
forwards: "forwards",
|
40 |
+
backwards: "backwards",
|
41 |
+
both: "both",
|
42 |
+
},
|
43 |
+
animationDirection: {
|
44 |
+
normal: "normal",
|
45 |
+
reverse: "reverse",
|
46 |
+
alternate: "alternate",
|
47 |
+
"alternate-reverse": "alternate-reverse",
|
48 |
+
},
|
49 |
+
animationOpacity: ({theme}) => ({
|
50 |
+
DEFAULT: 0,
|
51 |
+
...theme("opacity"),
|
52 |
+
}),
|
53 |
+
animationTranslate: ({theme}) => ({
|
54 |
+
DEFAULT: "100%",
|
55 |
+
...theme("translate"),
|
56 |
+
}),
|
57 |
+
animationScale: ({theme}) => ({
|
58 |
+
DEFAULT: 0,
|
59 |
+
...theme("scale"),
|
60 |
+
}),
|
61 |
+
animationRotate: ({theme}) => ({
|
62 |
+
DEFAULT: "30deg",
|
63 |
+
...theme("rotate"),
|
64 |
+
}),
|
65 |
+
animationRepeat: {
|
66 |
+
0: "0",
|
67 |
+
1: "1",
|
68 |
+
infinite: "infinite",
|
69 |
+
},
|
70 |
+
keyframes: {
|
71 |
+
enter: {
|
72 |
+
from: {
|
73 |
+
opacity: "var(--tw-enter-opacity, 1)",
|
74 |
+
transform:
|
75 |
+
"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))",
|
76 |
+
},
|
77 |
+
},
|
78 |
+
exit: {
|
79 |
+
to: {
|
80 |
+
opacity: "var(--tw-exit-opacity, 1)",
|
81 |
+
transform:
|
82 |
+
"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))",
|
83 |
+
},
|
84 |
+
},
|
85 |
+
},
|
86 |
+
colors: {
|
87 |
+
border: "hsl(var(--border))",
|
88 |
+
input: "hsl(var(--input))",
|
89 |
+
ring: "hsl(var(--ring))",
|
90 |
+
background: "hsl(var(--background))",
|
91 |
+
foreground: "hsl(var(--foreground))",
|
92 |
+
primary: {
|
93 |
+
DEFAULT: "hsl(var(--primary))",
|
94 |
+
foreground: "hsl(var(--primary-foreground))",
|
95 |
+
},
|
96 |
+
secondary: {
|
97 |
+
DEFAULT: "hsl(var(--secondary))",
|
98 |
+
foreground: "hsl(var(--secondary-foreground))",
|
99 |
+
},
|
100 |
+
destructive: {
|
101 |
+
DEFAULT: "hsl(var(--destructive))",
|
102 |
+
foreground: "hsl(var(--destructive-foreground))",
|
103 |
+
},
|
104 |
+
muted: {
|
105 |
+
DEFAULT: "hsl(var(--muted))",
|
106 |
+
foreground: "hsl(var(--muted-foreground))",
|
107 |
+
},
|
108 |
+
accent: {
|
109 |
+
DEFAULT: "hsl(var(--accent))",
|
110 |
+
foreground: "hsl(var(--accent-foreground))",
|
111 |
+
},
|
112 |
+
popover: {
|
113 |
+
DEFAULT: "hsl(var(--popover))",
|
114 |
+
foreground: "hsl(var(--popover-foreground))",
|
115 |
+
},
|
116 |
+
card: {
|
117 |
+
DEFAULT: "hsl(var(--card))",
|
118 |
+
foreground: "hsl(var(--card-foreground))",
|
119 |
+
},
|
120 |
+
},
|
121 |
+
borderRadius: {
|
122 |
+
lg: `var(--radius)`,
|
123 |
+
md: `calc(var(--radius) - 2px)`,
|
124 |
+
sm: "calc(var(--radius) - 4px)",
|
125 |
+
},
|
126 |
+
},
|
127 |
+
},
|
128 |
+
plugins: [
|
129 |
+
function ({addUtilities, matchUtilities, theme}) {
|
130 |
+
addUtilities({
|
131 |
+
"@keyframes enter": theme("keyframes.enter"),
|
132 |
+
"@keyframes exit": theme("keyframes.exit"),
|
133 |
+
".animate-in": {
|
134 |
+
animationName: "enter",
|
135 |
+
animationDuration: theme("animationDuration.DEFAULT"),
|
136 |
+
"--tw-enter-opacity": "initial",
|
137 |
+
"--tw-enter-scale": "initial",
|
138 |
+
"--tw-enter-rotate": "initial",
|
139 |
+
"--tw-enter-translate-x": "initial",
|
140 |
+
"--tw-enter-translate-y": "initial",
|
141 |
+
},
|
142 |
+
".animate-out": {
|
143 |
+
animationName: "exit",
|
144 |
+
animationDuration: theme("animationDuration.DEFAULT"),
|
145 |
+
"--tw-exit-opacity": "initial",
|
146 |
+
"--tw-exit-scale": "initial",
|
147 |
+
"--tw-exit-rotate": "initial",
|
148 |
+
"--tw-exit-translate-x": "initial",
|
149 |
+
"--tw-exit-translate-y": "initial",
|
150 |
+
},
|
151 |
+
});
|
152 |
+
|
153 |
+
matchUtilities(
|
154 |
+
{
|
155 |
+
"fade-in": (value) => ({"--tw-enter-opacity": value}),
|
156 |
+
"fade-out": (value) => ({"--tw-exit-opacity": value}),
|
157 |
+
},
|
158 |
+
{values: theme("animationOpacity")},
|
159 |
+
);
|
160 |
+
|
161 |
+
matchUtilities(
|
162 |
+
{
|
163 |
+
"zoom-in": (value) => ({"--tw-enter-scale": value}),
|
164 |
+
"zoom-out": (value) => ({"--tw-exit-scale": value}),
|
165 |
+
},
|
166 |
+
{values: theme("animationScale")},
|
167 |
+
);
|
168 |
+
|
169 |
+
matchUtilities(
|
170 |
+
{
|
171 |
+
"spin-in": (value) => ({"--tw-enter-rotate": value}),
|
172 |
+
"spin-out": (value) => ({"--tw-exit-rotate": value}),
|
173 |
+
},
|
174 |
+
{values: theme("animationRotate")},
|
175 |
+
);
|
176 |
+
|
177 |
+
matchUtilities(
|
178 |
+
{
|
179 |
+
"slide-in-from-top": (value) => ({
|
180 |
+
"--tw-enter-translate-y": `-${value}`,
|
181 |
+
}),
|
182 |
+
"slide-in-from-bottom": (value) => ({
|
183 |
+
"--tw-enter-translate-y": value,
|
184 |
+
}),
|
185 |
+
"slide-in-from-left": (value) => ({
|
186 |
+
"--tw-enter-translate-x": `-${value}`,
|
187 |
+
}),
|
188 |
+
"slide-in-from-right": (value) => ({
|
189 |
+
"--tw-enter-translate-x": value,
|
190 |
+
}),
|
191 |
+
"slide-out-to-top": (value) => ({
|
192 |
+
"--tw-exit-translate-y": `-${value}`,
|
193 |
+
}),
|
194 |
+
"slide-out-to-bottom": (value) => ({
|
195 |
+
"--tw-exit-translate-y": value,
|
196 |
+
}),
|
197 |
+
"slide-out-to-left": (value) => ({
|
198 |
+
"--tw-exit-translate-x": `-${value}`,
|
199 |
+
}),
|
200 |
+
"slide-out-to-right": (value) => ({
|
201 |
+
"--tw-exit-translate-x": value,
|
202 |
+
}),
|
203 |
+
},
|
204 |
+
{values: theme("animationTranslate")},
|
205 |
+
);
|
206 |
+
|
207 |
+
matchUtilities(
|
208 |
+
{duration: (value) => ({animationDuration: value})},
|
209 |
+
{values: filterDefault(theme("animationDuration"))},
|
210 |
+
);
|
211 |
+
|
212 |
+
matchUtilities(
|
213 |
+
{delay: (value) => ({animationDelay: value})},
|
214 |
+
{values: theme("animationDelay")},
|
215 |
+
);
|
216 |
+
|
217 |
+
matchUtilities(
|
218 |
+
{ease: (value) => ({animationTimingFunction: value})},
|
219 |
+
{values: filterDefault(theme("animationTimingFunction"))},
|
220 |
+
);
|
221 |
+
|
222 |
+
addUtilities({
|
223 |
+
".running": {animationPlayState: "running"},
|
224 |
+
".paused": {animationPlayState: "paused"},
|
225 |
+
});
|
226 |
+
|
227 |
+
matchUtilities(
|
228 |
+
{"fill-mode": (value) => ({animationFillMode: value})},
|
229 |
+
{values: theme("animationFillMode")},
|
230 |
+
);
|
231 |
+
|
232 |
+
matchUtilities(
|
233 |
+
{direction: (value) => ({animationDirection: value})},
|
234 |
+
{values: theme("animationDirection")},
|
235 |
+
);
|
236 |
+
|
237 |
+
matchUtilities(
|
238 |
+
{repeat: (value) => ({animationIterationCount: value})},
|
239 |
+
{values: theme("animationRepeat")},
|
240 |
+
);
|
241 |
+
},
|
242 |
+
],
|
243 |
+
};
|
src/tailwindcss
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:327703a4646081906e11d116ff4e8e43076466c3d269282bbe612555b9fe0c58
|
3 |
+
size 47351504
|
uv.lock
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
version = 1
|
2 |
-
requires-python = ">=3.10"
|
3 |
resolution-markers = [
|
4 |
"python_full_version < '3.11'",
|
5 |
"python_full_version == '3.11.*'",
|
6 |
-
"python_full_version
|
7 |
-
"python_full_version
|
8 |
]
|
9 |
|
10 |
[[package]]
|
@@ -3693,7 +3693,7 @@ dependencies = [
|
|
3693 |
{ name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" },
|
3694 |
{ name = "setuptools", marker = "python_full_version >= '3.12'" },
|
3695 |
{ name = "sympy" },
|
3696 |
-
{ name = "triton", marker = "
|
3697 |
{ name = "typing-extensions" },
|
3698 |
]
|
3699 |
wheels = [
|
@@ -3777,7 +3777,7 @@ name = "triton"
|
|
3777 |
version = "3.1.0"
|
3778 |
source = { registry = "https://pypi.org/simple" }
|
3779 |
dependencies = [
|
3780 |
-
{ name = "filelock"
|
3781 |
]
|
3782 |
wheels = [
|
3783 |
{ url = "https://files.pythonhosted.org/packages/98/29/69aa56dc0b2eb2602b553881e34243475ea2afd9699be042316842788ff5/triton-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b0dd10a925263abbe9fa37dcde67a5e9b2383fc269fdf59f5657cac38c5d1d8", size = 209460013 },
|
|
|
1 |
version = 1
|
2 |
+
requires-python = ">=3.10, <3.13"
|
3 |
resolution-markers = [
|
4 |
"python_full_version < '3.11'",
|
5 |
"python_full_version == '3.11.*'",
|
6 |
+
"python_full_version >= '3.12'",
|
7 |
+
"python_full_version < '0'",
|
8 |
]
|
9 |
|
10 |
[[package]]
|
|
|
3693 |
{ name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" },
|
3694 |
{ name = "setuptools", marker = "python_full_version >= '3.12'" },
|
3695 |
{ name = "sympy" },
|
3696 |
+
{ name = "triton", marker = "platform_machine == 'x86_64' and platform_system == 'Linux'" },
|
3697 |
{ name = "typing-extensions" },
|
3698 |
]
|
3699 |
wheels = [
|
|
|
3777 |
version = "3.1.0"
|
3778 |
source = { registry = "https://pypi.org/simple" }
|
3779 |
dependencies = [
|
3780 |
+
{ name = "filelock" },
|
3781 |
]
|
3782 |
wheels = [
|
3783 |
{ url = "https://files.pythonhosted.org/packages/98/29/69aa56dc0b2eb2602b553881e34243475ea2afd9699be042316842788ff5/triton-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b0dd10a925263abbe9fa37dcde67a5e9b2383fc269fdf59f5657cac38c5d1d8", size = 209460013 },
|