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
引数を適宜指定するだけです。 最低限必要なものにversion: 4
があります。 version
を省略するか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-family
プロパティに指定されたフォントリストから利用するフォントを選択します。 先頭にあるほど優先度が高く、
- インストールされているか
- 文字をレンダリング可能か
の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!!
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==