***** Wesnoth 1.12.6 で シナリオ開始時の文字列と シナリオ中の会話の文字列を取りだす方法調査 第1回目報告文書 ***
2016/5/30
// この文書のライセンスはWesnothやWesnoth本家配布のゲームWesnothのソースや文書と同じライセンスとします
// ライセンスが複数ある場合より自由度の高いものに従うものとします
// この文書による被害には一切責任を持ちません、この情報をもとにやるなら自己責任でお願いします。
// それほど危険な情報じゃないけど自己防衛の為に書いとます
**** 調べた環境
Wesnoth のバージョンは 1.12.6
Debian Linux Sid amd64 環境で以下の調査と検証を行ないました
(この環境でのDebianでもwesnothパッケージのバージョンは 1:1.12.6-1 )
**** 使ったツール
GNU Global(ソースを調べるのに)
GNU GDB (デバッガ)これが主役
Nemiver (これもデバッガ 最初これ使ってたけど途中からGDBにした)
*** 調査の目的
シナリオ開始時の英文と、シナリオプレイ中の台詞をテキストデータとして取りだす
それをChronium
*** 調査の経緯
これは省略
ソースを真面目に読まずに適当にやったためまわりみちしました
なので省略
*** 上手くいった調査方法
まず wesnothのデバッグ情報を含んだパッケージ wesnoth-1.12-dbg を 以下のコマンドでインストール
sudo aptitude install wesnoth-1.12-dbg
ソースも必要みたいだったので
/build/wesnoth-1.12-65cmTO
を作成して(このディレクトリはデバッガがソースないって文句いってきたディレクトリ)
そこで
apt-get source wesnoth
としてソースをダウンロード
*** 最初はGNU Golobalでソース調べてたので
cd wesnoth-1.12-1.12.6/src/
htags -gansx
としてソースを調べやすくするHTMLファイルも生成した
*** 上手くいった調査方法
まずWesnothを立ちあげてから
調べたいメッセージ表示中に
gdb等のデバッガでattachして
btをかけたりソースを調べて
それらしい文字列が含まれてそうな変数やクラスを
表示して見つけて
ブレイクポイントとして適切そうなものを調べた
*** wesnoth を起動して gdbを起動した後に入れたコマンド
実際はもっと色々試行錯誤したけど
それ書いても面白くもなんともないので
最終上手くいったものは
shell ps x | grep wesnoth
でattach すべき 実行してるwesnoth の pid を調べます
attach 調べたpid番号(22909みたいな数字)
その後
b storyscreen::part_ui::part_ui
b gui2::show_wml_message
でブレイクポイントを指定しておきます
あとはそれぞれのブレイクポイントで停止してから
command 1
p p->text_
c
end
を入力して
c
そして2番目のブレイクポイントで止まったら
command 2
p message
c
end
を入力して
c
これで後は画面がいっぱいになったときに
エンターを押すだけでgdbのターミナルにwesnothのシナリオ開始時のテキスト文と
シナリオ中の会話文がテキストとして表示されます
*** 今後
入れるタイミングとかあるし
gdbを起動した時にwesnothが起動してないなら
起動してpid調べるとかして
調べたpidでattachするとか面倒くさい作業が必要だったので
これを自動化するには
元のソースを改造して出力するようにするか
あるいは gdbの操作自体を expect のような自動化ツールを使ってやれば可能となりました
パッチあてるにしても必要な箇所が上で調べれたので
やるかやらんかわかりません
文字列の取りだしには成功したっぽいので
それが出来たらその文字列を自動翻訳にかけるなり
マウスでかざしたら楽に辞書ひける環境で使えるようにするなり
好きにできるので
また時間があったらやるかもしれません
ここまでで結構楽しかったし
当初の目的は達成されたので比較的満足してしまってる今日この頃
*** パッチを作てくれる人向けの場所説明
gdb で info b
として表示すると以下になってます
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000dd0e90 in storyscreen::part_ui::part_ui(storyscreen::part&, display&, gui::button&, gui::button&, gui::button&) at /build/wesnoth-1.12-65cmTO/wesnoth-1.12-1.12.6/src/storyscreen/render.cpp:80
2 breakpoint keep y 0x0000000000c22220 in gui2::show_wml_message(bool, CVideo&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, unsigned int, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, int*) at /build/wesnoth-1.12-65cmTO/wesnoth-1.12-1.12.6/src/gui/dialogs/wml_message.cpp:175
なので
storyscreen::part_ui::part_ui(storyscreen::part&, display&, gui::button&, gui::button&, gui::button&) at /build/wesnoth-1.12-65cmTO/wesnoth-1.12-1.12.6/src/storyscreen/render.cpp:80
と
gui2::show_wml_message(bool, CVideo&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, unsigned int, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, int*) at /build/wesnoth-1.12-65cmTO/wesnoth-1.12-1.12.6/src/gui/dialogs/wml_message.cpp:175
でなんとかすれば文字列をコピペする形で外に取りだすことは簡単だと思います
パッケージを改造するとバージョン上げるごとに
パッチをあてるのが面倒なので
私はもうちょっとgdbと他のツールでなんとかする方向で頑張るかもしれません
***その他の改造について
上の方法で調べれば、勝利条件とかポップアップダイアログの
職種や人種のマニュアルの文字も取りだして自動飜訳するために
ソースの何処をいじれば良いのか調べれると思います
今回GDBをメインで調べてみた感じだと
チートコード的なことをGDBで出来そう
ソースを調べるにはGNU GLOBAL使って
ヒットポイントが減って自分側なら
自動で増やすとか非確定簡単にできそう
ソース公開されてる分
クローズドソースのものよりずっとやりやすいし
誰かやってくれる人がいることを期待しつつ
この調査報告書を終ります
しばらくして誰もやってくれなくて
私がやる気になったら私がやるかも
得にGDBを利用した方はそれほど手間かけずに出来そうだし
つまり他の誰かがやってくれることを
非常に期待してます
buynnnmmm1
KioqKiogV2Vzbm90aCAxLjEyLjYg44GnIOOCt+ODiuODquOCqumWi+Wni+aZguOBruaWh+Wtl+WIl+OBqCDjgrfjg4rjg6rjgqrkuK3jga7kvJroqbHjga7mloflrZfliJfjgpLlj5bjgorjgaDjgZnmlrnms5Xoqr/mn7sg56ysMeWbnuebruWgseWRiuaWh+abuCAqKioKCjIwMTYvNS8zMAoKCi8vIOOBk+OBruaWh+abuOOBruODqeOCpOOCu+ODs+OCueOBr1dlc25vdGjjgoRXZXNub3Ro5pys5a626YWN5biD44Gu44Ky44O844OgV2Vzbm90aOOBruOCveODvOOCueOChOaWh+abuOOBqOWQjOOBmOODqeOCpOOCu+ODs+OCueOBqOOBl+OBvuOBmQovLyDjg6njgqTjgrvjg7PjgrnjgYzopIfmlbDjgYLjgovloLTlkIjjgojjgoroh6rnlLHluqbjga7pq5jjgYTjgoLjga7jgavlvpPjgYbjgoLjga7jgajjgZfjgb7jgZkKLy8g44GT44Gu5paH5pu444Gr44KI44KL6KKr5a6z44Gr44Gv5LiA5YiH6LKs5Lu744KS5oyB44Gh44G+44Gb44KT44CB44GT44Gu5oOF5aCx44KS44KC44Go44Gr44KE44KL44Gq44KJ6Ieq5bex6LKs5Lu744Gn44GK6aGY44GE44GX44G+44GZ44CCCi8vIOOBneOCjOOBu+OBqeWNsemZuuOBquaDheWgseOBmOOCg+OBquOBhOOBkeOBqeiHquW3semYsuihm+OBrueCuuOBq+abuOOBhOOBqOOBvuOBmQoKCioqKiog6Kq/44G544Gf55Kw5aKDCldlc25vdGgg44Gu44OQ44O844K444On44Oz44GvIDEuMTIuNiAKRGViaWFuIExpbnV4IFNpZCBhbWQ2NCDnkrDlooPjgafku6XkuIvjga7oqr/mn7vjgajmpJzoqLzjgpLooYzjgarjgYTjgb7jgZfjgZ8KKOOBk+OBrueSsOWig+OBp+OBrkRlYmlhbuOBp+OCgndlc25vdGjjg5Hjg4PjgrHjg7zjgrjjga7jg5Djg7zjgrjjg6fjg7Pjga8gMToxLjEyLjYtMSApCgoKKioqKiDkvb/jgaPjgZ/jg4Tjg7zjg6sKR05VIEdsb2JhbCjjgr3jg7zjgrnjgpLoqr/jgbnjgovjga7jgaspCkdOVSBHREIgKOODh+ODkOODg+OCrCnjgZPjgozjgYzkuLvlvbkKTmVtaXZlciAo44GT44KM44KC44OH44OQ44OD44KsIOacgOWIneOBk+OCjOS9v+OBo+OBpuOBn+OBkeOBqemAlOS4reOBi+OCiUdEQuOBq+OBl+OBnykKCgoqKiog6Kq/5p+744Gu55uu55qECuOCt+ODiuODquOCqumWi+Wni+aZguOBruiLseaWh+OBqOOAgeOCt+ODiuODquOCquODl+ODrOOCpOS4reOBruWPsOipnuOCkuODhuOCreOCueODiOODh+ODvOOCv+OBqOOBl+OBpuWPluOCiuOBoOOBmQrjgZ3jgozjgpJDaHJvbml1bQoKCioqKiDoqr/mn7vjga7ntYznt68K44GT44KM44Gv55yB55WlCuOCveODvOOCueOCkuecn+mdouebruOBq+iqreOBvuOBmuOBq+mBqeW9k+OBq+OChOOBo+OBn+OBn+OCgeOBvuOCj+OCiuOBv+OBoeOBl+OBvuOBl+OBnwrjgarjga7jgafnnIHnlaUKCgoqKiog5LiK5omL44GP44GE44Gj44Gf6Kq/5p+75pa55rOVCuOBvuOBmiB3ZXNub3Ro44Gu44OH44OQ44OD44Kw5oOF5aCx44KS5ZCr44KT44Gg44OR44OD44Kx44O844K4IHdlc25vdGgtMS4xMi1kYmcg44KSIOS7peS4i+OBruOCs+ODnuODs+ODieOBp+OCpOODs+OCueODiOODvOODqwoKc3VkbyBhcHRpdHVkZSBpbnN0YWxsIHdlc25vdGgtMS4xMi1kYmcKCuOCveODvOOCueOCguW/heimgeOBv+OBn+OBhOOBoOOBo+OBn+OBruOBpwoKL2J1aWxkL3dlc25vdGgtMS4xMi02NWNtVE8KCuOCkuS9nOaIkOOBl+OBpijjgZPjga7jg4fjgqPjg6zjgq/jg4jjg6rjga/jg4fjg5Djg4PjgqzjgYzjgr3jg7zjgrnjgarjgYTjgaPjgabmloflj6XjgYTjgaPjgabjgY3jgZ/jg4fjgqPjg6zjgq/jg4jjg6opCgrjgZ3jgZPjgacKCmFwdC1nZXQgc291cmNlIHdlc25vdGgKCuOBqOOBl+OBpuOCveODvOOCueOCkuODgOOCpuODs+ODreODvOODiQoKCioqKiDmnIDliJ3jga9HTlUgR29sb2JhbOOBp+OCveODvOOCueiqv+OBueOBpuOBn+OBruOBpwoKY2Qgd2Vzbm90aC0xLjEyLTEuMTIuNi9zcmMvCmh0YWdzIC1nYW5zeAoK44Go44GX44Gm44K944O844K544KS6Kq/44G544KE44GZ44GP44GZ44KLSFRNTOODleOCoeOCpOODq+OCgueUn+aIkOOBl+OBnwoKCioqKiDkuIrmiYvjgY/jgYTjgaPjgZ/oqr/mn7vmlrnms5UKCuOBvuOBmldlc25vdGjjgpLnq4vjgaHjgYLjgZLjgabjgYvjgokK6Kq/44G544Gf44GE44Oh44OD44K744O844K46KGo56S65Lit44GrCmdkYuetieOBruODh+ODkOODg+OCrOOBp2F0dGFjaOOBl+OBpgpidOOCkuOBi+OBkeOBn+OCiuOCveODvOOCueOCkuiqv+OBueOBpgrjgZ3jgozjgonjgZfjgYTmloflrZfliJfjgYzlkKvjgb7jgozjgabjgZ3jgYbjgarlpInmlbDjgoTjgq/jg6njgrnjgpIK6KGo56S644GX44Gm6KaL44Gk44GR44GmCuODluODrOOCpOOCr+ODneOCpOODs+ODiOOBqOOBl+OBpumBqeWIh+OBneOBhuOBquOCguOBruOCkuiqv+OBueOBnwoKCioqKiB3ZXNub3RoIOOCkui1t+WLleOBl+OBpiBnZGLjgpLotbfli5XjgZfjgZ/lvozjgavlhaXjgozjgZ/jgrPjg57jg7Pjg4kK5a6f6Zqb44Gv44KC44Gj44Go6Imy44CF6Kmm6KGM6Yyv6Kqk44GX44Gf44GR44GpCuOBneOCjOabuOOBhOOBpuOCgumdoueZveOBj+OCguOBquOCk+OBqOOCguOBquOBhOOBruOBpwrmnIDntYLkuIrmiYvjgY/jgYTjgaPjgZ/jgoLjga7jga8KCnNoZWxsIHBzIHggfCBncmVwIHdlc25vdGgKCuOBp2F0dGFjaCDjgZnjgbnjgY0g5a6f6KGM44GX44Gm44KLd2Vzbm90aCDjga4gcGlkIOOCkuiqv+OBueOBvuOBmQoKYXR0YWNoIOiqv+OBueOBn3BpZOeVquWPtygyMjkwOeOBv+OBn+OBhOOBquaVsOWtlykKCuOBneOBruW+jAoKYiBzdG9yeXNjcmVlbjo6cGFydF91aTo6cGFydF91aQpiIGd1aTI6OnNob3dfd21sX21lc3NhZ2UKCuOBp+ODluODrOOCpOOCr+ODneOCpOODs+ODiOOCkuaMh+WumuOBl+OBpuOBiuOBjeOBvuOBmQoK44GC44Go44Gv44Gd44KM44Ge44KM44Gu44OW44Os44Kk44Kv44Od44Kk44Oz44OI44Gn5YGc5q2i44GX44Gm44GL44KJCgpjb21tYW5kIDEKcCBwLT50ZXh0XwpjCmVuZAoK44KS5YWl5Yqb44GX44GmCgpjCgrjgZ3jgZfjgaYy55Wq55uu44Gu44OW44Os44Kk44Kv44Od44Kk44Oz44OI44Gn5q2i44G+44Gj44Gf44KJCgpjb21tYW5kIDIKcCBtZXNzYWdlCmMKZW5kCgrjgpLlhaXlipvjgZfjgaYKCmMKCuOBk+OCjOOBp+W+jOOBr+eUu+mdouOBjOOBhOOBo+OBseOBhOOBq+OBquOBo+OBn+OBqOOBjeOBqwrjgqjjg7Pjgr/jg7zjgpLmirzjgZnjgaDjgZHjgadnZGLjga7jgr/jg7zjg5/jg4rjg6vjgat3ZXNub3Ro44Gu44K344OK44Oq44Kq6ZaL5aeL5pmC44Gu44OG44Kt44K544OI5paH44GoCuOCt+ODiuODquOCquS4reOBruS8muipseaWh+OBjOODhuOCreOCueODiOOBqOOBl+OBpuihqOekuuOBleOCjOOBvuOBmQoKCgoqKiog5LuK5b6MCuWFpeOCjOOCi+OCv+OCpOODn+ODs+OCsOOBqOOBi+OBguOCi+OBlwpnZGLjgpLotbfli5XjgZfjgZ/mmYLjgat3ZXNub3Ro44GM6LW35YuV44GX44Gm44Gq44GE44Gq44KJCui1t+WLleOBl+OBpnBpZOiqv+OBueOCi+OBqOOBi+OBl+OBpgroqr/jgbnjgZ9waWTjgadhdHRhY2jjgZnjgovjgajjgYvpnaLlgJLjgY/jgZXjgYTkvZzmpa3jgYzlv4XopoHjgaDjgaPjgZ/jga7jgacKCuOBk+OCjOOCkuiHquWLleWMluOBmeOCi+OBq+OBrwrlhYPjga7jgr3jg7zjgrnjgpLmlLnpgKDjgZfjgablh7rlipvjgZnjgovjgojjgYbjgavjgZnjgovjgYsK44GC44KL44GE44GvIGdkYuOBruaTjeS9nOiHquS9k+OCkiBleHBlY3Qg44Gu44KI44GG44Gq6Ieq5YuV5YyW44OE44O844Or44KS5L2/44Gj44Gm44KE44KM44Gw5Y+v6IO944Go44Gq44KK44G+44GX44GfCgrjg5Hjg4Pjg4HjgYLjgabjgovjgavjgZfjgabjgoLlv4XopoHjgarnrofmiYDjgYzkuIrjgafoqr/jgbnjgozjgZ/jga7jgacK44KE44KL44GL44KE44KJ44KT44GL44KP44GL44KK44G+44Gb44KTCgrmloflrZfliJfjga7lj5bjgorjgaDjgZfjgavjga/miJDlip/jgZfjgZ/jgaPjgb3jgYTjga7jgacK44Gd44KM44GM5Ye65p2l44Gf44KJ44Gd44Gu5paH5a2X5YiX44KS6Ieq5YuV57+76Kiz44Gr44GL44GR44KL44Gq44KKCuODnuOCpuOCueOBp+OBi+OBluOBl+OBn+OCiealveOBq+i+nuabuOOBsuOBkeOCi+eSsOWig+OBp+S9v+OBiOOCi+OCiOOBhuOBq+OBmeOCi+OBquOCigrlpb3jgY3jgavjgafjgY3jgovjga7jgacK44G+44Gf5pmC6ZaT44GM44GC44Gj44Gf44KJ44KE44KL44GL44KC44GX44KM44G+44Gb44KTCgrjgZPjgZPjgb7jgafjgafntZDmp4vmpb3jgZfjgYvjgaPjgZ/jgZcK5b2T5Yid44Gu55uu55qE44Gv6YGU5oiQ44GV44KM44Gf44Gu44Gn5q+U6LyD55qE5rqA6Laz44GX44Gm44GX44G+44Gj44Gm44KL5LuK5pel44GT44Gu6aCDCgoKKioqIOODkeODg+ODgeOCkuS9nOOBpuOBj+OCjOOCi+S6uuWQkeOBkeOBruWgtOaJgOiqrOaYjgoKZ2RiIOOBpyBpbmZvIGIK44Go44GX44Gm6KGo56S644GZ44KL44Go5Lul5LiL44Gr44Gq44Gj44Gm44G+44GZCgpOdW0gICAgIFR5cGUgICAgICAgICAgIERpc3AgRW5iIEFkZHJlc3MgICAgICAgICAgICBXaGF0CjEgICAgICAgYnJlYWtwb2ludCAgICAga2VlcCB5ICAgMHgwMDAwMDAwMDAwZGQwZTkwIGluIHN0b3J5c2NyZWVuOjpwYXJ0X3VpOjpwYXJ0X3VpKHN0b3J5c2NyZWVuOjpwYXJ0JiwgZGlzcGxheSYsIGd1aTo6YnV0dG9uJiwgZ3VpOjpidXR0b24mLCBndWk6OmJ1dHRvbiYpIGF0IC9idWlsZC93ZXNub3RoLTEuMTItNjVjbVRPL3dlc25vdGgtMS4xMi0xLjEyLjYvc3JjL3N0b3J5c2NyZWVuL3JlbmRlci5jcHA6ODAKMiAgICAgICBicmVha3BvaW50ICAgICBrZWVwIHkgICAweDAwMDAwMDAwMDBjMjIyMjAgaW4gZ3VpMjo6c2hvd193bWxfbWVzc2FnZShib29sLCBDVmlkZW8mLCBzdGQ6Ol9fY3h4MTE6OmJhc2ljX3N0cmluZzxjaGFyLCBzdGQ6OmNoYXJfdHJhaXRzPGNoYXI+LCBzdGQ6OmFsbG9jYXRvcjxjaGFyPiA+IGNvbnN0Jiwgc3RkOjpfX2N4eDExOjpiYXNpY19zdHJpbmc8Y2hhciwgc3RkOjpjaGFyX3RyYWl0czxjaGFyPiwgc3RkOjphbGxvY2F0b3I8Y2hhcj4gPiBjb25zdCYsIHN0ZDo6X19jeHgxMTo6YmFzaWNfc3RyaW5nPGNoYXIsIHN0ZDo6Y2hhcl90cmFpdHM8Y2hhcj4sIHN0ZDo6YWxsb2NhdG9yPGNoYXI+ID4gY29uc3QmLCBib29sLCBib29sLCBzdGQ6Ol9fY3h4MTE6OmJhc2ljX3N0cmluZzxjaGFyLCBzdGQ6OmNoYXJfdHJhaXRzPGNoYXI+LCBzdGQ6OmFsbG9jYXRvcjxjaGFyPiA+IGNvbnN0Jiwgc3RkOjpfX2N4eDExOjpiYXNpY19zdHJpbmc8Y2hhciwgc3RkOjpjaGFyX3RyYWl0czxjaGFyPiwgc3RkOjphbGxvY2F0b3I8Y2hhcj4gPiosIHVuc2lnbmVkIGludCwgc3RkOjp2ZWN0b3I8c3RkOjpfX2N4eDExOjpiYXNpY19zdHJpbmc8Y2hhciwgc3RkOjpjaGFyX3RyYWl0czxjaGFyPiwgc3RkOjphbGxvY2F0b3I8Y2hhcj4gPiwgc3RkOjphbGxvY2F0b3I8c3RkOjpfX2N4eDExOjpiYXNpY19zdHJpbmc8Y2hhciwgc3RkOjpjaGFyX3RyYWl0czxjaGFyPiwgc3RkOjphbGxvY2F0b3I8Y2hhcj4gPiA+ID4gY29uc3QmLCBpbnQqKSBhdCAvYnVpbGQvd2Vzbm90aC0xLjEyLTY1Y21UTy93ZXNub3RoLTEuMTItMS4xMi42L3NyYy9ndWkvZGlhbG9ncy93bWxfbWVzc2FnZS5jcHA6MTc1CgoK44Gq44Gu44GnCgpzdG9yeXNjcmVlbjo6cGFydF91aTo6cGFydF91aShzdG9yeXNjcmVlbjo6cGFydCYsIGRpc3BsYXkmLCBndWk6OmJ1dHRvbiYsIGd1aTo6YnV0dG9uJiwgZ3VpOjpidXR0b24mKSBhdCAvYnVpbGQvd2Vzbm90aC0xLjEyLTY1Y21UTy93ZXNub3RoLTEuMTItMS4xMi42L3NyYy9zdG9yeXNjcmVlbi9yZW5kZXIuY3BwOjgwCgoK44GoCgpndWkyOjpzaG93X3dtbF9tZXNzYWdlKGJvb2wsIENWaWRlbyYsIHN0ZDo6X19jeHgxMTo6YmFzaWNfc3RyaW5nPGNoYXIsIHN0ZDo6Y2hhcl90cmFpdHM8Y2hhcj4sIHN0ZDo6YWxsb2NhdG9yPGNoYXI+ID4gY29uc3QmLCBzdGQ6Ol9fY3h4MTE6OmJhc2ljX3N0cmluZzxjaGFyLCBzdGQ6OmNoYXJfdHJhaXRzPGNoYXI+LCBzdGQ6OmFsbG9jYXRvcjxjaGFyPiA+IGNvbnN0Jiwgc3RkOjpfX2N4eDExOjpiYXNpY19zdHJpbmc8Y2hhciwgc3RkOjpjaGFyX3RyYWl0czxjaGFyPiwgc3RkOjphbGxvY2F0b3I8Y2hhcj4gPiBjb25zdCYsIGJvb2wsIGJvb2wsIHN0ZDo6X19jeHgxMTo6YmFzaWNfc3RyaW5nPGNoYXIsIHN0ZDo6Y2hhcl90cmFpdHM8Y2hhcj4sIHN0ZDo6YWxsb2NhdG9yPGNoYXI+ID4gY29uc3QmLCBzdGQ6Ol9fY3h4MTE6OmJhc2ljX3N0cmluZzxjaGFyLCBzdGQ6OmNoYXJfdHJhaXRzPGNoYXI+LCBzdGQ6OmFsbG9jYXRvcjxjaGFyPiA+KiwgdW5zaWduZWQgaW50LCBzdGQ6OnZlY3RvcjxzdGQ6Ol9fY3h4MTE6OmJhc2ljX3N0cmluZzxjaGFyLCBzdGQ6OmNoYXJfdHJhaXRzPGNoYXI+LCBzdGQ6OmFsbG9jYXRvcjxjaGFyPiA+LCBzdGQ6OmFsbG9jYXRvcjxzdGQ6Ol9fY3h4MTE6OmJhc2ljX3N0cmluZzxjaGFyLCBzdGQ6OmNoYXJfdHJhaXRzPGNoYXI+LCBzdGQ6OmFsbG9jYXRvcjxjaGFyPiA+ID4gPiBjb25zdCYsIGludCopIGF0IC9idWlsZC93ZXNub3RoLTEuMTItNjVjbVRPL3dlc25vdGgtMS4xMi0xLjEyLjYvc3JjL2d1aS9kaWFsb2dzL3dtbF9tZXNzYWdlLmNwcDoxNzUKCuOBp+OBquOCk+OBqOOBi+OBmeOCjOOBsOaWh+Wtl+WIl+OCkuOCs+ODlOODmuOBmeOCi+W9ouOBp+WkluOBq+WPluOCiuOBoOOBmeOBk+OBqOOBr+ewoeWNmOOBoOOBqOaAneOBhOOBvuOBmQoK44OR44OD44Kx44O844K444KS5pS56YCg44GZ44KL44Go44OQ44O844K444On44Oz5LiK44GS44KL44GU44Go44GrCuODkeODg+ODgeOCkuOBguOBpuOCi+OBruOBjOmdouWAkuOBquOBruOBpwrnp4Hjga/jgoLjgYbjgaHjgofjgaPjgahnZGLjgajku5bjga7jg4Tjg7zjg6vjgafjgarjgpPjgajjgYvjgZnjgovmlrnlkJHjgafpoJHlvLXjgovjgYvjgoLjgZfjgozjgb7jgZvjgpMKCgoqKirjgZ3jga7ku5bjga7mlLnpgKDjgavjgaTjgYTjgaYK5LiK44Gu5pa55rOV44Gn6Kq/44G544KM44Gw44CB5Yud5Yip5p2h5Lu244Go44GL44Od44OD44OX44Ki44OD44OX44OA44Kk44Ki44Ot44Kw44GuCuiBt+eoruOChOS6uueoruOBruODnuODi+ODpeOCouODq+OBruaWh+Wtl+OCguWPluOCiuOBoOOBl+OBpuiHquWLlemjnOios+OBmeOCi+OBn+OCgeOBqwrjgr3jg7zjgrnjga7kvZXlh6bjgpLjgYTjgZjjgozjgbDoia/jgYTjga7jgYvoqr/jgbnjgozjgovjgajmgJ3jgYTjgb7jgZkKCuS7iuWbnkdEQuOCkuODoeOCpOODs+OBp+iqv+OBueOBpuOBv+OBn+aEn+OBmOOBoOOBqArjg4Hjg7zjg4jjgrPjg7zjg4nnmoTjgarjgZPjgajjgpJHRELjgaflh7rmnaXjgZ3jgYYK44K944O844K544KS6Kq/44G544KL44Gr44GvR05VIEdMT0JBTOS9v+OBo+OBpgrjg5Ljg4Pjg4jjg53jgqTjg7Pjg4jjgYzmuJvjgaPjgaboh6rliIblgbTjgarjgokK6Ieq5YuV44Gn5aKX44KE44GZ44Go44GL6Z2e56K65a6a57Ch5Y2Y44Gr44Gn44GN44Gd44GGCuOCveODvOOCueWFrOmWi+OBleOCjOOBpuOCi+WIhgrjgq/jg63jg7zjgrrjg4njgr3jg7zjgrnjga7jgoLjga7jgojjgorjgZrjgaPjgajjgoTjgorjgoTjgZnjgYTjgZcKCuiqsOOBi+OChOOBo+OBpuOBj+OCjOOCi+S6uuOBjOOBhOOCi+OBk+OBqOOCkuacn+W+heOBl+OBpOOBpArjgZPjga7oqr/mn7vloLHlkYrmm7jjgpLntYLjgorjgb7jgZkKCuOBl+OBsOOCieOBj+OBl+OBpuiqsOOCguOChOOBo+OBpuOBj+OCjOOBquOBj+OBpgrnp4HjgYzjgoTjgovmsJfjgavjgarjgaPjgZ/jgonnp4HjgYzjgoTjgovjgYvjgoIK5b6X44GrR0RC44KS5Yip55So44GX44Gf5pa544Gv44Gd44KM44G744Gp5omL6ZaT44GL44GR44Ga44Gr5Ye65p2l44Gd44GG44Gg44GXCgrjgaTjgb7jgorku5bjga7oqrDjgYvjgYzjgoTjgaPjgabjgY/jgozjgovjgZPjgajjgpIK6Z2e5bi444Gr5pyf5b6F44GX44Gm44G+44GZCgoKYnV5bm5ubW1tMQ==