From da06576edc2f92b31f9413c7505daf9afd0c533c Mon Sep 17 00:00:00 2001 From: Daniel Wolf Date: Tue, 12 Apr 2016 22:22:20 +0200 Subject: [PATCH] Updated README.md --- README.md | 111 ++++++++++++++++++++++++++++++++++---------------- img/ken-A.png | Bin 0 -> 1023 bytes img/ken-B.png | Bin 0 -> 1029 bytes img/ken-C.png | Bin 0 -> 1127 bytes img/ken-D.png | Bin 0 -> 1105 bytes img/ken-E.png | Bin 0 -> 1058 bytes img/ken-F.png | Bin 0 -> 1024 bytes img/ken-G.png | Bin 0 -> 981 bytes img/ken-H.png | Bin 0 -> 1158 bytes 9 files changed, 76 insertions(+), 35 deletions(-) create mode 100644 img/ken-A.png create mode 100644 img/ken-B.png create mode 100644 img/ken-C.png create mode 100644 img/ken-D.png create mode 100644 img/ken-E.png create mode 100644 img/ken-F.png create mode 100644 img/ken-G.png create mode 100644 img/ken-H.png diff --git a/README.md b/README.md index 91d84b5..9e84e4b 100644 --- a/README.md +++ b/README.md @@ -2,76 +2,117 @@ [Rhubarb Lip-Sync](https://github.com/DanielSWolf/rhubarb-lip-sync) is a command-line tool that automatically creates mouth animation from voice recordings. You can use it for characters in computer games, in animated cartoons, or in any other project that requires animating mouths based on existing recordings. -Right now, Rhubarb Lip-Sync produces files in XML format (a special text format). If you're a programmer, this makes it easy for you to use the output in whatever way you like. If you're not a programmer, however, there is currently no direct way to import the result into your favorite animation tool. If this is what you need, feel free to [create an issue](https://github.com/DanielSWolf/rhubarb-lip-sync/issues) telling me what tool you're using. I might add support for a few popular animation tools in the future. +Rhubarb Lip-Sync produces output files in various text formats (TSV/XML/JSON). If you're a programmer, this makes it easy for you to use the output in whatever way you like. If you're not a programmer, there is currently no direct way to import the result into your favorite animation tool. If this is what you need, feel free to [create an issue](https://github.com/DanielSWolf/rhubarb-lip-sync/issues) telling me what tool you're using. I might add support for a few popular animation tools in the future. ## Mouth shapes -At the moment, Rhubarb Lip-Sync uses a fixed set of eight mouth shapes, named from A-H. These mouth shapes are based on the six mouth shapes (A-F) originally developed at the Hanna-Barbera studios for classic shows such as Scooby-Doo and The Flintstones. +Rhubarb Lip-Sync uses a fixed set of eight mouth shapes, named from A-H. These mouth shapes are based on the six mouth shapes (A-F) originally developed at the Hanna-Barbera animation studios for classic shows such as Scooby-Doo and The Flintstones. | Name | Image | Description | | ---- | ----- | ----------- | -| A | ![](http://sunewatts.dk/lipsync/lipsync/img/adam/A.png) | Closed mouth for rest position and the *P*, *B*, and *M* sounds. | -| B | ![](http://sunewatts.dk/lipsync/lipsync/img/adam/B.png) | Slightly open mouth with clenched teeth. Used for most consonants as well as the *EE* sound in b**ee** or sh**e**. | -| C | ![](http://sunewatts.dk/lipsync/lipsync/img/adam/C.png) | Open mouth for the vowels *EH* as in r**e**d, m**e**n; *IH* as in b**i**g, w**i**n; *AH* as in b**u**t, s**u**n, **a**lone; and *EY* as in s**a**y, **e**ight. | -| D | ![](http://sunewatts.dk/lipsync/lipsync/img/adam/D.png) | Wide open mouth for the vowels *AA* as in f**a**ther; *AE* as in **a**t, b**a**t; *AY* as in m**y**, wh**y**, r**i**de; and *AW* as in h**o**w, n**o**w. | -| E | ![](http://sunewatts.dk/lipsync/lipsync/img/adam/E.png) | Slightly rounded mouth for the vowels *AO* as in **o**ff, f**a**ll; *UH* as in sh**ou**ld, c**ou**ld; *OW* as in sh**o**w, c**o**at; and *ER* as in h**er**, b**ir**d. | -| F | ![](http://sunewatts.dk/lipsync/lipsync/img/adam/F.png) | Small rounded mouth for *UW* as in y**ou**, n**ew**; *OY* as in b**o**y, t**o**y; and *W* as in **w**ay. | -| G | ![](http://sunewatts.dk/lipsync/lipsync/img/adam/G.png) | Biting the lower lip for the *F* and *V* sounds. | -| H | ![](http://sunewatts.dk/lipsync/lipsync/img/adam/H.png) | The *L* sound with the tongue slightly visible. | +| A | ![](img/ken-A.png) | Closed mouth for rest position and the *P*, *B*, and *M* sounds. | +| B | ![](img/ken-B.png) | Slightly open mouth with clenched teeth. Used for most consonants as well as the *EE* sound in b**ee** or sh**e**. | +| C | ![](img/ken-C.png) | Open mouth for the vowels *EH* as in r**e**d, m**e**n; *IH* as in b**i**g, w**i**n; *AH* as in b**u**t, s**u**n, **a**lone; and *EY* as in s**a**y, **e**ight. | +| D | ![](img/ken-D.png) | Wide open mouth for the vowels *AA* as in f**a**ther; *AE* as in **a**t, b**a**t; *AY* as in m**y**, wh**y**, r**i**de; and *AW* as in h**o**w, n**o**w. | +| E | ![](img/ken-E.png) | Slightly rounded mouth for the vowels *AO* as in **o**ff, f**a**ll; *UH* as in sh**ou**ld, c**ou**ld; *OW* as in sh**o**w, c**o**at; and *ER* as in h**er**, b**ir**d. | +| F | ![](img/ken-F.png) | Small rounded mouth for *UW* as in y**ou**, n**ew**; *OY* as in b**o**y, t**o**y; and *W* as in **w**ay. | +| G | ![](img/ken-G.png) | Biting the lower lip for the *F* and *V* sounds. | +| H | ![](img/ken-H.png) | The *L* sound with the tongue slightly visible. | ## How to run Rhubarb Lip-Sync Rhubarb Lip-Sync is a command-line tool that is currently available for Windows and OS X. * Download the [latest release](https://github.com/DanielSWolf/rhubarb-lip-sync/releases) and unzip the file anywhere on your computer. -* Call `rhubarb`, passing it a WAVE file as argument, and redirecting the output to a file. This might look like this: `rhubarb my-recording.wav > output.xml`. +* Call `rhubarb`, passing it a WAVE file as argument, and redirecting the output to a file. This might look like this: `rhubarb my-recording.wav > output.txt`. * Rhubarb Lip-Sync will analyze the sound file and print the result to `stdout`. If you've redirected `stdout` to a file like above, you will now have an XML file containing the lip-sync data. +The following is a complete list of available command-line options. + +| Option | Description | +| ------ | ----------- | +| `-f` *format*,
`--exportFormat` *format* | The export format. Options: `tsv` (tab-separated values), `xml`, `json`. Default value: `tsv` | +| `-d` *text*,
`--dialog` *text* | Allows you to explicitly specify the text of the dialog rather than relying on Rhubarb Lip-Sync's automatic recognition. This is an experimental feature. Currently, the main limitation is that each word must be contained in Rhubarb Lip-Sync's internal dictionary, or the program will fail. | +| `--logFile` *path* | Creates a log file with diagnostic information at the specified path. | +| `--logLevel` *level* | Sets the log level for the log file. Options: `trace`, `debug`, `info`, `warning`, `error`, `fatal`. Default value: `debug` | +| `--version` | Displays version information and exits. | +| `-h`,
`--help` | Displays usage information and exits. | +| *input file* | The input file to be analyzed. Must be an sound file in WAVE format. || + ## How to use the output -The output of Rhubarb Lip-Sync is an XML file containing information about the sounds in the recording and -- more importantly -- the resulting mouth shapes. A (shortened) sample output looks like this: +The output of Rhubarb Lip-Sync is a file that tells you which mouth shape to display at what time within the recording. You can choose between three file formats -- TSV, XML, and JSON. The following paragraphs show you what each of these formats looks like. + +### Tab-separated values (`tsv`) + +TSV is the simplest and most compact export format supported by Rhubarb Lip-Sync. Each line starts with a timestamp (in seconds), followed by a tab, followed by the name of the mouth shape. The following is the output for a recording of a person saying 'Hi.' + +``` +0.00 A +0.09 C +0.17 D +0.38 A +0.47 A +``` + +You see that at the beginning of the recording, the mouth is closed (shape A). 0.09s into the recording, the mouth opens (shape C); a little later, it opens even wider (shape D). 0.38s into the recording, it closes again (shape A). + +The last output line in TSV format is special: Its timestamp is always the very end of the recording (truncated to a multiple of 0.01s) and its value is always a closed mouth (shape A). + +### XML format (`xml`) + +XML format is rather verbose. The following is the output for a person saying 'Hi,' the same recording as above. ```xml - - C:\...\my-recording.wav - - - None - M - AA - R - ... - + + C:\Users\Daniel\Desktop\audio-test\hi.wav + 0.47 + - A - F - B - H - C - ... + A + C + D + A ``` -* The `info` element tells you the name of the original sound file. -* The `phones` element contains the individual sounds found in the recording. You won't usually need them. -* The `mouthCues` element tells you which mouth shape needs to be displayed at what time interval. The `start` and `duration` values are in seconds. There are no gaps between mouth cues, so `entry.start` + `entry.duration` = `nextEntry.start`. +The file starts with a `metadata` block containing the full path of the original recording and its duration (truncated to a multiple of 0.01s). After that, each `mouthCue` element indicates the start and end of a certain mouth shape, as explained for TSV format. Note that the end of each mouth cue is identical with the start of the following one. This is a bit redundant, but it means that we don't need a special final element like in TSV format. + +### JSON format (`json`) + +JSON format is very similar to XML format -- the choice mainly depends on which is better supported by your programming language. The following is the output for a person saying 'Hi,' the same recording as above. + +```json +{ + "metadata": { + "soundFile": "C:\\Users\\Daniel\\Desktop\\audio-test\\hi.wav", + "duration": 0.47 + }, + "mouthCues": [ + { "start": 0.00, "end": 0.09, "value": "A" }, + { "start": 0.09, "end": 0.17, "value": "C" }, + { "start": 0.17, "end": 0.38, "value": "D" }, + { "start": 0.38, "end": 0.47, "value": "A" } + ] +} +``` + +There is nothing surprising here; everything said about XML format applies to JSON, too. ## Limitations Rhubarb Lip-Sync has some limitations you should be aware of. -### Only English dialog +### English only Rhubarb Lip-Sync only produces good results when you give it recordings in English. You'll get best results with American English. ### Fixed set of mouth shapes -Right now, Rhubarb Lip-Sync uses a fixed set of eight mouth shapes, as shown above. If you want to use fewer shapes, you can apply a custom mapping in your own code. - -I'm planning to make the mouth animation logic more flexible (and even better-looking) in future releases. +Rhubarb Lip-Sync uses a fixed set of eight mouth shapes, as shown above. If you want to use fewer shapes, you can apply a custom mapping in your own code. ## Tell me what you think! diff --git a/img/ken-A.png b/img/ken-A.png new file mode 100644 index 0000000000000000000000000000000000000000..15bcfbe31614753d4f3301610e5eeb2004d8958b GIT binary patch literal 1023 zcmeAS@N?(olHy`uVBq!ia0vp^(||aIg9%8!wv1a2q&N#aB8!1EBM38ED1C7NGE}NU zB1)W#QWHz^ix?Ox<`ny!^!Exa@X_|v4Jz>U_V(4&WMgowVmtTzY;hU`19PLNi(^Q| zoVRoJ`-L4Pj;&vkdWR69n!y|zYiXI0(IvS`b{NUiQJHW~Eh~<%s zD-ax23(0X}<-9Rd{m$)uXWqAl*}v!I|SO{DM<%;^ov|lZvEn+Xp6*ryiff@{wq%to!RrA8S*4pvIU636`gl@ zeCCP!mY2mn@wwA3&J%Buyyx#OyV8I2JbR z>$!_tinjlk<$HdAf9v5|;iI!}s>Hp_f2Y&7B=^E7Eix^ zZ5MyR{wis{P=wcvfBpQ_`f-!?-6cBLzFgILTs4Jr(fx(%dd;2dHcn4|P~9e7JNMk7 zg^$i8J9E99=v1|2!aU)<#_P69cd)H1nQXZKfXSOSadFAd+zI}hD!!S_b2kY>xYECS z?E%e~YRcaZwQDadVLS8l-G-VMbH!I3a&Lfz?>>vkmohF#?rPM&ecQ7v!83EI=gYpr zg<4D8Vb(3VIx}&b;Ozq{+Qp@8W<3TApD?GT%9}8+fGUvFT%!IwEjYc`Oz(~M`RMHU zV`6fjgKk)FE?{v+4(+$k1a~)HP1AU}tV{2z$i;V;Qj%+Hq{Dx2x_gMZW?kI;`cx#< zb0X$8ZkRkNFJ}2?z9qdkTuds~^aNC>B~1ef4k+3WZ^#b*)gy6H{`S4xE-PXLet{Lj=l{ie;l8&3KS{8KmZ2V$G?lq zj=dHA{oGdbO~r{FFCSYKpZ~Yt>%hA;frv;s|Kj}d?+U_V(4&WMgowVmtTzY;hU`19Q8li(^Q| zoVRlq=G_huX`6iVfP%t-1qTisP*|`)VZ(w0`5QcMEA#kh>AYm_=?{73a8NEGf#1MF zAiyFaAwVD@lXaq$LFVG`GP%nw_nL3~|Kk6RiOIij?eF{adQSEF<^JK*C;y*(eQV*D zA2+tWz2IE%IqL=Ega{2qn<)ZvUL5{rUl{)R+6yOcl+2LfFyMZ;u;oL5Qw303d8@JE zzoVgvk?Y?b{;;sV=4Y?!a_+zzr&b$Xoho_;tORVrdE+v-$mWGr{#g>Ins;pAJzX_< z4c`*BO6B*zb1P@Pazj??vD&yR_q#xwcy9WiAHG{T4*z~rF0pU_KEA`NRvkGxcSljS zSk;w_=WM=v-)~=7wP?mI-pwFK@~gJA3ms}sOn-LPRbthxGdKIET4??CzHE}XBBo9D z){TElr%hc`q~!KhrwGh@9%jb- zBrhqzeAD$@^_Uk|bj}|!@R5G%G&NZS$?E=mtq+1bq($eQ&a_azDSG2;(o7^XR!sHn zcy~;$ty@n#aqHH;c{8R5t@oRoeOLz+PR^X5NL&)LVs3%{)Mmlt#ax!PmeYGzdY$z! z(_b2QH}-Sk_eA8Fo@py?mR9*OVp_xWM?te=e5TFZdhPM;9n199=Xfnn5Q7>BOch3{ z5mR|7Dr4P}h_ne+L vz7*yv?kRbDu~_e$^fU9>eY~*L^;ul)qZ3nf{+12EEX?5P>gTe~DWM4fp^42{ literal 0 HcmV?d00001 diff --git a/img/ken-C.png b/img/ken-C.png new file mode 100644 index 0000000000000000000000000000000000000000..a973e5924adb9eef29f88e4ea180df13b50de69e GIT binary patch literal 1127 zcmeAS@N?(olHy`uVBq!ia0vp^(||aIg9%8!wv1a2q&N#aB8!1EBM38ED1C7NGE}NU zB1)W#QWHz^ix?Ox<`ny!^!Exa@X_|v4Jz>U_V(4&WMgowVmtTzY;hU`1M^Ey7srr_ zIdA7GW=JPWw9OVQT(qbsK+9=mM@Pqu6>Da!n4^)i;Y4Rwr;|3D>11I+(Pm$sFhfH_ zHwocjmDSuk6;jW|#S?dAxp(iFJ@rb<;$<7nPeHAb^Yq|fI``w> z)0wv=+RyHcPuy|uZCm2$SYDH|>6duenA1y=O^hyUB%}vrZ~C=1PC|$gAbzG9O6O(=im z$(uKCu08Wo-)w&AX8v7DrL$xHrd*Z`6+?uFO)6wO1b*AYD3wwBljkw8v1ErhAX4`BPW z>pSDO5U>1X5_UHx3vIVCg!03NX&n*aa+ literal 0 HcmV?d00001 diff --git a/img/ken-D.png b/img/ken-D.png new file mode 100644 index 0000000000000000000000000000000000000000..434d21195600921d35bd9dce1a0b53d1e49a103e GIT binary patch literal 1105 zcmeAS@N?(olHy`uVBq!ia0vp^(||aIg9%8!wv1a2q&N#aB8!1EBM38ED1C7NGE}NU zB1)W#QWHz^ix?Ox<`ny!^!Exa@X_|v4Jz>U_V(4&WMgowVmtTzY;hU`1M_817srr_ zIdA7G=0qimwBBZIT%o|tlx4TyT7~<&D{G1$w$^N(WxA0sa_*_EQ`R7y$L}`B@aNN~)7Rg-``vy{_ue@D zUeUGbL0X=bLZ5D0Eb%;oyB>5h5Y}x#-*&26Ww4K&k?N-FE z#;AGtOWrj0S6OjqPqn1V3%~m_J%#-sQXHq`@Vh=2|NSqscYYpMvaPO=QRHUjz0#B8 zdDIph1^O&K{gU)UO`b#al-z=Z4(tOBzljzr!^nJYYv$vlMMfPR# zq^AG&Wq-d;oT7I3N1@u$#V4&NU_V(4&WMgowVmtTzY;hU`1M?D37srr_ zIdA7G=1V&YwCZ1NWM*RvD><-fjn;t!3J($*9333$92^}T6R%G2_$lld2xJ1e3672- zuAvDI4h@ZtDY6Cz1{to;j-X|}Pen0oG$*0Tb&fPnA`KIS4vzzzs z{c4t6sWv&+{!o^jv3||wrN;%NorNwbbH1F|^2NicN=4Cj(gZnAkA9UU>UX~}?=kCs zEp5JM-|q6mi|(7+MV}MTvxwHa`(eY4^22B5XmLdJF-~cP>znuNw&Vx>`}uiyKU7#4 z*vKW9@;J`Ds3{Q6(c@;&-3K11@>j%GO{wp2v8E^n+(ztD8{c^*sM+rKXk@QVLS zV6ZuH_=c5}1lw(6<}y^*gx!!lc2sId{=4|SpU?O0oPRd1M)}5XYneTNezS#6XFxJn zz2H61{@t2=dsesFS3E0sy~!flv*3j2W@8Ct-!1C$?THQCw))lY@P{t@6c+4C$rt8Z zg&IIz|98#4y@=~d%0{)0Zx2uG$eJztdwS1G6h-{&&K=nyeJm)1XLI9s*3HrD15*E& z9KMu2X;;^eZ%BdTpJo04sIY>+WdE<@J5)TC?)qMr-g9P8+skVz3zl-s_?@5l%4N?{ zhBI^jPI{w&oS3fUWp6tlwDB(Q9(F6vn~}kjw@TmM-{83VOg!`Ve|%=!&U+vwjhmHL z){*rlC6TwuO! z?#+bkBHuf`yfT}_KXbM4KNUCM^QNxI87Xj|OA77$s{8DiLnttRGkCiCxvXU_V(4&WMgowVmtTzY;hU`19Ow7i(^Q| zoVRn==ihb^Ieu63fWiTVRXj{gTwH8iOx!^7m{}$xGczOeRg(?&NeLO!GqyA|G&LM- zY;0^g1Y|WeG%&30+S0_->?yssIx4Pa-{=1PZ+|za&!0Paf7Pk*_w(NK)$Oei%T<^A zGIh1z5qI~6a-p(6i*9}qDcjt&_CuiaWrc$aT0R6gRcI*M%w4AbA>S-k`;D!MNq^ad z_1DrYZ0qye&VVJS2*`PH_iN{vV3Wo+wtT3@BH7RWfx&?-Sm_H^+~&TZc~z#Zq5ALCUnS|^Wnml4-U5^)m!R! z?!3AySu8TGP5x2E?GqYZdXrstYUy|$&{JXD46+nxT)WVr&+<2Bo?Z6ifq8lPQTF{? zobTR!!SP->Z2Gdl+)v|>Y))^VyK?Oj2d~3AAYBl9-qe?>z5IHnVDHXwwt5>I6X)8E zFJtG4&u`0V-*|C$ZRw0wXb4OZnD=+PvDK!;>v_-jt|?Sg`}Jy4LnPD%K(h)r8(&>( z8@m0XPf=Z3Tlebh*PGtPyJ&y-an+-8(~l{h3RPt;6Ezf&Lo9lg@z&fa<&&1BY5eI< zFq$h`|LOAaS*Zn~`W1-%_=y zCVW*rCkK*Qo0B(Y@@JX<+RHp$eSO;fDXV?=Y9oc@@fBRXz{_Nc!TOR(15NZsz sbh{zB{BPc;;MdtYg)B@+sy~ZgJMsGNozDD9VD4q`boFyt=akR{09D++^#A|> literal 0 HcmV?d00001 diff --git a/img/ken-G.png b/img/ken-G.png new file mode 100644 index 0000000000000000000000000000000000000000..c2cc88050c73adcbe107ccb999ca1d46f5dd2dff GIT binary patch literal 981 zcmeAS@N?(olHy`uVBq!ia0vp^(||aIg9%8!wv1a2q&N#aB8!1EBM38ED1C7NGE}NU zB1)W#QWHz^ix?Ox<`ny!^!Exa@X_|v4Jz>U_V(4&WMgowVmtTzY;hU`19P~ii(^Q| zoVRlo^KS=;w9Y=Mut4E}!T}($V1Ysc5HDDelkk(Vc{0~;XS0Bntjx@;zd4y%TUlF~ z85vm_CyEKIWSnUB>)yqp*|*b=+ui(mV`}p8kIR?K?ERfn9=A@9-|Vt1PtV%l$Fqzw ze~H}Lll_auMJvdoU*wW<>lY72TO?-WW%UpF&)NfL>ff(h(Y}6rV&s#(8*1k1->b_I z{;}xahb7DOFKH}s=XyEOscOlDdDD(bhSx>@*~5SO{dfMv%EFj7)hFT{vi+CSkBiSf zGwovjj(|CWvnPPm%4sfHzO?Wdn_A4gw9OmlObaadQL=&W^u-F9Y0Sli7mmbu6<3vu zPn!_Gp{9n*d&Zi`nTD&XLnNY2p>_fFw;P?4nI6a{Id6XJ(_eq~K2Hd|5gGrVu}Yw~Ku(prB-&%GU%f$$lB>YSIo=hmDR)(*R|=1ir)?0I`l&mS(j)w^xiCEhoy z0}-LH{)ps`!kznmZ_|$X?d|wK{7P(7*`&MGOeP2i95=TPj^B0j_n#!@pGV_#KCk^D zGffH+gp+sv^I-hFu=xLNVRa(sy&-eUfrIRzRPo=&Z7AY_64c$x-BnG z?m=>&dh`r`@5bBRv0GH{9??v`**ovQ(EWf=<#pB5-@KGSHq3}aXF}crA5ZfO4wgpC zwI!bC1^o&uTe0OLQska{-!I>D_UqZZJHkXC?_29*ek0cCdHjPzasBz`wVy(f?cF?E z!Fu-Y!od4?db8V(e%)XV)UxknG?MFUyc@NB%-88KB(QkD__SmW+k{I7UXDl#tn|aD z->%EC!K@76ux?drtsi;!$v{`vVc?}+znZZnyPmTBeua!A-H qxl7KYqDp95)yaeV6rmAvK3+YRLFk|G;Syk$WbkzLb6Mw<&;$SmaJ!`d literal 0 HcmV?d00001 diff --git a/img/ken-H.png b/img/ken-H.png new file mode 100644 index 0000000000000000000000000000000000000000..e2c4bff425af931f4a9e1effbfd0d600ef9d855b GIT binary patch literal 1158 zcmeAS@N?(olHy`uVBq!ia0vp^(||aIg9%8!wv1a2q&N#aB8!1EBM38ED1C7NGE}NU zB1)W#QWHz^ix?Ox<`ny!^!Exa@X_|v4Jz>U_V(4&WMgowVmtTzY;hU`0}F?zi(^Q| zoVRlqW=98#9E*25A}lB>D5%&XC>R(hXnD-#sEbQtbEsd)w6aBOgeMCN3JQw?;pCsp zT8A_iZ(1~^qpKr8ONptQ!z3vwE%|#*$?~0*nUneV&9}bu`%~QK!WYLapWl6w$Nzou zOwa7CH_eTW-hQ9{m*cy!hwqOR&wfR*HkBprLYI^|UrucK;^9=KqG&s5f}E#^f89;~ z0`tX9oZXXu+P`}9!h%OyKfXor%4~&}?AlXDw;Je}nx*Z(#(v7MVG~GwKiHVfi^|ka z?eE#WJn_fdFFHK4Uw<{Qu{WGO`AEy*lYfqJuFJh~Rp;F@E7QdFId6JV^&MmHQWHO% zD8cvYn8h2F{f7#QtF3vm-Avn8rA(HmPiRm@} znR0s1zFPN|QT6U*gQ(paZ4WCy(q#|6-Lvsd&#~h5cKi3tdHC{QL2a#UoAvweY5UE%Pa(pEzkRNz=$VWUjn)sD z?ximdDGHPCd-&5;B5mf}mrJbAtwMEGTz!Rjo4dSyt0K?o61MQfiU+^MHNH5ss&ZwR z&At6E@Jh;t`>{+@THzr-&&DTr$<| z^KSj*$bZ3q+GU{*BI2IZ?W=sM^ZQ*|WIIdq?#69?BH2eD{hj^q((Wz``KAobnWB(5--+z;0`CZ&jQf~3(UpD{Uk6$Rzjx^9&oHqGKJ1kXoZZ-~V zHanfPDe;c4ai-Pm%_gfBefZn`|J|g1q@bF-(rWXp|-OrwP55sn8@2OtR|yZLD{ELzs`IC!AY-IKGoDY)RSU*|I-` zm%W?b{ERPV$p3IG5A literal 0 HcmV?d00001