Spaces:
Sleeping
Sleeping
lucacolombo97
commited on
Commit
•
718b812
1
Parent(s):
a20369f
New
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +3 -0
- __pycache__/app.cpython-310.pyc +0 -0
- __pycache__/dev_dhiria.cpython-310.pyc +0 -0
- __pycache__/server.cpython-310.pyc +0 -0
- __pycache__/stuff.cpython-310.pyc +0 -0
- __pycache__/symptoms_categories.cpython-310.pyc +0 -0
- __pycache__/utils.cpython-310.pyc +0 -0
- app.py +416 -429
- atlhete-high-resolution-logo-black-transparent.png +0 -0
- data/200_Users_Running_Dataset.csv +3 -0
- data/data_mental.csv +0 -0
- data/dataset_for_last_model.csv +97 -0
- data/example_input_ecg_fft.csv +3 -0
- data/synthetic_ecg_fft_dataset.csv +0 -0
- data_for_demo/focus_on_technique_mental.csv +2 -0
- data_for_demo/focus_on_technique_running.csv +0 -0
- data_for_demo/rest_mental.csv +2 -0
- data_for_demo/rest_running.csv +0 -0
- deployment_files/.DS_Store +0 -0
- deployment_files/.fhe_keys/2820248940/15341225681980396668/secretKey_0 +0 -0
- deployment_files/.fhe_keys/2820248940/encrypted_input +3 -0
- deployment_files/.fhe_keys/2820248940/evaluation_key +0 -0
- deployment_files/client/client.specs.json +1 -0
- deployment_files/client/serialized_processing.json +1 -0
- deployment_files/client/versions.json +1 -0
- deployment_files/client_dir/2820248940_encrypted_output +0 -0
- deployment_files/server/circuit.mlir +18 -0
- deployment_files/server/configuration.json +1 -0
- deployment_files/server/is_simulated +1 -0
- deployment_files/server/versions.json +1 -0
- deployment_files/server_dir/2820248940_encrypted_input +3 -0
- deployment_files/server_dir/2820248940_encrypted_output +0 -0
- deployment_files/server_dir/2820248940_valuation_key +0 -0
- deployment_files_generic/.fhe_keys/950347125_1/12513518805967278301/secretKey_0 +0 -0
- deployment_files_generic/.fhe_keys/950347125_1/encrypted_input_1 +0 -0
- deployment_files_generic/.fhe_keys/950347125_1/evaluation_key_1 +0 -0
- deployment_files_generic/.fhe_keys/950347125_2/454142848044555242/secretKey_0 +0 -0
- deployment_files_generic/.fhe_keys/950347125_2/encrypted_input_2 +0 -0
- deployment_files_generic/.fhe_keys/950347125_2/evaluation_key_2 +0 -0
- deployment_files_generic/client_dir/950347125_encrypted_output_1 +0 -0
- deployment_files_generic/client_dir/950347125_encrypted_output_2 +0 -0
- deployment_files_generic/server_dir/950347125_encrypted_input_model1 +0 -0
- deployment_files_generic/server_dir/950347125_encrypted_input_model2 +0 -0
- deployment_files_generic/server_dir/950347125_encrypted_output_model1 +0 -0
- deployment_files_generic/server_dir/950347125_encrypted_output_model2 +0 -0
- deployment_files_generic/server_dir/950347125_evaluation_key_1 +0 -0
- deployment_files_generic/server_dir/950347125_evaluation_key_2 +0 -0
- deployment_files_model1/client.zip +0 -0
- deployment_files_model1/server.zip +0 -0
- deployment_files_model1/versions.json +1 -0
.gitattributes
CHANGED
@@ -2,3 +2,6 @@
|
|
2 |
*.pt filter=lfs diff=lfs merge=lfs -text
|
3 |
*.extension filter=lfs diff=lfs merge=lfs -text
|
4 |
*.bin filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
2 |
*.pt filter=lfs diff=lfs merge=lfs -text
|
3 |
*.extension filter=lfs diff=lfs merge=lfs -text
|
4 |
*.bin filter=lfs diff=lfs merge=lfs -text
|
5 |
+
data/200_Users_Running_Dataset.csv filter=lfs diff=lfs merge=lfs -text
|
6 |
+
deployment_files/.fhe_keys/2820248940/encrypted_input filter=lfs diff=lfs merge=lfs -text
|
7 |
+
deployment_files/server_dir/2820248940_encrypted_input filter=lfs diff=lfs merge=lfs -text
|
__pycache__/app.cpython-310.pyc
ADDED
Binary file (11.1 kB). View file
|
|
__pycache__/dev_dhiria.cpython-310.pyc
ADDED
Binary file (5.28 kB). View file
|
|
__pycache__/server.cpython-310.pyc
ADDED
Binary file (5.9 kB). View file
|
|
__pycache__/stuff.cpython-310.pyc
ADDED
Binary file (1.09 kB). View file
|
|
__pycache__/symptoms_categories.cpython-310.pyc
ADDED
Binary file (3.35 kB). View file
|
|
__pycache__/utils.cpython-310.pyc
ADDED
Binary file (3.88 kB). View file
|
|
app.py
CHANGED
@@ -6,24 +6,28 @@ import gradio as gr # pylint: disable=import-error
|
|
6 |
import numpy as np
|
7 |
import pandas as pd
|
8 |
import requests
|
9 |
-
from
|
10 |
from utils import (
|
11 |
CLIENT_DIR,
|
12 |
CURRENT_DIR,
|
13 |
-
|
|
|
|
|
14 |
INPUT_BROWSER_LIMIT,
|
15 |
KEYS_DIR,
|
16 |
SERVER_URL,
|
17 |
-
TARGET_COLUMNS,
|
18 |
-
TRAINING_FILENAME,
|
19 |
clean_directory,
|
20 |
-
get_disease_name,
|
21 |
-
load_data,
|
22 |
-
pretty_print,
|
23 |
)
|
|
|
24 |
|
25 |
from concrete.ml.deployment import FHEModelClient
|
26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
subprocess.Popen(["uvicorn", "server:app"], cwd=CURRENT_DIR)
|
28 |
time.sleep(3)
|
29 |
|
@@ -43,92 +47,7 @@ def is_none(obj) -> bool:
|
|
43 |
return obj is None or (obj is not None and len(obj) < 1)
|
44 |
|
45 |
|
46 |
-
def
|
47 |
-
"""
|
48 |
-
Displays the symptoms of a given existing disease.
|
49 |
-
|
50 |
-
Args:
|
51 |
-
default_disease (str): Disease
|
52 |
-
Returns:
|
53 |
-
Dict: The according symptoms
|
54 |
-
"""
|
55 |
-
df = pd.read_csv(TRAINING_FILENAME)
|
56 |
-
df_filtred = df[df[TARGET_COLUMNS[1]] == default_disease]
|
57 |
-
|
58 |
-
return {
|
59 |
-
default_symptoms: gr.update(
|
60 |
-
visible=True,
|
61 |
-
value=pretty_print(
|
62 |
-
df_filtred.columns[df_filtred.eq(1).any()].to_list(), delimiter=", "
|
63 |
-
),
|
64 |
-
)
|
65 |
-
}
|
66 |
-
|
67 |
-
|
68 |
-
def get_user_symptoms_from_checkboxgroup(checkbox_symptoms: List) -> np.array:
|
69 |
-
"""
|
70 |
-
Convert the user symptoms into a binary vector representation.
|
71 |
-
|
72 |
-
Args:
|
73 |
-
checkbox_symptoms (List): A list of user symptoms.
|
74 |
-
|
75 |
-
Returns:
|
76 |
-
np.array: A binary vector representing the user's symptoms.
|
77 |
-
|
78 |
-
Raises:
|
79 |
-
KeyError: If a provided symptom is not recognized as a valid symptom.
|
80 |
-
|
81 |
-
"""
|
82 |
-
symptoms_vector = {key: 0 for key in valid_symptoms}
|
83 |
-
for pretty_symptom in checkbox_symptoms:
|
84 |
-
original_symptom = "_".join((pretty_symptom.lower().split(" ")))
|
85 |
-
if original_symptom not in symptoms_vector.keys():
|
86 |
-
raise KeyError(
|
87 |
-
f"The symptom '{original_symptom}' you provided is not recognized as a valid "
|
88 |
-
f"symptom.\nHere is the list of valid symptoms: {symptoms_vector}"
|
89 |
-
)
|
90 |
-
symptoms_vector[original_symptom] = 1
|
91 |
-
|
92 |
-
user_symptoms_vect = np.fromiter(symptoms_vector.values(), dtype=float)[np.newaxis, :]
|
93 |
-
|
94 |
-
assert all(value == 0 or value == 1 for value in user_symptoms_vect.flatten())
|
95 |
-
|
96 |
-
return user_symptoms_vect
|
97 |
-
|
98 |
-
|
99 |
-
def get_features_fn(*checked_symptoms: Tuple[str]) -> Dict:
|
100 |
-
"""
|
101 |
-
Get vector features based on the selected symptoms.
|
102 |
-
|
103 |
-
Args:
|
104 |
-
checked_symptoms (Tuple[str]): User symptoms
|
105 |
-
|
106 |
-
Returns:
|
107 |
-
Dict: The encoded user vector symptoms.
|
108 |
-
"""
|
109 |
-
if not any(lst for lst in checked_symptoms if lst):
|
110 |
-
return {
|
111 |
-
error_box1: gr.update(visible=True, value="⚠️ Please provide your chief complaints."),
|
112 |
-
}
|
113 |
-
|
114 |
-
if len(pretty_print(checked_symptoms)) < 5:
|
115 |
-
print("Provide at least 5 symptoms.")
|
116 |
-
return {
|
117 |
-
error_box1: gr.update(visible=True, value="⚠️ Provide at least 5 symptoms"),
|
118 |
-
one_hot_vect: None,
|
119 |
-
}
|
120 |
-
|
121 |
-
return {
|
122 |
-
error_box1: gr.update(visible=False),
|
123 |
-
one_hot_vect: gr.update(
|
124 |
-
visible=False,
|
125 |
-
value=get_user_symptoms_from_checkboxgroup(pretty_print(checked_symptoms)),
|
126 |
-
),
|
127 |
-
submit_btn: gr.update(value="Data submitted ✅"),
|
128 |
-
}
|
129 |
-
|
130 |
-
|
131 |
-
def key_gen_fn(user_symptoms: List[str]) -> Dict:
|
132 |
"""
|
133 |
Generate keys for a given user.
|
134 |
|
@@ -141,17 +60,11 @@ def key_gen_fn(user_symptoms: List[str]) -> Dict:
|
|
141 |
"""
|
142 |
clean_directory()
|
143 |
|
144 |
-
if is_none(user_symptoms):
|
145 |
-
print("Error: Please submit your symptoms or select a default disease.")
|
146 |
-
return {
|
147 |
-
error_box2: gr.update(visible=True, value="⚠️ Please submit your symptoms first."),
|
148 |
-
}
|
149 |
-
|
150 |
# Generate a random user ID
|
151 |
user_id = np.random.randint(0, 2**32)
|
152 |
print(f"Your user ID is: {user_id}....")
|
153 |
|
154 |
-
client = FHEModelClient(path_dir=
|
155 |
client.load()
|
156 |
|
157 |
# Creates the private and evaluation keys on the client side
|
@@ -162,24 +75,35 @@ def key_gen_fn(user_symptoms: List[str]) -> Dict:
|
|
162 |
assert isinstance(serialized_evaluation_keys, bytes)
|
163 |
|
164 |
# Save the evaluation key
|
165 |
-
evaluation_key_path = KEYS_DIR / f"{user_id}/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
with evaluation_key_path.open("wb") as f:
|
167 |
f.write(serialized_evaluation_keys)
|
168 |
|
169 |
-
serialized_evaluation_keys_shorten_hex = serialized_evaluation_keys.hex()[:INPUT_BROWSER_LIMIT]
|
170 |
|
171 |
return {
|
172 |
error_box2: gr.update(visible=False),
|
173 |
-
key_box: gr.update(visible=False, value=serialized_evaluation_keys_shorten_hex),
|
174 |
user_id_box: gr.update(visible=False, value=user_id),
|
175 |
-
key_len_box: gr.update(
|
176 |
-
visible=False, value=f"{len(serialized_evaluation_keys) / (10**6):.2f} MB"
|
177 |
-
),
|
178 |
gen_key_btn: gr.update(value="Keys have been generated ✅")
|
179 |
}
|
180 |
|
181 |
|
182 |
-
def encrypt_fn(
|
183 |
"""
|
184 |
Encrypt the user symptoms vector in the `Client Side`.
|
185 |
|
@@ -187,98 +111,110 @@ def encrypt_fn(user_symptoms: np.ndarray, user_id: str) -> None:
|
|
187 |
user_symptoms (List[str]): The vector symptoms provided by the user
|
188 |
user_id (user): The current user's ID
|
189 |
"""
|
190 |
-
|
191 |
-
if is_none(user_id) or is_none(user_symptoms):
|
192 |
print("Error in encryption step: Provide your symptoms and generate the evaluation keys.")
|
193 |
return {
|
194 |
-
error_box3: gr.update(
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
)
|
199 |
}
|
200 |
|
201 |
# Retrieve the client API
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
|
|
207 |
|
208 |
-
|
209 |
-
assert isinstance(
|
210 |
-
encrypted_input_path = KEYS_DIR / f"{user_id}/
|
211 |
|
212 |
with encrypted_input_path.open("wb") as f:
|
213 |
-
f.write(
|
214 |
-
|
215 |
-
encrypted_quantized_user_symptoms_shorten_hex = encrypted_quantized_user_symptoms.hex()[
|
216 |
-
:INPUT_BROWSER_LIMIT
|
217 |
-
]
|
218 |
|
219 |
return {
|
220 |
-
error_box3: gr.update(visible=False),
|
221 |
-
one_hot_vect_box: gr.update(visible=True, value=user_symptoms),
|
222 |
-
enc_vect_box: gr.update(visible=True, value=encrypted_quantized_user_symptoms_shorten_hex),
|
223 |
}
|
224 |
|
225 |
|
226 |
-
def send_input_fn(user_id: str,
|
227 |
"""Send the encrypted data and the evaluation key to the server.
|
228 |
|
229 |
Args:
|
230 |
user_id (str): The current user's ID
|
231 |
-
|
232 |
"""
|
233 |
|
234 |
-
if is_none(user_id)
|
235 |
return {
|
236 |
-
error_box4: gr.update(
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
)
|
242 |
}
|
243 |
|
244 |
-
|
245 |
-
|
246 |
|
247 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
248 |
print(
|
249 |
"Error Encountered While Sending Data to the Server: "
|
250 |
-
f"The key has been generated correctly - {
|
251 |
)
|
252 |
|
253 |
return {
|
254 |
-
error_box4: gr.update(visible=True, value="⚠️ Please generate the private key first.")
|
255 |
}
|
256 |
|
257 |
-
if not
|
258 |
print(
|
259 |
"Error Encountered While Sending Data to the Server: The data has not been encrypted "
|
260 |
-
f"correctly on the client side - {
|
261 |
)
|
262 |
return {
|
263 |
-
error_box4: gr.update(
|
264 |
-
visible=True,
|
265 |
-
value="⚠️ Please encrypt the data with the private key first.",
|
266 |
-
),
|
267 |
}
|
|
|
268 |
|
269 |
# Define the data and files to post
|
270 |
data = {
|
271 |
"user_id": user_id,
|
272 |
-
"input": user_symptoms,
|
273 |
}
|
274 |
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
|
280 |
# Send the encrypted input and evaluation key to the server
|
281 |
-
url = SERVER_URL + "
|
282 |
with requests.post(
|
283 |
url=url,
|
284 |
data=data,
|
@@ -309,12 +245,141 @@ def run_fhe_fn(user_id: str) -> Dict:
|
|
309 |
fhe_execution_time_box: None,
|
310 |
}
|
311 |
|
|
|
312 |
data = {
|
313 |
"user_id": user_id,
|
314 |
}
|
315 |
|
316 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
317 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
318 |
with requests.post(
|
319 |
url=url,
|
320 |
data=data,
|
@@ -333,22 +398,25 @@ def run_fhe_fn(user_id: str) -> Dict:
|
|
333 |
else:
|
334 |
time.sleep(1)
|
335 |
print(f"response.ok: {response.ok}, {response.json()} - Computed")
|
|
|
|
|
336 |
|
|
|
337 |
return {
|
338 |
error_box5: gr.update(visible=False),
|
339 |
-
fhe_execution_time_box: gr.update(visible=True, value=f"{
|
340 |
}
|
341 |
|
342 |
|
343 |
-
def get_output_fn(user_id: str
|
344 |
-
"""Retreive
|
345 |
-
|
346 |
Args:
|
347 |
user_id (str): The current user's ID
|
348 |
user_symptoms (np.ndarray): The user symptoms
|
349 |
"""
|
350 |
|
351 |
-
if is_none(user_id)
|
352 |
return {
|
353 |
error_box6: gr.update(
|
354 |
visible=True,
|
@@ -362,7 +430,7 @@ def get_output_fn(user_id: str, user_symptoms: np.ndarray) -> Dict:
|
|
362 |
}
|
363 |
|
364 |
# Retrieve the encrypted output
|
365 |
-
url = SERVER_URL + "
|
366 |
with requests.post(
|
367 |
url=url,
|
368 |
data=data,
|
@@ -374,28 +442,17 @@ def get_output_fn(user_id: str, user_symptoms: np.ndarray) -> Dict:
|
|
374 |
|
375 |
# Save the encrypted output to bytes in a file as it is too large to pass through
|
376 |
# regular Gradio buttons (see https://github.com/gradio-app/gradio/issues/1877)
|
377 |
-
encrypted_output_path = CLIENT_DIR / f"{user_id}
|
378 |
|
379 |
with encrypted_output_path.open("wb") as f:
|
380 |
f.write(encrypted_output)
|
381 |
-
return {error_box6: gr.update(visible=False), srv_resp_retrieve_data_box: "Data received"}
|
382 |
|
|
|
383 |
|
384 |
-
def decrypt_fn(
|
385 |
-
user_id: str, user_symptoms: np.ndarray, *checked_symptoms, threshold: int = 0.5
|
386 |
-
) -> Dict:
|
387 |
-
"""Dencrypt the data on the `Client Side`.
|
388 |
|
389 |
-
Args:
|
390 |
-
user_id (str): The current user's ID
|
391 |
-
user_symptoms (np.ndarray): The user symptoms
|
392 |
-
threshold (float): Probability confidence threshold
|
393 |
-
|
394 |
-
Returns:
|
395 |
-
Decrypted output
|
396 |
-
"""
|
397 |
|
398 |
-
|
|
|
399 |
return {
|
400 |
error_box7: gr.update(
|
401 |
visible=True,
|
@@ -405,7 +462,7 @@ def decrypt_fn(
|
|
405 |
}
|
406 |
|
407 |
# Get the encrypted output path
|
408 |
-
encrypted_output_path = CLIENT_DIR / f"{user_id}
|
409 |
|
410 |
if not encrypted_output_path.is_file():
|
411 |
print("Error in decryption step: Please run the FHE execution, first.")
|
@@ -422,42 +479,46 @@ def decrypt_fn(
|
|
422 |
decrypt_box: None,
|
423 |
}
|
424 |
|
425 |
-
# Load the encrypted output as bytes
|
426 |
with encrypted_output_path.open("rb") as f:
|
427 |
encrypted_output = f.read()
|
428 |
|
429 |
-
|
430 |
-
client = FHEModelClient(path_dir=DEPLOYMENT_DIR, key_dir=KEYS_DIR / f"{user_id}")
|
431 |
client.load()
|
432 |
|
433 |
# Deserialize, decrypt and post-process the encrypted output
|
434 |
output = client.deserialize_decrypt_dequantize(encrypted_output)
|
435 |
|
436 |
-
|
437 |
-
top3_proba = output[0][top3_diseases]
|
438 |
|
439 |
-
|
|
|
440 |
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
446 |
|
447 |
out = (
|
448 |
-
f"
|
449 |
-
f"{
|
450 |
-
"Here are the top3 predictions:\n\n"
|
451 |
-
f"1. « {get_disease_name(top3_diseases[0])} » with a probability of {top3_proba[0]:.2%}\n"
|
452 |
-
f"2. « {get_disease_name(top3_diseases[1])} » with a probability of {top3_proba[1]:.2%}\n"
|
453 |
-
f"3. « {get_disease_name(top3_diseases[2])} » with a probability of {top3_proba[2]:.2%}\n"
|
454 |
)
|
455 |
|
456 |
-
return
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
|
|
|
|
461 |
|
462 |
|
463 |
def reset_fn():
|
@@ -466,217 +527,178 @@ def reset_fn():
|
|
466 |
clean_directory()
|
467 |
|
468 |
return {
|
469 |
-
one_hot_vect: None,
|
470 |
-
one_hot_vect_box: None,
|
471 |
-
enc_vect_box: gr.update(visible=True, value=None),
|
472 |
-
quant_vect_box: gr.update(visible=False, value=None),
|
473 |
-
user_id_box: gr.update(visible=False, value=None),
|
474 |
-
default_symptoms: gr.update(visible=True, value=None),
|
475 |
-
default_disease_box: gr.update(visible=True, value=None),
|
476 |
-
key_box: gr.update(visible=True, value=None),
|
477 |
-
key_len_box: gr.update(visible=False, value=None),
|
478 |
-
fhe_execution_time_box: gr.update(visible=True, value=None),
|
479 |
-
decrypt_box: None,
|
480 |
-
submit_btn: gr.update(value="Submit"),
|
481 |
-
error_box7: gr.update(visible=False),
|
482 |
-
error_box1: gr.update(visible=False),
|
483 |
-
error_box2: gr.update(visible=False),
|
484 |
-
error_box3: gr.update(visible=False),
|
485 |
-
error_box4: gr.update(visible=False),
|
486 |
-
error_box5: gr.update(visible=False),
|
487 |
-
error_box6: gr.update(visible=False),
|
488 |
-
srv_resp_send_data_box: None,
|
489 |
-
srv_resp_retrieve_data_box: None,
|
490 |
-
**{box: None for box in check_boxes},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
491 |
}
|
492 |
|
493 |
|
|
|
494 |
if __name__ == "__main__":
|
495 |
|
496 |
print("Starting demo ...")
|
497 |
|
498 |
clean_directory()
|
499 |
|
500 |
-
|
501 |
-
|
502 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
503 |
|
504 |
# Link + images
|
505 |
gr.Markdown()
|
506 |
gr.Markdown(
|
507 |
"""
|
508 |
<p align="center">
|
509 |
-
<img width=
|
510 |
</p>
|
511 |
""")
|
512 |
-
|
513 |
-
|
514 |
-
gr.Markdown(
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
—
|
520 |
-
<a href="https://docs.zama.ai/concrete-ml"> <img style="vertical-align: middle; display:inline-block; margin-right: 3px;" width=15 src="https://user-images.githubusercontent.com/5758427/197976802-fddd34c5-f59a-48d0-9bff-7ad1b00cb1fb.png">Documentation</a>
|
521 |
-
—
|
522 |
-
<a href="https://zama.ai/community"> <img style="vertical-align: middle; display:inline-block; margin-right: 3px;" width=15 src="https://user-images.githubusercontent.com/5758427/197977153-8c9c01a7-451a-4993-8e10-5a6ed5343d02.png">Community</a>
|
523 |
-
—
|
524 |
-
<a href="https://twitter.com/zama_fhe"> <img style="vertical-align: middle; display:inline-block; margin-right: 3px;" width=15 src="https://user-images.githubusercontent.com/5758427/197975044-bab9d199-e120-433b-b3be-abd73b211a54.png">@zama_fhe</a>
|
525 |
-
</p>
|
526 |
""")
|
527 |
-
|
528 |
-
gr.Markdown(
|
529 |
-
""""
|
530 |
-
<p align="center">
|
531 |
-
<img width="65%" height="25%" src="https://raw.githubusercontent.com/kcelia/Img/main/healthcare_prediction.jpg">
|
532 |
-
</p>
|
533 |
-
"""
|
534 |
-
)
|
535 |
-
gr.Markdown("## Notes")
|
536 |
-
gr.Markdown(
|
537 |
-
"""
|
538 |
-
- The private key is used to encrypt and decrypt the data and shall never be shared.
|
539 |
-
- The evaluation key is a public key that the server needs to process encrypted data.
|
540 |
-
"""
|
541 |
-
)
|
542 |
-
|
543 |
-
# ------------------------- Step 1 -------------------------
|
544 |
-
gr.Markdown("\n")
|
545 |
-
gr.Markdown("## Step 1: Select chief complaints")
|
546 |
-
gr.Markdown("<hr />")
|
547 |
-
gr.Markdown("<span style='color:grey'>Client Side</span>")
|
548 |
-
gr.Markdown("Select at least 5 chief complaints from the list below.")
|
549 |
-
|
550 |
-
# Step 1.1: Provide symptoms
|
551 |
-
check_boxes = []
|
552 |
-
with gr.Row():
|
553 |
-
with gr.Column():
|
554 |
-
for category in SYMPTOMS_LIST[:3]:
|
555 |
-
with gr.Accordion(pretty_print(category.keys()), open=False):
|
556 |
-
check_box = gr.CheckboxGroup(pretty_print(category.values()), show_label=0)
|
557 |
-
check_boxes.append(check_box)
|
558 |
-
with gr.Column():
|
559 |
-
for category in SYMPTOMS_LIST[3:6]:
|
560 |
-
with gr.Accordion(pretty_print(category.keys()), open=False):
|
561 |
-
check_box = gr.CheckboxGroup(pretty_print(category.values()), show_label=0)
|
562 |
-
check_boxes.append(check_box)
|
563 |
-
with gr.Column():
|
564 |
-
for category in SYMPTOMS_LIST[6:]:
|
565 |
-
with gr.Accordion(pretty_print(category.keys()), open=False):
|
566 |
-
check_box = gr.CheckboxGroup(pretty_print(category.values()), show_label=0)
|
567 |
-
check_boxes.append(check_box)
|
568 |
-
|
569 |
-
error_box1 = gr.Textbox(label="Error ❌", visible=False)
|
570 |
-
|
571 |
-
# Default disease, picked from the dataframe
|
572 |
-
gr.Markdown(
|
573 |
-
"You can choose an **existing disease** and explore its associated symptoms.",
|
574 |
-
visible=False,
|
575 |
-
)
|
576 |
-
|
577 |
with gr.Row():
|
578 |
-
|
579 |
-
|
580 |
-
with gr.Column(scale=5):
|
581 |
-
default_symptoms = gr.Textbox(label="Related Symptoms:", visible=False)
|
582 |
-
# User vector symptoms encoded in oneHot representation
|
583 |
-
one_hot_vect = gr.Textbox(visible=False)
|
584 |
-
# Submit botton
|
585 |
-
submit_btn = gr.Button("Submit")
|
586 |
-
# Clear botton
|
587 |
-
clear_button = gr.Button("Reset Space 🔁", visible=False)
|
588 |
-
|
589 |
-
default_disease_box.change(
|
590 |
-
fn=display_default_symptoms_fn, inputs=[default_disease_box], outputs=[default_symptoms]
|
591 |
-
)
|
592 |
|
593 |
-
submit_btn.click(
|
594 |
-
fn=get_features_fn,
|
595 |
-
inputs=[*check_boxes],
|
596 |
-
outputs=[one_hot_vect, error_box1, submit_btn],
|
597 |
-
)
|
598 |
|
599 |
-
|
600 |
-
|
601 |
-
gr.Markdown("## Step 2: Encrypt data")
|
602 |
-
gr.Markdown("<hr />")
|
603 |
-
gr.Markdown("<span style='color:grey'>Client Side</span>")
|
604 |
-
# Step 2.1: Key generation
|
605 |
-
gr.Markdown(
|
606 |
-
"### Key Generation\n\n"
|
607 |
-
"In FHE schemes, a secret (enc/dec)ryption keys are generated for encrypting and decrypting data owned by the client. \n\n"
|
608 |
-
"Additionally, a public evaluation key is generated, enabling external entities to perform homomorphic operations on encrypted data, without the need to decrypt them. \n\n"
|
609 |
-
"The evaluation key will be transmitted to the server for further processing."
|
610 |
-
)
|
611 |
|
|
|
|
|
|
|
|
|
|
|
612 |
gen_key_btn = gr.Button("Generate the private and evaluation keys.")
|
613 |
error_box2 = gr.Textbox(label="Error ❌", visible=False)
|
614 |
user_id_box = gr.Textbox(label="User ID:", visible=False)
|
615 |
-
key_len_box = gr.Textbox(label="Evaluation Key Size:", visible=False)
|
616 |
-
key_box = gr.Textbox(label="Evaluation key (truncated):", max_lines=3, visible=False)
|
617 |
-
|
618 |
gen_key_btn.click(
|
619 |
key_gen_fn,
|
620 |
-
inputs=one_hot_vect,
|
621 |
outputs=[
|
622 |
-
key_box,
|
623 |
user_id_box,
|
624 |
-
key_len_box,
|
625 |
error_box2,
|
626 |
gen_key_btn,
|
627 |
],
|
628 |
)
|
629 |
|
630 |
-
#
|
631 |
-
gr.Markdown("
|
|
|
|
|
|
|
632 |
encrypt_btn = gr.Button("Encrypt the data using the private secret key")
|
633 |
error_box3 = gr.Textbox(label="Error ❌", visible=False)
|
634 |
-
|
635 |
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
encrypt_btn.click(
|
643 |
-
encrypt_fn,
|
644 |
-
inputs=[one_hot_vect, user_id_box],
|
645 |
-
outputs=[
|
646 |
-
one_hot_vect_box,
|
647 |
-
enc_vect_box,
|
648 |
-
error_box3,
|
649 |
-
],
|
650 |
-
)
|
651 |
-
# Step 2.3: Send encrypted data to the server
|
652 |
-
gr.Markdown(
|
653 |
-
"### Send the encrypted data to the <span style='color:grey'>Server Side</span>"
|
654 |
-
)
|
655 |
error_box4 = gr.Textbox(label="Error ❌", visible=False)
|
656 |
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
|
664 |
send_input_btn.click(
|
665 |
send_input_fn,
|
666 |
-
inputs=[user_id_box
|
667 |
outputs=[error_box4, srv_resp_send_data_box],
|
668 |
)
|
669 |
|
670 |
-
#
|
671 |
-
gr.Markdown("
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
gr.Markdown(
|
676 |
-
"Once the server receives the encrypted data, it can process and compute the output without ever decrypting the data just as it would on clear data.\n\n"
|
677 |
-
"This server employs a [Logistic Regression](https://github.com/zama-ai/concrete-ml/tree/release/1.1.x/use_case_examples/disease_prediction) model that has been trained on this [data-set](https://github.com/anujdutt9/Disease-Prediction-from-Symptoms/tree/master/dataset)."
|
678 |
-
)
|
679 |
-
|
680 |
run_fhe_btn = gr.Button("Run the FHE evaluation")
|
681 |
error_box5 = gr.Textbox(label="Error ❌", visible=False)
|
682 |
fhe_execution_time_box = gr.Textbox(label="Total FHE Execution Time:", visible=True)
|
@@ -686,19 +708,12 @@ if __name__ == "__main__":
|
|
686 |
outputs=[fhe_execution_time_box, error_box5],
|
687 |
)
|
688 |
|
689 |
-
#
|
690 |
-
gr.Markdown("
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
gr.Markdown(
|
695 |
-
"### Get the encrypted data from the <span style='color:grey'>Server Side</span>"
|
696 |
-
)
|
697 |
-
|
698 |
error_box6 = gr.Textbox(label="Error ❌", visible=False)
|
699 |
-
|
700 |
-
# Step 4.1: Data transmission
|
701 |
-
# with gr.Row().style(equal_height=True):
|
702 |
with gr.Row():
|
703 |
with gr.Column(scale=4):
|
704 |
get_output_btn = gr.Button("Get data")
|
@@ -707,65 +722,37 @@ if __name__ == "__main__":
|
|
707 |
|
708 |
get_output_btn.click(
|
709 |
get_output_fn,
|
710 |
-
inputs=[user_id_box
|
711 |
outputs=[srv_resp_retrieve_data_box, error_box6],
|
712 |
)
|
713 |
|
714 |
-
#
|
715 |
-
gr.Markdown("
|
|
|
|
|
|
|
716 |
decrypt_btn = gr.Button("Decrypt the output using the private secret key")
|
717 |
error_box7 = gr.Textbox(label="Error ❌", visible=False)
|
718 |
-
decrypt_box = gr.Textbox(label="Decrypted Output:")
|
719 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
720 |
decrypt_btn.click(
|
721 |
decrypt_fn,
|
722 |
-
inputs=[user_id_box
|
723 |
-
outputs=[decrypt_box,
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
gr.Markdown(
|
729 |
-
"""The app was built with [Concrete ML](https://github.com/zama-ai/concrete-ml), a Privacy-Preserving Machine Learning (PPML) open-source set of tools by Zama.
|
730 |
-
Try it yourself and don't forget to star on [Github](https://github.com/zama-ai/concrete-ml) ⭐.
|
731 |
-
"""
|
732 |
)
|
733 |
|
734 |
-
gr.Markdown("\n\n")
|
735 |
-
|
736 |
-
gr.Markdown(
|
737 |
-
"""**Please Note**: This space is intended solely for educational and demonstration purposes.
|
738 |
-
It should not be considered as a replacement for professional medical counsel, diagnosis, or therapy for any health or related issues.
|
739 |
-
Any questions or concerns about your individual health should be addressed to your doctor or another qualified healthcare provider.
|
740 |
-
"""
|
741 |
-
)
|
742 |
|
743 |
-
clear_button.click(
|
744 |
-
reset_fn,
|
745 |
-
outputs=[
|
746 |
-
one_hot_vect_box,
|
747 |
-
one_hot_vect,
|
748 |
-
submit_btn,
|
749 |
-
error_box1,
|
750 |
-
error_box2,
|
751 |
-
error_box3,
|
752 |
-
error_box4,
|
753 |
-
error_box5,
|
754 |
-
error_box6,
|
755 |
-
error_box7,
|
756 |
-
default_disease_box,
|
757 |
-
default_symptoms,
|
758 |
-
user_id_box,
|
759 |
-
key_len_box,
|
760 |
-
key_box,
|
761 |
-
quant_vect_box,
|
762 |
-
enc_vect_box,
|
763 |
-
srv_resp_send_data_box,
|
764 |
-
srv_resp_retrieve_data_box,
|
765 |
-
fhe_execution_time_box,
|
766 |
-
decrypt_box,
|
767 |
-
*check_boxes,
|
768 |
-
],
|
769 |
-
)
|
770 |
|
771 |
-
|
|
|
6 |
import numpy as np
|
7 |
import pandas as pd
|
8 |
import requests
|
9 |
+
from stuff import get_emoticon, plot_tachometer
|
10 |
from utils import (
|
11 |
CLIENT_DIR,
|
12 |
CURRENT_DIR,
|
13 |
+
DEPLOYMENT_DIR_MODEL1,
|
14 |
+
DEPLOYMENT_DIR_MODEL2,
|
15 |
+
DEPLOYMENT_DIR_MODEL3,
|
16 |
INPUT_BROWSER_LIMIT,
|
17 |
KEYS_DIR,
|
18 |
SERVER_URL,
|
|
|
|
|
19 |
clean_directory,
|
|
|
|
|
|
|
20 |
)
|
21 |
+
from dev_dhiria import frequency_domain, interpolation, statistics
|
22 |
|
23 |
from concrete.ml.deployment import FHEModelClient
|
24 |
|
25 |
+
global_df1 = None
|
26 |
+
global_df2 = None
|
27 |
+
|
28 |
+
global_output_1 = None
|
29 |
+
global_output_2 = None
|
30 |
+
|
31 |
subprocess.Popen(["uvicorn", "server:app"], cwd=CURRENT_DIR)
|
32 |
time.sleep(3)
|
33 |
|
|
|
47 |
return obj is None or (obj is not None and len(obj) < 1)
|
48 |
|
49 |
|
50 |
+
def key_gen_fn() -> Dict:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
"""
|
52 |
Generate keys for a given user.
|
53 |
|
|
|
60 |
"""
|
61 |
clean_directory()
|
62 |
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
# Generate a random user ID
|
64 |
user_id = np.random.randint(0, 2**32)
|
65 |
print(f"Your user ID is: {user_id}....")
|
66 |
|
67 |
+
client = FHEModelClient(path_dir=DEPLOYMENT_DIR_MODEL1, key_dir=KEYS_DIR / f"{user_id}_1")
|
68 |
client.load()
|
69 |
|
70 |
# Creates the private and evaluation keys on the client side
|
|
|
75 |
assert isinstance(serialized_evaluation_keys, bytes)
|
76 |
|
77 |
# Save the evaluation key
|
78 |
+
evaluation_key_path = KEYS_DIR / f"{user_id}_1/evaluation_key_1"
|
79 |
+
with evaluation_key_path.open("wb") as f:
|
80 |
+
f.write(serialized_evaluation_keys)
|
81 |
+
|
82 |
+
|
83 |
+
client = FHEModelClient(path_dir=DEPLOYMENT_DIR_MODEL2, key_dir=KEYS_DIR / f"{user_id}_2")
|
84 |
+
client.load()
|
85 |
+
|
86 |
+
# Creates the private and evaluation keys on the client side
|
87 |
+
client.generate_private_and_evaluation_keys()
|
88 |
+
|
89 |
+
# Get the serialized evaluation keys
|
90 |
+
serialized_evaluation_keys = client.get_serialized_evaluation_keys()
|
91 |
+
assert isinstance(serialized_evaluation_keys, bytes)
|
92 |
+
|
93 |
+
# Save the evaluation key
|
94 |
+
evaluation_key_path = KEYS_DIR / f"{user_id}_2/evaluation_key_2"
|
95 |
with evaluation_key_path.open("wb") as f:
|
96 |
f.write(serialized_evaluation_keys)
|
97 |
|
|
|
98 |
|
99 |
return {
|
100 |
error_box2: gr.update(visible=False),
|
|
|
101 |
user_id_box: gr.update(visible=False, value=user_id),
|
|
|
|
|
|
|
102 |
gen_key_btn: gr.update(value="Keys have been generated ✅")
|
103 |
}
|
104 |
|
105 |
|
106 |
+
def encrypt_fn(arr: np.ndarray, user_id: str, input_id: int) -> None:
|
107 |
"""
|
108 |
Encrypt the user symptoms vector in the `Client Side`.
|
109 |
|
|
|
111 |
user_symptoms (List[str]): The vector symptoms provided by the user
|
112 |
user_id (user): The current user's ID
|
113 |
"""
|
114 |
+
if is_none(user_id) or is_none(arr):
|
|
|
115 |
print("Error in encryption step: Provide your symptoms and generate the evaluation keys.")
|
116 |
return {
|
117 |
+
# error_box3: gr.update(
|
118 |
+
# visible=True,
|
119 |
+
# value="⚠️ Please ensure that your symptoms have been submitted and "
|
120 |
+
# "that you have generated the evaluation key.",
|
121 |
+
# )
|
122 |
}
|
123 |
|
124 |
# Retrieve the client API
|
125 |
+
if input_id == 1:
|
126 |
+
client = FHEModelClient(path_dir=DEPLOYMENT_DIR_MODEL1, key_dir=KEYS_DIR / f"{user_id}_1")
|
127 |
+
client.load()
|
128 |
+
else:
|
129 |
+
client = FHEModelClient(path_dir=DEPLOYMENT_DIR_MODEL2, key_dir=KEYS_DIR / f"{user_id}_2")
|
130 |
+
client.load()
|
131 |
|
132 |
+
encrypted_quantized_arr = client.quantize_encrypt_serialize(arr)
|
133 |
+
assert isinstance(encrypted_quantized_arr, bytes)
|
134 |
+
encrypted_input_path = KEYS_DIR / f"{user_id}_{input_id}/encrypted_input_{input_id}"
|
135 |
|
136 |
with encrypted_input_path.open("wb") as f:
|
137 |
+
f.write(encrypted_quantized_arr)
|
|
|
|
|
|
|
|
|
138 |
|
139 |
return {
|
140 |
+
# error_box3: gr.update(visible=False),
|
141 |
+
# one_hot_vect_box: gr.update(visible=True, value=user_symptoms),
|
142 |
+
# enc_vect_box: gr.update(visible=True, value=encrypted_quantized_user_symptoms_shorten_hex),
|
143 |
}
|
144 |
|
145 |
|
146 |
+
def send_input_fn(user_id: str, models_layer: int = 1) -> Dict:
|
147 |
"""Send the encrypted data and the evaluation key to the server.
|
148 |
|
149 |
Args:
|
150 |
user_id (str): The current user's ID
|
151 |
+
arr (np.ndarray): The input for a model
|
152 |
"""
|
153 |
|
154 |
+
if is_none(user_id):
|
155 |
return {
|
156 |
+
# error_box4: gr.update(
|
157 |
+
# visible=True,
|
158 |
+
# value="⚠️ Please check your connectivity \n"
|
159 |
+
# "⚠️ Ensure that the symptoms have been submitted and the evaluation "
|
160 |
+
# "key has been generated before sending the data to the server.",
|
161 |
+
# )
|
162 |
}
|
163 |
|
164 |
+
evaluation_key_path_1 = KEYS_DIR / f"{user_id}_1/evaluation_key_1"
|
165 |
+
evaluation_key_path_2 = KEYS_DIR / f"{user_id}_2/evaluation_key_2"
|
166 |
|
167 |
+
if models_layer == 1:
|
168 |
+
# First layer of models, we have two encrypted inputs
|
169 |
+
encrypted_input_path_1 = KEYS_DIR / f"{user_id}_1/encrypted_input_1"
|
170 |
+
encrypted_input_path_2 = KEYS_DIR / f"{user_id}_2/encrypted_input_2"
|
171 |
+
else:
|
172 |
+
encrypted_input_path_3 = KEYS_DIR / f"{user_id}/encrypted_input_3"
|
173 |
+
|
174 |
+
if not evaluation_key_path_1.is_file():
|
175 |
print(
|
176 |
"Error Encountered While Sending Data to the Server: "
|
177 |
+
f"The key has been generated correctly - {evaluation_key_path_1.is_file()=}"
|
178 |
)
|
179 |
|
180 |
return {
|
181 |
+
# error_box4: gr.update(visible=True, value="⚠️ Please generate the private key first.")
|
182 |
}
|
183 |
|
184 |
+
if not encrypted_input_path_1.is_file():
|
185 |
print(
|
186 |
"Error Encountered While Sending Data to the Server: The data has not been encrypted "
|
187 |
+
f"correctly on the client side - {encrypted_input_path_1.is_file()=}"
|
188 |
)
|
189 |
return {
|
190 |
+
# error_box4: gr.update(
|
191 |
+
# visible=True,
|
192 |
+
# value="⚠️ Please encrypt the data with the private key first.",
|
193 |
+
# ),
|
194 |
}
|
195 |
+
|
196 |
|
197 |
# Define the data and files to post
|
198 |
data = {
|
199 |
"user_id": user_id,
|
200 |
+
# "input": user_symptoms,
|
201 |
}
|
202 |
|
203 |
+
if models_layer == 1:
|
204 |
+
files = [
|
205 |
+
("files", open(encrypted_input_path_1, "rb")),
|
206 |
+
("files", open(encrypted_input_path_2, "rb")),
|
207 |
+
("files", open(evaluation_key_path_1, "rb")),
|
208 |
+
("files", open(evaluation_key_path_2, "rb")),
|
209 |
+
]
|
210 |
+
else:
|
211 |
+
files = [
|
212 |
+
("files", open(encrypted_input_path_3, "rb")),
|
213 |
+
# ("files", open(evaluation_key_path, "rb")),
|
214 |
+
]
|
215 |
|
216 |
# Send the encrypted input and evaluation key to the server
|
217 |
+
url = SERVER_URL + "send_input_first_layer"
|
218 |
with requests.post(
|
219 |
url=url,
|
220 |
data=data,
|
|
|
245 |
fhe_execution_time_box: None,
|
246 |
}
|
247 |
|
248 |
+
start_time = time.time()
|
249 |
data = {
|
250 |
"user_id": user_id,
|
251 |
}
|
252 |
|
253 |
+
# Run the first layer
|
254 |
+
url = SERVER_URL + "run_fhe_first_layer"
|
255 |
+
with requests.post(
|
256 |
+
url=url,
|
257 |
+
data=data,
|
258 |
+
) as response:
|
259 |
+
if not response.ok:
|
260 |
+
return {
|
261 |
+
error_box5: gr.update(
|
262 |
+
visible=True,
|
263 |
+
value=(
|
264 |
+
"⚠️ An error occurred on the Server Side. "
|
265 |
+
"Please check connectivity and data transmission."
|
266 |
+
),
|
267 |
+
),
|
268 |
+
fhe_execution_time_box: gr.update(visible=False),
|
269 |
+
}
|
270 |
+
else:
|
271 |
+
time.sleep(1)
|
272 |
+
print(f"response.ok: {response.ok}, {response.json()} - Computed")
|
273 |
+
|
274 |
+
print(f"First layer done!")
|
275 |
+
|
276 |
+
# Decrypt because ConcreteML doesn't provide output to input
|
277 |
+
url = SERVER_URL + "get_output_first_layer_1"
|
278 |
+
with requests.post(
|
279 |
+
url=url,
|
280 |
+
data=data,
|
281 |
+
) as response:
|
282 |
+
if response.ok:
|
283 |
+
print(f"Receive Data: {response.ok=}")
|
284 |
+
|
285 |
+
encrypted_output = response.content
|
286 |
+
|
287 |
+
# Save the encrypted output to bytes in a file as it is too large to pass through
|
288 |
+
# regular Gradio buttons (see https://github.com/gradio-app/gradio/issues/1877)
|
289 |
+
encrypted_output_path = CLIENT_DIR / f"{user_id}_encrypted_output_1"
|
290 |
+
|
291 |
+
with encrypted_output_path.open("wb") as f:
|
292 |
+
f.write(encrypted_output)
|
293 |
+
|
294 |
+
url = SERVER_URL + "get_output_first_layer_2"
|
295 |
+
with requests.post(
|
296 |
+
url=url,
|
297 |
+
data=data,
|
298 |
+
) as response:
|
299 |
+
if response.ok:
|
300 |
+
print(f"Receive Data: {response.ok=}")
|
301 |
+
|
302 |
+
encrypted_output = response.content
|
303 |
+
|
304 |
+
# Save the encrypted output to bytes in a file as it is too large to pass through
|
305 |
+
# regular Gradio buttons (see https://github.com/gradio-app/gradio/issues/1877)
|
306 |
+
encrypted_output_path = CLIENT_DIR / f"{user_id}_encrypted_output_2"
|
307 |
+
|
308 |
+
with encrypted_output_path.open("wb") as f:
|
309 |
+
f.write(encrypted_output)
|
310 |
+
|
311 |
+
encrypted_output_path_1 = CLIENT_DIR / f"{user_id}_encrypted_output_1"
|
312 |
+
encrypted_output_path_2 = CLIENT_DIR / f"{user_id}_encrypted_output_2"
|
313 |
+
|
314 |
+
# Load the encrypted output as bytes
|
315 |
+
with encrypted_output_path_1.open("rb") as f1, \
|
316 |
+
encrypted_output_path_2.open("rb") as f2:
|
317 |
+
encrypted_output_1 = f1.read()
|
318 |
+
encrypted_output_2 = f2.read()
|
319 |
+
|
320 |
+
# Retrieve the client API
|
321 |
+
client = FHEModelClient(path_dir=DEPLOYMENT_DIR_MODEL1, key_dir=KEYS_DIR / f"{user_id}_1")
|
322 |
+
client.load()
|
323 |
+
|
324 |
+
breakpoint()
|
325 |
+
# Deserialize, decrypt and post-process the encrypted output
|
326 |
+
global global_output_1, global_output_2
|
327 |
+
global_output_1 = client.deserialize_decrypt_dequantize(encrypted_output_1)[0][0]
|
328 |
+
min_risk_score = 1.8145127821625648
|
329 |
+
max_risk_score = 1.9523557655864805
|
330 |
+
global_output_1 = (global_output_1 - min_risk_score) / (max_risk_score - min_risk_score)
|
331 |
+
|
332 |
+
|
333 |
+
client = FHEModelClient(path_dir=DEPLOYMENT_DIR_MODEL2, key_dir=KEYS_DIR / f"{user_id}_2")
|
334 |
+
client.load()
|
335 |
+
global_output_2 = client.deserialize_decrypt_dequantize(encrypted_output_2)
|
336 |
+
global_output_2 = int(global_output_2 > 0.6)
|
337 |
+
|
338 |
+
# Now re-encrypt the two values because ConcreteML does not allow
|
339 |
+
# to use the output of two models as input of a third one.
|
340 |
+
new_input = np.array([[global_output_1, global_output_2]])
|
341 |
+
|
342 |
+
# Retrieve the client API
|
343 |
+
client = FHEModelClient(path_dir=DEPLOYMENT_DIR_MODEL3, key_dir=KEYS_DIR / f"{user_id}")
|
344 |
+
client.load()
|
345 |
+
|
346 |
+
# Creates the private and evaluation keys on the client side
|
347 |
+
client.generate_private_and_evaluation_keys()
|
348 |
+
|
349 |
+
# Get the serialized evaluation keys
|
350 |
+
serialized_evaluation_keys = client.get_serialized_evaluation_keys()
|
351 |
+
assert isinstance(serialized_evaluation_keys, bytes)
|
352 |
+
|
353 |
+
# Save the evaluation key
|
354 |
+
evaluation_key_path = KEYS_DIR / f"{user_id}/evaluation_key_second_layer"
|
355 |
+
with evaluation_key_path.open("wb") as f:
|
356 |
+
f.write(serialized_evaluation_keys)
|
357 |
|
358 |
+
encrypted_quantized_arr = client.quantize_encrypt_serialize(new_input)
|
359 |
+
assert isinstance(encrypted_quantized_arr, bytes)
|
360 |
+
encrypted_input_path = KEYS_DIR / f"{user_id}/encrypted_input_3"
|
361 |
+
|
362 |
+
with encrypted_input_path.open("wb") as f:
|
363 |
+
f.write(encrypted_quantized_arr)
|
364 |
+
|
365 |
+
# Send it
|
366 |
+
evaluation_key_path = KEYS_DIR / f"{user_id}/evaluation_key_second_layer"
|
367 |
+
files = [
|
368 |
+
("files", open(encrypted_input_path, "rb")),
|
369 |
+
("files", open(evaluation_key_path, "rb")),
|
370 |
+
]
|
371 |
+
|
372 |
+
# Send the encrypted input and evaluation key to the server
|
373 |
+
url = SERVER_URL + "send_input_second_layer"
|
374 |
+
with requests.post(
|
375 |
+
url=url,
|
376 |
+
data=data,
|
377 |
+
files=files,
|
378 |
+
) as response:
|
379 |
+
print(f"Sending Data: {response.ok}")
|
380 |
+
|
381 |
+
# Run the second layer
|
382 |
+
url = SERVER_URL + "run_fhe_second_layer"
|
383 |
with requests.post(
|
384 |
url=url,
|
385 |
data=data,
|
|
|
398 |
else:
|
399 |
time.sleep(1)
|
400 |
print(f"response.ok: {response.ok}, {response.json()} - Computed")
|
401 |
+
|
402 |
+
print("Second layer done!")
|
403 |
|
404 |
+
total_time = time.time() - start_time
|
405 |
return {
|
406 |
error_box5: gr.update(visible=False),
|
407 |
+
fhe_execution_time_box: gr.update(visible=True, value=f"{total_time:.2f} seconds"),
|
408 |
}
|
409 |
|
410 |
|
411 |
+
def get_output_fn(user_id: str) -> Dict:
|
412 |
+
"""Retreive
|
413 |
+
the encrypted data from the server.
|
414 |
Args:
|
415 |
user_id (str): The current user's ID
|
416 |
user_symptoms (np.ndarray): The user symptoms
|
417 |
"""
|
418 |
|
419 |
+
if is_none(user_id):
|
420 |
return {
|
421 |
error_box6: gr.update(
|
422 |
visible=True,
|
|
|
430 |
}
|
431 |
|
432 |
# Retrieve the encrypted output
|
433 |
+
url = SERVER_URL + "get_output_second_layer"
|
434 |
with requests.post(
|
435 |
url=url,
|
436 |
data=data,
|
|
|
442 |
|
443 |
# Save the encrypted output to bytes in a file as it is too large to pass through
|
444 |
# regular Gradio buttons (see https://github.com/gradio-app/gradio/issues/1877)
|
445 |
+
encrypted_output_path = CLIENT_DIR / f"{user_id}_encrypted_output_3"
|
446 |
|
447 |
with encrypted_output_path.open("wb") as f:
|
448 |
f.write(encrypted_output)
|
|
|
449 |
|
450 |
+
return {error_box6: gr.update(visible=False), srv_resp_retrieve_data_box: "Data received"}
|
451 |
|
|
|
|
|
|
|
|
|
452 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
453 |
|
454 |
+
def decrypt_fn(user_id: str) -> Dict:
|
455 |
+
if is_none(user_id):
|
456 |
return {
|
457 |
error_box7: gr.update(
|
458 |
visible=True,
|
|
|
462 |
}
|
463 |
|
464 |
# Get the encrypted output path
|
465 |
+
encrypted_output_path = CLIENT_DIR / f"{user_id}_encrypted_output_3"
|
466 |
|
467 |
if not encrypted_output_path.is_file():
|
468 |
print("Error in decryption step: Please run the FHE execution, first.")
|
|
|
479 |
decrypt_box: None,
|
480 |
}
|
481 |
|
|
|
482 |
with encrypted_output_path.open("rb") as f:
|
483 |
encrypted_output = f.read()
|
484 |
|
485 |
+
client = FHEModelClient(path_dir=DEPLOYMENT_DIR_MODEL3, key_dir=KEYS_DIR / f"{user_id}")
|
|
|
486 |
client.load()
|
487 |
|
488 |
# Deserialize, decrypt and post-process the encrypted output
|
489 |
output = client.deserialize_decrypt_dequantize(encrypted_output)
|
490 |
|
491 |
+
breakpoint()
|
|
|
492 |
|
493 |
+
# Load also the data from the first two models (they are already downloaded)
|
494 |
+
global global_output_1, global_output_2
|
495 |
|
496 |
+
tachometer_plot = plot_tachometer(global_output_1 * 100)
|
497 |
+
emoticon_image = get_emoticon(global_output_2)
|
498 |
+
|
499 |
+
# Predicted class
|
500 |
+
predicted_class = np.argmax(output)
|
501 |
+
|
502 |
+
# Labels
|
503 |
+
labels = {
|
504 |
+
0: "Continue what you are doing!",
|
505 |
+
1: "Focus on technique!",
|
506 |
+
2: "Focus on mental health!",
|
507 |
+
3: "Rest!"
|
508 |
+
}
|
509 |
|
510 |
out = (
|
511 |
+
f"Given your recent running and mental stress statistics, you should... "
|
512 |
+
f"{labels[predicted_class]}"
|
|
|
|
|
|
|
|
|
513 |
)
|
514 |
|
515 |
+
return [
|
516 |
+
gr.update(value=out, visible=True),
|
517 |
+
gr.update(visible=False),
|
518 |
+
gr.update(value="Submit"),
|
519 |
+
gr.update(value=tachometer_plot, visible=True),
|
520 |
+
gr.update(value=emoticon_image, visible=True)
|
521 |
+
]
|
522 |
|
523 |
|
524 |
def reset_fn():
|
|
|
527 |
clean_directory()
|
528 |
|
529 |
return {
|
530 |
+
# one_hot_vect: None,
|
531 |
+
# one_hot_vect_box: None,
|
532 |
+
# enc_vect_box: gr.update(visible=True, value=None),
|
533 |
+
# quant_vect_box: gr.update(visible=False, value=None),
|
534 |
+
# user_id_box: gr.update(visible=False, value=None),
|
535 |
+
# default_symptoms: gr.update(visible=True, value=None),
|
536 |
+
# default_disease_box: gr.update(visible=True, value=None),
|
537 |
+
# key_box: gr.update(visible=True, value=None),
|
538 |
+
# key_len_box: gr.update(visible=False, value=None),
|
539 |
+
# fhe_execution_time_box: gr.update(visible=True, value=None),
|
540 |
+
# decrypt_box: None,
|
541 |
+
# submit_btn: gr.update(value="Submit"),
|
542 |
+
# error_box7: gr.update(visible=False),
|
543 |
+
# error_box1: gr.update(visible=False),
|
544 |
+
# error_box2: gr.update(visible=False),
|
545 |
+
# error_box3: gr.update(visible=False),
|
546 |
+
# error_box4: gr.update(visible=False),
|
547 |
+
# error_box5: gr.update(visible=False),
|
548 |
+
# error_box6: gr.update(visible=False),
|
549 |
+
# srv_resp_send_data_box: None,
|
550 |
+
# srv_resp_retrieve_data_box: None,
|
551 |
+
# **{box: None for box in check_boxes},
|
552 |
+
}
|
553 |
+
|
554 |
+
|
555 |
+
def process_files(file1, file2):
|
556 |
+
global global_df1, global_df2
|
557 |
+
|
558 |
+
# Read the CSV files
|
559 |
+
df1 = pd.read_csv(file1.name)
|
560 |
+
df2 = pd.read_csv(file2.name)
|
561 |
+
|
562 |
+
# Store them in global variables to access later
|
563 |
+
global_df1 = df1
|
564 |
+
global_df2 = df2
|
565 |
+
|
566 |
+
return {
|
567 |
+
upload_button: gr.update(value="Data uploaded! ✅")
|
568 |
+
}
|
569 |
+
|
570 |
+
|
571 |
+
def encrypt_layer1(user_id_box):
|
572 |
+
global global_df1, global_df2
|
573 |
+
|
574 |
+
# INPUT ONE - RUNNING DATA
|
575 |
+
running_data, risk = statistics(global_df1)
|
576 |
+
running_data = pd.DataFrame(running_data)
|
577 |
+
input_model_1 = running_data.iloc[0, :].to_numpy()
|
578 |
+
input_model_1 = input_model_1.reshape(1, len(input_model_1))
|
579 |
+
|
580 |
+
# INPUT TWO - MENTAL HEALTH DATA
|
581 |
+
data = global_df2.iloc[:,2::].T
|
582 |
+
data.dropna(how='any', inplace=True, axis=0)
|
583 |
+
data = data.T
|
584 |
+
data = np.where((data.values > 1000) | (data.values<600), np.median(data.values), data.values)
|
585 |
+
rr_interpolated = interpolation(data, 4.0)
|
586 |
+
|
587 |
+
results = []
|
588 |
+
|
589 |
+
for i in range(len(data)):
|
590 |
+
results.append(frequency_domain(rr_interpolated[i]))
|
591 |
+
freq_col=['vlf','lf','hf','tot_pow','lf_hf_ratio','peak_vlf','peak_lf','peak_hf']
|
592 |
+
freq_features = pd.DataFrame(results, columns = freq_col)
|
593 |
+
input_model_2 = freq_features.iloc[0, :].to_numpy()
|
594 |
+
input_model_2 = input_model_2.reshape(1, len(input_model_2))
|
595 |
+
|
596 |
+
encrypt_fn(input_model_1, user_id_box, 1)
|
597 |
+
encrypt_fn(input_model_2, user_id_box, 2)
|
598 |
+
|
599 |
+
return {
|
600 |
+
error_box3: gr.update(visible=False, value="Error"),
|
601 |
+
encrypt_btn: gr.update(value="Data encrypted! ✅")
|
602 |
}
|
603 |
|
604 |
|
605 |
+
|
606 |
if __name__ == "__main__":
|
607 |
|
608 |
print("Starting demo ...")
|
609 |
|
610 |
clean_directory()
|
611 |
|
612 |
+
css = """
|
613 |
+
.centered-textbox textarea {
|
614 |
+
font-size: 24px !important;
|
615 |
+
text-align: center;
|
616 |
+
}
|
617 |
+
.large-emoticon textarea {
|
618 |
+
font-size: 72px !important;
|
619 |
+
text-align: center;
|
620 |
+
}
|
621 |
+
"""
|
622 |
+
|
623 |
+
with gr.Blocks(theme="light", css=css, title='AtlHEte') as demo:
|
624 |
|
625 |
# Link + images
|
626 |
gr.Markdown()
|
627 |
gr.Markdown(
|
628 |
"""
|
629 |
<p align="center">
|
630 |
+
<img width=300 src="file/atlhete-high-resolution-logo-black-transparent.png">
|
631 |
</p>
|
632 |
""")
|
633 |
+
|
634 |
+
# Title
|
635 |
+
gr.Markdown("""
|
636 |
+
# AtlHEte
|
637 |
+
## Data loading
|
638 |
+
Upload your running time-series, and your PPG.
|
639 |
+
> The app of AtlHEte would do this automatically.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
640 |
""")
|
641 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
642 |
with gr.Row():
|
643 |
+
file1 = gr.File(label="Upload running time-series")
|
644 |
+
file2 = gr.File(label="Upload PPG")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
645 |
|
|
|
|
|
|
|
|
|
|
|
646 |
|
647 |
+
upload_button = gr.Button("Upload")
|
648 |
+
upload_button.click(process_files, inputs=[file1, file2], outputs=[upload_button])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
649 |
|
650 |
+
# Keys generation
|
651 |
+
gr.Markdown("""
|
652 |
+
## Keys generation
|
653 |
+
Generate the TFHE keys.
|
654 |
+
""")
|
655 |
gen_key_btn = gr.Button("Generate the private and evaluation keys.")
|
656 |
error_box2 = gr.Textbox(label="Error ❌", visible=False)
|
657 |
user_id_box = gr.Textbox(label="User ID:", visible=False)
|
|
|
|
|
|
|
658 |
gen_key_btn.click(
|
659 |
key_gen_fn,
|
|
|
660 |
outputs=[
|
|
|
661 |
user_id_box,
|
|
|
662 |
error_box2,
|
663 |
gen_key_btn,
|
664 |
],
|
665 |
)
|
666 |
|
667 |
+
# Data encryption
|
668 |
+
gr.Markdown("""
|
669 |
+
## Data encryption
|
670 |
+
Encrypt both your running time-series and your PPG.
|
671 |
+
""")
|
672 |
encrypt_btn = gr.Button("Encrypt the data using the private secret key")
|
673 |
error_box3 = gr.Textbox(label="Error ❌", visible=False)
|
674 |
+
encrypt_btn.click(encrypt_layer1, inputs=[user_id_box], outputs=[error_box3, encrypt_btn])
|
675 |
|
676 |
+
|
677 |
+
# Data uploading
|
678 |
+
gr.Markdown("""
|
679 |
+
## Data upload
|
680 |
+
Upload your data safely to us.
|
681 |
+
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
682 |
error_box4 = gr.Textbox(label="Error ❌", visible=False)
|
683 |
|
684 |
+
with gr.Row().style(equal_height=False):
|
685 |
+
with gr.Row():
|
686 |
+
with gr.Column(scale=4):
|
687 |
+
send_input_btn = gr.Button("Send data")
|
688 |
+
with gr.Column(scale=1):
|
689 |
+
srv_resp_send_data_box = gr.Checkbox(label="Data Sent", show_label=False)
|
690 |
|
691 |
send_input_btn.click(
|
692 |
send_input_fn,
|
693 |
+
inputs=[user_id_box],
|
694 |
outputs=[error_box4, srv_resp_send_data_box],
|
695 |
)
|
696 |
|
697 |
+
# Encrypted processing
|
698 |
+
gr.Markdown("""
|
699 |
+
## Encrypted processing
|
700 |
+
Process your <span style='color:grey'>encrypted data</span> with AtlHEte!
|
701 |
+
""")
|
|
|
|
|
|
|
|
|
|
|
702 |
run_fhe_btn = gr.Button("Run the FHE evaluation")
|
703 |
error_box5 = gr.Textbox(label="Error ❌", visible=False)
|
704 |
fhe_execution_time_box = gr.Textbox(label="Total FHE Execution Time:", visible=True)
|
|
|
708 |
outputs=[fhe_execution_time_box, error_box5],
|
709 |
)
|
710 |
|
711 |
+
# Download the report
|
712 |
+
gr.Markdown("""
|
713 |
+
## Download the encrypted report
|
714 |
+
Download your personalized encrypted report...
|
715 |
+
""")
|
|
|
|
|
|
|
|
|
716 |
error_box6 = gr.Textbox(label="Error ❌", visible=False)
|
|
|
|
|
|
|
717 |
with gr.Row():
|
718 |
with gr.Column(scale=4):
|
719 |
get_output_btn = gr.Button("Get data")
|
|
|
722 |
|
723 |
get_output_btn.click(
|
724 |
get_output_fn,
|
725 |
+
inputs=[user_id_box],
|
726 |
outputs=[srv_resp_retrieve_data_box, error_box6],
|
727 |
)
|
728 |
|
729 |
+
# Download the report
|
730 |
+
gr.Markdown("""
|
731 |
+
## Decrypt the report
|
732 |
+
Decrypt the report to know how you are doing!
|
733 |
+
""")
|
734 |
decrypt_btn = gr.Button("Decrypt the output using the private secret key")
|
735 |
error_box7 = gr.Textbox(label="Error ❌", visible=False)
|
|
|
736 |
|
737 |
+
|
738 |
+
# Layout components
|
739 |
+
with gr.Row():
|
740 |
+
tachometer_plot = gr.Plot(label="Running Quality", visible=False)
|
741 |
+
emoticon_display = gr.Textbox(label="Mental Health", visible=False, elem_classes="large-emoticon")
|
742 |
+
|
743 |
+
with gr.Column():
|
744 |
+
decrypt_box = gr.Textbox(label="Decrypted Output:", visible=False, elem_classes="centered-textbox")
|
745 |
+
|
746 |
decrypt_btn.click(
|
747 |
decrypt_fn,
|
748 |
+
inputs=[user_id_box],
|
749 |
+
outputs=[decrypt_box,
|
750 |
+
error_box7,
|
751 |
+
decrypt_btn,
|
752 |
+
tachometer_plot,
|
753 |
+
emoticon_display],
|
|
|
|
|
|
|
|
|
754 |
)
|
755 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
756 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
757 |
|
758 |
+
demo.launch(favicon_path='atlhete-high-resolution-logo-black-transparent.png')
|
atlhete-high-resolution-logo-black-transparent.png
ADDED
data/200_Users_Running_Dataset.csv
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:79f7a734f8f85e763f2feee8344eb3a725b5b9c9e2c50694793411787b4bfe58
|
3 |
+
size 38539031
|
data/data_mental.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
data/dataset_for_last_model.csv
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
stressed,running_score,label
|
2 |
+
0,0.9,0
|
3 |
+
0,0.2,1
|
4 |
+
1,0.8,2
|
5 |
+
1,0.3,3
|
6 |
+
0,0.7,0
|
7 |
+
0,0.1,1
|
8 |
+
1,0.6,2
|
9 |
+
1,0.4,3
|
10 |
+
0,0.9,0
|
11 |
+
0,0.2,1
|
12 |
+
1,0.8,2
|
13 |
+
1,0.3,3
|
14 |
+
0,0.7,0
|
15 |
+
0,0.1,1
|
16 |
+
1,0.6,2
|
17 |
+
1,0.4,3
|
18 |
+
0,0.9,0
|
19 |
+
0,0.2,1
|
20 |
+
1,0.8,2
|
21 |
+
1,0.3,3
|
22 |
+
0,0.7,0
|
23 |
+
0,0.1,1
|
24 |
+
1,0.6,2
|
25 |
+
1,0.4,3
|
26 |
+
0,0.9,0
|
27 |
+
0,0.2,1
|
28 |
+
1,0.8,2
|
29 |
+
1,0.3,3
|
30 |
+
0,0.7,0
|
31 |
+
0,0.1,1
|
32 |
+
1,0.6,2
|
33 |
+
1,0.4,3
|
34 |
+
0,0.9,0
|
35 |
+
0,0.2,1
|
36 |
+
1,0.8,2
|
37 |
+
1,0.3,3
|
38 |
+
0,0.7,0
|
39 |
+
0,0.1,1
|
40 |
+
1,0.6,2
|
41 |
+
1,0.4,3
|
42 |
+
0,0.9,0
|
43 |
+
0,0.2,1
|
44 |
+
1,0.8,2
|
45 |
+
1,0.3,3
|
46 |
+
0,0.7,0
|
47 |
+
0,0.1,1
|
48 |
+
1,0.6,2
|
49 |
+
1,0.4,3
|
50 |
+
0,0.9,0
|
51 |
+
0,0.2,1
|
52 |
+
1,0.8,2
|
53 |
+
1,0.3,3
|
54 |
+
0,0.7,0
|
55 |
+
0,0.1,1
|
56 |
+
1,0.6,2
|
57 |
+
1,0.4,3
|
58 |
+
0,0.9,0
|
59 |
+
0,0.2,1
|
60 |
+
1,0.8,2
|
61 |
+
1,0.3,3
|
62 |
+
0,0.7,0
|
63 |
+
0,0.1,1
|
64 |
+
1,0.6,2
|
65 |
+
1,0.4,3
|
66 |
+
0,0.9,0
|
67 |
+
0,0.2,1
|
68 |
+
1,0.8,2
|
69 |
+
1,0.3,3
|
70 |
+
0,0.7,0
|
71 |
+
0,0.1,1
|
72 |
+
1,0.6,2
|
73 |
+
1,0.4,3
|
74 |
+
0,0.9,0
|
75 |
+
0,0.2,1
|
76 |
+
1,0.8,2
|
77 |
+
1,0.3,3
|
78 |
+
0,0.7,0
|
79 |
+
0,0.1,1
|
80 |
+
1,0.6,2
|
81 |
+
1,0.4,3
|
82 |
+
0,0.9,0
|
83 |
+
0,0.2,1
|
84 |
+
1,0.8,2
|
85 |
+
1,0.3,3
|
86 |
+
0,0.7,0
|
87 |
+
0,0.1,1
|
88 |
+
1,0.6,2
|
89 |
+
1,0.4,3
|
90 |
+
0,0.9,0
|
91 |
+
0,0.2,1
|
92 |
+
1,0.8,2
|
93 |
+
1,0.3,3
|
94 |
+
0,0.7,0
|
95 |
+
0,0.1,1
|
96 |
+
1,0.6,2
|
97 |
+
1,0.4,3
|
data/example_input_ecg_fft.csv
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99
|
2 |
+
14.872875780305444,22.143526988251853,5.73405833896032,22.38238316896958,16.01195632916591,53.47955454704578,41.53482080118708,17.054113973093433,20.95743380535224,39.61597021427792,20.97705171293844,23.996783984159627,15.526737429962628,31.992907356137117,37.18676776040511,25.41643719982816,30.007700296526217,29.914837865617525,10.115828072429668,15.607847026326871,29.747318796194346,17.377050445204127,15.253046802231863,16.92953587957562,17.170784045055033,43.32118785263813,17.69469599923355,32.16649655046516,27.938031982623798,40.755301297596944,43.02687527350755,21.597079118425473,40.57058678337461,24.739171346616665,24.92286456113743,4.131785416296717,34.463390110133744,3.789566396484583,7.445362287451477,33.136452355641815,30.026730043833766,24.30961243447321,32.77248876525434,6.276931786250562,20.878417631293548,12.633505359582188,10.189022776654749,24.478263313589082,17.547982116723503,4.513371272328763,42.82844273951283,26.358588682443795,21.997555953800543,7.620423284616399,22.015751172327132,12.154322312674934,22.930375729089302,20.166418029357256,26.90302697915671,34.58179808249238,25.834930772439396,22.342322667934756,29.425418853557478,21.773226940970737,50.12845435952189,39.91673386861348,41.38879043276297,15.823074888820976,17.96921608496425,30.292411100617493,13.922225414506821,31.779017031257382,39.741361624173656,33.71876565215107,12.394751948389203,14.254466789471014,22.803097137292657,31.18517133850695,28.74530687154142,25.194209821400158,15.706591952201508,36.71309490686993,21.250804038791582,17.445407858967666,20.114994941271135,23.431081219725876,8.99856106960488,26.47934941287815,20.60792244301221,32.04647626648783,36.907558200676306,45.01335412112925,12.243172103437661,31.077506555833324,23.64144356673854,13.327598689491015,24.235287209737933,22.021793688596837,46.732394420148154,30.598274179950252,1
|
3 |
+
6.462939119410598,27.421003112568716,28.593529917553667,16.109018699578034,17.319860601868363,33.37518268922808,28.57360956140721,20.094393334873242,41.56525617725834,29.439704995353438,10.254127725495934,3.9421058414118586,42.249553898630154,11.662736220533482,33.66196424966374,27.695887070663204,20.811366780493557,34.7704447824292,34.8376481918154,39.652131031106,42.402542707640464,36.588967115231846,16.24920098656159,23.35912746179328,22.721267193497265,18.750723384276494,38.67613444984027,38.725409498413086,26.093212083028778,10.984630738293362,15.488340473195093,21.970543536287618,10.77067588847615,37.91815001361052,36.63365842040771,33.89634205321656,17.362067529092656,34.911672625880435,33.88468054964107,17.873944296306576,26.371343114958478,19.78890114509962,15.549990617258496,34.0086736499675,46.014853871272216,25.433724293552384,31.089194585153596,11.57807385159379,13.775065185289979,31.31274380991934,31.28785544666112,42.71159723413852,40.04592110581326,42.977675266011886,26.519018169327925,6.645166938386291,33.00270584791462,11.663462005358642,20.451658904299038,27.588066431011264,15.604012333593756,21.784965571742493,9.321790348659414,6.344393830025857,35.322729707407106,37.492698153990624,35.133044766201465,42.49233702351144,28.789889680895634,27.948760853517108,29.91558894090087,11.303899264510436,22.55780873653814,35.34903414754004,42.25495522351421,43.69951115865071,17.134966788062155,39.06990459112003,20.70540846849873,6.797972590030854,33.190952150307346,17.036352333501863,15.93550911214561,22.825483131603118,36.5697182150259,33.33220442885662,18.742499330228334,22.873413183882178,20.121967152447976,12.621877407580783,23.79693523210685,37.84186263858249,31.86428438827771,27.124493332607056,13.012752833308724,29.983918825843748,58.719790501040265,25.458623422525765,20.20750792280666,46.71581971750777
|
data/synthetic_ecg_fft_dataset.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
data_for_demo/focus_on_technique_mental.csv
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
subject ID,labels,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681
|
2 |
+
sub_4,stress,398.0,252.0,426.0,636.0,640.0,634.0,662.0,632.0,622.0,628.0,624.0,632.0,658.0,648.0,634.0,630.0,626.0,630.0,646.0,610.0,644.0,658.0,664.0,672.0,670.0,652.0,664.0,674.0,680.0,660.0,668.0,654.0,656.0,668.0,664.0,672.0,682.0,662.0,660.0,622.0,658.0,616.0,634.0,646.0,654.0,650.0,636.0,642.0,648.0,632.0,634.0,674.0,672.0,670.0,668.0,662.0,652.0,642.0,638.0,652.0,658.0,652.0,656.0,658.0,670.0,668.0,664.0,658.0,654.0,638.0,632.0,614.0,622.0,644.0,646.0,666.0,684.0,708.0,684.0,692.0,704.0,718.0,710.0,712.0,700.0,672.0,666.0,662.0,654.0,632.0,634.0,662.0,678.0,676.0,688.0,676.0,682.0,684.0,690.0,670.0,696.0,684.0,682.0,656.0,648.0,666.0,656.0,664.0,660.0,690.0,682.0,688.0,684.0,660.0,662.0,676.0,698.0,660.0,672.0,688.0,680.0,686.0,676.0,686.0,674.0,676.0,680.0,684.0,678.0,684.0,660.0,670.0,668.0,654.0,662.0,656.0,664.0,668.0,662.0,676.0,662.0,648.0,682.0,680.0,688.0,696.0,682.0,668.0,630.0,632.0,678.0,642.0,634.0,664.0,642.0,646.0,664.0,676.0,692.0,710.0,700.0,666.0,688.0,702.0,688.0,654.0,662.0,672.0,682.0,688.0,672.0,680.0,674.0,682.0,674.0,684.0,690.0,676.0,658.0,626.0,648.0,652.0,636.0,642.0,646.0,648.0,614.0,608.0,628.0,616.0,662.0,586.0,606.0,588.0,590.0,604.0,602.0,608.0,618.0,628.0,666.0,672.0,652.0,664.0,666.0,650.0,628.0,648.0,636.0,638.0,644.0,638.0,626.0,630.0,642.0,660.0,658.0,646.0,624.0,654.0,656.0,654.0,646.0,616.0,628.0,652.0,648.0,650.0,644.0,620.0,642.0,654.0,640.0,656.0,664.0,686.0,670.0,708.0,668.0,686.0,690.0,674.0,684.0,688.0,674.0,670.0,662.0,666.0,682.0,680.0,670.0,674.0,670.0,684.0,668.0,678.0,682.0,700.0,698.0,686.0,670.0,666.0,662.0,644.0,654.0,652.0,650.0,652.0,668.0,662.0,668.0,664.0,646.0,644.0,650.0,672.0,624.0,616.0,598.0,608.0,622.0,620.0,606.0,624.0,636.0,634.0,648.0,618.0,616.0,644.0,628.0,640.0,636.0,646.0,628.0,612.0,616.0,618.0,628.0,624.0,642.0,620.0,608.0,626.0,610.0,644.0,614.0,622.0,588.0,602.0,614.0,618.0,648.0,626.0,632.0,638.0,628.0,632.0,622.0,616.0,592.0,594.0,590.0,588.0,590.0,604.0,602.0,600.0,608.0,622.0,656.0,654.0,642.0,652.0,654.0,598.0,614.0,616.0,626.0,648.0,614.0,600.0,620.0,612.0,606.0,604.0,590.0,588.0,584.0,592.0,612.0,648.0,630.0,638.0,642.0,638.0,634.0,638.0,626.0,622.0,624.0,600.0,598.0,604.0,624.0,626.0,638.0,646.0,640.0,656.0,682.0,684.0,700.0,686.0,676.0,658.0,660.0,620.0,626.0,630.0,634.0,644.0,642.0,682.0,660.0,622.0,602.0,674.0,634.0,620.0,598.0,582.0,600.0,598.0,620.0,622.0,634.0,628.0,640.0,654.0,658.0,654.0,640.0,636.0,648.0,660.0,650.0,658.0,672.0,644.0,650.0,658.0,646.0,648.0,622.0,616.0,626.0,636.0,612.0,640.0,650.0,656.0,674.0,680.0,688.0,672.0,676.0,660.0,664.0,652.0,628.0,632.0,626.0,630.0,628.0,602.0,614.0,630.0,640.0,646.0,644.0,658.0,670.0,686.0,674.0,678.0,682.0,654.0,668.0,660.0,638.0,656.0,650.0,642.0,640.0,646.0,614.0,626.0,648.0,644.0,640.0,658.0,650.0,648.0,638.0,642.0,636.0,610.0,636.0,634.0,630.0,636.0,628.0,638.0,632.0,646.0,642.0,648.0,664.0,656.0,668.0,632.0,648.0,632.0,640.0,646.0,584.0,600.0,580.0,584.0,578.0,592.0,600.0,606.0,616.0,634.0,648.0,666.0,692.0,704.0,698.0,710.0,664.0,682.0,680.0,696.0,658.0,664.0,642.0,628.0,646.0,630.0,634.0,654.0,662.0,624.0,648.0,658.0,650.0,656.0,668.0,662.0,670.0,664.0,628.0,654.0,628.0,604.0,600.0,608.0,616.0,660.0,662.0,666.0,700.0,696.0,684.0,680.0,682.0,680.0,694.0,676.0,690.0,686.0,676.0,648.0,656.0,658.0,668.0,646.0,648.0,662.0,684.0,678.0,686.0,678.0,640.0,612.0,614.0,626.0,636.0,610.0,594.0,592.0,584.0,598.0,606.0,662.0,666.0,680.0,692.0,680.0,682.0,672.0,644.0,650.0,630.0,616.0,604.0,598.0,600.0,610.0,646.0,676.0,690.0,688.0,702.0,712.0,704.0,700.0,714.0,720.0,692.0,592.0,356.0,352.0,1920.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
data_for_demo/focus_on_technique_running.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
data_for_demo/rest_mental.csv
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
subject ID,labels,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681
|
2 |
+
sub_15,stress,832.0,834.0,826.0,754.0,752.0,768.0,756.0,770.0,748.0,718.0,738.0,720.0,674.0,692.0,722.0,674.0,688.0,716.0,710.0,666.0,674.0,708.0,696.0,660.0,642.0,660.0,654.0,642.0,634.0,660.0,676.0,684.0,648.0,658.0,686.0,672.0,636.0,660.0,702.0,684.0,638.0,670.0,734.0,700.0,636.0,686.0,718.0,662.0,652.0,666.0,676.0,696.0,666.0,660.0,682.0,674.0,698.0,666.0,686.0,716.0,706.0,698.0,682.0,670.0,640.0,620.0,650.0,690.0,736.0,682.0,706.0,730.0,728.0,676.0,680.0,704.0,708.0,686.0,720.0,748.0,768.0,782.0,784.0,764.0,702.0,696.0,712.0,688.0,654.0,622.0,664.0,802.0,856.0,870.0,866.0,830.0,856.0,832.0,784.0,800.0,778.0,812.0,810.0,778.0,696.0,694.0,688.0,656.0,682.0,762.0,742.0,728.0,774.0,758.0,732.0,756.0,758.0,744.0,748.0,706.0,698.0,742.0,740.0,720.0,732.0,764.0,776.0,736.0,780.0,784.0,732.0,692.0,694.0,774.0,754.0,732.0,720.0,774.0,744.0,732.0,762.0,702.0,708.0,738.0,752.0,714.0,704.0,744.0,702.0,706.0,726.0,730.0,708.0,758.0,772.0,718.0,714.0,750.0,732.0,686.0,700.0,710.0,694.0,672.0,698.0,742.0,708.0,704.0,712.0,718.0,684.0,668.0,708.0,716.0,680.0,716.0,728.0,700.0,692.0,744.0,706.0,660.0,690.0,736.0,710.0,696.0,710.0,720.0,688.0,728.0,760.0,732.0,740.0,762.0,722.0,678.0,694.0,732.0,734.0,682.0,700.0,728.0,702.0,672.0,682.0,720.0,688.0,712.0,782.0,770.0,674.0,726.0,708.0,668.0,666.0,688.0,678.0,656.0,692.0,716.0,694.0,686.0,738.0,722.0,666.0,664.0,700.0,690.0,652.0,670.0,702.0,672.0,666.0,678.0,712.0,670.0,668.0,684.0,708.0,660.0,636.0,658.0,674.0,658.0,650.0,694.0,688.0,664.0,656.0,724.0,744.0,708.0,718.0,724.0,688.0,676.0,678.0,690.0,672.0,640.0,646.0,678.0,714.0,716.0,674.0,702.0,740.0,696.0,668.0,700.0,698.0,660.0,662.0,674.0,658.0,646.0,634.0,668.0,670.0,668.0,642.0,688.0,708.0,656.0,636.0,660.0,676.0,656.0,660.0,678.0,664.0,642.0,638.0,662.0,642.0,660.0,664.0,708.0,666.0,642.0,666.0,634.0,626.0,656.0,650.0,640.0,636.0,688.0,716.0,684.0,646.0,650.0,652.0,636.0,606.0,612.0,650.0,648.0,696.0,682.0,668.0,718.0,690.0,646.0,644.0,650.0,648.0,630.0,614.0,636.0,650.0,642.0,606.0,632.0,622.0,606.0,596.0,608.0,632.0,606.0,588.0,596.0,600.0,598.0,590.0,584.0,592.0,600.0,582.0,596.0,612.0,614.0,598.0,574.0,584.0,586.0,578.0,564.0,574.0,592.0,594.0,582.0,598.0,612.0,594.0,586.0,600.0,598.0,588.0,640.0,580.0,576.0,568.0,548.0,572.0,596.0,610.0,608.0,622.0,628.0,626.0,610.0,604.0,606.0,604.0,580.0,596.0,584.0,596.0,582.0,568.0,588.0,584.0,602.0,604.0,564.0,584.0,600.0,622.0,562.0,612.0,668.0,658.0,630.0,612.0,624.0,664.0,654.0,624.0,634.0,656.0,674.0,670.0,662.0,678.0,706.0,676.0,656.0,672.0,686.0,654.0,652.0,662.0,652.0,642.0,656.0,620.0,622.0,650.0,722.0,746.0,668.0,664.0,674.0,676.0,644.0,632.0,644.0,674.0,702.0,672.0,696.0,704.0,746.0,690.0,670.0,702.0,714.0,690.0,658.0,698.0,708.0,684.0,662.0,676.0,702.0,674.0,638.0,666.0,692.0,678.0,646.0,738.0,696.0,660.0,682.0,696.0,712.0,678.0,676.0,692.0,694.0,666.0,646.0,706.0,726.0,682.0,702.0,776.0,756.0,702.0,680.0,700.0,688.0,654.0,668.0,688.0,680.0,656.0,692.0,708.0,670.0,654.0,684.0,672.0,638.0,650.0,664.0,658.0,628.0,622.0,652.0,638.0,632.0,650.0,694.0,722.0,670.0,638.0,656.0,644.0,630.0,626.0,644.0,658.0,634.0,624.0,658.0,662.0,648.0,660.0,666.0,686.0,650.0,622.0,642.0,622.0,616.0,624.0,686.0,672.0,674.0,698.0,738.0,674.0,676.0,714.0,696.0,668.0,662.0,686.0,672.0,722.0,766.0,708.0,704.0,740.0,754.0,696.0,712.0,722.0,694.0,714.0,760.0,778.0,728.0,710.0,700.0,656.0,672.0,696.0,726.0,680.0,676.0,700.0,660.0,648.0,694.0,708.0,678.0,688.0,718.0,728.0,708.0,728.0,762.0,744.0,694.0,684.0,608.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
data_for_demo/rest_running.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
deployment_files/.DS_Store
ADDED
Binary file (6.15 kB). View file
|
|
deployment_files/.fhe_keys/2820248940/15341225681980396668/secretKey_0
ADDED
Binary file (15.7 kB). View file
|
|
deployment_files/.fhe_keys/2820248940/encrypted_input
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:1e509a3079177c527a89695b418b96d9050c72a25f2c7a81d89d17e09e99b2b1
|
3 |
+
size 2003208
|
deployment_files/.fhe_keys/2820248940/evaluation_key
ADDED
Binary file (64 Bytes). View file
|
|
deployment_files/client/client.specs.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"keyset":{"lweSecretKeys":[{"id":0,"params":{"lweDimension":1955,"integerPrecision":64,"keyType":"binary"}}],"lweBootstrapKeys":[],"lweKeyswitchKeys":[],"packingKeyswitchKeys":[]},"circuits":[{"inputs":[{"rawInfo":{"shape":{"dimensions":[1,128,1956]},"integerPrecision":64,"isSigned":false},"typeInfo":{"lweCiphertext":{"abstractShape":{"dimensions":[1,128]},"concreteShape":{"dimensions":[1,128,1956]},"integerPrecision":64,"encryption":{"keyId":0,"variance":3.0674321942082692e-30,"lweDimension":1955,"modulus":{"modulus":{"native":{}}}},"compression":"none","encoding":{"integer":{"width":30,"isSigned":true,"mode":{"native":{}}}}}}}],"outputs":[{"rawInfo":{"shape":{"dimensions":[1,41,1956]},"integerPrecision":64,"isSigned":false},"typeInfo":{"lweCiphertext":{"abstractShape":{"dimensions":[1,41]},"concreteShape":{"dimensions":[1,41,1956]},"integerPrecision":64,"encryption":{"keyId":0,"variance":3.0674321942082692e-30,"lweDimension":1955,"modulus":{"modulus":{"native":{}}}},"compression":"none","encoding":{"integer":{"width":30,"isSigned":true,"mode":{"native":{}}}}}}}],"name":"main"}]}
|
deployment_files/client/serialized_processing.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"model_type": {"type_name": "type", "serialized_value": "504b03041400000000003a7e33581c8da575be000000be0000000b000000736368656d612e6a736f6e7b0a2020225f5f636c6173735f5f223a20224c6f67697374696352656772657373696f6e222c0a2020225f5f6d6f64756c655f5f223a2022636f6e63726574652e6d6c2e736b6c6561726e2e6c696e6561725f6d6f64656c222c0a2020225f5f6c6f616465725f5f223a2022547970654e6f6465222c0a2020225f5f69645f5f223a2031313231383330323238382c0a20202270726f746f636f6c223a20302c0a2020225f736b6f70735f76657273696f6e223a2022302e352e30220a7d504b010214031400000000003a7e33581c8da575be000000be0000000b0000000000000000000000800100000000736368656d612e6a736f6e504b0506000000000100010039000000e70000000000"}, "model_post_processing_params": {}, "input_quantizers": [{"type_name": "UniformQuantizer", "serialized_value": {"n_bits": 13, "is_signed": true, "is_symmetric": false, "is_qat": false, "is_narrow": false, "is_precomputed_qat": false, "rmax": {"type_name": "numpy_float", "serialized_value": 1.0, "dtype": "float64"}, "rmin": {"type_name": "numpy_float", "serialized_value": 0.0, "dtype": "float64"}, "uvalues": {"type_name": "numpy_array", "serialized_value": [0.0, 1.0], "dtype": "float64"}, "scale": {"type_name": "numpy_float", "serialized_value": 0.00012208521548040532, "dtype": "float64"}, "zero_point": {"type_name": "numpy_integer", "serialized_value": -4096, "dtype": "int64"}, "offset": 4096, "no_clipping": false}}], "output_quantizers": [{"type_name": "UniformQuantizer", "serialized_value": {"is_signed": false, "is_symmetric": false, "is_qat": false, "is_narrow": false, "is_precomputed_qat": false, "rmax": null, "rmin": null, "uvalues": null, "scale": {"type_name": "numpy_float", "serialized_value": 6.042995485646492e-08, "dtype": "float64"}, "zero_point": {"type_name": "numpy_array", "serialized_value": [[70164480, 84975616, -21110784, 89104384, 27262976, 40034304, 26345472, -45858816, 39600128, -117047296, -104685568, -51388416, 17866752, 20783104, 93233152, 99688448, 3309568, 164372480, -97656832, -86663168, 76013568, 44916736, -127205376, 42672128, -59998208, -82386944, -85319680, 27385856, 2473984, 15482880, -39256064, -8798208, 109559808, 13656064, 16007168, -43048960, -8814592, -121692160, -74735616, 63086592, -12410880]], "dtype": "int64"}, "offset": 0, "no_clipping": true}}], "is_fitted": true}
|
deployment_files/client/versions.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"concrete-python": "2.5", "concrete-ml": "1.4.0", "python": "3.10.11"}
|
deployment_files/client_dir/2820248940_encrypted_output
ADDED
Binary file (642 kB). View file
|
|
deployment_files/server/circuit.mlir
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
module {
|
2 |
+
func.func @main(%arg0: tensor<1x128x!FHE.esint<30>>) -> tensor<1x41x!FHE.esint<30>> {
|
3 |
+
%cst = arith.constant dense<"0x3DF8FF7F34FAFF7FB6F9FF7F8DFAFF7F01FBFF7FCBFAFF7F0AFBFF7FA2030000C50C0000BBFBFF7F78FAFF7F41FBFF7FEBFAFF7FA7080000CE09000085FAFF7FAAFAFF7FB7FAFF7F2CFAFF7F22020000B6F7FF7FBFF5FF7FC1F9FF7F25FBFF7FA6FBFF7FC4FBFF7FA1FBFF7F40F9FF7F34070000C2FBFF7F9FFBFF7F5AFBFF7F60FAFF7FF1FAFF7F9FF9FF7FC4FBFF7F49FAFF7F27FBFF7FFEFAFF7F8CF9FF7F24FBFF7F050800003EF8FF7F1FFBFF7F10F9FF7F2DFAFF7F2AFAFF7F19FAFF7F9902000050FAFF7F64FBFF7FAF02000034FBFF7FEBF9FF7FF60500001F070000B3F9FF7F66FAFF7FFCF9FF7F97FBFF7FC6FAFF7F9AFAFF7F74FBFF7F78FBFF7F4DFAFF7F8AFBFF7FAEFBFF7F74FBFF7F47060000A3FAFF7FCAF9FF7F21FBFF7F1FFAFF7F8CF9FF7FD3FAFF7FBEFAFF7F6BFBFF7F5B04000058FBFF7F1CFBFF7F69F8FF7FA7FAFF7F7CFAFF7FD0FBFF7F25FCFF7FAEFBFF7FEDFBFF7F17FCFF7FEDFBFF7FDDFBFF7F9CFBFF7F4AFCFF7F46FCFF7F30FCFF7FE1FBFF7F0DF9FF7F4C0E0000CFFBFF7F1DFCFF7FD6FBFF7F4FFCFF7F2EFCFF7F20FCFF7F56FCFF7F58FCFF7FFFFBFF7F39FCFF7F49FCFF7F39FCFF7F40FBFF7FFCFBFF7F41FCFF7F26FCFF7F0AFCFF7FDFFBFF7F24FCFF7F1AFCFF7F40FCFF7F86FBFF7F55FCFF7F4FFCFF7FD1FBFF7F10FCFF7F8AFBFF7F6CFBFF7F06FCFF7F9F0A0000BEFBFF7FC6FBFF7FC1FBFF7FEEFBFF7F35FCFF7FB7010000F6FBFF7F18FCFF7FAEFBFF7FE3FBFF7F90FBFF7FAAFBFF7FCEFBFF7FD1FBFF7F45FCFF7F31FCFF7FE6FBFF7F4AFCFF7F4DFCFF7F83FBFF7F2CFCFF7F3EFCFF7F28FCFF7FCEFBFF7F28FCFF7F74FBFF7F0CFCFF7FE5FBFF7FA2FBFF7F14FCFF7FF6FBFF7F25FBFF7FE8FBFF7FC1FBFF7F00FCFF7F6CFBFF7FE6FBFF7F98FBFF7F91FBFF7F0CFCFF7F0D0B0000CBFBFF7F0FFCFF7FCAFBFF7F46FCFF7F36FCFF7F1DFCFF7F42FCFF7F24FCFF7FBBFBFF7FEBFBFF7F9AFBFF7FB0FBFF7F0DFCFF7FD7FBFF7F4BFCFF7F3FFCFF7FF6FBFF7F4CFCFF7F55FCFF7FEDFBFF7F34FCFF7F47FCFF7F32FCFF7FE4FBFF7F3DFCFF7FF0FBFF7F1BFCFF7FF0FBFF7FBDFBFF7F1DFCFF7FFDFBFF7F1BFCFF7FF2FBFF7F49FCFF7F2DFCFF7F7CFBFF7FFBFBFF7F1BFBFF7F2EFAFF7F9AFBFF7F8109000067FBFF7F2BF9FF7F66FBFF7F6EF9FF7FA0FBFF7F0600000055020000C6FBFF7F23FBFF7F73FBFF7F42FBFF7FB2F9FF7F92FAFF7F89F7FF7F84FAFF7FD9FBFF7F36FBFF7F7DFBFF7FF8FAFF7FD5FAFF7F60FBFF7F0DFBFF7FE8FBFF7FDEFAFF7FBCFAFF7F96050000BFFBFF7F87FBFF7FE9F9FF7FB6F9FF7F50FBFF7FB50200006CFBFF7F12010000FE03000004FBFF7F67FBFF7F48FAFF7F26FBFF7FF6FAFF7F14FBFF7F88F9FF7F9CFBFF7F9EFAFF7F82FAFF7F3FF4FF7FE5FBFF7F6E030000DAFBFF7F66FBFF7F2CFBFF7F88FAFF7FB7FAFF7F9CFBFF7F44FBFF7FB00300007EFAFF7FF0F6FF7F8C0A0000A5030000B6FBFF7FF1FBFF7FA9FBFF7FF1FBFF7FD4FAFF7F65F9FF7F97F9FF7FE8FBFF7FEB0600000EFBFF7F0EFBFF7F7BFAFF7FF7FBFF7FA606000091FBFF7FD9FAFF7F2EFBFF7F88FBFF7FBEFAFF7F7FFBFF7FAFFBFF7F5CFBFF7FBBFBFF7F7AFBFF7FCBFBFF7FC7FBFF7F57FBFF7FFCFBFF7FB7FBFF7F0AFCFF7F84FBFF7F330B00000EF8FF7F93FAFF7F6A090000F3F8FF7F1FFCFF7F1EFCFF7F06FCFF7FFAFBFF7FE6FBFF7F50FBFF7F0EFCFF7FECFBFF7F18FCFF7F3FFBFF7F29FBFF7F7CF9FF7FD3FBFF7FDDFBFF7FDEFAFF7F50FBFF7F84FBFF7FD2FBFF7F82FBFF7F08FCFF7F030600008DFAFF7FD4FBFF7FD3FBFF7FD1FBFF7FEDFBFF7FC8FBFF7F7BFBFF7FD9FBFF7F05FCFF7F35FCFF7F17FCFF7F25FCFF7F45FCFF7FE6FBFF7FE1FBFF7F53FBFF7FE8FBFF7F59FBFF7FBF0800007DF9FF7F41FCFF7F45FCFF7F28FCFF7F3AFCFF7F50FCFF7F36FBFF7F0AFCFF7FF2FAFF7F07FCFF7F00FCFF7F2AFCFF7F22FCFF7F3C05000008FCFF7FF0FAFF7FCBFBFF7F80FBFF7F0FFCFF7F05FCFF7F29FCFF7F11FCFF7FC5FBFF7F12FCFF7F15FCFF7F18FCFF7F0CFCFF7F12FCFF7F21FCFF7FFBFBFF7F2CFCFF7F55FCFF7F25FCFF7F39FCFF7F52FCFF7F42FCFF7F1BFCFF7F7DFBFF7F29FCFF7F84FBFF7F1B0900009BF9FF7F4BFCFF7F53FCFF7F4AFCFF7F41FCFF7F55FCFF7FBFFBFF7F4CFCFF7F48FCFF7F47FCFF7F2EFCFF7F37FCFF7F45FCFF7F16FCFF7F2DFCFF7F9FFBFF7F0EFCFF7FF7FBFF7F1DFCFF7F2FFCFF7F2FFCFF7F25FCFF7F10FCFF7F33FCFF7FBCFBFF7F6B0B000019FCFF7F9BFBFF7FD8FBFF7F59FBFF7FD8FBFF7F20FCFF7F40FCFF7F3AFCFF7F46FCFF7F2AFCFF7FCBFBFF7F01FCFF7FC9FBFF7FC5FBFF7F15FCFF7FEDFBFF7F4EFCFF7F46FCFF7F14FCFF7F59FCFF7F33FCFF7FF5FBFF7F38FCFF7F49FCFF7F35FCFF7F17FBFF7FEAFBFF7FECFBFF7F1FFCFF7FF9FBFF7FD2FBFF7F24FCFF7F09FCFF7F1DFCFF7FFFFBFF7F4AFCFF7F32FCFF7F94FBFF7F07FCFF7F1FF8FF7F3AF7FF7F3601000049F7FF7FE7F8FF7F40F8FF7FA7F8FF7F88F8FF7FF403000019FAFF7F690000000DFAFF7F73F8FF7F47F8FF7FB7F7FF7FF1040000000300000F060000F0FEFF7FBDF7FF7F02F2FF7F6E030000A3FFFF7FDCF5FF7FACF9FF7FE00000009AFAFF7FBDF8FF7FD6020000EA00000072F8FF7F21F9FF7F1A0500004003000064020000C9F7FF7F1BF9FF7FEA000000CCFFFF7FBDF7FF7F57F9FF7F72FAFF7F33FBFF7FE8FBFF7F0BFBFF7F85FBFF7FCFFBFF7F84FBFF7FD3FBFF7F99FBFF7F37FCFF7F3EFCFF7F04FCFF7F6FFBFF7FD40A0000CEF7FF7F50FBFF7F4FFBFF7F6CFBFF7F3CFCFF7F18FCFF7FCEFBFF7F45FCFF7F4EFCFF7FA9FBFF7F18FCFF7F36FCFF7F18FCFF7F24FBFF7FEEFBFF7F24FCFF7FF5FBFF7FBAFBFF7F66FBFF7FECFBFF7FD2FBFF7F25FCFF7F5FFBFF7F4BFCFF7F27FCFF7F65090000C7FBFF7F21FBFF7F01FCFF7F37FCFF7FEBFBFF7F10FCFF7F2EFCFF7F10FCFF7FF5FBFF7FC4FBFF7F50FCFF7F4EFCFF7F3DFCFF7F0AFCFF7F110C000065F8FF7F06FCFF7FA7FBFF7F15FCFF7F53FCFF7F38FCFF7F35FCFF7F59FCFF7F5AFCFF7F1FFCFF7F43FCFF7F4FFCFF7F43FCFF7F9BFBFF7F13FCFF7F4EFCFF7F37FCFF7F23FCFF7F0FFCFF7F37FCFF7F31FCFF7F49FCFF7FC6FBFF7F58FCFF7F3DFCFF7FF8FAFF7F27FCFF7F91F9FF7FE0F7FF7F33F9FF7FB0F8FF7FECF9FF7F8A030000F1F9FF7FE5000000DFF0FF7F58FFFF7F79000000CB000000D4F9FF7F9BF9FF7FD3F8FF7F09F9FF7F64F9FF7F41F6FF7F43F5FF7F2A000000000500000D0800001F010000A8F9FF7F9100000092010000CEFFFF7F0CF9FF7F7D03000011F5FF7F14F9FF7F45FAFF7FEEF8FF7F00F9FF7F16F9FF7FD20000001FFAFF7F2DFFFF7F8A0300007FF9FF7F0503000033FCFF7F34FCFF7F4BFCFF7F2DFCFF7F42FCFF7F24FCFF7FF0FBFF7F33FCFF7F5CFCFF7F54FCFF7F58FCFF7F30FCFF7F38FCFF7F45FCFF7F39FCFF7F3AFCFF7F4BFCFF7F47FCFF7F5CFCFF7F38FCFF7F21FCFF7F4AFCFF7F59FCFF7F03FCFF7FB0FBFF7F1FFCFF7F6702000043FCFF7F4AFCFF7F5AFCFF7F11FCFF7F44FCFF7F41FCFF7F53FCFF7F4AFCFF7F4EFCFF7F43FCFF7F5AFCFF7F50FCFF7F2DFCFF7F29FCFF7FD8FBFF7FDAFBFF7F16FCFF7FCDFBFF7F89FBFF7FE6FBFF7FB1FBFF7FFBFBFF7F2FFCFF7F31FCFF7F22FCFF7F83FBFF7FE7FBFF7F0DFCFF7FE4FBFF7FEBFBFF7FC5FBFF7F79FBFF7F4CFCFF7F20FCFF7FB4FBFF7FDCFBFF7F42FCFF7F52FBFF7FE7FAFF7F070300007002000005FCFF7F25FCFF7F82FBFF7FE40300000DFCFF7F00FBFF7F4DFBFF7FBBFBFF7F2BFCFF7F08FCFF7F44FCFF7FF3FBFF7FC9FBFF7FE3FBFF7F33FCFF7F34FCFF7F4BFCFF7F2DFCFF7F42FCFF7F24FCFF7FF0FBFF7F33FCFF7F5CFCFF7F54FCFF7F58FCFF7F30FCFF7F38FCFF7F45FCFF7F39FCFF7F3AFCFF7F4BFCFF7F47FCFF7F5CFCFF7F38FCFF7F21FCFF7F4AFCFF7F59FCFF7F03FCFF7FB0FBFF7F1FFCFF7F6702000043FCFF7F4AFCFF7F5AFCFF7F11FCFF7F44FCFF7F41FCFF7F53FCFF7F4AFCFF7F4EFCFF7F43FCFF7F5AFCFF7F50FCFF7F2DFCFF7F29FCFF7F07FCFF7F11FCFF7F3AFCFF7F03FCFF7FC7FBFF7FFDFBFF7FCEFBFF7F23FCFF7F59FCFF7F49FCFF7F51FCFF7F60FBFF7F12FCFF7F28FCFF7F11FCFF7F98FBFF7F3DFCFF7FF3FBFF7F4EFCFF7F27FCFF7FDAFBFF7F3DFCFF7F52FCFF7FECFBFF7F750300009AFBFF7FE301000027FCFF7FEEFBFF7F15FCFF7FCEFBFF7F2CFCFF7F2DFCFF7F49FCFF7F37FCFF7FDCFBFF7F26FCFF7F40FCFF7F2FFCFF7FFEFBFF7FF5FBFF7FD4FBFF7F62FBFF7F35FBFF7FBBFBFF7F93FBFF7FF3FAFF7FE4FBFF7F2CFBFF7FFCFAFF7FBCFBFF7F0DFCFF7F1B030000D9FBFF7FC0FBFF7F81FBFF7F32FBFF7FB5FBFF7F55FAFF7FFBFBFF7F38FBFF7F89FBFF7F70FAFF7FD9FAFF7F03FCFF7F0303000058FBFF7F83FBFF7FC5FBFF7F6B090000CCFBFF7FA5FBFF7FFFFBFF7FBCFBFF7F1CFCFF7FAFFBFF7FA8F9FF7F00FCFF7F5C0300006DFBFF7FBEFBFF7F31FBFF7FF6FBFF7F03FCFF7F36FCFF7FF0FBFF7FBBFBFF7FECFBFF7F0DFCFF7F16FCFF7F59FCFF7F45FCFF7F4FFCFF7F7703000003FCFF7F20FCFF7F05FCFF7F8AFBFF7F36FCFF7FECFBFF7F4DFCFF7F1DFCFF7FC2FBFF7F39FCFF7F51FCFF7F24FCFF7F5A03000088FBFF7FA6FBFF7F1EFCFF7F8FFBFF7F13FCFF7FB9FBFF7F20FCFF7F1FFCFF7F40FCFF7F31FCFF7FDAFBFF7F1CFCFF7F33FCFF7F2BFCFF7FEAFBFF7F77FBFF7F99FBFF7F9EFBFF7F07FCFF7FC0FBFF7FF0FBFF7F80FBFF7F9CFBFF7FC1040000D2FAFF7FF0FBFF7FDAFAFF7FB3030000D7FBFF7F43FBFF7FD3FAFF7FF0FBFF7F20FCFF7F1FFCFF7F03FCFF7FF7030000BAFAFF7F89FAFF7FE1FBFF7F90FBFF7FC9FAFF7FB0FBFF7FFB0100008BFBFF7F78FAFF7F45FCFF7F89FBFF7FFDFBFF7FC2FBFF7F22FCFF7FDFFBFF7F08FCFF7FE8FBFF7F90FBFF7F05FCFF7FBCFBFF7F35FBFF7FBCFBFF7F6B0B000019FCFF7F9BFBFF7FD8FBFF7F59FBFF7FD8FBFF7F20FCFF7F40FCFF7F3AFCFF7F46FCFF7F2AFCFF7FCBFBFF7F01FCFF7FC9FBFF7FC5FBFF7F15FCFF7FEDFBFF7F4EFCFF7F46FCFF7F14FCFF7F59FCFF7F33FCFF7FF5FBFF7F38FCFF7F49FCFF7F35FCFF7F17FBFF7FEAFBFF7FECFBFF7F1FFCFF7FF9FBFF7FD2FBFF7F24FCFF7F09FCFF7F1DFCFF7FFFFBFF7F4AFCFF7F32FCFF7F94FBFF7F07FCFF7F22FCFF7F27FCFF7F47FCFF7F19FCFF7F37FCFF7F14FCFF7F2FFCFF7F27FCFF7F5CFCFF7F50FCFF7F56FCFF7F3C0400002AFCFF7F3DFCFF7F2DFCFF7F2CFCFF7F44FCFF7F40FCFF7F5BFCFF7F2EFCFF7F09FCFF7F47FCFF7F57FCFF7F3BFCFF7F92FBFF7F0EFCFF7F32FCFF7F3AFCFF7FEBFBFF7F59FCFF7FFDFBFF7F38FCFF7F33FCFF7F4BFCFF7F44FCFF7F4CFCFF7F3AFCFF7F4CFCFF7F4BFCFF7F1AFCFF7FADFBFF7F94FBFF7F5AFAFF7FC9FBFF7FBFFAFF7FABFBFF7FCE060000BFFBFF7FF2FAFF7F03FCFF7F9500000096FBFF7FD5FBFF7F9DFBFF7F1BFBFF7FBDFBFF7F11FBFF7FF3080000A1F5FF7F18FCFF7FEDFBFF7F04FAFF7F1BFCFF7FDCFBFF7FD1FAFF7FAEFBFF7FFBFBFF7FF9FBFF7F30FBFF7F2BFBFF7F21FBFF7FD0FBFF7FCAFBFF7F21FBFF7FD5FBFF7F99FBFF7F41020000D5FBFF7F230100006AFBFF7F72FBFF7F76FBFF7F03F9FF7F7408000018FAFF7FA7F8FF7F80FAFF7F4E05000082FAFF7FE601000047F9FF7F5CFFFF7F57000000D2FAFF7F2EFAFF7F79F9FF7F68F8FF7FABF8FF7F9AF9FF7F5DF6FF7F34F9FF7FB7F9FF7FFEF7FF7FA6F1FF7F67070000FFF9FF7FBEFAFF7F91FAFF7F4CFBFF7F4D05000025060000D704000038FBFF7FC0FAFF7FAEF8FF7F1EF9FF7F2CFAFF7F2801000037FAFF7FD2FFFF7F5C020000E4F9FF7F3EFAFF7FC8FBFF7FC9FBFF7FD4FBFF7FB8FBFF7FEEFBFF7F18FCFF7FECFBFF7F48FCFF7F0EFCFF7F4BFCFF7F4AFCFF7F31FCFF7FE2FBFF7F0AFCFF7FD0FBFF7FE50C0000A7FBFF7FB9FAFF7FF2FBFF7F4AFCFF7F33FCFF7F42FCFF7F50FCFF7F16FCFF7F0FFCFF7F37FCFF7F39FCFF7FFEFBFF7F17FCFF7F94FBFF7F2FFCFF7F08FCFF7FDDFAFF7FCEFBFF7FA5FBFF7F48FCFF7F09FCFF7F48FCFF7F0FFCFF7FB7FBFF7F0FFCFF7F4FFBFF7F2AFAFF7F92FBFF7F04FBFF7F7EFBFF7FFB07000095FBFF7F3CFBFF7FD9FBFF7FF1FAFF7FD8FBFF7FC9FBFF7F6AFBFF7FC5FBFF7F65FBFF7F78FAFF7F38F9FF7F860C000013FCFF7FEFFBFF7FC6F9FF7F09FCFF7FD7FBFF7FB0FAFF7F81FBFF7FC2FBFF7FEFFBFF7F0CFBFF7F13FBFF7FE0FAFF7FFFFBFF7FA9FBFF7F9FFAFF7FABFBFF7F4BFBFF7FA3020000B1FBFF7F7B010000B4FBFF7F26FBFF7F60FBFF7F41FBFF7FB6FAFF7F69FBFF7F98FAFF7F22FBFF7F49F9FF7F9BFBFF7F46FBFF7F79FBFF7FCDFAFF7F9BFAFF7FE0FAFF7F60FBFF7FB6FBFF7F5AFBFF7FD8F8FF7F56F9FF7FBC0B0000DBFAFF7FF0FBFF7F4CFBFF7FA1FBFF7FD2FBFF7F6FFAFF7FB7020000F602000050FBFF7F45FBFF7F17FBFF7F6B0800004CFAFF7FA1FBFF7F50F9FF7FB7F9FF7F25FBFF7FE4020000A4FBFF7F67010000AFF9FF7F21FBFF7F6EFBFF7FC8FBFF7FC9FBFF7FD4FBFF7FB8FBFF7FEEFBFF7F18FCFF7FECFBFF7F48FCFF7F0EFCFF7F4BFCFF7F4AFCFF7F31FCFF7FE2FBFF7F0AFCFF7FD0FBFF7FE50C0000A7FBFF7FB9FAFF7FF2FBFF7F4AFCFF7F33FCFF7F42FCFF7F50FCFF7F16FCFF7F0FFCFF7F37FCFF7F39FCFF7FFEFBFF7F17FCFF7F94FBFF7F2FFCFF7F08FCFF7FDDFAFF7FCEFBFF7FA5FBFF7F48FCFF7F09FCFF7F48FCFF7F0FFCFF7FB7FBFF7F0FFCFF7FC8FBFF7FC6FBFF7F86FBFF7FB6FBFF7F76FBFF7F1BFCFF7FF4FBFF7F24FCFF7FB9FAFF7F3EFCFF7F34FCFF7FE6FBFF7FDDFBFF7F0CFCFF7FDEFBFF7F55FBFF7F87FBFF7F5CFBFF7F0EFCFF7F27FCFF7F1DFCFF7FBFFBFF7F31FCFF7FABFBFF7F07FCFF7FF2FAFF7F06FCFF7FFAFBFF7FFCFBFF7F22FCFF7F3805000009FCFF7FDAFAFF7FCCFBFF7F8E08000046FCFF7F04FCFF7F3BFCFF7F19FCFF7FB7FBFF7F10FCFF7F07FAFF7F68F9FF7FA9FAFF7F1EF9FF7F3EFAFF7F72FAFF7FEFF7FF7F1803000043FAFF7F670000001A010000D0FAFF7F5DFAFF7F4DFAFF7F9EF9FF7F9EF7FF7F6AF9FF7F0EF7FF7F3AFAFF7F0BFBFF7F6FFAFF7FA2FAFF7FD9FAFF7F56070000D4FAFF7F2E01000016FBFF7FF0F9FF7F40FAFF7FA8030000A7020000F9FAFF7FE008000008050000D9F9FF7F37FAFF7FB5FAFF7F78FAFF7F5F02000016FAFF7FD2FAFF7F03FBFF7F97FAFF7FA5040000DBFAFF7F24FBFF7FA2F9FF7F2AFBFF7FA8FAFF7F8E040000E8FBFF7FA6FAFF7F35FBFF7F0FFBFF7FBBFAFF7F14FAFF7FB5F9FF7FF1FAFF7F43FAFF7F36010000D5000000400600006D0100004E0000008EFBFF7F81FBFF7F2EFBFF7F91FBFF7F33FBFF7FA3040000E4FAFF7FCDFBFF7F06FBFF7F2DFAFF7FFDF9FF7F7DF7FF7FDCFBFF7F1CFBFF7FE7FAFF7F0CFAFF7FCDFAFF7FD7FAFF7FF5FBFF7F6FFBFF7F2EFAFF7FEAFBFF7FF6FBFF7F6EFBFF7FF3FBFF7F20FBFF7F45F2FF7F1EFCFF7F33FBFF7FB5FBFF7FEAFBFF7FB3FBFF7F7DFBFF7F26FBFF7FD4FBFF7FCDFBFF7F960300008402000071F6FF7FAC0800008502000018FCFF7FE5FBFF7FCAFBFF7FFAFBFF7FCEFBFF7FC10600005EFBFF7F29FCFF7F9EFBFF7F99FBFF7F8CFBFF7F5DFAFF7F13FCFF7FADFBFF7F7AFBFF7FC8FAFF7FDCFBFF7FAFFBFF7FCFFAFF7F53FAFF7F22F9FF7F2EFAFF7F16FBFF7FBAF9FF7F9DFAFF7FBAF9FF7FB90600003BFBFF7FB101000034FBFF7FCFFAFF7FE2FAFF7F90FAFF7F2CF8FF7F9AFAFF7F07F9FF7F5B000000B6F8FF7F4D06000078030000000100005FF9FF7FF5FAFF7F2D0200006CFBFF7FCDFAFF7FFAF6FF7F2604000013FAFF7FDCFAFF7FD8F6FF7F1607000019F8FF7F65FBFF7FC8FAFF7FB4FAFF7FDD010000B5FAFF7FC7FAFF7FA3FAFF7FACFAFF7FD9F8FF7FB3FAFF7F1CFBFF7F78F9FF7F12FBFF7F540200000A050000F7FAFF7F2902000034FBFF7F03FBFF7F53FAFF7F89F9FF7FBFF9FF7FABFAFF7FE3F8FF7FE90000008C000000C6050000250200006501000049FBFF7F8AFBFF7FF8FAFF7F77FBFF7FABFAFF7F13F6FF7FD1F8FF7F7CFBFF7FE9FAFF7FE2F9FF7F9EF9FF7FC30500004FF9FF7FBAFAFF7F63020000CAF9FF7FC1FAFF7FCCFAFF7F3FFCFF7F4AFCFF7F59FCFF7F47FCFF7F59FCFF7F49FCFF7F44FCFF7FB0FAFF7F55FCFF7F1AFCFF7FB205000055FCFF7F58FCFF7F50FCFF7F4FFCFF7F57FCFF7F56FCFF7F5DFCFF7F15FCFF7F54FCFF7F26FCFF7FE5FBFF7FD6FBFF7F55FCFF7F58FCFF7F2EFCFF7F56FCFF7F23FCFF7F51FCFF7F5BFAFF7F55FCFF7F47FCFF7F22FCFF7F04FCFF7F40FCFF7F38FCFF7F1CFCFF7F2CFCFF7FB7FBFF7F58FCFF7F4FFCFF7FC2FBFF7FC0FBFF7F21FCFF7FB1FBFF7F09FCFF7F06FCFF7F650900009EFAFF7F39FCFF7F09FCFF7F900500002CFCFF7FEEFBFF7F03FCFF7FD4FBFF7FDCFBFF7F1EFCFF7F01FCFF7F05FCFF7F3DFCFF7FE0FBFF7FD8FBFF7FCEFBFF7F65F9FF7F3AFCFF7F1CFCFF7F1BFCFF7FD0FBFF7F36FCFF7F46FAFF7F29FCFF7F6EFBFF7FD1FBFF7F56FBFF7FFEFBFF7F1EFCFF7FD8FBFF7F22FCFF7FA9FBFF7FCCFBFF7F0CFCFF7FB3FBFF7F7EFBFF7FF4FBFF7F68FBFF7FDAFBFF7FCCFBFF7FDDFBFF7F25FCFF7F15FCFF7F23FCFF7FCDFBFF7F1EFCFF7F29080000D0FBFF7FBCFBFF7F48FBFF7FC9FBFF7FC9FBFF7F30FCFF7F3BFCFF7FF1FBFF7F13FCFF7FEFFBFF7FDFFBFF7F1DFCFF7F03FCFF7F2BFCFF7FD5FBFF7F86FBFF7F91F9FF7F18FCFF7FF9FBFF7F78FBFF7F97FBFF7FD9FBFF7F16FCFF7FFBFBFF7F3CFCFF7F340600009CFBFF7FEEFBFF7FFFFAFF7F56FAFF7FF9030000A4FAFF7F1DFBFF7FC9FAFF7F22FBFF7FA4FAFF7F72050000C9FBFF7F3FFAFF7F47FBFF7FDDFAFF7F8BFAFF7F0AFAFF7F77F8FF7F4EFAFF7F58F9FF7F410100003B010000C1F2FF7FDB0300000B0100007EFBFF7F7EFBFF7F0FFBFF7F98FBFF7F0AFBFF7FCA0300002EF8FF7F82FBFF7FF9FAFF7F12F9FF7F7FF9FF7FFA050000BEFBFF7F11FBFF7FE7FAFF7F21040000C9FAFF7F07FBFF7F4AFBFF7FCAFAFF7F20FBFF7FAEFAFF7F2AFBFF7F79FBFF7F89FBFF7FF5FBFF7F70F9FF7FCAFBFF7F78FAFF7F33FBFF7F41FBFF7F90FBFF7F68FBFF7FA90C0000F4FAFF7F2EF9FF7F1F070000EFFBFF7F57FBFF7FD6F6FF7FB5FAFF7F98FBFF7F5A030000DFFAFF7F84FBFF7F59FBFF7F9CFAFF7FB1050000ADFBFF7F98FBFF7F34F9FF7FCCF9FF7FC8FAFF7F68FBFF7F9BFBFF7FC4FBFF7FFF03000029FBFF7F8FFBFF7FFFFBFF7FF6FBFF7F0DFCFF7F2EFCFF7F38FCFF7FABFBFF7F3DFCFF7F39050000A6F9FF7F96FBFF7F95FAFF7F16FCFF7F34FCFF7FA4FBFF7F5BFBFF7FA7FBFF7FEAFBFF7FBFFAFF7F640C000026FBFF7F87FBFF7FEBF4FF7FD3FAFF7F0DFCFF7F28FCFF7F2FFCFF7F30FCFF7FC2FBFF7FA3FBFF7F50FBFF7F3AFCFF7F21FCFF7FFDFBFF7F1FFCFF7FCDFBFF7FD4F9FF7F0CFCFF7FDA03000000FCFF7F32FCFF7F27FCFF7F4FFCFF7F50FCFF7F3CFCFF7F49FCFF7F4CFCFF7F52FCFF7F4DFCFF7F96FBFF7FF9FAFF7F54FCFF7F54FCFF7F3AFCFF7F4BFCFF7F32FCFF7F24FCFF7F55FCFF7F58FCFF7F5BFCFF7F21FCFF7F1705000094FBFF7FBFFAFF7F0BFCFF7F50FCFF7F54FCFF7F59FCFF7F46FCFF7F56FCFF7F58FBFF7F5FFCFF7F56FCFF7F53FCFF7F55FCFF7F5CFCFF7F32FCFF7F4CFCFF7F55FCFF7F42FCFF7F53FCFF7F49FCFF7F43FCFF7F70FBFF7F6BFBFF7FA4F9FF7F48FBFF7F85FBFF7F25FAFF7F8BFBFF7F39FAFF7FCC06000094FBFF7F9CFAFF7F94FBFF7F74FBFF7F46FBFF7FD8FAFF7FB4FAFF7F30FBFF7FD7F9FF7F4E02000039020000410500001C03000037020000C4FBFF7FBDFBFF7F60FBFF7FC2FBFF7FB0FBFF7FA1F6FF7FEAFAFF7FFAFBFF7F4AFBFF7F49FBFF7F6DFAFF7FA3F8FF7FA3F9FF7F5DFBFF7F62030000D2FAFF7F47FBFF7F3DFBFF7F59FCFF7F42FCFF7F3EFCFF7F59FCFF7F59FCFF7F49FCFF7F59FCFF7F56FCFF7F86FBFF7F5AFCFF7F21FCFF7F58FCFF7F58FCFF7F5CFCFF7F5DFCFF7F56FCFF7F56FCFF7F59FCFF7F68FBFF7F18FCFF7FCAFBFF7F28F4FF7F7E0A00005CFCFF7F59FCFF7F4EFCFF7F58FCFF7F4EFCFF7F5BFBFF7F55FCFF7F5CFCFF7F4BFCFF7F55FCFF7F4BFCFF7F2EFCFF7F5AFCFF7F4DFCFF7F41FCFF7F1FFCFF7F57FCFF7F53FCFF7F13FCFF7F19FCFF7F180800000CFCFF7F24FCFF7F42FCFF7F25FCFF7F56FCFF7F01FBFF7F53FCFF7F54FCFF7F46FCFF7F21FCFF7F39FCFF7F25FCFF7FA6FBFF7FFFFBFF7F89FBFF7F1CFCFF7F37FCFF7F41FCFF7FDEFBFF7F3EFCFF7F39FCFF7F4CFCFF7F48FCFF7F49FCFF7F2DFCFF7F59FBFF7F43FCFF7F44FCFF7F34FCFF7FA1FBFF7F19FCFF7F83FBFF7F52FCFF7F34FCFF7F54FCFF7F33FCFF7F0EFCFF7F38FCFF7F04FCFF7FDEFBFF7F4EFCFF7FA9FBFF7F39FCFF7F67FBFF7F44FCFF7FF004000032FCFF7F4001000081FAFF7F12FCFF7F38FCFF7FA5FBFF7F5BFBFF7F47FCFF7FC1FBFF7FD0FAFF7F22FCFF7F58FBFF7FE2FBFF7F4FFCFF7F11FCFF7FABFBFF7F2FFCFF7F31FCFF7F2EFCFF7FB7FBFF7FBEFBFF7FAAFBFF7F33FCFF7F3FFCFF7FF6FBFF7F3CFCFF7F21FCFF7FE5F8FF7F29FCFF7F74030000F3FBFF7F37FCFF7F1BFCFF7FB5FBFF7F65FBFF7F14FCFF7F22FBFF7F06FCFF7F80F9FF7F01FCFF7F4203000095FAFF7F60000000B2020000C5FBFF7F00FCFF7F44FBFF7FDCFAFF7F29FCFF7F48FBFF7FC3F8FF7F94FBFF7FE5040000AAFAFF7FF7F9FF7F1FFBFF7F4FFBFF7FC8FBFF7FE4FBFF7FF4FBFF7F37FBFF7F4FFAFF7F84F9FF7F12FCFF7F03FCFF7FA1FBFF7FDAFBFF7FC3FBFF7F2D030000C9FBFF7F3D01000019FBFF7FF9FBFF7FC1FBFF7FCAFBFF7FD0FBFF7F14FCFF7FBEFBFF7F80FBFF7FDAFBFF7FFAFBFF7FF3FBFF7F2FFCFF7F2EFCFF7F20FCFF7F9A030000DCFBFF7F06FCFF7FDBFBFF7FE1FBFF7FC0FBFF7F74FBFF7F4BFCFF7F1AFCFF7FA2FBFF7FDAFBFF7F41FCFF7F92FBFF7FDAFAFF7FF8020000BDFBFF7FFEFBFF7FC7FBFF7F81FBFF7FD203000003FCFF7FF5FAFF7F46FBFF7FB6FBFF7F2BFCFF7F00FCFF7F37FCFF7FF0FBFF7FB9FBFF7F6BFBFF7F37FCFF7FDBFBFF7F4AFCFF7F57FBFF7F38FCFF7FEDF9FF7F41FCFF7F26FBFF7F4AFCFF7F5C010000B6FBFF7F30FCFF7F35FCFF7F4AFCFF7F42FCFF7F49FCFF7F5DFBFF7FD0F8FF7F34FCFF7F13FCFF7F0CFCFF7F4BFCFF7F17FCFF7FA7FBFF7FEDFBFF7F30FCFF7F40FCFF7F0DFCFF7FECFBFF7F55FBFF7F44FCFF7F3CFCFF7F32FCFF7F4EFCFF7F36FCFF7F8003000040FCFF7F33020000EAFBFF7F2EFCFF7F17FCFF7F54FCFF7F39FCFF7F5AFCFF7FC1FBFF7F54FCFF7F11FCFF7F59FCFF7FFEFBFF7F5FFCFF7F840200000CFCFF7F54FCFF7F53FCFF7F5AFCFF7F58FCFF7F5BFCFF7F1CFCFF7F5CFCFF7F5AFCFF7F51FCFF7F50FCFF7F5FFCFF7F58FCFF7FECFBFF7F58FCFF7F56FCFF7F56FCFF7F49FCFF7F4AFCFF7FD8FBFF7F51FCFF7F55FCFF7F44FCFF7F57FCFF7F5AFCFF7F4DFBFF7F57FCFF7FC8FBFF7F30FCFF7F51FCFF7F4AFCFF7F54FCFF7F39FCFF7F5AFCFF7FC1FBFF7F54FCFF7F11FCFF7F59FCFF7FFEFBFF7F5FFCFF7F840200000CFCFF7F54FCFF7F53FCFF7F5AFCFF7F58FCFF7F5BFCFF7F1CFCFF7F5CFCFF7F5AFCFF7F51FCFF7F50FCFF7F5FFCFF7F58FCFF7FECFBFF7F58FCFF7F56FCFF7F56FCFF7F49FCFF7F4AFCFF7FD8FBFF7F51FCFF7F55FCFF7F44FCFF7F57FCFF7F5AFCFF7F4DFBFF7F57FCFF7FC8FBFF7F30FCFF7F51FCFF7F4AFCFF7F54FCFF7F39FCFF7F5AFCFF7FC1FBFF7F54FCFF7F11FCFF7F59FCFF7FFEFBFF7F5FFCFF7F840200000CFCFF7F54FCFF7F53FCFF7F5AFCFF7F58FCFF7F5BFCFF7F1CFCFF7F5CFCFF7F5AFCFF7F51FCFF7F50FCFF7F5FFCFF7F58FCFF7FECFBFF7F58FCFF7F56FCFF7F56FCFF7F49FCFF7F4AFCFF7FD8FBFF7F51FCFF7F55FCFF7F44FCFF7F57FCFF7F5AFCFF7F4DFBFF7F57FCFF7FC8FBFF7F30FCFF7F51FCFF7F4AFCFF7F54FCFF7F39FCFF7F5AFCFF7FC1FBFF7F54FCFF7F11FCFF7F59FCFF7FFEFBFF7F5FFCFF7F840200000CFCFF7F54FCFF7F53FCFF7F5AFCFF7F58FCFF7F5BFCFF7F1CFCFF7F5CFCFF7F5AFCFF7F51FCFF7F50FCFF7F5FFCFF7F58FCFF7FECFBFF7F58FCFF7F56FCFF7F56FCFF7F49FCFF7F4AFCFF7FD8FBFF7F51FCFF7F55FCFF7F44FCFF7F57FCFF7F5AFCFF7F4DFBFF7F57FCFF7FC8FBFF7F30FCFF7F51FCFF7F4AFCFF7F54FCFF7F39FCFF7F5AFCFF7FC1FBFF7F54FCFF7F11FCFF7F59FCFF7FFEFBFF7F5FFCFF7F840200000CFCFF7F54FCFF7F53FCFF7F5AFCFF7F58FCFF7F5BFCFF7F1CFCFF7F5CFCFF7F5AFCFF7F51FCFF7F50FCFF7F5FFCFF7F58FCFF7FECFBFF7F58FCFF7F56FCFF7F56FCFF7F49FCFF7F4AFCFF7FD8FBFF7F51FCFF7F55FCFF7F44FCFF7F57FCFF7F5AFCFF7F4DFBFF7F57FCFF7FC8FBFF7F30FCFF7F51FCFF7F4AFCFF7FBDFAFF7F75FAFF7F01FBFF7FD6F9FF7F0CFBFF7F58F8FF7FD4F8FF7FD0FAFF7F6CFBFF7FC000000073FBFF7FAAFBFF7FEBFAFF7F9CFAFF7FE8FAFF7F30F9FF7FA1060000140C0000E3FBFF7FCEFBFF7F81FBFF7FDAFBFF7FE9FBFF7FEE0800005AFBFF7F81FBFF7FB9FBFF7F14FBFF7F47FBFF7FE4F9FF7F5AFBFF7F52FBFF7FA8F8FF7FA4F9FF7F9AFAFF7FC702000053FBFF7F200100005FFBFF7F8FFAFF7F40FBFF7FE3FBFF7FD6FBFF7F28FCFF7FC9FBFF7F10FCFF7F1DFCFF7F7E0900004CFCFF7F44FCFF7F4EFCFF7F44FCFF7F37FCFF7FF6FBFF7F13FCFF7FE4FBFF7FE6FBFF7F28FCFF7F05FCFF7F50FCFF7F49FCFF7F1AFCFF7F52FCFF7F58FCFF7F72F9FF7F42FCFF7F4FFCFF7F25FCFF7F0CFCFF7F45FCFF7F49FCFF7F34FCFF7F87FBFF7F0EFCFF7FB0FBFF7F1EFCFF7F46FCFF7F1BFCFF7F56FCFF7F52FCFF7FD4FBFF7F1DFCFF7F1BFCFF7FEAFBFF7F43FCFF7FDAFBFF7FCEFBFF7F41FAFF7F2AFCFF7F2BFCFF7F5BFCFF7FA0FBFF7F2EFCFF7F7BFBFF7F21FCFF7F35FCFF7F24FCFF7FB4FBFF7FE2FBFF7FD1F9FF7F50FCFF7F2EFCFF7FFEFBFF7F4CFCFF7F46FCFF7F0CFCFF7FCE030000C4FBFF7FC3FBFF7F11FCFF7FD9FBFF7FBAFBFF7F12FCFF7F33FCFF7F43FCFF7F50FCFF7F41FCFF7F8A07000030FCFF7F4CFAFF7F0DFCFF7F12FCFF7F01FCFF7FBFFBFF7FB1FBFF7F1DFCFF7FA1FBFF7FE8FBFF7F10FCFF7FE8FBFF7F45FCFF7F3EFCFF7F4BFCFF7F54FCFF7F2FFCFF7F6108000003FCFF7FC3FBFF7FC9FBFF7F17FCFF7FCFFBFF7F4DFCFF7F45FCFF7F08FCFF7F4FFCFF7F56FCFF7FFCFBFF7F3BFCFF7F4BFCFF7F3BFCFF7FF8FBFF7F43FCFF7F45FCFF7F28FCFF7F06FCFF7FD3FBFF7F23FCFF7F10FCFF7F42FCFF7F06FCFF7F55FCFF7F29FCFF7FAAFBFF7F0EFCFF7FBFFBFF7FB1FBFF7F1DFCFF7FA1FBFF7FE8FBFF7F10FCFF7FE8FBFF7F45FCFF7F3EFCFF7F4BFCFF7F54FCFF7F2FFCFF7F6108000003FCFF7FC3FBFF7FC9FBFF7F17FCFF7FCFFBFF7F4DFCFF7F45FCFF7F08FCFF7F4FFCFF7F56FCFF7FFCFBFF7F3BFCFF7F4BFCFF7F3BFCFF7FF8FBFF7F43FCFF7F45FCFF7F28FCFF7F06FCFF7FD3FBFF7F23FCFF7F10FCFF7F42FCFF7F06FCFF7F55FCFF7F29FCFF7FAAFBFF7F0EFCFF7FBFFBFF7FB1FBFF7F1DFCFF7FA1FBFF7FE8FBFF7F10FCFF7FE8FBFF7F45FCFF7F3EFCFF7F4BFCFF7F54FCFF7F2FFCFF7F6108000003FCFF7FC3FBFF7FC9FBFF7F17FCFF7FCFFBFF7F4DFCFF7F45FCFF7F08FCFF7F4FFCFF7F56FCFF7FFCFBFF7F3BFCFF7F4BFCFF7F3BFCFF7FF8FBFF7F43FCFF7F45FCFF7F28FCFF7F06FCFF7FD3FBFF7F23FCFF7F10FCFF7F42FCFF7F06FCFF7F55FCFF7F29FCFF7FAAFBFF7F0EFCFF7FBFFBFF7FB1FBFF7F1DFCFF7FA1FBFF7FE8FBFF7F10FCFF7FE8FBFF7F45FCFF7F3EFCFF7F4BFCFF7F54FCFF7F2FFCFF7F6108000003FCFF7FC3FBFF7FC9FBFF7F17FCFF7FCFFBFF7F4DFCFF7F45FCFF7F08FCFF7F4FFCFF7F56FCFF7FFCFBFF7F3BFCFF7F4BFCFF7F3BFCFF7FF8FBFF7F43FCFF7F45FCFF7F28FCFF7F06FCFF7FD3FBFF7F23FCFF7F10FCFF7F42FCFF7F06FCFF7F55FCFF7F29FCFF7FAAFBFF7F0EFCFF7F70FBFF7F4EFBFF7FF2FBFF7F37FBFF7FADF9FF7FD9FBFF7F040A000038FCFF7F34FCFF7F3BFCFF7F29FCFF7F0DFCFF7F8CFBFF7FC7FBFF7F71FBFF7F71FBFF7FEAFBFF7F95FBFF7F29FCFF7F34FCFF7FE8FBFF7F0BFCFF7F44FCFF7FC4F8FF7F22FCFF7F3CFCFF7F00FCFF7FBBFBFF7F2FFCFF7F31FCFF7F06FCFF7F63070000A1FBFF7F6FFBFF7FE0FBFF7F2BFCFF7F59FBFF7F4CFCFF7F43FCFF7F49FBFF7FD9FBFF7F33FBFF7F21FBFF7FD9FBFF7F0AFBFF7F8DFBFF7FA7FBFF7FFB070000EDFBFF7F23FCFF7F0DFCFF7F24FCFF7FDAFBFF7F5DFBFF7FA9FBFF7F3FFBFF7F62FBFF7F72FBFF7F69FAFF7F39FCFF7F06FCFF7F8EFBFF7F2DFCFF7F47FCFF7F7F08000072FBFF7FECFBFF7FEB01000097FBFF7F14FCFF7F08FCFF7F82FBFF7F07FBFF7FC3FAFF7FD5F9FF7FC7FBFF7F00FCFF7FAEFBFF7F3EFCFF7F20FCFF7F0EFBFF7F9CFBFF7FF3FBFF7FF8FBFF7F35FCFF7FE6FBFF7F0DFCFF7FD3FBFF7F0DFCFF7F39FCFF7F57FCFF7F45FCFF7F4EFCFF7FCFFBFF7F04FCFF7F21FCFF7FFDFBFF7FFBFBFF7F2FFCFF7F17FCFF7F58FCFF7F3CFCFF7FB6FBFF7F27FCFF7F50FCFF7F1CFCFF7F30FCFF7F3EFCFF7F30FCFF7F1DFCFF7F26FCFF7F51FCFF7F3EFCFF7F20FCFF7F04FCFF7F38FCFF7F2CFCFF7F34FCFF7F21FCFF7F52FCFF7F3BFCFF7FE5FBFF7F7B060000F3FBFF7FF8FBFF7F35FCFF7FE6FBFF7F0DFCFF7FD3FBFF7F0DFCFF7F39FCFF7F57FCFF7F45FCFF7F4EFCFF7FCFFBFF7F04FCFF7F21FCFF7FFDFBFF7FFBFBFF7F2FFCFF7F17FCFF7F58FCFF7F3CFCFF7FB6FBFF7F27FCFF7F50FCFF7F1CFCFF7F30FCFF7F3EFCFF7F30FCFF7F1DFCFF7F26FCFF7F51FCFF7F3EFCFF7F20FCFF7F04FCFF7F38FCFF7F2CFCFF7F34FCFF7F21FCFF7F52FCFF7F3BFCFF7FE5FBFF7F7B060000B5FBFF7FBEFBFF7F1CFCFF7F9FFBFF7FE3FBFF7F86FBFF7FDBFBFF7FFFFBFF7F52FCFF7F35FCFF7F43FCFF7FB4030000CDFBFF7FFDFBFF7FC9FBFF7FC6FBFF7F13FCFF7FF7FBFF7F53FCFF7F09FCFF7F5FFBFF7F0EFCFF7F48FCFF7FF7FBFF7F61FBFF7FEBFBFF7F02FCFF7FF6FBFF7FB1FBFF7F4AFCFF7FDAFBFF7FF7FBFF7FD6FBFF7F22FCFF7F0FFCFF7F1FFCFF7FFAFBFF7F3EFCFF7F26FCFF7F9FFBFF7FD2050000F3FBFF7FF8FBFF7F35FCFF7FE6FBFF7F0DFCFF7FD3FBFF7F0DFCFF7F39FCFF7F57FCFF7F45FCFF7F4EFCFF7FCFFBFF7F04FCFF7F21FCFF7FFDFBFF7FFBFBFF7F2FFCFF7F17FCFF7F58FCFF7F3CFCFF7FB6FBFF7F27FCFF7F50FCFF7F1CFCFF7F30FCFF7F3EFCFF7F30FCFF7F1DFCFF7F26FCFF7F51FCFF7F3EFCFF7F20FCFF7F04FCFF7F38FCFF7F2CFCFF7F34FCFF7F21FCFF7F52FCFF7F3BFCFF7FE5FBFF7F7B060000FCFBFF7F00FCFF7F38FCFF7FEFFBFF7F14FCFF7FE0FBFF7F13FCFF7F3CFCFF7F57FCFF7F48FCFF7F4FFCFF7FDDFBFF7F0BFCFF7F26FCFF7F05FCFF7F03FCFF7F33FCFF7F1DFCFF7F59FCFF7F3FFCFF7FC5FBFF7F2CFCFF7F52FCFF7F22FCFF7F34FCFF7F41FCFF7F34FCFF7F23FCFF7F2BFCFF7F53FCFF7F41FCFF7F25FCFF7F0BFCFF7F3BFCFF7F30FCFF7F37FCFF7F26FCFF7F53FCFF7F3EFCFF7FEFFBFF7FA605000033FCFF7F34FCFF7F4BFCFF7F2DFCFF7F42FCFF7F24FCFF7FF0FBFF7F33FCFF7F5CFCFF7F54FCFF7F58FCFF7F30FCFF7F38FCFF7F45FCFF7F39FCFF7F3AFCFF7F4BFCFF7F47FCFF7F5CFCFF7F38FCFF7F21FCFF7F4AFCFF7F59FCFF7F03FCFF7FB0FBFF7F1FFCFF7F6702000043FCFF7F4AFCFF7F5AFCFF7F11FCFF7F44FCFF7F41FCFF7F53FCFF7F4AFCFF7F4EFCFF7F43FCFF7F5AFCFF7F50FCFF7F2DFCFF7F29FCFF7F30FCFF7F31FCFF7F4AFCFF7F29FCFF7F40FCFF7F1EFCFF7FE6FBFF7F2FFCFF7F5BFCFF7F52FCFF7F58FCFF7F2CFCFF7F35FCFF7F43FCFF7F36FCFF7F37FCFF7F49FCFF7F45FCFF7F5BFCFF7F34FCFF7F1BFCFF7F48FCFF7F58FCFF7FFBFBFF7F9FFBFF7F19FCFF7FEC02000041FCFF7F48FCFF7F5AFCFF7F0BFCFF7F42FCFF7F3EFCFF7F52FCFF7F48FCFF7F4CFCFF7F41FCFF7F59FCFF7F4FFCFF7F29FCFF7F24FCFF7F30FCFF7F31FCFF7F4AFCFF7F29FCFF7F40FCFF7F1EFCFF7FE6FBFF7F2FFCFF7F5BFCFF7F52FCFF7F58FCFF7F2CFCFF7F35FCFF7F43FCFF7F36FCFF7F37FCFF7F49FCFF7F45FCFF7F5BFCFF7F34FCFF7F1BFCFF7F48FCFF7F58FCFF7FFBFBFF7F9FFBFF7F19FCFF7FEC02000041FCFF7F48FCFF7F5AFCFF7F0BFCFF7F42FCFF7F3EFCFF7F52FCFF7F48FCFF7F4CFCFF7F41FCFF7F59FCFF7F4FFCFF7F29FCFF7F24FCFF7F30FCFF7F31FCFF7F4AFCFF7F29FCFF7F40FCFF7F1EFCFF7FE6FBFF7F2FFCFF7F5BFCFF7F52FCFF7F58FCFF7F2CFCFF7F35FCFF7F43FCFF7F36FCFF7F37FCFF7F49FCFF7F45FCFF7F5BFCFF7F34FCFF7F1BFCFF7F48FCFF7F58FCFF7FFBFBFF7F9FFBFF7F19FCFF7FEC02000041FCFF7F48FCFF7F5AFCFF7F0BFCFF7F42FCFF7F3EFCFF7F52FCFF7F48FCFF7F4CFCFF7F41FCFF7F59FCFF7F4FFCFF7F29FCFF7F24FCFF7F9CFBFF7FABFBFF7F01FCFF7F93FBFF7F04FBFF7FB1FBFF7FD6FBFF7FE1FBFF7F2AFCFF7F22FCFF7F15FCFF7FD2020000B4FBFF7FE8FBFF7FB1FBFF7F3BFBFF7FB0FBFF7F10FBFF7F3CFCFF7F08FCFF7F55FBFF7FC2FBFF7F39FCFF7F78FBFF7FA4020000120300002BFBFF7FE1FBFF7F68FBFF7F29FBFF7F84030000E9FBFF7FD4FAFF7F27FBFF7FA1FBFF7FB6FBFF7FE1FBFF7F1CFCFF7FC8FBFF7F87FBFF7F33FBFF7FBCFBFF7F6B0B000019FCFF7F9BFBFF7FD8FBFF7F59FBFF7FD8FBFF7F20FCFF7F40FCFF7F3AFCFF7F46FCFF7F2AFCFF7FCBFBFF7F01FCFF7FC9FBFF7FC5FBFF7F15FCFF7FEDFBFF7F4EFCFF7F46FCFF7F14FCFF7F59FCFF7F33FCFF7FF5FBFF7F38FCFF7F49FCFF7F35FCFF7F17FBFF7FEAFBFF7FECFBFF7F1FFCFF7FF9FBFF7FD2FBFF7F24FCFF7F09FCFF7F1DFCFF7FFFFBFF7F4AFCFF7F32FCFF7F94FBFF7F07FCFF7F4CFCFF7F51FCFF7F4BFCFF7F50FCFF7F53FCFF7F4AFCFF7F53FCFF7F4EFCFF7F42FCFF7F53FCFF7F38FCFF7F15FCFF7F4DFCFF7F53FCFF7F4FFCFF7F3FFCFF7F4CFCFF7FB0FBFF7F5AFCFF7F5AFCFF7F1CFCFF7FFCFBFF7F4FFCFF7F44FCFF7FEAFBFF7F870400002CFCFF7F53FCFF7F49FCFF7FAEFBFF7FEFFAFF7F50FCFF7FD7FBFF7FA1FBFF7F4DFCFF7F4CFCFF7F51FCFF7F51FCFF7F19FCFF7F4BFCFF7F41FCFF7F4AFCFF7F50FCFF7F49FCFF7F4EFCFF7F52FCFF7F48FCFF7F52FCFF7F4CFCFF7F40FCFF7F52FCFF7F34FCFF7F0DFCFF7F4CFCFF7F52FCFF7F4EFCFF7F3CFCFF7F4AFCFF7F9EFBFF7F59FCFF7F59FCFF7F15FCFF7FF0FBFF7F4DFCFF7F41FCFF7FDEFBFF7F6F05000026FCFF7F52FCFF7F47FCFF7F98FBFF7FC0FAFF7F4FFCFF7FC9FBFF7F8AFBFF7F4BFCFF7F4AFCFF7F50FCFF7F4FFCFF7F11FCFF7F49FCFF7F3EFCFF7FFCFBFF7FE9FBFF7F31FCFF7FE0FBFF7F09FAFF7F24FCFF7F38FBFF7F4EFCFF7F54FCFF7F4FFCFF7F49FCFF7F3BFCFF7F03FCFF7F1EFCFF7FFCFBFF7FFAFBFF7F29FCFF7FFCFBFF7F3CFCFF7F4EFCFF7F37FCFF7F1BFCFF7F4DFCFF7F29FCFF7F44FCFF7F50FCFF7F43FCFF7F1AFCFF7F4DFCFF7F4AFCFF7F38FCFF7F3F080000FDFBFF7F36FCFF7F2BFCFF7F48FCFF7FA7FBFF7F57FCFF7F53FCFF7FE6FBFF7F24FCFF7FFCFBFF7FE9FBFF7F31FCFF7FE0FBFF7F09FAFF7F24FCFF7F38FBFF7F4EFCFF7F54FCFF7F4FFCFF7F49FCFF7F3BFCFF7F03FCFF7F1EFCFF7FFCFBFF7FFAFBFF7F29FCFF7FFCFBFF7F3CFCFF7F4EFCFF7F37FCFF7F1BFCFF7F4DFCFF7F29FCFF7F44FCFF7F50FCFF7F43FCFF7F1AFCFF7F4DFCFF7F4AFCFF7F38FCFF7F3F080000FDFBFF7F36FCFF7F2BFCFF7F48FCFF7FA7FBFF7F57FCFF7F53FCFF7FE6FBFF7F24FCFF7F9FFBFF7F9BFBFF7F0DFCFF7F86FBFF7F24090000E9FBFF7FDCFBFF7F34FCFF7F3BFCFF7F3FFCFF7F4CFCFF7F4EFBFF7FBDFBFF7FE8FBFF7FA6FBFF7F27FBFF7F0CFCFF7F83FBFF7F3EFCFF7F34FCFF7FC1FBFF7F41FCFF7F4FFCFF7FECFBFF7F84040000BCFBFF7FA5FBFF7FE0FBFF7FDEFBFF7FF3FBFF7F96FBFF7F23FAFF7FCAFBFF7F18FCFF7F01FCFF7FC6FBFF7FF4FBFF7F39FCFF7F2BFCFF7F8AFBFF7FDAFBFF7F8CFBFF7F7AFBFF7F01FCFF7F69FBFF7F00090000F1FBFF7FD9FBFF7F25FCFF7F30FCFF7F37FCFF7F46FCFF7FDAFBFF7FACFBFF7FDFFBFF7F91FBFF7FADFBFF7FAEFBFF7FC3FBFF7F44FCFF7F38FCFF7FEBFBFF7F49FCFF7F51FCFF7F7AFBFF7FCAFBFF7FF7FAFF7FFEFBFF7FD0FBFF7F36FCFF7F1CFCFF7F0E05000018FAFF7F2FFBFF7FE1FBFF7F9DFBFF7F36FCFF7FE9FBFF7F4FFCFF7F3BFCFF7F73FBFF7FF2FBFF7F65FBFF7F44FBFF7FEEFBFF7F2DFBFF7F8F070000D5FBFF7FD1FAFF7F32FCFF7F30FCFF7F3AFCFF7F3BFCFF7F0FFCFF7F84FBFF7FC2FBFF7F69FBFF7F6BFBFF7FE1FBFF7F74FBFF7F27FCFF7F32FCFF7FE2FBFF7F09FCFF7F43FCFF7FCAFBFF7FEDFBFF7F3DFCFF7F20FCFF7FB4FBFF7F2FFCFF7F27FCFF7FB2FBFF7F5006000079FBFF7FF7FBFF7FDDFBFF7F2AFCFF7F55FBFF7F4CFCFF7F40FCFF7F3EFBFF7FD4FBFF7FCFFBFF7FC1FBFF7F20FCFF7FB4FBFF7F9109000014FCFF7F01FCFF7F46FCFF7F3EFCFF7F4BFCFF7F54FCFF7F36FCFF7FE7FBFF7F08FCFF7FD2FBFF7FD7FBFF7F1BFCFF7FDEFBFF7F4DFCFF7F46FCFF7F0EFCFF7F50FCFF7F56FCFF7F05FCFF7F0CFCFF7F4EFCFF7F3FFCFF7FFFFBFF7F43FCFF7F3FFCFF7FE0FBFF7F41FAFF7FE1FBFF7F24FCFF7F15FCFF7F44FCFF7F14FCFF7F55FCFF7F4EFCFF7FBEFBFF7F13FCFF7F1CFCFF7F22FCFF7F1EFCFF7F1DFCFF7F28FCFF7F41FCFF7FC5FBFF7F45FCFF7FAFFBFF7F4BFCFF7F26FCFF7F46FCFF7F25FCFF7F38FCFF7F25FCFF7FC2FBFF7F0AFCFF7FC9FBFF7F42FCFF7F57FCFF7F19FCFF7F1EFCFF7F4DFCFF7FBAFAFF7F4DFCFF7FF7FBFF7F4AFCFF7F33FCFF7F44FCFF7F69FBFF7F2AFCFF7F36FCFF7F43FAFF7FCB09000014FCFF7F54FCFF7F35FCFF7F54FCFF7F07FCFF7F15FCFF7F37FCFF7F06FBFF7FFAFAFF7F9CFBFF7FE5FAFF7F61FBFF7FBBFBFF7FAF070000F5FBFF7F54FBFF7FFAFBFF7FE5FBFF7FE7FBFF7F36FBFF7F8FFBFF7F17FBFF7FCDFAFF7F11FBFF7FADF9FF7F18FCFF7F22FCFF7F75FBFF7FF3FBFF7F36FCFF7F6C08000009FCFF7FACFBFF7FC3FBFF7F79FBFF7F07FCFF7FE0FAFF7F86FBFF7FECFAFF7F62F8FF7F2B09000081FBFF7FFEFBFF7F92FBFF7F35FCFF7FC3FBFF7FDDFAFF7F9DFBFF7F14FCFF7F1BFCFF7F17FCFF7F16FCFF7F21FCFF7F3EFCFF7FB2FBFF7F42FCFF7F97FBFF7F48FCFF7F1EFCFF7F43FCFF7F1EFCFF7F34FCFF7F1EFCFF7FB0FBFF7FFFFBFF7FB8FBFF7F3EFCFF7F56FCFF7F11FCFF7F15FCFF7F4AFCFF7F7EFAFF7F4BFCFF7FE8FBFF7F48FCFF7F2EFCFF7F41FCFF7F44FBFF7F24FCFF7F32FCFF7FFDF9FF7F7C0B00000CFCFF7F53FCFF7F31FCFF7F52FCFF7FFAFBFF7F0DFCFF7F33FCFF7FD4FBFF7FD5FBFF7FD6FBFF7FC7FBFF7FF3FBFF7F1CFCFF7F08FCFF7F2DFCFF7F05FCFF7F3DFCFF7F35FCFF7F31FCFF7FE8FBFF7F11FCFF7FE1FBFF7FE5FAFF7FB9FBFF7FE9FAFF7F43FCFF7F4BFCFF7F35FCFF7F34FCFF7F4FFCFF7F6CFBFF7F3EFCFF7F13FCFF7F39FCFF7F06FCFF7F17FCFF7FC1FBFF7FFAFBFF7F0AFCFF7F8E0D0000DEFAFF7FAFFBFF7F4AFCFF7F0DFCFF7F4AFCFF7F1EFCFF7FC1FBFF7F12FCFF7F54FCFF7F39FCFF7F5AFCFF7FC1FBFF7F54FCFF7F11FCFF7F59FCFF7FFEFBFF7F5FFCFF7F840200000CFCFF7F54FCFF7F53FCFF7F5AFCFF7F58FCFF7F5BFCFF7F1CFCFF7F5CFCFF7F5AFCFF7F51FCFF7F50FCFF7F5FFCFF7F58FCFF7FECFBFF7F58FCFF7F56FCFF7F56FCFF7F49FCFF7F4AFCFF7FD8FBFF7F51FCFF7F55FCFF7F44FCFF7F57FCFF7F5AFCFF7F4DFBFF7F57FCFF7FC8FBFF7F30FCFF7F51FCFF7F4AFCFF7FA4FBFF7F81FBFF7F0CFCFF7F6DFBFF7FCBFBFF7FFAFBFF7FCBFBFF7F40FCFF7F37FCFF7F46FCFF7F50FCFF7F24FCFF7FB9FBFF7FA2FAFF7FC9FBFF7F9BFBFF7F07FCFF7FAAFBFF7F48FCFF7F3FFCFF7FF2FBFF7F4BFCFF7F54FCFF7FE3FBFF7F32FCFF7F45FCFF7F32FCFF7FE3FBFF7F3AFCFF7F34FCFF7F1AFCFF7FF0FBFF7FAAFBFF7F10FCFF7FFAFBFF7F3AFCFF7FF4FBFF7F52FCFF7F49FCFF7F1D0C0000F9FBFF7FC4FBFF7FA8FBFF7F1BFCFF7F98FBFF7FE5FBFF7F0CFCFF7FE5FBFF7F45FCFF7F3EFCFF7F4AFCFF7F53FCFF7F2EFCFF7FD6FBFF7F04FBFF7FE1FBFF7FBEFBFF7F17FCFF7FCAFBFF7F4CFCFF7F45FCFF7F05FCFF7F4EFCFF7F56FCFF7FF9FBFF7F3AFCFF7F4AFCFF7F3AFCFF7FF8FBFF7F41FCFF7F3CFCFF7F27FCFF7F04FCFF7FCAFBFF7F1EFCFF7F0CFCFF7F41FCFF7F07FCFF7F54FCFF7F4DFCFF7F4C0900000BFCFF7FA4FBFF7F81FBFF7F0CFCFF7F6DFBFF7FCBFBFF7FFAFBFF7FCBFBFF7F40FCFF7F37FCFF7F46FCFF7F50FCFF7F24FCFF7FB9FBFF7FA2FAFF7FC9FBFF7F9BFBFF7F07FCFF7FAAFBFF7F48FCFF7F3FFCFF7FF2FBFF7F4BFCFF7F54FCFF7FE3FBFF7F32FCFF7F45FCFF7F32FCFF7FE3FBFF7F3AFCFF7F34FCFF7F1AFCFF7FF0FBFF7FAAFBFF7F10FCFF7FFAFBFF7F3AFCFF7FF4FBFF7F52FCFF7F49FCFF7F1D0C0000F9FBFF7F02FCFF7F05FCFF7F90FBFF7FF6FBFF7F16FCFF7F39FCFF7F15FCFF7F41FCFF7F90FAFF7F51FCFF7F3EFCFF7F3FFCFF7F0FFCFF7F30FCFF7F18FCFF7F68FBFF7FE8FBFF7F5EFBFF7F0FFCFF7F30FCFF7F3CFCFF7FB3FBFF7F31FCFF7F31FCFF7F47FCFF7F45FCFF7F44FCFF7F22FCFF7F01FCFF7F42FCFF7F08FCFF7F28FCFF7F72FBFF7F07FCFF7F5C0A000052FCFF7F29FCFF7F3DFCFF7F26FCFF7FF8FBFF7F2CFCFF7F02FCFF7F05FCFF7F90FBFF7FF6FBFF7F16FCFF7F39FCFF7F15FCFF7F41FCFF7F90FAFF7F51FCFF7F3EFCFF7F3FFCFF7F0FFCFF7F30FCFF7F18FCFF7F68FBFF7FE8FBFF7F5EFBFF7F0FFCFF7F30FCFF7F3CFCFF7FB3FBFF7F31FCFF7F31FCFF7F47FCFF7F45FCFF7F44FCFF7F22FCFF7F01FCFF7F42FCFF7F08FCFF7F28FCFF7F72FBFF7F07FCFF7F5C0A000052FCFF7F29FCFF7F3DFCFF7F26FCFF7FF8FBFF7F2CFCFF7F54FCFF7F2DFCFF7F37FCFF7F27FCFF7F52FCFF7F1CFCFF7F55FCFF7F40FCFF7F37FCFF7F38FCFF7FD9FBFF7F4FFCFF7F27FCFF7F2DFCFF7F5AFCFF7FDEFBFF7F12FCFF7F5BFCFF7F44FCFF7F56FCFF7F49FCFF7F24FCFF7FF9FBFF7F43FCFF7F42FCFF7F18FCFF7F51FCFF7F3DFCFF7FA3FBFF7FADF9FF7F50FCFF7F53FCFF7F05FCFF7FD4FBFF7F29FCFF7F34FCFF7F55FCFF7F48FCFF7F6C06000052FCFF7F40FCFF7FA7FBFF7FB3FBFF7F02FCFF7F9FFBFF7F02FBFF7FBAFBFF7F8BFBFF7FE8FBFF7F2AFCFF7F24FCFF7F17FCFF7F93FAFF7FBDFBFF7FECFBFF7FB7FBFF7F37FBFF7FB4FBFF7F0FFBFF7F3CFCFF7F0EFCFF7F61FBFF7FC3FBFF7F39FCFF7F37FBFF7F590300001F030000D5010000E6FBFF7FBEFBFF7F24FBFF7F94030000F2FBFF7FDDFAFF7F2EFBFF7FA4FBFF7FACFBFF7FE7FBFF7F27FCFF7FC9FBFF7F93FBFF7FA8FBFF7F00FCFF7F71FBFF7FE3FBFF7FFCFAFF7F1CFCFF7FCDFBFF7F14FCFF7F59FAFF7F7AF9FF7FE70100000203000032FCFF7F16FCFF7F2BFCFF7F1FFCFF7F30FAFF7FD7FBFF7F2CFBFF7FEB0A0000FFFBFF7F90FBFF7F8FF4FF7F6BFAFF7F96FBFF7F02FCFF7F7CFBFF7F36FCFF7FA7FBFF7FD3FBFF7F790A000019FCFF7FF6FBFF7FCCFAFF7F49FAFF7FB8FBFF7FD9FAFF7FD7FBFF7F3BFBFF7FFAF8FF7F09FCFF7F16FCFF7FC2FBFF7FC4FBFF7FC2FBFF7FB5FBFF7FE6FBFF7F14FCFF7FFEFBFF7F25FCFF7FF8FBFF7F38FCFF7F2DFCFF7F2BFCFF7FD9FBFF7F07FCFF7FD1FBFF7FB0FAFF7FA1FBFF7FB6FAFF7F3FFCFF7F49FCFF7F31FCFF7F2DFCFF7F4DFCFF7F49FBFF7F39FCFF7F06FCFF7F34FCFF7FFBFBFF7F0DFCFF7FA3FBFF7FEBFBFF7FFFFBFF7FFF0F000093FAFF7F95FBFF7F47FCFF7F02FCFF7F47FCFF7F12FCFF7FAEFBFF7F07FCFF7FEFFBFF7FF8FBFF7F52FCFF7F38FCFF7F43FCFF7FFAFBFF7F35FCFF7F6005000039FCFF7FD2FBFF7F640300001FFCFF7F41FCFF7F8DFBFF7F3CFBFF7F4BFCFF7F4FFCFF7F5AFCFF7F06FCFF7F5FFBFF7FDEFBFF7FECFBFF7FC7FBFF7F11FCFF7F49FCFF7F1BFCFF7F31FCFF7F93FBFF7FF1FBFF7F80FAFF7F38FCFF7F36FCFF7FD9FBFF7FF1FBFF7F1FFCFF7F1BFCFF7FF5FBFF7F86FBFF7F99FBFF7F43FCFF7F28FCFF7F00FCFF7F0BFCFF7F37FCFF7FFCFBFF7FBAFBFF7FF4FBFF7FC1FBFF7F1DFCFF7F58FCFF7F47FCFF7F50FCFF7F43FBFF7F0CFCFF7F24FCFF7F0BFCFF7F86FBFF7F3AFCFF7FEAFBFF7F4CFCFF7F22FCFF7FCEFBFF7F3AFCFF7F51FCFF7FE3FBFF7F2104000086FBFF7F5202000023FCFF7FE3FBFF7F0EFCFF7FC1FBFF7F28FCFF7F29FCFF7F47FCFF7F34FCFF7FCFFBFF7F22FCFF7F3DFCFF7F2BFCFF7FF6FBFF7FEBFBFF7F7CFAFF7FD0FBFF7F25FCFF7FAEFBFF7FEDFBFF7F17FCFF7FEDFBFF7FDDFBFF7F9CFBFF7F4AFCFF7F46FCFF7F30FCFF7FE1FBFF7F0DF9FF7F4C0E0000CFFBFF7F1DFCFF7FD6FBFF7F4FFCFF7F2EFCFF7F20FCFF7F56FCFF7F58FCFF7FFFFBFF7F39FCFF7F49FCFF7F39FCFF7F40FBFF7FFCFBFF7F41FCFF7F26FCFF7F0AFCFF7FDFFBFF7F24FCFF7F1AFCFF7F40FCFF7F86FBFF7F55FCFF7F4FFCFF7FD1FBFF7F10FCFF7F98FBFF7F91FBFF7F0CFCFF7F0D0B0000CBFBFF7F0FFCFF7FCAFBFF7F46FCFF7F36FCFF7F1DFCFF7F42FCFF7F24FCFF7FBBFBFF7FEBFBFF7F9AFBFF7FB0FBFF7F0DFCFF7FD7FBFF7F4BFCFF7F3FFCFF7FF6FBFF7F4CFCFF7F55FCFF7FEDFBFF7F34FCFF7F47FCFF7F32FCFF7FE4FBFF7F3DFCFF7FF0FBFF7F1BFCFF7FF0FBFF7FBDFBFF7F1DFCFF7FFDFBFF7F1BFCFF7FF2FBFF7F49FCFF7F2DFCFF7F7CFBFF7FFBFBFF7F1CFCFF7F22FCFF7F45FCFF7F13FCFF7F33FCFF7F0CFCFF7F2AFCFF7F21FCFF7F5BFCFF7F4EFCFF7F55FCFF7F0305000025FCFF7F39FCFF7F28FCFF7F28FCFF7F42FCFF7F3DFCFF7F5BFCFF7F29FCFF7F01FCFF7F45FCFF7F57FCFF7F38FCFF7F79FBFF7F05FCFF7F2EFCFF7F36FCFF7FDFFBFF7F58FCFF7FF3FBFF7F34FCFF7F2FFCFF7F49FCFF7F41FCFF7F4AFCFF7F36FCFF7F4AFCFF7F49FCFF7F14FCFF7F99FBFF7F1CFCFF7F22FCFF7F45FCFF7F13FCFF7F33FCFF7F0CFCFF7F2AFCFF7F21FCFF7F5BFCFF7F4EFCFF7F55FCFF7F0305000025FCFF7F39FCFF7F28FCFF7F28FCFF7F42FCFF7F3DFCFF7F5BFCFF7F29FCFF7F01FCFF7F45FCFF7F57FCFF7F38FCFF7F79FBFF7F05FCFF7F2EFCFF7F36FCFF7FDFFBFF7F58FCFF7FF3FBFF7F34FCFF7F2FFCFF7F49FCFF7F41FCFF7F4AFCFF7F36FCFF7F4AFCFF7F49FCFF7F14FCFF7F99FBFF7FA7FBFF7FC2FAFF7FFFFBFF7FA0FBFF7FC5FBFF7F56090000C6FBFF7FE4FBFF7F4BF9FF7F0EFCFF7F05FCFF7FE0FBFF7FB9FBFF7FFDFBFF7FD2FBFF7FE9FBFF7FBCFBFF7F91FBFF7FF8FBFF7F9CFBFF7FE90B0000D2F8FF7F80FBFF7FF5FBFF7F01FCFF7F02FCFF7F00FCFF7F74FBFF7F93FBFF7F21FCFF7F1DFCFF7FEDFBFF7FF4FBFF7FE3FBFF7FF9FBFF7F20FBFF7FF3FBFF7FE3FBFF7FE7FBFF7F87FBFF7F6BFBFF7F0AFCFF7F13FBFF7F3CFCFF7F09FCFF7F14FCFF7F850A000012FCFF7F1DFCFF7F5AFCFF7F27FCFF7F43FCFF7F21FCFF7F0EFCFF7F2FFCFF7F14FCFF7F1CFCFF7FE2FBFF7FB2FBFF7F5AFCFF7F44FCFF7F46FAFF7F51FCFF7F2AFCFF7F2FFCFF7F34FCFF7F43FCFF7F31FCFF7FADFBFF7FBBFBFF7F3BFCFF7F3DFCFF7F24FCFF7F21FCFF7F42FCFF7F36FCFF7F41FBFF7F28FCFF7F1DFCFF7F19FCFF7FF6FBFF7FE8FBFF7F47FCFF7F0CFCFF7F54FCFF7F03FCFF7F49FCFF7F67FAFF7F4CFCFF7F3BFCFF7F5EFCFF7FABFBFF7F34FCFF7F4CFCFF7F47FCFF7F52FCFF7F4BFCFF7F56FCFF7FF1FBFF7F23FAFF7F5EFCFF7F3EFCFF7F44FCFF7F5AFCFF7F4CFCFF7F23FCFF7F08FCFF7F49FCFF7F4FFCFF7F2CFCFF7F34FCFF7FFFFBFF7F56FCFF7F4BFCFF7F57FCFF7F5BFCFF7F54FCFF7F050800004DFCFF7F64FAFF7F2DFCFF7F41FCFF7F35FCFF7FE9FBFF7FE5FBFF7F2CFCFF7FE3FBFF7F03FCFF7F2EFCFF7F5AF9FF7F2EFCFF7F47FCFF7F2CFCFF7F4CFCFF7F37FCFF7FF9FBFF7F1AFCFF7FEEFBFF7F11FCFF7FBFFBFF7FD4FAFF7F50FCFF7F48FCFF7F1BFCFF7F52FCFF7F57FCFF7FE50C000043FCFF7F3FFCFF7F25FCFF7F12FCFF7F48FCFF7F25FCFF7FFEFBFF7F1EFCFF7F2FFBFF7F89FAFF7F27FCFF7F2DFCFF7F17FCFF7F50FCFF7F40FCFF7FDAFBFF7F1DFCFF7F1EFCFF7F19FCFF7F42FCFF7F16FCFF7FB9FBFF7F3EFCFF7F38FCFF7F40FCFF7F52FCFF7F4CFCFF7F53FCFF7F04FCFF7F26FCFF7F38FCFF7F20FCFF7F36FCFF7FF3FBFF7F47FCFF7F57FCFF7F53FCFF7F3EFCFF7F59FCFF7F5BFCFF7FD6FBFF7F1FFCFF7F0BFBFF7F20FCFF7F32FCFF7F54FCFF7F3EFCFF7F8C0500003CFCFF7FAEFBFF7F1EFCFF7FE8FBFF7F53FCFF7F36FCFF7F5BFCFF7F4DFCFF7F16FCFF7F3FFCFF7F4DFCFF7F4EFCFF7F38FCFF7F47FCFF7F4AFCFF7F50FCFF7F4BFCFF7F79FBFF7FD2FAFF7F52FCFF7F53FCFF7F35FCFF7F49FCFF7F2DFCFF7F1DFCFF7F54FCFF7F58FCFF7F5BFCFF7F19FCFF7F350600007EFBFF7F7EFAFF7F00FCFF7F4EFCFF7F52FCFF7F58FCFF7F42FCFF7F55FCFF7F30FBFF7F5FFCFF7F55FCFF7F51FCFF7F54FCFF7F5BFCFF7F2DFCFF7F4AFCFF7F53FCFF7F3FFCFF7F52FCFF7F47FCFF7F40FCFF7F4DFCFF7F4EFCFF7F38FCFF7F47FCFF7F4AFCFF7F50FCFF7F4BFCFF7F79FBFF7FD2FAFF7F52FCFF7F53FCFF7F35FCFF7F49FCFF7F2DFCFF7F1DFCFF7F54FCFF7F58FCFF7F5BFCFF7F19FCFF7F350600007EFBFF7F7EFAFF7F00FCFF7F4EFCFF7F52FCFF7F58FCFF7F42FCFF7F55FCFF7F30FBFF7F5FFCFF7F55FCFF7F51FCFF7F54FCFF7F5BFCFF7F2DFCFF7F4AFCFF7F53FCFF7F3FFCFF7F52FCFF7F47FCFF7F40FCFF7F58FCFF7F3DFCFF7F37FCFF7F58FCFF7F58FCFF7F44FCFF7F58FCFF7F54FCFF7F67FBFF7F59FCFF7F11FCFF7F56FCFF7F57FCFF7F5CFCFF7F5CFCFF7F54FCFF7F54FCFF7F57FCFF7F31FBFF7F0AFCFF7FB1FBFF7F00F0FF7FD50F00005BFCFF7F58FCFF7F4BFCFF7F57FCFF7F4AFCFF7F15FBFF7F53FCFF7F5CFCFF7F47FCFF7F53FCFF7F47FCFF7F26FCFF7F59FCFF7F49FCFF7F3AFCFF7F10FCFF7F56FCFF7F50FCFF7F13FCFF7F19FCFF7F180800000CFCFF7F24FCFF7F42FCFF7F25FCFF7F56FCFF7F01FBFF7F53FCFF7F54FCFF7F46FCFF7F21FCFF7F39FCFF7F25FCFF7FA6FBFF7FFFFBFF7F89FBFF7F1CFCFF7F37FCFF7F41FCFF7FDEFBFF7F3EFCFF7F39FCFF7F4CFCFF7F48FCFF7F49FCFF7F2DFCFF7F59FBFF7F43FCFF7F44FCFF7F34FCFF7FA1FBFF7F19FCFF7F83FBFF7F52FCFF7F34FCFF7F54FCFF7F33FCFF7F0EFCFF7F38FCFF7F13FCFF7F19FCFF7F180800000CFCFF7F24FCFF7F42FCFF7F25FCFF7F56FCFF7F01FBFF7F53FCFF7F54FCFF7F46FCFF7F21FCFF7F39FCFF7F25FCFF7FA6FBFF7FFFFBFF7F89FBFF7F1CFCFF7F37FCFF7F41FCFF7FDEFBFF7F3EFCFF7F39FCFF7F4CFCFF7F48FCFF7F49FCFF7F2DFCFF7F59FBFF7F43FCFF7F44FCFF7F34FCFF7FA1FBFF7F19FCFF7F83FBFF7F52FCFF7F34FCFF7F54FCFF7F33FCFF7F0EFCFF7F38FCFF7F13FCFF7F19FCFF7F180800000CFCFF7F24FCFF7F42FCFF7F25FCFF7F56FCFF7F01FBFF7F53FCFF7F54FCFF7F46FCFF7F21FCFF7F39FCFF7F25FCFF7FA6FBFF7FFFFBFF7F89FBFF7F1CFCFF7F37FCFF7F41FCFF7FDEFBFF7F3EFCFF7F39FCFF7F4CFCFF7F48FCFF7F49FCFF7F2DFCFF7F59FBFF7F43FCFF7F44FCFF7F34FCFF7FA1FBFF7F19FCFF7F83FBFF7F52FCFF7F34FCFF7F54FCFF7F33FCFF7F0EFCFF7F38FCFF7F5AFCFF7F4FFCFF7F5BFCFF7F4CFCFF7F59FCFF7FF8FBFF7F5AFCFF7FA9FBFF7F4CFCFF7FE3FBFF7F31FCFF7F4FFCFF7F59FCFF7F5DFCFF7F5DFCFF7F57FCFF7F06FCFF7FD6FAFF7F3BFCFF7F41FCFF7F35FCFF7F52FCFF7F31FCFF7F53FCFF7F45FCFF7F50FCFF7F59FCFF7F53FCFF7F2AFCFF7F35FCFF7F5DFCFF7F5AFCFF7F57FCFF7F5CFCFF7F46FCFF7FF2F9FF7F5BFCFF7FAB04000048FCFF7F59FCFF7F55FCFF7FF3FBFF7FF8FBFF7F35FCFF7FE6FBFF7F0DFCFF7FD3FBFF7F0DFCFF7F39FCFF7F57FCFF7F45FCFF7F4EFCFF7FCFFBFF7F04FCFF7F21FCFF7FFDFBFF7FFBFBFF7F2FFCFF7F17FCFF7F58FCFF7F3CFCFF7FB6FBFF7F27FCFF7F50FCFF7F1CFCFF7F30FCFF7F3EFCFF7F30FCFF7F1DFCFF7F26FCFF7F51FCFF7F3EFCFF7F20FCFF7F04FCFF7F38FCFF7F2CFCFF7F34FCFF7F21FCFF7F52FCFF7F3BFCFF7FE5FBFF7F7B0600004AFCFF7F50FCFF7F49FCFF7F4EFCFF7F52FCFF7F48FCFF7F52FCFF7F4CFCFF7F40FCFF7F52FCFF7F34FCFF7F0DFCFF7F4CFCFF7F52FCFF7F4EFCFF7F3CFCFF7F4AFCFF7F9EFBFF7F59FCFF7F59FCFF7F15FCFF7FF0FBFF7F4DFCFF7F41FCFF7FDEFBFF7F6F05000026FCFF7F52FCFF7F47FCFF7F98FBFF7FC0FAFF7F4FFCFF7FC9FBFF7F8AFBFF7F4BFCFF7F4AFCFF7F50FCFF7F4FFCFF7F11FCFF7F49FCFF7F3EFCFF7F65FBFF7F44FBFF7FEEFBFF7F2DFBFF7F8F070000D5FBFF7FD1FAFF7F32FCFF7F30FCFF7F3AFCFF7F3BFCFF7F0FFCFF7F84FBFF7FC2FBFF7F69FBFF7F6BFBFF7FE1FBFF7F74FBFF7F27FCFF7F32FCFF7FE2FBFF7F09FCFF7F43FCFF7FCAFBFF7FEDFBFF7F3DFCFF7F20FCFF7FB4FBFF7F2FFCFF7F27FCFF7FB2FBFF7F5006000079FBFF7FF7FBFF7FDDFBFF7F2AFCFF7F55FBFF7F4CFCFF7F40FCFF7F3EFBFF7FD4FBFF7F4C0C0000C1FBFF7F17FCFF7FA2FBFF7FE6FBFF7F0FFCFF7FE6FBFF7F1FFCFF7F3FFCFF7F49FCFF7F41FCFF7F2CFCFF7FD9FBFF7F32FBFF7F59FAFF7FC2FBFF7F15FCFF7FCBFBFF7F4BFCFF7F45FCFF7F05FCFF7F4EFCFF7F55FCFF7FF9FBFF7F37FCFF7F48FCFF7F38FCFF7F0BFBFF7F41FCFF7F40FCFF7F24FCFF7F07FCFF7FD1FBFF7F1EFCFF7F0AFCFF7F3FFCFF7F69FBFF7F54FCFF7F4DFCFF7FBAFBFF7F0AFCFF7F4C0C0000C1FBFF7F17FCFF7FA2FBFF7FE6FBFF7F0FFCFF7FE6FBFF7F1FFCFF7F3FFCFF7F49FCFF7F41FCFF7F2CFCFF7FD9FBFF7F32FBFF7F59FAFF7FC2FBFF7F15FCFF7FCBFBFF7F4BFCFF7F45FCFF7F05FCFF7F4EFCFF7F55FCFF7FF9FBFF7F37FCFF7F48FCFF7F38FCFF7F0BFBFF7F41FCFF7F40FCFF7F24FCFF7F07FCFF7FD1FBFF7F1EFCFF7F0AFCFF7F3FFCFF7F69FBFF7F54FCFF7F4DFCFF7FBAFBFF7F0AFCFF7F4C0C0000C1FBFF7F17FCFF7FA2FBFF7FE6FBFF7F0FFCFF7FE6FBFF7F1FFCFF7F3FFCFF7F49FCFF7F41FCFF7F2CFCFF7FD9FBFF7F32FBFF7F59FAFF7FC2FBFF7F15FCFF7FCBFBFF7F4BFCFF7F45FCFF7F05FCFF7F4EFCFF7F55FCFF7FF9FBFF7F37FCFF7F48FCFF7F38FCFF7F0BFBFF7F41FCFF7F40FCFF7F24FCFF7F07FCFF7FD1FBFF7F1EFCFF7F0AFCFF7F3FFCFF7F69FBFF7F54FCFF7F4DFCFF7FBAFBFF7F0AFCFF7F06FBFF7FFAFBFF7F32FCFF7FE7FBFF7F1DFCFF7F2AFCFF7F16FCFF7F39FCFF7F55FCFF7F50FCFF7F2EFCFF7F3CFCFF7F07FCFF7F9CFBFF7F1EFBFF7FFEFBFF7F2DFCFF7FFFFBFF7F3DFCFF7F50FCFF7F39FCFF7F1DFCFF7F4EFCFF7F1AFCFF7F44FCFF7F50FCFF7F44FCFF7F88FBFF7F50FCFF7F4FFCFF7F36FCFF7FA8FBFF7F05FCFF7F36FCFF7F2DFCFF7F49FCFF7F1708000058FCFF7F54FCFF7FF5FBFF7F27FCFF7F06FBFF7FFAFBFF7F32FCFF7FE7FBFF7F1DFCFF7F2AFCFF7F16FCFF7F39FCFF7F55FCFF7F50FCFF7F2EFCFF7F3CFCFF7F07FCFF7F9CFBFF7F1EFBFF7FFEFBFF7F2DFCFF7FFFFBFF7F3DFCFF7F50FCFF7F39FCFF7F1DFCFF7F4EFCFF7F1AFCFF7F44FCFF7F50FCFF7F44FCFF7F88FBFF7F50FCFF7F4FFCFF7F36FCFF7FA8FBFF7F05FCFF7F36FCFF7F2DFCFF7F49FCFF7F1708000058FCFF7F54FCFF7FF5FBFF7F27FCFF7F06FBFF7FFAFBFF7F32FCFF7FE7FBFF7F1DFCFF7F2AFCFF7F16FCFF7F39FCFF7F55FCFF7F50FCFF7F2EFCFF7F3CFCFF7F07FCFF7F9CFBFF7F1EFBFF7FFEFBFF7F2DFCFF7FFFFBFF7F3DFCFF7F50FCFF7F39FCFF7F1DFCFF7F4EFCFF7F1AFCFF7F44FCFF7F50FCFF7F44FCFF7F88FBFF7F50FCFF7F4FFCFF7F36FCFF7FA8FBFF7F05FCFF7F36FCFF7F2DFCFF7F49FCFF7F1708000058FCFF7F54FCFF7FF5FBFF7F27FCFF7F06FBFF7FFAFBFF7F32FCFF7FE7FBFF7F1DFCFF7F2AFCFF7F16FCFF7F39FCFF7F55FCFF7F50FCFF7F2EFCFF7F3CFCFF7F07FCFF7F9CFBFF7F1EFBFF7FFEFBFF7F2DFCFF7FFFFBFF7F3DFCFF7F50FCFF7F39FCFF7F1DFCFF7F4EFCFF7F1AFCFF7F44FCFF7F50FCFF7F44FCFF7F88FBFF7F50FCFF7F4FFCFF7F36FCFF7FA8FBFF7F05FCFF7F36FCFF7F2DFCFF7F49FCFF7F1708000058FCFF7F54FCFF7FF5FBFF7F27FCFF7FBCFAFF7FD2FAFF7F2AFCFF7FDFFBFF7F01FCFF7FB7FBFF7F01FCFF7FFEFBFF7F49FCFF7F45FCFF7F37FCFF7F37FCFF7FFAFBFF7F80FBFF7FEEFAFF7FF5FBFF7F2AFCFF7F0BFCFF7F52FCFF7F4DFCFF7F26FCFF7F59FCFF7F41FCFF7F14FCFF7F40FCFF7F4EFCFF7F3FFCFF7F160B000014FCFF7F1BFCFF7F2FFCFF7F1AFCFF7F00FCFF7F32FCFF7F20FCFF7F30FCFF7FA1FBFF7F51FCFF7F41FCFF7FE4FBFF7F1FFCFF7FBCFAFF7FD2FAFF7F2AFCFF7FDFFBFF7F01FCFF7FB7FBFF7F01FCFF7FFEFBFF7F49FCFF7F45FCFF7F37FCFF7F37FCFF7FFAFBFF7F80FBFF7FEEFAFF7FF5FBFF7F2AFCFF7F0BFCFF7F52FCFF7F4DFCFF7F26FCFF7F59FCFF7F41FCFF7F14FCFF7F40FCFF7F4EFCFF7F3FFCFF7F160B000014FCFF7F1BFCFF7F2FFCFF7F1AFCFF7F00FCFF7F32FCFF7F20FCFF7F30FCFF7FA1FBFF7F51FCFF7F41FCFF7FE4FBFF7F1FFCFF7FBCFAFF7FD2FAFF7F2AFCFF7FDFFBFF7F01FCFF7FB7FBFF7F01FCFF7FFEFBFF7F49FCFF7F45FCFF7F37FCFF7F37FCFF7FFAFBFF7F80FBFF7FEEFAFF7FF5FBFF7F2AFCFF7F0BFCFF7F52FCFF7F4DFCFF7F26FCFF7F59FCFF7F41FCFF7F14FCFF7F40FCFF7F4EFCFF7F3FFCFF7F160B000014FCFF7F1BFCFF7F2FFCFF7F1AFCFF7F00FCFF7F32FCFF7F20FCFF7F30FCFF7FA1FBFF7F51FCFF7F41FCFF7FE4FBFF7F1FFCFF7F"> : tensor<128x41xi31>
|
4 |
+
%0 = "FHELinalg.matmul_eint_int"(%arg0, %cst) : (tensor<1x128x!FHE.esint<30>>, tensor<128x41xi31>) -> tensor<1x41x!FHE.esint<30>>
|
5 |
+
%1 = "FHELinalg.to_unsigned"(%0) : (tensor<1x41x!FHE.esint<30>>) -> tensor<1x41x!FHE.eint<30>>
|
6 |
+
%2 = "FHELinalg.sum"(%arg0) {axes = [1], keep_dims = true} : (tensor<1x128x!FHE.esint<30>>) -> tensor<1x1x!FHE.esint<30>>
|
7 |
+
%c-928_i31 = arith.constant -928 : i31
|
8 |
+
%from_elements = tensor.from_elements %c-928_i31 : tensor<1xi31>
|
9 |
+
%3 = "FHELinalg.to_unsigned"(%2) : (tensor<1x1x!FHE.esint<30>>) -> tensor<1x1x!FHE.eint<30>>
|
10 |
+
%4 = "FHELinalg.mul_eint_int"(%3, %from_elements) : (tensor<1x1x!FHE.eint<30>>, tensor<1xi31>) -> tensor<1x1x!FHE.eint<30>>
|
11 |
+
%5 = "FHELinalg.to_signed"(%1) : (tensor<1x41x!FHE.eint<30>>) -> tensor<1x41x!FHE.esint<30>>
|
12 |
+
%6 = "FHELinalg.to_signed"(%4) : (tensor<1x1x!FHE.eint<30>>) -> tensor<1x1x!FHE.esint<30>>
|
13 |
+
%7 = "FHELinalg.sub_eint"(%5, %6) : (tensor<1x41x!FHE.esint<30>>, tensor<1x1x!FHE.esint<30>>) -> tensor<1x41x!FHE.esint<30>>
|
14 |
+
%cst_0 = arith.constant dense<[[55007587, 64672575, -8325351, 68799429, 27183085, 25897887, 26793162, -37370359, 9691029, -77060549, -79741437, -29642252, 24866418, 19172166, 66008164, 69263236, 5805906, 99861790, -68874205, -57767716, 45355732, 118646, -95272629, 31360153, -38812838, -59540471, -51388670, 24551846, -10687010, -1873264, -20900730, 3388994, 72444835, 7999021, 13874550, -33655965, 3273574, -90201021, -58513218, 54288116, -91177]]> : tensor<1x41xi31>
|
15 |
+
%8 = "FHELinalg.add_eint_int"(%7, %cst_0) : (tensor<1x41x!FHE.esint<30>>, tensor<1x41xi31>) -> tensor<1x41x!FHE.esint<30>>
|
16 |
+
return %8 : tensor<1x41x!FHE.esint<30>>
|
17 |
+
}
|
18 |
+
}
|
deployment_files/server/configuration.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"verbose": false, "compiler_debug_mode": false, "compiler_verbose_mode": false, "show_graph": null, "show_bit_width_constraints": null, "show_bit_width_assignments": null, "show_assigned_graph": null, "show_mlir": false, "show_optimizer": null, "show_statistics": null, "dump_artifacts_on_unexpected_failures": true, "enable_unsafe_features": false, "use_insecure_key_cache": false, "insecure_key_cache_location": null, "loop_parallelize": true, "dataflow_parallelize": false, "auto_parallelize": false, "compress_evaluation_keys": false, "p_error": 9.094947017729282e-13, "global_p_error": null, "auto_adjust_rounders": false, "auto_adjust_truncators": false, "single_precision": false, "parameter_selection_strategy": "multi", "show_progress": false, "progress_title": "", "progress_tag": false, "fhe_simulation": false, "fhe_execution": true, "comparison_strategy_preference": [], "bitwise_strategy_preference": [], "shifts_with_promotion": true, "multivariate_strategy_preference": [], "min_max_strategy_preference": [], "composable": false, "use_gpu": false}
|
deployment_files/server/is_simulated
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
0
|
deployment_files/server/versions.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"concrete-python": "2.5", "concrete-ml": "1.4.0", "python": "3.10.11"}
|
deployment_files/server_dir/2820248940_encrypted_input
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:1e509a3079177c527a89695b418b96d9050c72a25f2c7a81d89d17e09e99b2b1
|
3 |
+
size 2003208
|
deployment_files/server_dir/2820248940_encrypted_output
ADDED
Binary file (642 kB). View file
|
|
deployment_files/server_dir/2820248940_valuation_key
ADDED
Binary file (64 Bytes). View file
|
|
deployment_files_generic/.fhe_keys/950347125_1/12513518805967278301/secretKey_0
ADDED
Binary file (10.2 kB). View file
|
|
deployment_files_generic/.fhe_keys/950347125_1/encrypted_input_1
ADDED
Binary file (60.8 kB). View file
|
|
deployment_files_generic/.fhe_keys/950347125_1/evaluation_key_1
ADDED
Binary file (64 Bytes). View file
|
|
deployment_files_generic/.fhe_keys/950347125_2/454142848044555242/secretKey_0
ADDED
Binary file (16.9 kB). View file
|
|
deployment_files_generic/.fhe_keys/950347125_2/encrypted_input_2
ADDED
Binary file (135 kB). View file
|
|
deployment_files_generic/.fhe_keys/950347125_2/evaluation_key_2
ADDED
Binary file (64 Bytes). View file
|
|
deployment_files_generic/client_dir/950347125_encrypted_output_1
ADDED
Binary file (10.4 kB). View file
|
|
deployment_files_generic/client_dir/950347125_encrypted_output_2
ADDED
Binary file (17.1 kB). View file
|
|
deployment_files_generic/server_dir/950347125_encrypted_input_model1
ADDED
Binary file (60.8 kB). View file
|
|
deployment_files_generic/server_dir/950347125_encrypted_input_model2
ADDED
Binary file (135 kB). View file
|
|
deployment_files_generic/server_dir/950347125_encrypted_output_model1
ADDED
Binary file (10.4 kB). View file
|
|
deployment_files_generic/server_dir/950347125_encrypted_output_model2
ADDED
Binary file (17.1 kB). View file
|
|
deployment_files_generic/server_dir/950347125_evaluation_key_1
ADDED
Binary file (64 Bytes). View file
|
|
deployment_files_generic/server_dir/950347125_evaluation_key_2
ADDED
Binary file (64 Bytes). View file
|
|
deployment_files_model1/client.zip
ADDED
Binary file (4.04 kB). View file
|
|
deployment_files_model1/server.zip
ADDED
Binary file (1.32 kB). View file
|
|
deployment_files_model1/versions.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"concrete-python": "2.5", "concrete-ml": "1.4.0", "python": "3.10.14"}
|