Bootstrap 4って?

Bootstrapはレスポンシブデザインといって、PC・スマホなど閲覧デバイスの違い、ウィンドウサイズの変更に応じて最適なレイアウトを提供できるフレームワークです。 従来rmarkdownパッケージが提供しているBootstrapのバージョンは3で今回は4です。 主な変更点に関しては以下に纏められています。

Migrating to v4
https://getbootstrap.com/docs/4.0/migration/

R Markdownユーザーが主に影響を受けそうなところは後ほど説明します。

基本の使い方

今のところオプション機能なので、使用するには必要なパッケージを入れて、YAMLフロントマターで利用を宣言する必要があります。

2021/1/21現在、Bootstrap 4はGitHub版のrmarkdownパッケージで利用可能です。 また、利用には追加でbslibというパッケージが必要です。 以下のコマンドでインストールしましょう。

remotes::install_github(c("rstudio/rmarkdown", "rstudio/bslib"))

インストールできたら、 Rmdファイルのフロントマターのoutputフィールドにhtml_documentを指定し、 theme引数を適宜指定するだけです1。 最低限必要なものにversion: 4があります2versionを省略するか3にすると従来のBootstrap 3が適用されます。

output:
  html_document:
    theme:
      version: 4

テーマの指定

Bootstrap 3でよければ従来通り、theme引数に"cosmo"などの文字列を指定できます。 Bootstrap 4では更にテーマを指定するには以下のようにbootswatch要素を指定します。

output:
  html_document:
    theme:
      version: 4
      bootswatch: darkly

ちなみにこれが、このページの設定です。 従来のtheme引数に指定していた私がbootswatch要素にそのまま指定できます。 ただし、bslibパッケージの活躍により、利用可能なテーマは以下の通り増えました。 bootswatch要素を指定すればBootstrap 3利用時もすべてのテーマを利用できます。

bslib::bootswatch_themes()
##  [1] "cerulean"  "cosmo"     "cyborg"    "darkly"    "flatly"   
##  [6] "journal"   "litera"    "lumen"     "lux"       "materia"  
## [11] "minty"     "pulse"     "sandstone" "simplex"   "sketchy"  
## [16] "slate"     "solar"     "spacelab"  "superhero" "united"   
## [21] "yeti"

何が変わったの?

フォント周りが色々変わった

デフォルトフォントが変わった

適用するテーマによってフォントが変わりますが以下のように、使用候補となるフォントが増えました。 ブラウザはCSSのfont-family3プロパティに指定されたフォントリストから利用するフォントを選択します。 先頭にあるほど優先度が高く、

  • インストールされているか
  • 文字をレンダリング可能か

の2点を基準に1文字ずつ使うフォントを決定します。 沢山指定しておけば、良い感じの表示を実現できる可能性があがりそうですね。

具体的には以下のように変更されています(rmarkdown::html_documentの標準的な出力で比較)。 Robotoのようにモダンなフォント、Noto Sansのように多くの文字をレンダリング可能なフォント、Segoe UI Emojiのように絵文字に特価したフォント、色々とありますね。

  • Bootstrap 3
    • Helvetica Neue
    • Helvetica
    • Arial
    • sans-serif
  • Bootstrap 4
    • -apple-system
    • BlinkMacSystemFont
    • Segoe UI
    • Roboto
    • Helvetica Neue
    • Arial
    • Noto Sans
    • sans-serif
    • Apple Color Emoji
    • Segoe UI Emoji
    • Segoe UI Symbol
    • Noto Color Emoji

フォントサイズが大きくなった

基準となる文字サイズが14pxから16pxになりました。

フォントサイズが調整しやすくなった

また、見出しや段落などの各要素のフォントサイズは基準サイズの16pxからの相対値になりました(rem単位)。 たとえば、2remなら32pxですね。 以下のようにhtml要素に対してフォントサイズを変更してやれば、ページ内の各要素のフォントサイズも相対的に変更されます。

html {font-size: 18px;}

Rmdファイル上ではcssチャンクを使うだけで簡単にフォントサイズを変更できますね。

```{css, echo=FALSE}
html {font-size: 18px;}
``

Bootstrap 3ではフォントサイズがpxという絶対的な単位だったので、こういった変更が困難でした。

テーマが増え、カスタマイズも簡単になった

使えるテーマが増えた点は既に紹介した通りです。 実は、YAMLフロントマターにおてhtml_document関数のtheme引数に名前付きリストを指定すると、 リストは更にbslib::bs_theme関数の引数化します。 そしてこの関数は引数に応じてテーマの調整を可能としています。

output:
  html_document:
    theme:
      version: 4   # 3も可能。
      bootswatch: darkly
      bg: beige # 背景色。fgの指定が必須。
      fg: black # 表面色。文字色のことっぽい。

ちなみにbslib::bs_theme関数の引数は以下の通り。

names(formals(bslib::bs_theme))
##  [1] "version"      "bootswatch"   "..."          "bg"          
##  [5] "fg"           "primary"      "secondary"    "success"     
##  [9] "info"         "warning"      "danger"       "base_font"   
## [13] "code_font"    "heading_font"

可変長引数(...)以降がテーマ調整用の引数ですね。 これらの引数はCSSを動的に生成するためのフレームワークに引数として渡されています。 可変長引数もちゃんと渡されるので、他にも色々な調整が可能です。

利用可能な引数は以下のリンクから確認してください。 なお、html_document関数で指定するには-_に置換してください。

https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/bootstrap/_variables.scss

たとえばfont_size_base要素を指定すれば、基準となるフォントのサイズを変更可能です。 この方法ならBootstrap 3であってもフォントサイズを一元的に変更できます。 ただし、使える単位がBootstrap 4のremに対し、Bootstrap 3の場合はpxです。

感想と展望

従来のrmarkdown::html_document関数でテーマをカスタマイズするには、css引数にCSSファイルを指定する必要がありました。 これが減らせるのはとっても簡便で良いですね。 実はtheme引数には文字列、リストの他にbslib::bs_themeの実行結果を与えることも可能です。

output:
  html_document:
    theme: !expr bslib::bs_theme(version = 4)

!exprはR言語として評価してね、というキーワードです。 これ、言い変えるとbslib::bs_theme関数の返り値に準拠したカスタム関数を利用できます。 パッケージとしてカスタムテーマを提供する時とっても便利そうですよね。 私は前からHonokaという日本語向けのBootstrapテーマを使ってみたいと思っていました。

https://honokak.osaka/

bslibパッケージの挙動を参考に実装したいと思います。 パッケージ化するとしたらhonokadown::honoka_documentとかかなあ?

Enjoy!!


  1. html_documentrmarkdown::html_document関数です。YAMLフロントマターで、html_documentの下の階層に指定した値は、html_document関数の引数扱いになるため、theme引数と呼んでいます。↩︎

  2. YAMLフロントマターにおいて、html_documentの引数の値として、名前: 値のペアを指定すると、名前付きリストになります。このため、theme引数の下にversion: 4とあればリストのversion要素を記述した扱いになります。↩︎

  3. https://developer.mozilla.org/ja/docs/Web/CSS/font-family↩︎

LS0tCnRpdGxlOiAiUiBNYXJrZG93buOBp0Jvb3RzdHJhcCA044KS5L2/44GGIgphdXRob3I6IEF0dXN5CmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZToKICAgICAgdmVyc2lvbjogNAogICAgICBib290c3dhdGNoOiBkYXJrbHkKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCi0tLQoKIyBCb290c3RyYXAgNOOBo+OBpu+8nwoKQm9vdHN0cmFw44Gv44Os44K544Od44Oz44K344OW44OH44K244Kk44Oz44Go44GE44Gj44Gm44CBUEPjg7vjgrnjg57jg5vjgarjganplrLopqfjg4fjg5DjgqTjgrnjga7pgZXjgYTjgIHjgqbjgqPjg7Pjg4njgqbjgrXjgqTjgrrjga7lpInmm7Tjgavlv5zjgZjjgabmnIDpganjgarjg6zjgqTjgqLjgqbjg4jjgpLmj5DkvpvjgafjgY3jgovjg5Xjg6zjg7zjg6Djg6/jg7zjgq/jgafjgZnjgIIK5b6T5p2lcm1hcmtkb3du44OR44OD44Kx44O844K444GM5o+Q5L6b44GX44Gm44GE44KLQm9vdHN0cmFw44Gu44OQ44O844K444On44Oz44GvM+OBp+S7iuWbnuOBrzTjgafjgZnjgIIK5Li744Gq5aSJ5pu054K544Gr6Zai44GX44Gm44Gv5Lul5LiL44Gr57qP44KB44KJ44KM44Gm44GE44G+44GZ44CCCgo+IE1pZ3JhdGluZyB0byB2NCBcCj4gaHR0cHM6Ly9nZXRib290c3RyYXAuY29tL2RvY3MvNC4wL21pZ3JhdGlvbi8KClIgTWFya2Rvd27jg6bjg7zjgrbjg7zjgYzkuLvjgavlvbHpn7/jgpLlj5fjgZHjgZ3jgYbjgarjgajjgZPjgo3jga/lvozjgbvjganoqqzmmI7jgZfjgb7jgZnjgIIKCiMg5Z+65pys44Gu5L2/44GE5pa5Cgrku4rjga7jgajjgZPjgo3jgqrjg5fjgrfjg6fjg7PmqZ/og73jgarjga7jgafjgIHkvb/nlKjjgZnjgovjgavjga/lv4XopoHjgarjg5Hjg4PjgrHjg7zjgrjjgpLlhaXjgozjgabjgIFZQU1M44OV44Ot44Oz44OI44Oe44K/44O844Gn5Yip55So44KS5a6j6KiA44GZ44KL5b+F6KaB44GM44GC44KK44G+44GZ44CCCgoyMDIxLzEvMjHnj77lnKjjgIFCb290c3RyYXAgNOOBr0dpdEh1YueJiOOBrioqcm1hcmtkb3duKirjg5Hjg4PjgrHjg7zjgrjjgafliKnnlKjlj6/og73jgafjgZnjgIIK44G+44Gf44CB5Yip55So44Gr44Gv6L+95Yqg44GnKipic2xpYioq44Go44GE44GG44OR44OD44Kx44O844K444GM5b+F6KaB44Gn44GZ44CCCuS7peS4i+OBruOCs+ODnuODs+ODieOBp+OCpOODs+OCueODiOODvOODq+OBl+OBvuOBl+OCh+OBhuOAggoKYGBge3IsIGV2YWw9RkFMU0V9CnJlbW90ZXM6Omluc3RhbGxfZ2l0aHViKGMoInJzdHVkaW8vcm1hcmtkb3duIiwgInJzdHVkaW8vYnNsaWIiKSkKYGBgCgrjgqTjg7Pjgrnjg4jjg7zjg6vjgafjgY3jgZ/jgonjgIEKUm1k44OV44Kh44Kk44Or44Gu44OV44Ot44Oz44OI44Oe44K/44O844GuYG91dHB1dGDjg5XjgqPjg7zjg6vjg4njgatgaHRtbF9kb2N1bWVudGDjgpLmjIflrprjgZfjgIEKYHRoZW1lYOW8leaVsOOCkumBqeWunOaMh+WumuOBmeOCi+OBoOOBkeOBp+OBmVteYXJnXeOAggrmnIDkvY7pmZDlv4XopoHjgarjgoLjga7jgatgdmVyc2lvbjogNGDjgYzjgYLjgorjgb7jgZlbXmxpc3Rd44CCCmB2ZXJzaW9uYOOCkuecgeeVpeOBmeOCi+OBi2AzYOOBq+OBmeOCi+OBqOW+k+adpeOBrkJvb3RzdHJhcCAz44GM6YGp55So44GV44KM44G+44GZ44CCCgpgYGB5YW1sCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6CiAgICAgIHZlcnNpb246IDQKYGBgCgpbXmFyZ106IGBodG1sX2RvY3VtZW50YOOBr2BybWFya2Rvd246Omh0bWxfZG9jdW1lbnRg6Zai5pWw44Gn44GZ44CCWUFNTOODleODreODs+ODiOODnuOCv+ODvOOBp+OAgWBodG1sX2RvY3VtZW50YOOBruS4i+OBrumajuWxpOOBq+aMh+WumuOBl+OBn+WApOOBr+OAgWBodG1sX2RvY3VtZW50YOmWouaVsOOBruW8leaVsOaJseOBhOOBq+OBquOCi+OBn+OCgeOAgWB0aGVtZWAqKuW8leaVsCoq44Go5ZG844KT44Gn44GE44G+44GZ44CCCgpbXmxpc3RdOiBZQU1M44OV44Ot44Oz44OI44Oe44K/44O844Gr44GK44GE44Gm44CBYGh0bWxfZG9jdW1lbnRg44Gu5byV5pWw44Gu5YCk44Go44GX44Gm44CBYOWQjeWJjTog5YCkYOOBruODmuOCouOCkuaMh+WumuOBmeOCi+OBqOOAgeWQjeWJjeS7mOOBjeODquOCueODiOOBq+OBquOCiuOBvuOBmeOAguOBk+OBruOBn+OCgeOAgWB0aGVtZWDlvJXmlbDjga7kuIvjgatgdmVyc2lvbjogNGDjgajjgYLjgozjgbDjg6rjgrnjg4jjga5gdmVyc2lvbmAqKuimgee0oCoq44KS6KiY6L+w44GX44Gf5omx44GE44Gr44Gq44KK44G+44GZ44CCCgojIyDjg4bjg7zjg57jga7mjIflrpogeyN0aGVtaW5nfQoKQm9vdHN0cmFwIDPjgafjgojjgZHjgozjgbDlvpPmnaXpgJrjgorjgIFgdGhlbWVg5byV5pWw44GrYCJjb3NtbyJg44Gq44Gp44Gu5paH5a2X5YiX44KS5oyH5a6a44Gn44GN44G+44GZ44CCCkJvb3RzdHJhcCA044Gn44Gv5pu044Gr44OG44O844Oe44KS5oyH5a6a44GZ44KL44Gr44Gv5Lul5LiL44Gu44KI44GG44GrYGJvb3Rzd2F0Y2hg6KaB57Sg44KS5oyH5a6a44GX44G+44GZ44CCCgpgYGB5YW1sCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6CiAgICAgIHZlcnNpb246IDQKICAgICAgYm9vdHN3YXRjaDogZGFya2x5CmBgYAoK44Gh44Gq44G/44Gr44GT44KM44GM44CB44GT44Gu44Oa44O844K444Gu6Kit5a6a44Gn44GZ44CCCuW+k+adpeOBrmB0aGVtZWDlvJXmlbDjgavmjIflrprjgZfjgabjgYTjgZ/np4HjgYxgYm9vdHN3YXRjaGDopoHntKDjgavjgZ3jga7jgb7jgb7mjIflrprjgafjgY3jgb7jgZnjgIIK44Gf44Gg44GX44CBKipic2xpYioq44OR44OD44Kx44O844K444Gu5rS76LqN44Gr44KI44KK44CB5Yip55So5Y+v6IO944Gq44OG44O844Oe44Gv5Lul5LiL44Gu6YCa44KK5aKX44GI44G+44GX44Gf44CCCmBib290c3dhdGNoYOimgee0oOOCkuaMh+WumuOBmeOCjOOBsEJvb3RzdHJhcCAz5Yip55So5pmC44KC44GZ44G544Gm44Gu44OG44O844Oe44KS5Yip55So44Gn44GN44G+44GZ44CCCgpgYGB7cn0KYnNsaWI6OmJvb3Rzd2F0Y2hfdGhlbWVzKCkKYGBgCgojIOS9leOBjOWkieOCj+OBo+OBn+OBru+8nwoKIyMg44OV44Kp44Oz44OI5ZGo44KK44GM6Imy44CF5aSJ44KP44Gj44GfCgojIyMg44OH44OV44Kp44Or44OI44OV44Kp44Oz44OI44GM5aSJ44KP44Gj44GfCgrpgannlKjjgZnjgovjg4bjg7zjg57jgavjgojjgaPjgabjg5Xjgqnjg7Pjg4jjgYzlpInjgo/jgorjgb7jgZnjgYzku6XkuIvjga7jgojjgYbjgavjgIHkvb/nlKjlgJnoo5zjgajjgarjgovjg5Xjgqnjg7Pjg4jjgYzlopfjgYjjgb7jgZfjgZ/jgIIK44OW44Op44Km44K244GvQ1NT44GuYGZvbnQtZmFtaWx5YF5baHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvamEvZG9jcy9XZWIvQ1NTL2ZvbnQtZmFtaWx5Cl3jg5fjg63jg5Hjg4bjgqPjgavmjIflrprjgZXjgozjgZ/jg5Xjgqnjg7Pjg4jjg6rjgrnjg4jjgYvjgonliKnnlKjjgZnjgovjg5Xjgqnjg7Pjg4jjgpLpgbjmip7jgZfjgb7jgZnjgIIK5YWI6aCt44Gr44GC44KL44G744Gp5YSq5YWI5bqm44GM6auY44GP44CBCgotIOOCpOODs+OCueODiOODvOODq+OBleOCjOOBpuOBhOOCi+OBiwotIOaWh+Wtl+OCkuODrOODs+ODgOODquODs+OCsOWPr+iDveOBiwoK44GuMueCueOCkuWfuua6luOBqzHmloflrZfjgZrjgaTkvb/jgYbjg5Xjgqnjg7Pjg4jjgpLmsbrlrprjgZfjgb7jgZnjgIIK5rKi5bGx5oyH5a6a44GX44Gm44GK44GR44Gw44CB6Imv44GE5oSf44GY44Gu6KGo56S644KS5a6f54++44Gn44GN44KL5Y+v6IO95oCn44GM44GC44GM44KK44Gd44GG44Gn44GZ44Gt44CCCgrlhbfkvZPnmoTjgavjga/ku6XkuIvjga7jgojjgYbjgavlpInmm7TjgZXjgozjgabjgYTjgb7jgZnvvIhgcm1hcmtkb3duOjpodG1sX2RvY3VtZW50YOOBruaomea6lueahOOBquWHuuWKm+OBp+avlOi8g++8ieOAggpSb2JvdG/jga7jgojjgYbjgavjg6Ljg4Djg7Pjgarjg5Xjgqnjg7Pjg4jjgIFOb3RvIFNhbnPjga7jgojjgYbjgavlpJrjgY/jga7mloflrZfjgpLjg6zjg7Pjg4Djg6rjg7PjgrDlj6/og73jgarjg5Xjgqnjg7Pjg4jjgIFTZWdvZSBVSSBFbW9qaeOBruOCiOOBhuOBq+e1teaWh+Wtl+OBq+eJueS+oeOBl+OBn+ODleOCqeODs+ODiOOAgeiJsuOAheOBqOOBguOCiuOBvuOBmeOBreOAggoKLSBCb290c3RyYXAgMwogICAgLSBIZWx2ZXRpY2EgTmV1ZQogICAgLSBIZWx2ZXRpY2EKICAgIC0gQXJpYWwKICAgIC0gc2Fucy1zZXJpZgotIEJvb3RzdHJhcCA0CiAgICAtIC1hcHBsZS1zeXN0ZW0KICAgIC0gQmxpbmtNYWNTeXN0ZW1Gb250CiAgICAtIFNlZ29lIFVJCiAgICAtIFJvYm90bwogICAgLSBIZWx2ZXRpY2EgTmV1ZQogICAgLSBBcmlhbAogICAgLSBOb3RvIFNhbnMKICAgIC0gc2Fucy1zZXJpZgogICAgLSBBcHBsZSBDb2xvciBFbW9qaQogICAgLSBTZWdvZSBVSSBFbW9qaQogICAgLSBTZWdvZSBVSSBTeW1ib2wKICAgIC0gTm90byBDb2xvciBFbW9qaQoKCiMjIyDjg5Xjgqnjg7Pjg4jjgrXjgqTjgrrjgYzlpKfjgY3jgY/jgarjgaPjgZ8KCuWfuua6luOBqOOBquOCi+aWh+Wtl+OCteOCpOOCuuOBjGAxNHB4YOOBi+OCiWAxNnB4YOOBq+OBquOCiuOBvuOBl+OBn+OAggoKIyMjIOODleOCqeODs+ODiOOCteOCpOOCuuOBjOiqv+aVtOOBl+OChOOBmeOBj+OBquOBo+OBnwoK44G+44Gf44CB6KaL5Ye644GX44KE5q616JC944Gq44Gp44Gu5ZCE6KaB57Sg44Gu44OV44Kp44Oz44OI44K144Kk44K644Gv5Z+65rqW44K144Kk44K644GuMTZweOOBi+OCieOBruebuOWvvuWApOOBq+OBquOCiuOBvuOBl+OBn++8iGByZW1g5Y2Y5L2N77yJ44CCCuOBn+OBqOOBiOOBsOOAgWAycmVtYOOBquOCiWAzMnB4YOOBp+OBmeOBreOAggrku6XkuIvjga7jgojjgYbjgatgaHRtbGDopoHntKDjgavlr77jgZfjgabjg5Xjgqnjg7Pjg4jjgrXjgqTjgrrjgpLlpInmm7TjgZfjgabjgoTjgozjgbDjgIHjg5rjg7zjgrjlhoXjga7lkITopoHntKDjga7jg5Xjgqnjg7Pjg4jjgrXjgqTjgrrjgoLnm7jlr77nmoTjgavlpInmm7TjgZXjgozjgb7jgZnjgIIKCmBgYGNzcwpodG1sIHtmb250LXNpemU6IDE4cHg7fQpgYGAKClJtZOODleOCoeOCpOODq+S4iuOBp+OBr2Nzc+ODgeODo+ODs+OCr+OCkuS9v+OBhuOBoOOBkeOBp+ewoeWNmOOBq+ODleOCqeODs+ODiOOCteOCpOOCuuOCkuWkieabtOOBp+OBjeOBvuOBmeOBreOAggoKYGBgYApgciAnJ2BgYGB7Y3NzLCBlY2hvPUZBTFNFfQpodG1sIHtmb250LXNpemU6IDE4cHg7fQpgciAnJ2BgYApgYGBgCgpCb290c3RyYXAgM+OBp+OBr+ODleOCqeODs+ODiOOCteOCpOOCuuOBjGBweGDjgajjgYTjgYbntbblr77nmoTjgarljZjkvY3jgaDjgaPjgZ/jga7jgafjgIHjgZPjgYbjgYTjgaPjgZ/lpInmm7TjgYzlm7Dpm6PjgafjgZfjgZ/jgIIKCiMjIOODhuODvOODnuOBjOWil+OBiOOAgeOCq+OCueOCv+ODnuOCpOOCuuOCguewoeWNmOOBq+OBquOBo+OBnwoK5L2/44GI44KL44OG44O844Oe44GM5aKX44GI44Gf54K544Gv5pei44GrW+e0ueS7i10oI3RoZW1pbmcp44GX44Gf6YCa44KK44Gn44GZ44CCCuWun+OBr+OAgVlBTUzjg5Xjg63jg7Pjg4jjg57jgr/jg7zjgavjgYrjgaZgaHRtbF9kb2N1bWVudGDplqLmlbDjga5gdGhlbWVg5byV5pWw44Gr5ZCN5YmN5LuY44GN44Oq44K544OI44KS5oyH5a6a44GZ44KL44Go44CBCuODquOCueODiOOBr+abtOOBq2Bic2xpYjo6YnNfdGhlbWVg6Zai5pWw44Gu5byV5pWw5YyW44GX44G+44GZ44CCCuOBneOBl+OBpuOBk+OBrumWouaVsOOBr+W8leaVsOOBq+W/nOOBmOOBpuODhuODvOODnuOBruiqv+aVtOOCkuWPr+iDveOBqOOBl+OBpuOBhOOBvuOBmeOAggoKYGBgeWFtbApvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOgogICAgICB2ZXJzaW9uOiA0ICAgIyAz44KC5Y+v6IO944CCCiAgICAgIGJvb3Rzd2F0Y2g6IGRhcmtseQogICAgICBiZzogYmVpZ2UgIyDog4zmma/oibLjgIJmZ+OBruaMh+WumuOBjOW/hemgiOOAggogICAgICBmZzogYmxhY2sgIyDooajpnaLoibLjgILmloflrZfoibLjga7jgZPjgajjgaPjgb3jgYTjgIIKYGBgCgrjgaHjgarjgb/jgatgYnNsaWI6OmJzX3RoZW1lYOmWouaVsOOBruW8leaVsOOBr+S7peS4i+OBrumAmuOCiuOAggoKYGBge3J9Cm5hbWVzKGZvcm1hbHMoYnNsaWI6OmJzX3RoZW1lKSkKYGBgCgrlj6/lpInplbflvJXmlbDvvIhgLi4uYO+8ieS7pemZjeOBjOODhuODvOODnuiqv+aVtOeUqOOBruW8leaVsOOBp+OBmeOBreOAggrjgZPjgozjgonjga7lvJXmlbDjga9DU1PjgpLli5XnmoTjgavnlJ/miJDjgZnjgovjgZ/jgoHjga7jg5Xjg6zjg7zjg6Djg6/jg7zjgq/jgavlvJXmlbDjgajjgZfjgabmuKHjgZXjgozjgabjgYTjgb7jgZnjgIIK5Y+v5aSJ6ZW35byV5pWw44KC44Gh44KD44KT44Go5rih44GV44KM44KL44Gu44Gn44CB5LuW44Gr44KC6Imy44CF44Gq6Kq/5pW044GM5Y+v6IO944Gn44GZ44CCCgrliKnnlKjlj6/og73jgarlvJXmlbDjga/ku6XkuIvjga7jg6rjg7Pjgq/jgYvjgonnorroqo3jgZfjgabjgY/jgaDjgZXjgYTjgIIK44Gq44GK44CBYGh0bWxfZG9jdW1lbnRg6Zai5pWw44Gn5oyH5a6a44GZ44KL44Gr44GvYC1g44KSYF9g44Gr572u5o+b44GX44Gm44GP44Gg44GV44GE44CCCgo+IDxodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAtc2Fzcy9ibG9iL21hc3Rlci9hc3NldHMvc3R5bGVzaGVldHMvYm9vdHN0cmFwL192YXJpYWJsZXMuc2Nzcz4KCuOBn+OBqOOBiOOBsGBmb250X3NpemVfYmFzZWDopoHntKDjgpLmjIflrprjgZnjgozjgbDjgIHln7rmupbjgajjgarjgovjg5Xjgqnjg7Pjg4jjga7jgrXjgqTjgrrjgpLlpInmm7Tlj6/og73jgafjgZnjgIIK44GT44Gu5pa55rOV44Gq44KJQm9vdHN0cmFwIDPjgafjgYLjgaPjgabjgoLjg5Xjgqnjg7Pjg4jjgrXjgqTjgrrjgpLkuIDlhYPnmoTjgavlpInmm7TjgafjgY3jgb7jgZnjgIIK44Gf44Gg44GX44CB5L2/44GI44KL5Y2Y5L2N44GMQm9vdHN0cmFwIDTjga5gcmVtYOOBq+WvvuOBl+OAgUJvb3RzdHJhcCAz44Gu5aC05ZCI44GvYHB4YOOBp+OBmeOAggoKIyDmhJ/mg7PjgajlsZXmnJsKCuW+k+adpeOBrmBybWFya2Rvd246Omh0bWxfZG9jdW1lbnRg6Zai5pWw44Gn44OG44O844Oe44KS44Kr44K544K/44Oe44Kk44K644GZ44KL44Gr44Gv44CBYGNzc2DlvJXmlbDjgatDU1Pjg5XjgqHjgqTjg6vjgpLmjIflrprjgZnjgovlv4XopoHjgYzjgYLjgorjgb7jgZfjgZ/jgIIK44GT44KM44GM5rib44KJ44Gb44KL44Gu44Gv44Go44Gj44Gm44KC57Ch5L6/44Gn6Imv44GE44Gn44GZ44Gt44CCCuWun+OBr2B0aGVtZWDlvJXmlbDjgavjga/mloflrZfliJfjgIHjg6rjgrnjg4jjga7ku5bjgatgYnNsaWI6OmJzX3RoZW1lYOOBruWun+ihjOe1kOaenOOCkuS4juOBiOOCi+OBk+OBqOOCguWPr+iDveOBp+OBmeOAggoKYGBgeWFtbApvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOiAhZXhwciBic2xpYjo6YnNfdGhlbWUodmVyc2lvbiA9IDQpCmBgYAoKYCFleHByYOOBr1LoqIDoqp7jgajjgZfjgaboqZXkvqHjgZfjgabjga3jgIHjgajjgYTjgYbjgq3jg7zjg6/jg7zjg4njgafjgZnjgIIK44GT44KM44CB6KiA44GE5aSJ44GI44KL44GoYGJzbGliOjpic190aGVtZWDplqLmlbDjga7ov5TjgorlgKTjgavmupbmi6DjgZfjgZ/jgqvjgrnjgr/jg6DplqLmlbDjgpLliKnnlKjjgafjgY3jgb7jgZnjgIIK44OR44OD44Kx44O844K444Go44GX44Gm44Kr44K544K/44Og44OG44O844Oe44KS5o+Q5L6b44GZ44KL5pmC44Go44Gj44Gm44KC5L6/5Yip44Gd44GG44Gn44GZ44KI44Gt44CCCuengeOBr+WJjeOBi+OCiUhvbm9rYeOBqOOBhOOBhuaXpeacrOiqnuWQkeOBkeOBrkJvb3RzdHJhcOODhuODvOODnuOCkuS9v+OBo+OBpuOBv+OBn+OBhOOBqOaAneOBo+OBpuOBhOOBvuOBl+OBn+OAggoKPiA8aHR0cHM6Ly9ob25va2FrLm9zYWthLz4KCioqYnNsaWIqKuODkeODg+OCseODvOOCuOOBruaMmeWLleOCkuWPguiAg+OBq+Wun+ijheOBl+OBn+OBhOOBqOaAneOBhOOBvuOBmeOAggrjg5Hjg4PjgrHjg7zjgrjljJbjgZnjgovjgajjgZfjgZ/jgolgaG9ub2thZG93bjo6aG9ub2thX2RvY3VtZW50YOOBqOOBi+OBi+OBquOBgu+8nwoKIyBFbmpveSEhCg==