diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..f1731109 --- /dev/null +++ b/.nojekyll @@ -0,0 +1 @@ +This file makes sure that Github Pages doesn't process mdBook's output. diff --git a/404.html b/404.html new file mode 100644 index 00000000..cab666fe --- /dev/null +++ b/404.html @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Document not found (404)

+

This URL is invalid, sorry. Please use the navigation bar or search to continue.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FontAwesome/css/font-awesome.css b/FontAwesome/css/font-awesome.css new file mode 100644 index 00000000..540440ce --- /dev/null +++ b/FontAwesome/css/font-awesome.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/FontAwesome/fonts/FontAwesome.ttf b/FontAwesome/fonts/FontAwesome.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/FontAwesome/fonts/FontAwesome.ttf differ diff --git a/FontAwesome/fonts/fontawesome-webfont.eot b/FontAwesome/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/FontAwesome/fonts/fontawesome-webfont.eot differ diff --git a/FontAwesome/fonts/fontawesome-webfont.svg b/FontAwesome/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/FontAwesome/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FontAwesome/fonts/fontawesome-webfont.ttf b/FontAwesome/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/FontAwesome/fonts/fontawesome-webfont.ttf differ diff --git a/FontAwesome/fonts/fontawesome-webfont.woff b/FontAwesome/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/FontAwesome/fonts/fontawesome-webfont.woff differ diff --git a/FontAwesome/fonts/fontawesome-webfont.woff2 b/FontAwesome/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/FontAwesome/fonts/fontawesome-webfont.woff2 differ diff --git a/adapt_io_example.rs b/adapt_io_example.rs new file mode 100644 index 00000000..38d838a2 --- /dev/null +++ b/adapt_io_example.rs @@ -0,0 +1,63 @@ +// ANCHOR: all +use calloop::EventLoop; + +// ANCHOR: use_futures_io_traits +use futures::io::{AsyncReadExt, AsyncWriteExt}; +// ANCHOR_END: use_futures_io_traits + +fn main() -> std::io::Result<()> { + // ANCHOR: decl_executor + let (exec, sched) = calloop::futures::executor()?; + // ANCHOR_END: decl_executor + + // ANCHOR: decl_loop + let mut event_loop = EventLoop::try_new()?; + let handle = event_loop.handle(); + + handle + .insert_source(exec, |evt, _metadata, _shared| { + // Print the value of the async block ie. the return value. + println!("Async block ended with: {}", evt); + }) + .map_err(|e| e.error)?; + // ANCHOR_END: decl_loop + + // ANCHOR: decl_io + let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap(); + let mut sender = handle.adapt_io(sender).unwrap(); + let mut receiver = handle.adapt_io(receiver).unwrap(); + // ANCHOR_END: decl_io + + // ANCHOR: decl_async_receive + let async_receive = async move { + let mut buf = [0u8; 12]; + // Here's our async-ified Unix domain socket. + receiver.read_exact(&mut buf).await.unwrap(); + std::str::from_utf8(&buf).unwrap().to_owned() + }; + + // Schedule the async block to be run in the event loop. + sched.schedule(async_receive).unwrap(); + // ANCHOR_END: decl_async_receive + + // ANCHOR: decl_async_send + let async_send = async move { + // Here's our async-ified Unix domain socket. + sender.write_all(b"Hello, world!").await.unwrap(); + "Sent data...".to_owned() + }; + + // Schedule the async block to be run in the event loop. + sched.schedule(async_send).unwrap(); + // ANCHOR_END: decl_async_send + + // ANCHOR: run_loop + // Run the event loop. + println!("Starting event loop. Use Ctrl-C to exit."); + event_loop.run(None, &mut event_loop.get_signal(), |_| {})?; + println!("Event loop ended."); + // ANCHOR_END: run_loop + + Ok(()) +} +// ANCHOR_END: all diff --git a/api/.lock b/api/.lock new file mode 100644 index 00000000..e69de29b diff --git a/api/calloop/all.html b/api/calloop/all.html new file mode 100644 index 00000000..8abfecab --- /dev/null +++ b/api/calloop/all.html @@ -0,0 +1 @@ +List of all items in this crate

List of all items

Structs

Enums

Traits

Macros

Functions

Type Definitions

\ No newline at end of file diff --git a/api/calloop/channel/enum.Event.html b/api/calloop/channel/enum.Event.html new file mode 100644 index 00000000..faad8e90 --- /dev/null +++ b/api/calloop/channel/enum.Event.html @@ -0,0 +1,29 @@ +Event in calloop::channel - Rust

Enum calloop::channel::Event

source ·
pub enum Event<T> {
+    Msg(T),
+    Closed,
+}
Expand description

The events generated by the channel event source

+

Variants§

§

Msg(T)

A message was received and is bundled here

+
§

Closed

The channel was closed

+

This means all the Senders associated with this channel +have been dropped, no more messages will ever be received.

+

Trait Implementations§

source§

impl<T: Debug> Debug for Event<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for Event<T>where + T: RefUnwindSafe,

§

impl<T> Send for Event<T>where + T: Send,

§

impl<T> Sync for Event<T>where + T: Sync,

§

impl<T> Unpin for Event<T>where + T: Unpin,

§

impl<T> UnwindSafe for Event<T>where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/channel/fn.channel.html b/api/calloop/channel/fn.channel.html new file mode 100644 index 00000000..aff026ee --- /dev/null +++ b/api/calloop/channel/fn.channel.html @@ -0,0 +1,2 @@ +channel in calloop::channel - Rust

Function calloop::channel::channel

source ·
pub fn channel<T>() -> (Sender<T>, Channel<T>)
Expand description

Create a new asynchronous channel

+
\ No newline at end of file diff --git a/api/calloop/channel/fn.sync_channel.html b/api/calloop/channel/fn.sync_channel.html new file mode 100644 index 00000000..476badf7 --- /dev/null +++ b/api/calloop/channel/fn.sync_channel.html @@ -0,0 +1,2 @@ +sync_channel in calloop::channel - Rust

Function calloop::channel::sync_channel

source ·
pub fn sync_channel<T>(bound: usize) -> (SyncSender<T>, Channel<T>)
Expand description

Create a new synchronous, bounded channel

+
\ No newline at end of file diff --git a/api/calloop/channel/index.html b/api/calloop/channel/index.html new file mode 100644 index 00000000..dde59d00 --- /dev/null +++ b/api/calloop/channel/index.html @@ -0,0 +1,8 @@ +calloop::channel - Rust

Module calloop::channel

source ·
Expand description

An MPSC channel whose receiving end is an event source

+

Create a channel using channel(), which returns a +Sender that can be cloned and sent accross threads if T: Send, +and a Channel that can be inserted into an EventLoop. +It will generate one event per message.

+

A synchronous version of the channel is provided by sync_channel, in which +the SyncSender will block when the channel is full.

+

Structs

  • The receiving end of the channel
  • An error arising from processing events for a channel.
  • The sender end of a channel
  • The sender end of a synchronous channel

Enums

  • The events generated by the channel event source

Functions

\ No newline at end of file diff --git a/api/calloop/channel/sidebar-items.js b/api/calloop/channel/sidebar-items.js new file mode 100644 index 00000000..40615100 --- /dev/null +++ b/api/calloop/channel/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Event"],"fn":["channel","sync_channel"],"struct":["Channel","ChannelError","Sender","SyncSender"]}; \ No newline at end of file diff --git a/api/calloop/channel/struct.Channel.html b/api/calloop/channel/struct.Channel.html new file mode 100644 index 00000000..0c554c39 --- /dev/null +++ b/api/calloop/channel/struct.Channel.html @@ -0,0 +1,45 @@ +Channel in calloop::channel - Rust

Struct calloop::channel::Channel

source ·
pub struct Channel<T> { /* private fields */ }
Expand description

The receiving end of the channel

+

This is the event source to be inserted into your EventLoop.

+

Implementations§

source§

impl<T> Channel<T>

source

pub fn recv(&self) -> Result<T, RecvError>

Proxy for mpsc::Receiver::recv to manually poll events.

+

Note: Normally you would want to use the Channel by inserting +it into an event loop instead. Use this for example to immediately +dispatch pending events after creation.

+
source

pub fn try_recv(&self) -> Result<T, TryRecvError>

Proxy for mpsc::Receiver::try_recv to manually poll events.

+

Note: Normally you would want to use the Channel by inserting +it into an event loop instead. Use this for example to immediately +dispatch pending events after creation.

+

Trait Implementations§

source§

impl<T: Debug> Debug for Channel<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> EventSource for Channel<T>

§

type Event = Event<T>

The type of events generated by your source.
§

type Metadata = ()

Some metadata of your event source Read more
§

type Ret = ()

The return type of the user callback Read more
§

type Error = ChannelError

The error type returned from +process_events() (not the user callback!).
source§

fn process_events<C>( + &mut self, + readiness: Readiness, + token: Token, + callback: C +) -> Result<PostAction, Self::Error>where + C: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,

Process any relevant events Read more
source§

fn register( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

Register yourself to this poll instance Read more
source§

fn reregister( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

Re-register your file descriptors Read more
source§

fn unregister(&mut self, poll: &mut Poll) -> Result<()>

Unregister your file descriptors Read more
source§

const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = false

Whether this source needs to be sent the EventSource::before_sleep +and EventSource::before_handle_events notifications. These are opt-in because +they require more expensive checks, and almost all sources will not need these notifications
source§

fn before_sleep(&mut self) -> Result<Option<(Readiness, Token)>>

Notification that a single poll is about to begin Read more
source§

fn before_handle_events(&mut self, events: EventIterator<'_>)

Notification that polling is complete, and EventSource::process_events will +be called with the given events for this source. The iterator may be empty, +which indicates that no events were generated for this source Read more
source§

impl<T: Send> Send for Channel<T>

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for Channel<T>

§

impl<T> !Sync for Channel<T>

§

impl<T> Unpin for Channel<T>

§

impl<T> !UnwindSafe for Channel<T>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/channel/struct.ChannelError.html b/api/calloop/channel/struct.ChannelError.html new file mode 100644 index 00000000..45b4803e --- /dev/null +++ b/api/calloop/channel/struct.ChannelError.html @@ -0,0 +1,18 @@ +ChannelError in calloop::channel - Rust
pub struct ChannelError(_);
Expand description

An error arising from processing events for a channel.

+

Trait Implementations§

source§

impl Debug for ChannelError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for ChannelError

source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for ChannelError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/channel/struct.Sender.html b/api/calloop/channel/struct.Sender.html new file mode 100644 index 00000000..23733a15 --- /dev/null +++ b/api/calloop/channel/struct.Sender.html @@ -0,0 +1,24 @@ +Sender in calloop::channel - Rust

Struct calloop::channel::Sender

source ·
pub struct Sender<T> { /* private fields */ }
Expand description

The sender end of a channel

+

It can be cloned and sent accross threads (if T is).

+

Implementations§

source§

impl<T> Sender<T>

source

pub fn send(&self, t: T) -> Result<(), SendError<T>>

Send a message to the channel

+

This will wake the event loop and deliver an Event::Msg to +it containing the provided value.

+

Trait Implementations§

source§

impl<T> Clone for Sender<T>

source§

fn clone(&self) -> Sender<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for Sender<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> Drop for Sender<T>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for Sender<T>

§

impl<T> Send for Sender<T>where + T: Send,

§

impl<T> Sync for Sender<T>where + T: Send,

§

impl<T> Unpin for Sender<T>

§

impl<T> UnwindSafe for Sender<T>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/channel/struct.SyncSender.html b/api/calloop/channel/struct.SyncSender.html new file mode 100644 index 00000000..2db4abbd --- /dev/null +++ b/api/calloop/channel/struct.SyncSender.html @@ -0,0 +1,33 @@ +SyncSender in calloop::channel - Rust

Struct calloop::channel::SyncSender

source ·
pub struct SyncSender<T> { /* private fields */ }
Expand description

The sender end of a synchronous channel

+

It can be cloned and sent accross threads (if T is).

+

Implementations§

source§

impl<T> SyncSender<T>

source

pub fn send(&self, t: T) -> Result<(), SendError<T>>

Send a message to the synchronous channel

+

This will wake the event loop and deliver an Event::Msg to +it containing the provided value. If the channel is full, this +function will block until the event loop empties it and it can +deliver the message.

+

Due to the blocking behavior, this method should not be used on the +same thread as the one running the event loop, as it could cause deadlocks.

+
source

pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>>

Send a message to the synchronous channel

+

This will wake the event loop and deliver an Event::Msg to +it containing the provided value. If the channel is full, this +function will return an error, but the event loop will still be +signaled for readiness.

+

Trait Implementations§

source§

impl<T> Clone for SyncSender<T>

source§

fn clone(&self) -> SyncSender<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for SyncSender<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for SyncSender<T>

§

impl<T> Send for SyncSender<T>where + T: Send,

§

impl<T> Sync for SyncSender<T>where + T: Send,

§

impl<T> Unpin for SyncSender<T>

§

impl<T> UnwindSafe for SyncSender<T>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/enum.Mode.html b/api/calloop/enum.Mode.html new file mode 100644 index 00000000..de0051c1 --- /dev/null +++ b/api/calloop/enum.Mode.html @@ -0,0 +1,42 @@ +Mode in calloop - Rust

Enum calloop::Mode

source ·
pub enum Mode {
+    OneShot,
+    Level,
+    Edge,
+}
Expand description

Possible modes for registering a file descriptor

+

Variants§

§

OneShot

Single event generation

+

This FD will be disabled as soon as it has generated one event.

+

The user will need to use LoopHandle::update() to re-enable it if +desired.

+
§

Level

Level-triggering

+

This FD will report events on every poll as long as the requested interests +are available.

+
§

Edge

Edge-triggering

+

This FD will report events only when it gains one of the requested interests. +it must thus be fully processed before it’ll generate events again.

+

This mode is not supported on certain platforms, and an error will be returned +if it is used.

+
Supported Platforms
+

As of the time of writing, the platforms that support edge triggered polling are +as follows:

+
    +
  • Linux/Android
  • +
  • macOS/iOS/tvOS/watchOS
  • +
  • FreeBSD/OpenBSD/NetBSD/DragonflyBSD
  • +
+

Trait Implementations§

source§

impl Clone for Mode

source§

fn clone(&self) -> Mode

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Mode

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Mode

Auto Trait Implementations§

§

impl RefUnwindSafe for Mode

§

impl Send for Mode

§

impl Sync for Mode

§

impl Unpin for Mode

§

impl UnwindSafe for Mode

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/enum.PostAction.html b/api/calloop/enum.PostAction.html new file mode 100644 index 00000000..c2a85d44 --- /dev/null +++ b/api/calloop/enum.PostAction.html @@ -0,0 +1,45 @@ +PostAction in calloop - Rust

Enum calloop::PostAction

source ·
pub enum PostAction {
+    Continue,
+    Reregister,
+    Disable,
+    Remove,
+}
Expand description

Possible actions that can be requested to the event loop by an +event source once its events have been processed.

+

PostAction values can be combined with the | (bit-or) operator (or with +|=) with the result that:

+
    +
  • if both values are identical, the result is that value
  • +
  • if they are different, the result is Reregister
  • +
+

Bit-or-ing these results is useful for composed sources to combine the +results of their child sources, but note that it only applies to the child +sources. For example, if every child source returns Continue, the result +will be Continue, but the parent source might still need to return +Reregister or something else depending on any additional logic it uses.

+

Variants§

§

Continue

Continue listening for events on this source as before

+
§

Reregister

Trigger a re-registration of this source

+
§

Disable

Disable this source

+

Has the same effect as LoopHandle::disable

+
§

Remove

Remove this source from the eventloop

+

Has the same effect as LoopHandle::kill

+

Trait Implementations§

source§

impl BitOr<PostAction> for PostAction

Combines PostAction values returned from nested event sources.

+
§

type Output = PostAction

The resulting type after applying the | operator.
source§

fn bitor(self, rhs: Self) -> Self::Output

Performs the | operation. Read more
source§

impl BitOrAssign<PostAction> for PostAction

Combines PostAction values returned from nested event sources.

+
source§

fn bitor_assign(&mut self, rhs: Self)

Performs the |= operation. Read more
source§

impl Clone for PostAction

source§

fn clone(&self) -> PostAction

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for PostAction

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq<PostAction> for PostAction

source§

fn eq(&self, other: &PostAction) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for PostAction

source§

impl Eq for PostAction

source§

impl StructuralEq for PostAction

source§

impl StructuralPartialEq for PostAction

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/error/enum.Error.html b/api/calloop/error/enum.Error.html new file mode 100644 index 00000000..1f2d3ee0 --- /dev/null +++ b/api/calloop/error/enum.Error.html @@ -0,0 +1,34 @@ +Error in calloop::error - Rust

Enum calloop::error::Error

source ·
pub enum Error {
+    InvalidToken,
+    IoError(Error),
+    OtherError(Box<dyn Error + Sync + Send>),
+}
Expand description

The primary error type used by Calloop covering internal errors and I/O +errors that arise during loop operations such as source registration or +event dispatching.

+

Variants§

§

InvalidToken

When an event source is registered (or re- or un-registered) with the +event loop, this error variant will occur if the token Calloop uses to +keep track of the event source is not valid.

+
§

IoError(Error)

This variant wraps a std::io::Error, which might arise from +Calloop’s internal operations.

+
§

OtherError(Box<dyn Error + Sync + Send>)

Any other unexpected error kind (most likely from a user implementation of +EventSource::process_events()) will be wrapped in this.

+

Trait Implementations§

source§

impl Debug for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for Error

source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for Error

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Box<dyn Error + Sync + Send, Global>> for Error

source§

fn from(source: Box<dyn Error + Sync + Send>) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(err: Error) -> Self

Converts Calloop’s error type into a std::io::Error.

+
source§

impl<T> From<InsertError<T>> for Error

source§

fn from(e: InsertError<T>) -> Error

Converts the InsertError into Calloop’s error type, throwing away +the contained source.

+

Auto Trait Implementations§

§

impl !RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/error/index.html b/api/calloop/error/index.html new file mode 100644 index 00000000..a5a3573e --- /dev/null +++ b/api/calloop/error/index.html @@ -0,0 +1,19 @@ +calloop::error - Rust

Module calloop::error

source ·
Expand description

Error types used and generated by Calloop.

+

This module contains error types for Calloop’s operations. They are designed +to make it easy to deal with errors arising from Calloop’s internal I/O and +other operations.

+

There are two top-level error types:

+
    +
  • +

    Error: used by callback functions, internal operations, and some event +loop API calls

    +
  • +
  • +

    InsertError: used primarily by the insert_source() method when an +event source cannot be added to the loop and needs to be given back to the +caller

    +
  • +
+

Structs

  • An error generated when trying to insert an event source

Enums

  • The primary error type used by Calloop covering internal errors and I/O +errors that arise during loop operations such as source registration or +event dispatching.

Type Definitions

\ No newline at end of file diff --git a/api/calloop/error/sidebar-items.js b/api/calloop/error/sidebar-items.js new file mode 100644 index 00000000..541c1563 --- /dev/null +++ b/api/calloop/error/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Error"],"struct":["InsertError"],"type":["Result"]}; \ No newline at end of file diff --git a/api/calloop/error/struct.InsertError.html b/api/calloop/error/struct.InsertError.html new file mode 100644 index 00000000..211e55bf --- /dev/null +++ b/api/calloop/error/struct.InsertError.html @@ -0,0 +1,29 @@ +InsertError in calloop::error - Rust

Struct calloop::error::InsertError

source ·
pub struct InsertError<T> {
+    pub inserted: T,
+    pub error: Error,
+}
Expand description

An error generated when trying to insert an event source

+

Fields§

§inserted: T

The source that could not be inserted

+
§error: Error

The generated error

+

Trait Implementations§

source§

impl<T> Debug for InsertError<T>

source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<T> Display for InsertError<T>

source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> Error for InsertError<T>where + Self: Debug + Display,

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl<T> From<InsertError<T>> for Error

source§

fn from(e: InsertError<T>) -> Error

Converts the InsertError into Calloop’s error type, throwing away +the contained source.

+

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for InsertError<T>

§

impl<T> Send for InsertError<T>where + T: Send,

§

impl<T> Sync for InsertError<T>where + T: Sync,

§

impl<T> Unpin for InsertError<T>where + T: Unpin,

§

impl<T> !UnwindSafe for InsertError<T>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/error/type.Result.html b/api/calloop/error/type.Result.html new file mode 100644 index 00000000..637fc316 --- /dev/null +++ b/api/calloop/error/type.Result.html @@ -0,0 +1,2 @@ +Result in calloop::error - Rust

Type Definition calloop::error::Result

source ·
pub type Result<T> = Result<T, Error>;
Expand description

Result alias using Calloop’s error type.

+
\ No newline at end of file diff --git a/api/calloop/futures/enum.ExecutorError.html b/api/calloop/futures/enum.ExecutorError.html new file mode 100644 index 00000000..f67b5f12 --- /dev/null +++ b/api/calloop/futures/enum.ExecutorError.html @@ -0,0 +1,23 @@ +ExecutorError in calloop::futures - Rust
pub enum ExecutorError {
+    NewFutureError(ChannelError),
+    WakeError(PingError),
+}
Expand description

An error arising from processing events in an async executor event source.

+

Variants§

§

NewFutureError(ChannelError)

Error while reading new futures added via Scheduler::schedule().

+
§

WakeError(PingError)

Error while processing wake events from existing futures.

+

Trait Implementations§

source§

impl Debug for ExecutorError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for ExecutorError

source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for ExecutorError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/futures/fn.executor.html b/api/calloop/futures/fn.executor.html new file mode 100644 index 00000000..d1749573 --- /dev/null +++ b/api/calloop/futures/fn.executor.html @@ -0,0 +1,4 @@ +executor in calloop::futures - Rust

Function calloop::futures::executor

source ·
pub fn executor<T>() -> Result<(Executor<T>, Scheduler<T>)>
Expand description

Create a new executor, and its associated scheduler

+

May fail due to OS errors preventing calloop to setup its internal pipes (if your +process has reatched its file descriptor limit for example).

+
\ No newline at end of file diff --git a/api/calloop/futures/index.html b/api/calloop/futures/index.html new file mode 100644 index 00000000..c5c41190 --- /dev/null +++ b/api/calloop/futures/index.html @@ -0,0 +1,17 @@ +calloop::futures - Rust

Module calloop::futures

source ·
Expand description

A futures executor as an event source

+

Only available with the executor cargo feature of calloop.

+

This executor is intended for light futures, which will be polled as part of your +event loop. Such futures may be waiting for IO, or for some external computation on an +other thread for example.

+

You can create a new executor using the executor function, which creates a pair +(Executor<T>, Scheduler<T>) to handle futures that all evaluate to type T. The +executor should be inserted into your event loop, and will yield the return values of +the futures as they finish into your callback. The scheduler can be cloned and used +to send futures to be executed into the executor. A generic executor can be obtained +by choosing T = () and letting futures handle the forwarding of their return values +(if any) by their own means.

+

Note: The futures must have their own means of being woken up, as this executor is, +by itself, not I/O aware. See LoopHandle::adapt_io +for that, or you can use some other mechanism if you prefer.

+

Structs

  • A future executor as an event source
  • Error generated when trying to schedule a future after the +executor was destroyed.
  • A scheduler to send futures to an executor

Enums

  • An error arising from processing events in an async executor event source.

Functions

  • Create a new executor, and its associated scheduler
\ No newline at end of file diff --git a/api/calloop/futures/sidebar-items.js b/api/calloop/futures/sidebar-items.js new file mode 100644 index 00000000..750e61b7 --- /dev/null +++ b/api/calloop/futures/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["ExecutorError"],"fn":["executor"],"struct":["Executor","ExecutorDestroyed","Scheduler"]}; \ No newline at end of file diff --git a/api/calloop/futures/struct.Executor.html b/api/calloop/futures/struct.Executor.html new file mode 100644 index 00000000..8876d4aa --- /dev/null +++ b/api/calloop/futures/struct.Executor.html @@ -0,0 +1,36 @@ +Executor in calloop::futures - Rust

Struct calloop::futures::Executor

source ·
pub struct Executor<T> { /* private fields */ }
Expand description

A future executor as an event source

+

Trait Implementations§

source§

impl<T: Debug> Debug for Executor<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> Drop for Executor<T>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<T> EventSource for Executor<T>

§

type Event = T

The type of events generated by your source.
§

type Metadata = ()

Some metadata of your event source Read more
§

type Ret = ()

The return type of the user callback Read more
§

type Error = ExecutorError

The error type returned from +process_events() (not the user callback!).
source§

fn process_events<F>( + &mut self, + readiness: Readiness, + token: Token, + callback: F +) -> Result<PostAction, Self::Error>where + F: FnMut(T, &mut ()),

Process any relevant events Read more
source§

fn register( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

Register yourself to this poll instance Read more
source§

fn reregister( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

Re-register your file descriptors Read more
source§

fn unregister(&mut self, poll: &mut Poll) -> Result<()>

Unregister your file descriptors Read more
source§

const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = false

Whether this source needs to be sent the EventSource::before_sleep +and EventSource::before_handle_events notifications. These are opt-in because +they require more expensive checks, and almost all sources will not need these notifications
source§

fn before_sleep(&mut self) -> Result<Option<(Readiness, Token)>>

Notification that a single poll is about to begin Read more
source§

fn before_handle_events(&mut self, events: EventIterator<'_>)

Notification that polling is complete, and EventSource::process_events will +be called with the given events for this source. The iterator may be empty, +which indicates that no events were generated for this source Read more

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for Executor<T>

§

impl<T> !Send for Executor<T>

§

impl<T> !Sync for Executor<T>

§

impl<T> Unpin for Executor<T>

§

impl<T> !UnwindSafe for Executor<T>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/futures/struct.ExecutorDestroyed.html b/api/calloop/futures/struct.ExecutorDestroyed.html new file mode 100644 index 00000000..63a471b6 --- /dev/null +++ b/api/calloop/futures/struct.ExecutorDestroyed.html @@ -0,0 +1,19 @@ +ExecutorDestroyed in calloop::futures - Rust
pub struct ExecutorDestroyed;
Expand description

Error generated when trying to schedule a future after the +executor was destroyed.

+

Trait Implementations§

source§

impl Debug for ExecutorDestroyed

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for ExecutorDestroyed

source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for ExecutorDestroyed

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/futures/struct.Scheduler.html b/api/calloop/futures/struct.Scheduler.html new file mode 100644 index 00000000..38b17ebc --- /dev/null +++ b/api/calloop/futures/struct.Scheduler.html @@ -0,0 +1,22 @@ +Scheduler in calloop::futures - Rust

Struct calloop::futures::Scheduler

source ·
pub struct Scheduler<T> { /* private fields */ }
Expand description

A scheduler to send futures to an executor

+

Implementations§

source§

impl<T> Scheduler<T>

source

pub fn schedule<Fut>(&self, future: Fut) -> Result<(), ExecutorDestroyed>where + Fut: Future<Output = T> + 'static, + T: 'static,

Sends the given future to the executor associated to this scheduler

+

Returns an error if the the executor not longer exists.

+

Trait Implementations§

source§

impl<T: Clone> Clone for Scheduler<T>

source§

fn clone(&self) -> Scheduler<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for Scheduler<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for Scheduler<T>

§

impl<T> !Send for Scheduler<T>

§

impl<T> !Sync for Scheduler<T>

§

impl<T> Unpin for Scheduler<T>

§

impl<T> !UnwindSafe for Scheduler<T>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/generic/index.html b/api/calloop/generic/index.html new file mode 100644 index 00000000..5a550221 --- /dev/null +++ b/api/calloop/generic/index.html @@ -0,0 +1,27 @@ +calloop::generic - Rust

Module calloop::generic

source ·
Expand description

A generic event source wrapping an IO objects or file descriptor

+

You can use this general purpose adapter around file-descriptor backed objects to +insert into an EventLoop.

+

The event generated by this Generic event source are the Readiness +notification itself, and the monitored object is provided to your callback as the second +argument.

+ +
use calloop::{generic::Generic, Interest, Mode, PostAction};
+
+handle.insert_source(
+    // wrap your IO object in a Generic, here we register for read readiness
+    // in level-triggering mode
+    Generic::new(io_object, Interest::READ, Mode::Level),
+    |readiness, io_object, shared_data| {
+        // The first argument of the callback is a Readiness
+        // The second is a &mut reference to your object
+
+        // your callback needs to return a Result<PostAction, std::io::Error>
+        // if it returns an error, the event loop will consider this event
+        // event source as erroring and report it to the user.
+        Ok(PostAction::Continue)
+    }
+);
+

It can also help you implementing your own event sources: just have +these Generic<_> as fields of your event source, and delegate the +EventSource implementation to them.

+

Structs

  • Wrapper to use a type implementing AsRawFd but not AsFd with Generic
  • A generic event source wrapping a FD-backed type
  • A wrapper around a type that doesn’t expose it mutably safely.
\ No newline at end of file diff --git a/api/calloop/generic/sidebar-items.js b/api/calloop/generic/sidebar-items.js new file mode 100644 index 00000000..a68e2636 --- /dev/null +++ b/api/calloop/generic/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["FdWrapper","Generic","NoIoDrop"]}; \ No newline at end of file diff --git a/api/calloop/generic/struct.FdWrapper.html b/api/calloop/generic/struct.FdWrapper.html new file mode 100644 index 00000000..ab9d3e74 --- /dev/null +++ b/api/calloop/generic/struct.FdWrapper.html @@ -0,0 +1,28 @@ +FdWrapper in calloop::generic - Rust

Struct calloop::generic::FdWrapper

source ·
pub struct FdWrapper<T: AsRawFd>(_);
Expand description

Wrapper to use a type implementing AsRawFd but not AsFd with Generic

+

Implementations§

source§

impl<T: AsRawFd> FdWrapper<T>

source

pub unsafe fn new(inner: T) -> Self

Wrap inner with an AsFd implementation.

+
Safety
+

This is safe if the AsRawFd implementation of inner always returns +a valid fd. This should usually be true for types implementing +AsRawFd. But this isn’t guaranteed with FdWrapper<RawFd>.

+

Trait Implementations§

source§

impl<T: AsRawFd> AsFd for FdWrapper<T>

source§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more
source§

impl<T: Debug + AsRawFd> Debug for FdWrapper<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: AsRawFd> Deref for FdWrapper<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl<T: AsRawFd> DerefMut for FdWrapper<T>

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for FdWrapper<T>where + T: RefUnwindSafe,

§

impl<T> Send for FdWrapper<T>where + T: Send,

§

impl<T> Sync for FdWrapper<T>where + T: Sync,

§

impl<T> Unpin for FdWrapper<T>where + T: Unpin,

§

impl<T> UnwindSafe for FdWrapper<T>where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> AsSource for Twhere + T: AsFd,

§

fn source(&self) -> BorrowedFd<'_>

Returns the borrowed file descriptor.
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/generic/struct.Generic.html b/api/calloop/generic/struct.Generic.html new file mode 100644 index 00000000..fb180502 --- /dev/null +++ b/api/calloop/generic/struct.Generic.html @@ -0,0 +1,68 @@ +Generic in calloop::generic - Rust

Struct calloop::generic::Generic

source ·
pub struct Generic<F: AsFd, E = Error> {
+    pub interest: Interest,
+    pub mode: Mode,
+    /* private fields */
+}
Expand description

A generic event source wrapping a FD-backed type

+

Fields§

§interest: Interest

The programmed interest

+
§mode: Mode

The programmed mode

+

Implementations§

source§

impl<F: AsFd> Generic<F, Error>

source

pub fn new(file: F, interest: Interest, mode: Mode) -> Generic<F, Error>

Wrap a FD-backed type into a Generic event source that uses +std::io::Error as its error type.

+
source

pub fn new_with_error<E>( + file: F, + interest: Interest, + mode: Mode +) -> Generic<F, E>

Wrap a FD-backed type into a Generic event source using an arbitrary error type.

+
source§

impl<F: AsFd, E> Generic<F, E>

source

pub fn unwrap(self) -> F

Unwrap the Generic source to retrieve the underlying type

+
source

pub fn get_ref(&self) -> &F

Get a reference to the underlying type.

+
source

pub unsafe fn get_mut(&mut self) -> &mut F

Get a mutable reference to the underlying type.

+
Safety
+

This is unsafe because it allows you to modify the underlying type, which +allows you to drop the underlying event source. Dropping the underlying source +leads to a dangling reference.

+

Trait Implementations§

source§

impl<F: Debug + AsFd, E: Debug> Debug for Generic<F, E>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<F: AsFd, E> Drop for Generic<F, E>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<F, E> EventSource for Generic<F, E>where + F: AsFd, + E: Into<Box<dyn Error + Send + Sync>>,

§

type Event = Readiness

The type of events generated by your source.
§

type Metadata = NoIoDrop<F>

Some metadata of your event source Read more
§

type Ret = Result<PostAction, E>

The return type of the user callback Read more
§

type Error = E

The error type returned from +process_events() (not the user callback!).
source§

fn process_events<C>( + &mut self, + readiness: Readiness, + token: Token, + callback: C +) -> Result<PostAction, Self::Error>where + C: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,

Process any relevant events Read more
source§

fn register( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

Register yourself to this poll instance Read more
source§

fn reregister( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

Re-register your file descriptors Read more
source§

fn unregister(&mut self, poll: &mut Poll) -> Result<()>

Unregister your file descriptors Read more
source§

const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = false

Whether this source needs to be sent the EventSource::before_sleep +and EventSource::before_handle_events notifications. These are opt-in because +they require more expensive checks, and almost all sources will not need these notifications
source§

fn before_sleep(&mut self) -> Result<Option<(Readiness, Token)>>

Notification that a single poll is about to begin Read more
source§

fn before_handle_events(&mut self, events: EventIterator<'_>)

Notification that polling is complete, and EventSource::process_events will +be called with the given events for this source. The iterator may be empty, +which indicates that no events were generated for this source Read more

Auto Trait Implementations§

§

impl<F, E> RefUnwindSafe for Generic<F, E>where + E: RefUnwindSafe, + F: RefUnwindSafe,

§

impl<F, E> Send for Generic<F, E>where + E: Send, + F: Send,

§

impl<F, E> Sync for Generic<F, E>where + E: Sync, + F: Sync,

§

impl<F, E> Unpin for Generic<F, E>where + E: Unpin, + F: Unpin,

§

impl<F, E> UnwindSafe for Generic<F, E>where + E: UnwindSafe, + F: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/generic/struct.NoIoDrop.html b/api/calloop/generic/struct.NoIoDrop.html new file mode 100644 index 00000000..421a709a --- /dev/null +++ b/api/calloop/generic/struct.NoIoDrop.html @@ -0,0 +1,36 @@ +NoIoDrop in calloop::generic - Rust

Struct calloop::generic::NoIoDrop

source ·
pub struct NoIoDrop<T>(_);
Expand description

A wrapper around a type that doesn’t expose it mutably safely.

+

The EventSource trait’s Metadata type demands mutable access to the inner I/O source. +However, the inner polling source used by calloop keeps the handle-based equivalent of an +immutable pointer to the underlying object’s I/O handle. Therefore, if the inner source is +dropped, this leaves behind a dangling pointer which immediately invokes undefined behavior +on the next poll of the event loop.

+

In order to prevent this from happening, the Generic I/O source must not directly expose +a mutable reference to the underlying handle. This type wraps around the underlying handle and +easily allows users to take immutable (&) references to the type, but makes mutable (&mut) +references unsafe to get. Therefore, it prevents the source from being moved out and dropped +while it is still registered in the event loop.

+

Implementations§

source§

impl<T> NoIoDrop<T>

source

pub unsafe fn get_mut(&mut self) -> &mut T

Get a mutable reference.

+
Safety
+

The inner type’s I/O source must not be dropped.

+

Trait Implementations§

source§

impl<T: AsFd> AsFd for NoIoDrop<T>

source§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more
source§

impl<T> AsRef<T> for NoIoDrop<T>

source§

fn as_ref(&self) -> &T

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl<T> Borrow<T> for NoIoDrop<T>

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T: Debug> Debug for NoIoDrop<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> Deref for NoIoDrop<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for NoIoDrop<T>where + T: RefUnwindSafe,

§

impl<T> Send for NoIoDrop<T>where + T: Send,

§

impl<T> Sync for NoIoDrop<T>where + T: Sync,

§

impl<T> Unpin for NoIoDrop<T>where + T: Unpin,

§

impl<T> UnwindSafe for NoIoDrop<T>where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> AsSource for Twhere + T: AsFd,

§

fn source(&self) -> BorrowedFd<'_>

Returns the borrowed file descriptor.
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/index.html b/api/calloop/index.html new file mode 100644 index 00000000..99e9a4d1 --- /dev/null +++ b/api/calloop/index.html @@ -0,0 +1,128 @@ +calloop - Rust

Crate calloop

source ·
Expand description

Calloop, a Callback-based Event Loop

+

This crate provides an EventLoop type, which is a small abstraction +over a polling system. The main difference between this crate +and other traditional rust event loops is that it is based on callbacks: +you can register several event sources, each being associated with a callback +closure that will be invoked whenever the associated event source generates +events.

+

The main target use of this event loop is thus for apps that expect to spend +most of their time waiting for events and wishes to do so in a cheap and convenient +way. It is not meant for large scale high performance IO.

+

How to use it

+

Below is a quick usage example of calloop. For a more in-depth tutorial, see +the calloop book.

+

For simple uses, you can just add event sources with callbacks to the event +loop. For example, here’s a runnable program that exits after five seconds:

+ +
use calloop::{timer::{Timer, TimeoutAction}, EventLoop, LoopSignal};
+
+fn main() {
+    // Create the event loop. The loop is parameterised by the kind of shared
+    // data you want the callbacks to use. In this case, we want to be able to
+    // stop the loop when the timer fires, so we provide the loop with a
+    // LoopSignal, which has the ability to stop the loop from within events. We
+    // just annotate the type here; the actual data is provided later in the
+    // run() call.
+    let mut event_loop: EventLoop<LoopSignal> =
+        EventLoop::try_new().expect("Failed to initialize the event loop!");
+
+    // Retrieve a handle. It is used to insert new sources into the event loop
+    // It can be cloned, allowing you to insert sources from within source
+    // callbacks.
+    let handle = event_loop.handle();
+
+    // Create our event source, a timer, that will expire in 2 seconds
+    let source = Timer::from_duration(std::time::Duration::from_secs(2));
+
+    // Inserting an event source takes this general form. It can also be done
+    // from within the callback of another event source.
+    handle
+        .insert_source(
+            // a type which implements the EventSource trait
+            source,
+            // a callback that is invoked whenever this source generates an event
+            |event, _metadata, shared_data| {
+                // This callback is given 3 values:
+                // - the event generated by the source (in our case, timer events are the Instant
+                //   representing the deadline for which it has fired)
+                // - &mut access to some metadata, specific to the event source (in our case, a
+                //   timer handle)
+                // - &mut access to the global shared data that was passed to EventLoop::run or
+                //   EventLoop::dispatch (in our case, a LoopSignal object to stop the loop)
+                //
+                // The return type is just () because nothing uses it. Some
+                // sources will expect a Result of some kind instead.
+                println!("Timeout for {:?} expired!", event);
+                // notify the event loop to stop running using the signal in the shared data
+                // (see below)
+                shared_data.stop();
+                // The timer event source requires us to return a TimeoutAction to
+                // specify if the timer should be rescheduled. In our case we just drop it.
+                TimeoutAction::Drop
+            },
+        )
+        .expect("Failed to insert event source!");
+
+    // Create the shared data for our loop.
+    let mut shared_data = event_loop.get_signal();
+
+    // Actually run the event loop. This will dispatch received events to their
+    // callbacks, waiting at most 20ms for new events between each invocation of
+    // the provided callback (pass None for the timeout argument if you want to
+    // wait indefinitely between events).
+    //
+    // This is where we pass the *value* of the shared data, as a mutable
+    // reference that will be forwarded to all your callbacks, allowing them to
+    // share some state
+    event_loop
+        .run(
+            std::time::Duration::from_millis(20),
+            &mut shared_data,
+            |_shared_data| {
+                // Finally, this is where you can insert the processing you need
+                // to do do between each waiting event eg. drawing logic if
+                // you're doing a GUI app.
+            },
+        )
+        .expect("Error during event loop!");
+}
+

Event source types

+

The event loop is backed by an OS provided polling selector (epoll on Linux).

+

This crate also provide some adapters for common event sources such as:

+ +

As well as generic objects backed by file descriptors.

+

It is also possible to insert “idle” callbacks. These callbacks represent computations that +need to be done at some point, but are not as urgent as processing the events. These callbacks +are stored and then executed during EventLoop::dispatch, once all +events from the sources have been processed.

+

Async/Await compatibility

+

calloop can be used with futures, both as an executor and for monitoring Async IO.

+

Activating the executor cargo feature will add the futures module, which provides +a future executor that can be inserted into an EventLoop as yet another EventSource.

+

IO objects can be made Async-aware via the LoopHandle::adapt_io +method. Waking up the futures using these objects is handled by the associated EventLoop +directly.

+

Custom event sources

+

You can create custom event sources can will be inserted in the event loop by +implementing the EventSource trait. This can be done either directly from the file +descriptors of your source of interest, or by wrapping an other event source and further +processing its events. An EventSource can register more than one file descriptor and +aggregate them.

+

Platforms support

+

Currently, calloop is tested on Linux, FreeBSD and macOS.

+

The following platforms are also enabled at compile time but not tested: Android, NetBSD, +OpenBSD, DragonFlyBSD.

+

Those platforms should work based on the fact that they have the same polling mechanism as +tested platforms, but some subtle bugs might still occur.

+

Re-exports

Modules

  • An MPSC channel whose receiving end is an event source
  • Error types used and generated by Calloop.
  • A futures executor as an event source
  • A generic event source wrapping an IO objects or file descriptor
  • Adapters for async IO objects
  • Ping to the event loop
  • Timer event source
  • Wrapper for a transient Calloop event source.

Macros

Structs

Enums

  • Possible modes for registering a file descriptor
  • Possible actions that can be requested to the event loop by an +event source once its events have been processed.

Traits

\ No newline at end of file diff --git a/api/calloop/io/index.html b/api/calloop/io/index.html new file mode 100644 index 00000000..45332c85 --- /dev/null +++ b/api/calloop/io/index.html @@ -0,0 +1,5 @@ +calloop::io - Rust

Module calloop::io

source ·
Expand description

Adapters for async IO objects

+

This module mainly hosts the Async adapter for making IO objects async with readiness +monitoring backed by an EventLoop. See LoopHandle::adapt_io for +how to create them.

+

Structs

  • Adapter for async IO manipulations
  • A future that resolves once the associated object becomes ready for reading
  • A future that resolves once the associated object becomes ready for writing
\ No newline at end of file diff --git a/api/calloop/io/sidebar-items.js b/api/calloop/io/sidebar-items.js new file mode 100644 index 00000000..ade98208 --- /dev/null +++ b/api/calloop/io/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Async","Readable","Writable"]}; \ No newline at end of file diff --git a/api/calloop/io/struct.Async.html b/api/calloop/io/struct.Async.html new file mode 100644 index 00000000..88bc7ca0 --- /dev/null +++ b/api/calloop/io/struct.Async.html @@ -0,0 +1,26 @@ +Async in calloop::io - Rust

Struct calloop::io::Async

source ·
pub struct Async<'l, F: AsFd> { /* private fields */ }
Expand description

Adapter for async IO manipulations

+

This type wraps an IO object, providing methods to create futures waiting for its +readiness.

+

If the futures-io cargo feature is enabled, it also implements AsyncRead and/or +AsyncWrite if the underlying type implements Read and/or Write.

+

Note that this adapter and the futures procuded from it and not threadsafe.

+

Implementations§

source§

impl<'l, F: AsFd> Async<'l, F>

source

pub fn get_mut(&mut self) -> &mut F

Mutably access the underlying IO object

+
source

pub fn readable<'s>(&'s mut self) -> Readable<'s, 'l, F>

A future that resolves once the object becomes ready for reading

+
source

pub fn writable<'s>(&'s mut self) -> Writable<'s, 'l, F>

A future that resolves once the object becomes ready for writing

+
source

pub fn into_inner(self) -> F

Remove the async adapter and retrieve the underlying object

+

Trait Implementations§

source§

impl<'l, F: AsFd + Debug> Debug for Async<'l, F>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'l, F: AsFd> Drop for Async<'l, F>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<'l, F: AsFd> Unpin for Async<'l, F>

Auto Trait Implementations§

§

impl<'l, F> !RefUnwindSafe for Async<'l, F>

§

impl<'l, F> !Send for Async<'l, F>

§

impl<'l, F> !Sync for Async<'l, F>

§

impl<'l, F> !UnwindSafe for Async<'l, F>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/io/struct.Readable.html b/api/calloop/io/struct.Readable.html new file mode 100644 index 00000000..6366c951 --- /dev/null +++ b/api/calloop/io/struct.Readable.html @@ -0,0 +1,19 @@ +Readable in calloop::io - Rust

Struct calloop::io::Readable

source ·
pub struct Readable<'s, 'l, F: AsFd> { /* private fields */ }
Expand description

A future that resolves once the associated object becomes ready for reading

+

Trait Implementations§

source§

impl<'s, 'l, F: Debug + AsFd> Debug for Readable<'s, 'l, F>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'s, 'l, F: AsFd> Future for Readable<'s, 'l, F>

§

type Output = ()

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> TaskPoll<()>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more

Auto Trait Implementations§

§

impl<'s, 'l, F> !RefUnwindSafe for Readable<'s, 'l, F>

§

impl<'s, 'l, F> !Send for Readable<'s, 'l, F>

§

impl<'s, 'l, F> !Sync for Readable<'s, 'l, F>

§

impl<'s, 'l, F> Unpin for Readable<'s, 'l, F>

§

impl<'s, 'l, F> !UnwindSafe for Readable<'s, 'l, F>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for Fwhere + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/io/struct.Writable.html b/api/calloop/io/struct.Writable.html new file mode 100644 index 00000000..382eb3a9 --- /dev/null +++ b/api/calloop/io/struct.Writable.html @@ -0,0 +1,19 @@ +Writable in calloop::io - Rust

Struct calloop::io::Writable

source ·
pub struct Writable<'s, 'l, F: AsFd> { /* private fields */ }
Expand description

A future that resolves once the associated object becomes ready for writing

+

Trait Implementations§

source§

impl<'s, 'l, F: Debug + AsFd> Debug for Writable<'s, 'l, F>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'s, 'l, F: AsFd> Future for Writable<'s, 'l, F>

§

type Output = ()

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> TaskPoll<()>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more

Auto Trait Implementations§

§

impl<'s, 'l, F> !RefUnwindSafe for Writable<'s, 'l, F>

§

impl<'s, 'l, F> !Send for Writable<'s, 'l, F>

§

impl<'s, 'l, F> !Sync for Writable<'s, 'l, F>

§

impl<'s, 'l, F> Unpin for Writable<'s, 'l, F>

§

impl<'s, 'l, F> !UnwindSafe for Writable<'s, 'l, F>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for Fwhere + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/loop_logic/struct.EventIterator.html b/api/calloop/loop_logic/struct.EventIterator.html new file mode 100644 index 00000000..e59add1e --- /dev/null +++ b/api/calloop/loop_logic/struct.EventIterator.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/struct.EventIterator.html...

+ + + \ No newline at end of file diff --git a/api/calloop/loop_logic/struct.EventLoop.html b/api/calloop/loop_logic/struct.EventLoop.html new file mode 100644 index 00000000..11d4cad0 --- /dev/null +++ b/api/calloop/loop_logic/struct.EventLoop.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/struct.EventLoop.html...

+ + + \ No newline at end of file diff --git a/api/calloop/loop_logic/struct.LoopHandle.html b/api/calloop/loop_logic/struct.LoopHandle.html new file mode 100644 index 00000000..f97e3669 --- /dev/null +++ b/api/calloop/loop_logic/struct.LoopHandle.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/struct.LoopHandle.html...

+ + + \ No newline at end of file diff --git a/api/calloop/loop_logic/struct.LoopSignal.html b/api/calloop/loop_logic/struct.LoopSignal.html new file mode 100644 index 00000000..df0146bb --- /dev/null +++ b/api/calloop/loop_logic/struct.LoopSignal.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/struct.LoopSignal.html...

+ + + \ No newline at end of file diff --git a/api/calloop/loop_logic/struct.RegistrationToken.html b/api/calloop/loop_logic/struct.RegistrationToken.html new file mode 100644 index 00000000..f649cb7e --- /dev/null +++ b/api/calloop/loop_logic/struct.RegistrationToken.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/struct.RegistrationToken.html...

+ + + \ No newline at end of file diff --git a/api/calloop/macro.batch_register!.html b/api/calloop/macro.batch_register!.html new file mode 100644 index 00000000..c8a28b39 --- /dev/null +++ b/api/calloop/macro.batch_register!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.batch_register.html...

+ + + \ No newline at end of file diff --git a/api/calloop/macro.batch_register.html b/api/calloop/macro.batch_register.html new file mode 100644 index 00000000..f943fd59 --- /dev/null +++ b/api/calloop/macro.batch_register.html @@ -0,0 +1,18 @@ +batch_register in calloop - Rust
macro_rules! batch_register {
+    ($poll:ident, $token_fac:ident, $( $source:expr ),* $(,)?) => { ... };
+}
Expand description

Register a set of event sources. Effectively calls +EventSource::register() for all the sources provided.

+

Usage:

+
calloop::batch_register!(
+    poll, token_factory,
+    self.source_one,
+    self.source_two,
+    self.source_three,
+    self.source_four,
+)
+
+

Note that there is no scope for customisation; if you need to do special +things with a particular source, you’ll need to leave it off the list. Also +note that this only does try-or-early-return error handling in the order +that you list the sources; if you need anything else, don’t use this macro.

+
\ No newline at end of file diff --git a/api/calloop/macro.batch_reregister!.html b/api/calloop/macro.batch_reregister!.html new file mode 100644 index 00000000..ae279778 --- /dev/null +++ b/api/calloop/macro.batch_reregister!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.batch_reregister.html...

+ + + \ No newline at end of file diff --git a/api/calloop/macro.batch_reregister.html b/api/calloop/macro.batch_reregister.html new file mode 100644 index 00000000..0e38bfa7 --- /dev/null +++ b/api/calloop/macro.batch_reregister.html @@ -0,0 +1,18 @@ +batch_reregister in calloop - Rust
macro_rules! batch_reregister {
+    ($poll:ident, $token_fac:ident, $( $source:expr ),* $(,)?) => { ... };
+}
Expand description

Reregister a set of event sources. Effectively calls +EventSource::reregister() for all the sources provided.

+

Usage:

+
calloop::batch_reregister!(
+    poll, token_factory,
+    self.source_one,
+    self.source_two,
+    self.source_three,
+    self.source_four,
+)
+
+

Note that there is no scope for customisation; if you need to do special +things with a particular source, you’ll need to leave it off the list. Also +note that this only does try-or-early-return error handling in the order +that you list the sources; if you need anything else, don’t use this macro.

+
\ No newline at end of file diff --git a/api/calloop/macro.batch_unregister!.html b/api/calloop/macro.batch_unregister!.html new file mode 100644 index 00000000..765f7c58 --- /dev/null +++ b/api/calloop/macro.batch_unregister!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.batch_unregister.html...

+ + + \ No newline at end of file diff --git a/api/calloop/macro.batch_unregister.html b/api/calloop/macro.batch_unregister.html new file mode 100644 index 00000000..f14f8580 --- /dev/null +++ b/api/calloop/macro.batch_unregister.html @@ -0,0 +1,18 @@ +batch_unregister in calloop - Rust
macro_rules! batch_unregister {
+    ($poll:ident, $( $source:expr ),* $(,)?) => { ... };
+}
Expand description

Unregister a set of event sources. Effectively calls +EventSource::unregister() for all the sources provided.

+

Usage:

+
calloop::batch_unregister!(
+    poll,
+    self.source_one,
+    self.source_two,
+    self.source_three,
+    self.source_four,
+)
+
+

Note that there is no scope for customisation; if you need to do special +things with a particular source, you’ll need to leave it off the list. Also +note that this only does try-or-early-return error handling in the order +that you list the sources; if you need anything else, don’t use this macro.

+
\ No newline at end of file diff --git a/api/calloop/ping/fn.make_ping.html b/api/calloop/ping/fn.make_ping.html new file mode 100644 index 00000000..7aa84382 --- /dev/null +++ b/api/calloop/ping/fn.make_ping.html @@ -0,0 +1,5 @@ +make_ping in calloop::ping - Rust

Function calloop::ping::make_ping

source ·
pub fn make_ping() -> Result<(Ping, PingSource)>
Expand description

Create a new ping event source

+

you are given a Ping instance, which can be cloned and used to ping the +event loop, and a PingSource, which you can insert in your event loop to +receive the pings.

+
\ No newline at end of file diff --git a/api/calloop/ping/index.html b/api/calloop/ping/index.html new file mode 100644 index 00000000..7e5ae00a --- /dev/null +++ b/api/calloop/ping/index.html @@ -0,0 +1,9 @@ +calloop::ping - Rust

Module calloop::ping

source ·
Expand description

Ping to the event loop

+

This is an event source that just produces () events whevener the associated +Ping::ping method is called. If the event source is pinged multiple times +between a single dispatching, it’ll only generate one event.

+

This event source is a simple way of waking up the event loop from an other part of your program +(and is what backs the LoopSignal). It can also be used as a building +block to construct event sources whose source of event is not file descriptor, but rather an +userspace source (like an other thread).

+

Structs

  • An error arising from processing events for a ping.

Functions

Type Definitions

\ No newline at end of file diff --git a/api/calloop/ping/sidebar-items.js b/api/calloop/ping/sidebar-items.js new file mode 100644 index 00000000..b1c14c45 --- /dev/null +++ b/api/calloop/ping/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["make_ping"],"struct":["PingError"],"type":["Ping","PingSource"]}; \ No newline at end of file diff --git a/api/calloop/ping/struct.PingError.html b/api/calloop/ping/struct.PingError.html new file mode 100644 index 00000000..853eefd6 --- /dev/null +++ b/api/calloop/ping/struct.PingError.html @@ -0,0 +1,18 @@ +PingError in calloop::ping - Rust

Struct calloop::ping::PingError

source ·
pub struct PingError(_);
Expand description

An error arising from processing events for a ping.

+

Trait Implementations§

source§

impl Debug for PingError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for PingError

source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for PingError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/ping/type.Ping.html b/api/calloop/ping/type.Ping.html new file mode 100644 index 00000000..694f9a97 --- /dev/null +++ b/api/calloop/ping/type.Ping.html @@ -0,0 +1,5 @@ +Ping in calloop::ping - Rust

Type Definition calloop::ping::Ping

source ·
pub type Ping = Ping;
Expand description

The ping event source

+

You can insert it in your event loop to receive pings.

+

If you use it directly, it will automatically remove itself from the event loop +once all Ping instances are dropped.

+
\ No newline at end of file diff --git a/api/calloop/ping/type.PingSource.html b/api/calloop/ping/type.PingSource.html new file mode 100644 index 00000000..7c13ad6e --- /dev/null +++ b/api/calloop/ping/type.PingSource.html @@ -0,0 +1,4 @@ +PingSource in calloop::ping - Rust

Type Definition calloop::ping::PingSource

source ·
pub type PingSource = PingSource;
Expand description

The Ping handle

+

This handle can be cloned and sent accross threads. It can be used to +send pings to the PingSource.

+
\ No newline at end of file diff --git a/api/calloop/sidebar-items.js b/api/calloop/sidebar-items.js new file mode 100644 index 00000000..6add54d3 --- /dev/null +++ b/api/calloop/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Mode","PostAction"],"macro":["batch_register","batch_reregister","batch_unregister"],"mod":["channel","error","futures","generic","io","ping","timer","transient"],"struct":["Dispatcher","EventIterator","EventLoop","Idle","Interest","LoopHandle","LoopSignal","Poll","Readiness","RegistrationToken","Token","TokenFactory"],"trait":["EventSource"]}; \ No newline at end of file diff --git a/api/calloop/sources/channel/enum.Event.html b/api/calloop/sources/channel/enum.Event.html new file mode 100644 index 00000000..71b89e12 --- /dev/null +++ b/api/calloop/sources/channel/enum.Event.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/channel/enum.Event.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/channel/fn.channel.html b/api/calloop/sources/channel/fn.channel.html new file mode 100644 index 00000000..5af86020 --- /dev/null +++ b/api/calloop/sources/channel/fn.channel.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/channel/fn.channel.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/channel/fn.sync_channel.html b/api/calloop/sources/channel/fn.sync_channel.html new file mode 100644 index 00000000..e6075d60 --- /dev/null +++ b/api/calloop/sources/channel/fn.sync_channel.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/channel/fn.sync_channel.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/channel/index.html b/api/calloop/sources/channel/index.html new file mode 100644 index 00000000..b91f82ed --- /dev/null +++ b/api/calloop/sources/channel/index.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/channel/index.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/channel/struct.Channel.html b/api/calloop/sources/channel/struct.Channel.html new file mode 100644 index 00000000..c60ce13a --- /dev/null +++ b/api/calloop/sources/channel/struct.Channel.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/channel/struct.Channel.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/channel/struct.ChannelError.html b/api/calloop/sources/channel/struct.ChannelError.html new file mode 100644 index 00000000..77cad728 --- /dev/null +++ b/api/calloop/sources/channel/struct.ChannelError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/channel/struct.ChannelError.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/channel/struct.Sender.html b/api/calloop/sources/channel/struct.Sender.html new file mode 100644 index 00000000..bb3d1df2 --- /dev/null +++ b/api/calloop/sources/channel/struct.Sender.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/channel/struct.Sender.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/channel/struct.SyncSender.html b/api/calloop/sources/channel/struct.SyncSender.html new file mode 100644 index 00000000..25eda08f --- /dev/null +++ b/api/calloop/sources/channel/struct.SyncSender.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/channel/struct.SyncSender.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/enum.PostAction.html b/api/calloop/sources/enum.PostAction.html new file mode 100644 index 00000000..95cc41df --- /dev/null +++ b/api/calloop/sources/enum.PostAction.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/enum.PostAction.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/futures/enum.ExecutorError.html b/api/calloop/sources/futures/enum.ExecutorError.html new file mode 100644 index 00000000..df8d0d1b --- /dev/null +++ b/api/calloop/sources/futures/enum.ExecutorError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/futures/enum.ExecutorError.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/futures/fn.executor.html b/api/calloop/sources/futures/fn.executor.html new file mode 100644 index 00000000..fb9ca9d2 --- /dev/null +++ b/api/calloop/sources/futures/fn.executor.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/futures/fn.executor.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/futures/index.html b/api/calloop/sources/futures/index.html new file mode 100644 index 00000000..43a4f351 --- /dev/null +++ b/api/calloop/sources/futures/index.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/futures/index.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/futures/struct.Executor.html b/api/calloop/sources/futures/struct.Executor.html new file mode 100644 index 00000000..0b003d49 --- /dev/null +++ b/api/calloop/sources/futures/struct.Executor.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/futures/struct.Executor.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/futures/struct.ExecutorDestroyed.html b/api/calloop/sources/futures/struct.ExecutorDestroyed.html new file mode 100644 index 00000000..f41f7e42 --- /dev/null +++ b/api/calloop/sources/futures/struct.ExecutorDestroyed.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/futures/struct.ExecutorDestroyed.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/futures/struct.Scheduler.html b/api/calloop/sources/futures/struct.Scheduler.html new file mode 100644 index 00000000..cef7e561 --- /dev/null +++ b/api/calloop/sources/futures/struct.Scheduler.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/futures/struct.Scheduler.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/generic/index.html b/api/calloop/sources/generic/index.html new file mode 100644 index 00000000..ef1341ef --- /dev/null +++ b/api/calloop/sources/generic/index.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/generic/index.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/generic/struct.FdWrapper.html b/api/calloop/sources/generic/struct.FdWrapper.html new file mode 100644 index 00000000..f4b9d9b9 --- /dev/null +++ b/api/calloop/sources/generic/struct.FdWrapper.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/generic/struct.FdWrapper.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/generic/struct.Generic.html b/api/calloop/sources/generic/struct.Generic.html new file mode 100644 index 00000000..faf3c1e4 --- /dev/null +++ b/api/calloop/sources/generic/struct.Generic.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/generic/struct.Generic.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/generic/struct.NoIoDrop.html b/api/calloop/sources/generic/struct.NoIoDrop.html new file mode 100644 index 00000000..2f0d24aa --- /dev/null +++ b/api/calloop/sources/generic/struct.NoIoDrop.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/generic/struct.NoIoDrop.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/ping/fn.make_ping.html b/api/calloop/sources/ping/fn.make_ping.html new file mode 100644 index 00000000..d19bbd93 --- /dev/null +++ b/api/calloop/sources/ping/fn.make_ping.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/ping/fn.make_ping.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/ping/index.html b/api/calloop/sources/ping/index.html new file mode 100644 index 00000000..33281796 --- /dev/null +++ b/api/calloop/sources/ping/index.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/ping/index.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/ping/struct.PingError.html b/api/calloop/sources/ping/struct.PingError.html new file mode 100644 index 00000000..c156ce3c --- /dev/null +++ b/api/calloop/sources/ping/struct.PingError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/ping/struct.PingError.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/ping/type.Ping.html b/api/calloop/sources/ping/type.Ping.html new file mode 100644 index 00000000..6cf96c69 --- /dev/null +++ b/api/calloop/sources/ping/type.Ping.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/ping/type.Ping.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/ping/type.PingSource.html b/api/calloop/sources/ping/type.PingSource.html new file mode 100644 index 00000000..d8cbb6b2 --- /dev/null +++ b/api/calloop/sources/ping/type.PingSource.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/ping/type.PingSource.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/struct.Dispatcher.html b/api/calloop/sources/struct.Dispatcher.html new file mode 100644 index 00000000..3c2f6e0b --- /dev/null +++ b/api/calloop/sources/struct.Dispatcher.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/struct.Dispatcher.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/struct.Idle.html b/api/calloop/sources/struct.Idle.html new file mode 100644 index 00000000..8bb544ee --- /dev/null +++ b/api/calloop/sources/struct.Idle.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/struct.Idle.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/timer/enum.TimeoutAction.html b/api/calloop/sources/timer/enum.TimeoutAction.html new file mode 100644 index 00000000..41cad1fb --- /dev/null +++ b/api/calloop/sources/timer/enum.TimeoutAction.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/timer/enum.TimeoutAction.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/timer/index.html b/api/calloop/sources/timer/index.html new file mode 100644 index 00000000..1320f161 --- /dev/null +++ b/api/calloop/sources/timer/index.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/timer/index.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/timer/struct.TimeoutFuture.html b/api/calloop/sources/timer/struct.TimeoutFuture.html new file mode 100644 index 00000000..0d17fdc3 --- /dev/null +++ b/api/calloop/sources/timer/struct.TimeoutFuture.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/timer/struct.TimeoutFuture.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/timer/struct.Timer.html b/api/calloop/sources/timer/struct.Timer.html new file mode 100644 index 00000000..8d54a5c9 --- /dev/null +++ b/api/calloop/sources/timer/struct.Timer.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/timer/struct.Timer.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/trait.EventSource.html b/api/calloop/sources/trait.EventSource.html new file mode 100644 index 00000000..275d2733 --- /dev/null +++ b/api/calloop/sources/trait.EventSource.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/trait.EventSource.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/transient/index.html b/api/calloop/sources/transient/index.html new file mode 100644 index 00000000..4a4c759a --- /dev/null +++ b/api/calloop/sources/transient/index.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/transient/index.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sources/transient/struct.TransientSource.html b/api/calloop/sources/transient/struct.TransientSource.html new file mode 100644 index 00000000..ead34fdf --- /dev/null +++ b/api/calloop/sources/transient/struct.TransientSource.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../calloop/transient/struct.TransientSource.html...

+ + + \ No newline at end of file diff --git a/api/calloop/struct.Dispatcher.html b/api/calloop/struct.Dispatcher.html new file mode 100644 index 00000000..b1973443 --- /dev/null +++ b/api/calloop/struct.Dispatcher.html @@ -0,0 +1,38 @@ +Dispatcher in calloop - Rust

Struct calloop::Dispatcher

source ·
pub struct Dispatcher<'a, S, Data>(_);
Expand description

An event source with its callback.

+

The Dispatcher can be registered in an event loop. +Use the as_source_{ref,mut} functions to interact with the event source. +Use into_source_inner to get the event source back.

+

Implementations§

source§

impl<'a, S, Data> Dispatcher<'a, S, Data>where + S: EventSource + 'a,

source

pub fn new<F>(source: S, callback: F) -> Selfwhere + F: FnMut(S::Event, &mut S::Metadata, &mut Data) -> S::Ret + 'a,

Builds a dispatcher.

+

The resulting Dispatcher

+
source

pub fn as_source_ref(&self) -> Ref<'_, S>

Returns an immutable reference to the event source.

+
Panics
+

Has the same semantics as RefCell::borrow().

+

The dispatcher being mutably borrowed while its events are dispatched, +this method will panic if invoked from within the associated dispatching closure.

+
source

pub fn as_source_mut(&self) -> RefMut<'_, S>

Returns a mutable reference to the event source.

+
Panics
+

Has the same semantics as RefCell::borrow_mut().

+

The dispatcher being mutably borrowed while its events are dispatched, +this method will panic if invoked from within the associated dispatching closure.

+
source

pub fn into_source_inner(self) -> S

Consumes the Dispatcher and returns the inner event source.

+
Panics
+

Panics if the Dispatcher is still registered.

+

Trait Implementations§

source§

impl<'a, S, Data> Clone for Dispatcher<'a, S, Data>

source§

fn clone(&self) -> Dispatcher<'a, S, Data>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a, S, Data> Debug for Dispatcher<'a, S, Data>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a, S, Data> !RefUnwindSafe for Dispatcher<'a, S, Data>

§

impl<'a, S, Data> !Send for Dispatcher<'a, S, Data>

§

impl<'a, S, Data> !Sync for Dispatcher<'a, S, Data>

§

impl<'a, S, Data> Unpin for Dispatcher<'a, S, Data>

§

impl<'a, S, Data> !UnwindSafe for Dispatcher<'a, S, Data>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/struct.EventIterator.html b/api/calloop/struct.EventIterator.html new file mode 100644 index 00000000..c2452bef --- /dev/null +++ b/api/calloop/struct.EventIterator.html @@ -0,0 +1,204 @@ +EventIterator in calloop - Rust

Struct calloop::EventIterator

source ·
pub struct EventIterator<'a> { /* private fields */ }
Expand description

The EventIterator is an Iterator over the events relevant to a particular source +This type is used in the EventSource::before_handle_events methods for +two main reasons:

+
    +
  • To avoid dynamic dispatch overhead
  • +
  • Secondly, it is to allow this type to be Clone, which is not +possible with dynamic dispatch
  • +
+

Trait Implementations§

source§

impl<'a> Clone for EventIterator<'a>

source§

fn clone(&self) -> EventIterator<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for EventIterator<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> Iterator for EventIterator<'a>

§

type Item = (Readiness, Token)

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<Self::Item>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usizewhere + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Selfwhere + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> Bwhere + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut Ewhere + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> boolwhere + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> Rwhere + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> Rwhere + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> Bwhere + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryTypewhere + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryTypewhere + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
1.0.0 · source§

fn cycle(self) -> Cycle<Self>where + Self: Sized + Clone,

Repeats an iterator endlessly. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> Swhere + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> Pwhere + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Orderingwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> boolwhere + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> boolwhere + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> boolwhere + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> boolwhere + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for EventIterator<'a>

§

impl<'a> Send for EventIterator<'a>

§

impl<'a> Sync for EventIterator<'a>

§

impl<'a> Unpin for EventIterator<'a>

§

impl<'a> UnwindSafe for EventIterator<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for Iwhere + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/struct.EventLoop.html b/api/calloop/struct.EventLoop.html new file mode 100644 index 00000000..26ad2f35 --- /dev/null +++ b/api/calloop/struct.EventLoop.html @@ -0,0 +1,55 @@ +EventLoop in calloop - Rust

Struct calloop::EventLoop

source ·
pub struct EventLoop<'l, Data> { /* private fields */ }
Expand description

An event loop

+

This loop can host several event sources, that can be dynamically added or removed.

+

Implementations§

source§

impl<'l, Data> EventLoop<'l, Data>

source

pub fn try_new() -> Result<Self>

Create a new event loop

+

Fails if the initialization of the polling system failed.

+
source

pub fn handle(&self) -> LoopHandle<'l, Data>

Retrieve a loop handle

+
source

pub fn dispatch<D: Into<Option<Duration>>>( + &mut self, + timeout: D, + data: &mut Data +) -> Result<()>

Dispatch pending events to their callbacks

+

If some sources have events available, their callbacks will be immediatly called. +Otherwise this will wait until an event is receive or the provided timeout +is reached. If timeout is None, it will wait without a duration limit.

+

Once pending events have been processed or the timeout is reached, all pending +idle callbacks will be fired before this method returns.

+
source

pub fn get_signal(&self) -> LoopSignal

Get a signal to stop this event loop from running

+

To be used in conjunction with the run() method.

+
source

pub fn run<F, D: Into<Option<Duration>>>( + &mut self, + timeout: D, + data: &mut Data, + cb: F +) -> Result<()>where + F: FnMut(&mut Data),

Run this event loop

+

This will repeatedly try to dispatch events (see the dispatch() method) on +this event loop, waiting at most timeout every time.

+

Between each dispatch wait, your provided callback will be called.

+

You can use the get_signal() method to retrieve a way to stop or wakeup +the event loop from anywhere.

+
source

pub fn block_on<R>( + &mut self, + future: impl Future<Output = R>, + data: &mut Data, + cb: impl FnMut(&mut Data) +) -> Result<Option<R>>

Block a future on this event loop.

+

This will run the provided future on this event loop, blocking until it is +resolved.

+

If LoopSignal::stop() is called before the future is resolved, this function returns +None.

+

Trait Implementations§

source§

impl<'l, Data> Debug for EventLoop<'l, Data>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'l, Data> !RefUnwindSafe for EventLoop<'l, Data>

§

impl<'l, Data> !Send for EventLoop<'l, Data>

§

impl<'l, Data> !Sync for EventLoop<'l, Data>

§

impl<'l, Data> Unpin for EventLoop<'l, Data>

§

impl<'l, Data> !UnwindSafe for EventLoop<'l, Data>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/struct.Idle.html b/api/calloop/struct.Idle.html new file mode 100644 index 00000000..aafc881e --- /dev/null +++ b/api/calloop/struct.Idle.html @@ -0,0 +1,20 @@ +Idle in calloop - Rust

Struct calloop::Idle

source ·
pub struct Idle<'i> { /* private fields */ }
Expand description

An idle callback that was inserted in this loop

+

This handle allows you to cancel the callback. Dropping +it will not cancel it.

+

Implementations§

source§

impl<'i> Idle<'i>

source

pub fn cancel(self)

Cancel the idle callback if it was not already run

+

Trait Implementations§

source§

impl<'i> Debug for Idle<'i>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'i> !RefUnwindSafe for Idle<'i>

§

impl<'i> !Send for Idle<'i>

§

impl<'i> !Sync for Idle<'i>

§

impl<'i> Unpin for Idle<'i>

§

impl<'i> !UnwindSafe for Idle<'i>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/struct.Interest.html b/api/calloop/struct.Interest.html new file mode 100644 index 00000000..53c0bff7 --- /dev/null +++ b/api/calloop/struct.Interest.html @@ -0,0 +1,27 @@ +Interest in calloop - Rust

Struct calloop::Interest

source ·
pub struct Interest {
+    pub readable: bool,
+    pub writable: bool,
+}
Expand description

Interest to register regarding the file descriptor

+

Fields§

§readable: bool

Wait for the FD to be readable

+
§writable: bool

Wait for the FD to be writable

+

Implementations§

source§

impl Interest

source

pub const EMPTY: Interest = _

Shorthand for empty interest

+
source

pub const READ: Interest = _

Shorthand for read interest

+
source

pub const WRITE: Interest = _

Shorthand for write interest

+
source

pub const BOTH: Interest = _

Shorthand for read and write interest

+

Trait Implementations§

source§

impl Clone for Interest

source§

fn clone(&self) -> Interest

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Interest

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Interest

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/struct.LoopHandle.html b/api/calloop/struct.LoopHandle.html new file mode 100644 index 00000000..aba1285d --- /dev/null +++ b/api/calloop/struct.LoopHandle.html @@ -0,0 +1,59 @@ +LoopHandle in calloop - Rust

Struct calloop::LoopHandle

source ·
pub struct LoopHandle<'l, Data> { /* private fields */ }
Expand description

An handle to an event loop

+

This handle allows you to insert new sources and idles in this event loop, +it can be cloned, and it is possible to insert new sources from within a source +callback.

+

Implementations§

source§

impl<'l, Data> LoopHandle<'l, Data>

source

pub fn insert_source<S, F>( + &self, + source: S, + callback: F +) -> Result<RegistrationToken, InsertError<S>>where + S: EventSource + 'l, + F: FnMut(S::Event, &mut S::Metadata, &mut Data) -> S::Ret + 'l,

Inserts a new event source in the loop.

+

The provided callback will be called during the dispatching cycles whenever the +associated source generates events, see EventLoop::dispatch(..) for details.

+

This function takes ownership of the event source. Use register_dispatcher +if you need access to the event source after this call.

+
source

pub fn register_dispatcher<S>( + &self, + dispatcher: Dispatcher<'l, S, Data> +) -> Result<RegistrationToken>where + S: EventSource + 'l,

Registers a Dispatcher in the loop.

+

Use this function if you need access to the event source after its insertion in the loop.

+

See also insert_source.

+
source

pub fn insert_idle<'i, F: FnOnce(&mut Data) + 'l + 'i>( + &self, + callback: F +) -> Idle<'i>

Inserts an idle callback.

+

This callback will be called during a dispatching cycle when the event loop has +finished processing all pending events from the sources and becomes idle.

+
source

pub fn enable(&self, token: &RegistrationToken) -> Result<()>

Enables this previously disabled event source.

+

This previously disabled source will start generating events again.

+

Note: this cannot be done from within the source callback.

+
source

pub fn update(&self, token: &RegistrationToken) -> Result<()>

Makes this source update its registration.

+

If after accessing the source you changed its parameters in a way that requires +updating its registration.

+
source

pub fn disable(&self, token: &RegistrationToken) -> Result<()>

Disables this event source.

+

The source remains in the event loop, but it’ll no longer generate events

+
source

pub fn remove(&self, token: RegistrationToken)

Removes this source from the event loop.

+
source

pub fn adapt_io<F: AsFd>(&self, fd: F) -> Result<Async<'l, F>>

Wrap an IO object into an async adapter

+

This adapter turns the IO object into an async-aware one that can be used in futures. +The readiness of these futures will be driven by the event loop.

+

The produced futures can be polled in any executor, and notably the one provided by +calloop.

+

Trait Implementations§

source§

impl<'l, Data> Clone for LoopHandle<'l, Data>

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'l, Data> Debug for LoopHandle<'l, Data>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'l, Data> !RefUnwindSafe for LoopHandle<'l, Data>

§

impl<'l, Data> !Send for LoopHandle<'l, Data>

§

impl<'l, Data> !Sync for LoopHandle<'l, Data>

§

impl<'l, Data> Unpin for LoopHandle<'l, Data>

§

impl<'l, Data> !UnwindSafe for LoopHandle<'l, Data>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/struct.LoopSignal.html b/api/calloop/struct.LoopSignal.html new file mode 100644 index 00000000..814f6b13 --- /dev/null +++ b/api/calloop/struct.LoopSignal.html @@ -0,0 +1,28 @@ +LoopSignal in calloop - Rust

Struct calloop::LoopSignal

source ·
pub struct LoopSignal { /* private fields */ }
Expand description

A signal that can be shared between thread to stop or wakeup a running +event loop

+

Implementations§

source§

impl LoopSignal

source

pub fn stop(&self)

Stop the event loop

+

Once this method is called, the next time the event loop has finished +waiting for events, it will return rather than starting to wait again.

+

This is only useful if you are using the EventLoop::run() method.

+
source

pub fn wakeup(&self)

Wake up the event loop

+

This sends a dummy event to the event loop to simulate the reception +of an event, making the wait return early. Called after stop(), this +ensures the event loop will terminate quickly if you specified a long +timeout (or no timeout at all) to the dispatch or run method.

+

Trait Implementations§

source§

impl Clone for LoopSignal

source§

fn clone(&self) -> LoopSignal

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for LoopSignal

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/struct.Poll.html b/api/calloop/struct.Poll.html new file mode 100644 index 00000000..3b6ba1af --- /dev/null +++ b/api/calloop/struct.Poll.html @@ -0,0 +1,54 @@ +Poll in calloop - Rust

Struct calloop::Poll

source ·
pub struct Poll { /* private fields */ }
Expand description

The polling system

+

This type represents the polling system of calloop, on which you +can register your file descriptors. This interface is only accessible in +implementations of the EventSource trait.

+

You only need to interact with this type if you are implementing your +own event sources, while implementing the EventSource trait. +And even in this case, you can often just use the Generic event +source and delegate the implementations to it.

+

Implementations§

source§

impl Poll

source

pub unsafe fn register( + &self, + fd: impl AsFd, + interest: Interest, + mode: Mode, + token: Token +) -> Result<()>

Register a new file descriptor for polling

+

The file descriptor will be registered with given interest, +mode and token. This function will fail if given a +bad file descriptor or if the provided file descriptor is already +registered.

+
Safety
+

The registered source must not be dropped before it is unregistered.

+
Leaking tokens
+

If your event source is dropped without being unregistered, the token +passed in here will remain on the heap and continue to be used by the +polling system even though no event source will match it.

+
source

pub fn reregister( + &self, + fd: impl AsFd, + interest: Interest, + mode: Mode, + token: Token +) -> Result<()>

Update the registration for a file descriptor

+

This allows you to change the interest, mode or token of a file +descriptor. Fails if the provided fd is not currently registered.

+

See note on register() regarding leaking.

+
source

pub fn unregister(&self, fd: impl AsFd) -> Result<()>

Unregister a file descriptor

+

This file descriptor will no longer generate events. Fails if the +provided file descriptor is not currently registered.

+

Trait Implementations§

source§

impl Debug for Poll

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Poll

§

impl !Send for Poll

§

impl !Sync for Poll

§

impl Unpin for Poll

§

impl !UnwindSafe for Poll

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/struct.Readiness.html b/api/calloop/struct.Readiness.html new file mode 100644 index 00000000..064f3818 --- /dev/null +++ b/api/calloop/struct.Readiness.html @@ -0,0 +1,26 @@ +Readiness in calloop - Rust

Struct calloop::Readiness

source ·
pub struct Readiness {
+    pub readable: bool,
+    pub writable: bool,
+    pub error: bool,
+}
Expand description

Readiness for a file descriptor notification

+

Fields§

§readable: bool

Is the FD readable

+
§writable: bool

Is the FD writable

+
§error: bool

Is the FD in an error state

+

Implementations§

source§

impl Readiness

source

pub const EMPTY: Readiness = _

Shorthand for empty readiness

+

Trait Implementations§

source§

impl Clone for Readiness

source§

fn clone(&self) -> Readiness

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Readiness

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for Readiness

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/struct.RegistrationToken.html b/api/calloop/struct.RegistrationToken.html new file mode 100644 index 00000000..0a89e951 --- /dev/null +++ b/api/calloop/struct.RegistrationToken.html @@ -0,0 +1,24 @@ +RegistrationToken in calloop - Rust
pub struct RegistrationToken { /* private fields */ }
Expand description

A token representing a registration in the EventLoop.

+

This token is given to you by the EventLoop when an EventSource is inserted or +a Dispatcher is registered. You can use it to disable, +enable, update`, +remove or kill it.

+

Trait Implementations§

source§

impl Clone for RegistrationToken

source§

fn clone(&self) -> RegistrationToken

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for RegistrationToken

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq<RegistrationToken> for RegistrationToken

source§

fn eq(&self, other: &RegistrationToken) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for RegistrationToken

source§

impl Eq for RegistrationToken

source§

impl StructuralEq for RegistrationToken

source§

impl StructuralPartialEq for RegistrationToken

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/struct.Token.html b/api/calloop/struct.Token.html new file mode 100644 index 00000000..3de93104 --- /dev/null +++ b/api/calloop/struct.Token.html @@ -0,0 +1,24 @@ +Token in calloop - Rust

Struct calloop::Token

source ·
pub struct Token { /* private fields */ }
Expand description

A token (for implementation of the EventSource trait)

+

This token is produced by the TokenFactory and is used when calling the +EventSource implementations to process event, in order +to identify which sub-source produced them.

+

You should forward it to the Poll when registering your file descriptors.

+

Trait Implementations§

source§

impl Clone for Token

source§

fn clone(&self) -> Token

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Token

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq<Token> for Token

source§

fn eq(&self, other: &Token) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for Token

source§

impl Eq for Token

source§

impl StructuralEq for Token

source§

impl StructuralPartialEq for Token

Auto Trait Implementations§

§

impl RefUnwindSafe for Token

§

impl Send for Token

§

impl Sync for Token

§

impl Unpin for Token

§

impl UnwindSafe for Token

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/struct.TokenFactory.html b/api/calloop/struct.TokenFactory.html new file mode 100644 index 00000000..8cf08d7b --- /dev/null +++ b/api/calloop/struct.TokenFactory.html @@ -0,0 +1,21 @@ +TokenFactory in calloop - Rust

Struct calloop::TokenFactory

source ·
pub struct TokenFactory { /* private fields */ }
Expand description

Factory for creating tokens in your registrations

+

When composing event sources, each sub-source needs to +have its own token to identify itself. This factory is +provided to produce such unique tokens.

+

Implementations§

source§

impl TokenFactory

source

pub fn token(&mut self) -> Token

Produce a new unique token

+

Trait Implementations§

source§

impl Debug for TokenFactory

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/sys/enum.Mode.html b/api/calloop/sys/enum.Mode.html new file mode 100644 index 00000000..06c34cac --- /dev/null +++ b/api/calloop/sys/enum.Mode.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/enum.Mode.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sys/struct.Interest.html b/api/calloop/sys/struct.Interest.html new file mode 100644 index 00000000..f7a4b979 --- /dev/null +++ b/api/calloop/sys/struct.Interest.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/struct.Interest.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sys/struct.Poll.html b/api/calloop/sys/struct.Poll.html new file mode 100644 index 00000000..7af67df7 --- /dev/null +++ b/api/calloop/sys/struct.Poll.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/struct.Poll.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sys/struct.Readiness.html b/api/calloop/sys/struct.Readiness.html new file mode 100644 index 00000000..b71dde50 --- /dev/null +++ b/api/calloop/sys/struct.Readiness.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/struct.Readiness.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sys/struct.Token.html b/api/calloop/sys/struct.Token.html new file mode 100644 index 00000000..3ef87225 --- /dev/null +++ b/api/calloop/sys/struct.Token.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/struct.Token.html...

+ + + \ No newline at end of file diff --git a/api/calloop/sys/struct.TokenFactory.html b/api/calloop/sys/struct.TokenFactory.html new file mode 100644 index 00000000..8b4477e8 --- /dev/null +++ b/api/calloop/sys/struct.TokenFactory.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../calloop/struct.TokenFactory.html...

+ + + \ No newline at end of file diff --git a/api/calloop/timer/enum.TimeoutAction.html b/api/calloop/timer/enum.TimeoutAction.html new file mode 100644 index 00000000..8c4098c3 --- /dev/null +++ b/api/calloop/timer/enum.TimeoutAction.html @@ -0,0 +1,24 @@ +TimeoutAction in calloop::timer - Rust
pub enum TimeoutAction {
+    Drop,
+    ToInstant(Instant),
+    ToDuration(Duration),
+}
Expand description

Action to reschedule a timeout if necessary

+

Variants§

§

Drop

Don’t reschedule this timer

+
§

ToInstant(Instant)

Reschedule this timer to a given Instant

+
§

ToDuration(Duration)

Reschedule this timer to a given Duration in the future

+

Trait Implementations§

source§

impl Debug for TimeoutAction

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/timer/index.html b/api/calloop/timer/index.html new file mode 100644 index 00000000..fdcff770 --- /dev/null +++ b/api/calloop/timer/index.html @@ -0,0 +1,15 @@ +calloop::timer - Rust

Module calloop::timer

source ·
Expand description

Timer event source

+

The Timer is an event source that will fire its event after a certain amount of time +specified at creation. Its timing is tracked directly by the event loop core logic, and it does +not consume any system resource.

+

As of calloop v0.11.0, the event loop always uses high-precision timers. However, the timer +precision varies between operating systems; for instance, the scheduler granularity on Windows +is about 16 milliseconds. If you need to rely on good precision timers in general, you may need +to enable realtime features of your OS to ensure your thread is quickly woken up by the system +scheduler.

+

The provided event is an Instant representing the deadline for which this timer has fired +(which can be earlier than the current time depending on the event loop congestion).

+

The callback associated with this event source is expected to return a TimeoutAction, which +can be used to implement self-repeating timers by telling calloop to reprogram the same timer +for a later timeout after it has fired.

+

Structs

  • A future that resolves once a certain timeout is expired
  • A timer event source

Enums

\ No newline at end of file diff --git a/api/calloop/timer/sidebar-items.js b/api/calloop/timer/sidebar-items.js new file mode 100644 index 00000000..9c99595d --- /dev/null +++ b/api/calloop/timer/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["TimeoutAction"],"struct":["TimeoutFuture","Timer"]}; \ No newline at end of file diff --git a/api/calloop/timer/struct.TimeoutFuture.html b/api/calloop/timer/struct.TimeoutFuture.html new file mode 100644 index 00000000..7cc53d39 --- /dev/null +++ b/api/calloop/timer/struct.TimeoutFuture.html @@ -0,0 +1,27 @@ +TimeoutFuture in calloop::timer - Rust
pub struct TimeoutFuture { /* private fields */ }
Expand description

A future that resolves once a certain timeout is expired

+

Implementations§

source§

impl TimeoutFuture

source

pub fn from_duration<Data>( + handle: &LoopHandle<'_, Data>, + duration: Duration +) -> TimeoutFuture

Create a future that resolves after a given duration

+
source

pub fn from_deadline<Data>( + handle: &LoopHandle<'_, Data>, + deadline: Instant +) -> TimeoutFuture

Create a future that resolves at a given instant

+

Trait Implementations§

source§

impl Debug for TimeoutFuture

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Future for TimeoutFuture

§

type Output = ()

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for Fwhere + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/timer/struct.Timer.html b/api/calloop/timer/struct.Timer.html new file mode 100644 index 00000000..c7b24559 --- /dev/null +++ b/api/calloop/timer/struct.Timer.html @@ -0,0 +1,50 @@ +Timer in calloop::timer - Rust

Struct calloop::timer::Timer

source ·
pub struct Timer { /* private fields */ }
Expand description

A timer event source

+

When registered to the event loop, it will trigger an event once its deadline is reached. +If the deadline is in the past relative to the moment of its insertion in the event loop, +the TImer will trigger an event as soon as the event loop is dispatched.

+

Implementations§

source§

impl Timer

source

pub fn immediate() -> Timer

Create a timer that will fire immediately when inserted in the event loop

+
source

pub fn from_duration(duration: Duration) -> Timer

Create a timer that will fire after a given duration from now

+
source

pub fn from_deadline(deadline: Instant) -> Timer

Create a timer that will fire at a given instant

+
source

pub fn set_deadline(&mut self, deadline: Instant)

Changes the deadline of this timer to an Instant

+

If the Timer is currently registered in the event loop, it needs to be +re-registered for this change to take effect.

+
source

pub fn set_duration(&mut self, duration: Duration)

Changes the deadline of this timer to a Duration from now

+

If the Timer is currently registered in the event loop, it needs to be +re-registered for this change to take effect.

+
source

pub fn current_deadline(&self) -> Option<Instant>

Get the current deadline of this Timer

+

Returns None if the timer has overflowed.

+

Trait Implementations§

source§

impl Debug for Timer

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl EventSource for Timer

§

type Event = Instant

The type of events generated by your source.
§

type Metadata = ()

Some metadata of your event source Read more
§

type Ret = TimeoutAction

The return type of the user callback Read more
§

type Error = Error

The error type returned from +process_events() (not the user callback!).
source§

fn process_events<F>( + &mut self, + _: Readiness, + token: Token, + callback: F +) -> Result<PostAction, Self::Error>where + F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,

Process any relevant events Read more
source§

fn register( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

Register yourself to this poll instance Read more
source§

fn reregister( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

Re-register your file descriptors Read more
source§

fn unregister(&mut self, poll: &mut Poll) -> Result<()>

Unregister your file descriptors Read more
source§

const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = false

Whether this source needs to be sent the EventSource::before_sleep +and EventSource::before_handle_events notifications. These are opt-in because +they require more expensive checks, and almost all sources will not need these notifications
source§

fn before_sleep(&mut self) -> Result<Option<(Readiness, Token)>>

Notification that a single poll is about to begin Read more
source§

fn before_handle_events(&mut self, events: EventIterator<'_>)

Notification that polling is complete, and EventSource::process_events will +be called with the given events for this source. The iterator may be empty, +which indicates that no events were generated for this source Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Timer

§

impl !Send for Timer

§

impl !Sync for Timer

§

impl Unpin for Timer

§

impl !UnwindSafe for Timer

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/calloop/trait.EventSource.html b/api/calloop/trait.EventSource.html new file mode 100644 index 00000000..20081bd7 --- /dev/null +++ b/api/calloop/trait.EventSource.html @@ -0,0 +1,151 @@ +EventSource in calloop - Rust

Trait calloop::EventSource

source ·
pub trait EventSource {
+    type Event;
+    type Metadata;
+    type Ret;
+    type Error: Into<Box<dyn Error + Sync + Send>>;
+
+    const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = false;
+
+    // Required methods
+    fn process_events<F>(
+        &mut self,
+        readiness: Readiness,
+        token: Token,
+        callback: F
+    ) -> Result<PostAction, Self::Error>
+       where F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret;
+    fn register(
+        &mut self,
+        poll: &mut Poll,
+        token_factory: &mut TokenFactory
+    ) -> Result<()>;
+    fn reregister(
+        &mut self,
+        poll: &mut Poll,
+        token_factory: &mut TokenFactory
+    ) -> Result<()>;
+    fn unregister(&mut self, poll: &mut Poll) -> Result<()>;
+
+    // Provided methods
+    fn before_sleep(&mut self) -> Result<Option<(Readiness, Token)>> { ... }
+    fn before_handle_events(&mut self, events: EventIterator<'_>) { ... }
+}
Expand description

Trait representing an event source

+

This is the trait you need to implement if you wish to create your own +calloop-compatible event sources.

+

The 3 associated types define the type of closure the user will need to +provide to process events for your event source.

+

The process_events method will be called when one of the FD you registered +is ready, with the associated readiness and token.

+

The register, reregister and unregister methods are plumbing to let your +source register itself with the polling system. See their documentation for details.

+

In case your event source needs to do some special processing before or after a +polling session occurs (to prepare the underlying source for polling, and cleanup +after that), you can override NEEDS_EXTRA_LIFECYCLE_EVENTS to true. +For all sources for which that constant is true, the methods before_sleep and +before_handle_events will be called. +before_sleep is called before the polling system performs a poll operation. +before_handle_events is called before any process_events methods have been called. +This means that during process_events you can assume that all cleanup has occured on +all sources.

+

Required Associated Types§

source

type Event

The type of events generated by your source.

+
source

type Metadata

Some metadata of your event source

+

This is typically useful if your source contains some internal state that +the user may need to interact with when processing events. The user callback +will receive a &mut Metadata reference.

+

Set to () if not needed.

+
source

type Ret

The return type of the user callback

+

If the user needs to return some value back to your event source once its +processing is finshed (to indicate success or failure for example), you can +specify it using this type.

+

Set to () if not needed.

+
source

type Error: Into<Box<dyn Error + Sync + Send>>

The error type returned from +process_events() (not the user callback!).

+

Provided Associated Constants§

source

const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = false

Whether this source needs to be sent the EventSource::before_sleep +and EventSource::before_handle_events notifications. These are opt-in because +they require more expensive checks, and almost all sources will not need these notifications

+

Required Methods§

source

fn process_events<F>( + &mut self, + readiness: Readiness, + token: Token, + callback: F +) -> Result<PostAction, Self::Error>where + F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,

Process any relevant events

+

This method will be called every time one of the FD you registered becomes +ready, including the readiness details and the associated token.

+

Your event source will then do some processing of the file descriptor(s) to generate +events, and call the provided callback for each one of them.

+

You should ensure you drained the file descriptors of their events, especially if using +edge-triggered mode.

+
source

fn register( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

Register yourself to this poll instance

+

You should register all your relevant file descriptors to the provided Poll +using its Poll::register method.

+

If you need to register more than one file descriptor, you can change the +sub_id field of the Token to differentiate between them.

+
source

fn reregister( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

Re-register your file descriptors

+

Your should update the registration of all your relevant file descriptor to +the provided Poll using its Poll::reregister, +if necessary.

+
source

fn unregister(&mut self, poll: &mut Poll) -> Result<()>

Unregister your file descriptors

+

You should unregister all your file descriptors from this Poll using its +Poll::unregister method.

+

Provided Methods§

source

fn before_sleep(&mut self) -> Result<Option<(Readiness, Token)>>

Notification that a single poll is about to begin

+

Use this to perform operations which must be done before polling, +but which may conflict with other event handlers. For example, +if polling requires a lock to be taken

+

If this returns Ok(Some), this will be treated as an event arriving in polling, and +your event handler will be called with the returned Token and Readiness. +Polling will however still occur, but with a timeout of 0, so additional events +from this or other sources may also be handled in the same iterations. +The returned Token must belong to this source

+
source

fn before_handle_events(&mut self, events: EventIterator<'_>)

Notification that polling is complete, and EventSource::process_events will +be called with the given events for this source. The iterator may be empty, +which indicates that no events were generated for this source

+

Please note, the iterator excludes any synthetic events returned from +EventSource::before_sleep

+

Use this to perform a cleanup before event handlers with arbitrary +code may run. This could be used to drop a lock obtained in +EventSource::before_sleep

+

Implementations on Foreign Types§

source§

impl<T: EventSource> EventSource for Box<T>

Blanket implementation for boxed event sources. EventSource is not an +object safe trait, so this does not include trait objects.

+
§

type Event = <T as EventSource>::Event

§

type Metadata = <T as EventSource>::Metadata

§

type Ret = <T as EventSource>::Ret

§

type Error = <T as EventSource>::Error

source§

fn process_events<F>( + &mut self, + readiness: Readiness, + token: Token, + callback: F +) -> Result<PostAction, Self::Error>where + F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,

source§

fn register( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

source§

fn reregister( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

source§

fn unregister(&mut self, poll: &mut Poll) -> Result<()>

source§

const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = T::NEEDS_EXTRA_LIFECYCLE_EVENTS

source§

fn before_sleep(&mut self) -> Result<Option<(Readiness, Token)>>

source§

fn before_handle_events(&mut self, events: EventIterator<'_>)

source§

impl<T: EventSource> EventSource for &mut T

Blanket implementation for exclusive references to event sources. +EventSource is not an object safe trait, so this does not include trait +objects.

+
§

type Event = <T as EventSource>::Event

§

type Metadata = <T as EventSource>::Metadata

§

type Ret = <T as EventSource>::Ret

§

type Error = <T as EventSource>::Error

source§

fn process_events<F>( + &mut self, + readiness: Readiness, + token: Token, + callback: F +) -> Result<PostAction, Self::Error>where + F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,

source§

fn register( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

source§

fn reregister( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

source§

fn unregister(&mut self, poll: &mut Poll) -> Result<()>

source§

const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = T::NEEDS_EXTRA_LIFECYCLE_EVENTS

source§

fn before_sleep(&mut self) -> Result<Option<(Readiness, Token)>>

source§

fn before_handle_events(&mut self, events: EventIterator<'_>)

Implementors§

source§

impl EventSource for Timer

source§

impl<F, E> EventSource for Generic<F, E>where + F: AsFd, + E: Into<Box<dyn Error + Send + Sync>>,

source§

impl<T> EventSource for Channel<T>

§

type Event = Event<T>

§

type Metadata = ()

§

type Ret = ()

§

type Error = ChannelError

source§

impl<T> EventSource for Executor<T>

§

type Event = T

§

type Metadata = ()

§

type Ret = ()

§

type Error = ExecutorError

source§

impl<T: EventSource> EventSource for TransientSource<T>

§

type Event = <T as EventSource>::Event

§

type Metadata = <T as EventSource>::Metadata

§

type Ret = <T as EventSource>::Ret

§

type Error = <T as EventSource>::Error

\ No newline at end of file diff --git a/api/calloop/transient/index.html b/api/calloop/transient/index.html new file mode 100644 index 00000000..dd5de7ef --- /dev/null +++ b/api/calloop/transient/index.html @@ -0,0 +1,9 @@ +calloop::transient - Rust

Module calloop::transient

source ·
Expand description

Wrapper for a transient Calloop event source.

+

If you have high level event source that you expect to remain in the event +loop indefinitely, and another event source nested inside that one that you +expect to require removal or disabling from time to time, this module can +handle it for you.

+

Structs

  • A TransientSource wraps a Calloop event source and manages its +registration. A user of this type only needs to perform the usual Calloop +calls (process_events() and *register()) and the return value of +process_events().
\ No newline at end of file diff --git a/api/calloop/transient/sidebar-items.js b/api/calloop/transient/sidebar-items.js new file mode 100644 index 00000000..e9940e0b --- /dev/null +++ b/api/calloop/transient/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["TransientSource"]}; \ No newline at end of file diff --git a/api/calloop/transient/struct.TransientSource.html b/api/calloop/transient/struct.TransientSource.html new file mode 100644 index 00000000..9fa563f6 --- /dev/null +++ b/api/calloop/transient/struct.TransientSource.html @@ -0,0 +1,156 @@ +TransientSource in calloop::transient - Rust
pub struct TransientSource<T> { /* private fields */ }
Expand description

A TransientSource wraps a Calloop event source and manages its +registration. A user of this type only needs to perform the usual Calloop +calls (process_events() and *register()) and the return value of +process_events().

+

Rather than needing to check for the full set of +PostAction values returned from process_events(), +you can just check for Continue or Reregister and pass that back out +through your own process_events() implementation. In your registration +functions, you then only need to call the same function on this type ie. +register() inside register() etc.

+

For example, say you have a source that contains a channel along with some +other logic. If the channel’s sending end has been dropped, it needs to be +removed from the loop. So to manage this, you use this in your struct:

+
struct CompositeSource {
+   // Event source for channel.
+   mpsc_receiver: TransientSource<calloop::channel::Channel<T>>,
+
+   // Any other fields go here...
+}
+
+

To create the transient source, you can simply use the Into +implementation:

+
let (sender, source) = channel();
+let mpsc_receiver: TransientSource<Channel> = source.into();
+
+

(If you want to start off with an empty TransientSource, you can just use +Default::default() instead.)

+

TransientSource implements EventSource and passes +through process_events() calls, so in the parent’s process_events() +implementation you can just do this:

+
fn process_events<F>(
+    &mut self,
+    readiness: calloop::Readiness,
+    token: calloop::Token,
+    callback: F,
+) -> Result<calloop::PostAction, Self::Error>
+where
+    F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+{
+    let channel_return = self.mpsc_receiver.process_events(readiness, token, callback)?;
+
+    // Perform other logic here...
+
+    Ok(channel_return)
+}
+
+

Note that:

+
    +
  • +

    You can call process_events() on the TransientSource<Channel> even +if the channel has been unregistered and dropped. All that will happen +is that you won’t get any events from it.

    +
  • +
  • +

    The PostAction returned from process_events() +will only ever be PostAction::Continue or PostAction::Reregister. +You will still need to combine this with the result of any other sources +(transient or not).

    +
  • +
+

Once you return channel_return from your process_events() method (and +assuming it propagates all the way up to the event loop itself through any +other event sources), the event loop might call reregister() on your +source. All your source has to do is:

+
fn reregister(
+    &mut self,
+    poll: &mut calloop::Poll,
+    token_factory: &mut calloop::TokenFactory,
+) -> crate::Result<()> {
+    self.mpsc_receiver.reregister(poll, token_factory)?;
+
+    // Other registration actions...
+
+    Ok(())
+}
+
+

The TransientSource will take care of updating the registration of the +inner source, even if it actually needs to be unregistered or initially +registered.

+

Replacing or removing TransientSources

+

Not properly removing or replacing TransientSources can cause spurious +wakeups of the event loop, and in some cases can leak file descriptors or +fail to free entries in Calloop’s internal data structures. No unsoundness +or undefined behaviour will result, but leaking file descriptors can result +in errors or panics.

+

If you want to remove a source before it returns PostAction::Remove, use +the TransientSource::remove() method. If you want to replace a source +with another one, use the TransientSource::replace() method. Either of +these may be called at any time during processing or from outside the event +loop. Both require either returning PostAction::Reregister from the +process_event() call that does this, or reregistering the event source +some other way eg. via the top-level loop handle.

+

If, instead, you directly assign a new source to the variable holding the +TransientSource, the inner source will be dropped before it can be +unregistered. For example:

+
self.mpsc_receiver = Default::default();
+self.mpsc_receiver = new_channel.into();
+

Implementations§

source§

impl<T> TransientSource<T>

source

pub fn map<F, U>(&mut self, f: F) -> Option<U>where + F: FnOnce(&mut T) -> U,

Apply a function to the enclosed source, if it exists and is not about +to be removed.

+
source

pub fn is_none(&self) -> bool

Returns true if there is no wrapped event source.

+
source

pub fn remove(&mut self)

Removes the wrapped event source from the event loop and this wrapper.

+

If this is called from outside of the event loop, you will need to wake +up the event loop for any changes to take place. If it is called from +within the event loop, you must return PostAction::Reregister from +your own event source’s process_events(), and the source will be +unregistered as needed after it exits.

+
source

pub fn replace(&mut self, new: T)

Replace the currently wrapped source with the given one. No more events +will be generated from the old source after this point. The old source +will not be dropped immediately, it will be kept so that it can be +deregistered.

+

If this is called from outside of the event loop, you will need to wake +up the event loop for any changes to take place. If it is called from +within the event loop, you must return PostAction::Reregister from +your own event source’s process_events(), and the sources will be +registered and unregistered as needed after it exits.

+

Trait Implementations§

source§

impl<T: Debug> Debug for TransientSource<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: Default> Default for TransientSource<T>

source§

fn default() -> TransientSource<T>

Returns the “default value” for a type. Read more
source§

impl<T: EventSource> EventSource for TransientSource<T>

§

type Event = <T as EventSource>::Event

The type of events generated by your source.
§

type Metadata = <T as EventSource>::Metadata

Some metadata of your event source Read more
§

type Ret = <T as EventSource>::Ret

The return type of the user callback Read more
§

type Error = <T as EventSource>::Error

The error type returned from +process_events() (not the user callback!).
source§

fn process_events<F>( + &mut self, + readiness: Readiness, + token: Token, + callback: F +) -> Result<PostAction, Self::Error>where + F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,

Process any relevant events Read more
source§

fn register( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

Register yourself to this poll instance Read more
source§

fn reregister( + &mut self, + poll: &mut Poll, + token_factory: &mut TokenFactory +) -> Result<()>

Re-register your file descriptors Read more
source§

fn unregister(&mut self, poll: &mut Poll) -> Result<()>

Unregister your file descriptors Read more
source§

const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = false

Whether this source needs to be sent the EventSource::before_sleep +and EventSource::before_handle_events notifications. These are opt-in because +they require more expensive checks, and almost all sources will not need these notifications
source§

fn before_sleep(&mut self) -> Result<Option<(Readiness, Token)>>

Notification that a single poll is about to begin Read more
source§

fn before_handle_events(&mut self, events: EventIterator<'_>)

Notification that polling is complete, and EventSource::process_events will +be called with the given events for this source. The iterator may be empty, +which indicates that no events were generated for this source Read more
source§

impl<T: EventSource> From<T> for TransientSource<T>

source§

fn from(source: T) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for TransientSource<T>where + T: RefUnwindSafe,

§

impl<T> Send for TransientSource<T>where + T: Send,

§

impl<T> Sync for TransientSource<T>where + T: Sync,

§

impl<T> Unpin for TransientSource<T>where + T: Unpin,

§

impl<T> UnwindSafe for TransientSource<T>where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an +Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +WithDispatch wrapper. Read more
\ No newline at end of file diff --git a/api/crates.js b/api/crates.js new file mode 100644 index 00000000..083173b6 --- /dev/null +++ b/api/crates.js @@ -0,0 +1 @@ +window.ALL_CRATES = ["calloop"]; \ No newline at end of file diff --git a/api/help.html b/api/help.html new file mode 100644 index 00000000..a41d7ff5 --- /dev/null +++ b/api/help.html @@ -0,0 +1 @@ +Rustdoc help

Rustdoc help

Back
\ No newline at end of file diff --git a/api/implementors/calloop/sources/trait.EventSource.js b/api/implementors/calloop/sources/trait.EventSource.js new file mode 100644 index 00000000..8531c44c --- /dev/null +++ b/api/implementors/calloop/sources/trait.EventSource.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/borrow/trait.Borrow.js b/api/implementors/core/borrow/trait.Borrow.js new file mode 100644 index 00000000..8183c278 --- /dev/null +++ b/api/implementors/core/borrow/trait.Borrow.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl<T> Borrow<T> for NoIoDrop<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/clone/trait.Clone.js b/api/implementors/core/clone/trait.Clone.js new file mode 100644 index 00000000..add51ad3 --- /dev/null +++ b/api/implementors/core/clone/trait.Clone.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl<'a, S, Data> Clone for Dispatcher<'a, S, Data>"],["impl Clone for Token"],["impl Clone for Readiness"],["impl<T> Clone for SyncSender<T>"],["impl Clone for Mode"],["impl<T: Clone> Clone for Scheduler<T>"],["impl Clone for PostAction"],["impl<'a> Clone for EventIterator<'a>"],["impl<'l, Data> Clone for LoopHandle<'l, Data>"],["impl Clone for Interest"],["impl<T> Clone for Sender<T>"],["impl Clone for RegistrationToken"],["impl Clone for LoopSignal"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/cmp/trait.Eq.js b/api/implementors/core/cmp/trait.Eq.js new file mode 100644 index 00000000..77cf5c01 --- /dev/null +++ b/api/implementors/core/cmp/trait.Eq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl Eq for Token"],["impl Eq for RegistrationToken"],["impl Eq for PostAction"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/cmp/trait.PartialEq.js b/api/implementors/core/cmp/trait.PartialEq.js new file mode 100644 index 00000000..2b5f78e5 --- /dev/null +++ b/api/implementors/core/cmp/trait.PartialEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl PartialEq<PostAction> for PostAction"],["impl PartialEq<RegistrationToken> for RegistrationToken"],["impl PartialEq<Token> for Token"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/convert/trait.AsRef.js b/api/implementors/core/convert/trait.AsRef.js new file mode 100644 index 00000000..8e8e8d80 --- /dev/null +++ b/api/implementors/core/convert/trait.AsRef.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl<T> AsRef<T> for NoIoDrop<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/convert/trait.From.js b/api/implementors/core/convert/trait.From.js new file mode 100644 index 00000000..ca2eb7f9 --- /dev/null +++ b/api/implementors/core/convert/trait.From.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl From<Error> for Error"],["impl<T> From<InsertError<T>> for Error"],["impl From<Box<dyn Error + Sync + Send, Global>> for Error"],["impl From<Error> for Error"],["impl<T: EventSource> From<T> for TransientSource<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/default/trait.Default.js b/api/implementors/core/default/trait.Default.js new file mode 100644 index 00000000..01700b0e --- /dev/null +++ b/api/implementors/core/default/trait.Default.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl<T: Default> Default for TransientSource<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/error/trait.Error.js b/api/implementors/core/error/trait.Error.js new file mode 100644 index 00000000..2296f0ce --- /dev/null +++ b/api/implementors/core/error/trait.Error.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl Error for ChannelError"],["impl Error for PingError"],["impl Error for Error"],["impl Error for ExecutorDestroyed"],["impl Error for ExecutorError"],["impl<T> Error for InsertError<T>where\n Self: Debug + Display,"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/fmt/trait.Debug.js b/api/implementors/core/fmt/trait.Debug.js new file mode 100644 index 00000000..ab9bd32d --- /dev/null +++ b/api/implementors/core/fmt/trait.Debug.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl<T> Debug for InsertError<T>"],["impl<T: Debug + AsRawFd> Debug for FdWrapper<T>"],["impl Debug for Readiness"],["impl<T: Debug> Debug for Executor<T>"],["impl Debug for Error"],["impl Debug for ChannelError"],["impl<'l, Data> Debug for EventLoop<'l, Data>"],["impl Debug for ExecutorError"],["impl Debug for TimeoutFuture"],["impl<T: Debug> Debug for Scheduler<T>"],["impl Debug for Timer"],["impl Debug for RegistrationToken"],["impl Debug for Poll"],["impl Debug for PostAction"],["impl<T: Debug> Debug for NoIoDrop<T>"],["impl<T: Debug> Debug for Event<T>"],["impl Debug for Interest"],["impl<'l, Data> Debug for LoopHandle<'l, Data>"],["impl<'a> Debug for EventIterator<'a>"],["impl<T: Debug> Debug for SyncSender<T>"],["impl Debug for Token"],["impl<T: Debug> Debug for Sender<T>"],["impl Debug for PingError"],["impl<'l, F: AsFd + Debug> Debug for Async<'l, F>"],["impl Debug for Mode"],["impl<F: Debug + AsFd, E: Debug> Debug for Generic<F, E>"],["impl<T: Debug> Debug for TransientSource<T>"],["impl Debug for TimeoutAction"],["impl Debug for TokenFactory"],["impl<'s, 'l, F: Debug + AsFd> Debug for Writable<'s, 'l, F>"],["impl<'i> Debug for Idle<'i>"],["impl<T: Debug> Debug for Channel<T>"],["impl<'s, 'l, F: Debug + AsFd> Debug for Readable<'s, 'l, F>"],["impl Debug for ExecutorDestroyed"],["impl<'a, S, Data> Debug for Dispatcher<'a, S, Data>"],["impl Debug for LoopSignal"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/fmt/trait.Display.js b/api/implementors/core/fmt/trait.Display.js new file mode 100644 index 00000000..58b27c5c --- /dev/null +++ b/api/implementors/core/fmt/trait.Display.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl Display for Error"],["impl<T> Display for InsertError<T>"],["impl Display for PingError"],["impl Display for ChannelError"],["impl Display for ExecutorDestroyed"],["impl Display for ExecutorError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/future/future/trait.Future.js b/api/implementors/core/future/future/trait.Future.js new file mode 100644 index 00000000..59870600 --- /dev/null +++ b/api/implementors/core/future/future/trait.Future.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl Future for TimeoutFuture"],["impl<'s, 'l, F: AsFd> Future for Readable<'s, 'l, F>"],["impl<'s, 'l, F: AsFd> Future for Writable<'s, 'l, F>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/iter/traits/iterator/trait.Iterator.js b/api/implementors/core/iter/traits/iterator/trait.Iterator.js new file mode 100644 index 00000000..8da0ac9c --- /dev/null +++ b/api/implementors/core/iter/traits/iterator/trait.Iterator.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl<'a> Iterator for EventIterator<'a>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/marker/trait.Copy.js b/api/implementors/core/marker/trait.Copy.js new file mode 100644 index 00000000..34b1c065 --- /dev/null +++ b/api/implementors/core/marker/trait.Copy.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl Copy for Token"],["impl Copy for Interest"],["impl Copy for Readiness"],["impl Copy for PostAction"],["impl Copy for Mode"],["impl Copy for RegistrationToken"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/marker/trait.Freeze.js b/api/implementors/core/marker/trait.Freeze.js new file mode 100644 index 00000000..4741913f --- /dev/null +++ b/api/implementors/core/marker/trait.Freeze.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl Freeze for Mode",1,["calloop::sys::Mode"]],["impl Freeze for Interest",1,["calloop::sys::Interest"]],["impl Freeze for Readiness",1,["calloop::sys::Readiness"]],["impl Freeze for TokenFactory",1,["calloop::sys::TokenFactory"]],["impl Freeze for Token",1,["calloop::sys::Token"]],["impl !Freeze for Poll",1,["calloop::sys::Poll"]],["impl Freeze for Error",1,["calloop::error::Error"]],["impl<T> Freeze for InsertError<T>where\n T: Freeze,",1,["calloop::error::InsertError"]],["impl<'l, F> Freeze for Async<'l, F>where\n F: Freeze,",1,["calloop::io::Async"]],["impl<'s, 'l, F> Freeze for Readable<'s, 'l, F>",1,["calloop::io::Readable"]],["impl<'s, 'l, F> Freeze for Writable<'s, 'l, F>",1,["calloop::io::Writable"]],["impl Freeze for RegistrationToken",1,["calloop::loop_logic::RegistrationToken"]],["impl<'l, Data> Freeze for LoopHandle<'l, Data>",1,["calloop::loop_logic::LoopHandle"]],["impl<'l, Data> Freeze for EventLoop<'l, Data>",1,["calloop::loop_logic::EventLoop"]],["impl<'a> Freeze for EventIterator<'a>",1,["calloop::loop_logic::EventIterator"]],["impl Freeze for LoopSignal",1,["calloop::loop_logic::LoopSignal"]],["impl<T> Freeze for Event<T>where\n T: Freeze,",1,["calloop::sources::channel::Event"]],["impl<T> Freeze for Sender<T>",1,["calloop::sources::channel::Sender"]],["impl<T> Freeze for SyncSender<T>",1,["calloop::sources::channel::SyncSender"]],["impl<T> Freeze for Channel<T>",1,["calloop::sources::channel::Channel"]],["impl Freeze for ChannelError",1,["calloop::sources::channel::ChannelError"]],["impl<T> Freeze for Executor<T>",1,["calloop::sources::futures::Executor"]],["impl<T> Freeze for Scheduler<T>",1,["calloop::sources::futures::Scheduler"]],["impl Freeze for ExecutorDestroyed",1,["calloop::sources::futures::ExecutorDestroyed"]],["impl Freeze for ExecutorError",1,["calloop::sources::futures::ExecutorError"]],["impl<T> Freeze for FdWrapper<T>where\n T: Freeze,",1,["calloop::sources::generic::FdWrapper"]],["impl<T> Freeze for NoIoDrop<T>where\n T: Freeze,",1,["calloop::sources::generic::NoIoDrop"]],["impl<F, E> Freeze for Generic<F, E>where\n F: Freeze,",1,["calloop::sources::generic::Generic"]],["impl Freeze for PingError",1,["calloop::sources::ping::PingError"]],["impl Freeze for Timer",1,["calloop::sources::timer::Timer"]],["impl Freeze for TimeoutAction",1,["calloop::sources::timer::TimeoutAction"]],["impl Freeze for TimeoutFuture",1,["calloop::sources::timer::TimeoutFuture"]],["impl<T> Freeze for TransientSource<T>where\n T: Freeze,",1,["calloop::sources::transient::TransientSource"]],["impl Freeze for PostAction",1,["calloop::sources::PostAction"]],["impl<'a, S, Data> Freeze for Dispatcher<'a, S, Data>",1,["calloop::sources::Dispatcher"]],["impl<'i> Freeze for Idle<'i>",1,["calloop::sources::Idle"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/marker/trait.Send.js b/api/implementors/core/marker/trait.Send.js new file mode 100644 index 00000000..076b2454 --- /dev/null +++ b/api/implementors/core/marker/trait.Send.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl Send for Mode",1,["calloop::sys::Mode"]],["impl Send for Interest",1,["calloop::sys::Interest"]],["impl Send for Readiness",1,["calloop::sys::Readiness"]],["impl Send for TokenFactory",1,["calloop::sys::TokenFactory"]],["impl Send for Token",1,["calloop::sys::Token"]],["impl !Send for Poll",1,["calloop::sys::Poll"]],["impl Send for Error",1,["calloop::error::Error"]],["impl<T> Send for InsertError<T>where\n T: Send,",1,["calloop::error::InsertError"]],["impl<'l, F> !Send for Async<'l, F>",1,["calloop::io::Async"]],["impl<'s, 'l, F> !Send for Readable<'s, 'l, F>",1,["calloop::io::Readable"]],["impl<'s, 'l, F> !Send for Writable<'s, 'l, F>",1,["calloop::io::Writable"]],["impl Send for RegistrationToken",1,["calloop::loop_logic::RegistrationToken"]],["impl<'l, Data> !Send for LoopHandle<'l, Data>",1,["calloop::loop_logic::LoopHandle"]],["impl<'l, Data> !Send for EventLoop<'l, Data>",1,["calloop::loop_logic::EventLoop"]],["impl<'a> Send for EventIterator<'a>",1,["calloop::loop_logic::EventIterator"]],["impl Send for LoopSignal",1,["calloop::loop_logic::LoopSignal"]],["impl<T> Send for Event<T>where\n T: Send,",1,["calloop::sources::channel::Event"]],["impl<T> Send for Sender<T>where\n T: Send,",1,["calloop::sources::channel::Sender"]],["impl<T> Send for SyncSender<T>where\n T: Send,",1,["calloop::sources::channel::SyncSender"]],["impl Send for ChannelError",1,["calloop::sources::channel::ChannelError"]],["impl<T> !Send for Executor<T>",1,["calloop::sources::futures::Executor"]],["impl<T> !Send for Scheduler<T>",1,["calloop::sources::futures::Scheduler"]],["impl Send for ExecutorDestroyed",1,["calloop::sources::futures::ExecutorDestroyed"]],["impl Send for ExecutorError",1,["calloop::sources::futures::ExecutorError"]],["impl<T> Send for FdWrapper<T>where\n T: Send,",1,["calloop::sources::generic::FdWrapper"]],["impl<T> Send for NoIoDrop<T>where\n T: Send,",1,["calloop::sources::generic::NoIoDrop"]],["impl<F, E> Send for Generic<F, E>where\n E: Send,\n F: Send,",1,["calloop::sources::generic::Generic"]],["impl Send for PingError",1,["calloop::sources::ping::PingError"]],["impl !Send for Timer",1,["calloop::sources::timer::Timer"]],["impl Send for TimeoutAction",1,["calloop::sources::timer::TimeoutAction"]],["impl !Send for TimeoutFuture",1,["calloop::sources::timer::TimeoutFuture"]],["impl<T> Send for TransientSource<T>where\n T: Send,",1,["calloop::sources::transient::TransientSource"]],["impl Send for PostAction",1,["calloop::sources::PostAction"]],["impl<'a, S, Data> !Send for Dispatcher<'a, S, Data>",1,["calloop::sources::Dispatcher"]],["impl<'i> !Send for Idle<'i>",1,["calloop::sources::Idle"]],["impl<T: Send> Send for Channel<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/marker/trait.StructuralEq.js b/api/implementors/core/marker/trait.StructuralEq.js new file mode 100644 index 00000000..e0a93122 --- /dev/null +++ b/api/implementors/core/marker/trait.StructuralEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl StructuralEq for RegistrationToken"],["impl StructuralEq for PostAction"],["impl StructuralEq for Token"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/marker/trait.StructuralPartialEq.js b/api/implementors/core/marker/trait.StructuralPartialEq.js new file mode 100644 index 00000000..4ab160fd --- /dev/null +++ b/api/implementors/core/marker/trait.StructuralPartialEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl StructuralPartialEq for PostAction"],["impl StructuralPartialEq for RegistrationToken"],["impl StructuralPartialEq for Token"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/marker/trait.Sync.js b/api/implementors/core/marker/trait.Sync.js new file mode 100644 index 00000000..775aadf5 --- /dev/null +++ b/api/implementors/core/marker/trait.Sync.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl Sync for Mode",1,["calloop::sys::Mode"]],["impl Sync for Interest",1,["calloop::sys::Interest"]],["impl Sync for Readiness",1,["calloop::sys::Readiness"]],["impl Sync for TokenFactory",1,["calloop::sys::TokenFactory"]],["impl Sync for Token",1,["calloop::sys::Token"]],["impl !Sync for Poll",1,["calloop::sys::Poll"]],["impl Sync for Error",1,["calloop::error::Error"]],["impl<T> Sync for InsertError<T>where\n T: Sync,",1,["calloop::error::InsertError"]],["impl<'l, F> !Sync for Async<'l, F>",1,["calloop::io::Async"]],["impl<'s, 'l, F> !Sync for Readable<'s, 'l, F>",1,["calloop::io::Readable"]],["impl<'s, 'l, F> !Sync for Writable<'s, 'l, F>",1,["calloop::io::Writable"]],["impl Sync for RegistrationToken",1,["calloop::loop_logic::RegistrationToken"]],["impl<'l, Data> !Sync for LoopHandle<'l, Data>",1,["calloop::loop_logic::LoopHandle"]],["impl<'l, Data> !Sync for EventLoop<'l, Data>",1,["calloop::loop_logic::EventLoop"]],["impl<'a> Sync for EventIterator<'a>",1,["calloop::loop_logic::EventIterator"]],["impl Sync for LoopSignal",1,["calloop::loop_logic::LoopSignal"]],["impl<T> Sync for Event<T>where\n T: Sync,",1,["calloop::sources::channel::Event"]],["impl<T> Sync for Sender<T>where\n T: Send,",1,["calloop::sources::channel::Sender"]],["impl<T> Sync for SyncSender<T>where\n T: Send,",1,["calloop::sources::channel::SyncSender"]],["impl<T> !Sync for Channel<T>",1,["calloop::sources::channel::Channel"]],["impl Sync for ChannelError",1,["calloop::sources::channel::ChannelError"]],["impl<T> !Sync for Executor<T>",1,["calloop::sources::futures::Executor"]],["impl<T> !Sync for Scheduler<T>",1,["calloop::sources::futures::Scheduler"]],["impl Sync for ExecutorDestroyed",1,["calloop::sources::futures::ExecutorDestroyed"]],["impl Sync for ExecutorError",1,["calloop::sources::futures::ExecutorError"]],["impl<T> Sync for FdWrapper<T>where\n T: Sync,",1,["calloop::sources::generic::FdWrapper"]],["impl<T> Sync for NoIoDrop<T>where\n T: Sync,",1,["calloop::sources::generic::NoIoDrop"]],["impl<F, E> Sync for Generic<F, E>where\n E: Sync,\n F: Sync,",1,["calloop::sources::generic::Generic"]],["impl Sync for PingError",1,["calloop::sources::ping::PingError"]],["impl !Sync for Timer",1,["calloop::sources::timer::Timer"]],["impl Sync for TimeoutAction",1,["calloop::sources::timer::TimeoutAction"]],["impl !Sync for TimeoutFuture",1,["calloop::sources::timer::TimeoutFuture"]],["impl<T> Sync for TransientSource<T>where\n T: Sync,",1,["calloop::sources::transient::TransientSource"]],["impl Sync for PostAction",1,["calloop::sources::PostAction"]],["impl<'a, S, Data> !Sync for Dispatcher<'a, S, Data>",1,["calloop::sources::Dispatcher"]],["impl<'i> !Sync for Idle<'i>",1,["calloop::sources::Idle"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/marker/trait.Unpin.js b/api/implementors/core/marker/trait.Unpin.js new file mode 100644 index 00000000..f2350fa5 --- /dev/null +++ b/api/implementors/core/marker/trait.Unpin.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl Unpin for Mode",1,["calloop::sys::Mode"]],["impl Unpin for Interest",1,["calloop::sys::Interest"]],["impl Unpin for Readiness",1,["calloop::sys::Readiness"]],["impl Unpin for TokenFactory",1,["calloop::sys::TokenFactory"]],["impl Unpin for Token",1,["calloop::sys::Token"]],["impl Unpin for Poll",1,["calloop::sys::Poll"]],["impl Unpin for Error",1,["calloop::error::Error"]],["impl<T> Unpin for InsertError<T>where\n T: Unpin,",1,["calloop::error::InsertError"]],["impl<'s, 'l, F> Unpin for Readable<'s, 'l, F>",1,["calloop::io::Readable"]],["impl<'s, 'l, F> Unpin for Writable<'s, 'l, F>",1,["calloop::io::Writable"]],["impl Unpin for RegistrationToken",1,["calloop::loop_logic::RegistrationToken"]],["impl<'l, Data> Unpin for LoopHandle<'l, Data>",1,["calloop::loop_logic::LoopHandle"]],["impl<'l, Data> Unpin for EventLoop<'l, Data>",1,["calloop::loop_logic::EventLoop"]],["impl<'a> Unpin for EventIterator<'a>",1,["calloop::loop_logic::EventIterator"]],["impl Unpin for LoopSignal",1,["calloop::loop_logic::LoopSignal"]],["impl<T> Unpin for Event<T>where\n T: Unpin,",1,["calloop::sources::channel::Event"]],["impl<T> Unpin for Sender<T>",1,["calloop::sources::channel::Sender"]],["impl<T> Unpin for SyncSender<T>",1,["calloop::sources::channel::SyncSender"]],["impl<T> Unpin for Channel<T>",1,["calloop::sources::channel::Channel"]],["impl Unpin for ChannelError",1,["calloop::sources::channel::ChannelError"]],["impl<T> Unpin for Executor<T>",1,["calloop::sources::futures::Executor"]],["impl<T> Unpin for Scheduler<T>",1,["calloop::sources::futures::Scheduler"]],["impl Unpin for ExecutorDestroyed",1,["calloop::sources::futures::ExecutorDestroyed"]],["impl Unpin for ExecutorError",1,["calloop::sources::futures::ExecutorError"]],["impl<T> Unpin for FdWrapper<T>where\n T: Unpin,",1,["calloop::sources::generic::FdWrapper"]],["impl<T> Unpin for NoIoDrop<T>where\n T: Unpin,",1,["calloop::sources::generic::NoIoDrop"]],["impl<F, E> Unpin for Generic<F, E>where\n E: Unpin,\n F: Unpin,",1,["calloop::sources::generic::Generic"]],["impl Unpin for PingError",1,["calloop::sources::ping::PingError"]],["impl Unpin for Timer",1,["calloop::sources::timer::Timer"]],["impl Unpin for TimeoutAction",1,["calloop::sources::timer::TimeoutAction"]],["impl Unpin for TimeoutFuture",1,["calloop::sources::timer::TimeoutFuture"]],["impl<T> Unpin for TransientSource<T>where\n T: Unpin,",1,["calloop::sources::transient::TransientSource"]],["impl Unpin for PostAction",1,["calloop::sources::PostAction"]],["impl<'a, S, Data> Unpin for Dispatcher<'a, S, Data>",1,["calloop::sources::Dispatcher"]],["impl<'i> Unpin for Idle<'i>",1,["calloop::sources::Idle"]],["impl<'l, F: AsFd> Unpin for Async<'l, F>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/ops/bit/trait.BitOr.js b/api/implementors/core/ops/bit/trait.BitOr.js new file mode 100644 index 00000000..b963254a --- /dev/null +++ b/api/implementors/core/ops/bit/trait.BitOr.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl BitOr<PostAction> for PostAction"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/ops/bit/trait.BitOrAssign.js b/api/implementors/core/ops/bit/trait.BitOrAssign.js new file mode 100644 index 00000000..cf4c136d --- /dev/null +++ b/api/implementors/core/ops/bit/trait.BitOrAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl BitOrAssign<PostAction> for PostAction"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/ops/deref/trait.Deref.js b/api/implementors/core/ops/deref/trait.Deref.js new file mode 100644 index 00000000..1ce77e54 --- /dev/null +++ b/api/implementors/core/ops/deref/trait.Deref.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl<T> Deref for NoIoDrop<T>"],["impl<T: AsRawFd> Deref for FdWrapper<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/ops/deref/trait.DerefMut.js b/api/implementors/core/ops/deref/trait.DerefMut.js new file mode 100644 index 00000000..2d28b55e --- /dev/null +++ b/api/implementors/core/ops/deref/trait.DerefMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl<T: AsRawFd> DerefMut for FdWrapper<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/ops/drop/trait.Drop.js b/api/implementors/core/ops/drop/trait.Drop.js new file mode 100644 index 00000000..166e8ea7 --- /dev/null +++ b/api/implementors/core/ops/drop/trait.Drop.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl<T> Drop for Sender<T>"],["impl<'l, F: AsFd> Drop for Async<'l, F>"],["impl<F: AsFd, E> Drop for Generic<F, E>"],["impl<T> Drop for Executor<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js b/api/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js new file mode 100644 index 00000000..253e6532 --- /dev/null +++ b/api/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl RefUnwindSafe for Mode",1,["calloop::sys::Mode"]],["impl RefUnwindSafe for Interest",1,["calloop::sys::Interest"]],["impl RefUnwindSafe for Readiness",1,["calloop::sys::Readiness"]],["impl RefUnwindSafe for TokenFactory",1,["calloop::sys::TokenFactory"]],["impl RefUnwindSafe for Token",1,["calloop::sys::Token"]],["impl !RefUnwindSafe for Poll",1,["calloop::sys::Poll"]],["impl !RefUnwindSafe for Error",1,["calloop::error::Error"]],["impl<T> !RefUnwindSafe for InsertError<T>",1,["calloop::error::InsertError"]],["impl<'l, F> !RefUnwindSafe for Async<'l, F>",1,["calloop::io::Async"]],["impl<'s, 'l, F> !RefUnwindSafe for Readable<'s, 'l, F>",1,["calloop::io::Readable"]],["impl<'s, 'l, F> !RefUnwindSafe for Writable<'s, 'l, F>",1,["calloop::io::Writable"]],["impl RefUnwindSafe for RegistrationToken",1,["calloop::loop_logic::RegistrationToken"]],["impl<'l, Data> !RefUnwindSafe for LoopHandle<'l, Data>",1,["calloop::loop_logic::LoopHandle"]],["impl<'l, Data> !RefUnwindSafe for EventLoop<'l, Data>",1,["calloop::loop_logic::EventLoop"]],["impl<'a> RefUnwindSafe for EventIterator<'a>",1,["calloop::loop_logic::EventIterator"]],["impl RefUnwindSafe for LoopSignal",1,["calloop::loop_logic::LoopSignal"]],["impl<T> RefUnwindSafe for Event<T>where\n T: RefUnwindSafe,",1,["calloop::sources::channel::Event"]],["impl<T> RefUnwindSafe for Sender<T>",1,["calloop::sources::channel::Sender"]],["impl<T> RefUnwindSafe for SyncSender<T>",1,["calloop::sources::channel::SyncSender"]],["impl<T> !RefUnwindSafe for Channel<T>",1,["calloop::sources::channel::Channel"]],["impl !RefUnwindSafe for ChannelError",1,["calloop::sources::channel::ChannelError"]],["impl<T> !RefUnwindSafe for Executor<T>",1,["calloop::sources::futures::Executor"]],["impl<T> !RefUnwindSafe for Scheduler<T>",1,["calloop::sources::futures::Scheduler"]],["impl RefUnwindSafe for ExecutorDestroyed",1,["calloop::sources::futures::ExecutorDestroyed"]],["impl !RefUnwindSafe for ExecutorError",1,["calloop::sources::futures::ExecutorError"]],["impl<T> RefUnwindSafe for FdWrapper<T>where\n T: RefUnwindSafe,",1,["calloop::sources::generic::FdWrapper"]],["impl<T> RefUnwindSafe for NoIoDrop<T>where\n T: RefUnwindSafe,",1,["calloop::sources::generic::NoIoDrop"]],["impl<F, E> RefUnwindSafe for Generic<F, E>where\n E: RefUnwindSafe,\n F: RefUnwindSafe,",1,["calloop::sources::generic::Generic"]],["impl !RefUnwindSafe for PingError",1,["calloop::sources::ping::PingError"]],["impl !RefUnwindSafe for Timer",1,["calloop::sources::timer::Timer"]],["impl RefUnwindSafe for TimeoutAction",1,["calloop::sources::timer::TimeoutAction"]],["impl !RefUnwindSafe for TimeoutFuture",1,["calloop::sources::timer::TimeoutFuture"]],["impl<T> RefUnwindSafe for TransientSource<T>where\n T: RefUnwindSafe,",1,["calloop::sources::transient::TransientSource"]],["impl RefUnwindSafe for PostAction",1,["calloop::sources::PostAction"]],["impl<'a, S, Data> !RefUnwindSafe for Dispatcher<'a, S, Data>",1,["calloop::sources::Dispatcher"]],["impl<'i> !RefUnwindSafe for Idle<'i>",1,["calloop::sources::Idle"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/core/panic/unwind_safe/trait.UnwindSafe.js b/api/implementors/core/panic/unwind_safe/trait.UnwindSafe.js new file mode 100644 index 00000000..14a63518 --- /dev/null +++ b/api/implementors/core/panic/unwind_safe/trait.UnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl UnwindSafe for Mode",1,["calloop::sys::Mode"]],["impl UnwindSafe for Interest",1,["calloop::sys::Interest"]],["impl UnwindSafe for Readiness",1,["calloop::sys::Readiness"]],["impl UnwindSafe for TokenFactory",1,["calloop::sys::TokenFactory"]],["impl UnwindSafe for Token",1,["calloop::sys::Token"]],["impl !UnwindSafe for Poll",1,["calloop::sys::Poll"]],["impl !UnwindSafe for Error",1,["calloop::error::Error"]],["impl<T> !UnwindSafe for InsertError<T>",1,["calloop::error::InsertError"]],["impl<'l, F> !UnwindSafe for Async<'l, F>",1,["calloop::io::Async"]],["impl<'s, 'l, F> !UnwindSafe for Readable<'s, 'l, F>",1,["calloop::io::Readable"]],["impl<'s, 'l, F> !UnwindSafe for Writable<'s, 'l, F>",1,["calloop::io::Writable"]],["impl UnwindSafe for RegistrationToken",1,["calloop::loop_logic::RegistrationToken"]],["impl<'l, Data> !UnwindSafe for LoopHandle<'l, Data>",1,["calloop::loop_logic::LoopHandle"]],["impl<'l, Data> !UnwindSafe for EventLoop<'l, Data>",1,["calloop::loop_logic::EventLoop"]],["impl<'a> UnwindSafe for EventIterator<'a>",1,["calloop::loop_logic::EventIterator"]],["impl UnwindSafe for LoopSignal",1,["calloop::loop_logic::LoopSignal"]],["impl<T> UnwindSafe for Event<T>where\n T: UnwindSafe,",1,["calloop::sources::channel::Event"]],["impl<T> UnwindSafe for Sender<T>",1,["calloop::sources::channel::Sender"]],["impl<T> UnwindSafe for SyncSender<T>",1,["calloop::sources::channel::SyncSender"]],["impl<T> !UnwindSafe for Channel<T>",1,["calloop::sources::channel::Channel"]],["impl !UnwindSafe for ChannelError",1,["calloop::sources::channel::ChannelError"]],["impl<T> !UnwindSafe for Executor<T>",1,["calloop::sources::futures::Executor"]],["impl<T> !UnwindSafe for Scheduler<T>",1,["calloop::sources::futures::Scheduler"]],["impl UnwindSafe for ExecutorDestroyed",1,["calloop::sources::futures::ExecutorDestroyed"]],["impl !UnwindSafe for ExecutorError",1,["calloop::sources::futures::ExecutorError"]],["impl<T> UnwindSafe for FdWrapper<T>where\n T: UnwindSafe,",1,["calloop::sources::generic::FdWrapper"]],["impl<T> UnwindSafe for NoIoDrop<T>where\n T: UnwindSafe,",1,["calloop::sources::generic::NoIoDrop"]],["impl<F, E> UnwindSafe for Generic<F, E>where\n E: UnwindSafe,\n F: UnwindSafe,",1,["calloop::sources::generic::Generic"]],["impl !UnwindSafe for PingError",1,["calloop::sources::ping::PingError"]],["impl !UnwindSafe for Timer",1,["calloop::sources::timer::Timer"]],["impl UnwindSafe for TimeoutAction",1,["calloop::sources::timer::TimeoutAction"]],["impl !UnwindSafe for TimeoutFuture",1,["calloop::sources::timer::TimeoutFuture"]],["impl<T> UnwindSafe for TransientSource<T>where\n T: UnwindSafe,",1,["calloop::sources::transient::TransientSource"]],["impl UnwindSafe for PostAction",1,["calloop::sources::PostAction"]],["impl<'a, S, Data> !UnwindSafe for Dispatcher<'a, S, Data>",1,["calloop::sources::Dispatcher"]],["impl<'i> !UnwindSafe for Idle<'i>",1,["calloop::sources::Idle"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/implementors/std/os/fd/owned/trait.AsFd.js b/api/implementors/std/os/fd/owned/trait.AsFd.js new file mode 100644 index 00000000..9c731e91 --- /dev/null +++ b/api/implementors/std/os/fd/owned/trait.AsFd.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"calloop":[["impl<T: AsFd> AsFd for NoIoDrop<T>"],["impl<T: AsRawFd> AsFd for FdWrapper<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/api/index.html b/api/index.html new file mode 100644 index 00000000..c2510eb7 --- /dev/null +++ b/api/index.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/api/search-index.js b/api/search-index.js new file mode 100644 index 00000000..f275c3ca --- /dev/null +++ b/api/search-index.js @@ -0,0 +1,5 @@ +var searchIndex = JSON.parse('{\ +"calloop":{"doc":"Calloop, a Callback-based Event Loop","t":"SNNDSSNCQQDDIDCDNDDQESSNDESDDNNCQDDSLLLOOOLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLALLLLLLLLLLLLLLLLLLLLLLLLLLLLLAMLLLLLLLLLLLLLLLLLLLLLLLLLLLLAALLLLLLLLLLLLLLLLLLLLALLAKMMKLLLKLLLALLLLLLLLLLLALLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLKLLLMMDDNENDDLLLLLLLLLLFLLLLLLLLLLLLLLLLLLLLLLLLLLLLFLLLLLLLLLLLLLLLLLLLLLEDNNNGLLLLMLLLLLLLLLMLLLLLLLLLLLLDDENDNLLLLLLLLLLLFLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLDDDLLLLLLLLLLLLLLLLLLLLLLLMLLLMLLLLLLLLLLLLLLLLLDDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLGDGLLLLLLFLLLLLNEDDNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLDLLLLLLLLLLLLLLLLLL","n":["BOTH","Continue","Disable","Dispatcher","EMPTY","EMPTY","Edge","Error","Error","Event","EventIterator","EventLoop","EventSource","Idle","InsertError","Interest","Level","LoopHandle","LoopSignal","Metadata","Mode","NEEDS_EXTRA_LIFECYCLE_EVENTS","NEEDS_EXTRA_LIFECYCLE_EVENTS","OneShot","Poll","PostAction","READ","Readiness","RegistrationToken","Remove","Reregister","Result","Ret","Token","TokenFactory","WRITE","adapt_io","as_source_mut","as_source_ref","batch_register","batch_reregister","batch_unregister","before_handle_events","before_handle_events","before_sleep","before_sleep","bitor","bitor_assign","block_on","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","cancel","channel","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","disable","dispatch","enable","eq","eq","eq","equivalent","equivalent","equivalent","error","error","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","futures","generic","get_signal","handle","insert_idle","insert_source","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into_iter","into_source_inner","io","new","next","ping","process_events","readable","readable","register","register","register_dispatcher","remove","reregister","reregister","run","stop","timer","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","token","transient","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_new","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unregister","unregister","update","wakeup","writable","writable","Channel","ChannelError","Closed","Event","Msg","Sender","SyncSender","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","channel","clone","clone","clone_into","clone_into","drop","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","into","into","into","into","into","process_events","recv","register","reregister","send","send","source","sync_channel","to_owned","to_owned","to_string","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_recv","try_send","type_id","type_id","type_id","type_id","type_id","unregister","Error","InsertError","InvalidToken","IoError","OtherError","Result","borrow","borrow","borrow_mut","borrow_mut","error","fmt","fmt","fmt","fmt","from","from","from","from","from","inserted","into","into","source","source","to_string","to_string","try_from","try_from","try_into","try_into","type_id","type_id","Executor","ExecutorDestroyed","ExecutorError","NewFutureError","Scheduler","WakeError","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone_into","drop","executor","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","into","into","into","into","process_events","register","reregister","schedule","to_owned","to_string","to_string","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","unregister","FdWrapper","Generic","NoIoDrop","as_fd","as_fd","as_ref","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","deref","deref","deref_mut","drop","fmt","fmt","fmt","from","from","from","get_mut","get_mut","get_ref","interest","into","into","into","mode","new","new","new_with_error","process_events","register","reregister","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","unregister","unwrap","Async","Readable","Writable","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","drop","fmt","fmt","fmt","from","from","from","get_mut","into","into","into","into_future","into_future","into_inner","poll","poll","readable","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","writable","Ping","PingError","PingSource","borrow","borrow_mut","fmt","fmt","from","into","make_ping","source","to_string","try_from","try_into","type_id","Drop","TimeoutAction","TimeoutFuture","Timer","ToDuration","ToInstant","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","current_deadline","fmt","fmt","fmt","from","from","from","from_deadline","from_deadline","from_duration","from_duration","immediate","into","into","into","into_future","poll","process_events","register","reregister","set_deadline","set_duration","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","unregister","TransientSource","borrow","borrow_mut","default","fmt","from","from","into","is_none","map","process_events","register","remove","replace","reregister","try_from","try_into","type_id","unregister"],"q":[[0,"calloop"],[237,"calloop::channel"],[305,"calloop::error"],[338,"calloop::futures"],[390,"calloop::generic"],[438,"calloop::io"],[474,"calloop::ping"],[489,"calloop::timer"],[533,"calloop::transient"]],"d":["Shorthand for read and write interest","Continue listening for events on this source as before","Disable this source","An event source with its callback.","Shorthand for empty interest","Shorthand for empty readiness","Edge-triggering","","The error type returned from process_events() (not the …","The type of events generated by your source.","The EventIterator is an Iterator over the events relevant …","An event loop","Trait representing an event source","An idle callback that was inserted in this loop","","Interest to register regarding the file descriptor","Level-triggering","An handle to an event loop","A signal that can be shared between thread to stop or …","Some metadata of your event source","Possible modes for registering a file descriptor","Whether this source needs to be sent the …","Whether this source needs to be sent the …","Single event generation","The polling system","Possible actions that can be requested to the event loop …","Shorthand for read interest","Readiness for a file descriptor notification","A token representing a registration in the EventLoop.","Remove this source from the eventloop","Trigger a re-registration of this source","","The return type of the user callback","A token (for implementation of the EventSource trait)","Factory for creating tokens in your registrations","Shorthand for write interest","Wrap an IO object into an async adapter","Returns a mutable reference to the event source.","Returns an immutable reference to the event source.","Register a set of event sources. Effectively calls …","Reregister a set of event sources. Effectively calls …","Unregister a set of event sources. Effectively calls …","Notification that polling is complete, and …","Notification that polling is complete, and …","Notification that a single poll is about to begin","Notification that a single poll is about to begin","","","Block a future on this event loop.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Cancel the idle callback if it was not already run","An MPSC channel whose receiving end is an event source","","","","","","","","","","","","","","","","","","","","","Disables this event source.","Dispatch pending events to their callbacks","Enables this previously disabled event source.","","","","","","","Error types used and generated by Calloop.","Is the FD in an error state","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","A futures executor as an event source","A generic event source wrapping an IO objects or file …","Get a signal to stop this event loop from running","Retrieve a loop handle","Inserts an idle callback.","Inserts a new event source in the loop.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","Consumes the Dispatcher and returns the inner event source.","Adapters for async IO objects","Builds a dispatcher.","","Ping to the event loop","Process any relevant events","Wait for the FD to be readable","Is the FD readable","Register yourself to this poll instance","Register a new file descriptor for polling","Registers a Dispatcher in the loop.","Removes this source from the event loop.","Re-register your file descriptors","Update the registration for a file descriptor","Run this event loop","Stop the event loop","Timer event source","","","","","","","","","","","Produce a new unique token","Wrapper for a transient Calloop event source.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Create a new event loop","","","","","","","","","","","","","","","Unregister your file descriptors","Unregister a file descriptor","Makes this source update its registration.","Wake up the event loop","Wait for the FD to be writable","Is the FD writable","The receiving end of the channel","An error arising from processing events for a channel.","The channel was closed","The events generated by the channel event source","A message was received and is bundled here","The sender end of a channel","The sender end of a synchronous channel","","","","","","","","","","","Create a new asynchronous channel","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","Proxy for mpsc::Receiver::recv to manually poll events.","","","Send a message to the channel","Send a message to the synchronous channel","","Create a new synchronous, bounded channel","","","","","","","","","","","","","","Proxy for mpsc::Receiver::try_recv to manually poll events.","Send a message to the synchronous channel","","","","","","","The primary error type used by Calloop covering internal …","An error generated when trying to insert an event source","When an event source is registered (or re- or …","This variant wraps a std::io::Error, which might arise from","Any other unexpected error kind (most likely from a user …","Result alias using Calloop’s error type.","","","","","The generated error","","","","","","","Converts the InsertError into Calloop’s error type, …","Returns the argument unchanged.","Returns the argument unchanged.","The source that could not be inserted","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","A future executor as an event source","Error generated when trying to schedule a future after the …","An error arising from processing events in an async …","Error while reading new futures added via …","A scheduler to send futures to an executor","Error while processing wake events from existing futures.","","","","","","","","","","","","Create a new executor, and its associated scheduler","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","Sends the given future to the executor associated to this …","","","","","","","","","","","","","","","","","Wrapper to use a type implementing AsRawFd but not AsFd …","A generic event source wrapping a FD-backed type","A wrapper around a type that doesn’t expose it mutably …","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Get a mutable reference.","Get a mutable reference to the underlying type.","Get a reference to the underlying type.","The programmed interest","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","The programmed mode","Wrap inner with an AsFd implementation.","Wrap a FD-backed type into a Generic event source that uses","Wrap a FD-backed type into a Generic event source using an …","","","","","","","","","","","","","","Unwrap the Generic source to retrieve the underlying type","Adapter for async IO manipulations","A future that resolves once the associated object becomes …","A future that resolves once the associated object becomes …","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Mutably access the underlying IO object","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","Remove the async adapter and retrieve the underlying object","","","A future that resolves once the object becomes ready for …","","","","","","","","","","A future that resolves once the object becomes ready for …","The ping event source","An error arising from processing events for a ping.","The Ping handle","","","","","Returns the argument unchanged.","Calls U::from(self).","Create a new ping event source","","","","","","Don’t reschedule this timer","Action to reschedule a timeout if necessary","A future that resolves once a certain timeout is expired","A timer event source","Reschedule this timer to a given Duration in the future","Reschedule this timer to a given Instant","","","","","","","Get the current deadline of this Timer","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Create a future that resolves at a given instant","Create a timer that will fire at a given instant","Create a future that resolves after a given duration","Create a timer that will fire after a given duration from …","Create a timer that will fire immediately when inserted in …","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","Changes the deadline of this timer to an Instant","Changes the deadline of this timer to a Duration from now","","","","","","","","","","","A TransientSource wraps a Calloop event source and manages …","","","","","Returns the argument unchanged.","","Calls U::from(self).","Returns true if there is no wrapped event source.","Apply a function to the enclosed source, if it exists and …","","","Removes the wrapped event source from the event loop and …","Replace the currently wrapped source with the given one. …","","","","",""],"i":[17,11,11,0,17,18,16,0,5,5,0,0,0,0,0,0,16,0,0,5,0,5,5,16,0,0,17,0,0,11,11,0,5,0,0,17,1,6,6,0,0,0,5,5,5,5,11,11,12,25,1,12,6,15,16,17,18,28,19,20,9,21,11,25,1,12,6,15,16,17,18,28,19,20,9,21,11,15,0,1,6,16,17,18,19,20,9,21,11,1,6,16,17,18,19,20,9,21,11,1,12,1,19,20,11,19,20,11,0,18,25,1,12,6,15,16,17,18,28,19,20,9,21,11,25,1,12,6,15,16,17,18,28,19,20,9,21,11,0,0,12,12,1,1,25,1,12,6,15,16,17,18,28,19,20,9,21,11,9,6,0,6,9,0,5,17,18,5,25,1,1,5,25,12,21,0,1,6,16,17,18,19,20,9,21,11,28,0,25,1,12,6,15,16,17,18,28,19,20,9,21,11,25,1,12,6,15,16,17,18,28,19,20,9,21,11,12,25,1,12,6,15,16,17,18,28,19,20,9,21,11,5,25,1,21,17,18,0,0,36,0,36,0,0,36,33,34,37,38,36,33,34,37,38,0,33,34,33,34,33,36,33,34,37,38,38,36,33,34,37,38,36,33,34,37,38,37,37,37,37,33,34,38,0,33,34,38,36,33,34,37,38,36,33,34,37,38,37,34,36,33,34,37,38,37,0,0,46,46,46,0,46,30,46,30,30,46,46,30,30,46,46,46,46,30,30,46,30,46,30,46,30,46,30,46,30,46,30,0,0,0,54,0,54,52,51,53,54,52,51,53,54,51,51,52,0,52,51,53,53,54,54,52,51,53,54,52,51,53,54,52,52,52,51,51,53,54,52,51,53,54,52,51,53,54,52,51,53,54,52,0,0,0,56,58,58,56,58,58,59,56,58,59,56,58,56,59,56,58,59,56,58,59,58,59,59,59,56,58,59,59,56,59,59,59,59,59,56,58,59,56,58,59,56,58,59,59,59,0,0,0,3,60,61,3,60,61,3,3,60,61,3,60,61,3,3,60,61,60,61,3,60,61,3,3,60,61,3,60,61,3,60,61,3,0,0,0,65,65,65,65,65,65,0,65,65,65,65,65,70,0,0,0,70,70,69,67,70,69,67,70,67,69,67,70,69,67,70,69,67,69,67,67,69,67,70,69,69,67,67,67,67,67,69,67,70,69,67,70,69,67,70,67,0,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72],"f":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[1,2],[[4,[[3,[2]]]]]],[[[6,[5]]],[[7,[5]]]],[[[6,[5]]],[[8,[5]]]],0,0,0,[9],[9],[[],[[4,[10]]]],[[],[[4,[10]]]],[[11,11]],[[11,11]],[[12,13,14],[[4,[10]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[15],0,[1,1],[6,6],[16,16],[17,17],[18,18],[19,19],[20,20],[9,9],[21,21],[11,11],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[1,20],4],[[12,[23,[[10,[22]]]]],4],[[1,20],4],[[19,19],24],[[20,20],24],[[11,11],24],[[],24],[[],24],[[],24],0,0,[[25,26],27],[[1,26],27],[[12,26],27],[[6,26],27],[[15,26],27],[[16,26],27],[[17,26],27],[[18,26],27],[[28,26],27],[[19,26],27],[[20,26],27],[[9,26],27],[[21,26],27],[[11,26],27],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,[12,21],[12,1],[[1,29],15],[[1,5,14],[[31,[20,[30,[5]]]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[6,[5]]],5],0,[[5,14],[[6,[5]]]],[9,10],0,[[18,19,14],[[31,[11]]]],0,0,[[25,28],4],[[25,2,17,16,19],4],[[1,[6,[5]]],[[4,[20]]]],[[1,20]],[[25,28],4],[[25,2,17,16,19],4],[[12,[23,[[10,[22]]]],14],4],[21],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[28,19],0,[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],[[4,[12]]]],[[],32],[[],32],[[],32],[[],32],[[],32],[[],32],[[],32],[[],32],[[],32],[[],32],[[],32],[[],32],[[],32],[[],32],[25,4],[[25,2],4],[[1,20],4],[21],0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[33,33],[34,34],[[]],[[]],[33],[[[36,[35]],26],27],[[[33,[35]],26],27],[[[34,[35]],26],27],[[[37,[35]],26],27],[[38,26],27],[[38,26],27],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[37,18,19,14],[[31,[11]]]],[37,[[31,[39]]]],[[37,25,28],4],[[37,25,28],4],[33,[[31,[40]]]],[34,[[31,[40]]]],[38,[[10,[41]]]],[42],[[]],[[]],[[],43],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[37,[[31,[44]]]],[34,[[31,[45]]]],[[],32],[[],32],[[],32],[[],32],[[],32],[[37,25],4],0,0,0,0,0,0,[[]],[[]],[[]],[[]],0,[[46,26],27],[[46,26],27],[[30,26],[[31,[47]]]],[[30,26],27],[[[48,[41]]],46],[49,46],[30,46],[[]],[[]],0,[[]],[[]],[46,[[10,[41]]]],[30,[[10,[41]]]],[[],43],[[],43],[[],31],[[],31],[[],31],[[],31],[[],32],[[],32],0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[51,[50]]],[[51,[50]]]],[[]],[52],[[],4],[[[52,[35]],26],27],[[[51,[35]],26],27],[[53,26],27],[[53,26],27],[[54,26],27],[[54,26],27],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[52,18,19,14],[[31,[11]]]],[[52,25,28],4],[[52,25,28],4],[[51,13],[[31,[53]]]],[[]],[[],43],[[],43],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],32],[[],32],[[],32],[[],32],[[52,25],4],0,0,0,[[[56,[55]]],57],[[[58,[2]]],57],[58],[[]],[58],[[]],[[]],[[]],[[]],[[]],[[[56,[55]]]],[58],[[[56,[55]]]],[[[59,[2]]]],[[[56,[[0,[35,55]]]],26],27],[[[58,[35]],26],27],[[[59,[[0,[35,2]],35]],26],27],[[]],[[]],[[]],[58],[[[59,[2]]],2],[[[59,[2]]],2],0,[[]],[[]],[[]],0,[55,[[56,[55]]]],[[2,17,16],[[59,[2,49]]]],[[2,17,16],[[59,[2]]]],[[[59,[2,[23,[[48,[41]]]]]],18,19,14],[[31,[11]]]],[[[59,[2,[23,[[48,[41]]]]]],25,28],4],[[[59,[2,[23,[[48,[41]]]]]],25,28],4],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],32],[[],32],[[],32],[[[59,[2,[23,[[48,[41]]]]]],25],4],[[[59,[2]]],2],0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[[3,[2]]]],[[[3,[[0,[2,35]]]],26],27],[[[60,[[0,[35,2]]]],26],27],[[[61,[[0,[35,2]]]],26],27],[[]],[[]],[[]],[[[3,[2]]],2],[[]],[[]],[[]],[[]],[[]],[[[3,[2]]],2],[[[62,[[60,[2]]]],63],64],[[[62,[[61,[2]]]],63],64],[[[3,[2]]],[[60,[2]]]],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],32],[[],32],[[],32],[[[3,[2]]],[[61,[2]]]],0,0,0,[[]],[[]],[[65,26],27],[[65,26],27],[[]],[[]],[[],66],[65,[[10,[41]]]],[[],43],[[],31],[[],31],[[],32],0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[67,[[10,[68]]]],[[69,26],27],[[67,26],27],[[70,26],27],[[]],[[]],[[]],[[1,68],69],[68,67],[[1,22],69],[22,67],[[],67],[[]],[[]],[[]],[[]],[[[62,[69]],63],64],[[67,18,19,14],[[31,[11]]]],[[67,25,28],4],[[67,25,28],4],[[67,68]],[[67,22]],[[],31],[[],31],[[],31],[[],31],[[],31],[[],31],[[],32],[[],32],[[],32],[[67,25],4],0,[[]],[[]],[[],[[72,[71]]]],[[[72,[35]],26],27],[[]],[5,[[72,[5]]]],[[]],[72,24],[[72,29],10],[[[72,[5]],18,19,14],[[31,[11]]]],[[[72,[5]],25,28],4],[72],[72],[[[72,[5]],25,28],4],[[],31],[[],31],[[],32],[[[72,[5]],25],4]],"c":[],"p":[[3,"LoopHandle"],[8,"AsFd"],[3,"Async"],[6,"Result"],[8,"EventSource"],[3,"Dispatcher"],[3,"RefMut"],[3,"Ref"],[3,"EventIterator"],[4,"Option"],[4,"PostAction"],[3,"EventLoop"],[8,"Future"],[8,"FnMut"],[3,"Idle"],[4,"Mode"],[3,"Interest"],[3,"Readiness"],[3,"Token"],[3,"RegistrationToken"],[3,"LoopSignal"],[3,"Duration"],[8,"Into"],[15,"bool"],[3,"Poll"],[3,"Formatter"],[6,"Result"],[3,"TokenFactory"],[8,"FnOnce"],[3,"InsertError"],[4,"Result"],[3,"TypeId"],[3,"Sender"],[3,"SyncSender"],[8,"Debug"],[4,"Event"],[3,"Channel"],[3,"ChannelError"],[3,"RecvError"],[3,"SendError"],[8,"Error"],[15,"usize"],[3,"String"],[4,"TryRecvError"],[4,"TrySendError"],[4,"Error"],[3,"Error"],[3,"Box"],[3,"Error"],[8,"Clone"],[3,"Scheduler"],[3,"Executor"],[3,"ExecutorDestroyed"],[4,"ExecutorError"],[8,"AsRawFd"],[3,"FdWrapper"],[3,"BorrowedFd"],[3,"NoIoDrop"],[3,"Generic"],[3,"Readable"],[3,"Writable"],[3,"Pin"],[3,"Context"],[4,"Poll"],[3,"PingError"],[6,"Result"],[3,"Timer"],[3,"Instant"],[3,"TimeoutFuture"],[4,"TimeoutAction"],[8,"Default"],[3,"TransientSource"]]}\ +}'); +if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)}; +if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex}; diff --git a/api/settings.html b/api/settings.html new file mode 100644 index 00000000..49efb469 --- /dev/null +++ b/api/settings.html @@ -0,0 +1 @@ +Rustdoc settings

Rustdoc settings

Back
\ No newline at end of file diff --git a/api/src-files.js b/api/src-files.js new file mode 100644 index 00000000..b2340c23 --- /dev/null +++ b/api/src-files.js @@ -0,0 +1,4 @@ +var srcIndex = JSON.parse('{\ +"calloop":["",[["sources",[["ping",[],["eventfd.rs"]]],["channel.rs","futures.rs","generic.rs","mod.rs","ping.rs","timer.rs","transient.rs"]]],["error.rs","io.rs","lib.rs","loop_logic.rs","macros.rs","sys.rs"]]\ +}'); +createSrcSidebar(); diff --git a/api/src/calloop/error.rs.html b/api/src/calloop/error.rs.html new file mode 100644 index 00000000..31876d18 --- /dev/null +++ b/api/src/calloop/error.rs.html @@ -0,0 +1,167 @@ +error.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+
//! Error types used and generated by Calloop.
+//!
+//! This module contains error types for Calloop's operations. They are designed
+//! to make it easy to deal with errors arising from Calloop's internal I/O and
+//! other operations.
+//!
+//! There are two top-level error types:
+//!
+//! - [`Error`]: used by callback functions, internal operations, and some event
+//!   loop API calls
+//!
+//! - [`InsertError`]: used primarily by the [`insert_source()`] method when an
+//!   event source cannot be added to the loop and needs to be given back to the
+//!   caller
+//!
+//! [`insert_source()`]: crate::LoopHandle::insert_source()
+
+use std::fmt::{self, Debug, Formatter};
+
+/// The primary error type used by Calloop covering internal errors and I/O
+/// errors that arise during loop operations such as source registration or
+/// event dispatching.
+#[derive(thiserror::Error, Debug)]
+pub enum Error {
+    /// When an event source is registered (or re- or un-registered) with the
+    /// event loop, this error variant will occur if the token Calloop uses to
+    /// keep track of the event source is not valid.
+    #[error("invalid token provided to internal function")]
+    InvalidToken,
+
+    /// This variant wraps a [`std::io::Error`], which might arise from
+    /// Calloop's internal operations.
+    #[error("underlying IO error")]
+    IoError(#[from] std::io::Error),
+
+    /// Any other unexpected error kind (most likely from a user implementation of
+    /// [`EventSource::process_events()`]) will be wrapped in this.
+    ///
+    /// [`EventSource::process_events()`]: crate::EventSource::process_events()
+    #[error("other error during loop operation")]
+    OtherError(#[from] Box<dyn std::error::Error + Sync + Send>),
+}
+
+impl From<Error> for std::io::Error {
+    /// Converts Calloop's error type into a [`std::io::Error`].
+    fn from(err: Error) -> Self {
+        match err {
+            Error::IoError(source) => source,
+            Error::InvalidToken => Self::new(std::io::ErrorKind::InvalidInput, err.to_string()),
+            Error::OtherError(source) => Self::new(std::io::ErrorKind::Other, source),
+        }
+    }
+}
+
+/// [`Result`] alias using Calloop's error type.
+pub type Result<T> = core::result::Result<T, Error>;
+
+/// An error generated when trying to insert an event source
+#[derive(thiserror::Error)]
+#[error("error inserting event source")]
+pub struct InsertError<T> {
+    /// The source that could not be inserted
+    pub inserted: T,
+    /// The generated error
+    #[source]
+    pub error: Error,
+}
+
+impl<T> Debug for InsertError<T> {
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))]
+    fn fmt(&self, formatter: &mut Formatter) -> core::result::Result<(), fmt::Error> {
+        write!(formatter, "{:?}", self.error)
+    }
+}
+
+impl<T> From<InsertError<T>> for crate::Error {
+    /// Converts the [`InsertError`] into Calloop's error type, throwing away
+    /// the contained source.
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))]
+    fn from(e: InsertError<T>) -> crate::Error {
+        e.error
+    }
+}
+
\ No newline at end of file diff --git a/api/src/calloop/io.rs.html b/api/src/calloop/io.rs.html new file mode 100644 index 00000000..e33cafbe --- /dev/null +++ b/api/src/calloop/io.rs.html @@ -0,0 +1,1129 @@ +io.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+
//! Adapters for async IO objects
+//!
+//! This module mainly hosts the [`Async`] adapter for making IO objects async with readiness
+//! monitoring backed by an [`EventLoop`](crate::EventLoop). See [`LoopHandle::adapt_io`] for
+//! how to create them.
+//!
+//! [`LoopHandle::adapt_io`]: crate::LoopHandle#method.adapt_io
+
+use std::cell::RefCell;
+use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
+use std::pin::Pin;
+use std::rc::Rc;
+use std::task::{Context, Poll as TaskPoll, Waker};
+
+use rustix::fs::{fcntl_getfl, fcntl_setfl, OFlags};
+
+#[cfg(feature = "futures-io")]
+use futures_io::{AsyncRead, AsyncWrite, IoSlice, IoSliceMut};
+
+use crate::loop_logic::EventIterator;
+use crate::{
+    loop_logic::{LoopInner, MAX_SOURCES_MASK},
+    sources::EventDispatcher,
+    Interest, Mode, Poll, PostAction, Readiness, Token, TokenFactory,
+};
+use crate::{AdditionalLifecycleEventsSet, RegistrationToken};
+
+/// Adapter for async IO manipulations
+///
+/// This type wraps an IO object, providing methods to create futures waiting for its
+/// readiness.
+///
+/// If the `futures-io` cargo feature is enabled, it also implements `AsyncRead` and/or
+/// `AsyncWrite` if the underlying type implements `Read` and/or `Write`.
+///
+/// Note that this adapter and the futures procuded from it and *not* threadsafe.
+pub struct Async<'l, F: AsFd> {
+    fd: Option<F>,
+    dispatcher: Rc<RefCell<IoDispatcher>>,
+    inner: Rc<dyn IoLoopInner + 'l>,
+    old_flags: OFlags,
+}
+
+impl<'l, F: AsFd + std::fmt::Debug> std::fmt::Debug for Async<'l, F> {
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))]
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("Async").field("fd", &self.fd).finish()
+    }
+}
+
+impl<'l, F: AsFd> Async<'l, F> {
+    pub(crate) fn new<Data>(inner: Rc<LoopInner<'l, Data>>, fd: F) -> crate::Result<Async<'l, F>> {
+        // set non-blocking
+        let old_flags = fcntl_getfl(&fd).map_err(std::io::Error::from)?;
+        fcntl_setfl(&fd, old_flags | OFlags::NONBLOCK).map_err(std::io::Error::from)?;
+        // register in the loop
+        let dispatcher = Rc::new(RefCell::new(IoDispatcher {
+            fd: fd.as_fd().as_raw_fd(),
+            token: None,
+            waker: None,
+            is_registered: false,
+            interest: Interest::EMPTY,
+            last_readiness: Readiness::EMPTY,
+        }));
+        let key = inner.sources.borrow_mut().insert(dispatcher.clone());
+        dispatcher.borrow_mut().token = Some(Token { key });
+
+        // SAFETY: We are sure to deregister on drop.
+        unsafe {
+            inner.register(&dispatcher)?;
+        }
+
+        // Straightforward casting would require us to add the bound `Data: 'l` but we don't actually need it
+        // as this module never accesses the dispatch data, so we use transmute to erase it
+        let inner: Rc<dyn IoLoopInner + 'l> =
+            unsafe { std::mem::transmute(inner as Rc<dyn IoLoopInner>) };
+
+        Ok(Async {
+            fd: Some(fd),
+            dispatcher,
+            inner,
+            old_flags,
+        })
+    }
+
+    /// Mutably access the underlying IO object
+    pub fn get_mut(&mut self) -> &mut F {
+        self.fd.as_mut().unwrap()
+    }
+
+    /// A future that resolves once the object becomes ready for reading
+    pub fn readable<'s>(&'s mut self) -> Readable<'s, 'l, F> {
+        Readable { io: self }
+    }
+
+    /// A future that resolves once the object becomes ready for writing
+    pub fn writable<'s>(&'s mut self) -> Writable<'s, 'l, F> {
+        Writable { io: self }
+    }
+
+    /// Remove the async adapter and retrieve the underlying object
+    pub fn into_inner(mut self) -> F {
+        self.fd.take().unwrap()
+    }
+
+    fn readiness(&self) -> Readiness {
+        self.dispatcher.borrow_mut().readiness()
+    }
+
+    fn register_waker(&self, interest: Interest, waker: Waker) -> crate::Result<()> {
+        {
+            let mut disp = self.dispatcher.borrow_mut();
+            disp.interest = interest;
+            disp.waker = Some(waker);
+        }
+        self.inner.reregister(&self.dispatcher)
+    }
+}
+
+/// A future that resolves once the associated object becomes ready for reading
+#[derive(Debug)]
+pub struct Readable<'s, 'l, F: AsFd> {
+    io: &'s mut Async<'l, F>,
+}
+
+impl<'s, 'l, F: AsFd> std::future::Future for Readable<'s, 'l, F> {
+    type Output = ();
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> TaskPoll<()> {
+        let io = &mut self.as_mut().io;
+        let readiness = io.readiness();
+        if readiness.readable || readiness.error {
+            TaskPoll::Ready(())
+        } else {
+            let _ = io.register_waker(Interest::READ, cx.waker().clone());
+            TaskPoll::Pending
+        }
+    }
+}
+
+/// A future that resolves once the associated object becomes ready for writing
+#[derive(Debug)]
+pub struct Writable<'s, 'l, F: AsFd> {
+    io: &'s mut Async<'l, F>,
+}
+
+impl<'s, 'l, F: AsFd> std::future::Future for Writable<'s, 'l, F> {
+    type Output = ();
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> TaskPoll<()> {
+        let io = &mut self.as_mut().io;
+        let readiness = io.readiness();
+        if readiness.writable || readiness.error {
+            TaskPoll::Ready(())
+        } else {
+            let _ = io.register_waker(Interest::WRITE, cx.waker().clone());
+            TaskPoll::Pending
+        }
+    }
+}
+
+impl<'l, F: AsFd> Drop for Async<'l, F> {
+    fn drop(&mut self) {
+        self.inner.kill(&self.dispatcher);
+        // restore flags
+        let _ = fcntl_setfl(
+            unsafe { BorrowedFd::borrow_raw(self.dispatcher.borrow().fd) },
+            self.old_flags,
+        );
+    }
+}
+
+impl<'l, F: AsFd> Unpin for Async<'l, F> {}
+
+trait IoLoopInner {
+    unsafe fn register(&self, dispatcher: &RefCell<IoDispatcher>) -> crate::Result<()>;
+    fn reregister(&self, dispatcher: &RefCell<IoDispatcher>) -> crate::Result<()>;
+    fn kill(&self, dispatcher: &RefCell<IoDispatcher>);
+}
+
+impl<'l, Data> IoLoopInner for LoopInner<'l, Data> {
+    unsafe fn register(&self, dispatcher: &RefCell<IoDispatcher>) -> crate::Result<()> {
+        let disp = dispatcher.borrow();
+        self.poll.borrow_mut().register(
+            unsafe { BorrowedFd::borrow_raw(disp.fd) },
+            Interest::EMPTY,
+            Mode::OneShot,
+            disp.token.expect("No token for IO dispatcher"),
+        )
+    }
+
+    fn reregister(&self, dispatcher: &RefCell<IoDispatcher>) -> crate::Result<()> {
+        let disp = dispatcher.borrow();
+        self.poll.borrow_mut().reregister(
+            unsafe { BorrowedFd::borrow_raw(disp.fd) },
+            disp.interest,
+            Mode::OneShot,
+            disp.token.expect("No token for IO dispatcher"),
+        )
+    }
+
+    fn kill(&self, dispatcher: &RefCell<IoDispatcher>) {
+        let key = dispatcher
+            .borrow()
+            .token
+            .expect("No token for IO dispatcher")
+            .key
+            & MAX_SOURCES_MASK;
+        let _source = self
+            .sources
+            .borrow_mut()
+            .try_remove(key)
+            .expect("Attempting to remove a non-existent source?!");
+    }
+}
+
+struct IoDispatcher {
+    fd: RawFd, // FIXME: `BorrowedFd`? How to statically verify it doesn't outlive file?
+    token: Option<Token>,
+    waker: Option<Waker>,
+    is_registered: bool,
+    interest: Interest,
+    last_readiness: Readiness,
+}
+
+impl IoDispatcher {
+    fn readiness(&mut self) -> Readiness {
+        std::mem::replace(&mut self.last_readiness, Readiness::EMPTY)
+    }
+}
+
+impl<Data> EventDispatcher<Data> for RefCell<IoDispatcher> {
+    fn process_events(
+        &self,
+        readiness: Readiness,
+        _token: Token,
+        _data: &mut Data,
+    ) -> crate::Result<PostAction> {
+        let mut disp = self.borrow_mut();
+        disp.last_readiness = readiness;
+        if let Some(waker) = disp.waker.take() {
+            waker.wake();
+        }
+        Ok(PostAction::Continue)
+    }
+
+    fn register(
+        &self,
+        _: &mut Poll,
+        _: &mut AdditionalLifecycleEventsSet,
+        _: &mut TokenFactory,
+    ) -> crate::Result<()> {
+        // registration is handled by IoLoopInner
+        unreachable!()
+    }
+
+    fn reregister(
+        &self,
+        _: &mut Poll,
+        _: &mut AdditionalLifecycleEventsSet,
+        _: &mut TokenFactory,
+    ) -> crate::Result<bool> {
+        // registration is handled by IoLoopInner
+        unreachable!()
+    }
+
+    fn unregister(
+        &self,
+        poll: &mut Poll,
+        _: &mut AdditionalLifecycleEventsSet,
+        _: RegistrationToken,
+    ) -> crate::Result<bool> {
+        let disp = self.borrow();
+        if disp.is_registered {
+            poll.unregister(unsafe { BorrowedFd::borrow_raw(disp.fd) })?;
+        }
+        Ok(true)
+    }
+
+    fn before_sleep(&self) -> crate::Result<Option<(Readiness, Token)>> {
+        Ok(None)
+    }
+    fn before_handle_events(&self, _: EventIterator<'_>) {}
+}
+
+/*
+ * Async IO trait implementations
+ */
+
+#[cfg(feature = "futures-io")]
+#[cfg_attr(docsrs, doc(cfg(feature = "futures-io")))]
+impl<'l, F: AsFd + std::io::Read> AsyncRead for Async<'l, F> {
+    fn poll_read(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        buf: &mut [u8],
+    ) -> TaskPoll<std::io::Result<usize>> {
+        match (*self).get_mut().read(buf) {
+            Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => {}
+            res => return TaskPoll::Ready(res),
+        }
+        self.register_waker(Interest::READ, cx.waker().clone())?;
+        TaskPoll::Pending
+    }
+
+    fn poll_read_vectored(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        bufs: &mut [IoSliceMut<'_>],
+    ) -> TaskPoll<std::io::Result<usize>> {
+        match (*self).get_mut().read_vectored(bufs) {
+            Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => {}
+            res => return TaskPoll::Ready(res),
+        }
+        self.register_waker(Interest::READ, cx.waker().clone())?;
+        TaskPoll::Pending
+    }
+}
+
+#[cfg(feature = "futures-io")]
+#[cfg_attr(docsrs, doc(cfg(feature = "futures-io")))]
+impl<'l, F: AsFd + std::io::Write> AsyncWrite for Async<'l, F> {
+    fn poll_write(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        buf: &[u8],
+    ) -> TaskPoll<std::io::Result<usize>> {
+        match (*self).get_mut().write(buf) {
+            Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => {}
+            res => return TaskPoll::Ready(res),
+        }
+        self.register_waker(Interest::WRITE, cx.waker().clone())?;
+        TaskPoll::Pending
+    }
+
+    fn poll_write_vectored(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        bufs: &[IoSlice<'_>],
+    ) -> TaskPoll<std::io::Result<usize>> {
+        match (*self).get_mut().write_vectored(bufs) {
+            Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => {}
+            res => return TaskPoll::Ready(res),
+        }
+        self.register_waker(Interest::WRITE, cx.waker().clone())?;
+        TaskPoll::Pending
+    }
+
+    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> TaskPoll<std::io::Result<()>> {
+        match (*self).get_mut().flush() {
+            Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => {}
+            res => return TaskPoll::Ready(res),
+        }
+        self.register_waker(Interest::WRITE, cx.waker().clone())?;
+        TaskPoll::Pending
+    }
+
+    fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> TaskPoll<std::io::Result<()>> {
+        self.poll_flush(cx)
+    }
+}
+
+#[cfg(all(test, feature = "executor", feature = "futures-io"))]
+mod tests {
+    use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+    use crate::sources::futures::executor;
+
+    #[test]
+    fn read_write() {
+        let mut event_loop = crate::EventLoop::try_new().unwrap();
+        let handle = event_loop.handle();
+        let (exec, sched) = executor().unwrap();
+        handle
+            .insert_source(exec, move |ret, &mut (), got| {
+                *got = ret;
+            })
+            .unwrap();
+
+        let (tx, rx) = std::os::unix::net::UnixStream::pair().unwrap();
+        let mut tx = handle.adapt_io(tx).unwrap();
+        let mut rx = handle.adapt_io(rx).unwrap();
+        let received = std::rc::Rc::new(std::cell::Cell::new(false));
+        let fut_received = received.clone();
+
+        sched
+            .schedule(async move {
+                let mut buf = [0; 12];
+                rx.read_exact(&mut buf).await.unwrap();
+                assert_eq!(&buf, b"Hello World!");
+                fut_received.set(true);
+            })
+            .unwrap();
+
+        // The receiving future alone cannot advance
+        event_loop
+            .dispatch(Some(std::time::Duration::from_millis(10)), &mut ())
+            .unwrap();
+        assert!(!received.get());
+
+        // schedule the writing future as well and wait until finish
+        sched
+            .schedule(async move {
+                tx.write_all(b"Hello World!").await.unwrap();
+                tx.flush().await.unwrap();
+            })
+            .unwrap();
+
+        while !received.get() {
+            event_loop.dispatch(None, &mut ()).unwrap();
+        }
+    }
+
+    #[test]
+    fn read_write_vectored() {
+        let mut event_loop = crate::EventLoop::try_new().unwrap();
+        let handle = event_loop.handle();
+        let (exec, sched) = executor().unwrap();
+        handle
+            .insert_source(exec, move |ret, &mut (), got| {
+                *got = ret;
+            })
+            .unwrap();
+
+        let (tx, rx) = std::os::unix::net::UnixStream::pair().unwrap();
+        let mut tx = handle.adapt_io(tx).unwrap();
+        let mut rx = handle.adapt_io(rx).unwrap();
+        let received = std::rc::Rc::new(std::cell::Cell::new(false));
+        let fut_received = received.clone();
+
+        sched
+            .schedule(async move {
+                let mut buf = [0; 12];
+                let mut ioslices = buf
+                    .chunks_mut(2)
+                    .map(std::io::IoSliceMut::new)
+                    .collect::<Vec<_>>();
+                let count = rx.read_vectored(&mut ioslices).await.unwrap();
+                assert_eq!(count, 12);
+                assert_eq!(&buf, b"Hello World!");
+                fut_received.set(true);
+            })
+            .unwrap();
+
+        // The receiving future alone cannot advance
+        event_loop
+            .dispatch(Some(std::time::Duration::from_millis(10)), &mut ())
+            .unwrap();
+        assert!(!received.get());
+
+        // schedule the writing future as well and wait until finish
+        sched
+            .schedule(async move {
+                let buf = b"Hello World!";
+                let ioslices = buf.chunks(2).map(std::io::IoSlice::new).collect::<Vec<_>>();
+                let count = tx.write_vectored(&ioslices).await.unwrap();
+                assert_eq!(count, 12);
+                tx.flush().await.unwrap();
+            })
+            .unwrap();
+
+        while !received.get() {
+            event_loop.dispatch(None, &mut ()).unwrap();
+        }
+    }
+
+    #[test]
+    fn readable() {
+        use std::io::Write;
+
+        let mut event_loop = crate::EventLoop::try_new().unwrap();
+        let handle = event_loop.handle();
+        let (exec, sched) = executor().unwrap();
+        handle
+            .insert_source(exec, move |(), &mut (), got| {
+                *got = true;
+            })
+            .unwrap();
+
+        let (mut tx, rx) = std::os::unix::net::UnixStream::pair().unwrap();
+
+        let mut rx = handle.adapt_io(rx).unwrap();
+        sched
+            .schedule(async move {
+                rx.readable().await;
+            })
+            .unwrap();
+
+        let mut dispatched = false;
+
+        event_loop
+            .dispatch(Some(std::time::Duration::from_millis(100)), &mut dispatched)
+            .unwrap();
+        // The socket is not yet readable, so the readable() future has not completed
+        assert!(!dispatched);
+
+        tx.write_all(&[42]).unwrap();
+        tx.flush().unwrap();
+
+        // Now we should become readable
+        while !dispatched {
+            event_loop.dispatch(None, &mut dispatched).unwrap();
+        }
+    }
+
+    #[test]
+    fn writable() {
+        use std::io::{BufReader, BufWriter, Read, Write};
+
+        let mut event_loop = crate::EventLoop::try_new().unwrap();
+        let handle = event_loop.handle();
+        let (exec, sched) = executor().unwrap();
+        handle
+            .insert_source(exec, move |(), &mut (), got| {
+                *got = true;
+            })
+            .unwrap();
+
+        let (mut tx, mut rx) = std::os::unix::net::UnixStream::pair().unwrap();
+        tx.set_nonblocking(true).unwrap();
+        rx.set_nonblocking(true).unwrap();
+
+        // First, fill the socket buffers
+        {
+            let mut writer = BufWriter::new(&mut tx);
+            let data = vec![42u8; 1024];
+            loop {
+                if writer.write(&data).is_err() {
+                    break;
+                }
+            }
+        }
+
+        // Now, wait for it to be readable
+        let mut tx = handle.adapt_io(tx).unwrap();
+        sched
+            .schedule(async move {
+                tx.writable().await;
+            })
+            .unwrap();
+
+        let mut dispatched = false;
+
+        event_loop
+            .dispatch(Some(std::time::Duration::from_millis(100)), &mut dispatched)
+            .unwrap();
+        // The socket is not yet writable, so the readable() future has not completed
+        assert!(!dispatched);
+
+        // now read everything
+        {
+            let mut reader = BufReader::new(&mut rx);
+            let mut buffer = vec![0u8; 1024];
+            loop {
+                if reader.read(&mut buffer).is_err() {
+                    break;
+                }
+            }
+        }
+
+        // Now we should become writable
+        while !dispatched {
+            event_loop.dispatch(None, &mut dispatched).unwrap();
+        }
+    }
+}
+
\ No newline at end of file diff --git a/api/src/calloop/lib.rs.html b/api/src/calloop/lib.rs.html new file mode 100644 index 00000000..6fe5508c --- /dev/null +++ b/api/src/calloop/lib.rs.html @@ -0,0 +1,323 @@ +lib.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+
//! Calloop, a Callback-based Event Loop
+//!
+//! This crate provides an [`EventLoop`] type, which is a small abstraction
+//! over a polling system. The main difference between this crate
+//! and other traditional rust event loops is that it is based on callbacks:
+//! you can register several event sources, each being associated with a callback
+//! closure that will be invoked whenever the associated event source generates
+//! events.
+//!
+//! The main target use of this event loop is thus for apps that expect to spend
+//! most of their time waiting for events and wishes to do so in a cheap and convenient
+//! way. It is not meant for large scale high performance IO.
+//!
+//! ## How to use it
+//!
+//! Below is a quick usage example of calloop. For a more in-depth tutorial, see
+//! the [calloop book](https://smithay.github.io/calloop).
+//!
+//! For simple uses, you can just add event sources with callbacks to the event
+//! loop. For example, here's a runnable program that exits after five seconds:
+//!
+//! ```no_run
+//! use calloop::{timer::{Timer, TimeoutAction}, EventLoop, LoopSignal};
+//!
+//! fn main() {
+//!     // Create the event loop. The loop is parameterised by the kind of shared
+//!     // data you want the callbacks to use. In this case, we want to be able to
+//!     // stop the loop when the timer fires, so we provide the loop with a
+//!     // LoopSignal, which has the ability to stop the loop from within events. We
+//!     // just annotate the type here; the actual data is provided later in the
+//!     // run() call.
+//!     let mut event_loop: EventLoop<LoopSignal> =
+//!         EventLoop::try_new().expect("Failed to initialize the event loop!");
+//!
+//!     // Retrieve a handle. It is used to insert new sources into the event loop
+//!     // It can be cloned, allowing you to insert sources from within source
+//!     // callbacks.
+//!     let handle = event_loop.handle();
+//!
+//!     // Create our event source, a timer, that will expire in 2 seconds
+//!     let source = Timer::from_duration(std::time::Duration::from_secs(2));
+//!
+//!     // Inserting an event source takes this general form. It can also be done
+//!     // from within the callback of another event source.
+//!     handle
+//!         .insert_source(
+//!             // a type which implements the EventSource trait
+//!             source,
+//!             // a callback that is invoked whenever this source generates an event
+//!             |event, _metadata, shared_data| {
+//!                 // This callback is given 3 values:
+//!                 // - the event generated by the source (in our case, timer events are the Instant
+//!                 //   representing the deadline for which it has fired)
+//!                 // - &mut access to some metadata, specific to the event source (in our case, a
+//!                 //   timer handle)
+//!                 // - &mut access to the global shared data that was passed to EventLoop::run or
+//!                 //   EventLoop::dispatch (in our case, a LoopSignal object to stop the loop)
+//!                 //
+//!                 // The return type is just () because nothing uses it. Some
+//!                 // sources will expect a Result of some kind instead.
+//!                 println!("Timeout for {:?} expired!", event);
+//!                 // notify the event loop to stop running using the signal in the shared data
+//!                 // (see below)
+//!                 shared_data.stop();
+//!                 // The timer event source requires us to return a TimeoutAction to
+//!                 // specify if the timer should be rescheduled. In our case we just drop it.
+//!                 TimeoutAction::Drop
+//!             },
+//!         )
+//!         .expect("Failed to insert event source!");
+//!
+//!     // Create the shared data for our loop.
+//!     let mut shared_data = event_loop.get_signal();
+//!
+//!     // Actually run the event loop. This will dispatch received events to their
+//!     // callbacks, waiting at most 20ms for new events between each invocation of
+//!     // the provided callback (pass None for the timeout argument if you want to
+//!     // wait indefinitely between events).
+//!     //
+//!     // This is where we pass the *value* of the shared data, as a mutable
+//!     // reference that will be forwarded to all your callbacks, allowing them to
+//!     // share some state
+//!     event_loop
+//!         .run(
+//!             std::time::Duration::from_millis(20),
+//!             &mut shared_data,
+//!             |_shared_data| {
+//!                 // Finally, this is where you can insert the processing you need
+//!                 // to do do between each waiting event eg. drawing logic if
+//!                 // you're doing a GUI app.
+//!             },
+//!         )
+//!         .expect("Error during event loop!");
+//! }
+//! ```
+//!
+//! ## Event source types
+//!
+//! The event loop is backed by an OS provided polling selector (epoll on Linux).
+//!
+//! This crate also provide some adapters for common event sources such as:
+//!
+//! - [MPSC channels](channel)
+//! - [Timers](timer)
+//! - [unix signals](signals) on Linux
+//!
+//! As well as generic objects backed by file descriptors.
+//!
+//! It is also possible to insert "idle" callbacks. These callbacks represent computations that
+//! need to be done at some point, but are not as urgent as processing the events. These callbacks
+//! are stored and then executed during [`EventLoop::dispatch`](EventLoop#method.dispatch), once all
+//! events from the sources have been processed.
+//!
+//! ## Async/Await compatibility
+//!
+//! `calloop` can be used with futures, both as an executor and for monitoring Async IO.
+//!
+//! Activating the `executor` cargo feature will add the [`futures`] module, which provides
+//! a future executor that can be inserted into an [`EventLoop`] as yet another [`EventSource`].
+//!
+//! IO objects can be made Async-aware via the [`LoopHandle::adapt_io`](LoopHandle#method.adapt_io)
+//! method. Waking up the futures using these objects is handled by the associated [`EventLoop`]
+//! directly.
+//!
+//! ## Custom event sources
+//!
+//! You can create custom event sources can will be inserted in the event loop by
+//! implementing the [`EventSource`] trait. This can be done either directly from the file
+//! descriptors of your source of interest, or by wrapping an other event source and further
+//! processing its events. An [`EventSource`] can register more than one file descriptor and
+//! aggregate them.
+//!
+//! ## Platforms support
+//!
+//! Currently, calloop is tested on Linux, FreeBSD and macOS.
+//!
+//! The following platforms are also enabled at compile time but not tested: Android, NetBSD,
+//! OpenBSD, DragonFlyBSD.
+//!
+//! Those platforms *should* work based on the fact that they have the same polling mechanism as
+//! tested platforms, but some subtle bugs might still occur.
+
+#![warn(missing_docs, missing_debug_implementations)]
+#![allow(clippy::needless_doctest_main)]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![cfg_attr(feature = "nightly_coverage", feature(coverage_attribute))]
+
+mod sys;
+
+pub use sys::{Interest, Mode, Poll, Readiness, Token, TokenFactory};
+
+pub use self::loop_logic::{EventLoop, LoopHandle, LoopSignal, RegistrationToken};
+pub use self::sources::*;
+
+pub mod error;
+pub use error::{Error, InsertError, Result};
+
+pub mod io;
+mod loop_logic;
+mod macros;
+mod sources;
+
\ No newline at end of file diff --git a/api/src/calloop/loop_logic.rs.html b/api/src/calloop/loop_logic.rs.html new file mode 100644 index 00000000..785995fe --- /dev/null +++ b/api/src/calloop/loop_logic.rs.html @@ -0,0 +1,2911 @@ +loop_logic.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+
use std::cell::{Cell, RefCell};
+use std::fmt::Debug;
+use std::os::unix::io::AsFd;
+use std::rc::Rc;
+use std::sync::atomic::{AtomicBool, Ordering};
+use std::sync::Arc;
+use std::time::{Duration, Instant};
+use std::{io, slice};
+
+#[cfg(feature = "block_on")]
+use std::future::Future;
+
+use slab::Slab;
+
+use crate::sources::{Dispatcher, EventSource, Idle, IdleDispatcher};
+use crate::sys::{Notifier, PollEvent};
+use crate::{
+    AdditionalLifecycleEventsSet, EventDispatcher, InsertError, Poll, PostAction, Readiness, Token,
+    TokenFactory,
+};
+
+type IdleCallback<'i, Data> = Rc<RefCell<dyn IdleDispatcher<Data> + 'i>>;
+
+// The number of bits used to store the source ID.
+//
+// This plus `MAX_SUBSOURCES` must equal the number of bits in `usize`.
+#[cfg(target_pointer_width = "64")]
+pub(crate) const MAX_SOURCES: u32 = 44;
+#[cfg(target_pointer_width = "32")]
+pub(crate) const MAX_SOURCES: u32 = 22;
+#[cfg(target_pointer_width = "16")]
+pub(crate) const MAX_SOURCES: u32 = 10;
+
+// The number of bits used to store the sub-source ID.
+//
+// This plus `MAX_SOURCES` must equal the number of bits in `usize`.
+#[cfg(target_pointer_width = "64")]
+pub(crate) const MAX_SUBSOURCES: u32 = 20;
+#[cfg(target_pointer_width = "32")]
+pub(crate) const MAX_SUBSOURCES: u32 = 10;
+#[cfg(target_pointer_width = "16")]
+pub(crate) const MAX_SUBSOURCES: u32 = 6;
+
+pub(crate) const MAX_SOURCES_TOTAL: usize = 1 << MAX_SOURCES;
+pub(crate) const MAX_SUBSOURCES_TOTAL: usize = 1 << MAX_SUBSOURCES;
+pub(crate) const MAX_SOURCES_MASK: usize = MAX_SOURCES_TOTAL - 1;
+
+/// A token representing a registration in the [`EventLoop`].
+///
+/// This token is given to you by the [`EventLoop`] when an [`EventSource`] is inserted or
+/// a [`Dispatcher`] is registered. You can use it to [disable](LoopHandle#method.disable),
+/// [enable](LoopHandle#method.enable), [update`](LoopHandle#method.update),
+/// [remove](LoopHandle#method.remove) or [kill](LoopHandle#method.kill) it.
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub struct RegistrationToken {
+    key: usize,
+}
+
+impl RegistrationToken {
+    /// Create the RegistrationToken corresponding to the given raw key
+    /// This is needed because some methods use `RegistrationToken`s as
+    /// raw usizes within this crate
+    pub(crate) fn new(key: usize) -> Self {
+        Self { key }
+    }
+}
+
+pub(crate) struct LoopInner<'l, Data> {
+    pub(crate) poll: RefCell<Poll>,
+    pub(crate) sources: RefCell<Slab<Rc<dyn EventDispatcher<Data> + 'l>>>,
+    pub(crate) sources_with_additional_lifecycle_events: RefCell<AdditionalLifecycleEventsSet>,
+    idles: RefCell<Vec<IdleCallback<'l, Data>>>,
+    pending_action: Cell<PostAction>,
+}
+
+/// An handle to an event loop
+///
+/// This handle allows you to insert new sources and idles in this event loop,
+/// it can be cloned, and it is possible to insert new sources from within a source
+/// callback.
+pub struct LoopHandle<'l, Data> {
+    inner: Rc<LoopInner<'l, Data>>,
+}
+
+impl<'l, Data> std::fmt::Debug for LoopHandle<'l, Data> {
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))]
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.write_str("LoopHandle { ... }")
+    }
+}
+
+impl<'l, Data> Clone for LoopHandle<'l, Data> {
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))]
+    fn clone(&self) -> Self {
+        LoopHandle {
+            inner: self.inner.clone(),
+        }
+    }
+}
+
+impl<'l, Data> LoopHandle<'l, Data> {
+    /// Inserts a new event source in the loop.
+    ///
+    /// The provided callback will be called during the dispatching cycles whenever the
+    /// associated source generates events, see `EventLoop::dispatch(..)` for details.
+    ///
+    /// This function takes ownership of the event source. Use `register_dispatcher`
+    /// if you need access to the event source after this call.
+    pub fn insert_source<S, F>(
+        &self,
+        source: S,
+        callback: F,
+    ) -> Result<RegistrationToken, InsertError<S>>
+    where
+        S: EventSource + 'l,
+        F: FnMut(S::Event, &mut S::Metadata, &mut Data) -> S::Ret + 'l,
+    {
+        let dispatcher = Dispatcher::new(source, callback);
+        self.register_dispatcher(dispatcher.clone())
+            .map_err(|error| InsertError {
+                error,
+                inserted: dispatcher.into_source_inner(),
+            })
+    }
+
+    /// Registers a `Dispatcher` in the loop.
+    ///
+    /// Use this function if you need access to the event source after its insertion in the loop.
+    ///
+    /// See also `insert_source`.
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))] // Contains a branch we can't hit w/o OOM
+    pub fn register_dispatcher<S>(
+        &self,
+        dispatcher: Dispatcher<'l, S, Data>,
+    ) -> crate::Result<RegistrationToken>
+    where
+        S: EventSource + 'l,
+    {
+        let mut sources = self.inner.sources.borrow_mut();
+        let mut poll = self.inner.poll.borrow_mut();
+
+        // Make sure we won't overflow the token.
+        if sources.vacant_key() >= MAX_SOURCES_TOTAL {
+            return Err(crate::Error::IoError(std::io::Error::new(
+                std::io::ErrorKind::Other,
+                "Too many sources",
+            )));
+        }
+
+        let key = sources.insert(dispatcher.clone_as_event_dispatcher());
+        let ret = sources.get(key).unwrap().register(
+            &mut poll,
+            &mut self
+                .inner
+                .sources_with_additional_lifecycle_events
+                .borrow_mut(),
+            &mut TokenFactory::new(key),
+        );
+
+        if let Err(error) = ret {
+            sources.try_remove(key).expect("Source was just inserted?!");
+            return Err(error);
+        }
+
+        Ok(RegistrationToken { key })
+    }
+
+    /// Inserts an idle callback.
+    ///
+    /// This callback will be called during a dispatching cycle when the event loop has
+    /// finished processing all pending events from the sources and becomes idle.
+    pub fn insert_idle<'i, F: FnOnce(&mut Data) + 'l + 'i>(&self, callback: F) -> Idle<'i> {
+        let mut opt_cb = Some(callback);
+        let callback = Rc::new(RefCell::new(Some(move |data: &mut Data| {
+            if let Some(cb) = opt_cb.take() {
+                cb(data);
+            }
+        })));
+        self.inner.idles.borrow_mut().push(callback.clone());
+        Idle { callback }
+    }
+
+    /// Enables this previously disabled event source.
+    ///
+    /// This previously disabled source will start generating events again.
+    ///
+    /// **Note:** this cannot be done from within the source callback.
+    pub fn enable(&self, token: &RegistrationToken) -> crate::Result<()> {
+        if let Some(source) = self.inner.sources.borrow().get(token.key) {
+            source.register(
+                &mut self.inner.poll.borrow_mut(),
+                &mut self
+                    .inner
+                    .sources_with_additional_lifecycle_events
+                    .borrow_mut(),
+                &mut TokenFactory::new(token.key),
+            )?;
+        }
+        Ok(())
+    }
+
+    /// Makes this source update its registration.
+    ///
+    /// If after accessing the source you changed its parameters in a way that requires
+    /// updating its registration.
+    pub fn update(&self, token: &RegistrationToken) -> crate::Result<()> {
+        if let Some(source) = self.inner.sources.borrow().get(token.key) {
+            if !source.reregister(
+                &mut self.inner.poll.borrow_mut(),
+                &mut self
+                    .inner
+                    .sources_with_additional_lifecycle_events
+                    .borrow_mut(),
+                &mut TokenFactory::new(token.key),
+            )? {
+                // we are in a callback, store for later processing
+                self.inner.pending_action.set(PostAction::Reregister);
+            }
+        }
+        Ok(())
+    }
+
+    /// Disables this event source.
+    ///
+    /// The source remains in the event loop, but it'll no longer generate events
+    pub fn disable(&self, token: &RegistrationToken) -> crate::Result<()> {
+        if let Some(source) = self.inner.sources.borrow().get(token.key) {
+            if !source.unregister(
+                &mut self.inner.poll.borrow_mut(),
+                &mut self
+                    .inner
+                    .sources_with_additional_lifecycle_events
+                    .borrow_mut(),
+                *token,
+            )? {
+                // we are in a callback, store for later processing
+                self.inner.pending_action.set(PostAction::Disable);
+            }
+        }
+        Ok(())
+    }
+
+    /// Removes this source from the event loop.
+    pub fn remove(&self, token: RegistrationToken) {
+        if let Some(source) = self.inner.sources.borrow_mut().try_remove(token.key) {
+            if let Err(e) = source.unregister(
+                &mut self.inner.poll.borrow_mut(),
+                &mut self
+                    .inner
+                    .sources_with_additional_lifecycle_events
+                    .borrow_mut(),
+                token,
+            ) {
+                log::warn!(
+                    "[calloop] Failed to unregister source from the polling system: {:?}",
+                    e
+                );
+            }
+        }
+    }
+
+    /// Wrap an IO object into an async adapter
+    ///
+    /// This adapter turns the IO object into an async-aware one that can be used in futures.
+    /// The readiness of these futures will be driven by the event loop.
+    ///
+    /// The produced futures can be polled in any executor, and notably the one provided by
+    /// calloop.
+    pub fn adapt_io<F: AsFd>(&self, fd: F) -> crate::Result<crate::io::Async<'l, F>> {
+        crate::io::Async::new(self.inner.clone(), fd)
+    }
+}
+
+/// An event loop
+///
+/// This loop can host several event sources, that can be dynamically added or removed.
+pub struct EventLoop<'l, Data> {
+    handle: LoopHandle<'l, Data>,
+    signals: Arc<Signals>,
+    // A caching vector for synthetic poll events
+    synthetic_events: Vec<PollEvent>,
+}
+
+impl<'l, Data> std::fmt::Debug for EventLoop<'l, Data> {
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))]
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.write_str("EventLoop { ... }")
+    }
+}
+
+/// Signals related to the event loop.
+struct Signals {
+    /// Signal to stop the event loop.
+    stop: AtomicBool,
+
+    /// Signal that the future is ready.
+    #[cfg(feature = "block_on")]
+    future_ready: AtomicBool,
+}
+
+impl<'l, Data> EventLoop<'l, Data> {
+    /// Create a new event loop
+    ///
+    /// Fails if the initialization of the polling system failed.
+    pub fn try_new() -> crate::Result<Self> {
+        let poll = Poll::new()?;
+        let handle = LoopHandle {
+            inner: Rc::new(LoopInner {
+                poll: RefCell::new(poll),
+                sources: RefCell::new(Slab::new()),
+                idles: RefCell::new(Vec::new()),
+                pending_action: Cell::new(PostAction::Continue),
+                sources_with_additional_lifecycle_events: Default::default(),
+            }),
+        };
+
+        Ok(EventLoop {
+            handle,
+            signals: Arc::new(Signals {
+                stop: AtomicBool::new(false),
+                #[cfg(feature = "block_on")]
+                future_ready: AtomicBool::new(false),
+            }),
+            synthetic_events: vec![],
+        })
+    }
+
+    /// Retrieve a loop handle
+    pub fn handle(&self) -> LoopHandle<'l, Data> {
+        self.handle.clone()
+    }
+
+    fn dispatch_events(
+        &mut self,
+        mut timeout: Option<Duration>,
+        data: &mut Data,
+    ) -> crate::Result<()> {
+        let now = Instant::now();
+        {
+            let mut extra_lifecycle_sources = self
+                .handle
+                .inner
+                .sources_with_additional_lifecycle_events
+                .borrow_mut();
+            let sources = &self.handle.inner.sources.borrow();
+            for source in &mut *extra_lifecycle_sources.values {
+                if let Some(disp) = sources.get(source.key) {
+                    if let Some((readiness, token)) = disp.before_sleep()? {
+                        // Wake up instantly after polling if we recieved an event
+                        timeout = Some(Duration::ZERO);
+                        self.synthetic_events.push(PollEvent { readiness, token });
+                    }
+                } else {
+                    unreachable!()
+                }
+            }
+        }
+        let events = {
+            let poll = self.handle.inner.poll.borrow();
+            loop {
+                let result = poll.poll(timeout);
+
+                match result {
+                    Ok(events) => break events,
+                    Err(crate::Error::IoError(err)) if err.kind() == io::ErrorKind::Interrupted => {
+                        // Interrupted by a signal. Update timeout and retry.
+                        if let Some(to) = timeout {
+                            let elapsed = now.elapsed();
+                            if elapsed >= to {
+                                return Ok(());
+                            } else {
+                                timeout = Some(to - elapsed);
+                            }
+                        }
+                    }
+                    Err(err) => return Err(err),
+                };
+            }
+        };
+        {
+            let mut extra_lifecycle_sources = self
+                .handle
+                .inner
+                .sources_with_additional_lifecycle_events
+                .borrow_mut();
+            if !extra_lifecycle_sources.values.is_empty() {
+                for source in &mut *extra_lifecycle_sources.values {
+                    if let Some(disp) = self.handle.inner.sources.borrow().get(source.key) {
+                        let iter = EventIterator {
+                            inner: self.synthetic_events.iter(),
+                            registration_token: *source,
+                        };
+                        disp.before_handle_events(iter);
+                    } else {
+                        unreachable!()
+                    }
+                }
+            }
+        }
+
+        for event in self.synthetic_events.drain(..).chain(events) {
+            // Get the registration token associated with the event.
+            let registroken_token = event.token.key & MAX_SOURCES_MASK;
+
+            let opt_disp = self
+                .handle
+                .inner
+                .sources
+                .borrow()
+                .get(registroken_token)
+                .cloned();
+
+            if let Some(disp) = opt_disp {
+                let mut ret = disp.process_events(event.readiness, event.token, data)?;
+
+                // if the returned PostAction is Continue, it may be overwritten by an user-specified pending action
+                let pending_action = self
+                    .handle
+                    .inner
+                    .pending_action
+                    .replace(PostAction::Continue);
+                if let PostAction::Continue = ret {
+                    ret = pending_action;
+                }
+
+                match ret {
+                    PostAction::Reregister => {
+                        disp.reregister(
+                            &mut self.handle.inner.poll.borrow_mut(),
+                            &mut self
+                                .handle
+                                .inner
+                                .sources_with_additional_lifecycle_events
+                                .borrow_mut(),
+                            &mut TokenFactory::new(event.token.key),
+                        )?;
+                    }
+                    PostAction::Disable => {
+                        disp.unregister(
+                            &mut self.handle.inner.poll.borrow_mut(),
+                            &mut self
+                                .handle
+                                .inner
+                                .sources_with_additional_lifecycle_events
+                                .borrow_mut(),
+                            RegistrationToken::new(registroken_token),
+                        )?;
+                    }
+                    PostAction::Remove => {
+                        // delete the source from the list, it'll be cleaned up with the if just below
+                        self.handle
+                            .inner
+                            .sources
+                            .borrow_mut()
+                            .remove(event.token.key);
+                    }
+                    PostAction::Continue => {}
+                }
+
+                if !self
+                    .handle
+                    .inner
+                    .sources
+                    .borrow()
+                    .contains(registroken_token)
+                {
+                    // the source has been removed from within its callback, unregister it
+                    let mut poll = self.handle.inner.poll.borrow_mut();
+                    if let Err(e) = disp.unregister(
+                        &mut poll,
+                        &mut self
+                            .handle
+                            .inner
+                            .sources_with_additional_lifecycle_events
+                            .borrow_mut(),
+                        RegistrationToken::new(registroken_token),
+                    ) {
+                        log::warn!(
+                            "[calloop] Failed to unregister source from the polling system: {:?}",
+                            e
+                        );
+                    }
+                }
+            } else {
+                log::warn!(
+                    "[calloop] Received an event for non-existence source: {:?}",
+                    event.token.key
+                );
+            }
+        }
+
+        Ok(())
+    }
+
+    fn dispatch_idles(&mut self, data: &mut Data) {
+        let idles = std::mem::take(&mut *self.handle.inner.idles.borrow_mut());
+        for idle in idles {
+            idle.borrow_mut().dispatch(data);
+        }
+    }
+
+    /// Dispatch pending events to their callbacks
+    ///
+    /// If some sources have events available, their callbacks will be immediatly called.
+    /// Otherwise this will wait until an event is receive or the provided `timeout`
+    /// is reached. If `timeout` is `None`, it will wait without a duration limit.
+    ///
+    /// Once pending events have been processed or the timeout is reached, all pending
+    /// idle callbacks will be fired before this method returns.
+    pub fn dispatch<D: Into<Option<Duration>>>(
+        &mut self,
+        timeout: D,
+        data: &mut Data,
+    ) -> crate::Result<()> {
+        self.dispatch_events(timeout.into(), data)?;
+        self.dispatch_idles(data);
+
+        Ok(())
+    }
+
+    /// Get a signal to stop this event loop from running
+    ///
+    /// To be used in conjunction with the `run()` method.
+    pub fn get_signal(&self) -> LoopSignal {
+        LoopSignal {
+            signal: self.signals.clone(),
+            notifier: self.handle.inner.poll.borrow().notifier(),
+        }
+    }
+
+    /// Run this event loop
+    ///
+    /// This will repeatedly try to dispatch events (see the `dispatch()` method) on
+    /// this event loop, waiting at most `timeout` every time.
+    ///
+    /// Between each dispatch wait, your provided callback will be called.
+    ///
+    /// You can use the `get_signal()` method to retrieve a way to stop or wakeup
+    /// the event loop from anywhere.
+    pub fn run<F, D: Into<Option<Duration>>>(
+        &mut self,
+        timeout: D,
+        data: &mut Data,
+        mut cb: F,
+    ) -> crate::Result<()>
+    where
+        F: FnMut(&mut Data),
+    {
+        let timeout = timeout.into();
+        self.signals.stop.store(false, Ordering::Release);
+        while !self.signals.stop.load(Ordering::Acquire) {
+            self.dispatch(timeout, data)?;
+            cb(data);
+        }
+        Ok(())
+    }
+
+    /// Block a future on this event loop.
+    ///
+    /// This will run the provided future on this event loop, blocking until it is
+    /// resolved.
+    ///
+    /// If [`LoopSignal::stop()`] is called before the future is resolved, this function returns
+    /// `None`.
+    #[cfg(feature = "block_on")]
+    pub fn block_on<R>(
+        &mut self,
+        future: impl Future<Output = R>,
+        data: &mut Data,
+        mut cb: impl FnMut(&mut Data),
+    ) -> crate::Result<Option<R>> {
+        use std::task::{Context, Poll, Wake, Waker};
+
+        /// A waker that will wake up the event loop when it is ready to make progress.
+        struct EventLoopWaker(LoopSignal);
+
+        impl Wake for EventLoopWaker {
+            fn wake(self: Arc<Self>) {
+                // Set the waker.
+                self.0.signal.future_ready.store(true, Ordering::Release);
+                self.0.notifier.notify().ok();
+            }
+
+            fn wake_by_ref(self: &Arc<Self>) {
+                // Set the waker.
+                self.0.signal.future_ready.store(true, Ordering::Release);
+                self.0.notifier.notify().ok();
+            }
+        }
+
+        // Pin the future to the stack.
+        pin_utils::pin_mut!(future);
+
+        // Create a waker that will wake up the event loop when it is ready to make progress.
+        let waker = {
+            let handle = EventLoopWaker(self.get_signal());
+
+            Waker::from(Arc::new(handle))
+        };
+        let mut context = Context::from_waker(&waker);
+
+        // Begin running the loop.
+        let mut output = None;
+
+        self.signals.stop.store(false, Ordering::Release);
+        self.signals.future_ready.store(true, Ordering::Release);
+
+        while !self.signals.stop.load(Ordering::Acquire) {
+            // If the future is ready to be polled, poll it.
+            if self.signals.future_ready.swap(false, Ordering::AcqRel) {
+                // Poll the future and break the loop if it's ready.
+                if let Poll::Ready(result) = future.as_mut().poll(&mut context) {
+                    output = Some(result);
+                    break;
+                }
+            }
+
+            // Otherwise, block on the event loop.
+            self.dispatch_events(None, data)?;
+            self.dispatch_idles(data);
+            cb(data);
+        }
+
+        Ok(output)
+    }
+}
+
+#[derive(Clone, Debug)]
+/// The EventIterator is an `Iterator` over the events relevant to a particular source
+/// This type is used in the [`EventSource::before_handle_events`] methods for
+/// two main reasons:
+/// - To avoid dynamic dispatch overhead
+/// - Secondly, it is to allow this type to be `Clone`, which is not
+/// possible with dynamic dispatch
+pub struct EventIterator<'a> {
+    inner: slice::Iter<'a, PollEvent>,
+    registration_token: RegistrationToken,
+}
+
+impl<'a> Iterator for EventIterator<'a> {
+    type Item = (Readiness, Token);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        for next in self.inner.by_ref() {
+            if next.token.key & MAX_SOURCES_MASK == self.registration_token.key {
+                return Some((next.readiness, next.token));
+            }
+        }
+        None
+    }
+}
+
+/// A signal that can be shared between thread to stop or wakeup a running
+/// event loop
+#[derive(Clone)]
+pub struct LoopSignal {
+    signal: Arc<Signals>,
+    notifier: Notifier,
+}
+
+impl std::fmt::Debug for LoopSignal {
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))]
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.write_str("LoopSignal { ... }")
+    }
+}
+
+impl LoopSignal {
+    /// Stop the event loop
+    ///
+    /// Once this method is called, the next time the event loop has finished
+    /// waiting for events, it will return rather than starting to wait again.
+    ///
+    /// This is only useful if you are using the `EventLoop::run()` method.
+    pub fn stop(&self) {
+        self.signal.stop.store(true, Ordering::Release);
+    }
+
+    /// Wake up the event loop
+    ///
+    /// This sends a dummy event to the event loop to simulate the reception
+    /// of an event, making the wait return early. Called after `stop()`, this
+    /// ensures the event loop will terminate quickly if you specified a long
+    /// timeout (or no timeout at all) to the `dispatch` or `run` method.
+    pub fn wakeup(&self) {
+        self.notifier.notify().ok();
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::{cell::Cell, rc::Rc, time::Duration};
+
+    use crate::{
+        channel::{channel, Channel},
+        generic::Generic,
+        ping::*,
+        Dispatcher, EventIterator, EventSource, Interest, Mode, Poll, PostAction, Readiness,
+        RegistrationToken, Token, TokenFactory,
+    };
+
+    use super::EventLoop;
+
+    #[test]
+    fn dispatch_idle() {
+        let mut event_loop = EventLoop::try_new().unwrap();
+
+        let mut dispatched = false;
+
+        event_loop.handle().insert_idle(|d| {
+            *d = true;
+        });
+
+        event_loop
+            .dispatch(Some(Duration::ZERO), &mut dispatched)
+            .unwrap();
+
+        assert!(dispatched);
+    }
+
+    #[test]
+    fn cancel_idle() {
+        let mut event_loop = EventLoop::try_new().unwrap();
+
+        let mut dispatched = false;
+
+        let handle = event_loop.handle();
+        let idle = handle.insert_idle(move |d| {
+            *d = true;
+        });
+
+        idle.cancel();
+
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+
+        assert!(!dispatched);
+    }
+
+    #[test]
+    fn wakeup() {
+        let mut event_loop = EventLoop::try_new().unwrap();
+
+        let signal = event_loop.get_signal();
+
+        ::std::thread::spawn(move || {
+            ::std::thread::sleep(Duration::from_millis(500));
+            signal.wakeup();
+        });
+
+        // the test should return
+        event_loop.dispatch(None, &mut ()).unwrap();
+    }
+
+    #[test]
+    fn wakeup_stop() {
+        let mut event_loop = EventLoop::try_new().unwrap();
+
+        let signal = event_loop.get_signal();
+
+        ::std::thread::spawn(move || {
+            ::std::thread::sleep(Duration::from_millis(500));
+            signal.stop();
+            signal.wakeup();
+        });
+
+        // the test should return
+        event_loop.run(None, &mut (), |_| {}).unwrap();
+    }
+
+    #[test]
+    fn additional_events() {
+        let mut event_loop: EventLoop<'_, Lock> = EventLoop::try_new().unwrap();
+        let mut lock = Lock {
+            lock: Rc::new((Cell::new(false), Cell::new(0))),
+        };
+        let (sender, channel) = channel();
+        let token = event_loop
+            .handle()
+            .insert_source(
+                LockingSource {
+                    channel,
+                    lock: lock.clone(),
+                },
+                |_, _, lock| {
+                    lock.lock();
+                    lock.unlock();
+                },
+            )
+            .unwrap();
+        sender.send(()).unwrap();
+
+        event_loop.dispatch(None, &mut lock).unwrap();
+        // We should have been locked twice so far
+        assert_eq!(lock.lock.1.get(), 2);
+        event_loop.handle().disable(&token).unwrap();
+        event_loop
+            .dispatch(Some(Duration::ZERO), &mut lock)
+            .unwrap();
+        assert_eq!(lock.lock.1.get(), 2);
+
+        event_loop.handle().enable(&token).unwrap();
+        event_loop
+            .dispatch(Some(Duration::ZERO), &mut lock)
+            .unwrap();
+        assert_eq!(lock.lock.1.get(), 3);
+        event_loop.handle().remove(token);
+        event_loop
+            .dispatch(Some(Duration::ZERO), &mut lock)
+            .unwrap();
+        assert_eq!(lock.lock.1.get(), 3);
+
+        #[derive(Clone)]
+        struct Lock {
+            lock: Rc<(Cell<bool>, Cell<u32>)>,
+        }
+        impl Lock {
+            fn lock(&self) {
+                if self.lock.0.get() {
+                    panic!();
+                }
+                // Increase the count
+                self.lock.1.set(self.lock.1.get() + 1);
+                self.lock.0.set(true)
+            }
+            fn unlock(&self) {
+                if !self.lock.0.get() {
+                    panic!();
+                }
+                self.lock.0.set(false);
+            }
+        }
+        struct LockingSource {
+            channel: Channel<()>,
+            lock: Lock,
+        }
+        impl EventSource for LockingSource {
+            type Event = <Channel<()> as EventSource>::Event;
+
+            type Metadata = <Channel<()> as EventSource>::Metadata;
+
+            type Ret = <Channel<()> as EventSource>::Ret;
+
+            type Error = <Channel<()> as EventSource>::Error;
+
+            fn process_events<F>(
+                &mut self,
+                readiness: Readiness,
+                token: Token,
+                callback: F,
+            ) -> Result<PostAction, Self::Error>
+            where
+                F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+            {
+                self.channel.process_events(readiness, token, callback)
+            }
+
+            fn register(
+                &mut self,
+                poll: &mut Poll,
+                token_factory: &mut TokenFactory,
+            ) -> crate::Result<()> {
+                self.channel.register(poll, token_factory)
+            }
+
+            fn reregister(
+                &mut self,
+                poll: &mut Poll,
+                token_factory: &mut TokenFactory,
+            ) -> crate::Result<()> {
+                self.channel.reregister(poll, token_factory)
+            }
+
+            fn unregister(&mut self, poll: &mut Poll) -> crate::Result<()> {
+                self.channel.unregister(poll)
+            }
+
+            const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = true;
+
+            fn before_sleep(&mut self) -> crate::Result<Option<(Readiness, Token)>> {
+                self.lock.lock();
+                Ok(None)
+            }
+
+            fn before_handle_events(&mut self, _: EventIterator) {
+                self.lock.unlock();
+            }
+        }
+    }
+    #[test]
+    fn default_additional_events() {
+        let (sender, channel) = channel();
+        let mut test_source = NoopWithDefaultHandlers { channel };
+        let mut event_loop = EventLoop::try_new().unwrap();
+        event_loop
+            .handle()
+            .insert_source(Box::new(&mut test_source), |_, _, _| {})
+            .unwrap();
+        sender.send(()).unwrap();
+
+        event_loop.dispatch(None, &mut ()).unwrap();
+        struct NoopWithDefaultHandlers {
+            channel: Channel<()>,
+        }
+        impl EventSource for NoopWithDefaultHandlers {
+            type Event = <Channel<()> as EventSource>::Event;
+
+            type Metadata = <Channel<()> as EventSource>::Metadata;
+
+            type Ret = <Channel<()> as EventSource>::Ret;
+
+            type Error = <Channel<()> as EventSource>::Error;
+
+            fn process_events<F>(
+                &mut self,
+                readiness: Readiness,
+                token: Token,
+                callback: F,
+            ) -> Result<PostAction, Self::Error>
+            where
+                F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+            {
+                self.channel.process_events(readiness, token, callback)
+            }
+
+            fn register(
+                &mut self,
+                poll: &mut Poll,
+                token_factory: &mut TokenFactory,
+            ) -> crate::Result<()> {
+                self.channel.register(poll, token_factory)
+            }
+
+            fn reregister(
+                &mut self,
+                poll: &mut Poll,
+                token_factory: &mut TokenFactory,
+            ) -> crate::Result<()> {
+                self.channel.reregister(poll, token_factory)
+            }
+
+            fn unregister(&mut self, poll: &mut Poll) -> crate::Result<()> {
+                self.channel.unregister(poll)
+            }
+
+            const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = true;
+        }
+    }
+
+    #[test]
+    fn additional_events_synthetic() {
+        let mut event_loop: EventLoop<'_, Lock> = EventLoop::try_new().unwrap();
+        let mut lock = Lock {
+            lock: Rc::new(Cell::new(false)),
+        };
+        event_loop
+            .handle()
+            .insert_source(
+                InstantWakeupLockingSource {
+                    lock: lock.clone(),
+                    token: None,
+                },
+                |_, _, lock| {
+                    lock.lock();
+                    lock.unlock();
+                },
+            )
+            .unwrap();
+
+        // Loop should finish, as
+        event_loop.dispatch(None, &mut lock).unwrap();
+        #[derive(Clone)]
+        struct Lock {
+            lock: Rc<Cell<bool>>,
+        }
+        impl Lock {
+            fn lock(&self) {
+                if self.lock.get() {
+                    panic!();
+                }
+                self.lock.set(true)
+            }
+            fn unlock(&self) {
+                if !self.lock.get() {
+                    panic!();
+                }
+                self.lock.set(false);
+            }
+        }
+        struct InstantWakeupLockingSource {
+            lock: Lock,
+            token: Option<Token>,
+        }
+        impl EventSource for InstantWakeupLockingSource {
+            type Event = ();
+
+            type Metadata = ();
+
+            type Ret = ();
+
+            type Error = <Channel<()> as EventSource>::Error;
+
+            fn process_events<F>(
+                &mut self,
+                _: Readiness,
+                token: Token,
+                mut callback: F,
+            ) -> Result<PostAction, Self::Error>
+            where
+                F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+            {
+                assert_eq!(token, self.token.unwrap());
+                callback((), &mut ());
+                Ok(PostAction::Continue)
+            }
+
+            fn register(
+                &mut self,
+                _: &mut Poll,
+                token_factory: &mut TokenFactory,
+            ) -> crate::Result<()> {
+                self.token = Some(token_factory.token());
+                Ok(())
+            }
+
+            fn reregister(&mut self, _: &mut Poll, _: &mut TokenFactory) -> crate::Result<()> {
+                unreachable!()
+            }
+
+            fn unregister(&mut self, _: &mut Poll) -> crate::Result<()> {
+                unreachable!()
+            }
+
+            const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = true;
+
+            fn before_sleep(&mut self) -> crate::Result<Option<(Readiness, Token)>> {
+                self.lock.lock();
+                Ok(Some((Readiness::EMPTY, self.token.unwrap())))
+            }
+
+            fn before_handle_events(&mut self, _: EventIterator) {
+                self.lock.unlock();
+            }
+        }
+    }
+
+    #[test]
+    fn insert_bad_source() {
+        use std::os::unix::io::FromRawFd;
+
+        let event_loop = EventLoop::<()>::try_new().unwrap();
+        let fd = unsafe { std::os::unix::io::OwnedFd::from_raw_fd(420) };
+        let ret = event_loop.handle().insert_source(
+            crate::sources::generic::Generic::new(fd, Interest::READ, Mode::Level),
+            |_, _, _| Ok(PostAction::Continue),
+        );
+        assert!(ret.is_err());
+    }
+
+    #[test]
+    fn insert_source_no_interest() {
+        use rustix::pipe::pipe;
+
+        // Create a pipe to get an arbitrary fd.
+        let (read, _write) = pipe().unwrap();
+
+        let source = crate::sources::generic::Generic::new(read, Interest::EMPTY, Mode::Level);
+        let dispatcher = Dispatcher::new(source, |_, _, _| Ok(PostAction::Continue));
+
+        let event_loop = EventLoop::<()>::try_new().unwrap();
+        let handle = event_loop.handle();
+        let ret = handle.register_dispatcher(dispatcher.clone());
+
+        if let Ok(token) = ret {
+            // Unwrap the dispatcher+source and close the read end.
+            handle.remove(token);
+        } else {
+            // Fail the test.
+            panic!();
+        }
+    }
+
+    #[test]
+    fn disarm_rearm() {
+        let mut event_loop = EventLoop::<bool>::try_new().unwrap();
+        let (ping, ping_source) = make_ping().unwrap();
+
+        let ping_token = event_loop
+            .handle()
+            .insert_source(ping_source, |(), &mut (), dispatched| {
+                *dispatched = true;
+            })
+            .unwrap();
+
+        ping.ping();
+        let mut dispatched = false;
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(dispatched);
+
+        // disable the source
+        ping.ping();
+        event_loop.handle().disable(&ping_token).unwrap();
+        let mut dispatched = false;
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(!dispatched);
+
+        // reenable it, the previous ping now gets dispatched
+        event_loop.handle().enable(&ping_token).unwrap();
+        let mut dispatched = false;
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(dispatched);
+    }
+
+    #[test]
+    fn multiple_tokens() {
+        struct DoubleSource {
+            ping1: PingSource,
+            ping2: PingSource,
+        }
+
+        impl crate::EventSource for DoubleSource {
+            type Event = u32;
+            type Metadata = ();
+            type Ret = ();
+            type Error = PingError;
+
+            fn process_events<F>(
+                &mut self,
+                readiness: Readiness,
+                token: Token,
+                mut callback: F,
+            ) -> Result<PostAction, Self::Error>
+            where
+                F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+            {
+                self.ping1
+                    .process_events(readiness, token, |(), &mut ()| callback(1, &mut ()))?;
+                self.ping2
+                    .process_events(readiness, token, |(), &mut ()| callback(2, &mut ()))?;
+                Ok(PostAction::Continue)
+            }
+
+            fn register(
+                &mut self,
+                poll: &mut Poll,
+                token_factory: &mut TokenFactory,
+            ) -> crate::Result<()> {
+                self.ping1.register(poll, token_factory)?;
+                self.ping2.register(poll, token_factory)?;
+                Ok(())
+            }
+
+            fn reregister(
+                &mut self,
+                poll: &mut Poll,
+                token_factory: &mut TokenFactory,
+            ) -> crate::Result<()> {
+                self.ping1.reregister(poll, token_factory)?;
+                self.ping2.reregister(poll, token_factory)?;
+                Ok(())
+            }
+
+            fn unregister(&mut self, poll: &mut Poll) -> crate::Result<()> {
+                self.ping1.unregister(poll)?;
+                self.ping2.unregister(poll)?;
+                Ok(())
+            }
+        }
+
+        let mut event_loop = EventLoop::<u32>::try_new().unwrap();
+
+        let (ping1, source1) = make_ping().unwrap();
+        let (ping2, source2) = make_ping().unwrap();
+
+        let source = DoubleSource {
+            ping1: source1,
+            ping2: source2,
+        };
+
+        event_loop
+            .handle()
+            .insert_source(source, |i, _, d| {
+                eprintln!("Dispatching {}", i);
+                *d += i
+            })
+            .unwrap();
+
+        let mut dispatched = 0;
+        ping1.ping();
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert_eq!(dispatched, 1);
+
+        dispatched = 0;
+        ping2.ping();
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert_eq!(dispatched, 2);
+
+        dispatched = 0;
+        ping1.ping();
+        ping2.ping();
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert_eq!(dispatched, 3);
+    }
+
+    #[test]
+    fn change_interests() {
+        use rustix::io::write;
+        use rustix::net::{recv, socketpair, AddressFamily, RecvFlags, SocketFlags, SocketType};
+        let mut event_loop = EventLoop::<bool>::try_new().unwrap();
+
+        let (sock1, sock2) = socketpair(
+            AddressFamily::UNIX,
+            SocketType::STREAM,
+            SocketFlags::empty(),
+            None, // recv with DONTWAIT will suffice for platforms without SockFlag::SOCK_NONBLOCKING such as macOS
+        )
+        .unwrap();
+
+        let source = Generic::new(sock1, Interest::READ, Mode::Level);
+        let dispatcher = Dispatcher::new(source, |_, fd, dispatched| {
+            *dispatched = true;
+            // read all contents available to drain the socket
+            let mut buf = [0u8; 32];
+            loop {
+                match recv(&*fd, &mut buf, RecvFlags::DONTWAIT) {
+                    Ok(0) => break, // closed pipe, we are now inert
+                    Ok(_) => {}
+                    Err(e) => {
+                        let e: std::io::Error = e.into();
+                        if e.kind() == std::io::ErrorKind::WouldBlock {
+                            break;
+                        // nothing more to read
+                        } else {
+                            // propagate error
+                            return Err(e);
+                        }
+                    }
+                }
+            }
+            Ok(PostAction::Continue)
+        });
+
+        let sock_token_1 = event_loop
+            .handle()
+            .register_dispatcher(dispatcher.clone())
+            .unwrap();
+
+        // first dispatch, nothing is readable
+        let mut dispatched = false;
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(!dispatched);
+
+        // write something, the socket becomes readable
+        write(&sock2, &[1, 2, 3]).unwrap();
+        dispatched = false;
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(dispatched);
+
+        // All has been read, no longer readable
+        dispatched = false;
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(!dispatched);
+
+        // change the interests for writability instead
+        dispatcher.as_source_mut().interest = Interest::WRITE;
+        event_loop.handle().update(&sock_token_1).unwrap();
+
+        // the socket is writable
+        dispatched = false;
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(dispatched);
+
+        // change back to readable
+        dispatcher.as_source_mut().interest = Interest::READ;
+        event_loop.handle().update(&sock_token_1).unwrap();
+
+        // the socket is not readable
+        dispatched = false;
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(!dispatched);
+    }
+
+    #[test]
+    fn kill_source() {
+        let mut event_loop = EventLoop::<Option<RegistrationToken>>::try_new().unwrap();
+
+        let handle = event_loop.handle();
+        let (ping, ping_source) = make_ping().unwrap();
+        let ping_token = event_loop
+            .handle()
+            .insert_source(ping_source, move |(), &mut (), opt_src| {
+                if let Some(src) = opt_src.take() {
+                    handle.remove(src);
+                }
+            })
+            .unwrap();
+
+        ping.ping();
+
+        let mut opt_src = Some(ping_token);
+
+        event_loop.dispatch(Duration::ZERO, &mut opt_src).unwrap();
+
+        assert!(opt_src.is_none());
+    }
+
+    #[test]
+    fn non_static_data() {
+        use std::sync::mpsc;
+
+        let (sender, receiver) = mpsc::channel();
+
+        {
+            struct RefSender<'a>(&'a mpsc::Sender<()>);
+            let mut ref_sender = RefSender(&sender);
+
+            let mut event_loop = EventLoop::<RefSender<'_>>::try_new().unwrap();
+            let (ping, ping_source) = make_ping().unwrap();
+            let _ping_token = event_loop
+                .handle()
+                .insert_source(ping_source, |_, _, ref_sender| {
+                    ref_sender.0.send(()).unwrap();
+                })
+                .unwrap();
+
+            ping.ping();
+
+            event_loop
+                .dispatch(Duration::ZERO, &mut ref_sender)
+                .unwrap();
+        }
+
+        receiver.recv().unwrap();
+        // sender still usable (e.g. for another EventLoop)
+        drop(sender);
+    }
+
+    #[cfg(feature = "block_on")]
+    #[test]
+    fn block_on_test() {
+        use crate::sources::timer::TimeoutFuture;
+        use std::time::Duration;
+
+        let mut evl = EventLoop::<()>::try_new().unwrap();
+
+        let mut data = 22;
+        let timeout = {
+            let data = &mut data;
+            let evl_handle = evl.handle();
+
+            async move {
+                TimeoutFuture::from_duration(&evl_handle, Duration::from_secs(2)).await;
+                *data = 32;
+                11
+            }
+        };
+
+        let result = evl.block_on(timeout, &mut (), |&mut ()| {}).unwrap();
+        assert_eq!(result, Some(11));
+        assert_eq!(data, 32);
+    }
+
+    #[cfg(feature = "block_on")]
+    #[test]
+    fn block_on_early_cancel() {
+        use crate::sources::timer;
+        use std::time::Duration;
+
+        let mut evl = EventLoop::<()>::try_new().unwrap();
+
+        let mut data = 22;
+        let timeout = {
+            let data = &mut data;
+            let evl_handle = evl.handle();
+
+            async move {
+                timer::TimeoutFuture::from_duration(&evl_handle, Duration::from_secs(2)).await;
+                *data = 32;
+                11
+            }
+        };
+
+        let timer_source = timer::Timer::from_duration(Duration::from_secs(1));
+        let handle = evl.get_signal();
+        let _timer_token = evl
+            .handle()
+            .insert_source(timer_source, move |_, _, _| {
+                handle.stop();
+                timer::TimeoutAction::Drop
+            })
+            .unwrap();
+
+        let result = evl.block_on(timeout, &mut (), |&mut ()| {}).unwrap();
+        assert_eq!(result, None);
+        assert_eq!(data, 22);
+    }
+
+    // A dummy EventSource to test insertion and removal of sources
+    struct DummySource;
+
+    impl crate::EventSource for DummySource {
+        type Event = ();
+        type Metadata = ();
+        type Ret = ();
+        type Error = crate::Error;
+
+        fn process_events<F>(
+            &mut self,
+            _: Readiness,
+            _: Token,
+            mut callback: F,
+        ) -> Result<PostAction, Self::Error>
+        where
+            F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+        {
+            callback((), &mut ());
+            Ok(PostAction::Continue)
+        }
+
+        fn register(&mut self, _: &mut Poll, _: &mut TokenFactory) -> crate::Result<()> {
+            Ok(())
+        }
+
+        fn reregister(&mut self, _: &mut Poll, _: &mut TokenFactory) -> crate::Result<()> {
+            Ok(())
+        }
+
+        fn unregister(&mut self, _: &mut Poll) -> crate::Result<()> {
+            Ok(())
+        }
+    }
+}
+
\ No newline at end of file diff --git a/api/src/calloop/macros.rs.html b/api/src/calloop/macros.rs.html new file mode 100644 index 00000000..dae89808 --- /dev/null +++ b/api/src/calloop/macros.rs.html @@ -0,0 +1,447 @@ +macros.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+
//! Macros for helping with common operations in Calloop.
+
+/// Register a set of event sources. Effectively calls
+/// [`EventSource::register()`] for all the sources provided.
+///
+/// Usage:
+///
+/// ```none,actually-rust-but-see-https://github.com/rust-lang/rust/issues/63193
+/// calloop::batch_register!(
+///     poll, token_factory,
+///     self.source_one,
+///     self.source_two,
+///     self.source_three,
+///     self.source_four,
+/// )
+/// ```
+///
+/// Note that there is no scope for customisation; if you need to do special
+/// things with a particular source, you'll need to leave it off the list. Also
+/// note that this only does try-or-early-return error handling in the order
+/// that you list the sources; if you need anything else, don't use this macro.
+///
+/// [`EventSource::register()`]: crate::EventSource::register()
+#[macro_export]
+macro_rules! batch_register {
+    ($poll:ident, $token_fac:ident, $( $source:expr ),* $(,)?) => {
+        {
+            $(
+                $source.register($poll, $token_fac)?;
+            )*
+                $crate::Result::<_>::Ok(())
+        }
+    };
+}
+
+/// Reregister a set of event sources. Effectively calls
+/// [`EventSource::reregister()`] for all the sources provided.
+///
+/// Usage:
+///
+/// ```none,actually-rust-but-see-https://github.com/rust-lang/rust/issues/63193
+/// calloop::batch_reregister!(
+///     poll, token_factory,
+///     self.source_one,
+///     self.source_two,
+///     self.source_three,
+///     self.source_four,
+/// )
+/// ```
+///
+/// Note that there is no scope for customisation; if you need to do special
+/// things with a particular source, you'll need to leave it off the list. Also
+/// note that this only does try-or-early-return error handling in the order
+/// that you list the sources; if you need anything else, don't use this macro.
+///
+/// [`EventSource::reregister()`]: crate::EventSource::reregister()
+#[macro_export]
+macro_rules! batch_reregister {
+    ($poll:ident, $token_fac:ident, $( $source:expr ),* $(,)?) => {
+        {
+            $(
+                $source.reregister($poll, $token_fac)?;
+            )*
+                $crate::Result::<_>::Ok(())
+        }
+    };
+}
+
+/// Unregister a set of event sources. Effectively calls
+/// [`EventSource::unregister()`] for all the sources provided.
+///
+/// Usage:
+///
+/// ```none,actually-rust-but-see-https://github.com/rust-lang/rust/issues/63193
+/// calloop::batch_unregister!(
+///     poll,
+///     self.source_one,
+///     self.source_two,
+///     self.source_three,
+///     self.source_four,
+/// )
+/// ```
+///
+/// Note that there is no scope for customisation; if you need to do special
+/// things with a particular source, you'll need to leave it off the list. Also
+/// note that this only does try-or-early-return error handling in the order
+/// that you list the sources; if you need anything else, don't use this macro.
+///
+/// [`EventSource::unregister()`]: crate::EventSource::unregister()
+#[macro_export]
+macro_rules! batch_unregister {
+    ($poll:ident, $( $source:expr ),* $(,)?) => {
+        {
+            $(
+                $source.unregister($poll)?;
+            )*
+                $crate::Result::<_>::Ok(())
+        }
+    };
+}
+
+#[cfg(test)]
+mod tests {
+    use std::time::Duration;
+
+    use crate::{
+        ping::{make_ping, PingSource},
+        EventSource, PostAction,
+    };
+
+    struct BatchSource {
+        ping0: PingSource,
+        ping1: PingSource,
+        ping2: PingSource,
+    }
+
+    impl EventSource for BatchSource {
+        type Event = usize;
+        type Metadata = ();
+        type Ret = ();
+        type Error = Box<dyn std::error::Error + Sync + Send>;
+
+        fn process_events<F>(
+            &mut self,
+            readiness: crate::Readiness,
+            token: crate::Token,
+            mut callback: F,
+        ) -> Result<crate::PostAction, Self::Error>
+        where
+            F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+        {
+            self.ping0
+                .process_events(readiness, token, |_, m| callback(0, m))?;
+            self.ping1
+                .process_events(readiness, token, |_, m| callback(1, m))?;
+            self.ping2
+                .process_events(readiness, token, |_, m| callback(2, m))?;
+            Ok(PostAction::Continue)
+        }
+
+        fn register(
+            &mut self,
+            poll: &mut crate::Poll,
+            token_factory: &mut crate::TokenFactory,
+        ) -> crate::Result<()> {
+            crate::batch_register!(poll, token_factory, self.ping0, self.ping1, self.ping2)
+        }
+
+        fn reregister(
+            &mut self,
+            poll: &mut crate::Poll,
+            token_factory: &mut crate::TokenFactory,
+        ) -> crate::Result<()> {
+            crate::batch_reregister!(poll, token_factory, self.ping0, self.ping1, self.ping2)
+        }
+
+        fn unregister(&mut self, poll: &mut crate::Poll) -> crate::Result<()> {
+            crate::batch_unregister!(poll, self.ping0, self.ping1, self.ping2)
+        }
+    }
+
+    #[test]
+    fn test_batch_operations() {
+        let mut fired = [false; 3];
+
+        let (send0, ping0) = make_ping().unwrap();
+        let (send1, ping1) = make_ping().unwrap();
+        let (send2, ping2) = make_ping().unwrap();
+
+        let top = BatchSource {
+            ping0,
+            ping1,
+            ping2,
+        };
+
+        let mut event_loop = crate::EventLoop::<[bool; 3]>::try_new().unwrap();
+        let handle = event_loop.handle();
+
+        let token = handle
+            .insert_source(top, |idx, _, fired| {
+                fired[idx] = true;
+            })
+            .unwrap();
+
+        send0.ping();
+        send1.ping();
+        send2.ping();
+
+        event_loop
+            .dispatch(Duration::new(0, 0), &mut fired)
+            .unwrap();
+
+        assert_eq!(fired, [true; 3]);
+
+        fired = [false; 3];
+
+        handle.update(&token).unwrap();
+
+        send0.ping();
+        send1.ping();
+        send2.ping();
+
+        event_loop
+            .dispatch(Duration::new(0, 0), &mut fired)
+            .unwrap();
+
+        assert_eq!(fired, [true; 3]);
+
+        fired = [false; 3];
+
+        handle.remove(token);
+
+        send0.ping();
+        send1.ping();
+        send2.ping();
+
+        event_loop
+            .dispatch(Duration::new(0, 0), &mut fired)
+            .unwrap();
+
+        assert_eq!(fired, [false; 3]);
+    }
+}
+
\ No newline at end of file diff --git a/api/src/calloop/sources/channel.rs.html b/api/src/calloop/sources/channel.rs.html new file mode 100644 index 00000000..1f0b8906 --- /dev/null +++ b/api/src/calloop/sources/channel.rs.html @@ -0,0 +1,655 @@ +channel.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+
//! An MPSC channel whose receiving end is an event source
+//!
+//! Create a channel using [`channel()`](channel), which returns a
+//! [`Sender`] that can be cloned and sent accross threads if `T: Send`,
+//! and a [`Channel`] that can be inserted into an [`EventLoop`](crate::EventLoop).
+//! It will generate one event per message.
+//!
+//! A synchronous version of the channel is provided by [`sync_channel`], in which
+//! the [`SyncSender`] will block when the channel is full.
+
+use std::sync::mpsc;
+
+use crate::{EventSource, Poll, PostAction, Readiness, Token, TokenFactory};
+
+use super::ping::{make_ping, Ping, PingError, PingSource};
+
+/// The events generated by the channel event source
+#[derive(Debug)]
+pub enum Event<T> {
+    /// A message was received and is bundled here
+    Msg(T),
+    /// The channel was closed
+    ///
+    /// This means all the `Sender`s associated with this channel
+    /// have been dropped, no more messages will ever be received.
+    Closed,
+}
+
+/// The sender end of a channel
+///
+/// It can be cloned and sent accross threads (if `T` is).
+#[derive(Debug)]
+pub struct Sender<T> {
+    sender: mpsc::Sender<T>,
+    ping: Ping,
+}
+
+impl<T> Clone for Sender<T> {
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))]
+    fn clone(&self) -> Sender<T> {
+        Sender {
+            sender: self.sender.clone(),
+            ping: self.ping.clone(),
+        }
+    }
+}
+
+impl<T> Sender<T> {
+    /// Send a message to the channel
+    ///
+    /// This will wake the event loop and deliver an `Event::Msg` to
+    /// it containing the provided value.
+    pub fn send(&self, t: T) -> Result<(), mpsc::SendError<T>> {
+        self.sender.send(t).map(|()| self.ping.ping())
+    }
+}
+
+impl<T> Drop for Sender<T> {
+    fn drop(&mut self) {
+        // ping on drop, to notify about channel closure
+        self.ping.ping();
+    }
+}
+
+/// The sender end of a synchronous channel
+///
+/// It can be cloned and sent accross threads (if `T` is).
+#[derive(Debug)]
+pub struct SyncSender<T> {
+    sender: mpsc::SyncSender<T>,
+    ping: Ping,
+}
+
+impl<T> Clone for SyncSender<T> {
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))]
+    fn clone(&self) -> SyncSender<T> {
+        SyncSender {
+            sender: self.sender.clone(),
+            ping: self.ping.clone(),
+        }
+    }
+}
+
+impl<T> SyncSender<T> {
+    /// Send a message to the synchronous channel
+    ///
+    /// This will wake the event loop and deliver an `Event::Msg` to
+    /// it containing the provided value. If the channel is full, this
+    /// function will block until the event loop empties it and it can
+    /// deliver the message.
+    ///
+    /// Due to the blocking behavior, this method should not be used on the
+    /// same thread as the one running the event loop, as it could cause deadlocks.
+    pub fn send(&self, t: T) -> Result<(), mpsc::SendError<T>> {
+        let ret = self.try_send(t);
+        match ret {
+            Ok(()) => Ok(()),
+            Err(mpsc::TrySendError::Full(t)) => self.sender.send(t).map(|()| self.ping.ping()),
+            Err(mpsc::TrySendError::Disconnected(t)) => Err(mpsc::SendError(t)),
+        }
+    }
+
+    /// Send a message to the synchronous channel
+    ///
+    /// This will wake the event loop and deliver an `Event::Msg` to
+    /// it containing the provided value. If the channel is full, this
+    /// function will return an error, but the event loop will still be
+    /// signaled for readiness.
+    pub fn try_send(&self, t: T) -> Result<(), mpsc::TrySendError<T>> {
+        let ret = self.sender.try_send(t);
+        if let Ok(()) | Err(mpsc::TrySendError::Full(_)) = ret {
+            self.ping.ping();
+        }
+        ret
+    }
+}
+
+/// The receiving end of the channel
+///
+/// This is the event source to be inserted into your `EventLoop`.
+#[derive(Debug)]
+pub struct Channel<T> {
+    receiver: mpsc::Receiver<T>,
+    source: PingSource,
+}
+
+// This impl is safe because the Channel is only able to move around threads
+// when it is not inserted into an event loop. (Otherwise it is stuck into
+// a Source<_> and the internals of calloop, which are not Send).
+// At this point, the Arc<Receiver> has a count of 1, and it is obviously
+// safe to Send between threads.
+unsafe impl<T: Send> Send for Channel<T> {}
+
+impl<T> Channel<T> {
+    /// Proxy for [`mpsc::Receiver::recv`] to manually poll events.
+    ///
+    /// *Note*: Normally you would want to use the `Channel` by inserting
+    /// it into an event loop instead. Use this for example to immediately
+    /// dispatch pending events after creation.
+    pub fn recv(&self) -> Result<T, mpsc::RecvError> {
+        self.receiver.recv()
+    }
+
+    /// Proxy for [`mpsc::Receiver::try_recv`] to manually poll events.
+    ///
+    /// *Note*: Normally you would want to use the `Channel` by inserting
+    /// it into an event loop instead. Use this for example to immediately
+    /// dispatch pending events after creation.
+    pub fn try_recv(&self) -> Result<T, mpsc::TryRecvError> {
+        self.receiver.try_recv()
+    }
+}
+
+/// Create a new asynchronous channel
+pub fn channel<T>() -> (Sender<T>, Channel<T>) {
+    let (sender, receiver) = mpsc::channel();
+    let (ping, source) = make_ping().expect("Failed to create a Ping.");
+    (Sender { sender, ping }, Channel { receiver, source })
+}
+
+/// Create a new synchronous, bounded channel
+pub fn sync_channel<T>(bound: usize) -> (SyncSender<T>, Channel<T>) {
+    let (sender, receiver) = mpsc::sync_channel(bound);
+    let (ping, source) = make_ping().expect("Failed to create a Ping.");
+    (SyncSender { sender, ping }, Channel { receiver, source })
+}
+
+impl<T> EventSource for Channel<T> {
+    type Event = Event<T>;
+    type Metadata = ();
+    type Ret = ();
+    type Error = ChannelError;
+
+    fn process_events<C>(
+        &mut self,
+        readiness: Readiness,
+        token: Token,
+        mut callback: C,
+    ) -> Result<PostAction, Self::Error>
+    where
+        C: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+    {
+        let receiver = &self.receiver;
+        self.source
+            .process_events(readiness, token, |(), &mut ()| loop {
+                match receiver.try_recv() {
+                    Ok(val) => callback(Event::Msg(val), &mut ()),
+                    Err(mpsc::TryRecvError::Empty) => break,
+                    Err(mpsc::TryRecvError::Disconnected) => {
+                        callback(Event::Closed, &mut ());
+                        break;
+                    }
+                }
+            })
+            .map_err(ChannelError)
+    }
+
+    fn register(&mut self, poll: &mut Poll, token_factory: &mut TokenFactory) -> crate::Result<()> {
+        self.source.register(poll, token_factory)
+    }
+
+    fn reregister(
+        &mut self,
+        poll: &mut Poll,
+        token_factory: &mut TokenFactory,
+    ) -> crate::Result<()> {
+        self.source.reregister(poll, token_factory)
+    }
+
+    fn unregister(&mut self, poll: &mut Poll) -> crate::Result<()> {
+        self.source.unregister(poll)
+    }
+}
+
+/// An error arising from processing events for a channel.
+#[derive(thiserror::Error, Debug)]
+#[error(transparent)]
+pub struct ChannelError(PingError);
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn basic_channel() {
+        let mut event_loop = crate::EventLoop::try_new().unwrap();
+
+        let handle = event_loop.handle();
+
+        let (tx, rx) = channel::<()>();
+
+        // (got_msg, got_closed)
+        let mut got = (false, false);
+
+        let _channel_token = handle
+            .insert_source(rx, move |evt, &mut (), got: &mut (bool, bool)| match evt {
+                Event::Msg(()) => {
+                    got.0 = true;
+                }
+                Event::Closed => {
+                    got.1 = true;
+                }
+            })
+            .unwrap();
+
+        // nothing is sent, nothing is received
+        event_loop
+            .dispatch(Some(::std::time::Duration::ZERO), &mut got)
+            .unwrap();
+
+        assert_eq!(got, (false, false));
+
+        // a message is send
+        tx.send(()).unwrap();
+        event_loop
+            .dispatch(Some(::std::time::Duration::ZERO), &mut got)
+            .unwrap();
+
+        assert_eq!(got, (true, false));
+
+        // the sender is dropped
+        ::std::mem::drop(tx);
+        event_loop
+            .dispatch(Some(::std::time::Duration::ZERO), &mut got)
+            .unwrap();
+
+        assert_eq!(got, (true, true));
+    }
+
+    #[test]
+    fn basic_sync_channel() {
+        let mut event_loop = crate::EventLoop::try_new().unwrap();
+
+        let handle = event_loop.handle();
+
+        let (tx, rx) = sync_channel::<()>(2);
+
+        let mut received = (0, false);
+
+        let _channel_token = handle
+            .insert_source(
+                rx,
+                move |evt, &mut (), received: &mut (u32, bool)| match evt {
+                    Event::Msg(()) => {
+                        received.0 += 1;
+                    }
+                    Event::Closed => {
+                        received.1 = true;
+                    }
+                },
+            )
+            .unwrap();
+
+        // nothing is sent, nothing is received
+        event_loop
+            .dispatch(Some(::std::time::Duration::ZERO), &mut received)
+            .unwrap();
+
+        assert_eq!(received.0, 0);
+        assert!(!received.1);
+
+        // fill the channel
+        tx.send(()).unwrap();
+        tx.send(()).unwrap();
+        assert!(tx.try_send(()).is_err());
+
+        // empty it
+        event_loop
+            .dispatch(Some(::std::time::Duration::ZERO), &mut received)
+            .unwrap();
+
+        assert_eq!(received.0, 2);
+        assert!(!received.1);
+
+        // send a final message and drop the sender
+        tx.send(()).unwrap();
+        std::mem::drop(tx);
+
+        // final read of the channel
+        event_loop
+            .dispatch(Some(::std::time::Duration::ZERO), &mut received)
+            .unwrap();
+
+        assert_eq!(received.0, 3);
+        assert!(received.1);
+    }
+}
+
\ No newline at end of file diff --git a/api/src/calloop/sources/futures.rs.html b/api/src/calloop/sources/futures.rs.html new file mode 100644 index 00000000..e92a761a --- /dev/null +++ b/api/src/calloop/sources/futures.rs.html @@ -0,0 +1,841 @@ +futures.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+
//! A futures executor as an event source
+//!
+//! Only available with the `executor` cargo feature of `calloop`.
+//!
+//! This executor is intended for light futures, which will be polled as part of your
+//! event loop. Such futures may be waiting for IO, or for some external computation on an
+//! other thread for example.
+//!
+//! You can create a new executor using the `executor` function, which creates a pair
+//! `(Executor<T>, Scheduler<T>)` to handle futures that all evaluate to type `T`. The
+//! executor should be inserted into your event loop, and will yield the return values of
+//! the futures as they finish into your callback. The scheduler can be cloned and used
+//! to send futures to be executed into the executor. A generic executor can be obtained
+//! by choosing `T = ()` and letting futures handle the forwarding of their return values
+//! (if any) by their own means.
+//!
+//! **Note:** The futures must have their own means of being woken up, as this executor is,
+//! by itself, not I/O aware. See [`LoopHandle::adapt_io`](crate::LoopHandle#method.adapt_io)
+//! for that, or you can use some other mechanism if you prefer.
+
+use async_task::{Builder, Runnable};
+use slab::Slab;
+use std::{
+    cell::RefCell,
+    future::Future,
+    rc::Rc,
+    sync::{
+        atomic::{AtomicBool, Ordering},
+        mpsc, Arc, Mutex,
+    },
+    task::Waker,
+};
+
+use crate::{
+    sources::{
+        channel::ChannelError,
+        ping::{make_ping, Ping, PingError, PingSource},
+        EventSource,
+    },
+    Poll, PostAction, Readiness, Token, TokenFactory,
+};
+
+/// A future executor as an event source
+#[derive(Debug)]
+pub struct Executor<T> {
+    /// Shared state between the executor and the scheduler.
+    state: Rc<State<T>>,
+
+    /// Notifies us when the executor is woken up.
+    ping: PingSource,
+}
+
+/// A scheduler to send futures to an executor
+#[derive(Clone, Debug)]
+pub struct Scheduler<T> {
+    /// Shared state between the executor and the scheduler.
+    state: Rc<State<T>>,
+}
+
+/// The inner state of the executor.
+#[derive(Debug)]
+struct State<T> {
+    /// The incoming queue of runnables to be executed.
+    incoming: mpsc::Receiver<Runnable<usize>>,
+
+    /// The sender corresponding to `incoming`.
+    sender: Arc<Sender>,
+
+    /// The list of currently active tasks.
+    ///
+    /// This is set to `None` when the executor is destroyed.
+    active_tasks: RefCell<Option<Slab<Active<T>>>>,
+}
+
+/// Send a future to an executor.
+///
+/// This needs to be thread-safe, as it is called from a `Waker` that may be on a different thread.
+#[derive(Debug)]
+struct Sender {
+    /// The sender used to send runnables to the executor.
+    ///
+    /// `mpsc::Sender` is `!Sync`, wrapping it in a `Mutex` makes it `Sync`.
+    sender: Mutex<mpsc::Sender<Runnable<usize>>>,
+
+    /// The ping source used to wake up the executor.
+    wake_up: Ping,
+
+    /// Whether the executor has already been woken.
+    notified: AtomicBool,
+}
+
+/// An active future or its result.
+#[derive(Debug)]
+enum Active<T> {
+    /// The future is currently being polled.
+    ///
+    /// Waking this waker will insert the runnable into `incoming`.
+    Future(Waker),
+
+    /// The future has finished polling, and its result is stored here.
+    Finished(T),
+}
+
+impl<T> Active<T> {
+    fn is_finished(&self) -> bool {
+        matches!(self, Active::Finished(_))
+    }
+}
+
+impl<T> Scheduler<T> {
+    /// Sends the given future to the executor associated to this scheduler
+    ///
+    /// Returns an error if the the executor not longer exists.
+    pub fn schedule<Fut: 'static>(&self, future: Fut) -> Result<(), ExecutorDestroyed>
+    where
+        Fut: Future<Output = T>,
+        T: 'static,
+    {
+        /// Store this future's result in the executor.
+        struct StoreOnDrop<'a, T> {
+            index: usize,
+            value: Option<T>,
+            state: &'a State<T>,
+        }
+
+        impl<T> Drop for StoreOnDrop<'_, T> {
+            fn drop(&mut self) {
+                let mut active_tasks = self.state.active_tasks.borrow_mut();
+                if let Some(active_tasks) = active_tasks.as_mut() {
+                    if let Some(value) = self.value.take() {
+                        active_tasks[self.index] = Active::Finished(value);
+                    } else {
+                        // The future was dropped before it finished.
+                        // Remove it from the active list.
+                        active_tasks.remove(self.index);
+                    }
+                }
+            }
+        }
+
+        fn assert_send_and_sync<T: Send + Sync>(_: &T) {}
+
+        let mut active_guard = self.state.active_tasks.borrow_mut();
+        let active_tasks = active_guard.as_mut().ok_or(ExecutorDestroyed)?;
+
+        // Wrap the future in another future that polls it and stores the result.
+        let index = active_tasks.vacant_key();
+        let future = {
+            let state = self.state.clone();
+            async move {
+                let mut guard = StoreOnDrop {
+                    index,
+                    value: None,
+                    state: &state,
+                };
+
+                // Get the value of the future.
+                let value = future.await;
+
+                // Store it in the executor.
+                guard.value = Some(value);
+            }
+        };
+
+        // A schedule function that inserts the runnable into the incoming queue.
+        let schedule = {
+            let sender = self.state.sender.clone();
+            move |runnable| sender.send(runnable)
+        };
+
+        assert_send_and_sync(&schedule);
+
+        // Spawn the future.
+        let (runnable, task) = Builder::new()
+            .metadata(index)
+            .spawn_local(move |_| future, schedule);
+
+        // Insert the runnable into the set of active tasks.
+        active_tasks.insert(Active::Future(runnable.waker()));
+        drop(active_guard);
+
+        // Schedule the runnable and detach the task so it isn't cancellable.
+        runnable.schedule();
+        task.detach();
+
+        Ok(())
+    }
+}
+
+impl Sender {
+    /// Send a runnable to the executor.
+    fn send(&self, runnable: Runnable<usize>) {
+        // Send on the channel.
+        //
+        // All we do with the lock is call `send`, so there's no chance of any state being corrupted on
+        // panic. Therefore it's safe to ignore the mutex poison.
+        if let Err(e) = self
+            .sender
+            .lock()
+            .unwrap_or_else(|e| e.into_inner())
+            .send(runnable)
+        {
+            // The runnable must be dropped on its origin thread, since the original future might be
+            // !Send. This channel immediately sends it back to the Executor, which is pinned to the
+            // origin thread. The executor's Drop implementation will force all of the runnables to be
+            // dropped, therefore the channel should always be available. If we can't send the runnable,
+            // it indicates that the above behavior is broken and that unsoundness has occurred. The
+            // only option at this stage is to forget the runnable and leak the future.
+
+            std::mem::forget(e);
+            unreachable!("Attempted to send runnable to a stopped executor");
+        }
+
+        // If the executor is already awake, don't bother waking it up again.
+        if self.notified.swap(true, Ordering::SeqCst) {
+            return;
+        }
+
+        // Wake the executor.
+        self.wake_up.ping();
+    }
+}
+
+impl<T> Drop for Executor<T> {
+    fn drop(&mut self) {
+        let active_tasks = self.state.active_tasks.borrow_mut().take().unwrap();
+
+        // Wake all of the active tasks in order to destroy their runnables.
+        for (_, task) in active_tasks {
+            if let Active::Future(waker) = task {
+                // Don't let a panicking waker blow everything up.
+                //
+                // There is a chance that a future will panic and, during the unwinding process,
+                // drop this executor. However, since the future panicked, there is a possibility
+                // that the internal state of the waker will be invalid in such a way that the waker
+                // panics as well. Since this would be a panic during a panic, Rust will upgrade it
+                // into an abort.
+                //
+                // In the interest of not aborting without a good reason, we just drop the panic here.
+                std::panic::catch_unwind(|| waker.wake()).ok();
+            }
+        }
+
+        // Drain the queue in order to drop all of the runnables.
+        while self.state.incoming.try_recv().is_ok() {}
+    }
+}
+
+/// Error generated when trying to schedule a future after the
+/// executor was destroyed.
+#[derive(thiserror::Error, Debug)]
+#[error("the executor was destroyed")]
+pub struct ExecutorDestroyed;
+
+/// Create a new executor, and its associated scheduler
+///
+/// May fail due to OS errors preventing calloop to setup its internal pipes (if your
+/// process has reatched its file descriptor limit for example).
+pub fn executor<T>() -> crate::Result<(Executor<T>, Scheduler<T>)> {
+    let (sender, incoming) = mpsc::channel();
+    let (wake_up, ping) = make_ping()?;
+
+    let state = Rc::new(State {
+        incoming,
+        active_tasks: RefCell::new(Some(Slab::new())),
+        sender: Arc::new(Sender {
+            sender: Mutex::new(sender),
+            wake_up,
+            notified: AtomicBool::new(false),
+        }),
+    });
+
+    Ok((
+        Executor {
+            state: state.clone(),
+            ping,
+        },
+        Scheduler { state },
+    ))
+}
+
+impl<T> EventSource for Executor<T> {
+    type Event = T;
+    type Metadata = ();
+    type Ret = ();
+    type Error = ExecutorError;
+
+    fn process_events<F>(
+        &mut self,
+        readiness: Readiness,
+        token: Token,
+        mut callback: F,
+    ) -> Result<PostAction, Self::Error>
+    where
+        F: FnMut(T, &mut ()),
+    {
+        let state = &self.state;
+
+        // Set to the unnotified state.
+        state.sender.notified.store(false, Ordering::SeqCst);
+
+        let clear_readiness = {
+            let mut clear_readiness = false;
+
+            // Process runnables, but not too many at a time; better to move onto the next event quickly!
+            for _ in 0..1024 {
+                let runnable = match state.incoming.try_recv() {
+                    Ok(runnable) => runnable,
+                    Err(_) => {
+                        // Make sure to clear the readiness if there are no more runnables.
+                        clear_readiness = true;
+                        break;
+                    }
+                };
+
+                // Run the runnable.
+                let index = *runnable.metadata();
+                runnable.run();
+
+                // If the runnable finished with a result, call the callback.
+                let mut active_guard = state.active_tasks.borrow_mut();
+                let active_tasks = active_guard.as_mut().unwrap();
+
+                if let Some(state) = active_tasks.get(index) {
+                    if state.is_finished() {
+                        // Take out the state and provide it to the caller.
+                        let result = match active_tasks.remove(index) {
+                            Active::Finished(result) => result,
+                            _ => unreachable!(),
+                        };
+
+                        callback(result, &mut ());
+                    }
+                }
+            }
+
+            clear_readiness
+        };
+
+        // Clear the readiness of the ping source if there are no more runnables.
+        if clear_readiness {
+            self.ping
+                .process_events(readiness, token, |(), &mut ()| {})
+                .map_err(ExecutorError::WakeError)?;
+        }
+
+        Ok(PostAction::Continue)
+    }
+
+    fn register(&mut self, poll: &mut Poll, token_factory: &mut TokenFactory) -> crate::Result<()> {
+        self.ping.register(poll, token_factory)?;
+        Ok(())
+    }
+
+    fn reregister(
+        &mut self,
+        poll: &mut Poll,
+        token_factory: &mut TokenFactory,
+    ) -> crate::Result<()> {
+        self.ping.reregister(poll, token_factory)?;
+        Ok(())
+    }
+
+    fn unregister(&mut self, poll: &mut Poll) -> crate::Result<()> {
+        self.ping.unregister(poll)?;
+        Ok(())
+    }
+}
+
+/// An error arising from processing events in an async executor event source.
+#[derive(thiserror::Error, Debug)]
+pub enum ExecutorError {
+    /// Error while reading new futures added via [`Scheduler::schedule()`].
+    #[error("error adding new futures")]
+    NewFutureError(ChannelError),
+
+    /// Error while processing wake events from existing futures.
+    #[error("error processing wake events")]
+    WakeError(PingError),
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn ready() {
+        let mut event_loop = crate::EventLoop::<u32>::try_new().unwrap();
+
+        let handle = event_loop.handle();
+
+        let (exec, sched) = executor::<u32>().unwrap();
+
+        handle
+            .insert_source(exec, move |ret, &mut (), got| {
+                *got = ret;
+            })
+            .unwrap();
+
+        let mut got = 0;
+
+        let fut = async { 42 };
+
+        event_loop
+            .dispatch(Some(::std::time::Duration::ZERO), &mut got)
+            .unwrap();
+
+        // the future is not yet inserted, and thus has not yet run
+        assert_eq!(got, 0);
+
+        sched.schedule(fut).unwrap();
+
+        event_loop
+            .dispatch(Some(::std::time::Duration::ZERO), &mut got)
+            .unwrap();
+
+        // the future has run
+        assert_eq!(got, 42);
+    }
+}
+
\ No newline at end of file diff --git a/api/src/calloop/sources/generic.rs.html b/api/src/calloop/sources/generic.rs.html new file mode 100644 index 00000000..4a47ec39 --- /dev/null +++ b/api/src/calloop/sources/generic.rs.html @@ -0,0 +1,851 @@ +generic.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+
//! A generic event source wrapping an IO objects or file descriptor
+//!
+//! You can use this general purpose adapter around file-descriptor backed objects to
+//! insert into an [`EventLoop`](crate::EventLoop).
+//!
+//! The event generated by this [`Generic`] event source are the [`Readiness`](crate::Readiness)
+//! notification itself, and the monitored object is provided to your callback as the second
+//! argument.
+//!
+//! ```
+//! # extern crate calloop;
+//! use calloop::{generic::Generic, Interest, Mode, PostAction};
+//!
+//! # fn main() {
+//! # let mut event_loop = calloop::EventLoop::<()>::try_new()
+//! #                .expect("Failed to initialize the event loop!");
+//! # let handle = event_loop.handle();
+//! # let io_object = std::io::stdin();
+//! handle.insert_source(
+//!     // wrap your IO object in a Generic, here we register for read readiness
+//!     // in level-triggering mode
+//!     Generic::new(io_object, Interest::READ, Mode::Level),
+//!     |readiness, io_object, shared_data| {
+//!         // The first argument of the callback is a Readiness
+//!         // The second is a &mut reference to your object
+//!
+//!         // your callback needs to return a Result<PostAction, std::io::Error>
+//!         // if it returns an error, the event loop will consider this event
+//!         // event source as erroring and report it to the user.
+//!         Ok(PostAction::Continue)
+//!     }
+//! );
+//! # }
+//! ```
+//!
+//! It can also help you implementing your own event sources: just have
+//! these `Generic<_>` as fields of your event source, and delegate the
+//! [`EventSource`](crate::EventSource) implementation to them.
+
+use polling::Poller;
+use std::{
+    borrow,
+    marker::PhantomData,
+    ops,
+    os::unix::io::{AsFd, AsRawFd, BorrowedFd},
+    sync::Arc,
+};
+
+use crate::{EventSource, Interest, Mode, Poll, PostAction, Readiness, Token, TokenFactory};
+
+/// Wrapper to use a type implementing `AsRawFd` but not `AsFd` with `Generic`
+#[derive(Debug)]
+pub struct FdWrapper<T: AsRawFd>(T);
+
+impl<T: AsRawFd> FdWrapper<T> {
+    /// Wrap `inner` with an `AsFd` implementation.
+    ///
+    /// # Safety
+    /// This is safe if the `AsRawFd` implementation of `inner` always returns
+    /// a valid fd. This should usually be true for types implementing
+    /// `AsRawFd`. But this isn't guaranteed with `FdWrapper<RawFd>`.
+    pub unsafe fn new(inner: T) -> Self {
+        Self(inner)
+    }
+}
+
+impl<T: AsRawFd> ops::Deref for FdWrapper<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+impl<T: AsRawFd> ops::DerefMut for FdWrapper<T> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.0
+    }
+}
+
+impl<T: AsRawFd> AsFd for FdWrapper<T> {
+    fn as_fd(&self) -> BorrowedFd {
+        unsafe { BorrowedFd::borrow_raw(self.0.as_raw_fd()) }
+    }
+}
+
+/// A wrapper around a type that doesn't expose it mutably safely.
+///
+/// The [`EventSource`] trait's `Metadata` type demands mutable access to the inner I/O source.
+/// However, the inner polling source used by `calloop` keeps the handle-based equivalent of an
+/// immutable pointer to the underlying object's I/O handle. Therefore, if the inner source is
+/// dropped, this leaves behind a dangling pointer which immediately invokes undefined behavior
+/// on the next poll of the event loop.
+///
+/// In order to prevent this from happening, the [`Generic`] I/O source must not directly expose
+/// a mutable reference to the underlying handle. This type wraps around the underlying handle and
+/// easily allows users to take immutable (`&`) references to the type, but makes mutable (`&mut`)
+/// references unsafe to get. Therefore, it prevents the source from being moved out and dropped
+/// while it is still registered in the event loop.
+///
+/// [`EventSource`]: crate::EventSource
+#[derive(Debug)]
+pub struct NoIoDrop<T>(T);
+
+impl<T> NoIoDrop<T> {
+    /// Get a mutable reference.
+    ///
+    /// # Safety
+    ///
+    /// The inner type's I/O source must not be dropped.
+    pub unsafe fn get_mut(&mut self) -> &mut T {
+        &mut self.0
+    }
+}
+
+impl<T> AsRef<T> for NoIoDrop<T> {
+    fn as_ref(&self) -> &T {
+        &self.0
+    }
+}
+
+impl<T> borrow::Borrow<T> for NoIoDrop<T> {
+    fn borrow(&self) -> &T {
+        &self.0
+    }
+}
+
+impl<T> ops::Deref for NoIoDrop<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+impl<T: AsFd> AsFd for NoIoDrop<T> {
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        // SAFETY: The innter type is not mutated.
+        self.0.as_fd()
+    }
+}
+
+/// A generic event source wrapping a FD-backed type
+#[derive(Debug)]
+pub struct Generic<F: AsFd, E = std::io::Error> {
+    /// The wrapped FD-backed type.
+    ///
+    /// This must be deregistered before it is dropped.
+    file: Option<NoIoDrop<F>>,
+    /// The programmed interest
+    pub interest: Interest,
+    /// The programmed mode
+    pub mode: Mode,
+
+    /// Back-reference to the poller.
+    ///
+    /// This is needed to drop the original file.
+    poller: Option<Arc<Poller>>,
+
+    // This token is used by the event loop logic to look up this source when an
+    // event occurs.
+    token: Option<Token>,
+
+    // This allows us to make the associated error and return types generic.
+    _error_type: PhantomData<E>,
+}
+
+impl<F: AsFd> Generic<F, std::io::Error> {
+    /// Wrap a FD-backed type into a `Generic` event source that uses
+    /// [`std::io::Error`] as its error type.
+    pub fn new(file: F, interest: Interest, mode: Mode) -> Generic<F, std::io::Error> {
+        Generic {
+            file: Some(NoIoDrop(file)),
+            interest,
+            mode,
+            token: None,
+            poller: None,
+            _error_type: PhantomData,
+        }
+    }
+
+    /// Wrap a FD-backed type into a `Generic` event source using an arbitrary error type.
+    pub fn new_with_error<E>(file: F, interest: Interest, mode: Mode) -> Generic<F, E> {
+        Generic {
+            file: Some(NoIoDrop(file)),
+            interest,
+            mode,
+            token: None,
+            poller: None,
+            _error_type: PhantomData,
+        }
+    }
+}
+
+impl<F: AsFd, E> Generic<F, E> {
+    /// Unwrap the `Generic` source to retrieve the underlying type
+    pub fn unwrap(mut self) -> F {
+        let NoIoDrop(file) = self.file.take().unwrap();
+
+        // Remove it from the poller.
+        if let Some(poller) = self.poller.take() {
+            poller.delete(file.as_fd()).ok();
+        }
+
+        file
+    }
+
+    /// Get a reference to the underlying type.
+    pub fn get_ref(&self) -> &F {
+        &self.file.as_ref().unwrap().0
+    }
+
+    /// Get a mutable reference to the underlying type.
+    ///
+    /// # Safety
+    ///
+    /// This is unsafe because it allows you to modify the underlying type, which
+    /// allows you to drop the underlying event source. Dropping the underlying source
+    /// leads to a dangling reference.
+    pub unsafe fn get_mut(&mut self) -> &mut F {
+        self.file.as_mut().unwrap().get_mut()
+    }
+}
+
+impl<F: AsFd, E> Drop for Generic<F, E> {
+    fn drop(&mut self) {
+        // Remove it from the poller.
+        if let (Some(file), Some(poller)) = (self.file.take(), self.poller.take()) {
+            poller.delete(file.as_fd()).ok();
+        }
+    }
+}
+
+impl<F, E> EventSource for Generic<F, E>
+where
+    F: AsFd,
+    E: Into<Box<dyn std::error::Error + Send + Sync>>,
+{
+    type Event = Readiness;
+    type Metadata = NoIoDrop<F>;
+    type Ret = Result<PostAction, E>;
+    type Error = E;
+
+    fn process_events<C>(
+        &mut self,
+        readiness: Readiness,
+        token: Token,
+        mut callback: C,
+    ) -> Result<PostAction, Self::Error>
+    where
+        C: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+    {
+        // If the token is invalid or not ours, skip processing.
+        if self.token != Some(token) {
+            return Ok(PostAction::Continue);
+        }
+
+        callback(readiness, self.file.as_mut().unwrap())
+    }
+
+    fn register(&mut self, poll: &mut Poll, token_factory: &mut TokenFactory) -> crate::Result<()> {
+        let token = token_factory.token();
+
+        // Make sure we can use the poller to deregister if need be.
+        self.poller = Some(poll.poller().clone());
+
+        // SAFETY: We've now ensured that we have a poller to deregister with.
+        unsafe {
+            poll.register(
+                &self.file.as_ref().unwrap().0,
+                self.interest,
+                self.mode,
+                token,
+            )?;
+        }
+
+        self.token = Some(token);
+        Ok(())
+    }
+
+    fn reregister(
+        &mut self,
+        poll: &mut Poll,
+        token_factory: &mut TokenFactory,
+    ) -> crate::Result<()> {
+        let token = token_factory.token();
+
+        poll.reregister(
+            &self.file.as_ref().unwrap().0,
+            self.interest,
+            self.mode,
+            token,
+        )?;
+
+        self.token = Some(token);
+        Ok(())
+    }
+
+    fn unregister(&mut self, poll: &mut Poll) -> crate::Result<()> {
+        poll.unregister(&self.file.as_ref().unwrap().0)?;
+        self.poller = None;
+        self.token = None;
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::io::{Read, Write};
+
+    use super::Generic;
+    use crate::{Dispatcher, Interest, Mode, PostAction};
+    #[cfg(unix)]
+    #[test]
+    fn dispatch_unix() {
+        use std::os::unix::net::UnixStream;
+
+        let mut event_loop = crate::EventLoop::try_new().unwrap();
+
+        let handle = event_loop.handle();
+
+        let (mut tx, rx) = UnixStream::pair().unwrap();
+
+        let generic = Generic::new(rx, Interest::READ, Mode::Level);
+
+        let mut dispached = false;
+
+        let _generic_token = handle
+            .insert_source(generic, move |readiness, file, d| {
+                assert!(readiness.readable);
+                // we have not registered for writability
+                assert!(!readiness.writable);
+                let mut buffer = vec![0; 10];
+                let ret = (&**file).read(&mut buffer).unwrap();
+                assert_eq!(ret, 6);
+                assert_eq!(&buffer[..6], &[1, 2, 3, 4, 5, 6]);
+
+                *d = true;
+                Ok(PostAction::Continue)
+            })
+            .unwrap();
+
+        event_loop
+            .dispatch(Some(::std::time::Duration::ZERO), &mut dispached)
+            .unwrap();
+
+        assert!(!dispached);
+
+        let ret = tx.write(&[1, 2, 3, 4, 5, 6]).unwrap();
+        assert_eq!(ret, 6);
+        tx.flush().unwrap();
+
+        event_loop
+            .dispatch(Some(::std::time::Duration::ZERO), &mut dispached)
+            .unwrap();
+
+        assert!(dispached);
+    }
+
+    #[test]
+    fn register_deregister_unix() {
+        use std::os::unix::net::UnixStream;
+
+        let mut event_loop = crate::EventLoop::try_new().unwrap();
+
+        let handle = event_loop.handle();
+
+        let (mut tx, rx) = UnixStream::pair().unwrap();
+
+        let generic = Generic::new(rx, Interest::READ, Mode::Level);
+        let dispatcher = Dispatcher::new(generic, move |_, _, d| {
+            *d = true;
+            Ok(PostAction::Continue)
+        });
+
+        let mut dispached = false;
+
+        let generic_token = handle.register_dispatcher(dispatcher.clone()).unwrap();
+
+        event_loop
+            .dispatch(Some(::std::time::Duration::ZERO), &mut dispached)
+            .unwrap();
+
+        assert!(!dispached);
+
+        // remove the source, and then write something
+
+        event_loop.handle().remove(generic_token);
+
+        let ret = tx.write(&[1, 2, 3, 4, 5, 6]).unwrap();
+        assert_eq!(ret, 6);
+        tx.flush().unwrap();
+
+        event_loop
+            .dispatch(Some(::std::time::Duration::ZERO), &mut dispached)
+            .unwrap();
+
+        // the source has not been dispatched, as the source is no longer here
+        assert!(!dispached);
+
+        // insert it again
+        let generic = dispatcher.into_source_inner();
+        let _generic_token = handle
+            .insert_source(generic, move |readiness, file, d| {
+                assert!(readiness.readable);
+                // we have not registered for writability
+                assert!(!readiness.writable);
+                let mut buffer = vec![0; 10];
+                let ret = (&**file).read(&mut buffer).unwrap();
+                assert_eq!(ret, 6);
+                assert_eq!(&buffer[..6], &[1, 2, 3, 4, 5, 6]);
+
+                *d = true;
+                Ok(PostAction::Continue)
+            })
+            .unwrap();
+
+        event_loop
+            .dispatch(Some(::std::time::Duration::ZERO), &mut dispached)
+            .unwrap();
+
+        // the has now been properly dispatched
+        assert!(dispached);
+    }
+}
+
\ No newline at end of file diff --git a/api/src/calloop/sources/mod.rs.html b/api/src/calloop/sources/mod.rs.html new file mode 100644 index 00000000..fa784590 --- /dev/null +++ b/api/src/calloop/sources/mod.rs.html @@ -0,0 +1,1569 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+
use std::{
+    cell::{Ref, RefCell, RefMut},
+    ops::{BitOr, BitOrAssign},
+    rc::Rc,
+};
+
+pub use crate::loop_logic::EventIterator;
+use crate::{sys::TokenFactory, Poll, Readiness, RegistrationToken, Token};
+
+pub mod channel;
+#[cfg(feature = "executor")]
+#[cfg_attr(docsrs, doc(cfg(feature = "executor")))]
+pub mod futures;
+pub mod generic;
+pub mod ping;
+#[cfg(all(target_os = "linux", feature = "signals"))]
+#[cfg_attr(docsrs, doc(cfg(target_os = "linux")))]
+pub mod signals;
+pub mod timer;
+pub mod transient;
+
+/// Possible actions that can be requested to the event loop by an
+/// event source once its events have been processed.
+///
+/// `PostAction` values can be combined with the `|` (bit-or) operator (or with
+/// `|=`) with the result that:
+/// - if both values are identical, the result is that value
+/// - if they are different, the result is [`Reregister`](PostAction::Reregister)
+///
+/// Bit-or-ing these results is useful for composed sources to combine the
+/// results of their child sources, but note that it only applies to the child
+/// sources. For example, if every child source returns `Continue`, the result
+/// will be `Continue`, but the parent source might still need to return
+/// `Reregister` or something else depending on any additional logic it uses.
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum PostAction {
+    /// Continue listening for events on this source as before
+    Continue,
+    /// Trigger a re-registration of this source
+    Reregister,
+    /// Disable this source
+    ///
+    /// Has the same effect as [`LoopHandle::disable`](crate::LoopHandle#method.disable)
+    Disable,
+    /// Remove this source from the eventloop
+    ///
+    /// Has the same effect as [`LoopHandle::kill`](crate::LoopHandle#method.kill)
+    Remove,
+}
+
+/// Combines `PostAction` values returned from nested event sources.
+impl BitOr for PostAction {
+    type Output = Self;
+
+    fn bitor(self, rhs: Self) -> Self::Output {
+        if matches!(self, x if x == rhs) {
+            self
+        } else {
+            Self::Reregister
+        }
+    }
+}
+
+/// Combines `PostAction` values returned from nested event sources.
+impl BitOrAssign for PostAction {
+    fn bitor_assign(&mut self, rhs: Self) {
+        if *self != rhs {
+            *self = Self::Reregister;
+        }
+    }
+}
+
+/// Trait representing an event source
+///
+/// This is the trait you need to implement if you wish to create your own
+/// calloop-compatible event sources.
+///
+/// The 3 associated types define the type of closure the user will need to
+/// provide to process events for your event source.
+///
+/// The `process_events` method will be called when one of the FD you registered
+/// is ready, with the associated readiness and token.
+///
+/// The `register`, `reregister` and `unregister` methods are plumbing to let your
+/// source register itself with the polling system. See their documentation for details.
+///
+/// In case your event source needs to do some special processing before or after a
+/// polling session occurs (to prepare the underlying source for polling, and cleanup
+/// after that), you can override [`NEEDS_EXTRA_LIFECYCLE_EVENTS`] to `true`.
+/// For all sources for which that constant is `true`, the methods [`before_sleep`] and
+/// [`before_handle_events`] will be called.
+/// [`before_sleep`] is called before the polling system performs a poll operation.
+/// [`before_handle_events`] is called before any process_events methods have been called.
+/// This means that during `process_events` you can assume that all cleanup has occured on
+/// all sources.
+///
+/// [`NEEDS_EXTRA_LIFECYCLE_EVENTS`]: EventSource::NEEDS_EXTRA_LIFECYCLE_EVENTS
+/// [`before_sleep`]: EventSource::before_sleep
+/// [`before_handle_events`]: EventSource::before_handle_events
+pub trait EventSource {
+    /// The type of events generated by your source.
+    type Event;
+    /// Some metadata of your event source
+    ///
+    /// This is typically useful if your source contains some internal state that
+    /// the user may need to interact with when processing events. The user callback
+    /// will receive a `&mut Metadata` reference.
+    ///
+    /// Set to `()` if not needed.
+    type Metadata;
+    /// The return type of the user callback
+    ///
+    /// If the user needs to return some value back to your event source once its
+    /// processing is finshed (to indicate success or failure for example), you can
+    /// specify it using this type.
+    ///
+    /// Set to `()` if not needed.
+    type Ret;
+    /// The error type returned from
+    /// [`process_events()`](Self::process_events()) (not the user callback!).
+    type Error: Into<Box<dyn std::error::Error + Sync + Send>>;
+
+    /// Process any relevant events
+    ///
+    /// This method will be called every time one of the FD you registered becomes
+    /// ready, including the readiness details and the associated token.
+    ///
+    /// Your event source will then do some processing of the file descriptor(s) to generate
+    /// events, and call the provided `callback` for each one of them.
+    ///
+    /// You should ensure you drained the file descriptors of their events, especially if using
+    /// edge-triggered mode.
+    fn process_events<F>(
+        &mut self,
+        readiness: Readiness,
+        token: Token,
+        callback: F,
+    ) -> Result<PostAction, Self::Error>
+    where
+        F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret;
+
+    /// Register yourself to this poll instance
+    ///
+    /// You should register all your relevant file descriptors to the provided [`Poll`](crate::Poll)
+    /// using its [`Poll::register`](crate::Poll#method.register) method.
+    ///
+    /// If you need to register more than one file descriptor, you can change the
+    /// `sub_id` field of the [`Token`](crate::Token) to differentiate between them.
+    fn register(&mut self, poll: &mut Poll, token_factory: &mut TokenFactory) -> crate::Result<()>;
+
+    /// Re-register your file descriptors
+    ///
+    /// Your should update the registration of all your relevant file descriptor to
+    /// the provided [`Poll`](crate::Poll) using its [`Poll::reregister`](crate::Poll#method.reregister),
+    /// if necessary.
+    fn reregister(
+        &mut self,
+        poll: &mut Poll,
+        token_factory: &mut TokenFactory,
+    ) -> crate::Result<()>;
+
+    /// Unregister your file descriptors
+    ///
+    /// You should unregister all your file descriptors from this [`Poll`](crate::Poll) using its
+    /// [`Poll::unregister`](crate::Poll#method.unregister) method.
+    fn unregister(&mut self, poll: &mut Poll) -> crate::Result<()>;
+
+    /// Whether this source needs to be sent the [`EventSource::before_sleep`]
+    /// and [`EventSource::before_handle_events`] notifications. These are opt-in because
+    /// they require more expensive checks, and almost all sources will not need these notifications
+    const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = false;
+    /// Notification that a single `poll` is about to begin
+    ///
+    /// Use this to perform operations which must be done before polling,
+    /// but which may conflict with other event handlers. For example,
+    /// if polling requires a lock to be taken
+    ///
+    /// If this returns Ok(Some), this will be treated as an event arriving in polling, and
+    /// your event handler will be called with the returned `Token` and `Readiness`.
+    /// Polling will however still occur, but with a timeout of 0, so additional events
+    /// from this or other sources may also be handled in the same iterations.
+    /// The returned `Token` must belong to this source
+    // If you need to return multiple synthetic events from this notification, please
+    // open an issue
+    fn before_sleep(&mut self) -> crate::Result<Option<(Readiness, Token)>> {
+        Ok(None)
+    }
+    /// Notification that polling is complete, and [`EventSource::process_events`] will
+    /// be called with the given events for this source. The iterator may be empty,
+    /// which indicates that no events were generated for this source
+    ///
+    /// Please note, the iterator excludes any synthetic events returned from
+    /// [`EventSource::before_sleep`]
+    ///
+    /// Use this to perform a cleanup before event handlers with arbitrary
+    /// code may run. This could be used to drop a lock obtained in
+    /// [`EventSource::before_sleep`]
+    #[allow(unused_variables)]
+    fn before_handle_events(&mut self, events: EventIterator<'_>) {}
+}
+
+/// Blanket implementation for boxed event sources. [`EventSource`] is not an
+/// object safe trait, so this does not include trait objects.
+impl<T: EventSource> EventSource for Box<T> {
+    type Event = T::Event;
+    type Metadata = T::Metadata;
+    type Ret = T::Ret;
+    type Error = T::Error;
+
+    fn process_events<F>(
+        &mut self,
+        readiness: Readiness,
+        token: Token,
+        callback: F,
+    ) -> Result<PostAction, Self::Error>
+    where
+        F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+    {
+        T::process_events(&mut **self, readiness, token, callback)
+    }
+
+    fn register(&mut self, poll: &mut Poll, token_factory: &mut TokenFactory) -> crate::Result<()> {
+        T::register(&mut **self, poll, token_factory)
+    }
+
+    fn reregister(
+        &mut self,
+        poll: &mut Poll,
+        token_factory: &mut TokenFactory,
+    ) -> crate::Result<()> {
+        T::reregister(&mut **self, poll, token_factory)
+    }
+
+    fn unregister(&mut self, poll: &mut Poll) -> crate::Result<()> {
+        T::unregister(&mut **self, poll)
+    }
+
+    const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = T::NEEDS_EXTRA_LIFECYCLE_EVENTS;
+
+    fn before_sleep(&mut self) -> crate::Result<Option<(Readiness, Token)>> {
+        T::before_sleep(&mut **self)
+    }
+
+    fn before_handle_events(&mut self, events: EventIterator) {
+        T::before_handle_events(&mut **self, events)
+    }
+}
+
+/// Blanket implementation for exclusive references to event sources.
+/// [`EventSource`] is not an object safe trait, so this does not include trait
+/// objects.
+impl<T: EventSource> EventSource for &mut T {
+    type Event = T::Event;
+    type Metadata = T::Metadata;
+    type Ret = T::Ret;
+    type Error = T::Error;
+
+    fn process_events<F>(
+        &mut self,
+        readiness: Readiness,
+        token: Token,
+        callback: F,
+    ) -> Result<PostAction, Self::Error>
+    where
+        F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+    {
+        T::process_events(&mut **self, readiness, token, callback)
+    }
+
+    fn register(&mut self, poll: &mut Poll, token_factory: &mut TokenFactory) -> crate::Result<()> {
+        T::register(&mut **self, poll, token_factory)
+    }
+
+    fn reregister(
+        &mut self,
+        poll: &mut Poll,
+        token_factory: &mut TokenFactory,
+    ) -> crate::Result<()> {
+        T::reregister(&mut **self, poll, token_factory)
+    }
+
+    fn unregister(&mut self, poll: &mut Poll) -> crate::Result<()> {
+        T::unregister(&mut **self, poll)
+    }
+
+    const NEEDS_EXTRA_LIFECYCLE_EVENTS: bool = T::NEEDS_EXTRA_LIFECYCLE_EVENTS;
+
+    fn before_sleep(&mut self) -> crate::Result<Option<(Readiness, Token)>> {
+        T::before_sleep(&mut **self)
+    }
+
+    fn before_handle_events(&mut self, events: EventIterator) {
+        T::before_handle_events(&mut **self, events)
+    }
+}
+
+pub(crate) struct DispatcherInner<S, F> {
+    source: S,
+    callback: F,
+    needs_additional_lifecycle_events: bool,
+}
+
+impl<Data, S, F> EventDispatcher<Data> for RefCell<DispatcherInner<S, F>>
+where
+    S: EventSource,
+    F: FnMut(S::Event, &mut S::Metadata, &mut Data) -> S::Ret,
+{
+    fn process_events(
+        &self,
+        readiness: Readiness,
+        token: Token,
+        data: &mut Data,
+    ) -> crate::Result<PostAction> {
+        let mut disp = self.borrow_mut();
+        let DispatcherInner {
+            ref mut source,
+            ref mut callback,
+            ..
+        } = *disp;
+        source
+            .process_events(readiness, token, |event, meta| callback(event, meta, data))
+            .map_err(|e| crate::Error::OtherError(e.into()))
+    }
+
+    fn register(
+        &self,
+        poll: &mut Poll,
+        additional_lifecycle_register: &mut AdditionalLifecycleEventsSet,
+        token_factory: &mut TokenFactory,
+    ) -> crate::Result<()> {
+        let mut this = self.borrow_mut();
+
+        if this.needs_additional_lifecycle_events {
+            additional_lifecycle_register.register(token_factory.registration_token());
+        }
+        this.source.register(poll, token_factory)
+    }
+
+    fn reregister(
+        &self,
+        poll: &mut Poll,
+        additional_lifecycle_register: &mut AdditionalLifecycleEventsSet,
+        token_factory: &mut TokenFactory,
+    ) -> crate::Result<bool> {
+        if let Ok(mut me) = self.try_borrow_mut() {
+            me.source.reregister(poll, token_factory)?;
+            if me.needs_additional_lifecycle_events {
+                additional_lifecycle_register.register(token_factory.registration_token());
+            }
+            Ok(true)
+        } else {
+            Ok(false)
+        }
+    }
+
+    fn unregister(
+        &self,
+        poll: &mut Poll,
+        additional_lifecycle_register: &mut AdditionalLifecycleEventsSet,
+        registration_token: RegistrationToken,
+    ) -> crate::Result<bool> {
+        if let Ok(mut me) = self.try_borrow_mut() {
+            me.source.unregister(poll)?;
+            if me.needs_additional_lifecycle_events {
+                additional_lifecycle_register.unregister(registration_token);
+            }
+            Ok(true)
+        } else {
+            Ok(false)
+        }
+    }
+
+    fn before_sleep(&self) -> crate::Result<Option<(Readiness, Token)>> {
+        let mut disp = self.borrow_mut();
+        let DispatcherInner { ref mut source, .. } = *disp;
+        source.before_sleep()
+    }
+
+    fn before_handle_events(&self, events: EventIterator<'_>) {
+        let mut disp = self.borrow_mut();
+        let DispatcherInner { ref mut source, .. } = *disp;
+        source.before_handle_events(events);
+    }
+}
+
+pub(crate) trait EventDispatcher<Data> {
+    fn process_events(
+        &self,
+        readiness: Readiness,
+        token: Token,
+        data: &mut Data,
+    ) -> crate::Result<PostAction>;
+
+    fn register(
+        &self,
+        poll: &mut Poll,
+        additional_lifecycle_register: &mut AdditionalLifecycleEventsSet,
+        token_factory: &mut TokenFactory,
+    ) -> crate::Result<()>;
+
+    fn reregister(
+        &self,
+        poll: &mut Poll,
+        additional_lifecycle_register: &mut AdditionalLifecycleEventsSet,
+        token_factory: &mut TokenFactory,
+    ) -> crate::Result<bool>;
+
+    fn unregister(
+        &self,
+        poll: &mut Poll,
+        additional_lifecycle_register: &mut AdditionalLifecycleEventsSet,
+        registration_token: RegistrationToken,
+    ) -> crate::Result<bool>;
+
+    fn before_sleep(&self) -> crate::Result<Option<(Readiness, Token)>>;
+    fn before_handle_events(&self, events: EventIterator<'_>);
+}
+
+#[derive(Default)]
+/// The list of events
+pub(crate) struct AdditionalLifecycleEventsSet {
+    /// The list of sources
+    pub(crate) values: Vec<RegistrationToken>,
+}
+
+impl AdditionalLifecycleEventsSet {
+    fn register(&mut self, token: RegistrationToken) {
+        self.values.push(token)
+    }
+
+    fn unregister(&mut self, token: RegistrationToken) {
+        self.values.retain(|it| it != &token)
+    }
+}
+
+// An internal trait to erase the `F` type parameter of `DispatcherInner`
+trait ErasedDispatcher<'a, S, Data> {
+    fn as_source_ref(&self) -> Ref<S>;
+    fn as_source_mut(&self) -> RefMut<S>;
+    fn into_source_inner(self: Rc<Self>) -> S;
+    fn into_event_dispatcher(self: Rc<Self>) -> Rc<dyn EventDispatcher<Data> + 'a>;
+}
+
+impl<'a, S, Data, F> ErasedDispatcher<'a, S, Data> for RefCell<DispatcherInner<S, F>>
+where
+    S: EventSource + 'a,
+    F: FnMut(S::Event, &mut S::Metadata, &mut Data) -> S::Ret + 'a,
+{
+    fn as_source_ref(&self) -> Ref<S> {
+        Ref::map(self.borrow(), |inner| &inner.source)
+    }
+
+    fn as_source_mut(&self) -> RefMut<S> {
+        RefMut::map(self.borrow_mut(), |inner| &mut inner.source)
+    }
+
+    fn into_source_inner(self: Rc<Self>) -> S {
+        if let Ok(ref_cell) = Rc::try_unwrap(self) {
+            ref_cell.into_inner().source
+        } else {
+            panic!("Dispatcher is still registered");
+        }
+    }
+
+    fn into_event_dispatcher(self: Rc<Self>) -> Rc<dyn EventDispatcher<Data> + 'a>
+    where
+        S: 'a,
+    {
+        self as Rc<dyn EventDispatcher<Data> + 'a>
+    }
+}
+
+/// An event source with its callback.
+///
+/// The `Dispatcher` can be registered in an event loop.
+/// Use the `as_source_{ref,mut}` functions to interact with the event source.
+/// Use `into_source_inner` to get the event source back.
+pub struct Dispatcher<'a, S, Data>(Rc<dyn ErasedDispatcher<'a, S, Data> + 'a>);
+
+impl<'a, S, Data> std::fmt::Debug for Dispatcher<'a, S, Data> {
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))]
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.write_str("Dispatcher { ... }")
+    }
+}
+
+impl<'a, S, Data> Dispatcher<'a, S, Data>
+where
+    S: EventSource + 'a,
+{
+    /// Builds a dispatcher.
+    ///
+    /// The resulting `Dispatcher`
+    pub fn new<F>(source: S, callback: F) -> Self
+    where
+        F: FnMut(S::Event, &mut S::Metadata, &mut Data) -> S::Ret + 'a,
+    {
+        Dispatcher(Rc::new(RefCell::new(DispatcherInner {
+            source,
+            callback,
+            needs_additional_lifecycle_events: S::NEEDS_EXTRA_LIFECYCLE_EVENTS,
+        })))
+    }
+
+    /// Returns an immutable reference to the event source.
+    ///
+    /// # Panics
+    ///
+    /// Has the same semantics as `RefCell::borrow()`.
+    ///
+    /// The dispatcher being mutably borrowed while its events are dispatched,
+    /// this method will panic if invoked from within the associated dispatching closure.
+    pub fn as_source_ref(&self) -> Ref<S> {
+        self.0.as_source_ref()
+    }
+
+    /// Returns a mutable reference to the event source.
+    ///
+    /// # Panics
+    ///
+    /// Has the same semantics as `RefCell::borrow_mut()`.
+    ///
+    /// The dispatcher being mutably borrowed while its events are dispatched,
+    /// this method will panic if invoked from within the associated dispatching closure.
+    pub fn as_source_mut(&self) -> RefMut<S> {
+        self.0.as_source_mut()
+    }
+
+    /// Consumes the Dispatcher and returns the inner event source.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the `Dispatcher` is still registered.
+    pub fn into_source_inner(self) -> S {
+        self.0.into_source_inner()
+    }
+
+    pub(crate) fn clone_as_event_dispatcher(&self) -> Rc<dyn EventDispatcher<Data> + 'a> {
+        Rc::clone(&self.0).into_event_dispatcher()
+    }
+}
+
+impl<'a, S, Data> Clone for Dispatcher<'a, S, Data> {
+    fn clone(&self) -> Dispatcher<'a, S, Data> {
+        Dispatcher(Rc::clone(&self.0))
+    }
+}
+
+/// An idle callback that was inserted in this loop
+///
+/// This handle allows you to cancel the callback. Dropping
+/// it will *not* cancel it.
+pub struct Idle<'i> {
+    pub(crate) callback: Rc<RefCell<dyn CancellableIdle + 'i>>,
+}
+
+impl<'i> std::fmt::Debug for Idle<'i> {
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))]
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.write_str("Idle { ... }")
+    }
+}
+
+impl<'i> Idle<'i> {
+    /// Cancel the idle callback if it was not already run
+    pub fn cancel(self) {
+        self.callback.borrow_mut().cancel();
+    }
+}
+
+pub(crate) trait CancellableIdle {
+    fn cancel(&mut self);
+}
+
+impl<F> CancellableIdle for Option<F> {
+    fn cancel(&mut self) {
+        self.take();
+    }
+}
+
+pub(crate) trait IdleDispatcher<Data> {
+    fn dispatch(&mut self, data: &mut Data);
+}
+
+impl<Data, F> IdleDispatcher<Data> for Option<F>
+where
+    F: FnMut(&mut Data),
+{
+    fn dispatch(&mut self, data: &mut Data) {
+        if let Some(callabck) = self.as_mut() {
+            callabck(data);
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::time::Duration;
+
+    use crate::{ping::make_ping, EventLoop};
+
+    // Test event source boxing.
+    #[test]
+    fn test_boxed_source() {
+        let mut fired = false;
+
+        let (pinger, source) = make_ping().unwrap();
+        let boxed = Box::new(source);
+
+        let mut event_loop = EventLoop::try_new().unwrap();
+        let handle = event_loop.handle();
+
+        let token = handle
+            .insert_source(boxed, |_, _, fired| *fired = true)
+            .unwrap();
+
+        pinger.ping();
+
+        event_loop
+            .dispatch(Duration::new(0, 0), &mut fired)
+            .unwrap();
+
+        assert!(fired);
+        fired = false;
+
+        handle.update(&token).unwrap();
+
+        pinger.ping();
+
+        event_loop
+            .dispatch(Duration::new(0, 0), &mut fired)
+            .unwrap();
+
+        assert!(fired);
+        fired = false;
+
+        handle.remove(token);
+
+        event_loop
+            .dispatch(Duration::new(0, 0), &mut fired)
+            .unwrap();
+
+        assert!(!fired);
+    }
+
+    // Test event source trait methods via mut ref.
+    #[test]
+    fn test_mut_ref_source() {
+        let mut fired = false;
+
+        let (pinger, mut source) = make_ping().unwrap();
+        let source_ref = &mut source;
+
+        let mut event_loop = EventLoop::try_new().unwrap();
+        let handle = event_loop.handle();
+
+        let token = handle
+            .insert_source(source_ref, |_, _, fired| *fired = true)
+            .unwrap();
+
+        pinger.ping();
+
+        event_loop
+            .dispatch(Duration::new(0, 0), &mut fired)
+            .unwrap();
+
+        assert!(fired);
+        fired = false;
+
+        handle.update(&token).unwrap();
+
+        pinger.ping();
+
+        event_loop
+            .dispatch(Duration::new(0, 0), &mut fired)
+            .unwrap();
+
+        assert!(fired);
+        fired = false;
+
+        handle.remove(token);
+
+        event_loop
+            .dispatch(Duration::new(0, 0), &mut fired)
+            .unwrap();
+
+        assert!(!fired);
+    }
+
+    // Test PostAction combinations.
+    #[test]
+    fn post_action_combine() {
+        use super::PostAction::*;
+        assert_eq!(Continue | Continue, Continue);
+        assert_eq!(Continue | Reregister, Reregister);
+        assert_eq!(Continue | Disable, Reregister);
+        assert_eq!(Continue | Remove, Reregister);
+
+        assert_eq!(Reregister | Continue, Reregister);
+        assert_eq!(Reregister | Reregister, Reregister);
+        assert_eq!(Reregister | Disable, Reregister);
+        assert_eq!(Reregister | Remove, Reregister);
+
+        assert_eq!(Disable | Continue, Reregister);
+        assert_eq!(Disable | Reregister, Reregister);
+        assert_eq!(Disable | Disable, Disable);
+        assert_eq!(Disable | Remove, Reregister);
+
+        assert_eq!(Remove | Continue, Reregister);
+        assert_eq!(Remove | Reregister, Reregister);
+        assert_eq!(Remove | Disable, Reregister);
+        assert_eq!(Remove | Remove, Remove);
+    }
+
+    // Test PostAction self-assignment.
+    #[test]
+    fn post_action_combine_assign() {
+        use super::PostAction::*;
+
+        let mut action = Continue;
+        action |= Continue;
+        assert_eq!(action, Continue);
+
+        let mut action = Continue;
+        action |= Reregister;
+        assert_eq!(action, Reregister);
+
+        let mut action = Continue;
+        action |= Disable;
+        assert_eq!(action, Reregister);
+
+        let mut action = Continue;
+        action |= Remove;
+        assert_eq!(action, Reregister);
+
+        let mut action = Reregister;
+        action |= Continue;
+        assert_eq!(action, Reregister);
+
+        let mut action = Reregister;
+        action |= Reregister;
+        assert_eq!(action, Reregister);
+
+        let mut action = Reregister;
+        action |= Disable;
+        assert_eq!(action, Reregister);
+
+        let mut action = Reregister;
+        action |= Remove;
+        assert_eq!(action, Reregister);
+
+        let mut action = Disable;
+        action |= Continue;
+        assert_eq!(action, Reregister);
+
+        let mut action = Disable;
+        action |= Reregister;
+        assert_eq!(action, Reregister);
+
+        let mut action = Disable;
+        action |= Disable;
+        assert_eq!(action, Disable);
+
+        let mut action = Disable;
+        action |= Remove;
+        assert_eq!(action, Reregister);
+
+        let mut action = Remove;
+        action |= Continue;
+        assert_eq!(action, Reregister);
+
+        let mut action = Remove;
+        action |= Reregister;
+        assert_eq!(action, Reregister);
+
+        let mut action = Remove;
+        action |= Disable;
+        assert_eq!(action, Reregister);
+
+        let mut action = Remove;
+        action |= Remove;
+        assert_eq!(action, Remove);
+    }
+}
+
\ No newline at end of file diff --git a/api/src/calloop/sources/ping.rs.html b/api/src/calloop/sources/ping.rs.html new file mode 100644 index 00000000..509ee55f --- /dev/null +++ b/api/src/calloop/sources/ping.rs.html @@ -0,0 +1,553 @@ +ping.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+
//! Ping to the event loop
+//!
+//! This is an event source that just produces `()` events whevener the associated
+//! [`Ping::ping`](Ping#method.ping) method is called. If the event source is pinged multiple times
+//! between a single dispatching, it'll only generate one event.
+//!
+//! This event source is a simple way of waking up the event loop from an other part of your program
+//! (and is what backs the [`LoopSignal`](crate::LoopSignal)). It can also be used as a building
+//! block to construct event sources whose source of event is not file descriptor, but rather an
+//! userspace source (like an other thread).
+
+// The ping source has platform-dependent implementations provided by modules
+// under this one. These modules should expose:
+// - a make_ping() function
+// - a Ping type
+// - a PingSource type
+//
+// See eg. the pipe implementation for these items' specific requirements.
+
+#[cfg(target_os = "linux")]
+mod eventfd;
+#[cfg(target_os = "linux")]
+use eventfd as platform;
+
+#[cfg(not(target_os = "linux"))]
+mod pipe;
+#[cfg(not(target_os = "linux"))]
+use pipe as platform;
+
+/// Create a new ping event source
+///
+/// you are given a [`Ping`] instance, which can be cloned and used to ping the
+/// event loop, and a [`PingSource`], which you can insert in your event loop to
+/// receive the pings.
+pub fn make_ping() -> std::io::Result<(Ping, PingSource)> {
+    platform::make_ping()
+}
+
+/// The ping event source
+///
+/// You can insert it in your event loop to receive pings.
+///
+/// If you use it directly, it will automatically remove itself from the event loop
+/// once all [`Ping`] instances are dropped.
+pub type Ping = platform::Ping;
+
+/// The Ping handle
+///
+/// This handle can be cloned and sent accross threads. It can be used to
+/// send pings to the `PingSource`.
+pub type PingSource = platform::PingSource;
+
+/// An error arising from processing events for a ping.
+#[derive(thiserror::Error, Debug)]
+#[error(transparent)]
+pub struct PingError(Box<dyn std::error::Error + Sync + Send>);
+
+#[cfg(test)]
+mod tests {
+    use crate::transient::TransientSource;
+    use std::time::Duration;
+
+    use super::*;
+
+    #[test]
+    fn ping() {
+        let mut event_loop = crate::EventLoop::<bool>::try_new().unwrap();
+
+        let (ping, source) = make_ping().unwrap();
+
+        event_loop
+            .handle()
+            .insert_source(source, |(), &mut (), dispatched| *dispatched = true)
+            .unwrap();
+
+        ping.ping();
+
+        let mut dispatched = false;
+        event_loop
+            .dispatch(std::time::Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(dispatched);
+
+        // Ping has been drained an no longer generates events
+        let mut dispatched = false;
+        event_loop
+            .dispatch(std::time::Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(!dispatched);
+    }
+
+    #[test]
+    fn ping_closed() {
+        let mut event_loop = crate::EventLoop::<bool>::try_new().unwrap();
+
+        let (_, source) = make_ping().unwrap();
+        event_loop
+            .handle()
+            .insert_source(source, |(), &mut (), dispatched| *dispatched = true)
+            .unwrap();
+
+        let mut dispatched = false;
+
+        // If the sender is closed from the start, the ping should first trigger
+        // once, disabling itself but not invoking the callback
+        event_loop
+            .dispatch(std::time::Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(!dispatched);
+
+        // Then it should not trigger any more, so this dispatch should wait the whole 100ms
+        let now = std::time::Instant::now();
+        event_loop
+            .dispatch(std::time::Duration::from_millis(100), &mut dispatched)
+            .unwrap();
+        assert!(now.elapsed() >= std::time::Duration::from_millis(100));
+    }
+
+    #[test]
+    fn ping_removed() {
+        // This keeps track of whether the event fired.
+        let mut dispatched = false;
+
+        let mut event_loop = crate::EventLoop::<bool>::try_new().unwrap();
+
+        let (sender, source) = make_ping().unwrap();
+        let wrapper = TransientSource::from(source);
+
+        // Check that the source starts off in the wrapper.
+        assert!(!wrapper.is_none());
+
+        // Put the source in the loop.
+
+        let dispatcher =
+            crate::Dispatcher::new(wrapper, |(), &mut (), dispatched| *dispatched = true);
+
+        let token = event_loop
+            .handle()
+            .register_dispatcher(dispatcher.clone())
+            .unwrap();
+
+        // Drop the sender and check that it's actually removed.
+        drop(sender);
+
+        // There should be no event, but the loop still needs to wake up to
+        // process the close event (just like in the ping_closed() test).
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(!dispatched);
+
+        // Pull the source wrapper out.
+
+        event_loop.handle().remove(token);
+        let wrapper = dispatcher.into_source_inner();
+
+        // Check that the inner source is now gone.
+        assert!(wrapper.is_none());
+    }
+
+    #[test]
+    fn ping_fired_and_removed() {
+        // This is like ping_removed() with the single difference that we fire a
+        // ping and drop it between two successive dispatches of the loop.
+
+        // This keeps track of whether the event fired.
+        let mut dispatched = false;
+
+        let mut event_loop = crate::EventLoop::<bool>::try_new().unwrap();
+
+        let (sender, source) = make_ping().unwrap();
+        let wrapper = TransientSource::from(source);
+
+        // Check that the source starts off in the wrapper.
+        assert!(!wrapper.is_none());
+
+        // Put the source in the loop.
+
+        let dispatcher =
+            crate::Dispatcher::new(wrapper, |(), &mut (), dispatched| *dispatched = true);
+
+        let token = event_loop
+            .handle()
+            .register_dispatcher(dispatcher.clone())
+            .unwrap();
+
+        // Send a ping AND drop the sender and check that it's actually removed.
+        sender.ping();
+        drop(sender);
+
+        // There should be an event, but the source should be removed from the
+        // loop immediately after.
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(dispatched);
+
+        // Pull the source wrapper out.
+
+        event_loop.handle().remove(token);
+        let wrapper = dispatcher.into_source_inner();
+
+        // Check that the inner source is now gone.
+        assert!(wrapper.is_none());
+    }
+
+    #[test]
+    fn ping_multiple_senders() {
+        // This is like ping_removed() but for testing the behaviour of multiple
+        // senders.
+
+        // This keeps track of whether the event fired.
+        let mut dispatched = false;
+
+        let mut event_loop = crate::EventLoop::<bool>::try_new().unwrap();
+
+        let (sender0, source) = make_ping().unwrap();
+        let wrapper = TransientSource::from(source);
+        let sender1 = sender0.clone();
+        let sender2 = sender1.clone();
+
+        // Check that the source starts off in the wrapper.
+        assert!(!wrapper.is_none());
+
+        // Put the source in the loop.
+
+        let dispatcher =
+            crate::Dispatcher::new(wrapper, |(), &mut (), dispatched| *dispatched = true);
+
+        let token = event_loop
+            .handle()
+            .register_dispatcher(dispatcher.clone())
+            .unwrap();
+
+        // Send a ping AND drop the sender and check that it's actually removed.
+        sender0.ping();
+        drop(sender0);
+
+        // There should be an event, and the source should remain in the loop.
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(dispatched);
+
+        // Now test that the clones still work. Drop after the dispatch loop
+        // instead of before, this time.
+        dispatched = false;
+
+        sender1.ping();
+
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(dispatched);
+
+        // Finally, drop all of them without sending anything.
+
+        dispatched = false;
+
+        drop(sender1);
+        drop(sender2);
+
+        event_loop
+            .dispatch(Duration::ZERO, &mut dispatched)
+            .unwrap();
+        assert!(!dispatched);
+
+        // Pull the source wrapper out.
+
+        event_loop.handle().remove(token);
+        let wrapper = dispatcher.into_source_inner();
+
+        // Check that the inner source is now gone.
+        assert!(wrapper.is_none());
+    }
+}
+
\ No newline at end of file diff --git a/api/src/calloop/sources/ping/eventfd.rs.html b/api/src/calloop/sources/ping/eventfd.rs.html new file mode 100644 index 00000000..5188a379 --- /dev/null +++ b/api/src/calloop/sources/ping/eventfd.rs.html @@ -0,0 +1,389 @@ +eventfd.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+
//! Eventfd based implementation of the ping event source.
+//!
+//! # Implementation notes
+//!
+//! The eventfd is a much lighter signalling mechanism provided by the Linux
+//! kernel. Rather than write an arbitrary sequence of bytes, it only has a
+//! 64-bit counter.
+//!
+//! To avoid closing the eventfd early, we wrap it in a RAII-style closer
+//! `CloseOnDrop` in `make_ping()`. When all the senders are dropped, another
+//! wrapper `FlagOnDrop` handles signalling this to the event source, which is
+//! the sole owner of the eventfd itself. The senders have weak references to
+//! the eventfd, and if the source is dropped before the senders, they will
+//! simply not do anything (except log a message).
+//!
+//! To differentiate between regular ping events and close ping events, we add 2
+//! to the counter for regular events and 1 for close events. In the source we
+//! can then check the LSB and if it's set, we know it was a close event. This
+//! only works if a close event never fires more than once.
+
+use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
+use std::sync::Arc;
+
+use rustix::event::{eventfd, EventfdFlags};
+use rustix::io::{read, write, Errno};
+
+use super::PingError;
+use crate::{
+    generic::Generic, EventSource, Interest, Mode, Poll, PostAction, Readiness, Token, TokenFactory,
+};
+
+// These are not bitfields! They are increments to add to the eventfd counter.
+// Since the fd can only be closed once, we can effectively use the
+// INCREMENT_CLOSE value as a bitmask when checking.
+const INCREMENT_PING: u64 = 0x2;
+const INCREMENT_CLOSE: u64 = 0x1;
+
+#[inline]
+pub fn make_ping() -> std::io::Result<(Ping, PingSource)> {
+    let read = eventfd(0, EventfdFlags::CLOEXEC | EventfdFlags::NONBLOCK)?;
+
+    // We only have one fd for the eventfd. If the sending end closes it when
+    // all copies are dropped, the receiving end will be closed as well. We need
+    // to make sure the fd is not closed until all holders of it have dropped
+    // it.
+
+    let fd = Arc::new(read);
+
+    let ping = Ping {
+        event: Arc::new(FlagOnDrop(Arc::clone(&fd))),
+    };
+
+    let source = PingSource {
+        event: Generic::new(ArcAsFd(fd), Interest::READ, Mode::Level),
+    };
+
+    Ok((ping, source))
+}
+
+// Helper functions for the event source IO.
+
+#[inline]
+fn send_ping(fd: BorrowedFd<'_>, count: u64) -> std::io::Result<()> {
+    assert!(count > 0);
+    match write(fd, &count.to_ne_bytes()) {
+        // The write succeeded, the ping will wake up the loop.
+        Ok(_) => Ok(()),
+
+        // The counter hit its cap, which means previous calls to write() will
+        // wake up the loop.
+        Err(Errno::AGAIN) => Ok(()),
+
+        // Anything else is a real error.
+        Err(e) => Err(e.into()),
+    }
+}
+
+#[inline]
+fn drain_ping(fd: BorrowedFd<'_>) -> std::io::Result<u64> {
+    // The eventfd counter is effectively a u64.
+    const NBYTES: usize = 8;
+    let mut buf = [0u8; NBYTES];
+
+    match read(fd, &mut buf) {
+        // Reading from an eventfd should only ever produce 8 bytes. No looping
+        // is required.
+        Ok(NBYTES) => Ok(u64::from_ne_bytes(buf)),
+
+        Ok(_) => unreachable!(),
+
+        // Any other error can be propagated.
+        Err(e) => Err(e.into()),
+    }
+}
+
+// Rust 1.64.0 adds an `AsFd` implementation for `Arc`, so this won't be needed
+#[derive(Debug)]
+struct ArcAsFd(Arc<OwnedFd>);
+
+impl AsFd for ArcAsFd {
+    fn as_fd(&self) -> BorrowedFd {
+        self.0.as_fd()
+    }
+}
+
+// The event source is simply a generic source with one of the eventfds.
+#[derive(Debug)]
+pub struct PingSource {
+    event: Generic<ArcAsFd>,
+}
+
+impl EventSource for PingSource {
+    type Event = ();
+    type Metadata = ();
+    type Ret = ();
+    type Error = PingError;
+
+    fn process_events<C>(
+        &mut self,
+        readiness: Readiness,
+        token: Token,
+        mut callback: C,
+    ) -> Result<PostAction, Self::Error>
+    where
+        C: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+    {
+        self.event
+            .process_events(readiness, token, |_, fd| {
+                let counter = drain_ping(fd.as_fd())?;
+
+                // If the LSB is set, it means we were closed. If anything else
+                // is also set, it means we were pinged. The two are not
+                // mutually exclusive.
+                let close = (counter & INCREMENT_CLOSE) != 0;
+                let ping = (counter & (u64::MAX - 1)) != 0;
+
+                if ping {
+                    callback((), &mut ());
+                }
+
+                if close {
+                    Ok(PostAction::Remove)
+                } else {
+                    Ok(PostAction::Continue)
+                }
+            })
+            .map_err(|e| PingError(e.into()))
+    }
+
+    fn register(&mut self, poll: &mut Poll, token_factory: &mut TokenFactory) -> crate::Result<()> {
+        self.event.register(poll, token_factory)
+    }
+
+    fn reregister(
+        &mut self,
+        poll: &mut Poll,
+        token_factory: &mut TokenFactory,
+    ) -> crate::Result<()> {
+        self.event.reregister(poll, token_factory)
+    }
+
+    fn unregister(&mut self, poll: &mut Poll) -> crate::Result<()> {
+        self.event.unregister(poll)
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct Ping {
+    // This is an Arc because it's potentially shared with clones. The last one
+    // dropped needs to signal to the event source via the eventfd.
+    event: Arc<FlagOnDrop>,
+}
+
+impl Ping {
+    /// Send a ping to the `PingSource`.
+    pub fn ping(&self) {
+        if let Err(e) = send_ping(self.event.0.as_fd(), INCREMENT_PING) {
+            log::warn!("[calloop] Failed to write a ping: {:?}", e);
+        }
+    }
+}
+
+/// This manages signalling to the PingSource when it's dropped. There should
+/// only ever be one of these per PingSource.
+#[derive(Debug)]
+struct FlagOnDrop(Arc<OwnedFd>);
+
+impl Drop for FlagOnDrop {
+    fn drop(&mut self) {
+        if let Err(e) = send_ping(self.0.as_fd(), INCREMENT_CLOSE) {
+            log::warn!("[calloop] Failed to send close ping: {:?}", e);
+        }
+    }
+}
+
\ No newline at end of file diff --git a/api/src/calloop/sources/timer.rs.html b/api/src/calloop/sources/timer.rs.html new file mode 100644 index 00000000..d6085b24 --- /dev/null +++ b/api/src/calloop/sources/timer.rs.html @@ -0,0 +1,1295 @@ +timer.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+
//! Timer event source
+//!
+//! The [`Timer`] is an event source that will fire its event after a certain amount of time
+//! specified at creation. Its timing is tracked directly by the event loop core logic, and it does
+//! not consume any system resource.
+//!
+//! As of calloop v0.11.0, the event loop always uses high-precision timers. However, the timer
+//! precision varies between operating systems; for instance, the scheduler granularity on Windows
+//! is about 16 milliseconds. If you need to rely on good precision timers in general, you may need
+//! to enable realtime features of your OS to ensure your thread is quickly woken up by the system
+//! scheduler.
+//!
+//! The provided event is an [`Instant`] representing the deadline for which this timer has fired
+//! (which can be earlier than the current time depending on the event loop congestion).
+//!
+//! The callback associated with this event source is expected to return a [`TimeoutAction`], which
+//! can be used to implement self-repeating timers by telling calloop to reprogram the same timer
+//! for a later timeout after it has fired.
+
+/*
+ * This module provides two main types:
+ *
+ * - `Timer` is the user-facing type that represents a timer event source
+ * - `TimerWheel` is an internal data structure for tracking registered timeouts, it is used by
+ *   the polling logic in sys/mod.rs
+ */
+
+use std::{
+    cell::RefCell,
+    collections::BinaryHeap,
+    rc::Rc,
+    task::Waker,
+    time::{Duration, Instant},
+};
+
+use crate::{EventSource, LoopHandle, Poll, PostAction, Readiness, Token, TokenFactory};
+
+#[derive(Debug)]
+struct Registration {
+    token: Token,
+    wheel: Rc<RefCell<TimerWheel>>,
+    counter: u32,
+}
+
+/// A timer event source
+///
+/// When registered to the event loop, it will trigger an event once its deadline is reached.
+/// If the deadline is in the past relative to the moment of its insertion in the event loop,
+/// the `TImer` will trigger an event as soon as the event loop is dispatched.
+#[derive(Debug)]
+pub struct Timer {
+    registration: Option<Registration>,
+    deadline: Option<Instant>,
+}
+
+impl Timer {
+    /// Create a timer that will fire immediately when inserted in the event loop
+    pub fn immediate() -> Timer {
+        Self::from_deadline(Instant::now())
+    }
+
+    /// Create a timer that will fire after a given duration from now
+    pub fn from_duration(duration: Duration) -> Timer {
+        Self::from_deadline_inner(Instant::now().checked_add(duration))
+    }
+
+    /// Create a timer that will fire at a given instant
+    pub fn from_deadline(deadline: Instant) -> Timer {
+        Self::from_deadline_inner(Some(deadline))
+    }
+
+    fn from_deadline_inner(deadline: Option<Instant>) -> Timer {
+        Timer {
+            registration: None,
+            deadline,
+        }
+    }
+
+    /// Changes the deadline of this timer to an [`Instant`]
+    ///
+    /// If the `Timer` is currently registered in the event loop, it needs to be
+    /// re-registered for this change to take effect.
+    pub fn set_deadline(&mut self, deadline: Instant) {
+        self.deadline = Some(deadline);
+    }
+
+    /// Changes the deadline of this timer to a [`Duration`] from now
+    ///
+    /// If the `Timer` is currently registered in the event loop, it needs to be
+    /// re-registered for this change to take effect.
+    pub fn set_duration(&mut self, duration: Duration) {
+        self.deadline = Instant::now().checked_add(duration);
+    }
+
+    /// Get the current deadline of this `Timer`
+    ///
+    /// Returns `None` if the timer has overflowed.
+    pub fn current_deadline(&self) -> Option<Instant> {
+        self.deadline
+    }
+}
+
+impl EventSource for Timer {
+    type Event = Instant;
+    type Metadata = ();
+    type Ret = TimeoutAction;
+    type Error = std::io::Error;
+
+    fn process_events<F>(
+        &mut self,
+        _: Readiness,
+        token: Token,
+        mut callback: F,
+    ) -> Result<PostAction, Self::Error>
+    where
+        F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+    {
+        if let (Some(ref registration), Some(ref deadline)) = (&self.registration, &self.deadline) {
+            if registration.token != token {
+                return Ok(PostAction::Continue);
+            }
+            let new_deadline = match callback(*deadline, &mut ()) {
+                TimeoutAction::Drop => return Ok(PostAction::Remove),
+                TimeoutAction::ToInstant(instant) => instant,
+                TimeoutAction::ToDuration(duration) => match Instant::now().checked_add(duration) {
+                    Some(new_deadline) => new_deadline,
+                    None => {
+                        // The timer has overflowed, meaning we have no choice but to drop it.
+                        self.deadline = None;
+                        return Ok(PostAction::Remove);
+                    }
+                },
+            };
+            // If we received an event, we MUST have a valid counter value
+            registration.wheel.borrow_mut().insert_reuse(
+                registration.counter,
+                new_deadline,
+                registration.token,
+            );
+            self.deadline = Some(new_deadline);
+        }
+        Ok(PostAction::Continue)
+    }
+
+    fn register(&mut self, poll: &mut Poll, token_factory: &mut TokenFactory) -> crate::Result<()> {
+        // Only register a deadline if we haven't overflowed.
+        if let Some(deadline) = self.deadline {
+            let wheel = poll.timers.clone();
+            let token = token_factory.token();
+            let counter = wheel.borrow_mut().insert(deadline, token);
+            self.registration = Some(Registration {
+                token,
+                wheel,
+                counter,
+            });
+        }
+
+        Ok(())
+    }
+
+    fn reregister(
+        &mut self,
+        poll: &mut Poll,
+        token_factory: &mut TokenFactory,
+    ) -> crate::Result<()> {
+        self.unregister(poll)?;
+        self.register(poll, token_factory)
+    }
+
+    fn unregister(&mut self, poll: &mut Poll) -> crate::Result<()> {
+        if let Some(registration) = self.registration.take() {
+            poll.timers.borrow_mut().cancel(registration.counter);
+        }
+        Ok(())
+    }
+}
+
+/// Action to reschedule a timeout if necessary
+#[derive(Debug)]
+pub enum TimeoutAction {
+    /// Don't reschedule this timer
+    Drop,
+    /// Reschedule this timer to a given [`Instant`]
+    ToInstant(Instant),
+    /// Reschedule this timer to a given [`Duration`] in the future
+    ToDuration(Duration),
+}
+
+// Internal representation of a timeout registered in the TimerWheel
+#[derive(Debug)]
+struct TimeoutData {
+    deadline: Instant,
+    token: RefCell<Option<Token>>,
+    counter: u32,
+}
+
+// A data structure for tracking registered timeouts
+#[derive(Debug)]
+pub(crate) struct TimerWheel {
+    heap: BinaryHeap<TimeoutData>,
+    counter: u32,
+}
+
+impl TimerWheel {
+    pub(crate) fn new() -> TimerWheel {
+        TimerWheel {
+            heap: BinaryHeap::new(),
+            counter: 0,
+        }
+    }
+
+    pub(crate) fn insert(&mut self, deadline: Instant, token: Token) -> u32 {
+        self.heap.push(TimeoutData {
+            deadline,
+            token: RefCell::new(Some(token)),
+            counter: self.counter,
+        });
+        let ret = self.counter;
+        self.counter += 1;
+        ret
+    }
+
+    pub(crate) fn insert_reuse(&mut self, counter: u32, deadline: Instant, token: Token) {
+        self.heap.push(TimeoutData {
+            deadline,
+            token: RefCell::new(Some(token)),
+            counter,
+        });
+    }
+
+    pub(crate) fn cancel(&mut self, counter: u32) {
+        self.heap
+            .iter()
+            .find(|data| data.counter == counter)
+            .map(|data| data.token.take());
+    }
+
+    pub(crate) fn next_expired(&mut self, now: Instant) -> Option<(u32, Token)> {
+        loop {
+            // check if there is an expired item
+            if let Some(data) = self.heap.peek() {
+                if data.deadline > now {
+                    return None;
+                }
+                // there is an expired timeout, continue the
+                // loop body
+            } else {
+                return None;
+            }
+
+            // There is an item in the heap, this unwrap cannot blow
+            let data = self.heap.pop().unwrap();
+            if let Some(token) = data.token.into_inner() {
+                return Some((data.counter, token));
+            }
+            // otherwise this timeout was cancelled, continue looping
+        }
+    }
+
+    pub(crate) fn next_deadline(&self) -> Option<std::time::Instant> {
+        self.heap.peek().map(|data| data.deadline)
+    }
+}
+
+// trait implementations for TimeoutData
+
+impl std::cmp::Ord for TimeoutData {
+    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+        // earlier values have priority
+        self.deadline.cmp(&other.deadline).reverse()
+    }
+}
+
+impl std::cmp::PartialOrd for TimeoutData {
+    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+// This impl is required for PartialOrd but actually never used
+// and the type is private, so ignore its coverage
+impl std::cmp::PartialEq for TimeoutData {
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))]
+    fn eq(&self, other: &Self) -> bool {
+        self.deadline == other.deadline
+    }
+}
+
+impl std::cmp::Eq for TimeoutData {}
+
+// Logic for timer futures
+
+/// A future that resolves once a certain timeout is expired
+pub struct TimeoutFuture {
+    deadline: Option<Instant>,
+    waker: Rc<RefCell<Option<Waker>>>,
+}
+
+impl std::fmt::Debug for TimeoutFuture {
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))]
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("TimeoutFuture")
+            .field("deadline", &self.deadline)
+            .finish_non_exhaustive()
+    }
+}
+
+impl TimeoutFuture {
+    /// Create a future that resolves after a given duration
+    pub fn from_duration<Data>(handle: &LoopHandle<'_, Data>, duration: Duration) -> TimeoutFuture {
+        Self::from_deadline_inner(handle, Instant::now().checked_add(duration))
+    }
+
+    /// Create a future that resolves at a given instant
+    pub fn from_deadline<Data>(handle: &LoopHandle<'_, Data>, deadline: Instant) -> TimeoutFuture {
+        Self::from_deadline_inner(handle, Some(deadline))
+    }
+
+    /// Create a future that resolves at a given instant
+    fn from_deadline_inner<Data>(
+        handle: &LoopHandle<'_, Data>,
+        deadline: Option<Instant>,
+    ) -> TimeoutFuture {
+        let timer = Timer::from_deadline_inner(deadline);
+        let waker = Rc::new(RefCell::new(None::<Waker>));
+        handle
+            .insert_source(timer, {
+                let waker = waker.clone();
+                move |_, &mut (), _| {
+                    if let Some(waker) = waker.borrow_mut().clone() {
+                        waker.wake()
+                    }
+                    TimeoutAction::Drop
+                }
+            })
+            .unwrap();
+
+        TimeoutFuture { deadline, waker }
+    }
+}
+
+impl std::future::Future for TimeoutFuture {
+    type Output = ();
+
+    fn poll(
+        self: std::pin::Pin<&mut Self>,
+        cx: &mut std::task::Context<'_>,
+    ) -> std::task::Poll<Self::Output> {
+        match self.deadline {
+            None => return std::task::Poll::Pending,
+
+            Some(deadline) => {
+                if Instant::now() >= deadline {
+                    return std::task::Poll::Ready(());
+                }
+            }
+        }
+
+        *self.waker.borrow_mut() = Some(cx.waker().clone());
+        std::task::Poll::Pending
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::*;
+    use std::time::Duration;
+
+    #[test]
+    fn simple_timer() {
+        let mut event_loop = EventLoop::try_new().unwrap();
+
+        let mut dispatched = false;
+
+        event_loop
+            .handle()
+            .insert_source(
+                Timer::from_duration(Duration::from_millis(100)),
+                |_, &mut (), dispatched| {
+                    *dispatched = true;
+                    TimeoutAction::Drop
+                },
+            )
+            .unwrap();
+
+        event_loop
+            .dispatch(Some(Duration::ZERO), &mut dispatched)
+            .unwrap();
+        // not yet dispatched
+        assert!(!dispatched);
+
+        event_loop
+            .dispatch(Some(Duration::from_millis(150)), &mut dispatched)
+            .unwrap();
+        // now dispatched
+        assert!(dispatched);
+    }
+
+    #[test]
+    fn simple_timer_instant() {
+        let mut event_loop = EventLoop::try_new().unwrap();
+
+        let mut dispatched = false;
+
+        event_loop
+            .handle()
+            .insert_source(
+                Timer::from_duration(Duration::from_millis(100)),
+                |_, &mut (), dispatched| {
+                    *dispatched = true;
+                    TimeoutAction::Drop
+                },
+            )
+            .unwrap();
+
+        event_loop
+            .dispatch(Some(Duration::from_millis(150)), &mut dispatched)
+            .unwrap();
+        // now dispatched
+        assert!(dispatched);
+    }
+
+    #[test]
+    fn immediate_timer() {
+        let mut event_loop = EventLoop::try_new().unwrap();
+
+        let mut dispatched = false;
+
+        event_loop
+            .handle()
+            .insert_source(Timer::immediate(), |_, &mut (), dispatched| {
+                *dispatched = true;
+                TimeoutAction::Drop
+            })
+            .unwrap();
+
+        event_loop
+            .dispatch(Some(Duration::ZERO), &mut dispatched)
+            .unwrap();
+        // now dispatched
+        assert!(dispatched);
+    }
+
+    // We cannot actually test high precision timers, as they are only high precision in release mode
+    // This test is here to ensure that the high-precision codepath are executed and work as intended
+    // even if we cannot test if they are actually high precision
+    #[test]
+    fn high_precision_timer() {
+        let mut event_loop = EventLoop::try_new().unwrap();
+
+        let mut dispatched = false;
+
+        event_loop
+            .handle()
+            .insert_source(
+                Timer::from_duration(Duration::from_millis(100)),
+                |_, &mut (), dispatched| {
+                    *dispatched = true;
+                    TimeoutAction::Drop
+                },
+            )
+            .unwrap();
+
+        event_loop
+            .dispatch(Some(Duration::ZERO), &mut dispatched)
+            .unwrap();
+        // not yet dispatched
+        assert!(!dispatched);
+
+        event_loop
+            .dispatch(Some(Duration::from_micros(10200)), &mut dispatched)
+            .unwrap();
+        // yet not dispatched
+        assert!(!dispatched);
+
+        event_loop
+            .dispatch(Some(Duration::from_millis(100)), &mut dispatched)
+            .unwrap();
+        // now dispatched
+        assert!(dispatched);
+    }
+
+    #[test]
+    fn cancel_timer() {
+        let mut event_loop = EventLoop::try_new().unwrap();
+
+        let mut dispatched = false;
+
+        let token = event_loop
+            .handle()
+            .insert_source(
+                Timer::from_duration(Duration::from_millis(100)),
+                |_, &mut (), dispatched| {
+                    *dispatched = true;
+                    TimeoutAction::Drop
+                },
+            )
+            .unwrap();
+
+        event_loop
+            .dispatch(Some(Duration::ZERO), &mut dispatched)
+            .unwrap();
+        // not yet dispatched
+        assert!(!dispatched);
+
+        event_loop.handle().remove(token);
+
+        event_loop
+            .dispatch(Some(Duration::from_millis(150)), &mut dispatched)
+            .unwrap();
+        // still not dispatched
+        assert!(!dispatched);
+    }
+
+    #[test]
+    fn repeating_timer() {
+        let mut event_loop = EventLoop::try_new().unwrap();
+
+        let mut dispatched = 0;
+
+        event_loop
+            .handle()
+            .insert_source(
+                Timer::from_duration(Duration::from_millis(500)),
+                |_, &mut (), dispatched| {
+                    *dispatched += 1;
+                    TimeoutAction::ToDuration(Duration::from_millis(500))
+                },
+            )
+            .unwrap();
+
+        event_loop
+            .dispatch(Some(Duration::from_millis(250)), &mut dispatched)
+            .unwrap();
+        assert_eq!(dispatched, 0);
+
+        event_loop
+            .dispatch(Some(Duration::from_millis(510)), &mut dispatched)
+            .unwrap();
+        assert_eq!(dispatched, 1);
+
+        event_loop
+            .dispatch(Some(Duration::from_millis(510)), &mut dispatched)
+            .unwrap();
+        assert_eq!(dispatched, 2);
+
+        event_loop
+            .dispatch(Some(Duration::from_millis(510)), &mut dispatched)
+            .unwrap();
+        assert_eq!(dispatched, 3);
+    }
+
+    #[cfg(feature = "executor")]
+    #[test]
+    fn timeout_future() {
+        let mut event_loop = EventLoop::try_new().unwrap();
+
+        let mut dispatched = 0;
+
+        let timeout_1 =
+            TimeoutFuture::from_duration(&event_loop.handle(), Duration::from_millis(500));
+        let timeout_2 =
+            TimeoutFuture::from_duration(&event_loop.handle(), Duration::from_millis(1500));
+        // This one should never go off.
+        let timeout_3 = TimeoutFuture::from_duration(&event_loop.handle(), Duration::MAX);
+
+        let (exec, sched) = crate::sources::futures::executor().unwrap();
+        event_loop
+            .handle()
+            .insert_source(exec, move |(), &mut (), got| {
+                *got += 1;
+            })
+            .unwrap();
+
+        sched.schedule(timeout_1).unwrap();
+        sched.schedule(timeout_2).unwrap();
+        sched.schedule(timeout_3).unwrap();
+
+        // We do a 0-timeout dispatch after every regular dispatch to let the timeout triggers
+        // flow back to the executor
+
+        event_loop
+            .dispatch(Some(Duration::ZERO), &mut dispatched)
+            .unwrap();
+        event_loop
+            .dispatch(Some(Duration::ZERO), &mut dispatched)
+            .unwrap();
+        assert_eq!(dispatched, 0);
+
+        event_loop
+            .dispatch(Some(Duration::from_millis(1000)), &mut dispatched)
+            .unwrap();
+        event_loop
+            .dispatch(Some(Duration::ZERO), &mut dispatched)
+            .unwrap();
+        assert_eq!(dispatched, 1);
+
+        event_loop
+            .dispatch(Some(Duration::from_millis(1100)), &mut dispatched)
+            .unwrap();
+        event_loop
+            .dispatch(Some(Duration::ZERO), &mut dispatched)
+            .unwrap();
+        assert_eq!(dispatched, 2);
+    }
+
+    #[test]
+    fn no_overflow() {
+        let mut event_loop = EventLoop::try_new().unwrap();
+
+        let mut dispatched = 0;
+
+        event_loop
+            .handle()
+            .insert_source(
+                Timer::from_duration(Duration::from_millis(500)),
+                |_, &mut (), dispatched| {
+                    *dispatched += 1;
+                    TimeoutAction::Drop
+                },
+            )
+            .unwrap();
+
+        event_loop
+            .handle()
+            .insert_source(Timer::from_duration(Duration::MAX), |_, &mut (), _| {
+                panic!("This timer should never go off")
+            })
+            .unwrap();
+
+        event_loop
+            .dispatch(Some(Duration::from_millis(250)), &mut dispatched)
+            .unwrap();
+        assert_eq!(dispatched, 0);
+
+        event_loop
+            .dispatch(Some(Duration::from_millis(510)), &mut dispatched)
+            .unwrap();
+        assert_eq!(dispatched, 1);
+
+        event_loop
+            .dispatch(Some(Duration::from_millis(510)), &mut dispatched)
+            .unwrap();
+        assert_eq!(dispatched, 1);
+    }
+}
+
\ No newline at end of file diff --git a/api/src/calloop/sources/transient.rs.html b/api/src/calloop/sources/transient.rs.html new file mode 100644 index 00000000..b4fa3a3c --- /dev/null +++ b/api/src/calloop/sources/transient.rs.html @@ -0,0 +1,2265 @@ +transient.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+
//! Wrapper for a transient Calloop event source.
+//!
+//! If you have high level event source that you expect to remain in the event
+//! loop indefinitely, and another event source nested inside that one that you
+//! expect to require removal or disabling from time to time, this module can
+//! handle it for you.
+
+/// A [`TransientSource`] wraps a Calloop event source and manages its
+/// registration. A user of this type only needs to perform the usual Calloop
+/// calls (`process_events()` and `*register()`) and the return value of
+/// [`process_events()`](crate::EventSource::process_events).
+///
+/// Rather than needing to check for the full set of
+/// [`PostAction`](crate::PostAction) values returned from `process_events()`,
+/// you can just check for `Continue` or `Reregister` and pass that back out
+/// through your own `process_events()` implementation. In your registration
+/// functions, you then only need to call the same function on this type ie.
+/// `register()` inside `register()` etc.
+///
+/// For example, say you have a source that contains a channel along with some
+/// other logic. If the channel's sending end has been dropped, it needs to be
+/// removed from the loop. So to manage this, you use this in your struct:
+///
+/// ```none,actually-rust-but-see-https://github.com/rust-lang/rust/issues/63193
+/// struct CompositeSource {
+///    // Event source for channel.
+///    mpsc_receiver: TransientSource<calloop::channel::Channel<T>>,
+///
+///    // Any other fields go here...
+/// }
+/// ```
+///
+/// To create the transient source, you can simply use the `Into`
+/// implementation:
+///
+/// ```none,actually-rust-but-see-https://github.com/rust-lang/rust/issues/63193
+/// let (sender, source) = channel();
+/// let mpsc_receiver: TransientSource<Channel> = source.into();
+/// ```
+///
+/// (If you want to start off with an empty `TransientSource`, you can just use
+/// `Default::default()` instead.)
+///
+/// `TransientSource` implements [`EventSource`](crate::EventSource) and passes
+/// through `process_events()` calls, so in the parent's `process_events()`
+/// implementation you can just do this:
+///
+/// ```none,actually-rust-but-see-https://github.com/rust-lang/rust/issues/63193
+/// fn process_events<F>(
+///     &mut self,
+///     readiness: calloop::Readiness,
+///     token: calloop::Token,
+///     callback: F,
+/// ) -> Result<calloop::PostAction, Self::Error>
+/// where
+///     F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+/// {
+///     let channel_return = self.mpsc_receiver.process_events(readiness, token, callback)?;
+///
+///     // Perform other logic here...
+///
+///     Ok(channel_return)
+/// }
+/// ```
+///
+/// Note that:
+///
+///   - You can call `process_events()` on the `TransientSource<Channel>` even
+///     if the channel has been unregistered and dropped. All that will happen
+///     is that you won't get any events from it.
+///
+///   - The [`PostAction`](crate::PostAction) returned from `process_events()`
+///     will only ever be `PostAction::Continue` or `PostAction::Reregister`.
+///     You will still need to combine this with the result of any other sources
+///     (transient or not).
+///
+/// Once you return `channel_return` from your `process_events()` method (and
+/// assuming it propagates all the way up to the event loop itself through any
+/// other event sources), the event loop might call `reregister()` on your
+/// source. All your source has to do is:
+///
+/// ```none,actually-rust-but-see-https://github.com/rust-lang/rust/issues/63193
+/// fn reregister(
+///     &mut self,
+///     poll: &mut calloop::Poll,
+///     token_factory: &mut calloop::TokenFactory,
+/// ) -> crate::Result<()> {
+///     self.mpsc_receiver.reregister(poll, token_factory)?;
+///
+///     // Other registration actions...
+///
+///     Ok(())
+/// }
+/// ```
+///
+/// The `TransientSource` will take care of updating the registration of the
+/// inner source, even if it actually needs to be unregistered or initially
+/// registered.
+///
+/// ## Replacing or removing `TransientSource`s
+///
+/// Not properly removing or replacing `TransientSource`s can cause spurious
+/// wakeups of the event loop, and in some cases can leak file descriptors or
+/// fail to free entries in Calloop's internal data structures. No unsoundness
+/// or undefined behaviour will result, but leaking file descriptors can result
+/// in errors or panics.
+///
+/// If you want to remove a source before it returns `PostAction::Remove`, use
+/// the [`TransientSource::remove()`] method. If you want to replace a source
+/// with another one, use the [`TransientSource::replace()`] method. Either of
+/// these may be called at any time during processing or from outside the event
+/// loop. Both require either returning `PostAction::Reregister` from the
+/// `process_event()` call that does this, or reregistering the event source
+/// some other way eg. via the top-level loop handle.
+///
+/// If, instead, you directly assign a new source to the variable holding the
+/// `TransientSource`, the inner source will be dropped before it can be
+/// unregistered. For example:
+///
+/// ```none,actually-rust-but-see-https://github.com/rust-lang/rust/issues/63193
+/// self.mpsc_receiver = Default::default();
+/// self.mpsc_receiver = new_channel.into();
+/// ```
+#[derive(Debug, Default)]
+pub struct TransientSource<T> {
+    state: TransientSourceState<T>,
+}
+
+/// This is the internal state of the [`TransientSource`], as a separate type so
+/// it's not exposed.
+#[derive(Debug)]
+enum TransientSourceState<T> {
+    /// The source should be kept in the loop.
+    Keep(T),
+    /// The source needs to be registered with the loop.
+    Register(T),
+    /// The source needs to be disabled but kept.
+    Disable(T),
+    /// The source needs to be removed from the loop.
+    Remove(T),
+    /// The source is being replaced by another. For most API purposes (eg.
+    /// `map()`), this will be treated as the `Register` state enclosing the new
+    /// source.
+    Replace {
+        /// The new source, which will be registered and used from now on.
+        new: T,
+        /// The old source, which will be unregistered and dropped.
+        old: T,
+    },
+    /// The source has been removed from the loop and dropped (this might also
+    /// be observed if there is a panic while changing states).
+    None,
+}
+
+impl<T> Default for TransientSourceState<T> {
+    fn default() -> Self {
+        Self::None
+    }
+}
+
+impl<T> TransientSourceState<T> {
+    /// If a caller needs to flag the contained source for removal or
+    /// registration, we need to replace the enum variant safely. This requires
+    /// having a `None` value in there temporarily while we do the swap.
+    ///
+    /// If the variant is `None` the value will not change and `replacer` will
+    /// not be called. If the variant is `Replace` then `replacer` will be
+    /// called **on the new source**, which may cause the old source to leak
+    /// registration in the event loop if it has not yet been unregistered.
+    ///
+    /// The `replacer` function here is expected to be one of the enum variant
+    /// constructors eg. `replace(TransientSource::Remove)`.
+    fn replace_state<F>(&mut self, replacer: F)
+    where
+        F: FnOnce(T) -> Self,
+    {
+        *self = match std::mem::take(self) {
+            Self::Keep(source)
+            | Self::Register(source)
+            | Self::Remove(source)
+            | Self::Disable(source)
+            | Self::Replace { new: source, .. } => replacer(source),
+            Self::None => return,
+        };
+    }
+}
+
+impl<T> TransientSource<T> {
+    /// Apply a function to the enclosed source, if it exists and is not about
+    /// to be removed.
+    pub fn map<F, U>(&mut self, f: F) -> Option<U>
+    where
+        F: FnOnce(&mut T) -> U,
+    {
+        match &mut self.state {
+            TransientSourceState::Keep(source)
+            | TransientSourceState::Register(source)
+            | TransientSourceState::Disable(source)
+            | TransientSourceState::Replace { new: source, .. } => Some(f(source)),
+            TransientSourceState::Remove(_) | TransientSourceState::None => None,
+        }
+    }
+
+    /// Returns `true` if there is no wrapped event source.
+    pub fn is_none(&self) -> bool {
+        matches!(self.state, TransientSourceState::None)
+    }
+
+    /// Removes the wrapped event source from the event loop and this wrapper.
+    ///
+    /// If this is called from outside of the event loop, you will need to wake
+    /// up the event loop for any changes to take place. If it is called from
+    /// within the event loop, you must return `PostAction::Reregister` from
+    /// your own event source's `process_events()`, and the source will be
+    /// unregistered as needed after it exits.
+    pub fn remove(&mut self) {
+        self.state.replace_state(TransientSourceState::Remove);
+    }
+
+    /// Replace the currently wrapped source with the given one.  No more events
+    /// will be generated from the old source after this point. The old source
+    /// will not be dropped immediately, it will be kept so that it can be
+    /// deregistered.
+    ///
+    /// If this is called from outside of the event loop, you will need to wake
+    /// up the event loop for any changes to take place. If it is called from
+    /// within the event loop, you must return `PostAction::Reregister` from
+    /// your own event source's `process_events()`, and the sources will be
+    /// registered and unregistered as needed after it exits.
+    pub fn replace(&mut self, new: T) {
+        self.state
+            .replace_state(|old| TransientSourceState::Replace { new, old });
+    }
+}
+
+impl<T: crate::EventSource> From<T> for TransientSource<T> {
+    fn from(source: T) -> Self {
+        Self {
+            state: TransientSourceState::Register(source),
+        }
+    }
+}
+
+impl<T: crate::EventSource> crate::EventSource for TransientSource<T> {
+    type Event = T::Event;
+    type Metadata = T::Metadata;
+    type Ret = T::Ret;
+    type Error = T::Error;
+
+    fn process_events<F>(
+        &mut self,
+        readiness: crate::Readiness,
+        token: crate::Token,
+        callback: F,
+    ) -> Result<crate::PostAction, Self::Error>
+    where
+        F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+    {
+        let reregister = if let TransientSourceState::Keep(source) = &mut self.state {
+            let child_post_action = source.process_events(readiness, token, callback)?;
+
+            match child_post_action {
+                // Nothing needs to change.
+                crate::PostAction::Continue => false,
+
+                // Our child source needs re-registration, therefore this
+                // wrapper needs re-registration.
+                crate::PostAction::Reregister => true,
+
+                // If our nested source needs to be removed or disabled, we need
+                // to swap it out for the "Remove" or "Disable" variant.
+                crate::PostAction::Disable => {
+                    self.state.replace_state(TransientSourceState::Disable);
+                    true
+                }
+
+                crate::PostAction::Remove => {
+                    self.state.replace_state(TransientSourceState::Remove);
+                    true
+                }
+            }
+        } else {
+            false
+        };
+
+        let post_action = if reregister {
+            crate::PostAction::Reregister
+        } else {
+            crate::PostAction::Continue
+        };
+
+        Ok(post_action)
+    }
+
+    fn register(
+        &mut self,
+        poll: &mut crate::Poll,
+        token_factory: &mut crate::TokenFactory,
+    ) -> crate::Result<()> {
+        match &mut self.state {
+            TransientSourceState::Keep(source) => {
+                source.register(poll, token_factory)?;
+            }
+            TransientSourceState::Register(source)
+            | TransientSourceState::Disable(source)
+            | TransientSourceState::Replace { new: source, .. } => {
+                source.register(poll, token_factory)?;
+                self.state.replace_state(TransientSourceState::Keep);
+                // Drops the disposed source in the Replace case.
+            }
+            TransientSourceState::Remove(_source) => {
+                self.state.replace_state(|_| TransientSourceState::None);
+            }
+            TransientSourceState::None => (),
+        }
+        Ok(())
+    }
+
+    fn reregister(
+        &mut self,
+        poll: &mut crate::Poll,
+        token_factory: &mut crate::TokenFactory,
+    ) -> crate::Result<()> {
+        match &mut self.state {
+            TransientSourceState::Keep(source) => source.reregister(poll, token_factory)?,
+            TransientSourceState::Register(source) => {
+                source.register(poll, token_factory)?;
+                self.state.replace_state(TransientSourceState::Keep);
+            }
+            TransientSourceState::Disable(source) => {
+                source.unregister(poll)?;
+            }
+            TransientSourceState::Remove(source) => {
+                source.unregister(poll)?;
+                self.state.replace_state(|_| TransientSourceState::None);
+            }
+            TransientSourceState::Replace { new, old } => {
+                old.unregister(poll)?;
+                new.register(poll, token_factory)?;
+                self.state.replace_state(TransientSourceState::Keep);
+                // Drops 'dispose'.
+            }
+            TransientSourceState::None => (),
+        }
+        Ok(())
+    }
+
+    fn unregister(&mut self, poll: &mut crate::Poll) -> crate::Result<()> {
+        match &mut self.state {
+            TransientSourceState::Keep(source)
+            | TransientSourceState::Register(source)
+            | TransientSourceState::Disable(source) => source.unregister(poll)?,
+            TransientSourceState::Remove(source) => {
+                source.unregister(poll)?;
+                self.state.replace_state(|_| TransientSourceState::None);
+            }
+            TransientSourceState::Replace { new, old } => {
+                old.unregister(poll)?;
+                new.unregister(poll)?;
+                self.state.replace_state(TransientSourceState::Register);
+            }
+            TransientSourceState::None => (),
+        }
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{
+        channel::{channel, Channel, Event},
+        ping::{make_ping, PingSource},
+        Dispatcher, EventSource, PostAction,
+    };
+    use std::{
+        rc::Rc,
+        sync::atomic::{AtomicBool, Ordering},
+        time::Duration,
+    };
+
+    #[test]
+    fn test_transient_drop() {
+        // A test source that sets a flag when it's dropped.
+        struct TestSource<'a> {
+            dropped: &'a AtomicBool,
+            ping: PingSource,
+        }
+
+        impl<'a> Drop for TestSource<'a> {
+            fn drop(&mut self) {
+                self.dropped.store(true, Ordering::Relaxed)
+            }
+        }
+
+        impl<'a> crate::EventSource for TestSource<'a> {
+            type Event = ();
+            type Metadata = ();
+            type Ret = ();
+            type Error = Box<dyn std::error::Error + Sync + Send>;
+
+            fn process_events<F>(
+                &mut self,
+                readiness: crate::Readiness,
+                token: crate::Token,
+                callback: F,
+            ) -> Result<crate::PostAction, Self::Error>
+            where
+                F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+            {
+                self.ping.process_events(readiness, token, callback)?;
+                Ok(PostAction::Remove)
+            }
+
+            fn register(
+                &mut self,
+                poll: &mut crate::Poll,
+                token_factory: &mut crate::TokenFactory,
+            ) -> crate::Result<()> {
+                self.ping.register(poll, token_factory)
+            }
+
+            fn reregister(
+                &mut self,
+                poll: &mut crate::Poll,
+                token_factory: &mut crate::TokenFactory,
+            ) -> crate::Result<()> {
+                self.ping.reregister(poll, token_factory)
+            }
+
+            fn unregister(&mut self, poll: &mut crate::Poll) -> crate::Result<()> {
+                self.ping.unregister(poll)
+            }
+        }
+
+        // Test that the inner source is actually dropped when it asks to be
+        // removed from the loop, while the TransientSource remains. We use two
+        // flags for this:
+        // - fired: should be set only when the inner event source has an event
+        // - dropped: set by the drop handler for the inner source (it's an
+        //   AtomicBool becaues it requires a longer lifetime than the fired
+        //   flag)
+        let mut fired = false;
+        let dropped = false.into();
+
+        // The inner source that should be dropped after the first loop run.
+        let (pinger, ping) = make_ping().unwrap();
+        let inner = TestSource {
+            dropped: &dropped,
+            ping,
+        };
+
+        // The TransientSource wrapper.
+        let outer: TransientSource<_> = inner.into();
+
+        let mut event_loop = crate::EventLoop::try_new().unwrap();
+        let handle = event_loop.handle();
+
+        let _token = handle
+            .insert_source(outer, |_, _, fired| {
+                *fired = true;
+            })
+            .unwrap();
+
+        // First loop run: the ping generates an event for the inner source.
+        pinger.ping();
+
+        event_loop.dispatch(Duration::ZERO, &mut fired).unwrap();
+
+        assert!(fired);
+        assert!(dropped.load(Ordering::Relaxed));
+
+        // Second loop run: the ping does nothing because the receiver has been
+        // dropped.
+        fired = false;
+
+        pinger.ping();
+
+        event_loop.dispatch(Duration::ZERO, &mut fired).unwrap();
+        assert!(!fired);
+    }
+
+    #[test]
+    fn test_transient_passthrough() {
+        // Test that event processing works when a source is nested inside a
+        // TransientSource. In particular, we want to ensure that the final
+        // event is received even if it corresponds to that same event source
+        // returning `PostAction::Remove`.
+        let (sender, receiver) = channel();
+        let outer: TransientSource<_> = receiver.into();
+
+        let mut event_loop = crate::EventLoop::try_new().unwrap();
+        let handle = event_loop.handle();
+
+        // Our callback puts the receied events in here for us to check later.
+        let mut msg_queue = vec![];
+
+        let _token = handle
+            .insert_source(outer, |msg, _, queue: &mut Vec<_>| {
+                queue.push(msg);
+            })
+            .unwrap();
+
+        // Send some data and drop the sender. We specifically want to test that
+        // we get the "closed" message.
+        sender.send(0u32).unwrap();
+        sender.send(1u32).unwrap();
+        sender.send(2u32).unwrap();
+        sender.send(3u32).unwrap();
+        drop(sender);
+
+        // Run loop once to process events.
+        event_loop.dispatch(Duration::ZERO, &mut msg_queue).unwrap();
+
+        assert!(matches!(
+            msg_queue.as_slice(),
+            &[
+                Event::Msg(0u32),
+                Event::Msg(1u32),
+                Event::Msg(2u32),
+                Event::Msg(3u32),
+                Event::Closed
+            ]
+        ));
+    }
+
+    #[test]
+    fn test_transient_map() {
+        struct IdSource {
+            id: u32,
+            ping: PingSource,
+        }
+
+        impl EventSource for IdSource {
+            type Event = u32;
+            type Metadata = ();
+            type Ret = ();
+            type Error = Box<dyn std::error::Error + Sync + Send>;
+
+            fn process_events<F>(
+                &mut self,
+                readiness: crate::Readiness,
+                token: crate::Token,
+                mut callback: F,
+            ) -> Result<PostAction, Self::Error>
+            where
+                F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+            {
+                let id = self.id;
+                self.ping
+                    .process_events(readiness, token, |_, md| callback(id, md))?;
+
+                let action = if self.id > 2 {
+                    PostAction::Remove
+                } else {
+                    PostAction::Continue
+                };
+
+                Ok(action)
+            }
+
+            fn register(
+                &mut self,
+                poll: &mut crate::Poll,
+                token_factory: &mut crate::TokenFactory,
+            ) -> crate::Result<()> {
+                self.ping.register(poll, token_factory)
+            }
+
+            fn reregister(
+                &mut self,
+                poll: &mut crate::Poll,
+                token_factory: &mut crate::TokenFactory,
+            ) -> crate::Result<()> {
+                self.ping.reregister(poll, token_factory)
+            }
+
+            fn unregister(&mut self, poll: &mut crate::Poll) -> crate::Result<()> {
+                self.ping.unregister(poll)
+            }
+        }
+
+        struct WrapperSource(TransientSource<IdSource>);
+
+        impl EventSource for WrapperSource {
+            type Event = <IdSource as EventSource>::Event;
+            type Metadata = <IdSource as EventSource>::Metadata;
+            type Ret = <IdSource as EventSource>::Ret;
+            type Error = <IdSource as EventSource>::Error;
+
+            fn process_events<F>(
+                &mut self,
+                readiness: crate::Readiness,
+                token: crate::Token,
+                callback: F,
+            ) -> Result<PostAction, Self::Error>
+            where
+                F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+            {
+                let action = self.0.process_events(readiness, token, callback);
+                self.0.map(|inner| inner.id += 1);
+                action
+            }
+
+            fn register(
+                &mut self,
+                poll: &mut crate::Poll,
+                token_factory: &mut crate::TokenFactory,
+            ) -> crate::Result<()> {
+                self.0.map(|inner| inner.id += 1);
+                self.0.register(poll, token_factory)
+            }
+
+            fn reregister(
+                &mut self,
+                poll: &mut crate::Poll,
+                token_factory: &mut crate::TokenFactory,
+            ) -> crate::Result<()> {
+                self.0.map(|inner| inner.id += 1);
+                self.0.reregister(poll, token_factory)
+            }
+
+            fn unregister(&mut self, poll: &mut crate::Poll) -> crate::Result<()> {
+                self.0.map(|inner| inner.id += 1);
+                self.0.unregister(poll)
+            }
+        }
+
+        // To test the id later.
+        let mut id = 0;
+
+        // Create our source.
+        let (pinger, ping) = make_ping().unwrap();
+        let inner = IdSource { id, ping };
+
+        // The TransientSource wrapper.
+        let outer: TransientSource<_> = inner.into();
+
+        // The top level source.
+        let top = WrapperSource(outer);
+
+        // Create a dispatcher so we can check the source afterwards.
+        let dispatcher = Dispatcher::new(top, |got_id, _, test_id| {
+            *test_id = got_id;
+        });
+
+        let mut event_loop = crate::EventLoop::try_new().unwrap();
+        let handle = event_loop.handle();
+
+        let token = handle.register_dispatcher(dispatcher.clone()).unwrap();
+
+        // First loop run: the ping generates an event for the inner source.
+        // The ID should be 1 after the increment in register().
+        pinger.ping();
+        event_loop.dispatch(Duration::ZERO, &mut id).unwrap();
+        assert_eq!(id, 1);
+
+        // Second loop run: the ID should be 2 after the previous
+        // process_events().
+        pinger.ping();
+        event_loop.dispatch(Duration::ZERO, &mut id).unwrap();
+        assert_eq!(id, 2);
+
+        // Third loop run: the ID should be 3 after another process_events().
+        pinger.ping();
+        event_loop.dispatch(Duration::ZERO, &mut id).unwrap();
+        assert_eq!(id, 3);
+
+        // Fourth loop run: the callback is no longer called by the inner
+        // source, so our local ID is not incremented.
+        pinger.ping();
+        event_loop.dispatch(Duration::ZERO, &mut id).unwrap();
+        assert_eq!(id, 3);
+
+        // Remove the dispatcher so we can inspect the sources.
+        handle.remove(token);
+
+        let mut top_after = dispatcher.into_source_inner();
+
+        // I expect the inner source to be dropped, so the TransientSource
+        // variant is None (its version of None, not Option::None), so its map()
+        // won't call the passed-in function (hence the unreachable!()) and its
+        // return value should be Option::None.
+        assert!(top_after.0.map(|_| unreachable!()).is_none());
+    }
+
+    #[test]
+    fn test_transient_disable() {
+        // Test that disabling and enabling is handled properly.
+        struct DisablingSource(PingSource);
+
+        impl EventSource for DisablingSource {
+            type Event = ();
+            type Metadata = ();
+            type Ret = ();
+            type Error = Box<dyn std::error::Error + Sync + Send>;
+
+            fn process_events<F>(
+                &mut self,
+                readiness: crate::Readiness,
+                token: crate::Token,
+                callback: F,
+            ) -> Result<PostAction, Self::Error>
+            where
+                F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+            {
+                self.0.process_events(readiness, token, callback)?;
+                Ok(PostAction::Disable)
+            }
+
+            fn register(
+                &mut self,
+                poll: &mut crate::Poll,
+                token_factory: &mut crate::TokenFactory,
+            ) -> crate::Result<()> {
+                self.0.register(poll, token_factory)
+            }
+
+            fn reregister(
+                &mut self,
+                poll: &mut crate::Poll,
+                token_factory: &mut crate::TokenFactory,
+            ) -> crate::Result<()> {
+                self.0.reregister(poll, token_factory)
+            }
+
+            fn unregister(&mut self, poll: &mut crate::Poll) -> crate::Result<()> {
+                self.0.unregister(poll)
+            }
+        }
+
+        // Flag for checking when the source fires.
+        let mut fired = false;
+
+        // Create our source.
+        let (pinger, ping) = make_ping().unwrap();
+
+        let inner = DisablingSource(ping);
+
+        // The TransientSource wrapper.
+        let outer: TransientSource<_> = inner.into();
+
+        let mut event_loop = crate::EventLoop::try_new().unwrap();
+        let handle = event_loop.handle();
+        let token = handle
+            .insert_source(outer, |_, _, fired| {
+                *fired = true;
+            })
+            .unwrap();
+
+        // Ping here and not later, to check that disabling after an event is
+        // triggered but not processed does not discard the event.
+        pinger.ping();
+        event_loop.dispatch(Duration::ZERO, &mut fired).unwrap();
+        assert!(fired);
+
+        // Source should now be disabled.
+        pinger.ping();
+        fired = false;
+        event_loop.dispatch(Duration::ZERO, &mut fired).unwrap();
+        assert!(!fired);
+
+        // Re-enable the source.
+        handle.enable(&token).unwrap();
+
+        // Trigger another event.
+        pinger.ping();
+        fired = false;
+        event_loop.dispatch(Duration::ZERO, &mut fired).unwrap();
+        assert!(fired);
+    }
+
+    #[test]
+    fn test_transient_replace_unregister() {
+        // This is a bit of a complex test, but it essentially boils down to:
+        // how can a "parent" event source containing a TransientSource replace
+        // the "child" source without leaking the source's registration?
+
+        // First, a source that finishes immediately. This is so we cover the
+        // edge case of replacing a source as soon as it wants to be removed.
+        struct FinishImmediatelySource {
+            source: PingSource,
+            data: Option<i32>,
+            registered: bool,
+            dropped: Rc<AtomicBool>,
+        }
+
+        impl FinishImmediatelySource {
+            // The constructor passes out the drop flag so we can check that
+            // this source was or wasn't dropped.
+            fn new(source: PingSource, data: i32) -> (Self, Rc<AtomicBool>) {
+                let dropped = Rc::new(false.into());
+
+                (
+                    Self {
+                        source,
+                        data: Some(data),
+                        registered: false,
+                        dropped: Rc::clone(&dropped),
+                    },
+                    dropped,
+                )
+            }
+        }
+
+        impl EventSource for FinishImmediatelySource {
+            type Event = i32;
+            type Metadata = ();
+            type Ret = ();
+            type Error = Box<dyn std::error::Error + Sync + Send>;
+
+            fn process_events<F>(
+                &mut self,
+                readiness: crate::Readiness,
+                token: crate::Token,
+                mut callback: F,
+            ) -> Result<PostAction, Self::Error>
+            where
+                F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+            {
+                let mut data = self.data.take();
+
+                self.source.process_events(readiness, token, |_, _| {
+                    if let Some(data) = data.take() {
+                        callback(data, &mut ())
+                    }
+                })?;
+
+                self.data = data;
+
+                Ok(if self.data.is_none() {
+                    PostAction::Remove
+                } else {
+                    PostAction::Continue
+                })
+            }
+
+            fn register(
+                &mut self,
+                poll: &mut crate::Poll,
+                token_factory: &mut crate::TokenFactory,
+            ) -> crate::Result<()> {
+                self.registered = true;
+                self.source.register(poll, token_factory)
+            }
+
+            fn reregister(
+                &mut self,
+                poll: &mut crate::Poll,
+                token_factory: &mut crate::TokenFactory,
+            ) -> crate::Result<()> {
+                self.source.reregister(poll, token_factory)
+            }
+
+            fn unregister(&mut self, poll: &mut crate::Poll) -> crate::Result<()> {
+                self.registered = false;
+                self.source.unregister(poll)
+            }
+        }
+
+        // The drop handler sets a flag we can check for debugging (we want to
+        // know that the source itself was dropped), and also checks that the
+        // source was unregistered. Ultimately neither the source nor its
+        // registration should be leaked.
+
+        impl Drop for FinishImmediatelySource {
+            fn drop(&mut self) {
+                assert!(!self.registered, "source dropped while still registered");
+                self.dropped.store(true, Ordering::Relaxed);
+            }
+        }
+
+        // Our wrapper source handles detecting when the child source finishes,
+        // and replacing that child source with another one that will generate
+        // more events. This is one intended use case of the TransientSource.
+
+        struct WrapperSource {
+            current: TransientSource<FinishImmediatelySource>,
+            replacement: Option<FinishImmediatelySource>,
+            dropped: Rc<AtomicBool>,
+        }
+
+        impl WrapperSource {
+            // The constructor passes out the drop flag so we can check that
+            // this source was or wasn't dropped.
+            fn new(
+                first: FinishImmediatelySource,
+                second: FinishImmediatelySource,
+            ) -> (Self, Rc<AtomicBool>) {
+                let dropped = Rc::new(false.into());
+
+                (
+                    Self {
+                        current: first.into(),
+                        replacement: second.into(),
+                        dropped: Rc::clone(&dropped),
+                    },
+                    dropped,
+                )
+            }
+        }
+
+        impl EventSource for WrapperSource {
+            type Event = i32;
+            type Metadata = ();
+            type Ret = ();
+            type Error = Box<dyn std::error::Error + Sync + Send>;
+
+            fn process_events<F>(
+                &mut self,
+                readiness: crate::Readiness,
+                token: crate::Token,
+                mut callback: F,
+            ) -> Result<PostAction, Self::Error>
+            where
+                F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+            {
+                // Did our event source generate an event?
+                let mut fired = false;
+
+                let post_action = self.current.process_events(readiness, token, |data, _| {
+                    callback(data, &mut ());
+                    fired = true;
+                })?;
+
+                if fired {
+                    // The event source will be unregistered after the current
+                    // process_events() iteration is finished. The replace()
+                    // method will handle doing that even while we've added a
+                    // new source.
+                    if let Some(replacement) = self.replacement.take() {
+                        self.current.replace(replacement);
+                    }
+
+                    // Parent source is responsible for flagging this, but it's
+                    // already set.
+                    assert_eq!(post_action, PostAction::Reregister);
+                }
+
+                Ok(post_action)
+            }
+
+            fn register(
+                &mut self,
+                poll: &mut crate::Poll,
+                token_factory: &mut crate::TokenFactory,
+            ) -> crate::Result<()> {
+                self.current.register(poll, token_factory)
+            }
+
+            fn reregister(
+                &mut self,
+                poll: &mut crate::Poll,
+                token_factory: &mut crate::TokenFactory,
+            ) -> crate::Result<()> {
+                self.current.reregister(poll, token_factory)
+            }
+
+            fn unregister(&mut self, poll: &mut crate::Poll) -> crate::Result<()> {
+                self.current.unregister(poll)
+            }
+        }
+
+        impl Drop for WrapperSource {
+            fn drop(&mut self) {
+                self.dropped.store(true, Ordering::Relaxed);
+            }
+        }
+
+        // Construct the various nested sources - FinishImmediatelySource inside
+        // TransientSource inside WrapperSource. The numbers let us verify which
+        // event source fires first.
+        let (ping0_tx, ping0_rx) = crate::ping::make_ping().unwrap();
+        let (ping1_tx, ping1_rx) = crate::ping::make_ping().unwrap();
+        let (inner0, inner0_dropped) = FinishImmediatelySource::new(ping0_rx, 0);
+        let (inner1, inner1_dropped) = FinishImmediatelySource::new(ping1_rx, 1);
+        let (outer, outer_dropped) = WrapperSource::new(inner0, inner1);
+
+        // Now the actual test starts.
+
+        let mut event_loop: crate::EventLoop<(Option<i32>, crate::LoopSignal)> =
+            crate::EventLoop::try_new().unwrap();
+        let handle = event_loop.handle();
+        let signal = event_loop.get_signal();
+
+        // This is how we communicate with the event sources.
+        let mut context = (None, signal);
+
+        let _token = handle
+            .insert_source(outer, |data, _, (evt, sig)| {
+                *evt = Some(data);
+                sig.stop();
+            })
+            .unwrap();
+
+        // Ensure our sources fire.
+        ping0_tx.ping();
+        ping1_tx.ping();
+
+        // Use run() rather than dispatch() because it's not strictly part of
+        // any API contract as to how many runs of the event loop it takes to
+        // replace the nested source.
+        event_loop.run(None, &mut context, |_| {}).unwrap();
+
+        // First, make sure the inner source actually did fire.
+        assert_eq!(context.0.take(), Some(0), "first inner source did not fire");
+
+        // Make sure that the outer source is still alive.
+        assert!(
+            !outer_dropped.load(Ordering::Relaxed),
+            "outer source already dropped"
+        );
+
+        // Make sure that the inner child source IS dropped now.
+        assert!(
+            inner0_dropped.load(Ordering::Relaxed),
+            "first inner source not dropped"
+        );
+
+        // Make sure that, in between the first event and second event, the
+        // replacement child source still exists.
+        assert!(
+            !inner1_dropped.load(Ordering::Relaxed),
+            "replacement inner source dropped"
+        );
+
+        // Run the event loop until we get a second event.
+        event_loop.run(None, &mut context, |_| {}).unwrap();
+
+        // Ensure the replacement source fired (which checks that it was
+        // registered and is being processed by the TransientSource).
+        assert_eq!(context.0.take(), Some(1), "replacement source did not fire");
+    }
+
+    #[test]
+    fn test_transient_remove() {
+        // This tests that calling remove(), even before an event source has
+        // requested its own removal, results in the event source being removed.
+
+        const STOP_AT: i32 = 2;
+
+        // A wrapper source to automate the removal of the inner source.
+        struct WrapperSource {
+            inner: TransientSource<Channel<i32>>,
+        }
+
+        impl EventSource for WrapperSource {
+            type Event = i32;
+            type Metadata = ();
+            type Ret = ();
+            type Error = Box<dyn std::error::Error + Sync + Send>;
+
+            fn process_events<F>(
+                &mut self,
+                readiness: crate::Readiness,
+                token: crate::Token,
+                mut callback: F,
+            ) -> Result<PostAction, Self::Error>
+            where
+                F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+            {
+                let mut remove = false;
+
+                let mut post_action = self.inner.process_events(readiness, token, |evt, _| {
+                    if let Event::Msg(num) = evt {
+                        callback(num, &mut ());
+                        remove = num >= STOP_AT;
+                    }
+                })?;
+
+                if remove {
+                    self.inner.remove();
+                    post_action |= PostAction::Reregister;
+                }
+
+                Ok(post_action)
+            }
+
+            fn register(
+                &mut self,
+                poll: &mut crate::Poll,
+                token_factory: &mut crate::TokenFactory,
+            ) -> crate::Result<()> {
+                self.inner.register(poll, token_factory)
+            }
+
+            fn reregister(
+                &mut self,
+                poll: &mut crate::Poll,
+                token_factory: &mut crate::TokenFactory,
+            ) -> crate::Result<()> {
+                self.inner.reregister(poll, token_factory)
+            }
+
+            fn unregister(&mut self, poll: &mut crate::Poll) -> crate::Result<()> {
+                self.inner.unregister(poll)
+            }
+        }
+
+        // Create our sources and loop.
+
+        let (sender, receiver) = channel();
+        let wrapper = WrapperSource {
+            inner: receiver.into(),
+        };
+
+        let mut event_loop = crate::EventLoop::try_new().unwrap();
+        let handle = event_loop.handle();
+
+        handle
+            .insert_source(wrapper, |num, _, out: &mut Option<_>| {
+                *out = Some(num);
+            })
+            .unwrap();
+
+        // Storage for callback data.
+        let mut out = None;
+
+        // Send some data we expect to get callbacks for.
+        for num in 0..=STOP_AT {
+            sender.send(num).unwrap();
+            event_loop.dispatch(Duration::ZERO, &mut out).unwrap();
+            assert_eq!(out.take(), Some(num));
+        }
+
+        // Now we expect the receiver to be gone.
+        assert!(matches!(
+            sender.send(STOP_AT + 1),
+            Err(std::sync::mpsc::SendError { .. })
+        ));
+    }
+}
+
\ No newline at end of file diff --git a/api/src/calloop/sys.rs.html b/api/src/calloop/sys.rs.html new file mode 100644 index 00000000..34a466b4 --- /dev/null +++ b/api/src/calloop/sys.rs.html @@ -0,0 +1,1017 @@ +sys.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+
use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc, time::Duration};
+
+#[cfg(unix)]
+use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd as Borrowed, RawFd as Raw};
+
+#[cfg(windows)]
+use std::os::windows::io::{AsRawSocket, AsSocket, BorrowedSocket as Borrowed, RawSocket as Raw};
+
+use polling::{Event, Events, PollMode, Poller};
+
+use crate::loop_logic::{MAX_SOURCES, MAX_SUBSOURCES_TOTAL};
+use crate::sources::timer::TimerWheel;
+use crate::RegistrationToken;
+
+/// Possible modes for registering a file descriptor
+#[derive(Copy, Clone, Debug)]
+pub enum Mode {
+    /// Single event generation
+    ///
+    /// This FD will be disabled as soon as it has generated one event.
+    ///
+    /// The user will need to use `LoopHandle::update()` to re-enable it if
+    /// desired.
+    OneShot,
+
+    /// Level-triggering
+    ///
+    /// This FD will report events on every poll as long as the requested interests
+    /// are available.
+    Level,
+
+    /// Edge-triggering
+    ///
+    /// This FD will report events only when it *gains* one of the requested interests.
+    /// it must thus be fully processed before it'll generate events again.
+    ///
+    /// This mode is not supported on certain platforms, and an error will be returned
+    /// if it is used.
+    ///
+    /// ## Supported Platforms
+    ///
+    /// As of the time of writing, the platforms that support edge triggered polling are
+    /// as follows:
+    ///
+    /// - Linux/Android
+    /// - macOS/iOS/tvOS/watchOS
+    /// - FreeBSD/OpenBSD/NetBSD/DragonflyBSD
+    Edge,
+}
+
+/// Interest to register regarding the file descriptor
+#[derive(Copy, Clone, Debug)]
+pub struct Interest {
+    /// Wait for the FD to be readable
+    pub readable: bool,
+
+    /// Wait for the FD to be writable
+    pub writable: bool,
+}
+
+impl Interest {
+    /// Shorthand for empty interest
+    pub const EMPTY: Interest = Interest {
+        readable: false,
+        writable: false,
+    };
+
+    /// Shorthand for read interest
+    pub const READ: Interest = Interest {
+        readable: true,
+        writable: false,
+    };
+
+    /// Shorthand for write interest
+    pub const WRITE: Interest = Interest {
+        readable: false,
+        writable: true,
+    };
+
+    /// Shorthand for read and write interest
+    pub const BOTH: Interest = Interest {
+        readable: true,
+        writable: true,
+    };
+}
+
+/// Readiness for a file descriptor notification
+#[derive(Copy, Clone, Debug)]
+pub struct Readiness {
+    /// Is the FD readable
+    pub readable: bool,
+
+    /// Is the FD writable
+    pub writable: bool,
+
+    /// Is the FD in an error state
+    pub error: bool,
+}
+
+impl Readiness {
+    /// Shorthand for empty readiness
+    pub const EMPTY: Readiness = Readiness {
+        readable: false,
+        writable: false,
+        error: false,
+    };
+}
+
+#[derive(Debug)]
+pub(crate) struct PollEvent {
+    pub(crate) readiness: Readiness,
+    pub(crate) token: Token,
+}
+
+/// Factory for creating tokens in your registrations
+///
+/// When composing event sources, each sub-source needs to
+/// have its own token to identify itself. This factory is
+/// provided to produce such unique tokens.
+
+#[derive(Debug)]
+pub struct TokenFactory {
+    /// The key of the source this factory is associated with.
+    key: usize,
+
+    /// The next sub-id to use.
+    sub_id: u32,
+}
+
+impl TokenFactory {
+    pub(crate) fn new(key: usize) -> TokenFactory {
+        TokenFactory { key, sub_id: 0 }
+    }
+
+    /// Get the "raw" registration token of this TokenFactory
+    pub(crate) fn registration_token(&self) -> RegistrationToken {
+        RegistrationToken::new(self.key)
+    }
+
+    /// Produce a new unique token
+    pub fn token(&mut self) -> Token {
+        // Ensure we don't overflow the sub-id.
+        if self.sub_id >= MAX_SUBSOURCES_TOTAL as _ {
+            panic!("Too many sub-sources for this source");
+        }
+
+        // Compose the key and the sub-key together.
+        let mut key = self.key;
+        key |= (self.sub_id as usize) << MAX_SOURCES;
+
+        let token = Token { key };
+
+        self.sub_id += 1;
+
+        token
+    }
+}
+
+/// A token (for implementation of the [`EventSource`](crate::EventSource) trait)
+///
+/// This token is produced by the [`TokenFactory`] and is used when calling the
+/// [`EventSource`](crate::EventSource) implementations to process event, in order
+/// to identify which sub-source produced them.
+///
+/// You should forward it to the [`Poll`] when registering your file descriptors.
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub struct Token {
+    pub(crate) key: usize,
+}
+
+/// The polling system
+///
+/// This type represents the polling system of calloop, on which you
+/// can register your file descriptors. This interface is only accessible in
+/// implementations of the [`EventSource`](crate::EventSource) trait.
+///
+/// You only need to interact with this type if you are implementing your
+/// own event sources, while implementing the [`EventSource`](crate::EventSource) trait.
+/// And even in this case, you can often just use the [`Generic`](crate::generic::Generic) event
+/// source and delegate the implementations to it.
+pub struct Poll {
+    /// The handle to wepoll/epoll/kqueue/... used to poll for events.
+    poller: Arc<Poller>,
+
+    /// The buffer of events returned by the poller.
+    events: RefCell<Events>,
+
+    /// The sources registered as level triggered.
+    ///
+    /// Some platforms that `polling` supports do not support level-triggered events. As of the time
+    /// of writing, this only includes Solaris and illumos. To work around this, we emulate level
+    /// triggered events by keeping this map of file descriptors.
+    ///
+    /// One can emulate level triggered events on top of oneshot events by just re-registering the
+    /// file descriptor every time it is polled. However, this is not ideal, as it requires a
+    /// system call every time. It's better to use the intergrated system, if available.
+    level_triggered: Option<RefCell<HashMap<usize, (Raw, polling::Event)>>>,
+
+    pub(crate) timers: Rc<RefCell<TimerWheel>>,
+}
+
+impl std::fmt::Debug for Poll {
+    #[cfg_attr(feature = "nightly_coverage", coverage(off))]
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.write_str("Poll { ... }")
+    }
+}
+
+impl Poll {
+    pub(crate) fn new() -> crate::Result<Poll> {
+        Self::new_inner(false)
+    }
+
+    fn new_inner(force_fallback_lt: bool) -> crate::Result<Poll> {
+        let poller = Poller::new()?;
+        let level_triggered = if poller.supports_level() && !force_fallback_lt {
+            None
+        } else {
+            Some(RefCell::new(HashMap::new()))
+        };
+
+        Ok(Poll {
+            poller: Arc::new(poller),
+            events: RefCell::new(Events::new()),
+            timers: Rc::new(RefCell::new(TimerWheel::new())),
+            level_triggered,
+        })
+    }
+
+    pub(crate) fn poll(&self, mut timeout: Option<Duration>) -> crate::Result<Vec<PollEvent>> {
+        let now = std::time::Instant::now();
+
+        // Adjust the timeout for the timers.
+        if let Some(next_timeout) = self.timers.borrow().next_deadline() {
+            if next_timeout <= now {
+                timeout = Some(Duration::ZERO);
+            } else if let Some(deadline) = timeout {
+                timeout = Some(std::cmp::min(deadline, next_timeout - now));
+            } else {
+                timeout = Some(next_timeout - now);
+            }
+        };
+
+        let mut events = self.events.borrow_mut();
+        events.clear();
+        self.poller.wait(&mut events, timeout)?;
+
+        // Convert `polling` events to `calloop` events.
+        let level_triggered = self.level_triggered.as_ref().map(RefCell::borrow);
+        let mut poll_events = events
+            .iter()
+            .map(|ev| {
+                // If we need to emulate level-triggered events...
+                if let Some(level_triggered) = level_triggered.as_ref() {
+                    // ...and this event is from a level-triggered source...
+                    if let Some((source, interest)) = level_triggered.get(&ev.key) {
+                        // ...then we need to re-register the source.
+                        // SAFETY: The source is valid.
+                        self.poller
+                            .modify(unsafe { Borrowed::borrow_raw(*source) }, *interest)?;
+                    }
+                }
+
+                Ok(PollEvent {
+                    readiness: Readiness {
+                        readable: ev.readable,
+                        writable: ev.writable,
+                        error: false,
+                    },
+                    token: Token { key: ev.key },
+                })
+            })
+            .collect::<std::io::Result<Vec<_>>>()?;
+
+        drop(events);
+
+        // Update 'now' as some time may have elapsed in poll()
+        let now = std::time::Instant::now();
+        let mut timers = self.timers.borrow_mut();
+        while let Some((_, token)) = timers.next_expired(now) {
+            poll_events.push(PollEvent {
+                readiness: Readiness {
+                    readable: true,
+                    writable: false,
+                    error: false,
+                },
+                token,
+            });
+        }
+
+        Ok(poll_events)
+    }
+
+    /// Register a new file descriptor for polling
+    ///
+    /// The file descriptor will be registered with given interest,
+    /// mode and token. This function will fail if given a
+    /// bad file descriptor or if the provided file descriptor is already
+    /// registered.
+    ///
+    /// # Safety
+    ///
+    /// The registered source must not be dropped before it is unregistered.
+    ///
+    /// # Leaking tokens
+    ///
+    /// If your event source is dropped without being unregistered, the token
+    /// passed in here will remain on the heap and continue to be used by the
+    /// polling system even though no event source will match it.
+    pub unsafe fn register(
+        &self,
+        #[cfg(unix)] fd: impl AsFd,
+        #[cfg(windows)] fd: impl AsSocket,
+        interest: Interest,
+        mode: Mode,
+        token: Token,
+    ) -> crate::Result<()> {
+        let raw = {
+            #[cfg(unix)]
+            {
+                fd.as_fd().as_raw_fd()
+            }
+
+            #[cfg(windows)]
+            {
+                fd.as_socket().as_raw_socket()
+            }
+        };
+
+        let ev = cvt_interest(interest, token);
+
+        // SAFETY: See invariant on function.
+        unsafe {
+            self.poller
+                .add_with_mode(raw, ev, cvt_mode(mode, self.poller.supports_level()))?;
+        }
+
+        // If this is level triggered and we're emulating level triggered mode...
+        if let (Mode::Level, Some(level_triggered)) = (mode, self.level_triggered.as_ref()) {
+            // ...then we need to keep track of the source.
+            let mut level_triggered = level_triggered.borrow_mut();
+            level_triggered.insert(ev.key, (raw, ev));
+        }
+
+        Ok(())
+    }
+
+    /// Update the registration for a file descriptor
+    ///
+    /// This allows you to change the interest, mode or token of a file
+    /// descriptor. Fails if the provided fd is not currently registered.
+    ///
+    /// See note on [`register()`](Self::register()) regarding leaking.
+    pub fn reregister(
+        &self,
+        #[cfg(unix)] fd: impl AsFd,
+        #[cfg(windows)] fd: impl AsSocket,
+        interest: Interest,
+        mode: Mode,
+        token: Token,
+    ) -> crate::Result<()> {
+        let (borrowed, raw) = {
+            #[cfg(unix)]
+            {
+                (fd.as_fd(), fd.as_fd().as_raw_fd())
+            }
+
+            #[cfg(windows)]
+            {
+                (fd.as_socket(), fd.as_socket().as_raw_socket())
+            }
+        };
+
+        let ev = cvt_interest(interest, token);
+        self.poller
+            .modify_with_mode(borrowed, ev, cvt_mode(mode, self.poller.supports_level()))?;
+
+        // If this is level triggered and we're emulating level triggered mode...
+        if let (Mode::Level, Some(level_triggered)) = (mode, self.level_triggered.as_ref()) {
+            // ...then we need to keep track of the source.
+            let mut level_triggered = level_triggered.borrow_mut();
+            level_triggered.insert(ev.key, (raw, ev));
+        }
+
+        Ok(())
+    }
+
+    /// Unregister a file descriptor
+    ///
+    /// This file descriptor will no longer generate events. Fails if the
+    /// provided file descriptor is not currently registered.
+    pub fn unregister(
+        &self,
+        #[cfg(unix)] fd: impl AsFd,
+        #[cfg(windows)] fd: impl AsSocket,
+    ) -> crate::Result<()> {
+        let (borrowed, raw) = {
+            #[cfg(unix)]
+            {
+                (fd.as_fd(), fd.as_fd().as_raw_fd())
+            }
+
+            #[cfg(windows)]
+            {
+                (fd.as_socket(), fd.as_socket().as_raw_socket())
+            }
+        };
+        self.poller.delete(borrowed)?;
+
+        if let Some(level_triggered) = self.level_triggered.as_ref() {
+            let mut level_triggered = level_triggered.borrow_mut();
+            level_triggered.retain(|_, (source, _)| *source != raw);
+        }
+
+        Ok(())
+    }
+
+    /// Get a thread-safe handle which can be used to wake up the `Poll`.
+    pub(crate) fn notifier(&self) -> Notifier {
+        Notifier(self.poller.clone())
+    }
+
+    /// Get a reference to the poller.
+    pub(crate) fn poller(&self) -> &Arc<Poller> {
+        &self.poller
+    }
+}
+
+/// Thread-safe handle which can be used to wake up the `Poll`.
+#[derive(Clone)]
+pub(crate) struct Notifier(Arc<Poller>);
+
+impl Notifier {
+    pub(crate) fn notify(&self) -> crate::Result<()> {
+        self.0.notify()?;
+
+        Ok(())
+    }
+}
+
+fn cvt_interest(interest: Interest, tok: Token) -> Event {
+    let mut event = Event::none(tok.key);
+    event.readable = interest.readable;
+    event.writable = interest.writable;
+    event
+}
+
+fn cvt_mode(mode: Mode, supports_other_modes: bool) -> PollMode {
+    if !supports_other_modes {
+        return PollMode::Oneshot;
+    }
+
+    match mode {
+        Mode::Edge => PollMode::Edge,
+        Mode::Level => PollMode::Level,
+        Mode::OneShot => PollMode::Oneshot,
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{loop_logic::MAX_SOURCES_TOTAL, sources::ping::make_ping, EventSource};
+
+    #[should_panic]
+    #[test]
+    fn overflow_subid() {
+        let mut gen = TokenFactory {
+            key: 0,
+            sub_id: u32::MAX - 1,
+        };
+
+        let _ = gen.token();
+    }
+
+    #[test]
+    fn test_fallback_lt() {
+        let mut poll = Poll::new_inner(true).unwrap();
+        let mut gen = TokenFactory { key: 0, sub_id: 0 };
+        let (dst, mut src) = make_ping().unwrap();
+
+        src.register(&mut poll, &mut gen).unwrap();
+        let mut key = 0;
+
+        for _ in 0..2 {
+            // Send a ping.
+            dst.ping();
+
+            // The ping should arrive at this point.
+            let events = poll.poll(Some(Duration::from_secs(3))).unwrap();
+
+            assert_eq!(events.len(), 1);
+            assert_eq!(events[0].token, Token { key });
+
+            // Since we haven't read the ping, polling again should return the same result.
+            let events = poll.poll(Some(Duration::from_secs(3))).unwrap();
+            assert_eq!(events.len(), 1);
+            assert_eq!(events[0].token, Token { key });
+
+            // Reregister and poll again.
+            src.reregister(&mut poll, &mut gen).unwrap();
+            key += MAX_SOURCES_TOTAL;
+        }
+
+        // Remove the source.
+        src.unregister(&mut poll).unwrap();
+    }
+}
+
\ No newline at end of file diff --git a/api/static.files/COPYRIGHT-23e9bde6c69aea69.txt b/api/static.files/COPYRIGHT-23e9bde6c69aea69.txt new file mode 100644 index 00000000..1447df79 --- /dev/null +++ b/api/static.files/COPYRIGHT-23e9bde6c69aea69.txt @@ -0,0 +1,50 @@ +# REUSE-IgnoreStart + +These documentation pages include resources by third parties. This copyright +file applies only to those resources. The following third party resources are +included, and carry their own copyright notices and license terms: + +* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Sans. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraSans-LICENSE.txt. + +* rustdoc.css, main.js, and playpen.js: + + Copyright 2015 The Rust Developers. + Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or + the MIT license (LICENSE-MIT.txt) at your option. + +* normalize.css: + + Copyright (c) Nicolas Gallagher and Jonathan Neal. + Licensed under the MIT license (see LICENSE-MIT.txt). + +* Source Code Pro (SourceCodePro-Regular.ttf.woff2, + SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2): + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark + of Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceCodePro-LICENSE.txt. + +* Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2, + SourceSerif4-It.ttf.woff2): + + Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name + 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United + States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceSerif4-LICENSE.md. + +This copyright file is intended to be distributed with rustdoc output. + +# REUSE-IgnoreEnd diff --git a/api/static.files/FiraSans-LICENSE-db4b642586e02d97.txt b/api/static.files/FiraSans-LICENSE-db4b642586e02d97.txt new file mode 100644 index 00000000..d7e9c149 --- /dev/null +++ b/api/static.files/FiraSans-LICENSE-db4b642586e02d97.txt @@ -0,0 +1,98 @@ +// REUSE-IgnoreStart + +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/api/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 b/api/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 new file mode 100644 index 00000000..7a1e5fc5 Binary files /dev/null and b/api/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 differ diff --git a/api/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 b/api/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 new file mode 100644 index 00000000..e766e06c Binary files /dev/null and b/api/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 differ diff --git a/api/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt b/api/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/api/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/api/static.files/LICENSE-MIT-65090b722b3f6c56.txt b/api/static.files/LICENSE-MIT-65090b722b3f6c56.txt new file mode 100644 index 00000000..31aa7938 --- /dev/null +++ b/api/static.files/LICENSE-MIT-65090b722b3f6c56.txt @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/api/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 b/api/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 new file mode 100644 index 00000000..1866ad4b Binary files /dev/null and b/api/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 differ diff --git a/api/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt b/api/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt new file mode 100644 index 00000000..4b3edc29 --- /dev/null +++ b/api/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt @@ -0,0 +1,103 @@ +// REUSE-IgnoreStart + +Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/), + +with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, +NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, +Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco, +NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight, NanumBarunGothic, +Naver NanumBarunGothic, NanumSquareRound, NanumBarunPen, MaruBuri + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/api/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 b/api/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 new file mode 100644 index 00000000..462c34ef Binary files /dev/null and b/api/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 differ diff --git a/api/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt b/api/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt new file mode 100644 index 00000000..0d2941e1 --- /dev/null +++ b/api/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt @@ -0,0 +1,97 @@ +// REUSE-IgnoreStart + +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/api/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 b/api/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 new file mode 100644 index 00000000..10b558e0 Binary files /dev/null and b/api/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 differ diff --git a/api/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 b/api/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 new file mode 100644 index 00000000..5ec64eef Binary files /dev/null and b/api/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 differ diff --git a/api/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 b/api/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 new file mode 100644 index 00000000..181a07f6 Binary files /dev/null and b/api/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 differ diff --git a/api/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 b/api/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 new file mode 100644 index 00000000..2ae08a7b Binary files /dev/null and b/api/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 differ diff --git a/api/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 b/api/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 new file mode 100644 index 00000000..0263fc30 Binary files /dev/null and b/api/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 differ diff --git a/api/static.files/ayu-fd19013d6ce078bf.css b/api/static.files/ayu-fd19013d6ce078bf.css new file mode 100644 index 00000000..ba3aa60e --- /dev/null +++ b/api/static.files/ayu-fd19013d6ce078bf.css @@ -0,0 +1 @@ + :root{--main-background-color:#0f1419;--main-color:#c5c5c5;--settings-input-color:#ffb454;--settings-input-border-color:#999;--settings-button-color:#fff;--settings-button-border-focus:#e0e0e0;--sidebar-background-color:#14191f;--sidebar-background-color-hover:rgba(70,70,70,0.33);--code-block-background-color:#191f26;--scrollbar-track-background-color:transparent;--scrollbar-thumb-background-color:#5c6773;--scrollbar-color:#5c6773 #24292f;--headings-border-bottom-color:#5c6773;--border-color:#5c6773;--button-background-color:#141920;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#5c6773;--copy-path-button-color:#fff;--copy-path-img-filter:invert(70%);--copy-path-img-hover-filter:invert(100%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--type-link-color:#ffa0a5;--trait-link-color:#39afd7;--assoc-item-link-color:#39afd7;--function-link-color:#fdd687;--macro-link-color:#a37acc;--keyword-link-color:#39afd7;--mod-link-color:#39afd7;--link-color:#39afd7;--sidebar-link-color:#53b1db;--sidebar-current-link-background-color:transparent;--search-result-link-focus-background-color:#3c3c3c;--search-result-border-color:#aaa3;--search-color:#fff;--search-error-code-background-color:#4f4c4c;--search-results-alias-color:#c5c5c5;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:none;--search-tab-button-not-selected-background:transparent !important;--search-tab-button-selected-border-top-color:none;--search-tab-button-selected-background:#141920 !important;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ff7733;--code-highlight-kw-2-color:#ff7733;--code-highlight-lifetime-color:#ff7733;--code-highlight-prelude-color:#69f2df;--code-highlight-prelude-val-color:#ff7733;--code-highlight-number-color:#b8cc52;--code-highlight-string-color:#b8cc52;--code-highlight-literal-color:#ff7733;--code-highlight-attribute-color:#e6e1cf;--code-highlight-self-color:#36a3d9;--code-highlight-macro-color:#a37acc;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#788797;--code-highlight-doc-comment-color:#a1ac88;--src-line-numbers-span-color:#5c6773;--src-line-number-highlighted-background-color:rgba(255,236,164,0.06);--test-arrow-color:#788797;--test-arrow-background-color:rgba(57,175,215,0.09);--test-arrow-hover-color:#c5c5c5;--test-arrow-hover-background-color:rgba(57,175,215,0.368);--target-background-color:rgba(255,236,164,0.06);--target-border-color:rgba(255,180,76,0.85);--kbd-color:#c5c5c5;--kbd-background:#314559;--kbd-box-shadow-color:#5c6773;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);--crate-search-div-hover-filter:invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);--crate-search-hover-border:#e0e0e0;--src-sidebar-background-selected:#14191f;--src-sidebar-background-hover:#14191f;--table-alt-row-background-color:#191f26;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:rgb(91,59,1);--scrape-example-code-line-highlight-focus:rgb(124,75,15);--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(15,20,25,1);--scrape-example-code-wrapper-background-end:rgba(15,20,25,0);}h1,h2,h3,h4,h1 a,.sidebar h2 a,.sidebar h3 a,#src-sidebar>.title{color:#fff;}h4{border:none;}.docblock code{color:#ffb454;}.docblock a>code{color:#39AFD7 !important;}.code-header,.docblock pre>code,pre,pre>code,.item-info code,.rustdoc.src .example-wrap{color:#e6e1cf;}.sidebar .current,.sidebar a:hover,#src-sidebar div.files>a:hover,details.dir-entry summary:hover,#src-sidebar div.files>a:focus,details.dir-entry summary:focus,#src-sidebar div.files>a.selected{color:#ffb44c;}.sidebar-elems .location{color:#ff7733;}.src-line-numbers .line-highlighted{color:#708090;padding-right:7px;border-right:1px solid #ffb44c;}.search-results a:hover,.search-results a:focus{color:#fff !important;background-color:#3c3c3c;}.search-results a{color:#0096cf;}.search-results a div.desc{color:#c5c5c5;}.result-name .primitive>i,.result-name .keyword>i{color:#788797;}#search-tabs>button.selected{border-bottom:1px solid #ffb44c !important;border-top:none;}#search-tabs>button:not(.selected){border:none;background-color:transparent !important;}#search-tabs>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}#settings-menu>a img{filter:invert(100);} \ No newline at end of file diff --git a/api/static.files/clipboard-7571035ce49a181d.svg b/api/static.files/clipboard-7571035ce49a181d.svg new file mode 100644 index 00000000..8adbd996 --- /dev/null +++ b/api/static.files/clipboard-7571035ce49a181d.svg @@ -0,0 +1 @@ + diff --git a/api/static.files/dark-0a43001d3fc2282c.css b/api/static.files/dark-0a43001d3fc2282c.css new file mode 100644 index 00000000..81032b2f --- /dev/null +++ b/api/static.files/dark-0a43001d3fc2282c.css @@ -0,0 +1 @@ +:root{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2A2A2A;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:rgb(91,59,1);--scrape-example-code-line-highlight-focus:rgb(124,75,15);--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);} \ No newline at end of file diff --git a/api/static.files/favicon-16x16-8b506e7a72182f1c.png b/api/static.files/favicon-16x16-8b506e7a72182f1c.png new file mode 100644 index 00000000..ea4b45ca Binary files /dev/null and b/api/static.files/favicon-16x16-8b506e7a72182f1c.png differ diff --git a/api/static.files/favicon-2c020d218678b618.svg b/api/static.files/favicon-2c020d218678b618.svg new file mode 100644 index 00000000..8b34b511 --- /dev/null +++ b/api/static.files/favicon-2c020d218678b618.svg @@ -0,0 +1,24 @@ + + + + + diff --git a/api/static.files/favicon-32x32-422f7d1d52889060.png b/api/static.files/favicon-32x32-422f7d1d52889060.png new file mode 100644 index 00000000..69b8613c Binary files /dev/null and b/api/static.files/favicon-32x32-422f7d1d52889060.png differ diff --git a/api/static.files/light-1596385f77d47ef2.css b/api/static.files/light-1596385f77d47ef2.css new file mode 100644 index 00000000..50adde5b --- /dev/null +++ b/api/static.files/light-1596385f77d47ef2.css @@ -0,0 +1 @@ +:root{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#F5F5F5;--sidebar-background-color-hover:#E0E0E0;--code-block-background-color:#F5F5F5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#ffffff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#F5F5F5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);} \ No newline at end of file diff --git a/api/static.files/main-0795b7d26be81095.js b/api/static.files/main-0795b7d26be81095.js new file mode 100644 index 00000000..87b43389 --- /dev/null +++ b/api/static.files/main-0795b7d26be81095.js @@ -0,0 +1,12 @@ +"use strict";window.RUSTDOC_TOOLTIP_HOVER_MS=300;window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS=450;function resourcePath(basename,extension){return getVar("root-path")+basename+getVar("resource-suffix")+extension}function hideMain(){addClass(document.getElementById(MAIN_ID),"hidden")}function showMain(){removeClass(document.getElementById(MAIN_ID),"hidden")}function elemIsInParent(elem,parent){while(elem&&elem!==document.body){if(elem===parent){return true}elem=elem.parentElement}return false}function blurHandler(event,parentElem,hideCallback){if(!elemIsInParent(document.activeElement,parentElem)&&!elemIsInParent(event.relatedTarget,parentElem)){hideCallback()}}window.rootPath=getVar("root-path");window.currentCrate=getVar("current-crate");function setMobileTopbar(){const mobileLocationTitle=document.querySelector(".mobile-topbar h2");const locationTitle=document.querySelector(".sidebar h2.location");if(mobileLocationTitle&&locationTitle){mobileLocationTitle.innerHTML=locationTitle.innerHTML}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!=="undefined"){return ev.key}const c=ev.charCode||ev.keyCode;if(c===27){return"Escape"}return String.fromCharCode(c)}const MAIN_ID="main-content";const SETTINGS_BUTTON_ID="settings-menu";const ALTERNATIVE_DISPLAY_ID="alternative-display";const NOT_DISPLAYED_ID="not-displayed";const HELP_BUTTON_ID="help-button";function getSettingsButton(){return document.getElementById(SETTINGS_BUTTON_ID)}function getHelpButton(){return document.getElementById(HELP_BUTTON_ID)}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function insertAfter(newNode,referenceNode){referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling)}function getOrCreateSection(id,classes){let el=document.getElementById(id);if(!el){el=document.createElement("section");el.id=id;el.className=classes;insertAfter(el,document.getElementById(MAIN_ID))}return el}function getAlternativeDisplayElem(){return getOrCreateSection(ALTERNATIVE_DISPLAY_ID,"content hidden")}function getNotDisplayedElem(){return getOrCreateSection(NOT_DISPLAYED_ID,"hidden")}function switchDisplayedElement(elemToDisplay){const el=getAlternativeDisplayElem();if(el.children.length>0){getNotDisplayedElem().appendChild(el.firstElementChild)}if(elemToDisplay===null){addClass(el,"hidden");showMain();return}el.appendChild(elemToDisplay);hideMain();removeClass(el,"hidden")}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function loadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="stylesheet";document.getElementsByTagName("head")[0].appendChild(link)}function preLoadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="preload";link.as="style";document.getElementsByTagName("head")[0].appendChild(link)}(function(){const isHelpPage=window.location.pathname.endsWith("/help.html");function loadScript(url){const script=document.createElement("script");script.src=url;document.head.append(script)}getSettingsButton().onclick=event=>{if(event.ctrlKey||event.altKey||event.metaKey){return}window.hideAllModals(false);addClass(getSettingsButton(),"rotate");event.preventDefault();loadCss(getVar("static-root-path")+getVar("settings-css"));loadScript(getVar("static-root-path")+getVar("settings-js"));preLoadCss(getVar("static-root-path")+getVar("theme-light-css"));preLoadCss(getVar("static-root-path")+getVar("theme-dark-css"));preLoadCss(getVar("static-root-path")+getVar("theme-ayu-css"));setTimeout(()=>{const themes=getVar("themes").split(",");for(const theme of themes){if(theme!==""){preLoadCss(getVar("root-path")+theme+".css")}}},0)};window.searchState={loadingText:"Loading search results...",input:document.getElementsByClassName("search-input")[0],outputElement:()=>{let el=document.getElementById("search");if(!el){el=document.createElement("section");el.id="search";getNotDisplayedElem().appendChild(el)}return el},title:document.title,titleBeforeSearch:document.title,timeout:null,currentTab:0,focusedByTab:[null,null,null],clearInputTimeout:()=>{if(searchState.timeout!==null){clearTimeout(searchState.timeout);searchState.timeout=null}},isDisplayed:()=>searchState.outputElement().parentElement.id===ALTERNATIVE_DISPLAY_ID,focus:()=>{searchState.input.focus()},defocus:()=>{searchState.input.blur()},showResults:search=>{if(search===null||typeof search==="undefined"){search=searchState.outputElement()}switchDisplayedElement(search);searchState.mouseMovedAfterSearch=false;document.title=searchState.title},removeQueryParameters:()=>{document.title=searchState.titleBeforeSearch;if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.hash)}},hideResults:()=>{switchDisplayedElement(null);searchState.removeQueryParameters()},getQueryStringParams:()=>{const params={};window.location.search.substring(1).split("&").map(s=>{const pair=s.split("=");params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params},setup:()=>{const search_input=searchState.input;if(!searchState.input){return}let searchLoaded=false;function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(getVar("static-root-path")+getVar("search-js"));loadScript(resourcePath("search-index",".js"))}}search_input.addEventListener("focus",()=>{search_input.origPlaceholder=search_input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});if(search_input.value!==""){loadSearch()}const params=searchState.getQueryStringParams();if(params.search!==undefined){searchState.setLoadingSearch();loadSearch()}},setLoadingSearch:()=>{const search=searchState.outputElement();search.innerHTML="

"+searchState.loadingText+"

";searchState.showResults(search)},};const toggleAllDocsId="toggle-all-docs";let savedHash="";function handleHashes(ev){if(ev!==null&&searchState.isDisplayed()&&ev.newURL){switchDisplayedElement(null);const hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.search+"#"+hash)}const elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}const pageId=window.location.hash.replace(/^#/,"");if(savedHash!==pageId){savedHash=pageId;if(pageId!==""){expandSection(pageId)}}}function onHashChange(ev){hideSidebar();handleHashes(ev)}function openParentDetails(elem){while(elem){if(elem.tagName==="DETAILS"){elem.open=true}elem=elem.parentNode}}function expandSection(id){openParentDetails(document.getElementById(id))}function handleEscape(ev){searchState.clearInputTimeout();searchState.hideResults();ev.preventDefault();searchState.defocus();window.hideAllModals(true)}function handleShortcut(ev){const disableShortcuts=getSettingValue("disable-shortcuts")==="true";if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts){return}if(document.activeElement.tagName==="INPUT"&&document.activeElement.type!=="checkbox"&&document.activeElement.type!=="radio"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":ev.preventDefault();searchState.focus();break;case"+":ev.preventDefault();expandAllDocs();break;case"-":ev.preventDefault();collapseAllDocs();break;case"?":showHelp();break;default:break}}}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function addSidebarItems(){if(!window.SIDEBAR_ITEMS){return}const sidebar=document.getElementsByClassName("sidebar-elems")[0];function block(shortty,id,longty){const filtered=window.SIDEBAR_ITEMS[shortty];if(!filtered){return}const h3=document.createElement("h3");h3.innerHTML=`${longty}`;const ul=document.createElement("ul");ul.className="block "+shortty;for(const name of filtered){let path;if(shortty==="mod"){path=name+"/index.html"}else{path=shortty+"."+name+".html"}const current_page=document.location.href.split("/").pop();const link=document.createElement("a");link.href=path;if(path===current_page){link.className="current"}link.textContent=name;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebar.appendChild(h3);sidebar.appendChild(ul)}if(sidebar){block("primitive","primitives","Primitive Types");block("mod","modules","Modules");block("macro","macros","Macros");block("struct","structs","Structs");block("enum","enums","Enums");block("union","unions","Unions");block("constant","constants","Constants");block("static","static","Statics");block("trait","traits","Traits");block("fn","functions","Functions");block("type","types","Type Definitions");block("foreigntype","foreign-types","Foreign Types");block("keyword","keywords","Keywords");block("traitalias","trait-aliases","Trait Aliases")}}window.register_implementors=imp=>{const implementors=document.getElementById("implementors-list");const synthetic_implementors=document.getElementById("synthetic-implementors-list");const inlined_types=new Set();const TEXT_IDX=0;const SYNTHETIC_IDX=1;const TYPES_IDX=2;if(synthetic_implementors){onEachLazy(synthetic_implementors.getElementsByClassName("impl"),el=>{const aliases=el.getAttribute("data-aliases");if(!aliases){return}aliases.split(",").forEach(alias=>{inlined_types.add(alias)})})}let currentNbImpls=implementors.getElementsByClassName("impl").length;const traitName=document.querySelector(".main-heading h1 > .trait").textContent;const baseIdName="impl-"+traitName+"-";const libs=Object.getOwnPropertyNames(imp);const script=document.querySelector("script[data-ignore-extern-crates]");const ignoreExternCrates=new Set((script?script.getAttribute("data-ignore-extern-crates"):"").split(","));for(const lib of libs){if(lib===window.currentCrate||ignoreExternCrates.has(lib)){continue}const structs=imp[lib];struct_loop:for(const struct of structs){const list=struct[SYNTHETIC_IDX]?synthetic_implementors:implementors;if(struct[SYNTHETIC_IDX]){for(const struct_type of struct[TYPES_IDX]){if(inlined_types.has(struct_type)){continue struct_loop}inlined_types.add(struct_type)}}const code=document.createElement("h3");code.innerHTML=struct[TEXT_IDX];addClass(code,"code-header");onEachLazy(code.getElementsByTagName("a"),elem=>{const href=elem.getAttribute("href");if(href&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});const currentId=baseIdName+currentNbImpls;const anchor=document.createElement("a");anchor.href="#"+currentId;addClass(anchor,"anchor");const display=document.createElement("div");display.id=currentId;addClass(display,"impl");display.appendChild(anchor);display.appendChild(code);list.appendChild(display);currentNbImpls+=1}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}function addSidebarCrates(){if(!window.ALL_CRATES){return}const sidebarElems=document.getElementsByClassName("sidebar-elems")[0];if(!sidebarElems){return}const h3=document.createElement("h3");h3.innerHTML="Crates";const ul=document.createElement("ul");ul.className="block crate";for(const crate of window.ALL_CRATES){const link=document.createElement("a");link.href=window.rootPath+crate+"/index.html";if(window.rootPath!=="./"&&crate===window.currentCrate){link.className="current"}link.textContent=crate;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebarElems.appendChild(h3);sidebarElems.appendChild(ul)}function expandAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);removeClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hasClass(e,"type-contents-toggle")&&!hasClass(e,"more-examples-toggle")){e.open=true}});innerToggle.title="collapse all docs";innerToggle.children[0].innerText="\u2212"}function collapseAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);addClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(e.parentNode.id!=="implementations-list"||(!hasClass(e,"implementors-toggle")&&!hasClass(e,"type-contents-toggle"))){e.open=false}});innerToggle.title="expand all docs";innerToggle.children[0].innerText="+"}function toggleAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);if(!innerToggle){return}if(hasClass(innerToggle,"will-expand")){expandAllDocs()}else{collapseAllDocs()}}(function(){const toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}const hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";const hideImplementations=getSettingValue("auto-hide-trait-implementations")==="true";const hideLargeItemContents=getSettingValue("auto-hide-large-items")!=="false";function setImplementorsTogglesOpen(id,open){const list=document.getElementById(id);if(list!==null){onEachLazy(list.getElementsByClassName("implementors-toggle"),e=>{e.open=open})}}if(hideImplementations){setImplementorsTogglesOpen("trait-implementations-list",false);setImplementorsTogglesOpen("blanket-implementations-list",false)}onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hideLargeItemContents&&hasClass(e,"type-contents-toggle")){e.open=true}if(hideMethodDocs&&hasClass(e,"method-toggle")){e.open=false}})}());window.rustdoc_add_line_numbers_to_examples=()=>{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");if(line_numbers.length>0){return}const count=x.textContent.split("\n").length;const elems=[];for(let i=0;i{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");for(const node of line_numbers){parent.removeChild(node)}})};if(getSettingValue("line-numbers")==="true"){window.rustdoc_add_line_numbers_to_examples()}function showSidebar(){window.hideAllModals(false);const sidebar=document.getElementsByClassName("sidebar")[0];addClass(sidebar,"shown")}function hideSidebar(){const sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"shown")}window.addEventListener("resize",()=>{if(window.CURRENT_TOOLTIP_ELEMENT){const base=window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE;const force_visible=base.TOOLTIP_FORCE_VISIBLE;hideTooltip(false);if(force_visible){showTooltip(base);base.TOOLTIP_FORCE_VISIBLE=true}}});const mainElem=document.getElementById(MAIN_ID);if(mainElem){mainElem.addEventListener("click",hideSidebar)}onEachLazy(document.querySelectorAll("a[href^='#']"),el=>{el.addEventListener("click",()=>{expandSection(el.hash.slice(1));hideSidebar()})});onEachLazy(document.querySelectorAll(".toggle > summary:not(.hideme)"),el=>{el.addEventListener("click",e=>{if(e.target.tagName!=="SUMMARY"&&e.target.tagName!=="A"){e.preventDefault()}})});function showTooltip(e){const notable_ty=e.getAttribute("data-notable-ty");if(!window.NOTABLE_TRAITS&¬able_ty){const data=document.getElementById("notable-traits-data");if(data){window.NOTABLE_TRAITS=JSON.parse(data.innerText)}else{throw new Error("showTooltip() called with notable without any notable traits!")}}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE===e){clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);return}window.hideAllModals(false);const wrapper=document.createElement("div");if(notable_ty){wrapper.innerHTML="
"+window.NOTABLE_TRAITS[notable_ty]+"
"}else{if(e.getAttribute("title")!==null){e.setAttribute("data-title",e.getAttribute("title"));e.removeAttribute("title")}if(e.getAttribute("data-title")!==null){const titleContent=document.createElement("div");titleContent.className="content";titleContent.appendChild(document.createTextNode(e.getAttribute("data-title")));wrapper.appendChild(titleContent)}}wrapper.className="tooltip popover";const focusCatcher=document.createElement("div");focusCatcher.setAttribute("tabindex","0");focusCatcher.onfocus=hideTooltip;wrapper.appendChild(focusCatcher);const pos=e.getBoundingClientRect();wrapper.style.top=(pos.top+window.scrollY+pos.height)+"px";wrapper.style.left=0;wrapper.style.right="auto";wrapper.style.visibility="hidden";const body=document.getElementsByTagName("body")[0];body.appendChild(wrapper);const wrapperPos=wrapper.getBoundingClientRect();const finalPos=pos.left+window.scrollX-wrapperPos.width+24;if(finalPos>0){wrapper.style.left=finalPos+"px"}else{wrapper.style.setProperty("--popover-arrow-offset",(wrapperPos.right-pos.right+4)+"px")}wrapper.style.visibility="";window.CURRENT_TOOLTIP_ELEMENT=wrapper;window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE=e;clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);wrapper.onpointerenter=function(ev){if(ev.pointerType!=="mouse"){return}clearTooltipHoverTimeout(e)};wrapper.onpointerleave=function(ev){if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!elemIsInParent(ev.relatedTarget,e)){setTooltipHoverTimeout(e,false);addClass(wrapper,"fade-out")}}}function setTooltipHoverTimeout(element,show){clearTooltipHoverTimeout(element);if(!show&&!window.CURRENT_TOOLTIP_ELEMENT){return}if(show&&window.CURRENT_TOOLTIP_ELEMENT){return}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE!==element){return}element.TOOLTIP_HOVER_TIMEOUT=setTimeout(()=>{if(show){showTooltip(element)}else if(!element.TOOLTIP_FORCE_VISIBLE){hideTooltip(false)}},show?window.RUSTDOC_TOOLTIP_HOVER_MS:window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS)}function clearTooltipHoverTimeout(element){if(element.TOOLTIP_HOVER_TIMEOUT!==undefined){removeClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out");clearTimeout(element.TOOLTIP_HOVER_TIMEOUT);delete element.TOOLTIP_HOVER_TIMEOUT}}function tooltipBlurHandler(event){if(window.CURRENT_TOOLTIP_ELEMENT&&!elemIsInParent(document.activeElement,window.CURRENT_TOOLTIP_ELEMENT)&&!elemIsInParent(event.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT)&&!elemIsInParent(document.activeElement,window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE)&&!elemIsInParent(event.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE)){setTimeout(()=>hideTooltip(false),0)}}function hideTooltip(focus){if(window.CURRENT_TOOLTIP_ELEMENT){if(window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE){if(focus){window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.focus()}window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE=false}const body=document.getElementsByTagName("body")[0];body.removeChild(window.CURRENT_TOOLTIP_ELEMENT);clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);window.CURRENT_TOOLTIP_ELEMENT=null}}onEachLazy(document.getElementsByClassName("tooltip"),e=>{e.onclick=function(){this.TOOLTIP_FORCE_VISIBLE=this.TOOLTIP_FORCE_VISIBLE?false:true;if(window.CURRENT_TOOLTIP_ELEMENT&&!this.TOOLTIP_FORCE_VISIBLE){hideTooltip(true)}else{showTooltip(this);window.CURRENT_TOOLTIP_ELEMENT.setAttribute("tabindex","0");window.CURRENT_TOOLTIP_ELEMENT.focus();window.CURRENT_TOOLTIP_ELEMENT.onblur=tooltipBlurHandler}return false};e.onpointerenter=function(ev){if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(this,true)};e.onpointermove=function(ev){if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(this,true)};e.onpointerleave=function(ev){if(ev.pointerType!=="mouse"){return}if(!this.TOOLTIP_FORCE_VISIBLE&&!elemIsInParent(ev.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT)){setTooltipHoverTimeout(e,false);addClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out")}}});const sidebar_menu_toggle=document.getElementsByClassName("sidebar-menu-toggle")[0];if(sidebar_menu_toggle){sidebar_menu_toggle.addEventListener("click",()=>{const sidebar=document.getElementsByClassName("sidebar")[0];if(!hasClass(sidebar,"shown")){showSidebar()}else{hideSidebar()}})}function helpBlurHandler(event){blurHandler(event,getHelpButton(),window.hidePopoverMenus)}function buildHelpMenu(){const book_info=document.createElement("span");const channel=getVar("channel");book_info.className="top";book_info.innerHTML=`You can find more information in \ +the rustdoc book.`;const shortcuts=[["?","Show this help dialog"],["S","Focus the search field"],["↑","Move up in search results"],["↓","Move down in search results"],["← / →","Switch result tab (when results focused)"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(x=>"
"+x[0].split(" ").map((y,index)=>((index&1)===0?""+y+"":" "+y+" ")).join("")+"
"+x[1]+"
").join("");const div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

Keyboard Shortcuts

"+shortcuts+"
";const infos=[`For a full list of all search features, take a look here.`,"Prefix searches with a type followed by a colon (e.g., fn:) to \ + restrict the search to a given item kind.","Accepted kinds are: fn, mod, struct, \ + enum, trait, type, macro, \ + and const.","Search functions by type signature (e.g., vec -> usize or \ + -> vec or String, enum:Cow -> bool)","You can look for items with an exact name by putting double quotes around \ + your request: \"string\"","Look for functions that accept or return \ + slices and \ + arrays by writing \ + square brackets (e.g., -> [u8] or [] -> Option)","Look for items inside another one by searching for a path: vec::Vec",].map(x=>"

"+x+"

").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

Search Tricks

"+infos;const rustdoc_version=document.createElement("span");rustdoc_version.className="bottom";const rustdoc_version_code=document.createElement("code");rustdoc_version_code.innerText="rustdoc "+getVar("rustdoc-version");rustdoc_version.appendChild(rustdoc_version_code);const container=document.createElement("div");if(!isHelpPage){container.className="popover"}container.id="help";container.style.display="none";const side_by_side=document.createElement("div");side_by_side.className="side-by-side";side_by_side.appendChild(div_shortcuts);side_by_side.appendChild(div_infos);container.appendChild(book_info);container.appendChild(side_by_side);container.appendChild(rustdoc_version);if(isHelpPage){const help_section=document.createElement("section");help_section.appendChild(container);document.getElementById("main-content").appendChild(help_section);container.style.display="block"}else{const help_button=getHelpButton();help_button.appendChild(container);container.onblur=helpBlurHandler;help_button.onblur=helpBlurHandler;help_button.children[0].onblur=helpBlurHandler}return container}window.hideAllModals=function(switchFocus){hideSidebar();window.hidePopoverMenus();hideTooltip(switchFocus)};window.hidePopoverMenus=function(){onEachLazy(document.querySelectorAll(".search-form .popover"),elem=>{elem.style.display="none"})};function getHelpMenu(buildNeeded){let menu=getHelpButton().querySelector(".popover");if(!menu&&buildNeeded){menu=buildHelpMenu()}return menu}function showHelp(){getHelpButton().querySelector("a").focus();const menu=getHelpMenu(true);if(menu.style.display==="none"){window.hideAllModals();menu.style.display=""}}if(isHelpPage){showHelp();document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault()})}else{document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault();const menu=getHelpMenu(true);const shouldShowHelp=menu.style.display==="none";if(shouldShowHelp){showHelp()}else{window.hidePopoverMenus()}})}setMobileTopbar();addSidebarItems();addSidebarCrates();onHashChange(null);window.addEventListener("hashchange",onHashChange);searchState.setup()}());(function(){let reset_button_timeout=null;const but=document.getElementById("copy-path");if(!but){return}but.onclick=()=>{const parent=but.parentElement;const path=[];onEach(parent.childNodes,child=>{if(child.tagName==="A"){path.push(child.textContent)}});const el=document.createElement("textarea");el.value=path.join("::");el.setAttribute("readonly","");el.style.position="absolute";el.style.left="-9999px";document.body.appendChild(el);el.select();document.execCommand("copy");document.body.removeChild(el);but.children[0].style.display="none";let tmp;if(but.childNodes.length<2){tmp=document.createTextNode("✓");but.appendChild(tmp)}else{onEachLazy(but.childNodes,e=>{if(e.nodeType===Node.TEXT_NODE){tmp=e;return true}});tmp.textContent="✓"}if(reset_button_timeout!==null){window.clearTimeout(reset_button_timeout)}function reset_button(){tmp.textContent="";reset_button_timeout=null;but.children[0].style.display=""}reset_button_timeout=window.setTimeout(reset_button,1000)}}()) \ No newline at end of file diff --git a/api/static.files/normalize-76eba96aa4d2e634.css b/api/static.files/normalize-76eba96aa4d2e634.css new file mode 100644 index 00000000..469959f1 --- /dev/null +++ b/api/static.files/normalize-76eba96aa4d2e634.css @@ -0,0 +1,2 @@ + /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} \ No newline at end of file diff --git a/api/static.files/noscript-cffde32267a19fd6.css b/api/static.files/noscript-cffde32267a19fd6.css new file mode 100644 index 00000000..12d3f6dd --- /dev/null +++ b/api/static.files/noscript-cffde32267a19fd6.css @@ -0,0 +1 @@ + #main-content .attributes{margin-left:0 !important;}#copy-path{display:none;}nav.sub{display:none;}.src .sidebar{display:none;}.notable-traits{display:none;} \ No newline at end of file diff --git a/api/static.files/rust-logo-151179464ae7ed46.svg b/api/static.files/rust-logo-151179464ae7ed46.svg new file mode 100644 index 00000000..62424d8f --- /dev/null +++ b/api/static.files/rust-logo-151179464ae7ed46.svg @@ -0,0 +1,61 @@ + + + diff --git a/api/static.files/rustdoc-cb6f1f67f1bcd037.css b/api/static.files/rustdoc-cb6f1f67f1bcd037.css new file mode 100644 index 00000000..ac787240 --- /dev/null +++ b/api/static.files/rustdoc-cb6f1f67f1bcd037.css @@ -0,0 +1,8 @@ + :root{--nav-sub-mobile-padding:8px;--search-typename-width:6.75rem;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:400;src:local('Source Serif 4'),url("SourceSerif4-Regular-46f98efaafac5295.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:italic;font-weight:400;src:local('Source Serif 4 Italic'),url("SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:700;src:local('Source Serif 4 Bold'),url("SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:italic;font-weight:400;src:url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'NanumBarunGothic';src:url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");font-display:swap;unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF;}*{box-sizing:border-box;}body{font:1rem/1.5 "Source Serif 4",NanumBarunGothic,serif;margin:0;position:relative;overflow-wrap:break-word;overflow-wrap:anywhere;font-feature-settings:"kern","liga";background-color:var(--main-background-color);color:var(--main-color);}h1{font-size:1.5rem;}h2{font-size:1.375rem;}h3{font-size:1.25rem;}h1,h2,h3,h4,h5,h6{font-weight:500;}h1,h2,h3,h4{margin:25px 0 15px 0;padding-bottom:6px;}.docblock h3,.docblock h4,h5,h6{margin:15px 0 5px 0;}.docblock>h2:first-child,.docblock>h3:first-child,.docblock>h4:first-child,.docblock>h5:first-child,.docblock>h6:first-child{margin-top:0;}.main-heading h1{margin:0;padding:0;flex-grow:1;overflow-wrap:break-word;overflow-wrap:anywhere;}.main-heading{display:flex;flex-wrap:wrap;padding-bottom:6px;margin-bottom:15px;}.content h2,.top-doc .docblock>h3,.top-doc .docblock>h4{border-bottom:1px solid var(--headings-border-bottom-color);}h1,h2{line-height:1.25;padding-top:3px;padding-bottom:9px;}h3.code-header{font-size:1.125rem;}h4.code-header{font-size:1rem;}.code-header{font-weight:600;margin:0;padding:0;white-space:pre-wrap;}#crate-search,h1,h2,h3,h4,h5,h6,.sidebar,.mobile-topbar,.search-input,.search-results .result-name,.item-name>a,.out-of-band,span.since,a.src,#help-button>a,summary.hideme,.scraped-example-list,ul.all-items{font-family:"Fira Sans",Arial,NanumBarunGothic,sans-serif;}#toggle-all-docs,a.anchor,.small-section-header a,#src-sidebar a,.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,h1 a,.search-results a,.stab,.result-name i{color:var(--main-color);}span.enum,a.enum,span.struct,a.struct,span.union,a.union,span.primitive,a.primitive,span.type,a.type,span.foreigntype,a.foreigntype{color:var(--type-link-color);}span.trait,a.trait,span.traitalias,a.traitalias{color:var(--trait-link-color);}span.associatedtype,a.associatedtype,span.constant,a.constant,span.static,a.static{color:var(--assoc-item-link-color);}span.fn,a.fn,span.method,a.method,span.tymethod,a.tymethod{color:var(--function-link-color);}span.attr,a.attr,span.derive,a.derive,span.macro,a.macro{color:var(--macro-link-color);}span.mod,a.mod{color:var(--mod-link-color);}span.keyword,a.keyword{color:var(--keyword-link-color);}a{color:var(--link-color);text-decoration:none;}ol,ul{padding-left:24px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.625em;}p{margin:0 0 .75em 0;}p:last-child{margin:0;}button{padding:1px 6px;cursor:pointer;}button#toggle-all-docs{padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.rustdoc{display:flex;flex-direction:row;flex-wrap:nowrap;}main{position:relative;flex-grow:1;padding:10px 15px 40px 45px;min-width:0;}.src main{padding:15px;}.width-limiter{max-width:960px;margin-right:auto;}details:not(.toggle) summary{margin-bottom:.6em;}code,pre,a.test-arrow,.code-header{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.125em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;line-height:1.5;}pre.item-decl{overflow-x:auto;}.item-decl .type-contents-toggle{contain:initial;}.src .content pre{padding:20px;}.rustdoc.src .example-wrap pre.src-line-numbers{padding:20px 0 20px 4px;}img{max-width:100%;}.sub-logo-container,.logo-container{line-height:0;display:block;}.sub-logo-container{margin-right:32px;}.sub-logo-container>img{height:60px;width:60px;object-fit:contain;}.rust-logo{filter:var(--rust-logo-filter);}.sidebar{font-size:0.875rem;flex:0 0 200px;overflow-y:scroll;overscroll-behavior:contain;position:sticky;height:100vh;top:0;left:0;}.rustdoc.src .sidebar{flex-basis:50px;border-right:1px solid;overflow-x:hidden;overflow-y:hidden;z-index:1;}.sidebar,.mobile-topbar,.sidebar-menu-toggle,#src-sidebar-toggle,#src-sidebar{background-color:var(--sidebar-background-color);}#src-sidebar-toggle>button:hover,#src-sidebar-toggle>button:focus{background-color:var(--sidebar-background-color-hover);}.src .sidebar>*:not(#src-sidebar-toggle){visibility:hidden;}.src-sidebar-expanded .src .sidebar{overflow-y:auto;flex-basis:300px;}.src-sidebar-expanded .src .sidebar>*:not(#src-sidebar-toggle){visibility:visible;}#all-types{margin-top:1em;}*{scrollbar-width:initial;scrollbar-color:var(--scrollbar-color);}.sidebar{scrollbar-width:thin;scrollbar-color:var(--scrollbar-color);}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;background-color:var(--scrollbar-track-background-color);}.sidebar::-webkit-scrollbar-track{background-color:var(--scrollbar-track-background-color);}::-webkit-scrollbar-thumb,.sidebar::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-background-color);}.hidden{display:none !important;}.sidebar .logo-container{margin-top:10px;margin-bottom:10px;text-align:center;}.version{overflow-wrap:break-word;}.logo-container>img{height:100px;width:100px;}ul.block,.block li{padding:0;margin:0;list-style:none;}.sidebar-elems a,.sidebar>h2 a{display:block;padding:0.25rem;margin-left:-0.25rem;}.sidebar h2{overflow-wrap:anywhere;padding:0;margin:0.7rem 0;}.sidebar h3{font-size:1.125rem;padding:0;margin:0;}.sidebar-elems,.sidebar>h2{padding-left:24px;}.sidebar a{color:var(--sidebar-link-color);}.sidebar .current,.sidebar a:hover:not(.logo-container){background-color:var(--sidebar-current-link-background-color);}.sidebar-elems .block{margin-bottom:2em;}.sidebar-elems .block li a{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}.mobile-topbar{display:none;}.rustdoc .example-wrap{display:flex;position:relative;margin-bottom:10px;}.rustdoc .example-wrap:last-child{margin-bottom:0px;}.rustdoc .example-wrap pre{margin:0;flex-grow:1;}.rustdoc:not(.src) .example-wrap pre{overflow:auto hidden;}.rustdoc .example-wrap pre.example-line-numbers,.rustdoc .example-wrap pre.src-line-numbers{flex-grow:0;min-width:fit-content;overflow:initial;text-align:right;-webkit-user-select:none;user-select:none;padding:14px 8px;color:var(--src-line-numbers-span-color);}.rustdoc .example-wrap pre.src-line-numbers{padding:14px 0;}.src-line-numbers a,.src-line-numbers span{color:var(--src-line-numbers-span-color);padding:0 8px;}.src-line-numbers :target{background-color:transparent;border-right:none;padding:0 8px;}.src-line-numbers .line-highlighted{background-color:var(--src-line-number-highlighted-background-color);}.search-loading{text-align:center;}.docblock-short{overflow-wrap:break-word;overflow-wrap:anywhere;}.docblock :not(pre)>code,.docblock-short code{white-space:pre-wrap;}.top-doc .docblock h2{font-size:1.375rem;}.top-doc .docblock h3{font-size:1.25rem;}.top-doc .docblock h4,.top-doc .docblock h5{font-size:1.125rem;}.top-doc .docblock h6{font-size:1rem;}.docblock h5{font-size:1rem;}.docblock h6{font-size:0.875rem;}.docblock{margin-left:24px;position:relative;}.docblock>:not(.more-examples-toggle):not(.example-wrap){max-width:100%;overflow-x:auto;}.out-of-band{flex-grow:0;font-size:1.125rem;}.docblock code,.docblock-short code,pre,.rustdoc.src .example-wrap{background-color:var(--code-block-background-color);}#main-content{position:relative;}.docblock table{margin:.5em 0;border-collapse:collapse;}.docblock table td,.docblock table th{padding:.5em;border:1px solid var(--border-color);}.docblock table tbody tr:nth-child(2n){background:var(--table-alt-row-background-color);}.method .where,.fn .where,.where.fmt-newline{display:block;white-space:pre-wrap;font-size:0.875rem;}.item-info{display:block;margin-left:24px;}.item-info code{font-size:0.875rem;}#main-content>.item-info{margin-left:0;}nav.sub{flex-grow:1;flex-flow:row nowrap;margin:4px 0 25px 0;display:flex;align-items:center;}.search-form{position:relative;display:flex;height:34px;flex-grow:1;}.src nav.sub{margin:0 0 15px 0;}.small-section-header{display:block;position:relative;}.small-section-header:hover>.anchor,.impl:hover>.anchor,.trait-impl:hover>.anchor,.variant:hover>.anchor{display:initial;}.anchor{display:none;position:absolute;left:-0.5em;background:none !important;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-15px;padding-right:8px;}h2.small-section-header>.anchor{padding-right:6px;}.main-heading a:hover,.example-wrap .rust a:hover,.all-items a:hover,.docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.item-info a{text-decoration:underline;}.crate.block a.current{font-weight:500;}table,.item-table{overflow-wrap:break-word;}.item-table{display:table;padding:0;margin:0;}.item-table>li{display:table-row;}.item-table>li>div{display:table-cell;}.item-table>li>.item-name{padding-right:1.25rem;}.search-results-title{margin-top:0;white-space:nowrap;display:flex;align-items:baseline;}#crate-search-div{position:relative;min-width:5em;}#crate-search{min-width:115px;padding:0 23px 0 4px;max-width:100%;text-overflow:ellipsis;border:1px solid var(--border-color);border-radius:4px;outline:none;cursor:pointer;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;background-color:var(--main-background-color);color:inherit;line-height:1.5;font-weight:500;}#crate-search:hover,#crate-search:focus{border-color:var(--crate-search-hover-border);}#crate-search-div::after{pointer-events:none;width:100%;height:100%;position:absolute;top:0;left:0;content:"";background-repeat:no-repeat;background-size:20px;background-position:calc(100% - 2px) 56%;background-image:url('data:image/svg+xml, \ + ');filter:var(--crate-search-div-filter);}#crate-search-div:hover::after,#crate-search-div:focus-within::after{filter:var(--crate-search-div-hover-filter);}#crate-search>option{font-size:1rem;}.search-input{-webkit-appearance:none;outline:none;border:1px solid var(--border-color);border-radius:2px;padding:8px;font-size:1rem;flex-grow:1;background-color:var(--button-background-color);color:var(--search-color);}.search-input:focus{border-color:var(--search-input-focused-border-color);}.search-results{display:none;}.search-results.active{display:block;}.search-results>a{display:flex;margin-left:2px;margin-right:2px;border-bottom:1px solid var(--search-result-border-color);gap:1em;}.search-results>a>div.desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:2;}.search-results a:hover,.search-results a:focus{background-color:var(--search-result-link-focus-background-color);}.search-results .result-name{display:flex;align-items:center;justify-content:start;flex:3;}.search-results .result-name .alias{color:var(--search-results-alias-color);}.search-results .result-name .grey{color:var(--search-results-grey-color);}.search-results .result-name .typename{color:var(--search-results-grey-color);font-size:0.875rem;width:var(--search-typename-width);}.search-results .result-name .path{word-break:break-all;max-width:calc(100% - var(--search-typename-width));display:inline-block;}.search-results .result-name .path>*{display:inline;}.popover{position:absolute;top:100%;right:0;z-index:2;margin-top:7px;border-radius:3px;border:1px solid var(--border-color);background-color:var(--main-background-color);color:var(--main-color);--popover-arrow-offset:11px;}.popover::before{content:'';position:absolute;right:var(--popover-arrow-offset);border:solid var(--border-color);border-width:1px 1px 0 0;background-color:var(--main-background-color);padding:4px;transform:rotate(-45deg);top:-5px;}#help.popover{max-width:600px;--popover-arrow-offset:48px;}#help dt{float:left;clear:left;margin-right:0.5rem;}#help span.top,#help span.bottom{text-align:center;display:block;font-size:1.125rem;}#help span.top{margin:10px 0;border-bottom:1px solid var(--border-color);padding-bottom:4px;margin-bottom:6px;}#help span.bottom{clear:both;border-top:1px solid var(--border-color);}.side-by-side>div{width:50%;float:left;padding:0 20px 20px 17px;}.item-info .stab{min-height:36px;display:flex;padding:3px;margin-bottom:5px;align-items:center;vertical-align:text-bottom;}.item-name .stab{margin-left:0.3125em;}.stab{padding:0 2px;font-size:0.875rem;font-weight:normal;color:var(--main-color);background-color:var(--stab-background-color);width:fit-content;white-space:pre-wrap;border-radius:3px;display:inline;}.stab.portability>code{background:none;color:var(--stab-code-color);}.stab .emoji{font-size:1.25rem;margin-right:0.3rem;}.emoji{text-shadow:1px 0 0 black,-1px 0 0 black,0 1px 0 black,0 -1px 0 black;}.since{font-weight:normal;font-size:initial;}.rightside{padding-left:12px;float:right;}.rightside:not(a),.out-of-band{color:var(--right-side-color);}pre.rust{tab-size:4;-moz-tab-size:4;}pre.rust .kw{color:var(--code-highlight-kw-color);}pre.rust .kw-2{color:var(--code-highlight-kw-2-color);}pre.rust .lifetime{color:var(--code-highlight-lifetime-color);}pre.rust .prelude-ty{color:var(--code-highlight-prelude-color);}pre.rust .prelude-val{color:var(--code-highlight-prelude-val-color);}pre.rust .string{color:var(--code-highlight-string-color);}pre.rust .number{color:var(--code-highlight-number-color);}pre.rust .bool-val{color:var(--code-highlight-literal-color);}pre.rust .self{color:var(--code-highlight-self-color);}pre.rust .attr{color:var(--code-highlight-attribute-color);}pre.rust .macro,pre.rust .macro-nonterminal{color:var(--code-highlight-macro-color);}pre.rust .question-mark{font-weight:bold;color:var(--code-highlight-question-mark-color);}pre.rust .comment{color:var(--code-highlight-comment-color);}pre.rust .doccomment{color:var(--code-highlight-doc-comment-color);}.rustdoc.src .example-wrap pre.rust a{background:var(--codeblock-link-background);}.example-wrap.compile_fail,.example-wrap.should_panic{border-left:2px solid var(--codeblock-error-color);}.ignore.example-wrap{border-left:2px solid var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover,.example-wrap.should_panic:hover{border-left:2px solid var(--codeblock-error-hover-color);}.example-wrap.ignore:hover{border-left:2px solid var(--codeblock-ignore-hover-color);}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip{color:var(--codeblock-error-color);}.example-wrap.ignore .tooltip{color:var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover .tooltip,.example-wrap.should_panic:hover .tooltip{color:var(--codeblock-error-hover-color);}.example-wrap.ignore:hover .tooltip{color:var(--codeblock-ignore-hover-color);}.example-wrap .tooltip{position:absolute;display:block;left:-25px;top:5px;margin:0;line-height:1;}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip,.example-wrap.ignore .tooltip{font-weight:bold;font-size:1.25rem;}a.test-arrow{visibility:hidden;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:1.375rem;top:5px;right:5px;z-index:1;color:var(--test-arrow-color);background-color:var(--test-arrow-background-color);}a.test-arrow:hover{color:var(--test-arrow-hover-color);background-color:var(--test-arrow-hover-background-color);}.example-wrap:hover .test-arrow{visibility:visible;}.code-attribute{font-weight:300;color:var(--code-attribute-color);}.item-spacer{width:100%;height:12px;display:block;}.out-of-band>span.since{font-size:1.25rem;}.sub-variant h4{font-size:1rem;font-weight:400;margin-top:0;margin-bottom:0;}.sub-variant{margin-left:24px;margin-bottom:40px;}.sub-variant>.sub-variant-field{margin-left:24px;}:target{padding-right:3px;background-color:var(--target-background-color);border-right:3px solid var(--target-border-color);}.code-header a.tooltip{color:inherit;margin-right:15px;position:relative;}.code-header a.tooltip:hover{color:var(--link-color);}a.tooltip:hover::after{position:absolute;top:calc(100% - 10px);left:-15px;right:-15px;height:20px;content:"\00a0";}.fade-out{opacity:0;transition:opacity 0.45s cubic-bezier(0,0,0.1,1.0);}.popover.tooltip .content{margin:0.25em 0.5em;}.popover.tooltip .content pre,.popover.tooltip .content code{background:transparent;margin:0;padding:0;font-size:1.25rem;white-space:pre-wrap;}.popover.tooltip .content>h3:first-child{margin:0 0 5px 0;}.search-failed{text-align:center;margin-top:20px;display:none;}.search-failed.active{display:block;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#search-tabs{display:flex;flex-direction:row;gap:1px;margin-bottom:4px;}#search-tabs button{text-align:center;font-size:1.125rem;border:0;border-top:2px solid;flex:1;line-height:1.5;color:inherit;}#search-tabs button:not(.selected){background-color:var(--search-tab-button-not-selected-background);border-top-color:var(--search-tab-button-not-selected-border-top-color);}#search-tabs button:hover,#search-tabs button.selected{background-color:var(--search-tab-button-selected-background);border-top-color:var(--search-tab-button-selected-border-top-color);}#search-tabs .count{font-size:1rem;color:var(--search-tab-title-count-color);}#search .error code{border-radius:3px;background-color:var(--search-error-code-background-color);}.search-corrections{font-weight:normal;}#src-sidebar-toggle{position:sticky;top:0;left:0;font-size:1.25rem;border-bottom:1px solid;display:flex;height:40px;justify-content:stretch;align-items:stretch;z-index:10;}#src-sidebar{width:100%;overflow:auto;}#src-sidebar>.title{font-size:1.5rem;text-align:center;border-bottom:1px solid var(--border-color);margin-bottom:6px;}#src-sidebar div.files>a:hover,details.dir-entry summary:hover,#src-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:var(--src-sidebar-background-hover);}#src-sidebar div.files>a.selected{background-color:var(--src-sidebar-background-selected);}#src-sidebar-toggle>button{font-size:inherit;font-weight:bold;background:none;color:inherit;text-align:center;border:none;outline:none;flex:1 1;-webkit-appearance:none;opacity:1;}#settings-menu,#help-button{margin-left:4px;display:flex;}#settings-menu>a,#help-button>a{display:flex;align-items:center;justify-content:center;background-color:var(--button-background-color);border:1px solid var(--border-color);border-radius:2px;color:var(--settings-button-color);font-size:20px;width:33px;}#settings-menu>a:hover,#settings-menu>a:focus,#help-button>a:hover,#help-button>a:focus{border-color:var(--settings-button-border-focus);}#copy-path{color:var(--copy-path-button-color);background:var(--main-background-color);height:34px;margin-left:10px;padding:0;padding-left:2px;border:0;width:33px;}#copy-path>img{filter:var(--copy-path-img-filter);}#copy-path:hover>img{filter:var(--copy-path-img-hover-filter);}@keyframes rotating{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}#settings-menu.rotate>a img{animation:rotating 2s linear infinite;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px var(--border-color);border-radius:3px;color:var(--kbd-color);background-color:var(--kbd-background);box-shadow:inset 0 -1px 0 var(--kbd-box-shadow-color);}ul.all-items>li{list-style:none;}details.dir-entry{padding-left:4px;}details.dir-entry>summary{margin:0 0 0 -4px;padding:0 0 0 4px;cursor:pointer;}details.dir-entry div.folders,details.dir-entry div.files{padding-left:23px;}details.dir-entry a{display:block;}details.toggle{contain:layout;position:relative;}details.toggle>summary.hideme{cursor:pointer;font-size:1rem;}details.toggle>summary{list-style:none;outline:none;}details.toggle>summary::-webkit-details-marker,details.toggle>summary::marker{display:none;}details.toggle>summary.hideme>span{margin-left:9px;}details.toggle>summary::before{background:url('data:image/svg+xml,') no-repeat top left;content:"";cursor:pointer;width:16px;height:16px;display:inline-block;vertical-align:middle;opacity:.5;filter:var(--toggle-filter);}details.toggle>summary.hideme>span,.more-examples-toggle summary,.more-examples-toggle .hide-more{color:var(--toggles-color);}details.toggle>summary::after{content:"Expand";overflow:hidden;width:0;height:0;position:absolute;}details.toggle>summary.hideme::after{content:"";}details.toggle>summary:focus::before,details.toggle>summary:hover::before{opacity:1;}details.toggle>summary:focus-visible::before{outline:1px dotted #000;outline-offset:1px;}details.non-exhaustive{margin-bottom:8px;}details.toggle>summary.hideme::before{position:relative;}details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;top:4px;}.impl-items>details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;}details.toggle[open] >summary.hideme{position:absolute;}details.toggle[open] >summary.hideme>span{display:none;}details.toggle[open] >summary::before{background:url('data:image/svg+xml,') no-repeat top left;}details.toggle[open] >summary::after{content:"Collapse";}.docblock summary>*{display:inline-block;}.docblock>.example-wrap:first-child .tooltip{margin-top:16px;}@media (max-width:700px){*[id]{scroll-margin-top:45px;}.rustdoc{display:block;}main{padding-left:15px;padding-top:0px;}.main-heading{flex-direction:column;}.out-of-band{text-align:left;margin-left:initial;padding:initial;}.out-of-band .since::before{content:"Since ";}.sidebar .logo-container,.sidebar .location{display:none;}.sidebar{position:fixed;top:45px;left:-1000px;z-index:11;height:calc(100vh - 45px);width:200px;}.src main,.rustdoc.src .sidebar{top:0;padding:0;height:100vh;border:0;}.sidebar.shown,.src-sidebar-expanded .src .sidebar,.rustdoc:not(.src) .sidebar:focus-within{left:0;}.mobile-topbar h2{padding-bottom:0;margin:auto 0.5em auto auto;overflow:hidden;font-size:24px;}.mobile-topbar h2 a{display:block;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;}.mobile-topbar .logo-container>img{max-width:35px;max-height:35px;margin:5px 0 5px 20px;}.mobile-topbar{display:flex;flex-direction:row;position:sticky;z-index:10;font-size:2rem;height:45px;width:100%;left:0;top:0;}.sidebar-menu-toggle{width:45px;font-size:32px;border:none;color:var(--main-color);}.sidebar-elems{margin-top:1em;}.anchor{display:none !important;}#search-tabs .count{display:block;}#main-content>details.toggle>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}#src-sidebar-toggle{position:fixed;left:1px;top:100px;width:30px;font-size:1.5rem;padding:0;z-index:10;border-top-right-radius:3px;border-bottom-right-radius:3px;border:1px solid;border-left:0;}.src-sidebar-expanded #src-sidebar-toggle{left:unset;top:unset;width:unset;border-top-right-radius:unset;border-bottom-right-radius:unset;position:sticky;border:0;border-bottom:1px solid;}#copy-path,#help-button{display:none;}.item-table,.item-row,.item-table>li,.item-table>li>div,.search-results>a,.search-results>a>div{display:block;}.search-results>a{padding:5px 0px;}.search-results>a>div.desc,.item-table>li>div.desc{padding-left:2em;}.search-results .result-name{display:block;}.search-results .result-name .typename{width:initial;margin-right:0;}.search-results .result-name .typename,.search-results .result-name .path{display:inline;}.src-sidebar-expanded .src .sidebar{max-width:100vw;width:100vw;}details.toggle:not(.top-doc)>summary{margin-left:10px;}.impl-items>details.toggle>summary:not(.hideme)::before,#main-content>details.toggle:not(.top-doc)>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}.impl-items>.item-info{margin-left:34px;}.src nav.sub{margin:0;padding:var(--nav-sub-mobile-padding);}}@media (min-width:701px){.scraped-example-title{position:absolute;z-index:10;background:var(--main-background-color);bottom:8px;right:5px;padding:2px 4px;box-shadow:0 0 4px var(--main-background-color);}}@media print{nav.sidebar,nav.sub,.out-of-band,a.src,#copy-path,details.toggle[open] >summary::before,details.toggle>summary::before,details.toggle.top-doc>summary{display:none;}.docblock{margin-left:0;}main{padding:10px;}}@media (max-width:464px){.docblock{margin-left:12px;}.docblock code{overflow-wrap:break-word;overflow-wrap:anywhere;}nav.sub{flex-direction:column;}.search-form{align-self:stretch;}.sub-logo-container>img{height:35px;width:35px;margin-bottom:var(--nav-sub-mobile-padding);}}.variant,.implementors-toggle>summary,.impl,#implementors-list>.docblock,.impl-items>section,.impl-items>.toggle>summary,.methods>section,.methods>.toggle>summary{margin-bottom:0.75em;}.variants>.docblock,.implementors-toggle>.docblock,.impl-items>.toggle[open]:not(:last-child),.methods>.toggle[open]:not(:last-child),.implementors-toggle[open]:not(:last-child){margin-bottom:2em;}#trait-implementations-list .impl-items>.toggle:not(:last-child),#synthetic-implementations-list .impl-items>.toggle:not(:last-child),#blanket-implementations-list .impl-items>.toggle:not(:last-child){margin-bottom:1em;}.scraped-example-list .scrape-help{margin-left:10px;padding:0 4px;font-weight:normal;font-size:12px;position:relative;bottom:1px;border:1px solid var(--scrape-example-help-border-color);border-radius:50px;color:var(--scrape-example-help-color);}.scraped-example-list .scrape-help:hover{border-color:var(--scrape-example-help-hover-border-color);color:var(--scrape-example-help-hover-color);}.scraped-example{position:relative;}.scraped-example .code-wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;width:100%;}.scraped-example:not(.expanded) .code-wrapper{max-height:calc(1.5em * 5 + 10px);}.scraped-example:not(.expanded) .code-wrapper pre{overflow-y:hidden;padding-bottom:0;max-height:calc(1.5em * 5 + 10px);}.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre{max-height:calc(1.5em * 10 + 10px);}.scraped-example .code-wrapper .next,.scraped-example .code-wrapper .prev,.scraped-example .code-wrapper .expand{color:var(--main-color);position:absolute;top:0.25em;z-index:1;padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.scraped-example .code-wrapper .prev{right:2.25em;}.scraped-example .code-wrapper .next{right:1.25em;}.scraped-example .code-wrapper .expand{right:0.25em;}.scraped-example:not(.expanded) .code-wrapper::before,.scraped-example:not(.expanded) .code-wrapper::after{content:" ";width:100%;height:5px;position:absolute;z-index:1;}.scraped-example:not(.expanded) .code-wrapper::before{top:0;background:linear-gradient(to bottom,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example:not(.expanded) .code-wrapper::after{bottom:0;background:linear-gradient(to top,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example .code-wrapper .example-wrap{width:100%;overflow-y:hidden;margin-bottom:0;}.scraped-example:not(.expanded) .code-wrapper .example-wrap{overflow-x:hidden;}.scraped-example .example-wrap .rust span.highlight{background:var(--scrape-example-code-line-highlight);}.scraped-example .example-wrap .rust span.highlight.focus{background:var(--scrape-example-code-line-highlight-focus);}.more-examples-toggle{max-width:calc(100% + 25px);margin-top:10px;margin-left:-25px;}.more-examples-toggle .hide-more{margin-left:25px;cursor:pointer;}.more-scraped-examples{margin-left:25px;position:relative;}.toggle-line{position:absolute;top:5px;bottom:0;right:calc(100% + 10px);padding:0 4px;cursor:pointer;}.toggle-line-inner{min-width:2px;height:100%;background:var(--scrape-example-toggle-line-background);}.toggle-line:hover .toggle-line-inner{background:var(--scrape-example-toggle-line-hover-background);}.more-scraped-examples .scraped-example,.example-links{margin-top:20px;}.more-scraped-examples .scraped-example:first-child{margin-top:5px;}.example-links ul{margin-bottom:0;} \ No newline at end of file diff --git a/api/static.files/scrape-examples-ef1e698c1d417c0c.js b/api/static.files/scrape-examples-ef1e698c1d417c0c.js new file mode 100644 index 00000000..ba830e37 --- /dev/null +++ b/api/static.files/scrape-examples-ef1e698c1d417c0c.js @@ -0,0 +1 @@ +"use strict";(function(){const DEFAULT_MAX_LINES=5;const HIDDEN_MAX_LINES=10;function scrollToLoc(elt,loc,isHidden){const lines=elt.querySelector(".src-line-numbers");let scrollOffset;const maxLines=isHidden?HIDDEN_MAX_LINES:DEFAULT_MAX_LINES;if(loc[1]-loc[0]>maxLines){const line=Math.max(0,loc[0]-1);scrollOffset=lines.children[line].offsetTop}else{const wrapper=elt.querySelector(".code-wrapper");const halfHeight=wrapper.offsetHeight/2;const offsetTop=lines.children[loc[0]].offsetTop;const lastLine=lines.children[loc[1]];const offsetBot=lastLine.offsetTop+lastLine.offsetHeight;const offsetMid=(offsetTop+offsetBot)/2;scrollOffset=offsetMid-halfHeight}lines.scrollTo(0,scrollOffset);elt.querySelector(".rust").scrollTo(0,scrollOffset)}function updateScrapedExample(example,isHidden){const locs=JSON.parse(example.attributes.getNamedItem("data-locs").textContent);let locIndex=0;const highlights=Array.prototype.slice.call(example.querySelectorAll(".highlight"));const link=example.querySelector(".scraped-example-title a");if(locs.length>1){const onChangeLoc=changeIndex=>{removeClass(highlights[locIndex],"focus");changeIndex();scrollToLoc(example,locs[locIndex][0],isHidden);addClass(highlights[locIndex],"focus");const url=locs[locIndex][1];const title=locs[locIndex][2];link.href=url;link.innerHTML=title};example.querySelector(".prev").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex-1+locs.length)%locs.length})});example.querySelector(".next").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex+1)%locs.length})})}const expandButton=example.querySelector(".expand");if(expandButton){expandButton.addEventListener("click",()=>{if(hasClass(example,"expanded")){removeClass(example,"expanded");scrollToLoc(example,locs[0][0],isHidden)}else{addClass(example,"expanded")}})}scrollToLoc(example,locs[0][0],isHidden)}const firstExamples=document.querySelectorAll(".scraped-example-list > .scraped-example");onEachLazy(firstExamples,el=>updateScrapedExample(el,false));onEachLazy(document.querySelectorAll(".more-examples-toggle"),toggle=>{onEachLazy(toggle.querySelectorAll(".toggle-line, .hide-more"),button=>{button.addEventListener("click",()=>{toggle.open=false})});const moreExamples=toggle.querySelectorAll(".scraped-example");toggle.querySelector("summary").addEventListener("click",()=>{setTimeout(()=>{onEachLazy(moreExamples,el=>updateScrapedExample(el,true))})},{once:true})})})() \ No newline at end of file diff --git a/api/static.files/search-6dfdfced5eff6596.js b/api/static.files/search-6dfdfced5eff6596.js new file mode 100644 index 00000000..90d0eb75 --- /dev/null +++ b/api/static.files/search-6dfdfced5eff6596.js @@ -0,0 +1,5 @@ +"use strict";(function(){const itemTypes=["mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","primitive","associatedtype","constant","associatedconstant","union","foreigntype","keyword","existential","attr","derive","traitalias",];const longItemTypes=["module","extern crate","re-export","struct","enum","function","type alias","static","trait","","trait method","method","struct field","enum variant","macro","primitive type","assoc type","constant","assoc const","union","foreign type","keyword","existential type","attribute macro","derive macro","trait alias",];const TY_PRIMITIVE=itemTypes.indexOf("primitive");const TY_KEYWORD=itemTypes.indexOf("keyword");const ROOT_PATH=typeof window!=="undefined"?window.rootPath:"../";function hasOwnPropertyRustdoc(obj,property){return Object.prototype.hasOwnProperty.call(obj,property)}function printTab(nb){let iter=0;let foundCurrentTab=false;let foundCurrentResultSet=false;onEachLazy(document.getElementById("search-tabs").childNodes,elem=>{if(nb===iter){addClass(elem,"selected");foundCurrentTab=true}else{removeClass(elem,"selected")}iter+=1});const isTypeSearch=(nb>0||iter===1);iter=0;onEachLazy(document.getElementById("results").childNodes,elem=>{if(nb===iter){addClass(elem,"active");foundCurrentResultSet=true}else{removeClass(elem,"active")}iter+=1});if(foundCurrentTab&&foundCurrentResultSet){searchState.currentTab=nb;const correctionsElem=document.getElementsByClassName("search-corrections");if(isTypeSearch){removeClass(correctionsElem[0],"hidden")}else{addClass(correctionsElem[0],"hidden")}}else if(nb!==0){printTab(0)}}const editDistanceState={current:[],prev:[],prevPrev:[],calculate:function calculate(a,b,limit){if(a.lengthlimit){return limit+1}while(b.length>0&&b[0]===a[0]){a=a.substring(1);b=b.substring(1)}while(b.length>0&&b[b.length-1]===a[a.length-1]){a=a.substring(0,a.length-1);b=b.substring(0,b.length-1)}if(b.length===0){return minDist}const aLength=a.length;const bLength=b.length;for(let i=0;i<=bLength;++i){this.current[i]=0;this.prev[i]=i;this.prevPrev[i]=Number.MAX_VALUE}for(let i=1;i<=aLength;++i){this.current[0]=i;const aIdx=i-1;for(let j=1;j<=bLength;++j){const bIdx=j-1;const substitutionCost=a[aIdx]===b[bIdx]?0:1;this.current[j]=Math.min(this.prev[j]+1,this.current[j-1]+1,this.prev[j-1]+substitutionCost);if((i>1)&&(j>1)&&(a[aIdx]===b[bIdx-1])&&(a[aIdx-1]===b[bIdx])){this.current[j]=Math.min(this.current[j],this.prevPrev[j-2]+1)}}const prevPrevTmp=this.prevPrev;this.prevPrev=this.prev;this.prev=this.current;this.current=prevPrevTmp}const distance=this.prev[bLength];return distance<=limit?distance:(limit+1)},};function editDistance(a,b,limit){return editDistanceState.calculate(a,b,limit)}function initSearch(rawSearchIndex){const MAX_RESULTS=200;const NO_TYPE_FILTER=-1;let searchIndex;let currentResults;let typeNameIdMap;const ALIASES=new Map();let typeNameIdOfArray;let typeNameIdOfSlice;let typeNameIdOfArrayOrSlice;function buildTypeMapIndex(name){if(name===""||name===null){return-1}if(typeNameIdMap.has(name)){return typeNameIdMap.get(name)}else{const id=typeNameIdMap.size;typeNameIdMap.set(name,id);return id}}function isWhitespace(c){return" \t\n\r".indexOf(c)!==-1}function isSpecialStartCharacter(c){return"<\"".indexOf(c)!==-1}function isEndCharacter(c){return",>-]".indexOf(c)!==-1}function isStopCharacter(c){return isEndCharacter(c)}function isErrorCharacter(c){return"()".indexOf(c)!==-1}function itemTypeFromName(typename){const index=itemTypes.findIndex(i=>i===typename);if(index<0){throw["Unknown type filter ",typename]}return index}function getStringElem(query,parserState,isInGenerics){if(isInGenerics){throw["Unexpected ","\""," in generics"]}else if(query.literalSearch){throw["Cannot have more than one literal search element"]}else if(parserState.totalElems-parserState.genericsElems>0){throw["Cannot use literal search when there is more than one element"]}parserState.pos+=1;const start=parserState.pos;const end=getIdentEndPosition(parserState);if(parserState.pos>=parserState.length){throw["Unclosed ","\""]}else if(parserState.userQuery[end]!=="\""){throw["Unexpected ",parserState.userQuery[end]," in a string element"]}else if(start===end){throw["Cannot have empty string element"]}parserState.pos+=1;query.literalSearch=true}function isPathStart(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="::"}function isReturnArrow(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="->"}function isIdentCharacter(c){return(c==="_"||(c>="0"&&c<="9")||(c>="a"&&c<="z")||(c>="A"&&c<="Z"))}function isSeparatorCharacter(c){return c===","}function isPathSeparator(c){return c===":"||isWhitespace(c)}function prevIs(parserState,lookingFor){let pos=parserState.pos;while(pos>0){const c=parserState.userQuery[pos-1];if(c===lookingFor){return true}else if(!isWhitespace(c)){break}pos-=1}return false}function isLastElemGeneric(elems,parserState){return(elems.length>0&&elems[elems.length-1].generics.length>0)||prevIs(parserState,">")}function skipWhitespace(parserState){while(parserState.pos0){throw["Cannot have more than one element if you use quotes"]}const typeFilter=parserState.typeFilter;parserState.typeFilter=null;if(name==="!"){if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive never type ","!"," and ",typeFilter," both specified",]}if(generics.length!==0){throw["Never type ","!"," does not accept generic parameters",]}return{name:"never",id:-1,fullPath:["never"],pathWithoutLast:[],pathLast:"never",generics:[],typeFilter:"primitive",}}if(path.startsWith("::")){throw["Paths cannot start with ","::"]}else if(path.endsWith("::")){throw["Paths cannot end with ","::"]}else if(path.includes("::::")){throw["Unexpected ","::::"]}else if(path.includes(" ::")){throw["Unexpected "," ::"]}else if(path.includes(":: ")){throw["Unexpected ",":: "]}const pathSegments=path.split(/::|\s+/);if(pathSegments.length===0||(pathSegments.length===1&&pathSegments[0]==="")){if(generics.length>0||prevIs(parserState,">")){throw["Found generics without a path"]}else{throw["Unexpected ",parserState.userQuery[parserState.pos]]}}for(const[i,pathSegment]of pathSegments.entries()){if(pathSegment==="!"){if(i!==0){throw["Never type ","!"," is not associated item"]}pathSegments[i]="never"}}parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}return{name:name.trim(),id:-1,fullPath:pathSegments,pathWithoutLast:pathSegments.slice(0,pathSegments.length-1),pathLast:pathSegments[pathSegments.length-1],generics:generics,typeFilter,}}function getIdentEndPosition(parserState){const start=parserState.pos;let end=parserState.pos;let foundExclamation=-1;while(parserState.pos=end){throw["Found generics without a path"]}parserState.pos+=1;getItemsBefore(query,parserState,generics,">")}if(isStringElem){skipWhitespace(parserState)}if(start>=end&&generics.length===0){return}elems.push(createQueryElement(query,parserState,parserState.userQuery.slice(start,end),generics,isInGenerics))}}function getItemsBefore(query,parserState,elems,endChar){let foundStopChar=true;let start=parserState.pos;const oldTypeFilter=parserState.typeFilter;parserState.typeFilter=null;let extra="";if(endChar===">"){extra="<"}else if(endChar==="]"){extra="["}else if(endChar===""){extra="->"}else{extra=endChar}while(parserState.pos"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(endChar!==""){throw["Expected ",","," or ",endChar,...extra,", found ",c,]}throw["Expected ",",",...extra,", found ",c,]}const posBefore=parserState.pos;start=parserState.pos;getNextElem(query,parserState,elems,endChar!=="");if(endChar!==""&&parserState.pos>=parserState.length){throw["Unclosed ",extra]}if(posBefore===parserState.pos){parserState.pos+=1}foundStopChar=false}if(parserState.pos>=parserState.length&&endChar!==""){throw["Unclosed ",extra]}parserState.pos+=1;parserState.typeFilter=oldTypeFilter}function checkExtraTypeFilterCharacters(start,parserState){const query=parserState.userQuery.slice(start,parserState.pos).trim();for(const c in query){if(!isIdentCharacter(query[c])){throw["Unexpected ",query[c]," in type filter (before ",":",")",]}}}function parseInput(query,parserState){let foundStopChar=true;let start=parserState.pos;while(parserState.pos"){if(isReturnArrow(parserState)){break}throw["Unexpected ",c," (did you mean ","->","?)"]}throw["Unexpected ",c]}else if(c===":"&&!isPathStart(parserState)){if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}else if(query.elems.length===0){throw["Expected type filter before ",":"]}else if(query.literalSearch){throw["Cannot use quotes on type filter"]}const typeFilterElem=query.elems.pop();checkExtraTypeFilterCharacters(start,parserState);parserState.typeFilter=typeFilterElem.name;parserState.pos+=1;parserState.totalElems-=1;query.literalSearch=false;foundStopChar=true;continue}else if(isWhitespace(c)){skipWhitespace(parserState);continue}if(!foundStopChar){let extra="";if(isLastElemGeneric(query.elems,parserState)){extra=[" after ",">"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(parserState.typeFilter!==null){throw["Expected ",","," or ","->",...extra,", found ",c,]}throw["Expected ",",",", ",":"," or ","->",...extra,", found ",c,]}const before=query.elems.length;start=parserState.pos;getNextElem(query,parserState,query.elems,false);if(query.elems.length===before){parserState.pos+=1}foundStopChar=false}if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}while(parserState.pos"]}break}else{parserState.pos+=1}}}function newParsedQuery(userQuery){return{original:userQuery,userQuery:userQuery.toLowerCase(),elems:[],returned:[],foundElems:0,literalSearch:false,error:null,correction:null,}}function buildUrl(search,filterCrates){let extra="?search="+encodeURIComponent(search);if(filterCrates!==null){extra+="&filter-crate="+encodeURIComponent(filterCrates)}return getNakedUrl()+extra+window.location.hash}function getFilterCrates(){const elem=document.getElementById("crate-search");if(elem&&elem.value!=="all crates"&&hasOwnPropertyRustdoc(rawSearchIndex,elem.value)){return elem.value}return null}function parseQuery(userQuery){function convertTypeFilterOnElem(elem){if(elem.typeFilter!==null){let typeFilter=elem.typeFilter;if(typeFilter==="const"){typeFilter="constant"}elem.typeFilter=itemTypeFromName(typeFilter)}else{elem.typeFilter=NO_TYPE_FILTER}for(const elem2 of elem.generics){convertTypeFilterOnElem(elem2)}}userQuery=userQuery.trim();const parserState={length:userQuery.length,pos:0,totalElems:0,genericsElems:0,typeFilter:null,userQuery:userQuery.toLowerCase(),};let query=newParsedQuery(userQuery);try{parseInput(query,parserState);for(const elem of query.elems){convertTypeFilterOnElem(elem)}for(const elem of query.returned){convertTypeFilterOnElem(elem)}}catch(err){query=newParsedQuery(userQuery);query.error=err;return query}if(!query.literalSearch){query.literalSearch=parserState.totalElems>1}query.foundElems=query.elems.length+query.returned.length;return query}function createQueryResults(results_in_args,results_returned,results_others,parsedQuery){return{"in_args":results_in_args,"returned":results_returned,"others":results_others,"query":parsedQuery,}}function execQuery(parsedQuery,searchWords,filterCrates,currentCrate){const results_others=new Map(),results_in_args=new Map(),results_returned=new Map();function transformResults(results){const duplicates=new Set();const out=[];for(const result of results){if(result.id>-1){const obj=searchIndex[result.id];obj.dist=result.dist;const res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;if(duplicates.has(obj.fullPath)){continue}duplicates.add(obj.fullPath);obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}return out}function sortResults(results,isType,preferredCrate){if(results.size===0){return[]}const userQuery=parsedQuery.userQuery;const result_list=[];for(const result of results.values()){result.word=searchWords[result.id];result.item=searchIndex[result.id]||{};result_list.push(result)}result_list.sort((aaa,bbb)=>{let a,b;a=(aaa.word!==userQuery);b=(bbb.word!==userQuery);if(a!==b){return a-b}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.path_dist;b=bbb.path_dist;if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}a=(aaa.dist);b=(bbb.dist);if(a!==b){return a-b}a=aaa.item.deprecated;b=bbb.item.deprecated;if(a!==b){return a-b}a=(aaa.item.crate!==preferredCrate);b=(bbb.item.crate!==preferredCrate);if(a!==b){return a-b}a=aaa.word.length;b=bbb.word.length;if(a!==b){return a-b}a=aaa.word;b=bbb.word;if(a!==b){return(a>b?+1:-1)}if((aaa.item.ty===TY_PRIMITIVE&&bbb.item.ty!==TY_KEYWORD)||(aaa.item.ty===TY_KEYWORD&&bbb.item.ty!==TY_PRIMITIVE)){return-1}if((bbb.item.ty===TY_PRIMITIVE&&aaa.item.ty!==TY_PRIMITIVE)||(bbb.item.ty===TY_KEYWORD&&aaa.item.ty!==TY_KEYWORD)){return 1}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});let nameSplit=null;if(parsedQuery.elems.length===1){const hasPath=typeof parsedQuery.elems[0].path==="undefined";nameSplit=hasPath?null:parsedQuery.elems[0].path}for(const result of result_list){if(result.dontValidate){continue}const name=result.item.name.toLowerCase(),path=result.item.path.toLowerCase(),parent=result.item.parent;if(!isType&&!validateResult(name,path,nameSplit,parent)){result.id=-1}}return transformResults(result_list)}function checkGenerics(fnType,queryElem){return unifyFunctionTypes(fnType.generics,queryElem.generics)}function unifyFunctionTypes(fnTypes,queryElems){if(queryElems.length===0){return true}if(!fnTypes||fnTypes.length===0){return false}const queryElemSet=new Map();const addQueryElemToQueryElemSet=function addQueryElemToQueryElemSet(queryElem){let currentQueryElemList;if(queryElemSet.has(queryElem.id)){currentQueryElemList=queryElemSet.get(queryElem.id)}else{currentQueryElemList=[];queryElemSet.set(queryElem.id,currentQueryElemList)}currentQueryElemList.push(queryElem)};for(const queryElem of queryElems){addQueryElemToQueryElemSet(queryElem)}const fnTypeSet=new Map();const addFnTypeToFnTypeSet=function addFnTypeToFnTypeSet(fnType){const queryContainsArrayOrSliceElem=queryElemSet.has(typeNameIdOfArrayOrSlice);if(fnType.id===-1||!(queryElemSet.has(fnType.id)||(fnType.id===typeNameIdOfSlice&&queryContainsArrayOrSliceElem)||(fnType.id===typeNameIdOfArray&&queryContainsArrayOrSliceElem))){for(const innerFnType of fnType.generics){addFnTypeToFnTypeSet(innerFnType)}return}let currentQueryElemList=queryElemSet.get(fnType.id)||[];let matchIdx=currentQueryElemList.findIndex(queryElem=>{return typePassesFilter(queryElem.typeFilter,fnType.ty)&&checkGenerics(fnType,queryElem)});if(matchIdx===-1&&(fnType.id===typeNameIdOfSlice||fnType.id===typeNameIdOfArray)&&queryContainsArrayOrSliceElem){currentQueryElemList=queryElemSet.get(typeNameIdOfArrayOrSlice)||[];matchIdx=currentQueryElemList.findIndex(queryElem=>{return typePassesFilter(queryElem.typeFilter,fnType.ty)&&checkGenerics(fnType,queryElem)})}if(matchIdx===-1){for(const innerFnType of fnType.generics){addFnTypeToFnTypeSet(innerFnType)}return}let currentFnTypeList;if(fnTypeSet.has(fnType.id)){currentFnTypeList=fnTypeSet.get(fnType.id)}else{currentFnTypeList=[];fnTypeSet.set(fnType.id,currentFnTypeList)}currentFnTypeList.push(fnType)};for(const fnType of fnTypes){addFnTypeToFnTypeSet(fnType)}const doHandleQueryElemList=(currentFnTypeList,queryElemList)=>{if(queryElemList.length===0){return true}const queryElem=queryElemList.pop();const l=currentFnTypeList.length;for(let i=0;i{if(!fnTypeSet.has(id)){if(id===typeNameIdOfArrayOrSlice){return handleQueryElemList(typeNameIdOfSlice,queryElemList)||handleQueryElemList(typeNameIdOfArray,queryElemList)}return false}const currentFnTypeList=fnTypeSet.get(id);if(currentFnTypeList.length0?checkIfInList(row.generics,elem):false}const matchesExact=row.id===elem.id;const matchesArrayOrSlice=elem.id===typeNameIdOfArrayOrSlice&&(row.id===typeNameIdOfSlice||row.id===typeNameIdOfArray);if((matchesExact||matchesArrayOrSlice)&&typePassesFilter(elem.typeFilter,row.ty)){if(elem.generics.length>0){return checkGenerics(row,elem)}return true}return checkIfInList(row.generics,elem)}function checkPath(contains,ty,maxEditDistance){if(contains.length===0){return 0}let ret_dist=maxEditDistance+1;const path=ty.path.split("::");if(ty.parent&&ty.parent.name){path.push(ty.parent.name.toLowerCase())}const length=path.length;const clength=contains.length;if(clength>length){return maxEditDistance+1}for(let i=0;ilength){break}let dist_total=0;let aborted=false;for(let x=0;xmaxEditDistance){aborted=true;break}dist_total+=dist}if(!aborted){ret_dist=Math.min(ret_dist,Math.round(dist_total/clength))}}return ret_dist}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER||filter===type)return true;const name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,desc:item.desc,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,deprecated:item.deprecated,}}function handleAliases(ret,query,filterCrates,currentCrate){const lowerQuery=query.toLowerCase();const aliases=[];const crateAliases=[];if(filterCrates!==null){if(ALIASES.has(filterCrates)&&ALIASES.get(filterCrates).has(lowerQuery)){const query_aliases=ALIASES.get(filterCrates).get(lowerQuery);for(const alias of query_aliases){aliases.push(createAliasFromItem(searchIndex[alias]))}}}else{for(const[crate,crateAliasesIndex]of ALIASES){if(crateAliasesIndex.has(lowerQuery)){const pushTo=crate===currentCrate?crateAliases:aliases;const query_aliases=crateAliasesIndex.get(lowerQuery);for(const alias of query_aliases){pushTo.push(createAliasFromItem(searchIndex[alias]))}}}}const sortFunc=(aaa,bbb)=>{if(aaa.path{alias.alias=query;const res=buildHrefAndPath(alias);alias.displayPath=pathSplitter(res[0]);alias.fullPath=alias.displayPath+alias.name;alias.href=res[1];ret.others.unshift(alias);if(ret.others.length>MAX_RESULTS){ret.others.pop()}};aliases.forEach(pushFunc);crateAliases.forEach(pushFunc)}function addIntoResults(results,fullId,id,index,dist,path_dist,maxEditDistance){const inBounds=dist<=maxEditDistance||index!==-1;if(dist===0||(!parsedQuery.literalSearch&&inBounds)){if(results.has(fullId)){const result=results.get(fullId);if(result.dontValidate||result.dist<=dist){return}}results.set(fullId,{id:id,index:index,dontValidate:parsedQuery.literalSearch,dist:dist,path_dist:path_dist,})}}function handleSingleArg(row,pos,elem,results_others,results_in_args,results_returned,maxEditDistance){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let index=-1,path_dist=0;const fullId=row.id;const searchWord=searchWords[pos];const in_args=row.type&&row.type.inputs&&checkIfInList(row.type.inputs,elem);if(in_args){addIntoResults(results_in_args,fullId,pos,-1,0,0,maxEditDistance)}const returned=row.type&&row.type.output&&checkIfInList(row.type.output,elem);if(returned){addIntoResults(results_returned,fullId,pos,-1,0,0,maxEditDistance)}if(!typePassesFilter(elem.typeFilter,row.ty)){return}const row_index=row.normalizedName.indexOf(elem.pathLast);const word_index=searchWord.indexOf(elem.pathLast);if(row_index===-1){index=word_index}else if(word_index===-1){index=row_index}else if(word_index1){path_dist=checkPath(elem.pathWithoutLast,row,maxEditDistance);if(path_dist>maxEditDistance){return}}if(parsedQuery.literalSearch){if(searchWord===elem.name){addIntoResults(results_others,fullId,pos,index,0,path_dist)}return}const dist=editDistance(searchWord,elem.pathLast,maxEditDistance);if(index===-1&&dist+path_dist>maxEditDistance){return}addIntoResults(results_others,fullId,pos,index,dist,path_dist,maxEditDistance)}function handleArgs(row,pos,results){if(!row||(filterCrates!==null&&row.crate!==filterCrates)||!row.type){return}if(!unifyFunctionTypes(row.type.inputs,parsedQuery.elems)){return}if(!unifyFunctionTypes(row.type.output,parsedQuery.returned)){return}addIntoResults(results,row.id,pos,0,0,0,Number.MAX_VALUE)}function innerRunQuery(){let elem,i,nSearchWords,in_returned,row;let queryLen=0;for(const elem of parsedQuery.elems){queryLen+=elem.name.length}for(const elem of parsedQuery.returned){queryLen+=elem.name.length}const maxEditDistance=Math.floor(queryLen/3);function convertNameToId(elem){if(typeNameIdMap.has(elem.name)){elem.id=typeNameIdMap.get(elem.name)}else if(!parsedQuery.literalSearch){let match=-1;let matchDist=maxEditDistance+1;let matchName="";for(const[name,id]of typeNameIdMap){const dist=editDistance(name,elem.name,maxEditDistance);if(dist<=matchDist&&dist<=maxEditDistance){if(dist===matchDist&&matchName>name){continue}match=id;matchDist=dist;matchName=name}}if(match!==-1){parsedQuery.correction=matchName}elem.id=match}for(const elem2 of elem.generics){convertNameToId(elem2)}}for(const elem of parsedQuery.elems){convertNameToId(elem)}for(const elem of parsedQuery.returned){convertNameToId(elem)}if(parsedQuery.foundElems===1){if(parsedQuery.elems.length===1){elem=parsedQuery.elems[0];for(i=0,nSearchWords=searchWords.length;i0){for(i=0,nSearchWords=searchWords.length;i-1||path.indexOf(key)>-1||(parent!==undefined&&parent.name!==undefined&&parent.name.toLowerCase().indexOf(key)>-1)||editDistance(name,key,maxEditDistance)<=maxEditDistance)){return false}}return true}function nextTab(direction){const next=(searchState.currentTab+direction+3)%searchState.focusedByTab.length;searchState.focusedByTab[searchState.currentTab]=document.activeElement;printTab(next);focusSearchResult()}function focusSearchResult(){const target=searchState.focusedByTab[searchState.currentTab]||document.querySelectorAll(".search-results.active a").item(0)||document.querySelectorAll("#search-tabs button").item(searchState.currentTab);searchState.focusedByTab[searchState.currentTab]=null;if(target){target.focus()}}function buildHrefAndPath(item){let displayPath;let href;const type=itemTypes[item.ty];const name=item.name;let path=item.path;if(type==="mod"){displayPath=path+"::";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="import"){displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/index.html#reexport."+name}else if(type==="primitive"||type==="keyword"){displayPath="";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=ROOT_PATH+name+"/index.html"}else if(item.parent!==undefined){const myparent=item.parent;let anchor="#"+type+"."+name;const parentType=itemTypes[myparent.ty];let pageType=parentType;let pageName=myparent.name;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){const enumNameIdx=item.path.lastIndexOf("::");const enumName=item.path.substr(enumNameIdx+2);path=item.path.substr(0,enumNameIdx);displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="#variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}href=ROOT_PATH+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html"+anchor}else{displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href]}function pathSplitter(path){const tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){let extraClass="";if(display===true){extraClass=" active"}const output=document.createElement("div");let length=0;if(array.length>0){output.className="search-results "+extraClass;array.forEach(item=>{const name=item.name;const type=itemTypes[item.ty];const longType=longItemTypes[item.ty];const typeName=longType.length!==0?`${longType}`:"?";length+=1;const link=document.createElement("a");link.className="result-"+type;link.href=item.href;const resultName=document.createElement("div");resultName.className="result-name";resultName.insertAdjacentHTML("beforeend",`${typeName}`);link.appendChild(resultName);let alias=" ";if(item.is_alias){alias=`
\ +${item.alias} - see \ +
`}resultName.insertAdjacentHTML("beforeend",`
${alias}\ +${item.displayPath}${name}\ +
`);const description=document.createElement("div");description.className="desc";description.insertAdjacentHTML("beforeend",item.desc);link.appendChild(description);output.appendChild(link)})}else if(query.error===null){output.className="search-failed"+extraClass;output.innerHTML="No results :(
"+"Try on DuckDuckGo?

"+"Or try looking in one of these:"}return[output,length]}function makeTabHeader(tabNb,text,nbElems){if(searchState.currentTab===tabNb){return""}return""}function showResults(results,go_to_first,filterCrates){const search=searchState.outputElement();if(go_to_first||(results.others.length===1&&getSettingValue("go-to-only-result")==="true")){window.onunload=()=>{};searchState.removeQueryParameters();const elem=document.createElement("a");elem.href=results.others[0].href;removeClass(elem,"active");document.body.appendChild(elem);elem.click();return}if(results.query===undefined){results.query=parseQuery(searchState.input.value)}currentResults=results.query.userQuery;const ret_others=addTab(results.others,results.query,true);const ret_in_args=addTab(results.in_args,results.query,false);const ret_returned=addTab(results.returned,results.query,false);let currentTab=searchState.currentTab;if((currentTab===0&&ret_others[1]===0)||(currentTab===1&&ret_in_args[1]===0)||(currentTab===2&&ret_returned[1]===0)){if(ret_others[1]!==0){currentTab=0}else if(ret_in_args[1]!==0){currentTab=1}else if(ret_returned[1]!==0){currentTab=2}}let crates="";const crates_list=Object.keys(rawSearchIndex);if(crates_list.length>1){crates=" in 
"}let output=`

Results${crates}

`;if(results.query.error!==null){const error=results.query.error;error.forEach((value,index)=>{value=value.split("<").join("<").split(">").join(">");if(index%2!==0){error[index]=`${value.replaceAll(" ", " ")}`}else{error[index]=value}});output+=`

Query parser error: "${error.join("")}".

`;output+="
"+makeTabHeader(0,"In Names",ret_others[1])+"
";currentTab=0}else if(results.query.foundElems<=1&&results.query.returned.length===0){output+="
"+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
"}else{const signatureTabTitle=results.query.elems.length===0?"In Function Return Types":results.query.returned.length===0?"In Function Parameters":"In Function Signatures";output+="
"+makeTabHeader(0,signatureTabTitle,ret_others[1])+"
";currentTab=0}if(results.query.correction!==null){const orig=results.query.returned.length>0?results.query.returned[0].name:results.query.elems[0].name;output+="

"+`Type "${orig}" not found. `+"Showing results for closest type name "+`"${results.query.correction}" instead.

`}const resultsElem=document.createElement("div");resultsElem.id="results";resultsElem.appendChild(ret_others[0]);resultsElem.appendChild(ret_in_args[0]);resultsElem.appendChild(ret_returned[0]);search.innerHTML=output;const crateSearch=document.getElementById("crate-search");if(crateSearch){crateSearch.addEventListener("input",updateCrate)}search.appendChild(resultsElem);searchState.showResults(search);const elems=document.getElementById("search-tabs").childNodes;searchState.focusedByTab=[];let i=0;for(const elem of elems){const j=i;elem.onclick=()=>printTab(j);searchState.focusedByTab.push(null);i+=1}printTab(currentTab)}function updateSearchHistory(url){if(!browserSupportsHistoryApi()){return}const params=searchState.getQueryStringParams();if(!history.state&&!params.search){history.pushState(null,"",url)}else{history.replaceState(null,"",url)}}function search(e,forced){if(e){e.preventDefault()}const query=parseQuery(searchState.input.value.trim());let filterCrates=getFilterCrates();if(!forced&&query.userQuery===currentResults){if(query.userQuery.length>0){putBackSearch()}return}searchState.setLoadingSearch();const params=searchState.getQueryStringParams();if(filterCrates===null&¶ms["filter-crate"]!==undefined){filterCrates=params["filter-crate"]}searchState.title="Results for "+query.original+" - Rust";updateSearchHistory(buildUrl(query.original,filterCrates));showResults(execQuery(query,searchWords,filterCrates,window.currentCrate),params.go_to_first,filterCrates)}function buildItemSearchTypeAll(types,lowercasePaths){const PATH_INDEX_DATA=0;const GENERICS_DATA=1;return types.map(type=>{let pathIndex,generics;if(typeof type==="number"){pathIndex=type;generics=[]}else{pathIndex=type[PATH_INDEX_DATA];generics=buildItemSearchTypeAll(type[GENERICS_DATA],lowercasePaths)}return{id:pathIndex===0?-1:buildTypeMapIndex(lowercasePaths[pathIndex-1].name),ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics:generics,}})}function buildFunctionSearchType(functionSearchType,lowercasePaths){const INPUTS_DATA=0;const OUTPUT_DATA=1;if(functionSearchType===0){return null}let inputs,output;if(typeof functionSearchType[INPUTS_DATA]==="number"){const pathIndex=functionSearchType[INPUTS_DATA];inputs=[{id:pathIndex===0?-1:buildTypeMapIndex(lowercasePaths[pathIndex-1].name),ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics:[],}]}else{inputs=buildItemSearchTypeAll(functionSearchType[INPUTS_DATA],lowercasePaths)}if(functionSearchType.length>1){if(typeof functionSearchType[OUTPUT_DATA]==="number"){const pathIndex=functionSearchType[OUTPUT_DATA];output=[{id:pathIndex===0?-1:buildTypeMapIndex(lowercasePaths[pathIndex-1].name),ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics:[],}]}else{output=buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA],lowercasePaths)}}else{output=[]}return{inputs,output,}}function buildIndex(rawSearchIndex){searchIndex=[];const searchWords=[];typeNameIdMap=new Map();const charA="A".charCodeAt(0);let currentIndex=0;let id=0;typeNameIdOfArray=buildTypeMapIndex("array");typeNameIdOfSlice=buildTypeMapIndex("slice");typeNameIdOfArrayOrSlice=buildTypeMapIndex("[]");for(const crate in rawSearchIndex){if(!hasOwnPropertyRustdoc(rawSearchIndex,crate)){continue}let crateSize=0;const crateCorpus=rawSearchIndex[crate];searchWords.push(crate);const crateRow={crate:crate,ty:1,name:crate,path:"",desc:crateCorpus.doc,parent:undefined,type:null,id:id,normalizedName:crate.indexOf("_")===-1?crate:crate.replace(/_/g,""),deprecated:null,};id+=1;searchIndex.push(crateRow);currentIndex+=1;const itemTypes=crateCorpus.t;const itemNames=crateCorpus.n;const itemPaths=new Map(crateCorpus.q);const itemDescs=crateCorpus.d;const itemParentIdxs=crateCorpus.i;const itemFunctionSearchTypes=crateCorpus.f;const deprecatedItems=new Set(crateCorpus.c);const paths=crateCorpus.p;const aliases=crateCorpus.a;const lowercasePaths=[];let len=paths.length;for(let i=0;i0?paths[itemParentIdxs[i]-1]:undefined,type:buildFunctionSearchType(itemFunctionSearchTypes[i],lowercasePaths),id:id,normalizedName:word.indexOf("_")===-1?word:word.replace(/_/g,""),deprecated:deprecatedItems.has(i),};id+=1;searchIndex.push(row);lastPath=row.path;crateSize+=1}if(aliases){const currentCrateAliases=new Map();ALIASES.set(crate,currentCrateAliases);for(const alias_name in aliases){if(!hasOwnPropertyRustdoc(aliases,alias_name)){continue}let currentNameAliases;if(currentCrateAliases.has(alias_name)){currentNameAliases=currentCrateAliases.get(alias_name)}else{currentNameAliases=[];currentCrateAliases.set(alias_name,currentNameAliases)}for(const local_alias of aliases[alias_name]){currentNameAliases.push(local_alias+currentIndex)}}}currentIndex+=crateSize}return searchWords}function onSearchSubmit(e){e.preventDefault();searchState.clearInputTimeout();search()}function putBackSearch(){const search_input=searchState.input;if(!searchState.input){return}if(search_input.value!==""&&!searchState.isDisplayed()){searchState.showResults();if(browserSupportsHistoryApi()){history.replaceState(null,"",buildUrl(search_input.value,getFilterCrates()))}document.title=searchState.title}}function registerSearchEvents(){const params=searchState.getQueryStringParams();if(searchState.input.value===""){searchState.input.value=params.search||""}const searchAfter500ms=()=>{searchState.clearInputTimeout();if(searchState.input.value.length===0){searchState.hideResults()}else{searchState.timeout=setTimeout(search,500)}};searchState.input.onkeyup=searchAfter500ms;searchState.input.oninput=searchAfter500ms;document.getElementsByClassName("search-form")[0].onsubmit=onSearchSubmit;searchState.input.onchange=e=>{if(e.target!==document.activeElement){return}searchState.clearInputTimeout();setTimeout(search,0)};searchState.input.onpaste=searchState.input.onchange;searchState.outputElement().addEventListener("keydown",e=>{if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey){return}if(e.which===38){const previous=document.activeElement.previousElementSibling;if(previous){previous.focus()}else{searchState.focus()}e.preventDefault()}else if(e.which===40){const next=document.activeElement.nextElementSibling;if(next){next.focus()}const rect=document.activeElement.getBoundingClientRect();if(window.innerHeight-rect.bottom{if(e.which===40){focusSearchResult();e.preventDefault()}});searchState.input.addEventListener("focus",()=>{putBackSearch()});searchState.input.addEventListener("blur",()=>{searchState.input.placeholder=searchState.input.origPlaceholder});if(browserSupportsHistoryApi()){const previousTitle=document.title;window.addEventListener("popstate",e=>{const params=searchState.getQueryStringParams();document.title=previousTitle;currentResults=null;if(params.search&¶ms.search.length>0){searchState.input.value=params.search;search(e)}else{searchState.input.value="";searchState.hideResults()}})}window.onpageshow=()=>{const qSearch=searchState.getQueryStringParams().search;if(searchState.input.value===""&&qSearch){searchState.input.value=qSearch}search()}}function updateCrate(ev){if(ev.target.value==="all crates"){const query=searchState.input.value.trim();updateSearchHistory(buildUrl(query,null))}currentResults=null;search(undefined,true)}const searchWords=buildIndex(rawSearchIndex);if(typeof window!=="undefined"){registerSearchEvents();if(window.searchState.getQueryStringParams().search){search()}}if(typeof exports!=="undefined"){exports.initSearch=initSearch;exports.execQuery=execQuery;exports.parseQuery=parseQuery}return searchWords}if(typeof window!=="undefined"){window.initSearch=initSearch;if(window.searchIndex!==undefined){initSearch(window.searchIndex)}}else{initSearch({})}})() \ No newline at end of file diff --git a/api/static.files/settings-8c76f75bfb6bd192.css b/api/static.files/settings-8c76f75bfb6bd192.css new file mode 100644 index 00000000..5241bb86 --- /dev/null +++ b/api/static.files/settings-8c76f75bfb6bd192.css @@ -0,0 +1,3 @@ +.setting-line{margin:1.2em 0.6em;}.setting-radio input,.setting-check input{margin-right:0.3em;height:1.2rem;width:1.2rem;border:2px solid var(--settings-input-border-color);outline:none;-webkit-appearance:none;cursor:pointer;}.setting-radio input{border-radius:50%;}.setting-radio span,.setting-check span{padding-bottom:1px;}.setting-radio{margin-top:0.1em;margin-bottom:0.1em;min-width:3.8em;padding:0.3em;display:inline-flex;align-items:center;cursor:pointer;}.setting-radio+.setting-radio{margin-left:0.5em;}.setting-check{margin-right:20px;display:flex;align-items:center;cursor:pointer;}.setting-radio input:checked{box-shadow:inset 0 0 0 3px var(--main-background-color);background-color:var(--settings-input-color);}.setting-check input:checked{background-color:var(--settings-input-color);border-width:1px;content:url('data:image/svg+xml,\ + \ + ');}.setting-radio input:focus,.setting-check input:focus{box-shadow:0 0 1px 1px var(--settings-input-color);}.setting-radio input:checked:focus{box-shadow:inset 0 0 0 3px var(--main-background-color),0 0 2px 2px var(--settings-input-color);}.setting-radio input:hover,.setting-check input:hover{border-color:var(--settings-input-color) !important;} \ No newline at end of file diff --git a/api/static.files/settings-de11bff964e9d4e5.js b/api/static.files/settings-de11bff964e9d4e5.js new file mode 100644 index 00000000..cc508a86 --- /dev/null +++ b/api/static.files/settings-de11bff964e9d4e5.js @@ -0,0 +1,17 @@ +"use strict";(function(){const isSettingsPage=window.location.pathname.endsWith("/settings.html");function changeSetting(settingName,value){if(settingName==="theme"){const useSystem=value==="system preference"?"true":"false";updateLocalStorage("use-system-theme",useSystem)}updateLocalStorage(settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":updateTheme();updateLightAndDark();break;case"line-numbers":if(value===true){window.rustdoc_add_line_numbers_to_examples()}else{window.rustdoc_remove_line_numbers_from_examples()}break}}function showLightAndDark(){removeClass(document.getElementById("preferred-light-theme"),"hidden");removeClass(document.getElementById("preferred-dark-theme"),"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme"),"hidden");addClass(document.getElementById("preferred-dark-theme"),"hidden")}function updateLightAndDark(){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||(useSystem===null&&getSettingValue("theme")===null)){showLightAndDark()}else{hideLightAndDark()}}function setEvents(settingsElement){updateLightAndDark();onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"),toggle=>{const settingId=toggle.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=function(){changeSetting(this.id,this.checked)}});onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"),elem=>{const settingId=elem.name;let settingValue=getSettingValue(settingId);if(settingId==="theme"){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||settingValue===null){settingValue=useSystem==="false"?"light":"system preference"}}if(settingValue!==null&&settingValue!=="null"){elem.checked=settingValue===elem.value}elem.addEventListener("change",ev=>{changeSetting(ev.target.name,ev.target.value)})})}function buildSettingsPageSections(settings){let output="";for(const setting of settings){const js_data_name=setting["js_name"];const setting_name=setting["name"];if(setting["options"]!==undefined){output+=`\ +
+
${setting_name}
+
`;onEach(setting["options"],option=>{const checked=option===setting["default"]?" checked":"";const full=`${js_data_name}-${option.replace(/ /g,"-")}`;output+=`\ + `});output+=`\ +
+
`}else{const checked=setting["default"]===true?" checked":"";output+=`\ +
\ + \ +
`}}return output}function buildSettingsPage(){const theme_names=getVar("themes").split(",").filter(t=>t);theme_names.push("light","dark","ayu");const settings=[{"name":"Theme","js_name":"theme","default":"system preference","options":theme_names.concat("system preference"),},{"name":"Preferred light theme","js_name":"preferred-light-theme","default":"light","options":theme_names,},{"name":"Preferred dark theme","js_name":"preferred-dark-theme","default":"dark","options":theme_names,},{"name":"Auto-hide item contents for large items","js_name":"auto-hide-large-items","default":true,},{"name":"Auto-hide item methods' documentation","js_name":"auto-hide-method-docs","default":false,},{"name":"Auto-hide trait implementation documentation","js_name":"auto-hide-trait-implementations","default":false,},{"name":"Directly go to item in search if there is only one result","js_name":"go-to-only-result","default":false,},{"name":"Show line numbers on code examples","js_name":"line-numbers","default":false,},{"name":"Disable keyboard shortcuts","js_name":"disable-shortcuts","default":false,},];const elementKind=isSettingsPage?"section":"div";const innerHTML=`
${buildSettingsPageSections(settings)}
`;const el=document.createElement(elementKind);el.id="settings";if(!isSettingsPage){el.className="popover"}el.innerHTML=innerHTML;if(isSettingsPage){document.getElementById(MAIN_ID).appendChild(el)}else{el.setAttribute("tabindex","-1");getSettingsButton().appendChild(el)}return el}const settingsMenu=buildSettingsPage();function displaySettings(){settingsMenu.style.display=""}function settingsBlurHandler(event){blurHandler(event,getSettingsButton(),window.hidePopoverMenus)}if(isSettingsPage){getSettingsButton().onclick=function(event){event.preventDefault()}}else{const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=function(event){if(elemIsInParent(event.target,settingsMenu)){return}event.preventDefault();const shouldDisplaySettings=settingsMenu.style.display==="none";window.hideAllModals();if(shouldDisplaySettings){displaySettings()}};settingsButton.onblur=settingsBlurHandler;settingsButton.querySelector("a").onblur=settingsBlurHandler;onEachLazy(settingsMenu.querySelectorAll("input"),el=>{el.onblur=settingsBlurHandler});settingsMenu.onblur=settingsBlurHandler}setTimeout(()=>{setEvents(settingsMenu);if(!isSettingsPage){displaySettings()}removeClass(getSettingsButton(),"rotate")},0)})() \ No newline at end of file diff --git a/api/static.files/src-script-3280b574d94e47b4.js b/api/static.files/src-script-3280b574d94e47b4.js new file mode 100644 index 00000000..9ea88921 --- /dev/null +++ b/api/static.files/src-script-3280b574d94e47b4.js @@ -0,0 +1 @@ +"use strict";(function(){const rootPath=getVar("root-path");const NAME_OFFSET=0;const DIRS_OFFSET=1;const FILES_OFFSET=2;const RUSTDOC_MOBILE_BREAKPOINT=700;function closeSidebarIfMobile(){if(window.innerWidth"){addClass(document.documentElement,"src-sidebar-expanded");child.innerText="<";updateLocalStorage("source-sidebar-show","true")}else{removeClass(document.documentElement,"src-sidebar-expanded");child.innerText=">";updateLocalStorage("source-sidebar-show","false")}}function createSidebarToggle(){const sidebarToggle=document.createElement("div");sidebarToggle.id="src-sidebar-toggle";const inner=document.createElement("button");if(getCurrentValue("source-sidebar-show")==="true"){inner.innerText="<"}else{inner.innerText=">"}inner.onclick=toggleSidebar;sidebarToggle.appendChild(inner);return sidebarToggle}function createSrcSidebar(){const container=document.querySelector("nav.sidebar");const sidebarToggle=createSidebarToggle();container.insertBefore(sidebarToggle,container.firstChild);const sidebar=document.createElement("div");sidebar.id="src-sidebar";let hasFoundFile=false;const title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(srcIndex).forEach(key=>{srcIndex[key][NAME_OFFSET]=key;hasFoundFile=createDirEntry(srcIndex[key],sidebar,"",hasFoundFile)});container.appendChild(sidebar);const selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}const lineNumbersRegex=/^#?(\d+)(?:-(\d+))?$/;function highlightSrcLines(match){if(typeof match==="undefined"){match=window.location.hash.match(lineNumbersRegex)}if(!match){return}let from=parseInt(match[1],10);let to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to{onEachLazy(e.getElementsByTagName("a"),i_e=>{removeClass(i_e,"line-highlighted")})});for(let i=from;i<=to;++i){elem=document.getElementById(i);if(!elem){break}addClass(elem,"line-highlighted")}}const handleSrcHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSrcLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return ev=>{let cur_line_id=parseInt(ev.target.id,10);if(isNaN(cur_line_id)||ev.ctrlKey||ev.altKey||ev.metaKey){return}ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){const tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());window.addEventListener("hashchange",()=>{const match=window.location.hash.match(lineNumbersRegex);if(match){return highlightSrcLines(match)}});onEachLazy(document.getElementsByClassName("src-line-numbers"),el=>{el.addEventListener("click",handleSrcHighlight)});highlightSrcLines();window.createSrcSidebar=createSrcSidebar})() \ No newline at end of file diff --git a/api/static.files/storage-db41da1a38ea3cb8.js b/api/static.files/storage-db41da1a38ea3cb8.js new file mode 100644 index 00000000..b8728135 --- /dev/null +++ b/api/static.files/storage-db41da1a38ea3cb8.js @@ -0,0 +1 @@ +"use strict";const darkThemes=["dark","ayu"];window.currentTheme=document.getElementById("themeStyle");const settingsDataset=(function(){const settingsElement=document.getElementById("default-settings");return settingsElement&&settingsElement.dataset?settingsElement.dataset:null})();function getSettingValue(settingName){const current=getCurrentValue(settingName);if(current===null&&settingsDataset!==null){const def=settingsDataset[settingName.replace(/-/g,"_")];if(def!==undefined){return def}}return current}const localStoredTheme=getSettingValue("theme");function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(elem&&elem.classList){elem.classList.add(className)}}function removeClass(elem,className){if(elem&&elem.classList){elem.classList.remove(className)}}function onEach(arr,func,reversed){if(arr&&arr.length>0){if(reversed){for(let i=arr.length-1;i>=0;--i){if(func(arr[i])){return true}}}else{for(const elem of arr){if(func(elem)){return true}}}}return false}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed)}function updateLocalStorage(name,value){try{window.localStorage.setItem("rustdoc-"+name,value)}catch(e){}}function getCurrentValue(name){try{return window.localStorage.getItem("rustdoc-"+name)}catch(e){return null}}const getVar=(function getVar(name){const el=document.querySelector("head > meta[name='rustdoc-vars']");return el?el.attributes["data-"+name].value:null});function switchTheme(newThemeName,saveTheme){if(saveTheme){updateLocalStorage("theme",newThemeName)}let newHref;if(newThemeName==="light"||newThemeName==="dark"||newThemeName==="ayu"){newHref=getVar("static-root-path")+getVar("theme-"+newThemeName+"-css")}else{newHref=getVar("root-path")+newThemeName+getVar("resource-suffix")+".css"}if(!window.currentTheme){document.write(``);window.currentTheme=document.getElementById("themeStyle")}else if(newHref!==window.currentTheme.href){window.currentTheme.href=newHref}}const updateTheme=(function(){const mql=window.matchMedia("(prefers-color-scheme: dark)");function updateTheme(){if(getSettingValue("use-system-theme")!=="false"){const lightTheme=getSettingValue("preferred-light-theme")||"light";const darkTheme=getSettingValue("preferred-dark-theme")||"dark";updateLocalStorage("use-system-theme","true");switchTheme(mql.matches?darkTheme:lightTheme,true)}else{switchTheme(getSettingValue("theme"),false)}}mql.addEventListener("change",updateTheme);return updateTheme})();if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("preferred-dark-theme",localStoredTheme)}}updateTheme();if(getSettingValue("source-sidebar-show")==="true"){addClass(document.documentElement,"src-sidebar-expanded")}window.addEventListener("pageshow",ev=>{if(ev.persisted){setTimeout(updateTheme,0)}}) \ No newline at end of file diff --git a/api/static.files/wheel-7b819b6101059cd0.svg b/api/static.files/wheel-7b819b6101059cd0.svg new file mode 100644 index 00000000..83c07f63 --- /dev/null +++ b/api/static.files/wheel-7b819b6101059cd0.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/async_example.rs b/async_example.rs new file mode 100644 index 00000000..da9097a2 --- /dev/null +++ b/async_example.rs @@ -0,0 +1,70 @@ +// ANCHOR: all +use calloop::EventLoop; + +// futures = "0.3" +use futures::sink::SinkExt; +use futures::stream::StreamExt; + +fn main() -> std::io::Result<()> { + // ANCHOR: decl_executor + let (exec, sched) = calloop::futures::executor()?; + // ANCHOR_END: decl_executor + + // ANCHOR: decl_loop + let mut event_loop = EventLoop::try_new()?; + let handle = event_loop.handle(); + + handle + .insert_source(exec, |evt, _metadata, _shared| { + // Print the value of the async block ie. the return value. + println!("Async block ended with: {}", evt); + }) + .map_err(|e| e.error)?; + // ANCHOR_END: decl_loop + + // ANCHOR: decl_async + // Let's create two channels for our async blocks below. The blocks will + // exchange messages via these channels. + let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded(); + let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded(); + + // Our toy async code. + let async_friendly_task = async move { + sender_friendly.send("Hello,").await.ok(); + if let Some(msg) = receiver_aloof.next().await { + println!("Aloof said: {}", msg); + } + sender_friendly.send("world!").await.ok(); + if let Some(msg) = receiver_aloof.next().await { + println!("Aloof said: {}", msg); + } + "Bye!" + }; + + let async_aloof_task = async move { + if let Some(msg) = receiver_friendly.next().await { + println!("Friendly said: {}", msg); + } + sender_aloof.send("Oh,").await.ok(); + if let Some(msg) = receiver_friendly.next().await { + println!("Friendly said: {}", msg); + } + sender_aloof.send("it's you.").await.ok(); + "Regards." + }; + // ANCHOR_END: decl_async + + // ANCHOR: run_loop + // Schedule the async block to be run in the event loop. + sched.schedule(async_friendly_task).unwrap(); + sched.schedule(async_aloof_task).unwrap(); + + // Run the event loop. + println!("Starting event loop. Use Ctrl-C to exit."); + event_loop.run(None, &mut (), |_| {})?; + println!("Event loop ended."); + // ANCHOR_END: run_loop + + Ok(()) +} +// ANCHOR_END: all diff --git a/ayu-highlight.css b/ayu-highlight.css new file mode 100644 index 00000000..0c45c6f1 --- /dev/null +++ b/ayu-highlight.css @@ -0,0 +1,79 @@ +/* +Based off of the Ayu theme +Original by Dempfi (https://github.com/dempfi/ayu) +*/ + +.hljs { + display: block; + overflow-x: auto; + background: #191f26; + color: #e6e1cf; + padding: 0.5em; +} + +.hljs-comment, +.hljs-quote { + color: #5c6773; + font-style: italic; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-attr, +.hljs-regexp, +.hljs-link, +.hljs-selector-id, +.hljs-selector-class { + color: #ff7733; +} + +.hljs-number, +.hljs-meta, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #ffee99; +} + +.hljs-string, +.hljs-bullet { + color: #b8cc52; +} + +.hljs-title, +.hljs-built_in, +.hljs-section { + color: #ffb454; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-symbol { + color: #ff7733; +} + +.hljs-name { + color: #36a3d9; +} + +.hljs-tag { + color: #00568d; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-addition { + color: #91b362; +} + +.hljs-deletion { + color: #d96c75; +} diff --git a/book.js b/book.js new file mode 100644 index 00000000..5e386369 --- /dev/null +++ b/book.js @@ -0,0 +1,660 @@ +"use strict"; + +// Fix back button cache problem +window.onunload = function () { }; + +// Global variable, shared between modules +function playground_text(playground) { + let code_block = playground.querySelector("code"); + + if (window.ace && code_block.classList.contains("editable")) { + let editor = window.ace.edit(code_block); + return editor.getValue(); + } else { + return code_block.textContent; + } +} + +(function codeSnippets() { + function fetch_with_timeout(url, options, timeout = 6000) { + return Promise.race([ + fetch(url, options), + new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout)) + ]); + } + + var playgrounds = Array.from(document.querySelectorAll(".playground")); + if (playgrounds.length > 0) { + fetch_with_timeout("https://play.rust-lang.org/meta/crates", { + headers: { + 'Content-Type': "application/json", + }, + method: 'POST', + mode: 'cors', + }) + .then(response => response.json()) + .then(response => { + // get list of crates available in the rust playground + let playground_crates = response.crates.map(item => item["id"]); + playgrounds.forEach(block => handle_crate_list_update(block, playground_crates)); + }); + } + + function handle_crate_list_update(playground_block, playground_crates) { + // update the play buttons after receiving the response + update_play_button(playground_block, playground_crates); + + // and install on change listener to dynamically update ACE editors + if (window.ace) { + let code_block = playground_block.querySelector("code"); + if (code_block.classList.contains("editable")) { + let editor = window.ace.edit(code_block); + editor.addEventListener("change", function (e) { + update_play_button(playground_block, playground_crates); + }); + // add Ctrl-Enter command to execute rust code + editor.commands.addCommand({ + name: "run", + bindKey: { + win: "Ctrl-Enter", + mac: "Ctrl-Enter" + }, + exec: _editor => run_rust_code(playground_block) + }); + } + } + } + + // updates the visibility of play button based on `no_run` class and + // used crates vs ones available on http://play.rust-lang.org + function update_play_button(pre_block, playground_crates) { + var play_button = pre_block.querySelector(".play-button"); + + // skip if code is `no_run` + if (pre_block.querySelector('code').classList.contains("no_run")) { + play_button.classList.add("hidden"); + return; + } + + // get list of `extern crate`'s from snippet + var txt = playground_text(pre_block); + var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g; + var snippet_crates = []; + var item; + while (item = re.exec(txt)) { + snippet_crates.push(item[1]); + } + + // check if all used crates are available on play.rust-lang.org + var all_available = snippet_crates.every(function (elem) { + return playground_crates.indexOf(elem) > -1; + }); + + if (all_available) { + play_button.classList.remove("hidden"); + } else { + play_button.classList.add("hidden"); + } + } + + function run_rust_code(code_block) { + var result_block = code_block.querySelector(".result"); + if (!result_block) { + result_block = document.createElement('code'); + result_block.className = 'result hljs language-bash'; + + code_block.append(result_block); + } + + let text = playground_text(code_block); + let classes = code_block.querySelector('code').classList; + let has_2018 = classes.contains("edition2018"); + let edition = has_2018 ? "2018" : "2015"; + + var params = { + version: "stable", + optimize: "0", + code: text, + edition: edition + }; + + if (text.indexOf("#![feature") !== -1) { + params.version = "nightly"; + } + + result_block.innerText = "Running..."; + + fetch_with_timeout("https://play.rust-lang.org/evaluate.json", { + headers: { + 'Content-Type': "application/json", + }, + method: 'POST', + mode: 'cors', + body: JSON.stringify(params) + }) + .then(response => response.json()) + .then(response => result_block.innerText = response.result) + .catch(error => result_block.innerText = "Playground Communication: " + error.message); + } + + // Syntax highlighting Configuration + hljs.configure({ + tabReplace: ' ', // 4 spaces + languages: [], // Languages used for auto-detection + }); + + let code_nodes = Array + .from(document.querySelectorAll('code')) + // Don't highlight `inline code` blocks in headers. + .filter(function (node) {return !node.parentElement.classList.contains("header"); }); + + if (window.ace) { + // language-rust class needs to be removed for editable + // blocks or highlightjs will capture events + Array + .from(document.querySelectorAll('code.editable')) + .forEach(function (block) { block.classList.remove('language-rust'); }); + + Array + .from(document.querySelectorAll('code:not(.editable)')) + .forEach(function (block) { hljs.highlightBlock(block); }); + } else { + code_nodes.forEach(function (block) { hljs.highlightBlock(block); }); + } + + // Adding the hljs class gives code blocks the color css + // even if highlighting doesn't apply + code_nodes.forEach(function (block) { block.classList.add('hljs'); }); + + Array.from(document.querySelectorAll("code.language-rust")).forEach(function (block) { + + var lines = Array.from(block.querySelectorAll('.boring')); + // If no lines were hidden, return + if (!lines.length) { return; } + block.classList.add("hide-boring"); + + var buttons = document.createElement('div'); + buttons.className = 'buttons'; + buttons.innerHTML = ""; + + // add expand button + var pre_block = block.parentNode; + pre_block.insertBefore(buttons, pre_block.firstChild); + + pre_block.querySelector('.buttons').addEventListener('click', function (e) { + if (e.target.classList.contains('fa-eye')) { + e.target.classList.remove('fa-eye'); + e.target.classList.add('fa-eye-slash'); + e.target.title = 'Hide lines'; + e.target.setAttribute('aria-label', e.target.title); + + block.classList.remove('hide-boring'); + } else if (e.target.classList.contains('fa-eye-slash')) { + e.target.classList.remove('fa-eye-slash'); + e.target.classList.add('fa-eye'); + e.target.title = 'Show hidden lines'; + e.target.setAttribute('aria-label', e.target.title); + + block.classList.add('hide-boring'); + } + }); + }); + + if (window.playground_copyable) { + Array.from(document.querySelectorAll('pre code')).forEach(function (block) { + var pre_block = block.parentNode; + if (!pre_block.classList.contains('playground')) { + var buttons = pre_block.querySelector(".buttons"); + if (!buttons) { + buttons = document.createElement('div'); + buttons.className = 'buttons'; + pre_block.insertBefore(buttons, pre_block.firstChild); + } + + var clipButton = document.createElement('button'); + clipButton.className = 'fa fa-copy clip-button'; + clipButton.title = 'Copy to clipboard'; + clipButton.setAttribute('aria-label', clipButton.title); + clipButton.innerHTML = ''; + + buttons.insertBefore(clipButton, buttons.firstChild); + } + }); + } + + // Process playground code blocks + Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) { + // Add play button + var buttons = pre_block.querySelector(".buttons"); + if (!buttons) { + buttons = document.createElement('div'); + buttons.className = 'buttons'; + pre_block.insertBefore(buttons, pre_block.firstChild); + } + + var runCodeButton = document.createElement('button'); + runCodeButton.className = 'fa fa-play play-button'; + runCodeButton.hidden = true; + runCodeButton.title = 'Run this code'; + runCodeButton.setAttribute('aria-label', runCodeButton.title); + + buttons.insertBefore(runCodeButton, buttons.firstChild); + runCodeButton.addEventListener('click', function (e) { + run_rust_code(pre_block); + }); + + if (window.playground_copyable) { + var copyCodeClipboardButton = document.createElement('button'); + copyCodeClipboardButton.className = 'fa fa-copy clip-button'; + copyCodeClipboardButton.innerHTML = ''; + copyCodeClipboardButton.title = 'Copy to clipboard'; + copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title); + + buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild); + } + + let code_block = pre_block.querySelector("code"); + if (window.ace && code_block.classList.contains("editable")) { + var undoChangesButton = document.createElement('button'); + undoChangesButton.className = 'fa fa-history reset-button'; + undoChangesButton.title = 'Undo changes'; + undoChangesButton.setAttribute('aria-label', undoChangesButton.title); + + buttons.insertBefore(undoChangesButton, buttons.firstChild); + + undoChangesButton.addEventListener('click', function () { + let editor = window.ace.edit(code_block); + editor.setValue(editor.originalCode); + editor.clearSelection(); + }); + } + }); +})(); + +(function themes() { + var html = document.querySelector('html'); + var themeToggleButton = document.getElementById('theme-toggle'); + var themePopup = document.getElementById('theme-list'); + var themeColorMetaTag = document.querySelector('meta[name="theme-color"]'); + var stylesheets = { + ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"), + tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"), + highlight: document.querySelector("[href$='highlight.css']"), + }; + + function showThemes() { + themePopup.style.display = 'block'; + themeToggleButton.setAttribute('aria-expanded', true); + themePopup.querySelector("button#" + get_theme()).focus(); + } + + function hideThemes() { + themePopup.style.display = 'none'; + themeToggleButton.setAttribute('aria-expanded', false); + themeToggleButton.focus(); + } + + function get_theme() { + var theme; + try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { } + if (theme === null || theme === undefined) { + return default_theme; + } else { + return theme; + } + } + + function set_theme(theme, store = true) { + let ace_theme; + + if (theme == 'coal' || theme == 'navy') { + stylesheets.ayuHighlight.disabled = true; + stylesheets.tomorrowNight.disabled = false; + stylesheets.highlight.disabled = true; + + ace_theme = "ace/theme/tomorrow_night"; + } else if (theme == 'ayu') { + stylesheets.ayuHighlight.disabled = false; + stylesheets.tomorrowNight.disabled = true; + stylesheets.highlight.disabled = true; + ace_theme = "ace/theme/tomorrow_night"; + } else { + stylesheets.ayuHighlight.disabled = true; + stylesheets.tomorrowNight.disabled = true; + stylesheets.highlight.disabled = false; + ace_theme = "ace/theme/dawn"; + } + + setTimeout(function () { + themeColorMetaTag.content = getComputedStyle(document.body).backgroundColor; + }, 1); + + if (window.ace && window.editors) { + window.editors.forEach(function (editor) { + editor.setTheme(ace_theme); + }); + } + + var previousTheme = get_theme(); + + if (store) { + try { localStorage.setItem('mdbook-theme', theme); } catch (e) { } + } + + html.classList.remove(previousTheme); + html.classList.add(theme); + } + + // Set theme + var theme = get_theme(); + + set_theme(theme, false); + + themeToggleButton.addEventListener('click', function () { + if (themePopup.style.display === 'block') { + hideThemes(); + } else { + showThemes(); + } + }); + + themePopup.addEventListener('click', function (e) { + var theme = e.target.id || e.target.parentElement.id; + set_theme(theme); + }); + + themePopup.addEventListener('focusout', function(e) { + // e.relatedTarget is null in Safari and Firefox on macOS (see workaround below) + if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) { + hideThemes(); + } + }); + + // Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628 + document.addEventListener('click', function(e) { + if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) { + hideThemes(); + } + }); + + document.addEventListener('keydown', function (e) { + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; } + if (!themePopup.contains(e.target)) { return; } + + switch (e.key) { + case 'Escape': + e.preventDefault(); + hideThemes(); + break; + case 'ArrowUp': + e.preventDefault(); + var li = document.activeElement.parentElement; + if (li && li.previousElementSibling) { + li.previousElementSibling.querySelector('button').focus(); + } + break; + case 'ArrowDown': + e.preventDefault(); + var li = document.activeElement.parentElement; + if (li && li.nextElementSibling) { + li.nextElementSibling.querySelector('button').focus(); + } + break; + case 'Home': + e.preventDefault(); + themePopup.querySelector('li:first-child button').focus(); + break; + case 'End': + e.preventDefault(); + themePopup.querySelector('li:last-child button').focus(); + break; + } + }); +})(); + +(function sidebar() { + var html = document.querySelector("html"); + var sidebar = document.getElementById("sidebar"); + var sidebarLinks = document.querySelectorAll('#sidebar a'); + var sidebarToggleButton = document.getElementById("sidebar-toggle"); + var sidebarResizeHandle = document.getElementById("sidebar-resize-handle"); + var firstContact = null; + + function showSidebar() { + html.classList.remove('sidebar-hidden') + html.classList.add('sidebar-visible'); + Array.from(sidebarLinks).forEach(function (link) { + link.setAttribute('tabIndex', 0); + }); + sidebarToggleButton.setAttribute('aria-expanded', true); + sidebar.setAttribute('aria-hidden', false); + try { localStorage.setItem('mdbook-sidebar', 'visible'); } catch (e) { } + } + + + var sidebarAnchorToggles = document.querySelectorAll('#sidebar a.toggle'); + + function toggleSection(ev) { + ev.currentTarget.parentElement.classList.toggle('expanded'); + } + + Array.from(sidebarAnchorToggles).forEach(function (el) { + el.addEventListener('click', toggleSection); + }); + + function hideSidebar() { + html.classList.remove('sidebar-visible') + html.classList.add('sidebar-hidden'); + Array.from(sidebarLinks).forEach(function (link) { + link.setAttribute('tabIndex', -1); + }); + sidebarToggleButton.setAttribute('aria-expanded', false); + sidebar.setAttribute('aria-hidden', true); + try { localStorage.setItem('mdbook-sidebar', 'hidden'); } catch (e) { } + } + + // Toggle sidebar + sidebarToggleButton.addEventListener('click', function sidebarToggle() { + if (html.classList.contains("sidebar-hidden")) { + var current_width = parseInt( + document.documentElement.style.getPropertyValue('--sidebar-width'), 10); + if (current_width < 150) { + document.documentElement.style.setProperty('--sidebar-width', '150px'); + } + showSidebar(); + } else if (html.classList.contains("sidebar-visible")) { + hideSidebar(); + } else { + if (getComputedStyle(sidebar)['transform'] === 'none') { + hideSidebar(); + } else { + showSidebar(); + } + } + }); + + sidebarResizeHandle.addEventListener('mousedown', initResize, false); + + function initResize(e) { + window.addEventListener('mousemove', resize, false); + window.addEventListener('mouseup', stopResize, false); + html.classList.add('sidebar-resizing'); + } + function resize(e) { + var pos = (e.clientX - sidebar.offsetLeft); + if (pos < 20) { + hideSidebar(); + } else { + if (html.classList.contains("sidebar-hidden")) { + showSidebar(); + } + pos = Math.min(pos, window.innerWidth - 100); + document.documentElement.style.setProperty('--sidebar-width', pos + 'px'); + } + } + //on mouseup remove windows functions mousemove & mouseup + function stopResize(e) { + html.classList.remove('sidebar-resizing'); + window.removeEventListener('mousemove', resize, false); + window.removeEventListener('mouseup', stopResize, false); + } + + document.addEventListener('touchstart', function (e) { + firstContact = { + x: e.touches[0].clientX, + time: Date.now() + }; + }, { passive: true }); + + document.addEventListener('touchmove', function (e) { + if (!firstContact) + return; + + var curX = e.touches[0].clientX; + var xDiff = curX - firstContact.x, + tDiff = Date.now() - firstContact.time; + + if (tDiff < 250 && Math.abs(xDiff) >= 150) { + if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300)) + showSidebar(); + else if (xDiff < 0 && curX < 300) + hideSidebar(); + + firstContact = null; + } + }, { passive: true }); + + // Scroll sidebar to current active section + var activeSection = document.getElementById("sidebar").querySelector(".active"); + if (activeSection) { + // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView + activeSection.scrollIntoView({ block: 'center' }); + } +})(); + +(function chapterNavigation() { + document.addEventListener('keydown', function (e) { + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; } + if (window.search && window.search.hasFocus()) { return; } + + switch (e.key) { + case 'ArrowRight': + e.preventDefault(); + var nextButton = document.querySelector('.nav-chapters.next'); + if (nextButton) { + window.location.href = nextButton.href; + } + break; + case 'ArrowLeft': + e.preventDefault(); + var previousButton = document.querySelector('.nav-chapters.previous'); + if (previousButton) { + window.location.href = previousButton.href; + } + break; + } + }); +})(); + +(function clipboard() { + var clipButtons = document.querySelectorAll('.clip-button'); + + function hideTooltip(elem) { + elem.firstChild.innerText = ""; + elem.className = 'fa fa-copy clip-button'; + } + + function showTooltip(elem, msg) { + elem.firstChild.innerText = msg; + elem.className = 'fa fa-copy tooltipped'; + } + + var clipboardSnippets = new ClipboardJS('.clip-button', { + text: function (trigger) { + hideTooltip(trigger); + let playground = trigger.closest("pre"); + return playground_text(playground); + } + }); + + Array.from(clipButtons).forEach(function (clipButton) { + clipButton.addEventListener('mouseout', function (e) { + hideTooltip(e.currentTarget); + }); + }); + + clipboardSnippets.on('success', function (e) { + e.clearSelection(); + showTooltip(e.trigger, "Copied!"); + }); + + clipboardSnippets.on('error', function (e) { + showTooltip(e.trigger, "Clipboard error!"); + }); +})(); + +(function scrollToTop () { + var menuTitle = document.querySelector('.menu-title'); + + menuTitle.addEventListener('click', function () { + document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' }); + }); +})(); + +(function controllMenu() { + var menu = document.getElementById('menu-bar'); + + (function controllPosition() { + var scrollTop = document.scrollingElement.scrollTop; + var prevScrollTop = scrollTop; + var minMenuY = -menu.clientHeight - 50; + // When the script loads, the page can be at any scroll (e.g. if you reforesh it). + menu.style.top = scrollTop + 'px'; + // Same as parseInt(menu.style.top.slice(0, -2), but faster + var topCache = menu.style.top.slice(0, -2); + menu.classList.remove('sticky'); + var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster + document.addEventListener('scroll', function () { + scrollTop = Math.max(document.scrollingElement.scrollTop, 0); + // `null` means that it doesn't need to be updated + var nextSticky = null; + var nextTop = null; + var scrollDown = scrollTop > prevScrollTop; + var menuPosAbsoluteY = topCache - scrollTop; + if (scrollDown) { + nextSticky = false; + if (menuPosAbsoluteY > 0) { + nextTop = prevScrollTop; + } + } else { + if (menuPosAbsoluteY > 0) { + nextSticky = true; + } else if (menuPosAbsoluteY < minMenuY) { + nextTop = prevScrollTop + minMenuY; + } + } + if (nextSticky === true && stickyCache === false) { + menu.classList.add('sticky'); + stickyCache = true; + } else if (nextSticky === false && stickyCache === true) { + menu.classList.remove('sticky'); + stickyCache = false; + } + if (nextTop !== null) { + menu.style.top = nextTop + 'px'; + topCache = nextTop; + } + prevScrollTop = scrollTop; + }, { passive: true }); + })(); + (function controllBorder() { + menu.classList.remove('bordered'); + document.addEventListener('scroll', function () { + if (menu.offsetTop === 0) { + menu.classList.remove('bordered'); + } else { + menu.classList.add('bordered'); + } + }, { passive: true }); + })(); +})(); diff --git a/ch00-00-where-to-start.html b/ch00-00-where-to-start.html new file mode 100644 index 00000000..b5ef8daf --- /dev/null +++ b/ch00-00-where-to-start.html @@ -0,0 +1,243 @@ + + + + + + Where to start - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Calloop's Documentation

+

API

+

If you're looking for calloop's API documentation, they are available on docs.rs for the released versions. There are also the docs of the current development version.

+

Tutorial

+

This book presents a step-by-step tutorial to get yourself familiar with calloop and how it is used:

+
    +
  • Chapter 1 presents the general principles of an event loop that are important to have in mind when working with calloop.
  • +
  • Chapter 2 goes through the different kind of event sources that are provided in calloop, and provides examples of how to use them
  • +
  • Chapter 3 presents the integration with Rust's Async/Await ecosystem provided by calloop
  • +
  • Chapter 4 gives a detailed example of building a custom event source in calloop, by combining other sources
  • +
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch01-00-how-an-event-loop-works.html b/ch01-00-how-an-event-loop-works.html new file mode 100644 index 00000000..e7f43185 --- /dev/null +++ b/ch01-00-how-an-event-loop-works.html @@ -0,0 +1,280 @@ + + + + + + How an event loop works - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

How an event loop works

+

An event loop is one way to write concurrent code. Other ways include threading (sort of), or asynchronous syntax.

+

When you write concurrent code, you need to know two things:

+
    +
  • where in your program it could potentially block, and
  • +
  • how to let other parts of your program run while waiting for those operations to stop blocking
  • +
+

This chapter covers what the first thing means, and how Calloop accomplishes the second thing.

+

Terminology

+

A blocking operation is one that waits for an event to happen, and doesn't do anything else while it's waiting. For example, if you try to read from a network socket, and there is no data available, the read operation could wait for some indefinite amount of time. Your program will be in a state where it does not need to use any CPU cycles, or indeed do anything at all, and it won't proceed until there is data to read.

+

Examples of blocking operations are:

+
    +
  • waiting for a certain time to elapse
  • +
  • reading or writing to a file
  • +
  • reading or writing to a network socket
  • +
  • waiting for a thread to finish
  • +
+

When any of these operations are ready to go, we call it an event. We call the underlying things (files, network sockets, timers, etc.) sources for events. So, for example, you can create an event source that corresponds to a file, and it will generate events when it is ready for reading, or writing, or encounters an error.

+

Events and callbacks

+

An event loop like Calloop, as the name suggests, runs in a loop. At the start of the loop, Calloop checks all the sources you've added to see if any events have happened for those sources. If they have, Calloop will call a function that you provide (known as a callback).

+

This function will (possibly) be given some data for the event itself (eg. the bytes received), some state for the event source (eg. the socket, or a type that wraps it in a neater API), and some state for the whole program.

+

Calloop will do this one by one for each source that has a new event. If a file is ready for reading, your file-event-source callback will be called. If a timer has elapsed, your timer-event-source callback will be called.

+

It is up to you to write the code to do things when events happen. For example, your callback might read data from a file "ready for reading" event into a queue. When the queue contains a valid message, the same callback could send that message over an internal channel to another event source. That second event source could have its own callback that processes entire messages and updates the program's state. And so on.

+

Concurrency vs parallelism

+

This "one by one" nature of event loops is important. When you approach concurrency using threads, operations in any thread can be interleaved with operations in any other thread. This is typically made robust by either passing messages or using shared memory with synchronisation.

+

Callbacks in an event loop do not run in parallel, they run one after the other. Unless you (or your dependencies) have introduced threading, you can (and should) write your callbacks as single-threaded code.

+

Event loops vs async code

+

This single-threaded nature makes event loops much more similar to code that uses async/await than to multithreaded code. There are benefits and tradeoffs to either approach.

+

Calloop will take care of a lot of integration and error handling boilerplate for you. It also makes it clearer what parts of your code are the non-blocking actions to perform as a result of events. If you like to think of your program in terms of taking action in reaction to events, this can be a great advantage!

+

However, this comes at the expense of needing to make your program's state much more explicit. For example, take this async code:

+
do_thing_one().await;
+do_thing_two().await;
+do_thing_three().await;
+
+

The state of the program is simply given by: what line is it up to? You know if it's done "thing one" because execution has proceeded to line two. No other state is required. In Calloop, however, you will need extra variables and code so that when your callback is called, it knows whether to run do_thing_one(), do_thing_two(), or do_thing_three().

+

Never block the loop!

+

All of this leads us to the most important rule of event loop code: never block the loop! This means: never use blocking calls inside one of your event callbacks. Do not use synchronous file write() calls in a callback. Do not sleep() in a callback. Do not join() a thread in a callback. Don't you do it!

+

If you do, the event loop will have no way to proceed, and just... wait for your blocking operation to complete. Nothing is going to run in a parallel thread. Nothing is going to stop your callback and move on to the next one. If your callback needs to wait for a blocking operation, your code must allow it to keep track of where it's up to, return from the callback, and wait for the event like any other.

+

Calloop and composition

+

Calloop is designed to work by composition. This means that you build up more complex logic in your program by combining simpler event sources into more complex ones. Want a network socket with custom backoff/timeout logic? Create a type containing a network socket using the Generic file descriptor adapter, a timer, and tie them together with your backoff logic and state. There is a much more detailed example of composition in our ZeroMQ example.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch02-00-event-sources.html b/ch02-00-event-sources.html new file mode 100644 index 00000000..3059de42 --- /dev/null +++ b/ch02-00-event-sources.html @@ -0,0 +1,242 @@ + + + + + + Using event sources - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Using event sources

+

Calloop's structure is entirely built around the EventSource trait, which represents something that is capable of generating events. To receive those events, you need to give ownership of the event source to calloop, along with a closure that will be invoked whenever said source generated an event. This is thus a push-based model, that is most suited for contexts where your program needs to react to (unpredictable) outside events, rather than wait efficiently for the completion of some operation it initiated.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch02-01-generic.html b/ch02-01-generic.html new file mode 100644 index 00000000..77563ea4 --- /dev/null +++ b/ch02-01-generic.html @@ -0,0 +1,256 @@ + + + + + + Monitoring a file descriptor - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Monitoring a file descriptor

+

The Generic event source wraps a file descriptor ("fd") and fires its callback any time there are events on it ie. becoming readable or writable, or encountering an error. It's pretty simple, but it's what every other event source is based around. And since the platforms that calloop runs on expose many different kinds of events via fds, it's usually the key to using those events in calloop.

+

For example on Linux, fd-based interfaces are available for GPIO, I2C, USB, UART, network interfaces, timers and many other systems. Integrating these into calloop starts with obtaining the appropriate fd, creating a Generic event source from it, and building up a more useful, abstracted event source around that. A detailed example of this is given for ZeroMQ.

+

You do not have to use a low-level fd either: any type that implements AsFd can be provided. This means that you can use a wrapper type that handles allocation and disposal itself, and implement AsRawFd on it so that Generic can manage it in the event loop.

+

Creating a Generic source

+

Creating a Generic event source requires three things:

+
    +
  • An OwnedFd or a wrapper type that implements AsFd
  • +
  • The "interest" you have in this descriptor — this means, whether you want to generate events when the fd becomes readable, writeable, or both
  • +
  • The "mode" of event generation - level triggered or edge triggered
  • +
+

The easiest constructor to use is the new() method, but if you need control over the associated error type there is also new_with_error().

+

Ownership and AsFd wrappers

+

Rust 1.63 introduced a concept of file descriptor ownership and borrowing through the OwnedFd and BorrowedFd types, which are also available on older Rust versions through the io-lifetimes crate. The AsFd trait provides a way to get a BorrowedFd corresponding to a file, socket, etc. while guaranteeing the fd will be valid for the lifetime of the BorrowedFd.

+

Not all third party crates use AsFd yet, and may instead provide types implementing AsRawFd. 'AsFdWrapper' provides a way to adapt these types. To use this safely, ensure the AsRawFd implementation of the type it wraps returns a valid fd as long as the type exists. And to avoid an fd leak, it should ultimately be closed properly.

+

Safe types like OwnedFd and BorrowedFd should be preferred over RawFds, and the use of RawFds outside of implementing FFI shouldn't be necessary as libraries move to using the IO safe types and traits.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch02-02-timers.html b/ch02-02-timers.html new file mode 100644 index 00000000..e291c779 --- /dev/null +++ b/ch02-02-timers.html @@ -0,0 +1,335 @@ + + + + + + Timers - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Working with timers

+

Timer event sources are used to manipulate time-related actions. Those are provided under the calloop::timer module, with the Timer type at its core.

+

A Timer source has a simple behavior: it is programmed to wait for some duration, or until a certain point in time. Once that deadline is reached, the source generates an event.

+

So with use calloop::timer::Timer at the top of our .rs file, we can create a timer that will wait for 5 seconds:

+
use std::time::Duration;
+
+use calloop::{
+    timer::{TimeoutAction, Timer},
+    EventLoop,
+};
+
+fn main() {
+    let mut event_loop = EventLoop::try_new().expect("Failed to initialize the event loop!");
+
+    let timer = Timer::from_duration(Duration::from_secs(5));
+
+    event_loop
+        .handle()
+        .insert_source(timer, |deadline, _: &mut (), _shared_data| {
+            println!("Event fired for: {:?}", deadline);
+            TimeoutAction::Drop
+        })
+        .expect("Failed to insert event source!");
+
+    event_loop
+        .dispatch(None, &mut ())
+        .expect("Error during event loop!");
+}
+
+

Adding sources to the loop

+

We have an event source, we have our shared data, and we know how to start our loop running. All that is left is to learn how to combine these things:

+
use std::time::Duration;
+
+use calloop::{
+    timer::{TimeoutAction, Timer},
+    EventLoop,
+};
+
+fn main() {
+    let mut event_loop = EventLoop::try_new().expect("Failed to initialize the event loop!");
+
+    let timer = Timer::from_duration(Duration::from_secs(5));
+
+    event_loop
+        .handle()
+        .insert_source(timer, |deadline, _: &mut (), _shared_data| {
+            println!("Event fired for: {:?}", deadline);
+            TimeoutAction::Drop
+        })
+        .expect("Failed to insert event source!");
+
+    event_loop
+        .dispatch(None, &mut ())
+        .expect("Error during event loop!");
+}
+
+

Breaking this down, the callback we provide receives 3 arguments:

+
    +
  • The first one is an Instant representing the time at which this timer was scheduled to expire. Due to how the event loop works, it might be that your callback is not invoked at the exact time where the timer expired (if an other callback was being processed at the time for example), so the original deadline is given if you need precise time tracking.
  • +
  • The second argument is just &mut (), as the timers don't use the EventSource functionality.
  • +
  • The third argumument is the shared data passed to your event loop.
  • +
+

In addition your callback is expected to return a TimeoutAction, that will instruct calloop what to do next. This enum has 3 values:

+
    +
  • Drop will disable the timer and destroy it, freeing the callback.
  • +
  • ToInstant will rechedule the callback to fire again at given Instant, invoking the same callback again. This is useful if you need to create a timer that fires events at regular intervals, for example to encode key repetition in a graphical app. You would compute the next instant by adding the duration to the previous instant. It is not a problem if that duration is in the past, it'll simply cause the timer to fire again instantly. THis way, even if some other part of your app lags, you'll still have on average the correct amount of events per second.
  • +
  • ToDuration will reschedule the callback to fire again after a given Duration. This is useful if you need to schedule some background task to execute again after some time after it was last completed, when there is no point in catching up some previous lag.
  • +
+

The whole program

+

Putting it all together, we have:

+
use std::time::Duration;
+
+use calloop::{
+    timer::{TimeoutAction, Timer},
+    EventLoop,
+};
+
+fn main() {
+    let mut event_loop = EventLoop::try_new().expect("Failed to initialize the event loop!");
+
+    let timer = Timer::from_duration(Duration::from_secs(5));
+
+    event_loop
+        .handle()
+        .insert_source(timer, |deadline, _: &mut (), _shared_data| {
+            println!("Event fired for: {:?}", deadline);
+            TimeoutAction::Drop
+        })
+        .expect("Failed to insert event source!");
+
+    event_loop
+        .dispatch(None, &mut ())
+        .expect("Error during event loop!");
+}
+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch02-03-ping.html b/ch02-03-ping.html new file mode 100644 index 00000000..7dc9432f --- /dev/null +++ b/ch02-03-ping.html @@ -0,0 +1,248 @@ + + + + + + Ping - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

"Pinging" the event loop

+

The Ping event source has one very simple job — wake up the event loop. Use this when you know there are events for your event source to process, but those events aren't going to wake the event loop up themselves.

+

For example, calloop's own message channel uses Rust's native MPSC channel internally. Because there's no way for the internal message queue to wake up the event loop, it's coupled with a Ping source that wakes the loop up when there are new messages.

+

How to use the Ping source

+

The Ping has two ends — the event source part (PingSource), that goes in the event loop, and the sending end (Ping) you use to "send" the ping. To wake the event loop up, call ping() on the sending end.

+
+

Do not forget to process the events of the PingSource if you are using it as part of a larger event source! Even though the events carry no information (they are just () values), the process_events() method must be called in order to "reset" the PingSource. Otherwise the event loop will be continually woken up until you do, effectively becoming a busy-loop.

+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch02-04-channels.html b/ch02-04-channels.html new file mode 100644 index 00000000..02252716 --- /dev/null +++ b/ch02-04-channels.html @@ -0,0 +1,241 @@ + + + + + + Channels - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Channels

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch02-05-signals.html b/ch02-05-signals.html new file mode 100644 index 00000000..cd52684d --- /dev/null +++ b/ch02-05-signals.html @@ -0,0 +1,241 @@ + + + + + + Unix Signals - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Unix Signals

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch02-06-errors.html b/ch02-06-errors.html new file mode 100644 index 00000000..1ae483eb --- /dev/null +++ b/ch02-06-errors.html @@ -0,0 +1,267 @@ + + + + + + Error handling - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Error handling in Calloop

+

Overview

+

Most error handling crates/guides/documentation for Rust focus on one of two situations:

+
    +
  • Creating errors that an API can propagate out to a user of the API, or
  • +
  • Making your library deal nicely with the Results from closure or trait methods that it might call
  • +
+

Calloop has to do both of these things. It needs to provide a library user with errors that work well with ? and common error-handling idioms in their own code, and it needs to handle errors from the callbacks you give to process_events() or insert_source(). It also needs to provide some flexibility in the EventSource trait, which is used both for internal event sources and by users of the library.

+

Because of this, error handling in Calloop leans more towards having separate error types for different concerns. This may mean that there is some extra conversion code in places like returning results from process_events(), or in callbacks that use other libraries. However, we try to make it smoother to do these conversions, and to make sure information isn't lost in doing so.

+

If your crate already has some form of structured error handling, Calloop's error types should pose no problem to integrate into this. All of Calloop's errors implement std::error::Error and can be manipulated the same as any other error types.

+

The place where this becomes the most complex is in the process_events() method on the EventSource trait.

+

The Error type on the EventSource trait

+

The EventSource trait contains an associated type named Error, which forms part of the return type from process_events(). This type must be convertible into Box<dyn std::error::Error + Sync + Send>, which means you can use:

+
    +
  • Your own error type that implements std::error::Error
  • +
  • A structured error type created with Thiserror
  • +
  • Box<dyn std::error::Error + Sync + Send>
  • +
  • A flexible string-based error type such as Anyhow's anyhow::Error
  • +
+

As a rule, if you implement EventSource you should try to split your errors into two different categories:

+
    +
  • Errors that make sense as a kind of event. These should be a part of the Event associated type eg. as an enum or Result.
  • +
  • Errors that mean your event source simply cannot process more events. These should form the Error associated type.
  • +
+

For an example, take Calloop's channel type, calloop::channel::Channel. When the sending end is dropped, no more messages can be received after that point. But this is not returned as an error when calling process_events(), because you still want to (and can!) receive messages sent before that point that might still be in the queue. Hence the events received by the callback for this source can be Msg(e) or Closed.

+

However, if the internal ping source produces an error, there is no way for the sending end of the channel to notify the receiver. It is impossible to process more events on this event source, and the caller needs to decide how to recover from this situation. Hence this is returned as a ChannelError from process_events().

+

Another example might be an event source that represents a running subprocess. If the subprocess exits with a non-zero status code, or the executable can't be found, those don't mean that events can no longer be processed. They can be provided to the caller through the callback. But if the lower level sources being used to run (eg. an asynchronous executor or subprocess file descriptor) fail to work as expected, process_events() should return an error.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch03-00-async-await.html b/ch03-00-async-await.html new file mode 100644 index 00000000..1b425a11 --- /dev/null +++ b/ch03-00-async-await.html @@ -0,0 +1,242 @@ + + + + + + I need async/await! - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Async/await in calloop

+

While it is centered on event sources and callbacks, calloop also provides adapters to integrate with Rust's async ecosystem. These adapters come in two parts: a futures executor and an async adapter for IO type.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch03-01-run-async-code.html b/ch03-01-run-async-code.html new file mode 100644 index 00000000..8f4ba0de --- /dev/null +++ b/ch03-01-run-async-code.html @@ -0,0 +1,521 @@ + + + + + + Run async code - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Run async code

+
+

Enable the executor feature!

+

To use calloop::futures you need to enable the executor feature in your Cargo.toml like so:

+
[dependencies.calloop]
+features = [ "executor" ]
+version = ...
+
+
+

Let's say you have some async code that looks like this:

+
sender.send("Hello,").await.ok();
+receiver.next().await.map(|m| println!("Received: {}", m));
+sender.send("world!").await.ok();
+receiver.next().await.map(|m| println!("Received: {}", m));
+"So long!"
+
+

...and a corresponding block that receives and sends to this one. I will call one of these blocks "friendly" and the other one "aloof".

+

To run async code in Calloop, you use the components in calloop::futures. First, obtain both an executor and a scheduler with calloop::futures::executor():

+
use calloop::EventLoop;
+
+// futures = "0.3"
+use futures::sink::SinkExt;
+use futures::stream::StreamExt;
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    // Let's create two channels for our async blocks below. The blocks will
+    // exchange messages via these channels.
+    let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded();
+    let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded();
+
+    // Our toy async code.
+    let async_friendly_task = async move {
+        sender_friendly.send("Hello,").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        sender_friendly.send("world!").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        "Bye!"
+    };
+
+    let async_aloof_task = async move {
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("Oh,").await.ok();
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("it's you.").await.ok();
+        "Regards."
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_friendly_task).unwrap();
+    sched.schedule(async_aloof_task).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut (), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

The executor, the part that executes the future, goes in the event loop:

+
use calloop::EventLoop;
+
+// futures = "0.3"
+use futures::sink::SinkExt;
+use futures::stream::StreamExt;
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    // Let's create two channels for our async blocks below. The blocks will
+    // exchange messages via these channels.
+    let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded();
+    let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded();
+
+    // Our toy async code.
+    let async_friendly_task = async move {
+        sender_friendly.send("Hello,").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        sender_friendly.send("world!").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        "Bye!"
+    };
+
+    let async_aloof_task = async move {
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("Oh,").await.ok();
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("it's you.").await.ok();
+        "Regards."
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_friendly_task).unwrap();
+    sched.schedule(async_aloof_task).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut (), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

Now let's write our async code in full:

+
use calloop::EventLoop;
+
+// futures = "0.3"
+use futures::sink::SinkExt;
+use futures::stream::StreamExt;
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    // Let's create two channels for our async blocks below. The blocks will
+    // exchange messages via these channels.
+    let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded();
+    let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded();
+
+    // Our toy async code.
+    let async_friendly_task = async move {
+        sender_friendly.send("Hello,").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        sender_friendly.send("world!").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        "Bye!"
+    };
+
+    let async_aloof_task = async move {
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("Oh,").await.ok();
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("it's you.").await.ok();
+        "Regards."
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_friendly_task).unwrap();
+    sched.schedule(async_aloof_task).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut (), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

Like any block in Rust, the value of your async block is the last expression ie. it is effectively "returned" from the block, which means it will be provided to your executor's callback as the first argument (the "event"). You'll see this in the output with the Async block ended with: ... lines.

+

Finally, we run the loop:

+
use calloop::EventLoop;
+
+// futures = "0.3"
+use futures::sink::SinkExt;
+use futures::stream::StreamExt;
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    // Let's create two channels for our async blocks below. The blocks will
+    // exchange messages via these channels.
+    let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded();
+    let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded();
+
+    // Our toy async code.
+    let async_friendly_task = async move {
+        sender_friendly.send("Hello,").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        sender_friendly.send("world!").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        "Bye!"
+    };
+
+    let async_aloof_task = async move {
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("Oh,").await.ok();
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("it's you.").await.ok();
+        "Regards."
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_friendly_task).unwrap();
+    sched.schedule(async_aloof_task).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut (), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

And our output looks like:

+
Starting event loop.
+Friendly said: Hello,
+Aloof said: Oh,
+Friendly said: world!
+Async block ended with: Regards.
+Aloof said: it's you.
+Async block ended with: Bye!
+Event loop ended.
+
+

Note that for the sake of keeping this example short, I've written the async code before running the loop. But async code can be scheduled from callbacks, or other sources within the loop too.

+
+

Note about threads

+

One of Calloop's strengths is that it is completely single threaded as written. However, many async crates are implemented using threads eg. async-std and async-process. This is not an inherent problem! Calloop will work perfectly well with such implementations in general. However, if you have selected Calloop because of your own constraints around threading, be aware of this.

+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch03-02-async-io-types.html b/ch03-02-async-io-types.html new file mode 100644 index 00000000..ace23be0 --- /dev/null +++ b/ch03-02-async-io-types.html @@ -0,0 +1,603 @@ + + + + + + Async IO types - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Async IO types

+
+

This section is about adapting blocking IO types for use with async Rust code, and powering that async code with Calloop. If you just want to add blocking IO types to your event loop and use Calloop's callback/composition-based design, you only need to wrap your blocking IO type in a generic event source.

+
+

You may find that you need to write ordinary Rust async code around blocking IO types. Calloop provides the ability to wrap blocking types — anything that implements the AsFd trait — in its own async type. This can be polled in any executor you may have chosen for your async code, but if you're using Calloop you'll probably be using Calloop's executor.

+
+

Enable the futures-io feature!

+

To use calloop::io you need to enable the futures-io feature in your Cargo.toml like so:

+
[dependencies.calloop]
+features = [ "futures-io" ]
+version = ...
+
+

Realistically you will probably also want to use this with async code, so you should also enable the executor feature too.

+
+

Just like in the async example, we will use the components in calloop::futures. First, obtain both an executor and a scheduler with calloop::futures::executor():

+
use calloop::EventLoop;
+
+use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();
+    let mut sender = handle.adapt_io(sender).unwrap();
+    let mut receiver = handle.adapt_io(receiver).unwrap();
+
+    let async_receive = async move {
+        let mut buf = [0u8; 12];
+        // Here's our async-ified Unix domain socket.
+        receiver.read_exact(&mut buf).await.unwrap();
+        std::str::from_utf8(&buf).unwrap().to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_receive).unwrap();
+
+    let async_send = async move {
+        // Here's our async-ified Unix domain socket.
+        sender.write_all(b"Hello, world!").await.unwrap();
+        "Sent data...".to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_send).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

The executor goes in the event loop:

+
use calloop::EventLoop;
+
+use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();
+    let mut sender = handle.adapt_io(sender).unwrap();
+    let mut receiver = handle.adapt_io(receiver).unwrap();
+
+    let async_receive = async move {
+        let mut buf = [0u8; 12];
+        // Here's our async-ified Unix domain socket.
+        receiver.read_exact(&mut buf).await.unwrap();
+        std::str::from_utf8(&buf).unwrap().to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_receive).unwrap();
+
+    let async_send = async move {
+        // Here's our async-ified Unix domain socket.
+        sender.write_all(b"Hello, world!").await.unwrap();
+        "Sent data...".to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_send).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

For our blocking IO types, let's use an unnamed pair of Unix domain stream sockets. To convert them to async types, we simply call calloop::LoopHandle::adapt_io():

+
use calloop::EventLoop;
+
+use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();
+    let mut sender = handle.adapt_io(sender).unwrap();
+    let mut receiver = handle.adapt_io(receiver).unwrap();
+
+    let async_receive = async move {
+        let mut buf = [0u8; 12];
+        // Here's our async-ified Unix domain socket.
+        receiver.read_exact(&mut buf).await.unwrap();
+        std::str::from_utf8(&buf).unwrap().to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_receive).unwrap();
+
+    let async_send = async move {
+        // Here's our async-ified Unix domain socket.
+        sender.write_all(b"Hello, world!").await.unwrap();
+        "Sent data...".to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_send).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

Note that most of the useful async functionality for the returned type is expressed through various traits in futures::io. So we need to explicitly use these:

+
use calloop::EventLoop;
+
+use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();
+    let mut sender = handle.adapt_io(sender).unwrap();
+    let mut receiver = handle.adapt_io(receiver).unwrap();
+
+    let async_receive = async move {
+        let mut buf = [0u8; 12];
+        // Here's our async-ified Unix domain socket.
+        receiver.read_exact(&mut buf).await.unwrap();
+        std::str::from_utf8(&buf).unwrap().to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_receive).unwrap();
+
+    let async_send = async move {
+        // Here's our async-ified Unix domain socket.
+        sender.write_all(b"Hello, world!").await.unwrap();
+        "Sent data...".to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_send).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

We can now write async code around these types. Here's the receiving code:

+
use calloop::EventLoop;
+
+use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();
+    let mut sender = handle.adapt_io(sender).unwrap();
+    let mut receiver = handle.adapt_io(receiver).unwrap();
+
+    let async_receive = async move {
+        let mut buf = [0u8; 12];
+        // Here's our async-ified Unix domain socket.
+        receiver.read_exact(&mut buf).await.unwrap();
+        std::str::from_utf8(&buf).unwrap().to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_receive).unwrap();
+
+    let async_send = async move {
+        // Here's our async-ified Unix domain socket.
+        sender.write_all(b"Hello, world!").await.unwrap();
+        "Sent data...".to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_send).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

And here's the sending code. The receiving and sending code can be created and added to the executor in either order.

+
use calloop::EventLoop;
+
+use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();
+    let mut sender = handle.adapt_io(sender).unwrap();
+    let mut receiver = handle.adapt_io(receiver).unwrap();
+
+    let async_receive = async move {
+        let mut buf = [0u8; 12];
+        // Here's our async-ified Unix domain socket.
+        receiver.read_exact(&mut buf).await.unwrap();
+        std::str::from_utf8(&buf).unwrap().to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_receive).unwrap();
+
+    let async_send = async move {
+        // Here's our async-ified Unix domain socket.
+        sender.write_all(b"Hello, world!").await.unwrap();
+        "Sent data...".to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_send).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

All that's left is to run the loop:

+
use calloop::EventLoop;
+
+use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();
+    let mut sender = handle.adapt_io(sender).unwrap();
+    let mut receiver = handle.adapt_io(receiver).unwrap();
+
+    let async_receive = async move {
+        let mut buf = [0u8; 12];
+        // Here's our async-ified Unix domain socket.
+        receiver.read_exact(&mut buf).await.unwrap();
+        std::str::from_utf8(&buf).unwrap().to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_receive).unwrap();
+
+    let async_send = async move {
+        // Here's our async-ified Unix domain socket.
+        sender.write_all(b"Hello, world!").await.unwrap();
+        "Sent data...".to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_send).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

And the output we get is:

+
Starting event loop. Use Ctrl-C to exit.
+Async block ended with: Sent data...
+Async block ended with: Hello, world
+^C
+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch04-00-a-full-example-zeromq.html b/ch04-00-a-full-example-zeromq.html new file mode 100644 index 00000000..5268df73 --- /dev/null +++ b/ch04-00-a-full-example-zeromq.html @@ -0,0 +1,256 @@ + + + + + + A full example: ZeroMQ - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

A full example: ZeroMQ

+

The previous chapter showed how to use callbacks, event data and shared data to control our program. However, more complex programs will require more complex shared data, and more complex interactions between events. Eventually this will run up against ownership issues and just the basic mental load of the poor programmer.

+

In this chapter we're going to build something more complex: an event source based on ZeroMQ sockets.

+

ZeroMQ is (very) basically a highly abstracted socket library. You can create ZeroMQ sockets over TCP, PGM, IPC, in-process and more, and generally not worry about the transport mechanics. It guarantees atomic message transfer, and handles queuing, retries, reconnection and balancing under the hood. It also lets you integrate it with event loops and reactors by exposing a file descriptor that you can wait on.

+

But we can't just wrap this file descriptor in Calloop's generic::Generic source and be done — there are a few subtleties we need to take care of for it to work right and be useful.

+
+

Disclaimer

+

It might be tempting, at the end of this chapter, to think that the code we've written is the definitive ZeroMQ wrapper, able to address any use case or higher level pattern you like. Certainly it will be a lot more suited to Calloop than using ZeroMQ sockets by themselves, but it is not the only way to use them with Calloop. Here are some things I have not addressed, for the sake of simplicity:

+
    +
  • We will not handle fairness — our code will totally monopolise the event loop if we receive many messages at once.
  • +
  • We do not consider back pressure beyond whatever built-in zsocket settings the caller might use.
  • +
  • We just drop pending messages in the zsocket's internal queue (in and out) on shutdown. In a real application, you might want to make more specific decisions about the timeout and linger periods before dropping the zsocket, depending on your application's requirements.
  • +
  • We don't deal with zsocket errors much. In fact, the overall error handling of event sources is usually highly specific to your application, so what we end up writing here is almost certainly not going to survive contact with your own code base. Here we just use ? everywhere, which will eventually cause the event loop to exit with an error.
  • +
+

So by all means, take the code we write here and use and adapt it, but please please note the caveats above and think carefully about your own program.

+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch04-01-composition.html b/ch04-01-composition.html new file mode 100644 index 00000000..6421b2bf --- /dev/null +++ b/ch04-01-composition.html @@ -0,0 +1,266 @@ + + + + + + Composition - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Composing event sources

+

Calloop is designed to work by composition. It provides you with some single-responsibility sources (timers, message channels, file descriptors), and you can combine these together, bit by bit, to make more complex event sources. These new sources can express more and more of your program's internal logic and the relationships between them, always in terms of events and how you process them.

+

You can greatly simplify even a highly complex program if you identify and expose the "real" events you care about and use composition to tidy the other events away in internal details of event sources.

+

So what do we need to compose?

+

The generic source

+

Most obviously, ZeroMQ exposes a file descriptor for us to use. (This is a common thing for event-related libraries to do, so if you're wondering how to integrate, say, I²C or GPIO on Linux with Calloop, that's your answer.)

+

Calloop can use file descriptors via the calloop::generic::Generic source. So that's one.

+

The MPSC channel source

+

Secondly, we might want to send messages on the socket. This means our event source needs to react when we send it a message. Calloop has a message channel for precisely this purpose: calloop::channel::Channel. That's another one.

+

The wakeup call

+

The third event source we need is a bit subtle, but since this isn't a mystery novel I can save you hours of debugging and spoil the ending now: we need a "ping" event source because ZeroMQ's FD is edge triggered.

+

ZeroMQ's file descriptor is not the FD of an actual file or socket — you do not actually read data from it. It exists as an interface, with three important details:

+
    +
  • +

    It is only ever readable. Even if the underlying socket can be written to, the FD that ZeroMQ gives you signals this by becoming readable. In fact, this FD will become readable under three circumstances: the ZeroMQ socket (henceforth called a "zsocket") is readable, writeable, or has an error. There is a separate function call, zmq::Socket::get_events() that will tell you which.

    +
  • +
  • +

    It is edge triggered. It will only ever change from not-readable to readable when the socket's state changes. So if a zsocket receives two messages, and you only read one, the file descriptor will not wake up the event loop again. Why not? Because it hasn't changed state! After you read one message, the zsocket still has events waiting. If it receives yet another message... it still has events waiting. No change in internal state = no external event.

    +
  • +
  • +

    This edge triggering also covers user actions. If a zsocket becomes writeable, and then you write to the zsocket, it might immediately (and atomically) change from writeable to readable. In this case you will not get another event on the FD.

    +
  • +
+

(The docs make this quite explicit, but there's a lot of docs to read so I'm spelling it out here.)

+

What this adds up to is this: when we create our zsocket, it might already be readable or writeable. So when we add it to our event loop, it won't fire any events. Our entire source will just sit there until we wake it up by sending a message (which we might never do if it's eg. a pull socket).

+

So the last event source we need is something that doesn't really convey any kind of message except "please wake up the event loop on the next iteration", and that is exactly what a calloop::ping::PingSource does. And that's three.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch04-02-creating-our-source-part-1-our-types.html b/ch04-02-creating-our-source-part-1-our-types.html new file mode 100644 index 00000000..91132d9f --- /dev/null +++ b/ch04-02-creating-our-source-part-1-our-types.html @@ -0,0 +1,316 @@ + + + + + + Creating our source, part I: our types - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Creating our source, part I: our types

+

In the last chapter we worked out a list of the event sources we need to compose into a new type:

+
    +
  1. calloop::generic::Generic
  2. +
  3. calloop::channel::Channel
  4. +
  5. calloop::ping::Ping
  6. +
+

So at a minimum, our type needs to contain these:

+
pub struct ZeroMQSource
+{
+    // Calloop components.
+    socket: calloop::generic::Generic<calloop::generic::FdWrapper<zmq::Socket>>,
+    mpsc_receiver: calloop::channel::Channel<?>,
+    wake_ping_receiver: calloop::ping::PingSource,
+}
+
+

Note that I've left the type for the channel as ? — we'll get to that a bit later.

+

What else do we need? If the PingSource is there to wake up the loop manually, we need to keep the other end of it. The ping is an internal detail — users of our type don't need to know it's there. We also need the zsocket itself, so we can actually detect and process events on it. That gives us:

+
pub struct ZeroMQSource
+{
+    // Calloop components.
+    socket: calloop::generic::Generic<calloop::generic::FdWrapper<zmq::Socket>>,
+    mpsc_receiver: calloop::channel::Channel<?>,
+    wake_ping_receiver: calloop::ping::PingSource,
+
+    /// Sending end of the ping source.
+    wake_ping_sender: calloop::ping::Ping,
+}
+
+

The message type

+

The most obvious candidate for the type of the message queue would be zmq::Message. But ZeroMQ sockets are capable of sending multipart messages, and this is even mandatory for eg. the PUB zsocket type, where the first part of the message is the topic.

+

Therefore it makes more sense to accept a sequence of messages to cover the most general case, and that sequence can have a length of one for single-part messages. But with one more tweak: we can accept a sequence of things that can be transformed into zmq::Message values. The exact type we'll use will be a generic type like so:

+
pub struct ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    mpsc_receiver: calloop::channel::Channel<T>,
+	// ...
+}
+
+
+

Enforcing single messages

+

Remember that it's not just Vec<T> and other sequence types that implement IntoIteratorOption<T> implements it too! There is also std::iter::Once<T>. So if a user of our API wants to enforce that all "multi"-part messages actually contain exactly one part, they can use this API with T being, say, std::iter::Once<zmq::Message> (or even just [zmq::Message; 1] in Rust 2021 edition).

+
+

Associated types

+

The EventSource trait has four associated types:

+
    +
  • +

    Event - when an event is generated that our caller cares about (ie. not some internal thing), this is the data we provide to their callback. This will be another sequence of messages, but because we're constructing it we can be more opinionated about the type and use the return type of zmq::Socket::recv_multipart() which is Vec<Vec<u8>>.

    +
  • +
  • +

    Metadata - this is a more persistent kind of data, perhaps the underlying file descriptor or socket, or maybe some stateful object that the callback can manipulate. It is passed by exclusive reference to the Metadata type. In our case we don't use this, so it's ().

    +
  • +
  • +

    Ret - this is the return type of the callback that's called on an event. Usually this will be a Result of some sort; in our case it's std::io::Result<()> just to signal whether some underlying operation failed or not.

    +
  • +
  • +

    Error - this is the error type returned by process_events() (not the user callback!). Having this as an associated type allows you to have more control over error propagation in nested event sources. We will use Anyhow, which is like a more fully-features Box<dyn Error>. It allows you to add context to any other error with a context() method.

    +
  • +
+

So together these are:

+
impl<T> calloop::EventSource for ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    type Event = Vec<Vec<u8>>;
+    type Metadata = ();
+    type Ret = io::Result<()>;
+    type Error = anyhow::Error;
+    // ...
+}
+
+
+

I have saved one surprise for later to emphasise some important principles, but for now, let's move on to defining some methods!

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch04-03-creating-our-source-part-2-setup-methods.html b/ch04-03-creating-our-source-part-2-setup-methods.html new file mode 100644 index 00000000..cccf4e65 --- /dev/null +++ b/ch04-03-creating-our-source-part-2-setup-methods.html @@ -0,0 +1,342 @@ + + + + + + Creating our source, part II: setup methods - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Creating our source, part II: setup methods

+

Now that we've figured out the types we need, we can get to work writing some methods. We'll need to implement the methods defined in the calloop::EventSource trait, and a constructor function to create the source.

+

Our constructor

+

Creating our source is fairly straightforward. We can let the caller set up the zsocket the way they need, and take ownership of it when it's initialised. Our caller needs not only the source itself, but the sending end of the MPSC channel so they can send messages, so we need to return that too.

+

A common pattern in Calloop's own constructor functions is to return a tuple containing (a) the source and (b) a type to use the source. So that's what we'll do:

+
// Converts a `zmq::Socket` into a `ZeroMQSource` plus the sending end of an
+// MPSC channel to enqueue outgoing messages.
+pub fn from_socket(socket: zmq::Socket) -> io::Result<(Self, calloop::channel::Sender<T>)> {
+    let (mpsc_sender, mpsc_receiver) = calloop::channel::channel();
+    let (wake_ping_sender, wake_ping_receiver) = calloop::ping::make_ping()?;
+
+    let fd = socket.get_fd()?;
+
+    let socket_source =
+        calloop::generic::Generic::from_fd(fd, calloop::Interest::READ, calloop::Mode::Edge);
+
+    Ok((
+        Self {
+            socket,
+            socket_source,
+            mpsc_receiver,
+            wake_ping_receiver,
+            wake_ping_sender,
+        },
+        mpsc_sender,
+    ))
+}
+
+

Trait methods: registering sources

+

Calloop's event sources have a kind of life cycle, starting with registration. When you add an event source to the event loop, under the hood the source will register itself with the loop. Under certain circumstances a source will need to re-register itself. And finally there is the unregister action when an event source is removed from the loop. These are expressed via the calloop::EventSource methods:

+
    +
  • fn register(&mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory) -> calloop::Result<()>
  • +
  • fn reregister(&mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory) -> calloop::Result<()>
  • +
  • fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()>
  • +
+

The first two methods take a token factory, which is a way for Calloop to keep track of why your source was woken up. When we get to actually processing events, you'll see how this works. But for now, all you need to do is recursively pass the token factory into whatever sources your own event source is composed of. This includes other composed sources, which will pass the token factory into their sources, and so on.

+

In practise this looks like:

+
fn register(
+    &mut self,
+    poll: &mut calloop::Poll,
+    token_factory: &mut calloop::TokenFactory
+) -> calloop::Result<()>
+{
+    self.socket_source.register(poll, token_factory)?;
+    self.mpsc_receiver.register(poll, token_factory)?;
+    self.wake_ping_receiver.register(poll, token_factory)?;
+    self.wake_ping_sender.ping();
+
+    Ok(())
+}
+
+fn reregister(
+    &mut self,
+    poll: &mut calloop::Poll,
+    token_factory: &mut calloop::TokenFactory
+) -> calloop::Result<()>
+{
+    self.socket_source.reregister(poll, token_factory)?;
+    self.mpsc_receiver.reregister(poll, token_factory)?;
+    self.wake_ping_receiver.reregister(poll, token_factory)?;
+
+    self.wake_ping_sender.ping();
+
+    Ok(())
+}
+
+
+fn unregister(&mut self, poll: &mut calloop::Poll)-> calloop::Result<()> {
+    self.socket_source.unregister(poll)?;
+    self.mpsc_receiver.unregister(poll)?;
+    self.wake_ping_receiver.unregister(poll)?;
+    Ok(())
+}
+
+
+

Note the self.wake_ping_sender.ping() call in the first two functions! This is how we manually prompt the event loop to wake up and run our source on the next iteration, to properly account for the zsocket's edge-triggering.

+
+

Our drop handler

+

ZeroMQ sockets have their own internal queues and state, and therefore need a bit of care when shutting down. Depending on zsocket type and settings, when the ZeroMQ context is dropped, it could block waiting for certain operations to complete. We can write a drop handler to avoid this, but again note that it's only one of many ways to handle zsocket shutdown.

+
impl<T> Drop for ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    fn drop(&mut self) {
+        // This is one way to stop socket code (especially PUSH sockets) hanging
+        // at the end of any blocking functions.
+        //
+        // - https://stackoverflow.com/a/38338578/188535
+        // - http://api.zeromq.org/4-0:zmq-ctx-term
+        self.socket.set_linger(0).ok();
+        self.socket.set_rcvtimeo(0).ok();
+        self.socket.set_sndtimeo(0).ok();
+
+        // Double result because (a) possible failure on call and (b) possible
+        // failure decoding.
+        if let Ok(Ok(last_endpoint)) = self.socket.get_last_endpoint() {
+            self.socket.disconnect(&last_endpoint).ok();
+        }
+    }
+}
+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch04-04-creating-our-source-part-3-processing-events-almost.html b/ch04-04-creating-our-source-part-3-processing-events-almost.html new file mode 100644 index 00000000..c781d88d --- /dev/null +++ b/ch04-04-creating-our-source-part-3-processing-events-almost.html @@ -0,0 +1,403 @@ + + + + + + Creating our source, part III: processing events (almost) - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Creating our source, part III: processing events (almost)

+

Finally, the real functionality we care about! Processing events! This is also a method in the calloop::EventSource trait:

+
fn process_events<F>(
+    &mut self,
+    readiness: calloop::Readiness,
+    token: calloop::Token,
+    mut callback: F,
+) -> Result<calloop::PostAction, Self::Error>
+where
+    F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+
+

What a mouthful! But when you break it down, it's not so complicated:

+
    +
  • +

    We take our own state, of course, as &mut self.

    +
  • +
  • +

    We take a Readiness value - this is mainly useful for "real" file descriptors, and tells you whether the event source was woken up for a read or write event. We ignore it though, because our internal sources are always only readable (remember that even if the zsocket is writeable, the FD it exposes is only ever readable).

    +
  • +
  • +

    We take a token. This gives us a way to process events that arise from our internal sources. In general, composed sources should not actually need to use this directly; sub-sources will check their own tokens against this and run if necessary.

    +
  • +
  • +

    We take a callback. We call this callback with any "real" events that our caller will care about; in our case, that means messages we receive on the zsocket. It is closely related to the EventSource trait's associated types. Note that the callback our caller supplies when adding our source to the loop actually takes an extra argument, which is some data that we won't know about in our source. Calloop's internals take care of combining our arguments here with this extra data.

    +
  • +
  • +

    Finally we return a PostAction, which tells the loop whether it needs to change the state of our event source, perhaps as a result of actions we took. For example, you might require that your source be removed from the loop (with PostAction::Remove) if it only has a certain thing to do. Ordinarily though, you'd return PostAction::Continue for your source to keep waiting for events.

    +
  • +
+

Note that these PostAction values correspond to various methods on the LoopHandle type (eg. PostAction::Disable does the same as LoopHandle::disable()). Whether you control your event source by returning a PostAction or using the LoopHandle methods depends on whether it makes more sense for these actions to be taken from within your event source or by something else in your code.

+

Implementing process_events() for a type that contains various Calloop sources composed together, like we have, is done recursively by calling our internal sources' process_events() method. The token that Calloop gives us is how each event source determines whether it was responsible for the wakeup and has events to process.

+

If we were woken up because of the ping source, then the ping source's process_events() will see that the token matches its own, and call the callback (possibly multiple times). If we were woken up because a message was sent through the MPSC channel, then the channel's process_events() will match on the token instead and call the callback for every message waiting. The zsocket is a little different, and we'll go over that in detail.

+

For error handling we're using Anyhow, hence the context() calls on each fallible operation. These just add a message to any error that might appear in a traceback.

+

So a first draft of our code might look like:

+
fn process_events<F>(
+    &mut self,
+    readiness: calloop::Readiness,
+    token: calloop::Token,
+    mut callback: F,
+) -> Result<calloop::PostAction, Self::Error>
+where
+    F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+{
+    // Runs if we were woken up on startup/registration.
+    self.wake_ping_receiver
+        .process_events(readiness, token, |_, _| {})
+        .context("Failed after registration")?;
+
+    // Runs if we received a message over the MPSC channel.
+    self.mpsc_receiver
+        .process_events(readiness, token, |evt, _| {
+            // 'evt' could be a message or a "sending end closed"
+            // notification. We don't care about the latter.
+            if let calloop::channel::Event::Msg(msg) = evt {
+                self.socket
+                    .send_multipart(msg, 0)
+                    .context("Failed to send message")?;
+            }
+        })?;
+
+	// Runs if the zsocket became read/write-able.
+    self.socket
+        .process_events(readiness, token, |_, _| {
+            let events =
+                self.socket
+                    .get_events()
+                    .context("Failed to read ZeroMQ events")?;
+        
+            if events.contains(zmq::POLLOUT) {
+                // Wait, what do we do here?
+            }
+
+            if events.contains(zmq::POLLIN) {
+                let messages =
+                    self.socket
+                        .recv_multipart(0)
+                        .context("Failed to receive message")?;
+
+                callback(messages, &mut ())
+                    .context("Error in event callback")?;
+            }
+        })?;
+
+    Ok(calloop::PostAction::Continue)
+}
+
+

We process the events from whichever source woke up our composed source, and if we woke up because the zsocket became readable, we call the callback with the message we received. Finally we return PostAction::Continue to remain in the event loop.

+

Don't worry about getting this to compile, it is a good start but it's wrong in a few ways.

+

Firstly, we've gone to all the trouble of using a ping to wake up the source, and then we just... drain its internal events and return. Which achieves nothing.

+

Secondly, we don't seem to know what to do when our zsocket becomes writeable (the actual zsocket, not the "interface" file descriptor).

+

Thirdly, we commit one of the worst sins you can commit in an event-loop-based system. Can you see it? It's this part:

+
self.mpsc_receiver
+    .process_events(readiness, token, |evt, _| {
+        if let calloop::channel::Event::Msg(msg) = evt {
+            self.socket
+                .file
+                .send_multipart(msg, 0)
+                .context("Failed to send message")?;
+        }
+    })?;
+
+

We block the event loop! In the middle of processing events from the MPSC channel, we call zmq::Socket::send_multipart() which could, under certain circumstances, block! We shouldn't do that.

+

Let's deal with this badness first then. We want to decouple "receiving messages over the MPSC channel" from "sending messages on the zsocket". There are different ways to do this, but they boil down to: buffer messages or drop messages (or maybe a combination of both). We'll use the first approach, with an internal FIFO queue. When we receive messages, we push them onto the back of the queue. When the zsocket is writeable, we pop messages from the front of the queue.

+

The standard library has collections::VecDeque<T> which provides efficient double-ended queuing, so let's use that. This is some extra internal state, so we need to add it to our type, which becomes:

+
pub struct ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    // Calloop components.
+    socket: calloop::generic::Generic<calloop::generic::FdWrapper<zmq::Socket>>,
+    mpsc_receiver: calloop::channel::Channel<T>,
+    wake_ping_receiver: calloop::ping::PingSource,
+
+    /// Sending end of the ping source.
+    wake_ping_sender: calloop::ping::Ping,
+
+    /// FIFO queue for the messages to be published.
+    outbox: std::collections::VecDeque<T>,
+}
+
+

Our MPSC receiving code becomes:

+
let outbox = &mut self.outbox;
+
+self.mpsc_receiver
+    .process_events(readiness, token, |evt, _| {
+        if let calloop::channel::Event::Msg(msg) = evt {
+            outbox.push_back(msg);
+        }
+    })?;
+
+

And our "zsocket is writeable" code becomes:

+
self.socket
+    .file
+    .process_events(readiness, token, |_, _| {
+        let events = self
+            .socket
+            .file
+            .get_events()
+            .context("Failed to read ZeroMQ events")?;
+    
+        if events.contains(zmq::POLLOUT) {
+            if let Some(parts) = self.outbox.pop_front() {
+                self.socket
+                    .file
+                    .send_multipart(parts, 0)
+                    .context("Failed to send message")?;
+            }
+       }
+
+        if events.contains(zmq::POLLIN) {
+            let messages =
+                self.socket
+                    .file
+                    .recv_multipart(0)
+                    .context("Failed to receive message")?;
+            callback(messages, &mut ())
+                .context("Error in event callback")?;
+        }
+    })?;
+
+
+

So we've not only solved problem #3, we've also figured out #2, which suggests we're on the right track. But we still have (at least) that first issue to sort out.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch04-05-creating-our-source-part-4-processing-events-really.html b/ch04-05-creating-our-source-part-4-processing-events-really.html new file mode 100644 index 00000000..ae74e760 --- /dev/null +++ b/ch04-05-creating-our-source-part-4-processing-events-really.html @@ -0,0 +1,374 @@ + + + + + + Creating our source, part IV: processing events (really) - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Creating our source, part IV: processing events (really)

+

We have three events that could wake up our event source: the ping, the channel, and the zsocket itself becoming ready to use. All three of these reasons potentially mean doing something on the zsocket: if the ping fired, we need to check for any pending events. If the channel received a message, we want to check if the zsocket is already readable and send it. If the zsocket becomes readable or writeable, we want to read from or write to it. In other words... We want to run it every time!

+

Also notice that in the zsocket process_events() call, we don't use any of the arguments, including the event itself. That file descriptor is merely a signalling mechanism! Sending and receiving messages is what will actually clear any pending events on it, and reset it to a state where it will wake the event loop later.

+
let events = self
+    .socket
+    .get_events()
+    .context("Failed to read ZeroMQ events")?;
+
+if events.contains(zmq::POLLOUT) {
+    if let Some(parts) = self.outbox.pop_front() {
+        self.socket
+            .send_multipart(parts, 0)
+            .context("Failed to send message")?;
+    }
+}
+
+if events.contains(zmq::POLLIN) {
+    let messages =
+        self.socket
+            .recv_multipart(0)
+            .context("Failed to receive message")?;
+    callback(messages, &mut ())
+        .context("Error in event callback")?;
+}
+
+

So the second draft of our process_events() function is now:

+
fn process_events<F>(
+    &mut self,
+    readiness: calloop::Readiness,
+    token: calloop::Token,
+    mut callback: F,
+) -> Result<calloop::PostAction, Self::Error>
+where
+    F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+{
+    // Runs if we were woken up on startup/registration.
+    self.wake_ping_receiver
+        .process_events(readiness, token, |_, _| {})?;
+
+    // Runs if we were woken up because a message was sent on the channel.
+    let outbox = &mut self.outbox;
+
+    self.mpsc_receiver
+        .process_events(readiness, token, |evt, _| {
+            if let calloop::channel::Event::Msg(msg) = evt {
+                outbox.push_back(msg);
+            }
+        })?;
+
+	// Always process any pending zsocket events.
+
+    let events = self
+        .socket
+        .get_events()
+        .context("Failed to read ZeroMQ events")?;
+
+    if events.contains(zmq::POLLOUT) {
+        if let Some(parts) = self.outbox.pop_front() {
+            self.socket
+                .send_multipart(parts, 0)
+                .context("Failed to send message")?;
+        }
+    }
+
+    if events.contains(zmq::POLLIN) {
+        let messages =
+            self.socket
+                .recv_multipart(0)
+                .context("Failed to receive message")?;
+        callback(messages, &mut ())
+            .context("Error in event callback")?;
+    }
+
+    Ok(calloop::PostAction::Continue)
+}
+
+

There is one more issue to take care of, and it's got nothing to do with Calloop. We still haven't fully dealt with ZeroMQ's edge-triggered nature.

+

Consider this situation:

+
    +
  • We create a REQ zsocket. These are intended to be used in strict send/receive/send/receive/etc. sequence.
  • +
  • We wrap it in our ZeroMQSource and add that to our loop.
  • +
  • We send a message.
  • +
+

If we do this, it's possible we'll never actually receive any replies that are sent to our zsocket! Why? Because:

+
    +
  • we read the events on the socket into events
  • +
  • then we send a message on the socket
  • +
  • another process sends a reply so quickly, it arrives more or less immediately
  • +
  • then we use the same events to check if the socket is readable
  • +
  • then we exit
  • +
+

The zsocket will change from writeable to readable before we leave process_events(). So the "interface" file descriptor will become readable again. But because it is edge triggered, it will not wake up our event source after we leave process_events(). So our source will not wake up again (at least, not due to the self.socket event source).

+

For this specific example, it will suffice to re-read the zsocket events in between the if statements. Then when we get to the second events check, it will indeed contain zmq::POLLIN and receive the pending message. But this is not good enough for the general case! If we replace REQ with REP above, we'll get the opposite problem: our first check (for POLLOUT) will be false. Our second check (POLLIN) will be true. We'll receive a message, leave process_events(), and never wake up again.

+

The full solution is to recognise that any user action on a ZeroMQ socket can cause the pending events to change, or just to remain active, without re-triggering the "interface" file descriptor. So we need to (a) do this repeatedly and (b) keep track of when we have or haven't performed an action on the zsocket. Here's one way to do it:

+
loop {
+    let events = self
+        .socket
+        .get_events()
+        .context("Failed to read ZeroMQ events")?;
+
+    let mut used_socket = false;
+
+    if events.contains(zmq::POLLOUT) {
+        if let Some(parts) = self.outbox.pop_front() {
+            self.socket
+                .as_ref()
+                .send_multipart(parts, 0)
+                .context("Failed to send message")?;
+            used_socket = true;
+        }
+    }
+
+    if events.contains(zmq::POLLIN) {
+        let messages =
+            self.socket
+                .recv_multipart(0)
+                .context("Failed to receive message")?;
+        used_socket = true;
+
+        callback(messages, &mut ())
+            .context("Error in event callback")?;
+    }
+
+    if !used_socket {
+        break;
+    }
+}
+
+

Now we have a flag that we set if, and only if, we call a send or receive method on the zsocket. If that flag is set at the end of the loop, we go around again.

+
+

Greediness

+

Remember my disclaimer at the start of the chapter, about this code being "greedy"? This is what I mean. This loop will run until the entire message queue is empty, so if it has a lot of messages in it, any other sources in our event loop will not be run until this loop is finished.

+

An alternative approach is to use more state to determine whether we want to run again on the next loop iteration (perhaps using the ping source), so that Calloop can run any other sources in between individual messages being received.

+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ch04-06-the-full-zeromq-event-source-code.html b/ch04-06-the-full-zeromq-event-source-code.html new file mode 100644 index 00000000..29f66513 --- /dev/null +++ b/ch04-06-the-full-zeromq-event-source-code.html @@ -0,0 +1,508 @@ + + + + + + The full ZeroMQ event source code - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

The full ZeroMQ event source code

+

This is the full source code for a Calloop event source based on a ZeroMQ socket. You might find it useful as a kind of reference. Please read the disclaimer at the start of this chapter if you skipped straight here!

+
//! A Calloop event source implementation for ZeroMQ sockets.
+
+use std::{collections, io};
+
+use anyhow::Context;
+
+/// A Calloop event source that contains a ZeroMQ socket (of any kind) and a
+/// Calloop MPSC channel for sending over it.
+///
+/// The basic interface is:
+/// - create a zmq::Socket for your ZeroMQ socket
+/// - use `ZeroMQSource::from_socket()` to turn it into a Calloop event source
+///   (plus the sending end of the channel)
+/// - queue messages to be sent by sending them on the sending end of the MPSC
+///   channel
+/// - add the event source to the Calloop event loop with a callback to handle
+///   reading
+/// - the sending end of the MPSC channel can be cloned and sent across threads
+///   if necessary
+///
+/// This type is parameterised by `T`:
+///
+///     T where T: IntoIterator, T::Item: Into<zmq::Message>
+//
+/// This means that `T` is anything that can be converted to an iterator, and
+/// the items in the iterator are anything that can be converted to a
+/// `zmq::Message`. So eg. a `Vec<String>` would work.
+///
+/// The callback is called whenever the underlying socket becomes readable. It
+/// is called with a vec of byte sequences (`Vec<Vec<u8>>`) and the event loop
+/// data set by the user.
+///
+/// Note about why the read data is a vec of multipart message parts: we don't
+/// know what kind of socket this is, or what will be sent, so the most general
+/// thing we can do is receive the entirety of a multipart message and call the
+/// user callback with the whole set. Usually the number of parts in a multipart
+/// message will be one, but the code will work just the same when it's not.
+///
+/// This event source also allows you to use different event sources to publish
+/// messages over the same writeable ZeroMQ socket (usually PUB or PUSH).
+/// Messages should be sent over the Calloop MPSC channel sending end. This end
+/// can be cloned and used by multiple senders.
+
+pub struct ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    // Calloop components.
+    /// Event source for ZeroMQ socket.
+    socket: calloop::generic::Generic<calloop::generic::FdWrapper<zmq::Socket>>,
+
+    /// Event source for channel.
+    mpsc_receiver: calloop::channel::Channel<T>,
+
+    /// Because the ZeroMQ socket is edge triggered, we need a way to "wake" the
+    /// event source upon (re-)registration. We do this with a separate
+    /// `calloop::ping::Ping` source.
+    wake_ping_receiver: calloop::ping::PingSource,
+
+    /// Sending end of the ping source.
+    wake_ping_sender: calloop::ping::Ping,
+
+    // ZeroMQ socket.
+    /// FIFO queue for the messages to be published.
+    outbox: collections::VecDeque<T>,
+}
+
+impl<T> ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    // Converts a `zmq::Socket` into a `ZeroMQSource` plus the sending end of an
+    // MPSC channel to enqueue outgoing messages.
+    pub fn from_socket(socket: zmq::Socket) -> io::Result<(Self, calloop::channel::Sender<T>)> {
+        let (mpsc_sender, mpsc_receiver) = calloop::channel::channel();
+        let (wake_ping_sender, wake_ping_receiver) = calloop::ping::make_ping()?;
+
+        let socket = calloop::generic::Generic::new(
+            unsafe { calloop::generic::FdWrapper::new(socket) },
+            calloop::Interest::READ,
+            calloop::Mode::Edge,
+        );
+
+        Ok((
+            Self {
+                socket,
+                mpsc_receiver,
+                wake_ping_receiver,
+                wake_ping_sender,
+                outbox: collections::VecDeque::new(),
+            },
+            mpsc_sender,
+        ))
+    }
+}
+
+/// This event source runs for three events:
+///
+/// 1. The event source was registered. It is forced to run so that any pending
+///    events on the socket are processed.
+///
+/// 2. A message was sent over the MPSC channel. In this case we put it in the
+///    internal queue.
+///
+/// 3. The ZeroMQ socket is readable. For this, we read off a complete multipart
+///    message and call the user callback with it.
+///
+/// The callback provided to `process_events()` may be called multiple times
+/// within a single call to `process_events()`.
+impl<T> calloop::EventSource for ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    type Event = Vec<Vec<u8>>;
+    type Metadata = ();
+    type Ret = io::Result<()>;
+    type Error = anyhow::Error;
+
+    fn process_events<F>(
+        &mut self,
+        readiness: calloop::Readiness,
+        token: calloop::Token,
+        mut callback: F,
+    ) -> Result<calloop::PostAction, Self::Error>
+    where
+        F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+    {
+        // Runs if we were woken up on startup/registration.
+        self.wake_ping_receiver
+            .process_events(readiness, token, |_, _| {})
+            .context("Failed after registration")?;
+
+        // Runs if we were woken up because a message was sent on the channel.
+        let outbox = &mut self.outbox;
+
+        self.mpsc_receiver
+            .process_events(readiness, token, |evt, _| {
+                if let calloop::channel::Event::Msg(msg) = evt {
+                    outbox.push_back(msg);
+                }
+            })
+            .context("Failed to processing outgoing messages")?;
+
+        // The ZeroMQ file descriptor is edge triggered. This means that if (a)
+        // messages are added to the queue before registration, or (b) the
+        // socket became writeable before messages were enqueued, we will need
+        // to run the loop below. Hence, it always runs if this event source
+        // fires. The process_events() method doesn't do anything though, so we
+        // ignore it.
+
+        loop {
+            // According to the docs, the edge-triggered FD will not change
+            // state if a socket goes directly from being readable to being
+            // writeable (or vice-versa) without there being an in-between point
+            // where there are no events. This can happen as a result of sending
+            // or receiving on the socket while processing such an event. The
+            // "used_socket" flag below tracks whether we perform an operation
+            // on the socket that warrants reading the events again.
+            let events = self
+                .socket
+                .get_ref()
+                .get_events()
+                .context("Failed to read ZeroMQ events")?;
+
+            let mut used_socket = false;
+
+            if events.contains(zmq::POLLOUT) {
+                if let Some(parts) = self.outbox.pop_front() {
+                    self.socket
+                        .get_ref()
+                        .send_multipart(parts, 0)
+                        .context("Failed to send message")?;
+                    used_socket = true;
+                }
+            }
+
+            if events.contains(zmq::POLLIN) {
+                // Batch up multipart messages. ZeroMQ guarantees atomic message
+                // sending, which includes all parts of a multipart message.
+                let messages = self
+                    .socket
+                    .get_ref()
+                    .recv_multipart(0)
+                    .context("Failed to receive message")?;
+                used_socket = true;
+
+                // Capture and report errors from the callback, but don't propagate
+                // them up.
+                callback(messages, &mut ()).context("Error in event callback")?;
+            }
+
+            if !used_socket {
+                break;
+            }
+        }
+
+        Ok(calloop::PostAction::Continue)
+    }
+
+    fn register(
+        &mut self,
+        poll: &mut calloop::Poll,
+        token_factory: &mut calloop::TokenFactory,
+    ) -> calloop::Result<()> {
+        self.socket.register(poll, token_factory)?;
+        self.mpsc_receiver.register(poll, token_factory)?;
+        self.wake_ping_receiver.register(poll, token_factory)?;
+
+        self.wake_ping_sender.ping();
+
+        Ok(())
+    }
+
+    fn reregister(
+        &mut self,
+        poll: &mut calloop::Poll,
+        token_factory: &mut calloop::TokenFactory,
+    ) -> calloop::Result<()> {
+        self.socket.reregister(poll, token_factory)?;
+        self.mpsc_receiver.reregister(poll, token_factory)?;
+        self.wake_ping_receiver.reregister(poll, token_factory)?;
+
+        self.wake_ping_sender.ping();
+
+        Ok(())
+    }
+
+    fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> {
+        self.socket.unregister(poll)?;
+        self.mpsc_receiver.unregister(poll)?;
+        self.wake_ping_receiver.unregister(poll)?;
+        Ok(())
+    }
+}
+
+impl<T> Drop for ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    fn drop(&mut self) {
+        // This is one way to stop socket code (especially PUSH sockets) hanging
+        // at the end of any blocking functions.
+        //
+        // - https://stackoverflow.com/a/38338578/188535
+        // - http://api.zeromq.org/4-0:zmq-ctx-term
+        self.socket.get_ref().set_linger(0).ok();
+        self.socket.get_ref().set_rcvtimeo(0).ok();
+        self.socket.get_ref().set_sndtimeo(0).ok();
+
+        // Double result because (a) possible failure on call and (b) possible
+        // failure decoding.
+        if let Ok(Ok(last_endpoint)) = self.socket.get_ref().get_last_endpoint() {
+            self.socket.get_ref().disconnect(&last_endpoint).ok();
+        }
+    }
+}
+
+pub fn main() {}
+
+

Dependencies are:

+
    +
  • calloop (whatever version this document was built from)
  • +
  • zmq 0.9
  • +
  • anyhow 1.0
  • +
+
[dependencies]
+calloop = { path = '../..' }
+zmq = "0.9"
+anyhow = "1.0"
+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clipboard.min.js b/clipboard.min.js new file mode 100644 index 00000000..02c549e3 --- /dev/null +++ b/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.4 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function r(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}return r.m=n,r.c=o,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n .hljs { + color: var(--links); +} + +/* Menu Bar */ + +#menu-bar, +#menu-bar-hover-placeholder { + z-index: 101; + margin: auto calc(0px - var(--page-padding)); +} +#menu-bar { + position: relative; + display: flex; + flex-wrap: wrap; + background-color: var(--bg); + border-bottom-color: var(--bg); + border-bottom-width: 1px; + border-bottom-style: solid; +} +#menu-bar.sticky, +.js #menu-bar-hover-placeholder:hover + #menu-bar, +.js #menu-bar:hover, +.js.sidebar-visible #menu-bar { + position: -webkit-sticky; + position: sticky; + top: 0 !important; +} +#menu-bar-hover-placeholder { + position: sticky; + position: -webkit-sticky; + top: 0; + height: var(--menu-bar-height); +} +#menu-bar.bordered { + border-bottom-color: var(--table-border-color); +} +#menu-bar i, #menu-bar .icon-button { + position: relative; + padding: 0 8px; + z-index: 10; + line-height: var(--menu-bar-height); + cursor: pointer; + transition: color 0.5s; +} +@media only screen and (max-width: 420px) { + #menu-bar i, #menu-bar .icon-button { + padding: 0 5px; + } +} + +.icon-button { + border: none; + background: none; + padding: 0; + color: inherit; +} +.icon-button i { + margin: 0; +} + +.right-buttons { + margin: 0 15px; +} +.right-buttons a { + text-decoration: none; +} + +.left-buttons { + display: flex; + margin: 0 5px; +} +.no-js .left-buttons { + display: none; +} + +.menu-title { + display: inline-block; + font-weight: 200; + font-size: 2.4rem; + line-height: var(--menu-bar-height); + text-align: center; + margin: 0; + flex: 1; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.js .menu-title { + cursor: pointer; +} + +.menu-bar, +.menu-bar:visited, +.nav-chapters, +.nav-chapters:visited, +.mobile-nav-chapters, +.mobile-nav-chapters:visited, +.menu-bar .icon-button, +.menu-bar a i { + color: var(--icons); +} + +.menu-bar i:hover, +.menu-bar .icon-button:hover, +.nav-chapters:hover, +.mobile-nav-chapters i:hover { + color: var(--icons-hover); +} + +/* Nav Icons */ + +.nav-chapters { + font-size: 2.5em; + text-align: center; + text-decoration: none; + + position: fixed; + top: 0; + bottom: 0; + margin: 0; + max-width: 150px; + min-width: 90px; + + display: flex; + justify-content: center; + align-content: center; + flex-direction: column; + + transition: color 0.5s, background-color 0.5s; +} + +.nav-chapters:hover { + text-decoration: none; + background-color: var(--theme-hover); + transition: background-color 0.15s, color 0.15s; +} + +.nav-wrapper { + margin-top: 50px; + display: none; +} + +.mobile-nav-chapters { + font-size: 2.5em; + text-align: center; + text-decoration: none; + width: 90px; + border-radius: 5px; + background-color: var(--sidebar-bg); +} + +.previous { + float: left; +} + +.next { + float: right; + right: var(--page-padding); +} + +@media only screen and (max-width: 1080px) { + .nav-wide-wrapper { display: none; } + .nav-wrapper { display: block; } +} + +@media only screen and (max-width: 1380px) { + .sidebar-visible .nav-wide-wrapper { display: none; } + .sidebar-visible .nav-wrapper { display: block; } +} + +/* Inline code */ + +:not(pre) > .hljs { + display: inline; + padding: 0.1em 0.3em; + border-radius: 3px; +} + +:not(pre):not(a) > .hljs { + color: var(--inline-code-color); + overflow-x: initial; +} + +a:hover > .hljs { + text-decoration: underline; +} + +pre { + position: relative; +} +pre > .buttons { + position: absolute; + z-index: 100; + right: 5px; + top: 5px; + + color: var(--sidebar-fg); + cursor: pointer; +} +pre > .buttons :hover { + color: var(--sidebar-active); +} +pre > .buttons i { + margin-left: 8px; +} +pre > .buttons button { + color: inherit; + background: transparent; + border: none; + cursor: inherit; +} +pre > .result { + margin-top: 10px; +} + +/* Search */ + +#searchresults a { + text-decoration: none; +} + +mark { + border-radius: 2px; + padding: 0 3px 1px 3px; + margin: 0 -3px -1px -3px; + background-color: var(--search-mark-bg); + transition: background-color 300ms linear; + cursor: pointer; +} + +mark.fade-out { + background-color: rgba(0,0,0,0) !important; + cursor: auto; +} + +.searchbar-outer { + margin-left: auto; + margin-right: auto; + max-width: var(--content-max-width); +} + +#searchbar { + width: 100%; + margin: 5px auto 0px auto; + padding: 10px 16px; + transition: box-shadow 300ms ease-in-out; + border: 1px solid var(--searchbar-border-color); + border-radius: 3px; + background-color: var(--searchbar-bg); + color: var(--searchbar-fg); +} +#searchbar:focus, +#searchbar.active { + box-shadow: 0 0 3px var(--searchbar-shadow-color); +} + +.searchresults-header { + font-weight: bold; + font-size: 1em; + padding: 18px 0 0 5px; + color: var(--searchresults-header-fg); +} + +.searchresults-outer { + margin-left: auto; + margin-right: auto; + max-width: var(--content-max-width); + border-bottom: 1px dashed var(--searchresults-border-color); +} + +ul#searchresults { + list-style: none; + padding-left: 20px; +} +ul#searchresults li { + margin: 10px 0px; + padding: 2px; + border-radius: 2px; +} +ul#searchresults li.focus { + background-color: var(--searchresults-li-bg); +} +ul#searchresults span.teaser { + display: block; + clear: both; + margin: 5px 0 0 20px; + font-size: 0.8em; +} +ul#searchresults span.teaser em { + font-weight: bold; + font-style: normal; +} + +/* Sidebar */ + +.sidebar { + position: fixed; + left: 0; + top: 0; + bottom: 0; + width: var(--sidebar-width); + font-size: 0.875em; + box-sizing: border-box; + -webkit-overflow-scrolling: touch; + overscroll-behavior-y: contain; + background-color: var(--sidebar-bg); + color: var(--sidebar-fg); +} +.sidebar-resizing { + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} +.js:not(.sidebar-resizing) .sidebar { + transition: transform 0.3s; /* Animation: slide away */ +} +.sidebar code { + line-height: 2em; +} +.sidebar .sidebar-scrollbox { + overflow-y: auto; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + padding: 10px 10px; +} +.sidebar .sidebar-resize-handle { + position: absolute; + cursor: col-resize; + width: 0; + right: 0; + top: 0; + bottom: 0; +} +.js .sidebar .sidebar-resize-handle { + cursor: col-resize; + width: 5px; +} +.sidebar-hidden .sidebar { + transform: translateX(calc(0px - var(--sidebar-width))); +} +.sidebar::-webkit-scrollbar { + background: var(--sidebar-bg); +} +.sidebar::-webkit-scrollbar-thumb { + background: var(--scrollbar); +} + +.sidebar-visible .page-wrapper { + transform: translateX(var(--sidebar-width)); +} +@media only screen and (min-width: 620px) { + .sidebar-visible .page-wrapper { + transform: none; + margin-left: var(--sidebar-width); + } +} + +.chapter { + list-style: none outside none; + padding-left: 0; + line-height: 2.2em; +} + +.chapter ol { + width: 100%; +} + +.chapter li { + display: flex; + color: var(--sidebar-non-existant); +} +.chapter li a { + display: block; + padding: 0; + text-decoration: none; + color: var(--sidebar-fg); +} + +.chapter li a:hover { + color: var(--sidebar-active); +} + +.chapter li a.active { + color: var(--sidebar-active); +} + +.chapter li > a.toggle { + cursor: pointer; + display: block; + margin-left: auto; + padding: 0 10px; + user-select: none; + opacity: 0.68; +} + +.chapter li > a.toggle div { + transition: transform 0.5s; +} + +/* collapse the section */ +.chapter li:not(.expanded) + li > ol { + display: none; +} + +.chapter li.chapter-item { + line-height: 1.5em; + margin-top: 0.6em; +} + +.chapter li.expanded > a.toggle div { + transform: rotate(90deg); +} + +.spacer { + width: 100%; + height: 3px; + margin: 5px 0px; +} +.chapter .spacer { + background-color: var(--sidebar-spacer); +} + +@media (-moz-touch-enabled: 1), (pointer: coarse) { + .chapter li a { padding: 5px 0; } + .spacer { margin: 10px 0; } +} + +.section { + list-style: none outside none; + padding-left: 20px; + line-height: 1.9em; +} + +/* Theme Menu Popup */ + +.theme-popup { + position: absolute; + left: 10px; + top: var(--menu-bar-height); + z-index: 1000; + border-radius: 4px; + font-size: 0.7em; + color: var(--fg); + background: var(--theme-popup-bg); + border: 1px solid var(--theme-popup-border); + margin: 0; + padding: 0; + list-style: none; + display: none; +} +.theme-popup .default { + color: var(--icons); +} +.theme-popup .theme { + width: 100%; + border: 0; + margin: 0; + padding: 2px 10px; + line-height: 25px; + white-space: nowrap; + text-align: left; + cursor: pointer; + color: inherit; + background: inherit; + font-size: inherit; +} +.theme-popup .theme:hover { + background-color: var(--theme-hover); +} +.theme-popup .theme:hover:first-child, +.theme-popup .theme:hover:last-child { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} diff --git a/css/general.css b/css/general.css new file mode 100644 index 00000000..d437b51c --- /dev/null +++ b/css/general.css @@ -0,0 +1,177 @@ +/* Base styles and content styles */ + +@import 'variables.css'; + +:root { + /* Browser default font-size is 16px, this way 1 rem = 10px */ + font-size: 62.5%; +} + +html { + font-family: "Open Sans", sans-serif; + color: var(--fg); + background-color: var(--bg); + text-size-adjust: none; +} + +body { + margin: 0; + font-size: 1.6rem; + overflow-x: hidden; +} + +code { + font-family: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace !important; + font-size: 0.875em; /* please adjust the ace font size accordingly in editor.js */ +} + +/* Don't change font size in headers. */ +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + font-size: unset; +} + +.left { float: left; } +.right { float: right; } +.boring { opacity: 0.6; } +.hide-boring .boring { display: none; } +.hidden { display: none !important; } + +h2, h3 { margin-top: 2.5em; } +h4, h5 { margin-top: 2em; } + +.header + .header h3, +.header + .header h4, +.header + .header h5 { + margin-top: 1em; +} + +h1:target::before, +h2:target::before, +h3:target::before, +h4:target::before, +h5:target::before, +h6:target::before { + display: inline-block; + content: "»"; + margin-left: -30px; + width: 30px; +} + +/* This is broken on Safari as of version 14, but is fixed + in Safari Technology Preview 117 which I think will be Safari 14.2. + https://bugs.webkit.org/show_bug.cgi?id=218076 +*/ +:target { + scroll-margin-top: calc(var(--menu-bar-height) + 0.5em); +} + +.page { + outline: 0; + padding: 0 var(--page-padding); + margin-top: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */ +} +.page-wrapper { + box-sizing: border-box; +} +.js:not(.sidebar-resizing) .page-wrapper { + transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */ +} + +.content { + overflow-y: auto; + padding: 0 15px; + padding-bottom: 50px; +} +.content main { + margin-left: auto; + margin-right: auto; + max-width: var(--content-max-width); +} +.content p { line-height: 1.45em; } +.content ol { line-height: 1.45em; } +.content ul { line-height: 1.45em; } +.content a { text-decoration: none; } +.content a:hover { text-decoration: underline; } +.content img { max-width: 100%; } +.content .header:link, +.content .header:visited { + color: var(--fg); +} +.content .header:link, +.content .header:visited:hover { + text-decoration: none; +} + +table { + margin: 0 auto; + border-collapse: collapse; +} +table td { + padding: 3px 20px; + border: 1px var(--table-border-color) solid; +} +table thead { + background: var(--table-header-bg); +} +table thead td { + font-weight: 700; + border: none; +} +table thead th { + padding: 3px 20px; +} +table thead tr { + border: 1px var(--table-header-bg) solid; +} +/* Alternate background colors for rows */ +table tbody tr:nth-child(2n) { + background: var(--table-alternate-bg); +} + + +blockquote { + margin: 20px 0; + padding: 0 20px; + color: var(--fg); + background-color: var(--quote-bg); + border-top: .1em solid var(--quote-border); + border-bottom: .1em solid var(--quote-border); +} + + +:not(.footnote-definition) + .footnote-definition, +.footnote-definition + :not(.footnote-definition) { + margin-top: 2em; +} +.footnote-definition { + font-size: 0.9em; + margin: 0.5em 0; +} +.footnote-definition p { + display: inline; +} + +.tooltiptext { + position: absolute; + visibility: hidden; + color: #fff; + background-color: #333; + transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */ + left: -8px; /* Half of the width of the icon */ + top: -35px; + font-size: 0.8em; + text-align: center; + border-radius: 6px; + padding: 5px 8px; + margin: 5px; + z-index: 1000; +} +.tooltipped .tooltiptext { + visibility: visible; +} + +.chapter li.part-title { + color: var(--sidebar-fg); + margin: 5px 0px; + font-weight: bold; +} diff --git a/css/print.css b/css/print.css new file mode 100644 index 00000000..5e690f75 --- /dev/null +++ b/css/print.css @@ -0,0 +1,54 @@ + +#sidebar, +#menu-bar, +.nav-chapters, +.mobile-nav-chapters { + display: none; +} + +#page-wrapper.page-wrapper { + transform: none; + margin-left: 0px; + overflow-y: initial; +} + +#content { + max-width: none; + margin: 0; + padding: 0; +} + +.page { + overflow-y: initial; +} + +code { + background-color: #666666; + border-radius: 5px; + + /* Force background to be printed in Chrome */ + -webkit-print-color-adjust: exact; +} + +pre > .buttons { + z-index: 2; +} + +a, a:visited, a:active, a:hover { + color: #4183c4; + text-decoration: none; +} + +h1, h2, h3, h4, h5, h6 { + page-break-inside: avoid; + page-break-after: avoid; +} + +pre, code { + page-break-inside: avoid; + white-space: pre-wrap; +} + +.fa { + display: none !important; +} diff --git a/css/variables.css b/css/variables.css new file mode 100644 index 00000000..9ff64d6b --- /dev/null +++ b/css/variables.css @@ -0,0 +1,253 @@ + +/* Globals */ + +:root { + --sidebar-width: 300px; + --page-padding: 15px; + --content-max-width: 750px; + --menu-bar-height: 50px; +} + +/* Themes */ + +.ayu { + --bg: hsl(210, 25%, 8%); + --fg: #c5c5c5; + + --sidebar-bg: #14191f; + --sidebar-fg: #c8c9db; + --sidebar-non-existant: #5c6773; + --sidebar-active: #ffb454; + --sidebar-spacer: #2d334f; + + --scrollbar: var(--sidebar-fg); + + --icons: #737480; + --icons-hover: #b7b9cc; + + --links: #0096cf; + + --inline-code-color: #ffb454; + + --theme-popup-bg: #14191f; + --theme-popup-border: #5c6773; + --theme-hover: #191f26; + + --quote-bg: hsl(226, 15%, 17%); + --quote-border: hsl(226, 15%, 22%); + + --table-border-color: hsl(210, 25%, 13%); + --table-header-bg: hsl(210, 25%, 28%); + --table-alternate-bg: hsl(210, 25%, 11%); + + --searchbar-border-color: #848484; + --searchbar-bg: #424242; + --searchbar-fg: #fff; + --searchbar-shadow-color: #d4c89f; + --searchresults-header-fg: #666; + --searchresults-border-color: #888; + --searchresults-li-bg: #252932; + --search-mark-bg: #e3b171; +} + +.coal { + --bg: hsl(200, 7%, 8%); + --fg: #98a3ad; + + --sidebar-bg: #292c2f; + --sidebar-fg: #a1adb8; + --sidebar-non-existant: #505254; + --sidebar-active: #3473ad; + --sidebar-spacer: #393939; + + --scrollbar: var(--sidebar-fg); + + --icons: #43484d; + --icons-hover: #b3c0cc; + + --links: #2b79a2; + + --inline-code-color: #c5c8c6;; + + --theme-popup-bg: #141617; + --theme-popup-border: #43484d; + --theme-hover: #1f2124; + + --quote-bg: hsl(234, 21%, 18%); + --quote-border: hsl(234, 21%, 23%); + + --table-border-color: hsl(200, 7%, 13%); + --table-header-bg: hsl(200, 7%, 28%); + --table-alternate-bg: hsl(200, 7%, 11%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #b7b7b7; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #98a3ad; + --searchresults-li-bg: #2b2b2f; + --search-mark-bg: #355c7d; +} + +.light { + --bg: hsl(0, 0%, 100%); + --fg: hsl(0, 0%, 0%); + + --sidebar-bg: #fafafa; + --sidebar-fg: hsl(0, 0%, 0%); + --sidebar-non-existant: #aaaaaa; + --sidebar-active: #1f1fff; + --sidebar-spacer: #f4f4f4; + + --scrollbar: #8F8F8F; + + --icons: #747474; + --icons-hover: #000000; + + --links: #20609f; + + --inline-code-color: #301900; + + --theme-popup-bg: #fafafa; + --theme-popup-border: #cccccc; + --theme-hover: #e6e6e6; + + --quote-bg: hsl(197, 37%, 96%); + --quote-border: hsl(197, 37%, 91%); + + --table-border-color: hsl(0, 0%, 95%); + --table-header-bg: hsl(0, 0%, 80%); + --table-alternate-bg: hsl(0, 0%, 97%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #fafafa; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #888; + --searchresults-li-bg: #e4f2fe; + --search-mark-bg: #a2cff5; +} + +.navy { + --bg: hsl(226, 23%, 11%); + --fg: #bcbdd0; + + --sidebar-bg: #282d3f; + --sidebar-fg: #c8c9db; + --sidebar-non-existant: #505274; + --sidebar-active: #2b79a2; + --sidebar-spacer: #2d334f; + + --scrollbar: var(--sidebar-fg); + + --icons: #737480; + --icons-hover: #b7b9cc; + + --links: #2b79a2; + + --inline-code-color: #c5c8c6;; + + --theme-popup-bg: #161923; + --theme-popup-border: #737480; + --theme-hover: #282e40; + + --quote-bg: hsl(226, 15%, 17%); + --quote-border: hsl(226, 15%, 22%); + + --table-border-color: hsl(226, 23%, 16%); + --table-header-bg: hsl(226, 23%, 31%); + --table-alternate-bg: hsl(226, 23%, 14%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #aeaec6; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #5f5f71; + --searchresults-border-color: #5c5c68; + --searchresults-li-bg: #242430; + --search-mark-bg: #a2cff5; +} + +.rust { + --bg: hsl(60, 9%, 87%); + --fg: #262625; + + --sidebar-bg: #3b2e2a; + --sidebar-fg: #c8c9db; + --sidebar-non-existant: #505254; + --sidebar-active: #e69f67; + --sidebar-spacer: #45373a; + + --scrollbar: var(--sidebar-fg); + + --icons: #737480; + --icons-hover: #262625; + + --links: #2b79a2; + + --inline-code-color: #6e6b5e; + + --theme-popup-bg: #e1e1db; + --theme-popup-border: #b38f6b; + --theme-hover: #99908a; + + --quote-bg: hsl(60, 5%, 75%); + --quote-border: hsl(60, 5%, 70%); + + --table-border-color: hsl(60, 9%, 82%); + --table-header-bg: #b3a497; + --table-alternate-bg: hsl(60, 9%, 84%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #fafafa; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #888; + --searchresults-li-bg: #dec2a2; + --search-mark-bg: #e69f67; +} + +@media (prefers-color-scheme: dark) { + .light.no-js { + --bg: hsl(200, 7%, 8%); + --fg: #98a3ad; + + --sidebar-bg: #292c2f; + --sidebar-fg: #a1adb8; + --sidebar-non-existant: #505254; + --sidebar-active: #3473ad; + --sidebar-spacer: #393939; + + --scrollbar: var(--sidebar-fg); + + --icons: #43484d; + --icons-hover: #b3c0cc; + + --links: #2b79a2; + + --inline-code-color: #c5c8c6;; + + --theme-popup-bg: #141617; + --theme-popup-border: #43484d; + --theme-hover: #1f2124; + + --quote-bg: hsl(234, 21%, 18%); + --quote-border: hsl(234, 21%, 23%); + + --table-border-color: hsl(200, 7%, 13%); + --table-header-bg: hsl(200, 7%, 28%); + --table-alternate-bg: hsl(200, 7%, 11%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #b7b7b7; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #98a3ad; + --searchresults-li-bg: #2b2b2f; + --search-mark-bg: #355c7d; + } +} diff --git a/elasticlunr.min.js b/elasticlunr.min.js new file mode 100644 index 00000000..94b20dd2 --- /dev/null +++ b/elasticlunr.min.js @@ -0,0 +1,10 @@ +/** + * elasticlunr - http://weixsong.github.io + * Lightweight full-text search engine in Javascript for browser search and offline search. - 0.9.5 + * + * Copyright (C) 2017 Oliver Nightingale + * Copyright (C) 2017 Wei Song + * MIT Licensed + * @license + */ +!function(){function e(e){if(null===e||"object"!=typeof e)return e;var t=e.constructor();for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.9.5",lunr=t,t.utils={},t.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),t.utils.toString=function(e){return void 0===e||null===e?"":e.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var e=Array.prototype.slice.call(arguments),t=e.pop(),n=e;if("function"!=typeof t)throw new TypeError("last argument must be a function");n.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},t.EventEmitter.prototype.removeListener=function(e,t){if(this.hasHandler(e)){var n=this.events[e].indexOf(t);-1!==n&&(this.events[e].splice(n,1),0==this.events[e].length&&delete this.events[e])}},t.EventEmitter.prototype.emit=function(e){if(this.hasHandler(e)){var t=Array.prototype.slice.call(arguments,1);this.events[e].forEach(function(e){e.apply(void 0,t)},this)}},t.EventEmitter.prototype.hasHandler=function(e){return e in this.events},t.tokenizer=function(e){if(!arguments.length||null===e||void 0===e)return[];if(Array.isArray(e)){var n=e.filter(function(e){return null===e||void 0===e?!1:!0});n=n.map(function(e){return t.utils.toString(e).toLowerCase()});var i=[];return n.forEach(function(e){var n=e.split(t.tokenizer.seperator);i=i.concat(n)},this),i}return e.toString().trim().toLowerCase().split(t.tokenizer.seperator)},t.tokenizer.defaultSeperator=/[\s\-]+/,t.tokenizer.seperator=t.tokenizer.defaultSeperator,t.tokenizer.setSeperator=function(e){null!==e&&void 0!==e&&"object"==typeof e&&(t.tokenizer.seperator=e)},t.tokenizer.resetSeperator=function(){t.tokenizer.seperator=t.tokenizer.defaultSeperator},t.tokenizer.getSeperator=function(){return t.tokenizer.seperator},t.Pipeline=function(){this._queue=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in t.Pipeline.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[n]=e},t.Pipeline.getRegisteredFunction=function(e){return e in t.Pipeline.registeredFunctions!=!0?null:t.Pipeline.registeredFunctions[e]},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.getRegisteredFunction(e);if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i+1,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i,0,n)},t.Pipeline.prototype.remove=function(e){var t=this._queue.indexOf(e);-1!==t&&this._queue.splice(t,1)},t.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,i=this._queue.length,o=0;n>o;o++){for(var r=e[o],s=0;i>s&&(r=this._queue[s](r,o,e),void 0!==r&&null!==r);s++);void 0!==r&&null!==r&&t.push(r)}return t},t.Pipeline.prototype.reset=function(){this._queue=[]},t.Pipeline.prototype.get=function(){return this._queue},t.Pipeline.prototype.toJSON=function(){return this._queue.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.DocumentStore,this.index={},this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var e=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,e)},t.Index.prototype.off=function(e,t){return this.eventEmitter.removeListener(e,t)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;n._fields=e.fields,n._ref=e.ref,n.documentStore=t.DocumentStore.load(e.documentStore),n.pipeline=t.Pipeline.load(e.pipeline),n.index={};for(var i in e.index)n.index[i]=t.InvertedIndex.load(e.index[i]);return n},t.Index.prototype.addField=function(e){return this._fields.push(e),this.index[e]=new t.InvertedIndex,this},t.Index.prototype.setRef=function(e){return this._ref=e,this},t.Index.prototype.saveDocument=function(e){return this.documentStore=new t.DocumentStore(e),this},t.Index.prototype.addDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.addDoc(i,e),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));this.documentStore.addFieldLength(i,n,o.length);var r={};o.forEach(function(e){e in r?r[e]+=1:r[e]=1},this);for(var s in r){var u=r[s];u=Math.sqrt(u),this.index[n].addToken(s,{ref:i,tf:u})}},this),n&&this.eventEmitter.emit("add",e,this)}},t.Index.prototype.removeDocByRef=function(e){if(e&&this.documentStore.isDocStored()!==!1&&this.documentStore.hasDoc(e)){var t=this.documentStore.getDoc(e);this.removeDoc(t,!1)}},t.Index.prototype.removeDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.hasDoc(i)&&(this.documentStore.removeDoc(i),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));o.forEach(function(e){this.index[n].removeToken(e,i)},this)},this),n&&this.eventEmitter.emit("remove",e,this))}},t.Index.prototype.updateDoc=function(e,t){var t=void 0===t?!0:t;this.removeDocByRef(e[this._ref],!1),this.addDoc(e,!1),t&&this.eventEmitter.emit("update",e,this)},t.Index.prototype.idf=function(e,t){var n="@"+t+"/"+e;if(Object.prototype.hasOwnProperty.call(this._idfCache,n))return this._idfCache[n];var i=this.index[t].getDocFreq(e),o=1+Math.log(this.documentStore.length/(i+1));return this._idfCache[n]=o,o},t.Index.prototype.getFields=function(){return this._fields.slice()},t.Index.prototype.search=function(e,n){if(!e)return[];e="string"==typeof e?{any:e}:JSON.parse(JSON.stringify(e));var i=null;null!=n&&(i=JSON.stringify(n));for(var o=new t.Configuration(i,this.getFields()).get(),r={},s=Object.keys(e),u=0;u0&&t.push(e);for(var i in n)"docs"!==i&&"df"!==i&&this.expandToken(e+i,t,n[i]);return t},t.InvertedIndex.prototype.toJSON=function(){return{root:this.root}},t.Configuration=function(e,n){var e=e||"";if(void 0==n||null==n)throw new Error("fields should not be null");this.config={};var i;try{i=JSON.parse(e),this.buildUserConfig(i,n)}catch(o){t.utils.warn("user configuration parse failed, will use default configuration"),this.buildDefaultConfig(n)}},t.Configuration.prototype.buildDefaultConfig=function(e){this.reset(),e.forEach(function(e){this.config[e]={boost:1,bool:"OR",expand:!1}},this)},t.Configuration.prototype.buildUserConfig=function(e,n){var i="OR",o=!1;if(this.reset(),"bool"in e&&(i=e.bool||i),"expand"in e&&(o=e.expand||o),"fields"in e)for(var r in e.fields)if(n.indexOf(r)>-1){var s=e.fields[r],u=o;void 0!=s.expand&&(u=s.expand),this.config[r]={boost:s.boost||0===s.boost?s.boost:1,bool:s.bool||i,expand:u}}else t.utils.warn("field name in user configuration not found in index instance fields");else this.addAllFields2UserConfig(i,o,n)},t.Configuration.prototype.addAllFields2UserConfig=function(e,t,n){n.forEach(function(n){this.config[n]={boost:1,bool:e,expand:t}},this)},t.Configuration.prototype.get=function(){return this.config},t.Configuration.prototype.reset=function(){this.config={}},lunr.SortedSet=function(){this.length=0,this.elements=[]},lunr.SortedSet.load=function(e){var t=new this;return t.elements=e,t.length=e.length,t},lunr.SortedSet.prototype.add=function(){var e,t;for(e=0;e1;){if(r===e)return o;e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o]}return r===e?o:-1},lunr.SortedSet.prototype.locationFor=function(e){for(var t=0,n=this.elements.length,i=n-t,o=t+Math.floor(i/2),r=this.elements[o];i>1;)e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o];return r>e?o:e>r?o+1:void 0},lunr.SortedSet.prototype.intersect=function(e){for(var t=new lunr.SortedSet,n=0,i=0,o=this.length,r=e.length,s=this.elements,u=e.elements;;){if(n>o-1||i>r-1)break;s[n]!==u[i]?s[n]u[i]&&i++:(t.add(s[n]),n++,i++)}return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){var t,n,i;this.length>=e.length?(t=this,n=e):(t=e,n=this),i=t.clone();for(var o=0,r=n.toArray();o + + + + diff --git a/fonts/OPEN-SANS-LICENSE.txt b/fonts/OPEN-SANS-LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/fonts/OPEN-SANS-LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/fonts/SOURCE-CODE-PRO-LICENSE.txt b/fonts/SOURCE-CODE-PRO-LICENSE.txt new file mode 100644 index 00000000..366206f5 --- /dev/null +++ b/fonts/SOURCE-CODE-PRO-LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/fonts/fonts.css b/fonts/fonts.css new file mode 100644 index 00000000..858efa59 --- /dev/null +++ b/fonts/fonts.css @@ -0,0 +1,100 @@ +/* Open Sans is licensed under the Apache License, Version 2.0. See http://www.apache.org/licenses/LICENSE-2.0 */ +/* Source Code Pro is under the Open Font License. See https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL */ + +/* open-sans-300 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 300; + src: local('Open Sans Light'), local('OpenSans-Light'), + url('open-sans-v17-all-charsets-300.woff2') format('woff2'); +} + +/* open-sans-300italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 300; + src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'), + url('open-sans-v17-all-charsets-300italic.woff2') format('woff2'); +} + +/* open-sans-regular - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + src: local('Open Sans Regular'), local('OpenSans-Regular'), + url('open-sans-v17-all-charsets-regular.woff2') format('woff2'); +} + +/* open-sans-italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 400; + src: local('Open Sans Italic'), local('OpenSans-Italic'), + url('open-sans-v17-all-charsets-italic.woff2') format('woff2'); +} + +/* open-sans-600 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 600; + src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'), + url('open-sans-v17-all-charsets-600.woff2') format('woff2'); +} + +/* open-sans-600italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 600; + src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'), + url('open-sans-v17-all-charsets-600italic.woff2') format('woff2'); +} + +/* open-sans-700 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 700; + src: local('Open Sans Bold'), local('OpenSans-Bold'), + url('open-sans-v17-all-charsets-700.woff2') format('woff2'); +} + +/* open-sans-700italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 700; + src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'), + url('open-sans-v17-all-charsets-700italic.woff2') format('woff2'); +} + +/* open-sans-800 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 800; + src: local('Open Sans ExtraBold'), local('OpenSans-ExtraBold'), + url('open-sans-v17-all-charsets-800.woff2') format('woff2'); +} + +/* open-sans-800italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 800; + src: local('Open Sans ExtraBold Italic'), local('OpenSans-ExtraBoldItalic'), + url('open-sans-v17-all-charsets-800italic.woff2') format('woff2'); +} + +/* source-code-pro-500 - latin_vietnamese_latin-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Source Code Pro'; + font-style: normal; + font-weight: 500; + src: url('source-code-pro-v11-all-charsets-500.woff2') format('woff2'); +} diff --git a/fonts/open-sans-v17-all-charsets-300.woff2 b/fonts/open-sans-v17-all-charsets-300.woff2 new file mode 100644 index 00000000..9f51be37 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-300.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-300italic.woff2 b/fonts/open-sans-v17-all-charsets-300italic.woff2 new file mode 100644 index 00000000..2f545448 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-300italic.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-600.woff2 b/fonts/open-sans-v17-all-charsets-600.woff2 new file mode 100644 index 00000000..f503d558 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-600.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-600italic.woff2 b/fonts/open-sans-v17-all-charsets-600italic.woff2 new file mode 100644 index 00000000..c99aabe8 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-600italic.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-700.woff2 b/fonts/open-sans-v17-all-charsets-700.woff2 new file mode 100644 index 00000000..421a1ab2 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-700.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-700italic.woff2 b/fonts/open-sans-v17-all-charsets-700italic.woff2 new file mode 100644 index 00000000..12ce3d20 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-700italic.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-800.woff2 b/fonts/open-sans-v17-all-charsets-800.woff2 new file mode 100644 index 00000000..c94a223b Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-800.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-800italic.woff2 b/fonts/open-sans-v17-all-charsets-800italic.woff2 new file mode 100644 index 00000000..eed7d3c6 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-800italic.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-italic.woff2 b/fonts/open-sans-v17-all-charsets-italic.woff2 new file mode 100644 index 00000000..398b68a0 Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-italic.woff2 differ diff --git a/fonts/open-sans-v17-all-charsets-regular.woff2 b/fonts/open-sans-v17-all-charsets-regular.woff2 new file mode 100644 index 00000000..8383e94c Binary files /dev/null and b/fonts/open-sans-v17-all-charsets-regular.woff2 differ diff --git a/fonts/source-code-pro-v11-all-charsets-500.woff2 b/fonts/source-code-pro-v11-all-charsets-500.woff2 new file mode 100644 index 00000000..72224568 Binary files /dev/null and b/fonts/source-code-pro-v11-all-charsets-500.woff2 differ diff --git a/highlight.css b/highlight.css new file mode 100644 index 00000000..c2343227 --- /dev/null +++ b/highlight.css @@ -0,0 +1,83 @@ +/* + * An increased contrast highlighting scheme loosely based on the + * "Base16 Atelier Dune Light" theme by Bram de Haan + * (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) + * Original Base16 color scheme by Chris Kempson + * (https://github.com/chriskempson/base16) + */ + +/* Comment */ +.hljs-comment, +.hljs-quote { + color: #575757; +} + +/* Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #d70025; +} + +/* Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #b21e00; +} + +/* Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #008200; +} + +/* Blue */ +.hljs-title, +.hljs-section { + color: #0030f2; +} + +/* Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #9d00ec; +} + +.hljs { + display: block; + overflow-x: auto; + background: #f6f7f6; + color: #000; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-addition { + color: #22863a; + background-color: #f0fff4; +} + +.hljs-deletion { + color: #b31d28; + background-color: #ffeef0; +} diff --git a/highlight.js b/highlight.js new file mode 100644 index 00000000..180385b7 --- /dev/null +++ b/highlight.js @@ -0,0 +1,6 @@ +/* + Highlight.js 10.1.1 (93fd0d73) + License: BSD-3-Clause + Copyright (c) 2006-2020, Ivan Sagalaev +*/ +var hljs=function(){"use strict";function e(n){Object.freeze(n);var t="function"==typeof n;return Object.getOwnPropertyNames(n).forEach((function(r){!Object.hasOwnProperty.call(n,r)||null===n[r]||"object"!=typeof n[r]&&"function"!=typeof n[r]||t&&("caller"===r||"callee"===r||"arguments"===r)||Object.isFrozen(n[r])||e(n[r])})),n}class n{constructor(e){void 0===e.data&&(e.data={}),this.data=e.data}ignoreMatch(){this.ignore=!0}}function t(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function r(e,...n){var t={};for(const n in e)t[n]=e[n];return n.forEach((function(e){for(const n in e)t[n]=e[n]})),t}function a(e){return e.nodeName.toLowerCase()}var i=Object.freeze({__proto__:null,escapeHTML:t,inherit:r,nodeStream:function(e){var n=[];return function e(t,r){for(var i=t.firstChild;i;i=i.nextSibling)3===i.nodeType?r+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:r,node:i}),r=e(i,r),a(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:r,node:i}));return r}(e,0),n},mergeStreams:function(e,n,r){var i=0,s="",o=[];function l(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset"}function u(e){s+=""}function d(e){("start"===e.event?c:u)(e.node)}for(;e.length||n.length;){var g=l();if(s+=t(r.substring(i,g[0].offset)),i=g[0].offset,g===e){o.reverse().forEach(u);do{d(g.splice(0,1)[0]),g=l()}while(g===e&&g.length&&g[0].offset===i);o.reverse().forEach(c)}else"start"===g[0].event?o.push(g[0].node):o.pop(),d(g.splice(0,1)[0])}return s+t(r.substr(i))}});const s="
",o=e=>!!e.kind;class l{constructor(e,n){this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){this.buffer+=t(e)}openNode(e){if(!o(e))return;let n=e.kind;e.sublanguage||(n=`${this.classPrefix}${n}`),this.span(n)}closeNode(e){o(e)&&(this.buffer+=s)}value(){return this.buffer}span(e){this.buffer+=``}}class c{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){const n={kind:e,children:[]};this.add(n),this.stack.push(n)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n),n.children.forEach(n=>this._walk(e,n)),e.closeNode(n)),e}static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every(e=>"string"==typeof e)?e.children=[e.children.join("")]:e.children.forEach(e=>{c._collapse(e)}))}}class u extends c{constructor(e){super(),this.options=e}addKeyword(e,n){""!==e&&(this.openNode(n),this.addText(e),this.closeNode())}addText(e){""!==e&&this.add(e)}addSublanguage(e,n){const t=e.root;t.kind=n,t.sublanguage=!0,this.add(t)}toHTML(){return new l(this,this.options).value()}finalize(){return!0}}function d(e){return e?"string"==typeof e?e:e.source:null}const g="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",h={begin:"\\\\[\\s\\S]",relevance:0},f={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[h]},p={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[h]},b={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},m=function(e,n,t={}){var a=r({className:"comment",begin:e,end:n,contains:[]},t);return a.contains.push(b),a.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):",relevance:0}),a},v=m("//","$"),x=m("/\\*","\\*/"),E=m("#","$");var _=Object.freeze({__proto__:null,IDENT_RE:"[a-zA-Z]\\w*",UNDERSCORE_IDENT_RE:"[a-zA-Z_]\\w*",NUMBER_RE:"\\b\\d+(\\.\\d+)?",C_NUMBER_RE:g,BINARY_NUMBER_RE:"\\b(0b[01]+)",RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(e={})=>{const n=/^#![ ]*\//;return e.binary&&(e.begin=function(...e){return e.map(e=>d(e)).join("")}(n,/.*\b/,e.binary,/\b.*/)),r({className:"meta",begin:n,end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},BACKSLASH_ESCAPE:h,APOS_STRING_MODE:f,QUOTE_STRING_MODE:p,PHRASAL_WORDS_MODE:b,COMMENT:m,C_LINE_COMMENT_MODE:v,C_BLOCK_COMMENT_MODE:x,HASH_COMMENT_MODE:E,NUMBER_MODE:{className:"number",begin:"\\b\\d+(\\.\\d+)?",relevance:0},C_NUMBER_MODE:{className:"number",begin:g,relevance:0},BINARY_NUMBER_MODE:{className:"number",begin:"\\b(0b[01]+)",relevance:0},CSS_NUMBER_MODE:{className:"number",begin:"\\b\\d+(\\.\\d+)?(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},REGEXP_MODE:{begin:/(?=\/[^/\n]*\/)/,contains:[{className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[h,{begin:/\[/,end:/\]/,relevance:0,contains:[h]}]}]},TITLE_MODE:{className:"title",begin:"[a-zA-Z]\\w*",relevance:0},UNDERSCORE_TITLE_MODE:{className:"title",begin:"[a-zA-Z_]\\w*",relevance:0},METHOD_GUARD:{begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0},END_SAME_AS_BEGIN:function(e){return Object.assign(e,{"on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{n.data._beginMatch!==e[1]&&n.ignoreMatch()}})}}),N="of and for in not or if then".split(" ");function w(e,n){return n?+n:function(e){return N.includes(e.toLowerCase())}(e)?0:1}const R=t,y=r,{nodeStream:k,mergeStreams:O}=i,M=Symbol("nomatch");return function(t){var a=[],i={},s={},o=[],l=!0,c=/(^(<[^>]+>|\t|)+|\n)/gm,g="Could not find the language '{}', did you forget to load/include a language module?";const h={disableAutodetect:!0,name:"Plain text",contains:[]};var f={noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:null,__emitter:u};function p(e){return f.noHighlightRe.test(e)}function b(e,n,t,r){var a={code:n,language:e};S("before:highlight",a);var i=a.result?a.result:m(a.language,a.code,t,r);return i.code=a.code,S("after:highlight",i),i}function m(e,t,a,s){var o=t;function c(e,n){var t=E.case_insensitive?n[0].toLowerCase():n[0];return Object.prototype.hasOwnProperty.call(e.keywords,t)&&e.keywords[t]}function u(){null!=y.subLanguage?function(){if(""!==A){var e=null;if("string"==typeof y.subLanguage){if(!i[y.subLanguage])return void O.addText(A);e=m(y.subLanguage,A,!0,k[y.subLanguage]),k[y.subLanguage]=e.top}else e=v(A,y.subLanguage.length?y.subLanguage:null);y.relevance>0&&(I+=e.relevance),O.addSublanguage(e.emitter,e.language)}}():function(){if(!y.keywords)return void O.addText(A);let e=0;y.keywordPatternRe.lastIndex=0;let n=y.keywordPatternRe.exec(A),t="";for(;n;){t+=A.substring(e,n.index);const r=c(y,n);if(r){const[e,a]=r;O.addText(t),t="",I+=a,O.addKeyword(n[0],e)}else t+=n[0];e=y.keywordPatternRe.lastIndex,n=y.keywordPatternRe.exec(A)}t+=A.substr(e),O.addText(t)}(),A=""}function h(e){return e.className&&O.openNode(e.className),y=Object.create(e,{parent:{value:y}})}function p(e){return 0===y.matcher.regexIndex?(A+=e[0],1):(L=!0,0)}var b={};function x(t,r){var i=r&&r[0];if(A+=t,null==i)return u(),0;if("begin"===b.type&&"end"===r.type&&b.index===r.index&&""===i){if(A+=o.slice(r.index,r.index+1),!l){const n=Error("0 width match regex");throw n.languageName=e,n.badRule=b.rule,n}return 1}if(b=r,"begin"===r.type)return function(e){var t=e[0],r=e.rule;const a=new n(r),i=[r.__beforeBegin,r["on:begin"]];for(const n of i)if(n&&(n(e,a),a.ignore))return p(t);return r&&r.endSameAsBegin&&(r.endRe=RegExp(t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")),r.skip?A+=t:(r.excludeBegin&&(A+=t),u(),r.returnBegin||r.excludeBegin||(A=t)),h(r),r.returnBegin?0:t.length}(r);if("illegal"===r.type&&!a){const e=Error('Illegal lexeme "'+i+'" for mode "'+(y.className||"")+'"');throw e.mode=y,e}if("end"===r.type){var s=function(e){var t=e[0],r=o.substr(e.index),a=function e(t,r,a){let i=function(e,n){var t=e&&e.exec(n);return t&&0===t.index}(t.endRe,a);if(i){if(t["on:end"]){const e=new n(t);t["on:end"](r,e),e.ignore&&(i=!1)}if(i){for(;t.endsParent&&t.parent;)t=t.parent;return t}}if(t.endsWithParent)return e(t.parent,r,a)}(y,e,r);if(!a)return M;var i=y;i.skip?A+=t:(i.returnEnd||i.excludeEnd||(A+=t),u(),i.excludeEnd&&(A=t));do{y.className&&O.closeNode(),y.skip||y.subLanguage||(I+=y.relevance),y=y.parent}while(y!==a.parent);return a.starts&&(a.endSameAsBegin&&(a.starts.endRe=a.endRe),h(a.starts)),i.returnEnd?0:t.length}(r);if(s!==M)return s}if("illegal"===r.type&&""===i)return 1;if(B>1e5&&B>3*r.index)throw Error("potential infinite loop, way more iterations than matches");return A+=i,i.length}var E=T(e);if(!E)throw console.error(g.replace("{}",e)),Error('Unknown language: "'+e+'"');var _=function(e){function n(n,t){return RegExp(d(n),"m"+(e.case_insensitive?"i":"")+(t?"g":""))}class t{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,n){n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]),this.matchAt+=function(e){return RegExp(e.toString()+"|").exec("").length-1}(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);const e=this.regexes.map(e=>e[1]);this.matcherRe=n(function(e,n="|"){for(var t=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,r=0,a="",i=0;i0&&(a+=n),a+="(";o.length>0;){var l=t.exec(o);if(null==l){a+=o;break}a+=o.substring(0,l.index),o=o.substring(l.index+l[0].length),"\\"===l[0][0]&&l[1]?a+="\\"+(+l[1]+s):(a+=l[0],"("===l[0]&&r++)}a+=")"}return a}(e),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;const n=this.matcherRe.exec(e);if(!n)return null;const t=n.findIndex((e,n)=>n>0&&void 0!==e),r=this.matchIndexes[t];return n.splice(0,t),Object.assign(n,r)}}class a{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t;return this.rules.slice(e).forEach(([e,t])=>n.addRule(e,t)),n.compile(),this.multiRegexes[e]=n,n}considerAll(){this.regexIndex=0}addRule(e,n){this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex;const t=n.exec(e);return t&&(this.regexIndex+=t.position+1,this.regexIndex===this.count&&(this.regexIndex=0)),t}}function i(e,n){const t=e.input[e.index-1],r=e.input[e.index+e[0].length];"."!==t&&"."!==r||n.ignoreMatch()}if(e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return function t(s,o){const l=s;if(s.compiled)return l;s.compiled=!0,s.__beforeBegin=null,s.keywords=s.keywords||s.beginKeywords;let c=null;if("object"==typeof s.keywords&&(c=s.keywords.$pattern,delete s.keywords.$pattern),s.keywords&&(s.keywords=function(e,n){var t={};return"string"==typeof e?r("keyword",e):Object.keys(e).forEach((function(n){r(n,e[n])})),t;function r(e,r){n&&(r=r.toLowerCase()),r.split(" ").forEach((function(n){var r=n.split("|");t[r[0]]=[e,w(r[0],r[1])]}))}}(s.keywords,e.case_insensitive)),s.lexemes&&c)throw Error("ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) ");return l.keywordPatternRe=n(s.lexemes||c||/\w+/,!0),o&&(s.beginKeywords&&(s.begin="\\b("+s.beginKeywords.split(" ").join("|")+")(?=\\b|\\s)",s.__beforeBegin=i),s.begin||(s.begin=/\B|\b/),l.beginRe=n(s.begin),s.endSameAsBegin&&(s.end=s.begin),s.end||s.endsWithParent||(s.end=/\B|\b/),s.end&&(l.endRe=n(s.end)),l.terminator_end=d(s.end)||"",s.endsWithParent&&o.terminator_end&&(l.terminator_end+=(s.end?"|":"")+o.terminator_end)),s.illegal&&(l.illegalRe=n(s.illegal)),void 0===s.relevance&&(s.relevance=1),s.contains||(s.contains=[]),s.contains=[].concat(...s.contains.map((function(e){return function(e){return e.variants&&!e.cached_variants&&(e.cached_variants=e.variants.map((function(n){return r(e,{variants:null},n)}))),e.cached_variants?e.cached_variants:function e(n){return!!n&&(n.endsWithParent||e(n.starts))}(e)?r(e,{starts:e.starts?r(e.starts):null}):Object.isFrozen(e)?r(e):e}("self"===e?s:e)}))),s.contains.forEach((function(e){t(e,l)})),s.starts&&t(s.starts,o),l.matcher=function(e){const n=new a;return e.contains.forEach(e=>n.addRule(e.begin,{rule:e,type:"begin"})),e.terminator_end&&n.addRule(e.terminator_end,{type:"end"}),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n}(l),l}(e)}(E),N="",y=s||_,k={},O=new f.__emitter(f);!function(){for(var e=[],n=y;n!==E;n=n.parent)n.className&&e.unshift(n.className);e.forEach(e=>O.openNode(e))}();var A="",I=0,S=0,B=0,L=!1;try{for(y.matcher.considerAll();;){B++,L?L=!1:(y.matcher.lastIndex=S,y.matcher.considerAll());const e=y.matcher.exec(o);if(!e)break;const n=x(o.substring(S,e.index),e);S=e.index+n}return x(o.substr(S)),O.closeAllNodes(),O.finalize(),N=O.toHTML(),{relevance:I,value:N,language:e,illegal:!1,emitter:O,top:y}}catch(n){if(n.message&&n.message.includes("Illegal"))return{illegal:!0,illegalBy:{msg:n.message,context:o.slice(S-100,S+100),mode:n.mode},sofar:N,relevance:0,value:R(o),emitter:O};if(l)return{illegal:!1,relevance:0,value:R(o),emitter:O,language:e,top:y,errorRaised:n};throw n}}function v(e,n){n=n||f.languages||Object.keys(i);var t=function(e){const n={relevance:0,emitter:new f.__emitter(f),value:R(e),illegal:!1,top:h};return n.emitter.addText(e),n}(e),r=t;return n.filter(T).filter(I).forEach((function(n){var a=m(n,e,!1);a.language=n,a.relevance>r.relevance&&(r=a),a.relevance>t.relevance&&(r=t,t=a)})),r.language&&(t.second_best=r),t}function x(e){return f.tabReplace||f.useBR?e.replace(c,e=>"\n"===e?f.useBR?"
":e:f.tabReplace?e.replace(/\t/g,f.tabReplace):e):e}function E(e){let n=null;const t=function(e){var n=e.className+" ";n+=e.parentNode?e.parentNode.className:"";const t=f.languageDetectRe.exec(n);if(t){var r=T(t[1]);return r||(console.warn(g.replace("{}",t[1])),console.warn("Falling back to no-highlight mode for this block.",e)),r?t[1]:"no-highlight"}return n.split(/\s+/).find(e=>p(e)||T(e))}(e);if(p(t))return;S("before:highlightBlock",{block:e,language:t}),f.useBR?(n=document.createElement("div")).innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n"):n=e;const r=n.textContent,a=t?b(t,r,!0):v(r),i=k(n);if(i.length){const e=document.createElement("div");e.innerHTML=a.value,a.value=O(i,k(e),r)}a.value=x(a.value),S("after:highlightBlock",{block:e,result:a}),e.innerHTML=a.value,e.className=function(e,n,t){var r=n?s[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),e.includes(r)||a.push(r),a.join(" ").trim()}(e.className,t,a.language),e.result={language:a.language,re:a.relevance,relavance:a.relevance},a.second_best&&(e.second_best={language:a.second_best.language,re:a.second_best.relevance,relavance:a.second_best.relevance})}const N=()=>{if(!N.called){N.called=!0;var e=document.querySelectorAll("pre code");a.forEach.call(e,E)}};function T(e){return e=(e||"").toLowerCase(),i[e]||i[s[e]]}function A(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach(e=>{s[e]=n})}function I(e){var n=T(e);return n&&!n.disableAutodetect}function S(e,n){var t=e;o.forEach((function(e){e[t]&&e[t](n)}))}Object.assign(t,{highlight:b,highlightAuto:v,fixMarkup:x,highlightBlock:E,configure:function(e){f=y(f,e)},initHighlighting:N,initHighlightingOnLoad:function(){window.addEventListener("DOMContentLoaded",N,!1)},registerLanguage:function(e,n){var r=null;try{r=n(t)}catch(n){if(console.error("Language definition for '{}' could not be registered.".replace("{}",e)),!l)throw n;console.error(n),r=h}r.name||(r.name=e),i[e]=r,r.rawDefinition=n.bind(null,t),r.aliases&&A(r.aliases,{languageName:e})},listLanguages:function(){return Object.keys(i)},getLanguage:T,registerAliases:A,requireLanguage:function(e){var n=T(e);if(n)return n;throw Error("The '{}' language is required, but not loaded.".replace("{}",e))},autoDetection:I,inherit:y,addPlugin:function(e){o.push(e)}}),t.debugMode=function(){l=!1},t.safeMode=function(){l=!0},t.versionString="10.1.1";for(const n in _)"object"==typeof _[n]&&e(_[n]);return Object.assign(t,_),t}({})}();"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs);hljs.registerLanguage("php",function(){"use strict";return function(e){var r={begin:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},t={className:"meta",variants:[{begin:/<\?php/,relevance:10},{begin:/<\?[=]?/},{begin:/\?>/}]},a={className:"string",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:'b"',end:'"'},{begin:"b'",end:"'"},e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null})]},n={variants:[e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]},i={keyword:"__CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__ __METHOD__ __NAMESPACE__ __TRAIT__ die echo exit include include_once print require require_once array abstract and as binary bool boolean break callable case catch class clone const continue declare default do double else elseif empty enddeclare endfor endforeach endif endswitch endwhile eval extends final finally float for foreach from global goto if implements instanceof insteadof int integer interface isset iterable list new object or private protected public real return string switch throw trait try unset use var void while xor yield",literal:"false null true",built_in:"Error|0 AppendIterator ArgumentCountError ArithmeticError ArrayIterator ArrayObject AssertionError BadFunctionCallException BadMethodCallException CachingIterator CallbackFilterIterator CompileError Countable DirectoryIterator DivisionByZeroError DomainException EmptyIterator ErrorException Exception FilesystemIterator FilterIterator GlobIterator InfiniteIterator InvalidArgumentException IteratorIterator LengthException LimitIterator LogicException MultipleIterator NoRewindIterator OutOfBoundsException OutOfRangeException OuterIterator OverflowException ParentIterator ParseError RangeException RecursiveArrayIterator RecursiveCachingIterator RecursiveCallbackFilterIterator RecursiveDirectoryIterator RecursiveFilterIterator RecursiveIterator RecursiveIteratorIterator RecursiveRegexIterator RecursiveTreeIterator RegexIterator RuntimeException SeekableIterator SplDoublyLinkedList SplFileInfo SplFileObject SplFixedArray SplHeap SplMaxHeap SplMinHeap SplObjectStorage SplObserver SplObserver SplPriorityQueue SplQueue SplStack SplSubject SplSubject SplTempFileObject TypeError UnderflowException UnexpectedValueException ArrayAccess Closure Generator Iterator IteratorAggregate Serializable Throwable Traversable WeakReference Directory __PHP_Incomplete_Class parent php_user_filter self static stdClass"};return{aliases:["php","php3","php4","php5","php6","php7"],case_insensitive:!0,keywords:i,contains:[e.HASH_COMMENT_MODE,e.COMMENT("//","$",{contains:[t]}),e.COMMENT("/\\*","\\*/",{contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.COMMENT("__halt_compiler.+?;",!1,{endsWithParent:!0,keywords:"__halt_compiler"}),{className:"string",begin:/<<<['"]?\w+['"]?$/,end:/^\w+;?$/,contains:[e.BACKSLASH_ESCAPE,{className:"subst",variants:[{begin:/\$\w+/},{begin:/\{\$/,end:/\}/}]}]},t,{className:"keyword",begin:/\$this\b/},r,{begin:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{className:"function",beginKeywords:"fn function",end:/[;{]/,excludeEnd:!0,illegal:"[$%\\[]",contains:[e.UNDERSCORE_TITLE_MODE,{className:"params",begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:i,contains:["self",r,e.C_BLOCK_COMMENT_MODE,a,n]}]},{className:"class",beginKeywords:"class interface",end:"{",excludeEnd:!0,illegal:/[:\(\$"]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"namespace",end:";",illegal:/[\.']/,contains:[e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"use",end:";",contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"=>"},a,n]}}}());hljs.registerLanguage("nginx",function(){"use strict";return function(e){var n={className:"variable",variants:[{begin:/\$\d+/},{begin:/\$\{/,end:/}/},{begin:"[\\$\\@]"+e.UNDERSCORE_IDENT_RE}]},a={endsWithParent:!0,keywords:{$pattern:"[a-z/_]+",literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},relevance:0,illegal:"=>",contains:[e.HASH_COMMENT_MODE,{className:"string",contains:[e.BACKSLASH_ESCAPE,n],variants:[{begin:/"/,end:/"/},{begin:/'/,end:/'/}]},{begin:"([a-z]+):/",end:"\\s",endsWithParent:!0,excludeEnd:!0,contains:[n]},{className:"regexp",contains:[e.BACKSLASH_ESCAPE,n],variants:[{begin:"\\s\\^",end:"\\s|{|;",returnEnd:!0},{begin:"~\\*?\\s+",end:"\\s|{|;",returnEnd:!0},{begin:"\\*(\\.[a-z\\-]+)+"},{begin:"([a-z\\-]+\\.)+\\*"}]},{className:"number",begin:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{className:"number",begin:"\\b\\d+[kKmMgGdshdwy]*\\b",relevance:0},n]};return{name:"Nginx config",aliases:["nginxconf"],contains:[e.HASH_COMMENT_MODE,{begin:e.UNDERSCORE_IDENT_RE+"\\s+{",returnBegin:!0,end:"{",contains:[{className:"section",begin:e.UNDERSCORE_IDENT_RE}],relevance:0},{begin:e.UNDERSCORE_IDENT_RE+"\\s",end:";|{",returnBegin:!0,contains:[{className:"attribute",begin:e.UNDERSCORE_IDENT_RE,starts:a}],relevance:0}],illegal:"[^\\s\\}]"}}}());hljs.registerLanguage("csharp",function(){"use strict";return function(e){var n={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let nameof on orderby partial remove select set value var when where yield",literal:"null false true"},i=e.inherit(e.TITLE_MODE,{begin:"[a-zA-Z](\\.?\\w)*"}),a={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},s={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}]},t=e.inherit(s,{illegal:/\n/}),l={className:"subst",begin:"{",end:"}",keywords:n},r=e.inherit(l,{illegal:/\n/}),c={className:"string",begin:/\$"/,end:'"',illegal:/\n/,contains:[{begin:"{{"},{begin:"}}"},e.BACKSLASH_ESCAPE,r]},o={className:"string",begin:/\$@"/,end:'"',contains:[{begin:"{{"},{begin:"}}"},{begin:'""'},l]},g=e.inherit(o,{illegal:/\n/,contains:[{begin:"{{"},{begin:"}}"},{begin:'""'},r]});l.contains=[o,c,s,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_BLOCK_COMMENT_MODE],r.contains=[g,c,t,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.inherit(e.C_BLOCK_COMMENT_MODE,{illegal:/\n/})];var d={variants:[o,c,s,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},E={begin:"<",end:">",contains:[{beginKeywords:"in out"},i]},_=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?",b={begin:"@"+e.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"],keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0,contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{begin:"\x3c!--|--\x3e"},{begin:""}]}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#",end:"$",keywords:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},d,a,{beginKeywords:"class interface",end:/[{;=]/,illegal:/[^\s:,]/,contains:[{beginKeywords:"where class"},i,E,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace",end:/[{;=]/,illegal:/[^\s:]/,contains:[i,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta",begin:"^\\s*\\[",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{className:"meta-string",begin:/"/,end:/"/}]},{beginKeywords:"new return throw await else",relevance:0},{className:"function",begin:"("+_+"\\s+)+"+e.IDENT_RE+"\\s*(\\<.+\\>)?\\s*\\(",returnBegin:!0,end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{begin:e.IDENT_RE+"\\s*(\\<.+\\>)?\\s*\\(",returnBegin:!0,contains:[e.TITLE_MODE,E],relevance:0},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0,contains:[d,a,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},b]}}}());hljs.registerLanguage("perl",function(){"use strict";return function(e){var n={$pattern:/[\w.]+/,keyword:"getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qq fileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmget sub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedir ioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when"},t={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:n},s={begin:"->{",end:"}"},r={variants:[{begin:/\$\d/},{begin:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{begin:/[\$%@][^\s\w{]/,relevance:0}]},i=[e.BACKSLASH_ESCAPE,t,r],a=[r,e.HASH_COMMENT_MODE,e.COMMENT("^\\=\\w","\\=cut",{endsWithParent:!0}),s,{className:"string",contains:i,variants:[{begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[",end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*\\<",end:"\\>",relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'",contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE]},{begin:"{\\w+}",contains:[],relevance:0},{begin:"-?\\w+\\s*\\=\\>",contains:[],relevance:0}]},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*",keywords:"split return print reverse grep",relevance:0,contains:[e.HASH_COMMENT_MODE,{className:"regexp",begin:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",relevance:10},{className:"regexp",begin:"(m|qr)?/",end:"/[a-z]*",contains:[e.BACKSLASH_ESCAPE],relevance:0}]},{className:"function",beginKeywords:"sub",end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$",subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}]}];return t.contains=a,s.contains=a,{name:"Perl",aliases:["pl","pm"],keywords:n,contains:a}}}());hljs.registerLanguage("swift",function(){"use strict";return function(e){var i={keyword:"#available #colorLiteral #column #else #elseif #endif #file #fileLiteral #function #if #imageLiteral #line #selector #sourceLocation _ __COLUMN__ __FILE__ __FUNCTION__ __LINE__ Any as as! as? associatedtype associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false fileprivate final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating open operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c compactMap contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip"},n=e.COMMENT("/\\*","\\*/",{contains:["self"]}),t={className:"subst",begin:/\\\(/,end:"\\)",keywords:i,contains:[]},a={className:"string",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:/"""/,end:/"""/},{begin:/"/,end:/"/}]},r={className:"number",begin:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",relevance:0};return t.contains=[r],{name:"Swift",keywords:i,contains:[a,e.C_LINE_COMMENT_MODE,n,{className:"type",begin:"\\b[A-Z][\\wÀ-ʸ']*[!?]"},{className:"type",begin:"\\b[A-Z][\\wÀ-ʸ']*",relevance:0},r,{className:"function",beginKeywords:"func",end:"{",excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/}),{begin://},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:i,contains:["self",r,a,e.C_BLOCK_COMMENT_MODE,{begin:":"}],illegal:/["']/}],illegal:/\[|%/},{className:"class",beginKeywords:"struct protocol class extension enum",keywords:i,end:"\\{",excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/})]},{className:"meta",begin:"(@discardableResult|@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@objcMembers|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain|@dynamicMemberLookup|@propertyWrapper)\\b"},{beginKeywords:"import",end:/$/,contains:[e.C_LINE_COMMENT_MODE,n]}]}}}());hljs.registerLanguage("makefile",function(){"use strict";return function(e){var i={className:"variable",variants:[{begin:"\\$\\("+e.UNDERSCORE_IDENT_RE+"\\)",contains:[e.BACKSLASH_ESCAPE]},{begin:/\$[@%`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin:"",relevance:10,contains:[a,i,t,s,{begin:"\\[",end:"\\]",contains:[{className:"meta",begin:"",contains:[a,s,i,t]}]}]},e.COMMENT("\x3c!--","--\x3e",{relevance:10}),{begin:"<\\!\\[CDATA\\[",end:"\\]\\]>",relevance:10},n,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:")",end:">",keywords:{name:"style"},contains:[c],starts:{end:"",returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:")",end:">",keywords:{name:"script"},contains:[c],starts:{end:"<\/script>",returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:"",contains:[{className:"name",begin:/[^\/><\s]+/,relevance:0},c]}]}}}());hljs.registerLanguage("bash",function(){"use strict";return function(e){const s={};Object.assign(s,{className:"variable",variants:[{begin:/\$[\w\d#@][\w\d_]*/},{begin:/\$\{/,end:/\}/,contains:[{begin:/:-/,contains:[s]}]}]});const t={className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},n={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,s,t]};t.contains.push(n);const a={begin:/\$\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,s]},i=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10}),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{name:"Bash",aliases:["sh","zsh"],keywords:{$pattern:/\b-?[a-z\._]+\b/,keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},contains:[i,e.SHEBANG(),c,a,e.HASH_COMMENT_MODE,n,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},s]}}}());hljs.registerLanguage("c-like",function(){"use strict";return function(e){function t(e){return"(?:"+e+")?"}var n="(decltype\\(auto\\)|"+t("[a-zA-Z_]\\w*::")+"[a-zA-Z_]\\w*"+t("<.*?>")+")",r={className:"keyword",begin:"\\b[a-z\\d_]*_t\\b"},a={className:"string",variants:[{begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",end:"'",illegal:"."},e.END_SAME_AS_BEGIN({begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},i={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},s={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{"meta-keyword":"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"},contains:[{begin:/\\\n/,relevance:0},e.inherit(a,{className:"meta-string"}),{className:"meta-string",begin:/<.*?>/,end:/$/,illegal:"\\n"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},o={className:"title",begin:t("[a-zA-Z_]\\w*::")+e.IDENT_RE,relevance:0},c=t("[a-zA-Z_]\\w*::")+e.IDENT_RE+"\\s*\\(",l={keyword:"int float while private char char8_t char16_t char32_t catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid wchar_t short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignas alignof constexpr consteval constinit decltype concept co_await co_return co_yield requires noexcept static_assert thread_local restrict final override atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq",built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr _Bool complex _Complex imaginary _Imaginary",literal:"true false nullptr NULL"},d=[r,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,i,a],_={variants:[{begin:/=/,end:/;/},{begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],keywords:l,contains:d.concat([{begin:/\(/,end:/\)/,keywords:l,contains:d.concat(["self"]),relevance:0}]),relevance:0},u={className:"function",begin:"("+n+"[\\*&\\s]+)+"+c,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:l,illegal:/[^\w\s\*&:<>]/,contains:[{begin:"decltype\\(auto\\)",keywords:l,relevance:0},{begin:c,returnBegin:!0,contains:[o],relevance:0},{className:"params",begin:/\(/,end:/\)/,keywords:l,relevance:0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,i,r,{begin:/\(/,end:/\)/,keywords:l,relevance:0,contains:["self",e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,i,r]}]},r,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s]};return{aliases:["c","cc","h","c++","h++","hpp","hh","hxx","cxx"],keywords:l,disableAutodetect:!0,illegal:"",keywords:l,contains:["self",r]},{begin:e.IDENT_RE+"::",keywords:l},{className:"class",beginKeywords:"class struct",end:/[{;:]/,contains:[{begin://,contains:["self"]},e.TITLE_MODE]}]),exports:{preprocessor:s,strings:a,keywords:l}}}}());hljs.registerLanguage("coffeescript",function(){"use strict";const e=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],n=["true","false","null","undefined","NaN","Infinity"],a=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);return function(r){var t={keyword:e.concat(["then","unless","until","loop","by","when","and","or","is","isnt","not"]).filter((e=>n=>!e.includes(n))(["var","const","let","function","static"])).join(" "),literal:n.concat(["yes","no","on","off"]).join(" "),built_in:a.concat(["npm","print"]).join(" ")},i="[A-Za-z$_][0-9A-Za-z$_]*",s={className:"subst",begin:/#\{/,end:/}/,keywords:t},o=[r.BINARY_NUMBER_MODE,r.inherit(r.C_NUMBER_MODE,{starts:{end:"(\\s*/)?",relevance:0}}),{className:"string",variants:[{begin:/'''/,end:/'''/,contains:[r.BACKSLASH_ESCAPE]},{begin:/'/,end:/'/,contains:[r.BACKSLASH_ESCAPE]},{begin:/"""/,end:/"""/,contains:[r.BACKSLASH_ESCAPE,s]},{begin:/"/,end:/"/,contains:[r.BACKSLASH_ESCAPE,s]}]},{className:"regexp",variants:[{begin:"///",end:"///",contains:[s,r.HASH_COMMENT_MODE]},{begin:"//[gim]{0,3}(?=\\W)",relevance:0},{begin:/\/(?![ *]).*?(?![\\]).\/[gim]{0,3}(?=\W)/}]},{begin:"@"+i},{subLanguage:"javascript",excludeBegin:!0,excludeEnd:!0,variants:[{begin:"```",end:"```"},{begin:"`",end:"`"}]}];s.contains=o;var c=r.inherit(r.TITLE_MODE,{begin:i}),l={className:"params",begin:"\\([^\\(]",returnBegin:!0,contains:[{begin:/\(/,end:/\)/,keywords:t,contains:["self"].concat(o)}]};return{name:"CoffeeScript",aliases:["coffee","cson","iced"],keywords:t,illegal:/\/\*/,contains:o.concat([r.COMMENT("###","###"),r.HASH_COMMENT_MODE,{className:"function",begin:"^\\s*"+i+"\\s*=\\s*(\\(.*\\))?\\s*\\B[-=]>",end:"[-=]>",returnBegin:!0,contains:[c,l]},{begin:/[:\(,=]\s*/,relevance:0,contains:[{className:"function",begin:"(\\(.*\\))?\\s*\\B[-=]>",end:"[-=]>",returnBegin:!0,contains:[l]}]},{className:"class",beginKeywords:"class",end:"$",illegal:/[:="\[\]]/,contains:[{beginKeywords:"extends",endsWithParent:!0,illegal:/[:="\[\]]/,contains:[c]},c]},{begin:i+":",end:":",returnBegin:!0,returnEnd:!0,relevance:0}])}}}());hljs.registerLanguage("ruby",function(){"use strict";return function(e){var n="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",a={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},s={className:"doctag",begin:"@[A-Za-z]+"},i={begin:"#<",end:">"},r=[e.COMMENT("#","$",{contains:[s]}),e.COMMENT("^\\=begin","^\\=end",{contains:[s],relevance:10}),e.COMMENT("^__END__","\\n$")],c={className:"subst",begin:"#\\{",end:"}",keywords:a},t={className:"string",contains:[e.BACKSLASH_ESCAPE,c],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{begin:"%[qQwWx]?\\(",end:"\\)"},{begin:"%[qQwWx]?\\[",end:"\\]"},{begin:"%[qQwWx]?{",end:"}"},{begin:"%[qQwWx]?<",end:">"},{begin:"%[qQwWx]?/",end:"/"},{begin:"%[qQwWx]?%",end:"%"},{begin:"%[qQwWx]?-",end:"-"},{begin:"%[qQwWx]?\\|",end:"\\|"},{begin:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{begin:/<<[-~]?'?(\w+)(?:.|\n)*?\n\s*\1\b/,returnBegin:!0,contains:[{begin:/<<[-~]?'?/},e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,contains:[e.BACKSLASH_ESCAPE,c]})]}]},b={className:"params",begin:"\\(",end:"\\)",endsParent:!0,keywords:a},d=[t,i,{className:"class",beginKeywords:"class module",end:"$|;",illegal:/=/,contains:[e.inherit(e.TITLE_MODE,{begin:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{begin:"<\\s*",contains:[{begin:"("+e.IDENT_RE+"::)?"+e.IDENT_RE}]}].concat(r)},{className:"function",beginKeywords:"def",end:"$|;",contains:[e.inherit(e.TITLE_MODE,{begin:n}),b].concat(r)},{begin:e.IDENT_RE+"::"},{className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"(\\!|\\?)?:",relevance:0},{className:"symbol",begin:":(?!\\s)",contains:[t,{begin:n}],relevance:0},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{className:"params",begin:/\|/,end:/\|/,keywords:a},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*",keywords:"unless",contains:[i,{className:"regexp",contains:[e.BACKSLASH_ESCAPE,c],illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:"%r{",end:"}[a-z]*"},{begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[",end:"\\][a-z]*"}]}].concat(r),relevance:0}].concat(r);c.contains=d,b.contains=d;var g=[{begin:/^\s*=>/,starts:{end:"$",contains:d}},{className:"meta",begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>)",starts:{end:"$",contains:d}}];return{name:"Ruby",aliases:["rb","gemspec","podspec","thor","irb"],keywords:a,illegal:/\/\*/,contains:r.concat(g).concat(d)}}}());hljs.registerLanguage("yaml",function(){"use strict";return function(e){var n="true false yes no null",a="[\\w#;/?:@&=+$,.~*\\'()[\\]]+",s={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:"{{",end:"}}"},{begin:"%{",end:"}"}]}]},i=e.inherit(s,{variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),l={end:",",endsWithParent:!0,excludeEnd:!0,contains:[],keywords:n,relevance:0},t={begin:"{",end:"}",contains:[l],illegal:"\\n",relevance:0},g={begin:"\\[",end:"\\]",contains:[l],illegal:"\\n",relevance:0},b=[{className:"attr",variants:[{begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---s*$",relevance:10},{className:"string",begin:"[\\|>]([0-9]?[+-])?[ ]*\\n( *)[\\S ]+\\n(\\2[\\S ]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!\\w+!"+a},{className:"type",begin:"!<"+a+">"},{className:"type",begin:"!"+a},{className:"type",begin:"!!"+a},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"\\-(?=[ ]|$)",relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{className:"number",begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b"},{className:"number",begin:e.C_NUMBER_RE+"\\b"},t,g,s],c=[...b];return c.pop(),c.push(i),l.contains=c,{name:"YAML",case_insensitive:!0,aliases:["yml","YAML"],contains:b}}}());hljs.registerLanguage("d",function(){"use strict";return function(e){var a={$pattern:e.UNDERSCORE_IDENT_RE,keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"},d="((0|[1-9][\\d_]*)|0[bB][01_]+|0[xX]([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))",n="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};",t={className:"number",begin:"\\b"+d+"(L|u|U|Lu|LU|uL|UL)?",relevance:0},_={className:"number",begin:"\\b(((0[xX](([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)\\.([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)|\\.?([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))[pP][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d))|((0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)(\\.\\d*|([eE][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)))|\\d+\\.(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)|\\.(0|[1-9][\\d_]*)([eE][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d))?))([fF]|L|i|[fF]i|Li)?|"+d+"(i|[fF]i|Li))",relevance:0},r={className:"string",begin:"'("+n+"|.)",end:"'",illegal:"."},i={className:"string",begin:'"',contains:[{begin:n,relevance:0}],end:'"[cwd]?'},s=e.COMMENT("\\/\\+","\\+\\/",{contains:["self"],relevance:10});return{name:"D",keywords:a,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s,{className:"string",begin:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',relevance:10},i,{className:"string",begin:'[rq]"',end:'"[cwd]?',relevance:5},{className:"string",begin:"`",end:"`[cwd]?"},{className:"string",begin:'q"\\{',end:'\\}"'},_,t,r,{className:"meta",begin:"^#!",end:"$",relevance:5},{className:"meta",begin:"#(line)",end:"$",relevance:5},{className:"keyword",begin:"@[a-zA-Z_][a-zA-Z_\\d]*"}]}}}());hljs.registerLanguage("properties",function(){"use strict";return function(e){var n="[ \\t\\f]*",t="("+n+"[:=]"+n+"|[ \\t\\f]+)",a="([^\\\\:= \\t\\f\\n]|\\\\.)+",s={end:t,relevance:0,starts:{className:"string",end:/$/,relevance:0,contains:[{begin:"\\\\\\n"}]}};return{name:".properties",case_insensitive:!0,illegal:/\S/,contains:[e.COMMENT("^\\s*[!#]","$"),{begin:"([^\\\\\\W:= \\t\\f\\n]|\\\\.)+"+t,returnBegin:!0,contains:[{className:"attr",begin:"([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",endsParent:!0,relevance:0}],starts:s},{begin:a+t,returnBegin:!0,relevance:0,contains:[{className:"meta",begin:a,endsParent:!0,relevance:0}],starts:s},{className:"attr",relevance:0,begin:a+n+"$"}]}}}());hljs.registerLanguage("http",function(){"use strict";return function(e){var n="HTTP/[0-9\\.]+";return{name:"HTTP",aliases:["https"],illegal:"\\S",contains:[{begin:"^"+n,end:"$",contains:[{className:"number",begin:"\\b\\d{3}\\b"}]},{begin:"^[A-Z]+ (.*?) "+n+"$",returnBegin:!0,end:"$",contains:[{className:"string",begin:" ",end:" ",excludeBegin:!0,excludeEnd:!0},{begin:n},{className:"keyword",begin:"[A-Z]+"}]},{className:"attribute",begin:"^\\w",end:": ",excludeEnd:!0,illegal:"\\n|\\s|=",starts:{end:"$",relevance:0}},{begin:"\\n\\n",starts:{subLanguage:[],endsWithParent:!0}}]}}}());hljs.registerLanguage("haskell",function(){"use strict";return function(e){var n={variants:[e.COMMENT("--","$"),e.COMMENT("{-","-}",{contains:["self"]})]},i={className:"meta",begin:"{-#",end:"#-}"},a={className:"meta",begin:"^#",end:"$"},s={className:"type",begin:"\\b[A-Z][\\w']*",relevance:0},l={begin:"\\(",end:"\\)",illegal:'"',contains:[i,a,{className:"type",begin:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},e.inherit(e.TITLE_MODE,{begin:"[_a-z][\\w']*"}),n]};return{name:"Haskell",aliases:["hs"],keywords:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",contains:[{beginKeywords:"module",end:"where",keywords:"module where",contains:[l,n],illegal:"\\W\\.|;"},{begin:"\\bimport\\b",end:"$",keywords:"import qualified as hiding",contains:[l,n],illegal:"\\W\\.|;"},{className:"class",begin:"^(\\s*)?(class|instance)\\b",end:"where",keywords:"class family instance where",contains:[s,l,n]},{className:"class",begin:"\\b(data|(new)?type)\\b",end:"$",keywords:"data family type newtype deriving",contains:[i,s,l,{begin:"{",end:"}",contains:l.contains},n]},{beginKeywords:"default",end:"$",contains:[s,l,n]},{beginKeywords:"infix infixl infixr",end:"$",contains:[e.C_NUMBER_MODE,n]},{begin:"\\bforeign\\b",end:"$",keywords:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",contains:[s,e.QUOTE_STRING_MODE,n]},{className:"meta",begin:"#!\\/usr\\/bin\\/env runhaskell",end:"$"},i,a,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,s,e.inherit(e.TITLE_MODE,{begin:"^[_a-z][\\w']*"}),n,{begin:"->|<-"}]}}}());hljs.registerLanguage("handlebars",function(){"use strict";function e(...e){return e.map(e=>(function(e){return e?"string"==typeof e?e:e.source:null})(e)).join("")}return function(n){const a={"builtin-name":"action bindattr collection component concat debugger each each-in get hash if in input link-to loc log lookup mut outlet partial query-params render template textarea unbound unless view with yield"},t=/\[.*?\]/,s=/[^\s!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]+/,i=e("(",/'.*?'/,"|",/".*?"/,"|",t,"|",s,"|",/\.|\//,")+"),r=e("(",t,"|",s,")(?==)"),l={begin:i,lexemes:/[\w.\/]+/},c=n.inherit(l,{keywords:{literal:"true false undefined null"}}),o={begin:/\(/,end:/\)/},m={className:"attr",begin:r,relevance:0,starts:{begin:/=/,end:/=/,starts:{contains:[n.NUMBER_MODE,n.QUOTE_STRING_MODE,n.APOS_STRING_MODE,c,o]}}},d={contains:[n.NUMBER_MODE,n.QUOTE_STRING_MODE,n.APOS_STRING_MODE,{begin:/as\s+\|/,keywords:{keyword:"as"},end:/\|/,contains:[{begin:/\w+/}]},m,c,o],returnEnd:!0},g=n.inherit(l,{className:"name",keywords:a,starts:n.inherit(d,{end:/\)/})});o.contains=[g];const u=n.inherit(l,{keywords:a,className:"name",starts:n.inherit(d,{end:/}}/})}),b=n.inherit(l,{keywords:a,className:"name"}),h=n.inherit(l,{className:"name",keywords:a,starts:n.inherit(d,{end:/}}/})});return{name:"Handlebars",aliases:["hbs","html.hbs","html.handlebars","htmlbars"],case_insensitive:!0,subLanguage:"xml",contains:[{begin:/\\\{\{/,skip:!0},{begin:/\\\\(?=\{\{)/,skip:!0},n.COMMENT(/\{\{!--/,/--\}\}/),n.COMMENT(/\{\{!/,/\}\}/),{className:"template-tag",begin:/\{\{\{\{(?!\/)/,end:/\}\}\}\}/,contains:[u],starts:{end:/\{\{\{\{\//,returnEnd:!0,subLanguage:"xml"}},{className:"template-tag",begin:/\{\{\{\{\//,end:/\}\}\}\}/,contains:[b]},{className:"template-tag",begin:/\{\{#/,end:/\}\}/,contains:[u]},{className:"template-tag",begin:/\{\{(?=else\}\})/,end:/\}\}/,keywords:"else"},{className:"template-tag",begin:/\{\{\//,end:/\}\}/,contains:[b]},{className:"template-variable",begin:/\{\{\{/,end:/\}\}\}/,contains:[h]},{className:"template-variable",begin:/\{\{/,end:/\}\}/,contains:[h]}]}}}());hljs.registerLanguage("rust",function(){"use strict";return function(e){var n="([ui](8|16|32|64|128|size)|f(32|64))?",t="drop i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 str char bool Box Option Result String Vec Copy Send Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules! assert_ne! debug_assert_ne!";return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",keyword:"abstract as async await become box break const continue crate do dyn else enum extern false final fn for if impl in let loop macro match mod move mut override priv pub ref return self Self static struct super trait true try type typeof unsafe unsized use virtual where while yield",literal:"true false Some None Ok Err",built_in:t},illegal:""}]}}}());hljs.registerLanguage("cpp",function(){"use strict";return function(e){var t=e.getLanguage("c-like").rawDefinition();return t.disableAutodetect=!1,t.name="C++",t.aliases=["cc","c++","h++","hpp","hh","hxx","cxx"],t}}());hljs.registerLanguage("ini",function(){"use strict";function e(e){return e?"string"==typeof e?e:e.source:null}function n(...n){return n.map(n=>e(n)).join("")}return function(a){var s={className:"number",relevance:0,variants:[{begin:/([\+\-]+)?[\d]+_[\d_]+/},{begin:a.NUMBER_RE}]},i=a.COMMENT();i.variants=[{begin:/;/,end:/$/},{begin:/#/,end:/$/}];var t={className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{begin:/\$\{(.*?)}/}]},r={className:"literal",begin:/\bon|off|true|false|yes|no\b/},l={className:"string",contains:[a.BACKSLASH_ESCAPE],variants:[{begin:"'''",end:"'''",relevance:10},{begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"'},{begin:"'",end:"'"}]},c={begin:/\[/,end:/\]/,contains:[i,r,t,l,s,"self"],relevance:0},g="("+[/[A-Za-z0-9_-]+/,/"(\\"|[^"])*"/,/'[^']*'/].map(n=>e(n)).join("|")+")";return{name:"TOML, also INI",aliases:["toml"],case_insensitive:!0,illegal:/\S/,contains:[i,{className:"section",begin:/\[+/,end:/\]+/},{begin:n(g,"(\\s*\\.\\s*",g,")*",n("(?=",/\s*=\s*[^#\s]/,")")),className:"attr",starts:{end:/$/,contains:[i,c,r,t,l,s]}}]}}}());hljs.registerLanguage("objectivec",function(){"use strict";return function(e){var n=/[a-zA-Z@][a-zA-Z0-9_]*/,_={$pattern:n,keyword:"@interface @class @protocol @implementation"};return{name:"Objective-C",aliases:["mm","objc","obj-c"],keywords:{$pattern:n,keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},illegal:"/,end:/$/,illegal:"\\n"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class",begin:"("+_.keyword.split(" ").join("|")+")\\b",end:"({|$)",excludeEnd:!0,keywords:_,contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE,relevance:0}]}}}());hljs.registerLanguage("apache",function(){"use strict";return function(e){var n={className:"number",begin:"\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?"};return{name:"Apache config",aliases:["apacheconf"],case_insensitive:!0,contains:[e.HASH_COMMENT_MODE,{className:"section",begin:"",contains:[n,{className:"number",begin:":\\d{1,5}"},e.inherit(e.QUOTE_STRING_MODE,{relevance:0})]},{className:"attribute",begin:/\w+/,relevance:0,keywords:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{end:/$/,relevance:0,keywords:{literal:"on off all deny allow"},contains:[{className:"meta",begin:"\\s\\[",end:"\\]$"},{className:"variable",begin:"[\\$%]\\{",end:"\\}",contains:["self",{className:"number",begin:"[\\$%]\\d+"}]},n,{className:"number",begin:"\\d+"},e.QUOTE_STRING_MODE]}}],illegal:/\S/}}}());hljs.registerLanguage("java",function(){"use strict";function e(e){return e?"string"==typeof e?e:e.source:null}function n(e){return a("(",e,")?")}function a(...n){return n.map(n=>e(n)).join("")}function s(...n){return"("+n.map(n=>e(n)).join("|")+")"}return function(e){var t="false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",i={className:"meta",begin:"@[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",contains:[{begin:/\(/,end:/\)/,contains:["self"]}]},r=e=>a("[",e,"]+([",e,"_]*[",e,"]+)?"),c={className:"number",variants:[{begin:`\\b(0[bB]${r("01")})[lL]?`},{begin:`\\b(0${r("0-7")})[dDfFlL]?`},{begin:a(/\b0[xX]/,s(a(r("a-fA-F0-9"),/\./,r("a-fA-F0-9")),a(r("a-fA-F0-9"),/\.?/),a(/\./,r("a-fA-F0-9"))),/([pP][+-]?(\d+))?/,/[fFdDlL]?/)},{begin:a(/\b/,s(a(/\d*\./,r("\\d")),r("\\d")),/[eE][+-]?[\d]+[dDfF]?/)},{begin:a(/\b/,r(/\d/),n(/\.?/),n(r(/\d/)),/[dDfFlL]?/)}],relevance:0};return{name:"Java",aliases:["jsp"],keywords:t,illegal:/<\/|#/,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"class",beginKeywords:"class interface",end:/[{;=]/,excludeEnd:!0,keywords:"class interface",illegal:/[:"\[\]]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"new throw return else",relevance:0},{className:"function",begin:"([À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(<[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(\\s*,\\s*[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*)*>)?\\s+)+"+e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:t,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"params",begin:/\(/,end:/\)/,keywords:t,relevance:0,contains:[i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},c,i]}}}());hljs.registerLanguage("x86asm",function(){"use strict";return function(s){return{name:"Intel x86 Assembly",case_insensitive:!0,keywords:{$pattern:"[.%]?"+s.IDENT_RE,keyword:"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63",built_in:"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr",meta:"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %if %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist __FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__"},contains:[s.COMMENT(";","$",{relevance:0}),{className:"number",variants:[{begin:"\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\b",relevance:0},{begin:"\\$[0-9][0-9A-Fa-f]*",relevance:0},{begin:"\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[Hh]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b"},{begin:"\\b(?:0[Xx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b"}]},s.QUOTE_STRING_MODE,{className:"string",variants:[{begin:"'",end:"[^\\\\]'"},{begin:"`",end:"[^\\\\]`"}],relevance:0},{className:"symbol",variants:[{begin:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)"},{begin:"^\\s*%%[A-Za-z0-9_$#@~.?]*:"}],relevance:0},{className:"subst",begin:"%[0-9]+",relevance:0},{className:"subst",begin:"%!S+",relevance:0},{className:"meta",begin:/^\s*\.[\w_-]+/}]}}}());hljs.registerLanguage("kotlin",function(){"use strict";return function(e){var n={keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual trait volatile transient native default",built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",literal:"true false null"},a={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@"},i={className:"subst",begin:"\\${",end:"}",contains:[e.C_NUMBER_MODE]},s={className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},t={className:"string",variants:[{begin:'"""',end:'"""(?=[^"])',contains:[s,i]},{begin:"'",end:"'",illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/,contains:[e.BACKSLASH_ESCAPE,s,i]}]};i.contains.push(t);var r={className:"meta",begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?"},l={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/,end:/\)/,contains:[e.inherit(t,{className:"meta-string"})]}]},c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),o={variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/,contains:[]}]},d=o;return d.variants[1].contains=[o],o.variants[1].contains=[d],{name:"Kotlin",aliases:["kt"],keywords:n,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,c,{className:"keyword",begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol",begin:/@\w+/}]}},a,r,l,{className:"function",beginKeywords:"fun",end:"[(]|$",returnBegin:!0,excludeEnd:!0,keywords:n,illegal:/fun\s+(<.*>)?[^\s\(]+(\s+[^\s\(]+)\s*=/,relevance:5,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin://,keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/,endsWithParent:!0,contains:[o,e.C_LINE_COMMENT_MODE,c],relevance:0},e.C_LINE_COMMENT_MODE,c,r,l,t,e.C_NUMBER_MODE]},c]},{className:"class",beginKeywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0,illegal:"extends implements",contains:[{beginKeywords:"public protected internal private constructor"},e.UNDERSCORE_TITLE_MODE,{className:"type",begin://,excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,]|$/,excludeBegin:!0,returnEnd:!0},r,l]},t,{className:"meta",begin:"^#!/usr/bin/env",end:"$",illegal:"\n"},{className:"number",begin:"\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",relevance:0}]}}}());hljs.registerLanguage("armasm",function(){"use strict";return function(s){const e={variants:[s.COMMENT("^[ \\t]*(?=#)","$",{relevance:0,excludeBegin:!0}),s.COMMENT("[;@]","$",{relevance:0}),s.C_LINE_COMMENT_MODE,s.C_BLOCK_COMMENT_MODE]};return{name:"ARM Assembly",case_insensitive:!0,aliases:["arm"],keywords:{$pattern:"\\.?"+s.IDENT_RE,meta:".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .arm .thumb .code16 .code32 .force_thumb .thumb_func .ltorg ALIAS ALIGN ARM AREA ASSERT ATTR CN CODE CODE16 CODE32 COMMON CP DATA DCB DCD DCDU DCDO DCFD DCFDU DCI DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT EXPORTAS EXTERN FIELD FILL FUNCTION GBLA GBLL GBLS GET GLOBAL IF IMPORT INCBIN INCLUDE INFO KEEP LCLA LCLL LCLS LTORG MACRO MAP MEND MEXIT NOFP OPT PRESERVE8 PROC QN READONLY RELOC REQUIRE REQUIRE8 RLIST FN ROUT SETA SETL SETS SN SPACE SUBT THUMB THUMBX TTL WHILE WEND ",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 pc lr sp ip sl sb fp a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7 v8 f0 f1 f2 f3 f4 f5 f6 f7 p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 cpsr_c cpsr_x cpsr_s cpsr_f cpsr_cx cpsr_cxs cpsr_xs cpsr_xsf cpsr_sf cpsr_cxsf spsr_c spsr_x spsr_s spsr_f spsr_cx spsr_cxs spsr_xs spsr_xsf spsr_sf spsr_cxsf s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 {PC} {VAR} {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} {CODESIZE} {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET} {ARMASM_VERSION} {INTER} {ROPI} {RWPI} {SWST} {NOSWST} . @"},contains:[{className:"keyword",begin:"\\b(adc|(qd?|sh?|u[qh]?)?add(8|16)?|usada?8|(q|sh?|u[qh]?)?(as|sa)x|and|adrl?|sbc|rs[bc]|asr|b[lx]?|blx|bxj|cbn?z|tb[bh]|bic|bfc|bfi|[su]bfx|bkpt|cdp2?|clz|clrex|cmp|cmn|cpsi[ed]|cps|setend|dbg|dmb|dsb|eor|isb|it[te]{0,3}|lsl|lsr|ror|rrx|ldm(([id][ab])|f[ds])?|ldr((s|ex)?[bhd])?|movt?|mvn|mra|mar|mul|[us]mull|smul[bwt][bt]|smu[as]d|smmul|smmla|mla|umlaal|smlal?([wbt][bt]|d)|mls|smlsl?[ds]|smc|svc|sev|mia([bt]{2}|ph)?|mrr?c2?|mcrr2?|mrs|msr|orr|orn|pkh(tb|bt)|rbit|rev(16|sh)?|sel|[su]sat(16)?|nop|pop|push|rfe([id][ab])?|stm([id][ab])?|str(ex)?[bhd]?|(qd?)?sub|(sh?|q|u[qh]?)?sub(8|16)|[su]xt(a?h|a?b(16)?)|srs([id][ab])?|swpb?|swi|smi|tst|teq|wfe|wfi|yield)(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo)?[sptrx]?(?=\\s)"},e,s.QUOTE_STRING_MODE,{className:"string",begin:"'",end:"[^\\\\]'",relevance:0},{className:"title",begin:"\\|",end:"\\|",illegal:"\\n",relevance:0},{className:"number",variants:[{begin:"[#$=]?0x[0-9a-f]+"},{begin:"[#$=]?0b[01]+"},{begin:"[#$=]\\d+"},{begin:"\\b\\d+"}],relevance:0},{className:"symbol",variants:[{begin:"^[ \\t]*[a-z_\\.\\$][a-z0-9_\\.\\$]+:"},{begin:"^[a-z_\\.\\$][a-z0-9_\\.\\$]+"},{begin:"[=#]\\w+"}],relevance:0}]}}}());hljs.registerLanguage("go",function(){"use strict";return function(e){var n={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{name:"Go",aliases:["golang"],keywords:n,illegal:">>|\.\.\.) /},i={className:"subst",begin:/\{/,end:/\}/,keywords:n,illegal:/#/},s={begin:/\{\{/,relevance:0},r={className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:/(u|b)?r?'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,a],relevance:10},{begin:/(u|b)?r?"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,a],relevance:10},{begin:/(fr|rf|f)'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,a,s,i]},{begin:/(fr|rf|f)"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,a,s,i]},{begin:/(u|r|ur)'/,end:/'/,relevance:10},{begin:/(u|r|ur)"/,end:/"/,relevance:10},{begin:/(b|br)'/,end:/'/},{begin:/(b|br)"/,end:/"/},{begin:/(fr|rf|f)'/,end:/'/,contains:[e.BACKSLASH_ESCAPE,s,i]},{begin:/(fr|rf|f)"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,s,i]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},l={className:"number",relevance:0,variants:[{begin:e.BINARY_NUMBER_RE+"[lLjJ]?"},{begin:"\\b(0o[0-7]+)[lLjJ]?"},{begin:e.C_NUMBER_RE+"[lLjJ]?"}]},t={className:"params",variants:[{begin:/\(\s*\)/,skip:!0,className:null},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,contains:["self",a,l,r,e.HASH_COMMENT_MODE]}]};return i.contains=[r,l,a],{name:"Python",aliases:["py","gyp","ipython"],keywords:n,illegal:/(<\/|->|\?)|=>/,contains:[a,l,{beginKeywords:"if",relevance:0},r,e.HASH_COMMENT_MODE,{variants:[{className:"function",beginKeywords:"def"},{className:"class",beginKeywords:"class"}],end:/:/,illegal:/[${=;\n,]/,contains:[e.UNDERSCORE_TITLE_MODE,t,{begin:/->/,endsWithParent:!0,keywords:"None"}]},{className:"meta",begin:/^[\t ]*@/,end:/$/},{begin:/\b(print|exec)\(/}]}}}());hljs.registerLanguage("shell",function(){"use strict";return function(s){return{name:"Shell Session",aliases:["console"],contains:[{className:"meta",begin:"^\\s{0,3}[/\\w\\d\\[\\]()@-]*[>%$#]",starts:{end:"$",subLanguage:"bash"}}]}}}());hljs.registerLanguage("scala",function(){"use strict";return function(e){var n={className:"subst",variants:[{begin:"\\$[A-Za-z0-9_]+"},{begin:"\\${",end:"}"}]},a={className:"string",variants:[{begin:'"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:'"""',end:'"""',relevance:10},{begin:'[a-z]+"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE,n]},{className:"string",begin:'[a-z]+"""',end:'"""',contains:[n],relevance:10}]},s={className:"type",begin:"\\b[A-Z][A-Za-z0-9_]*",relevance:0},t={className:"title",begin:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,relevance:0},i={className:"class",beginKeywords:"class object trait type",end:/[:={\[\n;]/,excludeEnd:!0,contains:[{beginKeywords:"extends with",relevance:10},{begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[s]},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[s]},t]},l={className:"function",beginKeywords:"def",end:/[:={\[(\n;]/,excludeEnd:!0,contains:[t]};return{name:"Scala",keywords:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,{className:"symbol",begin:"'\\w[\\w\\d_]*(?!')"},s,l,i,e.C_NUMBER_MODE,{className:"meta",begin:"@[A-Za-z]+"}]}}}());hljs.registerLanguage("julia",function(){"use strict";return function(e){var r="[A-Za-z_\\u00A1-\\uFFFF][A-Za-z_0-9\\u00A1-\\uFFFF]*",t={$pattern:r,keyword:"in isa where baremodule begin break catch ccall const continue do else elseif end export false finally for function global if import importall let local macro module quote return true try using while type immutable abstract bitstype typealias ",literal:"true false ARGS C_NULL DevNull ENDIAN_BOM ENV I Inf Inf16 Inf32 Inf64 InsertionSort JULIA_HOME LOAD_PATH MergeSort NaN NaN16 NaN32 NaN64 PROGRAM_FILE QuickSort RoundDown RoundFromZero RoundNearest RoundNearestTiesAway RoundNearestTiesUp RoundToZero RoundUp STDERR STDIN STDOUT VERSION catalan e|0 eu|0 eulergamma golden im nothing pi γ π φ ",built_in:"ANY AbstractArray AbstractChannel AbstractFloat AbstractMatrix AbstractRNG AbstractSerializer AbstractSet AbstractSparseArray AbstractSparseMatrix AbstractSparseVector AbstractString AbstractUnitRange AbstractVecOrMat AbstractVector Any ArgumentError Array AssertionError Associative Base64DecodePipe Base64EncodePipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError BufferStream CachingPool CapturedException CartesianIndex CartesianRange Cchar Cdouble Cfloat Channel Char Cint Cintmax_t Clong Clonglong ClusterManager Cmd CodeInfo Colon Complex Complex128 Complex32 Complex64 CompositeException Condition ConjArray ConjMatrix ConjVector Cptrdiff_t Cshort Csize_t Cssize_t Cstring Cuchar Cuint Cuintmax_t Culong Culonglong Cushort Cwchar_t Cwstring DataType Date DateFormat DateTime DenseArray DenseMatrix DenseVecOrMat DenseVector Diagonal Dict DimensionMismatch Dims DirectIndexString Display DivideError DomainError EOFError EachLine Enum Enumerate ErrorException Exception ExponentialBackOff Expr Factorization FileMonitor Float16 Float32 Float64 Function Future GlobalRef GotoNode HTML Hermitian IO IOBuffer IOContext IOStream IPAddr IPv4 IPv6 IndexCartesian IndexLinear IndexStyle InexactError InitError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException InvalidStateException Irrational KeyError LabelNode LinSpace LineNumberNode LoadError LowerTriangular MIME Matrix MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode NullException Nullable Number ObjectIdDict OrdinalRange OutOfMemoryError OverflowError Pair ParseError PartialQuickSort PermutedDimsArray Pipe PollingFileWatcher ProcessExitedException Ptr QuoteNode RandomDevice Range RangeIndex Rational RawFD ReadOnlyMemoryError Real ReentrantLock Ref Regex RegexMatch RemoteChannel RemoteException RevString RoundingMode RowVector SSAValue SegmentationFault SerializationState Set SharedArray SharedMatrix SharedVector Signed SimpleVector Slot SlotNumber SparseMatrixCSC SparseVector StackFrame StackOverflowError StackTrace StepRange StepRangeLen StridedArray StridedMatrix StridedVecOrMat StridedVector String SubArray SubString SymTridiagonal Symbol Symmetric SystemError TCPSocket Task Text TextDisplay Timer Tridiagonal Tuple Type TypeError TypeMapEntry TypeMapLevel TypeName TypeVar TypedSlot UDPSocket UInt UInt128 UInt16 UInt32 UInt64 UInt8 UndefRefError UndefVarError UnicodeError UniformScaling Union UnionAll UnitRange Unsigned UpperTriangular Val Vararg VecElement VecOrMat Vector VersionNumber Void WeakKeyDict WeakRef WorkerConfig WorkerPool "},a={keywords:t,illegal:/<\//},n={className:"subst",begin:/\$\(/,end:/\)/,keywords:t},o={className:"variable",begin:"\\$"+r},i={className:"string",contains:[e.BACKSLASH_ESCAPE,n,o],variants:[{begin:/\w*"""/,end:/"""\w*/,relevance:10},{begin:/\w*"/,end:/"\w*/}]},l={className:"string",contains:[e.BACKSLASH_ESCAPE,n,o],begin:"`",end:"`"},s={className:"meta",begin:"@"+r};return a.name="Julia",a.contains=[{className:"number",begin:/(\b0x[\d_]*(\.[\d_]*)?|0x\.\d[\d_]*)p[-+]?\d+|\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\b\d[\d_]*(\.[\d_]*)?|\.\d[\d_]*)([eEfF][-+]?\d+)?/,relevance:0},{className:"string",begin:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},i,l,s,{className:"comment",variants:[{begin:"#=",end:"=#",relevance:10},{begin:"#",end:"$"}]},e.HASH_COMMENT_MODE,{className:"keyword",begin:"\\b(((abstract|primitive)\\s+)type|(mutable\\s+)?struct)\\b"},{begin:/<:/}],n.contains=a.contains,a}}());hljs.registerLanguage("php-template",function(){"use strict";return function(n){return{name:"PHP template",subLanguage:"xml",contains:[{begin:/<\?(php|=)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*",end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{begin:"b'",end:"'",skip:!0},n.inherit(n.APOS_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0}),n.inherit(n.QUOTE_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0})]}]}}}());hljs.registerLanguage("scss",function(){"use strict";return function(e){var t={className:"variable",begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b"},i={className:"number",begin:"#[0-9A-Fa-f]+"};return e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_BLOCK_COMMENT_MODE,{name:"SCSS",case_insensitive:!0,illegal:"[=/|']",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"selector-id",begin:"\\#[A-Za-z0-9_-]+",relevance:0},{className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0},{className:"selector-attr",begin:"\\[",end:"\\]",illegal:"$"},{className:"selector-tag",begin:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",relevance:0},{className:"selector-pseudo",begin:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{className:"selector-pseudo",begin:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},t,{className:"attribute",begin:"\\b(src|z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background-blend-mode|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",illegal:"[^\\s]"},{begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{begin:":",end:";",contains:[t,i,e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{className:"meta",begin:"!important"}]},{begin:"@(page|font-face)",lexemes:"@[a-z-]+",keywords:"@page @font-face"},{begin:"@",end:"[{;]",returnBegin:!0,keywords:"and or not only",contains:[{begin:"@[a-z-]+",className:"keyword"},t,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,i,e.CSS_NUMBER_MODE]}]}}}());hljs.registerLanguage("r",function(){"use strict";return function(e){var n="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{name:"R",contains:[e.HASH_COMMENT_MODE,{begin:n,keywords:{$pattern:n,keyword:"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},relevance:0},{className:"number",begin:"0[xX][0-9a-fA-F]+[Li]?\\b",relevance:0},{className:"number",begin:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",relevance:0},{className:"number",begin:"\\d+\\.(?!\\d)(?:i\\b)?",relevance:0},{className:"number",begin:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",relevance:0},{className:"number",begin:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",relevance:0},{begin:"`",end:"`",relevance:0},{className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:'"',end:'"'},{begin:"'",end:"'"}]}]}}}());hljs.registerLanguage("sql",function(){"use strict";return function(e){var t=e.COMMENT("--","$");return{name:"SQL",case_insensitive:!0,illegal:/[<>{}*]/,contains:[{beginKeywords:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment values with",end:/;/,endsWithParent:!0,keywords:{$pattern:/[\w\.]+/,keyword:"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias all allocate allow alter always analyze ancillary and anti any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound bucket buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain explode export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force foreign form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour hours http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lateral lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minutes minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notnull notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second seconds section securefile security seed segment select self semi sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tablesample tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unnest unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace window with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null unknown",built_in:"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp tinyint varchar varchar2 varying void"},contains:[{className:"string",begin:"'",end:"'",contains:[{begin:"''"}]},{className:"string",begin:'"',end:'"',contains:[{begin:'""'}]},{className:"string",begin:"`",end:"`"},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,e.HASH_COMMENT_MODE]},e.C_BLOCK_COMMENT_MODE,t,e.HASH_COMMENT_MODE]}}}());hljs.registerLanguage("c",function(){"use strict";return function(e){var n=e.getLanguage("c-like").rawDefinition();return n.name="C",n.aliases=["c","h"],n}}());hljs.registerLanguage("json",function(){"use strict";return function(n){var e={literal:"true false null"},i=[n.C_LINE_COMMENT_MODE,n.C_BLOCK_COMMENT_MODE],t=[n.QUOTE_STRING_MODE,n.C_NUMBER_MODE],a={end:",",endsWithParent:!0,excludeEnd:!0,contains:t,keywords:e},l={begin:"{",end:"}",contains:[{className:"attr",begin:/"/,end:/"/,contains:[n.BACKSLASH_ESCAPE],illegal:"\\n"},n.inherit(a,{begin:/:/})].concat(i),illegal:"\\S"},s={begin:"\\[",end:"\\]",contains:[n.inherit(a)],illegal:"\\S"};return t.push(l,s),i.forEach((function(n){t.push(n)})),{name:"JSON",contains:t,keywords:e,illegal:"\\S"}}}());hljs.registerLanguage("python-repl",function(){"use strict";return function(n){return{aliases:["pycon"],contains:[{className:"meta",starts:{end:/ |$/,starts:{end:"$",subLanguage:"python"}},variants:[{begin:/^>>>(?=[ ]|$)/},{begin:/^\.\.\.(?=[ ]|$)/}]}]}}}());hljs.registerLanguage("markdown",function(){"use strict";return function(n){const e={begin:"<",end:">",subLanguage:"xml",relevance:0},a={begin:"\\[.+?\\][\\(\\[].*?[\\)\\]]",returnBegin:!0,contains:[{className:"string",begin:"\\[",end:"\\]",excludeBegin:!0,returnEnd:!0,relevance:0},{className:"link",begin:"\\]\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0},{className:"symbol",begin:"\\]\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0}],relevance:10},i={className:"strong",contains:[],variants:[{begin:/_{2}/,end:/_{2}/},{begin:/\*{2}/,end:/\*{2}/}]},s={className:"emphasis",contains:[],variants:[{begin:/\*(?!\*)/,end:/\*/},{begin:/_(?!_)/,end:/_/,relevance:0}]};i.contains.push(s),s.contains.push(i);var c=[e,a];return i.contains=i.contains.concat(c),s.contains=s.contains.concat(c),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:c=c.concat(i,s)},{begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",contains:c}]}]},e,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",end:"\\s+",excludeEnd:!0},i,s,{className:"quote",begin:"^>\\s+",contains:c,end:"$"},{className:"code",variants:[{begin:"(`{3,})(.|\\n)*?\\1`*[ ]*"},{begin:"(~{3,})(.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))",contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{begin:"^[-\\*]{3,}",end:"$"},a,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}}}());hljs.registerLanguage("javascript",function(){"use strict";const e=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],n=["true","false","null","undefined","NaN","Infinity"],a=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);function s(e){return r("(?=",e,")")}function r(...e){return e.map(e=>(function(e){return e?"string"==typeof e?e:e.source:null})(e)).join("")}return function(t){var i="[A-Za-z$_][0-9A-Za-z$_]*",c={begin:/<[A-Za-z0-9\\._:-]+/,end:/\/[A-Za-z0-9\\._:-]+>|\/>/},o={$pattern:"[A-Za-z$_][0-9A-Za-z$_]*",keyword:e.join(" "),literal:n.join(" "),built_in:a.join(" ")},l={className:"number",variants:[{begin:"\\b(0[bB][01]+)n?"},{begin:"\\b(0[oO][0-7]+)n?"},{begin:t.C_NUMBER_RE+"n?"}],relevance:0},E={className:"subst",begin:"\\$\\{",end:"\\}",keywords:o,contains:[]},d={begin:"html`",end:"",starts:{end:"`",returnEnd:!1,contains:[t.BACKSLASH_ESCAPE,E],subLanguage:"xml"}},g={begin:"css`",end:"",starts:{end:"`",returnEnd:!1,contains:[t.BACKSLASH_ESCAPE,E],subLanguage:"css"}},u={className:"string",begin:"`",end:"`",contains:[t.BACKSLASH_ESCAPE,E]};E.contains=[t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,d,g,u,l,t.REGEXP_MODE];var b=E.contains.concat([{begin:/\(/,end:/\)/,contains:["self"].concat(E.contains,[t.C_BLOCK_COMMENT_MODE,t.C_LINE_COMMENT_MODE])},t.C_BLOCK_COMMENT_MODE,t.C_LINE_COMMENT_MODE]),_={className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,contains:b};return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:o,contains:[t.SHEBANG({binary:"node",relevance:5}),{className:"meta",relevance:10,begin:/^\s*['"]use (strict|asm)['"]/},t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,d,g,u,t.C_LINE_COMMENT_MODE,t.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+",contains:[{className:"type",begin:"\\{",end:"\\}",relevance:0},{className:"variable",begin:i+"(?=\\s*(-)|$)",endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}]}),t.C_BLOCK_COMMENT_MODE,l,{begin:r(/[{,\n]\s*/,s(r(/(((\/\/.*)|(\/\*(.|\n)*\*\/))\s*)*/,i+"\\s*:"))),relevance:0,contains:[{className:"attr",begin:i+s("\\s*:"),relevance:0}]},{begin:"("+t.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",contains:[t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,t.REGEXP_MODE,{className:"function",begin:"(\\([^(]*(\\([^(]*(\\([^(]*\\))?\\))?\\)|"+t.UNDERSCORE_IDENT_RE+")\\s*=>",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:t.UNDERSCORE_IDENT_RE},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:o,contains:b}]}]},{begin:/,/,relevance:0},{className:"",begin:/\s/,end:/\s*/,skip:!0},{variants:[{begin:"<>",end:""},{begin:c.begin,end:c.end}],subLanguage:"xml",contains:[{begin:c.begin,end:c.end,skip:!0,contains:["self"]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/\{/,excludeEnd:!0,contains:[t.inherit(t.TITLE_MODE,{begin:i}),_],illegal:/\[|%/},{begin:/\$[(.]/},t.METHOD_GUARD,{className:"class",beginKeywords:"class",end:/[{;=]/,excludeEnd:!0,illegal:/[:"\[\]]/,contains:[{beginKeywords:"extends"},t.UNDERSCORE_TITLE_MODE]},{beginKeywords:"constructor",end:/\{/,excludeEnd:!0},{begin:"(get|set)\\s+(?="+i+"\\()",end:/{/,keywords:"get set",contains:[t.inherit(t.TITLE_MODE,{begin:i}),{begin:/\(\)/},_]}],illegal:/#(?!!)/}}}());hljs.registerLanguage("typescript",function(){"use strict";const e=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],n=["true","false","null","undefined","NaN","Infinity"],a=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);return function(r){var t={$pattern:"[A-Za-z$_][0-9A-Za-z$_]*",keyword:e.concat(["type","namespace","typedef","interface","public","private","protected","implements","declare","abstract","readonly"]).join(" "),literal:n.join(" "),built_in:a.concat(["any","void","number","boolean","string","object","never","enum"]).join(" ")},s={className:"meta",begin:"@[A-Za-z$_][0-9A-Za-z$_]*"},i={className:"number",variants:[{begin:"\\b(0[bB][01]+)n?"},{begin:"\\b(0[oO][0-7]+)n?"},{begin:r.C_NUMBER_RE+"n?"}],relevance:0},o={className:"subst",begin:"\\$\\{",end:"\\}",keywords:t,contains:[]},c={begin:"html`",end:"",starts:{end:"`",returnEnd:!1,contains:[r.BACKSLASH_ESCAPE,o],subLanguage:"xml"}},l={begin:"css`",end:"",starts:{end:"`",returnEnd:!1,contains:[r.BACKSLASH_ESCAPE,o],subLanguage:"css"}},E={className:"string",begin:"`",end:"`",contains:[r.BACKSLASH_ESCAPE,o]};o.contains=[r.APOS_STRING_MODE,r.QUOTE_STRING_MODE,c,l,E,i,r.REGEXP_MODE];var d={begin:"\\(",end:/\)/,keywords:t,contains:["self",r.QUOTE_STRING_MODE,r.APOS_STRING_MODE,r.NUMBER_MODE]},u={className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:[r.C_LINE_COMMENT_MODE,r.C_BLOCK_COMMENT_MODE,s,d]};return{name:"TypeScript",aliases:["ts"],keywords:t,contains:[r.SHEBANG(),{className:"meta",begin:/^\s*['"]use strict['"]/},r.APOS_STRING_MODE,r.QUOTE_STRING_MODE,c,l,E,r.C_LINE_COMMENT_MODE,r.C_BLOCK_COMMENT_MODE,i,{begin:"("+r.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",contains:[r.C_LINE_COMMENT_MODE,r.C_BLOCK_COMMENT_MODE,r.REGEXP_MODE,{className:"function",begin:"(\\([^(]*(\\([^(]*(\\([^(]*\\))?\\))?\\)|"+r.UNDERSCORE_IDENT_RE+")\\s*=>",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:r.UNDERSCORE_IDENT_RE},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:d.contains}]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/[\{;]/,excludeEnd:!0,keywords:t,contains:["self",r.inherit(r.TITLE_MODE,{begin:"[A-Za-z$_][0-9A-Za-z$_]*"}),u],illegal:/%/,relevance:0},{beginKeywords:"constructor",end:/[\{;]/,excludeEnd:!0,contains:["self",u]},{begin:/module\./,keywords:{built_in:"module"},relevance:0},{beginKeywords:"module",end:/\{/,excludeEnd:!0},{beginKeywords:"interface",end:/\{/,excludeEnd:!0,keywords:"interface extends"},{begin:/\$[(.]/},{begin:"\\."+r.IDENT_RE,relevance:0},s,d]}}}());hljs.registerLanguage("plaintext",function(){"use strict";return function(t){return{name:"Plain text",aliases:["text","txt"],disableAutodetect:!0}}}());hljs.registerLanguage("less",function(){"use strict";return function(e){var n="([\\w-]+|@{[\\w-]+})",a=[],s=[],t=function(e){return{className:"string",begin:"~?"+e+".*?"+e}},r=function(e,n,a){return{className:e,begin:n,relevance:a}},i={begin:"\\(",end:"\\)",contains:s,relevance:0};s.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,t("'"),t('"'),e.CSS_NUMBER_MODE,{begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]",excludeEnd:!0}},r("number","#[0-9A-Fa-f]+\\b"),i,r("variable","@@?[\\w-]+",10),r("variable","@{[\\w-]+}"),r("built_in","~?`[^`]*?`"),{className:"attribute",begin:"[\\w-]+\\s*:",end:":",returnBegin:!0,excludeEnd:!0},{className:"meta",begin:"!important"});var c=s.concat({begin:"{",end:"}",contains:a}),l={beginKeywords:"when",endsWithParent:!0,contains:[{beginKeywords:"and not"}].concat(s)},o={begin:n+"\\s*:",returnBegin:!0,end:"[;}]",relevance:0,contains:[{className:"attribute",begin:n,end:":",excludeEnd:!0,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:s}}]},g={className:"keyword",begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{end:"[;{}]",returnEnd:!0,contains:s,relevance:0}},d={className:"variable",variants:[{begin:"@[\\w-]+\\s*:",relevance:15},{begin:"@[\\w-]+"}],starts:{end:"[;}]",returnEnd:!0,contains:c}},b={variants:[{begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:n,end:"{"}],returnBegin:!0,returnEnd:!0,illegal:"[<='$\"]",relevance:0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,l,r("keyword","all\\b"),r("variable","@{[\\w-]+}"),r("selector-tag",n+"%?",0),r("selector-id","#"+n),r("selector-class","\\."+n,0),r("selector-tag","&",0),{className:"selector-attr",begin:"\\[",end:"\\]"},{className:"selector-pseudo",begin:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{begin:"\\(",end:"\\)",contains:c},{begin:"!important"}]};return a.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,g,d,o,b),{name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:a}}}());hljs.registerLanguage("lua",function(){"use strict";return function(e){var t={begin:"\\[=*\\[",end:"\\]=*\\]",contains:["self"]},a=[e.COMMENT("--(?!\\[=*\\[)","$"),e.COMMENT("--\\[=*\\[","\\]=*\\]",{contains:[t],relevance:10})];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE,literal:"true false nil",keyword:"and break do else elseif end for goto if in local not or repeat return then until while",built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"},contains:a.concat([{className:"function",beginKeywords:"function",end:"\\)",contains:[e.inherit(e.TITLE_MODE,{begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params",begin:"\\(",endsWithParent:!0,contains:a}].concat(a)},e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string",begin:"\\[=*\\[",end:"\\]=*\\]",contains:[t],relevance:5}])}}}()); diff --git a/index.html b/index.html new file mode 100644 index 00000000..5b60fc21 --- /dev/null +++ b/index.html @@ -0,0 +1,243 @@ + + + + + + Where to start - A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Calloop's Documentation

+

API

+

If you're looking for calloop's API documentation, they are available on docs.rs for the released versions. There are also the docs of the current development version.

+

Tutorial

+

This book presents a step-by-step tutorial to get yourself familiar with calloop and how it is used:

+
    +
  • Chapter 1 presents the general principles of an event loop that are important to have in mind when working with calloop.
  • +
  • Chapter 2 goes through the different kind of event sources that are provided in calloop, and provides examples of how to use them
  • +
  • Chapter 3 presents the integration with Rust's Async/Await ecosystem provided by calloop
  • +
  • Chapter 4 gives a detailed example of building a custom event source in calloop, by combining other sources
  • +
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mark.min.js b/mark.min.js new file mode 100644 index 00000000..16362318 --- /dev/null +++ b/mark.min.js @@ -0,0 +1,7 @@ +/*!*************************************************** +* mark.js v8.11.1 +* https://markjs.io/ +* Copyright (c) 2014–2018, Julian Kühnel +* Released under the MIT license https://git.io/vwTVl +*****************************************************/ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Mark=t()}(this,function(){"use strict";var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},n=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:5e3;t(this,e),this.ctx=n,this.iframes=r,this.exclude=i,this.iframesTimeout=o}return n(e,[{key:"getContexts",value:function(){var e=[];return(void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach(function(t){var n=e.filter(function(e){return e.contains(t)}).length>0;-1!==e.indexOf(t)||n||e.push(t)}),e}},{key:"getIframeContents",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},r=void 0;try{var i=e.contentWindow;if(r=i.document,!i||!r)throw new Error("iframe inaccessible")}catch(e){n()}r&&t(r)}},{key:"isIframeBlank",value:function(e){var t="about:blank",n=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&n!==t&&n}},{key:"observeIframeLoad",value:function(e,t,n){var r=this,i=!1,o=null,a=function a(){if(!i){i=!0,clearTimeout(o);try{r.isIframeBlank(e)||(e.removeEventListener("load",a),r.getIframeContents(e,t,n))}catch(e){n()}}};e.addEventListener("load",a),o=setTimeout(a,this.iframesTimeout)}},{key:"onIframeReady",value:function(e,t,n){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,n):this.getIframeContents(e,t,n):this.observeIframeLoad(e,t,n)}catch(e){n()}}},{key:"waitForIframes",value:function(e,t){var n=this,r=0;this.forEachIframe(e,function(){return!0},function(e){r++,n.waitForIframes(e.querySelector("html"),function(){--r||t()})},function(e){e||t()})}},{key:"forEachIframe",value:function(t,n,r){var i=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},a=t.querySelectorAll("iframe"),s=a.length,c=0;a=Array.prototype.slice.call(a);var u=function(){--s<=0&&o(c)};s||u(),a.forEach(function(t){e.matches(t,i.exclude)?u():i.onIframeReady(t,function(e){n(t)&&(c++,r(e)),u()},u)})}},{key:"createIterator",value:function(e,t,n){return document.createNodeIterator(e,t,n,!1)}},{key:"createInstanceOnIframe",value:function(t){return new e(t.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(e,t,n){if(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}},{key:"getIteratorNode",value:function(e){var t=e.previousNode();return{prevNode:t,node:null===t?e.nextNode():e.nextNode()&&e.nextNode()}}},{key:"checkIframeFilter",value:function(e,t,n,r){var i=!1,o=!1;return r.forEach(function(e,t){e.val===n&&(i=t,o=e.handled)}),this.compareNodeIframe(e,t,n)?(!1!==i||o?!1===i||o||(r[i].handled=!0):r.push({val:n,handled:!0}),!0):(!1===i&&r.push({val:n,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(e,t,n,r){var i=this;e.forEach(function(e){e.handled||i.getIframeContents(e.val,function(e){i.createInstanceOnIframe(e).forEachNode(t,n,r)})})}},{key:"iterateThroughNodes",value:function(e,t,n,r,i){for(var o,a=this,s=this.createIterator(t,e,r),c=[],u=[],l=void 0,h=void 0;void 0,o=a.getIteratorNode(s),h=o.prevNode,l=o.node;)this.iframes&&this.forEachIframe(t,function(e){return a.checkIframeFilter(l,h,e,c)},function(t){a.createInstanceOnIframe(t).forEachNode(e,function(e){return u.push(e)},r)}),u.push(l);u.forEach(function(e){n(e)}),this.iframes&&this.handleOpenIframes(c,e,n,r),i()}},{key:"forEachNode",value:function(e,t,n){var r=this,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},o=this.getContexts(),a=o.length;a||i(),o.forEach(function(o){var s=function(){r.iterateThroughNodes(e,o,t,n,function(){--a<=0&&i()})};r.iframes?r.waitForIframes(o,s):s()})}}],[{key:"matches",value:function(e,t){var n="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){var i=!1;return n.every(function(t){return!r.call(e,t)||(i=!0,!1)}),i}return!1}}]),e}(),o=function(){function e(n){t(this,e),this.opt=r({},{diacritics:!0,synonyms:{},accuracy:"partially",caseSensitive:!1,ignoreJoiners:!1,ignorePunctuation:[],wildcards:"disabled"},n)}return n(e,[{key:"create",value:function(e){return"disabled"!==this.opt.wildcards&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),"disabled"!==this.opt.wildcards&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e),new RegExp(e,"gm"+(this.opt.caseSensitive?"":"i"))}},{key:"escapeStr",value:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}},{key:"createSynonymsRegExp",value:function(e){var t=this.opt.synonyms,n=this.opt.caseSensitive?"":"i",r=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(var i in t)if(t.hasOwnProperty(i)){var o=t[i],a="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(i):this.escapeStr(i),s="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(o):this.escapeStr(o);""!==a&&""!==s&&(e=e.replace(new RegExp("("+this.escapeStr(a)+"|"+this.escapeStr(s)+")","gm"+n),r+"("+this.processSynonyms(a)+"|"+this.processSynonyms(s)+")"+r))}return e}},{key:"processSynonyms",value:function(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}},{key:"setupWildcardsRegExp",value:function(e){return(e=e.replace(/(?:\\)*\?/g,function(e){return"\\"===e.charAt(0)?"?":""})).replace(/(?:\\)*\*/g,function(e){return"\\"===e.charAt(0)?"*":""})}},{key:"createWildcardsRegExp",value:function(e){var t="withSpaces"===this.opt.wildcards;return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}},{key:"setupIgnoreJoinersRegExp",value:function(e){return e.replace(/[^(|)\\]/g,function(e,t,n){var r=n.charAt(t+1);return/[(|)\\]/.test(r)||""===r?e:e+"\0"})}},{key:"createJoinersRegExp",value:function(e){var t=[],n=this.opt.ignorePunctuation;return Array.isArray(n)&&n.length&&t.push(this.escapeStr(n.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join("["+t.join("")+"]*"):e}},{key:"createDiacriticsRegExp",value:function(e){var t=this.opt.caseSensitive?"":"i",n=this.opt.caseSensitive?["aàáảãạăằắẳẵặâầấẩẫậäåāą","AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćč","CÇĆČ","dđď","DĐĎ","eèéẻẽẹêềếểễệëěēę","EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïī","IÌÍỈĨỊÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøō","OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rř","RŘ","sšśșş","SŠŚȘŞ","tťțţ","TŤȚŢ","uùúủũụưừứửữựûüůū","UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿ","YÝỲỶỸỴŸ","zžżź","ZŽŻŹ"]:["aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćčCÇĆČ","dđďDĐĎ","eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïīIÌÍỈĨỊÎÏĪ","lłLŁ","nñňńNÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rřRŘ","sšśșşSŠŚȘŞ","tťțţTŤȚŢ","uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿYÝỲỶỸỴŸ","zžżźZŽŻŹ"],r=[];return e.split("").forEach(function(i){n.every(function(n){if(-1!==n.indexOf(i)){if(r.indexOf(n)>-1)return!1;e=e.replace(new RegExp("["+n+"]","gm"+t),"["+n+"]"),r.push(n)}return!0})}),e}},{key:"createMergedBlanksRegExp",value:function(e){return e.replace(/[\s]+/gim,"[\\s]+")}},{key:"createAccuracyRegExp",value:function(e){var t=this,n=this.opt.accuracy,r="string"==typeof n?n:n.value,i="";switch(("string"==typeof n?[]:n.limiters).forEach(function(e){i+="|"+t.escapeStr(e)}),r){case"partially":default:return"()("+e+")";case"complementary":return"()([^"+(i="\\s"+(i||this.escapeStr("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿")))+"]*"+e+"[^"+i+"]*)";case"exactly":return"(^|\\s"+i+")("+e+")(?=$|\\s"+i+")"}}}]),e}(),a=function(){function a(e){t(this,a),this.ctx=e,this.ie=!1;var n=window.navigator.userAgent;(n.indexOf("MSIE")>-1||n.indexOf("Trident")>-1)&&(this.ie=!0)}return n(a,[{key:"log",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"debug",r=this.opt.log;this.opt.debug&&"object"===(void 0===r?"undefined":e(r))&&"function"==typeof r[n]&&r[n]("mark.js: "+t)}},{key:"getSeparatedKeywords",value:function(e){var t=this,n=[];return e.forEach(function(e){t.opt.separateWordSearch?e.split(" ").forEach(function(e){e.trim()&&-1===n.indexOf(e)&&n.push(e)}):e.trim()&&-1===n.indexOf(e)&&n.push(e)}),{keywords:n.sort(function(e,t){return t.length-e.length}),length:n.length}}},{key:"isNumeric",value:function(e){return Number(parseFloat(e))==e}},{key:"checkRanges",value:function(e){var t=this;if(!Array.isArray(e)||"[object Object]"!==Object.prototype.toString.call(e[0]))return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];var n=[],r=0;return e.sort(function(e,t){return e.start-t.start}).forEach(function(e){var i=t.callNoMatchOnInvalidRanges(e,r),o=i.start,a=i.end;i.valid&&(e.start=o,e.length=a-o,n.push(e),r=a)}),n}},{key:"callNoMatchOnInvalidRanges",value:function(e,t){var n=void 0,r=void 0,i=!1;return e&&void 0!==e.start?(r=(n=parseInt(e.start,10))+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&r-t>0&&r-n>0?i=!0:(this.log("Ignoring invalid or overlapping range: "+JSON.stringify(e)),this.opt.noMatch(e))):(this.log("Ignoring invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:n,end:r,valid:i}}},{key:"checkWhitespaceRanges",value:function(e,t,n){var r=void 0,i=!0,o=n.length,a=t-o,s=parseInt(e.start,10)-a;return(r=(s=s>o?o:s)+parseInt(e.length,10))>o&&(r=o,this.log("End range automatically set to the max value of "+o)),s<0||r-s<0||s>o||r>o?(i=!1,this.log("Invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)):""===n.substring(s,r).replace(/\s+/g,"")&&(i=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:s,end:r,valid:i}}},{key:"getTextNodes",value:function(e){var t=this,n="",r=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,function(e){r.push({start:n.length,end:(n+=e.textContent).length,node:e})},function(e){return t.matchesExclude(e.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},function(){e({value:n,nodes:r})})}},{key:"matchesExclude",value:function(e){return i.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}},{key:"wrapRangeInTextNode",value:function(e,t,n){var r=this.opt.element?this.opt.element:"mark",i=e.splitText(t),o=i.splitText(n-t),a=document.createElement(r);return a.setAttribute("data-markjs","true"),this.opt.className&&a.setAttribute("class",this.opt.className),a.textContent=i.textContent,i.parentNode.replaceChild(a,i),o}},{key:"wrapRangeInMappedTextNode",value:function(e,t,n,r,i){var o=this;e.nodes.every(function(a,s){var c=e.nodes[s+1];if(void 0===c||c.start>t){if(!r(a.node))return!1;var u=t-a.start,l=(n>a.end?a.end:n)-a.start,h=e.value.substr(0,a.start),f=e.value.substr(l+a.start);if(a.node=o.wrapRangeInTextNode(a.node,u,l),e.value=h+f,e.nodes.forEach(function(t,n){n>=s&&(e.nodes[n].start>0&&n!==s&&(e.nodes[n].start-=l),e.nodes[n].end-=l)}),n-=l,i(a.node.previousSibling,a.start),!(n>a.end))return!1;t=a.end}return!0})}},{key:"wrapGroups",value:function(e,t,n,r){return r((e=this.wrapRangeInTextNode(e,t,t+n)).previousSibling),e}},{key:"separateGroups",value:function(e,t,n,r,i){for(var o=t.length,a=1;a-1&&r(t[a],e)&&(e=this.wrapGroups(e,s,t[a].length,i))}return e}},{key:"wrapMatches",value:function(e,t,n,r,i){var o=this,a=0===t?0:t+1;this.getTextNodes(function(t){t.nodes.forEach(function(t){t=t.node;for(var i=void 0;null!==(i=e.exec(t.textContent))&&""!==i[a];){if(o.opt.separateGroups)t=o.separateGroups(t,i,a,n,r);else{if(!n(i[a],t))continue;var s=i.index;if(0!==a)for(var c=1;c + + + + + A Guide to Calloop + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + +
+
+

Calloop's Documentation

+

API

+

If you're looking for calloop's API documentation, they are available on docs.rs for the released versions. There are also the docs of the current development version.

+

Tutorial

+

This book presents a step-by-step tutorial to get yourself familiar with calloop and how it is used:

+
    +
  • Chapter 1 presents the general principles of an event loop that are important to have in mind when working with calloop.
  • +
  • Chapter 2 goes through the different kind of event sources that are provided in calloop, and provides examples of how to use them
  • +
  • Chapter 3 presents the integration with Rust's Async/Await ecosystem provided by calloop
  • +
  • Chapter 4 gives a detailed example of building a custom event source in calloop, by combining other sources
  • +
+

How an event loop works

+

An event loop is one way to write concurrent code. Other ways include threading (sort of), or asynchronous syntax.

+

When you write concurrent code, you need to know two things:

+
    +
  • where in your program it could potentially block, and
  • +
  • how to let other parts of your program run while waiting for those operations to stop blocking
  • +
+

This chapter covers what the first thing means, and how Calloop accomplishes the second thing.

+

Terminology

+

A blocking operation is one that waits for an event to happen, and doesn't do anything else while it's waiting. For example, if you try to read from a network socket, and there is no data available, the read operation could wait for some indefinite amount of time. Your program will be in a state where it does not need to use any CPU cycles, or indeed do anything at all, and it won't proceed until there is data to read.

+

Examples of blocking operations are:

+
    +
  • waiting for a certain time to elapse
  • +
  • reading or writing to a file
  • +
  • reading or writing to a network socket
  • +
  • waiting for a thread to finish
  • +
+

When any of these operations are ready to go, we call it an event. We call the underlying things (files, network sockets, timers, etc.) sources for events. So, for example, you can create an event source that corresponds to a file, and it will generate events when it is ready for reading, or writing, or encounters an error.

+

Events and callbacks

+

An event loop like Calloop, as the name suggests, runs in a loop. At the start of the loop, Calloop checks all the sources you've added to see if any events have happened for those sources. If they have, Calloop will call a function that you provide (known as a callback).

+

This function will (possibly) be given some data for the event itself (eg. the bytes received), some state for the event source (eg. the socket, or a type that wraps it in a neater API), and some state for the whole program.

+

Calloop will do this one by one for each source that has a new event. If a file is ready for reading, your file-event-source callback will be called. If a timer has elapsed, your timer-event-source callback will be called.

+

It is up to you to write the code to do things when events happen. For example, your callback might read data from a file "ready for reading" event into a queue. When the queue contains a valid message, the same callback could send that message over an internal channel to another event source. That second event source could have its own callback that processes entire messages and updates the program's state. And so on.

+

Concurrency vs parallelism

+

This "one by one" nature of event loops is important. When you approach concurrency using threads, operations in any thread can be interleaved with operations in any other thread. This is typically made robust by either passing messages or using shared memory with synchronisation.

+

Callbacks in an event loop do not run in parallel, they run one after the other. Unless you (or your dependencies) have introduced threading, you can (and should) write your callbacks as single-threaded code.

+

Event loops vs async code

+

This single-threaded nature makes event loops much more similar to code that uses async/await than to multithreaded code. There are benefits and tradeoffs to either approach.

+

Calloop will take care of a lot of integration and error handling boilerplate for you. It also makes it clearer what parts of your code are the non-blocking actions to perform as a result of events. If you like to think of your program in terms of taking action in reaction to events, this can be a great advantage!

+

However, this comes at the expense of needing to make your program's state much more explicit. For example, take this async code:

+
do_thing_one().await;
+do_thing_two().await;
+do_thing_three().await;
+
+

The state of the program is simply given by: what line is it up to? You know if it's done "thing one" because execution has proceeded to line two. No other state is required. In Calloop, however, you will need extra variables and code so that when your callback is called, it knows whether to run do_thing_one(), do_thing_two(), or do_thing_three().

+

Never block the loop!

+

All of this leads us to the most important rule of event loop code: never block the loop! This means: never use blocking calls inside one of your event callbacks. Do not use synchronous file write() calls in a callback. Do not sleep() in a callback. Do not join() a thread in a callback. Don't you do it!

+

If you do, the event loop will have no way to proceed, and just... wait for your blocking operation to complete. Nothing is going to run in a parallel thread. Nothing is going to stop your callback and move on to the next one. If your callback needs to wait for a blocking operation, your code must allow it to keep track of where it's up to, return from the callback, and wait for the event like any other.

+

Calloop and composition

+

Calloop is designed to work by composition. This means that you build up more complex logic in your program by combining simpler event sources into more complex ones. Want a network socket with custom backoff/timeout logic? Create a type containing a network socket using the Generic file descriptor adapter, a timer, and tie them together with your backoff logic and state. There is a much more detailed example of composition in our ZeroMQ example.

+

Using event sources

+

Calloop's structure is entirely built around the EventSource trait, which represents something that is capable of generating events. To receive those events, you need to give ownership of the event source to calloop, along with a closure that will be invoked whenever said source generated an event. This is thus a push-based model, that is most suited for contexts where your program needs to react to (unpredictable) outside events, rather than wait efficiently for the completion of some operation it initiated.

+

Monitoring a file descriptor

+

The Generic event source wraps a file descriptor ("fd") and fires its callback any time there are events on it ie. becoming readable or writable, or encountering an error. It's pretty simple, but it's what every other event source is based around. And since the platforms that calloop runs on expose many different kinds of events via fds, it's usually the key to using those events in calloop.

+

For example on Linux, fd-based interfaces are available for GPIO, I2C, USB, UART, network interfaces, timers and many other systems. Integrating these into calloop starts with obtaining the appropriate fd, creating a Generic event source from it, and building up a more useful, abstracted event source around that. A detailed example of this is given for ZeroMQ.

+

You do not have to use a low-level fd either: any type that implements AsFd can be provided. This means that you can use a wrapper type that handles allocation and disposal itself, and implement AsRawFd on it so that Generic can manage it in the event loop.

+

Creating a Generic source

+

Creating a Generic event source requires three things:

+
    +
  • An OwnedFd or a wrapper type that implements AsFd
  • +
  • The "interest" you have in this descriptor — this means, whether you want to generate events when the fd becomes readable, writeable, or both
  • +
  • The "mode" of event generation - level triggered or edge triggered
  • +
+

The easiest constructor to use is the new() method, but if you need control over the associated error type there is also new_with_error().

+

Ownership and AsFd wrappers

+

Rust 1.63 introduced a concept of file descriptor ownership and borrowing through the OwnedFd and BorrowedFd types, which are also available on older Rust versions through the io-lifetimes crate. The AsFd trait provides a way to get a BorrowedFd corresponding to a file, socket, etc. while guaranteeing the fd will be valid for the lifetime of the BorrowedFd.

+

Not all third party crates use AsFd yet, and may instead provide types implementing AsRawFd. 'AsFdWrapper' provides a way to adapt these types. To use this safely, ensure the AsRawFd implementation of the type it wraps returns a valid fd as long as the type exists. And to avoid an fd leak, it should ultimately be closed properly.

+

Safe types like OwnedFd and BorrowedFd should be preferred over RawFds, and the use of RawFds outside of implementing FFI shouldn't be necessary as libraries move to using the IO safe types and traits.

+

Working with timers

+

Timer event sources are used to manipulate time-related actions. Those are provided under the calloop::timer module, with the Timer type at its core.

+

A Timer source has a simple behavior: it is programmed to wait for some duration, or until a certain point in time. Once that deadline is reached, the source generates an event.

+

So with use calloop::timer::Timer at the top of our .rs file, we can create a timer that will wait for 5 seconds:

+
use std::time::Duration;
+
+use calloop::{
+    timer::{TimeoutAction, Timer},
+    EventLoop,
+};
+
+fn main() {
+    let mut event_loop = EventLoop::try_new().expect("Failed to initialize the event loop!");
+
+    let timer = Timer::from_duration(Duration::from_secs(5));
+
+    event_loop
+        .handle()
+        .insert_source(timer, |deadline, _: &mut (), _shared_data| {
+            println!("Event fired for: {:?}", deadline);
+            TimeoutAction::Drop
+        })
+        .expect("Failed to insert event source!");
+
+    event_loop
+        .dispatch(None, &mut ())
+        .expect("Error during event loop!");
+}
+
+

Adding sources to the loop

+

We have an event source, we have our shared data, and we know how to start our loop running. All that is left is to learn how to combine these things:

+
use std::time::Duration;
+
+use calloop::{
+    timer::{TimeoutAction, Timer},
+    EventLoop,
+};
+
+fn main() {
+    let mut event_loop = EventLoop::try_new().expect("Failed to initialize the event loop!");
+
+    let timer = Timer::from_duration(Duration::from_secs(5));
+
+    event_loop
+        .handle()
+        .insert_source(timer, |deadline, _: &mut (), _shared_data| {
+            println!("Event fired for: {:?}", deadline);
+            TimeoutAction::Drop
+        })
+        .expect("Failed to insert event source!");
+
+    event_loop
+        .dispatch(None, &mut ())
+        .expect("Error during event loop!");
+}
+
+

Breaking this down, the callback we provide receives 3 arguments:

+
    +
  • The first one is an Instant representing the time at which this timer was scheduled to expire. Due to how the event loop works, it might be that your callback is not invoked at the exact time where the timer expired (if an other callback was being processed at the time for example), so the original deadline is given if you need precise time tracking.
  • +
  • The second argument is just &mut (), as the timers don't use the EventSource functionality.
  • +
  • The third argumument is the shared data passed to your event loop.
  • +
+

In addition your callback is expected to return a TimeoutAction, that will instruct calloop what to do next. This enum has 3 values:

+
    +
  • Drop will disable the timer and destroy it, freeing the callback.
  • +
  • ToInstant will rechedule the callback to fire again at given Instant, invoking the same callback again. This is useful if you need to create a timer that fires events at regular intervals, for example to encode key repetition in a graphical app. You would compute the next instant by adding the duration to the previous instant. It is not a problem if that duration is in the past, it'll simply cause the timer to fire again instantly. THis way, even if some other part of your app lags, you'll still have on average the correct amount of events per second.
  • +
  • ToDuration will reschedule the callback to fire again after a given Duration. This is useful if you need to schedule some background task to execute again after some time after it was last completed, when there is no point in catching up some previous lag.
  • +
+

The whole program

+

Putting it all together, we have:

+
use std::time::Duration;
+
+use calloop::{
+    timer::{TimeoutAction, Timer},
+    EventLoop,
+};
+
+fn main() {
+    let mut event_loop = EventLoop::try_new().expect("Failed to initialize the event loop!");
+
+    let timer = Timer::from_duration(Duration::from_secs(5));
+
+    event_loop
+        .handle()
+        .insert_source(timer, |deadline, _: &mut (), _shared_data| {
+            println!("Event fired for: {:?}", deadline);
+            TimeoutAction::Drop
+        })
+        .expect("Failed to insert event source!");
+
+    event_loop
+        .dispatch(None, &mut ())
+        .expect("Error during event loop!");
+}
+
+

"Pinging" the event loop

+

The Ping event source has one very simple job — wake up the event loop. Use this when you know there are events for your event source to process, but those events aren't going to wake the event loop up themselves.

+

For example, calloop's own message channel uses Rust's native MPSC channel internally. Because there's no way for the internal message queue to wake up the event loop, it's coupled with a Ping source that wakes the loop up when there are new messages.

+

How to use the Ping source

+

The Ping has two ends — the event source part (PingSource), that goes in the event loop, and the sending end (Ping) you use to "send" the ping. To wake the event loop up, call ping() on the sending end.

+
+

Do not forget to process the events of the PingSource if you are using it as part of a larger event source! Even though the events carry no information (they are just () values), the process_events() method must be called in order to "reset" the PingSource. Otherwise the event loop will be continually woken up until you do, effectively becoming a busy-loop.

+
+

Channels

+

Unix Signals

+

Error handling in Calloop

+

Overview

+

Most error handling crates/guides/documentation for Rust focus on one of two situations:

+
    +
  • Creating errors that an API can propagate out to a user of the API, or
  • +
  • Making your library deal nicely with the Results from closure or trait methods that it might call
  • +
+

Calloop has to do both of these things. It needs to provide a library user with errors that work well with ? and common error-handling idioms in their own code, and it needs to handle errors from the callbacks you give to process_events() or insert_source(). It also needs to provide some flexibility in the EventSource trait, which is used both for internal event sources and by users of the library.

+

Because of this, error handling in Calloop leans more towards having separate error types for different concerns. This may mean that there is some extra conversion code in places like returning results from process_events(), or in callbacks that use other libraries. However, we try to make it smoother to do these conversions, and to make sure information isn't lost in doing so.

+

If your crate already has some form of structured error handling, Calloop's error types should pose no problem to integrate into this. All of Calloop's errors implement std::error::Error and can be manipulated the same as any other error types.

+

The place where this becomes the most complex is in the process_events() method on the EventSource trait.

+

The Error type on the EventSource trait

+

The EventSource trait contains an associated type named Error, which forms part of the return type from process_events(). This type must be convertible into Box<dyn std::error::Error + Sync + Send>, which means you can use:

+
    +
  • Your own error type that implements std::error::Error
  • +
  • A structured error type created with Thiserror
  • +
  • Box<dyn std::error::Error + Sync + Send>
  • +
  • A flexible string-based error type such as Anyhow's anyhow::Error
  • +
+

As a rule, if you implement EventSource you should try to split your errors into two different categories:

+
    +
  • Errors that make sense as a kind of event. These should be a part of the Event associated type eg. as an enum or Result.
  • +
  • Errors that mean your event source simply cannot process more events. These should form the Error associated type.
  • +
+

For an example, take Calloop's channel type, calloop::channel::Channel. When the sending end is dropped, no more messages can be received after that point. But this is not returned as an error when calling process_events(), because you still want to (and can!) receive messages sent before that point that might still be in the queue. Hence the events received by the callback for this source can be Msg(e) or Closed.

+

However, if the internal ping source produces an error, there is no way for the sending end of the channel to notify the receiver. It is impossible to process more events on this event source, and the caller needs to decide how to recover from this situation. Hence this is returned as a ChannelError from process_events().

+

Another example might be an event source that represents a running subprocess. If the subprocess exits with a non-zero status code, or the executable can't be found, those don't mean that events can no longer be processed. They can be provided to the caller through the callback. But if the lower level sources being used to run (eg. an asynchronous executor or subprocess file descriptor) fail to work as expected, process_events() should return an error.

+

Async/await in calloop

+

While it is centered on event sources and callbacks, calloop also provides adapters to integrate with Rust's async ecosystem. These adapters come in two parts: a futures executor and an async adapter for IO type.

+

Run async code

+
+

Enable the executor feature!

+

To use calloop::futures you need to enable the executor feature in your Cargo.toml like so:

+
[dependencies.calloop]
+features = [ "executor" ]
+version = ...
+
+
+

Let's say you have some async code that looks like this:

+
sender.send("Hello,").await.ok();
+receiver.next().await.map(|m| println!("Received: {}", m));
+sender.send("world!").await.ok();
+receiver.next().await.map(|m| println!("Received: {}", m));
+"So long!"
+
+

...and a corresponding block that receives and sends to this one. I will call one of these blocks "friendly" and the other one "aloof".

+

To run async code in Calloop, you use the components in calloop::futures. First, obtain both an executor and a scheduler with calloop::futures::executor():

+
use calloop::EventLoop;
+
+// futures = "0.3"
+use futures::sink::SinkExt;
+use futures::stream::StreamExt;
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    // Let's create two channels for our async blocks below. The blocks will
+    // exchange messages via these channels.
+    let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded();
+    let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded();
+
+    // Our toy async code.
+    let async_friendly_task = async move {
+        sender_friendly.send("Hello,").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        sender_friendly.send("world!").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        "Bye!"
+    };
+
+    let async_aloof_task = async move {
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("Oh,").await.ok();
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("it's you.").await.ok();
+        "Regards."
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_friendly_task).unwrap();
+    sched.schedule(async_aloof_task).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut (), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

The executor, the part that executes the future, goes in the event loop:

+
use calloop::EventLoop;
+
+// futures = "0.3"
+use futures::sink::SinkExt;
+use futures::stream::StreamExt;
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    // Let's create two channels for our async blocks below. The blocks will
+    // exchange messages via these channels.
+    let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded();
+    let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded();
+
+    // Our toy async code.
+    let async_friendly_task = async move {
+        sender_friendly.send("Hello,").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        sender_friendly.send("world!").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        "Bye!"
+    };
+
+    let async_aloof_task = async move {
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("Oh,").await.ok();
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("it's you.").await.ok();
+        "Regards."
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_friendly_task).unwrap();
+    sched.schedule(async_aloof_task).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut (), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

Now let's write our async code in full:

+
use calloop::EventLoop;
+
+// futures = "0.3"
+use futures::sink::SinkExt;
+use futures::stream::StreamExt;
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    // Let's create two channels for our async blocks below. The blocks will
+    // exchange messages via these channels.
+    let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded();
+    let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded();
+
+    // Our toy async code.
+    let async_friendly_task = async move {
+        sender_friendly.send("Hello,").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        sender_friendly.send("world!").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        "Bye!"
+    };
+
+    let async_aloof_task = async move {
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("Oh,").await.ok();
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("it's you.").await.ok();
+        "Regards."
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_friendly_task).unwrap();
+    sched.schedule(async_aloof_task).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut (), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

Like any block in Rust, the value of your async block is the last expression ie. it is effectively "returned" from the block, which means it will be provided to your executor's callback as the first argument (the "event"). You'll see this in the output with the Async block ended with: ... lines.

+

Finally, we run the loop:

+
use calloop::EventLoop;
+
+// futures = "0.3"
+use futures::sink::SinkExt;
+use futures::stream::StreamExt;
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    // Let's create two channels for our async blocks below. The blocks will
+    // exchange messages via these channels.
+    let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded();
+    let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded();
+
+    // Our toy async code.
+    let async_friendly_task = async move {
+        sender_friendly.send("Hello,").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        sender_friendly.send("world!").await.ok();
+        if let Some(msg) = receiver_aloof.next().await {
+            println!("Aloof said: {}", msg);
+        }
+        "Bye!"
+    };
+
+    let async_aloof_task = async move {
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("Oh,").await.ok();
+        if let Some(msg) = receiver_friendly.next().await {
+            println!("Friendly said: {}", msg);
+        }
+        sender_aloof.send("it's you.").await.ok();
+        "Regards."
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_friendly_task).unwrap();
+    sched.schedule(async_aloof_task).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut (), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

And our output looks like:

+
Starting event loop.
+Friendly said: Hello,
+Aloof said: Oh,
+Friendly said: world!
+Async block ended with: Regards.
+Aloof said: it's you.
+Async block ended with: Bye!
+Event loop ended.
+
+

Note that for the sake of keeping this example short, I've written the async code before running the loop. But async code can be scheduled from callbacks, or other sources within the loop too.

+
+

Note about threads

+

One of Calloop's strengths is that it is completely single threaded as written. However, many async crates are implemented using threads eg. async-std and async-process. This is not an inherent problem! Calloop will work perfectly well with such implementations in general. However, if you have selected Calloop because of your own constraints around threading, be aware of this.

+
+

Async IO types

+
+

This section is about adapting blocking IO types for use with async Rust code, and powering that async code with Calloop. If you just want to add blocking IO types to your event loop and use Calloop's callback/composition-based design, you only need to wrap your blocking IO type in a generic event source.

+
+

You may find that you need to write ordinary Rust async code around blocking IO types. Calloop provides the ability to wrap blocking types — anything that implements the AsFd trait — in its own async type. This can be polled in any executor you may have chosen for your async code, but if you're using Calloop you'll probably be using Calloop's executor.

+
+

Enable the futures-io feature!

+

To use calloop::io you need to enable the futures-io feature in your Cargo.toml like so:

+
[dependencies.calloop]
+features = [ "futures-io" ]
+version = ...
+
+

Realistically you will probably also want to use this with async code, so you should also enable the executor feature too.

+
+

Just like in the async example, we will use the components in calloop::futures. First, obtain both an executor and a scheduler with calloop::futures::executor():

+
use calloop::EventLoop;
+
+use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();
+    let mut sender = handle.adapt_io(sender).unwrap();
+    let mut receiver = handle.adapt_io(receiver).unwrap();
+
+    let async_receive = async move {
+        let mut buf = [0u8; 12];
+        // Here's our async-ified Unix domain socket.
+        receiver.read_exact(&mut buf).await.unwrap();
+        std::str::from_utf8(&buf).unwrap().to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_receive).unwrap();
+
+    let async_send = async move {
+        // Here's our async-ified Unix domain socket.
+        sender.write_all(b"Hello, world!").await.unwrap();
+        "Sent data...".to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_send).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

The executor goes in the event loop:

+
use calloop::EventLoop;
+
+use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();
+    let mut sender = handle.adapt_io(sender).unwrap();
+    let mut receiver = handle.adapt_io(receiver).unwrap();
+
+    let async_receive = async move {
+        let mut buf = [0u8; 12];
+        // Here's our async-ified Unix domain socket.
+        receiver.read_exact(&mut buf).await.unwrap();
+        std::str::from_utf8(&buf).unwrap().to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_receive).unwrap();
+
+    let async_send = async move {
+        // Here's our async-ified Unix domain socket.
+        sender.write_all(b"Hello, world!").await.unwrap();
+        "Sent data...".to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_send).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

For our blocking IO types, let's use an unnamed pair of Unix domain stream sockets. To convert them to async types, we simply call calloop::LoopHandle::adapt_io():

+
use calloop::EventLoop;
+
+use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();
+    let mut sender = handle.adapt_io(sender).unwrap();
+    let mut receiver = handle.adapt_io(receiver).unwrap();
+
+    let async_receive = async move {
+        let mut buf = [0u8; 12];
+        // Here's our async-ified Unix domain socket.
+        receiver.read_exact(&mut buf).await.unwrap();
+        std::str::from_utf8(&buf).unwrap().to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_receive).unwrap();
+
+    let async_send = async move {
+        // Here's our async-ified Unix domain socket.
+        sender.write_all(b"Hello, world!").await.unwrap();
+        "Sent data...".to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_send).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

Note that most of the useful async functionality for the returned type is expressed through various traits in futures::io. So we need to explicitly use these:

+
use calloop::EventLoop;
+
+use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();
+    let mut sender = handle.adapt_io(sender).unwrap();
+    let mut receiver = handle.adapt_io(receiver).unwrap();
+
+    let async_receive = async move {
+        let mut buf = [0u8; 12];
+        // Here's our async-ified Unix domain socket.
+        receiver.read_exact(&mut buf).await.unwrap();
+        std::str::from_utf8(&buf).unwrap().to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_receive).unwrap();
+
+    let async_send = async move {
+        // Here's our async-ified Unix domain socket.
+        sender.write_all(b"Hello, world!").await.unwrap();
+        "Sent data...".to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_send).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

We can now write async code around these types. Here's the receiving code:

+
use calloop::EventLoop;
+
+use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();
+    let mut sender = handle.adapt_io(sender).unwrap();
+    let mut receiver = handle.adapt_io(receiver).unwrap();
+
+    let async_receive = async move {
+        let mut buf = [0u8; 12];
+        // Here's our async-ified Unix domain socket.
+        receiver.read_exact(&mut buf).await.unwrap();
+        std::str::from_utf8(&buf).unwrap().to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_receive).unwrap();
+
+    let async_send = async move {
+        // Here's our async-ified Unix domain socket.
+        sender.write_all(b"Hello, world!").await.unwrap();
+        "Sent data...".to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_send).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

And here's the sending code. The receiving and sending code can be created and added to the executor in either order.

+
use calloop::EventLoop;
+
+use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();
+    let mut sender = handle.adapt_io(sender).unwrap();
+    let mut receiver = handle.adapt_io(receiver).unwrap();
+
+    let async_receive = async move {
+        let mut buf = [0u8; 12];
+        // Here's our async-ified Unix domain socket.
+        receiver.read_exact(&mut buf).await.unwrap();
+        std::str::from_utf8(&buf).unwrap().to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_receive).unwrap();
+
+    let async_send = async move {
+        // Here's our async-ified Unix domain socket.
+        sender.write_all(b"Hello, world!").await.unwrap();
+        "Sent data...".to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_send).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

All that's left is to run the loop:

+
use calloop::EventLoop;
+
+use futures::io::{AsyncReadExt, AsyncWriteExt};
+
+fn main() -> std::io::Result<()> {
+    let (exec, sched) = calloop::futures::executor()?;
+
+    let mut event_loop = EventLoop::try_new()?;
+    let handle = event_loop.handle();
+
+    handle
+        .insert_source(exec, |evt, _metadata, _shared| {
+            // Print the value of the async block ie. the return value.
+            println!("Async block ended with: {}", evt);
+        })
+        .map_err(|e| e.error)?;
+
+    let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();
+    let mut sender = handle.adapt_io(sender).unwrap();
+    let mut receiver = handle.adapt_io(receiver).unwrap();
+
+    let async_receive = async move {
+        let mut buf = [0u8; 12];
+        // Here's our async-ified Unix domain socket.
+        receiver.read_exact(&mut buf).await.unwrap();
+        std::str::from_utf8(&buf).unwrap().to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_receive).unwrap();
+
+    let async_send = async move {
+        // Here's our async-ified Unix domain socket.
+        sender.write_all(b"Hello, world!").await.unwrap();
+        "Sent data...".to_owned()
+    };
+
+    // Schedule the async block to be run in the event loop.
+    sched.schedule(async_send).unwrap();
+
+    // Run the event loop.
+    println!("Starting event loop. Use Ctrl-C to exit.");
+    event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;
+    println!("Event loop ended.");
+
+    Ok(())
+}
+
+

And the output we get is:

+
Starting event loop. Use Ctrl-C to exit.
+Async block ended with: Sent data...
+Async block ended with: Hello, world
+^C
+
+

A full example: ZeroMQ

+

The previous chapter showed how to use callbacks, event data and shared data to control our program. However, more complex programs will require more complex shared data, and more complex interactions between events. Eventually this will run up against ownership issues and just the basic mental load of the poor programmer.

+

In this chapter we're going to build something more complex: an event source based on ZeroMQ sockets.

+

ZeroMQ is (very) basically a highly abstracted socket library. You can create ZeroMQ sockets over TCP, PGM, IPC, in-process and more, and generally not worry about the transport mechanics. It guarantees atomic message transfer, and handles queuing, retries, reconnection and balancing under the hood. It also lets you integrate it with event loops and reactors by exposing a file descriptor that you can wait on.

+

But we can't just wrap this file descriptor in Calloop's generic::Generic source and be done — there are a few subtleties we need to take care of for it to work right and be useful.

+
+

Disclaimer

+

It might be tempting, at the end of this chapter, to think that the code we've written is the definitive ZeroMQ wrapper, able to address any use case or higher level pattern you like. Certainly it will be a lot more suited to Calloop than using ZeroMQ sockets by themselves, but it is not the only way to use them with Calloop. Here are some things I have not addressed, for the sake of simplicity:

+
    +
  • We will not handle fairness — our code will totally monopolise the event loop if we receive many messages at once.
  • +
  • We do not consider back pressure beyond whatever built-in zsocket settings the caller might use.
  • +
  • We just drop pending messages in the zsocket's internal queue (in and out) on shutdown. In a real application, you might want to make more specific decisions about the timeout and linger periods before dropping the zsocket, depending on your application's requirements.
  • +
  • We don't deal with zsocket errors much. In fact, the overall error handling of event sources is usually highly specific to your application, so what we end up writing here is almost certainly not going to survive contact with your own code base. Here we just use ? everywhere, which will eventually cause the event loop to exit with an error.
  • +
+

So by all means, take the code we write here and use and adapt it, but please please note the caveats above and think carefully about your own program.

+
+

Composing event sources

+

Calloop is designed to work by composition. It provides you with some single-responsibility sources (timers, message channels, file descriptors), and you can combine these together, bit by bit, to make more complex event sources. These new sources can express more and more of your program's internal logic and the relationships between them, always in terms of events and how you process them.

+

You can greatly simplify even a highly complex program if you identify and expose the "real" events you care about and use composition to tidy the other events away in internal details of event sources.

+

So what do we need to compose?

+

The generic source

+

Most obviously, ZeroMQ exposes a file descriptor for us to use. (This is a common thing for event-related libraries to do, so if you're wondering how to integrate, say, I²C or GPIO on Linux with Calloop, that's your answer.)

+

Calloop can use file descriptors via the calloop::generic::Generic source. So that's one.

+

The MPSC channel source

+

Secondly, we might want to send messages on the socket. This means our event source needs to react when we send it a message. Calloop has a message channel for precisely this purpose: calloop::channel::Channel. That's another one.

+

The wakeup call

+

The third event source we need is a bit subtle, but since this isn't a mystery novel I can save you hours of debugging and spoil the ending now: we need a "ping" event source because ZeroMQ's FD is edge triggered.

+

ZeroMQ's file descriptor is not the FD of an actual file or socket — you do not actually read data from it. It exists as an interface, with three important details:

+
    +
  • +

    It is only ever readable. Even if the underlying socket can be written to, the FD that ZeroMQ gives you signals this by becoming readable. In fact, this FD will become readable under three circumstances: the ZeroMQ socket (henceforth called a "zsocket") is readable, writeable, or has an error. There is a separate function call, zmq::Socket::get_events() that will tell you which.

    +
  • +
  • +

    It is edge triggered. It will only ever change from not-readable to readable when the socket's state changes. So if a zsocket receives two messages, and you only read one, the file descriptor will not wake up the event loop again. Why not? Because it hasn't changed state! After you read one message, the zsocket still has events waiting. If it receives yet another message... it still has events waiting. No change in internal state = no external event.

    +
  • +
  • +

    This edge triggering also covers user actions. If a zsocket becomes writeable, and then you write to the zsocket, it might immediately (and atomically) change from writeable to readable. In this case you will not get another event on the FD.

    +
  • +
+

(The docs make this quite explicit, but there's a lot of docs to read so I'm spelling it out here.)

+

What this adds up to is this: when we create our zsocket, it might already be readable or writeable. So when we add it to our event loop, it won't fire any events. Our entire source will just sit there until we wake it up by sending a message (which we might never do if it's eg. a pull socket).

+

So the last event source we need is something that doesn't really convey any kind of message except "please wake up the event loop on the next iteration", and that is exactly what a calloop::ping::PingSource does. And that's three.

+

Creating our source, part I: our types

+

In the last chapter we worked out a list of the event sources we need to compose into a new type:

+
    +
  1. calloop::generic::Generic
  2. +
  3. calloop::channel::Channel
  4. +
  5. calloop::ping::Ping
  6. +
+

So at a minimum, our type needs to contain these:

+
pub struct ZeroMQSource
+{
+    // Calloop components.
+    socket: calloop::generic::Generic<calloop::generic::FdWrapper<zmq::Socket>>,
+    mpsc_receiver: calloop::channel::Channel<?>,
+    wake_ping_receiver: calloop::ping::PingSource,
+}
+
+

Note that I've left the type for the channel as ? — we'll get to that a bit later.

+

What else do we need? If the PingSource is there to wake up the loop manually, we need to keep the other end of it. The ping is an internal detail — users of our type don't need to know it's there. We also need the zsocket itself, so we can actually detect and process events on it. That gives us:

+
pub struct ZeroMQSource
+{
+    // Calloop components.
+    socket: calloop::generic::Generic<calloop::generic::FdWrapper<zmq::Socket>>,
+    mpsc_receiver: calloop::channel::Channel<?>,
+    wake_ping_receiver: calloop::ping::PingSource,
+
+    /// Sending end of the ping source.
+    wake_ping_sender: calloop::ping::Ping,
+}
+
+

The message type

+

The most obvious candidate for the type of the message queue would be zmq::Message. But ZeroMQ sockets are capable of sending multipart messages, and this is even mandatory for eg. the PUB zsocket type, where the first part of the message is the topic.

+

Therefore it makes more sense to accept a sequence of messages to cover the most general case, and that sequence can have a length of one for single-part messages. But with one more tweak: we can accept a sequence of things that can be transformed into zmq::Message values. The exact type we'll use will be a generic type like so:

+
pub struct ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    mpsc_receiver: calloop::channel::Channel<T>,
+	// ...
+}
+
+
+

Enforcing single messages

+

Remember that it's not just Vec<T> and other sequence types that implement IntoIteratorOption<T> implements it too! There is also std::iter::Once<T>. So if a user of our API wants to enforce that all "multi"-part messages actually contain exactly one part, they can use this API with T being, say, std::iter::Once<zmq::Message> (or even just [zmq::Message; 1] in Rust 2021 edition).

+
+

Associated types

+

The EventSource trait has four associated types:

+
    +
  • +

    Event - when an event is generated that our caller cares about (ie. not some internal thing), this is the data we provide to their callback. This will be another sequence of messages, but because we're constructing it we can be more opinionated about the type and use the return type of zmq::Socket::recv_multipart() which is Vec<Vec<u8>>.

    +
  • +
  • +

    Metadata - this is a more persistent kind of data, perhaps the underlying file descriptor or socket, or maybe some stateful object that the callback can manipulate. It is passed by exclusive reference to the Metadata type. In our case we don't use this, so it's ().

    +
  • +
  • +

    Ret - this is the return type of the callback that's called on an event. Usually this will be a Result of some sort; in our case it's std::io::Result<()> just to signal whether some underlying operation failed or not.

    +
  • +
  • +

    Error - this is the error type returned by process_events() (not the user callback!). Having this as an associated type allows you to have more control over error propagation in nested event sources. We will use Anyhow, which is like a more fully-features Box<dyn Error>. It allows you to add context to any other error with a context() method.

    +
  • +
+

So together these are:

+
impl<T> calloop::EventSource for ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    type Event = Vec<Vec<u8>>;
+    type Metadata = ();
+    type Ret = io::Result<()>;
+    type Error = anyhow::Error;
+    // ...
+}
+
+
+

I have saved one surprise for later to emphasise some important principles, but for now, let's move on to defining some methods!

+

Creating our source, part II: setup methods

+

Now that we've figured out the types we need, we can get to work writing some methods. We'll need to implement the methods defined in the calloop::EventSource trait, and a constructor function to create the source.

+

Our constructor

+

Creating our source is fairly straightforward. We can let the caller set up the zsocket the way they need, and take ownership of it when it's initialised. Our caller needs not only the source itself, but the sending end of the MPSC channel so they can send messages, so we need to return that too.

+

A common pattern in Calloop's own constructor functions is to return a tuple containing (a) the source and (b) a type to use the source. So that's what we'll do:

+
// Converts a `zmq::Socket` into a `ZeroMQSource` plus the sending end of an
+// MPSC channel to enqueue outgoing messages.
+pub fn from_socket(socket: zmq::Socket) -> io::Result<(Self, calloop::channel::Sender<T>)> {
+    let (mpsc_sender, mpsc_receiver) = calloop::channel::channel();
+    let (wake_ping_sender, wake_ping_receiver) = calloop::ping::make_ping()?;
+
+    let fd = socket.get_fd()?;
+
+    let socket_source =
+        calloop::generic::Generic::from_fd(fd, calloop::Interest::READ, calloop::Mode::Edge);
+
+    Ok((
+        Self {
+            socket,
+            socket_source,
+            mpsc_receiver,
+            wake_ping_receiver,
+            wake_ping_sender,
+        },
+        mpsc_sender,
+    ))
+}
+
+

Trait methods: registering sources

+

Calloop's event sources have a kind of life cycle, starting with registration. When you add an event source to the event loop, under the hood the source will register itself with the loop. Under certain circumstances a source will need to re-register itself. And finally there is the unregister action when an event source is removed from the loop. These are expressed via the calloop::EventSource methods:

+
    +
  • fn register(&mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory) -> calloop::Result<()>
  • +
  • fn reregister(&mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory) -> calloop::Result<()>
  • +
  • fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()>
  • +
+

The first two methods take a token factory, which is a way for Calloop to keep track of why your source was woken up. When we get to actually processing events, you'll see how this works. But for now, all you need to do is recursively pass the token factory into whatever sources your own event source is composed of. This includes other composed sources, which will pass the token factory into their sources, and so on.

+

In practise this looks like:

+
fn register(
+    &mut self,
+    poll: &mut calloop::Poll,
+    token_factory: &mut calloop::TokenFactory
+) -> calloop::Result<()>
+{
+    self.socket_source.register(poll, token_factory)?;
+    self.mpsc_receiver.register(poll, token_factory)?;
+    self.wake_ping_receiver.register(poll, token_factory)?;
+    self.wake_ping_sender.ping();
+
+    Ok(())
+}
+
+fn reregister(
+    &mut self,
+    poll: &mut calloop::Poll,
+    token_factory: &mut calloop::TokenFactory
+) -> calloop::Result<()>
+{
+    self.socket_source.reregister(poll, token_factory)?;
+    self.mpsc_receiver.reregister(poll, token_factory)?;
+    self.wake_ping_receiver.reregister(poll, token_factory)?;
+
+    self.wake_ping_sender.ping();
+
+    Ok(())
+}
+
+
+fn unregister(&mut self, poll: &mut calloop::Poll)-> calloop::Result<()> {
+    self.socket_source.unregister(poll)?;
+    self.mpsc_receiver.unregister(poll)?;
+    self.wake_ping_receiver.unregister(poll)?;
+    Ok(())
+}
+
+
+

Note the self.wake_ping_sender.ping() call in the first two functions! This is how we manually prompt the event loop to wake up and run our source on the next iteration, to properly account for the zsocket's edge-triggering.

+
+

Our drop handler

+

ZeroMQ sockets have their own internal queues and state, and therefore need a bit of care when shutting down. Depending on zsocket type and settings, when the ZeroMQ context is dropped, it could block waiting for certain operations to complete. We can write a drop handler to avoid this, but again note that it's only one of many ways to handle zsocket shutdown.

+
impl<T> Drop for ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    fn drop(&mut self) {
+        // This is one way to stop socket code (especially PUSH sockets) hanging
+        // at the end of any blocking functions.
+        //
+        // - https://stackoverflow.com/a/38338578/188535
+        // - http://api.zeromq.org/4-0:zmq-ctx-term
+        self.socket.set_linger(0).ok();
+        self.socket.set_rcvtimeo(0).ok();
+        self.socket.set_sndtimeo(0).ok();
+
+        // Double result because (a) possible failure on call and (b) possible
+        // failure decoding.
+        if let Ok(Ok(last_endpoint)) = self.socket.get_last_endpoint() {
+            self.socket.disconnect(&last_endpoint).ok();
+        }
+    }
+}
+
+

Creating our source, part III: processing events (almost)

+

Finally, the real functionality we care about! Processing events! This is also a method in the calloop::EventSource trait:

+
fn process_events<F>(
+    &mut self,
+    readiness: calloop::Readiness,
+    token: calloop::Token,
+    mut callback: F,
+) -> Result<calloop::PostAction, Self::Error>
+where
+    F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+
+

What a mouthful! But when you break it down, it's not so complicated:

+
    +
  • +

    We take our own state, of course, as &mut self.

    +
  • +
  • +

    We take a Readiness value - this is mainly useful for "real" file descriptors, and tells you whether the event source was woken up for a read or write event. We ignore it though, because our internal sources are always only readable (remember that even if the zsocket is writeable, the FD it exposes is only ever readable).

    +
  • +
  • +

    We take a token. This gives us a way to process events that arise from our internal sources. In general, composed sources should not actually need to use this directly; sub-sources will check their own tokens against this and run if necessary.

    +
  • +
  • +

    We take a callback. We call this callback with any "real" events that our caller will care about; in our case, that means messages we receive on the zsocket. It is closely related to the EventSource trait's associated types. Note that the callback our caller supplies when adding our source to the loop actually takes an extra argument, which is some data that we won't know about in our source. Calloop's internals take care of combining our arguments here with this extra data.

    +
  • +
  • +

    Finally we return a PostAction, which tells the loop whether it needs to change the state of our event source, perhaps as a result of actions we took. For example, you might require that your source be removed from the loop (with PostAction::Remove) if it only has a certain thing to do. Ordinarily though, you'd return PostAction::Continue for your source to keep waiting for events.

    +
  • +
+

Note that these PostAction values correspond to various methods on the LoopHandle type (eg. PostAction::Disable does the same as LoopHandle::disable()). Whether you control your event source by returning a PostAction or using the LoopHandle methods depends on whether it makes more sense for these actions to be taken from within your event source or by something else in your code.

+

Implementing process_events() for a type that contains various Calloop sources composed together, like we have, is done recursively by calling our internal sources' process_events() method. The token that Calloop gives us is how each event source determines whether it was responsible for the wakeup and has events to process.

+

If we were woken up because of the ping source, then the ping source's process_events() will see that the token matches its own, and call the callback (possibly multiple times). If we were woken up because a message was sent through the MPSC channel, then the channel's process_events() will match on the token instead and call the callback for every message waiting. The zsocket is a little different, and we'll go over that in detail.

+

For error handling we're using Anyhow, hence the context() calls on each fallible operation. These just add a message to any error that might appear in a traceback.

+

So a first draft of our code might look like:

+
fn process_events<F>(
+    &mut self,
+    readiness: calloop::Readiness,
+    token: calloop::Token,
+    mut callback: F,
+) -> Result<calloop::PostAction, Self::Error>
+where
+    F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+{
+    // Runs if we were woken up on startup/registration.
+    self.wake_ping_receiver
+        .process_events(readiness, token, |_, _| {})
+        .context("Failed after registration")?;
+
+    // Runs if we received a message over the MPSC channel.
+    self.mpsc_receiver
+        .process_events(readiness, token, |evt, _| {
+            // 'evt' could be a message or a "sending end closed"
+            // notification. We don't care about the latter.
+            if let calloop::channel::Event::Msg(msg) = evt {
+                self.socket
+                    .send_multipart(msg, 0)
+                    .context("Failed to send message")?;
+            }
+        })?;
+
+	// Runs if the zsocket became read/write-able.
+    self.socket
+        .process_events(readiness, token, |_, _| {
+            let events =
+                self.socket
+                    .get_events()
+                    .context("Failed to read ZeroMQ events")?;
+        
+            if events.contains(zmq::POLLOUT) {
+                // Wait, what do we do here?
+            }
+
+            if events.contains(zmq::POLLIN) {
+                let messages =
+                    self.socket
+                        .recv_multipart(0)
+                        .context("Failed to receive message")?;
+
+                callback(messages, &mut ())
+                    .context("Error in event callback")?;
+            }
+        })?;
+
+    Ok(calloop::PostAction::Continue)
+}
+
+

We process the events from whichever source woke up our composed source, and if we woke up because the zsocket became readable, we call the callback with the message we received. Finally we return PostAction::Continue to remain in the event loop.

+

Don't worry about getting this to compile, it is a good start but it's wrong in a few ways.

+

Firstly, we've gone to all the trouble of using a ping to wake up the source, and then we just... drain its internal events and return. Which achieves nothing.

+

Secondly, we don't seem to know what to do when our zsocket becomes writeable (the actual zsocket, not the "interface" file descriptor).

+

Thirdly, we commit one of the worst sins you can commit in an event-loop-based system. Can you see it? It's this part:

+
self.mpsc_receiver
+    .process_events(readiness, token, |evt, _| {
+        if let calloop::channel::Event::Msg(msg) = evt {
+            self.socket
+                .file
+                .send_multipart(msg, 0)
+                .context("Failed to send message")?;
+        }
+    })?;
+
+

We block the event loop! In the middle of processing events from the MPSC channel, we call zmq::Socket::send_multipart() which could, under certain circumstances, block! We shouldn't do that.

+

Let's deal with this badness first then. We want to decouple "receiving messages over the MPSC channel" from "sending messages on the zsocket". There are different ways to do this, but they boil down to: buffer messages or drop messages (or maybe a combination of both). We'll use the first approach, with an internal FIFO queue. When we receive messages, we push them onto the back of the queue. When the zsocket is writeable, we pop messages from the front of the queue.

+

The standard library has collections::VecDeque<T> which provides efficient double-ended queuing, so let's use that. This is some extra internal state, so we need to add it to our type, which becomes:

+
pub struct ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    // Calloop components.
+    socket: calloop::generic::Generic<calloop::generic::FdWrapper<zmq::Socket>>,
+    mpsc_receiver: calloop::channel::Channel<T>,
+    wake_ping_receiver: calloop::ping::PingSource,
+
+    /// Sending end of the ping source.
+    wake_ping_sender: calloop::ping::Ping,
+
+    /// FIFO queue for the messages to be published.
+    outbox: std::collections::VecDeque<T>,
+}
+
+

Our MPSC receiving code becomes:

+
let outbox = &mut self.outbox;
+
+self.mpsc_receiver
+    .process_events(readiness, token, |evt, _| {
+        if let calloop::channel::Event::Msg(msg) = evt {
+            outbox.push_back(msg);
+        }
+    })?;
+
+

And our "zsocket is writeable" code becomes:

+
self.socket
+    .file
+    .process_events(readiness, token, |_, _| {
+        let events = self
+            .socket
+            .file
+            .get_events()
+            .context("Failed to read ZeroMQ events")?;
+    
+        if events.contains(zmq::POLLOUT) {
+            if let Some(parts) = self.outbox.pop_front() {
+                self.socket
+                    .file
+                    .send_multipart(parts, 0)
+                    .context("Failed to send message")?;
+            }
+       }
+
+        if events.contains(zmq::POLLIN) {
+            let messages =
+                self.socket
+                    .file
+                    .recv_multipart(0)
+                    .context("Failed to receive message")?;
+            callback(messages, &mut ())
+                .context("Error in event callback")?;
+        }
+    })?;
+
+
+

So we've not only solved problem #3, we've also figured out #2, which suggests we're on the right track. But we still have (at least) that first issue to sort out.

+

Creating our source, part IV: processing events (really)

+

We have three events that could wake up our event source: the ping, the channel, and the zsocket itself becoming ready to use. All three of these reasons potentially mean doing something on the zsocket: if the ping fired, we need to check for any pending events. If the channel received a message, we want to check if the zsocket is already readable and send it. If the zsocket becomes readable or writeable, we want to read from or write to it. In other words... We want to run it every time!

+

Also notice that in the zsocket process_events() call, we don't use any of the arguments, including the event itself. That file descriptor is merely a signalling mechanism! Sending and receiving messages is what will actually clear any pending events on it, and reset it to a state where it will wake the event loop later.

+
let events = self
+    .socket
+    .get_events()
+    .context("Failed to read ZeroMQ events")?;
+
+if events.contains(zmq::POLLOUT) {
+    if let Some(parts) = self.outbox.pop_front() {
+        self.socket
+            .send_multipart(parts, 0)
+            .context("Failed to send message")?;
+    }
+}
+
+if events.contains(zmq::POLLIN) {
+    let messages =
+        self.socket
+            .recv_multipart(0)
+            .context("Failed to receive message")?;
+    callback(messages, &mut ())
+        .context("Error in event callback")?;
+}
+
+

So the second draft of our process_events() function is now:

+
fn process_events<F>(
+    &mut self,
+    readiness: calloop::Readiness,
+    token: calloop::Token,
+    mut callback: F,
+) -> Result<calloop::PostAction, Self::Error>
+where
+    F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+{
+    // Runs if we were woken up on startup/registration.
+    self.wake_ping_receiver
+        .process_events(readiness, token, |_, _| {})?;
+
+    // Runs if we were woken up because a message was sent on the channel.
+    let outbox = &mut self.outbox;
+
+    self.mpsc_receiver
+        .process_events(readiness, token, |evt, _| {
+            if let calloop::channel::Event::Msg(msg) = evt {
+                outbox.push_back(msg);
+            }
+        })?;
+
+	// Always process any pending zsocket events.
+
+    let events = self
+        .socket
+        .get_events()
+        .context("Failed to read ZeroMQ events")?;
+
+    if events.contains(zmq::POLLOUT) {
+        if let Some(parts) = self.outbox.pop_front() {
+            self.socket
+                .send_multipart(parts, 0)
+                .context("Failed to send message")?;
+        }
+    }
+
+    if events.contains(zmq::POLLIN) {
+        let messages =
+            self.socket
+                .recv_multipart(0)
+                .context("Failed to receive message")?;
+        callback(messages, &mut ())
+            .context("Error in event callback")?;
+    }
+
+    Ok(calloop::PostAction::Continue)
+}
+
+

There is one more issue to take care of, and it's got nothing to do with Calloop. We still haven't fully dealt with ZeroMQ's edge-triggered nature.

+

Consider this situation:

+
    +
  • We create a REQ zsocket. These are intended to be used in strict send/receive/send/receive/etc. sequence.
  • +
  • We wrap it in our ZeroMQSource and add that to our loop.
  • +
  • We send a message.
  • +
+

If we do this, it's possible we'll never actually receive any replies that are sent to our zsocket! Why? Because:

+
    +
  • we read the events on the socket into events
  • +
  • then we send a message on the socket
  • +
  • another process sends a reply so quickly, it arrives more or less immediately
  • +
  • then we use the same events to check if the socket is readable
  • +
  • then we exit
  • +
+

The zsocket will change from writeable to readable before we leave process_events(). So the "interface" file descriptor will become readable again. But because it is edge triggered, it will not wake up our event source after we leave process_events(). So our source will not wake up again (at least, not due to the self.socket event source).

+

For this specific example, it will suffice to re-read the zsocket events in between the if statements. Then when we get to the second events check, it will indeed contain zmq::POLLIN and receive the pending message. But this is not good enough for the general case! If we replace REQ with REP above, we'll get the opposite problem: our first check (for POLLOUT) will be false. Our second check (POLLIN) will be true. We'll receive a message, leave process_events(), and never wake up again.

+

The full solution is to recognise that any user action on a ZeroMQ socket can cause the pending events to change, or just to remain active, without re-triggering the "interface" file descriptor. So we need to (a) do this repeatedly and (b) keep track of when we have or haven't performed an action on the zsocket. Here's one way to do it:

+
loop {
+    let events = self
+        .socket
+        .get_events()
+        .context("Failed to read ZeroMQ events")?;
+
+    let mut used_socket = false;
+
+    if events.contains(zmq::POLLOUT) {
+        if let Some(parts) = self.outbox.pop_front() {
+            self.socket
+                .as_ref()
+                .send_multipart(parts, 0)
+                .context("Failed to send message")?;
+            used_socket = true;
+        }
+    }
+
+    if events.contains(zmq::POLLIN) {
+        let messages =
+            self.socket
+                .recv_multipart(0)
+                .context("Failed to receive message")?;
+        used_socket = true;
+
+        callback(messages, &mut ())
+            .context("Error in event callback")?;
+    }
+
+    if !used_socket {
+        break;
+    }
+}
+
+

Now we have a flag that we set if, and only if, we call a send or receive method on the zsocket. If that flag is set at the end of the loop, we go around again.

+
+

Greediness

+

Remember my disclaimer at the start of the chapter, about this code being "greedy"? This is what I mean. This loop will run until the entire message queue is empty, so if it has a lot of messages in it, any other sources in our event loop will not be run until this loop is finished.

+

An alternative approach is to use more state to determine whether we want to run again on the next loop iteration (perhaps using the ping source), so that Calloop can run any other sources in between individual messages being received.

+
+

The full ZeroMQ event source code

+

This is the full source code for a Calloop event source based on a ZeroMQ socket. You might find it useful as a kind of reference. Please read the disclaimer at the start of this chapter if you skipped straight here!

+
//! A Calloop event source implementation for ZeroMQ sockets.
+
+use std::{collections, io};
+
+use anyhow::Context;
+
+/// A Calloop event source that contains a ZeroMQ socket (of any kind) and a
+/// Calloop MPSC channel for sending over it.
+///
+/// The basic interface is:
+/// - create a zmq::Socket for your ZeroMQ socket
+/// - use `ZeroMQSource::from_socket()` to turn it into a Calloop event source
+///   (plus the sending end of the channel)
+/// - queue messages to be sent by sending them on the sending end of the MPSC
+///   channel
+/// - add the event source to the Calloop event loop with a callback to handle
+///   reading
+/// - the sending end of the MPSC channel can be cloned and sent across threads
+///   if necessary
+///
+/// This type is parameterised by `T`:
+///
+///     T where T: IntoIterator, T::Item: Into<zmq::Message>
+//
+/// This means that `T` is anything that can be converted to an iterator, and
+/// the items in the iterator are anything that can be converted to a
+/// `zmq::Message`. So eg. a `Vec<String>` would work.
+///
+/// The callback is called whenever the underlying socket becomes readable. It
+/// is called with a vec of byte sequences (`Vec<Vec<u8>>`) and the event loop
+/// data set by the user.
+///
+/// Note about why the read data is a vec of multipart message parts: we don't
+/// know what kind of socket this is, or what will be sent, so the most general
+/// thing we can do is receive the entirety of a multipart message and call the
+/// user callback with the whole set. Usually the number of parts in a multipart
+/// message will be one, but the code will work just the same when it's not.
+///
+/// This event source also allows you to use different event sources to publish
+/// messages over the same writeable ZeroMQ socket (usually PUB or PUSH).
+/// Messages should be sent over the Calloop MPSC channel sending end. This end
+/// can be cloned and used by multiple senders.
+
+pub struct ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    // Calloop components.
+    /// Event source for ZeroMQ socket.
+    socket: calloop::generic::Generic<calloop::generic::FdWrapper<zmq::Socket>>,
+
+    /// Event source for channel.
+    mpsc_receiver: calloop::channel::Channel<T>,
+
+    /// Because the ZeroMQ socket is edge triggered, we need a way to "wake" the
+    /// event source upon (re-)registration. We do this with a separate
+    /// `calloop::ping::Ping` source.
+    wake_ping_receiver: calloop::ping::PingSource,
+
+    /// Sending end of the ping source.
+    wake_ping_sender: calloop::ping::Ping,
+
+    // ZeroMQ socket.
+    /// FIFO queue for the messages to be published.
+    outbox: collections::VecDeque<T>,
+}
+
+impl<T> ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    // Converts a `zmq::Socket` into a `ZeroMQSource` plus the sending end of an
+    // MPSC channel to enqueue outgoing messages.
+    pub fn from_socket(socket: zmq::Socket) -> io::Result<(Self, calloop::channel::Sender<T>)> {
+        let (mpsc_sender, mpsc_receiver) = calloop::channel::channel();
+        let (wake_ping_sender, wake_ping_receiver) = calloop::ping::make_ping()?;
+
+        let socket = calloop::generic::Generic::new(
+            unsafe { calloop::generic::FdWrapper::new(socket) },
+            calloop::Interest::READ,
+            calloop::Mode::Edge,
+        );
+
+        Ok((
+            Self {
+                socket,
+                mpsc_receiver,
+                wake_ping_receiver,
+                wake_ping_sender,
+                outbox: collections::VecDeque::new(),
+            },
+            mpsc_sender,
+        ))
+    }
+}
+
+/// This event source runs for three events:
+///
+/// 1. The event source was registered. It is forced to run so that any pending
+///    events on the socket are processed.
+///
+/// 2. A message was sent over the MPSC channel. In this case we put it in the
+///    internal queue.
+///
+/// 3. The ZeroMQ socket is readable. For this, we read off a complete multipart
+///    message and call the user callback with it.
+///
+/// The callback provided to `process_events()` may be called multiple times
+/// within a single call to `process_events()`.
+impl<T> calloop::EventSource for ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    type Event = Vec<Vec<u8>>;
+    type Metadata = ();
+    type Ret = io::Result<()>;
+    type Error = anyhow::Error;
+
+    fn process_events<F>(
+        &mut self,
+        readiness: calloop::Readiness,
+        token: calloop::Token,
+        mut callback: F,
+    ) -> Result<calloop::PostAction, Self::Error>
+    where
+        F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,
+    {
+        // Runs if we were woken up on startup/registration.
+        self.wake_ping_receiver
+            .process_events(readiness, token, |_, _| {})
+            .context("Failed after registration")?;
+
+        // Runs if we were woken up because a message was sent on the channel.
+        let outbox = &mut self.outbox;
+
+        self.mpsc_receiver
+            .process_events(readiness, token, |evt, _| {
+                if let calloop::channel::Event::Msg(msg) = evt {
+                    outbox.push_back(msg);
+                }
+            })
+            .context("Failed to processing outgoing messages")?;
+
+        // The ZeroMQ file descriptor is edge triggered. This means that if (a)
+        // messages are added to the queue before registration, or (b) the
+        // socket became writeable before messages were enqueued, we will need
+        // to run the loop below. Hence, it always runs if this event source
+        // fires. The process_events() method doesn't do anything though, so we
+        // ignore it.
+
+        loop {
+            // According to the docs, the edge-triggered FD will not change
+            // state if a socket goes directly from being readable to being
+            // writeable (or vice-versa) without there being an in-between point
+            // where there are no events. This can happen as a result of sending
+            // or receiving on the socket while processing such an event. The
+            // "used_socket" flag below tracks whether we perform an operation
+            // on the socket that warrants reading the events again.
+            let events = self
+                .socket
+                .get_ref()
+                .get_events()
+                .context("Failed to read ZeroMQ events")?;
+
+            let mut used_socket = false;
+
+            if events.contains(zmq::POLLOUT) {
+                if let Some(parts) = self.outbox.pop_front() {
+                    self.socket
+                        .get_ref()
+                        .send_multipart(parts, 0)
+                        .context("Failed to send message")?;
+                    used_socket = true;
+                }
+            }
+
+            if events.contains(zmq::POLLIN) {
+                // Batch up multipart messages. ZeroMQ guarantees atomic message
+                // sending, which includes all parts of a multipart message.
+                let messages = self
+                    .socket
+                    .get_ref()
+                    .recv_multipart(0)
+                    .context("Failed to receive message")?;
+                used_socket = true;
+
+                // Capture and report errors from the callback, but don't propagate
+                // them up.
+                callback(messages, &mut ()).context("Error in event callback")?;
+            }
+
+            if !used_socket {
+                break;
+            }
+        }
+
+        Ok(calloop::PostAction::Continue)
+    }
+
+    fn register(
+        &mut self,
+        poll: &mut calloop::Poll,
+        token_factory: &mut calloop::TokenFactory,
+    ) -> calloop::Result<()> {
+        self.socket.register(poll, token_factory)?;
+        self.mpsc_receiver.register(poll, token_factory)?;
+        self.wake_ping_receiver.register(poll, token_factory)?;
+
+        self.wake_ping_sender.ping();
+
+        Ok(())
+    }
+
+    fn reregister(
+        &mut self,
+        poll: &mut calloop::Poll,
+        token_factory: &mut calloop::TokenFactory,
+    ) -> calloop::Result<()> {
+        self.socket.reregister(poll, token_factory)?;
+        self.mpsc_receiver.reregister(poll, token_factory)?;
+        self.wake_ping_receiver.reregister(poll, token_factory)?;
+
+        self.wake_ping_sender.ping();
+
+        Ok(())
+    }
+
+    fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> {
+        self.socket.unregister(poll)?;
+        self.mpsc_receiver.unregister(poll)?;
+        self.wake_ping_receiver.unregister(poll)?;
+        Ok(())
+    }
+}
+
+impl<T> Drop for ZeroMQSource<T>
+where
+    T: IntoIterator,
+    T::Item: Into<zmq::Message>,
+{
+    fn drop(&mut self) {
+        // This is one way to stop socket code (especially PUSH sockets) hanging
+        // at the end of any blocking functions.
+        //
+        // - https://stackoverflow.com/a/38338578/188535
+        // - http://api.zeromq.org/4-0:zmq-ctx-term
+        self.socket.get_ref().set_linger(0).ok();
+        self.socket.get_ref().set_rcvtimeo(0).ok();
+        self.socket.get_ref().set_sndtimeo(0).ok();
+
+        // Double result because (a) possible failure on call and (b) possible
+        // failure decoding.
+        if let Ok(Ok(last_endpoint)) = self.socket.get_ref().get_last_endpoint() {
+            self.socket.get_ref().disconnect(&last_endpoint).ok();
+        }
+    }
+}
+
+pub fn main() {}
+
+

Dependencies are:

+
    +
  • calloop (whatever version this document was built from)
  • +
  • zmq 0.9
  • +
  • anyhow 1.0
  • +
+
[dependencies]
+calloop = { path = '../..' }
+zmq = "0.9"
+anyhow = "1.0"
+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/searcher.js b/searcher.js new file mode 100644 index 00000000..d2b0aeed --- /dev/null +++ b/searcher.js @@ -0,0 +1,483 @@ +"use strict"; +window.search = window.search || {}; +(function search(search) { + // Search functionality + // + // You can use !hasFocus() to prevent keyhandling in your key + // event handlers while the user is typing their search. + + if (!Mark || !elasticlunr) { + return; + } + + //IE 11 Compatibility from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith + if (!String.prototype.startsWith) { + String.prototype.startsWith = function(search, pos) { + return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; + }; + } + + var search_wrap = document.getElementById('search-wrapper'), + searchbar = document.getElementById('searchbar'), + searchbar_outer = document.getElementById('searchbar-outer'), + searchresults = document.getElementById('searchresults'), + searchresults_outer = document.getElementById('searchresults-outer'), + searchresults_header = document.getElementById('searchresults-header'), + searchicon = document.getElementById('search-toggle'), + content = document.getElementById('content'), + + searchindex = null, + doc_urls = [], + results_options = { + teaser_word_count: 30, + limit_results: 30, + }, + search_options = { + bool: "AND", + expand: true, + fields: { + title: {boost: 1}, + body: {boost: 1}, + breadcrumbs: {boost: 0} + } + }, + mark_exclude = [], + marker = new Mark(content), + current_searchterm = "", + URL_SEARCH_PARAM = 'search', + URL_MARK_PARAM = 'highlight', + teaser_count = 0, + + SEARCH_HOTKEY_KEYCODE = 83, + ESCAPE_KEYCODE = 27, + DOWN_KEYCODE = 40, + UP_KEYCODE = 38, + SELECT_KEYCODE = 13; + + function hasFocus() { + return searchbar === document.activeElement; + } + + function removeChildren(elem) { + while (elem.firstChild) { + elem.removeChild(elem.firstChild); + } + } + + // Helper to parse a url into its building blocks. + function parseURL(url) { + var a = document.createElement('a'); + a.href = url; + return { + source: url, + protocol: a.protocol.replace(':',''), + host: a.hostname, + port: a.port, + params: (function(){ + var ret = {}; + var seg = a.search.replace(/^\?/,'').split('&'); + var len = seg.length, i = 0, s; + for (;i': '>', + '"': '"', + "'": ''' + }; + var repl = function(c) { return MAP[c]; }; + return function(s) { + return s.replace(/[&<>'"]/g, repl); + }; + })(); + + function formatSearchMetric(count, searchterm) { + if (count == 1) { + return count + " search result for '" + searchterm + "':"; + } else if (count == 0) { + return "No search results for '" + searchterm + "'."; + } else { + return count + " search results for '" + searchterm + "':"; + } + } + + function formatSearchResult(result, searchterms) { + var teaser = makeTeaser(escapeHTML(result.doc.body), searchterms); + teaser_count++; + + // The ?URL_MARK_PARAM= parameter belongs inbetween the page and the #heading-anchor + var url = doc_urls[result.ref].split("#"); + if (url.length == 1) { // no anchor found + url.push(""); + } + + // encodeURIComponent escapes all chars that could allow an XSS except + // for '. Due to that we also manually replace ' with its url-encoded + // representation (%27). + var searchterms = encodeURIComponent(searchterms.join(" ")).replace(/\'/g, "%27"); + + return '' + result.doc.breadcrumbs + '' + + '' + + teaser + ''; + } + + function makeTeaser(body, searchterms) { + // The strategy is as follows: + // First, assign a value to each word in the document: + // Words that correspond to search terms (stemmer aware): 40 + // Normal words: 2 + // First word in a sentence: 8 + // Then use a sliding window with a constant number of words and count the + // sum of the values of the words within the window. Then use the window that got the + // maximum sum. If there are multiple maximas, then get the last one. + // Enclose the terms in . + var stemmed_searchterms = searchterms.map(function(w) { + return elasticlunr.stemmer(w.toLowerCase()); + }); + var searchterm_weight = 40; + var weighted = []; // contains elements of ["word", weight, index_in_document] + // split in sentences, then words + var sentences = body.toLowerCase().split('. '); + var index = 0; + var value = 0; + var searchterm_found = false; + for (var sentenceindex in sentences) { + var words = sentences[sentenceindex].split(' '); + value = 8; + for (var wordindex in words) { + var word = words[wordindex]; + if (word.length > 0) { + for (var searchtermindex in stemmed_searchterms) { + if (elasticlunr.stemmer(word).startsWith(stemmed_searchterms[searchtermindex])) { + value = searchterm_weight; + searchterm_found = true; + } + }; + weighted.push([word, value, index]); + value = 2; + } + index += word.length; + index += 1; // ' ' or '.' if last word in sentence + }; + index += 1; // because we split at a two-char boundary '. ' + }; + + if (weighted.length == 0) { + return body; + } + + var window_weight = []; + var window_size = Math.min(weighted.length, results_options.teaser_word_count); + + var cur_sum = 0; + for (var wordindex = 0; wordindex < window_size; wordindex++) { + cur_sum += weighted[wordindex][1]; + }; + window_weight.push(cur_sum); + for (var wordindex = 0; wordindex < weighted.length - window_size; wordindex++) { + cur_sum -= weighted[wordindex][1]; + cur_sum += weighted[wordindex + window_size][1]; + window_weight.push(cur_sum); + }; + + if (searchterm_found) { + var max_sum = 0; + var max_sum_window_index = 0; + // backwards + for (var i = window_weight.length - 1; i >= 0; i--) { + if (window_weight[i] > max_sum) { + max_sum = window_weight[i]; + max_sum_window_index = i; + } + }; + } else { + max_sum_window_index = 0; + } + + // add around searchterms + var teaser_split = []; + var index = weighted[max_sum_window_index][2]; + for (var i = max_sum_window_index; i < max_sum_window_index+window_size; i++) { + var word = weighted[i]; + if (index < word[2]) { + // missing text from index to start of `word` + teaser_split.push(body.substring(index, word[2])); + index = word[2]; + } + if (word[1] == searchterm_weight) { + teaser_split.push("") + } + index = word[2] + word[0].length; + teaser_split.push(body.substring(word[2], index)); + if (word[1] == searchterm_weight) { + teaser_split.push("") + } + }; + + return teaser_split.join(''); + } + + function init(config) { + results_options = config.results_options; + search_options = config.search_options; + searchbar_outer = config.searchbar_outer; + doc_urls = config.doc_urls; + searchindex = elasticlunr.Index.load(config.index); + + // Set up events + searchicon.addEventListener('click', function(e) { searchIconClickHandler(); }, false); + searchbar.addEventListener('keyup', function(e) { searchbarKeyUpHandler(); }, false); + document.addEventListener('keydown', function(e) { globalKeyHandler(e); }, false); + // If the user uses the browser buttons, do the same as if a reload happened + window.onpopstate = function(e) { doSearchOrMarkFromUrl(); }; + // Suppress "submit" events so the page doesn't reload when the user presses Enter + document.addEventListener('submit', function(e) { e.preventDefault(); }, false); + + // If reloaded, do the search or mark again, depending on the current url parameters + doSearchOrMarkFromUrl(); + } + + function unfocusSearchbar() { + // hacky, but just focusing a div only works once + var tmp = document.createElement('input'); + tmp.setAttribute('style', 'position: absolute; opacity: 0;'); + searchicon.appendChild(tmp); + tmp.focus(); + tmp.remove(); + } + + // On reload or browser history backwards/forwards events, parse the url and do search or mark + function doSearchOrMarkFromUrl() { + // Check current URL for search request + var url = parseURL(window.location.href); + if (url.params.hasOwnProperty(URL_SEARCH_PARAM) + && url.params[URL_SEARCH_PARAM] != "") { + showSearch(true); + searchbar.value = decodeURIComponent( + (url.params[URL_SEARCH_PARAM]+'').replace(/\+/g, '%20')); + searchbarKeyUpHandler(); // -> doSearch() + } else { + showSearch(false); + } + + if (url.params.hasOwnProperty(URL_MARK_PARAM)) { + var words = decodeURIComponent(url.params[URL_MARK_PARAM]).split(' '); + marker.mark(words, { + exclude: mark_exclude + }); + + var markers = document.querySelectorAll("mark"); + function hide() { + for (var i = 0; i < markers.length; i++) { + markers[i].classList.add("fade-out"); + window.setTimeout(function(e) { marker.unmark(); }, 300); + } + } + for (var i = 0; i < markers.length; i++) { + markers[i].addEventListener('click', hide); + } + } + } + + // Eventhandler for keyevents on `document` + function globalKeyHandler(e) { + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || e.target.type === 'textarea' || e.target.type === 'text') { return; } + + if (e.keyCode === ESCAPE_KEYCODE) { + e.preventDefault(); + searchbar.classList.remove("active"); + setSearchUrlParameters("", + (searchbar.value.trim() !== "") ? "push" : "replace"); + if (hasFocus()) { + unfocusSearchbar(); + } + showSearch(false); + marker.unmark(); + } else if (!hasFocus() && e.keyCode === SEARCH_HOTKEY_KEYCODE) { + e.preventDefault(); + showSearch(true); + window.scrollTo(0, 0); + searchbar.select(); + } else if (hasFocus() && e.keyCode === DOWN_KEYCODE) { + e.preventDefault(); + unfocusSearchbar(); + searchresults.firstElementChild.classList.add("focus"); + } else if (!hasFocus() && (e.keyCode === DOWN_KEYCODE + || e.keyCode === UP_KEYCODE + || e.keyCode === SELECT_KEYCODE)) { + // not `:focus` because browser does annoying scrolling + var focused = searchresults.querySelector("li.focus"); + if (!focused) return; + e.preventDefault(); + if (e.keyCode === DOWN_KEYCODE) { + var next = focused.nextElementSibling; + if (next) { + focused.classList.remove("focus"); + next.classList.add("focus"); + } + } else if (e.keyCode === UP_KEYCODE) { + focused.classList.remove("focus"); + var prev = focused.previousElementSibling; + if (prev) { + prev.classList.add("focus"); + } else { + searchbar.select(); + } + } else { // SELECT_KEYCODE + window.location.assign(focused.querySelector('a')); + } + } + } + + function showSearch(yes) { + if (yes) { + search_wrap.classList.remove('hidden'); + searchicon.setAttribute('aria-expanded', 'true'); + } else { + search_wrap.classList.add('hidden'); + searchicon.setAttribute('aria-expanded', 'false'); + var results = searchresults.children; + for (var i = 0; i < results.length; i++) { + results[i].classList.remove("focus"); + } + } + } + + function showResults(yes) { + if (yes) { + searchresults_outer.classList.remove('hidden'); + } else { + searchresults_outer.classList.add('hidden'); + } + } + + // Eventhandler for search icon + function searchIconClickHandler() { + if (search_wrap.classList.contains('hidden')) { + showSearch(true); + window.scrollTo(0, 0); + searchbar.select(); + } else { + showSearch(false); + } + } + + // Eventhandler for keyevents while the searchbar is focused + function searchbarKeyUpHandler() { + var searchterm = searchbar.value.trim(); + if (searchterm != "") { + searchbar.classList.add("active"); + doSearch(searchterm); + } else { + searchbar.classList.remove("active"); + showResults(false); + removeChildren(searchresults); + } + + setSearchUrlParameters(searchterm, "push_if_new_search_else_replace"); + + // Remove marks + marker.unmark(); + } + + // Update current url with ?URL_SEARCH_PARAM= parameter, remove ?URL_MARK_PARAM and #heading-anchor . + // `action` can be one of "push", "replace", "push_if_new_search_else_replace" + // and replaces or pushes a new browser history item. + // "push_if_new_search_else_replace" pushes if there is no `?URL_SEARCH_PARAM=abc` yet. + function setSearchUrlParameters(searchterm, action) { + var url = parseURL(window.location.href); + var first_search = ! url.params.hasOwnProperty(URL_SEARCH_PARAM); + if (searchterm != "" || action == "push_if_new_search_else_replace") { + url.params[URL_SEARCH_PARAM] = searchterm; + delete url.params[URL_MARK_PARAM]; + url.hash = ""; + } else { + delete url.params[URL_MARK_PARAM]; + delete url.params[URL_SEARCH_PARAM]; + } + // A new search will also add a new history item, so the user can go back + // to the page prior to searching. A updated search term will only replace + // the url. + if (action == "push" || (action == "push_if_new_search_else_replace" && first_search) ) { + history.pushState({}, document.title, renderURL(url)); + } else if (action == "replace" || (action == "push_if_new_search_else_replace" && !first_search) ) { + history.replaceState({}, document.title, renderURL(url)); + } + } + + function doSearch(searchterm) { + + // Don't search the same twice + if (current_searchterm == searchterm) { return; } + else { current_searchterm = searchterm; } + + if (searchindex == null) { return; } + + // Do the actual search + var results = searchindex.search(searchterm, search_options); + var resultcount = Math.min(results.length, results_options.limit_results); + + // Display search metrics + searchresults_header.innerText = formatSearchMetric(resultcount, searchterm); + + // Clear and insert results + var searchterms = searchterm.split(' '); + removeChildren(searchresults); + for(var i = 0; i < resultcount ; i++){ + var resultElem = document.createElement('li'); + resultElem.innerHTML = formatSearchResult(results[i], searchterms); + searchresults.appendChild(resultElem); + } + + // Display results + showResults(true); + } + + fetch(path_to_root + 'searchindex.json') + .then(response => response.json()) + .then(json => init(json)) + .catch(error => { // Try to load searchindex.js if fetch failed + var script = document.createElement('script'); + script.src = path_to_root + 'searchindex.js'; + script.onload = () => init(window.search); + document.head.appendChild(script); + }); + + // Exported functions + search.hasFocus = hasFocus; +})(window.search); diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 00000000..e14679c9 --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Object.assign(window.search, {"doc_urls":["ch00-00-where-to-start.html#calloops-documentation","ch00-00-where-to-start.html#api","ch00-00-where-to-start.html#tutorial","ch01-00-how-an-event-loop-works.html#how-an-event-loop-works","ch01-00-how-an-event-loop-works.html#terminology","ch01-00-how-an-event-loop-works.html#events-and-callbacks","ch01-00-how-an-event-loop-works.html#concurrency-vs-parallelism","ch01-00-how-an-event-loop-works.html#event-loops-vs-async-code","ch01-00-how-an-event-loop-works.html#never-block-the-loop","ch01-00-how-an-event-loop-works.html#calloop-and-composition","ch02-00-event-sources.html#using-event-sources","ch02-01-generic.html#monitoring-a-file-descriptor","ch02-01-generic.html#creating-a-generic-source","ch02-01-generic.html#ownership-and-asfd-wrappers","ch02-02-timers.html#working-with-timers","ch02-02-timers.html#adding-sources-to-the-loop","ch02-02-timers.html#the-whole-program","ch02-03-ping.html#pinging-the-event-loop","ch02-03-ping.html#how-to-use-the-ping-source","ch02-04-channels.html#channels","ch02-05-signals.html#unix-signals","ch02-06-errors.html#error-handling-in-calloop","ch02-06-errors.html#overview","ch02-06-errors.html#the-error-type-on-the-eventsource-trait","ch03-00-async-await.html#asyncawait-in-calloop","ch03-01-run-async-code.html#run-async-code","ch03-01-run-async-code.html#enable-the-executor-feature","ch03-01-run-async-code.html#note-about-threads","ch03-02-async-io-types.html#async-io-types","ch03-02-async-io-types.html#enable-the-futures-io-feature","ch04-00-a-full-example-zeromq.html#a-full-example-zeromq","ch04-00-a-full-example-zeromq.html#disclaimer","ch04-01-composition.html#composing-event-sources","ch04-01-composition.html#the-generic-source","ch04-01-composition.html#the-mpsc-channel-source","ch04-01-composition.html#the-wakeup-call","ch04-02-creating-our-source-part-1-our-types.html#creating-our-source-part-i-our-types","ch04-02-creating-our-source-part-1-our-types.html#the-message-type","ch04-02-creating-our-source-part-1-our-types.html#enforcing-single-messages","ch04-02-creating-our-source-part-1-our-types.html#associated-types","ch04-03-creating-our-source-part-2-setup-methods.html#creating-our-source-part-ii-setup-methods","ch04-03-creating-our-source-part-2-setup-methods.html#our-constructor","ch04-03-creating-our-source-part-2-setup-methods.html#trait-methods-registering-sources","ch04-03-creating-our-source-part-2-setup-methods.html#our-drop-handler","ch04-04-creating-our-source-part-3-processing-events-almost.html#creating-our-source-part-iii-processing-events-almost","ch04-05-creating-our-source-part-4-processing-events-really.html#creating-our-source-part-iv-processing-events-really","ch04-05-creating-our-source-part-4-processing-events-really.html#greediness","ch04-06-the-full-zeromq-event-source-code.html#the-full-zeromq-event-source-code"],"index":{"documentStore":{"docInfo":{"0":{"body":0,"breadcrumbs":3,"title":2},"1":{"body":13,"breadcrumbs":2,"title":1},"10":{"body":45,"breadcrumbs":6,"title":3},"11":{"body":101,"breadcrumbs":9,"title":3},"12":{"body":43,"breadcrumbs":9,"title":3},"13":{"body":89,"breadcrumbs":9,"title":3},"14":{"body":82,"breadcrumbs":6,"title":2},"15":{"body":197,"breadcrumbs":7,"title":3},"16":{"body":41,"breadcrumbs":6,"title":2},"17":{"body":54,"breadcrumbs":7,"title":3},"18":{"body":56,"breadcrumbs":7,"title":3},"19":{"body":0,"breadcrumbs":5,"title":1},"2":{"body":54,"breadcrumbs":2,"title":1},"20":{"body":0,"breadcrumbs":7,"title":2},"21":{"body":0,"breadcrumbs":8,"title":3},"22":{"body":118,"breadcrumbs":6,"title":1},"23":{"body":177,"breadcrumbs":9,"title":4},"24":{"body":21,"breadcrumbs":4,"title":2},"25":{"body":0,"breadcrumbs":8,"title":3},"26":{"body":596,"breadcrumbs":8,"title":3},"27":{"body":33,"breadcrumbs":7,"title":2},"28":{"body":69,"breadcrumbs":8,"title":3},"29":{"body":838,"breadcrumbs":9,"title":4},"3":{"body":40,"breadcrumbs":6,"title":3},"30":{"body":103,"breadcrumbs":6,"title":3},"31":{"body":127,"breadcrumbs":4,"title":1},"32":{"body":58,"breadcrumbs":7,"title":3},"33":{"body":29,"breadcrumbs":6,"title":2},"34":{"body":21,"breadcrumbs":7,"title":3},"35":{"body":190,"breadcrumbs":6,"title":2},"36":{"body":80,"breadcrumbs":11,"title":4},"37":{"body":62,"breadcrumbs":9,"title":2},"38":{"body":32,"breadcrumbs":10,"title":3},"39":{"body":134,"breadcrumbs":9,"title":2},"4":{"body":81,"breadcrumbs":4,"title":1},"40":{"body":20,"breadcrumbs":15,"title":6},"41":{"body":78,"breadcrumbs":10,"title":1},"42":{"body":174,"breadcrumbs":13,"title":4},"43":{"body":78,"breadcrumbs":11,"title":2},"44":{"body":637,"breadcrumbs":15,"title":6},"45":{"body":412,"breadcrumbs":17,"title":7},"46":{"body":49,"breadcrumbs":11,"title":1},"47":{"body":645,"breadcrumbs":13,"title":5},"5":{"body":107,"breadcrumbs":5,"title":2},"6":{"body":40,"breadcrumbs":6,"title":3},"7":{"body":90,"breadcrumbs":8,"title":5},"8":{"body":65,"breadcrumbs":6,"title":3},"9":{"body":47,"breadcrumbs":5,"title":2}},"docs":{"0":{"body":"","breadcrumbs":"Where to start » Calloop's Documentation","id":"0","title":"Calloop's Documentation"},"1":{"body":"If you're looking for calloop's API documentation, they are available on docs.rs for the released versions. There are also the docs of the current development version .","breadcrumbs":"Where to start » API","id":"1","title":"API"},"10":{"body":"Calloop's structure is entirely built around the EventSource trait, which represents something that is capable of generating events. To receive those events, you need to give ownership of the event source to calloop, along with a closure that will be invoked whenever said source generated an event. This is thus a push-based model, that is most suited for contexts where your program needs to react to (unpredictable) outside events, rather than wait efficiently for the completion of some operation it initiated.","breadcrumbs":"Using event sources » Using event sources","id":"10","title":"Using event sources"},"11":{"body":"The Generic event source wraps a file descriptor (\"fd\") and fires its callback any time there are events on it ie. becoming readable or writable, or encountering an error. It's pretty simple, but it's what every other event source is based around. And since the platforms that calloop runs on expose many different kinds of events via fds, it's usually the key to using those events in calloop. For example on Linux, fd-based interfaces are available for GPIO, I2C, USB, UART, network interfaces, timers and many other systems. Integrating these into calloop starts with obtaining the appropriate fd, creating a Generic event source from it, and building up a more useful, abstracted event source around that. A detailed example of this is given for ZeroMQ . You do not have to use a low-level fd either: any type that implements AsFd can be provided. This means that you can use a wrapper type that handles allocation and disposal itself, and implement AsRawFd on it so that Generic can manage it in the event loop.","breadcrumbs":"Using event sources » Monitoring a file descriptor » Monitoring a file descriptor","id":"11","title":"Monitoring a file descriptor"},"12":{"body":"Creating a Generic event source requires three things: An OwnedFd or a wrapper type that implements AsFd The \"interest\" you have in this descriptor — this means, whether you want to generate events when the fd becomes readable, writeable, or both The \"mode\" of event generation - level triggered or edge triggered The easiest constructor to use is the new() method, but if you need control over the associated error type there is also new_with_error() .","breadcrumbs":"Using event sources » Monitoring a file descriptor » Creating a Generic source","id":"12","title":"Creating a Generic source"},"13":{"body":"Rust 1.63 introduced a concept of file descriptor ownership and borrowing through the OwnedFd and BorrowedFd types, which are also available on older Rust versions through the io-lifetimes crate. The AsFd trait provides a way to get a BorrowedFd corresponding to a file, socket, etc. while guaranteeing the fd will be valid for the lifetime of the BorrowedFd. Not all third party crates use AsFd yet, and may instead provide types implementing AsRawFd. 'AsFdWrapper' provides a way to adapt these types. To use this safely, ensure the AsRawFd implementation of the type it wraps returns a valid fd as long as the type exists. And to avoid an fd leak, it should ultimately be closed properly. Safe types like OwnedFd and BorrowedFd should be preferred over RawFds, and the use of RawFds outside of implementing FFI shouldn't be necessary as libraries move to using the IO safe types and traits.","breadcrumbs":"Using event sources » Monitoring a file descriptor » Ownership and AsFd wrappers","id":"13","title":"Ownership and AsFd wrappers"},"14":{"body":"Timer event sources are used to manipulate time-related actions. Those are provided under the calloop::timer module, with the Timer type at its core. A Timer source has a simple behavior: it is programmed to wait for some duration, or until a certain point in time. Once that deadline is reached, the source generates an event. So with use calloop::timer::Timer at the top of our .rs file, we can create a timer that will wait for 5 seconds: # use std::time::Duration;\n# # use calloop::{\n# timer::{TimeoutAction, Timer},\n# EventLoop,\n# };\n# # fn main() {\n# let mut event_loop = EventLoop::try_new().expect(\"Failed to initialize the event loop!\");\n# let timer = Timer::from_duration(Duration::from_secs(5));\n# # event_loop\n# .handle()\n# .insert_source(timer, |deadline, _: &mut (), _shared_data| {\n# println!(\"Event fired for: {:?}\", deadline);\n# TimeoutAction::Drop\n# })\n# .expect(\"Failed to insert event source!\");\n# # event_loop\n# .dispatch(None, &mut ())\n# .expect(\"Error during event loop!\");\n# }","breadcrumbs":"Using event sources » Timers » Working with timers","id":"14","title":"Working with timers"},"15":{"body":"We have an event source, we have our shared data, and we know how to start our loop running. All that is left is to learn how to combine these things: # use std::time::Duration;\n# # use calloop::{\n# timer::{TimeoutAction, Timer},\n# EventLoop,\n# };\n# # fn main() {\n# let mut event_loop = EventLoop::try_new().expect(\"Failed to initialize the event loop!\");\n# # let timer = Timer::from_duration(Duration::from_secs(5));\n# event_loop .handle() .insert_source(timer, |deadline, _: &mut (), _shared_data| { println!(\"Event fired for: {:?}\", deadline); TimeoutAction::Drop }) .expect(\"Failed to insert event source!\");\n# # event_loop\n# .dispatch(None, &mut ())\n# .expect(\"Error during event loop!\");\n# } Breaking this down, the callback we provide receives 3 arguments: The first one is an Instant representing the time at which this timer was scheduled to expire. Due to how the event loop works, it might be that your callback is not invoked at the exact time where the timer expired (if an other callback was being processed at the time for example), so the original deadline is given if you need precise time tracking. The second argument is just &mut (), as the timers don't use the EventSource functionality. The third argumument is the shared data passed to your event loop. In addition your callback is expected to return a TimeoutAction , that will instruct calloop what to do next. This enum has 3 values: Drop will disable the timer and destroy it, freeing the callback. ToInstant will rechedule the callback to fire again at given Instant, invoking the same callback again. This is useful if you need to create a timer that fires events at regular intervals, for example to encode key repetition in a graphical app. You would compute the next instant by adding the duration to the previous instant. It is not a problem if that duration is in the past, it'll simply cause the timer to fire again instantly. THis way, even if some other part of your app lags, you'll still have on average the correct amount of events per second. ToDuration will reschedule the callback to fire again after a given Duration. This is useful if you need to schedule some background task to execute again after some time after it was last completed, when there is no point in catching up some previous lag.","breadcrumbs":"Using event sources » Timers » Adding sources to the loop","id":"15","title":"Adding sources to the loop"},"16":{"body":"Putting it all together, we have: use std::time::Duration; use calloop::{ timer::{TimeoutAction, Timer}, EventLoop,\n}; fn main() { let mut event_loop = EventLoop::try_new().expect(\"Failed to initialize the event loop!\"); let timer = Timer::from_duration(Duration::from_secs(5)); event_loop .handle() .insert_source(timer, |deadline, _: &mut (), _shared_data| { println!(\"Event fired for: {:?}\", deadline); TimeoutAction::Drop }) .expect(\"Failed to insert event source!\"); event_loop .dispatch(None, &mut ()) .expect(\"Error during event loop!\");\n}","breadcrumbs":"Using event sources » Timers » The whole program","id":"16","title":"The whole program"},"17":{"body":"The Ping event source has one very simple job — wake up the event loop. Use this when you know there are events for your event source to process, but those events aren't going to wake the event loop up themselves. For example, calloop's own message channel uses Rust's native MPSC channel internally. Because there's no way for the internal message queue to wake up the event loop, it's coupled with a Ping source that wakes the loop up when there are new messages.","breadcrumbs":"Using event sources » Ping » \"Pinging\" the event loop","id":"17","title":"\"Pinging\" the event loop"},"18":{"body":"The Ping has two ends — the event source part ( PingSource ), that goes in the event loop, and the sending end (Ping) you use to \"send\" the ping. To wake the event loop up, call ping() on the sending end. Do not forget to process the events of the PingSource if you are using it as part of a larger event source! Even though the events carry no information (they are just () values), the process_events() method must be called in order to \"reset\" the PingSource. Otherwise the event loop will be continually woken up until you do, effectively becoming a busy-loop.","breadcrumbs":"Using event sources » Ping » How to use the Ping source","id":"18","title":"How to use the Ping source"},"19":{"body":"","breadcrumbs":"Using event sources » Channels » Channels","id":"19","title":"Channels"},"2":{"body":"This book presents a step-by-step tutorial to get yourself familiar with calloop and how it is used: Chapter 1 presents the general principles of an event loop that are important to have in mind when working with calloop. Chapter 2 goes through the different kind of event sources that are provided in calloop, and provides examples of how to use them Chapter 3 presents the integration with Rust's Async/Await ecosystem provided by calloop Chapter 4 gives a detailed example of building a custom event source in calloop, by combining other sources","breadcrumbs":"Where to start » Tutorial","id":"2","title":"Tutorial"},"20":{"body":"","breadcrumbs":"Using event sources » Unix Signals » Unix Signals","id":"20","title":"Unix Signals"},"21":{"body":"","breadcrumbs":"Using event sources » Error handling » Error handling in Calloop","id":"21","title":"Error handling in Calloop"},"22":{"body":"Most error handling crates/guides/documentation for Rust focus on one of two situations: Creating errors that an API can propagate out to a user of the API, or Making your library deal nicely with the Results from closure or trait methods that it might call Calloop has to do both of these things. It needs to provide a library user with errors that work well with ? and common error-handling idioms in their own code, and it needs to handle errors from the callbacks you give to process_events() or insert_source(). It also needs to provide some flexibility in the EventSource trait, which is used both for internal event sources and by users of the library. Because of this, error handling in Calloop leans more towards having separate error types for different concerns. This may mean that there is some extra conversion code in places like returning results from process_events(), or in callbacks that use other libraries. However, we try to make it smoother to do these conversions, and to make sure information isn't lost in doing so. If your crate already has some form of structured error handling, Calloop's error types should pose no problem to integrate into this. All of Calloop's errors implement std::error::Error and can be manipulated the same as any other error types. The place where this becomes the most complex is in the process_events() method on the EventSource trait.","breadcrumbs":"Using event sources » Error handling » Overview","id":"22","title":"Overview"},"23":{"body":"The EventSource trait contains an associated type named Error, which forms part of the return type from process_events(). This type must be convertible into Box, which means you can use: Your own error type that implements std::error::Error A structured error type created with Thiserror Box A flexible string-based error type such as Anyhow's anyhow::Error As a rule, if you implement EventSource you should try to split your errors into two different categories: Errors that make sense as a kind of event. These should be a part of the Event associated type eg. as an enum or Result. Errors that mean your event source simply cannot process more events. These should form the Error associated type. For an example, take Calloop's channel type, calloop::channel::Channel . When the sending end is dropped, no more messages can be received after that point. But this is not returned as an error when calling process_events(), because you still want to (and can!) receive messages sent before that point that might still be in the queue. Hence the events received by the callback for this source can be Msg(e) or Closed. However, if the internal ping source produces an error, there is no way for the sending end of the channel to notify the receiver. It is impossible to process more events on this event source, and the caller needs to decide how to recover from this situation. Hence this is returned as a ChannelError from process_events(). Another example might be an event source that represents a running subprocess. If the subprocess exits with a non-zero status code, or the executable can't be found, those don't mean that events can no longer be processed. They can be provided to the caller through the callback. But if the lower level sources being used to run (eg. an asynchronous executor or subprocess file descriptor) fail to work as expected, process_events() should return an error.","breadcrumbs":"Using event sources » Error handling » The Error type on the EventSource trait","id":"23","title":"The Error type on the EventSource trait"},"24":{"body":"While it is centered on event sources and callbacks, calloop also provides adapters to integrate with Rust's async ecosystem. These adapters come in two parts: a futures executor and an async adapter for IO type .","breadcrumbs":"I need async/await! » Async/await in calloop","id":"24","title":"Async/await in calloop"},"25":{"body":"","breadcrumbs":"I need async/await! » Run async code » Run async code","id":"25","title":"Run async code"},"26":{"body":"To use calloop::futures you need to enable the executor feature in your Cargo.toml like so: [dependencies.calloop]\nfeatures = [ \"executor\" ]\nversion = ... Let's say you have some async code that looks like this: sender.send(\"Hello,\").await.ok();\nreceiver.next().await.map(|m| println!(\"Received: {}\", m));\nsender.send(\"world!\").await.ok();\nreceiver.next().await.map(|m| println!(\"Received: {}\", m));\n\"So long!\" ...and a corresponding block that receives and sends to this one. I will call one of these blocks \"friendly\" and the other one \"aloof\". To run async code in Calloop, you use the components in calloop::futures . First, obtain both an executor and a scheduler with calloop::futures::executor() : # use calloop::EventLoop;\n# # // futures = \"0.3\"\n# use futures::sink::SinkExt;\n# use futures::stream::StreamExt;\n# # fn main() -> std::io::Result<()> { let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# # // Let's create two channels for our async blocks below. The blocks will\n# // exchange messages via these channels.\n# let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded();\n# let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded();\n# # // Our toy async code.\n# let async_friendly_task = async move {\n# sender_friendly.send(\"Hello,\").await.ok();\n# if let Some(msg) = receiver_aloof.next().await {\n# println!(\"Aloof said: {}\", msg);\n# }\n# sender_friendly.send(\"world!\").await.ok();\n# if let Some(msg) = receiver_aloof.next().await {\n# println!(\"Aloof said: {}\", msg);\n# }\n# \"Bye!\"\n# };\n# # let async_aloof_task = async move {\n# if let Some(msg) = receiver_friendly.next().await {\n# println!(\"Friendly said: {}\", msg);\n# }\n# sender_aloof.send(\"Oh,\").await.ok();\n# if let Some(msg) = receiver_friendly.next().await {\n# println!(\"Friendly said: {}\", msg);\n# }\n# sender_aloof.send(\"it's you.\").await.ok();\n# \"Regards.\"\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_friendly_task).unwrap();\n# sched.schedule(async_aloof_task).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut (), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } The executor , the part that executes the future, goes in the event loop: # use calloop::EventLoop;\n# # // futures = \"0.3\"\n# use futures::sink::SinkExt;\n# use futures::stream::StreamExt;\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# let mut event_loop = EventLoop::try_new()?; let handle = event_loop.handle(); handle .insert_source(exec, |evt, _metadata, _shared| { // Print the value of the async block ie. the return value. println!(\"Async block ended with: {}\", evt); }) .map_err(|e| e.error)?;\n# # // Let's create two channels for our async blocks below. The blocks will\n# // exchange messages via these channels.\n# let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded();\n# let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded();\n# # // Our toy async code.\n# let async_friendly_task = async move {\n# sender_friendly.send(\"Hello,\").await.ok();\n# if let Some(msg) = receiver_aloof.next().await {\n# println!(\"Aloof said: {}\", msg);\n# }\n# sender_friendly.send(\"world!\").await.ok();\n# if let Some(msg) = receiver_aloof.next().await {\n# println!(\"Aloof said: {}\", msg);\n# }\n# \"Bye!\"\n# };\n# # let async_aloof_task = async move {\n# if let Some(msg) = receiver_friendly.next().await {\n# println!(\"Friendly said: {}\", msg);\n# }\n# sender_aloof.send(\"Oh,\").await.ok();\n# if let Some(msg) = receiver_friendly.next().await {\n# println!(\"Friendly said: {}\", msg);\n# }\n# sender_aloof.send(\"it's you.\").await.ok();\n# \"Regards.\"\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_friendly_task).unwrap();\n# sched.schedule(async_aloof_task).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut (), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } Now let's write our async code in full: # use calloop::EventLoop;\n# # // futures = \"0.3\"\n# use futures::sink::SinkExt;\n# use futures::stream::StreamExt;\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# // Let's create two channels for our async blocks below. The blocks will // exchange messages via these channels. let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded(); let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded(); // Our toy async code. let async_friendly_task = async move { sender_friendly.send(\"Hello,\").await.ok(); if let Some(msg) = receiver_aloof.next().await { println!(\"Aloof said: {}\", msg); } sender_friendly.send(\"world!\").await.ok(); if let Some(msg) = receiver_aloof.next().await { println!(\"Aloof said: {}\", msg); } \"Bye!\" }; let async_aloof_task = async move { if let Some(msg) = receiver_friendly.next().await { println!(\"Friendly said: {}\", msg); } sender_aloof.send(\"Oh,\").await.ok(); if let Some(msg) = receiver_friendly.next().await { println!(\"Friendly said: {}\", msg); } sender_aloof.send(\"it's you.\").await.ok(); \"Regards.\" };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_friendly_task).unwrap();\n# sched.schedule(async_aloof_task).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut (), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } Like any block in Rust, the value of your async block is the last expression ie. it is effectively \"returned\" from the block, which means it will be provided to your executor's callback as the first argument (the \"event\"). You'll see this in the output with the Async block ended with: ... lines. Finally, we run the loop: # use calloop::EventLoop;\n# # // futures = \"0.3\"\n# use futures::sink::SinkExt;\n# use futures::stream::StreamExt;\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# # // Let's create two channels for our async blocks below. The blocks will\n# // exchange messages via these channels.\n# let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded();\n# let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded();\n# # // Our toy async code.\n# let async_friendly_task = async move {\n# sender_friendly.send(\"Hello,\").await.ok();\n# if let Some(msg) = receiver_aloof.next().await {\n# println!(\"Aloof said: {}\", msg);\n# }\n# sender_friendly.send(\"world!\").await.ok();\n# if let Some(msg) = receiver_aloof.next().await {\n# println!(\"Aloof said: {}\", msg);\n# }\n# \"Bye!\"\n# };\n# # let async_aloof_task = async move {\n# if let Some(msg) = receiver_friendly.next().await {\n# println!(\"Friendly said: {}\", msg);\n# }\n# sender_aloof.send(\"Oh,\").await.ok();\n# if let Some(msg) = receiver_friendly.next().await {\n# println!(\"Friendly said: {}\", msg);\n# }\n# sender_aloof.send(\"it's you.\").await.ok();\n# \"Regards.\"\n# };\n# // Schedule the async block to be run in the event loop. sched.schedule(async_friendly_task).unwrap(); sched.schedule(async_aloof_task).unwrap(); // Run the event loop. println!(\"Starting event loop. Use Ctrl-C to exit.\"); event_loop.run(None, &mut (), |_| {})?; println!(\"Event loop ended.\");\n# # Ok(())\n# } And our output looks like: Starting event loop.\nFriendly said: Hello,\nAloof said: Oh,\nFriendly said: world!\nAsync block ended with: Regards.\nAloof said: it's you.\nAsync block ended with: Bye!\nEvent loop ended. Note that for the sake of keeping this example short, I've written the async code before running the loop. But async code can be scheduled from callbacks, or other sources within the loop too.","breadcrumbs":"I need async/await! » Run async code » Enable the executor feature!","id":"26","title":"Enable the executor feature!"},"27":{"body":"One of Calloop's strengths is that it is completely single threaded as written. However, many async crates are implemented using threads eg. async-std and async-process. This is not an inherent problem! Calloop will work perfectly well with such implementations in general. However, if you have selected Calloop because of your own constraints around threading, be aware of this.","breadcrumbs":"I need async/await! » Run async code » Note about threads","id":"27","title":"Note about threads"},"28":{"body":"This section is about adapting blocking IO types for use with async Rust code, and powering that async code with Calloop. If you just want to add blocking IO types to your event loop and use Calloop's callback/composition-based design, you only need to wrap your blocking IO type in a generic event source . You may find that you need to write ordinary Rust async code around blocking IO types. Calloop provides the ability to wrap blocking types — anything that implements the AsFd trait — in its own async type. This can be polled in any executor you may have chosen for your async code, but if you're using Calloop you'll probably be using Calloop's executor .","breadcrumbs":"I need async/await! » Async IO types » Async IO types","id":"28","title":"Async IO types"},"29":{"body":"To use calloop::io you need to enable the futures-io feature in your Cargo.toml like so: [dependencies.calloop]\nfeatures = [ \"futures-io\" ]\nversion = ... Realistically you will probably also want to use this with async code, so you should also enable the executor feature too. Just like in the async example, we will use the components in calloop::futures . First, obtain both an executor and a scheduler with calloop::futures::executor() : # use calloop::EventLoop;\n# # use futures::io::{AsyncReadExt, AsyncWriteExt};\n# # fn main() -> std::io::Result<()> { let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# # let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();\n# let mut sender = handle.adapt_io(sender).unwrap();\n# let mut receiver = handle.adapt_io(receiver).unwrap();\n# # let async_receive = async move {\n# let mut buf = [0u8; 12];\n# // Here's our async-ified Unix domain socket.\n# receiver.read_exact(&mut buf).await.unwrap();\n# std::str::from_utf8(&buf).unwrap().to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_receive).unwrap();\n# # let async_send = async move {\n# // Here's our async-ified Unix domain socket.\n# sender.write_all(b\"Hello, world!\").await.unwrap();\n# \"Sent data...\".to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_send).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } The executor goes in the event loop: # use calloop::EventLoop;\n# # use futures::io::{AsyncReadExt, AsyncWriteExt};\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# let mut event_loop = EventLoop::try_new()?; let handle = event_loop.handle(); handle .insert_source(exec, |evt, _metadata, _shared| { // Print the value of the async block ie. the return value. println!(\"Async block ended with: {}\", evt); }) .map_err(|e| e.error)?;\n# # let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();\n# let mut sender = handle.adapt_io(sender).unwrap();\n# let mut receiver = handle.adapt_io(receiver).unwrap();\n# # let async_receive = async move {\n# let mut buf = [0u8; 12];\n# // Here's our async-ified Unix domain socket.\n# receiver.read_exact(&mut buf).await.unwrap();\n# std::str::from_utf8(&buf).unwrap().to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_receive).unwrap();\n# # let async_send = async move {\n# // Here's our async-ified Unix domain socket.\n# sender.write_all(b\"Hello, world!\").await.unwrap();\n# \"Sent data...\".to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_send).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } For our blocking IO types, let's use an unnamed pair of Unix domain stream sockets . To convert them to async types, we simply call calloop::LoopHandle::adapt_io() : # use calloop::EventLoop;\n# # use futures::io::{AsyncReadExt, AsyncWriteExt};\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap(); let mut sender = handle.adapt_io(sender).unwrap(); let mut receiver = handle.adapt_io(receiver).unwrap();\n# # let async_receive = async move {\n# let mut buf = [0u8; 12];\n# // Here's our async-ified Unix domain socket.\n# receiver.read_exact(&mut buf).await.unwrap();\n# std::str::from_utf8(&buf).unwrap().to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_receive).unwrap();\n# # let async_send = async move {\n# // Here's our async-ified Unix domain socket.\n# sender.write_all(b\"Hello, world!\").await.unwrap();\n# \"Sent data...\".to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_send).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } Note that most of the useful async functionality for the returned type is expressed through various traits in futures::io . So we need to explicitly use these: # use calloop::EventLoop;\n# use futures::io::{AsyncReadExt, AsyncWriteExt};\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# # let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();\n# let mut sender = handle.adapt_io(sender).unwrap();\n# let mut receiver = handle.adapt_io(receiver).unwrap();\n# # let async_receive = async move {\n# let mut buf = [0u8; 12];\n# // Here's our async-ified Unix domain socket.\n# receiver.read_exact(&mut buf).await.unwrap();\n# std::str::from_utf8(&buf).unwrap().to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_receive).unwrap();\n# # let async_send = async move {\n# // Here's our async-ified Unix domain socket.\n# sender.write_all(b\"Hello, world!\").await.unwrap();\n# \"Sent data...\".to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_send).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } We can now write async code around these types. Here's the receiving code: # use calloop::EventLoop;\n# # use futures::io::{AsyncReadExt, AsyncWriteExt};\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# # let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();\n# let mut sender = handle.adapt_io(sender).unwrap();\n# let mut receiver = handle.adapt_io(receiver).unwrap();\n# let async_receive = async move { let mut buf = [0u8; 12]; // Here's our async-ified Unix domain socket. receiver.read_exact(&mut buf).await.unwrap(); std::str::from_utf8(&buf).unwrap().to_owned() }; // Schedule the async block to be run in the event loop. sched.schedule(async_receive).unwrap();\n# # let async_send = async move {\n# // Here's our async-ified Unix domain socket.\n# sender.write_all(b\"Hello, world!\").await.unwrap();\n# \"Sent data...\".to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_send).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } And here's the sending code. The receiving and sending code can be created and added to the executor in either order. # use calloop::EventLoop;\n# # use futures::io::{AsyncReadExt, AsyncWriteExt};\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# # let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();\n# let mut sender = handle.adapt_io(sender).unwrap();\n# let mut receiver = handle.adapt_io(receiver).unwrap();\n# # let async_receive = async move {\n# let mut buf = [0u8; 12];\n# // Here's our async-ified Unix domain socket.\n# receiver.read_exact(&mut buf).await.unwrap();\n# std::str::from_utf8(&buf).unwrap().to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_receive).unwrap();\n# let async_send = async move { // Here's our async-ified Unix domain socket. sender.write_all(b\"Hello, world!\").await.unwrap(); \"Sent data...\".to_owned() }; // Schedule the async block to be run in the event loop. sched.schedule(async_send).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } All that's left is to run the loop: # use calloop::EventLoop;\n# # use futures::io::{AsyncReadExt, AsyncWriteExt};\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# # let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();\n# let mut sender = handle.adapt_io(sender).unwrap();\n# let mut receiver = handle.adapt_io(receiver).unwrap();\n# # let async_receive = async move {\n# let mut buf = [0u8; 12];\n# // Here's our async-ified Unix domain socket.\n# receiver.read_exact(&mut buf).await.unwrap();\n# std::str::from_utf8(&buf).unwrap().to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_receive).unwrap();\n# # let async_send = async move {\n# // Here's our async-ified Unix domain socket.\n# sender.write_all(b\"Hello, world!\").await.unwrap();\n# \"Sent data...\".to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_send).unwrap();\n# // Run the event loop. println!(\"Starting event loop. Use Ctrl-C to exit.\"); event_loop.run(None, &mut event_loop.get_signal(), |_| {})?; println!(\"Event loop ended.\");\n# # Ok(())\n# } And the output we get is: Starting event loop. Use Ctrl-C to exit.\nAsync block ended with: Sent data...\nAsync block ended with: Hello, world\n^C","breadcrumbs":"I need async/await! » Async IO types » Enable the futures-io feature!","id":"29","title":"Enable the futures-io feature!"},"3":{"body":"An event loop is one way to write concurrent code. Other ways include threading (sort of), or asynchronous syntax. When you write concurrent code, you need to know two things: where in your program it could potentially block , and how to let other parts of your program run while waiting for those operations to stop blocking This chapter covers what the first thing means, and how Calloop accomplishes the second thing.","breadcrumbs":"How an event loop works » How an event loop works","id":"3","title":"How an event loop works"},"30":{"body":"The previous chapter showed how to use callbacks, event data and shared data to control our program. However, more complex programs will require more complex shared data, and more complex interactions between events. Eventually this will run up against ownership issues and just the basic mental load of the poor programmer. In this chapter we're going to build something more complex: an event source based on ZeroMQ sockets . ZeroMQ is (very) basically a highly abstracted socket library. You can create ZeroMQ sockets over TCP, PGM, IPC, in-process and more, and generally not worry about the transport mechanics. It guarantees atomic message transfer, and handles queuing, retries, reconnection and balancing under the hood. It also lets you integrate it with event loops and reactors by exposing a file descriptor that you can wait on. But we can't just wrap this file descriptor in Calloop's generic::Generic source and be done — there are a few subtleties we need to take care of for it to work right and be useful.","breadcrumbs":"A full example: ZeroMQ » A full example: ZeroMQ","id":"30","title":"A full example: ZeroMQ"},"31":{"body":"It might be tempting, at the end of this chapter, to think that the code we've written is the definitive ZeroMQ wrapper, able to address any use case or higher level pattern you like. Certainly it will be a lot more suited to Calloop than using ZeroMQ sockets by themselves, but it is not the only way to use them with Calloop. Here are some things I have not addressed, for the sake of simplicity: We will not handle fairness — our code will totally monopolise the event loop if we receive many messages at once. We do not consider back pressure beyond whatever built-in zsocket settings the caller might use. We just drop pending messages in the zsocket's internal queue (in and out) on shutdown. In a real application, you might want to make more specific decisions about the timeout and linger periods before dropping the zsocket, depending on your application's requirements. We don't deal with zsocket errors much. In fact, the overall error handling of event sources is usually highly specific to your application, so what we end up writing here is almost certainly not going to survive contact with your own code base. Here we just use ? everywhere, which will eventually cause the event loop to exit with an error. So by all means, take the code we write here and use and adapt it, but please please note the caveats above and think carefully about your own program.","breadcrumbs":"A full example: ZeroMQ » Disclaimer","id":"31","title":"Disclaimer"},"32":{"body":"Calloop is designed to work by composition . It provides you with some single-responsibility sources (timers, message channels, file descriptors), and you can combine these together, bit by bit, to make more complex event sources. These new sources can express more and more of your program's internal logic and the relationships between them, always in terms of events and how you process them. You can greatly simplify even a highly complex program if you identify and expose the \"real\" events you care about and use composition to tidy the other events away in internal details of event sources. So what do we need to compose?","breadcrumbs":"A full example: ZeroMQ » Composition » Composing event sources","id":"32","title":"Composing event sources"},"33":{"body":"Most obviously, ZeroMQ exposes a file descriptor for us to use. (This is a common thing for event-related libraries to do, so if you're wondering how to integrate, say, I²C or GPIO on Linux with Calloop, that's your answer.) Calloop can use file descriptors via the calloop::generic::Generic source. So that's one.","breadcrumbs":"A full example: ZeroMQ » Composition » The generic source","id":"33","title":"The generic source"},"34":{"body":"Secondly, we might want to send messages on the socket. This means our event source needs to react when we send it a message. Calloop has a message channel for precisely this purpose: calloop::channel::Channel. That's another one.","breadcrumbs":"A full example: ZeroMQ » Composition » The MPSC channel source","id":"34","title":"The MPSC channel source"},"35":{"body":"The third event source we need is a bit subtle, but since this isn't a mystery novel I can save you hours of debugging and spoil the ending now: we need a \"ping\" event source because ZeroMQ's FD is edge triggered. ZeroMQ's file descriptor is not the FD of an actual file or socket — you do not actually read data from it. It exists as an interface, with three important details: It is only ever readable. Even if the underlying socket can be written to, the FD that ZeroMQ gives you signals this by becoming readable. In fact, this FD will become readable under three circumstances: the ZeroMQ socket (henceforth called a \"zsocket\") is readable, writeable, or has an error. There is a separate function call, zmq::Socket::get_events() that will tell you which. It is edge triggered. It will only ever change from not-readable to readable when the socket's state changes. So if a zsocket receives two messages, and you only read one, the file descriptor will not wake up the event loop again . Why not? Because it hasn't changed state! After you read one message, the zsocket still has events waiting. If it receives yet another message... it still has events waiting. No change in internal state = no external event. This edge triggering also covers user actions. If a zsocket becomes writeable, and then you write to the zsocket, it might immediately (and atomically) change from writeable to readable. In this case you will not get another event on the FD . (The docs make this quite explicit, but there's a lot of docs to read so I'm spelling it out here.) What this adds up to is this: when we create our zsocket, it might already be readable or writeable. So when we add it to our event loop, it won't fire any events. Our entire source will just sit there until we wake it up by sending a message (which we might never do if it's eg. a pull socket). So the last event source we need is something that doesn't really convey any kind of message except \"please wake up the event loop on the next iteration\", and that is exactly what a calloop::ping::PingSource does. And that's three.","breadcrumbs":"A full example: ZeroMQ » Composition » The wakeup call","id":"35","title":"The wakeup call"},"36":{"body":"In the last chapter we worked out a list of the event sources we need to compose into a new type: calloop::generic::Generic calloop::channel::Channel calloop::ping::Ping So at a minimum, our type needs to contain these: pub struct ZeroMQSource\n{ // Calloop components. socket: calloop::generic::Generic>, mpsc_receiver: calloop::channel::Channel, wake_ping_receiver: calloop::ping::PingSource,\n} Note that I've left the type for the channel as ? — we'll get to that a bit later. What else do we need? If the PingSource is there to wake up the loop manually, we need to keep the other end of it. The ping is an internal detail — users of our type don't need to know it's there. We also need the zsocket itself, so we can actually detect and process events on it. That gives us: pub struct ZeroMQSource\n{ // Calloop components. socket: calloop::generic::Generic>, mpsc_receiver: calloop::channel::Channel, wake_ping_receiver: calloop::ping::PingSource, /// Sending end of the ping source. wake_ping_sender: calloop::ping::Ping,\n}","breadcrumbs":"A full example: ZeroMQ » Creating our source, part I: our types » Creating our source, part I: our types","id":"36","title":"Creating our source, part I: our types"},"37":{"body":"The most obvious candidate for the type of the message queue would be zmq::Message. But ZeroMQ sockets are capable of sending multipart messages, and this is even mandatory for eg. the PUB zsocket type, where the first part of the message is the topic. Therefore it makes more sense to accept a sequence of messages to cover the most general case, and that sequence can have a length of one for single-part messages. But with one more tweak: we can accept a sequence of things that can be transformed into zmq::Message values. The exact type we'll use will be a generic type like so: pub struct ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ mpsc_receiver: calloop::channel::Channel, // ...\n}","breadcrumbs":"A full example: ZeroMQ » Creating our source, part I: our types » The message type","id":"37","title":"The message type"},"38":{"body":"Remember that it's not just Vec and other sequence types that implement IntoIterator — Option implements it too! There is also std::iter::Once. So if a user of our API wants to enforce that all \"multi\"-part messages actually contain exactly one part, they can use this API with T being, say, std::iter::Once (or even just [zmq::Message; 1] in Rust 2021 edition).","breadcrumbs":"A full example: ZeroMQ » Creating our source, part I: our types » Enforcing single messages","id":"38","title":"Enforcing single messages"},"39":{"body":"The EventSource trait has four associated types: Event - when an event is generated that our caller cares about (ie. not some internal thing), this is the data we provide to their callback. This will be another sequence of messages, but because we're constructing it we can be more opinionated about the type and use the return type of zmq::Socket::recv_multipart() which is Vec>. Metadata - this is a more persistent kind of data, perhaps the underlying file descriptor or socket, or maybe some stateful object that the callback can manipulate. It is passed by exclusive reference to the Metadata type. In our case we don't use this, so it's (). Ret - this is the return type of the callback that's called on an event. Usually this will be a Result of some sort; in our case it's std::io::Result<()> just to signal whether some underlying operation failed or not. Error - this is the error type returned by process_events() (not the user callback!). Having this as an associated type allows you to have more control over error propagation in nested event sources. We will use Anyhow , which is like a more fully-features Box. It allows you to add context to any other error with a context() method. So together these are: impl calloop::EventSource for ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ type Event = Vec>; type Metadata = (); type Ret = io::Result<()>; type Error = anyhow::Error; // ...\n} I have saved one surprise for later to emphasise some important principles, but for now, let's move on to defining some methods!","breadcrumbs":"A full example: ZeroMQ » Creating our source, part I: our types » Associated types","id":"39","title":"Associated types"},"4":{"body":"A blocking operation is one that waits for an event to happen, and doesn't do anything else while it's waiting. For example, if you try to read from a network socket, and there is no data available, the read operation could wait for some indefinite amount of time. Your program will be in a state where it does not need to use any CPU cycles, or indeed do anything at all, and it won't proceed until there is data to read. Examples of blocking operations are: waiting for a certain time to elapse reading or writing to a file reading or writing to a network socket waiting for a thread to finish When any of these operations are ready to go, we call it an event . We call the underlying things (files, network sockets, timers, etc.) sources for events. So, for example, you can create an event source that corresponds to a file, and it will generate events when it is ready for reading, or writing, or encounters an error.","breadcrumbs":"How an event loop works » Terminology","id":"4","title":"Terminology"},"40":{"body":"Now that we've figured out the types we need, we can get to work writing some methods. We'll need to implement the methods defined in the calloop::EventSource trait, and a constructor function to create the source.","breadcrumbs":"A full example: ZeroMQ » Creating our source, part II: setup methods » Creating our source, part II: setup methods","id":"40","title":"Creating our source, part II: setup methods"},"41":{"body":"Creating our source is fairly straightforward. We can let the caller set up the zsocket the way they need, and take ownership of it when it's initialised. Our caller needs not only the source itself, but the sending end of the MPSC channel so they can send messages, so we need to return that too. A common pattern in Calloop's own constructor functions is to return a tuple containing (a) the source and (b) a type to use the source. So that's what we'll do: // Converts a `zmq::Socket` into a `ZeroMQSource` plus the sending end of an\n// MPSC channel to enqueue outgoing messages.\npub fn from_socket(socket: zmq::Socket) -> io::Result<(Self, calloop::channel::Sender)> { let (mpsc_sender, mpsc_receiver) = calloop::channel::channel(); let (wake_ping_sender, wake_ping_receiver) = calloop::ping::make_ping()?; let fd = socket.get_fd()?; let socket_source = calloop::generic::Generic::from_fd(fd, calloop::Interest::READ, calloop::Mode::Edge); Ok(( Self { socket, socket_source, mpsc_receiver, wake_ping_receiver, wake_ping_sender, }, mpsc_sender, ))\n}","breadcrumbs":"A full example: ZeroMQ » Creating our source, part II: setup methods » Our constructor","id":"41","title":"Our constructor"},"42":{"body":"Calloop's event sources have a kind of life cycle, starting with registration . When you add an event source to the event loop, under the hood the source will register itself with the loop. Under certain circumstances a source will need to re-register itself. And finally there is the unregister action when an event source is removed from the loop. These are expressed via the calloop::EventSource methods: fn register(&mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory) -> calloop::Result<()> fn reregister(&mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory) -> calloop::Result<()> fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> The first two methods take a token factory , which is a way for Calloop to keep track of why your source was woken up. When we get to actually processing events, you'll see how this works. But for now, all you need to do is recursively pass the token factory into whatever sources your own event source is composed of. This includes other composed sources, which will pass the token factory into their sources, and so on. In practise this looks like: fn register( &mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory\n) -> calloop::Result<()>\n{ self.socket_source.register(poll, token_factory)?; self.mpsc_receiver.register(poll, token_factory)?; self.wake_ping_receiver.register(poll, token_factory)?; self.wake_ping_sender.ping(); Ok(())\n} fn reregister( &mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory\n) -> calloop::Result<()>\n{ self.socket_source.reregister(poll, token_factory)?; self.mpsc_receiver.reregister(poll, token_factory)?; self.wake_ping_receiver.reregister(poll, token_factory)?; self.wake_ping_sender.ping(); Ok(())\n} fn unregister(&mut self, poll: &mut calloop::Poll)-> calloop::Result<()> { self.socket_source.unregister(poll)?; self.mpsc_receiver.unregister(poll)?; self.wake_ping_receiver.unregister(poll)?; Ok(())\n} Note the self.wake_ping_sender.ping() call in the first two functions! This is how we manually prompt the event loop to wake up and run our source on the next iteration, to properly account for the zsocket's edge-triggering .","breadcrumbs":"A full example: ZeroMQ » Creating our source, part II: setup methods » Trait methods: registering sources","id":"42","title":"Trait methods: registering sources"},"43":{"body":"ZeroMQ sockets have their own internal queues and state, and therefore need a bit of care when shutting down. Depending on zsocket type and settings, when the ZeroMQ context is dropped, it could block waiting for certain operations to complete. We can write a drop handler to avoid this, but again note that it's only one of many ways to handle zsocket shutdown. impl Drop for ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ fn drop(&mut self) { // This is one way to stop socket code (especially PUSH sockets) hanging // at the end of any blocking functions. // // - https://stackoverflow.com/a/38338578/188535 // - http://api.zeromq.org/4-0:zmq-ctx-term self.socket.set_linger(0).ok(); self.socket.set_rcvtimeo(0).ok(); self.socket.set_sndtimeo(0).ok(); // Double result because (a) possible failure on call and (b) possible // failure decoding. if let Ok(Ok(last_endpoint)) = self.socket.get_last_endpoint() { self.socket.disconnect(&last_endpoint).ok(); } }\n}","breadcrumbs":"A full example: ZeroMQ » Creating our source, part II: setup methods » Our drop handler","id":"43","title":"Our drop handler"},"44":{"body":"Finally, the real functionality we care about! Processing events! This is also a method in the calloop::EventSource trait: fn process_events( &mut self, readiness: calloop::Readiness, token: calloop::Token, mut callback: F,\n) -> Result\nwhere F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret, What a mouthful! But when you break it down, it's not so complicated: We take our own state, of course, as &mut self. We take a Readiness value - this is mainly useful for \"real\" file descriptors, and tells you whether the event source was woken up for a read or write event. We ignore it though, because our internal sources are always only readable (remember that even if the zsocket is writeable, the FD it exposes is only ever readable). We take a token. This gives us a way to process events that arise from our internal sources. In general, composed sources should not actually need to use this directly; sub-sources will check their own tokens against this and run if necessary. We take a callback. We call this callback with any \"real\" events that our caller will care about; in our case, that means messages we receive on the zsocket. It is closely related to the EventSource trait's associated types . Note that the callback our caller supplies when adding our source to the loop actually takes an extra argument, which is some data that we won't know about in our source. Calloop's internals take care of combining our arguments here with this extra data. Finally we return a PostAction, which tells the loop whether it needs to change the state of our event source, perhaps as a result of actions we took. For example, you might require that your source be removed from the loop (with PostAction::Remove) if it only has a certain thing to do. Ordinarily though, you'd return PostAction::Continue for your source to keep waiting for events. Note that these PostAction values correspond to various methods on the LoopHandle type (eg. PostAction::Disable does the same as LoopHandle::disable()). Whether you control your event source by returning a PostAction or using the LoopHandle methods depends on whether it makes more sense for these actions to be taken from within your event source or by something else in your code. Implementing process_events() for a type that contains various Calloop sources composed together, like we have, is done recursively by calling our internal sources' process_events() method. The token that Calloop gives us is how each event source determines whether it was responsible for the wakeup and has events to process. If we were woken up because of the ping source, then the ping source's process_events() will see that the token matches its own, and call the callback (possibly multiple times). If we were woken up because a message was sent through the MPSC channel, then the channel's process_events() will match on the token instead and call the callback for every message waiting. The zsocket is a little different, and we'll go over that in detail. For error handling we're using Anyhow , hence the context() calls on each fallible operation. These just add a message to any error that might appear in a traceback. So a first draft of our code might look like: fn process_events( &mut self, readiness: calloop::Readiness, token: calloop::Token, mut callback: F,\n) -> Result\nwhere F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,\n{ // Runs if we were woken up on startup/registration. self.wake_ping_receiver .process_events(readiness, token, |_, _| {}) .context(\"Failed after registration\")?; // Runs if we received a message over the MPSC channel. self.mpsc_receiver .process_events(readiness, token, |evt, _| { // 'evt' could be a message or a \"sending end closed\" // notification. We don't care about the latter. if let calloop::channel::Event::Msg(msg) = evt { self.socket .send_multipart(msg, 0) .context(\"Failed to send message\")?; } })?; // Runs if the zsocket became read/write-able. self.socket .process_events(readiness, token, |_, _| { let events = self.socket .get_events() .context(\"Failed to read ZeroMQ events\")?; if events.contains(zmq::POLLOUT) { // Wait, what do we do here? } if events.contains(zmq::POLLIN) { let messages = self.socket .recv_multipart(0) .context(\"Failed to receive message\")?; callback(messages, &mut ()) .context(\"Error in event callback\")?; } })?; Ok(calloop::PostAction::Continue)\n} We process the events from whichever source woke up our composed source, and if we woke up because the zsocket became readable, we call the callback with the message we received. Finally we return PostAction::Continue to remain in the event loop. Don't worry about getting this to compile, it is a good start but it's wrong in a few ways. Firstly, we've gone to all the trouble of using a ping to wake up the source, and then we just... drain its internal events and return. Which achieves nothing. Secondly, we don't seem to know what to do when our zsocket becomes writeable (the actual zsocket, not the \"interface\" file descriptor). Thirdly, we commit one of the worst sins you can commit in an event-loop-based system. Can you see it? It's this part: self.mpsc_receiver .process_events(readiness, token, |evt, _| { if let calloop::channel::Event::Msg(msg) = evt { self.socket .file .send_multipart(msg, 0) .context(\"Failed to send message\")?; } })?; We block the event loop! In the middle of processing events from the MPSC channel, we call zmq::Socket::send_multipart() which could , under certain circumstances, block! We shouldn't do that. Let's deal with this badness first then. We want to decouple \"receiving messages over the MPSC channel\" from \"sending messages on the zsocket\". There are different ways to do this, but they boil down to: buffer messages or drop messages (or maybe a combination of both). We'll use the first approach, with an internal FIFO queue. When we receive messages, we push them onto the back of the queue. When the zsocket is writeable, we pop messages from the front of the queue. The standard library has collections::VecDeque which provides efficient double-ended queuing, so let's use that. This is some extra internal state, so we need to add it to our type, which becomes: pub struct ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ // Calloop components. socket: calloop::generic::Generic>, mpsc_receiver: calloop::channel::Channel, wake_ping_receiver: calloop::ping::PingSource, /// Sending end of the ping source. wake_ping_sender: calloop::ping::Ping, /// FIFO queue for the messages to be published. outbox: std::collections::VecDeque,\n} Our MPSC receiving code becomes: let outbox = &mut self.outbox; self.mpsc_receiver .process_events(readiness, token, |evt, _| { if let calloop::channel::Event::Msg(msg) = evt { outbox.push_back(msg); } })?; And our \"zsocket is writeable\" code becomes: self.socket .file .process_events(readiness, token, |_, _| { let events = self .socket .file .get_events() .context(\"Failed to read ZeroMQ events\")?; if events.contains(zmq::POLLOUT) { if let Some(parts) = self.outbox.pop_front() { self.socket .file .send_multipart(parts, 0) .context(\"Failed to send message\")?; } } if events.contains(zmq::POLLIN) { let messages = self.socket .file .recv_multipart(0) .context(\"Failed to receive message\")?; callback(messages, &mut ()) .context(\"Error in event callback\")?; } })?; So we've not only solved problem #3, we've also figured out #2, which suggests we're on the right track. But we still have (at least) that first issue to sort out.","breadcrumbs":"A full example: ZeroMQ » Creating our source, part III: processing events (almost) » Creating our source, part III: processing events (almost)","id":"44","title":"Creating our source, part III: processing events (almost)"},"45":{"body":"We have three events that could wake up our event source: the ping, the channel, and the zsocket itself becoming ready to use. All three of these reasons potentially mean doing something on the zsocket: if the ping fired, we need to check for any pending events. If the channel received a message, we want to check if the zsocket is already readable and send it. If the zsocket becomes readable or writeable, we want to read from or write to it. In other words... We want to run it every time! Also notice that in the zsocket process_events() call, we don't use any of the arguments, including the event itself. That file descriptor is merely a signalling mechanism! Sending and receiving messages is what will actually clear any pending events on it, and reset it to a state where it will wake the event loop later. let events = self .socket .get_events() .context(\"Failed to read ZeroMQ events\")?; if events.contains(zmq::POLLOUT) { if let Some(parts) = self.outbox.pop_front() { self.socket .send_multipart(parts, 0) .context(\"Failed to send message\")?; }\n} if events.contains(zmq::POLLIN) { let messages = self.socket .recv_multipart(0) .context(\"Failed to receive message\")?; callback(messages, &mut ()) .context(\"Error in event callback\")?;\n} So the second draft of our process_events() function is now: fn process_events( &mut self, readiness: calloop::Readiness, token: calloop::Token, mut callback: F,\n) -> Result\nwhere F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,\n{ // Runs if we were woken up on startup/registration. self.wake_ping_receiver .process_events(readiness, token, |_, _| {})?; // Runs if we were woken up because a message was sent on the channel. let outbox = &mut self.outbox; self.mpsc_receiver .process_events(readiness, token, |evt, _| { if let calloop::channel::Event::Msg(msg) = evt { outbox.push_back(msg); } })?; // Always process any pending zsocket events. let events = self .socket .get_events() .context(\"Failed to read ZeroMQ events\")?; if events.contains(zmq::POLLOUT) { if let Some(parts) = self.outbox.pop_front() { self.socket .send_multipart(parts, 0) .context(\"Failed to send message\")?; } } if events.contains(zmq::POLLIN) { let messages = self.socket .recv_multipart(0) .context(\"Failed to receive message\")?; callback(messages, &mut ()) .context(\"Error in event callback\")?; } Ok(calloop::PostAction::Continue)\n} There is one more issue to take care of, and it's got nothing to do with Calloop. We still haven't fully dealt with ZeroMQ's edge-triggered nature. Consider this situation: We create a REQ zsocket. These are intended to be used in strict send/receive/send/receive/etc. sequence. We wrap it in our ZeroMQSource and add that to our loop. We send a message. If we do this, it's possible we'll never actually receive any replies that are sent to our zsocket! Why? Because: we read the events on the socket into events then we send a message on the socket another process sends a reply so quickly, it arrives more or less immediately then we use the same events to check if the socket is readable then we exit The zsocket will change from writeable to readable before we leave process_events(). So the \"interface\" file descriptor will become readable again. But because it is edge triggered, it will not wake up our event source after we leave process_events(). So our source will not wake up again (at least, not due to the self.socket event source). For this specific example , it will suffice to re-read the zsocket events in between the if statements. Then when we get to the second events check, it will indeed contain zmq::POLLIN and receive the pending message. But this is not good enough for the general case! If we replace REQ with REP above, we'll get the opposite problem: our first check (for POLLOUT) will be false. Our second check (POLLIN) will be true. We'll receive a message, leave process_events(), and never wake up again. The full solution is to recognise that any user action on a ZeroMQ socket can cause the pending events to change, or just to remain active, without re-triggering the \"interface\" file descriptor. So we need to (a) do this repeatedly and (b) keep track of when we have or haven't performed an action on the zsocket. Here's one way to do it: loop { let events = self .socket .get_events() .context(\"Failed to read ZeroMQ events\")?; let mut used_socket = false; if events.contains(zmq::POLLOUT) { if let Some(parts) = self.outbox.pop_front() { self.socket .as_ref() .send_multipart(parts, 0) .context(\"Failed to send message\")?; used_socket = true; } } if events.contains(zmq::POLLIN) { let messages = self.socket .recv_multipart(0) .context(\"Failed to receive message\")?; used_socket = true; callback(messages, &mut ()) .context(\"Error in event callback\")?; } if !used_socket { break; }\n} Now we have a flag that we set if, and only if, we call a send or receive method on the zsocket. If that flag is set at the end of the loop, we go around again.","breadcrumbs":"A full example: ZeroMQ » Creating our source, part IV: processing events (really) » Creating our source, part IV: processing events (really)","id":"45","title":"Creating our source, part IV: processing events (really)"},"46":{"body":"Remember my disclaimer at the start of the chapter, about this code being \"greedy\"? This is what I mean. This loop will run until the entire message queue is empty, so if it has a lot of messages in it, any other sources in our event loop will not be run until this loop is finished. An alternative approach is to use more state to determine whether we want to run again on the next loop iteration (perhaps using the ping source), so that Calloop can run any other sources in between individual messages being received.","breadcrumbs":"A full example: ZeroMQ » Creating our source, part IV: processing events (really) » Greediness","id":"46","title":"Greediness"},"47":{"body":"This is the full source code for a Calloop event source based on a ZeroMQ socket. You might find it useful as a kind of reference. Please read the disclaimer at the start of this chapter if you skipped straight here! //! A Calloop event source implementation for ZeroMQ sockets. use std::{collections, io}; use anyhow::Context; /// A Calloop event source that contains a ZeroMQ socket (of any kind) and a\n/// Calloop MPSC channel for sending over it.\n///\n/// The basic interface is:\n/// - create a zmq::Socket for your ZeroMQ socket\n/// - use `ZeroMQSource::from_socket()` to turn it into a Calloop event source\n/// (plus the sending end of the channel)\n/// - queue messages to be sent by sending them on the sending end of the MPSC\n/// channel\n/// - add the event source to the Calloop event loop with a callback to handle\n/// reading\n/// - the sending end of the MPSC channel can be cloned and sent across threads\n/// if necessary\n///\n/// This type is parameterised by `T`:\n///\n/// T where T: IntoIterator, T::Item: Into\n//\n/// This means that `T` is anything that can be converted to an iterator, and\n/// the items in the iterator are anything that can be converted to a\n/// `zmq::Message`. So eg. a `Vec` would work.\n///\n/// The callback is called whenever the underlying socket becomes readable. It\n/// is called with a vec of byte sequences (`Vec>`) and the event loop\n/// data set by the user.\n///\n/// Note about why the read data is a vec of multipart message parts: we don't\n/// know what kind of socket this is, or what will be sent, so the most general\n/// thing we can do is receive the entirety of a multipart message and call the\n/// user callback with the whole set. Usually the number of parts in a multipart\n/// message will be one, but the code will work just the same when it's not.\n///\n/// This event source also allows you to use different event sources to publish\n/// messages over the same writeable ZeroMQ socket (usually PUB or PUSH).\n/// Messages should be sent over the Calloop MPSC channel sending end. This end\n/// can be cloned and used by multiple senders. pub struct ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ // Calloop components. /// Event source for ZeroMQ socket. socket: calloop::generic::Generic>, /// Event source for channel. mpsc_receiver: calloop::channel::Channel, /// Because the ZeroMQ socket is edge triggered, we need a way to \"wake\" the /// event source upon (re-)registration. We do this with a separate /// `calloop::ping::Ping` source. wake_ping_receiver: calloop::ping::PingSource, /// Sending end of the ping source. wake_ping_sender: calloop::ping::Ping, // ZeroMQ socket. /// FIFO queue for the messages to be published. outbox: collections::VecDeque,\n} impl ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ // Converts a `zmq::Socket` into a `ZeroMQSource` plus the sending end of an // MPSC channel to enqueue outgoing messages. pub fn from_socket(socket: zmq::Socket) -> io::Result<(Self, calloop::channel::Sender)> { let (mpsc_sender, mpsc_receiver) = calloop::channel::channel(); let (wake_ping_sender, wake_ping_receiver) = calloop::ping::make_ping()?; let socket = calloop::generic::Generic::new( unsafe { calloop::generic::FdWrapper::new(socket) }, calloop::Interest::READ, calloop::Mode::Edge, ); Ok(( Self { socket, mpsc_receiver, wake_ping_receiver, wake_ping_sender, outbox: collections::VecDeque::new(), }, mpsc_sender, )) }\n} /// This event source runs for three events:\n///\n/// 1. The event source was registered. It is forced to run so that any pending\n/// events on the socket are processed.\n///\n/// 2. A message was sent over the MPSC channel. In this case we put it in the\n/// internal queue.\n///\n/// 3. The ZeroMQ socket is readable. For this, we read off a complete multipart\n/// message and call the user callback with it.\n///\n/// The callback provided to `process_events()` may be called multiple times\n/// within a single call to `process_events()`.\nimpl calloop::EventSource for ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ type Event = Vec>; type Metadata = (); type Ret = io::Result<()>; type Error = anyhow::Error; fn process_events( &mut self, readiness: calloop::Readiness, token: calloop::Token, mut callback: F, ) -> Result where F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret, { // Runs if we were woken up on startup/registration. self.wake_ping_receiver .process_events(readiness, token, |_, _| {}) .context(\"Failed after registration\")?; // Runs if we were woken up because a message was sent on the channel. let outbox = &mut self.outbox; self.mpsc_receiver .process_events(readiness, token, |evt, _| { if let calloop::channel::Event::Msg(msg) = evt { outbox.push_back(msg); } }) .context(\"Failed to processing outgoing messages\")?; // The ZeroMQ file descriptor is edge triggered. This means that if (a) // messages are added to the queue before registration, or (b) the // socket became writeable before messages were enqueued, we will need // to run the loop below. Hence, it always runs if this event source // fires. The process_events() method doesn't do anything though, so we // ignore it. loop { // According to the docs, the edge-triggered FD will not change // state if a socket goes directly from being readable to being // writeable (or vice-versa) without there being an in-between point // where there are no events. This can happen as a result of sending // or receiving on the socket while processing such an event. The // \"used_socket\" flag below tracks whether we perform an operation // on the socket that warrants reading the events again. let events = self .socket .get_ref() .get_events() .context(\"Failed to read ZeroMQ events\")?; let mut used_socket = false; if events.contains(zmq::POLLOUT) { if let Some(parts) = self.outbox.pop_front() { self.socket .get_ref() .send_multipart(parts, 0) .context(\"Failed to send message\")?; used_socket = true; } } if events.contains(zmq::POLLIN) { // Batch up multipart messages. ZeroMQ guarantees atomic message // sending, which includes all parts of a multipart message. let messages = self .socket .get_ref() .recv_multipart(0) .context(\"Failed to receive message\")?; used_socket = true; // Capture and report errors from the callback, but don't propagate // them up. callback(messages, &mut ()).context(\"Error in event callback\")?; } if !used_socket { break; } } Ok(calloop::PostAction::Continue) } fn register( &mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory, ) -> calloop::Result<()> { self.socket.register(poll, token_factory)?; self.mpsc_receiver.register(poll, token_factory)?; self.wake_ping_receiver.register(poll, token_factory)?; self.wake_ping_sender.ping(); Ok(()) } fn reregister( &mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory, ) -> calloop::Result<()> { self.socket.reregister(poll, token_factory)?; self.mpsc_receiver.reregister(poll, token_factory)?; self.wake_ping_receiver.reregister(poll, token_factory)?; self.wake_ping_sender.ping(); Ok(()) } fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> { self.socket.unregister(poll)?; self.mpsc_receiver.unregister(poll)?; self.wake_ping_receiver.unregister(poll)?; Ok(()) }\n} impl Drop for ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ fn drop(&mut self) { // This is one way to stop socket code (especially PUSH sockets) hanging // at the end of any blocking functions. // // - https://stackoverflow.com/a/38338578/188535 // - http://api.zeromq.org/4-0:zmq-ctx-term self.socket.get_ref().set_linger(0).ok(); self.socket.get_ref().set_rcvtimeo(0).ok(); self.socket.get_ref().set_sndtimeo(0).ok(); // Double result because (a) possible failure on call and (b) possible // failure decoding. if let Ok(Ok(last_endpoint)) = self.socket.get_ref().get_last_endpoint() { self.socket.get_ref().disconnect(&last_endpoint).ok(); } }\n} pub fn main() {} Dependencies are: calloop (whatever version this document was built from) zmq 0.9 anyhow 1.0 [dependencies]\ncalloop = { path = '../..' }\nzmq = \"0.9\"\nanyhow = \"1.0\"","breadcrumbs":"A full example: ZeroMQ » The full ZeroMQ event source code » The full ZeroMQ event source code","id":"47","title":"The full ZeroMQ event source code"},"5":{"body":"An event loop like Calloop, as the name suggests, runs in a loop. At the start of the loop, Calloop checks all the sources you've added to see if any events have happened for those sources. If they have, Calloop will call a function that you provide (known as a callback ). This function will (possibly) be given some data for the event itself (eg. the bytes received), some state for the event source (eg. the socket, or a type that wraps it in a neater API), and some state for the whole program. Calloop will do this one by one for each source that has a new event. If a file is ready for reading, your file-event-source callback will be called. If a timer has elapsed, your timer-event-source callback will be called. It is up to you to write the code to do things when events happen. For example, your callback might read data from a file \"ready for reading\" event into a queue. When the queue contains a valid message, the same callback could send that message over an internal channel to another event source. That second event source could have its own callback that processes entire messages and updates the program's state. And so on.","breadcrumbs":"How an event loop works » Events and callbacks","id":"5","title":"Events and callbacks"},"6":{"body":"This \"one by one\" nature of event loops is important. When you approach concurrency using threads, operations in any thread can be interleaved with operations in any other thread. This is typically made robust by either passing messages or using shared memory with synchronisation. Callbacks in an event loop do not run in parallel, they run one after the other. Unless you (or your dependencies) have introduced threading, you can (and should) write your callbacks as single-threaded code.","breadcrumbs":"How an event loop works » Concurrency vs parallelism","id":"6","title":"Concurrency vs parallelism"},"7":{"body":"This single-threaded nature makes event loops much more similar to code that uses async/await than to multithreaded code. There are benefits and tradeoffs to either approach. Calloop will take care of a lot of integration and error handling boilerplate for you. It also makes it clearer what parts of your code are the non-blocking actions to perform as a result of events. If you like to think of your program in terms of taking action in reaction to events, this can be a great advantage! However, this comes at the expense of needing to make your program's state much more explicit. For example, take this async code: do_thing_one().await;\ndo_thing_two().await;\ndo_thing_three().await; The state of the program is simply given by: what line is it up to? You know if it's done \"thing one\" because execution has proceeded to line two. No other state is required. In Calloop, however, you will need extra variables and code so that when your callback is called, it knows whether to run do_thing_one(), do_thing_two(), or do_thing_three().","breadcrumbs":"How an event loop works » Event loops vs async code","id":"7","title":"Event loops vs async code"},"8":{"body":"All of this leads us to the most important rule of event loop code: never block the loop! This means: never use blocking calls inside one of your event callbacks. Do not use synchronous file write() calls in a callback. Do not sleep() in a callback. Do not join() a thread in a callback. Don't you do it! If you do, the event loop will have no way to proceed, and just... wait for your blocking operation to complete. Nothing is going to run in a parallel thread. Nothing is going to stop your callback and move on to the next one. If your callback needs to wait for a blocking operation, your code must allow it to keep track of where it's up to, return from the callback, and wait for the event like any other.","breadcrumbs":"How an event loop works » Never block the loop!","id":"8","title":"Never block the loop!"},"9":{"body":"Calloop is designed to work by composition . This means that you build up more complex logic in your program by combining simpler event sources into more complex ones. Want a network socket with custom backoff/timeout logic? Create a type containing a network socket using the Generic file descriptor adapter , a timer , and tie them together with your backoff logic and state. There is a much more detailed example of composition in our ZeroMQ example .","breadcrumbs":"How an event loop works » Calloop and composition","id":"9","title":"Calloop and composition"}},"length":48,"save":true},"fields":["title","body","breadcrumbs"],"index":{"body":{"root":{"0":{".":{"3":{"df":1,"docs":{"26":{"tf":2.0}}},"9":{"df":1,"docs":{"47":{"tf":1.4142135623730951}}},"df":0,"docs":{}},":":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":3,"docs":{"44":{"tf":1.7320508075688772},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}},"u":{"8":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}},"1":{".":{"0":{"df":1,"docs":{"47":{"tf":1.4142135623730951}}},"6":{"3":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":3,"docs":{"2":{"tf":1.0},"38":{"tf":1.0},"47":{"tf":1.0}}},"2":{"0":{"2":{"1":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"2":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"3":{"df":4,"docs":{"15":{"tf":1.4142135623730951},"2":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"4":{"df":1,"docs":{"2":{"tf":1.0}}},"5":{"df":1,"docs":{"14":{"tf":1.0}}},"_":{"df":8,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"44":{"tf":3.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.7320508075688772}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"d":{"_":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}},"df":0,"docs":{}}}},"a":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"28":{"tf":1.0}}}},"o":{"df":0,"docs":{},"v":{"df":2,"docs":{"31":{"tf":1.0},"45":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"11":{"tf":1.0},"30":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"37":{"tf":1.4142135623730951}}}}},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"r":{"d":{"df":1,"docs":{"47":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":6,"docs":{"14":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951}}}},"v":{"df":1,"docs":{"45":{"tf":1.0}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":6,"docs":{"35":{"tf":1.4142135623730951},"36":{"tf":1.0},"38":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"d":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":5,"docs":{"13":{"tf":1.0},"24":{"tf":1.7320508075688772},"28":{"tf":1.0},"31":{"tf":1.0},"9":{"tf":1.0}}}}},"d":{"df":7,"docs":{"28":{"tf":1.0},"35":{"tf":1.4142135623730951},"39":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"31":{"tf":1.4142135623730951}}}}}}},"df":5,"docs":{"15":{"tf":1.4142135623730951},"29":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0}},"v":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"7":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"15":{"tf":2.23606797749979},"35":{"tf":1.0},"43":{"tf":1.0},"45":{"tf":2.0},"46":{"tf":1.0},"47":{"tf":1.0}},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{},"w":{"df":3,"docs":{"39":{"tf":1.4142135623730951},"47":{"tf":1.0},"8":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"10":{"tf":1.0}}}},"o":{"df":0,"docs":{},"f":{"df":1,"docs":{"26":{"tf":1.7320508075688772}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":3,"docs":{"22":{"tf":1.0},"35":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"46":{"tf":1.0}}}}}},"w":{"a":{"df":0,"docs":{},"y":{"df":4,"docs":{"32":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"15":{"tf":1.0},"4":{"tf":1.0}}}}}}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":6,"docs":{"23":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.4142135623730951},"39":{"tf":1.0},"45":{"tf":1.0},"5":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}}}}}},"y":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"'":{"df":1,"docs":{"23":{"tf":1.0}}},":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"23":{"tf":1.0},"39":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":3,"docs":{"39":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}},"t":{"df":0,"docs":{},"h":{"df":3,"docs":{"28":{"tf":1.0},"4":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}}}}},"p":{"df":0,"docs":{},"i":{"df":4,"docs":{"1":{"tf":1.4142135623730951},"22":{"tf":1.4142135623730951},"38":{"tf":1.4142135623730951},"5":{"tf":1.0}}},"p":{"df":1,"docs":{"15":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"i":{"c":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"'":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}}}}},"df":1,"docs":{"31":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"o":{"a":{"c":{"df":0,"docs":{},"h":{"df":4,"docs":{"44":{"tf":1.0},"46":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"11":{"tf":1.0}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"15":{"tf":1.4142135623730951},"26":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0}}}}},"u":{"df":1,"docs":{"15":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":6,"docs":{"10":{"tf":1.0},"11":{"tf":1.4142135623730951},"27":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"45":{"tf":1.0}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"df":0,"docs":{},"f":{"d":{"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"28":{"tf":1.0}},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":1,"docs":{"13":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"r":{"a":{"df":0,"docs":{},"w":{"df":0,"docs":{},"f":{"d":{"df":2,"docs":{"11":{"tf":1.0},"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"i":{"df":4,"docs":{"12":{"tf":1.0},"23":{"tf":1.7320508075688772},"39":{"tf":1.7320508075688772},"44":{"tf":1.0}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"n":{"c":{"/":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":3,"docs":{"2":{"tf":1.0},"24":{"tf":1.0},"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}}}},"df":7,"docs":{"24":{"tf":1.4142135623730951},"25":{"tf":1.0},"26":{"tf":5.744562646538029},"27":{"tf":1.7320508075688772},"28":{"tf":2.449489742783178},"29":{"tf":7.483314773547883},"7":{"tf":1.4142135623730951}},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"23":{"tf":1.0},"3":{"tf":1.0}}}}}},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}}}}}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":3,"docs":{"30":{"tf":1.0},"35":{"tf":1.0},"47":{"tf":1.0}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":4,"docs":{"1":{"tf":1.0},"11":{"tf":1.0},"13":{"tf":1.0},"4":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"13":{"tf":1.0},"43":{"tf":1.0}}},"df":0,"docs":{}}}},"w":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"27":{"tf":1.0}}},"y":{"df":1,"docs":{"32":{"tf":1.0}}}},"df":0,"docs":{}}},"b":{"a":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"31":{"tf":1.0},"44":{"tf":1.0}},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{}}}}}},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"/":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}},"df":1,"docs":{"9":{"tf":1.0}}}}}}},"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":8,"docs":{"10":{"tf":1.0},"11":{"tf":1.4142135623730951},"23":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"i":{"c":{"df":2,"docs":{"30":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}}},"df":4,"docs":{"41":{"tf":1.0},"43":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951}},"e":{"c":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":8,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"18":{"tf":1.0},"22":{"tf":1.0},"35":{"tf":1.7320508075688772},"44":{"tf":2.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}},"df":5,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"38":{"tf":1.0},"46":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"23":{"tf":1.0},"26":{"tf":1.0},"31":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}},"h":{"a":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":2,"docs":{"26":{"tf":2.0},"47":{"tf":1.4142135623730951}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":5,"docs":{"30":{"tf":1.0},"32":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"df":0,"docs":{},"t":{"df":4,"docs":{"32":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.0},"43":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":10,"docs":{"26":{"tf":5.291502622129181},"28":{"tf":2.23606797749979},"29":{"tf":5.5677643628300215},"3":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951},"43":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951},"47":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":2.23606797749979}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"2":{"tf":1.0}}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"13":{"tf":1.0}},"e":{"d":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"13":{"tf":2.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"t":{"df":0,"docs":{},"h":{"df":5,"docs":{"12":{"tf":1.0},"22":{"tf":1.4142135623730951},"26":{"tf":1.0},"29":{"tf":1.0},"44":{"tf":1.0}}}},"x":{"<":{"d":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"df":2,"docs":{"23":{"tf":1.4142135623730951},"39":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"k":{"df":4,"docs":{"15":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"f":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"29":{"tf":2.6457513110645907}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"l":{"d":{"df":4,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"30":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.0},"31":{"tf":1.0},"47":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"df":1,"docs":{"18":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"e":{"df":1,"docs":{"26":{"tf":2.23606797749979}}},"t":{"df":0,"docs":{},"e":{"df":2,"docs":{"47":{"tf":1.0},"5":{"tf":1.0}}}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"28":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}},"df":15,"docs":{"11":{"tf":1.0},"15":{"tf":2.8284271247461903},"22":{"tf":1.4142135623730951},"23":{"tf":1.4142135623730951},"24":{"tf":1.0},"26":{"tf":1.4142135623730951},"30":{"tf":1.0},"39":{"tf":2.0},"44":{"tf":3.1622776601683795},"45":{"tf":2.0},"47":{"tf":2.8284271247461903},"5":{"tf":2.6457513110645907},"6":{"tf":1.4142135623730951},"7":{"tf":1.0},"8":{"tf":2.6457513110645907}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":16,"docs":{"18":{"tf":1.4142135623730951},"22":{"tf":1.0},"23":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"35":{"tf":1.7320508075688772},"39":{"tf":1.0},"4":{"tf":1.4142135623730951},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.6457513110645907},"45":{"tf":1.4142135623730951},"47":{"tf":2.6457513110645907},"5":{"tf":1.7320508075688772},"7":{"tf":1.0},"8":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"23":{"tf":1.4142135623730951},"31":{"tf":1.0},"39":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"'":{"df":12,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"10":{"tf":1.0},"17":{"tf":1.0},"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.4142135623730951},"30":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0}}},":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"<":{"df":0,"docs":{},"t":{"df":3,"docs":{"37":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}},"df":5,"docs":{"23":{"tf":1.0},"34":{"tf":1.0},"36":{"tf":1.7320508075688772},"41":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":3,"docs":{"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"<":{"df":0,"docs":{},"t":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":5,"docs":{"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}}}}}}},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"26":{"tf":1.4142135623730951},"29":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"26":{"tf":2.23606797749979},"29":{"tf":2.8284271247461903}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"c":{":":{":":{"df":0,"docs":{},"f":{"d":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"33":{"tf":1.0},"36":{"tf":1.0}},"i":{"c":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"f":{"d":{"(":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"<":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"c":{":":{":":{"df":0,"docs":{},"f":{"d":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"<":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"o":{"df":1,"docs":{"29":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{":":{":":{"a":{"d":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":1,"docs":{"29":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"m":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"g":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{":":{":":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"p":{"df":3,"docs":{"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.4142135623730951}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":4,"docs":{"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":2.449489742783178},"47":{"tf":1.7320508075688772}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":2.449489742783178},"47":{"tf":1.7320508075688772}}}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"42":{"tf":2.0},"47":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":26,"docs":{"10":{"tf":1.0},"11":{"tf":1.7320508075688772},"14":{"tf":1.0},"15":{"tf":1.4142135623730951},"16":{"tf":1.0},"2":{"tf":2.23606797749979},"21":{"tf":1.0},"22":{"tf":1.4142135623730951},"24":{"tf":1.4142135623730951},"26":{"tf":1.0},"27":{"tf":1.4142135623730951},"28":{"tf":1.7320508075688772},"3":{"tf":1.0},"31":{"tf":1.4142135623730951},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"34":{"tf":1.0},"36":{"tf":1.4142135623730951},"42":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":3.1622776601683795},"5":{"tf":2.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}}}}},"n":{"'":{"df":0,"docs":{},"t":{"df":2,"docs":{"23":{"tf":1.0},"30":{"tf":1.0}}}},"d":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"37":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"p":{"a":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"10":{"tf":1.0},"37":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":7,"docs":{"30":{"tf":1.0},"32":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.0},"7":{"tf":1.0}},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}},"g":{"df":0,"docs":{},"o":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"18":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":7,"docs":{"31":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"39":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"23":{"tf":1.0}}}}}}}},"u":{"df":0,"docs":{},"s":{"df":3,"docs":{"15":{"tf":1.0},"31":{"tf":1.0},"45":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":3.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"24":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"14":{"tf":1.0},"4":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"31":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":4,"docs":{"35":{"tf":2.23606797749979},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"'":{"df":1,"docs":{"44":{"tf":1.0}}},"df":12,"docs":{"17":{"tf":1.4142135623730951},"19":{"tf":1.0},"23":{"tf":1.4142135623730951},"26":{"tf":2.8284271247461903},"32":{"tf":1.0},"34":{"tf":1.4142135623730951},"36":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":2.0},"45":{"tf":1.7320508075688772},"47":{"tf":3.0},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}}}}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"2":{"tf":2.0},"3":{"tf":1.0},"30":{"tf":1.4142135623730951},"31":{"tf":1.0},"36":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"k":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":2.449489742783178},"5":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"28":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":3,"docs":{"35":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"45":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"7":{"tf":1.0}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":1,"docs":{"47":{"tf":1.4142135623730951}}}},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"23":{"tf":1.0},"44":{"tf":1.4142135623730951}}},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}}}}},"o":{"d":{"df":0,"docs":{},"e":{"df":16,"docs":{"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"25":{"tf":1.0},"26":{"tf":3.0},"28":{"tf":2.0},"29":{"tf":2.23606797749979},"3":{"tf":1.4142135623730951},"31":{"tf":2.0},"43":{"tf":1.0},"44":{"tf":2.0},"46":{"tf":1.0},"47":{"tf":2.0},"5":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":2.449489742783178},"8":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"c":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"<":{"df":0,"docs":{},"t":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"m":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"15":{"tf":1.0},"2":{"tf":1.0},"32":{"tf":1.0},"44":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":2,"docs":{"24":{"tf":1.0},"7":{"tf":1.0}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"22":{"tf":1.0},"33":{"tf":1.0},"41":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":6,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"27":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.0},"8":{"tf":1.0}}},"x":{"df":4,"docs":{"22":{"tf":1.0},"30":{"tf":2.0},"32":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}},"i":{"c":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"26":{"tf":1.0},"29":{"tf":1.0},"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}}},"s":{"df":4,"docs":{"32":{"tf":1.4142135623730951},"36":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"32":{"tf":1.4142135623730951},"9":{"tf":1.7320508075688772}}}}}},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}}}},"n":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"22":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":2,"docs":{"3":{"tf":1.4142135623730951},"6":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"31":{"tf":1.0},"45":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"27":{"tf":1.0}}}}}},"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"12":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}}},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":9,"docs":{"23":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"41":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"\"":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}}}},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"44":{"tf":2.8284271247461903},"45":{"tf":3.0},"47":{"tf":2.23606797749979}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":4,"docs":{"10":{"tf":1.0},"39":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":1,"docs":{"18":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":4,"docs":{"12":{"tf":1.0},"30":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":1,"docs":{"22":{"tf":1.4142135623730951}}},"t":{"df":4,"docs":{"23":{"tf":1.0},"29":{"tf":1.0},"41":{"tf":1.0},"47":{"tf":1.7320508075688772}}}},"y":{"df":1,"docs":{"35":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":4,"docs":{"13":{"tf":1.0},"26":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"u":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"r":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"3":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"4":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"22":{"tf":1.0},"27":{"tf":1.0}},"s":{"/":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"/":{"d":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":18,"docs":{"11":{"tf":1.0},"12":{"tf":1.4142135623730951},"14":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"4":{"tf":1.0},"40":{"tf":1.4142135623730951},"41":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.8284271247461903}}}},"x":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":2,"docs":{"2":{"tf":1.0},"9":{"tf":1.0}}}}}}},"y":{"c":{"df":0,"docs":{},"l":{"df":2,"docs":{"4":{"tf":1.0},"42":{"tf":1.0}}}},"df":0,"docs":{}}},"d":{"a":{"df":0,"docs":{},"t":{"a":{".":{".":{".":{"\"":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":9,"docs":{"15":{"tf":1.4142135623730951},"29":{"tf":1.0},"30":{"tf":1.7320508075688772},"35":{"tf":1.0},"39":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"5":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"14":{"tf":1.7320508075688772},"15":{"tf":1.7320508075688772},"16":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"l":{"df":3,"docs":{"22":{"tf":1.0},"31":{"tf":1.0},"44":{"tf":1.0}},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}},"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":1,"docs":{"35":{"tf":1.0}}}}},"c":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"23":{"tf":1.0}}},"df":0,"docs":{},"s":{"df":1,"docs":{"31":{"tf":1.0}}}},"o":{"d":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"39":{"tf":1.0},"40":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":5,"docs":{"31":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951},"6":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{".":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"s":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":13,"docs":{"11":{"tf":1.4142135623730951},"12":{"tf":1.0},"13":{"tf":1.0},"23":{"tf":1.0},"30":{"tf":1.4142135623730951},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"35":{"tf":1.4142135623730951},"39":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":3,"docs":{"28":{"tf":1.0},"32":{"tf":1.0},"9":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"y":{"df":1,"docs":{"15":{"tf":1.0}}}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":7,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"32":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"36":{"tf":1.0}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"44":{"tf":1.0},"46":{"tf":1.0}}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":1,"docs":{"1":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":6,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"s":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"31":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"(":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"11":{"tf":1.0}}}}}}},"o":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"7":{"tf":1.0}},"e":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"7":{"tf":1.0}},"e":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"w":{"df":0,"docs":{},"o":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"7":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"c":{"df":3,"docs":{"1":{"tf":1.0},"35":{"tf":1.4142135623730951},"47":{"tf":1.0}},"s":{".":{"df":0,"docs":{},"r":{"df":1,"docs":{"1":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":2,"docs":{"22":{"tf":1.0},"45":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":3,"docs":{"35":{"tf":1.0},"4":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":3.872983346207417}}}}},"df":0,"docs":{}},"n":{"'":{"df":0,"docs":{},"t":{"df":9,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0},"36":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"8":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":3,"docs":{"30":{"tf":1.0},"44":{"tf":1.0},"7":{"tf":1.0}}}},"u":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"df":0,"docs":{},"n":{"df":3,"docs":{"15":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951}}}}},"r":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":2,"docs":{"44":{"tf":1.0},"45":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":6,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.4142135623730951},"43":{"tf":2.0},"44":{"tf":1.0},"47":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"e":{"df":2,"docs":{"15":{"tf":1.0},"45":{"tf":1.0}}},"r":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"14":{"tf":1.0},"15":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"e":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":2,"docs":{"44":{"tf":1.4142135623730951},"5":{"tf":1.0}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"12":{"tf":1.0}}}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"2":{"tf":1.0},"24":{"tf":1.0}}}}}}}}}},"d":{"df":0,"docs":{},"g":{"df":5,"docs":{"12":{"tf":1.0},"35":{"tf":1.7320508075688772},"42":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"38":{"tf":1.0}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"18":{"tf":1.0},"26":{"tf":1.0}}}},"df":0,"docs":{}},"i":{"c":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"44":{"tf":1.0}}}},"df":0,"docs":{}}}},"g":{"df":7,"docs":{"23":{"tf":1.4142135623730951},"27":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}},"l":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"df":2,"docs":{"4":{"tf":1.0},"5":{"tf":1.0}}}}},"df":0,"docs":{}},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"46":{"tf":1.0}}}}}},"n":{"a":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":1.4142135623730951},"29":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"11":{"tf":1.0},"4":{"tf":1.0}}}}}}},"d":{"df":12,"docs":{"18":{"tf":1.7320508075688772},"23":{"tf":1.4142135623730951},"26":{"tf":3.4641016151377544},"29":{"tf":4.0},"31":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"41":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":2.8284271247461903}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"38":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":4,"docs":{"10":{"tf":1.0},"35":{"tf":1.0},"46":{"tf":1.0},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}},"u":{"df":0,"docs":{},"m":{"df":2,"docs":{"15":{"tf":1.0},"23":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":12,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":3.3166247903554},"23":{"tf":3.4641016151377544},"31":{"tf":1.7320508075688772},"35":{"tf":1.0},"39":{"tf":2.449489742783178},"4":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"7":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"t":{"c":{"df":2,"docs":{"13":{"tf":1.0},"4":{"tf":1.0}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":7,"docs":{"15":{"tf":1.0},"18":{"tf":1.0},"32":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":1.0},"44":{"tf":1.0}},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{".":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"(":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}}},"df":5,"docs":{"14":{"tf":1.7320508075688772},"15":{"tf":1.7320508075688772},"16":{"tf":1.7320508075688772},"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}}},"df":35,"docs":{"10":{"tf":2.449489742783178},"11":{"tf":2.8284271247461903},"12":{"tf":1.7320508075688772},"14":{"tf":2.23606797749979},"15":{"tf":2.8284271247461903},"16":{"tf":1.7320508075688772},"17":{"tf":2.8284271247461903},"18":{"tf":2.6457513110645907},"2":{"tf":1.7320508075688772},"22":{"tf":1.0},"23":{"tf":3.0},"24":{"tf":1.0},"26":{"tf":4.0},"28":{"tf":1.4142135623730951},"29":{"tf":5.477225575051661},"3":{"tf":1.4142135623730951},"30":{"tf":2.0},"31":{"tf":1.7320508075688772},"32":{"tf":2.449489742783178},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":3.3166247903554},"36":{"tf":1.4142135623730951},"39":{"tf":2.23606797749979},"4":{"tf":2.23606797749979},"42":{"tf":2.6457513110645907},"44":{"tf":4.898979485566356},"45":{"tf":5.0},"46":{"tf":1.0},"47":{"tf":5.0},"5":{"tf":3.4641016151377544},"6":{"tf":1.4142135623730951},"7":{"tf":2.0},"8":{"tf":2.0},"9":{"tf":1.0}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{")":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"\"":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"s":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"(":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":6,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.4142135623730951},"23":{"tf":1.7320508075688772},"39":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"df":2,"docs":{"30":{"tf":1.0},"31":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"y":{"df":0,"docs":{},"w":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}}},"t":{"df":5,"docs":{"26":{"tf":2.8284271247461903},"29":{"tf":3.7416573867739413},"44":{"tf":2.6457513110645907},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}},"x":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"15":{"tf":1.0},"37":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"35":{"tf":1.0},"38":{"tf":1.0}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":14,"docs":{"11":{"tf":1.4142135623730951},"15":{"tf":1.4142135623730951},"17":{"tf":1.0},"2":{"tf":1.4142135623730951},"23":{"tf":1.4142135623730951},"26":{"tf":1.0},"29":{"tf":1.0},"30":{"tf":1.0},"4":{"tf":1.7320508075688772},"44":{"tf":1.0},"45":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"35":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"c":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"26":{"tf":1.0},"7":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"'":{"df":1,"docs":{"26":{"tf":1.0}}},"df":5,"docs":{"23":{"tf":1.0},"24":{"tf":1.0},"26":{"tf":2.23606797749979},"28":{"tf":1.4142135623730951},"29":{"tf":2.0}}}}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"35":{"tf":1.0}}}},"t":{"df":5,"docs":{"23":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.8284271247461903},"31":{"tf":1.0},"45":{"tf":1.0}}}},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"\"":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}}},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":2,"docs":{"15":{"tf":1.0},"23":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":1,"docs":{"7":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"15":{"tf":1.4142135623730951}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"35":{"tf":1.0},"7":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"29":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"s":{"df":5,"docs":{"11":{"tf":1.0},"30":{"tf":1.0},"32":{"tf":1.0},"33":{"tf":1.0},"44":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":4,"docs":{"26":{"tf":1.0},"29":{"tf":1.0},"32":{"tf":1.0},"42":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"35":{"tf":1.0}}}}},"r":{"a":{"df":3,"docs":{"22":{"tf":1.0},"44":{"tf":1.7320508075688772},"7":{"tf":1.0}}},"df":0,"docs":{}}}}},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"31":{"tf":1.0},"35":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"42":{"tf":1.7320508075688772}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"23":{"tf":1.0},"39":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"43":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}}},"r":{"df":1,"docs":{"31":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"41":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":2,"docs":{"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"2":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"d":{"df":7,"docs":{"11":{"tf":2.23606797749979},"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"35":{"tf":2.23606797749979},"41":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"df":3,"docs":{"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"26":{"tf":1.7320508075688772},"29":{"tf":2.0},"39":{"tf":1.0}}}}}},"df":0,"docs":{},"w":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.0}}}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":2,"docs":{"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"40":{"tf":1.0},"44":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"e":{"df":16,"docs":{"11":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"14":{"tf":1.0},"23":{"tf":1.0},"30":{"tf":1.4142135623730951},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"35":{"tf":1.7320508075688772},"39":{"tf":1.0},"4":{"tf":1.7320508075688772},"44":{"tf":2.6457513110645907},"45":{"tf":1.7320508075688772},"47":{"tf":1.0},"5":{"tf":1.7320508075688772},"8":{"tf":1.0},"9":{"tf":1.0}}}},"n":{"a":{"df":0,"docs":{},"l":{"df":3,"docs":{"26":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.7320508075688772}}}},"d":{"df":2,"docs":{"28":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":2,"docs":{"4":{"tf":1.0},"46":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":7,"docs":{"11":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":2.23606797749979},"16":{"tf":1.0},"35":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":8,"docs":{"15":{"tf":1.0},"26":{"tf":1.4142135623730951},"29":{"tf":1.0},"3":{"tf":1.0},"37":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":2.0},"45":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}}}},"l":{"a":{"df":0,"docs":{},"g":{"df":2,"docs":{"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"22":{"tf":1.0},"23":{"tf":1.0}}}},"df":0,"docs":{}}}}},"n":{"df":11,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"41":{"tf":1.0},"42":{"tf":2.449489742783178},"43":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":2.6457513110645907}},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"o":{"c":{"df":0,"docs":{},"u":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"47":{"tf":1.0}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"18":{"tf":1.0}}}}},"m":{"df":2,"docs":{"22":{"tf":1.0},"23":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"23":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":1,"docs":{"39":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":1,"docs":{"15":{"tf":1.0}}}},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":4,"docs":{"26":{"tf":1.0},"30":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951}},"i":{"df":2,"docs":{"39":{"tf":1.0},"45":{"tf":1.0}}}}},"n":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":11,"docs":{"15":{"tf":1.0},"29":{"tf":1.0},"35":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"24":{"tf":1.0},"26":{"tf":2.23606797749979},"29":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"s":{":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"c":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{":":{":":{"df":0,"docs":{},"{":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"29":{"tf":1.0}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"k":{":":{":":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.0}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.0}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":16,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.7320508075688772},"12":{"tf":2.0},"14":{"tf":1.0},"2":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.0},"33":{"tf":1.0},"37":{"tf":1.4142135623730951},"39":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"9":{"tf":1.0}},"i":{"c":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"47":{"tf":1.7320508075688772}}}}}},"df":1,"docs":{"44":{"tf":1.0}}}},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":6,"docs":{"10":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.4142135623730951}},"n":{"df":4,"docs":{"11":{"tf":1.0},"15":{"tf":1.7320508075688772},"5":{"tf":1.0},"7":{"tf":1.0}}}}}},"o":{"df":7,"docs":{"17":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"8":{"tf":1.4142135623730951}},"e":{"df":5,"docs":{"18":{"tf":1.0},"2":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"47":{"tf":1.0}}},"n":{"df":0,"docs":{},"e":{"df":1,"docs":{"44":{"tf":1.0}}}},"o":{"d":{"df":2,"docs":{"44":{"tf":1.0},"45":{"tf":1.0}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":2,"docs":{"11":{"tf":1.0},"33":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"46":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"u":{"a":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"30":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":14,"docs":{"11":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":2.23606797749979},"26":{"tf":2.8284271247461903},"29":{"tf":3.7416573867739413},"30":{"tf":1.0},"31":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}},"e":{".":{"a":{"d":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"(":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":1,"docs":{"43":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"g":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"4":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}}}}},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"35":{"tf":1.0}}}},"df":0,"docs":{}}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"22":{"tf":1.0},"39":{"tf":1.0}},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}}},"n":{"c":{"df":3,"docs":{"23":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"35":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"e":{"'":{"df":2,"docs":{"29":{"tf":4.0},"45":{"tf":1.0}}},"df":4,"docs":{"31":{"tf":2.0},"35":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}},"l":{"df":0,"docs":{},"i":{"df":3,"docs":{"30":{"tf":1.0},"31":{"tf":1.0},"32":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"o":{"d":{"df":2,"docs":{"30":{"tf":1.0},"42":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"35":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"p":{":":{"/":{"/":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{".":{"df":0,"docs":{},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"g":{"/":{"4":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"s":{":":{"/":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"/":{"a":{"/":{"3":{"8":{"3":{"3":{"8":{"5":{"7":{"8":{"/":{"1":{"8":{"8":{"5":{"3":{"5":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"i":{"'":{"df":0,"docs":{},"m":{"df":1,"docs":{"35":{"tf":1.0}}},"v":{"df":2,"docs":{"26":{"tf":1.0},"36":{"tf":1.0}}}},"2":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":4,"docs":{"11":{"tf":1.0},"26":{"tf":2.23606797749979},"29":{"tf":2.6457513110645907},"39":{"tf":1.0}}},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"29":{"tf":3.7416573867739413}}}},"g":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.0}}}}}},"i":{"df":1,"docs":{"40":{"tf":1.0}},"i":{"df":1,"docs":{"44":{"tf":1.0}}}},"m":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":2,"docs":{"35":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"<":{"df":0,"docs":{},"t":{"df":3,"docs":{"39":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":11,"docs":{"11":{"tf":1.4142135623730951},"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"22":{"tf":1.0},"23":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.0},"38":{"tf":1.4142135623730951},"40":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":5,"docs":{"2":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"23":{"tf":1.0}}}}}}},"n":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":4,"docs":{"3":{"tf":1.0},"42":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":2,"docs":{"4":{"tf":1.0},"45":{"tf":1.0}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"u":{"df":1,"docs":{"46":{"tf":1.0}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"18":{"tf":1.0},"22":{"tf":1.0}}}}}},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"27":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"41":{"tf":1.0}}}}}},"df":4,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"22":{"tf":1.0}},"e":{"(":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"e":{"c":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"i":{"d":{"df":1,"docs":{"8":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":2.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"15":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":2,"docs":{"13":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":7,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"24":{"tf":1.0},"30":{"tf":1.0},"33":{"tf":1.0},"7":{"tf":1.0}}}},"n":{"d":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"12":{"tf":1.0}}}}},"f":{"a":{"c":{"df":5,"docs":{"11":{"tf":1.4142135623730951},"35":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"v":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}}},"n":{"df":12,"docs":{"17":{"tf":1.4142135623730951},"22":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0},"32":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.6457513110645907},"47":{"tf":1.0},"5":{"tf":1.0}}},"v":{"df":1,"docs":{"15":{"tf":1.0}}}}},"o":{"<":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":5,"docs":{"37":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.23606797749979}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":6,"docs":{"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.23606797749979}}}}}}},"r":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"u":{"c":{"df":2,"docs":{"13":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":2,"docs":{"10":{"tf":1.0},"15":{"tf":1.4142135623730951}}}}}},"o":{":":{":":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"<":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"39":{"tf":1.0},"47":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":5,"docs":{"13":{"tf":1.4142135623730951},"24":{"tf":1.0},"28":{"tf":2.23606797749979},"29":{"tf":2.0},"47":{"tf":1.0}}},"p":{"c":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":2,"docs":{"22":{"tf":1.0},"35":{"tf":1.0}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"u":{"df":3,"docs":{"30":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}}},"t":{"'":{"df":15,"docs":{"11":{"tf":1.7320508075688772},"17":{"tf":1.0},"26":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.4142135623730951},"4":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.0}},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"47":{"tf":1.0}}},"r":{"df":4,"docs":{"35":{"tf":1.0},"42":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":6,"docs":{"11":{"tf":1.0},"36":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.4142135623730951},"45":{"tf":1.4142135623730951},"5":{"tf":1.0}}}}}}},"v":{"df":1,"docs":{"45":{"tf":1.0}}},"²":{"c":{"df":1,"docs":{"33":{"tf":1.0}}},"df":0,"docs":{}}},"j":{"df":0,"docs":{},"o":{"b":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":6,"docs":{"26":{"tf":1.0},"36":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"8":{"tf":1.0}}}},"y":{"df":2,"docs":{"11":{"tf":1.0},"15":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"d":{"df":7,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"23":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"42":{"tf":1.0},"47":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":7,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"3":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0},"7":{"tf":1.4142135623730951}},"n":{"df":1,"docs":{"5":{"tf":1.0}}}}}}},"l":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"15":{"tf":1.4142135623730951}}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"18":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"15":{"tf":1.0},"26":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"36":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"8":{"tf":1.0}}},"df":0,"docs":{},"k":{"df":1,"docs":{"13":{"tf":1.0}}},"n":{"df":1,"docs":{"22":{"tf":1.0}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"15":{"tf":1.0}}}},"v":{"df":1,"docs":{"45":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":3,"docs":{"15":{"tf":1.0},"29":{"tf":1.0},"36":{"tf":1.0}}}},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"37":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"45":{"tf":1.0}}}},"t":{"'":{"df":4,"docs":{"26":{"tf":2.449489742783178},"29":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.4142135623730951}}},"df":1,"docs":{"30":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0}}}}}},"i":{"b":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":5,"docs":{"13":{"tf":1.0},"22":{"tf":2.0},"30":{"tf":1.0},"33":{"tf":1.0},"44":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":1,"docs":{"42":{"tf":1.0}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}}},"n":{"df":0,"docs":{},"e":{"df":2,"docs":{"26":{"tf":1.0},"7":{"tf":1.4142135623730951}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"x":{"df":2,"docs":{"11":{"tf":1.0},"33":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"36":{"tf":1.0}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"o":{"a":{"d":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"32":{"tf":1.0},"9":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"g":{"df":2,"docs":{"13":{"tf":1.0},"26":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"k":{"df":4,"docs":{"1":{"tf":1.0},"26":{"tf":1.4142135623730951},"42":{"tf":1.0},"44":{"tf":1.0}}},"p":{"df":24,"docs":{"11":{"tf":1.0},"14":{"tf":1.4142135623730951},"15":{"tf":2.449489742783178},"16":{"tf":1.4142135623730951},"17":{"tf":2.23606797749979},"18":{"tf":2.0},"2":{"tf":1.0},"26":{"tf":4.69041575982343},"28":{"tf":1.0},"29":{"tf":6.164414002968976},"3":{"tf":1.4142135623730951},"30":{"tf":1.0},"31":{"tf":1.4142135623730951},"35":{"tf":1.7320508075688772},"36":{"tf":1.0},"42":{"tf":2.0},"44":{"tf":2.449489742783178},"45":{"tf":2.0},"46":{"tf":2.0},"47":{"tf":2.0},"5":{"tf":1.7320508075688772},"6":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951},"8":{"tf":2.0}},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.4142135623730951}},"e":{":":{":":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}},"t":{"df":4,"docs":{"31":{"tf":1.0},"35":{"tf":1.0},"46":{"tf":1.0},"7":{"tf":1.0}}},"w":{"df":1,"docs":{"11":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}}},"m":{"a":{"d":{"df":0,"docs":{},"e":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"47":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":8,"docs":{"22":{"tf":1.7320508075688772},"23":{"tf":1.0},"31":{"tf":1.0},"32":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0},"7":{"tf":1.7320508075688772}}}},"n":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"11":{"tf":1.0}}}},"d":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"37":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":4,"docs":{"11":{"tf":1.4142135623730951},"27":{"tf":1.0},"31":{"tf":1.0},"43":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.0},"22":{"tf":1.0},"39":{"tf":1.0}}}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"36":{"tf":1.0},"42":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"|":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"y":{"b":{"df":2,"docs":{"39":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"26":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"n":{"df":14,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.7320508075688772},"26":{"tf":1.0},"3":{"tf":1.0},"31":{"tf":1.0},"34":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}}},"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"30":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"45":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":18,"docs":{"17":{"tf":1.7320508075688772},"23":{"tf":1.4142135623730951},"26":{"tf":2.0},"30":{"tf":1.0},"31":{"tf":1.4142135623730951},"32":{"tf":1.0},"34":{"tf":1.7320508075688772},"35":{"tf":2.23606797749979},"37":{"tf":2.449489742783178},"38":{"tf":1.4142135623730951},"39":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":4.58257569495584},"45":{"tf":4.0},"46":{"tf":1.7320508075688772},"47":{"tf":4.47213595499958},"5":{"tf":1.7320508075688772},"6":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":2,"docs":{"39":{"tf":1.7320508075688772},"47":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"d":{"df":9,"docs":{"12":{"tf":1.0},"18":{"tf":1.0},"22":{"tf":1.4142135623730951},"39":{"tf":1.4142135623730951},"40":{"tf":1.7320508075688772},"42":{"tf":1.7320508075688772},"44":{"tf":2.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"d":{"d":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"2":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":1,"docs":{"36":{"tf":1.0}}}}}}}},"o":{"d":{"df":0,"docs":{},"e":{"df":1,"docs":{"12":{"tf":1.0}},"l":{"df":1,"docs":{"10":{"tf":1.0}}}},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"11":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":13,"docs":{"11":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.7320508075688772},"30":{"tf":2.23606797749979},"31":{"tf":1.4142135623730951},"32":{"tf":1.7320508075688772},"37":{"tf":1.4142135623730951},"39":{"tf":2.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"46":{"tf":1.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.7320508075688772}}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"44":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"e":{"df":5,"docs":{"13":{"tf":1.0},"26":{"tf":2.8284271247461903},"29":{"tf":3.7416573867739413},"39":{"tf":1.0},"8":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"s":{"c":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":5,"docs":{"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"41":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}}}},"df":5,"docs":{"17":{"tf":1.0},"34":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":2.23606797749979},"47":{"tf":2.449489742783178}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"g":{"(":{"df":0,"docs":{},"e":{"df":1,"docs":{"23":{"tf":1.0}}}},"df":1,"docs":{"26":{"tf":4.0}}}},"u":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"31":{"tf":1.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"38":{"tf":1.0}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"37":{"tf":1.0},"47":{"tf":2.449489742783178}}}}},"df":0,"docs":{},"l":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"7":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"t":{"df":9,"docs":{"14":{"tf":1.7320508075688772},"15":{"tf":2.0},"16":{"tf":1.7320508075688772},"26":{"tf":4.898979485566356},"29":{"tf":5.916079783099616},"42":{"tf":3.4641016151377544},"44":{"tf":3.1622776601683795},"45":{"tf":2.8284271247461903},"47":{"tf":3.605551275463989}}}},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"35":{"tf":1.0}}}}}}}}},"n":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":2,"docs":{"23":{"tf":1.0},"5":{"tf":1.0}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"17":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"45":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"5":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":3,"docs":{"13":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"d":{"df":24,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.0},"15":{"tf":1.7320508075688772},"22":{"tf":1.7320508075688772},"23":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.4142135623730951},"29":{"tf":1.4142135623730951},"3":{"tf":1.0},"30":{"tf":1.0},"32":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.7320508075688772},"36":{"tf":2.449489742783178},"4":{"tf":1.0},"40":{"tf":1.4142135623730951},"41":{"tf":1.7320508075688772},"42":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951},"8":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":3,"docs":{"11":{"tf":1.0},"4":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"35":{"tf":1.0},"45":{"tf":1.4142135623730951},"8":{"tf":1.7320508075688772}}}}},"w":{"_":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"12":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}}}},"df":5,"docs":{"12":{"tf":1.0},"17":{"tf":1.0},"32":{"tf":1.0},"36":{"tf":1.0},"5":{"tf":1.0}}},"x":{"df":0,"docs":{},"t":{"df":5,"docs":{"15":{"tf":1.4142135623730951},"35":{"tf":1.0},"42":{"tf":1.0},"46":{"tf":1.0},"8":{"tf":1.0}}}}},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"23":{"tf":1.0},"7":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":9,"docs":{"26":{"tf":1.0},"27":{"tf":1.0},"29":{"tf":1.0},"31":{"tf":1.0},"36":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"h":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"8":{"tf":1.4142135623730951}}},"i":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{},"f":{"df":1,"docs":{"44":{"tf":1.0}},"i":{"df":1,"docs":{"23":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}}},"w":{"df":7,"docs":{"26":{"tf":1.0},"29":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"45":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"m":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}}}},"o":{"b":{"df":0,"docs":{},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"11":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":1,"docs":{"37":{"tf":1.0}},"s":{"df":1,"docs":{"33":{"tf":1.0}}}}}}}},"df":0,"docs":{},"h":{"df":1,"docs":{"26":{"tf":1.0}}},"k":{"(":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"(":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":5,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"41":{"tf":1.0},"42":{"tf":1.7320508075688772},"47":{"tf":2.0}}},"l":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}},"df":0,"docs":{}},"n":{"c":{"df":2,"docs":{"14":{"tf":1.0},"31":{"tf":1.0}}},"df":22,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"22":{"tf":1.0},"26":{"tf":1.7320508075688772},"27":{"tf":1.0},"3":{"tf":1.0},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.4142135623730951},"37":{"tf":1.4142135623730951},"38":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"5":{"tf":1.4142135623730951},"6":{"tf":1.7320508075688772},"7":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}},"t":{"df":0,"docs":{},"o":{"df":1,"docs":{"44":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":9,"docs":{"10":{"tf":1.0},"3":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":2.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"39":{"tf":1.0}}}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"<":{"df":0,"docs":{},"t":{"df":1,"docs":{"38":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"18":{"tf":1.0},"29":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"28":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"15":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"18":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"t":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"x":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"_":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}},"df":6,"docs":{"22":{"tf":1.0},"31":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"40":{"tf":1.0},"44":{"tf":1.4142135623730951}},"g":{"df":0,"docs":{},"o":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"26":{"tf":1.4142135623730951},"29":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"10":{"tf":1.0},"13":{"tf":1.0}}},"df":0,"docs":{}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":7,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"30":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.7320508075688772},"47":{"tf":2.0},"5":{"tf":1.0}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"22":{"tf":1.0}}}}}}}}},"w":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"f":{"d":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":4,"docs":{"10":{"tf":1.0},"13":{"tf":1.4142135623730951},"30":{"tf":1.0},"41":{"tf":1.0}}}}}}}}}}},"p":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"29":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":2,"docs":{"6":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}}}},"df":0,"docs":{},"t":{"df":14,"docs":{"15":{"tf":1.0},"18":{"tf":1.4142135623730951},"23":{"tf":1.4142135623730951},"24":{"tf":1.0},"26":{"tf":1.0},"3":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.4142135623730951},"38":{"tf":1.4142135623730951},"40":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.7320508075688772},"7":{"tf":1.0}},"i":{"df":1,"docs":{"13":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"s":{"df":4,"docs":{"15":{"tf":1.0},"39":{"tf":1.0},"42":{"tf":1.4142135623730951},"6":{"tf":1.0}}},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"47":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":2,"docs":{"31":{"tf":1.0},"41":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":3,"docs":{"31":{"tf":1.0},"45":{"tf":2.23606797749979},"47":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":1,"docs":{"15":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"27":{"tf":1.0}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":3,"docs":{"45":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}}}}}},"h":{"a":{"df":0,"docs":{},"p":{"df":3,"docs":{"39":{"tf":1.0},"44":{"tf":1.0},"46":{"tf":1.0}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}}}}}},"g":{"df":0,"docs":{},"m":{"df":1,"docs":{"30":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":9,"docs":{"17":{"tf":1.7320508075688772},"18":{"tf":2.23606797749979},"23":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"46":{"tf":1.0},"47":{"tf":1.0}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":2,"docs":{"18":{"tf":1.7320508075688772},"36":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"l":{"a":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"11":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":3,"docs":{"31":{"tf":1.4142135623730951},"35":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"l":{"df":3,"docs":{"28":{"tf":1.0},"42":{"tf":2.449489742783178},"47":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}},"p":{"df":1,"docs":{"44":{"tf":1.0}}},"s":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.0}}},"s":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":5,"docs":{"43":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"5":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}}}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":1,"docs":{"44":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"3":{"tf":1.0},"45":{"tf":1.0}}}}}}},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"28":{"tf":1.0}}}}}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":2,"docs":{"15":{"tf":1.0},"34":{"tf":1.0}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.7320508075688772}}}}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"11":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"15":{"tf":1.4142135623730951},"30":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":2,"docs":{"2":{"tf":1.0},"39":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}},"l":{"df":0,"docs":{},"n":{"!":{"(":{"\"":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}}},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":5,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"26":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"o":{"b":{"a":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"28":{"tf":1.0},"29":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":5,"docs":{"15":{"tf":1.0},"22":{"tf":1.0},"27":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"df":2,"docs":{"4":{"tf":1.0},"8":{"tf":1.0}},"e":{"d":{"df":1,"docs":{"7":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":7,"docs":{"18":{"tf":1.0},"22":{"tf":1.7320508075688772},"23":{"tf":2.0},"39":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":2.23606797749979},"47":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"s":{"(":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":3,"docs":{"44":{"tf":2.449489742783178},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"<":{"df":0,"docs":{},"f":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"df":13,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"23":{"tf":1.7320508075688772},"27":{"tf":1.0},"30":{"tf":1.0},"32":{"tf":1.0},"36":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.449489742783178},"45":{"tf":1.7320508075688772},"47":{"tf":1.7320508075688772},"5":{"tf":1.0}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":1,"docs":{"23":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"'":{"df":3,"docs":{"32":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.0}}},"df":11,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"16":{"tf":1.0},"3":{"tf":1.4142135623730951},"30":{"tf":1.4142135623730951},"31":{"tf":1.0},"32":{"tf":1.0},"4":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.0}},"m":{"df":1,"docs":{"30":{"tf":1.0}}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}},"p":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"22":{"tf":1.0},"39":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"13":{"tf":1.0},"42":{"tf":1.0}}}}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":15,"docs":{"11":{"tf":1.0},"13":{"tf":1.7320508075688772},"14":{"tf":1.0},"15":{"tf":1.0},"2":{"tf":1.7320508075688772},"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"24":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.0},"32":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"b":{"df":5,"docs":{"36":{"tf":1.4142135623730951},"37":{"tf":1.4142135623730951},"41":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.0}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"34":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"h":{"df":4,"docs":{"10":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"t":{"df":2,"docs":{"16":{"tf":1.0},"47":{"tf":1.0}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}},"e":{"df":9,"docs":{"17":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0},"37":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.0},"46":{"tf":1.0},"47":{"tf":2.0},"5":{"tf":1.4142135623730951}}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":1,"docs":{"35":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"w":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"14":{"tf":1.0}}},"t":{"df":2,"docs":{"10":{"tf":1.0},"34":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"7":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}}}},"d":{"/":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"a":{"b":{"df":0,"docs":{},"l":{"df":6,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"35":{"tf":2.8284271247461903},"44":{"tf":1.7320508075688772},"45":{"tf":2.23606797749979},"47":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"df":6,"docs":{"35":{"tf":2.0},"4":{"tf":2.449489742783178},"44":{"tf":1.7320508075688772},"45":{"tf":2.449489742783178},"47":{"tf":2.449489742783178},"5":{"tf":1.7320508075688772}},"i":{"df":5,"docs":{"4":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"l":{"df":3,"docs":{"31":{"tf":1.0},"32":{"tf":1.0},"44":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"35":{"tf":1.0},"45":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":12,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":2.0},"26":{"tf":1.0},"29":{"tf":4.0},"31":{"tf":1.0},"35":{"tf":1.4142135623730951},"44":{"tf":2.8284271247461903},"45":{"tf":3.0},"46":{"tf":1.0},"47":{"tf":1.7320508075688772},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"p":{"(":{"df":0,"docs":{},"|":{"df":0,"docs":{},"m":{"df":1,"docs":{"26":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"a":{"c":{"df":0,"docs":{},"t":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{".":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":1,"docs":{"26":{"tf":2.0}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":2.0}}},"y":{".":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}}}},"h":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":0,"docs":{}}}},"v":{"df":1,"docs":{"23":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":2,"docs":{"42":{"tf":1.0},"44":{"tf":1.0}}}}},"v":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"(":{"0":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}},"df":3,"docs":{"42":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"39":{"tf":1.0},"47":{"tf":1.0}}}}},"g":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"26":{"tf":2.23606797749979}}},"df":0,"docs":{}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":2.0},"47":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"df":3,"docs":{"42":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}}},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}}}},"l":{"a":{"df":0,"docs":{},"t":{"df":3,"docs":{"14":{"tf":1.0},"33":{"tf":1.0},"44":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":1,"docs":{"32":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":1,"docs":{"1":{"tf":1.0}}}},"df":0,"docs":{}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"44":{"tf":1.0},"45":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"b":{"df":3,"docs":{"38":{"tf":1.0},"44":{"tf":1.0},"46":{"tf":1.0}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"v":{"df":2,"docs":{"42":{"tf":1.0},"44":{"tf":1.0}}}}},"p":{"df":1,"docs":{"45":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"45":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}}}},"l":{"a":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":1,"docs":{"45":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":3,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":1.0}}}}}},"q":{"df":1,"docs":{"45":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":5,"docs":{"12":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"44":{"tf":1.0},"7":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"s":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"18":{"tf":1.0},"45":{"tf":1.0}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":2,"docs":{"32":{"tf":1.0},"44":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"<":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":7,"docs":{"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951},"7":{"tf":1.0}}}}}},"t":{"df":2,"docs":{"39":{"tf":1.4142135623730951},"47":{"tf":1.0}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"30":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":10,"docs":{"13":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":2.0},"26":{"tf":2.23606797749979},"29":{"tf":2.8284271247461903},"39":{"tf":1.7320508075688772},"41":{"tf":1.4142135623730951},"44":{"tf":2.23606797749979},"8":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}}}},"o":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"df":0,"docs":{}},"s":{"df":1,"docs":{"14":{"tf":1.0}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":2,"docs":{"23":{"tf":1.0},"8":{"tf":1.0}}}},"n":{"df":17,"docs":{"11":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":1.4142135623730951},"25":{"tf":1.0},"26":{"tf":3.3166247903554},"29":{"tf":4.69041575982343},"3":{"tf":1.0},"30":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.7320508075688772},"46":{"tf":2.0},"47":{"tf":2.449489742783178},"5":{"tf":1.0},"6":{"tf":1.4142135623730951},"7":{"tf":1.0},"8":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"'":{"df":3,"docs":{"17":{"tf":1.0},"2":{"tf":1.0},"24":{"tf":1.0}}},"df":5,"docs":{"13":{"tf":1.4142135623730951},"22":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.4142135623730951},"38":{"tf":1.0}}}}}},"s":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":1,"docs":{"13":{"tf":1.7320508075688772}}}},"k":{"df":0,"docs":{},"e":{"df":2,"docs":{"26":{"tf":1.0},"31":{"tf":1.0}}}},"m":{"df":0,"docs":{},"e":{"df":6,"docs":{"15":{"tf":1.0},"22":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"5":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"35":{"tf":1.0},"39":{"tf":1.0}}}}},"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{".":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"(":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"26":{"tf":2.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"26":{"tf":2.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"15":{"tf":1.4142135623730951},"26":{"tf":2.449489742783178},"29":{"tf":3.872983346207417}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":5,"docs":{"14":{"tf":1.0},"15":{"tf":1.4142135623730951},"3":{"tf":1.0},"45":{"tf":1.7320508075688772},"5":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"34":{"tf":1.0},"44":{"tf":1.0}}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"28":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":4,"docs":{"26":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.4142135623730951},"5":{"tf":1.0}},"m":{"df":1,"docs":{"44":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"27":{"tf":1.0}}}},"df":0,"docs":{}},"f":{".":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"c":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"x":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}}},"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{".":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"&":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"43":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"(":{")":{".":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"&":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"r":{"c":{"df":0,"docs":{},"v":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"r":{"c":{"df":0,"docs":{},"v":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":3,"docs":{"44":{"tf":2.8284271247461903},"45":{"tf":2.6457513110645907},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"w":{"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"p":{"df":2,"docs":{"42":{"tf":1.7320508075688772},"47":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":6,"docs":{"41":{"tf":1.0},"42":{"tf":2.449489742783178},"43":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":2.0},"47":{"tf":2.8284271247461903}}}},"n":{"d":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"/":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"df":13,"docs":{"18":{"tf":1.7320508075688772},"23":{"tf":2.0},"26":{"tf":1.0},"29":{"tf":1.4142135623730951},"34":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"41":{"tf":1.7320508075688772},"44":{"tf":2.449489742783178},"45":{"tf":3.0},"47":{"tf":3.3166247903554},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"\"":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{",":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"d":{"!":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"(":{"b":{"\"":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"\"":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"26":{"tf":2.0}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"h":{",":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":1,"docs":{"26":{"tf":2.0}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":2.0}}},"y":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"\"":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{",":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"d":{"!":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}},"df":2,"docs":{"29":{"tf":3.7416573867739413},"47":{"tf":1.0}}}}},"df":0,"docs":{},"s":{"df":3,"docs":{"23":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0}}},"t":{"df":5,"docs":{"23":{"tf":1.0},"29":{"tf":2.8284271247461903},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":2.449489742783178}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":3,"docs":{"22":{"tf":1.0},"35":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":5,"docs":{"37":{"tf":1.7320508075688772},"38":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}},"t":{"df":5,"docs":{"31":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"40":{"tf":1.0}}}}}},"h":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":3,"docs":{"15":{"tf":1.4142135623730951},"30":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":1.0}}}},"u":{"df":0,"docs":{},"l":{"d":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"44":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"w":{"df":1,"docs":{"30":{"tf":1.0}}}},"u":{"df":0,"docs":{},"t":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":2,"docs":{"31":{"tf":1.0},"43":{"tf":1.0}}}}}},"df":1,"docs":{"43":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"l":{"df":4,"docs":{"20":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"7":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":3,"docs":{"11":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}},"i":{"c":{"df":1,"docs":{"31":{"tf":1.0}}},"df":4,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"29":{"tf":1.0},"7":{"tf":1.0}},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}}}},"n":{"df":1,"docs":{"44":{"tf":1.0}},"g":{"df":0,"docs":{},"l":{"df":7,"docs":{"27":{"tf":1.0},"32":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":1.0},"47":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0}}}}},"t":{"df":1,"docs":{"35":{"tf":1.0}},"u":{"a":{"df":0,"docs":{},"t":{"df":3,"docs":{"22":{"tf":1.0},"23":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}}},"k":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":1,"docs":{"47":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}}}}},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"35":{"tf":1.0}}},".":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"41":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}}},"df":17,"docs":{"13":{"tf":1.0},"29":{"tf":3.872983346207417},"30":{"tf":1.7320508075688772},"31":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":2.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.7320508075688772},"41":{"tf":1.0},"43":{"tf":1.7320508075688772},"44":{"tf":1.4142135623730951},"45":{"tf":2.6457513110645907},"47":{"tf":4.795831523312719},"5":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}},"v":{"df":1,"docs":{"44":{"tf":1.0}}}},"m":{"df":0,"docs":{},"e":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":1,"docs":{"26":{"tf":4.0}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":5,"docs":{"10":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"3":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"c":{"df":32,"docs":{"10":{"tf":1.7320508075688772},"11":{"tf":2.0},"12":{"tf":1.4142135623730951},"14":{"tf":2.0},"15":{"tf":1.7320508075688772},"16":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.7320508075688772},"2":{"tf":1.7320508075688772},"22":{"tf":1.0},"23":{"tf":2.449489742783178},"24":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.4142135623730951},"31":{"tf":1.0},"32":{"tf":2.23606797749979},"33":{"tf":1.4142135623730951},"34":{"tf":1.4142135623730951},"35":{"tf":2.0},"36":{"tf":1.7320508075688772},"39":{"tf":1.0},"4":{"tf":1.4142135623730951},"40":{"tf":1.4142135623730951},"41":{"tf":2.0},"42":{"tf":3.4641016151377544},"44":{"tf":4.58257569495584},"45":{"tf":2.23606797749979},"46":{"tf":1.7320508075688772},"47":{"tf":4.123105625617661},"5":{"tf":2.8284271247461903},"9":{"tf":1.0}},"e":{"'":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":2,"docs":{"31":{"tf":1.4142135623730951},"45":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"23":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":9,"docs":{"11":{"tf":1.0},"15":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}}}}},"t":{"df":0,"docs":{},"e":{"df":11,"docs":{"35":{"tf":1.7320508075688772},"39":{"tf":1.0},"4":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.7320508075688772},"7":{"tf":1.7320508075688772},"9":{"tf":1.0}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}}}},"u":{"df":1,"docs":{"23":{"tf":1.0}}}}},"d":{":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"c":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"<":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"22":{"tf":1.0},"23":{"tf":1.7320508075688772}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"i":{"df":0,"docs":{},"o":{":":{":":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":3,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"39":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"e":{"<":{"df":0,"docs":{},"t":{"df":1,"docs":{"38":{"tf":1.0}}},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"38":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"8":{"(":{"&":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"(":{")":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"{":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":1,"docs":{"2":{"tf":1.4142135623730951}}}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":5,"docs":{"15":{"tf":1.0},"23":{"tf":1.4142135623730951},"35":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"p":{"df":4,"docs":{"3":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.0},"8":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"27":{"tf":1.0}}}}}}},"i":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"23":{"tf":1.0}}}}},"u":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"u":{"b":{"df":1,"docs":{"44":{"tf":1.0}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"23":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"30":{"tf":1.0}}}}}}}},"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"23":{"tf":1.0},"27":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}}}},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"44":{"tf":1.0},"5":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"31":{"tf":1.0}}}},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.0}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"31":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"23":{"tf":1.4142135623730951}},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"x":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"11":{"tf":1.0},"44":{"tf":1.0}}}}}}}},"t":{":":{":":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":5,"docs":{"37":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.23606797749979}}}}}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":8,"docs":{"23":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.449489742783178},"45":{"tf":1.0},"7":{"tf":1.7320508075688772}},"n":{"df":1,"docs":{"44":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"15":{"tf":1.0}}}}},"c":{"df":0,"docs":{},"p":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":6,"docs":{"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.8284271247461903}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"35":{"tf":1.0},"44":{"tf":1.4142135623730951}}}},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"m":{"df":4,"docs":{"32":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}}}}},"h":{"a":{"df":0,"docs":{},"t":{"'":{"df":6,"docs":{"29":{"tf":1.0},"33":{"tf":1.4142135623730951},"34":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":2,"docs":{"17":{"tf":1.0},"31":{"tf":1.0}}}}}}},"r":{"df":0,"docs":{},"e":{"'":{"df":2,"docs":{"17":{"tf":1.0},"35":{"tf":1.0}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"37":{"tf":1.0},"43":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":13,"docs":{"12":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.0},"3":{"tf":1.7320508075688772},"31":{"tf":1.0},"33":{"tf":1.0},"37":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.0}}},"k":{"df":2,"docs":{"31":{"tf":1.4142135623730951},"7":{"tf":1.0}}}},"r":{"d":{"df":3,"docs":{"13":{"tf":1.0},"15":{"tf":1.0},"35":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}}}}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":7,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.0},"23":{"tf":1.0},"3":{"tf":1.0},"5":{"tf":1.0}}}},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":3,"docs":{"18":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":7,"docs":{"27":{"tf":2.0},"3":{"tf":1.0},"4":{"tf":1.0},"47":{"tf":1.0},"6":{"tf":2.23606797749979},"7":{"tf":1.0},"8":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":4,"docs":{"12":{"tf":1.0},"35":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":5,"docs":{"13":{"tf":1.4142135623730951},"2":{"tf":1.0},"23":{"tf":1.0},"29":{"tf":1.0},"44":{"tf":1.0}}}}}}},"u":{"df":1,"docs":{"10":{"tf":1.0}}}},"i":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}},"m":{"df":0,"docs":{},"e":{"df":7,"docs":{"11":{"tf":1.0},"14":{"tf":1.4142135623730951},"15":{"tf":2.23606797749979},"4":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"d":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":1,"docs":{"31":{"tf":1.0}}}}},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"(":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"s":{"(":{"5":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"{":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":8,"docs":{"11":{"tf":1.0},"14":{"tf":2.6457513110645907},"15":{"tf":2.8284271247461903},"16":{"tf":1.4142135623730951},"32":{"tf":1.0},"4":{"tf":1.0},"5":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}}},"o":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":5,"docs":{"16":{"tf":1.0},"32":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0},"9":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"42":{"tf":3.1622776601683795},"47":{"tf":2.8284271247461903}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":4,"docs":{"42":{"tf":1.7320508075688772},"44":{"tf":3.605551275463989},"45":{"tf":1.7320508075688772},"47":{"tf":1.7320508075688772}}}}},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"44":{"tf":1.0}}}},"p":{"df":1,"docs":{"14":{"tf":1.0}},"i":{"c":{"df":1,"docs":{"37":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"22":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"y":{"df":1,"docs":{"26":{"tf":2.0}}}},"r":{"a":{"c":{"df":0,"docs":{},"e":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"k":{"df":6,"docs":{"15":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"8":{"tf":1.0}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"7":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"44":{"tf":1.0}}},"df":10,"docs":{"10":{"tf":1.0},"13":{"tf":1.4142135623730951},"22":{"tf":1.7320508075688772},"23":{"tf":1.4142135623730951},"28":{"tf":1.0},"29":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0}}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"37":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"30":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"i":{"df":3,"docs":{"22":{"tf":1.0},"23":{"tf":1.0},"4":{"tf":1.0}},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"12":{"tf":1.4142135623730951},"35":{"tf":1.7320508075688772},"42":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.7320508075688772}}}}}}},"o":{"df":0,"docs":{},"u":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"e":{"df":2,"docs":{"45":{"tf":1.7320508075688772},"47":{"tf":1.4142135623730951}}}}},"u":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"41":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"47":{"tf":1.0}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.4142135623730951}}}}}}},"w":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"k":{"df":1,"docs":{"37":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":9,"docs":{"18":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"24":{"tf":1.0},"26":{"tf":2.0},"3":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.4142135623730951},"7":{"tf":1.0}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":20,"docs":{"11":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":2.6457513110645907},"14":{"tf":1.0},"22":{"tf":1.7320508075688772},"23":{"tf":3.1622776601683795},"24":{"tf":1.0},"28":{"tf":2.6457513110645907},"29":{"tf":2.0},"36":{"tf":2.23606797749979},"37":{"tf":2.23606797749979},"38":{"tf":1.0},"39":{"tf":3.4641016151377544},"40":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.0},"47":{"tf":2.23606797749979},"5":{"tf":1.0},"9":{"tf":1.0}}},"i":{"c":{"df":1,"docs":{"6":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"11":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.0}}}}}},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"14":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":4,"docs":{"35":{"tf":1.0},"39":{"tf":1.4142135623730951},"4":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":2,"docs":{"20":{"tf":1.0},"29":{"tf":3.872983346207417}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"s":{"a":{"df":0,"docs":{},"f":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":5,"docs":{"14":{"tf":1.0},"18":{"tf":1.0},"35":{"tf":1.0},"4":{"tf":1.0},"46":{"tf":1.4142135623730951}}}}}},"p":{"d":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"5":{"tf":1.0}}}},"df":0,"docs":{}},"df":17,"docs":{"11":{"tf":1.0},"15":{"tf":1.0},"17":{"tf":2.0},"18":{"tf":1.4142135623730951},"30":{"tf":1.0},"31":{"tf":1.0},"35":{"tf":2.0},"36":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":2.6457513110645907},"45":{"tf":2.449489742783178},"47":{"tf":2.0},"5":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"47":{"tf":1.0}}}}},"s":{"b":{"df":1,"docs":{"11":{"tf":1.0}}},"df":33,"docs":{"10":{"tf":1.0},"11":{"tf":2.0},"12":{"tf":1.0},"13":{"tf":2.0},"14":{"tf":2.0},"15":{"tf":2.23606797749979},"16":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"18":{"tf":1.7320508075688772},"2":{"tf":1.4142135623730951},"22":{"tf":1.4142135623730951},"23":{"tf":1.4142135623730951},"26":{"tf":4.242640687119285},"27":{"tf":1.0},"28":{"tf":2.0},"29":{"tf":5.291502622129181},"30":{"tf":1.4142135623730951},"31":{"tf":2.449489742783178},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.7320508075688772},"4":{"tf":1.0},"41":{"tf":1.0},"44":{"tf":2.6457513110645907},"45":{"tf":2.0},"46":{"tf":1.4142135623730951},"47":{"tf":2.449489742783178},"6":{"tf":1.4142135623730951},"7":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}},"e":{"d":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"45":{"tf":2.0},"47":{"tf":2.23606797749979}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":7,"docs":{"22":{"tf":1.7320508075688772},"35":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.7320508075688772}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":4,"docs":{"11":{"tf":1.0},"31":{"tf":1.0},"39":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"5":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":6,"docs":{"15":{"tf":1.0},"18":{"tf":1.0},"26":{"tf":3.0},"29":{"tf":3.7416573867739413},"37":{"tf":1.0},"44":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"i":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"29":{"tf":1.0},"44":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{},"e":{"c":{"<":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"47":{"tf":1.0}}}}},"t":{"df":1,"docs":{"38":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"c":{"<":{"df":0,"docs":{},"u":{"8":{"df":2,"docs":{"39":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":1,"docs":{"47":{"tf":1.4142135623730951}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"17":{"tf":1.0},"30":{"tf":1.0}}},"s":{"a":{"df":1,"docs":{"47":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"1":{"tf":1.4142135623730951},"13":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"i":{"a":{"df":4,"docs":{"11":{"tf":1.0},"26":{"tf":2.0},"33":{"tf":1.0},"42":{"tf":1.0}}},"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}},"s":{"df":2,"docs":{"6":{"tf":1.0},"7":{"tf":1.0}}}},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":9,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"3":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.4142135623730951},"4":{"tf":2.23606797749979},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"8":{"tf":1.7320508075688772}}}},"k":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":4,"docs":{"36":{"tf":1.4142135623730951},"41":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":4,"docs":{"36":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":8,"docs":{"17":{"tf":2.0},"18":{"tf":1.0},"35":{"tf":1.7320508075688772},"36":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":2.23606797749979},"47":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":2,"docs":{"35":{"tf":1.0},"44":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"t":{"df":10,"docs":{"12":{"tf":1.0},"23":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"31":{"tf":1.0},"34":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"46":{"tf":1.0},"9":{"tf":1.0}}}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"y":{"df":13,"docs":{"13":{"tf":1.4142135623730951},"15":{"tf":1.0},"17":{"tf":1.0},"23":{"tf":1.0},"3":{"tf":1.4142135623730951},"31":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"8":{"tf":1.0}}}},"df":0,"docs":{},"e":{"'":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":6,"docs":{"36":{"tf":1.0},"37":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772}}}},"r":{"df":3,"docs":{"30":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.4142135623730951}}},"v":{"df":3,"docs":{"31":{"tf":1.0},"40":{"tf":1.0},"44":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"22":{"tf":1.0},"27":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":3,"docs":{"31":{"tf":1.0},"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":2,"docs":{"10":{"tf":1.0},"47":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":6,"docs":{"12":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":2.23606797749979},"46":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}}}}}}},"i":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":3,"docs":{"16":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"26":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"45":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":1,"docs":{"44":{"tf":1.4142135623730951}},"n":{"df":5,"docs":{"18":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}}},"n":{"'":{"df":0,"docs":{},"t":{"df":3,"docs":{"35":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}}}}},"df":0,"docs":{}},"r":{"d":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{},"k":{"df":14,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"27":{"tf":1.0},"3":{"tf":1.0},"30":{"tf":1.0},"32":{"tf":1.0},"36":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"47":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"l":{"d":{"!":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":6,"docs":{"11":{"tf":1.0},"13":{"tf":1.0},"28":{"tf":1.4142135623730951},"30":{"tf":1.0},"45":{"tf":1.0},"5":{"tf":1.0}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"31":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"11":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"a":{"b":{"df":0,"docs":{},"l":{"df":5,"docs":{"12":{"tf":1.0},"35":{"tf":2.0},"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"df":14,"docs":{"26":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"3":{"tf":1.4142135623730951},"31":{"tf":1.4142135623730951},"35":{"tf":1.0},"4":{"tf":1.7320508075688772},"40":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":4,"docs":{"26":{"tf":1.0},"27":{"tf":1.0},"31":{"tf":1.0},"35":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"'":{"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":4,"docs":{"15":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.0},"42":{"tf":1.0}}}},"r":{"df":3,"docs":{"1":{"tf":1.0},"28":{"tf":1.0},"33":{"tf":1.0}}},"v":{"df":1,"docs":{"5":{"tf":1.0}}}},".":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":1,"docs":{"2":{"tf":1.0}}}}}}}}}},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":1,"docs":{"23":{"tf":1.0}},"m":{"df":0,"docs":{},"q":{"'":{"df":2,"docs":{"35":{"tf":1.4142135623730951},"45":{"tf":1.0}}},"df":11,"docs":{"11":{"tf":1.0},"30":{"tf":2.0},"31":{"tf":1.4142135623730951},"33":{"tf":1.0},"35":{"tf":1.4142135623730951},"37":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951},"45":{"tf":2.0},"47":{"tf":3.605551275463989},"9":{"tf":1.0}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":4,"docs":{"36":{"tf":1.4142135623730951},"41":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}},"e":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"<":{"df":0,"docs":{},"t":{"df":5,"docs":{"37":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"37":{"tf":1.4142135623730951},"38":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}}}}}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"35":{"tf":1.0}}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"v":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"41":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":1,"docs":{"47":{"tf":1.4142135623730951}}}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"'":{"df":2,"docs":{"31":{"tf":1.0},"42":{"tf":1.0}}},"df":8,"docs":{"31":{"tf":1.7320508075688772},"35":{"tf":2.449489742783178},"36":{"tf":1.0},"37":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":3.1622776601683795},"45":{"tf":3.4641016151377544}}}}}},"df":0,"docs":{}}}}}},"breadcrumbs":{"root":{"0":{".":{"3":{"df":1,"docs":{"26":{"tf":2.0}}},"9":{"df":1,"docs":{"47":{"tf":1.4142135623730951}}},"df":0,"docs":{}},":":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":3,"docs":{"44":{"tf":1.7320508075688772},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}},"u":{"8":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}},"1":{".":{"0":{"df":1,"docs":{"47":{"tf":1.4142135623730951}}},"6":{"3":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":3,"docs":{"2":{"tf":1.0},"38":{"tf":1.0},"47":{"tf":1.0}}},"2":{"0":{"2":{"1":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"2":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"3":{"df":4,"docs":{"15":{"tf":1.4142135623730951},"2":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"4":{"df":1,"docs":{"2":{"tf":1.0}}},"5":{"df":1,"docs":{"14":{"tf":1.0}}},"_":{"df":8,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"44":{"tf":3.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.7320508075688772}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"d":{"_":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}},"df":0,"docs":{}}}},"a":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"28":{"tf":1.0}}}},"o":{"df":0,"docs":{},"v":{"df":2,"docs":{"31":{"tf":1.0},"45":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"11":{"tf":1.0},"30":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"37":{"tf":1.4142135623730951}}}}},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"r":{"d":{"df":1,"docs":{"47":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":6,"docs":{"14":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951}}}},"v":{"df":1,"docs":{"45":{"tf":1.0}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":6,"docs":{"35":{"tf":1.4142135623730951},"36":{"tf":1.0},"38":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"d":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":5,"docs":{"13":{"tf":1.0},"24":{"tf":1.7320508075688772},"28":{"tf":1.0},"31":{"tf":1.0},"9":{"tf":1.0}}}}},"d":{"df":7,"docs":{"28":{"tf":1.0},"35":{"tf":1.4142135623730951},"39":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"31":{"tf":1.4142135623730951}}}}}}},"df":5,"docs":{"15":{"tf":1.7320508075688772},"29":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0}},"v":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"7":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"15":{"tf":2.23606797749979},"35":{"tf":1.0},"43":{"tf":1.0},"45":{"tf":2.0},"46":{"tf":1.0},"47":{"tf":1.0}},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{},"w":{"df":3,"docs":{"39":{"tf":1.4142135623730951},"47":{"tf":1.0},"8":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"10":{"tf":1.0}}}},"o":{"df":0,"docs":{},"f":{"df":1,"docs":{"26":{"tf":1.7320508075688772}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":3,"docs":{"22":{"tf":1.0},"35":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"46":{"tf":1.0}}}}}},"w":{"a":{"df":0,"docs":{},"y":{"df":4,"docs":{"32":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"15":{"tf":1.0},"4":{"tf":1.0}}}}}}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":6,"docs":{"23":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.4142135623730951},"39":{"tf":1.0},"45":{"tf":1.0},"5":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}}}}}},"y":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"'":{"df":1,"docs":{"23":{"tf":1.0}}},":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"23":{"tf":1.0},"39":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":3,"docs":{"39":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}},"t":{"df":0,"docs":{},"h":{"df":3,"docs":{"28":{"tf":1.0},"4":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}}}}},"p":{"df":0,"docs":{},"i":{"df":4,"docs":{"1":{"tf":1.7320508075688772},"22":{"tf":1.4142135623730951},"38":{"tf":1.4142135623730951},"5":{"tf":1.0}}},"p":{"df":1,"docs":{"15":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"i":{"c":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"'":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}}}}},"df":1,"docs":{"31":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"o":{"a":{"c":{"df":0,"docs":{},"h":{"df":4,"docs":{"44":{"tf":1.0},"46":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"11":{"tf":1.0}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"15":{"tf":1.4142135623730951},"26":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0}}}}},"u":{"df":1,"docs":{"15":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":6,"docs":{"10":{"tf":1.0},"11":{"tf":1.4142135623730951},"27":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"45":{"tf":1.0}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"df":0,"docs":{},"f":{"d":{"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":2.0},"28":{"tf":1.0}},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":1,"docs":{"13":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"r":{"a":{"df":0,"docs":{},"w":{"df":0,"docs":{},"f":{"d":{"df":2,"docs":{"11":{"tf":1.0},"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"i":{"df":4,"docs":{"12":{"tf":1.0},"23":{"tf":1.7320508075688772},"39":{"tf":2.0},"44":{"tf":1.0}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"n":{"c":{"/":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":8,"docs":{"2":{"tf":1.0},"24":{"tf":1.7320508075688772},"25":{"tf":1.0},"26":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}}}},"df":7,"docs":{"24":{"tf":1.4142135623730951},"25":{"tf":1.7320508075688772},"26":{"tf":5.830951894845301},"27":{"tf":2.0},"28":{"tf":2.8284271247461903},"29":{"tf":7.54983443527075},"7":{"tf":1.7320508075688772}},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"23":{"tf":1.0},"3":{"tf":1.0}}}}}},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}}}}}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":3,"docs":{"30":{"tf":1.0},"35":{"tf":1.0},"47":{"tf":1.0}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":4,"docs":{"1":{"tf":1.0},"11":{"tf":1.0},"13":{"tf":1.0},"4":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"13":{"tf":1.0},"43":{"tf":1.0}}},"df":0,"docs":{}}}},"w":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"27":{"tf":1.0}}},"y":{"df":1,"docs":{"32":{"tf":1.0}}}},"df":0,"docs":{}}},"b":{"a":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"31":{"tf":1.0},"44":{"tf":1.0}},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{}}}}}},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"/":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}},"df":1,"docs":{"9":{"tf":1.0}}}}}}},"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":8,"docs":{"10":{"tf":1.0},"11":{"tf":1.4142135623730951},"23":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"i":{"c":{"df":2,"docs":{"30":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}}},"df":4,"docs":{"41":{"tf":1.0},"43":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951}},"e":{"c":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":8,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"18":{"tf":1.0},"22":{"tf":1.0},"35":{"tf":1.7320508075688772},"44":{"tf":2.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}},"df":5,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"38":{"tf":1.0},"46":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"23":{"tf":1.0},"26":{"tf":1.0},"31":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}},"h":{"a":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":2,"docs":{"26":{"tf":2.0},"47":{"tf":1.4142135623730951}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":5,"docs":{"30":{"tf":1.0},"32":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"df":0,"docs":{},"t":{"df":4,"docs":{"32":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.0},"43":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":10,"docs":{"26":{"tf":5.291502622129181},"28":{"tf":2.23606797749979},"29":{"tf":5.5677643628300215},"3":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951},"43":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951},"47":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":2.449489742783178}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"2":{"tf":1.0}}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"13":{"tf":1.0}},"e":{"d":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"13":{"tf":2.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"t":{"df":0,"docs":{},"h":{"df":5,"docs":{"12":{"tf":1.0},"22":{"tf":1.4142135623730951},"26":{"tf":1.0},"29":{"tf":1.0},"44":{"tf":1.0}}}},"x":{"<":{"d":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"df":2,"docs":{"23":{"tf":1.4142135623730951},"39":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"k":{"df":4,"docs":{"15":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"f":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"29":{"tf":2.6457513110645907}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"l":{"d":{"df":4,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"30":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.0},"31":{"tf":1.0},"47":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"df":1,"docs":{"18":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"e":{"df":1,"docs":{"26":{"tf":2.23606797749979}}},"t":{"df":0,"docs":{},"e":{"df":2,"docs":{"47":{"tf":1.0},"5":{"tf":1.0}}}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"28":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}},"df":15,"docs":{"11":{"tf":1.0},"15":{"tf":2.8284271247461903},"22":{"tf":1.4142135623730951},"23":{"tf":1.4142135623730951},"24":{"tf":1.0},"26":{"tf":1.4142135623730951},"30":{"tf":1.0},"39":{"tf":2.0},"44":{"tf":3.1622776601683795},"45":{"tf":2.0},"47":{"tf":2.8284271247461903},"5":{"tf":2.8284271247461903},"6":{"tf":1.4142135623730951},"7":{"tf":1.0},"8":{"tf":2.6457513110645907}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":16,"docs":{"18":{"tf":1.4142135623730951},"22":{"tf":1.0},"23":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"35":{"tf":2.0},"39":{"tf":1.0},"4":{"tf":1.4142135623730951},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.6457513110645907},"45":{"tf":1.4142135623730951},"47":{"tf":2.6457513110645907},"5":{"tf":1.7320508075688772},"7":{"tf":1.0},"8":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"23":{"tf":1.4142135623730951},"31":{"tf":1.0},"39":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"'":{"df":12,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"10":{"tf":1.0},"17":{"tf":1.0},"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.4142135623730951},"30":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0}}},":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"<":{"df":0,"docs":{},"t":{"df":3,"docs":{"37":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}},"df":5,"docs":{"23":{"tf":1.0},"34":{"tf":1.0},"36":{"tf":1.7320508075688772},"41":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":3,"docs":{"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"<":{"df":0,"docs":{},"t":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":5,"docs":{"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}}}}}}},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"26":{"tf":1.4142135623730951},"29":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"26":{"tf":2.23606797749979},"29":{"tf":2.8284271247461903}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"c":{":":{":":{"df":0,"docs":{},"f":{"d":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"33":{"tf":1.0},"36":{"tf":1.0}},"i":{"c":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"f":{"d":{"(":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"<":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"c":{":":{":":{"df":0,"docs":{},"f":{"d":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"<":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"o":{"df":1,"docs":{"29":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{":":{":":{"a":{"d":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":1,"docs":{"29":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"m":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"g":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{":":{":":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"p":{"df":3,"docs":{"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.4142135623730951}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":4,"docs":{"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":2.449489742783178},"47":{"tf":1.7320508075688772}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":2.449489742783178},"47":{"tf":1.7320508075688772}}}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"42":{"tf":2.0},"47":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":26,"docs":{"10":{"tf":1.0},"11":{"tf":1.7320508075688772},"14":{"tf":1.0},"15":{"tf":1.4142135623730951},"16":{"tf":1.0},"2":{"tf":2.23606797749979},"21":{"tf":1.4142135623730951},"22":{"tf":1.4142135623730951},"24":{"tf":1.7320508075688772},"26":{"tf":1.0},"27":{"tf":1.4142135623730951},"28":{"tf":1.7320508075688772},"3":{"tf":1.0},"31":{"tf":1.4142135623730951},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"34":{"tf":1.0},"36":{"tf":1.4142135623730951},"42":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":3.1622776601683795},"5":{"tf":2.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.7320508075688772}}}}}}},"n":{"'":{"df":0,"docs":{},"t":{"df":2,"docs":{"23":{"tf":1.0},"30":{"tf":1.0}}}},"d":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"37":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"p":{"a":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"10":{"tf":1.0},"37":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":7,"docs":{"30":{"tf":1.0},"32":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.0},"7":{"tf":1.0}},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}},"g":{"df":0,"docs":{},"o":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"18":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":7,"docs":{"31":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"39":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"23":{"tf":1.0}}}}}}}},"u":{"df":0,"docs":{},"s":{"df":3,"docs":{"15":{"tf":1.0},"31":{"tf":1.0},"45":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":3.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"24":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"14":{"tf":1.0},"4":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"31":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":4,"docs":{"35":{"tf":2.23606797749979},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"'":{"df":1,"docs":{"44":{"tf":1.0}}},"df":12,"docs":{"17":{"tf":1.4142135623730951},"19":{"tf":1.7320508075688772},"23":{"tf":1.4142135623730951},"26":{"tf":2.8284271247461903},"32":{"tf":1.0},"34":{"tf":1.7320508075688772},"36":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":2.0},"45":{"tf":1.7320508075688772},"47":{"tf":3.0},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}}}}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"2":{"tf":2.0},"3":{"tf":1.0},"30":{"tf":1.4142135623730951},"31":{"tf":1.0},"36":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"k":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":2.449489742783178},"5":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"28":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":3,"docs":{"35":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"45":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"7":{"tf":1.0}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":1,"docs":{"47":{"tf":1.4142135623730951}}}},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"23":{"tf":1.0},"44":{"tf":1.4142135623730951}}},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}}}}},"o":{"d":{"df":0,"docs":{},"e":{"df":17,"docs":{"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"25":{"tf":1.7320508075688772},"26":{"tf":3.1622776601683795},"27":{"tf":1.0},"28":{"tf":2.0},"29":{"tf":2.23606797749979},"3":{"tf":1.4142135623730951},"31":{"tf":2.0},"43":{"tf":1.0},"44":{"tf":2.0},"46":{"tf":1.0},"47":{"tf":2.449489742783178},"5":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":2.6457513110645907},"8":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"c":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"<":{"df":0,"docs":{},"t":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"m":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"15":{"tf":1.0},"2":{"tf":1.0},"32":{"tf":1.0},"44":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":2,"docs":{"24":{"tf":1.0},"7":{"tf":1.0}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"22":{"tf":1.0},"33":{"tf":1.0},"41":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":6,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"27":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.0},"8":{"tf":1.0}}},"x":{"df":4,"docs":{"22":{"tf":1.0},"30":{"tf":2.0},"32":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}},"i":{"c":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"26":{"tf":1.0},"29":{"tf":1.0},"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}}},"s":{"df":4,"docs":{"32":{"tf":1.7320508075688772},"36":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"t":{"df":5,"docs":{"32":{"tf":1.7320508075688772},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"9":{"tf":2.0}}}}}},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}}}},"n":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"22":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":2,"docs":{"3":{"tf":1.4142135623730951},"6":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"31":{"tf":1.0},"45":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"27":{"tf":1.0}}}}}},"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"12":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}}}},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":9,"docs":{"23":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"41":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"\"":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}}}},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"44":{"tf":2.8284271247461903},"45":{"tf":3.0},"47":{"tf":2.23606797749979}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":4,"docs":{"10":{"tf":1.0},"39":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":1,"docs":{"18":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":4,"docs":{"12":{"tf":1.0},"30":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":1,"docs":{"22":{"tf":1.4142135623730951}}},"t":{"df":4,"docs":{"23":{"tf":1.0},"29":{"tf":1.0},"41":{"tf":1.0},"47":{"tf":1.7320508075688772}}}},"y":{"df":1,"docs":{"35":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":4,"docs":{"13":{"tf":1.0},"26":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"u":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"r":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"3":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"4":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"22":{"tf":1.0},"27":{"tf":1.0}},"s":{"/":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"/":{"d":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":24,"docs":{"11":{"tf":1.0},"12":{"tf":1.7320508075688772},"14":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.7320508075688772},"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.0},"40":{"tf":2.0},"41":{"tf":1.4142135623730951},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":2.0},"46":{"tf":1.0},"47":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.8284271247461903}}}},"x":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":2,"docs":{"2":{"tf":1.0},"9":{"tf":1.0}}}}}}},"y":{"c":{"df":0,"docs":{},"l":{"df":2,"docs":{"4":{"tf":1.0},"42":{"tf":1.0}}}},"df":0,"docs":{}}},"d":{"a":{"df":0,"docs":{},"t":{"a":{".":{".":{".":{"\"":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":9,"docs":{"15":{"tf":1.4142135623730951},"29":{"tf":1.0},"30":{"tf":1.7320508075688772},"35":{"tf":1.0},"39":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"5":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"14":{"tf":1.7320508075688772},"15":{"tf":1.7320508075688772},"16":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"l":{"df":3,"docs":{"22":{"tf":1.0},"31":{"tf":1.0},"44":{"tf":1.0}},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}},"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":1,"docs":{"35":{"tf":1.0}}}}},"c":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"23":{"tf":1.0}}},"df":0,"docs":{},"s":{"df":1,"docs":{"31":{"tf":1.0}}}},"o":{"d":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"39":{"tf":1.0},"40":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":5,"docs":{"31":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951},"6":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{".":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"s":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":13,"docs":{"11":{"tf":2.0},"12":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"23":{"tf":1.0},"30":{"tf":1.4142135623730951},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"35":{"tf":1.4142135623730951},"39":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":3,"docs":{"28":{"tf":1.0},"32":{"tf":1.0},"9":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"y":{"df":1,"docs":{"15":{"tf":1.0}}}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":7,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"32":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"36":{"tf":1.0}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"44":{"tf":1.0},"46":{"tf":1.0}}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":1,"docs":{"1":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":6,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"s":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"31":{"tf":1.4142135623730951},"46":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"(":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"11":{"tf":1.0}}}}}}},"o":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"7":{"tf":1.0}},"e":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"7":{"tf":1.0}},"e":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"w":{"df":0,"docs":{},"o":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"7":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"c":{"df":3,"docs":{"1":{"tf":1.0},"35":{"tf":1.4142135623730951},"47":{"tf":1.0}},"s":{".":{"df":0,"docs":{},"r":{"df":1,"docs":{"1":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":2,"docs":{"22":{"tf":1.0},"45":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":3,"docs":{"35":{"tf":1.0},"4":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":3.872983346207417}}}}},"df":0,"docs":{}},"n":{"'":{"df":0,"docs":{},"t":{"df":9,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0},"36":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"8":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":3,"docs":{"30":{"tf":1.0},"44":{"tf":1.0},"7":{"tf":1.0}}}},"u":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"df":0,"docs":{},"n":{"df":3,"docs":{"15":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951}}}}},"r":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":2,"docs":{"44":{"tf":1.0},"45":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":6,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.4142135623730951},"43":{"tf":2.23606797749979},"44":{"tf":1.0},"47":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"e":{"df":2,"docs":{"15":{"tf":1.0},"45":{"tf":1.0}}},"r":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"14":{"tf":1.0},"15":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"e":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":2,"docs":{"44":{"tf":1.4142135623730951},"5":{"tf":1.0}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"12":{"tf":1.0}}}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"2":{"tf":1.0},"24":{"tf":1.0}}}}}}}}}},"d":{"df":0,"docs":{},"g":{"df":5,"docs":{"12":{"tf":1.0},"35":{"tf":1.7320508075688772},"42":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"38":{"tf":1.0}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"18":{"tf":1.0},"26":{"tf":1.0}}}},"df":0,"docs":{}},"i":{"c":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"44":{"tf":1.0}}}},"df":0,"docs":{}}}},"g":{"df":7,"docs":{"23":{"tf":1.4142135623730951},"27":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}},"l":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"df":2,"docs":{"4":{"tf":1.0},"5":{"tf":1.0}}}}},"df":0,"docs":{}},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"46":{"tf":1.0}}}}}},"n":{"a":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":1.7320508075688772},"29":{"tf":2.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"11":{"tf":1.0},"4":{"tf":1.0}}}}}}},"d":{"df":12,"docs":{"18":{"tf":1.7320508075688772},"23":{"tf":1.4142135623730951},"26":{"tf":3.4641016151377544},"29":{"tf":4.0},"31":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"41":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":2.8284271247461903}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"38":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":4,"docs":{"10":{"tf":1.0},"35":{"tf":1.0},"46":{"tf":1.0},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}},"u":{"df":0,"docs":{},"m":{"df":2,"docs":{"15":{"tf":1.0},"23":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":12,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"21":{"tf":1.7320508075688772},"22":{"tf":3.4641016151377544},"23":{"tf":3.7416573867739413},"31":{"tf":1.7320508075688772},"35":{"tf":1.0},"39":{"tf":2.449489742783178},"4":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"7":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"t":{"c":{"df":2,"docs":{"13":{"tf":1.0},"4":{"tf":1.0}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":7,"docs":{"15":{"tf":1.0},"18":{"tf":1.0},"32":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":1.0},"44":{"tf":1.0}},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{".":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"(":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}}},"df":5,"docs":{"14":{"tf":1.7320508075688772},"15":{"tf":1.7320508075688772},"16":{"tf":1.7320508075688772},"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}}},"df":39,"docs":{"10":{"tf":2.8284271247461903},"11":{"tf":3.0},"12":{"tf":2.0},"13":{"tf":1.0},"14":{"tf":2.449489742783178},"15":{"tf":3.0},"16":{"tf":2.0},"17":{"tf":3.1622776601683795},"18":{"tf":2.8284271247461903},"19":{"tf":1.0},"2":{"tf":1.7320508075688772},"20":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.4142135623730951},"23":{"tf":3.1622776601683795},"24":{"tf":1.0},"26":{"tf":4.0},"28":{"tf":1.4142135623730951},"29":{"tf":5.477225575051661},"3":{"tf":2.0},"30":{"tf":2.0},"31":{"tf":1.7320508075688772},"32":{"tf":2.6457513110645907},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":3.3166247903554},"36":{"tf":1.4142135623730951},"39":{"tf":2.23606797749979},"4":{"tf":2.449489742783178},"42":{"tf":2.6457513110645907},"44":{"tf":5.0990195135927845},"45":{"tf":5.196152422706632},"46":{"tf":1.4142135623730951},"47":{"tf":5.196152422706632},"5":{"tf":3.7416573867739413},"6":{"tf":1.7320508075688772},"7":{"tf":2.449489742783178},"8":{"tf":2.23606797749979},"9":{"tf":1.4142135623730951}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{")":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"\"":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"s":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"(":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":6,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.4142135623730951},"23":{"tf":2.0},"39":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"df":2,"docs":{"30":{"tf":1.0},"31":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"y":{"df":0,"docs":{},"w":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}}},"t":{"df":5,"docs":{"26":{"tf":2.8284271247461903},"29":{"tf":3.7416573867739413},"44":{"tf":2.6457513110645907},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}},"x":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"15":{"tf":1.0},"37":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"35":{"tf":1.0},"38":{"tf":1.0}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":29,"docs":{"11":{"tf":1.4142135623730951},"15":{"tf":1.4142135623730951},"17":{"tf":1.0},"2":{"tf":1.4142135623730951},"23":{"tf":1.4142135623730951},"26":{"tf":1.0},"29":{"tf":1.0},"30":{"tf":1.7320508075688772},"31":{"tf":1.0},"32":{"tf":1.0},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.7320508075688772},"40":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.4142135623730951},"46":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"35":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"c":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"26":{"tf":1.0},"7":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"'":{"df":1,"docs":{"26":{"tf":1.0}}},"df":5,"docs":{"23":{"tf":1.0},"24":{"tf":1.0},"26":{"tf":2.449489742783178},"28":{"tf":1.4142135623730951},"29":{"tf":2.0}}}}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"35":{"tf":1.0}}}},"t":{"df":5,"docs":{"23":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.8284271247461903},"31":{"tf":1.0},"45":{"tf":1.0}}}},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"\"":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}}},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":2,"docs":{"15":{"tf":1.0},"23":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":1,"docs":{"7":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"15":{"tf":1.4142135623730951}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"35":{"tf":1.0},"7":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"29":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"s":{"df":5,"docs":{"11":{"tf":1.0},"30":{"tf":1.0},"32":{"tf":1.0},"33":{"tf":1.0},"44":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":4,"docs":{"26":{"tf":1.0},"29":{"tf":1.0},"32":{"tf":1.0},"42":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"35":{"tf":1.0}}}}},"r":{"a":{"df":3,"docs":{"22":{"tf":1.0},"44":{"tf":1.7320508075688772},"7":{"tf":1.0}}},"df":0,"docs":{}}}}},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"31":{"tf":1.0},"35":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"42":{"tf":1.7320508075688772}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"23":{"tf":1.0},"39":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"43":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}}},"r":{"df":1,"docs":{"31":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"41":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":2,"docs":{"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"2":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"d":{"df":7,"docs":{"11":{"tf":2.23606797749979},"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"35":{"tf":2.23606797749979},"41":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"df":3,"docs":{"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"26":{"tf":2.0},"29":{"tf":2.23606797749979},"39":{"tf":1.0}}}}}},"df":0,"docs":{},"w":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.0}}}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":2,"docs":{"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"40":{"tf":1.0},"44":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"e":{"df":17,"docs":{"11":{"tf":2.0},"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"14":{"tf":1.0},"23":{"tf":1.0},"30":{"tf":1.4142135623730951},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"35":{"tf":1.7320508075688772},"39":{"tf":1.0},"4":{"tf":1.7320508075688772},"44":{"tf":2.6457513110645907},"45":{"tf":1.7320508075688772},"47":{"tf":1.0},"5":{"tf":1.7320508075688772},"8":{"tf":1.0},"9":{"tf":1.0}}}},"n":{"a":{"df":0,"docs":{},"l":{"df":3,"docs":{"26":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.7320508075688772}}}},"d":{"df":2,"docs":{"28":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":2,"docs":{"4":{"tf":1.0},"46":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":7,"docs":{"11":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":2.23606797749979},"16":{"tf":1.0},"35":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":8,"docs":{"15":{"tf":1.0},"26":{"tf":1.4142135623730951},"29":{"tf":1.0},"3":{"tf":1.0},"37":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":2.0},"45":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}}}},"l":{"a":{"df":0,"docs":{},"g":{"df":2,"docs":{"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"22":{"tf":1.0},"23":{"tf":1.0}}}},"df":0,"docs":{}}}}},"n":{"df":11,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"41":{"tf":1.0},"42":{"tf":2.449489742783178},"43":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":2.6457513110645907}},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"o":{"c":{"df":0,"docs":{},"u":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"47":{"tf":1.0}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"18":{"tf":1.0}}}}},"m":{"df":2,"docs":{"22":{"tf":1.0},"23":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"23":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":1,"docs":{"39":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":1,"docs":{"15":{"tf":1.0}}}},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":19,"docs":{"26":{"tf":1.0},"30":{"tf":1.7320508075688772},"31":{"tf":1.0},"32":{"tf":1.0},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"46":{"tf":1.0},"47":{"tf":2.23606797749979}},"i":{"df":2,"docs":{"39":{"tf":1.0},"45":{"tf":1.0}}}}},"n":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":11,"docs":{"15":{"tf":1.0},"29":{"tf":1.0},"35":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"24":{"tf":1.0},"26":{"tf":2.23606797749979},"29":{"tf":2.0}},"e":{"df":0,"docs":{},"s":{":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"c":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{":":{":":{"df":0,"docs":{},"{":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"29":{"tf":1.0}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"k":{":":{":":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.0}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.0}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":16,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.7320508075688772},"12":{"tf":2.23606797749979},"14":{"tf":1.0},"2":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.0},"33":{"tf":1.4142135623730951},"37":{"tf":1.4142135623730951},"39":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"9":{"tf":1.0}},"i":{"c":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"47":{"tf":1.7320508075688772}}}}}},"df":1,"docs":{"44":{"tf":1.0}}}},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":6,"docs":{"10":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.4142135623730951}},"n":{"df":4,"docs":{"11":{"tf":1.0},"15":{"tf":1.7320508075688772},"5":{"tf":1.0},"7":{"tf":1.0}}}}}},"o":{"df":7,"docs":{"17":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"8":{"tf":1.4142135623730951}},"e":{"df":5,"docs":{"18":{"tf":1.0},"2":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"47":{"tf":1.0}}},"n":{"df":0,"docs":{},"e":{"df":1,"docs":{"44":{"tf":1.0}}}},"o":{"d":{"df":2,"docs":{"44":{"tf":1.0},"45":{"tf":1.0}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":2,"docs":{"11":{"tf":1.0},"33":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"46":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}}},"u":{"a":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"30":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":15,"docs":{"11":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"21":{"tf":1.7320508075688772},"22":{"tf":2.449489742783178},"23":{"tf":1.0},"26":{"tf":2.8284271247461903},"29":{"tf":3.7416573867739413},"30":{"tf":1.0},"31":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}},"e":{".":{"a":{"d":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"(":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":1,"docs":{"43":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{},"g":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"4":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}}}}},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"35":{"tf":1.0}}}},"df":0,"docs":{}}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"22":{"tf":1.0},"39":{"tf":1.0}},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}}},"n":{"c":{"df":3,"docs":{"23":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"35":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"e":{"'":{"df":2,"docs":{"29":{"tf":4.0},"45":{"tf":1.0}}},"df":4,"docs":{"31":{"tf":2.0},"35":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}},"l":{"df":0,"docs":{},"i":{"df":3,"docs":{"30":{"tf":1.0},"31":{"tf":1.0},"32":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"o":{"d":{"df":2,"docs":{"30":{"tf":1.0},"42":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"35":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"p":{":":{"/":{"/":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{".":{"df":0,"docs":{},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"g":{"/":{"4":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"s":{":":{"/":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"/":{"a":{"/":{"3":{"8":{"3":{"3":{"8":{"5":{"7":{"8":{"/":{"1":{"8":{"8":{"5":{"3":{"5":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"i":{"'":{"df":0,"docs":{},"m":{"df":1,"docs":{"35":{"tf":1.0}}},"v":{"df":2,"docs":{"26":{"tf":1.0},"36":{"tf":1.0}}}},"2":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":4,"docs":{"11":{"tf":1.0},"26":{"tf":2.23606797749979},"29":{"tf":2.6457513110645907},"39":{"tf":1.0}}},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"29":{"tf":3.7416573867739413}}}},"g":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.0}}}}}},"i":{"df":4,"docs":{"40":{"tf":1.7320508075688772},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0}},"i":{"df":1,"docs":{"44":{"tf":1.7320508075688772}}}},"m":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":2,"docs":{"35":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"<":{"df":0,"docs":{},"t":{"df":3,"docs":{"39":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":11,"docs":{"11":{"tf":1.4142135623730951},"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"22":{"tf":1.0},"23":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.0},"38":{"tf":1.4142135623730951},"40":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":5,"docs":{"2":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"23":{"tf":1.0}}}}}}},"n":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":4,"docs":{"3":{"tf":1.0},"42":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":2,"docs":{"4":{"tf":1.0},"45":{"tf":1.0}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"u":{"df":1,"docs":{"46":{"tf":1.0}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"18":{"tf":1.0},"22":{"tf":1.0}}}}}},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"27":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"41":{"tf":1.0}}}}}},"df":4,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"22":{"tf":1.0}},"e":{"(":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"e":{"c":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"i":{"d":{"df":1,"docs":{"8":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":2.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"15":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":2,"docs":{"13":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":7,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"24":{"tf":1.0},"30":{"tf":1.0},"33":{"tf":1.0},"7":{"tf":1.0}}}},"n":{"d":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"12":{"tf":1.0}}}}},"f":{"a":{"c":{"df":5,"docs":{"11":{"tf":1.4142135623730951},"35":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"v":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}}},"n":{"df":12,"docs":{"17":{"tf":1.4142135623730951},"22":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0},"32":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.6457513110645907},"47":{"tf":1.0},"5":{"tf":1.0}}},"v":{"df":1,"docs":{"15":{"tf":1.0}}}}},"o":{"<":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":5,"docs":{"37":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.23606797749979}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":6,"docs":{"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.23606797749979}}}}}}},"r":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"u":{"c":{"df":2,"docs":{"13":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":2,"docs":{"10":{"tf":1.0},"15":{"tf":1.4142135623730951}}}}}},"o":{":":{":":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"<":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"39":{"tf":1.0},"47":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":5,"docs":{"13":{"tf":1.4142135623730951},"24":{"tf":1.0},"28":{"tf":2.6457513110645907},"29":{"tf":2.449489742783178},"47":{"tf":1.0}}},"p":{"c":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":2,"docs":{"22":{"tf":1.0},"35":{"tf":1.0}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"u":{"df":3,"docs":{"30":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}}},"t":{"'":{"df":15,"docs":{"11":{"tf":1.7320508075688772},"17":{"tf":1.0},"26":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.4142135623730951},"4":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.0}},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"47":{"tf":1.0}}},"r":{"df":4,"docs":{"35":{"tf":1.0},"42":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":6,"docs":{"11":{"tf":1.0},"36":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.4142135623730951},"45":{"tf":1.4142135623730951},"5":{"tf":1.0}}}}}}},"v":{"df":2,"docs":{"45":{"tf":1.7320508075688772},"46":{"tf":1.0}}},"²":{"c":{"df":1,"docs":{"33":{"tf":1.0}}},"df":0,"docs":{}}},"j":{"df":0,"docs":{},"o":{"b":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":6,"docs":{"26":{"tf":1.0},"36":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"8":{"tf":1.0}}}},"y":{"df":2,"docs":{"11":{"tf":1.0},"15":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"d":{"df":7,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"23":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"42":{"tf":1.0},"47":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":7,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"3":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0},"7":{"tf":1.4142135623730951}},"n":{"df":1,"docs":{"5":{"tf":1.0}}}}}}},"l":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"15":{"tf":1.4142135623730951}}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"18":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"15":{"tf":1.0},"26":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"36":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"8":{"tf":1.0}}},"df":0,"docs":{},"k":{"df":1,"docs":{"13":{"tf":1.0}}},"n":{"df":1,"docs":{"22":{"tf":1.0}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"15":{"tf":1.0}}}},"v":{"df":1,"docs":{"45":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":3,"docs":{"15":{"tf":1.0},"29":{"tf":1.0},"36":{"tf":1.0}}}},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"37":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"45":{"tf":1.0}}}},"t":{"'":{"df":4,"docs":{"26":{"tf":2.449489742783178},"29":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.4142135623730951}}},"df":1,"docs":{"30":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0}}}}}},"i":{"b":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":5,"docs":{"13":{"tf":1.0},"22":{"tf":2.0},"30":{"tf":1.0},"33":{"tf":1.0},"44":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":1,"docs":{"42":{"tf":1.0}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}}},"n":{"df":0,"docs":{},"e":{"df":2,"docs":{"26":{"tf":1.0},"7":{"tf":1.4142135623730951}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"x":{"df":2,"docs":{"11":{"tf":1.0},"33":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"36":{"tf":1.0}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"o":{"a":{"d":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"32":{"tf":1.0},"9":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"g":{"df":2,"docs":{"13":{"tf":1.0},"26":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"k":{"df":4,"docs":{"1":{"tf":1.0},"26":{"tf":1.4142135623730951},"42":{"tf":1.0},"44":{"tf":1.0}}},"p":{"df":26,"docs":{"11":{"tf":1.0},"14":{"tf":1.4142135623730951},"15":{"tf":2.6457513110645907},"16":{"tf":1.4142135623730951},"17":{"tf":2.449489742783178},"18":{"tf":2.0},"2":{"tf":1.0},"26":{"tf":4.69041575982343},"28":{"tf":1.0},"29":{"tf":6.164414002968976},"3":{"tf":2.0},"30":{"tf":1.0},"31":{"tf":1.4142135623730951},"35":{"tf":1.7320508075688772},"36":{"tf":1.0},"4":{"tf":1.0},"42":{"tf":2.0},"44":{"tf":2.449489742783178},"45":{"tf":2.0},"46":{"tf":2.0},"47":{"tf":2.0},"5":{"tf":2.0},"6":{"tf":1.7320508075688772},"7":{"tf":2.0},"8":{"tf":2.449489742783178},"9":{"tf":1.0}},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.4142135623730951}},"e":{":":{":":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}},"t":{"df":4,"docs":{"31":{"tf":1.0},"35":{"tf":1.0},"46":{"tf":1.0},"7":{"tf":1.0}}},"w":{"df":1,"docs":{"11":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}}},"m":{"a":{"d":{"df":0,"docs":{},"e":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"47":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":8,"docs":{"22":{"tf":1.7320508075688772},"23":{"tf":1.0},"31":{"tf":1.0},"32":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0},"7":{"tf":1.7320508075688772}}}},"n":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"11":{"tf":1.0}}}},"d":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"37":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":4,"docs":{"11":{"tf":1.4142135623730951},"27":{"tf":1.0},"31":{"tf":1.0},"43":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.0},"22":{"tf":1.0},"39":{"tf":1.0}}}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"36":{"tf":1.0},"42":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"|":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"y":{"b":{"df":2,"docs":{"39":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"26":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"n":{"df":14,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.7320508075688772},"26":{"tf":1.0},"3":{"tf":1.0},"31":{"tf":1.0},"34":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}}},"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"30":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"45":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":18,"docs":{"17":{"tf":1.7320508075688772},"23":{"tf":1.4142135623730951},"26":{"tf":2.0},"30":{"tf":1.0},"31":{"tf":1.4142135623730951},"32":{"tf":1.0},"34":{"tf":1.7320508075688772},"35":{"tf":2.23606797749979},"37":{"tf":2.6457513110645907},"38":{"tf":1.7320508075688772},"39":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":4.58257569495584},"45":{"tf":4.0},"46":{"tf":1.7320508075688772},"47":{"tf":4.47213595499958},"5":{"tf":1.7320508075688772},"6":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":2,"docs":{"39":{"tf":1.7320508075688772},"47":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"d":{"df":11,"docs":{"12":{"tf":1.0},"18":{"tf":1.0},"22":{"tf":1.4142135623730951},"39":{"tf":1.4142135623730951},"40":{"tf":2.23606797749979},"41":{"tf":1.0},"42":{"tf":2.23606797749979},"43":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"d":{"d":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"2":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":1,"docs":{"36":{"tf":1.0}}}}}}}},"o":{"d":{"df":0,"docs":{},"e":{"df":1,"docs":{"12":{"tf":1.0}},"l":{"df":1,"docs":{"10":{"tf":1.0}}}},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"11":{"tf":1.7320508075688772},"12":{"tf":1.0},"13":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":13,"docs":{"11":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.7320508075688772},"30":{"tf":2.23606797749979},"31":{"tf":1.4142135623730951},"32":{"tf":1.7320508075688772},"37":{"tf":1.4142135623730951},"39":{"tf":2.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"46":{"tf":1.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.7320508075688772}}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"44":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"e":{"df":5,"docs":{"13":{"tf":1.0},"26":{"tf":2.8284271247461903},"29":{"tf":3.7416573867739413},"39":{"tf":1.0},"8":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"s":{"c":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":5,"docs":{"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"41":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}}}},"df":5,"docs":{"17":{"tf":1.0},"34":{"tf":1.4142135623730951},"41":{"tf":1.4142135623730951},"44":{"tf":2.23606797749979},"47":{"tf":2.449489742783178}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"g":{"(":{"df":0,"docs":{},"e":{"df":1,"docs":{"23":{"tf":1.0}}}},"df":1,"docs":{"26":{"tf":4.0}}}},"u":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"31":{"tf":1.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"38":{"tf":1.0}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"37":{"tf":1.0},"47":{"tf":2.449489742783178}}}}},"df":0,"docs":{},"l":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"7":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"t":{"df":9,"docs":{"14":{"tf":1.7320508075688772},"15":{"tf":2.0},"16":{"tf":1.7320508075688772},"26":{"tf":4.898979485566356},"29":{"tf":5.916079783099616},"42":{"tf":3.4641016151377544},"44":{"tf":3.1622776601683795},"45":{"tf":2.8284271247461903},"47":{"tf":3.605551275463989}}}},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"35":{"tf":1.0}}}}}}}}},"n":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":2,"docs":{"23":{"tf":1.0},"5":{"tf":1.0}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"17":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"45":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"5":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":3,"docs":{"13":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"d":{"df":27,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.0},"15":{"tf":1.7320508075688772},"22":{"tf":1.7320508075688772},"23":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0},"26":{"tf":1.4142135623730951},"27":{"tf":1.0},"28":{"tf":1.7320508075688772},"29":{"tf":1.7320508075688772},"3":{"tf":1.0},"30":{"tf":1.0},"32":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.7320508075688772},"36":{"tf":2.449489742783178},"4":{"tf":1.0},"40":{"tf":1.4142135623730951},"41":{"tf":1.7320508075688772},"42":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951},"8":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":3,"docs":{"11":{"tf":1.0},"4":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"35":{"tf":1.0},"45":{"tf":1.4142135623730951},"8":{"tf":2.0}}}}},"w":{"_":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"12":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}}}},"df":5,"docs":{"12":{"tf":1.0},"17":{"tf":1.0},"32":{"tf":1.0},"36":{"tf":1.0},"5":{"tf":1.0}}},"x":{"df":0,"docs":{},"t":{"df":5,"docs":{"15":{"tf":1.4142135623730951},"35":{"tf":1.0},"42":{"tf":1.0},"46":{"tf":1.0},"8":{"tf":1.0}}}}},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"23":{"tf":1.0},"7":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":9,"docs":{"26":{"tf":1.0},"27":{"tf":1.4142135623730951},"29":{"tf":1.0},"31":{"tf":1.0},"36":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"h":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"8":{"tf":1.4142135623730951}}},"i":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{},"f":{"df":1,"docs":{"44":{"tf":1.0}},"i":{"df":1,"docs":{"23":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}}},"w":{"df":7,"docs":{"26":{"tf":1.0},"29":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"45":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"m":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}}}},"o":{"b":{"df":0,"docs":{},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"11":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":1,"docs":{"37":{"tf":1.0}},"s":{"df":1,"docs":{"33":{"tf":1.0}}}}}}}},"df":0,"docs":{},"h":{"df":1,"docs":{"26":{"tf":1.0}}},"k":{"(":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"(":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":5,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"41":{"tf":1.0},"42":{"tf":1.7320508075688772},"47":{"tf":2.0}}},"l":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}},"df":0,"docs":{}},"n":{"c":{"df":2,"docs":{"14":{"tf":1.0},"31":{"tf":1.0}}},"df":22,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"22":{"tf":1.0},"26":{"tf":1.7320508075688772},"27":{"tf":1.0},"3":{"tf":1.0},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.4142135623730951},"37":{"tf":1.4142135623730951},"38":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"5":{"tf":1.4142135623730951},"6":{"tf":1.7320508075688772},"7":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}},"t":{"df":0,"docs":{},"o":{"df":1,"docs":{"44":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":9,"docs":{"10":{"tf":1.0},"3":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":2.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"39":{"tf":1.0}}}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"<":{"df":0,"docs":{},"t":{"df":1,"docs":{"38":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"18":{"tf":1.0},"29":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"28":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"15":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"18":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"t":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"x":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"_":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}},"df":6,"docs":{"22":{"tf":1.0},"31":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"40":{"tf":1.0},"44":{"tf":1.4142135623730951}},"g":{"df":0,"docs":{},"o":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"26":{"tf":1.4142135623730951},"29":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"10":{"tf":1.0},"13":{"tf":1.0}}},"df":0,"docs":{}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":7,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"30":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.7320508075688772},"47":{"tf":2.0},"5":{"tf":1.0}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"22":{"tf":1.4142135623730951}}}}}}}}},"w":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"f":{"d":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":4,"docs":{"10":{"tf":1.0},"13":{"tf":1.7320508075688772},"30":{"tf":1.0},"41":{"tf":1.0}}}}}}}}}}},"p":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"29":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":2,"docs":{"6":{"tf":1.7320508075688772},"8":{"tf":1.0}}}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}}}},"df":0,"docs":{},"t":{"df":19,"docs":{"15":{"tf":1.0},"18":{"tf":1.4142135623730951},"23":{"tf":1.4142135623730951},"24":{"tf":1.0},"26":{"tf":1.0},"3":{"tf":1.0},"36":{"tf":1.7320508075688772},"37":{"tf":1.7320508075688772},"38":{"tf":1.7320508075688772},"39":{"tf":1.0},"40":{"tf":1.7320508075688772},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.7320508075688772},"46":{"tf":1.0},"47":{"tf":1.7320508075688772},"7":{"tf":1.0}},"i":{"df":1,"docs":{"13":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"s":{"df":4,"docs":{"15":{"tf":1.0},"39":{"tf":1.0},"42":{"tf":1.4142135623730951},"6":{"tf":1.0}}},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"47":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":2,"docs":{"31":{"tf":1.0},"41":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":3,"docs":{"31":{"tf":1.0},"45":{"tf":2.23606797749979},"47":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":1,"docs":{"15":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"27":{"tf":1.0}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":3,"docs":{"45":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}}}}}},"h":{"a":{"df":0,"docs":{},"p":{"df":3,"docs":{"39":{"tf":1.0},"44":{"tf":1.0},"46":{"tf":1.0}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}}}}}},"g":{"df":0,"docs":{},"m":{"df":1,"docs":{"30":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":9,"docs":{"17":{"tf":2.23606797749979},"18":{"tf":2.6457513110645907},"23":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"46":{"tf":1.0},"47":{"tf":1.0}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":2,"docs":{"18":{"tf":1.7320508075688772},"36":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"l":{"a":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"11":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":3,"docs":{"31":{"tf":1.4142135623730951},"35":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"l":{"df":3,"docs":{"28":{"tf":1.0},"42":{"tf":2.449489742783178},"47":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}},"p":{"df":1,"docs":{"44":{"tf":1.0}}},"s":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.0}}},"s":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":5,"docs":{"43":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"5":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}}}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":1,"docs":{"44":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"3":{"tf":1.0},"45":{"tf":1.0}}}}}}},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"28":{"tf":1.0}}}}}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":2,"docs":{"15":{"tf":1.0},"34":{"tf":1.0}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.7320508075688772}}}}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"11":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"15":{"tf":1.4142135623730951},"30":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":2,"docs":{"2":{"tf":1.0},"39":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}},"l":{"df":0,"docs":{},"n":{"!":{"(":{"\"":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}}},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":5,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"26":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"o":{"b":{"a":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"28":{"tf":1.0},"29":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":5,"docs":{"15":{"tf":1.0},"22":{"tf":1.0},"27":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"df":2,"docs":{"4":{"tf":1.0},"8":{"tf":1.0}},"e":{"d":{"df":1,"docs":{"7":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":7,"docs":{"18":{"tf":1.0},"22":{"tf":1.7320508075688772},"23":{"tf":2.0},"39":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":2.23606797749979},"47":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"s":{"(":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":3,"docs":{"44":{"tf":2.449489742783178},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"<":{"df":0,"docs":{},"f":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"df":14,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"23":{"tf":1.7320508075688772},"27":{"tf":1.0},"30":{"tf":1.0},"32":{"tf":1.0},"36":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.8284271247461903},"45":{"tf":2.23606797749979},"46":{"tf":1.0},"47":{"tf":1.7320508075688772},"5":{"tf":1.0}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":1,"docs":{"23":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"'":{"df":3,"docs":{"32":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.0}}},"df":11,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"16":{"tf":1.4142135623730951},"3":{"tf":1.4142135623730951},"30":{"tf":1.4142135623730951},"31":{"tf":1.0},"32":{"tf":1.0},"4":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.0}},"m":{"df":1,"docs":{"30":{"tf":1.0}}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}},"p":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"22":{"tf":1.0},"39":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"13":{"tf":1.0},"42":{"tf":1.0}}}}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":15,"docs":{"11":{"tf":1.0},"13":{"tf":1.7320508075688772},"14":{"tf":1.0},"15":{"tf":1.0},"2":{"tf":1.7320508075688772},"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"24":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.0},"32":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"b":{"df":5,"docs":{"36":{"tf":1.4142135623730951},"37":{"tf":1.4142135623730951},"41":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.0}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"34":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"h":{"df":4,"docs":{"10":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"t":{"df":2,"docs":{"16":{"tf":1.0},"47":{"tf":1.0}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}},"e":{"df":9,"docs":{"17":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0},"37":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.0},"46":{"tf":1.0},"47":{"tf":2.0},"5":{"tf":1.4142135623730951}}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":1,"docs":{"35":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"w":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"14":{"tf":1.0}}},"t":{"df":2,"docs":{"10":{"tf":1.0},"34":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"7":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}}}},"d":{"/":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"a":{"b":{"df":0,"docs":{},"l":{"df":6,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"35":{"tf":2.8284271247461903},"44":{"tf":1.7320508075688772},"45":{"tf":2.23606797749979},"47":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"df":6,"docs":{"35":{"tf":2.0},"4":{"tf":2.449489742783178},"44":{"tf":1.7320508075688772},"45":{"tf":2.449489742783178},"47":{"tf":2.449489742783178},"5":{"tf":1.7320508075688772}},"i":{"df":5,"docs":{"4":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"l":{"df":3,"docs":{"31":{"tf":1.0},"32":{"tf":1.0},"44":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"df":3,"docs":{"35":{"tf":1.0},"45":{"tf":1.7320508075688772},"46":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":12,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":2.0},"26":{"tf":1.0},"29":{"tf":4.0},"31":{"tf":1.0},"35":{"tf":1.4142135623730951},"44":{"tf":2.8284271247461903},"45":{"tf":3.0},"46":{"tf":1.0},"47":{"tf":1.7320508075688772},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"p":{"(":{"df":0,"docs":{},"|":{"df":0,"docs":{},"m":{"df":1,"docs":{"26":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"a":{"c":{"df":0,"docs":{},"t":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{".":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":1,"docs":{"26":{"tf":2.0}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":2.0}}},"y":{".":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}}}},"h":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":0,"docs":{}}}},"v":{"df":1,"docs":{"23":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":2,"docs":{"42":{"tf":1.0},"44":{"tf":1.0}}}}},"v":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"(":{"0":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}},"df":3,"docs":{"42":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"39":{"tf":1.0},"47":{"tf":1.0}}}}},"g":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"26":{"tf":2.23606797749979}}},"df":0,"docs":{}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":2.23606797749979},"47":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"df":3,"docs":{"42":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}}},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}}}},"l":{"a":{"df":0,"docs":{},"t":{"df":3,"docs":{"14":{"tf":1.0},"33":{"tf":1.0},"44":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":1,"docs":{"32":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":1,"docs":{"1":{"tf":1.0}}}},"df":0,"docs":{}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"44":{"tf":1.0},"45":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"b":{"df":3,"docs":{"38":{"tf":1.0},"44":{"tf":1.0},"46":{"tf":1.0}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"v":{"df":2,"docs":{"42":{"tf":1.0},"44":{"tf":1.0}}}}},"p":{"df":1,"docs":{"45":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"45":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}}}},"l":{"a":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":1,"docs":{"45":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":3,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":1.0}}}}}},"q":{"df":1,"docs":{"45":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":5,"docs":{"12":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"44":{"tf":1.0},"7":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"s":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"18":{"tf":1.0},"45":{"tf":1.0}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":2,"docs":{"32":{"tf":1.0},"44":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"<":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":7,"docs":{"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951},"7":{"tf":1.0}}}}}},"t":{"df":2,"docs":{"39":{"tf":1.4142135623730951},"47":{"tf":1.0}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"30":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":10,"docs":{"13":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":2.0},"26":{"tf":2.23606797749979},"29":{"tf":2.8284271247461903},"39":{"tf":1.7320508075688772},"41":{"tf":1.4142135623730951},"44":{"tf":2.23606797749979},"8":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}}}},"o":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"df":0,"docs":{}},"s":{"df":1,"docs":{"14":{"tf":1.0}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":2,"docs":{"23":{"tf":1.0},"8":{"tf":1.0}}}},"n":{"df":18,"docs":{"11":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":1.4142135623730951},"25":{"tf":1.7320508075688772},"26":{"tf":3.4641016151377544},"27":{"tf":1.0},"29":{"tf":4.69041575982343},"3":{"tf":1.0},"30":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.7320508075688772},"46":{"tf":2.0},"47":{"tf":2.449489742783178},"5":{"tf":1.0},"6":{"tf":1.4142135623730951},"7":{"tf":1.0},"8":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"'":{"df":3,"docs":{"17":{"tf":1.0},"2":{"tf":1.0},"24":{"tf":1.0}}},"df":5,"docs":{"13":{"tf":1.4142135623730951},"22":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.4142135623730951},"38":{"tf":1.0}}}}}},"s":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":1,"docs":{"13":{"tf":1.7320508075688772}}}},"k":{"df":0,"docs":{},"e":{"df":2,"docs":{"26":{"tf":1.0},"31":{"tf":1.0}}}},"m":{"df":0,"docs":{},"e":{"df":6,"docs":{"15":{"tf":1.0},"22":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"5":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"35":{"tf":1.0},"39":{"tf":1.0}}}}},"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{".":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"(":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"26":{"tf":2.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"26":{"tf":2.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"15":{"tf":1.4142135623730951},"26":{"tf":2.449489742783178},"29":{"tf":3.872983346207417}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":5,"docs":{"14":{"tf":1.0},"15":{"tf":1.4142135623730951},"3":{"tf":1.0},"45":{"tf":1.7320508075688772},"5":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"34":{"tf":1.0},"44":{"tf":1.0}}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"28":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":4,"docs":{"26":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.4142135623730951},"5":{"tf":1.0}},"m":{"df":1,"docs":{"44":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"27":{"tf":1.0}}}},"df":0,"docs":{}},"f":{".":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"c":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"x":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}}},"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{".":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"&":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"43":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"(":{")":{".":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"&":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"r":{"c":{"df":0,"docs":{},"v":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"r":{"c":{"df":0,"docs":{},"v":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":3,"docs":{"44":{"tf":2.8284271247461903},"45":{"tf":2.6457513110645907},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"w":{"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"p":{"df":2,"docs":{"42":{"tf":1.7320508075688772},"47":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":6,"docs":{"41":{"tf":1.0},"42":{"tf":2.449489742783178},"43":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":2.0},"47":{"tf":2.8284271247461903}}}},"n":{"d":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"/":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"df":13,"docs":{"18":{"tf":1.7320508075688772},"23":{"tf":2.0},"26":{"tf":1.0},"29":{"tf":1.4142135623730951},"34":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"41":{"tf":1.7320508075688772},"44":{"tf":2.449489742783178},"45":{"tf":3.0},"47":{"tf":3.3166247903554},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"\"":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{",":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"d":{"!":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"(":{"b":{"\"":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"\"":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"26":{"tf":2.0}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"h":{",":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":1,"docs":{"26":{"tf":2.0}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":2.0}}},"y":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"\"":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{",":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"d":{"!":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}},"df":2,"docs":{"29":{"tf":3.7416573867739413},"47":{"tf":1.0}}}}},"df":0,"docs":{},"s":{"df":3,"docs":{"23":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0}}},"t":{"df":5,"docs":{"23":{"tf":1.0},"29":{"tf":2.8284271247461903},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":2.449489742783178}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":3,"docs":{"22":{"tf":1.0},"35":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":5,"docs":{"37":{"tf":1.7320508075688772},"38":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}},"t":{"df":5,"docs":{"31":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"p":{"df":4,"docs":{"40":{"tf":1.7320508075688772},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0}}}}}},"h":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":3,"docs":{"15":{"tf":1.4142135623730951},"30":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":1.0}}}},"u":{"df":0,"docs":{},"l":{"d":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"44":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"w":{"df":1,"docs":{"30":{"tf":1.0}}}},"u":{"df":0,"docs":{},"t":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":2,"docs":{"31":{"tf":1.0},"43":{"tf":1.0}}}}}},"df":1,"docs":{"43":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"l":{"df":4,"docs":{"20":{"tf":1.7320508075688772},"35":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"7":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":3,"docs":{"11":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}},"i":{"c":{"df":1,"docs":{"31":{"tf":1.0}}},"df":4,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"29":{"tf":1.0},"7":{"tf":1.0}},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}}}},"n":{"df":1,"docs":{"44":{"tf":1.0}},"g":{"df":0,"docs":{},"l":{"df":7,"docs":{"27":{"tf":1.0},"32":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":1.4142135623730951},"47":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0}}}}},"t":{"df":1,"docs":{"35":{"tf":1.0}},"u":{"a":{"df":0,"docs":{},"t":{"df":3,"docs":{"22":{"tf":1.0},"23":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}}},"k":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":1,"docs":{"47":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}}}}},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"35":{"tf":1.0}}},".":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"41":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}}},"df":17,"docs":{"13":{"tf":1.0},"29":{"tf":3.872983346207417},"30":{"tf":1.7320508075688772},"31":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":2.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.7320508075688772},"41":{"tf":1.0},"43":{"tf":1.7320508075688772},"44":{"tf":1.4142135623730951},"45":{"tf":2.6457513110645907},"47":{"tf":4.795831523312719},"5":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}},"v":{"df":1,"docs":{"44":{"tf":1.0}}}},"m":{"df":0,"docs":{},"e":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":1,"docs":{"26":{"tf":4.0}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":5,"docs":{"10":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"3":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"c":{"df":39,"docs":{"10":{"tf":2.23606797749979},"11":{"tf":2.23606797749979},"12":{"tf":2.0},"13":{"tf":1.0},"14":{"tf":2.23606797749979},"15":{"tf":2.23606797749979},"16":{"tf":1.4142135623730951},"17":{"tf":2.0},"18":{"tf":2.23606797749979},"19":{"tf":1.0},"2":{"tf":1.7320508075688772},"20":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.4142135623730951},"23":{"tf":2.6457513110645907},"24":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.4142135623730951},"31":{"tf":1.0},"32":{"tf":2.449489742783178},"33":{"tf":1.7320508075688772},"34":{"tf":1.7320508075688772},"35":{"tf":2.0},"36":{"tf":2.23606797749979},"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951},"40":{"tf":2.0},"41":{"tf":2.23606797749979},"42":{"tf":3.7416573867739413},"43":{"tf":1.0},"44":{"tf":4.795831523312719},"45":{"tf":2.6457513110645907},"46":{"tf":2.0},"47":{"tf":4.358898943540674},"5":{"tf":2.8284271247461903},"9":{"tf":1.0}},"e":{"'":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":2,"docs":{"31":{"tf":1.4142135623730951},"45":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"23":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":12,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"11":{"tf":1.0},"15":{"tf":1.0},"2":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}}}}},"t":{"df":0,"docs":{},"e":{"df":11,"docs":{"35":{"tf":1.7320508075688772},"39":{"tf":1.0},"4":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.7320508075688772},"7":{"tf":1.7320508075688772},"9":{"tf":1.0}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}}}},"u":{"df":1,"docs":{"23":{"tf":1.0}}}}},"d":{":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"c":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"<":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"22":{"tf":1.0},"23":{"tf":1.7320508075688772}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"i":{"df":0,"docs":{},"o":{":":{":":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":3,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"39":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"e":{"<":{"df":0,"docs":{},"t":{"df":1,"docs":{"38":{"tf":1.0}}},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"38":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"8":{"(":{"&":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"(":{")":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"{":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":1,"docs":{"2":{"tf":1.4142135623730951}}}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":5,"docs":{"15":{"tf":1.0},"23":{"tf":1.4142135623730951},"35":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"p":{"df":4,"docs":{"3":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.0},"8":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"27":{"tf":1.0}}}}}}},"i":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"23":{"tf":1.0}}}}},"u":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"u":{"b":{"df":1,"docs":{"44":{"tf":1.0}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"23":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"30":{"tf":1.0}}}}}}}},"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"23":{"tf":1.0},"27":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}}}},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"44":{"tf":1.0},"5":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"31":{"tf":1.0}}}},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.0}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"31":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"23":{"tf":1.4142135623730951}},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"x":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"11":{"tf":1.0},"44":{"tf":1.0}}}}}}}},"t":{":":{":":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":5,"docs":{"37":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.23606797749979}}}}}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":8,"docs":{"23":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.449489742783178},"45":{"tf":1.0},"7":{"tf":1.7320508075688772}},"n":{"df":1,"docs":{"44":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"15":{"tf":1.0}}}}},"c":{"df":0,"docs":{},"p":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":6,"docs":{"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.8284271247461903}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"35":{"tf":1.0},"44":{"tf":1.4142135623730951}}}},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"m":{"df":4,"docs":{"32":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":1,"docs":{"4":{"tf":1.4142135623730951}}}}}}}}}}},"h":{"a":{"df":0,"docs":{},"t":{"'":{"df":6,"docs":{"29":{"tf":1.0},"33":{"tf":1.4142135623730951},"34":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":2,"docs":{"17":{"tf":1.0},"31":{"tf":1.0}}}}}}},"r":{"df":0,"docs":{},"e":{"'":{"df":2,"docs":{"17":{"tf":1.0},"35":{"tf":1.0}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"37":{"tf":1.0},"43":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":13,"docs":{"12":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.0},"3":{"tf":1.7320508075688772},"31":{"tf":1.0},"33":{"tf":1.0},"37":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.0}}},"k":{"df":2,"docs":{"31":{"tf":1.4142135623730951},"7":{"tf":1.0}}}},"r":{"d":{"df":3,"docs":{"13":{"tf":1.0},"15":{"tf":1.0},"35":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}}}}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":7,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.0},"23":{"tf":1.0},"3":{"tf":1.0},"5":{"tf":1.0}}}},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":3,"docs":{"18":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":7,"docs":{"27":{"tf":2.23606797749979},"3":{"tf":1.0},"4":{"tf":1.0},"47":{"tf":1.0},"6":{"tf":2.23606797749979},"7":{"tf":1.0},"8":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":4,"docs":{"12":{"tf":1.0},"35":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":5,"docs":{"13":{"tf":1.4142135623730951},"2":{"tf":1.0},"23":{"tf":1.0},"29":{"tf":1.0},"44":{"tf":1.0}}}}}}},"u":{"df":1,"docs":{"10":{"tf":1.0}}}},"i":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}},"m":{"df":0,"docs":{},"e":{"df":7,"docs":{"11":{"tf":1.0},"14":{"tf":1.4142135623730951},"15":{"tf":2.23606797749979},"4":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"d":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":1,"docs":{"31":{"tf":1.0}}}}},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"(":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"s":{"(":{"5":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"{":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":8,"docs":{"11":{"tf":1.0},"14":{"tf":3.0},"15":{"tf":3.0},"16":{"tf":1.7320508075688772},"32":{"tf":1.0},"4":{"tf":1.0},"5":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}}},"o":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":5,"docs":{"16":{"tf":1.0},"32":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0},"9":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"42":{"tf":3.1622776601683795},"47":{"tf":2.8284271247461903}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":4,"docs":{"42":{"tf":1.7320508075688772},"44":{"tf":3.605551275463989},"45":{"tf":1.7320508075688772},"47":{"tf":1.7320508075688772}}}}},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"44":{"tf":1.0}}}},"p":{"df":1,"docs":{"14":{"tf":1.0}},"i":{"c":{"df":1,"docs":{"37":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"22":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"y":{"df":1,"docs":{"26":{"tf":2.0}}}},"r":{"a":{"c":{"df":0,"docs":{},"e":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"k":{"df":6,"docs":{"15":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"8":{"tf":1.0}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"7":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"44":{"tf":1.0}}},"df":10,"docs":{"10":{"tf":1.0},"13":{"tf":1.4142135623730951},"22":{"tf":1.7320508075688772},"23":{"tf":1.7320508075688772},"28":{"tf":1.0},"29":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":1.0}}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"37":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"30":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"i":{"df":3,"docs":{"22":{"tf":1.0},"23":{"tf":1.0},"4":{"tf":1.0}},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"12":{"tf":1.4142135623730951},"35":{"tf":1.7320508075688772},"42":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.7320508075688772}}}}}}},"o":{"df":0,"docs":{},"u":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"e":{"df":2,"docs":{"45":{"tf":1.7320508075688772},"47":{"tf":1.4142135623730951}}}}},"u":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"41":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"47":{"tf":1.0}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.7320508075688772}}}}}}},"w":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"k":{"df":1,"docs":{"37":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":9,"docs":{"18":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"24":{"tf":1.0},"26":{"tf":2.0},"3":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.4142135623730951},"7":{"tf":1.0}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":20,"docs":{"11":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":2.6457513110645907},"14":{"tf":1.0},"22":{"tf":1.7320508075688772},"23":{"tf":3.3166247903554},"24":{"tf":1.0},"28":{"tf":3.0},"29":{"tf":2.23606797749979},"36":{"tf":2.6457513110645907},"37":{"tf":2.6457513110645907},"38":{"tf":1.4142135623730951},"39":{"tf":3.7416573867739413},"40":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.0},"47":{"tf":2.23606797749979},"5":{"tf":1.0},"9":{"tf":1.0}}},"i":{"c":{"df":1,"docs":{"6":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"11":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.0}}}}}},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"14":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":4,"docs":{"35":{"tf":1.0},"39":{"tf":1.4142135623730951},"4":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":2,"docs":{"20":{"tf":1.7320508075688772},"29":{"tf":3.872983346207417}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"s":{"a":{"df":0,"docs":{},"f":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":5,"docs":{"14":{"tf":1.0},"18":{"tf":1.0},"35":{"tf":1.0},"4":{"tf":1.0},"46":{"tf":1.4142135623730951}}}}}},"p":{"d":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"5":{"tf":1.0}}}},"df":0,"docs":{}},"df":17,"docs":{"11":{"tf":1.0},"15":{"tf":1.0},"17":{"tf":2.0},"18":{"tf":1.4142135623730951},"30":{"tf":1.0},"31":{"tf":1.0},"35":{"tf":2.0},"36":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":2.6457513110645907},"45":{"tf":2.449489742783178},"47":{"tf":2.0},"5":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"47":{"tf":1.0}}}}},"s":{"b":{"df":1,"docs":{"11":{"tf":1.0}}},"df":36,"docs":{"10":{"tf":1.7320508075688772},"11":{"tf":2.23606797749979},"12":{"tf":1.4142135623730951},"13":{"tf":2.23606797749979},"14":{"tf":2.23606797749979},"15":{"tf":2.449489742783178},"16":{"tf":1.7320508075688772},"17":{"tf":1.7320508075688772},"18":{"tf":2.23606797749979},"19":{"tf":1.0},"2":{"tf":1.4142135623730951},"20":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.7320508075688772},"23":{"tf":1.7320508075688772},"26":{"tf":4.242640687119285},"27":{"tf":1.0},"28":{"tf":2.0},"29":{"tf":5.291502622129181},"30":{"tf":1.4142135623730951},"31":{"tf":2.449489742783178},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.7320508075688772},"4":{"tf":1.0},"41":{"tf":1.0},"44":{"tf":2.6457513110645907},"45":{"tf":2.0},"46":{"tf":1.4142135623730951},"47":{"tf":2.449489742783178},"6":{"tf":1.4142135623730951},"7":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}},"e":{"d":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"45":{"tf":2.0},"47":{"tf":2.23606797749979}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":7,"docs":{"22":{"tf":1.7320508075688772},"35":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.7320508075688772}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":4,"docs":{"11":{"tf":1.0},"31":{"tf":1.0},"39":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"5":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":6,"docs":{"15":{"tf":1.0},"18":{"tf":1.0},"26":{"tf":3.0},"29":{"tf":3.7416573867739413},"37":{"tf":1.0},"44":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"i":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"29":{"tf":1.0},"44":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{},"e":{"c":{"<":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"47":{"tf":1.0}}}}},"t":{"df":1,"docs":{"38":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"c":{"<":{"df":0,"docs":{},"u":{"8":{"df":2,"docs":{"39":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":1,"docs":{"47":{"tf":1.4142135623730951}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"17":{"tf":1.0},"30":{"tf":1.0}}},"s":{"a":{"df":1,"docs":{"47":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"1":{"tf":1.4142135623730951},"13":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"i":{"a":{"df":4,"docs":{"11":{"tf":1.0},"26":{"tf":2.0},"33":{"tf":1.0},"42":{"tf":1.0}}},"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}},"s":{"df":2,"docs":{"6":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951}}}},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":9,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"3":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.4142135623730951},"4":{"tf":2.23606797749979},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"8":{"tf":1.7320508075688772}}}},"k":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":4,"docs":{"36":{"tf":1.4142135623730951},"41":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":4,"docs":{"36":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":8,"docs":{"17":{"tf":2.0},"18":{"tf":1.0},"35":{"tf":1.7320508075688772},"36":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":2.23606797749979},"47":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":2,"docs":{"35":{"tf":1.4142135623730951},"44":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"t":{"df":10,"docs":{"12":{"tf":1.0},"23":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"31":{"tf":1.0},"34":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"46":{"tf":1.0},"9":{"tf":1.0}}}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"y":{"df":13,"docs":{"13":{"tf":1.4142135623730951},"15":{"tf":1.0},"17":{"tf":1.0},"23":{"tf":1.0},"3":{"tf":1.4142135623730951},"31":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"8":{"tf":1.0}}}},"df":0,"docs":{},"e":{"'":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":6,"docs":{"36":{"tf":1.0},"37":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772}}}},"r":{"df":3,"docs":{"30":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.4142135623730951}}},"v":{"df":3,"docs":{"31":{"tf":1.0},"40":{"tf":1.0},"44":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"22":{"tf":1.0},"27":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":3,"docs":{"31":{"tf":1.0},"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":2,"docs":{"10":{"tf":1.0},"47":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":6,"docs":{"12":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":2.23606797749979},"46":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}}}}}}},"i":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":3,"docs":{"16":{"tf":1.4142135623730951},"47":{"tf":1.0},"5":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"26":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"45":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":1,"docs":{"44":{"tf":1.4142135623730951}},"n":{"df":5,"docs":{"18":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}}},"n":{"'":{"df":0,"docs":{},"t":{"df":3,"docs":{"35":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}}}}},"df":0,"docs":{}},"r":{"d":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{},"k":{"df":19,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"27":{"tf":1.0},"3":{"tf":1.7320508075688772},"30":{"tf":1.0},"32":{"tf":1.0},"36":{"tf":1.0},"4":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"47":{"tf":1.4142135623730951},"5":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"l":{"d":{"!":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":6,"docs":{"11":{"tf":1.0},"13":{"tf":1.0},"28":{"tf":1.4142135623730951},"30":{"tf":1.0},"45":{"tf":1.0},"5":{"tf":1.0}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"31":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"11":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"a":{"b":{"df":0,"docs":{},"l":{"df":5,"docs":{"12":{"tf":1.0},"35":{"tf":2.0},"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"df":14,"docs":{"26":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"3":{"tf":1.4142135623730951},"31":{"tf":1.4142135623730951},"35":{"tf":1.0},"4":{"tf":1.7320508075688772},"40":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":4,"docs":{"26":{"tf":1.0},"27":{"tf":1.0},"31":{"tf":1.0},"35":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"'":{"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":4,"docs":{"15":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.0},"42":{"tf":1.0}}}},"r":{"df":3,"docs":{"1":{"tf":1.0},"28":{"tf":1.0},"33":{"tf":1.0}}},"v":{"df":1,"docs":{"5":{"tf":1.0}}}},".":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":1,"docs":{"2":{"tf":1.0}}}}}}}}}},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":1,"docs":{"23":{"tf":1.0}},"m":{"df":0,"docs":{},"q":{"'":{"df":2,"docs":{"35":{"tf":1.4142135623730951},"45":{"tf":1.0}}},"df":20,"docs":{"11":{"tf":1.0},"30":{"tf":2.449489742783178},"31":{"tf":1.7320508075688772},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"34":{"tf":1.0},"35":{"tf":1.7320508075688772},"36":{"tf":1.0},"37":{"tf":1.4142135623730951},"38":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.7320508075688772},"44":{"tf":1.7320508075688772},"45":{"tf":2.23606797749979},"46":{"tf":1.0},"47":{"tf":4.0},"9":{"tf":1.0}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":4,"docs":{"36":{"tf":1.4142135623730951},"41":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}},"e":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"<":{"df":0,"docs":{},"t":{"df":5,"docs":{"37":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"37":{"tf":1.4142135623730951},"38":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}}}}}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"35":{"tf":1.0}}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"v":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"41":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":1,"docs":{"47":{"tf":1.4142135623730951}}}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"'":{"df":2,"docs":{"31":{"tf":1.0},"42":{"tf":1.0}}},"df":8,"docs":{"31":{"tf":1.7320508075688772},"35":{"tf":2.449489742783178},"36":{"tf":1.0},"37":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":3.1622776601683795},"45":{"tf":3.4641016151377544}}}}}},"df":0,"docs":{}}}}}},"title":{"root":{"a":{"d":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":1,"docs":{"1":{"tf":1.0}}}},"s":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"i":{"df":1,"docs":{"39":{"tf":1.0}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"n":{"c":{"/":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"24":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":3,"docs":{"25":{"tf":1.0},"28":{"tf":1.0},"7":{"tf":1.0}}},"df":0,"docs":{}}}}},"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"5":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"35":{"tf":1.0}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"'":{"df":1,"docs":{"0":{"tf":1.0}}},"df":3,"docs":{"21":{"tf":1.0},"24":{"tf":1.0},"9":{"tf":1.0}}}}}}}},"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":2,"docs":{"19":{"tf":1.0},"34":{"tf":1.0}}}}}}},"df":0,"docs":{}},"o":{"d":{"df":0,"docs":{},"e":{"df":3,"docs":{"25":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"32":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}},"n":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"41":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":5,"docs":{"12":{"tf":1.0},"36":{"tf":1.0},"40":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"11":{"tf":1.0}}}}}}}}},"df":0,"docs":{}}},"i":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"31":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"o":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":1,"docs":{"43":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"a":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"21":{"tf":1.0},"23":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":9,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"3":{"tf":1.0},"32":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.0}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"23":{"tf":1.0}}},"df":0,"docs":{}}}}}}}}},"x":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"30":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"26":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"f":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"11":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"30":{"tf":1.0},"47":{"tf":1.0}}}},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"29":{"tf":1.0}}}}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"12":{"tf":1.0},"33":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"46":{"tf":1.0}}}},"df":0,"docs":{}}}}},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":1,"docs":{"21":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"43":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"i":{"df":1,"docs":{"40":{"tf":1.0}},"i":{"df":1,"docs":{"44":{"tf":1.0}}}},"o":{"df":2,"docs":{"28":{"tf":1.0},"29":{"tf":1.0}}},"v":{"df":1,"docs":{"45":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":5,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"3":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.0}}}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":2,"docs":{"37":{"tf":1.0},"38":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"d":{"df":2,"docs":{"40":{"tf":1.0},"42":{"tf":1.0}}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"11":{"tf":1.0}}}}}}}},"p":{"df":0,"docs":{},"s":{"c":{"df":1,"docs":{"34":{"tf":1.0}}},"df":0,"docs":{}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":1,"docs":{"27":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"22":{"tf":1.0}}}}}}}}},"w":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":1,"docs":{"13":{"tf":1.0}}}}}}}}}}},"p":{"a":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"6":{"tf":1.0}}}}}}},"df":0,"docs":{},"t":{"df":4,"docs":{"36":{"tf":1.0},"40":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":2,"docs":{"17":{"tf":1.0},"18":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":2,"docs":{"44":{"tf":1.0},"45":{"tf":1.0}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"16":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}}}},"u":{"df":0,"docs":{},"n":{"df":1,"docs":{"25":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"40":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"20":{"tf":1.0}}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":1,"docs":{"38":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":13,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"15":{"tf":1.0},"18":{"tf":1.0},"32":{"tf":1.0},"33":{"tf":1.0},"34":{"tf":1.0},"36":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}}}}},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"23":{"tf":1.0},"42":{"tf":1.0}}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":5,"docs":{"23":{"tf":1.0},"28":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"39":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":1,"docs":{"20":{"tf":1.0}}}}},"s":{"df":2,"docs":{"10":{"tf":1.0},"18":{"tf":1.0}}}},"v":{"df":0,"docs":{},"s":{"df":2,"docs":{"6":{"tf":1.0},"7":{"tf":1.0}}}},"w":{"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"35":{"tf":1.0}}}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"16":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":2,"docs":{"14":{"tf":1.0},"3":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{"df":2,"docs":{"30":{"tf":1.0},"47":{"tf":1.0}}}}}}}}}}},"lang":"English","pipeline":["trimmer","stopWordFilter","stemmer"],"ref":"id","version":"0.9.5"},"results_options":{"limit_results":30,"teaser_word_count":30},"search_options":{"bool":"OR","expand":true,"fields":{"body":{"boost":1},"breadcrumbs":{"boost":1},"title":{"boost":2}}}}); \ No newline at end of file diff --git a/searchindex.json b/searchindex.json new file mode 100644 index 00000000..ad62ef1a --- /dev/null +++ b/searchindex.json @@ -0,0 +1 @@ +{"doc_urls":["ch00-00-where-to-start.html#calloops-documentation","ch00-00-where-to-start.html#api","ch00-00-where-to-start.html#tutorial","ch01-00-how-an-event-loop-works.html#how-an-event-loop-works","ch01-00-how-an-event-loop-works.html#terminology","ch01-00-how-an-event-loop-works.html#events-and-callbacks","ch01-00-how-an-event-loop-works.html#concurrency-vs-parallelism","ch01-00-how-an-event-loop-works.html#event-loops-vs-async-code","ch01-00-how-an-event-loop-works.html#never-block-the-loop","ch01-00-how-an-event-loop-works.html#calloop-and-composition","ch02-00-event-sources.html#using-event-sources","ch02-01-generic.html#monitoring-a-file-descriptor","ch02-01-generic.html#creating-a-generic-source","ch02-01-generic.html#ownership-and-asfd-wrappers","ch02-02-timers.html#working-with-timers","ch02-02-timers.html#adding-sources-to-the-loop","ch02-02-timers.html#the-whole-program","ch02-03-ping.html#pinging-the-event-loop","ch02-03-ping.html#how-to-use-the-ping-source","ch02-04-channels.html#channels","ch02-05-signals.html#unix-signals","ch02-06-errors.html#error-handling-in-calloop","ch02-06-errors.html#overview","ch02-06-errors.html#the-error-type-on-the-eventsource-trait","ch03-00-async-await.html#asyncawait-in-calloop","ch03-01-run-async-code.html#run-async-code","ch03-01-run-async-code.html#enable-the-executor-feature","ch03-01-run-async-code.html#note-about-threads","ch03-02-async-io-types.html#async-io-types","ch03-02-async-io-types.html#enable-the-futures-io-feature","ch04-00-a-full-example-zeromq.html#a-full-example-zeromq","ch04-00-a-full-example-zeromq.html#disclaimer","ch04-01-composition.html#composing-event-sources","ch04-01-composition.html#the-generic-source","ch04-01-composition.html#the-mpsc-channel-source","ch04-01-composition.html#the-wakeup-call","ch04-02-creating-our-source-part-1-our-types.html#creating-our-source-part-i-our-types","ch04-02-creating-our-source-part-1-our-types.html#the-message-type","ch04-02-creating-our-source-part-1-our-types.html#enforcing-single-messages","ch04-02-creating-our-source-part-1-our-types.html#associated-types","ch04-03-creating-our-source-part-2-setup-methods.html#creating-our-source-part-ii-setup-methods","ch04-03-creating-our-source-part-2-setup-methods.html#our-constructor","ch04-03-creating-our-source-part-2-setup-methods.html#trait-methods-registering-sources","ch04-03-creating-our-source-part-2-setup-methods.html#our-drop-handler","ch04-04-creating-our-source-part-3-processing-events-almost.html#creating-our-source-part-iii-processing-events-almost","ch04-05-creating-our-source-part-4-processing-events-really.html#creating-our-source-part-iv-processing-events-really","ch04-05-creating-our-source-part-4-processing-events-really.html#greediness","ch04-06-the-full-zeromq-event-source-code.html#the-full-zeromq-event-source-code"],"index":{"documentStore":{"docInfo":{"0":{"body":0,"breadcrumbs":3,"title":2},"1":{"body":13,"breadcrumbs":2,"title":1},"10":{"body":45,"breadcrumbs":6,"title":3},"11":{"body":101,"breadcrumbs":9,"title":3},"12":{"body":43,"breadcrumbs":9,"title":3},"13":{"body":89,"breadcrumbs":9,"title":3},"14":{"body":82,"breadcrumbs":6,"title":2},"15":{"body":197,"breadcrumbs":7,"title":3},"16":{"body":41,"breadcrumbs":6,"title":2},"17":{"body":54,"breadcrumbs":7,"title":3},"18":{"body":56,"breadcrumbs":7,"title":3},"19":{"body":0,"breadcrumbs":5,"title":1},"2":{"body":54,"breadcrumbs":2,"title":1},"20":{"body":0,"breadcrumbs":7,"title":2},"21":{"body":0,"breadcrumbs":8,"title":3},"22":{"body":118,"breadcrumbs":6,"title":1},"23":{"body":177,"breadcrumbs":9,"title":4},"24":{"body":21,"breadcrumbs":4,"title":2},"25":{"body":0,"breadcrumbs":8,"title":3},"26":{"body":596,"breadcrumbs":8,"title":3},"27":{"body":33,"breadcrumbs":7,"title":2},"28":{"body":69,"breadcrumbs":8,"title":3},"29":{"body":838,"breadcrumbs":9,"title":4},"3":{"body":40,"breadcrumbs":6,"title":3},"30":{"body":103,"breadcrumbs":6,"title":3},"31":{"body":127,"breadcrumbs":4,"title":1},"32":{"body":58,"breadcrumbs":7,"title":3},"33":{"body":29,"breadcrumbs":6,"title":2},"34":{"body":21,"breadcrumbs":7,"title":3},"35":{"body":190,"breadcrumbs":6,"title":2},"36":{"body":80,"breadcrumbs":11,"title":4},"37":{"body":62,"breadcrumbs":9,"title":2},"38":{"body":32,"breadcrumbs":10,"title":3},"39":{"body":134,"breadcrumbs":9,"title":2},"4":{"body":81,"breadcrumbs":4,"title":1},"40":{"body":20,"breadcrumbs":15,"title":6},"41":{"body":78,"breadcrumbs":10,"title":1},"42":{"body":174,"breadcrumbs":13,"title":4},"43":{"body":78,"breadcrumbs":11,"title":2},"44":{"body":637,"breadcrumbs":15,"title":6},"45":{"body":412,"breadcrumbs":17,"title":7},"46":{"body":49,"breadcrumbs":11,"title":1},"47":{"body":645,"breadcrumbs":13,"title":5},"5":{"body":107,"breadcrumbs":5,"title":2},"6":{"body":40,"breadcrumbs":6,"title":3},"7":{"body":90,"breadcrumbs":8,"title":5},"8":{"body":65,"breadcrumbs":6,"title":3},"9":{"body":47,"breadcrumbs":5,"title":2}},"docs":{"0":{"body":"","breadcrumbs":"Where to start » Calloop's Documentation","id":"0","title":"Calloop's Documentation"},"1":{"body":"If you're looking for calloop's API documentation, they are available on docs.rs for the released versions. There are also the docs of the current development version .","breadcrumbs":"Where to start » API","id":"1","title":"API"},"10":{"body":"Calloop's structure is entirely built around the EventSource trait, which represents something that is capable of generating events. To receive those events, you need to give ownership of the event source to calloop, along with a closure that will be invoked whenever said source generated an event. This is thus a push-based model, that is most suited for contexts where your program needs to react to (unpredictable) outside events, rather than wait efficiently for the completion of some operation it initiated.","breadcrumbs":"Using event sources » Using event sources","id":"10","title":"Using event sources"},"11":{"body":"The Generic event source wraps a file descriptor (\"fd\") and fires its callback any time there are events on it ie. becoming readable or writable, or encountering an error. It's pretty simple, but it's what every other event source is based around. And since the platforms that calloop runs on expose many different kinds of events via fds, it's usually the key to using those events in calloop. For example on Linux, fd-based interfaces are available for GPIO, I2C, USB, UART, network interfaces, timers and many other systems. Integrating these into calloop starts with obtaining the appropriate fd, creating a Generic event source from it, and building up a more useful, abstracted event source around that. A detailed example of this is given for ZeroMQ . You do not have to use a low-level fd either: any type that implements AsFd can be provided. This means that you can use a wrapper type that handles allocation and disposal itself, and implement AsRawFd on it so that Generic can manage it in the event loop.","breadcrumbs":"Using event sources » Monitoring a file descriptor » Monitoring a file descriptor","id":"11","title":"Monitoring a file descriptor"},"12":{"body":"Creating a Generic event source requires three things: An OwnedFd or a wrapper type that implements AsFd The \"interest\" you have in this descriptor — this means, whether you want to generate events when the fd becomes readable, writeable, or both The \"mode\" of event generation - level triggered or edge triggered The easiest constructor to use is the new() method, but if you need control over the associated error type there is also new_with_error() .","breadcrumbs":"Using event sources » Monitoring a file descriptor » Creating a Generic source","id":"12","title":"Creating a Generic source"},"13":{"body":"Rust 1.63 introduced a concept of file descriptor ownership and borrowing through the OwnedFd and BorrowedFd types, which are also available on older Rust versions through the io-lifetimes crate. The AsFd trait provides a way to get a BorrowedFd corresponding to a file, socket, etc. while guaranteeing the fd will be valid for the lifetime of the BorrowedFd. Not all third party crates use AsFd yet, and may instead provide types implementing AsRawFd. 'AsFdWrapper' provides a way to adapt these types. To use this safely, ensure the AsRawFd implementation of the type it wraps returns a valid fd as long as the type exists. And to avoid an fd leak, it should ultimately be closed properly. Safe types like OwnedFd and BorrowedFd should be preferred over RawFds, and the use of RawFds outside of implementing FFI shouldn't be necessary as libraries move to using the IO safe types and traits.","breadcrumbs":"Using event sources » Monitoring a file descriptor » Ownership and AsFd wrappers","id":"13","title":"Ownership and AsFd wrappers"},"14":{"body":"Timer event sources are used to manipulate time-related actions. Those are provided under the calloop::timer module, with the Timer type at its core. A Timer source has a simple behavior: it is programmed to wait for some duration, or until a certain point in time. Once that deadline is reached, the source generates an event. So with use calloop::timer::Timer at the top of our .rs file, we can create a timer that will wait for 5 seconds: # use std::time::Duration;\n# # use calloop::{\n# timer::{TimeoutAction, Timer},\n# EventLoop,\n# };\n# # fn main() {\n# let mut event_loop = EventLoop::try_new().expect(\"Failed to initialize the event loop!\");\n# let timer = Timer::from_duration(Duration::from_secs(5));\n# # event_loop\n# .handle()\n# .insert_source(timer, |deadline, _: &mut (), _shared_data| {\n# println!(\"Event fired for: {:?}\", deadline);\n# TimeoutAction::Drop\n# })\n# .expect(\"Failed to insert event source!\");\n# # event_loop\n# .dispatch(None, &mut ())\n# .expect(\"Error during event loop!\");\n# }","breadcrumbs":"Using event sources » Timers » Working with timers","id":"14","title":"Working with timers"},"15":{"body":"We have an event source, we have our shared data, and we know how to start our loop running. All that is left is to learn how to combine these things: # use std::time::Duration;\n# # use calloop::{\n# timer::{TimeoutAction, Timer},\n# EventLoop,\n# };\n# # fn main() {\n# let mut event_loop = EventLoop::try_new().expect(\"Failed to initialize the event loop!\");\n# # let timer = Timer::from_duration(Duration::from_secs(5));\n# event_loop .handle() .insert_source(timer, |deadline, _: &mut (), _shared_data| { println!(\"Event fired for: {:?}\", deadline); TimeoutAction::Drop }) .expect(\"Failed to insert event source!\");\n# # event_loop\n# .dispatch(None, &mut ())\n# .expect(\"Error during event loop!\");\n# } Breaking this down, the callback we provide receives 3 arguments: The first one is an Instant representing the time at which this timer was scheduled to expire. Due to how the event loop works, it might be that your callback is not invoked at the exact time where the timer expired (if an other callback was being processed at the time for example), so the original deadline is given if you need precise time tracking. The second argument is just &mut (), as the timers don't use the EventSource functionality. The third argumument is the shared data passed to your event loop. In addition your callback is expected to return a TimeoutAction , that will instruct calloop what to do next. This enum has 3 values: Drop will disable the timer and destroy it, freeing the callback. ToInstant will rechedule the callback to fire again at given Instant, invoking the same callback again. This is useful if you need to create a timer that fires events at regular intervals, for example to encode key repetition in a graphical app. You would compute the next instant by adding the duration to the previous instant. It is not a problem if that duration is in the past, it'll simply cause the timer to fire again instantly. THis way, even if some other part of your app lags, you'll still have on average the correct amount of events per second. ToDuration will reschedule the callback to fire again after a given Duration. This is useful if you need to schedule some background task to execute again after some time after it was last completed, when there is no point in catching up some previous lag.","breadcrumbs":"Using event sources » Timers » Adding sources to the loop","id":"15","title":"Adding sources to the loop"},"16":{"body":"Putting it all together, we have: use std::time::Duration; use calloop::{ timer::{TimeoutAction, Timer}, EventLoop,\n}; fn main() { let mut event_loop = EventLoop::try_new().expect(\"Failed to initialize the event loop!\"); let timer = Timer::from_duration(Duration::from_secs(5)); event_loop .handle() .insert_source(timer, |deadline, _: &mut (), _shared_data| { println!(\"Event fired for: {:?}\", deadline); TimeoutAction::Drop }) .expect(\"Failed to insert event source!\"); event_loop .dispatch(None, &mut ()) .expect(\"Error during event loop!\");\n}","breadcrumbs":"Using event sources » Timers » The whole program","id":"16","title":"The whole program"},"17":{"body":"The Ping event source has one very simple job — wake up the event loop. Use this when you know there are events for your event source to process, but those events aren't going to wake the event loop up themselves. For example, calloop's own message channel uses Rust's native MPSC channel internally. Because there's no way for the internal message queue to wake up the event loop, it's coupled with a Ping source that wakes the loop up when there are new messages.","breadcrumbs":"Using event sources » Ping » \"Pinging\" the event loop","id":"17","title":"\"Pinging\" the event loop"},"18":{"body":"The Ping has two ends — the event source part ( PingSource ), that goes in the event loop, and the sending end (Ping) you use to \"send\" the ping. To wake the event loop up, call ping() on the sending end. Do not forget to process the events of the PingSource if you are using it as part of a larger event source! Even though the events carry no information (they are just () values), the process_events() method must be called in order to \"reset\" the PingSource. Otherwise the event loop will be continually woken up until you do, effectively becoming a busy-loop.","breadcrumbs":"Using event sources » Ping » How to use the Ping source","id":"18","title":"How to use the Ping source"},"19":{"body":"","breadcrumbs":"Using event sources » Channels » Channels","id":"19","title":"Channels"},"2":{"body":"This book presents a step-by-step tutorial to get yourself familiar with calloop and how it is used: Chapter 1 presents the general principles of an event loop that are important to have in mind when working with calloop. Chapter 2 goes through the different kind of event sources that are provided in calloop, and provides examples of how to use them Chapter 3 presents the integration with Rust's Async/Await ecosystem provided by calloop Chapter 4 gives a detailed example of building a custom event source in calloop, by combining other sources","breadcrumbs":"Where to start » Tutorial","id":"2","title":"Tutorial"},"20":{"body":"","breadcrumbs":"Using event sources » Unix Signals » Unix Signals","id":"20","title":"Unix Signals"},"21":{"body":"","breadcrumbs":"Using event sources » Error handling » Error handling in Calloop","id":"21","title":"Error handling in Calloop"},"22":{"body":"Most error handling crates/guides/documentation for Rust focus on one of two situations: Creating errors that an API can propagate out to a user of the API, or Making your library deal nicely with the Results from closure or trait methods that it might call Calloop has to do both of these things. It needs to provide a library user with errors that work well with ? and common error-handling idioms in their own code, and it needs to handle errors from the callbacks you give to process_events() or insert_source(). It also needs to provide some flexibility in the EventSource trait, which is used both for internal event sources and by users of the library. Because of this, error handling in Calloop leans more towards having separate error types for different concerns. This may mean that there is some extra conversion code in places like returning results from process_events(), or in callbacks that use other libraries. However, we try to make it smoother to do these conversions, and to make sure information isn't lost in doing so. If your crate already has some form of structured error handling, Calloop's error types should pose no problem to integrate into this. All of Calloop's errors implement std::error::Error and can be manipulated the same as any other error types. The place where this becomes the most complex is in the process_events() method on the EventSource trait.","breadcrumbs":"Using event sources » Error handling » Overview","id":"22","title":"Overview"},"23":{"body":"The EventSource trait contains an associated type named Error, which forms part of the return type from process_events(). This type must be convertible into Box, which means you can use: Your own error type that implements std::error::Error A structured error type created with Thiserror Box A flexible string-based error type such as Anyhow's anyhow::Error As a rule, if you implement EventSource you should try to split your errors into two different categories: Errors that make sense as a kind of event. These should be a part of the Event associated type eg. as an enum or Result. Errors that mean your event source simply cannot process more events. These should form the Error associated type. For an example, take Calloop's channel type, calloop::channel::Channel . When the sending end is dropped, no more messages can be received after that point. But this is not returned as an error when calling process_events(), because you still want to (and can!) receive messages sent before that point that might still be in the queue. Hence the events received by the callback for this source can be Msg(e) or Closed. However, if the internal ping source produces an error, there is no way for the sending end of the channel to notify the receiver. It is impossible to process more events on this event source, and the caller needs to decide how to recover from this situation. Hence this is returned as a ChannelError from process_events(). Another example might be an event source that represents a running subprocess. If the subprocess exits with a non-zero status code, or the executable can't be found, those don't mean that events can no longer be processed. They can be provided to the caller through the callback. But if the lower level sources being used to run (eg. an asynchronous executor or subprocess file descriptor) fail to work as expected, process_events() should return an error.","breadcrumbs":"Using event sources » Error handling » The Error type on the EventSource trait","id":"23","title":"The Error type on the EventSource trait"},"24":{"body":"While it is centered on event sources and callbacks, calloop also provides adapters to integrate with Rust's async ecosystem. These adapters come in two parts: a futures executor and an async adapter for IO type .","breadcrumbs":"I need async/await! » Async/await in calloop","id":"24","title":"Async/await in calloop"},"25":{"body":"","breadcrumbs":"I need async/await! » Run async code » Run async code","id":"25","title":"Run async code"},"26":{"body":"To use calloop::futures you need to enable the executor feature in your Cargo.toml like so: [dependencies.calloop]\nfeatures = [ \"executor\" ]\nversion = ... Let's say you have some async code that looks like this: sender.send(\"Hello,\").await.ok();\nreceiver.next().await.map(|m| println!(\"Received: {}\", m));\nsender.send(\"world!\").await.ok();\nreceiver.next().await.map(|m| println!(\"Received: {}\", m));\n\"So long!\" ...and a corresponding block that receives and sends to this one. I will call one of these blocks \"friendly\" and the other one \"aloof\". To run async code in Calloop, you use the components in calloop::futures . First, obtain both an executor and a scheduler with calloop::futures::executor() : # use calloop::EventLoop;\n# # // futures = \"0.3\"\n# use futures::sink::SinkExt;\n# use futures::stream::StreamExt;\n# # fn main() -> std::io::Result<()> { let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# # // Let's create two channels for our async blocks below. The blocks will\n# // exchange messages via these channels.\n# let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded();\n# let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded();\n# # // Our toy async code.\n# let async_friendly_task = async move {\n# sender_friendly.send(\"Hello,\").await.ok();\n# if let Some(msg) = receiver_aloof.next().await {\n# println!(\"Aloof said: {}\", msg);\n# }\n# sender_friendly.send(\"world!\").await.ok();\n# if let Some(msg) = receiver_aloof.next().await {\n# println!(\"Aloof said: {}\", msg);\n# }\n# \"Bye!\"\n# };\n# # let async_aloof_task = async move {\n# if let Some(msg) = receiver_friendly.next().await {\n# println!(\"Friendly said: {}\", msg);\n# }\n# sender_aloof.send(\"Oh,\").await.ok();\n# if let Some(msg) = receiver_friendly.next().await {\n# println!(\"Friendly said: {}\", msg);\n# }\n# sender_aloof.send(\"it's you.\").await.ok();\n# \"Regards.\"\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_friendly_task).unwrap();\n# sched.schedule(async_aloof_task).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut (), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } The executor , the part that executes the future, goes in the event loop: # use calloop::EventLoop;\n# # // futures = \"0.3\"\n# use futures::sink::SinkExt;\n# use futures::stream::StreamExt;\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# let mut event_loop = EventLoop::try_new()?; let handle = event_loop.handle(); handle .insert_source(exec, |evt, _metadata, _shared| { // Print the value of the async block ie. the return value. println!(\"Async block ended with: {}\", evt); }) .map_err(|e| e.error)?;\n# # // Let's create two channels for our async blocks below. The blocks will\n# // exchange messages via these channels.\n# let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded();\n# let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded();\n# # // Our toy async code.\n# let async_friendly_task = async move {\n# sender_friendly.send(\"Hello,\").await.ok();\n# if let Some(msg) = receiver_aloof.next().await {\n# println!(\"Aloof said: {}\", msg);\n# }\n# sender_friendly.send(\"world!\").await.ok();\n# if let Some(msg) = receiver_aloof.next().await {\n# println!(\"Aloof said: {}\", msg);\n# }\n# \"Bye!\"\n# };\n# # let async_aloof_task = async move {\n# if let Some(msg) = receiver_friendly.next().await {\n# println!(\"Friendly said: {}\", msg);\n# }\n# sender_aloof.send(\"Oh,\").await.ok();\n# if let Some(msg) = receiver_friendly.next().await {\n# println!(\"Friendly said: {}\", msg);\n# }\n# sender_aloof.send(\"it's you.\").await.ok();\n# \"Regards.\"\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_friendly_task).unwrap();\n# sched.schedule(async_aloof_task).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut (), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } Now let's write our async code in full: # use calloop::EventLoop;\n# # // futures = \"0.3\"\n# use futures::sink::SinkExt;\n# use futures::stream::StreamExt;\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# // Let's create two channels for our async blocks below. The blocks will // exchange messages via these channels. let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded(); let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded(); // Our toy async code. let async_friendly_task = async move { sender_friendly.send(\"Hello,\").await.ok(); if let Some(msg) = receiver_aloof.next().await { println!(\"Aloof said: {}\", msg); } sender_friendly.send(\"world!\").await.ok(); if let Some(msg) = receiver_aloof.next().await { println!(\"Aloof said: {}\", msg); } \"Bye!\" }; let async_aloof_task = async move { if let Some(msg) = receiver_friendly.next().await { println!(\"Friendly said: {}\", msg); } sender_aloof.send(\"Oh,\").await.ok(); if let Some(msg) = receiver_friendly.next().await { println!(\"Friendly said: {}\", msg); } sender_aloof.send(\"it's you.\").await.ok(); \"Regards.\" };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_friendly_task).unwrap();\n# sched.schedule(async_aloof_task).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut (), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } Like any block in Rust, the value of your async block is the last expression ie. it is effectively \"returned\" from the block, which means it will be provided to your executor's callback as the first argument (the \"event\"). You'll see this in the output with the Async block ended with: ... lines. Finally, we run the loop: # use calloop::EventLoop;\n# # // futures = \"0.3\"\n# use futures::sink::SinkExt;\n# use futures::stream::StreamExt;\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# # // Let's create two channels for our async blocks below. The blocks will\n# // exchange messages via these channels.\n# let (mut sender_friendly, mut receiver_friendly) = futures::channel::mpsc::unbounded();\n# let (mut sender_aloof, mut receiver_aloof) = futures::channel::mpsc::unbounded();\n# # // Our toy async code.\n# let async_friendly_task = async move {\n# sender_friendly.send(\"Hello,\").await.ok();\n# if let Some(msg) = receiver_aloof.next().await {\n# println!(\"Aloof said: {}\", msg);\n# }\n# sender_friendly.send(\"world!\").await.ok();\n# if let Some(msg) = receiver_aloof.next().await {\n# println!(\"Aloof said: {}\", msg);\n# }\n# \"Bye!\"\n# };\n# # let async_aloof_task = async move {\n# if let Some(msg) = receiver_friendly.next().await {\n# println!(\"Friendly said: {}\", msg);\n# }\n# sender_aloof.send(\"Oh,\").await.ok();\n# if let Some(msg) = receiver_friendly.next().await {\n# println!(\"Friendly said: {}\", msg);\n# }\n# sender_aloof.send(\"it's you.\").await.ok();\n# \"Regards.\"\n# };\n# // Schedule the async block to be run in the event loop. sched.schedule(async_friendly_task).unwrap(); sched.schedule(async_aloof_task).unwrap(); // Run the event loop. println!(\"Starting event loop. Use Ctrl-C to exit.\"); event_loop.run(None, &mut (), |_| {})?; println!(\"Event loop ended.\");\n# # Ok(())\n# } And our output looks like: Starting event loop.\nFriendly said: Hello,\nAloof said: Oh,\nFriendly said: world!\nAsync block ended with: Regards.\nAloof said: it's you.\nAsync block ended with: Bye!\nEvent loop ended. Note that for the sake of keeping this example short, I've written the async code before running the loop. But async code can be scheduled from callbacks, or other sources within the loop too.","breadcrumbs":"I need async/await! » Run async code » Enable the executor feature!","id":"26","title":"Enable the executor feature!"},"27":{"body":"One of Calloop's strengths is that it is completely single threaded as written. However, many async crates are implemented using threads eg. async-std and async-process. This is not an inherent problem! Calloop will work perfectly well with such implementations in general. However, if you have selected Calloop because of your own constraints around threading, be aware of this.","breadcrumbs":"I need async/await! » Run async code » Note about threads","id":"27","title":"Note about threads"},"28":{"body":"This section is about adapting blocking IO types for use with async Rust code, and powering that async code with Calloop. If you just want to add blocking IO types to your event loop and use Calloop's callback/composition-based design, you only need to wrap your blocking IO type in a generic event source . You may find that you need to write ordinary Rust async code around blocking IO types. Calloop provides the ability to wrap blocking types — anything that implements the AsFd trait — in its own async type. This can be polled in any executor you may have chosen for your async code, but if you're using Calloop you'll probably be using Calloop's executor .","breadcrumbs":"I need async/await! » Async IO types » Async IO types","id":"28","title":"Async IO types"},"29":{"body":"To use calloop::io you need to enable the futures-io feature in your Cargo.toml like so: [dependencies.calloop]\nfeatures = [ \"futures-io\" ]\nversion = ... Realistically you will probably also want to use this with async code, so you should also enable the executor feature too. Just like in the async example, we will use the components in calloop::futures . First, obtain both an executor and a scheduler with calloop::futures::executor() : # use calloop::EventLoop;\n# # use futures::io::{AsyncReadExt, AsyncWriteExt};\n# # fn main() -> std::io::Result<()> { let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# # let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();\n# let mut sender = handle.adapt_io(sender).unwrap();\n# let mut receiver = handle.adapt_io(receiver).unwrap();\n# # let async_receive = async move {\n# let mut buf = [0u8; 12];\n# // Here's our async-ified Unix domain socket.\n# receiver.read_exact(&mut buf).await.unwrap();\n# std::str::from_utf8(&buf).unwrap().to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_receive).unwrap();\n# # let async_send = async move {\n# // Here's our async-ified Unix domain socket.\n# sender.write_all(b\"Hello, world!\").await.unwrap();\n# \"Sent data...\".to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_send).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } The executor goes in the event loop: # use calloop::EventLoop;\n# # use futures::io::{AsyncReadExt, AsyncWriteExt};\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# let mut event_loop = EventLoop::try_new()?; let handle = event_loop.handle(); handle .insert_source(exec, |evt, _metadata, _shared| { // Print the value of the async block ie. the return value. println!(\"Async block ended with: {}\", evt); }) .map_err(|e| e.error)?;\n# # let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();\n# let mut sender = handle.adapt_io(sender).unwrap();\n# let mut receiver = handle.adapt_io(receiver).unwrap();\n# # let async_receive = async move {\n# let mut buf = [0u8; 12];\n# // Here's our async-ified Unix domain socket.\n# receiver.read_exact(&mut buf).await.unwrap();\n# std::str::from_utf8(&buf).unwrap().to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_receive).unwrap();\n# # let async_send = async move {\n# // Here's our async-ified Unix domain socket.\n# sender.write_all(b\"Hello, world!\").await.unwrap();\n# \"Sent data...\".to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_send).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } For our blocking IO types, let's use an unnamed pair of Unix domain stream sockets . To convert them to async types, we simply call calloop::LoopHandle::adapt_io() : # use calloop::EventLoop;\n# # use futures::io::{AsyncReadExt, AsyncWriteExt};\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap(); let mut sender = handle.adapt_io(sender).unwrap(); let mut receiver = handle.adapt_io(receiver).unwrap();\n# # let async_receive = async move {\n# let mut buf = [0u8; 12];\n# // Here's our async-ified Unix domain socket.\n# receiver.read_exact(&mut buf).await.unwrap();\n# std::str::from_utf8(&buf).unwrap().to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_receive).unwrap();\n# # let async_send = async move {\n# // Here's our async-ified Unix domain socket.\n# sender.write_all(b\"Hello, world!\").await.unwrap();\n# \"Sent data...\".to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_send).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } Note that most of the useful async functionality for the returned type is expressed through various traits in futures::io . So we need to explicitly use these: # use calloop::EventLoop;\n# use futures::io::{AsyncReadExt, AsyncWriteExt};\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# # let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();\n# let mut sender = handle.adapt_io(sender).unwrap();\n# let mut receiver = handle.adapt_io(receiver).unwrap();\n# # let async_receive = async move {\n# let mut buf = [0u8; 12];\n# // Here's our async-ified Unix domain socket.\n# receiver.read_exact(&mut buf).await.unwrap();\n# std::str::from_utf8(&buf).unwrap().to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_receive).unwrap();\n# # let async_send = async move {\n# // Here's our async-ified Unix domain socket.\n# sender.write_all(b\"Hello, world!\").await.unwrap();\n# \"Sent data...\".to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_send).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } We can now write async code around these types. Here's the receiving code: # use calloop::EventLoop;\n# # use futures::io::{AsyncReadExt, AsyncWriteExt};\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# # let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();\n# let mut sender = handle.adapt_io(sender).unwrap();\n# let mut receiver = handle.adapt_io(receiver).unwrap();\n# let async_receive = async move { let mut buf = [0u8; 12]; // Here's our async-ified Unix domain socket. receiver.read_exact(&mut buf).await.unwrap(); std::str::from_utf8(&buf).unwrap().to_owned() }; // Schedule the async block to be run in the event loop. sched.schedule(async_receive).unwrap();\n# # let async_send = async move {\n# // Here's our async-ified Unix domain socket.\n# sender.write_all(b\"Hello, world!\").await.unwrap();\n# \"Sent data...\".to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_send).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } And here's the sending code. The receiving and sending code can be created and added to the executor in either order. # use calloop::EventLoop;\n# # use futures::io::{AsyncReadExt, AsyncWriteExt};\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# # let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();\n# let mut sender = handle.adapt_io(sender).unwrap();\n# let mut receiver = handle.adapt_io(receiver).unwrap();\n# # let async_receive = async move {\n# let mut buf = [0u8; 12];\n# // Here's our async-ified Unix domain socket.\n# receiver.read_exact(&mut buf).await.unwrap();\n# std::str::from_utf8(&buf).unwrap().to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_receive).unwrap();\n# let async_send = async move { // Here's our async-ified Unix domain socket. sender.write_all(b\"Hello, world!\").await.unwrap(); \"Sent data...\".to_owned() }; // Schedule the async block to be run in the event loop. sched.schedule(async_send).unwrap();\n# # // Run the event loop.\n# println!(\"Starting event loop. Use Ctrl-C to exit.\");\n# event_loop.run(None, &mut event_loop.get_signal(), |_| {})?;\n# println!(\"Event loop ended.\");\n# # Ok(())\n# } All that's left is to run the loop: # use calloop::EventLoop;\n# # use futures::io::{AsyncReadExt, AsyncWriteExt};\n# # fn main() -> std::io::Result<()> {\n# let (exec, sched) = calloop::futures::executor()?;\n# # let mut event_loop = EventLoop::try_new()?;\n# let handle = event_loop.handle();\n# # handle\n# .insert_source(exec, |evt, _metadata, _shared| {\n# // Print the value of the async block ie. the return value.\n# println!(\"Async block ended with: {}\", evt);\n# })\n# .map_err(|e| e.error)?;\n# # let (sender, receiver) = std::os::unix::net::UnixStream::pair().unwrap();\n# let mut sender = handle.adapt_io(sender).unwrap();\n# let mut receiver = handle.adapt_io(receiver).unwrap();\n# # let async_receive = async move {\n# let mut buf = [0u8; 12];\n# // Here's our async-ified Unix domain socket.\n# receiver.read_exact(&mut buf).await.unwrap();\n# std::str::from_utf8(&buf).unwrap().to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_receive).unwrap();\n# # let async_send = async move {\n# // Here's our async-ified Unix domain socket.\n# sender.write_all(b\"Hello, world!\").await.unwrap();\n# \"Sent data...\".to_owned()\n# };\n# # // Schedule the async block to be run in the event loop.\n# sched.schedule(async_send).unwrap();\n# // Run the event loop. println!(\"Starting event loop. Use Ctrl-C to exit.\"); event_loop.run(None, &mut event_loop.get_signal(), |_| {})?; println!(\"Event loop ended.\");\n# # Ok(())\n# } And the output we get is: Starting event loop. Use Ctrl-C to exit.\nAsync block ended with: Sent data...\nAsync block ended with: Hello, world\n^C","breadcrumbs":"I need async/await! » Async IO types » Enable the futures-io feature!","id":"29","title":"Enable the futures-io feature!"},"3":{"body":"An event loop is one way to write concurrent code. Other ways include threading (sort of), or asynchronous syntax. When you write concurrent code, you need to know two things: where in your program it could potentially block , and how to let other parts of your program run while waiting for those operations to stop blocking This chapter covers what the first thing means, and how Calloop accomplishes the second thing.","breadcrumbs":"How an event loop works » How an event loop works","id":"3","title":"How an event loop works"},"30":{"body":"The previous chapter showed how to use callbacks, event data and shared data to control our program. However, more complex programs will require more complex shared data, and more complex interactions between events. Eventually this will run up against ownership issues and just the basic mental load of the poor programmer. In this chapter we're going to build something more complex: an event source based on ZeroMQ sockets . ZeroMQ is (very) basically a highly abstracted socket library. You can create ZeroMQ sockets over TCP, PGM, IPC, in-process and more, and generally not worry about the transport mechanics. It guarantees atomic message transfer, and handles queuing, retries, reconnection and balancing under the hood. It also lets you integrate it with event loops and reactors by exposing a file descriptor that you can wait on. But we can't just wrap this file descriptor in Calloop's generic::Generic source and be done — there are a few subtleties we need to take care of for it to work right and be useful.","breadcrumbs":"A full example: ZeroMQ » A full example: ZeroMQ","id":"30","title":"A full example: ZeroMQ"},"31":{"body":"It might be tempting, at the end of this chapter, to think that the code we've written is the definitive ZeroMQ wrapper, able to address any use case or higher level pattern you like. Certainly it will be a lot more suited to Calloop than using ZeroMQ sockets by themselves, but it is not the only way to use them with Calloop. Here are some things I have not addressed, for the sake of simplicity: We will not handle fairness — our code will totally monopolise the event loop if we receive many messages at once. We do not consider back pressure beyond whatever built-in zsocket settings the caller might use. We just drop pending messages in the zsocket's internal queue (in and out) on shutdown. In a real application, you might want to make more specific decisions about the timeout and linger periods before dropping the zsocket, depending on your application's requirements. We don't deal with zsocket errors much. In fact, the overall error handling of event sources is usually highly specific to your application, so what we end up writing here is almost certainly not going to survive contact with your own code base. Here we just use ? everywhere, which will eventually cause the event loop to exit with an error. So by all means, take the code we write here and use and adapt it, but please please note the caveats above and think carefully about your own program.","breadcrumbs":"A full example: ZeroMQ » Disclaimer","id":"31","title":"Disclaimer"},"32":{"body":"Calloop is designed to work by composition . It provides you with some single-responsibility sources (timers, message channels, file descriptors), and you can combine these together, bit by bit, to make more complex event sources. These new sources can express more and more of your program's internal logic and the relationships between them, always in terms of events and how you process them. You can greatly simplify even a highly complex program if you identify and expose the \"real\" events you care about and use composition to tidy the other events away in internal details of event sources. So what do we need to compose?","breadcrumbs":"A full example: ZeroMQ » Composition » Composing event sources","id":"32","title":"Composing event sources"},"33":{"body":"Most obviously, ZeroMQ exposes a file descriptor for us to use. (This is a common thing for event-related libraries to do, so if you're wondering how to integrate, say, I²C or GPIO on Linux with Calloop, that's your answer.) Calloop can use file descriptors via the calloop::generic::Generic source. So that's one.","breadcrumbs":"A full example: ZeroMQ » Composition » The generic source","id":"33","title":"The generic source"},"34":{"body":"Secondly, we might want to send messages on the socket. This means our event source needs to react when we send it a message. Calloop has a message channel for precisely this purpose: calloop::channel::Channel. That's another one.","breadcrumbs":"A full example: ZeroMQ » Composition » The MPSC channel source","id":"34","title":"The MPSC channel source"},"35":{"body":"The third event source we need is a bit subtle, but since this isn't a mystery novel I can save you hours of debugging and spoil the ending now: we need a \"ping\" event source because ZeroMQ's FD is edge triggered. ZeroMQ's file descriptor is not the FD of an actual file or socket — you do not actually read data from it. It exists as an interface, with three important details: It is only ever readable. Even if the underlying socket can be written to, the FD that ZeroMQ gives you signals this by becoming readable. In fact, this FD will become readable under three circumstances: the ZeroMQ socket (henceforth called a \"zsocket\") is readable, writeable, or has an error. There is a separate function call, zmq::Socket::get_events() that will tell you which. It is edge triggered. It will only ever change from not-readable to readable when the socket's state changes. So if a zsocket receives two messages, and you only read one, the file descriptor will not wake up the event loop again . Why not? Because it hasn't changed state! After you read one message, the zsocket still has events waiting. If it receives yet another message... it still has events waiting. No change in internal state = no external event. This edge triggering also covers user actions. If a zsocket becomes writeable, and then you write to the zsocket, it might immediately (and atomically) change from writeable to readable. In this case you will not get another event on the FD . (The docs make this quite explicit, but there's a lot of docs to read so I'm spelling it out here.) What this adds up to is this: when we create our zsocket, it might already be readable or writeable. So when we add it to our event loop, it won't fire any events. Our entire source will just sit there until we wake it up by sending a message (which we might never do if it's eg. a pull socket). So the last event source we need is something that doesn't really convey any kind of message except \"please wake up the event loop on the next iteration\", and that is exactly what a calloop::ping::PingSource does. And that's three.","breadcrumbs":"A full example: ZeroMQ » Composition » The wakeup call","id":"35","title":"The wakeup call"},"36":{"body":"In the last chapter we worked out a list of the event sources we need to compose into a new type: calloop::generic::Generic calloop::channel::Channel calloop::ping::Ping So at a minimum, our type needs to contain these: pub struct ZeroMQSource\n{ // Calloop components. socket: calloop::generic::Generic>, mpsc_receiver: calloop::channel::Channel, wake_ping_receiver: calloop::ping::PingSource,\n} Note that I've left the type for the channel as ? — we'll get to that a bit later. What else do we need? If the PingSource is there to wake up the loop manually, we need to keep the other end of it. The ping is an internal detail — users of our type don't need to know it's there. We also need the zsocket itself, so we can actually detect and process events on it. That gives us: pub struct ZeroMQSource\n{ // Calloop components. socket: calloop::generic::Generic>, mpsc_receiver: calloop::channel::Channel, wake_ping_receiver: calloop::ping::PingSource, /// Sending end of the ping source. wake_ping_sender: calloop::ping::Ping,\n}","breadcrumbs":"A full example: ZeroMQ » Creating our source, part I: our types » Creating our source, part I: our types","id":"36","title":"Creating our source, part I: our types"},"37":{"body":"The most obvious candidate for the type of the message queue would be zmq::Message. But ZeroMQ sockets are capable of sending multipart messages, and this is even mandatory for eg. the PUB zsocket type, where the first part of the message is the topic. Therefore it makes more sense to accept a sequence of messages to cover the most general case, and that sequence can have a length of one for single-part messages. But with one more tweak: we can accept a sequence of things that can be transformed into zmq::Message values. The exact type we'll use will be a generic type like so: pub struct ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ mpsc_receiver: calloop::channel::Channel, // ...\n}","breadcrumbs":"A full example: ZeroMQ » Creating our source, part I: our types » The message type","id":"37","title":"The message type"},"38":{"body":"Remember that it's not just Vec and other sequence types that implement IntoIterator — Option implements it too! There is also std::iter::Once. So if a user of our API wants to enforce that all \"multi\"-part messages actually contain exactly one part, they can use this API with T being, say, std::iter::Once (or even just [zmq::Message; 1] in Rust 2021 edition).","breadcrumbs":"A full example: ZeroMQ » Creating our source, part I: our types » Enforcing single messages","id":"38","title":"Enforcing single messages"},"39":{"body":"The EventSource trait has four associated types: Event - when an event is generated that our caller cares about (ie. not some internal thing), this is the data we provide to their callback. This will be another sequence of messages, but because we're constructing it we can be more opinionated about the type and use the return type of zmq::Socket::recv_multipart() which is Vec>. Metadata - this is a more persistent kind of data, perhaps the underlying file descriptor or socket, or maybe some stateful object that the callback can manipulate. It is passed by exclusive reference to the Metadata type. In our case we don't use this, so it's (). Ret - this is the return type of the callback that's called on an event. Usually this will be a Result of some sort; in our case it's std::io::Result<()> just to signal whether some underlying operation failed or not. Error - this is the error type returned by process_events() (not the user callback!). Having this as an associated type allows you to have more control over error propagation in nested event sources. We will use Anyhow , which is like a more fully-features Box. It allows you to add context to any other error with a context() method. So together these are: impl calloop::EventSource for ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ type Event = Vec>; type Metadata = (); type Ret = io::Result<()>; type Error = anyhow::Error; // ...\n} I have saved one surprise for later to emphasise some important principles, but for now, let's move on to defining some methods!","breadcrumbs":"A full example: ZeroMQ » Creating our source, part I: our types » Associated types","id":"39","title":"Associated types"},"4":{"body":"A blocking operation is one that waits for an event to happen, and doesn't do anything else while it's waiting. For example, if you try to read from a network socket, and there is no data available, the read operation could wait for some indefinite amount of time. Your program will be in a state where it does not need to use any CPU cycles, or indeed do anything at all, and it won't proceed until there is data to read. Examples of blocking operations are: waiting for a certain time to elapse reading or writing to a file reading or writing to a network socket waiting for a thread to finish When any of these operations are ready to go, we call it an event . We call the underlying things (files, network sockets, timers, etc.) sources for events. So, for example, you can create an event source that corresponds to a file, and it will generate events when it is ready for reading, or writing, or encounters an error.","breadcrumbs":"How an event loop works » Terminology","id":"4","title":"Terminology"},"40":{"body":"Now that we've figured out the types we need, we can get to work writing some methods. We'll need to implement the methods defined in the calloop::EventSource trait, and a constructor function to create the source.","breadcrumbs":"A full example: ZeroMQ » Creating our source, part II: setup methods » Creating our source, part II: setup methods","id":"40","title":"Creating our source, part II: setup methods"},"41":{"body":"Creating our source is fairly straightforward. We can let the caller set up the zsocket the way they need, and take ownership of it when it's initialised. Our caller needs not only the source itself, but the sending end of the MPSC channel so they can send messages, so we need to return that too. A common pattern in Calloop's own constructor functions is to return a tuple containing (a) the source and (b) a type to use the source. So that's what we'll do: // Converts a `zmq::Socket` into a `ZeroMQSource` plus the sending end of an\n// MPSC channel to enqueue outgoing messages.\npub fn from_socket(socket: zmq::Socket) -> io::Result<(Self, calloop::channel::Sender)> { let (mpsc_sender, mpsc_receiver) = calloop::channel::channel(); let (wake_ping_sender, wake_ping_receiver) = calloop::ping::make_ping()?; let fd = socket.get_fd()?; let socket_source = calloop::generic::Generic::from_fd(fd, calloop::Interest::READ, calloop::Mode::Edge); Ok(( Self { socket, socket_source, mpsc_receiver, wake_ping_receiver, wake_ping_sender, }, mpsc_sender, ))\n}","breadcrumbs":"A full example: ZeroMQ » Creating our source, part II: setup methods » Our constructor","id":"41","title":"Our constructor"},"42":{"body":"Calloop's event sources have a kind of life cycle, starting with registration . When you add an event source to the event loop, under the hood the source will register itself with the loop. Under certain circumstances a source will need to re-register itself. And finally there is the unregister action when an event source is removed from the loop. These are expressed via the calloop::EventSource methods: fn register(&mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory) -> calloop::Result<()> fn reregister(&mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory) -> calloop::Result<()> fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> The first two methods take a token factory , which is a way for Calloop to keep track of why your source was woken up. When we get to actually processing events, you'll see how this works. But for now, all you need to do is recursively pass the token factory into whatever sources your own event source is composed of. This includes other composed sources, which will pass the token factory into their sources, and so on. In practise this looks like: fn register( &mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory\n) -> calloop::Result<()>\n{ self.socket_source.register(poll, token_factory)?; self.mpsc_receiver.register(poll, token_factory)?; self.wake_ping_receiver.register(poll, token_factory)?; self.wake_ping_sender.ping(); Ok(())\n} fn reregister( &mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory\n) -> calloop::Result<()>\n{ self.socket_source.reregister(poll, token_factory)?; self.mpsc_receiver.reregister(poll, token_factory)?; self.wake_ping_receiver.reregister(poll, token_factory)?; self.wake_ping_sender.ping(); Ok(())\n} fn unregister(&mut self, poll: &mut calloop::Poll)-> calloop::Result<()> { self.socket_source.unregister(poll)?; self.mpsc_receiver.unregister(poll)?; self.wake_ping_receiver.unregister(poll)?; Ok(())\n} Note the self.wake_ping_sender.ping() call in the first two functions! This is how we manually prompt the event loop to wake up and run our source on the next iteration, to properly account for the zsocket's edge-triggering .","breadcrumbs":"A full example: ZeroMQ » Creating our source, part II: setup methods » Trait methods: registering sources","id":"42","title":"Trait methods: registering sources"},"43":{"body":"ZeroMQ sockets have their own internal queues and state, and therefore need a bit of care when shutting down. Depending on zsocket type and settings, when the ZeroMQ context is dropped, it could block waiting for certain operations to complete. We can write a drop handler to avoid this, but again note that it's only one of many ways to handle zsocket shutdown. impl Drop for ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ fn drop(&mut self) { // This is one way to stop socket code (especially PUSH sockets) hanging // at the end of any blocking functions. // // - https://stackoverflow.com/a/38338578/188535 // - http://api.zeromq.org/4-0:zmq-ctx-term self.socket.set_linger(0).ok(); self.socket.set_rcvtimeo(0).ok(); self.socket.set_sndtimeo(0).ok(); // Double result because (a) possible failure on call and (b) possible // failure decoding. if let Ok(Ok(last_endpoint)) = self.socket.get_last_endpoint() { self.socket.disconnect(&last_endpoint).ok(); } }\n}","breadcrumbs":"A full example: ZeroMQ » Creating our source, part II: setup methods » Our drop handler","id":"43","title":"Our drop handler"},"44":{"body":"Finally, the real functionality we care about! Processing events! This is also a method in the calloop::EventSource trait: fn process_events( &mut self, readiness: calloop::Readiness, token: calloop::Token, mut callback: F,\n) -> Result\nwhere F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret, What a mouthful! But when you break it down, it's not so complicated: We take our own state, of course, as &mut self. We take a Readiness value - this is mainly useful for \"real\" file descriptors, and tells you whether the event source was woken up for a read or write event. We ignore it though, because our internal sources are always only readable (remember that even if the zsocket is writeable, the FD it exposes is only ever readable). We take a token. This gives us a way to process events that arise from our internal sources. In general, composed sources should not actually need to use this directly; sub-sources will check their own tokens against this and run if necessary. We take a callback. We call this callback with any \"real\" events that our caller will care about; in our case, that means messages we receive on the zsocket. It is closely related to the EventSource trait's associated types . Note that the callback our caller supplies when adding our source to the loop actually takes an extra argument, which is some data that we won't know about in our source. Calloop's internals take care of combining our arguments here with this extra data. Finally we return a PostAction, which tells the loop whether it needs to change the state of our event source, perhaps as a result of actions we took. For example, you might require that your source be removed from the loop (with PostAction::Remove) if it only has a certain thing to do. Ordinarily though, you'd return PostAction::Continue for your source to keep waiting for events. Note that these PostAction values correspond to various methods on the LoopHandle type (eg. PostAction::Disable does the same as LoopHandle::disable()). Whether you control your event source by returning a PostAction or using the LoopHandle methods depends on whether it makes more sense for these actions to be taken from within your event source or by something else in your code. Implementing process_events() for a type that contains various Calloop sources composed together, like we have, is done recursively by calling our internal sources' process_events() method. The token that Calloop gives us is how each event source determines whether it was responsible for the wakeup and has events to process. If we were woken up because of the ping source, then the ping source's process_events() will see that the token matches its own, and call the callback (possibly multiple times). If we were woken up because a message was sent through the MPSC channel, then the channel's process_events() will match on the token instead and call the callback for every message waiting. The zsocket is a little different, and we'll go over that in detail. For error handling we're using Anyhow , hence the context() calls on each fallible operation. These just add a message to any error that might appear in a traceback. So a first draft of our code might look like: fn process_events( &mut self, readiness: calloop::Readiness, token: calloop::Token, mut callback: F,\n) -> Result\nwhere F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,\n{ // Runs if we were woken up on startup/registration. self.wake_ping_receiver .process_events(readiness, token, |_, _| {}) .context(\"Failed after registration\")?; // Runs if we received a message over the MPSC channel. self.mpsc_receiver .process_events(readiness, token, |evt, _| { // 'evt' could be a message or a \"sending end closed\" // notification. We don't care about the latter. if let calloop::channel::Event::Msg(msg) = evt { self.socket .send_multipart(msg, 0) .context(\"Failed to send message\")?; } })?; // Runs if the zsocket became read/write-able. self.socket .process_events(readiness, token, |_, _| { let events = self.socket .get_events() .context(\"Failed to read ZeroMQ events\")?; if events.contains(zmq::POLLOUT) { // Wait, what do we do here? } if events.contains(zmq::POLLIN) { let messages = self.socket .recv_multipart(0) .context(\"Failed to receive message\")?; callback(messages, &mut ()) .context(\"Error in event callback\")?; } })?; Ok(calloop::PostAction::Continue)\n} We process the events from whichever source woke up our composed source, and if we woke up because the zsocket became readable, we call the callback with the message we received. Finally we return PostAction::Continue to remain in the event loop. Don't worry about getting this to compile, it is a good start but it's wrong in a few ways. Firstly, we've gone to all the trouble of using a ping to wake up the source, and then we just... drain its internal events and return. Which achieves nothing. Secondly, we don't seem to know what to do when our zsocket becomes writeable (the actual zsocket, not the \"interface\" file descriptor). Thirdly, we commit one of the worst sins you can commit in an event-loop-based system. Can you see it? It's this part: self.mpsc_receiver .process_events(readiness, token, |evt, _| { if let calloop::channel::Event::Msg(msg) = evt { self.socket .file .send_multipart(msg, 0) .context(\"Failed to send message\")?; } })?; We block the event loop! In the middle of processing events from the MPSC channel, we call zmq::Socket::send_multipart() which could , under certain circumstances, block! We shouldn't do that. Let's deal with this badness first then. We want to decouple \"receiving messages over the MPSC channel\" from \"sending messages on the zsocket\". There are different ways to do this, but they boil down to: buffer messages or drop messages (or maybe a combination of both). We'll use the first approach, with an internal FIFO queue. When we receive messages, we push them onto the back of the queue. When the zsocket is writeable, we pop messages from the front of the queue. The standard library has collections::VecDeque which provides efficient double-ended queuing, so let's use that. This is some extra internal state, so we need to add it to our type, which becomes: pub struct ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ // Calloop components. socket: calloop::generic::Generic>, mpsc_receiver: calloop::channel::Channel, wake_ping_receiver: calloop::ping::PingSource, /// Sending end of the ping source. wake_ping_sender: calloop::ping::Ping, /// FIFO queue for the messages to be published. outbox: std::collections::VecDeque,\n} Our MPSC receiving code becomes: let outbox = &mut self.outbox; self.mpsc_receiver .process_events(readiness, token, |evt, _| { if let calloop::channel::Event::Msg(msg) = evt { outbox.push_back(msg); } })?; And our \"zsocket is writeable\" code becomes: self.socket .file .process_events(readiness, token, |_, _| { let events = self .socket .file .get_events() .context(\"Failed to read ZeroMQ events\")?; if events.contains(zmq::POLLOUT) { if let Some(parts) = self.outbox.pop_front() { self.socket .file .send_multipart(parts, 0) .context(\"Failed to send message\")?; } } if events.contains(zmq::POLLIN) { let messages = self.socket .file .recv_multipart(0) .context(\"Failed to receive message\")?; callback(messages, &mut ()) .context(\"Error in event callback\")?; } })?; So we've not only solved problem #3, we've also figured out #2, which suggests we're on the right track. But we still have (at least) that first issue to sort out.","breadcrumbs":"A full example: ZeroMQ » Creating our source, part III: processing events (almost) » Creating our source, part III: processing events (almost)","id":"44","title":"Creating our source, part III: processing events (almost)"},"45":{"body":"We have three events that could wake up our event source: the ping, the channel, and the zsocket itself becoming ready to use. All three of these reasons potentially mean doing something on the zsocket: if the ping fired, we need to check for any pending events. If the channel received a message, we want to check if the zsocket is already readable and send it. If the zsocket becomes readable or writeable, we want to read from or write to it. In other words... We want to run it every time! Also notice that in the zsocket process_events() call, we don't use any of the arguments, including the event itself. That file descriptor is merely a signalling mechanism! Sending and receiving messages is what will actually clear any pending events on it, and reset it to a state where it will wake the event loop later. let events = self .socket .get_events() .context(\"Failed to read ZeroMQ events\")?; if events.contains(zmq::POLLOUT) { if let Some(parts) = self.outbox.pop_front() { self.socket .send_multipart(parts, 0) .context(\"Failed to send message\")?; }\n} if events.contains(zmq::POLLIN) { let messages = self.socket .recv_multipart(0) .context(\"Failed to receive message\")?; callback(messages, &mut ()) .context(\"Error in event callback\")?;\n} So the second draft of our process_events() function is now: fn process_events( &mut self, readiness: calloop::Readiness, token: calloop::Token, mut callback: F,\n) -> Result\nwhere F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret,\n{ // Runs if we were woken up on startup/registration. self.wake_ping_receiver .process_events(readiness, token, |_, _| {})?; // Runs if we were woken up because a message was sent on the channel. let outbox = &mut self.outbox; self.mpsc_receiver .process_events(readiness, token, |evt, _| { if let calloop::channel::Event::Msg(msg) = evt { outbox.push_back(msg); } })?; // Always process any pending zsocket events. let events = self .socket .get_events() .context(\"Failed to read ZeroMQ events\")?; if events.contains(zmq::POLLOUT) { if let Some(parts) = self.outbox.pop_front() { self.socket .send_multipart(parts, 0) .context(\"Failed to send message\")?; } } if events.contains(zmq::POLLIN) { let messages = self.socket .recv_multipart(0) .context(\"Failed to receive message\")?; callback(messages, &mut ()) .context(\"Error in event callback\")?; } Ok(calloop::PostAction::Continue)\n} There is one more issue to take care of, and it's got nothing to do with Calloop. We still haven't fully dealt with ZeroMQ's edge-triggered nature. Consider this situation: We create a REQ zsocket. These are intended to be used in strict send/receive/send/receive/etc. sequence. We wrap it in our ZeroMQSource and add that to our loop. We send a message. If we do this, it's possible we'll never actually receive any replies that are sent to our zsocket! Why? Because: we read the events on the socket into events then we send a message on the socket another process sends a reply so quickly, it arrives more or less immediately then we use the same events to check if the socket is readable then we exit The zsocket will change from writeable to readable before we leave process_events(). So the \"interface\" file descriptor will become readable again. But because it is edge triggered, it will not wake up our event source after we leave process_events(). So our source will not wake up again (at least, not due to the self.socket event source). For this specific example , it will suffice to re-read the zsocket events in between the if statements. Then when we get to the second events check, it will indeed contain zmq::POLLIN and receive the pending message. But this is not good enough for the general case! If we replace REQ with REP above, we'll get the opposite problem: our first check (for POLLOUT) will be false. Our second check (POLLIN) will be true. We'll receive a message, leave process_events(), and never wake up again. The full solution is to recognise that any user action on a ZeroMQ socket can cause the pending events to change, or just to remain active, without re-triggering the \"interface\" file descriptor. So we need to (a) do this repeatedly and (b) keep track of when we have or haven't performed an action on the zsocket. Here's one way to do it: loop { let events = self .socket .get_events() .context(\"Failed to read ZeroMQ events\")?; let mut used_socket = false; if events.contains(zmq::POLLOUT) { if let Some(parts) = self.outbox.pop_front() { self.socket .as_ref() .send_multipart(parts, 0) .context(\"Failed to send message\")?; used_socket = true; } } if events.contains(zmq::POLLIN) { let messages = self.socket .recv_multipart(0) .context(\"Failed to receive message\")?; used_socket = true; callback(messages, &mut ()) .context(\"Error in event callback\")?; } if !used_socket { break; }\n} Now we have a flag that we set if, and only if, we call a send or receive method on the zsocket. If that flag is set at the end of the loop, we go around again.","breadcrumbs":"A full example: ZeroMQ » Creating our source, part IV: processing events (really) » Creating our source, part IV: processing events (really)","id":"45","title":"Creating our source, part IV: processing events (really)"},"46":{"body":"Remember my disclaimer at the start of the chapter, about this code being \"greedy\"? This is what I mean. This loop will run until the entire message queue is empty, so if it has a lot of messages in it, any other sources in our event loop will not be run until this loop is finished. An alternative approach is to use more state to determine whether we want to run again on the next loop iteration (perhaps using the ping source), so that Calloop can run any other sources in between individual messages being received.","breadcrumbs":"A full example: ZeroMQ » Creating our source, part IV: processing events (really) » Greediness","id":"46","title":"Greediness"},"47":{"body":"This is the full source code for a Calloop event source based on a ZeroMQ socket. You might find it useful as a kind of reference. Please read the disclaimer at the start of this chapter if you skipped straight here! //! A Calloop event source implementation for ZeroMQ sockets. use std::{collections, io}; use anyhow::Context; /// A Calloop event source that contains a ZeroMQ socket (of any kind) and a\n/// Calloop MPSC channel for sending over it.\n///\n/// The basic interface is:\n/// - create a zmq::Socket for your ZeroMQ socket\n/// - use `ZeroMQSource::from_socket()` to turn it into a Calloop event source\n/// (plus the sending end of the channel)\n/// - queue messages to be sent by sending them on the sending end of the MPSC\n/// channel\n/// - add the event source to the Calloop event loop with a callback to handle\n/// reading\n/// - the sending end of the MPSC channel can be cloned and sent across threads\n/// if necessary\n///\n/// This type is parameterised by `T`:\n///\n/// T where T: IntoIterator, T::Item: Into\n//\n/// This means that `T` is anything that can be converted to an iterator, and\n/// the items in the iterator are anything that can be converted to a\n/// `zmq::Message`. So eg. a `Vec` would work.\n///\n/// The callback is called whenever the underlying socket becomes readable. It\n/// is called with a vec of byte sequences (`Vec>`) and the event loop\n/// data set by the user.\n///\n/// Note about why the read data is a vec of multipart message parts: we don't\n/// know what kind of socket this is, or what will be sent, so the most general\n/// thing we can do is receive the entirety of a multipart message and call the\n/// user callback with the whole set. Usually the number of parts in a multipart\n/// message will be one, but the code will work just the same when it's not.\n///\n/// This event source also allows you to use different event sources to publish\n/// messages over the same writeable ZeroMQ socket (usually PUB or PUSH).\n/// Messages should be sent over the Calloop MPSC channel sending end. This end\n/// can be cloned and used by multiple senders. pub struct ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ // Calloop components. /// Event source for ZeroMQ socket. socket: calloop::generic::Generic>, /// Event source for channel. mpsc_receiver: calloop::channel::Channel, /// Because the ZeroMQ socket is edge triggered, we need a way to \"wake\" the /// event source upon (re-)registration. We do this with a separate /// `calloop::ping::Ping` source. wake_ping_receiver: calloop::ping::PingSource, /// Sending end of the ping source. wake_ping_sender: calloop::ping::Ping, // ZeroMQ socket. /// FIFO queue for the messages to be published. outbox: collections::VecDeque,\n} impl ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ // Converts a `zmq::Socket` into a `ZeroMQSource` plus the sending end of an // MPSC channel to enqueue outgoing messages. pub fn from_socket(socket: zmq::Socket) -> io::Result<(Self, calloop::channel::Sender)> { let (mpsc_sender, mpsc_receiver) = calloop::channel::channel(); let (wake_ping_sender, wake_ping_receiver) = calloop::ping::make_ping()?; let socket = calloop::generic::Generic::new( unsafe { calloop::generic::FdWrapper::new(socket) }, calloop::Interest::READ, calloop::Mode::Edge, ); Ok(( Self { socket, mpsc_receiver, wake_ping_receiver, wake_ping_sender, outbox: collections::VecDeque::new(), }, mpsc_sender, )) }\n} /// This event source runs for three events:\n///\n/// 1. The event source was registered. It is forced to run so that any pending\n/// events on the socket are processed.\n///\n/// 2. A message was sent over the MPSC channel. In this case we put it in the\n/// internal queue.\n///\n/// 3. The ZeroMQ socket is readable. For this, we read off a complete multipart\n/// message and call the user callback with it.\n///\n/// The callback provided to `process_events()` may be called multiple times\n/// within a single call to `process_events()`.\nimpl calloop::EventSource for ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ type Event = Vec>; type Metadata = (); type Ret = io::Result<()>; type Error = anyhow::Error; fn process_events( &mut self, readiness: calloop::Readiness, token: calloop::Token, mut callback: F, ) -> Result where F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret, { // Runs if we were woken up on startup/registration. self.wake_ping_receiver .process_events(readiness, token, |_, _| {}) .context(\"Failed after registration\")?; // Runs if we were woken up because a message was sent on the channel. let outbox = &mut self.outbox; self.mpsc_receiver .process_events(readiness, token, |evt, _| { if let calloop::channel::Event::Msg(msg) = evt { outbox.push_back(msg); } }) .context(\"Failed to processing outgoing messages\")?; // The ZeroMQ file descriptor is edge triggered. This means that if (a) // messages are added to the queue before registration, or (b) the // socket became writeable before messages were enqueued, we will need // to run the loop below. Hence, it always runs if this event source // fires. The process_events() method doesn't do anything though, so we // ignore it. loop { // According to the docs, the edge-triggered FD will not change // state if a socket goes directly from being readable to being // writeable (or vice-versa) without there being an in-between point // where there are no events. This can happen as a result of sending // or receiving on the socket while processing such an event. The // \"used_socket\" flag below tracks whether we perform an operation // on the socket that warrants reading the events again. let events = self .socket .get_ref() .get_events() .context(\"Failed to read ZeroMQ events\")?; let mut used_socket = false; if events.contains(zmq::POLLOUT) { if let Some(parts) = self.outbox.pop_front() { self.socket .get_ref() .send_multipart(parts, 0) .context(\"Failed to send message\")?; used_socket = true; } } if events.contains(zmq::POLLIN) { // Batch up multipart messages. ZeroMQ guarantees atomic message // sending, which includes all parts of a multipart message. let messages = self .socket .get_ref() .recv_multipart(0) .context(\"Failed to receive message\")?; used_socket = true; // Capture and report errors from the callback, but don't propagate // them up. callback(messages, &mut ()).context(\"Error in event callback\")?; } if !used_socket { break; } } Ok(calloop::PostAction::Continue) } fn register( &mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory, ) -> calloop::Result<()> { self.socket.register(poll, token_factory)?; self.mpsc_receiver.register(poll, token_factory)?; self.wake_ping_receiver.register(poll, token_factory)?; self.wake_ping_sender.ping(); Ok(()) } fn reregister( &mut self, poll: &mut calloop::Poll, token_factory: &mut calloop::TokenFactory, ) -> calloop::Result<()> { self.socket.reregister(poll, token_factory)?; self.mpsc_receiver.reregister(poll, token_factory)?; self.wake_ping_receiver.reregister(poll, token_factory)?; self.wake_ping_sender.ping(); Ok(()) } fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> { self.socket.unregister(poll)?; self.mpsc_receiver.unregister(poll)?; self.wake_ping_receiver.unregister(poll)?; Ok(()) }\n} impl Drop for ZeroMQSource\nwhere T: IntoIterator, T::Item: Into,\n{ fn drop(&mut self) { // This is one way to stop socket code (especially PUSH sockets) hanging // at the end of any blocking functions. // // - https://stackoverflow.com/a/38338578/188535 // - http://api.zeromq.org/4-0:zmq-ctx-term self.socket.get_ref().set_linger(0).ok(); self.socket.get_ref().set_rcvtimeo(0).ok(); self.socket.get_ref().set_sndtimeo(0).ok(); // Double result because (a) possible failure on call and (b) possible // failure decoding. if let Ok(Ok(last_endpoint)) = self.socket.get_ref().get_last_endpoint() { self.socket.get_ref().disconnect(&last_endpoint).ok(); } }\n} pub fn main() {} Dependencies are: calloop (whatever version this document was built from) zmq 0.9 anyhow 1.0 [dependencies]\ncalloop = { path = '../..' }\nzmq = \"0.9\"\nanyhow = \"1.0\"","breadcrumbs":"A full example: ZeroMQ » The full ZeroMQ event source code » The full ZeroMQ event source code","id":"47","title":"The full ZeroMQ event source code"},"5":{"body":"An event loop like Calloop, as the name suggests, runs in a loop. At the start of the loop, Calloop checks all the sources you've added to see if any events have happened for those sources. If they have, Calloop will call a function that you provide (known as a callback ). This function will (possibly) be given some data for the event itself (eg. the bytes received), some state for the event source (eg. the socket, or a type that wraps it in a neater API), and some state for the whole program. Calloop will do this one by one for each source that has a new event. If a file is ready for reading, your file-event-source callback will be called. If a timer has elapsed, your timer-event-source callback will be called. It is up to you to write the code to do things when events happen. For example, your callback might read data from a file \"ready for reading\" event into a queue. When the queue contains a valid message, the same callback could send that message over an internal channel to another event source. That second event source could have its own callback that processes entire messages and updates the program's state. And so on.","breadcrumbs":"How an event loop works » Events and callbacks","id":"5","title":"Events and callbacks"},"6":{"body":"This \"one by one\" nature of event loops is important. When you approach concurrency using threads, operations in any thread can be interleaved with operations in any other thread. This is typically made robust by either passing messages or using shared memory with synchronisation. Callbacks in an event loop do not run in parallel, they run one after the other. Unless you (or your dependencies) have introduced threading, you can (and should) write your callbacks as single-threaded code.","breadcrumbs":"How an event loop works » Concurrency vs parallelism","id":"6","title":"Concurrency vs parallelism"},"7":{"body":"This single-threaded nature makes event loops much more similar to code that uses async/await than to multithreaded code. There are benefits and tradeoffs to either approach. Calloop will take care of a lot of integration and error handling boilerplate for you. It also makes it clearer what parts of your code are the non-blocking actions to perform as a result of events. If you like to think of your program in terms of taking action in reaction to events, this can be a great advantage! However, this comes at the expense of needing to make your program's state much more explicit. For example, take this async code: do_thing_one().await;\ndo_thing_two().await;\ndo_thing_three().await; The state of the program is simply given by: what line is it up to? You know if it's done \"thing one\" because execution has proceeded to line two. No other state is required. In Calloop, however, you will need extra variables and code so that when your callback is called, it knows whether to run do_thing_one(), do_thing_two(), or do_thing_three().","breadcrumbs":"How an event loop works » Event loops vs async code","id":"7","title":"Event loops vs async code"},"8":{"body":"All of this leads us to the most important rule of event loop code: never block the loop! This means: never use blocking calls inside one of your event callbacks. Do not use synchronous file write() calls in a callback. Do not sleep() in a callback. Do not join() a thread in a callback. Don't you do it! If you do, the event loop will have no way to proceed, and just... wait for your blocking operation to complete. Nothing is going to run in a parallel thread. Nothing is going to stop your callback and move on to the next one. If your callback needs to wait for a blocking operation, your code must allow it to keep track of where it's up to, return from the callback, and wait for the event like any other.","breadcrumbs":"How an event loop works » Never block the loop!","id":"8","title":"Never block the loop!"},"9":{"body":"Calloop is designed to work by composition . This means that you build up more complex logic in your program by combining simpler event sources into more complex ones. Want a network socket with custom backoff/timeout logic? Create a type containing a network socket using the Generic file descriptor adapter , a timer , and tie them together with your backoff logic and state. There is a much more detailed example of composition in our ZeroMQ example .","breadcrumbs":"How an event loop works » Calloop and composition","id":"9","title":"Calloop and composition"}},"length":48,"save":true},"fields":["title","body","breadcrumbs"],"index":{"body":{"root":{"0":{".":{"3":{"df":1,"docs":{"26":{"tf":2.0}}},"9":{"df":1,"docs":{"47":{"tf":1.4142135623730951}}},"df":0,"docs":{}},":":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":3,"docs":{"44":{"tf":1.7320508075688772},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}},"u":{"8":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}},"1":{".":{"0":{"df":1,"docs":{"47":{"tf":1.4142135623730951}}},"6":{"3":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":3,"docs":{"2":{"tf":1.0},"38":{"tf":1.0},"47":{"tf":1.0}}},"2":{"0":{"2":{"1":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"2":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"3":{"df":4,"docs":{"15":{"tf":1.4142135623730951},"2":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"4":{"df":1,"docs":{"2":{"tf":1.0}}},"5":{"df":1,"docs":{"14":{"tf":1.0}}},"_":{"df":8,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"44":{"tf":3.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.7320508075688772}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"d":{"_":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}},"df":0,"docs":{}}}},"a":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"28":{"tf":1.0}}}},"o":{"df":0,"docs":{},"v":{"df":2,"docs":{"31":{"tf":1.0},"45":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"11":{"tf":1.0},"30":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"37":{"tf":1.4142135623730951}}}}},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"r":{"d":{"df":1,"docs":{"47":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":6,"docs":{"14":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951}}}},"v":{"df":1,"docs":{"45":{"tf":1.0}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":6,"docs":{"35":{"tf":1.4142135623730951},"36":{"tf":1.0},"38":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"d":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":5,"docs":{"13":{"tf":1.0},"24":{"tf":1.7320508075688772},"28":{"tf":1.0},"31":{"tf":1.0},"9":{"tf":1.0}}}}},"d":{"df":7,"docs":{"28":{"tf":1.0},"35":{"tf":1.4142135623730951},"39":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"31":{"tf":1.4142135623730951}}}}}}},"df":5,"docs":{"15":{"tf":1.4142135623730951},"29":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0}},"v":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"7":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"15":{"tf":2.23606797749979},"35":{"tf":1.0},"43":{"tf":1.0},"45":{"tf":2.0},"46":{"tf":1.0},"47":{"tf":1.0}},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{},"w":{"df":3,"docs":{"39":{"tf":1.4142135623730951},"47":{"tf":1.0},"8":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"10":{"tf":1.0}}}},"o":{"df":0,"docs":{},"f":{"df":1,"docs":{"26":{"tf":1.7320508075688772}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":3,"docs":{"22":{"tf":1.0},"35":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"46":{"tf":1.0}}}}}},"w":{"a":{"df":0,"docs":{},"y":{"df":4,"docs":{"32":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"15":{"tf":1.0},"4":{"tf":1.0}}}}}}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":6,"docs":{"23":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.4142135623730951},"39":{"tf":1.0},"45":{"tf":1.0},"5":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}}}}}},"y":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"'":{"df":1,"docs":{"23":{"tf":1.0}}},":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"23":{"tf":1.0},"39":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":3,"docs":{"39":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}},"t":{"df":0,"docs":{},"h":{"df":3,"docs":{"28":{"tf":1.0},"4":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}}}}},"p":{"df":0,"docs":{},"i":{"df":4,"docs":{"1":{"tf":1.4142135623730951},"22":{"tf":1.4142135623730951},"38":{"tf":1.4142135623730951},"5":{"tf":1.0}}},"p":{"df":1,"docs":{"15":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"i":{"c":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"'":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}}}}},"df":1,"docs":{"31":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"o":{"a":{"c":{"df":0,"docs":{},"h":{"df":4,"docs":{"44":{"tf":1.0},"46":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"11":{"tf":1.0}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"15":{"tf":1.4142135623730951},"26":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0}}}}},"u":{"df":1,"docs":{"15":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":6,"docs":{"10":{"tf":1.0},"11":{"tf":1.4142135623730951},"27":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"45":{"tf":1.0}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"df":0,"docs":{},"f":{"d":{"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"28":{"tf":1.0}},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":1,"docs":{"13":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"r":{"a":{"df":0,"docs":{},"w":{"df":0,"docs":{},"f":{"d":{"df":2,"docs":{"11":{"tf":1.0},"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"i":{"df":4,"docs":{"12":{"tf":1.0},"23":{"tf":1.7320508075688772},"39":{"tf":1.7320508075688772},"44":{"tf":1.0}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"n":{"c":{"/":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":3,"docs":{"2":{"tf":1.0},"24":{"tf":1.0},"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}}}},"df":7,"docs":{"24":{"tf":1.4142135623730951},"25":{"tf":1.0},"26":{"tf":5.744562646538029},"27":{"tf":1.7320508075688772},"28":{"tf":2.449489742783178},"29":{"tf":7.483314773547883},"7":{"tf":1.4142135623730951}},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"23":{"tf":1.0},"3":{"tf":1.0}}}}}},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}}}}}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":3,"docs":{"30":{"tf":1.0},"35":{"tf":1.0},"47":{"tf":1.0}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":4,"docs":{"1":{"tf":1.0},"11":{"tf":1.0},"13":{"tf":1.0},"4":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"13":{"tf":1.0},"43":{"tf":1.0}}},"df":0,"docs":{}}}},"w":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"27":{"tf":1.0}}},"y":{"df":1,"docs":{"32":{"tf":1.0}}}},"df":0,"docs":{}}},"b":{"a":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"31":{"tf":1.0},"44":{"tf":1.0}},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{}}}}}},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"/":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}},"df":1,"docs":{"9":{"tf":1.0}}}}}}},"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":8,"docs":{"10":{"tf":1.0},"11":{"tf":1.4142135623730951},"23":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"i":{"c":{"df":2,"docs":{"30":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}}},"df":4,"docs":{"41":{"tf":1.0},"43":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951}},"e":{"c":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":8,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"18":{"tf":1.0},"22":{"tf":1.0},"35":{"tf":1.7320508075688772},"44":{"tf":2.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}},"df":5,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"38":{"tf":1.0},"46":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"23":{"tf":1.0},"26":{"tf":1.0},"31":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}},"h":{"a":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":2,"docs":{"26":{"tf":2.0},"47":{"tf":1.4142135623730951}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":5,"docs":{"30":{"tf":1.0},"32":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"df":0,"docs":{},"t":{"df":4,"docs":{"32":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.0},"43":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":10,"docs":{"26":{"tf":5.291502622129181},"28":{"tf":2.23606797749979},"29":{"tf":5.5677643628300215},"3":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951},"43":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951},"47":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":2.23606797749979}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"2":{"tf":1.0}}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"13":{"tf":1.0}},"e":{"d":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"13":{"tf":2.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"t":{"df":0,"docs":{},"h":{"df":5,"docs":{"12":{"tf":1.0},"22":{"tf":1.4142135623730951},"26":{"tf":1.0},"29":{"tf":1.0},"44":{"tf":1.0}}}},"x":{"<":{"d":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"df":2,"docs":{"23":{"tf":1.4142135623730951},"39":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"k":{"df":4,"docs":{"15":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"f":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"29":{"tf":2.6457513110645907}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"l":{"d":{"df":4,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"30":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.0},"31":{"tf":1.0},"47":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"df":1,"docs":{"18":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"e":{"df":1,"docs":{"26":{"tf":2.23606797749979}}},"t":{"df":0,"docs":{},"e":{"df":2,"docs":{"47":{"tf":1.0},"5":{"tf":1.0}}}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"28":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}},"df":15,"docs":{"11":{"tf":1.0},"15":{"tf":2.8284271247461903},"22":{"tf":1.4142135623730951},"23":{"tf":1.4142135623730951},"24":{"tf":1.0},"26":{"tf":1.4142135623730951},"30":{"tf":1.0},"39":{"tf":2.0},"44":{"tf":3.1622776601683795},"45":{"tf":2.0},"47":{"tf":2.8284271247461903},"5":{"tf":2.6457513110645907},"6":{"tf":1.4142135623730951},"7":{"tf":1.0},"8":{"tf":2.6457513110645907}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":16,"docs":{"18":{"tf":1.4142135623730951},"22":{"tf":1.0},"23":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"35":{"tf":1.7320508075688772},"39":{"tf":1.0},"4":{"tf":1.4142135623730951},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.6457513110645907},"45":{"tf":1.4142135623730951},"47":{"tf":2.6457513110645907},"5":{"tf":1.7320508075688772},"7":{"tf":1.0},"8":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"23":{"tf":1.4142135623730951},"31":{"tf":1.0},"39":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"'":{"df":12,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"10":{"tf":1.0},"17":{"tf":1.0},"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.4142135623730951},"30":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0}}},":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"<":{"df":0,"docs":{},"t":{"df":3,"docs":{"37":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}},"df":5,"docs":{"23":{"tf":1.0},"34":{"tf":1.0},"36":{"tf":1.7320508075688772},"41":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":3,"docs":{"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"<":{"df":0,"docs":{},"t":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":5,"docs":{"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}}}}}}},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"26":{"tf":1.4142135623730951},"29":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"26":{"tf":2.23606797749979},"29":{"tf":2.8284271247461903}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"c":{":":{":":{"df":0,"docs":{},"f":{"d":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"33":{"tf":1.0},"36":{"tf":1.0}},"i":{"c":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"f":{"d":{"(":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"<":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"c":{":":{":":{"df":0,"docs":{},"f":{"d":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"<":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"o":{"df":1,"docs":{"29":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{":":{":":{"a":{"d":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":1,"docs":{"29":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"m":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"g":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{":":{":":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"p":{"df":3,"docs":{"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.4142135623730951}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":4,"docs":{"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":2.449489742783178},"47":{"tf":1.7320508075688772}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":2.449489742783178},"47":{"tf":1.7320508075688772}}}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"42":{"tf":2.0},"47":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":26,"docs":{"10":{"tf":1.0},"11":{"tf":1.7320508075688772},"14":{"tf":1.0},"15":{"tf":1.4142135623730951},"16":{"tf":1.0},"2":{"tf":2.23606797749979},"21":{"tf":1.0},"22":{"tf":1.4142135623730951},"24":{"tf":1.4142135623730951},"26":{"tf":1.0},"27":{"tf":1.4142135623730951},"28":{"tf":1.7320508075688772},"3":{"tf":1.0},"31":{"tf":1.4142135623730951},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"34":{"tf":1.0},"36":{"tf":1.4142135623730951},"42":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":3.1622776601683795},"5":{"tf":2.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}}}}},"n":{"'":{"df":0,"docs":{},"t":{"df":2,"docs":{"23":{"tf":1.0},"30":{"tf":1.0}}}},"d":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"37":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"p":{"a":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"10":{"tf":1.0},"37":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":7,"docs":{"30":{"tf":1.0},"32":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.0},"7":{"tf":1.0}},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}},"g":{"df":0,"docs":{},"o":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"18":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":7,"docs":{"31":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"39":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"23":{"tf":1.0}}}}}}}},"u":{"df":0,"docs":{},"s":{"df":3,"docs":{"15":{"tf":1.0},"31":{"tf":1.0},"45":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":3.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"24":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"14":{"tf":1.0},"4":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"31":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":4,"docs":{"35":{"tf":2.23606797749979},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"'":{"df":1,"docs":{"44":{"tf":1.0}}},"df":12,"docs":{"17":{"tf":1.4142135623730951},"19":{"tf":1.0},"23":{"tf":1.4142135623730951},"26":{"tf":2.8284271247461903},"32":{"tf":1.0},"34":{"tf":1.4142135623730951},"36":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":2.0},"45":{"tf":1.7320508075688772},"47":{"tf":3.0},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}}}}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"2":{"tf":2.0},"3":{"tf":1.0},"30":{"tf":1.4142135623730951},"31":{"tf":1.0},"36":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"k":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":2.449489742783178},"5":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"28":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":3,"docs":{"35":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"45":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"7":{"tf":1.0}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":1,"docs":{"47":{"tf":1.4142135623730951}}}},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"23":{"tf":1.0},"44":{"tf":1.4142135623730951}}},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}}}}},"o":{"d":{"df":0,"docs":{},"e":{"df":16,"docs":{"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"25":{"tf":1.0},"26":{"tf":3.0},"28":{"tf":2.0},"29":{"tf":2.23606797749979},"3":{"tf":1.4142135623730951},"31":{"tf":2.0},"43":{"tf":1.0},"44":{"tf":2.0},"46":{"tf":1.0},"47":{"tf":2.0},"5":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":2.449489742783178},"8":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"c":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"<":{"df":0,"docs":{},"t":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"m":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"15":{"tf":1.0},"2":{"tf":1.0},"32":{"tf":1.0},"44":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":2,"docs":{"24":{"tf":1.0},"7":{"tf":1.0}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"22":{"tf":1.0},"33":{"tf":1.0},"41":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":6,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"27":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.0},"8":{"tf":1.0}}},"x":{"df":4,"docs":{"22":{"tf":1.0},"30":{"tf":2.0},"32":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}},"i":{"c":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"26":{"tf":1.0},"29":{"tf":1.0},"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}}},"s":{"df":4,"docs":{"32":{"tf":1.4142135623730951},"36":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"32":{"tf":1.4142135623730951},"9":{"tf":1.7320508075688772}}}}}},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}}}},"n":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"22":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":2,"docs":{"3":{"tf":1.4142135623730951},"6":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"31":{"tf":1.0},"45":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"27":{"tf":1.0}}}}}},"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"12":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}}},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":9,"docs":{"23":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"41":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"\"":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}}}},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"44":{"tf":2.8284271247461903},"45":{"tf":3.0},"47":{"tf":2.23606797749979}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":4,"docs":{"10":{"tf":1.0},"39":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":1,"docs":{"18":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":4,"docs":{"12":{"tf":1.0},"30":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":1,"docs":{"22":{"tf":1.4142135623730951}}},"t":{"df":4,"docs":{"23":{"tf":1.0},"29":{"tf":1.0},"41":{"tf":1.0},"47":{"tf":1.7320508075688772}}}},"y":{"df":1,"docs":{"35":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":4,"docs":{"13":{"tf":1.0},"26":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"u":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"r":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"3":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"4":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"22":{"tf":1.0},"27":{"tf":1.0}},"s":{"/":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"/":{"d":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":18,"docs":{"11":{"tf":1.0},"12":{"tf":1.4142135623730951},"14":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"4":{"tf":1.0},"40":{"tf":1.4142135623730951},"41":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.8284271247461903}}}},"x":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":2,"docs":{"2":{"tf":1.0},"9":{"tf":1.0}}}}}}},"y":{"c":{"df":0,"docs":{},"l":{"df":2,"docs":{"4":{"tf":1.0},"42":{"tf":1.0}}}},"df":0,"docs":{}}},"d":{"a":{"df":0,"docs":{},"t":{"a":{".":{".":{".":{"\"":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":9,"docs":{"15":{"tf":1.4142135623730951},"29":{"tf":1.0},"30":{"tf":1.7320508075688772},"35":{"tf":1.0},"39":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"5":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"14":{"tf":1.7320508075688772},"15":{"tf":1.7320508075688772},"16":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"l":{"df":3,"docs":{"22":{"tf":1.0},"31":{"tf":1.0},"44":{"tf":1.0}},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}},"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":1,"docs":{"35":{"tf":1.0}}}}},"c":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"23":{"tf":1.0}}},"df":0,"docs":{},"s":{"df":1,"docs":{"31":{"tf":1.0}}}},"o":{"d":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"39":{"tf":1.0},"40":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":5,"docs":{"31":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951},"6":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{".":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"s":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":13,"docs":{"11":{"tf":1.4142135623730951},"12":{"tf":1.0},"13":{"tf":1.0},"23":{"tf":1.0},"30":{"tf":1.4142135623730951},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"35":{"tf":1.4142135623730951},"39":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":3,"docs":{"28":{"tf":1.0},"32":{"tf":1.0},"9":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"y":{"df":1,"docs":{"15":{"tf":1.0}}}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":7,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"32":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"36":{"tf":1.0}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"44":{"tf":1.0},"46":{"tf":1.0}}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":1,"docs":{"1":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":6,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"s":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"31":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"(":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"11":{"tf":1.0}}}}}}},"o":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"7":{"tf":1.0}},"e":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"7":{"tf":1.0}},"e":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"w":{"df":0,"docs":{},"o":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"7":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"c":{"df":3,"docs":{"1":{"tf":1.0},"35":{"tf":1.4142135623730951},"47":{"tf":1.0}},"s":{".":{"df":0,"docs":{},"r":{"df":1,"docs":{"1":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":2,"docs":{"22":{"tf":1.0},"45":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":3,"docs":{"35":{"tf":1.0},"4":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":3.872983346207417}}}}},"df":0,"docs":{}},"n":{"'":{"df":0,"docs":{},"t":{"df":9,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0},"36":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"8":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":3,"docs":{"30":{"tf":1.0},"44":{"tf":1.0},"7":{"tf":1.0}}}},"u":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"df":0,"docs":{},"n":{"df":3,"docs":{"15":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951}}}}},"r":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":2,"docs":{"44":{"tf":1.0},"45":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":6,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.4142135623730951},"43":{"tf":2.0},"44":{"tf":1.0},"47":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"e":{"df":2,"docs":{"15":{"tf":1.0},"45":{"tf":1.0}}},"r":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"14":{"tf":1.0},"15":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"e":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":2,"docs":{"44":{"tf":1.4142135623730951},"5":{"tf":1.0}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"12":{"tf":1.0}}}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"2":{"tf":1.0},"24":{"tf":1.0}}}}}}}}}},"d":{"df":0,"docs":{},"g":{"df":5,"docs":{"12":{"tf":1.0},"35":{"tf":1.7320508075688772},"42":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"38":{"tf":1.0}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"18":{"tf":1.0},"26":{"tf":1.0}}}},"df":0,"docs":{}},"i":{"c":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"44":{"tf":1.0}}}},"df":0,"docs":{}}}},"g":{"df":7,"docs":{"23":{"tf":1.4142135623730951},"27":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}},"l":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"df":2,"docs":{"4":{"tf":1.0},"5":{"tf":1.0}}}}},"df":0,"docs":{}},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"46":{"tf":1.0}}}}}},"n":{"a":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":1.4142135623730951},"29":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"11":{"tf":1.0},"4":{"tf":1.0}}}}}}},"d":{"df":12,"docs":{"18":{"tf":1.7320508075688772},"23":{"tf":1.4142135623730951},"26":{"tf":3.4641016151377544},"29":{"tf":4.0},"31":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"41":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":2.8284271247461903}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"38":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":4,"docs":{"10":{"tf":1.0},"35":{"tf":1.0},"46":{"tf":1.0},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}},"u":{"df":0,"docs":{},"m":{"df":2,"docs":{"15":{"tf":1.0},"23":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":12,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":3.3166247903554},"23":{"tf":3.4641016151377544},"31":{"tf":1.7320508075688772},"35":{"tf":1.0},"39":{"tf":2.449489742783178},"4":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"7":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"t":{"c":{"df":2,"docs":{"13":{"tf":1.0},"4":{"tf":1.0}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":7,"docs":{"15":{"tf":1.0},"18":{"tf":1.0},"32":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":1.0},"44":{"tf":1.0}},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{".":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"(":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}}},"df":5,"docs":{"14":{"tf":1.7320508075688772},"15":{"tf":1.7320508075688772},"16":{"tf":1.7320508075688772},"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}}},"df":35,"docs":{"10":{"tf":2.449489742783178},"11":{"tf":2.8284271247461903},"12":{"tf":1.7320508075688772},"14":{"tf":2.23606797749979},"15":{"tf":2.8284271247461903},"16":{"tf":1.7320508075688772},"17":{"tf":2.8284271247461903},"18":{"tf":2.6457513110645907},"2":{"tf":1.7320508075688772},"22":{"tf":1.0},"23":{"tf":3.0},"24":{"tf":1.0},"26":{"tf":4.0},"28":{"tf":1.4142135623730951},"29":{"tf":5.477225575051661},"3":{"tf":1.4142135623730951},"30":{"tf":2.0},"31":{"tf":1.7320508075688772},"32":{"tf":2.449489742783178},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":3.3166247903554},"36":{"tf":1.4142135623730951},"39":{"tf":2.23606797749979},"4":{"tf":2.23606797749979},"42":{"tf":2.6457513110645907},"44":{"tf":4.898979485566356},"45":{"tf":5.0},"46":{"tf":1.0},"47":{"tf":5.0},"5":{"tf":3.4641016151377544},"6":{"tf":1.4142135623730951},"7":{"tf":2.0},"8":{"tf":2.0},"9":{"tf":1.0}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{")":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"\"":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"s":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"(":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":6,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.4142135623730951},"23":{"tf":1.7320508075688772},"39":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"df":2,"docs":{"30":{"tf":1.0},"31":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"y":{"df":0,"docs":{},"w":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}}},"t":{"df":5,"docs":{"26":{"tf":2.8284271247461903},"29":{"tf":3.7416573867739413},"44":{"tf":2.6457513110645907},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}},"x":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"15":{"tf":1.0},"37":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"35":{"tf":1.0},"38":{"tf":1.0}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":14,"docs":{"11":{"tf":1.4142135623730951},"15":{"tf":1.4142135623730951},"17":{"tf":1.0},"2":{"tf":1.4142135623730951},"23":{"tf":1.4142135623730951},"26":{"tf":1.0},"29":{"tf":1.0},"30":{"tf":1.0},"4":{"tf":1.7320508075688772},"44":{"tf":1.0},"45":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"35":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"c":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"26":{"tf":1.0},"7":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"'":{"df":1,"docs":{"26":{"tf":1.0}}},"df":5,"docs":{"23":{"tf":1.0},"24":{"tf":1.0},"26":{"tf":2.23606797749979},"28":{"tf":1.4142135623730951},"29":{"tf":2.0}}}}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"35":{"tf":1.0}}}},"t":{"df":5,"docs":{"23":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.8284271247461903},"31":{"tf":1.0},"45":{"tf":1.0}}}},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"\"":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}}},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":2,"docs":{"15":{"tf":1.0},"23":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":1,"docs":{"7":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"15":{"tf":1.4142135623730951}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"35":{"tf":1.0},"7":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"29":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"s":{"df":5,"docs":{"11":{"tf":1.0},"30":{"tf":1.0},"32":{"tf":1.0},"33":{"tf":1.0},"44":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":4,"docs":{"26":{"tf":1.0},"29":{"tf":1.0},"32":{"tf":1.0},"42":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"35":{"tf":1.0}}}}},"r":{"a":{"df":3,"docs":{"22":{"tf":1.0},"44":{"tf":1.7320508075688772},"7":{"tf":1.0}}},"df":0,"docs":{}}}}},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"31":{"tf":1.0},"35":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"42":{"tf":1.7320508075688772}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"23":{"tf":1.0},"39":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"43":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}}},"r":{"df":1,"docs":{"31":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"41":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":2,"docs":{"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"2":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"d":{"df":7,"docs":{"11":{"tf":2.23606797749979},"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"35":{"tf":2.23606797749979},"41":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"df":3,"docs":{"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"26":{"tf":1.7320508075688772},"29":{"tf":2.0},"39":{"tf":1.0}}}}}},"df":0,"docs":{},"w":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.0}}}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":2,"docs":{"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"40":{"tf":1.0},"44":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"e":{"df":16,"docs":{"11":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"14":{"tf":1.0},"23":{"tf":1.0},"30":{"tf":1.4142135623730951},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"35":{"tf":1.7320508075688772},"39":{"tf":1.0},"4":{"tf":1.7320508075688772},"44":{"tf":2.6457513110645907},"45":{"tf":1.7320508075688772},"47":{"tf":1.0},"5":{"tf":1.7320508075688772},"8":{"tf":1.0},"9":{"tf":1.0}}}},"n":{"a":{"df":0,"docs":{},"l":{"df":3,"docs":{"26":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.7320508075688772}}}},"d":{"df":2,"docs":{"28":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":2,"docs":{"4":{"tf":1.0},"46":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":7,"docs":{"11":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":2.23606797749979},"16":{"tf":1.0},"35":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":8,"docs":{"15":{"tf":1.0},"26":{"tf":1.4142135623730951},"29":{"tf":1.0},"3":{"tf":1.0},"37":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":2.0},"45":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}}}},"l":{"a":{"df":0,"docs":{},"g":{"df":2,"docs":{"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"22":{"tf":1.0},"23":{"tf":1.0}}}},"df":0,"docs":{}}}}},"n":{"df":11,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"41":{"tf":1.0},"42":{"tf":2.449489742783178},"43":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":2.6457513110645907}},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"o":{"c":{"df":0,"docs":{},"u":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"47":{"tf":1.0}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"18":{"tf":1.0}}}}},"m":{"df":2,"docs":{"22":{"tf":1.0},"23":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"23":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":1,"docs":{"39":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":1,"docs":{"15":{"tf":1.0}}}},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":4,"docs":{"26":{"tf":1.0},"30":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951}},"i":{"df":2,"docs":{"39":{"tf":1.0},"45":{"tf":1.0}}}}},"n":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":11,"docs":{"15":{"tf":1.0},"29":{"tf":1.0},"35":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"24":{"tf":1.0},"26":{"tf":2.23606797749979},"29":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"s":{":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"c":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{":":{":":{"df":0,"docs":{},"{":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"29":{"tf":1.0}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"k":{":":{":":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.0}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.0}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":16,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.7320508075688772},"12":{"tf":2.0},"14":{"tf":1.0},"2":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.0},"33":{"tf":1.0},"37":{"tf":1.4142135623730951},"39":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"9":{"tf":1.0}},"i":{"c":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"47":{"tf":1.7320508075688772}}}}}},"df":1,"docs":{"44":{"tf":1.0}}}},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":6,"docs":{"10":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.4142135623730951}},"n":{"df":4,"docs":{"11":{"tf":1.0},"15":{"tf":1.7320508075688772},"5":{"tf":1.0},"7":{"tf":1.0}}}}}},"o":{"df":7,"docs":{"17":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"8":{"tf":1.4142135623730951}},"e":{"df":5,"docs":{"18":{"tf":1.0},"2":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"47":{"tf":1.0}}},"n":{"df":0,"docs":{},"e":{"df":1,"docs":{"44":{"tf":1.0}}}},"o":{"d":{"df":2,"docs":{"44":{"tf":1.0},"45":{"tf":1.0}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":2,"docs":{"11":{"tf":1.0},"33":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"46":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"u":{"a":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"30":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":14,"docs":{"11":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":2.23606797749979},"26":{"tf":2.8284271247461903},"29":{"tf":3.7416573867739413},"30":{"tf":1.0},"31":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}},"e":{".":{"a":{"d":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"(":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":1,"docs":{"43":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"g":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"4":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}}}}},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"35":{"tf":1.0}}}},"df":0,"docs":{}}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"22":{"tf":1.0},"39":{"tf":1.0}},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}}},"n":{"c":{"df":3,"docs":{"23":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"35":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"e":{"'":{"df":2,"docs":{"29":{"tf":4.0},"45":{"tf":1.0}}},"df":4,"docs":{"31":{"tf":2.0},"35":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}},"l":{"df":0,"docs":{},"i":{"df":3,"docs":{"30":{"tf":1.0},"31":{"tf":1.0},"32":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"o":{"d":{"df":2,"docs":{"30":{"tf":1.0},"42":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"35":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"p":{":":{"/":{"/":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{".":{"df":0,"docs":{},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"g":{"/":{"4":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"s":{":":{"/":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"/":{"a":{"/":{"3":{"8":{"3":{"3":{"8":{"5":{"7":{"8":{"/":{"1":{"8":{"8":{"5":{"3":{"5":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"i":{"'":{"df":0,"docs":{},"m":{"df":1,"docs":{"35":{"tf":1.0}}},"v":{"df":2,"docs":{"26":{"tf":1.0},"36":{"tf":1.0}}}},"2":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":4,"docs":{"11":{"tf":1.0},"26":{"tf":2.23606797749979},"29":{"tf":2.6457513110645907},"39":{"tf":1.0}}},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"29":{"tf":3.7416573867739413}}}},"g":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.0}}}}}},"i":{"df":1,"docs":{"40":{"tf":1.0}},"i":{"df":1,"docs":{"44":{"tf":1.0}}}},"m":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":2,"docs":{"35":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"<":{"df":0,"docs":{},"t":{"df":3,"docs":{"39":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":11,"docs":{"11":{"tf":1.4142135623730951},"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"22":{"tf":1.0},"23":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.0},"38":{"tf":1.4142135623730951},"40":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":5,"docs":{"2":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"23":{"tf":1.0}}}}}}},"n":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":4,"docs":{"3":{"tf":1.0},"42":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":2,"docs":{"4":{"tf":1.0},"45":{"tf":1.0}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"u":{"df":1,"docs":{"46":{"tf":1.0}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"18":{"tf":1.0},"22":{"tf":1.0}}}}}},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"27":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"41":{"tf":1.0}}}}}},"df":4,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"22":{"tf":1.0}},"e":{"(":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"e":{"c":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"i":{"d":{"df":1,"docs":{"8":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":2.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"15":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":2,"docs":{"13":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":7,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"24":{"tf":1.0},"30":{"tf":1.0},"33":{"tf":1.0},"7":{"tf":1.0}}}},"n":{"d":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"12":{"tf":1.0}}}}},"f":{"a":{"c":{"df":5,"docs":{"11":{"tf":1.4142135623730951},"35":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"v":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}}},"n":{"df":12,"docs":{"17":{"tf":1.4142135623730951},"22":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0},"32":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.6457513110645907},"47":{"tf":1.0},"5":{"tf":1.0}}},"v":{"df":1,"docs":{"15":{"tf":1.0}}}}},"o":{"<":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":5,"docs":{"37":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.23606797749979}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":6,"docs":{"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.23606797749979}}}}}}},"r":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"u":{"c":{"df":2,"docs":{"13":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":2,"docs":{"10":{"tf":1.0},"15":{"tf":1.4142135623730951}}}}}},"o":{":":{":":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"<":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"39":{"tf":1.0},"47":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":5,"docs":{"13":{"tf":1.4142135623730951},"24":{"tf":1.0},"28":{"tf":2.23606797749979},"29":{"tf":2.0},"47":{"tf":1.0}}},"p":{"c":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":2,"docs":{"22":{"tf":1.0},"35":{"tf":1.0}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"u":{"df":3,"docs":{"30":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}}},"t":{"'":{"df":15,"docs":{"11":{"tf":1.7320508075688772},"17":{"tf":1.0},"26":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.4142135623730951},"4":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.0}},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"47":{"tf":1.0}}},"r":{"df":4,"docs":{"35":{"tf":1.0},"42":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":6,"docs":{"11":{"tf":1.0},"36":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.4142135623730951},"45":{"tf":1.4142135623730951},"5":{"tf":1.0}}}}}}},"v":{"df":1,"docs":{"45":{"tf":1.0}}},"²":{"c":{"df":1,"docs":{"33":{"tf":1.0}}},"df":0,"docs":{}}},"j":{"df":0,"docs":{},"o":{"b":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":6,"docs":{"26":{"tf":1.0},"36":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"8":{"tf":1.0}}}},"y":{"df":2,"docs":{"11":{"tf":1.0},"15":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"d":{"df":7,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"23":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"42":{"tf":1.0},"47":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":7,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"3":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0},"7":{"tf":1.4142135623730951}},"n":{"df":1,"docs":{"5":{"tf":1.0}}}}}}},"l":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"15":{"tf":1.4142135623730951}}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"18":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"15":{"tf":1.0},"26":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"36":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"8":{"tf":1.0}}},"df":0,"docs":{},"k":{"df":1,"docs":{"13":{"tf":1.0}}},"n":{"df":1,"docs":{"22":{"tf":1.0}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"15":{"tf":1.0}}}},"v":{"df":1,"docs":{"45":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":3,"docs":{"15":{"tf":1.0},"29":{"tf":1.0},"36":{"tf":1.0}}}},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"37":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"45":{"tf":1.0}}}},"t":{"'":{"df":4,"docs":{"26":{"tf":2.449489742783178},"29":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.4142135623730951}}},"df":1,"docs":{"30":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0}}}}}},"i":{"b":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":5,"docs":{"13":{"tf":1.0},"22":{"tf":2.0},"30":{"tf":1.0},"33":{"tf":1.0},"44":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":1,"docs":{"42":{"tf":1.0}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}}},"n":{"df":0,"docs":{},"e":{"df":2,"docs":{"26":{"tf":1.0},"7":{"tf":1.4142135623730951}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"x":{"df":2,"docs":{"11":{"tf":1.0},"33":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"36":{"tf":1.0}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"o":{"a":{"d":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"32":{"tf":1.0},"9":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"g":{"df":2,"docs":{"13":{"tf":1.0},"26":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"k":{"df":4,"docs":{"1":{"tf":1.0},"26":{"tf":1.4142135623730951},"42":{"tf":1.0},"44":{"tf":1.0}}},"p":{"df":24,"docs":{"11":{"tf":1.0},"14":{"tf":1.4142135623730951},"15":{"tf":2.449489742783178},"16":{"tf":1.4142135623730951},"17":{"tf":2.23606797749979},"18":{"tf":2.0},"2":{"tf":1.0},"26":{"tf":4.69041575982343},"28":{"tf":1.0},"29":{"tf":6.164414002968976},"3":{"tf":1.4142135623730951},"30":{"tf":1.0},"31":{"tf":1.4142135623730951},"35":{"tf":1.7320508075688772},"36":{"tf":1.0},"42":{"tf":2.0},"44":{"tf":2.449489742783178},"45":{"tf":2.0},"46":{"tf":2.0},"47":{"tf":2.0},"5":{"tf":1.7320508075688772},"6":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951},"8":{"tf":2.0}},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.4142135623730951}},"e":{":":{":":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}},"t":{"df":4,"docs":{"31":{"tf":1.0},"35":{"tf":1.0},"46":{"tf":1.0},"7":{"tf":1.0}}},"w":{"df":1,"docs":{"11":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}}},"m":{"a":{"d":{"df":0,"docs":{},"e":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"47":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":8,"docs":{"22":{"tf":1.7320508075688772},"23":{"tf":1.0},"31":{"tf":1.0},"32":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0},"7":{"tf":1.7320508075688772}}}},"n":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"11":{"tf":1.0}}}},"d":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"37":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":4,"docs":{"11":{"tf":1.4142135623730951},"27":{"tf":1.0},"31":{"tf":1.0},"43":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.0},"22":{"tf":1.0},"39":{"tf":1.0}}}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"36":{"tf":1.0},"42":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"|":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"y":{"b":{"df":2,"docs":{"39":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"26":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"n":{"df":14,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.7320508075688772},"26":{"tf":1.0},"3":{"tf":1.0},"31":{"tf":1.0},"34":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}}},"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"30":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"45":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":18,"docs":{"17":{"tf":1.7320508075688772},"23":{"tf":1.4142135623730951},"26":{"tf":2.0},"30":{"tf":1.0},"31":{"tf":1.4142135623730951},"32":{"tf":1.0},"34":{"tf":1.7320508075688772},"35":{"tf":2.23606797749979},"37":{"tf":2.449489742783178},"38":{"tf":1.4142135623730951},"39":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":4.58257569495584},"45":{"tf":4.0},"46":{"tf":1.7320508075688772},"47":{"tf":4.47213595499958},"5":{"tf":1.7320508075688772},"6":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":2,"docs":{"39":{"tf":1.7320508075688772},"47":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"d":{"df":9,"docs":{"12":{"tf":1.0},"18":{"tf":1.0},"22":{"tf":1.4142135623730951},"39":{"tf":1.4142135623730951},"40":{"tf":1.7320508075688772},"42":{"tf":1.7320508075688772},"44":{"tf":2.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"d":{"d":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"2":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":1,"docs":{"36":{"tf":1.0}}}}}}}},"o":{"d":{"df":0,"docs":{},"e":{"df":1,"docs":{"12":{"tf":1.0}},"l":{"df":1,"docs":{"10":{"tf":1.0}}}},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"11":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":13,"docs":{"11":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.7320508075688772},"30":{"tf":2.23606797749979},"31":{"tf":1.4142135623730951},"32":{"tf":1.7320508075688772},"37":{"tf":1.4142135623730951},"39":{"tf":2.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"46":{"tf":1.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.7320508075688772}}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"44":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"e":{"df":5,"docs":{"13":{"tf":1.0},"26":{"tf":2.8284271247461903},"29":{"tf":3.7416573867739413},"39":{"tf":1.0},"8":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"s":{"c":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":5,"docs":{"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"41":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}}}},"df":5,"docs":{"17":{"tf":1.0},"34":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":2.23606797749979},"47":{"tf":2.449489742783178}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"g":{"(":{"df":0,"docs":{},"e":{"df":1,"docs":{"23":{"tf":1.0}}}},"df":1,"docs":{"26":{"tf":4.0}}}},"u":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"31":{"tf":1.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"38":{"tf":1.0}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"37":{"tf":1.0},"47":{"tf":2.449489742783178}}}}},"df":0,"docs":{},"l":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"7":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"t":{"df":9,"docs":{"14":{"tf":1.7320508075688772},"15":{"tf":2.0},"16":{"tf":1.7320508075688772},"26":{"tf":4.898979485566356},"29":{"tf":5.916079783099616},"42":{"tf":3.4641016151377544},"44":{"tf":3.1622776601683795},"45":{"tf":2.8284271247461903},"47":{"tf":3.605551275463989}}}},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"35":{"tf":1.0}}}}}}}}},"n":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":2,"docs":{"23":{"tf":1.0},"5":{"tf":1.0}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"17":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"45":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"5":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":3,"docs":{"13":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"d":{"df":24,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.0},"15":{"tf":1.7320508075688772},"22":{"tf":1.7320508075688772},"23":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.4142135623730951},"29":{"tf":1.4142135623730951},"3":{"tf":1.0},"30":{"tf":1.0},"32":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.7320508075688772},"36":{"tf":2.449489742783178},"4":{"tf":1.0},"40":{"tf":1.4142135623730951},"41":{"tf":1.7320508075688772},"42":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951},"8":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":3,"docs":{"11":{"tf":1.0},"4":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"35":{"tf":1.0},"45":{"tf":1.4142135623730951},"8":{"tf":1.7320508075688772}}}}},"w":{"_":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"12":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}}}},"df":5,"docs":{"12":{"tf":1.0},"17":{"tf":1.0},"32":{"tf":1.0},"36":{"tf":1.0},"5":{"tf":1.0}}},"x":{"df":0,"docs":{},"t":{"df":5,"docs":{"15":{"tf":1.4142135623730951},"35":{"tf":1.0},"42":{"tf":1.0},"46":{"tf":1.0},"8":{"tf":1.0}}}}},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"23":{"tf":1.0},"7":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":9,"docs":{"26":{"tf":1.0},"27":{"tf":1.0},"29":{"tf":1.0},"31":{"tf":1.0},"36":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"h":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"8":{"tf":1.4142135623730951}}},"i":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{},"f":{"df":1,"docs":{"44":{"tf":1.0}},"i":{"df":1,"docs":{"23":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}}},"w":{"df":7,"docs":{"26":{"tf":1.0},"29":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"45":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"m":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}}}},"o":{"b":{"df":0,"docs":{},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"11":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":1,"docs":{"37":{"tf":1.0}},"s":{"df":1,"docs":{"33":{"tf":1.0}}}}}}}},"df":0,"docs":{},"h":{"df":1,"docs":{"26":{"tf":1.0}}},"k":{"(":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"(":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":5,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"41":{"tf":1.0},"42":{"tf":1.7320508075688772},"47":{"tf":2.0}}},"l":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}},"df":0,"docs":{}},"n":{"c":{"df":2,"docs":{"14":{"tf":1.0},"31":{"tf":1.0}}},"df":22,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"22":{"tf":1.0},"26":{"tf":1.7320508075688772},"27":{"tf":1.0},"3":{"tf":1.0},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.4142135623730951},"37":{"tf":1.4142135623730951},"38":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"5":{"tf":1.4142135623730951},"6":{"tf":1.7320508075688772},"7":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}},"t":{"df":0,"docs":{},"o":{"df":1,"docs":{"44":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":9,"docs":{"10":{"tf":1.0},"3":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":2.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"39":{"tf":1.0}}}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"<":{"df":0,"docs":{},"t":{"df":1,"docs":{"38":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"18":{"tf":1.0},"29":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"28":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"15":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"18":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"t":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"x":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"_":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}},"df":6,"docs":{"22":{"tf":1.0},"31":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"40":{"tf":1.0},"44":{"tf":1.4142135623730951}},"g":{"df":0,"docs":{},"o":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"26":{"tf":1.4142135623730951},"29":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"10":{"tf":1.0},"13":{"tf":1.0}}},"df":0,"docs":{}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":7,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"30":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.7320508075688772},"47":{"tf":2.0},"5":{"tf":1.0}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"22":{"tf":1.0}}}}}}}}},"w":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"f":{"d":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":4,"docs":{"10":{"tf":1.0},"13":{"tf":1.4142135623730951},"30":{"tf":1.0},"41":{"tf":1.0}}}}}}}}}}},"p":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"29":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":2,"docs":{"6":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}}}},"df":0,"docs":{},"t":{"df":14,"docs":{"15":{"tf":1.0},"18":{"tf":1.4142135623730951},"23":{"tf":1.4142135623730951},"24":{"tf":1.0},"26":{"tf":1.0},"3":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.4142135623730951},"38":{"tf":1.4142135623730951},"40":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.7320508075688772},"7":{"tf":1.0}},"i":{"df":1,"docs":{"13":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"s":{"df":4,"docs":{"15":{"tf":1.0},"39":{"tf":1.0},"42":{"tf":1.4142135623730951},"6":{"tf":1.0}}},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"47":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":2,"docs":{"31":{"tf":1.0},"41":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":3,"docs":{"31":{"tf":1.0},"45":{"tf":2.23606797749979},"47":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":1,"docs":{"15":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"27":{"tf":1.0}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":3,"docs":{"45":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}}}}}},"h":{"a":{"df":0,"docs":{},"p":{"df":3,"docs":{"39":{"tf":1.0},"44":{"tf":1.0},"46":{"tf":1.0}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}}}}}},"g":{"df":0,"docs":{},"m":{"df":1,"docs":{"30":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":9,"docs":{"17":{"tf":1.7320508075688772},"18":{"tf":2.23606797749979},"23":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"46":{"tf":1.0},"47":{"tf":1.0}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":2,"docs":{"18":{"tf":1.7320508075688772},"36":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"l":{"a":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"11":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":3,"docs":{"31":{"tf":1.4142135623730951},"35":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"l":{"df":3,"docs":{"28":{"tf":1.0},"42":{"tf":2.449489742783178},"47":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}},"p":{"df":1,"docs":{"44":{"tf":1.0}}},"s":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.0}}},"s":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":5,"docs":{"43":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"5":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}}}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":1,"docs":{"44":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"3":{"tf":1.0},"45":{"tf":1.0}}}}}}},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"28":{"tf":1.0}}}}}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":2,"docs":{"15":{"tf":1.0},"34":{"tf":1.0}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.7320508075688772}}}}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"11":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"15":{"tf":1.4142135623730951},"30":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":2,"docs":{"2":{"tf":1.0},"39":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}},"l":{"df":0,"docs":{},"n":{"!":{"(":{"\"":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}}},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":5,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"26":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"o":{"b":{"a":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"28":{"tf":1.0},"29":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":5,"docs":{"15":{"tf":1.0},"22":{"tf":1.0},"27":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"df":2,"docs":{"4":{"tf":1.0},"8":{"tf":1.0}},"e":{"d":{"df":1,"docs":{"7":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":7,"docs":{"18":{"tf":1.0},"22":{"tf":1.7320508075688772},"23":{"tf":2.0},"39":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":2.23606797749979},"47":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"s":{"(":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":3,"docs":{"44":{"tf":2.449489742783178},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"<":{"df":0,"docs":{},"f":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"df":13,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"23":{"tf":1.7320508075688772},"27":{"tf":1.0},"30":{"tf":1.0},"32":{"tf":1.0},"36":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.449489742783178},"45":{"tf":1.7320508075688772},"47":{"tf":1.7320508075688772},"5":{"tf":1.0}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":1,"docs":{"23":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"'":{"df":3,"docs":{"32":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.0}}},"df":11,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"16":{"tf":1.0},"3":{"tf":1.4142135623730951},"30":{"tf":1.4142135623730951},"31":{"tf":1.0},"32":{"tf":1.0},"4":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.0}},"m":{"df":1,"docs":{"30":{"tf":1.0}}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}},"p":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"22":{"tf":1.0},"39":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"13":{"tf":1.0},"42":{"tf":1.0}}}}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":15,"docs":{"11":{"tf":1.0},"13":{"tf":1.7320508075688772},"14":{"tf":1.0},"15":{"tf":1.0},"2":{"tf":1.7320508075688772},"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"24":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.0},"32":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"b":{"df":5,"docs":{"36":{"tf":1.4142135623730951},"37":{"tf":1.4142135623730951},"41":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.0}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"34":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"h":{"df":4,"docs":{"10":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"t":{"df":2,"docs":{"16":{"tf":1.0},"47":{"tf":1.0}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}},"e":{"df":9,"docs":{"17":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0},"37":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.0},"46":{"tf":1.0},"47":{"tf":2.0},"5":{"tf":1.4142135623730951}}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":1,"docs":{"35":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"w":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"14":{"tf":1.0}}},"t":{"df":2,"docs":{"10":{"tf":1.0},"34":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"7":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}}}},"d":{"/":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"a":{"b":{"df":0,"docs":{},"l":{"df":6,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"35":{"tf":2.8284271247461903},"44":{"tf":1.7320508075688772},"45":{"tf":2.23606797749979},"47":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"df":6,"docs":{"35":{"tf":2.0},"4":{"tf":2.449489742783178},"44":{"tf":1.7320508075688772},"45":{"tf":2.449489742783178},"47":{"tf":2.449489742783178},"5":{"tf":1.7320508075688772}},"i":{"df":5,"docs":{"4":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"l":{"df":3,"docs":{"31":{"tf":1.0},"32":{"tf":1.0},"44":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"35":{"tf":1.0},"45":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":12,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":2.0},"26":{"tf":1.0},"29":{"tf":4.0},"31":{"tf":1.0},"35":{"tf":1.4142135623730951},"44":{"tf":2.8284271247461903},"45":{"tf":3.0},"46":{"tf":1.0},"47":{"tf":1.7320508075688772},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"p":{"(":{"df":0,"docs":{},"|":{"df":0,"docs":{},"m":{"df":1,"docs":{"26":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"a":{"c":{"df":0,"docs":{},"t":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{".":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":1,"docs":{"26":{"tf":2.0}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":2.0}}},"y":{".":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}}}},"h":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":0,"docs":{}}}},"v":{"df":1,"docs":{"23":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":2,"docs":{"42":{"tf":1.0},"44":{"tf":1.0}}}}},"v":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"(":{"0":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}},"df":3,"docs":{"42":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"39":{"tf":1.0},"47":{"tf":1.0}}}}},"g":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"26":{"tf":2.23606797749979}}},"df":0,"docs":{}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":2.0},"47":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"df":3,"docs":{"42":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}}},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}}}},"l":{"a":{"df":0,"docs":{},"t":{"df":3,"docs":{"14":{"tf":1.0},"33":{"tf":1.0},"44":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":1,"docs":{"32":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":1,"docs":{"1":{"tf":1.0}}}},"df":0,"docs":{}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"44":{"tf":1.0},"45":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"b":{"df":3,"docs":{"38":{"tf":1.0},"44":{"tf":1.0},"46":{"tf":1.0}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"v":{"df":2,"docs":{"42":{"tf":1.0},"44":{"tf":1.0}}}}},"p":{"df":1,"docs":{"45":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"45":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}}}},"l":{"a":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":1,"docs":{"45":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":3,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":1.0}}}}}},"q":{"df":1,"docs":{"45":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":5,"docs":{"12":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"44":{"tf":1.0},"7":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"s":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"18":{"tf":1.0},"45":{"tf":1.0}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":2,"docs":{"32":{"tf":1.0},"44":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"<":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":7,"docs":{"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951},"7":{"tf":1.0}}}}}},"t":{"df":2,"docs":{"39":{"tf":1.4142135623730951},"47":{"tf":1.0}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"30":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":10,"docs":{"13":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":2.0},"26":{"tf":2.23606797749979},"29":{"tf":2.8284271247461903},"39":{"tf":1.7320508075688772},"41":{"tf":1.4142135623730951},"44":{"tf":2.23606797749979},"8":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}}}},"o":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"df":0,"docs":{}},"s":{"df":1,"docs":{"14":{"tf":1.0}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":2,"docs":{"23":{"tf":1.0},"8":{"tf":1.0}}}},"n":{"df":17,"docs":{"11":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":1.4142135623730951},"25":{"tf":1.0},"26":{"tf":3.3166247903554},"29":{"tf":4.69041575982343},"3":{"tf":1.0},"30":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.7320508075688772},"46":{"tf":2.0},"47":{"tf":2.449489742783178},"5":{"tf":1.0},"6":{"tf":1.4142135623730951},"7":{"tf":1.0},"8":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"'":{"df":3,"docs":{"17":{"tf":1.0},"2":{"tf":1.0},"24":{"tf":1.0}}},"df":5,"docs":{"13":{"tf":1.4142135623730951},"22":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.4142135623730951},"38":{"tf":1.0}}}}}},"s":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":1,"docs":{"13":{"tf":1.7320508075688772}}}},"k":{"df":0,"docs":{},"e":{"df":2,"docs":{"26":{"tf":1.0},"31":{"tf":1.0}}}},"m":{"df":0,"docs":{},"e":{"df":6,"docs":{"15":{"tf":1.0},"22":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"5":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"35":{"tf":1.0},"39":{"tf":1.0}}}}},"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{".":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"(":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"26":{"tf":2.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"26":{"tf":2.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"15":{"tf":1.4142135623730951},"26":{"tf":2.449489742783178},"29":{"tf":3.872983346207417}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":5,"docs":{"14":{"tf":1.0},"15":{"tf":1.4142135623730951},"3":{"tf":1.0},"45":{"tf":1.7320508075688772},"5":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"34":{"tf":1.0},"44":{"tf":1.0}}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"28":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":4,"docs":{"26":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.4142135623730951},"5":{"tf":1.0}},"m":{"df":1,"docs":{"44":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"27":{"tf":1.0}}}},"df":0,"docs":{}},"f":{".":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"c":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"x":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}}},"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{".":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"&":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"43":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"(":{")":{".":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"&":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"r":{"c":{"df":0,"docs":{},"v":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"r":{"c":{"df":0,"docs":{},"v":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":3,"docs":{"44":{"tf":2.8284271247461903},"45":{"tf":2.6457513110645907},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"w":{"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"p":{"df":2,"docs":{"42":{"tf":1.7320508075688772},"47":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":6,"docs":{"41":{"tf":1.0},"42":{"tf":2.449489742783178},"43":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":2.0},"47":{"tf":2.8284271247461903}}}},"n":{"d":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"/":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"df":13,"docs":{"18":{"tf":1.7320508075688772},"23":{"tf":2.0},"26":{"tf":1.0},"29":{"tf":1.4142135623730951},"34":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"41":{"tf":1.7320508075688772},"44":{"tf":2.449489742783178},"45":{"tf":3.0},"47":{"tf":3.3166247903554},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"\"":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{",":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"d":{"!":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"(":{"b":{"\"":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"\"":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"26":{"tf":2.0}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"h":{",":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":1,"docs":{"26":{"tf":2.0}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":2.0}}},"y":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"\"":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{",":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"d":{"!":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}},"df":2,"docs":{"29":{"tf":3.7416573867739413},"47":{"tf":1.0}}}}},"df":0,"docs":{},"s":{"df":3,"docs":{"23":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0}}},"t":{"df":5,"docs":{"23":{"tf":1.0},"29":{"tf":2.8284271247461903},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":2.449489742783178}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":3,"docs":{"22":{"tf":1.0},"35":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":5,"docs":{"37":{"tf":1.7320508075688772},"38":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}},"t":{"df":5,"docs":{"31":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"40":{"tf":1.0}}}}}},"h":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":3,"docs":{"15":{"tf":1.4142135623730951},"30":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":1.0}}}},"u":{"df":0,"docs":{},"l":{"d":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"44":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"w":{"df":1,"docs":{"30":{"tf":1.0}}}},"u":{"df":0,"docs":{},"t":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":2,"docs":{"31":{"tf":1.0},"43":{"tf":1.0}}}}}},"df":1,"docs":{"43":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"l":{"df":4,"docs":{"20":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"7":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":3,"docs":{"11":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}},"i":{"c":{"df":1,"docs":{"31":{"tf":1.0}}},"df":4,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"29":{"tf":1.0},"7":{"tf":1.0}},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}}}},"n":{"df":1,"docs":{"44":{"tf":1.0}},"g":{"df":0,"docs":{},"l":{"df":7,"docs":{"27":{"tf":1.0},"32":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":1.0},"47":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0}}}}},"t":{"df":1,"docs":{"35":{"tf":1.0}},"u":{"a":{"df":0,"docs":{},"t":{"df":3,"docs":{"22":{"tf":1.0},"23":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}}},"k":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":1,"docs":{"47":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}}}}},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"35":{"tf":1.0}}},".":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"41":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}}},"df":17,"docs":{"13":{"tf":1.0},"29":{"tf":3.872983346207417},"30":{"tf":1.7320508075688772},"31":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":2.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.7320508075688772},"41":{"tf":1.0},"43":{"tf":1.7320508075688772},"44":{"tf":1.4142135623730951},"45":{"tf":2.6457513110645907},"47":{"tf":4.795831523312719},"5":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}},"v":{"df":1,"docs":{"44":{"tf":1.0}}}},"m":{"df":0,"docs":{},"e":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":1,"docs":{"26":{"tf":4.0}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":5,"docs":{"10":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"3":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"c":{"df":32,"docs":{"10":{"tf":1.7320508075688772},"11":{"tf":2.0},"12":{"tf":1.4142135623730951},"14":{"tf":2.0},"15":{"tf":1.7320508075688772},"16":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.7320508075688772},"2":{"tf":1.7320508075688772},"22":{"tf":1.0},"23":{"tf":2.449489742783178},"24":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.4142135623730951},"31":{"tf":1.0},"32":{"tf":2.23606797749979},"33":{"tf":1.4142135623730951},"34":{"tf":1.4142135623730951},"35":{"tf":2.0},"36":{"tf":1.7320508075688772},"39":{"tf":1.0},"4":{"tf":1.4142135623730951},"40":{"tf":1.4142135623730951},"41":{"tf":2.0},"42":{"tf":3.4641016151377544},"44":{"tf":4.58257569495584},"45":{"tf":2.23606797749979},"46":{"tf":1.7320508075688772},"47":{"tf":4.123105625617661},"5":{"tf":2.8284271247461903},"9":{"tf":1.0}},"e":{"'":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":2,"docs":{"31":{"tf":1.4142135623730951},"45":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"23":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":9,"docs":{"11":{"tf":1.0},"15":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}}}}},"t":{"df":0,"docs":{},"e":{"df":11,"docs":{"35":{"tf":1.7320508075688772},"39":{"tf":1.0},"4":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.7320508075688772},"7":{"tf":1.7320508075688772},"9":{"tf":1.0}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}}}},"u":{"df":1,"docs":{"23":{"tf":1.0}}}}},"d":{":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"c":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"<":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"22":{"tf":1.0},"23":{"tf":1.7320508075688772}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"i":{"df":0,"docs":{},"o":{":":{":":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":3,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"39":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"e":{"<":{"df":0,"docs":{},"t":{"df":1,"docs":{"38":{"tf":1.0}}},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"38":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"8":{"(":{"&":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"(":{")":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"{":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":1,"docs":{"2":{"tf":1.4142135623730951}}}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":5,"docs":{"15":{"tf":1.0},"23":{"tf":1.4142135623730951},"35":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"p":{"df":4,"docs":{"3":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.0},"8":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"27":{"tf":1.0}}}}}}},"i":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"23":{"tf":1.0}}}}},"u":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"u":{"b":{"df":1,"docs":{"44":{"tf":1.0}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"23":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"30":{"tf":1.0}}}}}}}},"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"23":{"tf":1.0},"27":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}}}},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"44":{"tf":1.0},"5":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"31":{"tf":1.0}}}},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.0}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"31":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"23":{"tf":1.4142135623730951}},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"x":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"11":{"tf":1.0},"44":{"tf":1.0}}}}}}}},"t":{":":{":":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":5,"docs":{"37":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.23606797749979}}}}}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":8,"docs":{"23":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.449489742783178},"45":{"tf":1.0},"7":{"tf":1.7320508075688772}},"n":{"df":1,"docs":{"44":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"15":{"tf":1.0}}}}},"c":{"df":0,"docs":{},"p":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":6,"docs":{"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.8284271247461903}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"35":{"tf":1.0},"44":{"tf":1.4142135623730951}}}},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"m":{"df":4,"docs":{"32":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}}}}},"h":{"a":{"df":0,"docs":{},"t":{"'":{"df":6,"docs":{"29":{"tf":1.0},"33":{"tf":1.4142135623730951},"34":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":2,"docs":{"17":{"tf":1.0},"31":{"tf":1.0}}}}}}},"r":{"df":0,"docs":{},"e":{"'":{"df":2,"docs":{"17":{"tf":1.0},"35":{"tf":1.0}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"37":{"tf":1.0},"43":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":13,"docs":{"12":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.0},"3":{"tf":1.7320508075688772},"31":{"tf":1.0},"33":{"tf":1.0},"37":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.0}}},"k":{"df":2,"docs":{"31":{"tf":1.4142135623730951},"7":{"tf":1.0}}}},"r":{"d":{"df":3,"docs":{"13":{"tf":1.0},"15":{"tf":1.0},"35":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}}}}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":7,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.0},"23":{"tf":1.0},"3":{"tf":1.0},"5":{"tf":1.0}}}},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":3,"docs":{"18":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":7,"docs":{"27":{"tf":2.0},"3":{"tf":1.0},"4":{"tf":1.0},"47":{"tf":1.0},"6":{"tf":2.23606797749979},"7":{"tf":1.0},"8":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":4,"docs":{"12":{"tf":1.0},"35":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":5,"docs":{"13":{"tf":1.4142135623730951},"2":{"tf":1.0},"23":{"tf":1.0},"29":{"tf":1.0},"44":{"tf":1.0}}}}}}},"u":{"df":1,"docs":{"10":{"tf":1.0}}}},"i":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}},"m":{"df":0,"docs":{},"e":{"df":7,"docs":{"11":{"tf":1.0},"14":{"tf":1.4142135623730951},"15":{"tf":2.23606797749979},"4":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"d":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":1,"docs":{"31":{"tf":1.0}}}}},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"(":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"s":{"(":{"5":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"{":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":8,"docs":{"11":{"tf":1.0},"14":{"tf":2.6457513110645907},"15":{"tf":2.8284271247461903},"16":{"tf":1.4142135623730951},"32":{"tf":1.0},"4":{"tf":1.0},"5":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}}},"o":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":5,"docs":{"16":{"tf":1.0},"32":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0},"9":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"42":{"tf":3.1622776601683795},"47":{"tf":2.8284271247461903}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":4,"docs":{"42":{"tf":1.7320508075688772},"44":{"tf":3.605551275463989},"45":{"tf":1.7320508075688772},"47":{"tf":1.7320508075688772}}}}},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"44":{"tf":1.0}}}},"p":{"df":1,"docs":{"14":{"tf":1.0}},"i":{"c":{"df":1,"docs":{"37":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"22":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"y":{"df":1,"docs":{"26":{"tf":2.0}}}},"r":{"a":{"c":{"df":0,"docs":{},"e":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"k":{"df":6,"docs":{"15":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"8":{"tf":1.0}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"7":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"44":{"tf":1.0}}},"df":10,"docs":{"10":{"tf":1.0},"13":{"tf":1.4142135623730951},"22":{"tf":1.7320508075688772},"23":{"tf":1.4142135623730951},"28":{"tf":1.0},"29":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0}}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"37":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"30":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"i":{"df":3,"docs":{"22":{"tf":1.0},"23":{"tf":1.0},"4":{"tf":1.0}},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"12":{"tf":1.4142135623730951},"35":{"tf":1.7320508075688772},"42":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.7320508075688772}}}}}}},"o":{"df":0,"docs":{},"u":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"e":{"df":2,"docs":{"45":{"tf":1.7320508075688772},"47":{"tf":1.4142135623730951}}}}},"u":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"41":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"47":{"tf":1.0}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.4142135623730951}}}}}}},"w":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"k":{"df":1,"docs":{"37":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":9,"docs":{"18":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"24":{"tf":1.0},"26":{"tf":2.0},"3":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.4142135623730951},"7":{"tf":1.0}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":20,"docs":{"11":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":2.6457513110645907},"14":{"tf":1.0},"22":{"tf":1.7320508075688772},"23":{"tf":3.1622776601683795},"24":{"tf":1.0},"28":{"tf":2.6457513110645907},"29":{"tf":2.0},"36":{"tf":2.23606797749979},"37":{"tf":2.23606797749979},"38":{"tf":1.0},"39":{"tf":3.4641016151377544},"40":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.0},"47":{"tf":2.23606797749979},"5":{"tf":1.0},"9":{"tf":1.0}}},"i":{"c":{"df":1,"docs":{"6":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"11":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.0}}}}}},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"14":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":4,"docs":{"35":{"tf":1.0},"39":{"tf":1.4142135623730951},"4":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":2,"docs":{"20":{"tf":1.0},"29":{"tf":3.872983346207417}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"s":{"a":{"df":0,"docs":{},"f":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":5,"docs":{"14":{"tf":1.0},"18":{"tf":1.0},"35":{"tf":1.0},"4":{"tf":1.0},"46":{"tf":1.4142135623730951}}}}}},"p":{"d":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"5":{"tf":1.0}}}},"df":0,"docs":{}},"df":17,"docs":{"11":{"tf":1.0},"15":{"tf":1.0},"17":{"tf":2.0},"18":{"tf":1.4142135623730951},"30":{"tf":1.0},"31":{"tf":1.0},"35":{"tf":2.0},"36":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":2.6457513110645907},"45":{"tf":2.449489742783178},"47":{"tf":2.0},"5":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"47":{"tf":1.0}}}}},"s":{"b":{"df":1,"docs":{"11":{"tf":1.0}}},"df":33,"docs":{"10":{"tf":1.0},"11":{"tf":2.0},"12":{"tf":1.0},"13":{"tf":2.0},"14":{"tf":2.0},"15":{"tf":2.23606797749979},"16":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"18":{"tf":1.7320508075688772},"2":{"tf":1.4142135623730951},"22":{"tf":1.4142135623730951},"23":{"tf":1.4142135623730951},"26":{"tf":4.242640687119285},"27":{"tf":1.0},"28":{"tf":2.0},"29":{"tf":5.291502622129181},"30":{"tf":1.4142135623730951},"31":{"tf":2.449489742783178},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.7320508075688772},"4":{"tf":1.0},"41":{"tf":1.0},"44":{"tf":2.6457513110645907},"45":{"tf":2.0},"46":{"tf":1.4142135623730951},"47":{"tf":2.449489742783178},"6":{"tf":1.4142135623730951},"7":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}},"e":{"d":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"45":{"tf":2.0},"47":{"tf":2.23606797749979}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":7,"docs":{"22":{"tf":1.7320508075688772},"35":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.7320508075688772}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":4,"docs":{"11":{"tf":1.0},"31":{"tf":1.0},"39":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"5":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":6,"docs":{"15":{"tf":1.0},"18":{"tf":1.0},"26":{"tf":3.0},"29":{"tf":3.7416573867739413},"37":{"tf":1.0},"44":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"i":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"29":{"tf":1.0},"44":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{},"e":{"c":{"<":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"47":{"tf":1.0}}}}},"t":{"df":1,"docs":{"38":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"c":{"<":{"df":0,"docs":{},"u":{"8":{"df":2,"docs":{"39":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":1,"docs":{"47":{"tf":1.4142135623730951}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"17":{"tf":1.0},"30":{"tf":1.0}}},"s":{"a":{"df":1,"docs":{"47":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"1":{"tf":1.4142135623730951},"13":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"i":{"a":{"df":4,"docs":{"11":{"tf":1.0},"26":{"tf":2.0},"33":{"tf":1.0},"42":{"tf":1.0}}},"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}},"s":{"df":2,"docs":{"6":{"tf":1.0},"7":{"tf":1.0}}}},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":9,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"3":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.4142135623730951},"4":{"tf":2.23606797749979},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"8":{"tf":1.7320508075688772}}}},"k":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":4,"docs":{"36":{"tf":1.4142135623730951},"41":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":4,"docs":{"36":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":8,"docs":{"17":{"tf":2.0},"18":{"tf":1.0},"35":{"tf":1.7320508075688772},"36":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":2.23606797749979},"47":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":2,"docs":{"35":{"tf":1.0},"44":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"t":{"df":10,"docs":{"12":{"tf":1.0},"23":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"31":{"tf":1.0},"34":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"46":{"tf":1.0},"9":{"tf":1.0}}}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"y":{"df":13,"docs":{"13":{"tf":1.4142135623730951},"15":{"tf":1.0},"17":{"tf":1.0},"23":{"tf":1.0},"3":{"tf":1.4142135623730951},"31":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"8":{"tf":1.0}}}},"df":0,"docs":{},"e":{"'":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":6,"docs":{"36":{"tf":1.0},"37":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772}}}},"r":{"df":3,"docs":{"30":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.4142135623730951}}},"v":{"df":3,"docs":{"31":{"tf":1.0},"40":{"tf":1.0},"44":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"22":{"tf":1.0},"27":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":3,"docs":{"31":{"tf":1.0},"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":2,"docs":{"10":{"tf":1.0},"47":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":6,"docs":{"12":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":2.23606797749979},"46":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}}}}}}},"i":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":3,"docs":{"16":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"26":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"45":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":1,"docs":{"44":{"tf":1.4142135623730951}},"n":{"df":5,"docs":{"18":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}}},"n":{"'":{"df":0,"docs":{},"t":{"df":3,"docs":{"35":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}}}}},"df":0,"docs":{}},"r":{"d":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{},"k":{"df":14,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"27":{"tf":1.0},"3":{"tf":1.0},"30":{"tf":1.0},"32":{"tf":1.0},"36":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"47":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"l":{"d":{"!":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":6,"docs":{"11":{"tf":1.0},"13":{"tf":1.0},"28":{"tf":1.4142135623730951},"30":{"tf":1.0},"45":{"tf":1.0},"5":{"tf":1.0}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"31":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"11":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"a":{"b":{"df":0,"docs":{},"l":{"df":5,"docs":{"12":{"tf":1.0},"35":{"tf":2.0},"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"df":14,"docs":{"26":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"3":{"tf":1.4142135623730951},"31":{"tf":1.4142135623730951},"35":{"tf":1.0},"4":{"tf":1.7320508075688772},"40":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":4,"docs":{"26":{"tf":1.0},"27":{"tf":1.0},"31":{"tf":1.0},"35":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"'":{"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":4,"docs":{"15":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.0},"42":{"tf":1.0}}}},"r":{"df":3,"docs":{"1":{"tf":1.0},"28":{"tf":1.0},"33":{"tf":1.0}}},"v":{"df":1,"docs":{"5":{"tf":1.0}}}},".":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":1,"docs":{"2":{"tf":1.0}}}}}}}}}},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":1,"docs":{"23":{"tf":1.0}},"m":{"df":0,"docs":{},"q":{"'":{"df":2,"docs":{"35":{"tf":1.4142135623730951},"45":{"tf":1.0}}},"df":11,"docs":{"11":{"tf":1.0},"30":{"tf":2.0},"31":{"tf":1.4142135623730951},"33":{"tf":1.0},"35":{"tf":1.4142135623730951},"37":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951},"45":{"tf":2.0},"47":{"tf":3.605551275463989},"9":{"tf":1.0}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":4,"docs":{"36":{"tf":1.4142135623730951},"41":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}},"e":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"<":{"df":0,"docs":{},"t":{"df":5,"docs":{"37":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"37":{"tf":1.4142135623730951},"38":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}}}}}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"35":{"tf":1.0}}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"v":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"41":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":1,"docs":{"47":{"tf":1.4142135623730951}}}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"'":{"df":2,"docs":{"31":{"tf":1.0},"42":{"tf":1.0}}},"df":8,"docs":{"31":{"tf":1.7320508075688772},"35":{"tf":2.449489742783178},"36":{"tf":1.0},"37":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":3.1622776601683795},"45":{"tf":3.4641016151377544}}}}}},"df":0,"docs":{}}}}}},"breadcrumbs":{"root":{"0":{".":{"3":{"df":1,"docs":{"26":{"tf":2.0}}},"9":{"df":1,"docs":{"47":{"tf":1.4142135623730951}}},"df":0,"docs":{}},":":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":3,"docs":{"44":{"tf":1.7320508075688772},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}},"u":{"8":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}},"1":{".":{"0":{"df":1,"docs":{"47":{"tf":1.4142135623730951}}},"6":{"3":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"2":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":3,"docs":{"2":{"tf":1.0},"38":{"tf":1.0},"47":{"tf":1.0}}},"2":{"0":{"2":{"1":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":3,"docs":{"2":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"3":{"df":4,"docs":{"15":{"tf":1.4142135623730951},"2":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"4":{"df":1,"docs":{"2":{"tf":1.0}}},"5":{"df":1,"docs":{"14":{"tf":1.0}}},"_":{"df":8,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"44":{"tf":3.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.7320508075688772}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"d":{"_":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}},"df":0,"docs":{}}}},"a":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"28":{"tf":1.0}}}},"o":{"df":0,"docs":{},"v":{"df":2,"docs":{"31":{"tf":1.0},"45":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"11":{"tf":1.0},"30":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"37":{"tf":1.4142135623730951}}}}},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"r":{"d":{"df":1,"docs":{"47":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":6,"docs":{"14":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951}}}},"v":{"df":1,"docs":{"45":{"tf":1.0}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":6,"docs":{"35":{"tf":1.4142135623730951},"36":{"tf":1.0},"38":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"d":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":5,"docs":{"13":{"tf":1.0},"24":{"tf":1.7320508075688772},"28":{"tf":1.0},"31":{"tf":1.0},"9":{"tf":1.0}}}}},"d":{"df":7,"docs":{"28":{"tf":1.0},"35":{"tf":1.4142135623730951},"39":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"31":{"tf":1.4142135623730951}}}}}}},"df":5,"docs":{"15":{"tf":1.7320508075688772},"29":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0}},"v":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"7":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"15":{"tf":2.23606797749979},"35":{"tf":1.0},"43":{"tf":1.0},"45":{"tf":2.0},"46":{"tf":1.0},"47":{"tf":1.0}},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{},"w":{"df":3,"docs":{"39":{"tf":1.4142135623730951},"47":{"tf":1.0},"8":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"10":{"tf":1.0}}}},"o":{"df":0,"docs":{},"f":{"df":1,"docs":{"26":{"tf":1.7320508075688772}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":3,"docs":{"22":{"tf":1.0},"35":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"46":{"tf":1.0}}}}}},"w":{"a":{"df":0,"docs":{},"y":{"df":4,"docs":{"32":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"15":{"tf":1.0},"4":{"tf":1.0}}}}}}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":6,"docs":{"23":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.4142135623730951},"39":{"tf":1.0},"45":{"tf":1.0},"5":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}}}}}},"y":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"'":{"df":1,"docs":{"23":{"tf":1.0}}},":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"23":{"tf":1.0},"39":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":3,"docs":{"39":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}},"t":{"df":0,"docs":{},"h":{"df":3,"docs":{"28":{"tf":1.0},"4":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}}}}},"p":{"df":0,"docs":{},"i":{"df":4,"docs":{"1":{"tf":1.7320508075688772},"22":{"tf":1.4142135623730951},"38":{"tf":1.4142135623730951},"5":{"tf":1.0}}},"p":{"df":1,"docs":{"15":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"i":{"c":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"'":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}}}}},"df":1,"docs":{"31":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"o":{"a":{"c":{"df":0,"docs":{},"h":{"df":4,"docs":{"44":{"tf":1.0},"46":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"11":{"tf":1.0}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"15":{"tf":1.4142135623730951},"26":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0}}}}},"u":{"df":1,"docs":{"15":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":6,"docs":{"10":{"tf":1.0},"11":{"tf":1.4142135623730951},"27":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"45":{"tf":1.0}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"df":0,"docs":{},"f":{"d":{"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":2.0},"28":{"tf":1.0}},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":1,"docs":{"13":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"r":{"a":{"df":0,"docs":{},"w":{"df":0,"docs":{},"f":{"d":{"df":2,"docs":{"11":{"tf":1.0},"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"i":{"df":4,"docs":{"12":{"tf":1.0},"23":{"tf":1.7320508075688772},"39":{"tf":2.0},"44":{"tf":1.0}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"n":{"c":{"/":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":8,"docs":{"2":{"tf":1.0},"24":{"tf":1.7320508075688772},"25":{"tf":1.0},"26":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}}}},"df":7,"docs":{"24":{"tf":1.4142135623730951},"25":{"tf":1.7320508075688772},"26":{"tf":5.830951894845301},"27":{"tf":2.0},"28":{"tf":2.8284271247461903},"29":{"tf":7.54983443527075},"7":{"tf":1.7320508075688772}},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"23":{"tf":1.0},"3":{"tf":1.0}}}}}},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}}}}}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":3,"docs":{"30":{"tf":1.0},"35":{"tf":1.0},"47":{"tf":1.0}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":4,"docs":{"1":{"tf":1.0},"11":{"tf":1.0},"13":{"tf":1.0},"4":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"13":{"tf":1.0},"43":{"tf":1.0}}},"df":0,"docs":{}}}},"w":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"27":{"tf":1.0}}},"y":{"df":1,"docs":{"32":{"tf":1.0}}}},"df":0,"docs":{}}},"b":{"a":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"31":{"tf":1.0},"44":{"tf":1.0}},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{}}}}}},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"/":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}},"df":1,"docs":{"9":{"tf":1.0}}}}}}},"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":8,"docs":{"10":{"tf":1.0},"11":{"tf":1.4142135623730951},"23":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"i":{"c":{"df":2,"docs":{"30":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}}},"df":4,"docs":{"41":{"tf":1.0},"43":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951}},"e":{"c":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":8,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"18":{"tf":1.0},"22":{"tf":1.0},"35":{"tf":1.7320508075688772},"44":{"tf":2.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}},"df":5,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"38":{"tf":1.0},"46":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":5,"docs":{"23":{"tf":1.0},"26":{"tf":1.0},"31":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}},"h":{"a":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":2,"docs":{"26":{"tf":2.0},"47":{"tf":1.4142135623730951}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":5,"docs":{"30":{"tf":1.0},"32":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"df":0,"docs":{},"t":{"df":4,"docs":{"32":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.0},"43":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":10,"docs":{"26":{"tf":5.291502622129181},"28":{"tf":2.23606797749979},"29":{"tf":5.5677643628300215},"3":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951},"43":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951},"47":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":2.449489742783178}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"2":{"tf":1.0}}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"13":{"tf":1.0}},"e":{"d":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"13":{"tf":2.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"t":{"df":0,"docs":{},"h":{"df":5,"docs":{"12":{"tf":1.0},"22":{"tf":1.4142135623730951},"26":{"tf":1.0},"29":{"tf":1.0},"44":{"tf":1.0}}}},"x":{"<":{"d":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"df":2,"docs":{"23":{"tf":1.4142135623730951},"39":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"k":{"df":4,"docs":{"15":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"f":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"29":{"tf":2.6457513110645907}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"l":{"d":{"df":4,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"30":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.0},"31":{"tf":1.0},"47":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"df":1,"docs":{"18":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"e":{"df":1,"docs":{"26":{"tf":2.23606797749979}}},"t":{"df":0,"docs":{},"e":{"df":2,"docs":{"47":{"tf":1.0},"5":{"tf":1.0}}}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"28":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}},"df":15,"docs":{"11":{"tf":1.0},"15":{"tf":2.8284271247461903},"22":{"tf":1.4142135623730951},"23":{"tf":1.4142135623730951},"24":{"tf":1.0},"26":{"tf":1.4142135623730951},"30":{"tf":1.0},"39":{"tf":2.0},"44":{"tf":3.1622776601683795},"45":{"tf":2.0},"47":{"tf":2.8284271247461903},"5":{"tf":2.8284271247461903},"6":{"tf":1.4142135623730951},"7":{"tf":1.0},"8":{"tf":2.6457513110645907}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":16,"docs":{"18":{"tf":1.4142135623730951},"22":{"tf":1.0},"23":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"35":{"tf":2.0},"39":{"tf":1.0},"4":{"tf":1.4142135623730951},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.6457513110645907},"45":{"tf":1.4142135623730951},"47":{"tf":2.6457513110645907},"5":{"tf":1.7320508075688772},"7":{"tf":1.0},"8":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"23":{"tf":1.4142135623730951},"31":{"tf":1.0},"39":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"'":{"df":12,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"10":{"tf":1.0},"17":{"tf":1.0},"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.4142135623730951},"30":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0}}},":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"<":{"df":0,"docs":{},"t":{"df":3,"docs":{"37":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}},"df":5,"docs":{"23":{"tf":1.0},"34":{"tf":1.0},"36":{"tf":1.7320508075688772},"41":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":3,"docs":{"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"<":{"df":0,"docs":{},"t":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":5,"docs":{"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}}}}}}},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"26":{"tf":1.4142135623730951},"29":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"26":{"tf":2.23606797749979},"29":{"tf":2.8284271247461903}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"c":{":":{":":{"df":0,"docs":{},"f":{"d":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"33":{"tf":1.0},"36":{"tf":1.0}},"i":{"c":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"f":{"d":{"(":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"<":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"c":{":":{":":{"df":0,"docs":{},"f":{"d":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"<":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"o":{"df":1,"docs":{"29":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{":":{":":{"a":{"d":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":1,"docs":{"29":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"m":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"g":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{":":{":":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"p":{"df":3,"docs":{"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.4142135623730951}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":4,"docs":{"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":2.449489742783178},"47":{"tf":1.7320508075688772}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":2.449489742783178},"47":{"tf":1.7320508075688772}}}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"42":{"tf":2.0},"47":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":26,"docs":{"10":{"tf":1.0},"11":{"tf":1.7320508075688772},"14":{"tf":1.0},"15":{"tf":1.4142135623730951},"16":{"tf":1.0},"2":{"tf":2.23606797749979},"21":{"tf":1.4142135623730951},"22":{"tf":1.4142135623730951},"24":{"tf":1.7320508075688772},"26":{"tf":1.0},"27":{"tf":1.4142135623730951},"28":{"tf":1.7320508075688772},"3":{"tf":1.0},"31":{"tf":1.4142135623730951},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"34":{"tf":1.0},"36":{"tf":1.4142135623730951},"42":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":3.1622776601683795},"5":{"tf":2.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.7320508075688772}}}}}}},"n":{"'":{"df":0,"docs":{},"t":{"df":2,"docs":{"23":{"tf":1.0},"30":{"tf":1.0}}}},"d":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"37":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"p":{"a":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"10":{"tf":1.0},"37":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":7,"docs":{"30":{"tf":1.0},"32":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.0},"7":{"tf":1.0}},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}},"g":{"df":0,"docs":{},"o":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"18":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":7,"docs":{"31":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"39":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"23":{"tf":1.0}}}}}}}},"u":{"df":0,"docs":{},"s":{"df":3,"docs":{"15":{"tf":1.0},"31":{"tf":1.0},"45":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":3.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"24":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"14":{"tf":1.0},"4":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"31":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":4,"docs":{"35":{"tf":2.23606797749979},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"'":{"df":1,"docs":{"44":{"tf":1.0}}},"df":12,"docs":{"17":{"tf":1.4142135623730951},"19":{"tf":1.7320508075688772},"23":{"tf":1.4142135623730951},"26":{"tf":2.8284271247461903},"32":{"tf":1.0},"34":{"tf":1.7320508075688772},"36":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":2.0},"45":{"tf":1.7320508075688772},"47":{"tf":3.0},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}}}}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"2":{"tf":2.0},"3":{"tf":1.0},"30":{"tf":1.4142135623730951},"31":{"tf":1.0},"36":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"k":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":2.449489742783178},"5":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"28":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":3,"docs":{"35":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"45":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"7":{"tf":1.0}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":1,"docs":{"47":{"tf":1.4142135623730951}}}},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"23":{"tf":1.0},"44":{"tf":1.4142135623730951}}},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}}}}},"o":{"d":{"df":0,"docs":{},"e":{"df":17,"docs":{"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"25":{"tf":1.7320508075688772},"26":{"tf":3.1622776601683795},"27":{"tf":1.0},"28":{"tf":2.0},"29":{"tf":2.23606797749979},"3":{"tf":1.4142135623730951},"31":{"tf":2.0},"43":{"tf":1.0},"44":{"tf":2.0},"46":{"tf":1.0},"47":{"tf":2.449489742783178},"5":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":2.6457513110645907},"8":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"c":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"<":{"df":0,"docs":{},"t":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"m":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"15":{"tf":1.0},"2":{"tf":1.0},"32":{"tf":1.0},"44":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":2,"docs":{"24":{"tf":1.0},"7":{"tf":1.0}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"22":{"tf":1.0},"33":{"tf":1.0},"41":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":6,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"27":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.0},"8":{"tf":1.0}}},"x":{"df":4,"docs":{"22":{"tf":1.0},"30":{"tf":2.0},"32":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}},"i":{"c":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"26":{"tf":1.0},"29":{"tf":1.0},"36":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}}},"s":{"df":4,"docs":{"32":{"tf":1.7320508075688772},"36":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"t":{"df":5,"docs":{"32":{"tf":1.7320508075688772},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"9":{"tf":2.0}}}}}},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}}}},"n":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"22":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":2,"docs":{"3":{"tf":1.4142135623730951},"6":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"31":{"tf":1.0},"45":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"27":{"tf":1.0}}}}}},"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"12":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}}}},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":9,"docs":{"23":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"41":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{"\"":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}}}},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"44":{"tf":2.8284271247461903},"45":{"tf":3.0},"47":{"tf":2.23606797749979}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":4,"docs":{"10":{"tf":1.0},"39":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":1,"docs":{"18":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":4,"docs":{"12":{"tf":1.0},"30":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":1,"docs":{"22":{"tf":1.4142135623730951}}},"t":{"df":4,"docs":{"23":{"tf":1.0},"29":{"tf":1.0},"41":{"tf":1.0},"47":{"tf":1.7320508075688772}}}},"y":{"df":1,"docs":{"35":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":4,"docs":{"13":{"tf":1.0},"26":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"u":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"r":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"3":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"4":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"22":{"tf":1.0},"27":{"tf":1.0}},"s":{"/":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"/":{"d":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":24,"docs":{"11":{"tf":1.0},"12":{"tf":1.7320508075688772},"14":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.7320508075688772},"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.0},"40":{"tf":2.0},"41":{"tf":1.4142135623730951},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":2.0},"46":{"tf":1.0},"47":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.8284271247461903}}}},"x":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"1":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":2,"docs":{"2":{"tf":1.0},"9":{"tf":1.0}}}}}}},"y":{"c":{"df":0,"docs":{},"l":{"df":2,"docs":{"4":{"tf":1.0},"42":{"tf":1.0}}}},"df":0,"docs":{}}},"d":{"a":{"df":0,"docs":{},"t":{"a":{".":{".":{".":{"\"":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":9,"docs":{"15":{"tf":1.4142135623730951},"29":{"tf":1.0},"30":{"tf":1.7320508075688772},"35":{"tf":1.0},"39":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951},"44":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"5":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"14":{"tf":1.7320508075688772},"15":{"tf":1.7320508075688772},"16":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"l":{"df":3,"docs":{"22":{"tf":1.0},"31":{"tf":1.0},"44":{"tf":1.0}},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}},"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":1,"docs":{"35":{"tf":1.0}}}}},"c":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"23":{"tf":1.0}}},"df":0,"docs":{},"s":{"df":1,"docs":{"31":{"tf":1.0}}}},"o":{"d":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"39":{"tf":1.0},"40":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":5,"docs":{"31":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951},"6":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{".":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"s":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":13,"docs":{"11":{"tf":2.0},"12":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"23":{"tf":1.0},"30":{"tf":1.4142135623730951},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"35":{"tf":1.4142135623730951},"39":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":3,"docs":{"28":{"tf":1.0},"32":{"tf":1.0},"9":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"y":{"df":1,"docs":{"15":{"tf":1.0}}}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":7,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"32":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"36":{"tf":1.0}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"44":{"tf":1.0},"46":{"tf":1.0}}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":1,"docs":{"1":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":6,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"s":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"31":{"tf":1.4142135623730951},"46":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"(":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"11":{"tf":1.0}}}}}}},"o":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"7":{"tf":1.0}},"e":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"7":{"tf":1.0}},"e":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"w":{"df":0,"docs":{},"o":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"7":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"c":{"df":3,"docs":{"1":{"tf":1.0},"35":{"tf":1.4142135623730951},"47":{"tf":1.0}},"s":{".":{"df":0,"docs":{},"r":{"df":1,"docs":{"1":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":2,"docs":{"22":{"tf":1.0},"45":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":3,"docs":{"35":{"tf":1.0},"4":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":3.872983346207417}}}}},"df":0,"docs":{}},"n":{"'":{"df":0,"docs":{},"t":{"df":9,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0},"36":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"8":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":3,"docs":{"30":{"tf":1.0},"44":{"tf":1.0},"7":{"tf":1.0}}}},"u":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"df":0,"docs":{},"n":{"df":3,"docs":{"15":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951}}}}},"r":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":2,"docs":{"44":{"tf":1.0},"45":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":6,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.4142135623730951},"43":{"tf":2.23606797749979},"44":{"tf":1.0},"47":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"e":{"df":2,"docs":{"15":{"tf":1.0},"45":{"tf":1.0}}},"r":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"14":{"tf":1.0},"15":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"e":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":2,"docs":{"44":{"tf":1.4142135623730951},"5":{"tf":1.0}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"12":{"tf":1.0}}}}}}}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"2":{"tf":1.0},"24":{"tf":1.0}}}}}}}}}},"d":{"df":0,"docs":{},"g":{"df":5,"docs":{"12":{"tf":1.0},"35":{"tf":1.7320508075688772},"42":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"38":{"tf":1.0}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"18":{"tf":1.0},"26":{"tf":1.0}}}},"df":0,"docs":{}},"i":{"c":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"44":{"tf":1.0}}}},"df":0,"docs":{}}}},"g":{"df":7,"docs":{"23":{"tf":1.4142135623730951},"27":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}},"l":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"df":2,"docs":{"4":{"tf":1.0},"5":{"tf":1.0}}}}},"df":0,"docs":{}},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"46":{"tf":1.0}}}}}},"n":{"a":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":1.7320508075688772},"29":{"tf":2.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"11":{"tf":1.0},"4":{"tf":1.0}}}}}}},"d":{"df":12,"docs":{"18":{"tf":1.7320508075688772},"23":{"tf":1.4142135623730951},"26":{"tf":3.4641016151377544},"29":{"tf":4.0},"31":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"41":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":2.8284271247461903}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"38":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":4,"docs":{"10":{"tf":1.0},"35":{"tf":1.0},"46":{"tf":1.0},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}},"u":{"df":0,"docs":{},"m":{"df":2,"docs":{"15":{"tf":1.0},"23":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":12,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"21":{"tf":1.7320508075688772},"22":{"tf":3.4641016151377544},"23":{"tf":3.7416573867739413},"31":{"tf":1.7320508075688772},"35":{"tf":1.0},"39":{"tf":2.449489742783178},"4":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"7":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}},"t":{"c":{"df":2,"docs":{"13":{"tf":1.0},"4":{"tf":1.0}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":7,"docs":{"15":{"tf":1.0},"18":{"tf":1.0},"32":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":1.0},"44":{"tf":1.0}},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{".":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"(":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}}},"df":5,"docs":{"14":{"tf":1.7320508075688772},"15":{"tf":1.7320508075688772},"16":{"tf":1.7320508075688772},"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}}},"df":39,"docs":{"10":{"tf":2.8284271247461903},"11":{"tf":3.0},"12":{"tf":2.0},"13":{"tf":1.0},"14":{"tf":2.449489742783178},"15":{"tf":3.0},"16":{"tf":2.0},"17":{"tf":3.1622776601683795},"18":{"tf":2.8284271247461903},"19":{"tf":1.0},"2":{"tf":1.7320508075688772},"20":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.4142135623730951},"23":{"tf":3.1622776601683795},"24":{"tf":1.0},"26":{"tf":4.0},"28":{"tf":1.4142135623730951},"29":{"tf":5.477225575051661},"3":{"tf":2.0},"30":{"tf":2.0},"31":{"tf":1.7320508075688772},"32":{"tf":2.6457513110645907},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":3.3166247903554},"36":{"tf":1.4142135623730951},"39":{"tf":2.23606797749979},"4":{"tf":2.449489742783178},"42":{"tf":2.6457513110645907},"44":{"tf":5.0990195135927845},"45":{"tf":5.196152422706632},"46":{"tf":1.4142135623730951},"47":{"tf":5.196152422706632},"5":{"tf":3.7416573867739413},"6":{"tf":1.7320508075688772},"7":{"tf":2.449489742783178},"8":{"tf":2.23606797749979},"9":{"tf":1.4142135623730951}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{")":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"\"":{"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"s":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"(":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":6,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.4142135623730951},"23":{"tf":2.0},"39":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"df":2,"docs":{"30":{"tf":1.0},"31":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"y":{"df":0,"docs":{},"w":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}}},"t":{"df":5,"docs":{"26":{"tf":2.8284271247461903},"29":{"tf":3.7416573867739413},"44":{"tf":2.6457513110645907},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}},"x":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"15":{"tf":1.0},"37":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"35":{"tf":1.0},"38":{"tf":1.0}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":29,"docs":{"11":{"tf":1.4142135623730951},"15":{"tf":1.4142135623730951},"17":{"tf":1.0},"2":{"tf":1.4142135623730951},"23":{"tf":1.4142135623730951},"26":{"tf":1.0},"29":{"tf":1.0},"30":{"tf":1.7320508075688772},"31":{"tf":1.0},"32":{"tf":1.0},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.7320508075688772},"40":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.4142135623730951},"46":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"35":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"c":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"26":{"tf":1.0},"7":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"'":{"df":1,"docs":{"26":{"tf":1.0}}},"df":5,"docs":{"23":{"tf":1.0},"24":{"tf":1.0},"26":{"tf":2.449489742783178},"28":{"tf":1.4142135623730951},"29":{"tf":2.0}}}}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"35":{"tf":1.0}}}},"t":{"df":5,"docs":{"23":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.8284271247461903},"31":{"tf":1.0},"45":{"tf":1.0}}}},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"\"":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}}},"f":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":2,"docs":{"15":{"tf":1.0},"23":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":1,"docs":{"7":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"15":{"tf":1.4142135623730951}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"35":{"tf":1.0},"7":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"29":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"s":{"df":5,"docs":{"11":{"tf":1.0},"30":{"tf":1.0},"32":{"tf":1.0},"33":{"tf":1.0},"44":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":4,"docs":{"26":{"tf":1.0},"29":{"tf":1.0},"32":{"tf":1.0},"42":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"35":{"tf":1.0}}}}},"r":{"a":{"df":3,"docs":{"22":{"tf":1.0},"44":{"tf":1.7320508075688772},"7":{"tf":1.0}}},"df":0,"docs":{}}}}},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"31":{"tf":1.0},"35":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"42":{"tf":1.7320508075688772}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":2,"docs":{"23":{"tf":1.0},"39":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"43":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}}},"r":{"df":1,"docs":{"31":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"41":{"tf":1.0}}}}}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":2,"docs":{"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"2":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"d":{"df":7,"docs":{"11":{"tf":2.23606797749979},"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"35":{"tf":2.23606797749979},"41":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}},"df":3,"docs":{"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"26":{"tf":2.0},"29":{"tf":2.23606797749979},"39":{"tf":1.0}}}}}},"df":0,"docs":{},"w":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.0}}}},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":2,"docs":{"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"40":{"tf":1.0},"44":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"e":{"df":17,"docs":{"11":{"tf":2.0},"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"14":{"tf":1.0},"23":{"tf":1.0},"30":{"tf":1.4142135623730951},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"35":{"tf":1.7320508075688772},"39":{"tf":1.0},"4":{"tf":1.7320508075688772},"44":{"tf":2.6457513110645907},"45":{"tf":1.7320508075688772},"47":{"tf":1.0},"5":{"tf":1.7320508075688772},"8":{"tf":1.0},"9":{"tf":1.0}}}},"n":{"a":{"df":0,"docs":{},"l":{"df":3,"docs":{"26":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.7320508075688772}}}},"d":{"df":2,"docs":{"28":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":2,"docs":{"4":{"tf":1.0},"46":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":7,"docs":{"11":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":2.23606797749979},"16":{"tf":1.0},"35":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":8,"docs":{"15":{"tf":1.0},"26":{"tf":1.4142135623730951},"29":{"tf":1.0},"3":{"tf":1.0},"37":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":2.0},"45":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}}}},"l":{"a":{"df":0,"docs":{},"g":{"df":2,"docs":{"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"22":{"tf":1.0},"23":{"tf":1.0}}}},"df":0,"docs":{}}}}},"n":{"df":11,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"41":{"tf":1.0},"42":{"tf":2.449489742783178},"43":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":2.6457513110645907}},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}}},"o":{"c":{"df":0,"docs":{},"u":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"47":{"tf":1.0}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"18":{"tf":1.0}}}}},"m":{"df":2,"docs":{"22":{"tf":1.0},"23":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"23":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":1,"docs":{"39":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":1,"docs":{"15":{"tf":1.0}}}},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":1.7320508075688772}}}}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":19,"docs":{"26":{"tf":1.0},"30":{"tf":1.7320508075688772},"31":{"tf":1.0},"32":{"tf":1.0},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"46":{"tf":1.0},"47":{"tf":2.23606797749979}},"i":{"df":2,"docs":{"39":{"tf":1.0},"45":{"tf":1.0}}}}},"n":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":11,"docs":{"15":{"tf":1.0},"29":{"tf":1.0},"35":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"24":{"tf":1.0},"26":{"tf":2.23606797749979},"29":{"tf":2.0}},"e":{"df":0,"docs":{},"s":{":":{":":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"c":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{":":{":":{"df":0,"docs":{},"{":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"29":{"tf":1.0}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"k":{":":{":":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.0}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.0}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":16,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.7320508075688772},"12":{"tf":2.23606797749979},"14":{"tf":1.0},"2":{"tf":1.0},"27":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.0},"33":{"tf":1.4142135623730951},"37":{"tf":1.4142135623730951},"39":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"9":{"tf":1.0}},"i":{"c":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"47":{"tf":1.7320508075688772}}}}}},"df":1,"docs":{"44":{"tf":1.0}}}},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":6,"docs":{"10":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.4142135623730951}},"n":{"df":4,"docs":{"11":{"tf":1.0},"15":{"tf":1.7320508075688772},"5":{"tf":1.0},"7":{"tf":1.0}}}}}},"o":{"df":7,"docs":{"17":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"8":{"tf":1.4142135623730951}},"e":{"df":5,"docs":{"18":{"tf":1.0},"2":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"47":{"tf":1.0}}},"n":{"df":0,"docs":{},"e":{"df":1,"docs":{"44":{"tf":1.0}}}},"o":{"d":{"df":2,"docs":{"44":{"tf":1.0},"45":{"tf":1.0}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":2,"docs":{"11":{"tf":1.0},"33":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"7":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"46":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}}},"u":{"a":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"30":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":15,"docs":{"11":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"21":{"tf":1.7320508075688772},"22":{"tf":2.449489742783178},"23":{"tf":1.0},"26":{"tf":2.8284271247461903},"29":{"tf":3.7416573867739413},"30":{"tf":1.0},"31":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}},"e":{".":{"a":{"d":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"(":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":1,"docs":{"43":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{},"g":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"4":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}}}}},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"35":{"tf":1.0}}}},"df":0,"docs":{}}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"22":{"tf":1.0},"39":{"tf":1.0}},"n":{"'":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}}},"n":{"c":{"df":3,"docs":{"23":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"35":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"e":{"'":{"df":2,"docs":{"29":{"tf":4.0},"45":{"tf":1.0}}},"df":4,"docs":{"31":{"tf":2.0},"35":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}},"l":{"df":0,"docs":{},"i":{"df":3,"docs":{"30":{"tf":1.0},"31":{"tf":1.0},"32":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"o":{"d":{"df":2,"docs":{"30":{"tf":1.0},"42":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"35":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"p":{":":{"/":{"/":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{".":{"df":0,"docs":{},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"g":{"/":{"4":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"s":{":":{"/":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"f":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"/":{"a":{"/":{"3":{"8":{"3":{"3":{"8":{"5":{"7":{"8":{"/":{"1":{"8":{"8":{"5":{"3":{"5":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"i":{"'":{"df":0,"docs":{},"m":{"df":1,"docs":{"35":{"tf":1.0}}},"v":{"df":2,"docs":{"26":{"tf":1.0},"36":{"tf":1.0}}}},"2":{"c":{"df":1,"docs":{"11":{"tf":1.0}}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":4,"docs":{"11":{"tf":1.0},"26":{"tf":2.23606797749979},"29":{"tf":2.6457513110645907},"39":{"tf":1.0}}},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"29":{"tf":3.7416573867739413}}}},"g":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.0}}}}}},"i":{"df":4,"docs":{"40":{"tf":1.7320508075688772},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0}},"i":{"df":1,"docs":{"44":{"tf":1.7320508075688772}}}},"m":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":2,"docs":{"35":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"<":{"df":0,"docs":{},"t":{"df":3,"docs":{"39":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":11,"docs":{"11":{"tf":1.4142135623730951},"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"22":{"tf":1.0},"23":{"tf":1.4142135623730951},"27":{"tf":1.4142135623730951},"28":{"tf":1.0},"38":{"tf":1.4142135623730951},"40":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":5,"docs":{"2":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"23":{"tf":1.0}}}}}}},"n":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":4,"docs":{"3":{"tf":1.0},"42":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":2,"docs":{"4":{"tf":1.0},"45":{"tf":1.0}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"u":{"df":1,"docs":{"46":{"tf":1.0}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"18":{"tf":1.0},"22":{"tf":1.0}}}}}},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"27":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"41":{"tf":1.0}}}}}},"df":4,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"22":{"tf":1.0}},"e":{"(":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"e":{"c":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"i":{"d":{"df":1,"docs":{"8":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":2.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"15":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":2,"docs":{"13":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":7,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"24":{"tf":1.0},"30":{"tf":1.0},"33":{"tf":1.0},"7":{"tf":1.0}}}},"n":{"d":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"12":{"tf":1.0}}}}},"f":{"a":{"c":{"df":5,"docs":{"11":{"tf":1.4142135623730951},"35":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"v":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}}},"n":{"df":12,"docs":{"17":{"tf":1.4142135623730951},"22":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0},"32":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.6457513110645907},"47":{"tf":1.0},"5":{"tf":1.0}}},"v":{"df":1,"docs":{"15":{"tf":1.0}}}}},"o":{"<":{"df":0,"docs":{},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":5,"docs":{"37":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.23606797749979}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":6,"docs":{"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.23606797749979}}}}}}},"r":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"u":{"c":{"df":2,"docs":{"13":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":2,"docs":{"10":{"tf":1.0},"15":{"tf":1.4142135623730951}}}}}},"o":{":":{":":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"<":{"(":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"39":{"tf":1.0},"47":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":5,"docs":{"13":{"tf":1.4142135623730951},"24":{"tf":1.0},"28":{"tf":2.6457513110645907},"29":{"tf":2.449489742783178},"47":{"tf":1.0}}},"p":{"c":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":2,"docs":{"22":{"tf":1.0},"35":{"tf":1.0}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"u":{"df":3,"docs":{"30":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}}},"t":{"'":{"df":15,"docs":{"11":{"tf":1.7320508075688772},"17":{"tf":1.0},"26":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.4142135623730951},"4":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.0}},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"47":{"tf":1.0}}},"r":{"df":4,"docs":{"35":{"tf":1.0},"42":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":6,"docs":{"11":{"tf":1.0},"36":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.4142135623730951},"45":{"tf":1.4142135623730951},"5":{"tf":1.0}}}}}}},"v":{"df":2,"docs":{"45":{"tf":1.7320508075688772},"46":{"tf":1.0}}},"²":{"c":{"df":1,"docs":{"33":{"tf":1.0}}},"df":0,"docs":{}}},"j":{"df":0,"docs":{},"o":{"b":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":6,"docs":{"26":{"tf":1.0},"36":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"8":{"tf":1.0}}}},"y":{"df":2,"docs":{"11":{"tf":1.0},"15":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"d":{"df":7,"docs":{"11":{"tf":1.0},"2":{"tf":1.0},"23":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"42":{"tf":1.0},"47":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":7,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"3":{"tf":1.0},"36":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0},"7":{"tf":1.4142135623730951}},"n":{"df":1,"docs":{"5":{"tf":1.0}}}}}}},"l":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"15":{"tf":1.4142135623730951}}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"18":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"15":{"tf":1.0},"26":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"36":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"8":{"tf":1.0}}},"df":0,"docs":{},"k":{"df":1,"docs":{"13":{"tf":1.0}}},"n":{"df":1,"docs":{"22":{"tf":1.0}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"15":{"tf":1.0}}}},"v":{"df":1,"docs":{"45":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":3,"docs":{"15":{"tf":1.0},"29":{"tf":1.0},"36":{"tf":1.0}}}},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"37":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"45":{"tf":1.0}}}},"t":{"'":{"df":4,"docs":{"26":{"tf":2.449489742783178},"29":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.4142135623730951}}},"df":1,"docs":{"30":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0}}}}}},"i":{"b":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":5,"docs":{"13":{"tf":1.0},"22":{"tf":2.0},"30":{"tf":1.0},"33":{"tf":1.0},"44":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":1,"docs":{"42":{"tf":1.0}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}}},"n":{"df":0,"docs":{},"e":{"df":2,"docs":{"26":{"tf":1.0},"7":{"tf":1.4142135623730951}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"x":{"df":2,"docs":{"11":{"tf":1.0},"33":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"36":{"tf":1.0}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"o":{"a":{"d":{"df":1,"docs":{"30":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"c":{"df":2,"docs":{"32":{"tf":1.0},"9":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"g":{"df":2,"docs":{"13":{"tf":1.0},"26":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"k":{"df":4,"docs":{"1":{"tf":1.0},"26":{"tf":1.4142135623730951},"42":{"tf":1.0},"44":{"tf":1.0}}},"p":{"df":26,"docs":{"11":{"tf":1.0},"14":{"tf":1.4142135623730951},"15":{"tf":2.6457513110645907},"16":{"tf":1.4142135623730951},"17":{"tf":2.449489742783178},"18":{"tf":2.0},"2":{"tf":1.0},"26":{"tf":4.69041575982343},"28":{"tf":1.0},"29":{"tf":6.164414002968976},"3":{"tf":2.0},"30":{"tf":1.0},"31":{"tf":1.4142135623730951},"35":{"tf":1.7320508075688772},"36":{"tf":1.0},"4":{"tf":1.0},"42":{"tf":2.0},"44":{"tf":2.449489742783178},"45":{"tf":2.0},"46":{"tf":2.0},"47":{"tf":2.0},"5":{"tf":2.0},"6":{"tf":1.7320508075688772},"7":{"tf":2.0},"8":{"tf":2.449489742783178},"9":{"tf":1.0}},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.4142135623730951}},"e":{":":{":":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"22":{"tf":1.0}}}},"t":{"df":4,"docs":{"31":{"tf":1.0},"35":{"tf":1.0},"46":{"tf":1.0},"7":{"tf":1.0}}},"w":{"df":1,"docs":{"11":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}}},"m":{"a":{"d":{"df":0,"docs":{},"e":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":6,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"47":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":8,"docs":{"22":{"tf":1.7320508075688772},"23":{"tf":1.0},"31":{"tf":1.0},"32":{"tf":1.0},"35":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0},"7":{"tf":1.7320508075688772}}}},"n":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"11":{"tf":1.0}}}},"d":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"37":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":4,"docs":{"11":{"tf":1.4142135623730951},"27":{"tf":1.0},"31":{"tf":1.0},"43":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.0},"22":{"tf":1.0},"39":{"tf":1.0}}}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"36":{"tf":1.0},"42":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"|":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"y":{"b":{"df":2,"docs":{"39":{"tf":1.0},"44":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"26":{"tf":1.4142135623730951}},"e":{"a":{"df":0,"docs":{},"n":{"df":14,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.7320508075688772},"26":{"tf":1.0},"3":{"tf":1.0},"31":{"tf":1.0},"34":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}}},"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"30":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"45":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":18,"docs":{"17":{"tf":1.7320508075688772},"23":{"tf":1.4142135623730951},"26":{"tf":2.0},"30":{"tf":1.0},"31":{"tf":1.4142135623730951},"32":{"tf":1.0},"34":{"tf":1.7320508075688772},"35":{"tf":2.23606797749979},"37":{"tf":2.6457513110645907},"38":{"tf":1.7320508075688772},"39":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":4.58257569495584},"45":{"tf":4.0},"46":{"tf":1.7320508075688772},"47":{"tf":4.47213595499958},"5":{"tf":1.7320508075688772},"6":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":2,"docs":{"39":{"tf":1.7320508075688772},"47":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"d":{"df":11,"docs":{"12":{"tf":1.0},"18":{"tf":1.0},"22":{"tf":1.4142135623730951},"39":{"tf":1.4142135623730951},"40":{"tf":2.23606797749979},"41":{"tf":1.0},"42":{"tf":2.23606797749979},"43":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"d":{"d":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"2":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":1,"docs":{"36":{"tf":1.0}}}}}}}},"o":{"d":{"df":0,"docs":{},"e":{"df":1,"docs":{"12":{"tf":1.0}},"l":{"df":1,"docs":{"10":{"tf":1.0}}}},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"11":{"tf":1.7320508075688772},"12":{"tf":1.0},"13":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"31":{"tf":1.0}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":13,"docs":{"11":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.7320508075688772},"30":{"tf":2.23606797749979},"31":{"tf":1.4142135623730951},"32":{"tf":1.7320508075688772},"37":{"tf":1.4142135623730951},"39":{"tf":2.0},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"46":{"tf":1.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.7320508075688772}}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"44":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"e":{"df":5,"docs":{"13":{"tf":1.0},"26":{"tf":2.8284271247461903},"29":{"tf":3.7416573867739413},"39":{"tf":1.0},"8":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"s":{"c":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":5,"docs":{"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"41":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}}}},"df":5,"docs":{"17":{"tf":1.0},"34":{"tf":1.4142135623730951},"41":{"tf":1.4142135623730951},"44":{"tf":2.23606797749979},"47":{"tf":2.449489742783178}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"g":{"(":{"df":0,"docs":{},"e":{"df":1,"docs":{"23":{"tf":1.0}}}},"df":1,"docs":{"26":{"tf":4.0}}}},"u":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"31":{"tf":1.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"38":{"tf":1.0}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"37":{"tf":1.0},"47":{"tf":2.449489742783178}}}}},"df":0,"docs":{},"l":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"7":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"t":{"df":9,"docs":{"14":{"tf":1.7320508075688772},"15":{"tf":2.0},"16":{"tf":1.7320508075688772},"26":{"tf":4.898979485566356},"29":{"tf":5.916079783099616},"42":{"tf":3.4641016151377544},"44":{"tf":3.1622776601683795},"45":{"tf":2.8284271247461903},"47":{"tf":3.605551275463989}}}},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"35":{"tf":1.0}}}}}}}}},"n":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":2,"docs":{"23":{"tf":1.0},"5":{"tf":1.0}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"17":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"45":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"5":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":3,"docs":{"13":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"d":{"df":27,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.0},"15":{"tf":1.7320508075688772},"22":{"tf":1.7320508075688772},"23":{"tf":1.0},"24":{"tf":1.0},"25":{"tf":1.0},"26":{"tf":1.4142135623730951},"27":{"tf":1.0},"28":{"tf":1.7320508075688772},"29":{"tf":1.7320508075688772},"3":{"tf":1.0},"30":{"tf":1.0},"32":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.7320508075688772},"36":{"tf":2.449489742783178},"4":{"tf":1.0},"40":{"tf":1.4142135623730951},"41":{"tf":1.7320508075688772},"42":{"tf":1.4142135623730951},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951},"8":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":3,"docs":{"11":{"tf":1.0},"4":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"35":{"tf":1.0},"45":{"tf":1.4142135623730951},"8":{"tf":2.0}}}}},"w":{"_":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"12":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}}}},"df":5,"docs":{"12":{"tf":1.0},"17":{"tf":1.0},"32":{"tf":1.0},"36":{"tf":1.0},"5":{"tf":1.0}}},"x":{"df":0,"docs":{},"t":{"df":5,"docs":{"15":{"tf":1.4142135623730951},"35":{"tf":1.0},"42":{"tf":1.0},"46":{"tf":1.0},"8":{"tf":1.0}}}}},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"23":{"tf":1.0},"7":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":9,"docs":{"26":{"tf":1.0},"27":{"tf":1.4142135623730951},"29":{"tf":1.0},"31":{"tf":1.0},"36":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}},"h":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"8":{"tf":1.4142135623730951}}},"i":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{},"f":{"df":1,"docs":{"44":{"tf":1.0}},"i":{"df":1,"docs":{"23":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}}},"w":{"df":7,"docs":{"26":{"tf":1.0},"29":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"45":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"m":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}}}},"o":{"b":{"df":0,"docs":{},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"11":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":1,"docs":{"37":{"tf":1.0}},"s":{"df":1,"docs":{"33":{"tf":1.0}}}}}}}},"df":0,"docs":{},"h":{"df":1,"docs":{"26":{"tf":1.0}}},"k":{"(":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"(":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"43":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":5,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"41":{"tf":1.0},"42":{"tf":1.7320508075688772},"47":{"tf":2.0}}},"l":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}},"df":0,"docs":{}},"n":{"c":{"df":2,"docs":{"14":{"tf":1.0},"31":{"tf":1.0}}},"df":22,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"22":{"tf":1.0},"26":{"tf":1.7320508075688772},"27":{"tf":1.0},"3":{"tf":1.0},"33":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":1.4142135623730951},"37":{"tf":1.4142135623730951},"38":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951},"5":{"tf":1.4142135623730951},"6":{"tf":1.7320508075688772},"7":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}},"t":{"df":0,"docs":{},"o":{"df":1,"docs":{"44":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":9,"docs":{"10":{"tf":1.0},"3":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":2.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"39":{"tf":1.0}}}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"<":{"df":0,"docs":{},"t":{"df":1,"docs":{"38":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"18":{"tf":1.0},"29":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"28":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"15":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"18":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"t":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"x":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"_":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}},"df":6,"docs":{"22":{"tf":1.0},"31":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.0},"40":{"tf":1.0},"44":{"tf":1.4142135623730951}},"g":{"df":0,"docs":{},"o":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"26":{"tf":1.4142135623730951},"29":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"10":{"tf":1.0},"13":{"tf":1.0}}},"df":0,"docs":{}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":7,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"30":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.7320508075688772},"47":{"tf":2.0},"5":{"tf":1.0}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"22":{"tf":1.4142135623730951}}}}}}}}},"w":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"f":{"d":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":4,"docs":{"10":{"tf":1.0},"13":{"tf":1.7320508075688772},"30":{"tf":1.0},"41":{"tf":1.0}}}}}}}}}}},"p":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"29":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":2,"docs":{"6":{"tf":1.7320508075688772},"8":{"tf":1.0}}}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}}}},"df":0,"docs":{},"t":{"df":19,"docs":{"15":{"tf":1.0},"18":{"tf":1.4142135623730951},"23":{"tf":1.4142135623730951},"24":{"tf":1.0},"26":{"tf":1.0},"3":{"tf":1.0},"36":{"tf":1.7320508075688772},"37":{"tf":1.7320508075688772},"38":{"tf":1.7320508075688772},"39":{"tf":1.0},"40":{"tf":1.7320508075688772},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.7320508075688772},"46":{"tf":1.0},"47":{"tf":1.7320508075688772},"7":{"tf":1.0}},"i":{"df":1,"docs":{"13":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"s":{"df":4,"docs":{"15":{"tf":1.0},"39":{"tf":1.0},"42":{"tf":1.4142135623730951},"6":{"tf":1.0}}},"t":{"df":1,"docs":{"15":{"tf":1.0}}}},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"47":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":2,"docs":{"31":{"tf":1.0},"41":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":3,"docs":{"31":{"tf":1.0},"45":{"tf":2.23606797749979},"47":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":1,"docs":{"15":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"27":{"tf":1.0}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":3,"docs":{"45":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}}}}}},"h":{"a":{"df":0,"docs":{},"p":{"df":3,"docs":{"39":{"tf":1.0},"44":{"tf":1.0},"46":{"tf":1.0}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"31":{"tf":1.0}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}}}}}},"g":{"df":0,"docs":{},"m":{"df":1,"docs":{"30":{"tf":1.0}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":9,"docs":{"17":{"tf":2.23606797749979},"18":{"tf":2.6457513110645907},"23":{"tf":1.0},"35":{"tf":1.0},"36":{"tf":1.4142135623730951},"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"46":{"tf":1.0},"47":{"tf":1.0}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":2,"docs":{"18":{"tf":1.7320508075688772},"36":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"l":{"a":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"11":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":3,"docs":{"31":{"tf":1.4142135623730951},"35":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":2,"docs":{"41":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"l":{"df":3,"docs":{"28":{"tf":1.0},"42":{"tf":2.449489742783178},"47":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}},"p":{"df":1,"docs":{"44":{"tf":1.0}}},"s":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.0}}},"s":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":5,"docs":{"43":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"5":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}}}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":1,"docs":{"44":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"3":{"tf":1.0},"45":{"tf":1.0}}}}}}},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"28":{"tf":1.0}}}}}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":2,"docs":{"15":{"tf":1.0},"34":{"tf":1.0}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"2":{"tf":1.7320508075688772}}}}},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"31":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"11":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"15":{"tf":1.4142135623730951},"30":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":2,"docs":{"2":{"tf":1.0},"39":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}},"l":{"df":0,"docs":{},"n":{"!":{"(":{"\"":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}}},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":5,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0},"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"26":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"o":{"b":{"a":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"28":{"tf":1.0},"29":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":5,"docs":{"15":{"tf":1.0},"22":{"tf":1.0},"27":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"df":2,"docs":{"4":{"tf":1.0},"8":{"tf":1.0}},"e":{"d":{"df":1,"docs":{"7":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":7,"docs":{"18":{"tf":1.0},"22":{"tf":1.7320508075688772},"23":{"tf":2.0},"39":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":2.23606797749979},"47":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"s":{"(":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"i":{"df":3,"docs":{"44":{"tf":2.449489742783178},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"<":{"df":0,"docs":{},"f":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"df":14,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"23":{"tf":1.7320508075688772},"27":{"tf":1.0},"30":{"tf":1.0},"32":{"tf":1.0},"36":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.8284271247461903},"45":{"tf":2.23606797749979},"46":{"tf":1.0},"47":{"tf":1.7320508075688772},"5":{"tf":1.0}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":1,"docs":{"23":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"'":{"df":3,"docs":{"32":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.0}}},"df":11,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"16":{"tf":1.4142135623730951},"3":{"tf":1.4142135623730951},"30":{"tf":1.4142135623730951},"31":{"tf":1.0},"32":{"tf":1.0},"4":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.4142135623730951},"9":{"tf":1.0}},"m":{"df":1,"docs":{"30":{"tf":1.0}}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}},"p":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"22":{"tf":1.0},"39":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"13":{"tf":1.0},"42":{"tf":1.0}}}}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":15,"docs":{"11":{"tf":1.0},"13":{"tf":1.7320508075688772},"14":{"tf":1.0},"15":{"tf":1.0},"2":{"tf":1.7320508075688772},"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"24":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.0},"32":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"b":{"df":5,"docs":{"36":{"tf":1.4142135623730951},"37":{"tf":1.4142135623730951},"41":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.0}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":2,"docs":{"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"34":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"h":{"df":4,"docs":{"10":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"t":{"df":2,"docs":{"16":{"tf":1.0},"47":{"tf":1.0}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}},"e":{"df":9,"docs":{"17":{"tf":1.0},"23":{"tf":1.0},"31":{"tf":1.0},"37":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.0},"46":{"tf":1.0},"47":{"tf":2.0},"5":{"tf":1.4142135623730951}}}}},"i":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":1,"docs":{"35":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"w":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"14":{"tf":1.0}}},"t":{"df":2,"docs":{"10":{"tf":1.0},"34":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"7":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}}}},"d":{"/":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"a":{"b":{"df":0,"docs":{},"l":{"df":6,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"35":{"tf":2.8284271247461903},"44":{"tf":1.7320508075688772},"45":{"tf":2.23606797749979},"47":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"df":6,"docs":{"35":{"tf":2.0},"4":{"tf":2.449489742783178},"44":{"tf":1.7320508075688772},"45":{"tf":2.449489742783178},"47":{"tf":2.449489742783178},"5":{"tf":1.7320508075688772}},"i":{"df":5,"docs":{"4":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.0},"5":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"l":{"df":3,"docs":{"31":{"tf":1.0},"32":{"tf":1.0},"44":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"df":3,"docs":{"35":{"tf":1.0},"45":{"tf":1.7320508075688772},"46":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":12,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":2.0},"26":{"tf":1.0},"29":{"tf":4.0},"31":{"tf":1.0},"35":{"tf":1.4142135623730951},"44":{"tf":2.8284271247461903},"45":{"tf":3.0},"46":{"tf":1.0},"47":{"tf":1.7320508075688772},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"p":{"(":{"df":0,"docs":{},"|":{"df":0,"docs":{},"m":{"df":1,"docs":{"26":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"a":{"c":{"df":0,"docs":{},"t":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{".":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":1,"docs":{"26":{"tf":2.0}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":2.0}}},"y":{".":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"(":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":2.8284271247461903}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}}}},"h":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":0,"docs":{}}}},"v":{"df":1,"docs":{"23":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":2,"docs":{"42":{"tf":1.0},"44":{"tf":1.0}}}}},"v":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"(":{"0":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}},"df":3,"docs":{"42":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"39":{"tf":1.0},"47":{"tf":1.0}}}}},"g":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"26":{"tf":2.23606797749979}}},"df":0,"docs":{}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":2.23606797749979},"47":{"tf":1.4142135623730951}},"e":{"df":0,"docs":{},"r":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"r":{"df":3,"docs":{"42":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}}},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"15":{"tf":1.0}}}},"df":0,"docs":{}}}},"l":{"a":{"df":0,"docs":{},"t":{"df":3,"docs":{"14":{"tf":1.0},"33":{"tf":1.0},"44":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":1,"docs":{"32":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"s":{"df":1,"docs":{"1":{"tf":1.0}}}},"df":0,"docs":{}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"44":{"tf":1.0},"45":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"b":{"df":3,"docs":{"38":{"tf":1.0},"44":{"tf":1.0},"46":{"tf":1.0}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"v":{"df":2,"docs":{"42":{"tf":1.0},"44":{"tf":1.0}}}}},"p":{"df":1,"docs":{"45":{"tf":1.0}},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"45":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}}}},"l":{"a":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{},"i":{"df":1,"docs":{"45":{"tf":1.4142135623730951}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":3,"docs":{"10":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":1.0}}}}}},"q":{"df":1,"docs":{"45":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":5,"docs":{"12":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"44":{"tf":1.0},"7":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"s":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"18":{"tf":1.0},"45":{"tf":1.0}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":2,"docs":{"32":{"tf":1.0},"44":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"<":{"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{":":{":":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":7,"docs":{"22":{"tf":1.4142135623730951},"23":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.4142135623730951},"7":{"tf":1.0}}}}}},"t":{"df":2,"docs":{"39":{"tf":1.4142135623730951},"47":{"tf":1.0}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"30":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":10,"docs":{"13":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":2.0},"26":{"tf":2.23606797749979},"29":{"tf":2.8284271247461903},"39":{"tf":1.7320508075688772},"41":{"tf":1.4142135623730951},"44":{"tf":2.23606797749979},"8":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}}}},"o":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"df":0,"docs":{}},"s":{"df":1,"docs":{"14":{"tf":1.0}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":2,"docs":{"23":{"tf":1.0},"8":{"tf":1.0}}}},"n":{"df":18,"docs":{"11":{"tf":1.0},"15":{"tf":1.0},"23":{"tf":1.4142135623730951},"25":{"tf":1.7320508075688772},"26":{"tf":3.4641016151377544},"27":{"tf":1.0},"29":{"tf":4.69041575982343},"3":{"tf":1.0},"30":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.7320508075688772},"46":{"tf":2.0},"47":{"tf":2.449489742783178},"5":{"tf":1.0},"6":{"tf":1.4142135623730951},"7":{"tf":1.0},"8":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"'":{"df":3,"docs":{"17":{"tf":1.0},"2":{"tf":1.0},"24":{"tf":1.0}}},"df":5,"docs":{"13":{"tf":1.4142135623730951},"22":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.4142135623730951},"38":{"tf":1.0}}}}}},"s":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":1,"docs":{"13":{"tf":1.7320508075688772}}}},"k":{"df":0,"docs":{},"e":{"df":2,"docs":{"26":{"tf":1.0},"31":{"tf":1.0}}}},"m":{"df":0,"docs":{},"e":{"df":6,"docs":{"15":{"tf":1.0},"22":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"5":{"tf":1.0}}}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"35":{"tf":1.0},"39":{"tf":1.0}}}}},"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{".":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"(":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"n":{"c":{"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"26":{"tf":2.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"_":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"k":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"26":{"tf":2.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":2,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907}},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"15":{"tf":1.4142135623730951},"26":{"tf":2.449489742783178},"29":{"tf":3.872983346207417}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":5,"docs":{"14":{"tf":1.0},"15":{"tf":1.4142135623730951},"3":{"tf":1.0},"45":{"tf":1.7320508075688772},"5":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"34":{"tf":1.0},"44":{"tf":1.0}}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"28":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":4,"docs":{"26":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.4142135623730951},"5":{"tf":1.0}},"m":{"df":1,"docs":{"44":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"27":{"tf":1.0}}}},"df":0,"docs":{}},"f":{".":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"s":{"c":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"x":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}}},"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{".":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"&":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"43":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"(":{")":{".":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"(":{"&":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"r":{"c":{"df":0,"docs":{},"v":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"r":{"c":{"df":0,"docs":{},"v":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"(":{"0":{")":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"43":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":1,"docs":{"42":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":3,"docs":{"44":{"tf":2.8284271247461903},"45":{"tf":2.6457513110645907},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}},"w":{"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}}}}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"p":{"df":2,"docs":{"42":{"tf":1.7320508075688772},"47":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.4142135623730951},"45":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":6,"docs":{"41":{"tf":1.0},"42":{"tf":2.449489742783178},"43":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":2.0},"47":{"tf":2.8284271247461903}}}},"n":{"d":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"/":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":1,"docs":{"44":{"tf":1.4142135623730951}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}},"df":13,"docs":{"18":{"tf":1.7320508075688772},"23":{"tf":2.0},"26":{"tf":1.0},"29":{"tf":1.4142135623730951},"34":{"tf":1.4142135623730951},"35":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"41":{"tf":1.7320508075688772},"44":{"tf":2.449489742783178},"45":{"tf":3.0},"47":{"tf":3.3166247903554},"5":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"\"":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{",":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"d":{"!":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":1.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"w":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"(":{"b":{"\"":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"_":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"\"":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"26":{"tf":2.0}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"h":{",":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":1,"docs":{"26":{"tf":2.0}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"26":{"tf":2.0}}},"y":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"\"":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{",":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"d":{"!":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}},"df":2,"docs":{"29":{"tf":3.7416573867739413},"47":{"tf":1.0}}}}},"df":0,"docs":{},"s":{"df":3,"docs":{"23":{"tf":1.0},"37":{"tf":1.0},"44":{"tf":1.0}}},"t":{"df":5,"docs":{"23":{"tf":1.0},"29":{"tf":2.8284271247461903},"44":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":2.449489742783178}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":3,"docs":{"22":{"tf":1.0},"35":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":5,"docs":{"37":{"tf":1.7320508075688772},"38":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}},"t":{"df":5,"docs":{"31":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"p":{"df":4,"docs":{"40":{"tf":1.7320508075688772},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.0}}}}}},"h":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":3,"docs":{"15":{"tf":1.4142135623730951},"30":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"26":{"tf":1.0}}}},"u":{"df":0,"docs":{},"l":{"d":{"df":0,"docs":{},"n":{"'":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"44":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"w":{"df":1,"docs":{"30":{"tf":1.0}}}},"u":{"df":0,"docs":{},"t":{"d":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":2,"docs":{"31":{"tf":1.0},"43":{"tf":1.0}}}}}},"df":1,"docs":{"43":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"l":{"df":4,"docs":{"20":{"tf":1.7320508075688772},"35":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"7":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":3,"docs":{"11":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}},"i":{"c":{"df":1,"docs":{"31":{"tf":1.0}}},"df":4,"docs":{"15":{"tf":1.0},"23":{"tf":1.0},"29":{"tf":1.0},"7":{"tf":1.0}},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}}}}}},"n":{"df":1,"docs":{"44":{"tf":1.0}},"g":{"df":0,"docs":{},"l":{"df":7,"docs":{"27":{"tf":1.0},"32":{"tf":1.0},"37":{"tf":1.0},"38":{"tf":1.4142135623730951},"47":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0}}}}},"t":{"df":1,"docs":{"35":{"tf":1.0}},"u":{"a":{"df":0,"docs":{},"t":{"df":3,"docs":{"22":{"tf":1.0},"23":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}}},"k":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":1,"docs":{"47":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}}}}}}},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"35":{"tf":1.0}}},".":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"41":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}}},"df":17,"docs":{"13":{"tf":1.0},"29":{"tf":3.872983346207417},"30":{"tf":1.7320508075688772},"31":{"tf":1.0},"34":{"tf":1.0},"35":{"tf":2.0},"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.7320508075688772},"41":{"tf":1.0},"43":{"tf":1.7320508075688772},"44":{"tf":1.4142135623730951},"45":{"tf":2.6457513110645907},"47":{"tf":4.795831523312719},"5":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}},"v":{"df":1,"docs":{"44":{"tf":1.0}}}},"m":{"df":0,"docs":{},"e":{"(":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"g":{"df":1,"docs":{"26":{"tf":4.0}}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":5,"docs":{"10":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"3":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"c":{"df":39,"docs":{"10":{"tf":2.23606797749979},"11":{"tf":2.23606797749979},"12":{"tf":2.0},"13":{"tf":1.0},"14":{"tf":2.23606797749979},"15":{"tf":2.23606797749979},"16":{"tf":1.4142135623730951},"17":{"tf":2.0},"18":{"tf":2.23606797749979},"19":{"tf":1.0},"2":{"tf":1.7320508075688772},"20":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.4142135623730951},"23":{"tf":2.6457513110645907},"24":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.0},"30":{"tf":1.4142135623730951},"31":{"tf":1.0},"32":{"tf":2.449489742783178},"33":{"tf":1.7320508075688772},"34":{"tf":1.7320508075688772},"35":{"tf":2.0},"36":{"tf":2.23606797749979},"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951},"40":{"tf":2.0},"41":{"tf":2.23606797749979},"42":{"tf":3.7416573867739413},"43":{"tf":1.0},"44":{"tf":4.795831523312719},"45":{"tf":2.6457513110645907},"46":{"tf":2.0},"47":{"tf":4.358898943540674},"5":{"tf":2.8284271247461903},"9":{"tf":1.0}},"e":{"'":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":2,"docs":{"31":{"tf":1.4142135623730951},"45":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"23":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":12,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"11":{"tf":1.0},"15":{"tf":1.0},"2":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":3,"docs":{"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}}}}},"t":{"df":0,"docs":{},"e":{"df":11,"docs":{"35":{"tf":1.7320508075688772},"39":{"tf":1.0},"4":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"46":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.7320508075688772},"7":{"tf":1.7320508075688772},"9":{"tf":1.0}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}}}}},"u":{"df":1,"docs":{"23":{"tf":1.0}}}}},"d":{":":{":":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"c":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"<":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"22":{"tf":1.0},"23":{"tf":1.7320508075688772}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"i":{"df":0,"docs":{},"o":{":":{":":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":3,"docs":{"26":{"tf":2.0},"29":{"tf":2.6457513110645907},"39":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"e":{"<":{"df":0,"docs":{},"t":{"df":1,"docs":{"38":{"tf":1.0}}},"z":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"38":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"s":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{":":{":":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"(":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"f":{"8":{"(":{"&":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{")":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"(":{")":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"{":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":1,"docs":{"2":{"tf":1.4142135623730951}}}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":5,"docs":{"15":{"tf":1.0},"23":{"tf":1.4142135623730951},"35":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"p":{"df":4,"docs":{"3":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.0},"8":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"27":{"tf":1.0}}}}}}},"i":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"45":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"23":{"tf":1.0}}}}},"u":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"36":{"tf":1.4142135623730951},"37":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"u":{"b":{"df":1,"docs":{"44":{"tf":1.0}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"23":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"l":{"df":1,"docs":{"35":{"tf":1.0}},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"30":{"tf":1.0}}}}}}}},"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"23":{"tf":1.0},"27":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{}}}},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"44":{"tf":1.0},"5":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"31":{"tf":1.0}}}},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"22":{"tf":1.0}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"39":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"31":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"23":{"tf":1.4142135623730951}},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"x":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":2,"docs":{"11":{"tf":1.0},"44":{"tf":1.0}}}}}}}},"t":{":":{":":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":5,"docs":{"37":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.23606797749979}}}}}}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":8,"docs":{"23":{"tf":1.0},"30":{"tf":1.0},"31":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.449489742783178},"45":{"tf":1.0},"7":{"tf":1.7320508075688772}},"n":{"df":1,"docs":{"44":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"15":{"tf":1.0}}}}},"c":{"df":0,"docs":{},"p":{"df":1,"docs":{"30":{"tf":1.0}}}},"df":6,"docs":{"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.8284271247461903}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"35":{"tf":1.0},"44":{"tf":1.4142135623730951}}}},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"31":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"m":{"df":4,"docs":{"32":{"tf":1.0},"43":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":1,"docs":{"4":{"tf":1.4142135623730951}}}}}}}}}}},"h":{"a":{"df":0,"docs":{},"t":{"'":{"df":6,"docs":{"29":{"tf":1.0},"33":{"tf":1.4142135623730951},"34":{"tf":1.0},"35":{"tf":1.0},"39":{"tf":1.0},"41":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":2,"docs":{"17":{"tf":1.0},"31":{"tf":1.0}}}}}}},"r":{"df":0,"docs":{},"e":{"'":{"df":2,"docs":{"17":{"tf":1.0},"35":{"tf":1.0}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"37":{"tf":1.0},"43":{"tf":1.0}}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":13,"docs":{"12":{"tf":1.0},"15":{"tf":1.0},"22":{"tf":1.0},"3":{"tf":1.7320508075688772},"31":{"tf":1.0},"33":{"tf":1.0},"37":{"tf":1.0},"39":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.0}}},"k":{"df":2,"docs":{"31":{"tf":1.4142135623730951},"7":{"tf":1.0}}}},"r":{"d":{"df":3,"docs":{"13":{"tf":1.0},"15":{"tf":1.0},"35":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"23":{"tf":1.0}}}}}}}}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":7,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.0},"23":{"tf":1.0},"3":{"tf":1.0},"5":{"tf":1.0}}}},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":3,"docs":{"18":{"tf":1.0},"44":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":7,"docs":{"27":{"tf":2.23606797749979},"3":{"tf":1.0},"4":{"tf":1.0},"47":{"tf":1.0},"6":{"tf":2.23606797749979},"7":{"tf":1.0},"8":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":4,"docs":{"12":{"tf":1.0},"35":{"tf":1.7320508075688772},"45":{"tf":1.4142135623730951},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":5,"docs":{"13":{"tf":1.4142135623730951},"2":{"tf":1.0},"23":{"tf":1.0},"29":{"tf":1.0},"44":{"tf":1.0}}}}}}},"u":{"df":1,"docs":{"10":{"tf":1.0}}}},"i":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"32":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}},"m":{"df":0,"docs":{},"e":{"df":7,"docs":{"11":{"tf":1.0},"14":{"tf":1.4142135623730951},"15":{"tf":2.23606797749979},"4":{"tf":1.4142135623730951},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"d":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":1,"docs":{"31":{"tf":1.0}}}}},"r":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"(":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"s":{"(":{"5":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"{":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}},"df":0,"docs":{}},"df":8,"docs":{"11":{"tf":1.0},"14":{"tf":3.0},"15":{"tf":3.0},"16":{"tf":1.7320508075688772},"32":{"tf":1.0},"4":{"tf":1.0},"5":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}}},"o":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":5,"docs":{"16":{"tf":1.0},"32":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.0},"9":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"15":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"42":{"tf":3.1622776601683795},"47":{"tf":2.8284271247461903}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":4,"docs":{"42":{"tf":1.7320508075688772},"44":{"tf":3.605551275463989},"45":{"tf":1.7320508075688772},"47":{"tf":1.7320508075688772}}}}},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"44":{"tf":1.0}}}},"p":{"df":1,"docs":{"14":{"tf":1.0}},"i":{"c":{"df":1,"docs":{"37":{"tf":1.0}}},"df":0,"docs":{}}},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"31":{"tf":1.0}}}},"df":0,"docs":{}},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"22":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"y":{"df":1,"docs":{"26":{"tf":2.0}}}},"r":{"a":{"c":{"df":0,"docs":{},"e":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"k":{"df":6,"docs":{"15":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"8":{"tf":1.0}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":1,"docs":{"7":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"44":{"tf":1.0}}},"df":10,"docs":{"10":{"tf":1.0},"13":{"tf":1.4142135623730951},"22":{"tf":1.7320508075688772},"23":{"tf":1.7320508075688772},"28":{"tf":1.0},"29":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":1.0}}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"30":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"37":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"30":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"i":{"df":3,"docs":{"22":{"tf":1.0},"23":{"tf":1.0},"4":{"tf":1.0}},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"12":{"tf":1.4142135623730951},"35":{"tf":1.7320508075688772},"42":{"tf":1.0},"45":{"tf":1.7320508075688772},"47":{"tf":1.7320508075688772}}}}}}},"o":{"df":0,"docs":{},"u":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"44":{"tf":1.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"e":{"df":2,"docs":{"45":{"tf":1.7320508075688772},"47":{"tf":1.4142135623730951}}}}},"u":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"41":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"47":{"tf":1.0}}}},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.7320508075688772}}}}}}},"w":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"k":{"df":1,"docs":{"37":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":9,"docs":{"18":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"24":{"tf":1.0},"26":{"tf":2.0},"3":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.4142135623730951},"7":{"tf":1.0}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":20,"docs":{"11":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":2.6457513110645907},"14":{"tf":1.0},"22":{"tf":1.7320508075688772},"23":{"tf":3.3166247903554},"24":{"tf":1.0},"28":{"tf":3.0},"29":{"tf":2.23606797749979},"36":{"tf":2.6457513110645907},"37":{"tf":2.6457513110645907},"38":{"tf":1.4142135623730951},"39":{"tf":3.7416573867739413},"40":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":2.0},"47":{"tf":2.23606797749979},"5":{"tf":1.0},"9":{"tf":1.0}}},"i":{"c":{"df":1,"docs":{"6":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"11":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.0}}}}}},"n":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"14":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":4,"docs":{"35":{"tf":1.0},"39":{"tf":1.4142135623730951},"4":{"tf":1.0},"47":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":2,"docs":{"20":{"tf":1.7320508075688772},"29":{"tf":3.872983346207417}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"29":{"tf":1.0}}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"42":{"tf":1.4142135623730951},"47":{"tf":1.0}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"s":{"a":{"df":0,"docs":{},"f":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":5,"docs":{"14":{"tf":1.0},"18":{"tf":1.0},"35":{"tf":1.0},"4":{"tf":1.0},"46":{"tf":1.4142135623730951}}}}}},"p":{"d":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"5":{"tf":1.0}}}},"df":0,"docs":{}},"df":17,"docs":{"11":{"tf":1.0},"15":{"tf":1.0},"17":{"tf":2.0},"18":{"tf":1.4142135623730951},"30":{"tf":1.0},"31":{"tf":1.0},"35":{"tf":2.0},"36":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.4142135623730951},"44":{"tf":2.6457513110645907},"45":{"tf":2.449489742783178},"47":{"tf":2.0},"5":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"47":{"tf":1.0}}}}},"s":{"b":{"df":1,"docs":{"11":{"tf":1.0}}},"df":36,"docs":{"10":{"tf":1.7320508075688772},"11":{"tf":2.23606797749979},"12":{"tf":1.4142135623730951},"13":{"tf":2.23606797749979},"14":{"tf":2.23606797749979},"15":{"tf":2.449489742783178},"16":{"tf":1.7320508075688772},"17":{"tf":1.7320508075688772},"18":{"tf":2.23606797749979},"19":{"tf":1.0},"2":{"tf":1.4142135623730951},"20":{"tf":1.0},"21":{"tf":1.0},"22":{"tf":1.7320508075688772},"23":{"tf":1.7320508075688772},"26":{"tf":4.242640687119285},"27":{"tf":1.0},"28":{"tf":2.0},"29":{"tf":5.291502622129181},"30":{"tf":1.4142135623730951},"31":{"tf":2.449489742783178},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"37":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.7320508075688772},"4":{"tf":1.0},"41":{"tf":1.0},"44":{"tf":2.6457513110645907},"45":{"tf":2.0},"46":{"tf":1.4142135623730951},"47":{"tf":2.449489742783178},"6":{"tf":1.4142135623730951},"7":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}},"e":{"d":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":2,"docs":{"45":{"tf":2.0},"47":{"tf":2.23606797749979}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":7,"docs":{"22":{"tf":1.7320508075688772},"35":{"tf":1.0},"36":{"tf":1.0},"38":{"tf":1.0},"39":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.7320508075688772}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":4,"docs":{"11":{"tf":1.0},"31":{"tf":1.0},"39":{"tf":1.0},"47":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"5":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":6,"docs":{"15":{"tf":1.0},"18":{"tf":1.0},"26":{"tf":3.0},"29":{"tf":3.7416573867739413},"37":{"tf":1.0},"44":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"i":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"7":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"29":{"tf":1.0},"44":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{},"e":{"c":{"<":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"47":{"tf":1.0}}}}},"t":{"df":1,"docs":{"38":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"c":{"<":{"df":0,"docs":{},"u":{"8":{"df":2,"docs":{"39":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":1,"docs":{"47":{"tf":1.4142135623730951}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"17":{"tf":1.0},"30":{"tf":1.0}}},"s":{"a":{"df":1,"docs":{"47":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"1":{"tf":1.4142135623730951},"13":{"tf":1.0},"26":{"tf":1.0},"29":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"i":{"a":{"df":4,"docs":{"11":{"tf":1.0},"26":{"tf":2.0},"33":{"tf":1.0},"42":{"tf":1.0}}},"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"47":{"tf":1.0}}}},"df":0,"docs":{}},"s":{"df":2,"docs":{"6":{"tf":1.4142135623730951},"7":{"tf":1.4142135623730951}}}},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":9,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"3":{"tf":1.0},"30":{"tf":1.0},"35":{"tf":1.4142135623730951},"4":{"tf":2.23606797749979},"43":{"tf":1.0},"44":{"tf":1.7320508075688772},"8":{"tf":1.7320508075688772}}}},"k":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":4,"docs":{"36":{"tf":1.4142135623730951},"41":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":4,"docs":{"36":{"tf":1.0},"41":{"tf":1.4142135623730951},"44":{"tf":1.0},"47":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":8,"docs":{"17":{"tf":2.0},"18":{"tf":1.0},"35":{"tf":1.7320508075688772},"36":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":2.23606797749979},"47":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":2,"docs":{"35":{"tf":1.4142135623730951},"44":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"t":{"df":10,"docs":{"12":{"tf":1.0},"23":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"31":{"tf":1.0},"34":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.7320508075688772},"46":{"tf":1.0},"9":{"tf":1.0}}}},"r":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}},"df":0,"docs":{}}},"y":{"df":13,"docs":{"13":{"tf":1.4142135623730951},"15":{"tf":1.0},"17":{"tf":1.0},"23":{"tf":1.0},"3":{"tf":1.4142135623730951},"31":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":1.7320508075688772},"45":{"tf":1.0},"47":{"tf":1.4142135623730951},"8":{"tf":1.0}}}},"df":0,"docs":{},"e":{"'":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":6,"docs":{"36":{"tf":1.0},"37":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"44":{"tf":1.4142135623730951},"45":{"tf":1.7320508075688772}}}},"r":{"df":3,"docs":{"30":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":1.4142135623730951}}},"v":{"df":3,"docs":{"31":{"tf":1.0},"40":{"tf":1.0},"44":{"tf":1.7320508075688772}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"22":{"tf":1.0},"27":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":3,"docs":{"31":{"tf":1.0},"42":{"tf":1.0},"47":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":2,"docs":{"10":{"tf":1.0},"47":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":6,"docs":{"12":{"tf":1.0},"39":{"tf":1.0},"44":{"tf":2.23606797749979},"46":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}}}}}}},"i":{"c":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":3,"docs":{"16":{"tf":1.4142135623730951},"47":{"tf":1.0},"5":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"26":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":2,"docs":{"45":{"tf":1.0},"47":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":1,"docs":{"44":{"tf":1.4142135623730951}},"n":{"df":5,"docs":{"18":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.4142135623730951}}}}},"n":{"'":{"df":0,"docs":{},"t":{"df":3,"docs":{"35":{"tf":1.0},"4":{"tf":1.0},"44":{"tf":1.0}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"33":{"tf":1.0}}}}},"df":0,"docs":{}},"r":{"d":{"df":1,"docs":{"45":{"tf":1.0}}},"df":0,"docs":{},"k":{"df":19,"docs":{"14":{"tf":1.4142135623730951},"15":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"23":{"tf":1.0},"27":{"tf":1.0},"3":{"tf":1.7320508075688772},"30":{"tf":1.0},"32":{"tf":1.0},"36":{"tf":1.0},"4":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"47":{"tf":1.4142135623730951},"5":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"l":{"d":{"!":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"w":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"29":{"tf":2.6457513110645907}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"30":{"tf":1.0},"44":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":6,"docs":{"11":{"tf":1.0},"13":{"tf":1.0},"28":{"tf":1.4142135623730951},"30":{"tf":1.0},"45":{"tf":1.0},"5":{"tf":1.0}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"31":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"11":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"a":{"b":{"df":0,"docs":{},"l":{"df":5,"docs":{"12":{"tf":1.0},"35":{"tf":2.0},"44":{"tf":2.0},"45":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"df":14,"docs":{"26":{"tf":1.0},"28":{"tf":1.0},"29":{"tf":1.0},"3":{"tf":1.4142135623730951},"31":{"tf":1.4142135623730951},"35":{"tf":1.0},"4":{"tf":1.7320508075688772},"40":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":4,"docs":{"26":{"tf":1.0},"27":{"tf":1.0},"31":{"tf":1.0},"35":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"44":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"'":{"d":{"df":1,"docs":{"44":{"tf":1.0}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":4,"docs":{"15":{"tf":1.0},"26":{"tf":1.0},"28":{"tf":1.0},"42":{"tf":1.0}}}},"r":{"df":3,"docs":{"1":{"tf":1.0},"28":{"tf":1.0},"33":{"tf":1.0}}},"v":{"df":1,"docs":{"5":{"tf":1.0}}}},".":{"\"":{")":{".":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"26":{"tf":2.0}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"f":{"df":1,"docs":{"2":{"tf":1.0}}}}}}}}}},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":1,"docs":{"23":{"tf":1.0}},"m":{"df":0,"docs":{},"q":{"'":{"df":2,"docs":{"35":{"tf":1.4142135623730951},"45":{"tf":1.0}}},"df":20,"docs":{"11":{"tf":1.0},"30":{"tf":2.449489742783178},"31":{"tf":1.7320508075688772},"32":{"tf":1.0},"33":{"tf":1.4142135623730951},"34":{"tf":1.0},"35":{"tf":1.7320508075688772},"36":{"tf":1.0},"37":{"tf":1.4142135623730951},"38":{"tf":1.0},"39":{"tf":1.0},"40":{"tf":1.0},"41":{"tf":1.0},"42":{"tf":1.0},"43":{"tf":1.7320508075688772},"44":{"tf":1.7320508075688772},"45":{"tf":2.23606797749979},"46":{"tf":1.0},"47":{"tf":4.0},"9":{"tf":1.0}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":4,"docs":{"36":{"tf":1.4142135623730951},"41":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}},"e":{":":{":":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"_":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"47":{"tf":1.0}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"<":{"df":0,"docs":{},"t":{"df":5,"docs":{"37":{"tf":1.0},"39":{"tf":1.0},"43":{"tf":1.0},"44":{"tf":1.0},"47":{"tf":2.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}}},"m":{"df":0,"docs":{},"q":{":":{":":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"37":{"tf":1.4142135623730951},"38":{"tf":1.0},"47":{"tf":1.0}}}},"df":0,"docs":{}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"45":{"tf":1.0}}}}}}}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{":":{":":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"35":{"tf":1.0}}}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"v":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"39":{"tf":1.0}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"44":{"tf":1.0}}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":2,"docs":{"41":{"tf":1.4142135623730951},"47":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":1,"docs":{"47":{"tf":1.4142135623730951}}}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"'":{"df":2,"docs":{"31":{"tf":1.0},"42":{"tf":1.0}}},"df":8,"docs":{"31":{"tf":1.7320508075688772},"35":{"tf":2.449489742783178},"36":{"tf":1.0},"37":{"tf":1.0},"41":{"tf":1.0},"43":{"tf":1.4142135623730951},"44":{"tf":3.1622776601683795},"45":{"tf":3.4641016151377544}}}}}},"df":0,"docs":{}}}}}},"title":{"root":{"a":{"d":{"df":1,"docs":{"15":{"tf":1.0}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":1,"docs":{"1":{"tf":1.0}}}},"s":{"df":0,"docs":{},"f":{"d":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"i":{"df":1,"docs":{"39":{"tf":1.0}}}},"df":0,"docs":{}}},"y":{"df":0,"docs":{},"n":{"c":{"/":{"a":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"24":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":3,"docs":{"25":{"tf":1.0},"28":{"tf":1.0},"7":{"tf":1.0}}},"df":0,"docs":{}}}}},"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"b":{"a":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"5":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":1,"docs":{"35":{"tf":1.0}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"'":{"df":1,"docs":{"0":{"tf":1.0}}},"df":3,"docs":{"21":{"tf":1.0},"24":{"tf":1.0},"9":{"tf":1.0}}}}}}}},"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":2,"docs":{"19":{"tf":1.0},"34":{"tf":1.0}}}}}}},"df":0,"docs":{}},"o":{"d":{"df":0,"docs":{},"e":{"df":3,"docs":{"25":{"tf":1.0},"47":{"tf":1.0},"7":{"tf":1.0}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":1,"docs":{"32":{"tf":1.0}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}},"n":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"41":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":5,"docs":{"12":{"tf":1.0},"36":{"tf":1.0},"40":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"11":{"tf":1.0}}}}}}}}},"df":0,"docs":{}}},"i":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"31":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"o":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":1,"docs":{"43":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"a":{"b":{"df":0,"docs":{},"l":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"38":{"tf":1.0}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"21":{"tf":1.0},"23":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":9,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"3":{"tf":1.0},"32":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0},"5":{"tf":1.0},"7":{"tf":1.0}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":1,"docs":{"23":{"tf":1.0}}},"df":0,"docs":{}}}}}}}}},"x":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"30":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"26":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"f":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"26":{"tf":1.0},"29":{"tf":1.0}}}}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"11":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"30":{"tf":1.0},"47":{"tf":1.0}}}},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"29":{"tf":1.0}}}}}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"12":{"tf":1.0},"33":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"46":{"tf":1.0}}}},"df":0,"docs":{}}}}},"h":{"a":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"l":{"df":1,"docs":{"21":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"43":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"i":{"df":0,"docs":{},"i":{"df":1,"docs":{"40":{"tf":1.0}},"i":{"df":1,"docs":{"44":{"tf":1.0}}}},"o":{"df":2,"docs":{"28":{"tf":1.0},"29":{"tf":1.0}}},"v":{"df":1,"docs":{"45":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":5,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"3":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.0}}}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"g":{"df":2,"docs":{"37":{"tf":1.0},"38":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"d":{"df":2,"docs":{"40":{"tf":1.0},"42":{"tf":1.0}}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"11":{"tf":1.0}}}}}}}},"p":{"df":0,"docs":{},"s":{"c":{"df":1,"docs":{"34":{"tf":1.0}}},"df":0,"docs":{}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":1,"docs":{"27":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"22":{"tf":1.0}}}}}}}}},"w":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":1,"docs":{"13":{"tf":1.0}}}}}}}}}}},"p":{"a":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"6":{"tf":1.0}}}}}}},"df":0,"docs":{},"t":{"df":4,"docs":{"36":{"tf":1.0},"40":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":2,"docs":{"17":{"tf":1.0},"18":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":2,"docs":{"44":{"tf":1.0},"45":{"tf":1.0}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"16":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"45":{"tf":1.0}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"42":{"tf":1.0}}}}}}},"u":{"df":0,"docs":{},"n":{"df":1,"docs":{"25":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"40":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"20":{"tf":1.0}}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":1,"docs":{"38":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"c":{"df":13,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"15":{"tf":1.0},"18":{"tf":1.0},"32":{"tf":1.0},"33":{"tf":1.0},"34":{"tf":1.0},"36":{"tf":1.0},"40":{"tf":1.0},"42":{"tf":1.0},"44":{"tf":1.0},"45":{"tf":1.0},"47":{"tf":1.0}}},"df":0,"docs":{}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}}}}},"h":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"27":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"i":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"23":{"tf":1.0},"42":{"tf":1.0}}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"2":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":5,"docs":{"23":{"tf":1.0},"28":{"tf":1.0},"36":{"tf":1.0},"37":{"tf":1.0},"39":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":1,"docs":{"20":{"tf":1.0}}}}},"s":{"df":2,"docs":{"10":{"tf":1.0},"18":{"tf":1.0}}}},"v":{"df":0,"docs":{},"s":{"df":2,"docs":{"6":{"tf":1.0},"7":{"tf":1.0}}}},"w":{"a":{"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"35":{"tf":1.0}}}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"16":{"tf":1.0}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":2,"docs":{"14":{"tf":1.0},"3":{"tf":1.0}}}}},"r":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"q":{"df":2,"docs":{"30":{"tf":1.0},"47":{"tf":1.0}}}}}}}}}}},"lang":"English","pipeline":["trimmer","stopWordFilter","stemmer"],"ref":"id","version":"0.9.5"},"results_options":{"limit_results":30,"teaser_word_count":30},"search_options":{"bool":"OR","expand":true,"fields":{"body":{"boost":1},"breadcrumbs":{"boost":1},"title":{"boost":2}}}} \ No newline at end of file diff --git a/timer_example.rs b/timer_example.rs new file mode 100644 index 00000000..f83d6bda --- /dev/null +++ b/timer_example.rs @@ -0,0 +1,30 @@ +// ANCHOR: all +use std::time::Duration; + +use calloop::{ + timer::{TimeoutAction, Timer}, + EventLoop, +}; + +fn main() { + let mut event_loop = EventLoop::try_new().expect("Failed to initialize the event loop!"); + + // ANCHOR: decl_source + let timer = Timer::from_duration(Duration::from_secs(5)); + // ANCHOR_END: decl_source + + // ANCHOR: insert_source + event_loop + .handle() + .insert_source(timer, |deadline, _: &mut (), _shared_data| { + println!("Event fired for: {:?}", deadline); + TimeoutAction::Drop + }) + .expect("Failed to insert event source!"); + // ANCHOR_END: insert_source + + event_loop + .dispatch(None, &mut ()) + .expect("Error during event loop!"); +} +// ANCHOR_END: all diff --git a/tomorrow-night.css b/tomorrow-night.css new file mode 100644 index 00000000..f7197925 --- /dev/null +++ b/tomorrow-night.css @@ -0,0 +1,104 @@ +/* Tomorrow Night Theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + +/* Tomorrow Comment */ +.hljs-comment { + color: #969896; +} + +/* Tomorrow Red */ +.hljs-variable, +.hljs-attribute, +.hljs-tag, +.hljs-regexp, +.ruby .hljs-constant, +.xml .hljs-tag .hljs-title, +.xml .hljs-pi, +.xml .hljs-doctype, +.html .hljs-doctype, +.css .hljs-id, +.css .hljs-class, +.css .hljs-pseudo { + color: #cc6666; +} + +/* Tomorrow Orange */ +.hljs-number, +.hljs-preprocessor, +.hljs-pragma, +.hljs-built_in, +.hljs-literal, +.hljs-params, +.hljs-constant { + color: #de935f; +} + +/* Tomorrow Yellow */ +.ruby .hljs-class .hljs-title, +.css .hljs-rule .hljs-attribute { + color: #f0c674; +} + +/* Tomorrow Green */ +.hljs-string, +.hljs-value, +.hljs-inheritance, +.hljs-header, +.hljs-name, +.ruby .hljs-symbol, +.xml .hljs-cdata { + color: #b5bd68; +} + +/* Tomorrow Aqua */ +.hljs-title, +.css .hljs-hexcolor { + color: #8abeb7; +} + +/* Tomorrow Blue */ +.hljs-function, +.python .hljs-decorator, +.python .hljs-title, +.ruby .hljs-function .hljs-title, +.ruby .hljs-title .hljs-keyword, +.perl .hljs-sub, +.javascript .hljs-title, +.coffeescript .hljs-title { + color: #81a2be; +} + +/* Tomorrow Purple */ +.hljs-keyword, +.javascript .hljs-function { + color: #b294bb; +} + +.hljs { + display: block; + overflow-x: auto; + background: #1d1f21; + color: #c5c8c6; + padding: 0.5em; + -webkit-text-size-adjust: none; +} + +.coffeescript .javascript, +.javascript .xml, +.tex .hljs-formula, +.xml .javascript, +.xml .vbscript, +.xml .css, +.xml .hljs-cdata { + opacity: 0.5; +} + +.hljs-addition { + color: #718c00; +} + +.hljs-deletion { + color: #c82829; +} diff --git a/zmqsource.rs b/zmqsource.rs new file mode 100644 index 00000000..cb57af79 --- /dev/null +++ b/zmqsource.rs @@ -0,0 +1,262 @@ +//! A Calloop event source implementation for ZeroMQ sockets. + +use std::{collections, io}; + +use anyhow::Context; + +/// A Calloop event source that contains a ZeroMQ socket (of any kind) and a +/// Calloop MPSC channel for sending over it. +/// +/// The basic interface is: +/// - create a zmq::Socket for your ZeroMQ socket +/// - use `ZeroMQSource::from_socket()` to turn it into a Calloop event source +/// (plus the sending end of the channel) +/// - queue messages to be sent by sending them on the sending end of the MPSC +/// channel +/// - add the event source to the Calloop event loop with a callback to handle +/// reading +/// - the sending end of the MPSC channel can be cloned and sent across threads +/// if necessary +/// +/// This type is parameterised by `T`: +/// +/// T where T: IntoIterator, T::Item: Into +// +/// This means that `T` is anything that can be converted to an iterator, and +/// the items in the iterator are anything that can be converted to a +/// `zmq::Message`. So eg. a `Vec` would work. +/// +/// The callback is called whenever the underlying socket becomes readable. It +/// is called with a vec of byte sequences (`Vec>`) and the event loop +/// data set by the user. +/// +/// Note about why the read data is a vec of multipart message parts: we don't +/// know what kind of socket this is, or what will be sent, so the most general +/// thing we can do is receive the entirety of a multipart message and call the +/// user callback with the whole set. Usually the number of parts in a multipart +/// message will be one, but the code will work just the same when it's not. +/// +/// This event source also allows you to use different event sources to publish +/// messages over the same writeable ZeroMQ socket (usually PUB or PUSH). +/// Messages should be sent over the Calloop MPSC channel sending end. This end +/// can be cloned and used by multiple senders. + +pub struct ZeroMQSource +where + T: IntoIterator, + T::Item: Into, +{ + // Calloop components. + /// Event source for ZeroMQ socket. + socket: calloop::generic::Generic>, + + /// Event source for channel. + mpsc_receiver: calloop::channel::Channel, + + /// Because the ZeroMQ socket is edge triggered, we need a way to "wake" the + /// event source upon (re-)registration. We do this with a separate + /// `calloop::ping::Ping` source. + wake_ping_receiver: calloop::ping::PingSource, + + /// Sending end of the ping source. + wake_ping_sender: calloop::ping::Ping, + + // ZeroMQ socket. + /// FIFO queue for the messages to be published. + outbox: collections::VecDeque, +} + +impl ZeroMQSource +where + T: IntoIterator, + T::Item: Into, +{ + // Converts a `zmq::Socket` into a `ZeroMQSource` plus the sending end of an + // MPSC channel to enqueue outgoing messages. + pub fn from_socket(socket: zmq::Socket) -> io::Result<(Self, calloop::channel::Sender)> { + let (mpsc_sender, mpsc_receiver) = calloop::channel::channel(); + let (wake_ping_sender, wake_ping_receiver) = calloop::ping::make_ping()?; + + let socket = calloop::generic::Generic::new( + unsafe { calloop::generic::FdWrapper::new(socket) }, + calloop::Interest::READ, + calloop::Mode::Edge, + ); + + Ok(( + Self { + socket, + mpsc_receiver, + wake_ping_receiver, + wake_ping_sender, + outbox: collections::VecDeque::new(), + }, + mpsc_sender, + )) + } +} + +/// This event source runs for three events: +/// +/// 1. The event source was registered. It is forced to run so that any pending +/// events on the socket are processed. +/// +/// 2. A message was sent over the MPSC channel. In this case we put it in the +/// internal queue. +/// +/// 3. The ZeroMQ socket is readable. For this, we read off a complete multipart +/// message and call the user callback with it. +/// +/// The callback provided to `process_events()` may be called multiple times +/// within a single call to `process_events()`. +impl calloop::EventSource for ZeroMQSource +where + T: IntoIterator, + T::Item: Into, +{ + type Event = Vec>; + type Metadata = (); + type Ret = io::Result<()>; + type Error = anyhow::Error; + + fn process_events( + &mut self, + readiness: calloop::Readiness, + token: calloop::Token, + mut callback: F, + ) -> Result + where + F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret, + { + // Runs if we were woken up on startup/registration. + self.wake_ping_receiver + .process_events(readiness, token, |_, _| {}) + .context("Failed after registration")?; + + // Runs if we were woken up because a message was sent on the channel. + let outbox = &mut self.outbox; + + self.mpsc_receiver + .process_events(readiness, token, |evt, _| { + if let calloop::channel::Event::Msg(msg) = evt { + outbox.push_back(msg); + } + }) + .context("Failed to processing outgoing messages")?; + + // The ZeroMQ file descriptor is edge triggered. This means that if (a) + // messages are added to the queue before registration, or (b) the + // socket became writeable before messages were enqueued, we will need + // to run the loop below. Hence, it always runs if this event source + // fires. The process_events() method doesn't do anything though, so we + // ignore it. + + loop { + // According to the docs, the edge-triggered FD will not change + // state if a socket goes directly from being readable to being + // writeable (or vice-versa) without there being an in-between point + // where there are no events. This can happen as a result of sending + // or receiving on the socket while processing such an event. The + // "used_socket" flag below tracks whether we perform an operation + // on the socket that warrants reading the events again. + let events = self + .socket + .get_ref() + .get_events() + .context("Failed to read ZeroMQ events")?; + + let mut used_socket = false; + + if events.contains(zmq::POLLOUT) { + if let Some(parts) = self.outbox.pop_front() { + self.socket + .get_ref() + .send_multipart(parts, 0) + .context("Failed to send message")?; + used_socket = true; + } + } + + if events.contains(zmq::POLLIN) { + // Batch up multipart messages. ZeroMQ guarantees atomic message + // sending, which includes all parts of a multipart message. + let messages = self + .socket + .get_ref() + .recv_multipart(0) + .context("Failed to receive message")?; + used_socket = true; + + // Capture and report errors from the callback, but don't propagate + // them up. + callback(messages, &mut ()).context("Error in event callback")?; + } + + if !used_socket { + break; + } + } + + Ok(calloop::PostAction::Continue) + } + + fn register( + &mut self, + poll: &mut calloop::Poll, + token_factory: &mut calloop::TokenFactory, + ) -> calloop::Result<()> { + self.socket.register(poll, token_factory)?; + self.mpsc_receiver.register(poll, token_factory)?; + self.wake_ping_receiver.register(poll, token_factory)?; + + self.wake_ping_sender.ping(); + + Ok(()) + } + + fn reregister( + &mut self, + poll: &mut calloop::Poll, + token_factory: &mut calloop::TokenFactory, + ) -> calloop::Result<()> { + self.socket.reregister(poll, token_factory)?; + self.mpsc_receiver.reregister(poll, token_factory)?; + self.wake_ping_receiver.reregister(poll, token_factory)?; + + self.wake_ping_sender.ping(); + + Ok(()) + } + + fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> { + self.socket.unregister(poll)?; + self.mpsc_receiver.unregister(poll)?; + self.wake_ping_receiver.unregister(poll)?; + Ok(()) + } +} + +impl Drop for ZeroMQSource +where + T: IntoIterator, + T::Item: Into, +{ + fn drop(&mut self) { + // This is one way to stop socket code (especially PUSH sockets) hanging + // at the end of any blocking functions. + // + // - https://stackoverflow.com/a/38338578/188535 + // - http://api.zeromq.org/4-0:zmq-ctx-term + self.socket.get_ref().set_linger(0).ok(); + self.socket.get_ref().set_rcvtimeo(0).ok(); + self.socket.get_ref().set_sndtimeo(0).ok(); + + // Double result because (a) possible failure on call and (b) possible + // failure decoding. + if let Ok(Ok(last_endpoint)) = self.socket.get_ref().get_last_endpoint() { + self.socket.get_ref().disconnect(&last_endpoint).ok(); + } + } +} + +pub fn main() {}