From 6adced12b4690f5bf0da0468fa7f5b364c48547a Mon Sep 17 00:00:00 2001
From: seyffejn <55194230+seyffejn@users.noreply.github.com>
Date: Wed, 17 Jun 2020 16:16:10 +0200
Subject: [PATCH] ditigalFilter.py removed + small GUI changes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
ein paar kleinere GUI skalierungsänderungen
---
.gitignore | 5 +
TinnitusAnalyse/.idea/workspace.xml | 183 +++++++++++-------
TinnitusAnalyse/DigitalFilter.py | 96 ---------
TinnitusAnalyse/SoundGenerator.py | 2 +-
TinnitusAnalyse/TinnitusAnalyse_GUI.py | 45 +++--
TinnitusAnalyse/TinnitusDaten.csv | 16 +-
.../__pycache__/SoundGenerator.cpython-35.pyc | Bin 3434 -> 4192 bytes
7 files changed, 149 insertions(+), 198 deletions(-)
delete mode 100644 TinnitusAnalyse/DigitalFilter.py
diff --git a/.gitignore b/.gitignore
index 9e90d22..eb8ebaa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,8 @@ TinnitusAnalyse/.idea/workspace.xml
TinnitusAnalyse/eggs.csv
TinnitusAnalyse/.idea/workspace.xml
*.xml
+TinnitusAnalyse/sound.wav
+*.pyc
+*.xml
+TinnitusAnalyse/.idea/workspace.xml
+TinnitusAnalyse/__pycache__/SoundGenerator.cpython-35.pyc
diff --git a/TinnitusAnalyse/.idea/workspace.xml b/TinnitusAnalyse/.idea/workspace.xml
index 33d846b..67546c9 100644
--- a/TinnitusAnalyse/.idea/workspace.xml
+++ b/TinnitusAnalyse/.idea/workspace.xml
@@ -2,8 +2,12 @@
-
+
+
+
+
+
@@ -16,8 +20,8 @@
-
-
+
+
@@ -34,11 +38,11 @@
-
+
-
-
+
+
@@ -46,22 +50,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -99,6 +91,8 @@
scale_lautstärke_links_change
mute
Sound(
+ 700
+ nachname
C:\Users\Julian\PycharmProjects\TinnitusAnalyse
@@ -111,9 +105,11 @@
@@ -153,7 +149,28 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -175,6 +192,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -217,33 +255,13 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -269,13 +287,13 @@
-
+
-
+
@@ -314,6 +332,13 @@
+
+
+
+
+
+
+
@@ -321,36 +346,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -358,5 +356,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TinnitusAnalyse/DigitalFilter.py b/TinnitusAnalyse/DigitalFilter.py
deleted file mode 100644
index 6c03c6b..0000000
--- a/TinnitusAnalyse/DigitalFilter.py
+++ /dev/null
@@ -1,96 +0,0 @@
-import matplotlib.pyplot as plt # For plotting
-from math import sin, pi, cos # For generating input signals
-import numpy as np
-import sys # For reading command line arguments
-
-
-fs = 44100 # sampling frequency (Abtastfrequenz)
-
-koeff = {
- "b0": 0,
- "b1": 0,
- "b2": 0,
- "a1": 0,
- "a2": 0
-}
-
-def koeffizienten_berechnen(omega, r):
- # Koeffizientenberechnung nach Tobola VL S.107 - IIR Filter, 2. Ordnung
- koeff["b0"] = 1
- koeff["b1"] = 0
- koeff["b2"] = -1
- koeff["a1"] = -2*r*cos(omega)
- koeff["a2"] = r**2
-
-def filter(x):
- y = [0]*len(x)
- for k in range(4, len(x)):
- y[k] = koeff["b0"]*x[k] + koeff["b1"]*x[k-1] + koeff["b2"]*x[k-2] - koeff["a1"]*y[k-1] - koeff["a2"]*y[k-2]
-
- return y
-
-
-
-
-dauer_ms = 10000 # 10 Sekunden
-num_samples = dauer_ms * (fs / 1000) # framerate -pro Sekunde- umgerechnet in -pro Millisekunde-
-
-t = np.linspace(0, 10, int(num_samples)) # array zum darstellen der x-Achse
-amp = 1
-
-f_input1 = 1
-f_input2 = 5
-f_input3 = 10
-
-input1 = []
-input2 = []
-input3 = []
-for x in range(int(num_samples)): # einen einfachen Sinus ins array schreiben
- input1.append(amp * sin(2 * pi * f_input1 * (x / fs)))
- input2.append(amp * sin(2 * pi * f_input2 * (x / fs)))
- input3.append(amp * sin(2 * pi * f_input3 * (x / fs)))
-
-
-input_ges = np.add(input1, input2) # Sinus aufaddieren um ein halbwegs realistisches Audiosignal zu bekommen
-#input_ges = np.add(input_ges, input3)
-
-#Filterparameter hier einstellen
-fr = 5
-omega = 2*pi*fr/fs
-r = 0.01
-koeffizienten_berechnen(omega, r) # Koeffizienten berechnen mit Mittelfrequenz 10Hz
-
-output = filter(input_ges)
-
-### Plot the signals for comparison
-plt.figure(1)
-plt.subplot(231)
-plt.ylabel('Amplitude')
-plt.xlabel('t [s]')
-plt.title('Input1 f=' + str(f_input1) + "Hz")
-plt.plot(t, input1)
-
-plt.subplot(232)
-plt.ylabel('Amplitude')
-plt.xlabel('t [s]')
-plt.title('Input2 f=' + str(f_input2) + "Hz")
-plt.plot(t, input2)
-
-# plt.subplot(233)
-# plt.ylabel('Amplitude')
-# plt.xlabel('t [s]')
-# plt.title('Input3 f=' + str(f_input3) + "Hz")
-# plt.plot(t, input3)
-
-plt.subplot(234)
-plt.ylabel('Amplitude')
-plt.xlabel('t [s]')
-plt.title('input_ges = i1 + i2')
-plt.plot(t, input_ges)
-
-plt.subplot(235)
-plt.ylabel('Amplitude')
-plt.xlabel('Samples')
-plt.title('gefiltertes Signal mit Resonanzfrequenz = ' + str(fr) + "Hz")
-plt.plot(t, output)
-plt.show()
\ No newline at end of file
diff --git a/TinnitusAnalyse/SoundGenerator.py b/TinnitusAnalyse/SoundGenerator.py
index ef27282..4e6d132 100644
--- a/TinnitusAnalyse/SoundGenerator.py
+++ b/TinnitusAnalyse/SoundGenerator.py
@@ -55,7 +55,7 @@ class Sound:
audio = []
self.tinnitus = tinnitus
self.name = name
- self.audio = audio # ein Array, in das die Sound-Werte geschrieben werden
+ self.audio = audio # ein Array, in das die Sound-Werte geschrieben werden (von -1, bis +1)
self.nchannels = nchannels # Zahl der audio channels (1:mono 2:stereo)
self.sampwidth = sampwidth # Größe eines einzelnen Sound-Werts (in bytes)
self.framerate = framerate # Abtastrate
diff --git a/TinnitusAnalyse/TinnitusAnalyse_GUI.py b/TinnitusAnalyse/TinnitusAnalyse_GUI.py
index db37015..0a33b5a 100644
--- a/TinnitusAnalyse/TinnitusAnalyse_GUI.py
+++ b/TinnitusAnalyse/TinnitusAnalyse_GUI.py
@@ -107,6 +107,7 @@ def unten_button_speichern_press():
tinnitus.kommentar = untenTextKommentar.get("1.0", END)
print("Speichere Patientendaten, siehe TinnitusDaten.csv")
tinnitus.speichern()
+ sound.wav_speichern()
def unten_button_play_press():
@@ -129,15 +130,17 @@ print("test")
root = Tk() # build the main window
root.title("Tinnitus Analyse")
#root.iconbitmap('headphones.ico') #todo: fix icon
-#root.minsize(width=200, height=600)
+root.minsize(width=800, height=500)
root.resizable(True, True)
-root.columnconfigure(0, weight=1) # falls freier Platz im Fenster ist, werden die Frames diesen benutzen
+root.columnconfigure(0, weight=1)
+root.columnconfigure(1, weight=1)
root.rowconfigure(0, weight=1)
"""------------------------------------------LINKER FRAME------------------------------------------------------------"""
linkerFrame = LabelFrame(root, text="Linkes Ohr", font="bold") # parent is root, padding is extra space at the edges
-linkerFrame.grid(column=0, row=0, sticky=(N + W + E)) # the frame sticks to every side of the window when resized
+linkerFrame.grid(column=0, row=0, sticky=(N+W+E+S)) # the frame sticks to every side of the window when resized
+
linksLautstärke = DoubleVar()
linksFrequenz = DoubleVar()
@@ -147,44 +150,45 @@ linksRauschenFrequenzband = DoubleVar()
# ------------------ LAUTSTÄRKE ------------------
linksLabelLautstärke = Label(linkerFrame, text="Lautstärke [%]:")
linksLabelLautstärke.grid(column=0, row=0, sticky=W)
-linksScaleLautstärke = Scale(linkerFrame, from_=0, to=100, orient=HORIZONTAL, length=700,
+linksScaleLautstärke = Scale(linkerFrame, from_=0, to=100, orient=HORIZONTAL, length=400,
command=links_scale_lautstärke_change)
-linksScaleLautstärke.grid(column=1, row=0, columnspan=10, sticky=W)
+linksScaleLautstärke.grid(column=1, row=0, sticky=N+S+W+E)
# -------- FREQUENZ ------------------------
linksLabelFrequenz = Label(linkerFrame, text="Frequenz [kHz]")
linksLabelFrequenz.grid(column=0, row=1, sticky=W) # sticky = w(est) makes the text left aligned
-linksScaleFrequenz = Scale(linkerFrame, from_=0, to=20, orient=HORIZONTAL, length=700, resolution=-1.0,
+linksScaleFrequenz = Scale(linkerFrame, from_=0, to=20, orient=HORIZONTAL, length=400, resolution=-1.0,
command=links_scale_frequenz_change)
-linksScaleFrequenz.grid(column=1, row=1, columnspan=10, sticky=(W+E))
+linksScaleFrequenz.grid(column=1, row=1, sticky=(W+E))
# ----------- ABTRENNSTRICH ----------------
linksSeparator = Separator(linkerFrame, orient="horizontal")
-linksSeparator.grid(column=0, row=2, columnspan=10, sticky=(W + E))
+linksSeparator.grid(column=0, row=2, sticky=(W + E), columnspan=3)
# ----------- RAUSCHEN --------------------
linksLabelRauschenLautstärke = Label(linkerFrame, text="Rauschen Lautstärke %", anchor="w")
linksLabelRauschenLautstärke.grid(column=0, row=3, sticky=W)
-linksScaleRauschenLautstärke = Scale(linkerFrame, from_=0, to=100, orient=HORIZONTAL, length=700,
+linksScaleRauschenLautstärke = Scale(linkerFrame, from_=0, to=100, orient=HORIZONTAL, length=400,
command=links_scale_rauschen_lautstärke_change)
linksScaleRauschenLautstärke.grid(column=1, row=3, sticky=(W+E))
linksLabelRauschenMittelFrequenz = Label(linkerFrame, text="Rauschen Mittelfrequenz [kHz]", anchor="w")
-linksLabelRauschenMittelFrequenz .grid(column=0, row=4)
-linksScaleRauschenMittelFrequenz = Scale(linkerFrame, from_=0, to=20, orient=HORIZONTAL, length=700, resolution=-1.0,
+linksLabelRauschenMittelFrequenz .grid(column=0, row=4, sticky=(W+E))
+linksScaleRauschenMittelFrequenz = Scale(linkerFrame, from_=0, to=20, orient=HORIZONTAL, length=400, resolution=-1.0,
command=links_scale_rauschen_mittelfrequenz_change)
-linksScaleRauschenMittelFrequenz.grid(column=1, row=4)
+linksScaleRauschenMittelFrequenz.grid(column=1, row=4, sticky=(W+E))
linksLabelRauschenBandbreite= Label(linkerFrame, text="Rauschen Bandbreite [kHz]", anchor="w")
linksLabelRauschenBandbreite.grid(column=0, row=5, sticky=W)
-linksScaleRauschenBandbreite = Scale(linkerFrame, from_=0, to=20, orient=HORIZONTAL, length=700, resolution=-1.0,
+linksScaleRauschenBandbreite = Scale(linkerFrame, from_=0, to=20, orient=HORIZONTAL, length=400, resolution=-1.0,
command=links_scale_rauschen_bandbreite_change)
linksScaleRauschenBandbreite.grid(column=1, row=5, sticky=(W+E))
"""----------------------------------------------RECHTER FRAME-------------------------------------------------------"""
rechterFrame = LabelFrame(root, text="Rechtes Ohr", font="bold")
-rechterFrame.grid(column=2, row=0, sticky=(N + E + W))
+rechterFrame.grid(column=2, row=0, sticky=(N+E+W+S))
+
# Variablen Rechts
rechtsFrequenz = DoubleVar()
@@ -195,14 +199,14 @@ rechtsLautstärke = DoubleVar()
# ------------------ LAUTSTÄRKE ------------------
rechtsLabelLautstärke = Label(rechterFrame, text="Lautstärke [%]:")
rechtsLabelLautstärke.grid(column=0, row=0, sticky=W)
-rechtsScaleLautstärke = Scale(rechterFrame, from_=0, to=100, orient=HORIZONTAL, length=700,
+rechtsScaleLautstärke = Scale(rechterFrame, from_=0, to=100, orient=HORIZONTAL, length=400,
command=rechts_scale_lautstärke_change)
rechtsScaleLautstärke.grid(column=1, row=0, columnspan=10, sticky=W)
# -------- FREQUENZ ------------------------
rechtsLabelFrequenz = Label(rechterFrame, text="Frequenz [kHz]")
rechtsLabelFrequenz.grid(column=0, row=1, sticky=W) # sticky = w(est) makes the text left aligned
-rechtsScaleFrequenz = Scale(rechterFrame, from_=0, to=20, orient=HORIZONTAL, length=700, resolution=-1.0,
+rechtsScaleFrequenz = Scale(rechterFrame, from_=0, to=20, orient=HORIZONTAL, length=400, resolution=-1.0,
command=rechts_scale_frequenz_change)
rechtsScaleFrequenz.grid(column=1, row=1, columnspan=10, sticky=(W+E))
@@ -213,26 +217,26 @@ rechtsSeparator.grid(column=0, row=2, columnspan=10, sticky=(W + E))
# ----------- RAUSCHEN --------------------
rechtsLabelRauschenLautstärke = Label(rechterFrame, text="Rauschen Lautstärke %", anchor="w")
rechtsLabelRauschenLautstärke.grid(column=0, row=3, sticky=W)
-rechtsScaleRauschenLautstärke = Scale(rechterFrame, from_=0, to=100, orient=HORIZONTAL, length=700,
+rechtsScaleRauschenLautstärke = Scale(rechterFrame, from_=0, to=100, orient=HORIZONTAL, length=400,
command=rechts_scale_rauschen_lautstärke_change)
rechtsScaleRauschenLautstärke.grid(column=1, row=3, sticky=(W+E))
rechtsLabelRauschenMittelFrequenz = Label(rechterFrame, text="Rauschen Mittelfrequenz [kHz]", anchor="w")
rechtsLabelRauschenMittelFrequenz .grid(column=0, row=4)
-rechtsScaleRauschenMittelFrequenz = Scale(rechterFrame, from_=0, to=20, orient=HORIZONTAL, length=700, resolution=-1.0,
+rechtsScaleRauschenMittelFrequenz = Scale(rechterFrame, from_=0, to=20, orient=HORIZONTAL, length=400, resolution=-1.0,
command=rechts_scale_rauschen_mittelfrequenz_change)
rechtsScaleRauschenMittelFrequenz.grid(column=1, row=4)
rechtsLabelRauschenBandbreite = Label(rechterFrame, text="Rauschen Bandbreite [kHz]", anchor="w")
rechtsLabelRauschenBandbreite.grid(column=0, row=5, sticky=W)
-rechtsScaleRauschenBandbreite = Scale(rechterFrame, from_=0, to=20, orient=HORIZONTAL, length=700, resolution=-1.0,
+rechtsScaleRauschenBandbreite = Scale(rechterFrame, from_=0, to=20, orient=HORIZONTAL, length=400, resolution=-1.0,
command=rechts_scale_rauschen_bandbreite_change)
rechtsScaleRauschenBandbreite.grid(column=1, row=5, sticky=(W+E))
"""------------------------------------------------ UNTERER FRAME----------------------------------------------------"""
untererFrame = LabelFrame(root, text="Generelles", border=10)
-untererFrame.grid(column=0, row=1, sticky=(N + W + S))
+untererFrame.grid(column=0, row=1, sticky=(N + W + S), columnspan=2)
vorname = StringVar() # Name des Patienten als String um den generierten Tinnitus später zuordnen zu können
nachname = StringVar()
@@ -290,7 +294,6 @@ untenButtonSpeichern.grid(column=4, row=6, sticky=S)
-# todo: , relief="raised" für play button
root.mainloop()
\ No newline at end of file
diff --git a/TinnitusAnalyse/TinnitusDaten.csv b/TinnitusAnalyse/TinnitusDaten.csv
index b21eb78..13b0f2c 100644
--- a/TinnitusAnalyse/TinnitusDaten.csv
+++ b/TinnitusAnalyse/TinnitusDaten.csv
@@ -1,6 +1,10 @@
-linke Frequenz;1890.0
-linke Lautstärke;0.18
-linkes Rauschen;0
-rechte Frequenz;600
-rechte Lautstärke;0
-rechtes Rauschen;0
+Vorname;asdas
+Nachname;asda
+linke Frequenz;1410.0
+linke Lautstärke;0.03
+linkes Rauschen;0.0
+rechte Frequenz;0.0
+rechte Lautstärke;0.0
+rechtes Rauschen;0.0
+Kommentar;
+
diff --git a/TinnitusAnalyse/__pycache__/SoundGenerator.cpython-35.pyc b/TinnitusAnalyse/__pycache__/SoundGenerator.cpython-35.pyc
index 1812ae953d980ed72c0106650ddfcdf3cb471bae..1af9cd58767427b35bcdfe666375469de824513e 100644
GIT binary patch
literal 4192
zcmai1U2hx56}`LMC6^SbZ&y<6v~*l2W!ngGliE$>rb?p3ZQ3$L?9{-*_F~N)Sxb>i
zYG!Fktn}nO^r`&=eJlbL=#MB6q(5R_TA)wvOWz9=?YT2tii!+$rMY`|KJUz&d+z00
zqfz_MxBmHP{tD4QXyz$F-$qdqBEi2yJ)&@`I}|!ay-T56=p_ohLiZ^w7kY)l3f)Q2
zuSB0?mJ&U~umDx)?wcy#R8@JYyRGtbtV`_<%i^g**+x-6h7hpESioyTx%h9_!onq*
zF2cr@F?~e`_tGp&^O2GcX6pnH{P5dF`2a;dg22QlMA1|+>u`-rC$_0XC(u#j(Ft@Y
zKAk{^Ql=B=P%3l+9ZEna(4ki(eL7g-)l-RPy+
zzWPXtgOSL_dR~goUViqyXqtZ!k8+jALhcK_WP8k3t(#7t#v|3)6WMIbhVA^KrqWpelLpq!_b%J74#x$CJzHS(PRVX_a~AIc>O#7;GGAbDIwK^
zk4L>U&K~RtwVw}$4~lze-uc<+N
z!@;!cds*B&R^q|k!6-}ahzuk0f!rJ(>mZ6!+;SAL4QdsFoa%+Y@ls*LX3@XHsNjbk
z!9y{CXrMMXPymtv;8UQ%TzS`_HGpjG6i5K>%%yi-TX$Hk#?|%&)m!5Q#-V5yVBQ)n<8W=A1?8821cJB52Gl||3s|DY
z;B{agv*0c{mz>M9e{RDW
zFHcc89n^05jA15(DAKhk>JO4pkM(*K9gO0hZIMfuR`TRC>oepf8zGs{*i^+kt~*!j
zrly0B>BAe{Mp3xc3*2g$)N&};GpSG#Pyzz0(dU7o*Eve+%;8M04NB&X?o+Zr$)eFQ
zYKf9%qhq)W=3CLe@z-%xvD`D~CkJA?jE3Z+DH
zufxXj!*9Mdf0uXnb0Z_9=&g2xZ5D
zuPtSRyYX+h`=n|VxY-=L14kcoNNDZi0L;u?I5U;F|NMjzz(Oz&!L1zzoxM2AL{G_Y
z!fqXO;$H7@+}RIn3Z&X&1`{SSwH9@dPePUUOl0umQIZaHH7n)-$}s3KP4Ycm-IV|f
z57(uh$aEz$6$(q>1oPt|Vhn3$Ca*t2KUXDT{gY8X9OZX&DdN6tvQ740qQT=XRPb&d
zrO8pNW@K?H@FHZ=W@wLJ*@2;BN
zUo!F=MjEts(TY=9Gjg4FO&oEKZt(b>hb=kYL7e
z?smmcKcA}!A2tZo+VD4`@gs9t&BIhC&A6wU?9;DvR7jgoM8RqKX7l|t&qebPkV3rJ
z+^p>g*+jT_5@%1E`*4e9C*Ewn`9|}u*atI+teM0kFevU2&u_onw#xSJw~h1IFZ%mW
zw6kaQzx?-a+vDZC1@Sf?3xQek&DP7>gGEAe9$>(${h>^=+@iU{wP*a#K-Rv5P4Fai
z(&c!FsF7%|AH&Z|D$TSzOtqU0bs61~L0^0Pmap+d-+>6LO60>B4yk55Wa=E@oCzlr
z|12X0jXJsZhM)nthT#)m3j-J(?WQ0F_O;M6Sy*7sBefH6-ymI%?k#P0O()^EH#bVJ|-3
zLpKx0IFTFItR39&;^moZ?DAlT*;QR>7W5Qy&=;>K-@{n^=pn@ciKdJ3hz_R>{4i+B
zC}yu8V%H!J312b_cqq5qbsXpD4<@@Z?zHppcQb@z;tgmARE59;vRGw{!9-PPmX>O?
z#&vTO9^t6w(?(LF+mo(H-7xe8b2R?n93I_1c$MxS9nPAUvUxn?JarfN+>p|)Gc8)f
z7LgBeCO9#|->{LBZC*4KHR-oR@+%X9*;o&ZcGhpnQrTA^LnPQ;P>xHt+^AMWNbMQK
zbBHi;P`(V!xHrMoTg&nWzTt((O2cy!A*K8Q_r1!(c=3-|yUF4f3*+9KtTE1QW@mD|
zxB2rO7AEiGY_C343DKbJI1uh6wTl^7)_bJ@
literal 3434
zcmbVPTW{mW6`mnQijpPY6UW_b*W08QHm!?Zom&ehyUn&qqZC;O+pC5E<`lbrHEv0cSPjWx+|hat$QN!YTXx+FYcvi=ZYs7
z#TAdytqBvFdu;O96wp-nL;oD}ie8^&eYK$M;xRvmQ1FI5pt+&ohBAM<0%JdEiUdOT`!DR`dWa_
zcMjWCV>DJp<(g7!+Ij7fXp*2HXrBZfvdVj;vr<)FKOY$ty1ETx_>FNv&vktw`BN!FQP{nc8j^p7do#do<;`n%y
zn=O45W*4nu7mq=Nt`QX=#mr(Ko
zizfkd)q+SnHCJ^-y2v^RY)Pcctb?EY}@jr)7uLds-V1}=c++bsk~&8W}~WA^beDwP`LpRz*
zv^=a@2O4ca6{>P`0IylF!Bhb)v^*UvtMN#U;iObyo1vzk$2#>*5??2Ai^LX*+az8j
z@l6unBEcBA1OmY%#ACh&A!JATSLkTzqBLFP$Xw?nIuG-LCiMq8Y9%Wk$
zfHbRg#5!WTZZj7~y0MN<^vL5shzA#bF=~%op+6TVKfOM~?aLW3j<;EM#h^1Y@>Ev+;-=LKmpQ92%)$fcYY*i@&AXrY)4W5QIf
zOeIgAiZ+m^CNYEXWw>IVgRn90$PO51#od%U?yB6Bx8!umMts(zU#B5j&n)C$pkTL_
zqImKiaX*d%hwBZ(z{$&GDlH7K`v@;8x&CI24n_fu0#G<&6P5CKM?5&*5D#$f27K0#
zI}m3|bci;BloCO57$a00?C4uffSDDZpdKf(r_6Yc0lh)NzZ9RB|0XS?CL-X{BZNYELx
z=aJ9ocd2ay1gA881=!R34bonKh+0OK;{<$Q=1%kMAV&+Fa4zV`bU~F
zT
1FjmCNt
z1BAZaMq;nZF*qROJUO*gM+6s2yV|FSjR5`;9z!V_D*=%`FQ;wmJB@I~WpbNcrXb?8
z3XT$