From e304a741ee95e26a41ae963f9a695b2123e478d6 Mon Sep 17 00:00:00 2001 From: Daniel Wolf Date: Thu, 11 Aug 2016 15:54:00 +0200 Subject: [PATCH] Updated README.adoc --- README.adoc | 105 ++++++++++++++++++++++++++++++++------------------ img/ken-A.png | Bin 1023 -> 984 bytes img/ken-B.png | Bin 1029 -> 1078 bytes img/ken-C.png | Bin 1127 -> 1155 bytes img/ken-D.png | Bin 1105 -> 1142 bytes img/ken-E.png | Bin 1058 -> 1074 bytes img/ken-F.png | Bin 1024 -> 1026 bytes img/ken-G.png | Bin 981 -> 1003 bytes img/ken-H.png | Bin 1158 -> 1185 bytes img/ken-X.png | Bin 0 -> 1066 bytes 10 files changed, 67 insertions(+), 38 deletions(-) create mode 100644 img/ken-X.png diff --git a/README.adoc b/README.adoc index 27d9f36..3fba9d6 100644 --- a/README.adoc +++ b/README.adoc @@ -9,41 +9,55 @@ :H: Ⓗ :X: Ⓧ -https://github.com/DanielSWolf/rhubarb-lip-sync[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. +https://github.com/DanielSWolf/rhubarb-lip-sync[Rhubarb Lip-Sync] is a command-line tool that automatically creates 2D mouth animation from voice recordings. You can use it for animating speech in computer games, animated cartoons, or any similar project. 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 https://github.com/DanielSWolf/rhubarb-lip-sync/issues[create an issue] telling me what tool you're using. I might add support for a few popular animation tools in the future. == Mouth shapes -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. +Rhubarb Lip-Sync uses a set of nine mouth positions. To get good results, you must draw at least the first six mouth shapes ({A}-{F}) for your character. These six mouth shapes were invented at the Hanna-Barbera studios for shows such as Scooby-Doo and The Flintstones. Since then, they have evolved into a _de-facto_ standard for 2D animation, and have been widely used by studios like Disney and Warner Bros. -[cols="1,2,6"] +The additional three mouth shapes ({G}, {H}, and {X}) are optional. You may choose to draw all three of them, pick just one or two, or leave them out entirely. + +[cols="1h,2,6"] |=== -| Name | Image | Description | {A} | image:img/ken-A.png[] -| Closed mouth for rest position and the "`P`", "`B`", and "`M`" sounds. +| Closed mouth for the "`P`", "`B`", and "`M`" sounds. This is almost identical to the {X} shape, but there is slight pressure between the lips. | {B} | image: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**. +| Slightly open mouth with clenched teeth. This mouth shape is used for most consonants ("`K`", "`S`", "`T`", etc.). It's also used for some vowels such as the "`EE`" sound in b**ee**. | {C} | image: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. +| Open mouth. This mouth shape is used for vowels like "`EH`" as in m**e**n, "`AH`" as in s**u**n, and "`EY`" as in s**a**y. It's also used for some consonants, depending on context. + +This shape is also used as an in-between when animating from {A} or {B} to {D}. So make sure the animations {A}{C}{D} and {B}{C}{D} look smooth! | {D} | image: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. +| Wide open mouth. This mouth shapes is used for vowels like "`AA`" as in f**a**ther, "`AE`" as in b**a**t, and "`AY`" as in wh**y**. | {E} | image: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. +| Slightly rounded mouth. This mouth shape is used for vowels like "`AO`" as in **o**ff, "`UH`" as in sh**ou**ld, and "`OW`" as in sh**o**w. + +This shape is also used as an in-between when animating from {C} or {D} to {F}. Make sure the mouth isn't wider open than for {C}. Both {C}{E}{F} and {D}{E}{F} should result in smooth animation. | {F} | image: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. +| Puckered lips. This mouth shape is used for "`UW`" as in y**ou**, "`OY`" as in b**o**y, and "`W`" as in **w**ay. | {G} | image:img/ken-G.png[] | Biting the lower lip for the "`F`" and "`V`" sounds. +This mouth shape is *optional*. If your art style is detailed enough, it greatly improves the overall look of the animation. If you decide not to use it, you can show the {B} shape instead. + | {H} | image:img/ken-H.png[] -| The "`L`" sound with the tongue slightly visible. +| This shape should identical to {C}, except for the tongue showing. It is used for the "`L`" sound, so the tongue should touch behind the upper teeth. + +This mouth shape is *optional*. Depending on your art style and the angle of the head, the tongue may not be visible at all. In this case, there is no point in drawing this extra shape. If you decide not to use it, you can show the {C} shape instead. + +| {X} | image:img/ken-X.png[] +| Idle position. This mouth shape is used for pauses in speech. It is almost identical to {A}, but without the pressure between the lips: For {X}, the lips should be relaxed but closed. + +This mouth shape is *optional*. Whether there should be any visible difference between the rest position {X} and the closed talking mouth {A} depends on your art style and personal taste. If you decide not to use this shape, you can safely show the {A} shape instead. |=== == How to run Rhubarb Lip-Sync @@ -56,15 +70,20 @@ Rhubarb Lip-Sync is a command-line tool that is currently available for Windows The following is a complete list of available command-line options. -[cols="1,2"] +[cols="2,5"] |=== | Option | Description -| `-f` __,`--exportFormat` __ -| The export format. Options: `tsv` (tab-separated values), `xml`, `json`. Default value: `tsv` +| `-f` __, `--exportFormat` __ +| The export format. Options: `tsv` (tab-separated values, see <>), `xml` (see <>), `json` (see <>). Default value: `tsv` -| `-d` __, `--dialog` __ -| 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. +| `-d` __, `--dialogFile` __ +| Allows you to explicitly provide the spoken text rather than relying on Rhubarb Lip-Sync's automatic recognition. Specifying the dialog text often results in more accurate lip-sync. The dialog text must be stored in a plain-text file in ASCII or UTF-8 format. + +| `--threads` __ +| Rhubarb Lip-Sync uses multithreading to speed up processing. By default, it creates as many worker threads as there are cores on your CPU, which results in optimal processing speed. You may choose to specify a lower number if you feel that Rhubarb Lip-Sync is slowing down other applications. Specifying a higher number is not recommended, as it won't result in any additional speed-up. + +Note that for short audio files, Rhubarb Lip-Sync may choose to use fewer threads than specified. | `--logFile` __ | Creates a log file with diagnostic information at the specified path. @@ -86,23 +105,30 @@ The following is a complete list of available command-line options. 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. +[[tsv]] === 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.' [source] ---- -0.00 A -0.09 C -0.17 D -0.38 A -0.47 A +0.00 X +0.05 D +0.27 C +0.31 B +0.43 X +0.47 X ---- -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}). +Here's how to read it: -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}). +* At the beginning of the recording (0.00s), the mouth is closed (shape {X}). The very first output will always have the timestamp 0.00s. +* 0.05s into the recording, the mouth opens wide (shape {D}) for the "`HH`" sound, anticipating the "`AY`" sound that will follow. +* The second half of the "`AY`" diphtong (0.31s into the recording) requires clenched teeth (shape {B}). Before that, shape {C} is inserted as an in-between at 0.27s. This allows for a smoother animation from {D} to {B}. +* 0.43s into the recording, the dialog is finished and the mouth closes again (shape {X}). +* 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 {X}). +[[xml]] === XML format (`xml`) XML format is rather verbose. The following is the output for a person saying 'Hi,' the same recording as above. @@ -112,36 +138,39 @@ XML format is rather verbose. The following is the output for a person saying 'H - C:\Users\Daniel\Desktop\audio-test\hi.wav + C:\Users\Daniel\Desktop\av\hi\hi.wav 0.47 - A - C - D - A + X + D + C + B + X ---- -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. +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 <>. 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]] === 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 format is very similar to <>. The choice mainly depends on the programming language you use, which may have built-in support for one format but not the other. The following is the output for a person saying 'Hi,' the same recording as above. [source,json] ---- { "metadata": { - "soundFile": "C:\\Users\\Daniel\\Desktop\\audio-test\\hi.wav", + "soundFile": "C:\\Users\\Daniel\\Desktop\\av\\hi\\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" } + { "start": 0.00, "end": 0.05, "value": "X" }, + { "start": 0.05, "end": 0.27, "value": "D" }, + { "start": 0.27, "end": 0.31, "value": "C" }, + { "start": 0.31, "end": 0.43, "value": "B" }, + { "start": 0.43, "end": 0.47, "value": "X" } ] } ---- @@ -156,10 +185,10 @@ Rhubarb Lip-Sync has some limitations you should be aware of. 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 +=== 2D animation only -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. +Rhubarb Lip-Sync tries to imitate the animation style used in classic 2D animated cartoons. The results look stylized, and that's intentional. If you're working on a realistic 3D game or movie, Rhubarb Lip-Sync may not be the best choice. == Tell me what you think! -Right now, Rhubarb Lip-Sync is very much work in progress. If you need help or have any suggestions, feel free to https://github.com/DanielSWolf/rhubarb-lip-sync/issues[create an issue]. +I'd love to hear from you! If you need help or have any suggestions, feel free to https://github.com/DanielSWolf/rhubarb-lip-sync/issues[create an issue]. diff --git a/img/ken-A.png b/img/ken-A.png index 15bcfbe31614753d4f3301610e5eeb2004d8958b..33c71f2ac6cfde3a23603dbfa4392904202035da 100644 GIT binary patch literal 984 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`19Oz8i(^Q| zoVRn&W{Eh8xLI4dxt>{}5*RqCVMYV@_Q+2Egs@*uc1_mzodgAAIGPqbxYpZYFW5Yz z<;4$Y6UUP1zl!F;!M2x+AC;F)pZ9Xzyu+z_+gI;WE6cmTN{H|5+3^2{yWfZ3mUA*= zza`h8d6es8grc1Gk>u8jH3I#jk2X5lgmo;x{Egw?+3Sn97G&*SS}0H;1`$5a^|8m> z^7D(Mvmd;ey0STQ$KH@?CAFh{HU?4lG1gYUvln~}1p;e%J2v)wZh@8(H;Ta~!+>z7KYeQV{XCZ153p1+2tCN>@JsPip8 ztYU6v#uaaa*Dn23^!WRMD)Ro~^7FAR}13|i=OejbnAo}K?J zd3Rr5x9nl(^{xBPKlvH8Sp8UJ2hj0gk8XCiROVT~D>HkO&$S@6${Syjir^Ti(JYhlPymGdKP>=KiRVJO>f1)jq6xEAv_=ZY_G^WTdsT^+(^LlLoy)|Id9Y z@k9!yCu?&~t;%CL(!5GSQ#<9~yAKnVdpB){M@@RnJ?rL#l&{`*`UH^-cYW&Pxw)-l zkA}a7X4#YF-M0;q^ejL5?o5T=q^u8Tp1)eCqqm;xl;qss*3&;C1+u?-Tto1tJryyl zX3vZg{Z#y^T1qZb`j6?sT|1o)zFH!LWRZ7*&;dlm0H}4d7=C7MDDcwV1Q&!^_jVy+|$^q%_Di%mj`cp?%4Au zEK>hPcOfFRJ$ZX`%GE-NxYElHgjP+=ZB#g7t;A9I9w|1BKR!Qr*CcO)t>Aa%NA?9u yg@;|gy^7nj7p|RSsL}(>l?ZpxMb literal 1023 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 diff --git a/img/ken-C.png b/img/ken-C.png index a973e5924adb9eef29f88e4ea180df13b50de69e..09697dee4b8d805fa11e86de14150d67d0134afc 100644 GIT binary patch literal 1155 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}HFCi(^Q| zoVRoRJwgH{j?R@(ckbl*FT$tgp~s@E=%X6-+9~{9G{@UJS5~Jrc0Wa7Adrd(Qnct>3?_c=D%A{`=kU@2cDT%XfU={a%%; zeEBM`WxKYn{n9LX^XHtkUj(`~S6$)m56O^FGE-5soistt)1zNyiM!AxWzLrqTfTTW zRZW^IcVOP+o#pp=rDwgmyCE~>25;go&R@3<%zS-*uI}FTygtVnPB~S%BSBI|8x4(&$7n}sR$3YUpn{Y`}f@suddZK zpR;DQ@vn2|&%Zx8<6rWNQ%^7Pv;Ai}v#hN*3`v9fnR5s1o_W2!&G!G(qV3nSzlK*f zc;4r_`Hrn7I6Qp1befUm;`hgXyPET?n!9m%G6S;KjirxwNiV;&{Ip&8(mQ8gcUtGo zke1f|9TMQhyw&(-&NYsO5o}%)vZbZG<=JjXo;@d11Pe_5TapSV?uMK?=aBm0+pnmX zwaqbZW}9=i9CCZBalO{SAa4s3lK=fD9#vcMa>HHUrPCH=vH!Yb@RXlftoDJkv01{D zoWo4f2b%BrUU((6KnD@OZxS^Nmfqow$@uxONBoy|u;Hc3Wp^`LZ%OX{X3l}^hco9` ze6Ps}=*4{&%lj0c{98Nt>+YkE*#9b@x~D3Qtnktso})n`7cR-%F5ND@=XU!n+1*xZ zr%-J@vh&7~7kLdEcFyK|&$imxYr^e)KkW4~cz5U^yG`Y7t%IX~tM5@>(jC#Q`Nihj<}$uX7d^6gVzk@pO^7Ts`N!u! z8>Nr`IM%nxD0Oqb^pV9ivT9xRjAeQi_t#Y3dgJ>P+1d4s?cI`J-kENl3oJkwJYD@< J);T3K0RYz16kz}W 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+ diff --git a/img/ken-D.png b/img/ken-D.png index 434d21195600921d35bd9dce1a0b53d1e49a103e..13bc9b98771105d88679a811762341bc9ce99bb7 100644 GIT binary patch literal 1142 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 V<#^mnm=DbF44$rjF6*2UngGg6^7#M& literal 1058 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 diff --git a/img/ken-G.png b/img/ken-G.png index c2cc88050c73adcbe107ccb999ca1d46f5dd2dff..09f247fc10f628ed563fd6b53f233f05600cfc10 100644 GIT binary patch literal 1003 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`19PsYi(^Q| zoVRoLX9p*WvBK)S7grH1+y0i|5y0v|01lQXlpZ{7T3B*8hm`A zin^Rm(NfA{rW;>W?GvwlGyT2V&itDBZwn^hx&6D~#p&{Q{YmNBn+vRx!^P&TUF=?- zUw)%q;Ox#s`34VHu9p*?s+LTU(_G??U@kX#!~DZKUZ3UZ(f51*U-`|>pBuUE%#BY4 z`>+1?-+iDjZQc4WneML;8c$}<={%)>eEt0!pRR76zAa{V;AYh);vBNp@~;G~%Ph0D z=k8o(q3q`jwPN0!W0LX_1wSL!-`*4%z5VIlL;BJ8Zr#|Bx;3h_>`I2ooVD7wZ*Ob) zQ*?!^DEReT>*zyCzRN$}ym_(W>!!`2u^#;*my}z-cqrOVDNK8KYm@HucXzfuJ$ZIT z>4eD(D!v?=wzbK-LgMM+=7P_QbQ3}~B80u1Q8g9Sp1o;xEyp^#cGo*A53b2iBctEV z=ilac{EtXYIFi!;9mWNZi~hg6eeT1pc&=sktd~_K)PHVPcR*58xZ3!yx4H8C_!@=% zKg3Vl%;nbmA1DrWV33Eu<|}#42lgfJ>Z@7qZwNq0@UJ_!+UW&v-VHG%f)(#1R`VhRsZgTts9tkullhdb9HA& zzS_g}`wz^lsrg=a-Z}{3MgNoXO*}bo)w=$zz3Z}egNyAOzH^~%`Jcj&l-yZ*Kyuma z6*>$KEZ#FeEs2;%TbVFk6T%LA2fry%E)5XsJd-yKvLtnw(Cka<3K-27V{<$`6#Ro;U R_5w31gQu&X%Q~loCIBzo$E*MV 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 diff --git a/img/ken-H.png b/img/ken-H.png index e2c4bff425af931f4a9e1effbfd0d600ef9d855b..127253c34b7c00c7e24b95559bceb0e3b3050b0b 100644 GIT binary patch literal 1185 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`1BP}XI=3_(v_ zme#ft1){n!8Qi^wCzl)y*|O4g_M-28h3WTd(&tzf*zG?3`=1oQIRE#1?|)x=s(w7# zb@GcBI{y;f>S|(Eep41n`@29~ZpEeKj!lZ3FDJHq@o=hAQM8>jLC({oUuB8A&?VvZ z-s9y*8#dp2_DdbTyQS{?p{bAO?F|&Wqztn^ z>&m$s4i}#s{<Z~= zv$oB$+wTNKLR}0r=-~$AZS{=5iss)bIPsqGsF87A$&Q^zdCSfA?NAJf@Uz=gHPbiU5Y%X zZ6ZI_9O-x&zu*G1=rn}|H@EC~a@Rb==*Bxe##4yM@RwO;_G+?v&*H@CJ8N%;^1tKO z*FKu`uR0*}yk^hOcgNUtJSXhlIo(5~euJ%!aLXn{1U6rtsZhQ-zajrqdiBP&##27r zIU5juYll$}lk(oUyXmQk7p-nA-+Ws8#DNJLd+)|FO=*QEf_Y45)o$ONvN1waA9cvW{Dez*cy62F}%<-ZT~TS!8@S^I-tY?iNh(yWyk(Kn3!9(=*@5L z@V4U>e-jpc@oq0rn`;!77~ytS?V~t6b)}_eZ5CyHGw-;&V;7UX&Qfhy+EtuhQ;_SH^?~bXR(tcp-G@+hx nU47lFHvLU_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 diff --git a/img/ken-X.png b/img/ken-X.png new file mode 100644 index 0000000000000000000000000000000000000000..bfde113b910875d5845b02c2c1aad48c94aae466 GIT binary patch literal 1066 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?bB7srr_ zIdA9sXA1|49PK@JLuuQxC;hG)TNAj0SR75b9Sa^_n)=}TN97%#qcxP)v5MC6DE_M+Do$CBUo0`s3e^Gz#y@TY9LPg>lwf|C#LS?6mV_m`W0;>^p_+Bf;rQobZE zf1}!y{@zDqo=&EulDUea?W75Eo*w-wOWcJnDRaJ@*z(20scKcK{)789bNdgqCVIY} z!Mi|)S%VuY1=L}jmHuq|qGjhb{*~;I`?}}A8;8RjdmLUrf3n)@-;V5>UrRU7x!#)7 z_VtCjCXz1E>u-1_Jl61izd1Q0b@hL39{oL)vTf|mjuLvhddqZltP5fprd`aqdiX=m z;>;TH9-%)qsR-9C=Mrtdwe;zK*(j9{{kfl4R$KF2pS}FhhdWtMcJABTUvv4v&(#K7 zbU7LLQs16hRrulGy+nz=yx4BLd)r>w9oXI5p148>;l+f_C!gjmSUWjr4ddm)?Y19h z{!_|x)!nj~d+WQqC+pO9Sl<8s``Ez;@f&0|=iW`0lYwa~sPhH^u%au$*$J!8Bj4w5NG$D=3U1K|g=4 zr{osRGj|Wnd^`7J&f!T$UXzVvA3H@NV#IURxiilsHuCChN(@V1kl4bfYM&7L&CR%B z6C&a!r*B@l#xP0x_nEaVuWwcVeaO*YsWoTrON*X`NUDOjw!6P!44WNUXnwXk@ylW{ z-b?4c%Dh!MV7f1-{{w^mE&fgOBav*D44%uldGe#YnBAYxosihrJ>`1%t!07mY<;8k&oBQLcj_-e4*Alwr>~+U4((s} zS0=#g?Xja@vdq_Ub!WRvU!PmD5J_Rk+nIc~7cSW`d&=Fn31>B9=N&S;Ia}@&EZl%e z_Wen<@V~6T!Wgz}jG2-ulM@qttYweG><9>Xo&AmaU{CR0%!HW&X-leBgZZ3ayZ_m8HP7FEs+4~E%ky3I! ZgUcqnZJfSsw}JVb!PC{xWt~$(69B#=@}vL& literal 0 HcmV?d00001