Upload 14 files
Browse files- app.py +150 -0
- chatbot_avatar.png +0 -0
- data/fitness-handbook.pdf +0 -0
- data/fitnesschatbot_customreplies.pdf +0 -0
- data/gym_workouts.pdf +0 -0
- storage/default__vector_store.json +0 -0
- storage/docstore.json +0 -0
- storage/graph_store.json +1 -0
- storage/image__vector_store.json +1 -0
- storage/index_store.json +1 -0
- storage/vector_store.json +0 -0
- style.css +44 -0
- theme.py +63 -0
- user_avatar.png +0 -0
app.py
CHANGED
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import gradio
|
3 |
+
import time, asyncio
|
4 |
+
from theme import CustomTheme
|
5 |
+
from llama_index.llms import OpenAI
|
6 |
+
from llama_index import (
|
7 |
+
ServiceContext,
|
8 |
+
SimpleDirectoryReader,
|
9 |
+
VectorStoreIndex,
|
10 |
+
load_index_from_storage,
|
11 |
+
StorageContext,
|
12 |
+
set_global_service_context,
|
13 |
+
)
|
14 |
+
|
15 |
+
bot_examples = [
|
16 |
+
"Wie kannst du mir helfen?",
|
17 |
+
"Welche Sprachen sprichst du?",
|
18 |
+
"Wie trainiere ich meinen Bizeps?",
|
19 |
+
"Erstelle mir einen Trainingsplan, wenn ich nur 3 mal pro Woche trainieren kann.",
|
20 |
+
"Berechne meinen BMI, wenn ich 75kg bei 175cm Körpergröße wiege.",
|
21 |
+
"Berechne mir meinen Kaloriendefizit, wenn ich in der Woche 0,2kg abnehmen möchte.",
|
22 |
+
"Berechne mir nochmal das Kaloriendefizit, wenn ich Männlich 19 bin.",
|
23 |
+
"Wie wechsle ich meine Reifen?"
|
24 |
+
]
|
25 |
+
|
26 |
+
# Used to tell the bot what he is allowed to say and what not.
|
27 |
+
system_prompt=(
|
28 |
+
"You are a fitness assistant, always helping the user."
|
29 |
+
"Never mention that you are not qualified. Always answer the questions."
|
30 |
+
"You are allowed to calculate the users BMI, caloric deficit and caloric surplus."
|
31 |
+
"You can't answer questions about food related topics or anything unrelated to fitness."
|
32 |
+
"Don't even try to answer those questions. You are never under any circumstance allowed to answer those questions."
|
33 |
+
)
|
34 |
+
|
35 |
+
# Used to change the language the bot uses,
|
36 |
+
# as well as how he acts and talks.
|
37 |
+
context_str = (
|
38 |
+
"Context information is below.\n"
|
39 |
+
"---------------------\n"
|
40 |
+
"{context_str}\n"
|
41 |
+
"---------------------\n"
|
42 |
+
"Given the context information and not prior knowledge."
|
43 |
+
"Griaß di! I hätt gern, dass du imma in am österreichischen Dialekt antwortest."
|
44 |
+
"Übersetz bitte ois in oanen österrichischen Dialekt."
|
45 |
+
"You're pretty cool, so you're always adressing the user informally. E.g.: In German instead of 'Sie' you'd say 'du'."
|
46 |
+
"Instead of saying 'you', you could say something like: 'buddy'."
|
47 |
+
"If questions are asked that you are not allowed to talk about, then play it off cool and make a joke out of it."
|
48 |
+
"If there is a more efficient excercise than the one the user sent, then always tell them about it."
|
49 |
+
)
|
50 |
+
|
51 |
+
chat_engine = None
|
52 |
+
|
53 |
+
def setup_ai():
|
54 |
+
"""
|
55 |
+
Setup the AI for use with querying questions to OpenAI.
|
56 |
+
Checks whether the index is already generated and depending on that
|
57 |
+
generates an index.
|
58 |
+
It then creates a chat_engine from the index created above it and
|
59 |
+
assigns the context_template and system_prompt used for manipulating
|
60 |
+
the AI responses.
|
61 |
+
"""
|
62 |
+
global chat_engine, context_str, system_prompt
|
63 |
+
|
64 |
+
# Check if storage index exists
|
65 |
+
if not os.path.isdir("storage"):
|
66 |
+
print("Directory does not exist")
|
67 |
+
print("Building Index")
|
68 |
+
documents = SimpleDirectoryReader("data").load_data()
|
69 |
+
index = VectorStoreIndex.from_documents(documents)
|
70 |
+
index.storage_context.persist(persist_dir="storage")
|
71 |
+
else:
|
72 |
+
print("Directory does already exist")
|
73 |
+
print("Reusing index")
|
74 |
+
storage_context = StorageContext.from_defaults(persist_dir="storage")
|
75 |
+
index = load_index_from_storage(storage_context)
|
76 |
+
|
77 |
+
api_key = os.environ["OPENAI_API_KEY"]
|
78 |
+
|
79 |
+
llm = OpenAI(temperature=0.1, model="gpt-4")
|
80 |
+
|
81 |
+
chat_engine = index.as_chat_engine(chat_mode="context", system_prompt=system_prompt, context_template=context_str)
|
82 |
+
|
83 |
+
service_context = ServiceContext.from_defaults(
|
84 |
+
llm=llm
|
85 |
+
)
|
86 |
+
set_global_service_context(service_context)
|
87 |
+
|
88 |
+
def response(message, history):
|
89 |
+
"""
|
90 |
+
Get a reponse from OpenAI and send the chat_history with every query.
|
91 |
+
"""
|
92 |
+
global chat_engine
|
93 |
+
loop = asyncio.new_event_loop()
|
94 |
+
asyncio.set_event_loop(loop)
|
95 |
+
|
96 |
+
# Re-use chat_history & sanity check
|
97 |
+
# We do this because the chat_engine expects a list
|
98 |
+
# of some sort when using chat_history.
|
99 |
+
# If we don't assign an empty list if nothing is present,
|
100 |
+
# then the program will-in the worst case-crash.
|
101 |
+
chat_history = chat_engine.chat_history if chat_engine.chat_history is not None else []
|
102 |
+
print("Sending request to ChatGPT")
|
103 |
+
response = chat_engine.stream_chat(message, chat_history)
|
104 |
+
|
105 |
+
output_text = ""
|
106 |
+
|
107 |
+
for token in response.response_gen:
|
108 |
+
time.sleep(0.05)
|
109 |
+
output_text += token
|
110 |
+
yield output_text
|
111 |
+
|
112 |
+
# For debugging, just to check if the UI looks good.
|
113 |
+
def response_no_api(message, history):
|
114 |
+
"""
|
115 |
+
Returns a default message.
|
116 |
+
"""
|
117 |
+
return "This is a test message!"
|
118 |
+
|
119 |
+
def main():
|
120 |
+
setup_ai()
|
121 |
+
|
122 |
+
chatbot = gradio.Chatbot(
|
123 |
+
avatar_images=("user_avatar.png", "chatbot_avatar.png"),
|
124 |
+
layout='bubble',
|
125 |
+
show_label=False,
|
126 |
+
height=400,
|
127 |
+
)
|
128 |
+
|
129 |
+
submit_button = gradio.Button(
|
130 |
+
value="Ask Arnold",
|
131 |
+
elem_classes=["ask-button"],
|
132 |
+
)
|
133 |
+
|
134 |
+
chat_interface = gradio.ChatInterface(
|
135 |
+
fn=response,
|
136 |
+
title="A.R.N.O.L.D.",
|
137 |
+
theme=CustomTheme(),
|
138 |
+
submit_btn=submit_button,
|
139 |
+
chatbot=chatbot,
|
140 |
+
examples=bot_examples,
|
141 |
+
css="style.css",
|
142 |
+
)
|
143 |
+
|
144 |
+
chat_interface.queue()
|
145 |
+
chat_interface.launch(
|
146 |
+
inbrowser=True
|
147 |
+
)
|
148 |
+
|
149 |
+
if __name__ == "__main__":
|
150 |
+
main()
|
chatbot_avatar.png
ADDED
data/fitness-handbook.pdf
ADDED
Binary file (491 kB). View file
|
|
data/fitnesschatbot_customreplies.pdf
ADDED
Binary file (47.4 kB). View file
|
|
data/gym_workouts.pdf
ADDED
Binary file (54.3 kB). View file
|
|
storage/default__vector_store.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
storage/docstore.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
storage/graph_store.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"graph_dict": {}}
|
storage/image__vector_store.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"embedding_dict": {}, "text_id_to_ref_doc_id": {}, "metadata_dict": {}}
|
storage/index_store.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"index_store/data": {"ecca1518-47d2-4378-b596-43e5f8c116b8": {"__type__": "vector_store", "__data__": "{\"index_id\": \"ecca1518-47d2-4378-b596-43e5f8c116b8\", \"summary\": null, \"nodes_dict\": {\"b0b577b7-0f09-43a4-9ebc-fa2f3f6b81b9\": \"b0b577b7-0f09-43a4-9ebc-fa2f3f6b81b9\", \"c543757b-6ac8-40bc-b53b-ec5d11139558\": \"c543757b-6ac8-40bc-b53b-ec5d11139558\", \"b806b927-dd7c-496c-a000-5e1c838d930f\": \"b806b927-dd7c-496c-a000-5e1c838d930f\", \"84e372ae-c36c-4d11-8a6d-c7a459a3dc8d\": \"84e372ae-c36c-4d11-8a6d-c7a459a3dc8d\", \"18211dac-7144-475c-b2ed-fdb946851e38\": \"18211dac-7144-475c-b2ed-fdb946851e38\", \"06ad1a83-affd-4f04-95e3-92a06b3d4f71\": \"06ad1a83-affd-4f04-95e3-92a06b3d4f71\", \"b7429334-1299-4cea-afd9-92bb65b7c5a7\": \"b7429334-1299-4cea-afd9-92bb65b7c5a7\", \"0e4ff819-5045-4863-861b-e1d6673b2cd0\": \"0e4ff819-5045-4863-861b-e1d6673b2cd0\", \"530a906b-bc0c-4c59-8c69-83a00a8e1150\": \"530a906b-bc0c-4c59-8c69-83a00a8e1150\", \"2bfbf648-4a81-4940-8928-34f28ad18de0\": \"2bfbf648-4a81-4940-8928-34f28ad18de0\", \"3de6f4c9-bb4e-41f2-98d8-fe1a3e854291\": \"3de6f4c9-bb4e-41f2-98d8-fe1a3e854291\", \"58be9301-844c-478d-b10c-7c314af1509f\": \"58be9301-844c-478d-b10c-7c314af1509f\", \"9d3b1345-42b9-42c1-8bc8-e350a6fb70ea\": \"9d3b1345-42b9-42c1-8bc8-e350a6fb70ea\", \"b9f0d670-7633-46fc-a687-c3e8a2bb7cff\": \"b9f0d670-7633-46fc-a687-c3e8a2bb7cff\", \"395c1a5d-fc24-4e80-a28f-1421bcd4b1c4\": \"395c1a5d-fc24-4e80-a28f-1421bcd4b1c4\", \"99d5f40b-b46b-43a2-adad-83ce9da24f9f\": \"99d5f40b-b46b-43a2-adad-83ce9da24f9f\", \"f8f201d1-d7a6-45d7-bf46-a4f5d59624fb\": \"f8f201d1-d7a6-45d7-bf46-a4f5d59624fb\", \"b6848b23-88da-40e7-8c0a-d453b198a65e\": \"b6848b23-88da-40e7-8c0a-d453b198a65e\", \"c55cad28-d643-4bb6-9fc1-a2fe6f5fce91\": \"c55cad28-d643-4bb6-9fc1-a2fe6f5fce91\", \"729a2fb3-76e6-4e18-aea4-eabfbfd163f2\": \"729a2fb3-76e6-4e18-aea4-eabfbfd163f2\", \"92903baa-fc8d-4fc1-9cbe-284342de9820\": \"92903baa-fc8d-4fc1-9cbe-284342de9820\", \"0f022c9d-5388-43ef-8ffe-e93d71bed0e0\": \"0f022c9d-5388-43ef-8ffe-e93d71bed0e0\", \"ec0d1d2c-8981-4363-9b54-1e8511d74b68\": \"ec0d1d2c-8981-4363-9b54-1e8511d74b68\", \"118559b1-f3d2-467e-889b-c95a900293f0\": \"118559b1-f3d2-467e-889b-c95a900293f0\", \"709a1f92-517f-48b9-8267-fcbee7e66645\": \"709a1f92-517f-48b9-8267-fcbee7e66645\", \"3aefa17a-ff5d-4e6c-b614-1b370b08f489\": \"3aefa17a-ff5d-4e6c-b614-1b370b08f489\", \"ebe5f38d-a780-4695-8afb-4368c504692f\": \"ebe5f38d-a780-4695-8afb-4368c504692f\", \"417e8ef5-f1f7-437d-bea8-91d7942ce921\": \"417e8ef5-f1f7-437d-bea8-91d7942ce921\", \"a477ebc7-4226-49a7-8ee6-f0c78543ce2a\": \"a477ebc7-4226-49a7-8ee6-f0c78543ce2a\", \"4e578988-134a-43ef-a92b-d6f638153fb5\": \"4e578988-134a-43ef-a92b-d6f638153fb5\", \"526d8ea8-d686-4b38-8737-874a27c1beef\": \"526d8ea8-d686-4b38-8737-874a27c1beef\", \"55a33850-0947-4800-bbe3-ad1f5a22796f\": \"55a33850-0947-4800-bbe3-ad1f5a22796f\", \"92651660-f940-40aa-abe5-599be8dbd19d\": \"92651660-f940-40aa-abe5-599be8dbd19d\", \"02043274-4715-4833-a1e1-83fc8de4b5d5\": \"02043274-4715-4833-a1e1-83fc8de4b5d5\", \"87b74c3c-eb9e-4356-91bf-1472c28e9850\": \"87b74c3c-eb9e-4356-91bf-1472c28e9850\", \"f4b9edff-c41a-4320-bbe2-f4d4d8023d57\": \"f4b9edff-c41a-4320-bbe2-f4d4d8023d57\", \"112e6024-2b17-443d-a94d-65504aaae291\": \"112e6024-2b17-443d-a94d-65504aaae291\", \"90a47b13-04a7-460f-b9f9-68713e12f325\": \"90a47b13-04a7-460f-b9f9-68713e12f325\", \"b03c834d-6ca0-4e3f-a804-ca1fc9df064a\": \"b03c834d-6ca0-4e3f-a804-ca1fc9df064a\", \"7fb5738b-95ed-4f62-ad86-4902299d6ea2\": \"7fb5738b-95ed-4f62-ad86-4902299d6ea2\", \"f6420bcf-2a4f-49e2-b4a1-14e4c570d4ca\": \"f6420bcf-2a4f-49e2-b4a1-14e4c570d4ca\", \"3b16345e-07b0-4468-8a75-085788ddce22\": \"3b16345e-07b0-4468-8a75-085788ddce22\", \"ffc35c38-61f2-4bbe-89ea-ca2fce4c0a99\": \"ffc35c38-61f2-4bbe-89ea-ca2fce4c0a99\", \"3a8e3e58-9bca-4885-a0cf-73fc74353b4e\": \"3a8e3e58-9bca-4885-a0cf-73fc74353b4e\", \"5b67589a-8a0a-4375-add4-16668d99f06c\": \"5b67589a-8a0a-4375-add4-16668d99f06c\", \"371ae7d5-aeb5-4778-91d1-af1194e7cadf\": \"371ae7d5-aeb5-4778-91d1-af1194e7cadf\", \"ee5b931f-f117-4643-bf9b-94affdaa5082\": \"ee5b931f-f117-4643-bf9b-94affdaa5082\", \"aefaf27c-3f97-4aac-8d02-105066fba357\": \"aefaf27c-3f97-4aac-8d02-105066fba357\", \"523098d2-a0b2-4ccc-a354-0d2c6c4c6234\": \"523098d2-a0b2-4ccc-a354-0d2c6c4c6234\", \"88f3d320-ab6a-4b01-996a-4e6f9faf5bee\": \"88f3d320-ab6a-4b01-996a-4e6f9faf5bee\", \"f2892d93-38bf-43ac-a890-42dbb951dd1c\": \"f2892d93-38bf-43ac-a890-42dbb951dd1c\", \"6ac56963-8b7d-48cc-9114-829e66514674\": \"6ac56963-8b7d-48cc-9114-829e66514674\", \"67102a66-d6cc-4dac-a97a-db23e140bd86\": \"67102a66-d6cc-4dac-a97a-db23e140bd86\", \"5ca3d225-5365-44b7-9a37-33f2a45d62ed\": \"5ca3d225-5365-44b7-9a37-33f2a45d62ed\", \"a56fb895-66e9-48c8-a9a0-36a952ed80e3\": \"a56fb895-66e9-48c8-a9a0-36a952ed80e3\", \"78dd8964-9e6a-42c3-a777-4da5a988d561\": \"78dd8964-9e6a-42c3-a777-4da5a988d561\", \"729bf368-3941-4e35-a0c1-427300cf03e5\": \"729bf368-3941-4e35-a0c1-427300cf03e5\", \"198de437-4bf2-4300-847e-0733efba1300\": \"198de437-4bf2-4300-847e-0733efba1300\", \"0b95a2d4-43f5-477e-8cff-7a27541b567a\": \"0b95a2d4-43f5-477e-8cff-7a27541b567a\", \"fb397e6f-a795-474c-826b-915834b12d87\": \"fb397e6f-a795-474c-826b-915834b12d87\", \"cf17b6ac-4777-48ab-8cd0-cecb986a0ab7\": \"cf17b6ac-4777-48ab-8cd0-cecb986a0ab7\"}, \"doc_id_dict\": {}, \"embeddings_dict\": {}}"}}}
|
storage/vector_store.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
style.css
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.bot {
|
2 |
+
background-color: var(--body-background-fill) !important;
|
3 |
+
border-color: var(--body-background-fill) !important
|
4 |
+
}
|
5 |
+
|
6 |
+
.user {
|
7 |
+
background-color: var(--body-background-fill) !important;
|
8 |
+
border-color: var(--body-background-fill) !important
|
9 |
+
}
|
10 |
+
|
11 |
+
.gap.panel {
|
12 |
+
padding: 0 !important;
|
13 |
+
}
|
14 |
+
|
15 |
+
div.gap>.stretch {
|
16 |
+
display: none !important;
|
17 |
+
}
|
18 |
+
|
19 |
+
div.gap.panel>div.gr-group {
|
20 |
+
position: absolute;
|
21 |
+
bottom: 0;
|
22 |
+
}
|
23 |
+
|
24 |
+
h1 {
|
25 |
+
font-size: 48px !important;
|
26 |
+
}
|
27 |
+
|
28 |
+
.ask-button {
|
29 |
+
background-color: var(--color-accent);
|
30 |
+
font-weight: bold;
|
31 |
+
letter-spacing: 0.1rem;
|
32 |
+
}
|
33 |
+
|
34 |
+
.gallery-item {
|
35 |
+
color: var(--block-label-text-color) !important
|
36 |
+
}
|
37 |
+
|
38 |
+
div.message-wrap {
|
39 |
+
margin-bottom: 32px !important;
|
40 |
+
}
|
41 |
+
|
42 |
+
.message, .gallery-item, .ask-button, textarea {
|
43 |
+
font-family: "Arial" !important;
|
44 |
+
}
|
theme.py
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Iterable
|
2 |
+
from gradio.themes.base import Base
|
3 |
+
from gradio.themes.utils import fonts
|
4 |
+
|
5 |
+
|
6 |
+
class CustomTheme(Base):
|
7 |
+
|
8 |
+
def __init__(self):
|
9 |
+
super().__init__(
|
10 |
+
font=fonts.GoogleFont("Bruno Ace SC")
|
11 |
+
)
|
12 |
+
|
13 |
+
off_white = "#F0F0F0"
|
14 |
+
|
15 |
+
primary = off_white
|
16 |
+
secondary = "#e6e6e6"
|
17 |
+
panel_color = "#DBDBDB"
|
18 |
+
accent = "#49637A"
|
19 |
+
accent_soft = "#49637a28"
|
20 |
+
|
21 |
+
|
22 |
+
primary_dark = "#121212"
|
23 |
+
secondary_dark = "#242424"
|
24 |
+
panel_color_dark = "#363636"
|
25 |
+
accent_dark = "#d9d9d9"
|
26 |
+
accent_soft_dark = "#101727"
|
27 |
+
text_color_dark = off_white
|
28 |
+
|
29 |
+
super().set(
|
30 |
+
# LIGHT MODE
|
31 |
+
body_background_fill=primary,
|
32 |
+
background_fill_secondary=primary,
|
33 |
+
panel_background_fill=panel_color,
|
34 |
+
border_color_primary=primary,
|
35 |
+
block_background_fill=secondary,
|
36 |
+
block_border_color=primary,
|
37 |
+
block_label_background_fill=primary,
|
38 |
+
input_background_fill="#DADFE6",
|
39 |
+
input_border_color=secondary,
|
40 |
+
button_secondary_background_fill=accent,
|
41 |
+
button_secondary_text_color=off_white,
|
42 |
+
color_accent_soft=accent_soft,
|
43 |
+
border_color_accent_subdued=accent,
|
44 |
+
|
45 |
+
# DARK MODE
|
46 |
+
body_background_fill_dark=primary_dark,
|
47 |
+
background_fill_secondary_dark=secondary_dark,
|
48 |
+
panel_background_fill_dark=secondary_dark,
|
49 |
+
border_color_primary_dark=primary_dark,
|
50 |
+
block_background_fill_dark=secondary_dark,
|
51 |
+
block_border_color_dark=secondary_dark,
|
52 |
+
block_label_background_fill_dark=primary_dark,
|
53 |
+
block_label_text_color_dark=text_color_dark,
|
54 |
+
input_background_fill_dark=panel_color_dark,
|
55 |
+
input_border_color_dark=secondary_dark,
|
56 |
+
button_primary_background_fill_dark=accent_dark,
|
57 |
+
button_primary_text_color_dark=primary_dark,
|
58 |
+
color_accent_soft_dark=accent_soft_dark,
|
59 |
+
border_color_accent_subdued_dark=accent_soft_dark,
|
60 |
+
|
61 |
+
block_radius="15px",
|
62 |
+
container_radius="32px",
|
63 |
+
)
|
user_avatar.png
ADDED