lucacolombo97 commited on
Commit
718b812
1 Parent(s): a20369f
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +3 -0
  2. __pycache__/app.cpython-310.pyc +0 -0
  3. __pycache__/dev_dhiria.cpython-310.pyc +0 -0
  4. __pycache__/server.cpython-310.pyc +0 -0
  5. __pycache__/stuff.cpython-310.pyc +0 -0
  6. __pycache__/symptoms_categories.cpython-310.pyc +0 -0
  7. __pycache__/utils.cpython-310.pyc +0 -0
  8. app.py +416 -429
  9. atlhete-high-resolution-logo-black-transparent.png +0 -0
  10. data/200_Users_Running_Dataset.csv +3 -0
  11. data/data_mental.csv +0 -0
  12. data/dataset_for_last_model.csv +97 -0
  13. data/example_input_ecg_fft.csv +3 -0
  14. data/synthetic_ecg_fft_dataset.csv +0 -0
  15. data_for_demo/focus_on_technique_mental.csv +2 -0
  16. data_for_demo/focus_on_technique_running.csv +0 -0
  17. data_for_demo/rest_mental.csv +2 -0
  18. data_for_demo/rest_running.csv +0 -0
  19. deployment_files/.DS_Store +0 -0
  20. deployment_files/.fhe_keys/2820248940/15341225681980396668/secretKey_0 +0 -0
  21. deployment_files/.fhe_keys/2820248940/encrypted_input +3 -0
  22. deployment_files/.fhe_keys/2820248940/evaluation_key +0 -0
  23. deployment_files/client/client.specs.json +1 -0
  24. deployment_files/client/serialized_processing.json +1 -0
  25. deployment_files/client/versions.json +1 -0
  26. deployment_files/client_dir/2820248940_encrypted_output +0 -0
  27. deployment_files/server/circuit.mlir +18 -0
  28. deployment_files/server/configuration.json +1 -0
  29. deployment_files/server/is_simulated +1 -0
  30. deployment_files/server/versions.json +1 -0
  31. deployment_files/server_dir/2820248940_encrypted_input +3 -0
  32. deployment_files/server_dir/2820248940_encrypted_output +0 -0
  33. deployment_files/server_dir/2820248940_valuation_key +0 -0
  34. deployment_files_generic/.fhe_keys/950347125_1/12513518805967278301/secretKey_0 +0 -0
  35. deployment_files_generic/.fhe_keys/950347125_1/encrypted_input_1 +0 -0
  36. deployment_files_generic/.fhe_keys/950347125_1/evaluation_key_1 +0 -0
  37. deployment_files_generic/.fhe_keys/950347125_2/454142848044555242/secretKey_0 +0 -0
  38. deployment_files_generic/.fhe_keys/950347125_2/encrypted_input_2 +0 -0
  39. deployment_files_generic/.fhe_keys/950347125_2/evaluation_key_2 +0 -0
  40. deployment_files_generic/client_dir/950347125_encrypted_output_1 +0 -0
  41. deployment_files_generic/client_dir/950347125_encrypted_output_2 +0 -0
  42. deployment_files_generic/server_dir/950347125_encrypted_input_model1 +0 -0
  43. deployment_files_generic/server_dir/950347125_encrypted_input_model2 +0 -0
  44. deployment_files_generic/server_dir/950347125_encrypted_output_model1 +0 -0
  45. deployment_files_generic/server_dir/950347125_encrypted_output_model2 +0 -0
  46. deployment_files_generic/server_dir/950347125_evaluation_key_1 +0 -0
  47. deployment_files_generic/server_dir/950347125_evaluation_key_2 +0 -0
  48. deployment_files_model1/client.zip +0 -0
  49. deployment_files_model1/server.zip +0 -0
  50. 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 symptoms_categories import SYMPTOMS_LIST
10
  from utils import (
11
  CLIENT_DIR,
12
  CURRENT_DIR,
13
- DEPLOYMENT_DIR,
 
 
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 display_default_symptoms_fn(default_disease: str) -> Dict:
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=DEPLOYMENT_DIR, key_dir=KEYS_DIR / f"{user_id}")
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}/evaluation_key"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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(user_symptoms: np.ndarray, user_id: str) -> None:
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
- visible=True,
196
- value="⚠️ Please ensure that your symptoms have been submitted and "
197
- "that you have generated the evaluation key.",
198
- )
199
  }
200
 
201
  # Retrieve the client API
202
- client = FHEModelClient(path_dir=DEPLOYMENT_DIR, key_dir=KEYS_DIR / f"{user_id}")
203
- client.load()
204
-
205
- user_symptoms = np.fromstring(user_symptoms[2:-2], dtype=int, sep=".").reshape(1, -1)
206
- # quant_user_symptoms = client.model.quantize_input(user_symptoms)
 
207
 
208
- encrypted_quantized_user_symptoms = client.quantize_encrypt_serialize(user_symptoms)
209
- assert isinstance(encrypted_quantized_user_symptoms, bytes)
210
- encrypted_input_path = KEYS_DIR / f"{user_id}/encrypted_input"
211
 
212
  with encrypted_input_path.open("wb") as f:
213
- f.write(encrypted_quantized_user_symptoms)
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, user_symptoms: np.ndarray) -> Dict:
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
- user_symptoms (np.ndarray): The user symptoms
232
  """
233
 
234
- if is_none(user_id) or is_none(user_symptoms):
235
  return {
236
- error_box4: gr.update(
237
- visible=True,
238
- value="⚠️ Please check your connectivity \n"
239
- "⚠️ Ensure that the symptoms have been submitted and the evaluation "
240
- "key has been generated before sending the data to the server.",
241
- )
242
  }
243
 
244
- evaluation_key_path = KEYS_DIR / f"{user_id}/evaluation_key"
245
- encrypted_input_path = KEYS_DIR / f"{user_id}/encrypted_input"
246
 
247
- if not evaluation_key_path.is_file():
 
 
 
 
 
 
 
248
  print(
249
  "Error Encountered While Sending Data to the Server: "
250
- f"The key has been generated correctly - {evaluation_key_path.is_file()=}"
251
  )
252
 
253
  return {
254
- error_box4: gr.update(visible=True, value="⚠️ Please generate the private key first.")
255
  }
256
 
257
- if not encrypted_input_path.is_file():
258
  print(
259
  "Error Encountered While Sending Data to the Server: The data has not been encrypted "
260
- f"correctly on the client side - {encrypted_input_path.is_file()=}"
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
- files = [
276
- ("files", open(encrypted_input_path, "rb")),
277
- ("files", open(evaluation_key_path, "rb")),
278
- ]
 
 
 
 
 
 
 
 
279
 
280
  # Send the encrypted input and evaluation key to the server
281
- url = SERVER_URL + "send_input"
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
- url = SERVER_URL + "run_fhe"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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"{response.json():.2f} seconds"),
340
  }
341
 
342
 
343
- def get_output_fn(user_id: str, user_symptoms: np.ndarray) -> Dict:
344
- """Retreive the encrypted data from the server.
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) or is_none(user_symptoms):
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 + "get_output"
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}_encrypted_output"
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
- if is_none(user_id) or is_none(user_symptoms):
 
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}_encrypted_output"
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
- # Retrieve the client API
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
- top3_diseases = np.argsort(output.flatten())[-3:][::-1]
437
- top3_proba = output[0][top3_diseases]
438
 
439
- out = ""
 
440
 
441
- if top3_proba[0] < threshold or abs(top3_proba[0] - top3_proba[1]) < 0.1:
442
- out = (
443
- "⚠️ The prediction appears uncertain; including more symptoms "
444
- "may improve the results.\n\n"
445
- )
 
 
 
 
 
 
 
 
446
 
447
  out = (
448
- f"{out}Given the symptoms you provided: "
449
- f"{pretty_print(checked_symptoms, case_conversion=str.capitalize, delimiter=', ')}\n\n"
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
- error_box7: gr.update(visible=False),
458
- decrypt_box: out,
459
- submit_btn: gr.update(value="Submit"),
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
- (X_train, X_test), (y_train, y_test), valid_symptoms, diseases = load_data()
501
-
502
- with gr.Blocks() as demo:
 
 
 
 
 
 
 
 
 
503
 
504
  # Link + images
505
  gr.Markdown()
506
  gr.Markdown(
507
  """
508
  <p align="center">
509
- <img width=200 src="https://user-images.githubusercontent.com/5758427/197816413-d9cddad3-ba38-4793-847d-120975e1da11.png">
510
  </p>
511
  """)
512
- gr.Markdown()
513
- gr.Markdown("""<h2 align="center">Health Prediction On Encrypted Data Using Fully Homomorphic Encryption</h2>""")
514
- gr.Markdown()
515
- gr.Markdown(
516
- """
517
- <p align="center">
518
- <a href="https://github.com/zama-ai/concrete-ml"> <img style="vertical-align: middle; display:inline-block; margin-right: 3px;" width=15 src="https://user-images.githubusercontent.com/5758427/197972109-faaaff3e-10e2-4ab6-80f5-7531f7cfb08f.png">Concrete-ML</a>
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
- gr.Markdown()
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
- with gr.Column(scale=2):
579
- default_disease_box = gr.Dropdown(sorted(diseases), label="Diseases", visible=False)
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
- # ------------------------- Step 2 -------------------------
600
- gr.Markdown("\n")
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
- # Step 2.2: Encrypt data locally
631
- gr.Markdown("### Encrypt the data")
 
 
 
632
  encrypt_btn = gr.Button("Encrypt the data using the private secret key")
633
  error_box3 = gr.Textbox(label="Error ❌", visible=False)
634
- quant_vect_box = gr.Textbox(label="Quantized Vector:", visible=False)
635
 
636
- with gr.Row():
637
- with gr.Column():
638
- one_hot_vect_box = gr.Textbox(label="User Symptoms Vector:", max_lines=10)
639
- with gr.Column():
640
- enc_vect_box = gr.Textbox(label="Encrypted Vector:", max_lines=10)
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
- # with gr.Row().style(equal_height=False):
658
- with gr.Row():
659
- with gr.Column(scale=4):
660
- send_input_btn = gr.Button("Send data")
661
- with gr.Column(scale=1):
662
- srv_resp_send_data_box = gr.Checkbox(label="Data Sent", show_label=False)
663
 
664
  send_input_btn.click(
665
  send_input_fn,
666
- inputs=[user_id_box, one_hot_vect],
667
  outputs=[error_box4, srv_resp_send_data_box],
668
  )
669
 
670
- # ------------------------- Step 3 -------------------------
671
- gr.Markdown("\n")
672
- gr.Markdown("## Step 3: Run the FHE evaluation")
673
- gr.Markdown("<hr />")
674
- gr.Markdown("<span style='color:grey'>Server Side</span>")
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
- # ------------------------- Step 4 -------------------------
690
- gr.Markdown("\n")
691
- gr.Markdown("## Step 4: Decrypt the data")
692
- gr.Markdown("<hr />")
693
- gr.Markdown("<span style='color:grey'>Client Side</span>")
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, one_hot_vect],
711
  outputs=[srv_resp_retrieve_data_box, error_box6],
712
  )
713
 
714
- # Step 4.1: Data transmission
715
- gr.Markdown("### Decrypt the output")
 
 
 
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, one_hot_vect, *check_boxes],
723
- outputs=[decrypt_box, error_box7, submit_btn],
724
- )
725
-
726
- # ------------------------- End -------------------------
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
- demo.launch()
 
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"}