[
  {
    "path": ".gitignore",
    "content": "site/\n.DS_Store\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) <year> <copyright holders>\n\nAnti 996 License Version 1.0 (Draft)\n\nPermission is hereby granted to any individual or legal entity\nobtaining a copy of this licensed work (including the source code,\ndocumentation and/or related items, hereinafter collectively referred\nto as the \"licensed work\"), free of charge, to deal with the licensed\nwork for any purpose, including without limitation, the rights to use,\nreproduce, modify, prepare derivative works of, distribute, publish \nand sublicense the licensed work, subject to the following conditions:\n\n1. The individual or the legal entity must conspicuously display,\nwithout modification, this License and the notice on each redistributed \nor derivative copy of the Licensed Work.\n\n2. The individual or the legal entity must strictly comply with all\napplicable laws, regulations, rules and standards of the jurisdiction\nrelating to labor and employment where the individual is physically\nlocated or where the individual was born or naturalized; or where the\nlegal entity is registered or is operating (whichever is stricter). In\ncase that the jurisdiction has no such laws, regulations, rules and\nstandards or its laws, regulations, rules and standards are\nunenforceable, the individual or the legal entity are required to\ncomply with Core International Labor Standards.\n\n3. The individual or the legal entity shall not induce or force its\nemployee(s), whether full-time or part-time, or its independent\ncontractor(s), in any methods, to agree in oral or written form, to\ndirectly or indirectly restrict, weaken or relinquish his or her\nrights or remedies under such laws, regulations, rules and standards\nrelating to labor and employment as mentioned above, no matter whether\nsuch written or oral agreement are enforceable under the laws of the\nsaid jurisdiction, nor shall such individual or the legal entity\nlimit, in any methods, the rights of its employee(s) or independent\ncontractor(s) from reporting or complaining to the copyright holder or\nrelevant authorities monitoring the compliance of the license about\nits violation(s) of the said license.\n\nTHE LICENSED WORK IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM,\nDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN ANY WAY CONNECTION WITH THE\nLICENSED WORK OR THE USE OR OTHER DEALINGS IN THE LICENSED WORK."
  },
  {
    "path": "README.md",
    "content": "## SecurityPaper\n\n所有文档都来自中国互联网一线安全工程师编写整理\n\n\n## 官网\n\n```\nhttps://www.SecurityPaper.org\n```\n\n官网状态：[![Build Status](https://travis-ci.com/SecurityPaper/SecurityPaper-web.svg?branch=master)](https://travis-ci.com/SecurityPaper/SecurityPaper-web)\n\n## 下载文档方法\n\nclone 项目到本地\n\n所有文档都在**docs**目录下，以markdown文件进行存储，可以直接保存\n\n\n\n## 提交文章和改进\n\n请参考git工作流方法\n\nfork项目到自己账户，修改后提交给主分支，审核后即可展示。\n提交可以多种方式，如web、命令、客户端，这里演示web提交方式\n提交SDL落地方案-产品设计\n1. 选择相应的文件,所有文档都在**_post**目录下\n```\nSecurityPaper-web/_posts/3.SDL落地方案/2018-08-17-SDL-3-产品设计.md\n```\n\n选择**edit**或者**create new file**，文件名必须要符合: ```YEAR-MONTH-DAY-title.md```\n\n![图片1](https://github.com/SecurityPaper/SecurityPaper-web/raw/master/docs/images/2018/10/github/1.png)\n\n2. 编辑文档\n所有博客文章顶部必须有一段YAML头信息(YAML front- matter),文章可以使用markdown格式编写\n```\n---\ndate: 2018-08-17\ntitle: 03.产品设计\ncategories:\n  - 3.SDL落地方案\ndescription: 和研发同学进行产品设计定框架部分应该怎么去执行\ntype: Document\n---\n```\n\n编辑完成之后点击**commit changes**(同命令```git add . && git commit -m \"添加产品设计\" && git pusht origin master```)\n\n![图片2](https://github.com/SecurityPaper/SecurityPaper-web/raw/master/docs/images/2018/10/github/2.png)\n\n3. 提交pull请求\n点击**New pull request**\n\n![图片3](https://github.com/SecurityPaper/SecurityPaper-web/raw/master/docs/images/2018/10/github/3.png)\n\n检查没有问题，点击**Create pull request**\n\n![图片4](https://github.com/SecurityPaper/SecurityPaper-web/raw/master/docs/images/2018/10/github/4.png)\n\n提交成功，等待管理员**Merge**之后就成功了\n\n![图片5](https://github.com/SecurityPaper/SecurityPaper-web/raw/master/docs/images/2018/10/github/5.png)\n\n## 署名\n\n原则上对文章修改后即可进行署名在协作者添加上自己的ID。\n\n## About页面变更\n\n需要对网站文档进行提交建议以及文档改进或者文档编写方可在About页面添加自己ID\n\n排序需要按照字母顺序排序。\n"
  },
  {
    "path": "SecurityPaper-themes/404.html",
    "content": "{% extends \"base.html\" %}\n{% block content %}\n  <h1>404 - Not found</h1>\n{% endblock %}\n"
  },
  {
    "path": "SecurityPaper-themes/__init__.py",
    "content": ""
  },
  {
    "path": "SecurityPaper-themes/assets/fonts/font-awesome.css",
    "content": "/*!\n *  Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome\n *  License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n */@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(\"specimen/FontAwesome.woff2\") format(\"woff2\"),url(\"specimen/FontAwesome.woff\") format(\"woff\"),url(\"specimen/FontAwesome.ttf\") format(\"truetype\")}.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}"
  },
  {
    "path": "SecurityPaper-themes/assets/fonts/material-icons.css",
    "content": "/*!\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n * use this file except in compliance with the License. You may obtain a copy\n * of the License at:\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE\n * DISTRIBUTED UNDER THE LICENSE IS DISTRIBUTED ON AN \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\n * SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING PERMISSIONS AND\n * LIMITATIONS UNDER THE LICENSE.\n */@font-face{font-family:\"Material Icons\";font-style:normal;font-weight:400;src:local(\"Material Icons\"),local(\"MaterialIcons-Regular\"),url(\"specimen/MaterialIcons-Regular.woff2\") format(\"woff2\"),url(\"specimen/MaterialIcons-Regular.woff\") format(\"woff\"),url(\"specimen/MaterialIcons-Regular.ttf\") format(\"truetype\")}"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/application.js",
    "content": "(function(e, a) { for(var i in a) e[i] = a[i]; }(window, /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 6);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Module\n * ------------------------------------------------------------------------- */\n\n/* eslint-disable no-underscore-dangle */\nexports.default = /* JSX */{\n\n  /**\n   * Create a native DOM node from JSX's intermediate representation\n   *\n   * @param {string} tag - Tag name\n   * @param {?Object} properties - Properties\n   * @param {Array<string | number | { __html: string } | Array<HTMLElement>>}\n   *   children - Child nodes\n   * @return {HTMLElement} Native DOM node\n   */\n  createElement: function createElement(tag, properties) {\n    var el = document.createElement(tag);\n\n    /* Set all properties */\n    if (properties) Array.prototype.forEach.call(Object.keys(properties), function (attr) {\n      el.setAttribute(attr, properties[attr]);\n    });\n\n    /* Iterate child nodes */\n    var iterateChildNodes = function iterateChildNodes(nodes) {\n      Array.prototype.forEach.call(nodes, function (node) {\n\n        /* Directly append text content */\n        if (typeof node === \"string\" || typeof node === \"number\") {\n          el.textContent += node;\n\n          /* Recurse, if we got an array */\n        } else if (Array.isArray(node)) {\n          iterateChildNodes(node);\n\n          /* Append raw HTML */\n        } else if (typeof node.__html !== \"undefined\") {\n          el.innerHTML += node.__html;\n\n          /* Append regular nodes */\n        } else if (node instanceof Node) {\n          el.appendChild(node);\n        }\n      });\n    };\n\n    /* Iterate child nodes and return element */\n\n    for (var _len = arguments.length, children = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {\n      children[_key - 2] = arguments[_key];\n    }\n\n    iterateChildNodes(children);\n    return el;\n  }\n};\nmodule.exports = exports.default;\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports) {\n\nvar g;\r\n\r\n// This works in non-strict mode\r\ng = (function() {\r\n\treturn this;\r\n})();\r\n\r\ntry {\r\n\t// This works if eval is allowed (see CSP)\r\n\tg = g || Function(\"return this\")() || (1,eval)(\"this\");\r\n} catch(e) {\r\n\t// This works if the window reference is available\r\n\tif(typeof window === \"object\")\r\n\t\tg = window;\r\n}\r\n\r\n// g can still be undefined, but nothing to do about it...\r\n// We return undefined, instead of nothing here, so it's\r\n// easier to handle this case. if(!global) { ...}\r\n\r\nmodule.exports = g;\r\n\n\n/***/ }),\n/* 2 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\nvar index = typeof fetch=='function' ? fetch.bind() : function(url, options) {\n\toptions = options || {};\n\treturn new Promise( function (resolve, reject) {\n\t\tvar request = new XMLHttpRequest();\n\n\t\trequest.open(options.method || 'get', url, true);\n\n\t\tfor (var i in options.headers) {\n\t\t\trequest.setRequestHeader(i, options.headers[i]);\n\t\t}\n\n\t\trequest.withCredentials = options.credentials=='include';\n\n\t\trequest.onload = function () {\n\t\t\tresolve(response());\n\t\t};\n\n\t\trequest.onerror = reject;\n\n\t\trequest.send(options.body || null);\n\n\t\tfunction response() {\n\t\t\tvar keys = [],\n\t\t\t\tall = [],\n\t\t\t\theaders = {},\n\t\t\t\theader;\n\n\t\t\trequest.getAllResponseHeaders().replace(/^(.*?):[^\\S\\n]*([\\s\\S]*?)$/gm, function (m, key, value) {\n\t\t\t\tkeys.push(key = key.toLowerCase());\n\t\t\t\tall.push([key, value]);\n\t\t\t\theader = headers[key];\n\t\t\t\theaders[key] = header ? (header + \",\" + value) : value;\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tok: (request.status/100|0) == 2,\t\t// 200-299\n\t\t\t\tstatus: request.status,\n\t\t\t\tstatusText: request.statusText,\n\t\t\t\turl: request.responseURL,\n\t\t\t\tclone: response,\n\t\t\t\ttext: function () { return Promise.resolve(request.responseText); },\n\t\t\t\tjson: function () { return Promise.resolve(request.responseText).then(JSON.parse); },\n\t\t\t\tblob: function () { return Promise.resolve(new Blob([request.response])); },\n\t\t\t\theaders: {\n\t\t\t\t\tkeys: function () { return keys; },\n\t\t\t\t\tentries: function () { return all; },\n\t\t\t\t\tget: function (n) { return headers[n.toLowerCase()]; },\n\t\t\t\t\thas: function (n) { return n.toLowerCase() in headers; }\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n};\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (index);\n//# sourceMappingURL=unfetch.es.js.map\n\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\nvar Listener = function () {\n\n  /**\n   * Generic event listener\n   *\n   * @constructor\n   *\n   * @property {(Array<EventTarget>)} els_ - Event targets\n   * @property {Object} handler_- Event handlers\n   * @property {Array<string>} events_ - Event names\n   * @property {Function} update_ - Update handler\n   *\n   * @param {?(string|EventTarget|NodeList<EventTarget>)} els -\n   *   Selector or Event targets\n   * @param {(string|Array<string>)} events - Event names\n   * @param {(Object|Function)} handler - Handler to be invoked\n   */\n  function Listener(els, events, handler) {\n    var _this = this;\n\n    _classCallCheck(this, Listener);\n\n    this.els_ = Array.prototype.slice.call(typeof els === \"string\" ? document.querySelectorAll(els) : [].concat(els));\n\n    /* Set handler as function or directly as object */\n    this.handler_ = typeof handler === \"function\" ? { update: handler } : handler;\n\n    /* Initialize event names and update handler */\n    this.events_ = [].concat(events);\n    this.update_ = function (ev) {\n      return _this.handler_.update(ev);\n    };\n  }\n\n  /**\n   * Register listener for all relevant events\n   */\n\n\n  Listener.prototype.listen = function listen() {\n    var _this2 = this;\n\n    this.els_.forEach(function (el) {\n      _this2.events_.forEach(function (event) {\n        el.addEventListener(event, _this2.update_, false);\n      });\n    });\n\n    /* Execute setup handler, if implemented */\n    if (typeof this.handler_.setup === \"function\") this.handler_.setup();\n  };\n\n  /**\n   * Unregister listener for all relevant events\n   */\n\n\n  Listener.prototype.unlisten = function unlisten() {\n    var _this3 = this;\n\n    this.els_.forEach(function (el) {\n      _this3.events_.forEach(function (event) {\n        el.removeEventListener(event, _this3.update_);\n      });\n    });\n\n    /* Execute reset handler, if implemented */\n    if (typeof this.handler_.reset === \"function\") this.handler_.reset();\n  };\n\n  return Listener;\n}();\n\nexports.default = Listener;\n\n/***/ }),\n/* 4 */,\n/* 5 */,\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(JSX) {\n\nexports.__esModule = true;\nexports.app = undefined;\n\n__webpack_require__(7);\n\n__webpack_require__(8);\n\n__webpack_require__(9);\n\n__webpack_require__(10);\n\n__webpack_require__(11);\n\n__webpack_require__(12);\n\n__webpack_require__(13);\n\nvar _promisePolyfill = __webpack_require__(14);\n\nvar _promisePolyfill2 = _interopRequireDefault(_promisePolyfill);\n\nvar _clipboard = __webpack_require__(19);\n\nvar _clipboard2 = _interopRequireDefault(_clipboard);\n\nvar _fastclick = __webpack_require__(20);\n\nvar _fastclick2 = _interopRequireDefault(_fastclick);\n\nvar _Material = __webpack_require__(21);\n\nvar _Material2 = _interopRequireDefault(_Material);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nwindow.Promise = window.Promise || _promisePolyfill2.default;\n\n/* ----------------------------------------------------------------------------\n * Dependencies\n * ------------------------------------------------------------------------- */\n\n/* ----------------------------------------------------------------------------\n * Polyfills\n * ------------------------------------------------------------------------- */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Return the meta tag value for the given key\n *\n * @param {string} key - Meta name\n *\n * @return {string} Meta content value\n */\nvar translate = function translate(key) {\n  var meta = document.getElementsByName(\"lang:\" + key)[0];\n  if (!(meta instanceof HTMLMetaElement)) throw new ReferenceError();\n  return meta.content;\n};\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/**\n * Initialize Material for MkDocs\n *\n * @param {Object} config - Configuration\n */\nfunction initialize(config) {\n  // eslint-disable-line func-style\n\n  /* Initialize Modernizr and FastClick */\n  new _Material2.default.Event.Listener(document, \"DOMContentLoaded\", function () {\n    if (!(document.body instanceof HTMLElement)) throw new ReferenceError();\n\n    /* Attach FastClick to mitigate 300ms delay on touch devices */\n    _fastclick2.default.attach(document.body);\n\n    /* Test for iOS */\n    Modernizr.addTest(\"ios\", function () {\n      return !!navigator.userAgent.match(/(iPad|iPhone|iPod)/g);\n    });\n\n    /* Wrap all data tables for better overflow scrolling */\n    var tables = document.querySelectorAll(\"table:not([class])\"); // TODO: this is JSX, we should rename the file\n    Array.prototype.forEach.call(tables, function (table) {\n      var wrap = JSX.createElement(\n        \"div\",\n        { \"class\": \"md-typeset__scrollwrap\" },\n        JSX.createElement(\"div\", { \"class\": \"md-typeset__table\" })\n      );\n      if (table.nextSibling) {\n        table.parentNode.insertBefore(wrap, table.nextSibling);\n      } else {\n        table.parentNode.appendChild(wrap);\n      }\n      wrap.children[0].appendChild(table);\n    });\n\n    /* Clipboard integration */\n    if (_clipboard2.default.isSupported()) {\n      var blocks = document.querySelectorAll(\".codehilite > pre, pre > code\");\n      Array.prototype.forEach.call(blocks, function (block, index) {\n        var id = \"__code_\" + index;\n\n        /* Create button with message container */\n        var button = JSX.createElement(\n          \"button\",\n          { \"class\": \"md-clipboard\", title: translate(\"clipboard.copy\"),\n            \"data-clipboard-target\": \"#\" + id + \" pre, #\" + id + \" code\" },\n          JSX.createElement(\"span\", { \"class\": \"md-clipboard__message\" })\n        );\n\n        /* Link to block and insert button */\n        var parent = block.parentNode;\n        parent.id = id;\n        parent.insertBefore(button, block);\n      });\n\n      /* Initialize Clipboard listener */\n      var copy = new _clipboard2.default(\".md-clipboard\");\n\n      /* Success handler */\n      copy.on(\"success\", function (action) {\n        var message = action.trigger.querySelector(\".md-clipboard__message\");\n        if (!(message instanceof HTMLElement)) throw new ReferenceError();\n\n        /* Clear selection and reset debounce logic */\n        action.clearSelection();\n        if (message.dataset.mdTimer) clearTimeout(parseInt(message.dataset.mdTimer, 10));\n\n        /* Set message indicating success and show it */\n        message.classList.add(\"md-clipboard__message--active\");\n        message.innerHTML = translate(\"clipboard.copied\");\n\n        /* Hide message after two seconds */\n        message.dataset.mdTimer = setTimeout(function () {\n          message.classList.remove(\"md-clipboard__message--active\");\n          message.dataset.mdTimer = \"\";\n        }, 2000).toString();\n      });\n    }\n\n    /* Polyfill details/summary functionality */\n    if (!Modernizr.details) {\n      var _blocks = document.querySelectorAll(\"details > summary\");\n      Array.prototype.forEach.call(_blocks, function (summary) {\n        summary.addEventListener(\"click\", function (ev) {\n          var details = ev.target.parentNode;\n          if (details.hasAttribute(\"open\")) {\n            details.removeAttribute(\"open\");\n          } else {\n            details.setAttribute(\"open\", \"\");\n          }\n        });\n      });\n    }\n\n    /* Open details after anchor jump */\n    var details = function details() {\n      if (document.location.hash) {\n        var el = document.getElementById(document.location.hash.substring(1));\n        if (!el) return;\n\n        /* Walk up as long as we're not in a details tag */\n        var parent = el.parentNode;\n        while (parent && !(parent instanceof HTMLDetailsElement)) {\n          parent = parent.parentNode;\n        } /* If there's a details tag, open it */\n        if (parent && !parent.open) {\n          parent.open = true;\n\n          /* Force reload, so the viewport repositions */\n          var loc = location.hash;\n          location.hash = \" \";\n          location.hash = loc;\n        }\n      }\n    };\n    window.addEventListener(\"hashchange\", details);\n    details();\n\n    /* Force 1px scroll offset to trigger overflow scrolling */\n    if (Modernizr.ios) {\n      var scrollable = document.querySelectorAll(\"[data-md-scrollfix]\");\n      Array.prototype.forEach.call(scrollable, function (item) {\n        item.addEventListener(\"touchstart\", function () {\n          var top = item.scrollTop;\n\n          /* We're at the top of the container */\n          if (top === 0) {\n            item.scrollTop = 1;\n\n            /* We're at the bottom of the container */\n          } else if (top + item.offsetHeight === item.scrollHeight) {\n            item.scrollTop = top - 1;\n          }\n        });\n      });\n    }\n  }).listen();\n\n  /* Component: header shadow toggle */\n  new _Material2.default.Event.Listener(window, [\"scroll\", \"resize\", \"orientationchange\"], new _Material2.default.Header.Shadow(\"[data-md-component=container]\", \"[data-md-component=header]\")).listen();\n\n  /* Component: header title toggle */\n  new _Material2.default.Event.Listener(window, [\"scroll\", \"resize\", \"orientationchange\"], new _Material2.default.Header.Title(\"[data-md-component=title]\", \".md-typeset h1\")).listen();\n\n  /* Component: hero visibility toggle */\n  if (document.querySelector(\"[data-md-component=hero]\")) new _Material2.default.Event.Listener(window, [\"scroll\", \"resize\", \"orientationchange\"], new _Material2.default.Tabs.Toggle(\"[data-md-component=hero]\")).listen();\n\n  /* Component: tabs visibility toggle */\n  if (document.querySelector(\"[data-md-component=tabs]\")) new _Material2.default.Event.Listener(window, [\"scroll\", \"resize\", \"orientationchange\"], new _Material2.default.Tabs.Toggle(\"[data-md-component=tabs]\")).listen();\n\n  /* Component: sidebar with navigation */\n  new _Material2.default.Event.MatchMedia(\"(min-width: 1220px)\", new _Material2.default.Event.Listener(window, [\"scroll\", \"resize\", \"orientationchange\"], new _Material2.default.Sidebar.Position(\"[data-md-component=navigation]\", \"[data-md-component=header]\")));\n\n  /* Component: sidebar with table of contents (missing on 404 page) */\n  if (document.querySelector(\"[data-md-component=toc]\")) new _Material2.default.Event.MatchMedia(\"(min-width: 960px)\", new _Material2.default.Event.Listener(window, [\"scroll\", \"resize\", \"orientationchange\"], new _Material2.default.Sidebar.Position(\"[data-md-component=toc]\", \"[data-md-component=header]\")));\n\n  /* Component: link blurring for table of contents */\n  new _Material2.default.Event.MatchMedia(\"(min-width: 960px)\", new _Material2.default.Event.Listener(window, \"scroll\", new _Material2.default.Nav.Blur(\"[data-md-component=toc] [href]\")));\n\n  /* Component: collapsible elements for navigation */\n  var collapsibles = document.querySelectorAll(\"[data-md-component=collapsible]\");\n  Array.prototype.forEach.call(collapsibles, function (collapse) {\n    new _Material2.default.Event.MatchMedia(\"(min-width: 1220px)\", new _Material2.default.Event.Listener(collapse.previousElementSibling, \"click\", new _Material2.default.Nav.Collapse(collapse)));\n  });\n\n  /* Component: active pane monitor for iOS scrolling fixes */\n  new _Material2.default.Event.MatchMedia(\"(max-width: 1219px)\", new _Material2.default.Event.Listener(\"[data-md-component=navigation] [data-md-toggle]\", \"change\", new _Material2.default.Nav.Scrolling(\"[data-md-component=navigation] nav\")));\n\n  /* Initialize search, if available */\n  if (document.querySelector(\"[data-md-component=search]\")) {\n\n    /* Component: search body lock for mobile */\n    new _Material2.default.Event.MatchMedia(\"(max-width: 959px)\", new _Material2.default.Event.Listener(\"[data-md-toggle=search]\", \"change\", new _Material2.default.Search.Lock(\"[data-md-toggle=search]\")));\n\n    /* Component: search results */\n    new _Material2.default.Event.Listener(\"[data-md-component=query]\", [\"focus\", \"keyup\", \"change\"], new _Material2.default.Search.Result(\"[data-md-component=result]\", function () {\n      return fetch(config.url.base + \"/\" + (config.version < \"0.17\" ? \"mkdocs\" : \"search\") + \"/search_index.json\", {\n        credentials: \"same-origin\"\n      }).then(function (response) {\n        return response.json();\n      }).then(function (data) {\n        return data.docs.map(function (doc) {\n          doc.location = config.url.base + \"/\" + doc.location;\n          return doc;\n        });\n      });\n    })).listen();\n\n    /* Listener: focus input after form reset */\n    new _Material2.default.Event.Listener(\"[data-md-component=reset]\", \"click\", function () {\n      setTimeout(function () {\n        var query = document.querySelector(\"[data-md-component=query]\");\n        if (!(query instanceof HTMLInputElement)) throw new ReferenceError();\n        query.focus();\n      }, 10);\n    }).listen();\n\n    /* Listener: focus input after opening search */\n    new _Material2.default.Event.Listener(\"[data-md-toggle=search]\", \"change\", function (ev) {\n      setTimeout(function (toggle) {\n        if (!(toggle instanceof HTMLInputElement)) throw new ReferenceError();\n        if (toggle.checked) {\n          var query = document.querySelector(\"[data-md-component=query]\");\n          if (!(query instanceof HTMLInputElement)) throw new ReferenceError();\n          query.focus();\n        }\n      }, 400, ev.target);\n    }).listen();\n\n    /* Listener: open search on focus */\n    new _Material2.default.Event.MatchMedia(\"(min-width: 960px)\", new _Material2.default.Event.Listener(\"[data-md-component=query]\", \"focus\", function () {\n      var toggle = document.querySelector(\"[data-md-toggle=search]\");\n      if (!(toggle instanceof HTMLInputElement)) throw new ReferenceError();\n      if (!toggle.checked) {\n        toggle.checked = true;\n        toggle.dispatchEvent(new CustomEvent(\"change\"));\n      }\n    }));\n\n    /* Listener: keyboard handlers */ // eslint-disable-next-line complexity\n    new _Material2.default.Event.Listener(window, \"keydown\", function (ev) {\n      // TODO: split up into component to reduce complexity\n      var toggle = document.querySelector(\"[data-md-toggle=search]\");\n      if (!(toggle instanceof HTMLInputElement)) throw new ReferenceError();\n      var query = document.querySelector(\"[data-md-component=query]\");\n      if (!(query instanceof HTMLInputElement)) throw new ReferenceError();\n\n      /* Abort if meta key (macOS) or ctrl key (Windows) is pressed */\n      if (ev.metaKey || ev.ctrlKey) return;\n\n      /* Search is open */\n      if (toggle.checked) {\n\n        /* Enter: prevent form submission */\n        if (ev.keyCode === 13) {\n          if (query === document.activeElement) {\n            ev.preventDefault();\n\n            /* Go to current active/focused link */\n            var focus = document.querySelector(\"[data-md-component=search] [href][data-md-state=active]\");\n            if (focus instanceof HTMLLinkElement) {\n              window.location = focus.getAttribute(\"href\");\n\n              /* Close search */\n              toggle.checked = false;\n              toggle.dispatchEvent(new CustomEvent(\"change\"));\n              query.blur();\n            }\n          }\n\n          /* Escape or Tab: close search */\n        } else if (ev.keyCode === 9 || ev.keyCode === 27) {\n          toggle.checked = false;\n          toggle.dispatchEvent(new CustomEvent(\"change\"));\n          query.blur();\n\n          /* Horizontal arrows and backspace: focus input */\n        } else if ([8, 37, 39].indexOf(ev.keyCode) !== -1) {\n          if (query !== document.activeElement) query.focus();\n\n          /* Vertical arrows: select previous or next search result */\n        } else if ([38, 40].indexOf(ev.keyCode) !== -1) {\n          var key = ev.keyCode;\n\n          /* Retrieve all results */\n          var links = Array.prototype.slice.call(document.querySelectorAll(\"[data-md-component=query], [data-md-component=search] [href]\"));\n\n          /* Retrieve current active/focused result */\n          var _focus = links.find(function (link) {\n            if (!(link instanceof HTMLElement)) throw new ReferenceError();\n            return link.dataset.mdState === \"active\";\n          });\n          if (_focus) _focus.dataset.mdState = \"\";\n\n          /* Calculate index depending on direction, add length to form ring */\n          var index = Math.max(0, (links.indexOf(_focus) + links.length + (key === 38 ? -1 : +1)) % links.length);\n\n          /* Set active state and focus */\n          if (links[index]) {\n            links[index].dataset.mdState = \"active\";\n            links[index].focus();\n          }\n\n          /* Prevent scrolling of page */\n          ev.preventDefault();\n          ev.stopPropagation();\n\n          /* Return false prevents the cursor position from changing */\n          return false;\n        }\n\n        /* Search is closed and we're not inside a form */\n      } else if (document.activeElement && !document.activeElement.form) {\n\n        /* F/S: Open search if not in input field */\n        if (ev.keyCode === 70 || ev.keyCode === 83) {\n          query.focus();\n          ev.preventDefault();\n        }\n      }\n    }).listen();\n\n    /* Listener: focus query if in search is open and character is typed */\n    new _Material2.default.Event.Listener(window, \"keypress\", function () {\n      var toggle = document.querySelector(\"[data-md-toggle=search]\");\n      if (!(toggle instanceof HTMLInputElement)) throw new ReferenceError();\n      if (toggle.checked) {\n        var query = document.querySelector(\"[data-md-component=query]\");\n        if (!(query instanceof HTMLInputElement)) throw new ReferenceError();\n        if (query !== document.activeElement) query.focus();\n      }\n    }).listen();\n  }\n\n  /* Listener: handle tabbing context for better accessibility */\n  new _Material2.default.Event.Listener(document.body, \"keydown\", function (ev) {\n    if (ev.keyCode === 9) {\n      var labels = document.querySelectorAll(\"[data-md-component=navigation] .md-nav__link[for]:not([tabindex])\");\n      Array.prototype.forEach.call(labels, function (label) {\n        if (label.offsetHeight) label.tabIndex = 0;\n      });\n    }\n  }).listen();\n\n  /* Listener: reset tabbing behavior */\n  new _Material2.default.Event.Listener(document.body, \"mousedown\", function () {\n    var labels = document.querySelectorAll(\"[data-md-component=navigation] .md-nav__link[tabindex]\");\n    Array.prototype.forEach.call(labels, function (label) {\n      label.removeAttribute(\"tabIndex\");\n    });\n  }).listen();\n\n  document.body.addEventListener(\"click\", function () {\n    if (document.body.dataset.mdState === \"tabbing\") document.body.dataset.mdState = \"\";\n  });\n\n  /* Listener: close drawer when anchor links are clicked */\n  new _Material2.default.Event.MatchMedia(\"(max-width: 959px)\", new _Material2.default.Event.Listener(\"[data-md-component=navigation] [href^='#']\", \"click\", function () {\n    var toggle = document.querySelector(\"[data-md-toggle=drawer]\");\n    if (!(toggle instanceof HTMLInputElement)) throw new ReferenceError();\n    if (toggle.checked) {\n      toggle.checked = false;\n      toggle.dispatchEvent(new CustomEvent(\"change\"));\n    }\n  }))\n\n  /* Retrieve facts for the given repository type */\n  ;(function () {\n    var el = document.querySelector(\"[data-md-source]\");\n    if (!el) return _promisePolyfill2.default.resolve([]);else if (!(el instanceof HTMLAnchorElement)) throw new ReferenceError();\n    switch (el.dataset.mdSource) {\n      case \"github\":\n        return new _Material2.default.Source.Adapter.GitHub(el).fetch();\n      default:\n        return _promisePolyfill2.default.resolve([]);\n    }\n\n    /* Render repository information */\n  })().then(function (facts) {\n    var sources = document.querySelectorAll(\"[data-md-source]\");\n    Array.prototype.forEach.call(sources, function (source) {\n      new _Material2.default.Source.Repository(source).initialize(facts);\n    });\n  });\n}\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\n/* Provide this for downward compatibility for now */\nvar app = {\n  initialize: initialize\n};\n\nexports.app = app;\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__.p + \"assets/images/icons/bitbucket.svg\";\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__.p + \"assets/images/icons/github.svg\";\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__.p + \"assets/images/icons/gitlab.svg\";\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports) {\n\n// removed by extract-text-webpack-plugin\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports) {\n\n// Polyfill for creating CustomEvents on IE9/10/11\n\n// code pulled from:\n// https://github.com/d4tocchini/customevent-polyfill\n// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent#Polyfill\n\n(function() {\n  if (typeof window === 'undefined') {\n    return;\n  }\n\n  try {\n    var ce = new window.CustomEvent('test', { cancelable: true });\n    ce.preventDefault();\n    if (ce.defaultPrevented !== true) {\n      // IE has problems with .preventDefault() on custom events\n      // http://stackoverflow.com/questions/23349191\n      throw new Error('Could not prevent default');\n    }\n  } catch (e) {\n    var CustomEvent = function(event, params) {\n      var evt, origPrevent;\n      params = params || {\n        bubbles: false,\n        cancelable: false,\n        detail: undefined\n      };\n\n      evt = document.createEvent('CustomEvent');\n      evt.initCustomEvent(\n        event,\n        params.bubbles,\n        params.cancelable,\n        params.detail\n      );\n      origPrevent = evt.preventDefault;\n      evt.preventDefault = function() {\n        origPrevent.call(this);\n        try {\n          Object.defineProperty(this, 'defaultPrevented', {\n            get: function() {\n              return true;\n            }\n          });\n        } catch (e) {\n          this.defaultPrevented = true;\n        }\n      };\n      return evt;\n    };\n\n    CustomEvent.prototype = window.Event.prototype;\n    window.CustomEvent = CustomEvent; // expose definition to window\n  }\n})();\n\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\nif (!window.fetch) window.fetch = __webpack_require__(2).default || __webpack_require__(2);\n\n\n/***/ }),\n/* 14 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\n/* WEBPACK VAR INJECTION */(function(setImmediate) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__finally__ = __webpack_require__(18);\n\n\n// Store setTimeout reference so promise-polyfill will be unaffected by\n// other code modifying setTimeout (like sinon.useFakeTimers())\nvar setTimeoutFunc = setTimeout;\n\nfunction noop() {}\n\n// Polyfill for Function.prototype.bind\nfunction bind(fn, thisArg) {\n  return function() {\n    fn.apply(thisArg, arguments);\n  };\n}\n\n/**\n * @constructor\n * @param {Function} fn\n */\nfunction Promise(fn) {\n  if (!(this instanceof Promise))\n    throw new TypeError('Promises must be constructed via new');\n  if (typeof fn !== 'function') throw new TypeError('not a function');\n  /** @type {!number} */\n  this._state = 0;\n  /** @type {!boolean} */\n  this._handled = false;\n  /** @type {Promise|undefined} */\n  this._value = undefined;\n  /** @type {!Array<!Function>} */\n  this._deferreds = [];\n\n  doResolve(fn, this);\n}\n\nfunction handle(self, deferred) {\n  while (self._state === 3) {\n    self = self._value;\n  }\n  if (self._state === 0) {\n    self._deferreds.push(deferred);\n    return;\n  }\n  self._handled = true;\n  Promise._immediateFn(function() {\n    var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;\n    if (cb === null) {\n      (self._state === 1 ? resolve : reject)(deferred.promise, self._value);\n      return;\n    }\n    var ret;\n    try {\n      ret = cb(self._value);\n    } catch (e) {\n      reject(deferred.promise, e);\n      return;\n    }\n    resolve(deferred.promise, ret);\n  });\n}\n\nfunction resolve(self, newValue) {\n  try {\n    // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure\n    if (newValue === self)\n      throw new TypeError('A promise cannot be resolved with itself.');\n    if (\n      newValue &&\n      (typeof newValue === 'object' || typeof newValue === 'function')\n    ) {\n      var then = newValue.then;\n      if (newValue instanceof Promise) {\n        self._state = 3;\n        self._value = newValue;\n        finale(self);\n        return;\n      } else if (typeof then === 'function') {\n        doResolve(bind(then, newValue), self);\n        return;\n      }\n    }\n    self._state = 1;\n    self._value = newValue;\n    finale(self);\n  } catch (e) {\n    reject(self, e);\n  }\n}\n\nfunction reject(self, newValue) {\n  self._state = 2;\n  self._value = newValue;\n  finale(self);\n}\n\nfunction finale(self) {\n  if (self._state === 2 && self._deferreds.length === 0) {\n    Promise._immediateFn(function() {\n      if (!self._handled) {\n        Promise._unhandledRejectionFn(self._value);\n      }\n    });\n  }\n\n  for (var i = 0, len = self._deferreds.length; i < len; i++) {\n    handle(self, self._deferreds[i]);\n  }\n  self._deferreds = null;\n}\n\n/**\n * @constructor\n */\nfunction Handler(onFulfilled, onRejected, promise) {\n  this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;\n  this.onRejected = typeof onRejected === 'function' ? onRejected : null;\n  this.promise = promise;\n}\n\n/**\n * Take a potentially misbehaving resolver function and make sure\n * onFulfilled and onRejected are only called once.\n *\n * Makes no guarantees about asynchrony.\n */\nfunction doResolve(fn, self) {\n  var done = false;\n  try {\n    fn(\n      function(value) {\n        if (done) return;\n        done = true;\n        resolve(self, value);\n      },\n      function(reason) {\n        if (done) return;\n        done = true;\n        reject(self, reason);\n      }\n    );\n  } catch (ex) {\n    if (done) return;\n    done = true;\n    reject(self, ex);\n  }\n}\n\nPromise.prototype['catch'] = function(onRejected) {\n  return this.then(null, onRejected);\n};\n\nPromise.prototype.then = function(onFulfilled, onRejected) {\n  // @ts-ignore\n  var prom = new this.constructor(noop);\n\n  handle(this, new Handler(onFulfilled, onRejected, prom));\n  return prom;\n};\n\nPromise.prototype['finally'] = __WEBPACK_IMPORTED_MODULE_0__finally__[\"a\" /* default */];\n\nPromise.all = function(arr) {\n  return new Promise(function(resolve, reject) {\n    if (!arr || typeof arr.length === 'undefined')\n      throw new TypeError('Promise.all accepts an array');\n    var args = Array.prototype.slice.call(arr);\n    if (args.length === 0) return resolve([]);\n    var remaining = args.length;\n\n    function res(i, val) {\n      try {\n        if (val && (typeof val === 'object' || typeof val === 'function')) {\n          var then = val.then;\n          if (typeof then === 'function') {\n            then.call(\n              val,\n              function(val) {\n                res(i, val);\n              },\n              reject\n            );\n            return;\n          }\n        }\n        args[i] = val;\n        if (--remaining === 0) {\n          resolve(args);\n        }\n      } catch (ex) {\n        reject(ex);\n      }\n    }\n\n    for (var i = 0; i < args.length; i++) {\n      res(i, args[i]);\n    }\n  });\n};\n\nPromise.resolve = function(value) {\n  if (value && typeof value === 'object' && value.constructor === Promise) {\n    return value;\n  }\n\n  return new Promise(function(resolve) {\n    resolve(value);\n  });\n};\n\nPromise.reject = function(value) {\n  return new Promise(function(resolve, reject) {\n    reject(value);\n  });\n};\n\nPromise.race = function(values) {\n  return new Promise(function(resolve, reject) {\n    for (var i = 0, len = values.length; i < len; i++) {\n      values[i].then(resolve, reject);\n    }\n  });\n};\n\n// Use polyfill for setImmediate for performance gains\nPromise._immediateFn =\n  (typeof setImmediate === 'function' &&\n    function(fn) {\n      setImmediate(fn);\n    }) ||\n  function(fn) {\n    setTimeoutFunc(fn, 0);\n  };\n\nPromise._unhandledRejectionFn = function _unhandledRejectionFn(err) {\n  if (typeof console !== 'undefined' && console) {\n    console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console\n  }\n};\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (Promise);\n\n/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(15).setImmediate))\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports, __webpack_require__) {\n\n/* WEBPACK VAR INJECTION */(function(global) {var scope = (typeof global !== \"undefined\" && global) ||\n            (typeof self !== \"undefined\" && self) ||\n            window;\nvar apply = Function.prototype.apply;\n\n// DOM APIs, for completeness\n\nexports.setTimeout = function() {\n  return new Timeout(apply.call(setTimeout, scope, arguments), clearTimeout);\n};\nexports.setInterval = function() {\n  return new Timeout(apply.call(setInterval, scope, arguments), clearInterval);\n};\nexports.clearTimeout =\nexports.clearInterval = function(timeout) {\n  if (timeout) {\n    timeout.close();\n  }\n};\n\nfunction Timeout(id, clearFn) {\n  this._id = id;\n  this._clearFn = clearFn;\n}\nTimeout.prototype.unref = Timeout.prototype.ref = function() {};\nTimeout.prototype.close = function() {\n  this._clearFn.call(scope, this._id);\n};\n\n// Does not start the time, just sets up the members needed.\nexports.enroll = function(item, msecs) {\n  clearTimeout(item._idleTimeoutId);\n  item._idleTimeout = msecs;\n};\n\nexports.unenroll = function(item) {\n  clearTimeout(item._idleTimeoutId);\n  item._idleTimeout = -1;\n};\n\nexports._unrefActive = exports.active = function(item) {\n  clearTimeout(item._idleTimeoutId);\n\n  var msecs = item._idleTimeout;\n  if (msecs >= 0) {\n    item._idleTimeoutId = setTimeout(function onTimeout() {\n      if (item._onTimeout)\n        item._onTimeout();\n    }, msecs);\n  }\n};\n\n// setimmediate attaches itself to the global object\n__webpack_require__(16);\n// On some exotic environments, it's not clear which object `setimmediate` was\n// able to install onto.  Search each possibility in the same order as the\n// `setimmediate` library.\nexports.setImmediate = (typeof self !== \"undefined\" && self.setImmediate) ||\n                       (typeof global !== \"undefined\" && global.setImmediate) ||\n                       (this && this.setImmediate);\nexports.clearImmediate = (typeof self !== \"undefined\" && self.clearImmediate) ||\n                         (typeof global !== \"undefined\" && global.clearImmediate) ||\n                         (this && this.clearImmediate);\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1)))\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports, __webpack_require__) {\n\n/* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) {\n    \"use strict\";\n\n    if (global.setImmediate) {\n        return;\n    }\n\n    var nextHandle = 1; // Spec says greater than zero\n    var tasksByHandle = {};\n    var currentlyRunningATask = false;\n    var doc = global.document;\n    var registerImmediate;\n\n    function setImmediate(callback) {\n      // Callback can either be a function or a string\n      if (typeof callback !== \"function\") {\n        callback = new Function(\"\" + callback);\n      }\n      // Copy function arguments\n      var args = new Array(arguments.length - 1);\n      for (var i = 0; i < args.length; i++) {\n          args[i] = arguments[i + 1];\n      }\n      // Store and register the task\n      var task = { callback: callback, args: args };\n      tasksByHandle[nextHandle] = task;\n      registerImmediate(nextHandle);\n      return nextHandle++;\n    }\n\n    function clearImmediate(handle) {\n        delete tasksByHandle[handle];\n    }\n\n    function run(task) {\n        var callback = task.callback;\n        var args = task.args;\n        switch (args.length) {\n        case 0:\n            callback();\n            break;\n        case 1:\n            callback(args[0]);\n            break;\n        case 2:\n            callback(args[0], args[1]);\n            break;\n        case 3:\n            callback(args[0], args[1], args[2]);\n            break;\n        default:\n            callback.apply(undefined, args);\n            break;\n        }\n    }\n\n    function runIfPresent(handle) {\n        // From the spec: \"Wait until any invocations of this algorithm started before this one have completed.\"\n        // So if we're currently running a task, we'll need to delay this invocation.\n        if (currentlyRunningATask) {\n            // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a\n            // \"too much recursion\" error.\n            setTimeout(runIfPresent, 0, handle);\n        } else {\n            var task = tasksByHandle[handle];\n            if (task) {\n                currentlyRunningATask = true;\n                try {\n                    run(task);\n                } finally {\n                    clearImmediate(handle);\n                    currentlyRunningATask = false;\n                }\n            }\n        }\n    }\n\n    function installNextTickImplementation() {\n        registerImmediate = function(handle) {\n            process.nextTick(function () { runIfPresent(handle); });\n        };\n    }\n\n    function canUsePostMessage() {\n        // The test against `importScripts` prevents this implementation from being installed inside a web worker,\n        // where `global.postMessage` means something completely different and can't be used for this purpose.\n        if (global.postMessage && !global.importScripts) {\n            var postMessageIsAsynchronous = true;\n            var oldOnMessage = global.onmessage;\n            global.onmessage = function() {\n                postMessageIsAsynchronous = false;\n            };\n            global.postMessage(\"\", \"*\");\n            global.onmessage = oldOnMessage;\n            return postMessageIsAsynchronous;\n        }\n    }\n\n    function installPostMessageImplementation() {\n        // Installs an event handler on `global` for the `message` event: see\n        // * https://developer.mozilla.org/en/DOM/window.postMessage\n        // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages\n\n        var messagePrefix = \"setImmediate$\" + Math.random() + \"$\";\n        var onGlobalMessage = function(event) {\n            if (event.source === global &&\n                typeof event.data === \"string\" &&\n                event.data.indexOf(messagePrefix) === 0) {\n                runIfPresent(+event.data.slice(messagePrefix.length));\n            }\n        };\n\n        if (global.addEventListener) {\n            global.addEventListener(\"message\", onGlobalMessage, false);\n        } else {\n            global.attachEvent(\"onmessage\", onGlobalMessage);\n        }\n\n        registerImmediate = function(handle) {\n            global.postMessage(messagePrefix + handle, \"*\");\n        };\n    }\n\n    function installMessageChannelImplementation() {\n        var channel = new MessageChannel();\n        channel.port1.onmessage = function(event) {\n            var handle = event.data;\n            runIfPresent(handle);\n        };\n\n        registerImmediate = function(handle) {\n            channel.port2.postMessage(handle);\n        };\n    }\n\n    function installReadyStateChangeImplementation() {\n        var html = doc.documentElement;\n        registerImmediate = function(handle) {\n            // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted\n            // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.\n            var script = doc.createElement(\"script\");\n            script.onreadystatechange = function () {\n                runIfPresent(handle);\n                script.onreadystatechange = null;\n                html.removeChild(script);\n                script = null;\n            };\n            html.appendChild(script);\n        };\n    }\n\n    function installSetTimeoutImplementation() {\n        registerImmediate = function(handle) {\n            setTimeout(runIfPresent, 0, handle);\n        };\n    }\n\n    // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.\n    var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);\n    attachTo = attachTo && attachTo.setTimeout ? attachTo : global;\n\n    // Don't get fooled by e.g. browserify environments.\n    if ({}.toString.call(global.process) === \"[object process]\") {\n        // For Node.js before 0.9\n        installNextTickImplementation();\n\n    } else if (canUsePostMessage()) {\n        // For non-IE10 modern browsers\n        installPostMessageImplementation();\n\n    } else if (global.MessageChannel) {\n        // For web workers, where supported\n        installMessageChannelImplementation();\n\n    } else if (doc && \"onreadystatechange\" in doc.createElement(\"script\")) {\n        // For IE 6–8\n        installReadyStateChangeImplementation();\n\n    } else {\n        // For older browsers\n        installSetTimeoutImplementation();\n    }\n\n    attachTo.setImmediate = setImmediate;\n    attachTo.clearImmediate = clearImmediate;\n}(typeof self === \"undefined\" ? typeof global === \"undefined\" ? this : global : self));\n\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1), __webpack_require__(17)))\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports) {\n\n// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things.  But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals.  It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n    throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n    throw new Error('clearTimeout has not been defined');\n}\n(function () {\n    try {\n        if (typeof setTimeout === 'function') {\n            cachedSetTimeout = setTimeout;\n        } else {\n            cachedSetTimeout = defaultSetTimout;\n        }\n    } catch (e) {\n        cachedSetTimeout = defaultSetTimout;\n    }\n    try {\n        if (typeof clearTimeout === 'function') {\n            cachedClearTimeout = clearTimeout;\n        } else {\n            cachedClearTimeout = defaultClearTimeout;\n        }\n    } catch (e) {\n        cachedClearTimeout = defaultClearTimeout;\n    }\n} ())\nfunction runTimeout(fun) {\n    if (cachedSetTimeout === setTimeout) {\n        //normal enviroments in sane situations\n        return setTimeout(fun, 0);\n    }\n    // if setTimeout wasn't available but was latter defined\n    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n        cachedSetTimeout = setTimeout;\n        return setTimeout(fun, 0);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedSetTimeout(fun, 0);\n    } catch(e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n            return cachedSetTimeout.call(null, fun, 0);\n        } catch(e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n            return cachedSetTimeout.call(this, fun, 0);\n        }\n    }\n\n\n}\nfunction runClearTimeout(marker) {\n    if (cachedClearTimeout === clearTimeout) {\n        //normal enviroments in sane situations\n        return clearTimeout(marker);\n    }\n    // if clearTimeout wasn't available but was latter defined\n    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n        cachedClearTimeout = clearTimeout;\n        return clearTimeout(marker);\n    }\n    try {\n        // when when somebody has screwed with setTimeout but no I.E. maddness\n        return cachedClearTimeout(marker);\n    } catch (e){\n        try {\n            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally\n            return cachedClearTimeout.call(null, marker);\n        } catch (e){\n            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n            // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n            return cachedClearTimeout.call(this, marker);\n        }\n    }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n    if (!draining || !currentQueue) {\n        return;\n    }\n    draining = false;\n    if (currentQueue.length) {\n        queue = currentQueue.concat(queue);\n    } else {\n        queueIndex = -1;\n    }\n    if (queue.length) {\n        drainQueue();\n    }\n}\n\nfunction drainQueue() {\n    if (draining) {\n        return;\n    }\n    var timeout = runTimeout(cleanUpNextTick);\n    draining = true;\n\n    var len = queue.length;\n    while(len) {\n        currentQueue = queue;\n        queue = [];\n        while (++queueIndex < len) {\n            if (currentQueue) {\n                currentQueue[queueIndex].run();\n            }\n        }\n        queueIndex = -1;\n        len = queue.length;\n    }\n    currentQueue = null;\n    draining = false;\n    runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n    var args = new Array(arguments.length - 1);\n    if (arguments.length > 1) {\n        for (var i = 1; i < arguments.length; i++) {\n            args[i - 1] = arguments[i];\n        }\n    }\n    queue.push(new Item(fun, args));\n    if (queue.length === 1 && !draining) {\n        runTimeout(drainQueue);\n    }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n    this.fun = fun;\n    this.array = array;\n}\nItem.prototype.run = function () {\n    this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n    throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n    throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n\n/***/ }),\n/* 18 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/**\n * @this {Promise}\n */\nfunction finallyConstructor(callback) {\n  var constructor = this.constructor;\n  return this.then(\n    function(value) {\n      return constructor.resolve(callback()).then(function() {\n        return value;\n      });\n    },\n    function(reason) {\n      return constructor.resolve(callback()).then(function() {\n        return constructor.reject(reason);\n      });\n    }\n  );\n}\n\n/* harmony default export */ __webpack_exports__[\"a\"] = (finallyConstructor);\n\n\n/***/ }),\n/* 19 */\n/***/ (function(module, exports, __webpack_require__) {\n\n/*!\n * clipboard.js v2.0.4\n * https://zenorocha.github.io/clipboard.js\n * \n * Licensed MIT © Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(true)\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = function(exports) {\n/******/ \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, '__esModule', { value: true });\n/******/ \t};\n/******/\n/******/ \t// create a fake namespace object\n/******/ \t// mode & 1: value is a module id, require it\n/******/ \t// mode & 2: merge all properties of value into the ns\n/******/ \t// mode & 4: return value when already ns object\n/******/ \t// mode & 8|1: behave like require\n/******/ \t__webpack_require__.t = function(value, mode) {\n/******/ \t\tif(mode & 1) value = __webpack_require__(value);\n/******/ \t\tif(mode & 8) return value;\n/******/ \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n/******/ \t\tvar ns = Object.create(null);\n/******/ \t\t__webpack_require__.r(ns);\n/******/ \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n/******/ \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n/******/ \t\treturn ns;\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _clipboardAction = __webpack_require__(1);\n\nvar _clipboardAction2 = _interopRequireDefault(_clipboardAction);\n\nvar _tinyEmitter = __webpack_require__(3);\n\nvar _tinyEmitter2 = _interopRequireDefault(_tinyEmitter);\n\nvar _goodListener = __webpack_require__(4);\n\nvar _goodListener2 = _interopRequireDefault(_goodListener);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\nvar Clipboard = function (_Emitter) {\n    _inherits(Clipboard, _Emitter);\n\n    /**\n     * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n     * @param {Object} options\n     */\n    function Clipboard(trigger, options) {\n        _classCallCheck(this, Clipboard);\n\n        var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this));\n\n        _this.resolveOptions(options);\n        _this.listenClick(trigger);\n        return _this;\n    }\n\n    /**\n     * Defines if attributes would be resolved using internal setter functions\n     * or custom functions that were passed in the constructor.\n     * @param {Object} options\n     */\n\n\n    _createClass(Clipboard, [{\n        key: 'resolveOptions',\n        value: function resolveOptions() {\n            var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n            this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n            this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n            this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n            this.container = _typeof(options.container) === 'object' ? options.container : document.body;\n        }\n\n        /**\n         * Adds a click event listener to the passed trigger.\n         * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n         */\n\n    }, {\n        key: 'listenClick',\n        value: function listenClick(trigger) {\n            var _this2 = this;\n\n            this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) {\n                return _this2.onClick(e);\n            });\n        }\n\n        /**\n         * Defines a new `ClipboardAction` on each click event.\n         * @param {Event} e\n         */\n\n    }, {\n        key: 'onClick',\n        value: function onClick(e) {\n            var trigger = e.delegateTarget || e.currentTarget;\n\n            if (this.clipboardAction) {\n                this.clipboardAction = null;\n            }\n\n            this.clipboardAction = new _clipboardAction2.default({\n                action: this.action(trigger),\n                target: this.target(trigger),\n                text: this.text(trigger),\n                container: this.container,\n                trigger: trigger,\n                emitter: this\n            });\n        }\n\n        /**\n         * Default `action` lookup function.\n         * @param {Element} trigger\n         */\n\n    }, {\n        key: 'defaultAction',\n        value: function defaultAction(trigger) {\n            return getAttributeValue('action', trigger);\n        }\n\n        /**\n         * Default `target` lookup function.\n         * @param {Element} trigger\n         */\n\n    }, {\n        key: 'defaultTarget',\n        value: function defaultTarget(trigger) {\n            var selector = getAttributeValue('target', trigger);\n\n            if (selector) {\n                return document.querySelector(selector);\n            }\n        }\n\n        /**\n         * Returns the support of the given action, or all actions if no action is\n         * given.\n         * @param {String} [action]\n         */\n\n    }, {\n        key: 'defaultText',\n\n\n        /**\n         * Default `text` lookup function.\n         * @param {Element} trigger\n         */\n        value: function defaultText(trigger) {\n            return getAttributeValue('text', trigger);\n        }\n\n        /**\n         * Destroy lifecycle.\n         */\n\n    }, {\n        key: 'destroy',\n        value: function destroy() {\n            this.listener.destroy();\n\n            if (this.clipboardAction) {\n                this.clipboardAction.destroy();\n                this.clipboardAction = null;\n            }\n        }\n    }], [{\n        key: 'isSupported',\n        value: function isSupported() {\n            var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n\n            var actions = typeof action === 'string' ? [action] : action;\n            var support = !!document.queryCommandSupported;\n\n            actions.forEach(function (action) {\n                support = support && !!document.queryCommandSupported(action);\n            });\n\n            return support;\n        }\n    }]);\n\n    return Clipboard;\n}(_tinyEmitter2.default);\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\n\nfunction getAttributeValue(suffix, element) {\n    var attribute = 'data-clipboard-' + suffix;\n\n    if (!element.hasAttribute(attribute)) {\n        return;\n    }\n\n    return element.getAttribute(attribute);\n}\n\nmodule.exports = Clipboard;\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _select = __webpack_require__(2);\n\nvar _select2 = _interopRequireDefault(_select);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * Inner class which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n */\nvar ClipboardAction = function () {\n    /**\n     * @param {Object} options\n     */\n    function ClipboardAction(options) {\n        _classCallCheck(this, ClipboardAction);\n\n        this.resolveOptions(options);\n        this.initSelection();\n    }\n\n    /**\n     * Defines base properties passed from constructor.\n     * @param {Object} options\n     */\n\n\n    _createClass(ClipboardAction, [{\n        key: 'resolveOptions',\n        value: function resolveOptions() {\n            var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n            this.action = options.action;\n            this.container = options.container;\n            this.emitter = options.emitter;\n            this.target = options.target;\n            this.text = options.text;\n            this.trigger = options.trigger;\n\n            this.selectedText = '';\n        }\n\n        /**\n         * Decides which selection strategy is going to be applied based\n         * on the existence of `text` and `target` properties.\n         */\n\n    }, {\n        key: 'initSelection',\n        value: function initSelection() {\n            if (this.text) {\n                this.selectFake();\n            } else if (this.target) {\n                this.selectTarget();\n            }\n        }\n\n        /**\n         * Creates a fake textarea element, sets its value from `text` property,\n         * and makes a selection on it.\n         */\n\n    }, {\n        key: 'selectFake',\n        value: function selectFake() {\n            var _this = this;\n\n            var isRTL = document.documentElement.getAttribute('dir') == 'rtl';\n\n            this.removeFake();\n\n            this.fakeHandlerCallback = function () {\n                return _this.removeFake();\n            };\n            this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || true;\n\n            this.fakeElem = document.createElement('textarea');\n            // Prevent zooming on iOS\n            this.fakeElem.style.fontSize = '12pt';\n            // Reset box model\n            this.fakeElem.style.border = '0';\n            this.fakeElem.style.padding = '0';\n            this.fakeElem.style.margin = '0';\n            // Move element out of screen horizontally\n            this.fakeElem.style.position = 'absolute';\n            this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px';\n            // Move element to the same position vertically\n            var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n            this.fakeElem.style.top = yPosition + 'px';\n\n            this.fakeElem.setAttribute('readonly', '');\n            this.fakeElem.value = this.text;\n\n            this.container.appendChild(this.fakeElem);\n\n            this.selectedText = (0, _select2.default)(this.fakeElem);\n            this.copyText();\n        }\n\n        /**\n         * Only removes the fake element after another click event, that way\n         * a user can hit `Ctrl+C` to copy because selection still exists.\n         */\n\n    }, {\n        key: 'removeFake',\n        value: function removeFake() {\n            if (this.fakeHandler) {\n                this.container.removeEventListener('click', this.fakeHandlerCallback);\n                this.fakeHandler = null;\n                this.fakeHandlerCallback = null;\n            }\n\n            if (this.fakeElem) {\n                this.container.removeChild(this.fakeElem);\n                this.fakeElem = null;\n            }\n        }\n\n        /**\n         * Selects the content from element passed on `target` property.\n         */\n\n    }, {\n        key: 'selectTarget',\n        value: function selectTarget() {\n            this.selectedText = (0, _select2.default)(this.target);\n            this.copyText();\n        }\n\n        /**\n         * Executes the copy operation based on the current selection.\n         */\n\n    }, {\n        key: 'copyText',\n        value: function copyText() {\n            var succeeded = void 0;\n\n            try {\n                succeeded = document.execCommand(this.action);\n            } catch (err) {\n                succeeded = false;\n            }\n\n            this.handleResult(succeeded);\n        }\n\n        /**\n         * Fires an event based on the copy operation result.\n         * @param {Boolean} succeeded\n         */\n\n    }, {\n        key: 'handleResult',\n        value: function handleResult(succeeded) {\n            this.emitter.emit(succeeded ? 'success' : 'error', {\n                action: this.action,\n                text: this.selectedText,\n                trigger: this.trigger,\n                clearSelection: this.clearSelection.bind(this)\n            });\n        }\n\n        /**\n         * Moves focus away from `target` and back to the trigger, removes current selection.\n         */\n\n    }, {\n        key: 'clearSelection',\n        value: function clearSelection() {\n            if (this.trigger) {\n                this.trigger.focus();\n            }\n\n            window.getSelection().removeAllRanges();\n        }\n\n        /**\n         * Sets the `action` to be performed which can be either 'copy' or 'cut'.\n         * @param {String} action\n         */\n\n    }, {\n        key: 'destroy',\n\n\n        /**\n         * Destroy lifecycle.\n         */\n        value: function destroy() {\n            this.removeFake();\n        }\n    }, {\n        key: 'action',\n        set: function set() {\n            var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy';\n\n            this._action = action;\n\n            if (this._action !== 'copy' && this._action !== 'cut') {\n                throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n            }\n        }\n\n        /**\n         * Gets the `action` property.\n         * @return {String}\n         */\n        ,\n        get: function get() {\n            return this._action;\n        }\n\n        /**\n         * Sets the `target` property using an element\n         * that will be have its content copied.\n         * @param {Element} target\n         */\n\n    }, {\n        key: 'target',\n        set: function set(target) {\n            if (target !== undefined) {\n                if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) {\n                    if (this.action === 'copy' && target.hasAttribute('disabled')) {\n                        throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n                    }\n\n                    if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n                        throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n                    }\n\n                    this._target = target;\n                } else {\n                    throw new Error('Invalid \"target\" value, use a valid Element');\n                }\n            }\n        }\n\n        /**\n         * Gets the `target` property.\n         * @return {String|HTMLElement}\n         */\n        ,\n        get: function get() {\n            return this._target;\n        }\n    }]);\n\n    return ClipboardAction;\n}();\n\nmodule.exports = ClipboardAction;\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports) {\n\nfunction select(element) {\n    var selectedText;\n\n    if (element.nodeName === 'SELECT') {\n        element.focus();\n\n        selectedText = element.value;\n    }\n    else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n        var isReadOnly = element.hasAttribute('readonly');\n\n        if (!isReadOnly) {\n            element.setAttribute('readonly', '');\n        }\n\n        element.select();\n        element.setSelectionRange(0, element.value.length);\n\n        if (!isReadOnly) {\n            element.removeAttribute('readonly');\n        }\n\n        selectedText = element.value;\n    }\n    else {\n        if (element.hasAttribute('contenteditable')) {\n            element.focus();\n        }\n\n        var selection = window.getSelection();\n        var range = document.createRange();\n\n        range.selectNodeContents(element);\n        selection.removeAllRanges();\n        selection.addRange(range);\n\n        selectedText = selection.toString();\n    }\n\n    return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports) {\n\nfunction E () {\n  // Keep this empty so it's easier to inherit from\n  // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n  on: function (name, callback, ctx) {\n    var e = this.e || (this.e = {});\n\n    (e[name] || (e[name] = [])).push({\n      fn: callback,\n      ctx: ctx\n    });\n\n    return this;\n  },\n\n  once: function (name, callback, ctx) {\n    var self = this;\n    function listener () {\n      self.off(name, listener);\n      callback.apply(ctx, arguments);\n    };\n\n    listener._ = callback\n    return this.on(name, listener, ctx);\n  },\n\n  emit: function (name) {\n    var data = [].slice.call(arguments, 1);\n    var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n    var i = 0;\n    var len = evtArr.length;\n\n    for (i; i < len; i++) {\n      evtArr[i].fn.apply(evtArr[i].ctx, data);\n    }\n\n    return this;\n  },\n\n  off: function (name, callback) {\n    var e = this.e || (this.e = {});\n    var evts = e[name];\n    var liveEvents = [];\n\n    if (evts && callback) {\n      for (var i = 0, len = evts.length; i < len; i++) {\n        if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n          liveEvents.push(evts[i]);\n      }\n    }\n\n    // Remove event from queue to prevent memory leak\n    // Suggested by https://github.com/lazd\n    // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n    (liveEvents.length)\n      ? e[name] = liveEvents\n      : delete e[name];\n\n    return this;\n  }\n};\n\nmodule.exports = E;\n\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar is = __webpack_require__(5);\nvar delegate = __webpack_require__(6);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n    if (!target && !type && !callback) {\n        throw new Error('Missing required arguments');\n    }\n\n    if (!is.string(type)) {\n        throw new TypeError('Second argument must be a String');\n    }\n\n    if (!is.fn(callback)) {\n        throw new TypeError('Third argument must be a Function');\n    }\n\n    if (is.node(target)) {\n        return listenNode(target, type, callback);\n    }\n    else if (is.nodeList(target)) {\n        return listenNodeList(target, type, callback);\n    }\n    else if (is.string(target)) {\n        return listenSelector(target, type, callback);\n    }\n    else {\n        throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n    }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n    node.addEventListener(type, callback);\n\n    return {\n        destroy: function() {\n            node.removeEventListener(type, callback);\n        }\n    }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n    Array.prototype.forEach.call(nodeList, function(node) {\n        node.addEventListener(type, callback);\n    });\n\n    return {\n        destroy: function() {\n            Array.prototype.forEach.call(nodeList, function(node) {\n                node.removeEventListener(type, callback);\n            });\n        }\n    }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n    return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n    return value !== undefined\n        && value instanceof HTMLElement\n        && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n    var type = Object.prototype.toString.call(value);\n\n    return value !== undefined\n        && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n        && ('length' in value)\n        && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n    return typeof value === 'string'\n        || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n    var type = Object.prototype.toString.call(value);\n\n    return type === '[object Function]';\n};\n\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar closest = __webpack_require__(7);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n    var listenerFn = listener.apply(this, arguments);\n\n    element.addEventListener(type, listenerFn, useCapture);\n\n    return {\n        destroy: function() {\n            element.removeEventListener(type, listenerFn, useCapture);\n        }\n    }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n    // Handle the regular Element usage\n    if (typeof elements.addEventListener === 'function') {\n        return _delegate.apply(null, arguments);\n    }\n\n    // Handle Element-less usage, it defaults to global delegation\n    if (typeof type === 'function') {\n        // Use `document` as the first parameter, then apply arguments\n        // This is a short way to .unshift `arguments` without running into deoptimizations\n        return _delegate.bind(null, document).apply(null, arguments);\n    }\n\n    // Handle Selector-based usage\n    if (typeof elements === 'string') {\n        elements = document.querySelectorAll(elements);\n    }\n\n    // Handle Array-like based usage\n    return Array.prototype.map.call(elements, function (element) {\n        return _delegate(element, selector, type, callback, useCapture);\n    });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n    return function(e) {\n        e.delegateTarget = closest(e.target, selector);\n\n        if (e.delegateTarget) {\n            callback.call(element, e);\n        }\n    }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n    var proto = Element.prototype;\n\n    proto.matches = proto.matchesSelector ||\n                    proto.mozMatchesSelector ||\n                    proto.msMatchesSelector ||\n                    proto.oMatchesSelector ||\n                    proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n    while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n        if (typeof element.matches === 'function' &&\n            element.matches(selector)) {\n          return element;\n        }\n        element = element.parentNode;\n    }\n}\n\nmodule.exports = closest;\n\n\n/***/ })\n/******/ ]);\n});\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar __WEBPACK_AMD_DEFINE_RESULT__;;(function () {\n\t'use strict';\n\n\t/**\n\t * @preserve FastClick: polyfill to remove click delays on browsers with touch UIs.\n\t *\n\t * @codingstandard ftlabs-jsv2\n\t * @copyright The Financial Times Limited [All Rights Reserved]\n\t * @license MIT License (see LICENSE.txt)\n\t */\n\n\t/*jslint browser:true, node:true*/\n\t/*global define, Event, Node*/\n\n\n\t/**\n\t * Instantiate fast-clicking listeners on the specified layer.\n\t *\n\t * @constructor\n\t * @param {Element} layer The layer to listen on\n\t * @param {Object} [options={}] The options to override the defaults\n\t */\n\tfunction FastClick(layer, options) {\n\t\tvar oldOnClick;\n\n\t\toptions = options || {};\n\n\t\t/**\n\t\t * Whether a click is currently being tracked.\n\t\t *\n\t\t * @type boolean\n\t\t */\n\t\tthis.trackingClick = false;\n\n\n\t\t/**\n\t\t * Timestamp for when click tracking started.\n\t\t *\n\t\t * @type number\n\t\t */\n\t\tthis.trackingClickStart = 0;\n\n\n\t\t/**\n\t\t * The element being tracked for a click.\n\t\t *\n\t\t * @type EventTarget\n\t\t */\n\t\tthis.targetElement = null;\n\n\n\t\t/**\n\t\t * X-coordinate of touch start event.\n\t\t *\n\t\t * @type number\n\t\t */\n\t\tthis.touchStartX = 0;\n\n\n\t\t/**\n\t\t * Y-coordinate of touch start event.\n\t\t *\n\t\t * @type number\n\t\t */\n\t\tthis.touchStartY = 0;\n\n\n\t\t/**\n\t\t * ID of the last touch, retrieved from Touch.identifier.\n\t\t *\n\t\t * @type number\n\t\t */\n\t\tthis.lastTouchIdentifier = 0;\n\n\n\t\t/**\n\t\t * Touchmove boundary, beyond which a click will be cancelled.\n\t\t *\n\t\t * @type number\n\t\t */\n\t\tthis.touchBoundary = options.touchBoundary || 10;\n\n\n\t\t/**\n\t\t * The FastClick layer.\n\t\t *\n\t\t * @type Element\n\t\t */\n\t\tthis.layer = layer;\n\n\t\t/**\n\t\t * The minimum time between tap(touchstart and touchend) events\n\t\t *\n\t\t * @type number\n\t\t */\n\t\tthis.tapDelay = options.tapDelay || 200;\n\n\t\t/**\n\t\t * The maximum time for a tap\n\t\t *\n\t\t * @type number\n\t\t */\n\t\tthis.tapTimeout = options.tapTimeout || 700;\n\n\t\tif (FastClick.notNeeded(layer)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Some old versions of Android don't have Function.prototype.bind\n\t\tfunction bind(method, context) {\n\t\t\treturn function() { return method.apply(context, arguments); };\n\t\t}\n\n\n\t\tvar methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'];\n\t\tvar context = this;\n\t\tfor (var i = 0, l = methods.length; i < l; i++) {\n\t\t\tcontext[methods[i]] = bind(context[methods[i]], context);\n\t\t}\n\n\t\t// Set up event handlers as required\n\t\tif (deviceIsAndroid) {\n\t\t\tlayer.addEventListener('mouseover', this.onMouse, true);\n\t\t\tlayer.addEventListener('mousedown', this.onMouse, true);\n\t\t\tlayer.addEventListener('mouseup', this.onMouse, true);\n\t\t}\n\n\t\tlayer.addEventListener('click', this.onClick, true);\n\t\tlayer.addEventListener('touchstart', this.onTouchStart, false);\n\t\tlayer.addEventListener('touchmove', this.onTouchMove, false);\n\t\tlayer.addEventListener('touchend', this.onTouchEnd, false);\n\t\tlayer.addEventListener('touchcancel', this.onTouchCancel, false);\n\n\t\t// Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)\n\t\t// which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick\n\t\t// layer when they are cancelled.\n\t\tif (!Event.prototype.stopImmediatePropagation) {\n\t\t\tlayer.removeEventListener = function(type, callback, capture) {\n\t\t\t\tvar rmv = Node.prototype.removeEventListener;\n\t\t\t\tif (type === 'click') {\n\t\t\t\t\trmv.call(layer, type, callback.hijacked || callback, capture);\n\t\t\t\t} else {\n\t\t\t\t\trmv.call(layer, type, callback, capture);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tlayer.addEventListener = function(type, callback, capture) {\n\t\t\t\tvar adv = Node.prototype.addEventListener;\n\t\t\t\tif (type === 'click') {\n\t\t\t\t\tadv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {\n\t\t\t\t\t\tif (!event.propagationStopped) {\n\t\t\t\t\t\t\tcallback(event);\n\t\t\t\t\t\t}\n\t\t\t\t\t}), capture);\n\t\t\t\t} else {\n\t\t\t\t\tadv.call(layer, type, callback, capture);\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\t// If a handler is already declared in the element's onclick attribute, it will be fired before\n\t\t// FastClick's onClick handler. Fix this by pulling out the user-defined handler function and\n\t\t// adding it as listener.\n\t\tif (typeof layer.onclick === 'function') {\n\n\t\t\t// Android browser on at least 3.2 requires a new reference to the function in layer.onclick\n\t\t\t// - the old one won't work if passed to addEventListener directly.\n\t\t\toldOnClick = layer.onclick;\n\t\t\tlayer.addEventListener('click', function(event) {\n\t\t\t\toldOnClick(event);\n\t\t\t}, false);\n\t\t\tlayer.onclick = null;\n\t\t}\n\t}\n\n\t/**\n\t* Windows Phone 8.1 fakes user agent string to look like Android and iPhone.\n\t*\n\t* @type boolean\n\t*/\n\tvar deviceIsWindowsPhone = navigator.userAgent.indexOf(\"Windows Phone\") >= 0;\n\n\t/**\n\t * Android requires exceptions.\n\t *\n\t * @type boolean\n\t */\n\tvar deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0 && !deviceIsWindowsPhone;\n\n\n\t/**\n\t * iOS requires exceptions.\n\t *\n\t * @type boolean\n\t */\n\tvar deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent) && !deviceIsWindowsPhone;\n\n\n\t/**\n\t * iOS 4 requires an exception for select elements.\n\t *\n\t * @type boolean\n\t */\n\tvar deviceIsIOS4 = deviceIsIOS && (/OS 4_\\d(_\\d)?/).test(navigator.userAgent);\n\n\n\t/**\n\t * iOS 6.0-7.* requires the target element to be manually derived\n\t *\n\t * @type boolean\n\t */\n\tvar deviceIsIOSWithBadTarget = deviceIsIOS && (/OS [6-7]_\\d/).test(navigator.userAgent);\n\n\t/**\n\t * BlackBerry requires exceptions.\n\t *\n\t * @type boolean\n\t */\n\tvar deviceIsBlackBerry10 = navigator.userAgent.indexOf('BB10') > 0;\n\n\t/**\n\t * Determine whether a given element requires a native click.\n\t *\n\t * @param {EventTarget|Element} target Target DOM element\n\t * @returns {boolean} Returns true if the element needs a native click\n\t */\n\tFastClick.prototype.needsClick = function(target) {\n\t\tswitch (target.nodeName.toLowerCase()) {\n\n\t\t// Don't send a synthetic click to disabled inputs (issue #62)\n\t\tcase 'button':\n\t\tcase 'select':\n\t\tcase 'textarea':\n\t\t\tif (target.disabled) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tbreak;\n\t\tcase 'input':\n\n\t\t\t// File inputs need real clicks on iOS 6 due to a browser bug (issue #68)\n\t\t\tif ((deviceIsIOS && target.type === 'file') || target.disabled) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tbreak;\n\t\tcase 'label':\n\t\tcase 'iframe': // iOS8 homescreen apps can prevent events bubbling into frames\n\t\tcase 'video':\n\t\t\treturn true;\n\t\t}\n\n\t\treturn (/\\bneedsclick\\b/).test(target.className);\n\t};\n\n\n\t/**\n\t * Determine whether a given element requires a call to focus to simulate click into element.\n\t *\n\t * @param {EventTarget|Element} target Target DOM element\n\t * @returns {boolean} Returns true if the element requires a call to focus to simulate native click.\n\t */\n\tFastClick.prototype.needsFocus = function(target) {\n\t\tswitch (target.nodeName.toLowerCase()) {\n\t\tcase 'textarea':\n\t\t\treturn true;\n\t\tcase 'select':\n\t\t\treturn !deviceIsAndroid;\n\t\tcase 'input':\n\t\t\tswitch (target.type) {\n\t\t\tcase 'button':\n\t\t\tcase 'checkbox':\n\t\t\tcase 'file':\n\t\t\tcase 'image':\n\t\t\tcase 'radio':\n\t\t\tcase 'submit':\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// No point in attempting to focus disabled inputs\n\t\t\treturn !target.disabled && !target.readOnly;\n\t\tdefault:\n\t\t\treturn (/\\bneedsfocus\\b/).test(target.className);\n\t\t}\n\t};\n\n\n\t/**\n\t * Send a click event to the specified element.\n\t *\n\t * @param {EventTarget|Element} targetElement\n\t * @param {Event} event\n\t */\n\tFastClick.prototype.sendClick = function(targetElement, event) {\n\t\tvar clickEvent, touch;\n\n\t\t// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)\n\t\tif (document.activeElement && document.activeElement !== targetElement) {\n\t\t\tdocument.activeElement.blur();\n\t\t}\n\n\t\ttouch = event.changedTouches[0];\n\n\t\t// Synthesise a click event, with an extra attribute so it can be tracked\n\t\tclickEvent = document.createEvent('MouseEvents');\n\t\tclickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);\n\t\tclickEvent.forwardedTouchEvent = true;\n\t\ttargetElement.dispatchEvent(clickEvent);\n\t};\n\n\tFastClick.prototype.determineEventType = function(targetElement) {\n\n\t\t//Issue #159: Android Chrome Select Box does not open with a synthetic click event\n\t\tif (deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') {\n\t\t\treturn 'mousedown';\n\t\t}\n\n\t\treturn 'click';\n\t};\n\n\n\t/**\n\t * @param {EventTarget|Element} targetElement\n\t */\n\tFastClick.prototype.focus = function(targetElement) {\n\t\tvar length;\n\n\t\t// Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.\n\t\tif (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month') {\n\t\t\tlength = targetElement.value.length;\n\t\t\ttargetElement.setSelectionRange(length, length);\n\t\t} else {\n\t\t\ttargetElement.focus();\n\t\t}\n\t};\n\n\n\t/**\n\t * Check whether the given target element is a child of a scrollable layer and if so, set a flag on it.\n\t *\n\t * @param {EventTarget|Element} targetElement\n\t */\n\tFastClick.prototype.updateScrollParent = function(targetElement) {\n\t\tvar scrollParent, parentElement;\n\n\t\tscrollParent = targetElement.fastClickScrollParent;\n\n\t\t// Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the\n\t\t// target element was moved to another parent.\n\t\tif (!scrollParent || !scrollParent.contains(targetElement)) {\n\t\t\tparentElement = targetElement;\n\t\t\tdo {\n\t\t\t\tif (parentElement.scrollHeight > parentElement.offsetHeight) {\n\t\t\t\t\tscrollParent = parentElement;\n\t\t\t\t\ttargetElement.fastClickScrollParent = parentElement;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tparentElement = parentElement.parentElement;\n\t\t\t} while (parentElement);\n\t\t}\n\n\t\t// Always update the scroll top tracker if possible.\n\t\tif (scrollParent) {\n\t\t\tscrollParent.fastClickLastScrollTop = scrollParent.scrollTop;\n\t\t}\n\t};\n\n\n\t/**\n\t * @param {EventTarget} targetElement\n\t * @returns {Element|EventTarget}\n\t */\n\tFastClick.prototype.getTargetElementFromEventTarget = function(eventTarget) {\n\n\t\t// On some older browsers (notably Safari on iOS 4.1 - see issue #56) the event target may be a text node.\n\t\tif (eventTarget.nodeType === Node.TEXT_NODE) {\n\t\t\treturn eventTarget.parentNode;\n\t\t}\n\n\t\treturn eventTarget;\n\t};\n\n\n\t/**\n\t * On touch start, record the position and scroll offset.\n\t *\n\t * @param {Event} event\n\t * @returns {boolean}\n\t */\n\tFastClick.prototype.onTouchStart = function(event) {\n\t\tvar targetElement, touch, selection;\n\n\t\t// Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111).\n\t\tif (event.targetTouches.length > 1) {\n\t\t\treturn true;\n\t\t}\n\n\t\ttargetElement = this.getTargetElementFromEventTarget(event.target);\n\t\ttouch = event.targetTouches[0];\n\n\t\tif (deviceIsIOS) {\n\n\t\t\t// Only trusted events will deselect text on iOS (issue #49)\n\t\t\tselection = window.getSelection();\n\t\t\tif (selection.rangeCount && !selection.isCollapsed) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (!deviceIsIOS4) {\n\n\t\t\t\t// Weird things happen on iOS when an alert or confirm dialog is opened from a click event callback (issue #23):\n\t\t\t\t// when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched\n\t\t\t\t// with the same identifier as the touch event that previously triggered the click that triggered the alert.\n\t\t\t\t// Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an\n\t\t\t\t// immediately preceeding touch event (issue #52), so this fix is unavailable on that platform.\n\t\t\t\t// Issue 120: touch.identifier is 0 when Chrome dev tools 'Emulate touch events' is set with an iOS device UA string,\n\t\t\t\t// which causes all touch events to be ignored. As this block only applies to iOS, and iOS identifiers are always long,\n\t\t\t\t// random integers, it's safe to to continue if the identifier is 0 here.\n\t\t\t\tif (touch.identifier && touch.identifier === this.lastTouchIdentifier) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tthis.lastTouchIdentifier = touch.identifier;\n\n\t\t\t\t// If the target element is a child of a scrollable layer (using -webkit-overflow-scrolling: touch) and:\n\t\t\t\t// 1) the user does a fling scroll on the scrollable layer\n\t\t\t\t// 2) the user stops the fling scroll with another tap\n\t\t\t\t// then the event.target of the last 'touchend' event will be the element that was under the user's finger\n\t\t\t\t// when the fling scroll was started, causing FastClick to send a click event to that layer - unless a check\n\t\t\t\t// is made to ensure that a parent layer was not scrolled before sending a synthetic click (issue #42).\n\t\t\t\tthis.updateScrollParent(targetElement);\n\t\t\t}\n\t\t}\n\n\t\tthis.trackingClick = true;\n\t\tthis.trackingClickStart = event.timeStamp;\n\t\tthis.targetElement = targetElement;\n\n\t\tthis.touchStartX = touch.pageX;\n\t\tthis.touchStartY = touch.pageY;\n\n\t\t// Prevent phantom clicks on fast double-tap (issue #36)\n\t\tif ((event.timeStamp - this.lastClickTime) < this.tapDelay) {\n\t\t\tevent.preventDefault();\n\t\t}\n\n\t\treturn true;\n\t};\n\n\n\t/**\n\t * Based on a touchmove event object, check whether the touch has moved past a boundary since it started.\n\t *\n\t * @param {Event} event\n\t * @returns {boolean}\n\t */\n\tFastClick.prototype.touchHasMoved = function(event) {\n\t\tvar touch = event.changedTouches[0], boundary = this.touchBoundary;\n\n\t\tif (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\n\t/**\n\t * Update the last position.\n\t *\n\t * @param {Event} event\n\t * @returns {boolean}\n\t */\n\tFastClick.prototype.onTouchMove = function(event) {\n\t\tif (!this.trackingClick) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// If the touch has moved, cancel the click tracking\n\t\tif (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) {\n\t\t\tthis.trackingClick = false;\n\t\t\tthis.targetElement = null;\n\t\t}\n\n\t\treturn true;\n\t};\n\n\n\t/**\n\t * Attempt to find the labelled control for the given label element.\n\t *\n\t * @param {EventTarget|HTMLLabelElement} labelElement\n\t * @returns {Element|null}\n\t */\n\tFastClick.prototype.findControl = function(labelElement) {\n\n\t\t// Fast path for newer browsers supporting the HTML5 control attribute\n\t\tif (labelElement.control !== undefined) {\n\t\t\treturn labelElement.control;\n\t\t}\n\n\t\t// All browsers under test that support touch events also support the HTML5 htmlFor attribute\n\t\tif (labelElement.htmlFor) {\n\t\t\treturn document.getElementById(labelElement.htmlFor);\n\t\t}\n\n\t\t// If no for attribute exists, attempt to retrieve the first labellable descendant element\n\t\t// the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label\n\t\treturn labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea');\n\t};\n\n\n\t/**\n\t * On touch end, determine whether to send a click event at once.\n\t *\n\t * @param {Event} event\n\t * @returns {boolean}\n\t */\n\tFastClick.prototype.onTouchEnd = function(event) {\n\t\tvar forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;\n\n\t\tif (!this.trackingClick) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Prevent phantom clicks on fast double-tap (issue #36)\n\t\tif ((event.timeStamp - this.lastClickTime) < this.tapDelay) {\n\t\t\tthis.cancelNextClick = true;\n\t\t\treturn true;\n\t\t}\n\n\t\tif ((event.timeStamp - this.trackingClickStart) > this.tapTimeout) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Reset to prevent wrong click cancel on input (issue #156).\n\t\tthis.cancelNextClick = false;\n\n\t\tthis.lastClickTime = event.timeStamp;\n\n\t\ttrackingClickStart = this.trackingClickStart;\n\t\tthis.trackingClick = false;\n\t\tthis.trackingClickStart = 0;\n\n\t\t// On some iOS devices, the targetElement supplied with the event is invalid if the layer\n\t\t// is performing a transition or scroll, and has to be re-detected manually. Note that\n\t\t// for this to function correctly, it must be called *after* the event target is checked!\n\t\t// See issue #57; also filed as rdar://13048589 .\n\t\tif (deviceIsIOSWithBadTarget) {\n\t\t\ttouch = event.changedTouches[0];\n\n\t\t\t// In certain cases arguments of elementFromPoint can be negative, so prevent setting targetElement to null\n\t\t\ttargetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement;\n\t\t\ttargetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent;\n\t\t}\n\n\t\ttargetTagName = targetElement.tagName.toLowerCase();\n\t\tif (targetTagName === 'label') {\n\t\t\tforElement = this.findControl(targetElement);\n\t\t\tif (forElement) {\n\t\t\t\tthis.focus(targetElement);\n\t\t\t\tif (deviceIsAndroid) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\ttargetElement = forElement;\n\t\t\t}\n\t\t} else if (this.needsFocus(targetElement)) {\n\n\t\t\t// Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through.\n\t\t\t// Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37).\n\t\t\tif ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) {\n\t\t\t\tthis.targetElement = null;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis.focus(targetElement);\n\t\t\tthis.sendClick(targetElement, event);\n\n\t\t\t// Select elements need the event to go through on iOS 4, otherwise the selector menu won't open.\n\t\t\t// Also this breaks opening selects when VoiceOver is active on iOS6, iOS7 (and possibly others)\n\t\t\tif (!deviceIsIOS || targetTagName !== 'select') {\n\t\t\t\tthis.targetElement = null;\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tif (deviceIsIOS && !deviceIsIOS4) {\n\n\t\t\t// Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled\n\t\t\t// and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42).\n\t\t\tscrollParent = targetElement.fastClickScrollParent;\n\t\t\tif (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t// Prevent the actual click from going though - unless the target node is marked as requiring\n\t\t// real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted.\n\t\tif (!this.needsClick(targetElement)) {\n\t\t\tevent.preventDefault();\n\t\t\tthis.sendClick(targetElement, event);\n\t\t}\n\n\t\treturn false;\n\t};\n\n\n\t/**\n\t * On touch cancel, stop tracking the click.\n\t *\n\t * @returns {void}\n\t */\n\tFastClick.prototype.onTouchCancel = function() {\n\t\tthis.trackingClick = false;\n\t\tthis.targetElement = null;\n\t};\n\n\n\t/**\n\t * Determine mouse events which should be permitted.\n\t *\n\t * @param {Event} event\n\t * @returns {boolean}\n\t */\n\tFastClick.prototype.onMouse = function(event) {\n\n\t\t// If a target element was never set (because a touch event was never fired) allow the event\n\t\tif (!this.targetElement) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (event.forwardedTouchEvent) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Programmatically generated events targeting a specific element should be permitted\n\t\tif (!event.cancelable) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Derive and check the target element to see whether the mouse event needs to be permitted;\n\t\t// unless explicitly enabled, prevent non-touch click events from triggering actions,\n\t\t// to prevent ghost/doubleclicks.\n\t\tif (!this.needsClick(this.targetElement) || this.cancelNextClick) {\n\n\t\t\t// Prevent any user-added listeners declared on FastClick element from being fired.\n\t\t\tif (event.stopImmediatePropagation) {\n\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t} else {\n\n\t\t\t\t// Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)\n\t\t\t\tevent.propagationStopped = true;\n\t\t\t}\n\n\t\t\t// Cancel the event\n\t\t\tevent.stopPropagation();\n\t\t\tevent.preventDefault();\n\n\t\t\treturn false;\n\t\t}\n\n\t\t// If the mouse event is permitted, return true for the action to go through.\n\t\treturn true;\n\t};\n\n\n\t/**\n\t * On actual clicks, determine whether this is a touch-generated click, a click action occurring\n\t * naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or\n\t * an actual click which should be permitted.\n\t *\n\t * @param {Event} event\n\t * @returns {boolean}\n\t */\n\tFastClick.prototype.onClick = function(event) {\n\t\tvar permitted;\n\n\t\t// It's possible for another FastClick-like library delivered with third-party code to fire a click event before FastClick does (issue #44). In that case, set the click-tracking flag back to false and return early. This will cause onTouchEnd to return early.\n\t\tif (this.trackingClick) {\n\t\t\tthis.targetElement = null;\n\t\t\tthis.trackingClick = false;\n\t\t\treturn true;\n\t\t}\n\n\t\t// Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target.\n\t\tif (event.target.type === 'submit' && event.detail === 0) {\n\t\t\treturn true;\n\t\t}\n\n\t\tpermitted = this.onMouse(event);\n\n\t\t// Only unset targetElement if the click is not permitted. This will ensure that the check for !targetElement in onMouse fails and the browser's click doesn't go through.\n\t\tif (!permitted) {\n\t\t\tthis.targetElement = null;\n\t\t}\n\n\t\t// If clicks are permitted, return true for the action to go through.\n\t\treturn permitted;\n\t};\n\n\n\t/**\n\t * Remove all FastClick's event listeners.\n\t *\n\t * @returns {void}\n\t */\n\tFastClick.prototype.destroy = function() {\n\t\tvar layer = this.layer;\n\n\t\tif (deviceIsAndroid) {\n\t\t\tlayer.removeEventListener('mouseover', this.onMouse, true);\n\t\t\tlayer.removeEventListener('mousedown', this.onMouse, true);\n\t\t\tlayer.removeEventListener('mouseup', this.onMouse, true);\n\t\t}\n\n\t\tlayer.removeEventListener('click', this.onClick, true);\n\t\tlayer.removeEventListener('touchstart', this.onTouchStart, false);\n\t\tlayer.removeEventListener('touchmove', this.onTouchMove, false);\n\t\tlayer.removeEventListener('touchend', this.onTouchEnd, false);\n\t\tlayer.removeEventListener('touchcancel', this.onTouchCancel, false);\n\t};\n\n\n\t/**\n\t * Check whether FastClick is needed.\n\t *\n\t * @param {Element} layer The layer to listen on\n\t */\n\tFastClick.notNeeded = function(layer) {\n\t\tvar metaViewport;\n\t\tvar chromeVersion;\n\t\tvar blackberryVersion;\n\t\tvar firefoxVersion;\n\n\t\t// Devices that don't support touch don't need FastClick\n\t\tif (typeof window.ontouchstart === 'undefined') {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Chrome version - zero for other browsers\n\t\tchromeVersion = +(/Chrome\\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];\n\n\t\tif (chromeVersion) {\n\n\t\t\tif (deviceIsAndroid) {\n\t\t\t\tmetaViewport = document.querySelector('meta[name=viewport]');\n\n\t\t\t\tif (metaViewport) {\n\t\t\t\t\t// Chrome on Android with user-scalable=\"no\" doesn't need FastClick (issue #89)\n\t\t\t\t\tif (metaViewport.content.indexOf('user-scalable=no') !== -1) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\t// Chrome 32 and above with width=device-width or less don't need FastClick\n\t\t\t\t\tif (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Chrome desktop doesn't need FastClick (issue #15)\n\t\t\t} else {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tif (deviceIsBlackBerry10) {\n\t\t\tblackberryVersion = navigator.userAgent.match(/Version\\/([0-9]*)\\.([0-9]*)/);\n\n\t\t\t// BlackBerry 10.3+ does not require Fastclick library.\n\t\t\t// https://github.com/ftlabs/fastclick/issues/251\n\t\t\tif (blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3) {\n\t\t\t\tmetaViewport = document.querySelector('meta[name=viewport]');\n\n\t\t\t\tif (metaViewport) {\n\t\t\t\t\t// user-scalable=no eliminates click delay.\n\t\t\t\t\tif (metaViewport.content.indexOf('user-scalable=no') !== -1) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\t// width=device-width (or less than device-width) eliminates click delay.\n\t\t\t\t\tif (document.documentElement.scrollWidth <= window.outerWidth) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// IE10 with -ms-touch-action: none or manipulation, which disables double-tap-to-zoom (issue #97)\n\t\tif (layer.style.msTouchAction === 'none' || layer.style.touchAction === 'manipulation') {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Firefox version - zero for other browsers\n\t\tfirefoxVersion = +(/Firefox\\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];\n\n\t\tif (firefoxVersion >= 27) {\n\t\t\t// Firefox 27+ does not have tap delay if the content is not zoomable - https://bugzilla.mozilla.org/show_bug.cgi?id=922896\n\n\t\t\tmetaViewport = document.querySelector('meta[name=viewport]');\n\t\t\tif (metaViewport && (metaViewport.content.indexOf('user-scalable=no') !== -1 || document.documentElement.scrollWidth <= window.outerWidth)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t// IE11: prefixed -ms-touch-action is no longer supported and it's recomended to use non-prefixed version\n\t\t// http://msdn.microsoft.com/en-us/library/windows/apps/Hh767313.aspx\n\t\tif (layer.style.touchAction === 'none' || layer.style.touchAction === 'manipulation') {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\n\t/**\n\t * Factory method for creating a FastClick object\n\t *\n\t * @param {Element} layer The layer to listen on\n\t * @param {Object} [options={}] The options to override the defaults\n\t */\n\tFastClick.attach = function(layer, options) {\n\t\treturn new FastClick(layer, options);\n\t};\n\n\n\tif (true) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\t!(__WEBPACK_AMD_DEFINE_RESULT__ = (function() {\n\t\t\treturn FastClick;\n\t\t}).call(exports, __webpack_require__, exports, module),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t} else if (typeof module !== 'undefined' && module.exports) {\n\t\tmodule.exports = FastClick.attach;\n\t\tmodule.exports.FastClick = FastClick;\n\t} else {\n\t\twindow.FastClick = FastClick;\n\t}\n}());\n\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nvar _Event = __webpack_require__(22);\n\nvar _Event2 = _interopRequireDefault(_Event);\n\nvar _Header = __webpack_require__(24);\n\nvar _Header2 = _interopRequireDefault(_Header);\n\nvar _Nav = __webpack_require__(27);\n\nvar _Nav2 = _interopRequireDefault(_Nav);\n\nvar _Search = __webpack_require__(31);\n\nvar _Search2 = _interopRequireDefault(_Search);\n\nvar _Sidebar = __webpack_require__(37);\n\nvar _Sidebar2 = _interopRequireDefault(_Sidebar);\n\nvar _Source = __webpack_require__(39);\n\nvar _Source2 = _interopRequireDefault(_Source);\n\nvar _Tabs = __webpack_require__(45);\n\nvar _Tabs2 = _interopRequireDefault(_Tabs);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/* ----------------------------------------------------------------------------\n * Module\n * ------------------------------------------------------------------------- */\n\nexports.default = {\n  Event: _Event2.default,\n  Header: _Header2.default,\n  Nav: _Nav2.default,\n  Search: _Search2.default,\n  Sidebar: _Sidebar2.default,\n  Source: _Source2.default,\n  Tabs: _Tabs2.default\n}; /*\n    * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n    *\n    * Permission is hereby granted, free of charge, to any person obtaining a copy\n    * of this software and associated documentation files (the \"Software\"), to\n    * deal in the Software without restriction, including without limitation the\n    * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n    * sell copies of the Software, and to permit persons to whom the Software is\n    * furnished to do so, subject to the following conditions:\n    *\n    * The above copyright notice and this permission notice shall be included in\n    * all copies or substantial portions of the Software.\n    *\n    * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n    * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n    * IN THE SOFTWARE.\n    */\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nvar _Listener = __webpack_require__(3);\n\nvar _Listener2 = _interopRequireDefault(_Listener);\n\nvar _MatchMedia = __webpack_require__(23);\n\nvar _MatchMedia2 = _interopRequireDefault(_MatchMedia);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/* ----------------------------------------------------------------------------\n * Module\n * ------------------------------------------------------------------------- */\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nexports.default = {\n  Listener: _Listener2.default,\n  MatchMedia: _MatchMedia2.default\n};\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nvar _Listener = __webpack_require__(3);\n\nvar _Listener2 = _interopRequireDefault(_Listener);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } /*\n                                                                                                                                                           * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n                                                                                                                                                           *\n                                                                                                                                                           * Permission is hereby granted, free of charge, to any person obtaining a copy\n                                                                                                                                                           * of this software and associated documentation files (the \"Software\"), to\n                                                                                                                                                           * deal in the Software without restriction, including without limitation the\n                                                                                                                                                           * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n                                                                                                                                                           * sell copies of the Software, and to permit persons to whom the Software is\n                                                                                                                                                           * furnished to do so, subject to the following conditions:\n                                                                                                                                                           *\n                                                                                                                                                           * The above copyright notice and this permission notice shall be included in\n                                                                                                                                                           * all copies or substantial portions of the Software.\n                                                                                                                                                           *\n                                                                                                                                                           * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n                                                                                                                                                           * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n                                                                                                                                                           * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n                                                                                                                                                           * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n                                                                                                                                                           * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n                                                                                                                                                           * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n                                                                                                                                                           * IN THE SOFTWARE.\n                                                                                                                                                           */\n\n// eslint-disable-line no-unused-vars\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\nvar MatchMedia =\n\n/**\n * Media query listener\n *\n * This class listens for state changes of media queries and automatically\n * switches the given listeners on or off.\n *\n * @constructor\n *\n * @property {Function} handler_ - Media query event handler\n *\n * @param {string} query - Media query to test for\n * @param {Listener} listener - Event listener\n */\nfunction MatchMedia(query, listener) {\n  _classCallCheck(this, MatchMedia);\n\n  this.handler_ = function (mq) {\n    if (mq.matches) listener.listen();else listener.unlisten();\n  };\n\n  /* Initialize media query listener */\n  var media = window.matchMedia(query);\n  media.addListener(this.handler_);\n\n  /* Always check at initialization */\n  this.handler_(media);\n};\n\nexports.default = MatchMedia;\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nvar _Shadow = __webpack_require__(25);\n\nvar _Shadow2 = _interopRequireDefault(_Shadow);\n\nvar _Title = __webpack_require__(26);\n\nvar _Title2 = _interopRequireDefault(_Title);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/* ----------------------------------------------------------------------------\n * Module\n * ------------------------------------------------------------------------- */\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nexports.default = {\n  Shadow: _Shadow2.default,\n  Title: _Title2.default\n};\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\nvar Shadow = function () {\n\n  /**\n   * Show or hide header shadow depending on page y-offset\n   *\n   * @constructor\n   *\n   * @property {HTMLElement} el_ - Content container\n   * @property {HTMLElement} header_ - Header\n   * @property {number} height_ - Offset height of previous nodes\n   * @property {boolean} active_ - Header shadow state\n   *\n   * @param {(string|HTMLElement)} el - Selector or HTML element\n   * @param {(string|HTMLElement)} header - Selector or HTML element\n   */\n  function Shadow(el, header) {\n    _classCallCheck(this, Shadow);\n\n    var ref = typeof el === \"string\" ? document.querySelector(el) : el;\n    if (!(ref instanceof HTMLElement) || !(ref.parentNode instanceof HTMLElement)) throw new ReferenceError();\n    this.el_ = ref.parentNode;\n\n    /* Retrieve header */\n    ref = typeof header === \"string\" ? document.querySelector(header) : header;\n    if (!(ref instanceof HTMLElement)) throw new ReferenceError();\n    this.header_ = ref;\n\n    /* Initialize height and state */\n    this.height_ = 0;\n    this.active_ = false;\n  }\n\n  /**\n   * Calculate total height of previous nodes\n   */\n\n\n  Shadow.prototype.setup = function setup() {\n    var current = this.el_;\n    while (current = current.previousElementSibling) {\n      if (!(current instanceof HTMLElement)) throw new ReferenceError();\n      this.height_ += current.offsetHeight;\n    }\n    this.update();\n  };\n\n  /**\n   * Update shadow state\n   *\n   * @param {Event} ev - Event\n   */\n\n\n  Shadow.prototype.update = function update(ev) {\n    if (ev && (ev.type === \"resize\" || ev.type === \"orientationchange\")) {\n      this.height_ = 0;\n      this.setup();\n    } else {\n      var active = window.pageYOffset >= this.height_;\n      if (active !== this.active_) this.header_.dataset.mdState = (this.active_ = active) ? \"shadow\" : \"\";\n    }\n  };\n\n  /**\n   * Reset shadow state\n   */\n\n\n  Shadow.prototype.reset = function reset() {\n    this.header_.dataset.mdState = \"\";\n    this.height_ = 0;\n    this.active_ = false;\n  };\n\n  return Shadow;\n}();\n\nexports.default = Shadow;\n\n/***/ }),\n/* 26 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\nvar Title = function () {\n\n  /**\n   * Swap header title topics when header is scrolled past\n   *\n   * @constructor\n   *\n   * @property {HTMLElement} el_ - Element\n   * @property {HTMLElement} header_ - Header\n   * @property {boolean} active_ - Title state\n   *\n   * @param {(string|HTMLElement)} el - Selector or HTML element\n   * @param {(string|HTMLHeadingElement)} header - Selector or HTML element\n   */\n  function Title(el, header) {\n    _classCallCheck(this, Title);\n\n    var ref = typeof el === \"string\" ? document.querySelector(el) : el;\n    if (!(ref instanceof HTMLElement)) throw new ReferenceError();\n    this.el_ = ref;\n\n    /* Retrieve header */\n    ref = typeof header === \"string\" ? document.querySelector(header) : header;\n    if (!(ref instanceof HTMLHeadingElement)) throw new ReferenceError();\n    this.header_ = ref;\n\n    /* Initialize state */\n    this.active_ = false;\n  }\n\n  /**\n   * Setup title state\n   */\n\n\n  Title.prototype.setup = function setup() {\n    var _this = this;\n\n    Array.prototype.forEach.call(this.el_.children, function (node) {\n      // TODO: use childNodes here for IE?\n      node.style.width = _this.el_.offsetWidth - 20 + \"px\";\n    });\n  };\n\n  /**\n   * Update title state\n   *\n   * @param {Event} ev - Event\n   */\n\n\n  Title.prototype.update = function update(ev) {\n    var _this2 = this;\n\n    var active = window.pageYOffset >= this.header_.offsetTop;\n    if (active !== this.active_) this.el_.dataset.mdState = (this.active_ = active) ? \"active\" : \"\";\n\n    /* Hack: induce ellipsis on topics */\n    if (ev.type === \"resize\" || ev.type === \"orientationchange\") {\n      Array.prototype.forEach.call(this.el_.children, function (node) {\n        node.style.width = _this2.el_.offsetWidth - 20 + \"px\";\n      });\n    }\n  };\n\n  /**\n   * Reset title state\n   */\n\n\n  Title.prototype.reset = function reset() {\n    this.el_.dataset.mdState = \"\";\n    this.el_.style.width = \"\";\n    this.active_ = false;\n  };\n\n  return Title;\n}();\n\nexports.default = Title;\n\n/***/ }),\n/* 27 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nvar _Blur = __webpack_require__(28);\n\nvar _Blur2 = _interopRequireDefault(_Blur);\n\nvar _Collapse = __webpack_require__(29);\n\nvar _Collapse2 = _interopRequireDefault(_Collapse);\n\nvar _Scrolling = __webpack_require__(30);\n\nvar _Scrolling2 = _interopRequireDefault(_Scrolling);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/* ----------------------------------------------------------------------------\n * Module\n * ------------------------------------------------------------------------- */\n\nexports.default = {\n  Blur: _Blur2.default,\n  Collapse: _Collapse2.default,\n  Scrolling: _Scrolling2.default\n}; /*\n    * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n    *\n    * Permission is hereby granted, free of charge, to any person obtaining a copy\n    * of this software and associated documentation files (the \"Software\"), to\n    * deal in the Software without restriction, including without limitation the\n    * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n    * sell copies of the Software, and to permit persons to whom the Software is\n    * furnished to do so, subject to the following conditions:\n    *\n    * The above copyright notice and this permission notice shall be included in\n    * all copies or substantial portions of the Software.\n    *\n    * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n    * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n    * IN THE SOFTWARE.\n    */\n\n/***/ }),\n/* 28 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\nvar Blur = function () {\n\n  /**\n   * Blur links within the table of contents above current page y-offset\n   *\n   * @constructor\n   *\n   * @property {NodeList<HTMLElement>} els_ - Table of contents links\n   * @property {Array<HTMLElement>} anchors_ - Referenced anchor nodes\n   * @property {number} index_ - Current link index\n   * @property {number} offset_ - Current page y-offset\n   * @property {boolean} dir_ - Scroll direction change\n   *\n   * @param {(string|NodeList<HTMLElement>)} els - Selector or HTML elements\n   */\n  function Blur(els) {\n    _classCallCheck(this, Blur);\n\n    this.els_ = typeof els === \"string\" ? document.querySelectorAll(els) : els;\n\n    /* Initialize index and page y-offset */\n    this.index_ = 0;\n    this.offset_ = window.pageYOffset;\n\n    /* Necessary state to correctly reset the index */\n    this.dir_ = false;\n\n    /* Index anchor node offsets for fast lookup */\n    this.anchors_ = [].reduce.call(this.els_, function (anchors, el) {\n      return anchors.concat(document.getElementById(el.hash.substring(1)) || []);\n    }, []);\n  }\n\n  /**\n   * Initialize blur states\n   */\n\n\n  Blur.prototype.setup = function setup() {\n    this.update();\n  };\n\n  /**\n   * Update blur states\n   *\n   * Deduct the static offset of the header (56px) and sidebar offset (24px),\n   * see _permalinks.scss for more information.\n   */\n\n\n  Blur.prototype.update = function update() {\n    var offset = window.pageYOffset;\n    var dir = this.offset_ - offset < 0;\n\n    /* Hack: reset index if direction changed to catch very fast scrolling,\n       because otherwise we would have to register a timer and that sucks */\n    if (this.dir_ !== dir) this.index_ = dir ? this.index_ = 0 : this.index_ = this.els_.length - 1;\n\n    /* Exit when there are no anchors */\n    if (this.anchors_.length === 0) return;\n\n    /* Scroll direction is down */\n    if (this.offset_ <= offset) {\n      for (var i = this.index_ + 1; i < this.els_.length; i++) {\n        if (this.anchors_[i].offsetTop - (56 + 24) <= offset) {\n          if (i > 0) this.els_[i - 1].dataset.mdState = \"blur\";\n          this.index_ = i;\n        } else {\n          break;\n        }\n      }\n\n      /* Scroll direction is up */\n    } else {\n      for (var _i = this.index_; _i >= 0; _i--) {\n        if (this.anchors_[_i].offsetTop - (56 + 24) > offset) {\n          if (_i > 0) this.els_[_i - 1].dataset.mdState = \"\";\n        } else {\n          this.index_ = _i;\n          break;\n        }\n      }\n    }\n\n    /* Remember current offset and direction for next iteration */\n    this.offset_ = offset;\n    this.dir_ = dir;\n  };\n\n  /**\n   * Reset blur states\n   */\n\n\n  Blur.prototype.reset = function reset() {\n    Array.prototype.forEach.call(this.els_, function (el) {\n      el.dataset.mdState = \"\";\n    });\n\n    /* Reset index and page y-offset */\n    this.index_ = 0;\n    this.offset_ = window.pageYOffset;\n  };\n\n  return Blur;\n}();\n\nexports.default = Blur;\n\n/***/ }),\n/* 29 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\nvar Collapse = function () {\n\n  /**\n   * Expand or collapse navigation on toggle\n   *\n   * @constructor\n   *\n   * @property {HTMLElement} el_ - Navigation list\n   *\n   * @param {(string|HTMLElement)} el - Selector or HTML element\n   */\n  function Collapse(el) {\n    _classCallCheck(this, Collapse);\n\n    var ref = typeof el === \"string\" ? document.querySelector(el) : el;\n    if (!(ref instanceof HTMLElement)) throw new ReferenceError();\n    this.el_ = ref;\n  }\n\n  /**\n   * Initialize overflow and display for accessibility\n   */\n\n\n  Collapse.prototype.setup = function setup() {\n    var current = this.el_.getBoundingClientRect().height;\n\n    /* Hidden links should not be focusable, so hide them when the navigation\n       is collapsed and set overflow so the outline is not cut off */\n    this.el_.style.display = current ? \"block\" : \"none\";\n    this.el_.style.overflow = current ? \"visible\" : \"hidden\";\n  };\n\n  /**\n   * Animate expand and collapse smoothly\n   *\n   * Internet Explorer 11 is very slow at recognizing changes on the dataset\n   * which results in the menu not expanding or collapsing properly. THerefore,\n   * for reasons of compatibility, the attribute accessors are used.\n   */\n\n\n  Collapse.prototype.update = function update() {\n    var _this = this;\n\n    var current = this.el_.getBoundingClientRect().height;\n\n    /* Reset overflow to CSS defaults */\n    this.el_.style.display = \"block\";\n    this.el_.style.overflow = \"\";\n\n    /* Expanded, so collapse */\n    if (current) {\n      this.el_.style.maxHeight = current + \"px\";\n      requestAnimationFrame(function () {\n        _this.el_.setAttribute(\"data-md-state\", \"animate\");\n        _this.el_.style.maxHeight = \"0px\";\n      });\n\n      /* Collapsed, so expand */\n    } else {\n      this.el_.setAttribute(\"data-md-state\", \"expand\");\n      this.el_.style.maxHeight = \"\";\n\n      /* Read height and unset pseudo-toggled state */\n      var height = this.el_.getBoundingClientRect().height;\n      this.el_.removeAttribute(\"data-md-state\");\n\n      /* Set initial state and animate */\n      this.el_.style.maxHeight = \"0px\";\n      requestAnimationFrame(function () {\n        _this.el_.setAttribute(\"data-md-state\", \"animate\");\n        _this.el_.style.maxHeight = height + \"px\";\n      });\n    }\n\n    /* Remove state on end of transition */\n    var end = function end(ev) {\n      var target = ev.target;\n      if (!(target instanceof HTMLElement)) throw new ReferenceError();\n\n      /* Reset height and state */\n      target.removeAttribute(\"data-md-state\");\n      target.style.maxHeight = \"\";\n\n      /* Hidden links should not be focusable, so hide them when the navigation\n         is collapsed and set overflow so the outline is not cut off */\n      target.style.display = current ? \"none\" : \"block\";\n      target.style.overflow = current ? \"hidden\" : \"visible\";\n\n      /* Only fire once, so directly remove event listener */\n      target.removeEventListener(\"transitionend\", end);\n    };\n    this.el_.addEventListener(\"transitionend\", end, false);\n  };\n\n  /**\n   * Reset height and pseudo-toggled state\n   */\n\n\n  Collapse.prototype.reset = function reset() {\n    this.el_.dataset.mdState = \"\";\n    this.el_.style.maxHeight = \"\";\n    this.el_.style.display = \"\";\n    this.el_.style.overflow = \"\";\n  };\n\n  return Collapse;\n}();\n\nexports.default = Collapse;\n\n/***/ }),\n/* 30 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\nvar Scrolling = function () {\n\n  /**\n   * Set overflow scrolling on the current active pane (for iOS)\n   *\n   * @constructor\n   *\n   * @property {HTMLElement} el_ - Primary navigation\n   *\n   * @param {(string|HTMLElement)} el - Selector or HTML element\n   */\n  function Scrolling(el) {\n    _classCallCheck(this, Scrolling);\n\n    var ref = typeof el === \"string\" ? document.querySelector(el) : el;\n    if (!(ref instanceof HTMLElement)) throw new ReferenceError();\n    this.el_ = ref;\n  }\n\n  /**\n   * Setup panes\n   */\n\n\n  Scrolling.prototype.setup = function setup() {\n\n    /* Initially set overflow scrolling on main pane */\n    var main = this.el_.children[this.el_.children.length - 1];\n    main.style.webkitOverflowScrolling = \"touch\";\n\n    /* Find all toggles and check which one is active */\n    var toggles = this.el_.querySelectorAll(\"[data-md-toggle]\");\n    Array.prototype.forEach.call(toggles, function (toggle) {\n      if (!(toggle instanceof HTMLInputElement)) throw new ReferenceError();\n      if (toggle.checked) {\n\n        /* Find corresponding navigational pane */\n        var pane = toggle.nextElementSibling;\n        if (!(pane instanceof HTMLElement)) throw new ReferenceError();\n        while (pane.tagName !== \"NAV\" && pane.nextElementSibling) {\n          pane = pane.nextElementSibling;\n        } /* Check references */\n        if (!(toggle.parentNode instanceof HTMLElement) || !(toggle.parentNode.parentNode instanceof HTMLElement)) throw new ReferenceError();\n\n        /* Find current and parent list elements */\n        var parent = toggle.parentNode.parentNode;\n        var target = pane.children[pane.children.length - 1];\n\n        /* Always reset all lists when transitioning */\n        parent.style.webkitOverflowScrolling = \"\";\n        target.style.webkitOverflowScrolling = \"touch\";\n      }\n    });\n  };\n\n  /**\n   * Update active panes\n   *\n   * @param {Event} ev - Change event\n   */\n\n\n  Scrolling.prototype.update = function update(ev) {\n    var target = ev.target;\n    if (!(target instanceof HTMLElement)) throw new ReferenceError();\n\n    /* Find corresponding navigational pane */\n    var pane = target.nextElementSibling;\n    if (!(pane instanceof HTMLElement)) throw new ReferenceError();\n    while (pane.tagName !== \"NAV\" && pane.nextElementSibling) {\n      pane = pane.nextElementSibling;\n    } /* Check references */\n    if (!(target.parentNode instanceof HTMLElement) || !(target.parentNode.parentNode instanceof HTMLElement)) throw new ReferenceError();\n\n    /* Find parent and active panes */\n    var parent = target.parentNode.parentNode;\n    var active = pane.children[pane.children.length - 1];\n\n    /* Always reset all lists when transitioning */\n    parent.style.webkitOverflowScrolling = \"\";\n    active.style.webkitOverflowScrolling = \"\";\n\n    /* Set overflow scrolling on parent pane */\n    if (!target.checked) {\n      var end = function end() {\n        if (pane instanceof HTMLElement) {\n          parent.style.webkitOverflowScrolling = \"touch\";\n          pane.removeEventListener(\"transitionend\", end);\n        }\n      };\n      pane.addEventListener(\"transitionend\", end, false);\n    }\n\n    /* Set overflow scrolling on active pane */\n    if (target.checked) {\n      var _end = function _end() {\n        if (pane instanceof HTMLElement) {\n          active.style.webkitOverflowScrolling = \"touch\";\n          pane.removeEventListener(\"transitionend\", _end);\n        }\n      };\n      pane.addEventListener(\"transitionend\", _end, false);\n    }\n  };\n\n  /**\n   * Reset panes\n   */\n\n\n  Scrolling.prototype.reset = function reset() {\n\n    /* Reset overflow scrolling on main pane */\n    this.el_.children[1].style.webkitOverflowScrolling = \"\";\n\n    /* Find all toggles and check which one is active */\n    var toggles = this.el_.querySelectorAll(\"[data-md-toggle]\");\n    Array.prototype.forEach.call(toggles, function (toggle) {\n      if (!(toggle instanceof HTMLInputElement)) throw new ReferenceError();\n      if (toggle.checked) {\n\n        /* Find corresponding navigational pane */\n        var pane = toggle.nextElementSibling;\n        if (!(pane instanceof HTMLElement)) throw new ReferenceError();\n        while (pane.tagName !== \"NAV\" && pane.nextElementSibling) {\n          pane = pane.nextElementSibling;\n        } /* Check references */\n        if (!(toggle.parentNode instanceof HTMLElement) || !(toggle.parentNode.parentNode instanceof HTMLElement)) throw new ReferenceError();\n\n        /* Find parent and active panes */\n        var parent = toggle.parentNode.parentNode;\n        var active = pane.children[pane.children.length - 1];\n\n        /* Always reset all lists when transitioning */\n        parent.style.webkitOverflowScrolling = \"\";\n        active.style.webkitOverflowScrolling = \"\";\n      }\n    });\n  };\n\n  return Scrolling;\n}();\n\nexports.default = Scrolling;\n\n/***/ }),\n/* 31 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nvar _Lock = __webpack_require__(32);\n\nvar _Lock2 = _interopRequireDefault(_Lock);\n\nvar _Result = __webpack_require__(33);\n\nvar _Result2 = _interopRequireDefault(_Result);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/* ----------------------------------------------------------------------------\n * Module\n * ------------------------------------------------------------------------- */\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nexports.default = {\n  Lock: _Lock2.default,\n  Result: _Result2.default\n};\n\n/***/ }),\n/* 32 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\nvar Lock = function () {\n\n  /**\n   * Lock body for full-screen search modal\n   *\n   * @constructor\n   *\n   * @property {HTMLInputElement} el_ - Lock toggle\n   * @property {HTMLElement} lock_ - Element to lock (document body)\n   * @property {number} offset_ - Current page y-offset\n   *\n   * @param {(string|HTMLElement)} el - Selector or HTML element\n   */\n  function Lock(el) {\n    _classCallCheck(this, Lock);\n\n    var ref = typeof el === \"string\" ? document.querySelector(el) : el;\n    if (!(ref instanceof HTMLInputElement)) throw new ReferenceError();\n    this.el_ = ref;\n\n    /* Retrieve element to lock (= body) */\n    if (!document.body) throw new ReferenceError();\n    this.lock_ = document.body;\n  }\n\n  /**\n   * Setup locked state\n   */\n\n\n  Lock.prototype.setup = function setup() {\n    this.update();\n  };\n\n  /**\n   * Update locked state\n   */\n\n\n  Lock.prototype.update = function update() {\n    var _this = this;\n\n    /* Entering search mode */\n    if (this.el_.checked) {\n      this.offset_ = window.pageYOffset;\n\n      /* Scroll to top after transition, to omit flickering */\n      setTimeout(function () {\n        window.scrollTo(0, 0);\n\n        /* Lock body after finishing transition */\n        if (_this.el_.checked) {\n          _this.lock_.dataset.mdState = \"lock\";\n        }\n      }, 400);\n\n      /* Exiting search mode */\n    } else {\n      this.lock_.dataset.mdState = \"\";\n\n      /* Scroll to former position, but wait for 100ms to prevent flashes on\n         iOS. A short timeout seems to do the trick */\n      setTimeout(function () {\n        if (typeof _this.offset_ !== \"undefined\") window.scrollTo(0, _this.offset_);\n      }, 100);\n    }\n  };\n\n  /**\n   * Reset locked state and page y-offset\n   */\n\n\n  Lock.prototype.reset = function reset() {\n    if (this.lock_.dataset.mdState === \"lock\") window.scrollTo(0, this.offset_);\n    this.lock_.dataset.mdState = \"\";\n  };\n\n  return Lock;\n}();\n\nexports.default = Lock;\n\n/***/ }),\n/* 33 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(JSX) {\n\nexports.__esModule = true;\n\nvar _escapeStringRegexp = __webpack_require__(34);\n\nvar _escapeStringRegexp2 = _interopRequireDefault(_escapeStringRegexp);\n\nvar _exposeLoaderLunrLunr = __webpack_require__(35);\n\nvar _exposeLoaderLunrLunr2 = _interopRequireDefault(_exposeLoaderLunrLunr);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } /*\n                                                                                                                                                           * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n                                                                                                                                                           *\n                                                                                                                                                           * Permission is hereby granted, free of charge, to any person obtaining a copy\n                                                                                                                                                           * of this software and associated documentation files (the \"Software\"), to\n                                                                                                                                                           * deal in the Software without restriction, including without limitation the\n                                                                                                                                                           * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n                                                                                                                                                           * sell copies of the Software, and to permit persons to whom the Software is\n                                                                                                                                                           * furnished to do so, subject to the following conditions:\n                                                                                                                                                           *\n                                                                                                                                                           * The above copyright notice and this permission notice shall be included in\n                                                                                                                                                           * all copies or substantial portions of the Software.\n                                                                                                                                                           *\n                                                                                                                                                           * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n                                                                                                                                                           * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n                                                                                                                                                           * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n                                                                                                                                                           * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n                                                                                                                                                           * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n                                                                                                                                                           * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n                                                                                                                                                           * IN THE SOFTWARE.\n                                                                                                                                                           */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Escape HTML strings\n *\n * Documentation may contain code JavaScript code snippets which would get\n * executed when inserted into the DOM as plain HTML.\n *\n * See https://github.com/squidfunk/mkdocs-material/issues/906\n *\n * @param {string} html - HTML string\n *\n * @return {string} Escaped HTML string\n */\nvar escapeHTML = function escapeHTML(html) {\n  var text = document.createTextNode(html);\n  var p = document.createElement('p');\n  p.appendChild(text);\n  return p.innerHTML;\n};\n\n/**\n * Truncate a string after the given number of character\n *\n * This is not a reasonable approach, since the summaries kind of suck. It\n * would be better to create something more intelligent, highlighting the\n * search occurrences and making a better summary out of it.\n *\n * @param {string} string - String to be truncated\n * @param {number} n - Number of characters\n * @return {string} Truncated string\n */\nvar truncate = function truncate(string, n) {\n  var i = n;\n  if (string.length > i) {\n    while (string[i] !== \" \" && --i > 0) {}\n    return string.substring(0, i) + \"...\";\n  }\n  return string;\n};\n\n/**\n * Return the meta tag value for the given key\n *\n * @param {string} key - Meta name\n *\n * @return {string} Meta content value\n */\nvar translate = function translate(key) {\n  var meta = document.getElementsByName(\"lang:\" + key)[0];\n  if (!(meta instanceof HTMLMetaElement)) throw new ReferenceError();\n  return meta.content;\n};\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\nvar Result = function () {\n\n  /**\n   * Perform search and update results on keyboard events\n   *\n   * @constructor\n   *\n   * @property {HTMLElement} el_ - Search result container\n   * @property {(Array<Object>|Function)} data_ - Raw document data\n   * @property {Object} docs_ - Indexed documents\n   * @property {HTMLElement} meta_ - Search meta information\n   * @property {HTMLElement} list_ - Search result list\n   * @property {Array<string>} lang_ - Search languages\n   * @property {Object} message_ - Search result messages\n   * @property {Object} index_ - Search index\n   * @property {Array<Function>} stack_ - Search result stack\n   * @property {string} value_ - Last input value\n   *\n   * @param {(string|HTMLElement)} el - Selector or HTML element\n   * @param {(Array<Object>|Function)} data - Function providing data or array\n   */\n  function Result(el, data) {\n    _classCallCheck(this, Result);\n\n    var ref = typeof el === \"string\" ? document.querySelector(el) : el;\n    if (!(ref instanceof HTMLElement)) throw new ReferenceError();\n    this.el_ = ref;\n\n    /* Retrieve metadata and list element */\n\n    var _Array$prototype$slic = Array.prototype.slice.call(this.el_.children),\n        meta = _Array$prototype$slic[0],\n        list = _Array$prototype$slic[1];\n\n    /* Set data, metadata and list elements */\n\n\n    this.data_ = data;\n    this.meta_ = meta;\n    this.list_ = list;\n\n    /* Load messages for metadata display */\n    this.message_ = {\n      placeholder: this.meta_.textContent,\n      none: translate(\"search.result.none\"),\n      one: translate(\"search.result.one\"),\n      other: translate(\"search.result.other\")\n\n      /* Override tokenizer separator, if given */\n    };var tokenizer = translate(\"search.tokenizer\");\n    if (tokenizer.length) _exposeLoaderLunrLunr2.default.tokenizer.separator = tokenizer;\n\n    /* Load search languages */\n    this.lang_ = translate(\"search.language\").split(\",\").filter(Boolean).map(function (lang) {\n      return lang.trim();\n    });\n  }\n\n  /**\n   * Update search results\n   *\n   * @param {Event} ev - Input or focus event\n   */\n\n\n  Result.prototype.update = function update(ev) {\n    var _this = this;\n\n    /* Initialize index, if this has not be done yet */\n    if (ev.type === \"focus\" && !this.index_) {\n\n      /* Initialize index */\n      var init = function init(data) {\n\n        /* Preprocess and index sections and documents */\n        _this.docs_ = data.reduce(function (docs, doc) {\n          var _doc$location$split = doc.location.split(\"#\"),\n              path = _doc$location$split[0],\n              hash = _doc$location$split[1];\n\n          /* Escape HTML */\n\n\n          doc.title = escapeHTML(doc.title);\n          doc.text = escapeHTML(doc.text);\n\n          /* Associate section with parent document */\n          if (hash) {\n            doc.parent = docs.get(path);\n\n            /* Override page title with document title if first section */\n            if (doc.parent && !doc.parent.done) {\n              doc.parent.title = doc.title;\n              doc.parent.text = doc.text;\n              doc.parent.done = true;\n            }\n          }\n\n          /* Some cleanup on the text */\n          doc.text = doc.text.replace(/\\n/g, \" \") /* Remove newlines */\n          .replace(/\\s+/g, \" \") /* Compact whitespace */\n          .replace(/\\s+([,.:;!?])/g, /* Correct punctuation */\n          function (_, char) {\n            return char;\n          });\n\n          /* Index sections and documents, but skip top-level headline */\n          if (!doc.parent || doc.parent.title !== doc.title) docs.set(doc.location, doc);\n          return docs;\n        }, new Map());\n\n        /* eslint-disable no-invalid-this */\n        var docs = _this.docs_,\n            lang = _this.lang_;\n\n        /* Create stack and index */\n        _this.stack_ = [];\n        _this.index_ = (0, _exposeLoaderLunrLunr2.default)(function () {\n          var _pipeline,\n              _this2 = this;\n\n          var filters = {\n            \"search.pipeline.trimmer\": _exposeLoaderLunrLunr2.default.trimmer,\n            \"search.pipeline.stopwords\": _exposeLoaderLunrLunr2.default.stopWordFilter\n\n            /* Disable stop words filter and trimmer, if desired */\n          };var pipeline = Object.keys(filters).reduce(function (result, name) {\n            if (!translate(name).match(/^false$/i)) result.push(filters[name]);\n            return result;\n          }, []);\n\n          /* Remove stemmer, as it cripples search experience */\n          this.pipeline.reset();\n          if (pipeline) (_pipeline = this.pipeline).add.apply(_pipeline, pipeline);\n\n          /* Set up alternate search languages */\n          if (lang.length === 1 && lang[0] !== \"en\" && _exposeLoaderLunrLunr2.default[lang[0]]) {\n            this.use(_exposeLoaderLunrLunr2.default[lang[0]]);\n          } else if (lang.length > 1) {\n            this.use(_exposeLoaderLunrLunr2.default.multiLanguage.apply(_exposeLoaderLunrLunr2.default, lang));\n          }\n\n          /* Index fields */\n          this.field(\"title\", { boost: 10 });\n          this.field(\"text\");\n          this.ref(\"location\");\n\n          /* Index documents */\n          docs.forEach(function (doc) {\n            return _this2.add(doc);\n          });\n        });\n\n        /* Register event handler for lazy rendering */\n        var container = _this.el_.parentNode;\n        if (!(container instanceof HTMLElement)) throw new ReferenceError();\n        container.addEventListener(\"scroll\", function () {\n          while (_this.stack_.length && container.scrollTop + container.offsetHeight >= container.scrollHeight - 16) {\n            _this.stack_.splice(0, 10).forEach(function (render) {\n              return render();\n            });\n          }\n        });\n      };\n      /* eslint-enable no-invalid-this */\n\n      /* Initialize index after short timeout to account for transition */\n      setTimeout(function () {\n        return typeof _this.data_ === \"function\" ? _this.data_().then(init) : init(_this.data_);\n      }, 250);\n\n      /* Execute search on new input event */\n    } else if (ev.type === \"focus\" || ev.type === \"keyup\") {\n      var target = ev.target;\n      if (!(target instanceof HTMLInputElement)) throw new ReferenceError();\n\n      /* Abort early, if index is not build or input hasn't changed */\n      if (!this.index_ || target.value === this.value_) return;\n\n      /* Clear current list */\n      while (this.list_.firstChild) {\n        this.list_.removeChild(this.list_.firstChild);\n      } /* Abort early, if search input is empty */\n      this.value_ = target.value;\n      if (this.value_.length === 0) {\n        this.meta_.textContent = this.message_.placeholder;\n        return;\n      }\n\n      /* Perform search on index and group sections by document */\n      var result = this.index_\n\n      /* Append trailing wildcard to all terms for prefix querying */\n      .query(function (query) {\n        _this.value_.toLowerCase().split(\" \").filter(Boolean).forEach(function (term) {\n          query.term(term, { wildcard: _exposeLoaderLunrLunr2.default.Query.wildcard.TRAILING });\n        });\n      })\n\n      /* Process query results */\n      .reduce(function (items, item) {\n        var doc = _this.docs_.get(item.ref);\n        if (doc.parent) {\n          var ref = doc.parent.location;\n          items.set(ref, (items.get(ref) || []).concat(item));\n        } else {\n          var _ref = doc.location;\n          items.set(_ref, items.get(_ref) || []);\n        }\n        return items;\n      }, new Map());\n\n      /* Assemble regular expressions for matching */\n      var query = (0, _escapeStringRegexp2.default)(this.value_.trim()).replace(new RegExp(_exposeLoaderLunrLunr2.default.tokenizer.separator, \"img\"), \"|\");\n      var match = new RegExp(\"(^|\" + _exposeLoaderLunrLunr2.default.tokenizer.separator + \")(\" + query + \")\", \"img\");\n      var highlight = function highlight(_, separator, token) {\n        return separator + \"<em>\" + token + \"</em>\";\n      };\n\n      /* Reset stack and render results */\n      this.stack_ = [];\n      result.forEach(function (items, ref) {\n        var _stack_;\n\n        var doc = _this.docs_.get(ref);\n\n        /* Render article */\n        var article = JSX.createElement(\n          \"li\",\n          { \"class\": \"md-search-result__item\" },\n          JSX.createElement(\n            \"a\",\n            { href: doc.location, title: doc.title,\n              \"class\": \"md-search-result__link\", tabindex: \"-1\" },\n            JSX.createElement(\n              \"article\",\n              { \"class\": \"md-search-result__article md-search-result__article--document\" },\n              JSX.createElement(\n                \"h1\",\n                { \"class\": \"md-search-result__title\" },\n                { __html: doc.title.replace(match, highlight) }\n              ),\n              doc.text.length ? JSX.createElement(\n                \"p\",\n                { \"class\": \"md-search-result__teaser\" },\n                { __html: doc.text.replace(match, highlight) }\n              ) : {}\n            )\n          )\n        );\n\n        /* Render sections for article */\n        var sections = items.map(function (item) {\n          return function () {\n            var section = _this.docs_.get(item.ref);\n            article.appendChild(JSX.createElement(\n              \"a\",\n              { href: section.location, title: section.title,\n                \"class\": \"md-search-result__link\", \"data-md-rel\": \"anchor\",\n                tabindex: \"-1\" },\n              JSX.createElement(\n                \"article\",\n                { \"class\": \"md-search-result__article\" },\n                JSX.createElement(\n                  \"h1\",\n                  { \"class\": \"md-search-result__title\" },\n                  { __html: section.title.replace(match, highlight) }\n                ),\n                section.text.length ? JSX.createElement(\n                  \"p\",\n                  { \"class\": \"md-search-result__teaser\" },\n                  { __html: truncate(section.text.replace(match, highlight), 400)\n                  }\n                ) : {}\n              )\n            ));\n          };\n        });\n\n        /* Push articles and section renderers onto stack */\n        (_stack_ = _this.stack_).push.apply(_stack_, [function () {\n          return _this.list_.appendChild(article);\n        }].concat(sections));\n      });\n\n      /* Gradually add results as long as the height of the container grows */\n      var container = this.el_.parentNode;\n      if (!(container instanceof HTMLElement)) throw new ReferenceError();\n      while (this.stack_.length && container.offsetHeight >= container.scrollHeight - 16) {\n        this.stack_.shift()();\n      } /* Bind click handlers for anchors */\n      var anchors = this.list_.querySelectorAll(\"[data-md-rel=anchor]\");\n      Array.prototype.forEach.call(anchors, function (anchor) {\n        [\"click\", \"keydown\"].forEach(function (action) {\n          anchor.addEventListener(action, function (ev2) {\n            if (action === \"keydown\" && ev2.keyCode !== 13) return;\n\n            /* Close search */\n            var toggle = document.querySelector(\"[data-md-toggle=search]\");\n            if (!(toggle instanceof HTMLInputElement)) throw new ReferenceError();\n            if (toggle.checked) {\n              toggle.checked = false;\n              toggle.dispatchEvent(new CustomEvent(\"change\"));\n            }\n\n            /* Hack: prevent default, as the navigation needs to be delayed due\n               to the search body lock on mobile */\n            ev2.preventDefault();\n            setTimeout(function () {\n              document.location.href = anchor.href;\n            }, 100);\n          });\n        });\n      });\n\n      /* Update search metadata */\n      switch (result.size) {\n        case 0:\n          this.meta_.textContent = this.message_.none;\n          break;\n        case 1:\n          this.meta_.textContent = this.message_.one;\n          break;\n        default:\n          this.meta_.textContent = this.message_.other.replace(\"#\", result.size);\n      }\n    }\n  };\n\n  return Result;\n}();\n\nexports.default = Result;\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))\n\n/***/ }),\n/* 34 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar matchOperatorsRe = /[|\\\\{}()[\\]^$+*?.]/g;\n\nmodule.exports = function (str) {\n\tif (typeof str !== 'string') {\n\t\tthrow new TypeError('Expected a string');\n\t}\n\n\treturn str.replace(matchOperatorsRe, '\\\\$&');\n};\n\n\n/***/ }),\n/* 35 */\n/***/ (function(module, exports, __webpack_require__) {\n\n/* WEBPACK VAR INJECTION */(function(global) {module.exports = global[\"lunr\"] = __webpack_require__(36);\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1)))\n\n/***/ }),\n/* 36 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/**\n * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.5\n * Copyright (C) 2018 Oliver Nightingale\n * @license MIT\n */\n\n;(function(){\n\n/**\n * A convenience function for configuring and constructing\n * a new lunr Index.\n *\n * A lunr.Builder instance is created and the pipeline setup\n * with a trimmer, stop word filter and stemmer.\n *\n * This builder object is yielded to the configuration function\n * that is passed as a parameter, allowing the list of fields\n * and other builder parameters to be customised.\n *\n * All documents _must_ be added within the passed config function.\n *\n * @example\n * var idx = lunr(function () {\n *   this.field('title')\n *   this.field('body')\n *   this.ref('id')\n *\n *   documents.forEach(function (doc) {\n *     this.add(doc)\n *   }, this)\n * })\n *\n * @see {@link lunr.Builder}\n * @see {@link lunr.Pipeline}\n * @see {@link lunr.trimmer}\n * @see {@link lunr.stopWordFilter}\n * @see {@link lunr.stemmer}\n * @namespace {function} lunr\n */\nvar lunr = function (config) {\n  var builder = new lunr.Builder\n\n  builder.pipeline.add(\n    lunr.trimmer,\n    lunr.stopWordFilter,\n    lunr.stemmer\n  )\n\n  builder.searchPipeline.add(\n    lunr.stemmer\n  )\n\n  config.call(builder, builder)\n  return builder.build()\n}\n\nlunr.version = \"2.3.5\"\n/*!\n * lunr.utils\n * Copyright (C) 2018 Oliver Nightingale\n */\n\n/**\n * A namespace containing utils for the rest of the lunr library\n * @namespace lunr.utils\n */\nlunr.utils = {}\n\n/**\n * Print a warning message to the console.\n *\n * @param {String} message The message to be printed.\n * @memberOf lunr.utils\n * @function\n */\nlunr.utils.warn = (function (global) {\n  /* eslint-disable no-console */\n  return function (message) {\n    if (global.console && console.warn) {\n      console.warn(message)\n    }\n  }\n  /* eslint-enable no-console */\n})(this)\n\n/**\n * Convert an object to a string.\n *\n * In the case of `null` and `undefined` the function returns\n * the empty string, in all other cases the result of calling\n * `toString` on the passed object is returned.\n *\n * @param {Any} obj The object to convert to a string.\n * @return {String} string representation of the passed object.\n * @memberOf lunr.utils\n */\nlunr.utils.asString = function (obj) {\n  if (obj === void 0 || obj === null) {\n    return \"\"\n  } else {\n    return obj.toString()\n  }\n}\n\n/**\n * Clones an object.\n *\n * Will create a copy of an existing object such that any mutations\n * on the copy cannot affect the original.\n *\n * Only shallow objects are supported, passing a nested object to this\n * function will cause a TypeError.\n *\n * Objects with primitives, and arrays of primitives are supported.\n *\n * @param {Object} obj The object to clone.\n * @return {Object} a clone of the passed object.\n * @throws {TypeError} when a nested object is passed.\n * @memberOf Utils\n */\nlunr.utils.clone = function (obj) {\n  if (obj === null || obj === undefined) {\n    return obj\n  }\n\n  var clone = Object.create(null),\n      keys = Object.keys(obj)\n\n  for (var i = 0; i < keys.length; i++) {\n    var key = keys[i],\n        val = obj[key]\n\n    if (Array.isArray(val)) {\n      clone[key] = val.slice()\n      continue\n    }\n\n    if (typeof val === 'string' ||\n        typeof val === 'number' ||\n        typeof val === 'boolean') {\n      clone[key] = val\n      continue\n    }\n\n    throw new TypeError(\"clone is not deep and does not support nested objects\")\n  }\n\n  return clone\n}\nlunr.FieldRef = function (docRef, fieldName, stringValue) {\n  this.docRef = docRef\n  this.fieldName = fieldName\n  this._stringValue = stringValue\n}\n\nlunr.FieldRef.joiner = \"/\"\n\nlunr.FieldRef.fromString = function (s) {\n  var n = s.indexOf(lunr.FieldRef.joiner)\n\n  if (n === -1) {\n    throw \"malformed field ref string\"\n  }\n\n  var fieldRef = s.slice(0, n),\n      docRef = s.slice(n + 1)\n\n  return new lunr.FieldRef (docRef, fieldRef, s)\n}\n\nlunr.FieldRef.prototype.toString = function () {\n  if (this._stringValue == undefined) {\n    this._stringValue = this.fieldName + lunr.FieldRef.joiner + this.docRef\n  }\n\n  return this._stringValue\n}\n/*!\n * lunr.Set\n * Copyright (C) 2018 Oliver Nightingale\n */\n\n/**\n * A lunr set.\n *\n * @constructor\n */\nlunr.Set = function (elements) {\n  this.elements = Object.create(null)\n\n  if (elements) {\n    this.length = elements.length\n\n    for (var i = 0; i < this.length; i++) {\n      this.elements[elements[i]] = true\n    }\n  } else {\n    this.length = 0\n  }\n}\n\n/**\n * A complete set that contains all elements.\n *\n * @static\n * @readonly\n * @type {lunr.Set}\n */\nlunr.Set.complete = {\n  intersect: function (other) {\n    return other\n  },\n\n  union: function (other) {\n    return other\n  },\n\n  contains: function () {\n    return true\n  }\n}\n\n/**\n * An empty set that contains no elements.\n *\n * @static\n * @readonly\n * @type {lunr.Set}\n */\nlunr.Set.empty = {\n  intersect: function () {\n    return this\n  },\n\n  union: function (other) {\n    return other\n  },\n\n  contains: function () {\n    return false\n  }\n}\n\n/**\n * Returns true if this set contains the specified object.\n *\n * @param {object} object - Object whose presence in this set is to be tested.\n * @returns {boolean} - True if this set contains the specified object.\n */\nlunr.Set.prototype.contains = function (object) {\n  return !!this.elements[object]\n}\n\n/**\n * Returns a new set containing only the elements that are present in both\n * this set and the specified set.\n *\n * @param {lunr.Set} other - set to intersect with this set.\n * @returns {lunr.Set} a new set that is the intersection of this and the specified set.\n */\n\nlunr.Set.prototype.intersect = function (other) {\n  var a, b, elements, intersection = []\n\n  if (other === lunr.Set.complete) {\n    return this\n  }\n\n  if (other === lunr.Set.empty) {\n    return other\n  }\n\n  if (this.length < other.length) {\n    a = this\n    b = other\n  } else {\n    a = other\n    b = this\n  }\n\n  elements = Object.keys(a.elements)\n\n  for (var i = 0; i < elements.length; i++) {\n    var element = elements[i]\n    if (element in b.elements) {\n      intersection.push(element)\n    }\n  }\n\n  return new lunr.Set (intersection)\n}\n\n/**\n * Returns a new set combining the elements of this and the specified set.\n *\n * @param {lunr.Set} other - set to union with this set.\n * @return {lunr.Set} a new set that is the union of this and the specified set.\n */\n\nlunr.Set.prototype.union = function (other) {\n  if (other === lunr.Set.complete) {\n    return lunr.Set.complete\n  }\n\n  if (other === lunr.Set.empty) {\n    return this\n  }\n\n  return new lunr.Set(Object.keys(this.elements).concat(Object.keys(other.elements)))\n}\n/**\n * A function to calculate the inverse document frequency for\n * a posting. This is shared between the builder and the index\n *\n * @private\n * @param {object} posting - The posting for a given term\n * @param {number} documentCount - The total number of documents.\n */\nlunr.idf = function (posting, documentCount) {\n  var documentsWithTerm = 0\n\n  for (var fieldName in posting) {\n    if (fieldName == '_index') continue // Ignore the term index, its not a field\n    documentsWithTerm += Object.keys(posting[fieldName]).length\n  }\n\n  var x = (documentCount - documentsWithTerm + 0.5) / (documentsWithTerm + 0.5)\n\n  return Math.log(1 + Math.abs(x))\n}\n\n/**\n * A token wraps a string representation of a token\n * as it is passed through the text processing pipeline.\n *\n * @constructor\n * @param {string} [str=''] - The string token being wrapped.\n * @param {object} [metadata={}] - Metadata associated with this token.\n */\nlunr.Token = function (str, metadata) {\n  this.str = str || \"\"\n  this.metadata = metadata || {}\n}\n\n/**\n * Returns the token string that is being wrapped by this object.\n *\n * @returns {string}\n */\nlunr.Token.prototype.toString = function () {\n  return this.str\n}\n\n/**\n * A token update function is used when updating or optionally\n * when cloning a token.\n *\n * @callback lunr.Token~updateFunction\n * @param {string} str - The string representation of the token.\n * @param {Object} metadata - All metadata associated with this token.\n */\n\n/**\n * Applies the given function to the wrapped string token.\n *\n * @example\n * token.update(function (str, metadata) {\n *   return str.toUpperCase()\n * })\n *\n * @param {lunr.Token~updateFunction} fn - A function to apply to the token string.\n * @returns {lunr.Token}\n */\nlunr.Token.prototype.update = function (fn) {\n  this.str = fn(this.str, this.metadata)\n  return this\n}\n\n/**\n * Creates a clone of this token. Optionally a function can be\n * applied to the cloned token.\n *\n * @param {lunr.Token~updateFunction} [fn] - An optional function to apply to the cloned token.\n * @returns {lunr.Token}\n */\nlunr.Token.prototype.clone = function (fn) {\n  fn = fn || function (s) { return s }\n  return new lunr.Token (fn(this.str, this.metadata), this.metadata)\n}\n/*!\n * lunr.tokenizer\n * Copyright (C) 2018 Oliver Nightingale\n */\n\n/**\n * A function for splitting a string into tokens ready to be inserted into\n * the search index. Uses `lunr.tokenizer.separator` to split strings, change\n * the value of this property to change how strings are split into tokens.\n *\n * This tokenizer will convert its parameter to a string by calling `toString` and\n * then will split this string on the character in `lunr.tokenizer.separator`.\n * Arrays will have their elements converted to strings and wrapped in a lunr.Token.\n *\n * Optional metadata can be passed to the tokenizer, this metadata will be cloned and\n * added as metadata to every token that is created from the object to be tokenized.\n *\n * @static\n * @param {?(string|object|object[])} obj - The object to convert into tokens\n * @param {?object} metadata - Optional metadata to associate with every token\n * @returns {lunr.Token[]}\n * @see {@link lunr.Pipeline}\n */\nlunr.tokenizer = function (obj, metadata) {\n  if (obj == null || obj == undefined) {\n    return []\n  }\n\n  if (Array.isArray(obj)) {\n    return obj.map(function (t) {\n      return new lunr.Token(\n        lunr.utils.asString(t).toLowerCase(),\n        lunr.utils.clone(metadata)\n      )\n    })\n  }\n\n  var str = obj.toString().trim().toLowerCase(),\n      len = str.length,\n      tokens = []\n\n  for (var sliceEnd = 0, sliceStart = 0; sliceEnd <= len; sliceEnd++) {\n    var char = str.charAt(sliceEnd),\n        sliceLength = sliceEnd - sliceStart\n\n    if ((char.match(lunr.tokenizer.separator) || sliceEnd == len)) {\n\n      if (sliceLength > 0) {\n        var tokenMetadata = lunr.utils.clone(metadata) || {}\n        tokenMetadata[\"position\"] = [sliceStart, sliceLength]\n        tokenMetadata[\"index\"] = tokens.length\n\n        tokens.push(\n          new lunr.Token (\n            str.slice(sliceStart, sliceEnd),\n            tokenMetadata\n          )\n        )\n      }\n\n      sliceStart = sliceEnd + 1\n    }\n\n  }\n\n  return tokens\n}\n\n/**\n * The separator used to split a string into tokens. Override this property to change the behaviour of\n * `lunr.tokenizer` behaviour when tokenizing strings. By default this splits on whitespace and hyphens.\n *\n * @static\n * @see lunr.tokenizer\n */\nlunr.tokenizer.separator = /[\\s\\-]+/\n/*!\n * lunr.Pipeline\n * Copyright (C) 2018 Oliver Nightingale\n */\n\n/**\n * lunr.Pipelines maintain an ordered list of functions to be applied to all\n * tokens in documents entering the search index and queries being ran against\n * the index.\n *\n * An instance of lunr.Index created with the lunr shortcut will contain a\n * pipeline with a stop word filter and an English language stemmer. Extra\n * functions can be added before or after either of these functions or these\n * default functions can be removed.\n *\n * When run the pipeline will call each function in turn, passing a token, the\n * index of that token in the original list of all tokens and finally a list of\n * all the original tokens.\n *\n * The output of functions in the pipeline will be passed to the next function\n * in the pipeline. To exclude a token from entering the index the function\n * should return undefined, the rest of the pipeline will not be called with\n * this token.\n *\n * For serialisation of pipelines to work, all functions used in an instance of\n * a pipeline should be registered with lunr.Pipeline. Registered functions can\n * then be loaded. If trying to load a serialised pipeline that uses functions\n * that are not registered an error will be thrown.\n *\n * If not planning on serialising the pipeline then registering pipeline functions\n * is not necessary.\n *\n * @constructor\n */\nlunr.Pipeline = function () {\n  this._stack = []\n}\n\nlunr.Pipeline.registeredFunctions = Object.create(null)\n\n/**\n * A pipeline function maps lunr.Token to lunr.Token. A lunr.Token contains the token\n * string as well as all known metadata. A pipeline function can mutate the token string\n * or mutate (or add) metadata for a given token.\n *\n * A pipeline function can indicate that the passed token should be discarded by returning\n * null. This token will not be passed to any downstream pipeline functions and will not be\n * added to the index.\n *\n * Multiple tokens can be returned by returning an array of tokens. Each token will be passed\n * to any downstream pipeline functions and all will returned tokens will be added to the index.\n *\n * Any number of pipeline functions may be chained together using a lunr.Pipeline.\n *\n * @interface lunr.PipelineFunction\n * @param {lunr.Token} token - A token from the document being processed.\n * @param {number} i - The index of this token in the complete list of tokens for this document/field.\n * @param {lunr.Token[]} tokens - All tokens for this document/field.\n * @returns {(?lunr.Token|lunr.Token[])}\n */\n\n/**\n * Register a function with the pipeline.\n *\n * Functions that are used in the pipeline should be registered if the pipeline\n * needs to be serialised, or a serialised pipeline needs to be loaded.\n *\n * Registering a function does not add it to a pipeline, functions must still be\n * added to instances of the pipeline for them to be used when running a pipeline.\n *\n * @param {lunr.PipelineFunction} fn - The function to check for.\n * @param {String} label - The label to register this function with\n */\nlunr.Pipeline.registerFunction = function (fn, label) {\n  if (label in this.registeredFunctions) {\n    lunr.utils.warn('Overwriting existing registered function: ' + label)\n  }\n\n  fn.label = label\n  lunr.Pipeline.registeredFunctions[fn.label] = fn\n}\n\n/**\n * Warns if the function is not registered as a Pipeline function.\n *\n * @param {lunr.PipelineFunction} fn - The function to check for.\n * @private\n */\nlunr.Pipeline.warnIfFunctionNotRegistered = function (fn) {\n  var isRegistered = fn.label && (fn.label in this.registeredFunctions)\n\n  if (!isRegistered) {\n    lunr.utils.warn('Function is not registered with pipeline. This may cause problems when serialising the index.\\n', fn)\n  }\n}\n\n/**\n * Loads a previously serialised pipeline.\n *\n * All functions to be loaded must already be registered with lunr.Pipeline.\n * If any function from the serialised data has not been registered then an\n * error will be thrown.\n *\n * @param {Object} serialised - The serialised pipeline to load.\n * @returns {lunr.Pipeline}\n */\nlunr.Pipeline.load = function (serialised) {\n  var pipeline = new lunr.Pipeline\n\n  serialised.forEach(function (fnName) {\n    var fn = lunr.Pipeline.registeredFunctions[fnName]\n\n    if (fn) {\n      pipeline.add(fn)\n    } else {\n      throw new Error('Cannot load unregistered function: ' + fnName)\n    }\n  })\n\n  return pipeline\n}\n\n/**\n * Adds new functions to the end of the pipeline.\n *\n * Logs a warning if the function has not been registered.\n *\n * @param {lunr.PipelineFunction[]} functions - Any number of functions to add to the pipeline.\n */\nlunr.Pipeline.prototype.add = function () {\n  var fns = Array.prototype.slice.call(arguments)\n\n  fns.forEach(function (fn) {\n    lunr.Pipeline.warnIfFunctionNotRegistered(fn)\n    this._stack.push(fn)\n  }, this)\n}\n\n/**\n * Adds a single function after a function that already exists in the\n * pipeline.\n *\n * Logs a warning if the function has not been registered.\n *\n * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline.\n * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline.\n */\nlunr.Pipeline.prototype.after = function (existingFn, newFn) {\n  lunr.Pipeline.warnIfFunctionNotRegistered(newFn)\n\n  var pos = this._stack.indexOf(existingFn)\n  if (pos == -1) {\n    throw new Error('Cannot find existingFn')\n  }\n\n  pos = pos + 1\n  this._stack.splice(pos, 0, newFn)\n}\n\n/**\n * Adds a single function before a function that already exists in the\n * pipeline.\n *\n * Logs a warning if the function has not been registered.\n *\n * @param {lunr.PipelineFunction} existingFn - A function that already exists in the pipeline.\n * @param {lunr.PipelineFunction} newFn - The new function to add to the pipeline.\n */\nlunr.Pipeline.prototype.before = function (existingFn, newFn) {\n  lunr.Pipeline.warnIfFunctionNotRegistered(newFn)\n\n  var pos = this._stack.indexOf(existingFn)\n  if (pos == -1) {\n    throw new Error('Cannot find existingFn')\n  }\n\n  this._stack.splice(pos, 0, newFn)\n}\n\n/**\n * Removes a function from the pipeline.\n *\n * @param {lunr.PipelineFunction} fn The function to remove from the pipeline.\n */\nlunr.Pipeline.prototype.remove = function (fn) {\n  var pos = this._stack.indexOf(fn)\n  if (pos == -1) {\n    return\n  }\n\n  this._stack.splice(pos, 1)\n}\n\n/**\n * Runs the current list of functions that make up the pipeline against the\n * passed tokens.\n *\n * @param {Array} tokens The tokens to run through the pipeline.\n * @returns {Array}\n */\nlunr.Pipeline.prototype.run = function (tokens) {\n  var stackLength = this._stack.length\n\n  for (var i = 0; i < stackLength; i++) {\n    var fn = this._stack[i]\n    var memo = []\n\n    for (var j = 0; j < tokens.length; j++) {\n      var result = fn(tokens[j], j, tokens)\n\n      if (result === void 0 || result === '') continue\n\n      if (Array.isArray(result)) {\n        for (var k = 0; k < result.length; k++) {\n          memo.push(result[k])\n        }\n      } else {\n        memo.push(result)\n      }\n    }\n\n    tokens = memo\n  }\n\n  return tokens\n}\n\n/**\n * Convenience method for passing a string through a pipeline and getting\n * strings out. This method takes care of wrapping the passed string in a\n * token and mapping the resulting tokens back to strings.\n *\n * @param {string} str - The string to pass through the pipeline.\n * @param {?object} metadata - Optional metadata to associate with the token\n * passed to the pipeline.\n * @returns {string[]}\n */\nlunr.Pipeline.prototype.runString = function (str, metadata) {\n  var token = new lunr.Token (str, metadata)\n\n  return this.run([token]).map(function (t) {\n    return t.toString()\n  })\n}\n\n/**\n * Resets the pipeline by removing any existing processors.\n *\n */\nlunr.Pipeline.prototype.reset = function () {\n  this._stack = []\n}\n\n/**\n * Returns a representation of the pipeline ready for serialisation.\n *\n * Logs a warning if the function has not been registered.\n *\n * @returns {Array}\n */\nlunr.Pipeline.prototype.toJSON = function () {\n  return this._stack.map(function (fn) {\n    lunr.Pipeline.warnIfFunctionNotRegistered(fn)\n\n    return fn.label\n  })\n}\n/*!\n * lunr.Vector\n * Copyright (C) 2018 Oliver Nightingale\n */\n\n/**\n * A vector is used to construct the vector space of documents and queries. These\n * vectors support operations to determine the similarity between two documents or\n * a document and a query.\n *\n * Normally no parameters are required for initializing a vector, but in the case of\n * loading a previously dumped vector the raw elements can be provided to the constructor.\n *\n * For performance reasons vectors are implemented with a flat array, where an elements\n * index is immediately followed by its value. E.g. [index, value, index, value]. This\n * allows the underlying array to be as sparse as possible and still offer decent\n * performance when being used for vector calculations.\n *\n * @constructor\n * @param {Number[]} [elements] - The flat list of element index and element value pairs.\n */\nlunr.Vector = function (elements) {\n  this._magnitude = 0\n  this.elements = elements || []\n}\n\n\n/**\n * Calculates the position within the vector to insert a given index.\n *\n * This is used internally by insert and upsert. If there are duplicate indexes then\n * the position is returned as if the value for that index were to be updated, but it\n * is the callers responsibility to check whether there is a duplicate at that index\n *\n * @param {Number} insertIdx - The index at which the element should be inserted.\n * @returns {Number}\n */\nlunr.Vector.prototype.positionForIndex = function (index) {\n  // For an empty vector the tuple can be inserted at the beginning\n  if (this.elements.length == 0) {\n    return 0\n  }\n\n  var start = 0,\n      end = this.elements.length / 2,\n      sliceLength = end - start,\n      pivotPoint = Math.floor(sliceLength / 2),\n      pivotIndex = this.elements[pivotPoint * 2]\n\n  while (sliceLength > 1) {\n    if (pivotIndex < index) {\n      start = pivotPoint\n    }\n\n    if (pivotIndex > index) {\n      end = pivotPoint\n    }\n\n    if (pivotIndex == index) {\n      break\n    }\n\n    sliceLength = end - start\n    pivotPoint = start + Math.floor(sliceLength / 2)\n    pivotIndex = this.elements[pivotPoint * 2]\n  }\n\n  if (pivotIndex == index) {\n    return pivotPoint * 2\n  }\n\n  if (pivotIndex > index) {\n    return pivotPoint * 2\n  }\n\n  if (pivotIndex < index) {\n    return (pivotPoint + 1) * 2\n  }\n}\n\n/**\n * Inserts an element at an index within the vector.\n *\n * Does not allow duplicates, will throw an error if there is already an entry\n * for this index.\n *\n * @param {Number} insertIdx - The index at which the element should be inserted.\n * @param {Number} val - The value to be inserted into the vector.\n */\nlunr.Vector.prototype.insert = function (insertIdx, val) {\n  this.upsert(insertIdx, val, function () {\n    throw \"duplicate index\"\n  })\n}\n\n/**\n * Inserts or updates an existing index within the vector.\n *\n * @param {Number} insertIdx - The index at which the element should be inserted.\n * @param {Number} val - The value to be inserted into the vector.\n * @param {function} fn - A function that is called for updates, the existing value and the\n * requested value are passed as arguments\n */\nlunr.Vector.prototype.upsert = function (insertIdx, val, fn) {\n  this._magnitude = 0\n  var position = this.positionForIndex(insertIdx)\n\n  if (this.elements[position] == insertIdx) {\n    this.elements[position + 1] = fn(this.elements[position + 1], val)\n  } else {\n    this.elements.splice(position, 0, insertIdx, val)\n  }\n}\n\n/**\n * Calculates the magnitude of this vector.\n *\n * @returns {Number}\n */\nlunr.Vector.prototype.magnitude = function () {\n  if (this._magnitude) return this._magnitude\n\n  var sumOfSquares = 0,\n      elementsLength = this.elements.length\n\n  for (var i = 1; i < elementsLength; i += 2) {\n    var val = this.elements[i]\n    sumOfSquares += val * val\n  }\n\n  return this._magnitude = Math.sqrt(sumOfSquares)\n}\n\n/**\n * Calculates the dot product of this vector and another vector.\n *\n * @param {lunr.Vector} otherVector - The vector to compute the dot product with.\n * @returns {Number}\n */\nlunr.Vector.prototype.dot = function (otherVector) {\n  var dotProduct = 0,\n      a = this.elements, b = otherVector.elements,\n      aLen = a.length, bLen = b.length,\n      aVal = 0, bVal = 0,\n      i = 0, j = 0\n\n  while (i < aLen && j < bLen) {\n    aVal = a[i], bVal = b[j]\n    if (aVal < bVal) {\n      i += 2\n    } else if (aVal > bVal) {\n      j += 2\n    } else if (aVal == bVal) {\n      dotProduct += a[i + 1] * b[j + 1]\n      i += 2\n      j += 2\n    }\n  }\n\n  return dotProduct\n}\n\n/**\n * Calculates the similarity between this vector and another vector.\n *\n * @param {lunr.Vector} otherVector - The other vector to calculate the\n * similarity with.\n * @returns {Number}\n */\nlunr.Vector.prototype.similarity = function (otherVector) {\n  return this.dot(otherVector) / this.magnitude() || 0\n}\n\n/**\n * Converts the vector to an array of the elements within the vector.\n *\n * @returns {Number[]}\n */\nlunr.Vector.prototype.toArray = function () {\n  var output = new Array (this.elements.length / 2)\n\n  for (var i = 1, j = 0; i < this.elements.length; i += 2, j++) {\n    output[j] = this.elements[i]\n  }\n\n  return output\n}\n\n/**\n * A JSON serializable representation of the vector.\n *\n * @returns {Number[]}\n */\nlunr.Vector.prototype.toJSON = function () {\n  return this.elements\n}\n/* eslint-disable */\n/*!\n * lunr.stemmer\n * Copyright (C) 2018 Oliver Nightingale\n * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt\n */\n\n/**\n * lunr.stemmer is an english language stemmer, this is a JavaScript\n * implementation of the PorterStemmer taken from http://tartarus.org/~martin\n *\n * @static\n * @implements {lunr.PipelineFunction}\n * @param {lunr.Token} token - The string to stem\n * @returns {lunr.Token}\n * @see {@link lunr.Pipeline}\n * @function\n */\nlunr.stemmer = (function(){\n  var step2list = {\n      \"ational\" : \"ate\",\n      \"tional\" : \"tion\",\n      \"enci\" : \"ence\",\n      \"anci\" : \"ance\",\n      \"izer\" : \"ize\",\n      \"bli\" : \"ble\",\n      \"alli\" : \"al\",\n      \"entli\" : \"ent\",\n      \"eli\" : \"e\",\n      \"ousli\" : \"ous\",\n      \"ization\" : \"ize\",\n      \"ation\" : \"ate\",\n      \"ator\" : \"ate\",\n      \"alism\" : \"al\",\n      \"iveness\" : \"ive\",\n      \"fulness\" : \"ful\",\n      \"ousness\" : \"ous\",\n      \"aliti\" : \"al\",\n      \"iviti\" : \"ive\",\n      \"biliti\" : \"ble\",\n      \"logi\" : \"log\"\n    },\n\n    step3list = {\n      \"icate\" : \"ic\",\n      \"ative\" : \"\",\n      \"alize\" : \"al\",\n      \"iciti\" : \"ic\",\n      \"ical\" : \"ic\",\n      \"ful\" : \"\",\n      \"ness\" : \"\"\n    },\n\n    c = \"[^aeiou]\",          // consonant\n    v = \"[aeiouy]\",          // vowel\n    C = c + \"[^aeiouy]*\",    // consonant sequence\n    V = v + \"[aeiou]*\",      // vowel sequence\n\n    mgr0 = \"^(\" + C + \")?\" + V + C,               // [C]VC... is m>0\n    meq1 = \"^(\" + C + \")?\" + V + C + \"(\" + V + \")?$\",  // [C]VC[V] is m=1\n    mgr1 = \"^(\" + C + \")?\" + V + C + V + C,       // [C]VCVC... is m>1\n    s_v = \"^(\" + C + \")?\" + v;                   // vowel in stem\n\n  var re_mgr0 = new RegExp(mgr0);\n  var re_mgr1 = new RegExp(mgr1);\n  var re_meq1 = new RegExp(meq1);\n  var re_s_v = new RegExp(s_v);\n\n  var re_1a = /^(.+?)(ss|i)es$/;\n  var re2_1a = /^(.+?)([^s])s$/;\n  var re_1b = /^(.+?)eed$/;\n  var re2_1b = /^(.+?)(ed|ing)$/;\n  var re_1b_2 = /.$/;\n  var re2_1b_2 = /(at|bl|iz)$/;\n  var re3_1b_2 = new RegExp(\"([^aeiouylsz])\\\\1$\");\n  var re4_1b_2 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n\n  var re_1c = /^(.+?[^aeiou])y$/;\n  var re_2 = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;\n\n  var re_3 = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;\n\n  var re_4 = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;\n  var re2_4 = /^(.+?)(s|t)(ion)$/;\n\n  var re_5 = /^(.+?)e$/;\n  var re_5_1 = /ll$/;\n  var re3_5 = new RegExp(\"^\" + C + v + \"[^aeiouwxy]$\");\n\n  var porterStemmer = function porterStemmer(w) {\n    var stem,\n      suffix,\n      firstch,\n      re,\n      re2,\n      re3,\n      re4;\n\n    if (w.length < 3) { return w; }\n\n    firstch = w.substr(0,1);\n    if (firstch == \"y\") {\n      w = firstch.toUpperCase() + w.substr(1);\n    }\n\n    // Step 1a\n    re = re_1a\n    re2 = re2_1a;\n\n    if (re.test(w)) { w = w.replace(re,\"$1$2\"); }\n    else if (re2.test(w)) { w = w.replace(re2,\"$1$2\"); }\n\n    // Step 1b\n    re = re_1b;\n    re2 = re2_1b;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      re = re_mgr0;\n      if (re.test(fp[1])) {\n        re = re_1b_2;\n        w = w.replace(re,\"\");\n      }\n    } else if (re2.test(w)) {\n      var fp = re2.exec(w);\n      stem = fp[1];\n      re2 = re_s_v;\n      if (re2.test(stem)) {\n        w = stem;\n        re2 = re2_1b_2;\n        re3 = re3_1b_2;\n        re4 = re4_1b_2;\n        if (re2.test(w)) { w = w + \"e\"; }\n        else if (re3.test(w)) { re = re_1b_2; w = w.replace(re,\"\"); }\n        else if (re4.test(w)) { w = w + \"e\"; }\n      }\n    }\n\n    // Step 1c - replace suffix y or Y by i if preceded by a non-vowel which is not the first letter of the word (so cry -> cri, by -> by, say -> say)\n    re = re_1c;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      w = stem + \"i\";\n    }\n\n    // Step 2\n    re = re_2;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      suffix = fp[2];\n      re = re_mgr0;\n      if (re.test(stem)) {\n        w = stem + step2list[suffix];\n      }\n    }\n\n    // Step 3\n    re = re_3;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      suffix = fp[2];\n      re = re_mgr0;\n      if (re.test(stem)) {\n        w = stem + step3list[suffix];\n      }\n    }\n\n    // Step 4\n    re = re_4;\n    re2 = re2_4;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = re_mgr1;\n      if (re.test(stem)) {\n        w = stem;\n      }\n    } else if (re2.test(w)) {\n      var fp = re2.exec(w);\n      stem = fp[1] + fp[2];\n      re2 = re_mgr1;\n      if (re2.test(stem)) {\n        w = stem;\n      }\n    }\n\n    // Step 5\n    re = re_5;\n    if (re.test(w)) {\n      var fp = re.exec(w);\n      stem = fp[1];\n      re = re_mgr1;\n      re2 = re_meq1;\n      re3 = re3_5;\n      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) {\n        w = stem;\n      }\n    }\n\n    re = re_5_1;\n    re2 = re_mgr1;\n    if (re.test(w) && re2.test(w)) {\n      re = re_1b_2;\n      w = w.replace(re,\"\");\n    }\n\n    // and turn initial Y back to y\n\n    if (firstch == \"y\") {\n      w = firstch.toLowerCase() + w.substr(1);\n    }\n\n    return w;\n  };\n\n  return function (token) {\n    return token.update(porterStemmer);\n  }\n})();\n\nlunr.Pipeline.registerFunction(lunr.stemmer, 'stemmer')\n/*!\n * lunr.stopWordFilter\n * Copyright (C) 2018 Oliver Nightingale\n */\n\n/**\n * lunr.generateStopWordFilter builds a stopWordFilter function from the provided\n * list of stop words.\n *\n * The built in lunr.stopWordFilter is built using this generator and can be used\n * to generate custom stopWordFilters for applications or non English languages.\n *\n * @function\n * @param {Array} token The token to pass through the filter\n * @returns {lunr.PipelineFunction}\n * @see lunr.Pipeline\n * @see lunr.stopWordFilter\n */\nlunr.generateStopWordFilter = function (stopWords) {\n  var words = stopWords.reduce(function (memo, stopWord) {\n    memo[stopWord] = stopWord\n    return memo\n  }, {})\n\n  return function (token) {\n    if (token && words[token.toString()] !== token.toString()) return token\n  }\n}\n\n/**\n * lunr.stopWordFilter is an English language stop word list filter, any words\n * contained in the list will not be passed through the filter.\n *\n * This is intended to be used in the Pipeline. If the token does not pass the\n * filter then undefined will be returned.\n *\n * @function\n * @implements {lunr.PipelineFunction}\n * @params {lunr.Token} token - A token to check for being a stop word.\n * @returns {lunr.Token}\n * @see {@link lunr.Pipeline}\n */\nlunr.stopWordFilter = lunr.generateStopWordFilter([\n  'a',\n  'able',\n  'about',\n  'across',\n  'after',\n  'all',\n  'almost',\n  'also',\n  'am',\n  'among',\n  'an',\n  'and',\n  'any',\n  'are',\n  'as',\n  'at',\n  'be',\n  'because',\n  'been',\n  'but',\n  'by',\n  'can',\n  'cannot',\n  'could',\n  'dear',\n  'did',\n  'do',\n  'does',\n  'either',\n  'else',\n  'ever',\n  'every',\n  'for',\n  'from',\n  'get',\n  'got',\n  'had',\n  'has',\n  'have',\n  'he',\n  'her',\n  'hers',\n  'him',\n  'his',\n  'how',\n  'however',\n  'i',\n  'if',\n  'in',\n  'into',\n  'is',\n  'it',\n  'its',\n  'just',\n  'least',\n  'let',\n  'like',\n  'likely',\n  'may',\n  'me',\n  'might',\n  'most',\n  'must',\n  'my',\n  'neither',\n  'no',\n  'nor',\n  'not',\n  'of',\n  'off',\n  'often',\n  'on',\n  'only',\n  'or',\n  'other',\n  'our',\n  'own',\n  'rather',\n  'said',\n  'say',\n  'says',\n  'she',\n  'should',\n  'since',\n  'so',\n  'some',\n  'than',\n  'that',\n  'the',\n  'their',\n  'them',\n  'then',\n  'there',\n  'these',\n  'they',\n  'this',\n  'tis',\n  'to',\n  'too',\n  'twas',\n  'us',\n  'wants',\n  'was',\n  'we',\n  'were',\n  'what',\n  'when',\n  'where',\n  'which',\n  'while',\n  'who',\n  'whom',\n  'why',\n  'will',\n  'with',\n  'would',\n  'yet',\n  'you',\n  'your'\n])\n\nlunr.Pipeline.registerFunction(lunr.stopWordFilter, 'stopWordFilter')\n/*!\n * lunr.trimmer\n * Copyright (C) 2018 Oliver Nightingale\n */\n\n/**\n * lunr.trimmer is a pipeline function for trimming non word\n * characters from the beginning and end of tokens before they\n * enter the index.\n *\n * This implementation may not work correctly for non latin\n * characters and should either be removed or adapted for use\n * with languages with non-latin characters.\n *\n * @static\n * @implements {lunr.PipelineFunction}\n * @param {lunr.Token} token The token to pass through the filter\n * @returns {lunr.Token}\n * @see lunr.Pipeline\n */\nlunr.trimmer = function (token) {\n  return token.update(function (s) {\n    return s.replace(/^\\W+/, '').replace(/\\W+$/, '')\n  })\n}\n\nlunr.Pipeline.registerFunction(lunr.trimmer, 'trimmer')\n/*!\n * lunr.TokenSet\n * Copyright (C) 2018 Oliver Nightingale\n */\n\n/**\n * A token set is used to store the unique list of all tokens\n * within an index. Token sets are also used to represent an\n * incoming query to the index, this query token set and index\n * token set are then intersected to find which tokens to look\n * up in the inverted index.\n *\n * A token set can hold multiple tokens, as in the case of the\n * index token set, or it can hold a single token as in the\n * case of a simple query token set.\n *\n * Additionally token sets are used to perform wildcard matching.\n * Leading, contained and trailing wildcards are supported, and\n * from this edit distance matching can also be provided.\n *\n * Token sets are implemented as a minimal finite state automata,\n * where both common prefixes and suffixes are shared between tokens.\n * This helps to reduce the space used for storing the token set.\n *\n * @constructor\n */\nlunr.TokenSet = function () {\n  this.final = false\n  this.edges = {}\n  this.id = lunr.TokenSet._nextId\n  lunr.TokenSet._nextId += 1\n}\n\n/**\n * Keeps track of the next, auto increment, identifier to assign\n * to a new tokenSet.\n *\n * TokenSets require a unique identifier to be correctly minimised.\n *\n * @private\n */\nlunr.TokenSet._nextId = 1\n\n/**\n * Creates a TokenSet instance from the given sorted array of words.\n *\n * @param {String[]} arr - A sorted array of strings to create the set from.\n * @returns {lunr.TokenSet}\n * @throws Will throw an error if the input array is not sorted.\n */\nlunr.TokenSet.fromArray = function (arr) {\n  var builder = new lunr.TokenSet.Builder\n\n  for (var i = 0, len = arr.length; i < len; i++) {\n    builder.insert(arr[i])\n  }\n\n  builder.finish()\n  return builder.root\n}\n\n/**\n * Creates a token set from a query clause.\n *\n * @private\n * @param {Object} clause - A single clause from lunr.Query.\n * @param {string} clause.term - The query clause term.\n * @param {number} [clause.editDistance] - The optional edit distance for the term.\n * @returns {lunr.TokenSet}\n */\nlunr.TokenSet.fromClause = function (clause) {\n  if ('editDistance' in clause) {\n    return lunr.TokenSet.fromFuzzyString(clause.term, clause.editDistance)\n  } else {\n    return lunr.TokenSet.fromString(clause.term)\n  }\n}\n\n/**\n * Creates a token set representing a single string with a specified\n * edit distance.\n *\n * Insertions, deletions, substitutions and transpositions are each\n * treated as an edit distance of 1.\n *\n * Increasing the allowed edit distance will have a dramatic impact\n * on the performance of both creating and intersecting these TokenSets.\n * It is advised to keep the edit distance less than 3.\n *\n * @param {string} str - The string to create the token set from.\n * @param {number} editDistance - The allowed edit distance to match.\n * @returns {lunr.Vector}\n */\nlunr.TokenSet.fromFuzzyString = function (str, editDistance) {\n  var root = new lunr.TokenSet\n\n  var stack = [{\n    node: root,\n    editsRemaining: editDistance,\n    str: str\n  }]\n\n  while (stack.length) {\n    var frame = stack.pop()\n\n    // no edit\n    if (frame.str.length > 0) {\n      var char = frame.str.charAt(0),\n          noEditNode\n\n      if (char in frame.node.edges) {\n        noEditNode = frame.node.edges[char]\n      } else {\n        noEditNode = new lunr.TokenSet\n        frame.node.edges[char] = noEditNode\n      }\n\n      if (frame.str.length == 1) {\n        noEditNode.final = true\n      }\n\n      stack.push({\n        node: noEditNode,\n        editsRemaining: frame.editsRemaining,\n        str: frame.str.slice(1)\n      })\n    }\n\n    // deletion\n    // can only do a deletion if we have enough edits remaining\n    // and if there are characters left to delete in the string\n    if (frame.editsRemaining > 0 && frame.str.length > 1) {\n      var char = frame.str.charAt(1),\n          deletionNode\n\n      if (char in frame.node.edges) {\n        deletionNode = frame.node.edges[char]\n      } else {\n        deletionNode = new lunr.TokenSet\n        frame.node.edges[char] = deletionNode\n      }\n\n      if (frame.str.length <= 2) {\n        deletionNode.final = true\n      } else {\n        stack.push({\n          node: deletionNode,\n          editsRemaining: frame.editsRemaining - 1,\n          str: frame.str.slice(2)\n        })\n      }\n    }\n\n    // deletion\n    // just removing the last character from the str\n    if (frame.editsRemaining > 0 && frame.str.length == 1) {\n      frame.node.final = true\n    }\n\n    // substitution\n    // can only do a substitution if we have enough edits remaining\n    // and if there are characters left to substitute\n    if (frame.editsRemaining > 0 && frame.str.length >= 1) {\n      if (\"*\" in frame.node.edges) {\n        var substitutionNode = frame.node.edges[\"*\"]\n      } else {\n        var substitutionNode = new lunr.TokenSet\n        frame.node.edges[\"*\"] = substitutionNode\n      }\n\n      if (frame.str.length == 1) {\n        substitutionNode.final = true\n      } else {\n        stack.push({\n          node: substitutionNode,\n          editsRemaining: frame.editsRemaining - 1,\n          str: frame.str.slice(1)\n        })\n      }\n    }\n\n    // insertion\n    // can only do insertion if there are edits remaining\n    if (frame.editsRemaining > 0) {\n      if (\"*\" in frame.node.edges) {\n        var insertionNode = frame.node.edges[\"*\"]\n      } else {\n        var insertionNode = new lunr.TokenSet\n        frame.node.edges[\"*\"] = insertionNode\n      }\n\n      if (frame.str.length == 0) {\n        insertionNode.final = true\n      } else {\n        stack.push({\n          node: insertionNode,\n          editsRemaining: frame.editsRemaining - 1,\n          str: frame.str\n        })\n      }\n    }\n\n    // transposition\n    // can only do a transposition if there are edits remaining\n    // and there are enough characters to transpose\n    if (frame.editsRemaining > 0 && frame.str.length > 1) {\n      var charA = frame.str.charAt(0),\n          charB = frame.str.charAt(1),\n          transposeNode\n\n      if (charB in frame.node.edges) {\n        transposeNode = frame.node.edges[charB]\n      } else {\n        transposeNode = new lunr.TokenSet\n        frame.node.edges[charB] = transposeNode\n      }\n\n      if (frame.str.length == 1) {\n        transposeNode.final = true\n      } else {\n        stack.push({\n          node: transposeNode,\n          editsRemaining: frame.editsRemaining - 1,\n          str: charA + frame.str.slice(2)\n        })\n      }\n    }\n  }\n\n  return root\n}\n\n/**\n * Creates a TokenSet from a string.\n *\n * The string may contain one or more wildcard characters (*)\n * that will allow wildcard matching when intersecting with\n * another TokenSet.\n *\n * @param {string} str - The string to create a TokenSet from.\n * @returns {lunr.TokenSet}\n */\nlunr.TokenSet.fromString = function (str) {\n  var node = new lunr.TokenSet,\n      root = node\n\n  /*\n   * Iterates through all characters within the passed string\n   * appending a node for each character.\n   *\n   * When a wildcard character is found then a self\n   * referencing edge is introduced to continually match\n   * any number of any characters.\n   */\n  for (var i = 0, len = str.length; i < len; i++) {\n    var char = str[i],\n        final = (i == len - 1)\n\n    if (char == \"*\") {\n      node.edges[char] = node\n      node.final = final\n\n    } else {\n      var next = new lunr.TokenSet\n      next.final = final\n\n      node.edges[char] = next\n      node = next\n    }\n  }\n\n  return root\n}\n\n/**\n * Converts this TokenSet into an array of strings\n * contained within the TokenSet.\n *\n * @returns {string[]}\n */\nlunr.TokenSet.prototype.toArray = function () {\n  var words = []\n\n  var stack = [{\n    prefix: \"\",\n    node: this\n  }]\n\n  while (stack.length) {\n    var frame = stack.pop(),\n        edges = Object.keys(frame.node.edges),\n        len = edges.length\n\n    if (frame.node.final) {\n      /* In Safari, at this point the prefix is sometimes corrupted, see:\n       * https://github.com/olivernn/lunr.js/issues/279 Calling any\n       * String.prototype method forces Safari to \"cast\" this string to what\n       * it's supposed to be, fixing the bug. */\n      frame.prefix.charAt(0)\n      words.push(frame.prefix)\n    }\n\n    for (var i = 0; i < len; i++) {\n      var edge = edges[i]\n\n      stack.push({\n        prefix: frame.prefix.concat(edge),\n        node: frame.node.edges[edge]\n      })\n    }\n  }\n\n  return words\n}\n\n/**\n * Generates a string representation of a TokenSet.\n *\n * This is intended to allow TokenSets to be used as keys\n * in objects, largely to aid the construction and minimisation\n * of a TokenSet. As such it is not designed to be a human\n * friendly representation of the TokenSet.\n *\n * @returns {string}\n */\nlunr.TokenSet.prototype.toString = function () {\n  // NOTE: Using Object.keys here as this.edges is very likely\n  // to enter 'hash-mode' with many keys being added\n  //\n  // avoiding a for-in loop here as it leads to the function\n  // being de-optimised (at least in V8). From some simple\n  // benchmarks the performance is comparable, but allowing\n  // V8 to optimize may mean easy performance wins in the future.\n\n  if (this._str) {\n    return this._str\n  }\n\n  var str = this.final ? '1' : '0',\n      labels = Object.keys(this.edges).sort(),\n      len = labels.length\n\n  for (var i = 0; i < len; i++) {\n    var label = labels[i],\n        node = this.edges[label]\n\n    str = str + label + node.id\n  }\n\n  return str\n}\n\n/**\n * Returns a new TokenSet that is the intersection of\n * this TokenSet and the passed TokenSet.\n *\n * This intersection will take into account any wildcards\n * contained within the TokenSet.\n *\n * @param {lunr.TokenSet} b - An other TokenSet to intersect with.\n * @returns {lunr.TokenSet}\n */\nlunr.TokenSet.prototype.intersect = function (b) {\n  var output = new lunr.TokenSet,\n      frame = undefined\n\n  var stack = [{\n    qNode: b,\n    output: output,\n    node: this\n  }]\n\n  while (stack.length) {\n    frame = stack.pop()\n\n    // NOTE: As with the #toString method, we are using\n    // Object.keys and a for loop instead of a for-in loop\n    // as both of these objects enter 'hash' mode, causing\n    // the function to be de-optimised in V8\n    var qEdges = Object.keys(frame.qNode.edges),\n        qLen = qEdges.length,\n        nEdges = Object.keys(frame.node.edges),\n        nLen = nEdges.length\n\n    for (var q = 0; q < qLen; q++) {\n      var qEdge = qEdges[q]\n\n      for (var n = 0; n < nLen; n++) {\n        var nEdge = nEdges[n]\n\n        if (nEdge == qEdge || qEdge == '*') {\n          var node = frame.node.edges[nEdge],\n              qNode = frame.qNode.edges[qEdge],\n              final = node.final && qNode.final,\n              next = undefined\n\n          if (nEdge in frame.output.edges) {\n            // an edge already exists for this character\n            // no need to create a new node, just set the finality\n            // bit unless this node is already final\n            next = frame.output.edges[nEdge]\n            next.final = next.final || final\n\n          } else {\n            // no edge exists yet, must create one\n            // set the finality bit and insert it\n            // into the output\n            next = new lunr.TokenSet\n            next.final = final\n            frame.output.edges[nEdge] = next\n          }\n\n          stack.push({\n            qNode: qNode,\n            output: next,\n            node: node\n          })\n        }\n      }\n    }\n  }\n\n  return output\n}\nlunr.TokenSet.Builder = function () {\n  this.previousWord = \"\"\n  this.root = new lunr.TokenSet\n  this.uncheckedNodes = []\n  this.minimizedNodes = {}\n}\n\nlunr.TokenSet.Builder.prototype.insert = function (word) {\n  var node,\n      commonPrefix = 0\n\n  if (word < this.previousWord) {\n    throw new Error (\"Out of order word insertion\")\n  }\n\n  for (var i = 0; i < word.length && i < this.previousWord.length; i++) {\n    if (word[i] != this.previousWord[i]) break\n    commonPrefix++\n  }\n\n  this.minimize(commonPrefix)\n\n  if (this.uncheckedNodes.length == 0) {\n    node = this.root\n  } else {\n    node = this.uncheckedNodes[this.uncheckedNodes.length - 1].child\n  }\n\n  for (var i = commonPrefix; i < word.length; i++) {\n    var nextNode = new lunr.TokenSet,\n        char = word[i]\n\n    node.edges[char] = nextNode\n\n    this.uncheckedNodes.push({\n      parent: node,\n      char: char,\n      child: nextNode\n    })\n\n    node = nextNode\n  }\n\n  node.final = true\n  this.previousWord = word\n}\n\nlunr.TokenSet.Builder.prototype.finish = function () {\n  this.minimize(0)\n}\n\nlunr.TokenSet.Builder.prototype.minimize = function (downTo) {\n  for (var i = this.uncheckedNodes.length - 1; i >= downTo; i--) {\n    var node = this.uncheckedNodes[i],\n        childKey = node.child.toString()\n\n    if (childKey in this.minimizedNodes) {\n      node.parent.edges[node.char] = this.minimizedNodes[childKey]\n    } else {\n      // Cache the key for this node since\n      // we know it can't change anymore\n      node.child._str = childKey\n\n      this.minimizedNodes[childKey] = node.child\n    }\n\n    this.uncheckedNodes.pop()\n  }\n}\n/*!\n * lunr.Index\n * Copyright (C) 2018 Oliver Nightingale\n */\n\n/**\n * An index contains the built index of all documents and provides a query interface\n * to the index.\n *\n * Usually instances of lunr.Index will not be created using this constructor, instead\n * lunr.Builder should be used to construct new indexes, or lunr.Index.load should be\n * used to load previously built and serialized indexes.\n *\n * @constructor\n * @param {Object} attrs - The attributes of the built search index.\n * @param {Object} attrs.invertedIndex - An index of term/field to document reference.\n * @param {Object<string, lunr.Vector>} attrs.fieldVectors - Field vectors\n * @param {lunr.TokenSet} attrs.tokenSet - An set of all corpus tokens.\n * @param {string[]} attrs.fields - The names of indexed document fields.\n * @param {lunr.Pipeline} attrs.pipeline - The pipeline to use for search terms.\n */\nlunr.Index = function (attrs) {\n  this.invertedIndex = attrs.invertedIndex\n  this.fieldVectors = attrs.fieldVectors\n  this.tokenSet = attrs.tokenSet\n  this.fields = attrs.fields\n  this.pipeline = attrs.pipeline\n}\n\n/**\n * A result contains details of a document matching a search query.\n * @typedef {Object} lunr.Index~Result\n * @property {string} ref - The reference of the document this result represents.\n * @property {number} score - A number between 0 and 1 representing how similar this document is to the query.\n * @property {lunr.MatchData} matchData - Contains metadata about this match including which term(s) caused the match.\n */\n\n/**\n * Although lunr provides the ability to create queries using lunr.Query, it also provides a simple\n * query language which itself is parsed into an instance of lunr.Query.\n *\n * For programmatically building queries it is advised to directly use lunr.Query, the query language\n * is best used for human entered text rather than program generated text.\n *\n * At its simplest queries can just be a single term, e.g. `hello`, multiple terms are also supported\n * and will be combined with OR, e.g `hello world` will match documents that contain either 'hello'\n * or 'world', though those that contain both will rank higher in the results.\n *\n * Wildcards can be included in terms to match one or more unspecified characters, these wildcards can\n * be inserted anywhere within the term, and more than one wildcard can exist in a single term. Adding\n * wildcards will increase the number of documents that will be found but can also have a negative\n * impact on query performance, especially with wildcards at the beginning of a term.\n *\n * Terms can be restricted to specific fields, e.g. `title:hello`, only documents with the term\n * hello in the title field will match this query. Using a field not present in the index will lead\n * to an error being thrown.\n *\n * Modifiers can also be added to terms, lunr supports edit distance and boost modifiers on terms. A term\n * boost will make documents matching that term score higher, e.g. `foo^5`. Edit distance is also supported\n * to provide fuzzy matching, e.g. 'hello~2' will match documents with hello with an edit distance of 2.\n * Avoid large values for edit distance to improve query performance.\n *\n * Each term also supports a presence modifier. By default a term's presence in document is optional, however\n * this can be changed to either required or prohibited. For a term's presence to be required in a document the\n * term should be prefixed with a '+', e.g. `+foo bar` is a search for documents that must contain 'foo' and\n * optionally contain 'bar'. Conversely a leading '-' sets the terms presence to prohibited, i.e. it must not\n * appear in a document, e.g. `-foo bar` is a search for documents that do not contain 'foo' but may contain 'bar'.\n *\n * To escape special characters the backslash character '\\' can be used, this allows searches to include\n * characters that would normally be considered modifiers, e.g. `foo\\~2` will search for a term \"foo~2\" instead\n * of attempting to apply a boost of 2 to the search term \"foo\".\n *\n * @typedef {string} lunr.Index~QueryString\n * @example <caption>Simple single term query</caption>\n * hello\n * @example <caption>Multiple term query</caption>\n * hello world\n * @example <caption>term scoped to a field</caption>\n * title:hello\n * @example <caption>term with a boost of 10</caption>\n * hello^10\n * @example <caption>term with an edit distance of 2</caption>\n * hello~2\n * @example <caption>terms with presence modifiers</caption>\n * -foo +bar baz\n */\n\n/**\n * Performs a search against the index using lunr query syntax.\n *\n * Results will be returned sorted by their score, the most relevant results\n * will be returned first.  For details on how the score is calculated, please see\n * the {@link https://lunrjs.com/guides/searching.html#scoring|guide}.\n *\n * For more programmatic querying use lunr.Index#query.\n *\n * @param {lunr.Index~QueryString} queryString - A string containing a lunr query.\n * @throws {lunr.QueryParseError} If the passed query string cannot be parsed.\n * @returns {lunr.Index~Result[]}\n */\nlunr.Index.prototype.search = function (queryString) {\n  return this.query(function (query) {\n    var parser = new lunr.QueryParser(queryString, query)\n    parser.parse()\n  })\n}\n\n/**\n * A query builder callback provides a query object to be used to express\n * the query to perform on the index.\n *\n * @callback lunr.Index~queryBuilder\n * @param {lunr.Query} query - The query object to build up.\n * @this lunr.Query\n */\n\n/**\n * Performs a query against the index using the yielded lunr.Query object.\n *\n * If performing programmatic queries against the index, this method is preferred\n * over lunr.Index#search so as to avoid the additional query parsing overhead.\n *\n * A query object is yielded to the supplied function which should be used to\n * express the query to be run against the index.\n *\n * Note that although this function takes a callback parameter it is _not_ an\n * asynchronous operation, the callback is just yielded a query object to be\n * customized.\n *\n * @param {lunr.Index~queryBuilder} fn - A function that is used to build the query.\n * @returns {lunr.Index~Result[]}\n */\nlunr.Index.prototype.query = function (fn) {\n  // for each query clause\n  // * process terms\n  // * expand terms from token set\n  // * find matching documents and metadata\n  // * get document vectors\n  // * score documents\n\n  var query = new lunr.Query(this.fields),\n      matchingFields = Object.create(null),\n      queryVectors = Object.create(null),\n      termFieldCache = Object.create(null),\n      requiredMatches = Object.create(null),\n      prohibitedMatches = Object.create(null)\n\n  /*\n   * To support field level boosts a query vector is created per\n   * field. An empty vector is eagerly created to support negated\n   * queries.\n   */\n  for (var i = 0; i < this.fields.length; i++) {\n    queryVectors[this.fields[i]] = new lunr.Vector\n  }\n\n  fn.call(query, query)\n\n  for (var i = 0; i < query.clauses.length; i++) {\n    /*\n     * Unless the pipeline has been disabled for this term, which is\n     * the case for terms with wildcards, we need to pass the clause\n     * term through the search pipeline. A pipeline returns an array\n     * of processed terms. Pipeline functions may expand the passed\n     * term, which means we may end up performing multiple index lookups\n     * for a single query term.\n     */\n    var clause = query.clauses[i],\n        terms = null,\n        clauseMatches = lunr.Set.complete\n\n    if (clause.usePipeline) {\n      terms = this.pipeline.runString(clause.term, {\n        fields: clause.fields\n      })\n    } else {\n      terms = [clause.term]\n    }\n\n    for (var m = 0; m < terms.length; m++) {\n      var term = terms[m]\n\n      /*\n       * Each term returned from the pipeline needs to use the same query\n       * clause object, e.g. the same boost and or edit distance. The\n       * simplest way to do this is to re-use the clause object but mutate\n       * its term property.\n       */\n      clause.term = term\n\n      /*\n       * From the term in the clause we create a token set which will then\n       * be used to intersect the indexes token set to get a list of terms\n       * to lookup in the inverted index\n       */\n      var termTokenSet = lunr.TokenSet.fromClause(clause),\n          expandedTerms = this.tokenSet.intersect(termTokenSet).toArray()\n\n      /*\n       * If a term marked as required does not exist in the tokenSet it is\n       * impossible for the search to return any matches. We set all the field\n       * scoped required matches set to empty and stop examining any further\n       * clauses.\n       */\n      if (expandedTerms.length === 0 && clause.presence === lunr.Query.presence.REQUIRED) {\n        for (var k = 0; k < clause.fields.length; k++) {\n          var field = clause.fields[k]\n          requiredMatches[field] = lunr.Set.empty\n        }\n\n        break\n      }\n\n      for (var j = 0; j < expandedTerms.length; j++) {\n        /*\n         * For each term get the posting and termIndex, this is required for\n         * building the query vector.\n         */\n        var expandedTerm = expandedTerms[j],\n            posting = this.invertedIndex[expandedTerm],\n            termIndex = posting._index\n\n        for (var k = 0; k < clause.fields.length; k++) {\n          /*\n           * For each field that this query term is scoped by (by default\n           * all fields are in scope) we need to get all the document refs\n           * that have this term in that field.\n           *\n           * The posting is the entry in the invertedIndex for the matching\n           * term from above.\n           */\n          var field = clause.fields[k],\n              fieldPosting = posting[field],\n              matchingDocumentRefs = Object.keys(fieldPosting),\n              termField = expandedTerm + \"/\" + field,\n              matchingDocumentsSet = new lunr.Set(matchingDocumentRefs)\n\n          /*\n           * if the presence of this term is required ensure that the matching\n           * documents are added to the set of required matches for this clause.\n           *\n           */\n          if (clause.presence == lunr.Query.presence.REQUIRED) {\n            clauseMatches = clauseMatches.union(matchingDocumentsSet)\n\n            if (requiredMatches[field] === undefined) {\n              requiredMatches[field] = lunr.Set.complete\n            }\n          }\n\n          /*\n           * if the presence of this term is prohibited ensure that the matching\n           * documents are added to the set of prohibited matches for this field,\n           * creating that set if it does not yet exist.\n           */\n          if (clause.presence == lunr.Query.presence.PROHIBITED) {\n            if (prohibitedMatches[field] === undefined) {\n              prohibitedMatches[field] = lunr.Set.empty\n            }\n\n            prohibitedMatches[field] = prohibitedMatches[field].union(matchingDocumentsSet)\n\n            /*\n             * Prohibited matches should not be part of the query vector used for\n             * similarity scoring and no metadata should be extracted so we continue\n             * to the next field\n             */\n            continue\n          }\n\n          /*\n           * The query field vector is populated using the termIndex found for\n           * the term and a unit value with the appropriate boost applied.\n           * Using upsert because there could already be an entry in the vector\n           * for the term we are working with. In that case we just add the scores\n           * together.\n           */\n          queryVectors[field].upsert(termIndex, clause.boost, function (a, b) { return a + b })\n\n          /**\n           * If we've already seen this term, field combo then we've already collected\n           * the matching documents and metadata, no need to go through all that again\n           */\n          if (termFieldCache[termField]) {\n            continue\n          }\n\n          for (var l = 0; l < matchingDocumentRefs.length; l++) {\n            /*\n             * All metadata for this term/field/document triple\n             * are then extracted and collected into an instance\n             * of lunr.MatchData ready to be returned in the query\n             * results\n             */\n            var matchingDocumentRef = matchingDocumentRefs[l],\n                matchingFieldRef = new lunr.FieldRef (matchingDocumentRef, field),\n                metadata = fieldPosting[matchingDocumentRef],\n                fieldMatch\n\n            if ((fieldMatch = matchingFields[matchingFieldRef]) === undefined) {\n              matchingFields[matchingFieldRef] = new lunr.MatchData (expandedTerm, field, metadata)\n            } else {\n              fieldMatch.add(expandedTerm, field, metadata)\n            }\n\n          }\n\n          termFieldCache[termField] = true\n        }\n      }\n    }\n\n    /**\n     * If the presence was required we need to update the requiredMatches field sets.\n     * We do this after all fields for the term have collected their matches because\n     * the clause terms presence is required in _any_ of the fields not _all_ of the\n     * fields.\n     */\n    if (clause.presence === lunr.Query.presence.REQUIRED) {\n      for (var k = 0; k < clause.fields.length; k++) {\n        var field = clause.fields[k]\n        requiredMatches[field] = requiredMatches[field].intersect(clauseMatches)\n      }\n    }\n  }\n\n  /**\n   * Need to combine the field scoped required and prohibited\n   * matching documents into a global set of required and prohibited\n   * matches\n   */\n  var allRequiredMatches = lunr.Set.complete,\n      allProhibitedMatches = lunr.Set.empty\n\n  for (var i = 0; i < this.fields.length; i++) {\n    var field = this.fields[i]\n\n    if (requiredMatches[field]) {\n      allRequiredMatches = allRequiredMatches.intersect(requiredMatches[field])\n    }\n\n    if (prohibitedMatches[field]) {\n      allProhibitedMatches = allProhibitedMatches.union(prohibitedMatches[field])\n    }\n  }\n\n  var matchingFieldRefs = Object.keys(matchingFields),\n      results = [],\n      matches = Object.create(null)\n\n  /*\n   * If the query is negated (contains only prohibited terms)\n   * we need to get _all_ fieldRefs currently existing in the\n   * index. This is only done when we know that the query is\n   * entirely prohibited terms to avoid any cost of getting all\n   * fieldRefs unnecessarily.\n   *\n   * Additionally, blank MatchData must be created to correctly\n   * populate the results.\n   */\n  if (query.isNegated()) {\n    matchingFieldRefs = Object.keys(this.fieldVectors)\n\n    for (var i = 0; i < matchingFieldRefs.length; i++) {\n      var matchingFieldRef = matchingFieldRefs[i]\n      var fieldRef = lunr.FieldRef.fromString(matchingFieldRef)\n      matchingFields[matchingFieldRef] = new lunr.MatchData\n    }\n  }\n\n  for (var i = 0; i < matchingFieldRefs.length; i++) {\n    /*\n     * Currently we have document fields that match the query, but we\n     * need to return documents. The matchData and scores are combined\n     * from multiple fields belonging to the same document.\n     *\n     * Scores are calculated by field, using the query vectors created\n     * above, and combined into a final document score using addition.\n     */\n    var fieldRef = lunr.FieldRef.fromString(matchingFieldRefs[i]),\n        docRef = fieldRef.docRef\n\n    if (!allRequiredMatches.contains(docRef)) {\n      continue\n    }\n\n    if (allProhibitedMatches.contains(docRef)) {\n      continue\n    }\n\n    var fieldVector = this.fieldVectors[fieldRef],\n        score = queryVectors[fieldRef.fieldName].similarity(fieldVector),\n        docMatch\n\n    if ((docMatch = matches[docRef]) !== undefined) {\n      docMatch.score += score\n      docMatch.matchData.combine(matchingFields[fieldRef])\n    } else {\n      var match = {\n        ref: docRef,\n        score: score,\n        matchData: matchingFields[fieldRef]\n      }\n      matches[docRef] = match\n      results.push(match)\n    }\n  }\n\n  /*\n   * Sort the results objects by score, highest first.\n   */\n  return results.sort(function (a, b) {\n    return b.score - a.score\n  })\n}\n\n/**\n * Prepares the index for JSON serialization.\n *\n * The schema for this JSON blob will be described in a\n * separate JSON schema file.\n *\n * @returns {Object}\n */\nlunr.Index.prototype.toJSON = function () {\n  var invertedIndex = Object.keys(this.invertedIndex)\n    .sort()\n    .map(function (term) {\n      return [term, this.invertedIndex[term]]\n    }, this)\n\n  var fieldVectors = Object.keys(this.fieldVectors)\n    .map(function (ref) {\n      return [ref, this.fieldVectors[ref].toJSON()]\n    }, this)\n\n  return {\n    version: lunr.version,\n    fields: this.fields,\n    fieldVectors: fieldVectors,\n    invertedIndex: invertedIndex,\n    pipeline: this.pipeline.toJSON()\n  }\n}\n\n/**\n * Loads a previously serialized lunr.Index\n *\n * @param {Object} serializedIndex - A previously serialized lunr.Index\n * @returns {lunr.Index}\n */\nlunr.Index.load = function (serializedIndex) {\n  var attrs = {},\n      fieldVectors = {},\n      serializedVectors = serializedIndex.fieldVectors,\n      invertedIndex = Object.create(null),\n      serializedInvertedIndex = serializedIndex.invertedIndex,\n      tokenSetBuilder = new lunr.TokenSet.Builder,\n      pipeline = lunr.Pipeline.load(serializedIndex.pipeline)\n\n  if (serializedIndex.version != lunr.version) {\n    lunr.utils.warn(\"Version mismatch when loading serialised index. Current version of lunr '\" + lunr.version + \"' does not match serialized index '\" + serializedIndex.version + \"'\")\n  }\n\n  for (var i = 0; i < serializedVectors.length; i++) {\n    var tuple = serializedVectors[i],\n        ref = tuple[0],\n        elements = tuple[1]\n\n    fieldVectors[ref] = new lunr.Vector(elements)\n  }\n\n  for (var i = 0; i < serializedInvertedIndex.length; i++) {\n    var tuple = serializedInvertedIndex[i],\n        term = tuple[0],\n        posting = tuple[1]\n\n    tokenSetBuilder.insert(term)\n    invertedIndex[term] = posting\n  }\n\n  tokenSetBuilder.finish()\n\n  attrs.fields = serializedIndex.fields\n\n  attrs.fieldVectors = fieldVectors\n  attrs.invertedIndex = invertedIndex\n  attrs.tokenSet = tokenSetBuilder.root\n  attrs.pipeline = pipeline\n\n  return new lunr.Index(attrs)\n}\n/*!\n * lunr.Builder\n * Copyright (C) 2018 Oliver Nightingale\n */\n\n/**\n * lunr.Builder performs indexing on a set of documents and\n * returns instances of lunr.Index ready for querying.\n *\n * All configuration of the index is done via the builder, the\n * fields to index, the document reference, the text processing\n * pipeline and document scoring parameters are all set on the\n * builder before indexing.\n *\n * @constructor\n * @property {string} _ref - Internal reference to the document reference field.\n * @property {string[]} _fields - Internal reference to the document fields to index.\n * @property {object} invertedIndex - The inverted index maps terms to document fields.\n * @property {object} documentTermFrequencies - Keeps track of document term frequencies.\n * @property {object} documentLengths - Keeps track of the length of documents added to the index.\n * @property {lunr.tokenizer} tokenizer - Function for splitting strings into tokens for indexing.\n * @property {lunr.Pipeline} pipeline - The pipeline performs text processing on tokens before indexing.\n * @property {lunr.Pipeline} searchPipeline - A pipeline for processing search terms before querying the index.\n * @property {number} documentCount - Keeps track of the total number of documents indexed.\n * @property {number} _b - A parameter to control field length normalization, setting this to 0 disabled normalization, 1 fully normalizes field lengths, the default value is 0.75.\n * @property {number} _k1 - A parameter to control how quickly an increase in term frequency results in term frequency saturation, the default value is 1.2.\n * @property {number} termIndex - A counter incremented for each unique term, used to identify a terms position in the vector space.\n * @property {array} metadataWhitelist - A list of metadata keys that have been whitelisted for entry in the index.\n */\nlunr.Builder = function () {\n  this._ref = \"id\"\n  this._fields = Object.create(null)\n  this._documents = Object.create(null)\n  this.invertedIndex = Object.create(null)\n  this.fieldTermFrequencies = {}\n  this.fieldLengths = {}\n  this.tokenizer = lunr.tokenizer\n  this.pipeline = new lunr.Pipeline\n  this.searchPipeline = new lunr.Pipeline\n  this.documentCount = 0\n  this._b = 0.75\n  this._k1 = 1.2\n  this.termIndex = 0\n  this.metadataWhitelist = []\n}\n\n/**\n * Sets the document field used as the document reference. Every document must have this field.\n * The type of this field in the document should be a string, if it is not a string it will be\n * coerced into a string by calling toString.\n *\n * The default ref is 'id'.\n *\n * The ref should _not_ be changed during indexing, it should be set before any documents are\n * added to the index. Changing it during indexing can lead to inconsistent results.\n *\n * @param {string} ref - The name of the reference field in the document.\n */\nlunr.Builder.prototype.ref = function (ref) {\n  this._ref = ref\n}\n\n/**\n * A function that is used to extract a field from a document.\n *\n * Lunr expects a field to be at the top level of a document, if however the field\n * is deeply nested within a document an extractor function can be used to extract\n * the right field for indexing.\n *\n * @callback fieldExtractor\n * @param {object} doc - The document being added to the index.\n * @returns {?(string|object|object[])} obj - The object that will be indexed for this field.\n * @example <caption>Extracting a nested field</caption>\n * function (doc) { return doc.nested.field }\n */\n\n/**\n * Adds a field to the list of document fields that will be indexed. Every document being\n * indexed should have this field. Null values for this field in indexed documents will\n * not cause errors but will limit the chance of that document being retrieved by searches.\n *\n * All fields should be added before adding documents to the index. Adding fields after\n * a document has been indexed will have no effect on already indexed documents.\n *\n * Fields can be boosted at build time. This allows terms within that field to have more\n * importance when ranking search results. Use a field boost to specify that matches within\n * one field are more important than other fields.\n *\n * @param {string} fieldName - The name of a field to index in all documents.\n * @param {object} attributes - Optional attributes associated with this field.\n * @param {number} [attributes.boost=1] - Boost applied to all terms within this field.\n * @param {fieldExtractor} [attributes.extractor] - Function to extract a field from a document.\n * @throws {RangeError} fieldName cannot contain unsupported characters '/'\n */\nlunr.Builder.prototype.field = function (fieldName, attributes) {\n  if (/\\//.test(fieldName)) {\n    throw new RangeError (\"Field '\" + fieldName + \"' contains illegal character '/'\")\n  }\n\n  this._fields[fieldName] = attributes || {}\n}\n\n/**\n * A parameter to tune the amount of field length normalisation that is applied when\n * calculating relevance scores. A value of 0 will completely disable any normalisation\n * and a value of 1 will fully normalise field lengths. The default is 0.75. Values of b\n * will be clamped to the range 0 - 1.\n *\n * @param {number} number - The value to set for this tuning parameter.\n */\nlunr.Builder.prototype.b = function (number) {\n  if (number < 0) {\n    this._b = 0\n  } else if (number > 1) {\n    this._b = 1\n  } else {\n    this._b = number\n  }\n}\n\n/**\n * A parameter that controls the speed at which a rise in term frequency results in term\n * frequency saturation. The default value is 1.2. Setting this to a higher value will give\n * slower saturation levels, a lower value will result in quicker saturation.\n *\n * @param {number} number - The value to set for this tuning parameter.\n */\nlunr.Builder.prototype.k1 = function (number) {\n  this._k1 = number\n}\n\n/**\n * Adds a document to the index.\n *\n * Before adding fields to the index the index should have been fully setup, with the document\n * ref and all fields to index already having been specified.\n *\n * The document must have a field name as specified by the ref (by default this is 'id') and\n * it should have all fields defined for indexing, though null or undefined values will not\n * cause errors.\n *\n * Entire documents can be boosted at build time. Applying a boost to a document indicates that\n * this document should rank higher in search results than other documents.\n *\n * @param {object} doc - The document to add to the index.\n * @param {object} attributes - Optional attributes associated with this document.\n * @param {number} [attributes.boost=1] - Boost applied to all terms within this document.\n */\nlunr.Builder.prototype.add = function (doc, attributes) {\n  var docRef = doc[this._ref],\n      fields = Object.keys(this._fields)\n\n  this._documents[docRef] = attributes || {}\n  this.documentCount += 1\n\n  for (var i = 0; i < fields.length; i++) {\n    var fieldName = fields[i],\n        extractor = this._fields[fieldName].extractor,\n        field = extractor ? extractor(doc) : doc[fieldName],\n        tokens = this.tokenizer(field, {\n          fields: [fieldName]\n        }),\n        terms = this.pipeline.run(tokens),\n        fieldRef = new lunr.FieldRef (docRef, fieldName),\n        fieldTerms = Object.create(null)\n\n    this.fieldTermFrequencies[fieldRef] = fieldTerms\n    this.fieldLengths[fieldRef] = 0\n\n    // store the length of this field for this document\n    this.fieldLengths[fieldRef] += terms.length\n\n    // calculate term frequencies for this field\n    for (var j = 0; j < terms.length; j++) {\n      var term = terms[j]\n\n      if (fieldTerms[term] == undefined) {\n        fieldTerms[term] = 0\n      }\n\n      fieldTerms[term] += 1\n\n      // add to inverted index\n      // create an initial posting if one doesn't exist\n      if (this.invertedIndex[term] == undefined) {\n        var posting = Object.create(null)\n        posting[\"_index\"] = this.termIndex\n        this.termIndex += 1\n\n        for (var k = 0; k < fields.length; k++) {\n          posting[fields[k]] = Object.create(null)\n        }\n\n        this.invertedIndex[term] = posting\n      }\n\n      // add an entry for this term/fieldName/docRef to the invertedIndex\n      if (this.invertedIndex[term][fieldName][docRef] == undefined) {\n        this.invertedIndex[term][fieldName][docRef] = Object.create(null)\n      }\n\n      // store all whitelisted metadata about this token in the\n      // inverted index\n      for (var l = 0; l < this.metadataWhitelist.length; l++) {\n        var metadataKey = this.metadataWhitelist[l],\n            metadata = term.metadata[metadataKey]\n\n        if (this.invertedIndex[term][fieldName][docRef][metadataKey] == undefined) {\n          this.invertedIndex[term][fieldName][docRef][metadataKey] = []\n        }\n\n        this.invertedIndex[term][fieldName][docRef][metadataKey].push(metadata)\n      }\n    }\n\n  }\n}\n\n/**\n * Calculates the average document length for this index\n *\n * @private\n */\nlunr.Builder.prototype.calculateAverageFieldLengths = function () {\n\n  var fieldRefs = Object.keys(this.fieldLengths),\n      numberOfFields = fieldRefs.length,\n      accumulator = {},\n      documentsWithField = {}\n\n  for (var i = 0; i < numberOfFields; i++) {\n    var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]),\n        field = fieldRef.fieldName\n\n    documentsWithField[field] || (documentsWithField[field] = 0)\n    documentsWithField[field] += 1\n\n    accumulator[field] || (accumulator[field] = 0)\n    accumulator[field] += this.fieldLengths[fieldRef]\n  }\n\n  var fields = Object.keys(this._fields)\n\n  for (var i = 0; i < fields.length; i++) {\n    var fieldName = fields[i]\n    accumulator[fieldName] = accumulator[fieldName] / documentsWithField[fieldName]\n  }\n\n  this.averageFieldLength = accumulator\n}\n\n/**\n * Builds a vector space model of every document using lunr.Vector\n *\n * @private\n */\nlunr.Builder.prototype.createFieldVectors = function () {\n  var fieldVectors = {},\n      fieldRefs = Object.keys(this.fieldTermFrequencies),\n      fieldRefsLength = fieldRefs.length,\n      termIdfCache = Object.create(null)\n\n  for (var i = 0; i < fieldRefsLength; i++) {\n    var fieldRef = lunr.FieldRef.fromString(fieldRefs[i]),\n        fieldName = fieldRef.fieldName,\n        fieldLength = this.fieldLengths[fieldRef],\n        fieldVector = new lunr.Vector,\n        termFrequencies = this.fieldTermFrequencies[fieldRef],\n        terms = Object.keys(termFrequencies),\n        termsLength = terms.length\n\n\n    var fieldBoost = this._fields[fieldName].boost || 1,\n        docBoost = this._documents[fieldRef.docRef].boost || 1\n\n    for (var j = 0; j < termsLength; j++) {\n      var term = terms[j],\n          tf = termFrequencies[term],\n          termIndex = this.invertedIndex[term]._index,\n          idf, score, scoreWithPrecision\n\n      if (termIdfCache[term] === undefined) {\n        idf = lunr.idf(this.invertedIndex[term], this.documentCount)\n        termIdfCache[term] = idf\n      } else {\n        idf = termIdfCache[term]\n      }\n\n      score = idf * ((this._k1 + 1) * tf) / (this._k1 * (1 - this._b + this._b * (fieldLength / this.averageFieldLength[fieldName])) + tf)\n      score *= fieldBoost\n      score *= docBoost\n      scoreWithPrecision = Math.round(score * 1000) / 1000\n      // Converts 1.23456789 to 1.234.\n      // Reducing the precision so that the vectors take up less\n      // space when serialised. Doing it now so that they behave\n      // the same before and after serialisation. Also, this is\n      // the fastest approach to reducing a number's precision in\n      // JavaScript.\n\n      fieldVector.insert(termIndex, scoreWithPrecision)\n    }\n\n    fieldVectors[fieldRef] = fieldVector\n  }\n\n  this.fieldVectors = fieldVectors\n}\n\n/**\n * Creates a token set of all tokens in the index using lunr.TokenSet\n *\n * @private\n */\nlunr.Builder.prototype.createTokenSet = function () {\n  this.tokenSet = lunr.TokenSet.fromArray(\n    Object.keys(this.invertedIndex).sort()\n  )\n}\n\n/**\n * Builds the index, creating an instance of lunr.Index.\n *\n * This completes the indexing process and should only be called\n * once all documents have been added to the index.\n *\n * @returns {lunr.Index}\n */\nlunr.Builder.prototype.build = function () {\n  this.calculateAverageFieldLengths()\n  this.createFieldVectors()\n  this.createTokenSet()\n\n  return new lunr.Index({\n    invertedIndex: this.invertedIndex,\n    fieldVectors: this.fieldVectors,\n    tokenSet: this.tokenSet,\n    fields: Object.keys(this._fields),\n    pipeline: this.searchPipeline\n  })\n}\n\n/**\n * Applies a plugin to the index builder.\n *\n * A plugin is a function that is called with the index builder as its context.\n * Plugins can be used to customise or extend the behaviour of the index\n * in some way. A plugin is just a function, that encapsulated the custom\n * behaviour that should be applied when building the index.\n *\n * The plugin function will be called with the index builder as its argument, additional\n * arguments can also be passed when calling use. The function will be called\n * with the index builder as its context.\n *\n * @param {Function} plugin The plugin to apply.\n */\nlunr.Builder.prototype.use = function (fn) {\n  var args = Array.prototype.slice.call(arguments, 1)\n  args.unshift(this)\n  fn.apply(this, args)\n}\n/**\n * Contains and collects metadata about a matching document.\n * A single instance of lunr.MatchData is returned as part of every\n * lunr.Index~Result.\n *\n * @constructor\n * @param {string} term - The term this match data is associated with\n * @param {string} field - The field in which the term was found\n * @param {object} metadata - The metadata recorded about this term in this field\n * @property {object} metadata - A cloned collection of metadata associated with this document.\n * @see {@link lunr.Index~Result}\n */\nlunr.MatchData = function (term, field, metadata) {\n  var clonedMetadata = Object.create(null),\n      metadataKeys = Object.keys(metadata || {})\n\n  // Cloning the metadata to prevent the original\n  // being mutated during match data combination.\n  // Metadata is kept in an array within the inverted\n  // index so cloning the data can be done with\n  // Array#slice\n  for (var i = 0; i < metadataKeys.length; i++) {\n    var key = metadataKeys[i]\n    clonedMetadata[key] = metadata[key].slice()\n  }\n\n  this.metadata = Object.create(null)\n\n  if (term !== undefined) {\n    this.metadata[term] = Object.create(null)\n    this.metadata[term][field] = clonedMetadata\n  }\n}\n\n/**\n * An instance of lunr.MatchData will be created for every term that matches a\n * document. However only one instance is required in a lunr.Index~Result. This\n * method combines metadata from another instance of lunr.MatchData with this\n * objects metadata.\n *\n * @param {lunr.MatchData} otherMatchData - Another instance of match data to merge with this one.\n * @see {@link lunr.Index~Result}\n */\nlunr.MatchData.prototype.combine = function (otherMatchData) {\n  var terms = Object.keys(otherMatchData.metadata)\n\n  for (var i = 0; i < terms.length; i++) {\n    var term = terms[i],\n        fields = Object.keys(otherMatchData.metadata[term])\n\n    if (this.metadata[term] == undefined) {\n      this.metadata[term] = Object.create(null)\n    }\n\n    for (var j = 0; j < fields.length; j++) {\n      var field = fields[j],\n          keys = Object.keys(otherMatchData.metadata[term][field])\n\n      if (this.metadata[term][field] == undefined) {\n        this.metadata[term][field] = Object.create(null)\n      }\n\n      for (var k = 0; k < keys.length; k++) {\n        var key = keys[k]\n\n        if (this.metadata[term][field][key] == undefined) {\n          this.metadata[term][field][key] = otherMatchData.metadata[term][field][key]\n        } else {\n          this.metadata[term][field][key] = this.metadata[term][field][key].concat(otherMatchData.metadata[term][field][key])\n        }\n\n      }\n    }\n  }\n}\n\n/**\n * Add metadata for a term/field pair to this instance of match data.\n *\n * @param {string} term - The term this match data is associated with\n * @param {string} field - The field in which the term was found\n * @param {object} metadata - The metadata recorded about this term in this field\n */\nlunr.MatchData.prototype.add = function (term, field, metadata) {\n  if (!(term in this.metadata)) {\n    this.metadata[term] = Object.create(null)\n    this.metadata[term][field] = metadata\n    return\n  }\n\n  if (!(field in this.metadata[term])) {\n    this.metadata[term][field] = metadata\n    return\n  }\n\n  var metadataKeys = Object.keys(metadata)\n\n  for (var i = 0; i < metadataKeys.length; i++) {\n    var key = metadataKeys[i]\n\n    if (key in this.metadata[term][field]) {\n      this.metadata[term][field][key] = this.metadata[term][field][key].concat(metadata[key])\n    } else {\n      this.metadata[term][field][key] = metadata[key]\n    }\n  }\n}\n/**\n * A lunr.Query provides a programmatic way of defining queries to be performed\n * against a {@link lunr.Index}.\n *\n * Prefer constructing a lunr.Query using the {@link lunr.Index#query} method\n * so the query object is pre-initialized with the right index fields.\n *\n * @constructor\n * @property {lunr.Query~Clause[]} clauses - An array of query clauses.\n * @property {string[]} allFields - An array of all available fields in a lunr.Index.\n */\nlunr.Query = function (allFields) {\n  this.clauses = []\n  this.allFields = allFields\n}\n\n/**\n * Constants for indicating what kind of automatic wildcard insertion will be used when constructing a query clause.\n *\n * This allows wildcards to be added to the beginning and end of a term without having to manually do any string\n * concatenation.\n *\n * The wildcard constants can be bitwise combined to select both leading and trailing wildcards.\n *\n * @constant\n * @default\n * @property {number} wildcard.NONE - The term will have no wildcards inserted, this is the default behaviour\n * @property {number} wildcard.LEADING - Prepend the term with a wildcard, unless a leading wildcard already exists\n * @property {number} wildcard.TRAILING - Append a wildcard to the term, unless a trailing wildcard already exists\n * @see lunr.Query~Clause\n * @see lunr.Query#clause\n * @see lunr.Query#term\n * @example <caption>query term with trailing wildcard</caption>\n * query.term('foo', { wildcard: lunr.Query.wildcard.TRAILING })\n * @example <caption>query term with leading and trailing wildcard</caption>\n * query.term('foo', {\n *   wildcard: lunr.Query.wildcard.LEADING | lunr.Query.wildcard.TRAILING\n * })\n */\n\nlunr.Query.wildcard = new String (\"*\")\nlunr.Query.wildcard.NONE = 0\nlunr.Query.wildcard.LEADING = 1\nlunr.Query.wildcard.TRAILING = 2\n\n/**\n * Constants for indicating what kind of presence a term must have in matching documents.\n *\n * @constant\n * @enum {number}\n * @see lunr.Query~Clause\n * @see lunr.Query#clause\n * @see lunr.Query#term\n * @example <caption>query term with required presence</caption>\n * query.term('foo', { presence: lunr.Query.presence.REQUIRED })\n */\nlunr.Query.presence = {\n  /**\n   * Term's presence in a document is optional, this is the default value.\n   */\n  OPTIONAL: 1,\n\n  /**\n   * Term's presence in a document is required, documents that do not contain\n   * this term will not be returned.\n   */\n  REQUIRED: 2,\n\n  /**\n   * Term's presence in a document is prohibited, documents that do contain\n   * this term will not be returned.\n   */\n  PROHIBITED: 3\n}\n\n/**\n * A single clause in a {@link lunr.Query} contains a term and details on how to\n * match that term against a {@link lunr.Index}.\n *\n * @typedef {Object} lunr.Query~Clause\n * @property {string[]} fields - The fields in an index this clause should be matched against.\n * @property {number} [boost=1] - Any boost that should be applied when matching this clause.\n * @property {number} [editDistance] - Whether the term should have fuzzy matching applied, and how fuzzy the match should be.\n * @property {boolean} [usePipeline] - Whether the term should be passed through the search pipeline.\n * @property {number} [wildcard=lunr.Query.wildcard.NONE] - Whether the term should have wildcards appended or prepended.\n * @property {number} [presence=lunr.Query.presence.OPTIONAL] - The terms presence in any matching documents.\n */\n\n/**\n * Adds a {@link lunr.Query~Clause} to this query.\n *\n * Unless the clause contains the fields to be matched all fields will be matched. In addition\n * a default boost of 1 is applied to the clause.\n *\n * @param {lunr.Query~Clause} clause - The clause to add to this query.\n * @see lunr.Query~Clause\n * @returns {lunr.Query}\n */\nlunr.Query.prototype.clause = function (clause) {\n  if (!('fields' in clause)) {\n    clause.fields = this.allFields\n  }\n\n  if (!('boost' in clause)) {\n    clause.boost = 1\n  }\n\n  if (!('usePipeline' in clause)) {\n    clause.usePipeline = true\n  }\n\n  if (!('wildcard' in clause)) {\n    clause.wildcard = lunr.Query.wildcard.NONE\n  }\n\n  if ((clause.wildcard & lunr.Query.wildcard.LEADING) && (clause.term.charAt(0) != lunr.Query.wildcard)) {\n    clause.term = \"*\" + clause.term\n  }\n\n  if ((clause.wildcard & lunr.Query.wildcard.TRAILING) && (clause.term.slice(-1) != lunr.Query.wildcard)) {\n    clause.term = \"\" + clause.term + \"*\"\n  }\n\n  if (!('presence' in clause)) {\n    clause.presence = lunr.Query.presence.OPTIONAL\n  }\n\n  this.clauses.push(clause)\n\n  return this\n}\n\n/**\n * A negated query is one in which every clause has a presence of\n * prohibited. These queries require some special processing to return\n * the expected results.\n *\n * @returns boolean\n */\nlunr.Query.prototype.isNegated = function () {\n  for (var i = 0; i < this.clauses.length; i++) {\n    if (this.clauses[i].presence != lunr.Query.presence.PROHIBITED) {\n      return false\n    }\n  }\n\n  return true\n}\n\n/**\n * Adds a term to the current query, under the covers this will create a {@link lunr.Query~Clause}\n * to the list of clauses that make up this query.\n *\n * The term is used as is, i.e. no tokenization will be performed by this method. Instead conversion\n * to a token or token-like string should be done before calling this method.\n *\n * The term will be converted to a string by calling `toString`. Multiple terms can be passed as an\n * array, each term in the array will share the same options.\n *\n * @param {object|object[]} term - The term(s) to add to the query.\n * @param {object} [options] - Any additional properties to add to the query clause.\n * @returns {lunr.Query}\n * @see lunr.Query#clause\n * @see lunr.Query~Clause\n * @example <caption>adding a single term to a query</caption>\n * query.term(\"foo\")\n * @example <caption>adding a single term to a query and specifying search fields, term boost and automatic trailing wildcard</caption>\n * query.term(\"foo\", {\n *   fields: [\"title\"],\n *   boost: 10,\n *   wildcard: lunr.Query.wildcard.TRAILING\n * })\n * @example <caption>using lunr.tokenizer to convert a string to tokens before using them as terms</caption>\n * query.term(lunr.tokenizer(\"foo bar\"))\n */\nlunr.Query.prototype.term = function (term, options) {\n  if (Array.isArray(term)) {\n    term.forEach(function (t) { this.term(t, lunr.utils.clone(options)) }, this)\n    return this\n  }\n\n  var clause = options || {}\n  clause.term = term.toString()\n\n  this.clause(clause)\n\n  return this\n}\nlunr.QueryParseError = function (message, start, end) {\n  this.name = \"QueryParseError\"\n  this.message = message\n  this.start = start\n  this.end = end\n}\n\nlunr.QueryParseError.prototype = new Error\nlunr.QueryLexer = function (str) {\n  this.lexemes = []\n  this.str = str\n  this.length = str.length\n  this.pos = 0\n  this.start = 0\n  this.escapeCharPositions = []\n}\n\nlunr.QueryLexer.prototype.run = function () {\n  var state = lunr.QueryLexer.lexText\n\n  while (state) {\n    state = state(this)\n  }\n}\n\nlunr.QueryLexer.prototype.sliceString = function () {\n  var subSlices = [],\n      sliceStart = this.start,\n      sliceEnd = this.pos\n\n  for (var i = 0; i < this.escapeCharPositions.length; i++) {\n    sliceEnd = this.escapeCharPositions[i]\n    subSlices.push(this.str.slice(sliceStart, sliceEnd))\n    sliceStart = sliceEnd + 1\n  }\n\n  subSlices.push(this.str.slice(sliceStart, this.pos))\n  this.escapeCharPositions.length = 0\n\n  return subSlices.join('')\n}\n\nlunr.QueryLexer.prototype.emit = function (type) {\n  this.lexemes.push({\n    type: type,\n    str: this.sliceString(),\n    start: this.start,\n    end: this.pos\n  })\n\n  this.start = this.pos\n}\n\nlunr.QueryLexer.prototype.escapeCharacter = function () {\n  this.escapeCharPositions.push(this.pos - 1)\n  this.pos += 1\n}\n\nlunr.QueryLexer.prototype.next = function () {\n  if (this.pos >= this.length) {\n    return lunr.QueryLexer.EOS\n  }\n\n  var char = this.str.charAt(this.pos)\n  this.pos += 1\n  return char\n}\n\nlunr.QueryLexer.prototype.width = function () {\n  return this.pos - this.start\n}\n\nlunr.QueryLexer.prototype.ignore = function () {\n  if (this.start == this.pos) {\n    this.pos += 1\n  }\n\n  this.start = this.pos\n}\n\nlunr.QueryLexer.prototype.backup = function () {\n  this.pos -= 1\n}\n\nlunr.QueryLexer.prototype.acceptDigitRun = function () {\n  var char, charCode\n\n  do {\n    char = this.next()\n    charCode = char.charCodeAt(0)\n  } while (charCode > 47 && charCode < 58)\n\n  if (char != lunr.QueryLexer.EOS) {\n    this.backup()\n  }\n}\n\nlunr.QueryLexer.prototype.more = function () {\n  return this.pos < this.length\n}\n\nlunr.QueryLexer.EOS = 'EOS'\nlunr.QueryLexer.FIELD = 'FIELD'\nlunr.QueryLexer.TERM = 'TERM'\nlunr.QueryLexer.EDIT_DISTANCE = 'EDIT_DISTANCE'\nlunr.QueryLexer.BOOST = 'BOOST'\nlunr.QueryLexer.PRESENCE = 'PRESENCE'\n\nlunr.QueryLexer.lexField = function (lexer) {\n  lexer.backup()\n  lexer.emit(lunr.QueryLexer.FIELD)\n  lexer.ignore()\n  return lunr.QueryLexer.lexText\n}\n\nlunr.QueryLexer.lexTerm = function (lexer) {\n  if (lexer.width() > 1) {\n    lexer.backup()\n    lexer.emit(lunr.QueryLexer.TERM)\n  }\n\n  lexer.ignore()\n\n  if (lexer.more()) {\n    return lunr.QueryLexer.lexText\n  }\n}\n\nlunr.QueryLexer.lexEditDistance = function (lexer) {\n  lexer.ignore()\n  lexer.acceptDigitRun()\n  lexer.emit(lunr.QueryLexer.EDIT_DISTANCE)\n  return lunr.QueryLexer.lexText\n}\n\nlunr.QueryLexer.lexBoost = function (lexer) {\n  lexer.ignore()\n  lexer.acceptDigitRun()\n  lexer.emit(lunr.QueryLexer.BOOST)\n  return lunr.QueryLexer.lexText\n}\n\nlunr.QueryLexer.lexEOS = function (lexer) {\n  if (lexer.width() > 0) {\n    lexer.emit(lunr.QueryLexer.TERM)\n  }\n}\n\n// This matches the separator used when tokenising fields\n// within a document. These should match otherwise it is\n// not possible to search for some tokens within a document.\n//\n// It is possible for the user to change the separator on the\n// tokenizer so it _might_ clash with any other of the special\n// characters already used within the search string, e.g. :.\n//\n// This means that it is possible to change the separator in\n// such a way that makes some words unsearchable using a search\n// string.\nlunr.QueryLexer.termSeparator = lunr.tokenizer.separator\n\nlunr.QueryLexer.lexText = function (lexer) {\n  while (true) {\n    var char = lexer.next()\n\n    if (char == lunr.QueryLexer.EOS) {\n      return lunr.QueryLexer.lexEOS\n    }\n\n    // Escape character is '\\'\n    if (char.charCodeAt(0) == 92) {\n      lexer.escapeCharacter()\n      continue\n    }\n\n    if (char == \":\") {\n      return lunr.QueryLexer.lexField\n    }\n\n    if (char == \"~\") {\n      lexer.backup()\n      if (lexer.width() > 0) {\n        lexer.emit(lunr.QueryLexer.TERM)\n      }\n      return lunr.QueryLexer.lexEditDistance\n    }\n\n    if (char == \"^\") {\n      lexer.backup()\n      if (lexer.width() > 0) {\n        lexer.emit(lunr.QueryLexer.TERM)\n      }\n      return lunr.QueryLexer.lexBoost\n    }\n\n    // \"+\" indicates term presence is required\n    // checking for length to ensure that only\n    // leading \"+\" are considered\n    if (char == \"+\" && lexer.width() === 1) {\n      lexer.emit(lunr.QueryLexer.PRESENCE)\n      return lunr.QueryLexer.lexText\n    }\n\n    // \"-\" indicates term presence is prohibited\n    // checking for length to ensure that only\n    // leading \"-\" are considered\n    if (char == \"-\" && lexer.width() === 1) {\n      lexer.emit(lunr.QueryLexer.PRESENCE)\n      return lunr.QueryLexer.lexText\n    }\n\n    if (char.match(lunr.QueryLexer.termSeparator)) {\n      return lunr.QueryLexer.lexTerm\n    }\n  }\n}\n\nlunr.QueryParser = function (str, query) {\n  this.lexer = new lunr.QueryLexer (str)\n  this.query = query\n  this.currentClause = {}\n  this.lexemeIdx = 0\n}\n\nlunr.QueryParser.prototype.parse = function () {\n  this.lexer.run()\n  this.lexemes = this.lexer.lexemes\n\n  var state = lunr.QueryParser.parseClause\n\n  while (state) {\n    state = state(this)\n  }\n\n  return this.query\n}\n\nlunr.QueryParser.prototype.peekLexeme = function () {\n  return this.lexemes[this.lexemeIdx]\n}\n\nlunr.QueryParser.prototype.consumeLexeme = function () {\n  var lexeme = this.peekLexeme()\n  this.lexemeIdx += 1\n  return lexeme\n}\n\nlunr.QueryParser.prototype.nextClause = function () {\n  var completedClause = this.currentClause\n  this.query.clause(completedClause)\n  this.currentClause = {}\n}\n\nlunr.QueryParser.parseClause = function (parser) {\n  var lexeme = parser.peekLexeme()\n\n  if (lexeme == undefined) {\n    return\n  }\n\n  switch (lexeme.type) {\n    case lunr.QueryLexer.PRESENCE:\n      return lunr.QueryParser.parsePresence\n    case lunr.QueryLexer.FIELD:\n      return lunr.QueryParser.parseField\n    case lunr.QueryLexer.TERM:\n      return lunr.QueryParser.parseTerm\n    default:\n      var errorMessage = \"expected either a field or a term, found \" + lexeme.type\n\n      if (lexeme.str.length >= 1) {\n        errorMessage += \" with value '\" + lexeme.str + \"'\"\n      }\n\n      throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n  }\n}\n\nlunr.QueryParser.parsePresence = function (parser) {\n  var lexeme = parser.consumeLexeme()\n\n  if (lexeme == undefined) {\n    return\n  }\n\n  switch (lexeme.str) {\n    case \"-\":\n      parser.currentClause.presence = lunr.Query.presence.PROHIBITED\n      break\n    case \"+\":\n      parser.currentClause.presence = lunr.Query.presence.REQUIRED\n      break\n    default:\n      var errorMessage = \"unrecognised presence operator'\" + lexeme.str + \"'\"\n      throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n  }\n\n  var nextLexeme = parser.peekLexeme()\n\n  if (nextLexeme == undefined) {\n    var errorMessage = \"expecting term or field, found nothing\"\n    throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n  }\n\n  switch (nextLexeme.type) {\n    case lunr.QueryLexer.FIELD:\n      return lunr.QueryParser.parseField\n    case lunr.QueryLexer.TERM:\n      return lunr.QueryParser.parseTerm\n    default:\n      var errorMessage = \"expecting term or field, found '\" + nextLexeme.type + \"'\"\n      throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n  }\n}\n\nlunr.QueryParser.parseField = function (parser) {\n  var lexeme = parser.consumeLexeme()\n\n  if (lexeme == undefined) {\n    return\n  }\n\n  if (parser.query.allFields.indexOf(lexeme.str) == -1) {\n    var possibleFields = parser.query.allFields.map(function (f) { return \"'\" + f + \"'\" }).join(', '),\n        errorMessage = \"unrecognised field '\" + lexeme.str + \"', possible fields: \" + possibleFields\n\n    throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n  }\n\n  parser.currentClause.fields = [lexeme.str]\n\n  var nextLexeme = parser.peekLexeme()\n\n  if (nextLexeme == undefined) {\n    var errorMessage = \"expecting term, found nothing\"\n    throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n  }\n\n  switch (nextLexeme.type) {\n    case lunr.QueryLexer.TERM:\n      return lunr.QueryParser.parseTerm\n    default:\n      var errorMessage = \"expecting term, found '\" + nextLexeme.type + \"'\"\n      throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n  }\n}\n\nlunr.QueryParser.parseTerm = function (parser) {\n  var lexeme = parser.consumeLexeme()\n\n  if (lexeme == undefined) {\n    return\n  }\n\n  parser.currentClause.term = lexeme.str.toLowerCase()\n\n  if (lexeme.str.indexOf(\"*\") != -1) {\n    parser.currentClause.usePipeline = false\n  }\n\n  var nextLexeme = parser.peekLexeme()\n\n  if (nextLexeme == undefined) {\n    parser.nextClause()\n    return\n  }\n\n  switch (nextLexeme.type) {\n    case lunr.QueryLexer.TERM:\n      parser.nextClause()\n      return lunr.QueryParser.parseTerm\n    case lunr.QueryLexer.FIELD:\n      parser.nextClause()\n      return lunr.QueryParser.parseField\n    case lunr.QueryLexer.EDIT_DISTANCE:\n      return lunr.QueryParser.parseEditDistance\n    case lunr.QueryLexer.BOOST:\n      return lunr.QueryParser.parseBoost\n    case lunr.QueryLexer.PRESENCE:\n      parser.nextClause()\n      return lunr.QueryParser.parsePresence\n    default:\n      var errorMessage = \"Unexpected lexeme type '\" + nextLexeme.type + \"'\"\n      throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n  }\n}\n\nlunr.QueryParser.parseEditDistance = function (parser) {\n  var lexeme = parser.consumeLexeme()\n\n  if (lexeme == undefined) {\n    return\n  }\n\n  var editDistance = parseInt(lexeme.str, 10)\n\n  if (isNaN(editDistance)) {\n    var errorMessage = \"edit distance must be numeric\"\n    throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n  }\n\n  parser.currentClause.editDistance = editDistance\n\n  var nextLexeme = parser.peekLexeme()\n\n  if (nextLexeme == undefined) {\n    parser.nextClause()\n    return\n  }\n\n  switch (nextLexeme.type) {\n    case lunr.QueryLexer.TERM:\n      parser.nextClause()\n      return lunr.QueryParser.parseTerm\n    case lunr.QueryLexer.FIELD:\n      parser.nextClause()\n      return lunr.QueryParser.parseField\n    case lunr.QueryLexer.EDIT_DISTANCE:\n      return lunr.QueryParser.parseEditDistance\n    case lunr.QueryLexer.BOOST:\n      return lunr.QueryParser.parseBoost\n    case lunr.QueryLexer.PRESENCE:\n      parser.nextClause()\n      return lunr.QueryParser.parsePresence\n    default:\n      var errorMessage = \"Unexpected lexeme type '\" + nextLexeme.type + \"'\"\n      throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n  }\n}\n\nlunr.QueryParser.parseBoost = function (parser) {\n  var lexeme = parser.consumeLexeme()\n\n  if (lexeme == undefined) {\n    return\n  }\n\n  var boost = parseInt(lexeme.str, 10)\n\n  if (isNaN(boost)) {\n    var errorMessage = \"boost must be numeric\"\n    throw new lunr.QueryParseError (errorMessage, lexeme.start, lexeme.end)\n  }\n\n  parser.currentClause.boost = boost\n\n  var nextLexeme = parser.peekLexeme()\n\n  if (nextLexeme == undefined) {\n    parser.nextClause()\n    return\n  }\n\n  switch (nextLexeme.type) {\n    case lunr.QueryLexer.TERM:\n      parser.nextClause()\n      return lunr.QueryParser.parseTerm\n    case lunr.QueryLexer.FIELD:\n      parser.nextClause()\n      return lunr.QueryParser.parseField\n    case lunr.QueryLexer.EDIT_DISTANCE:\n      return lunr.QueryParser.parseEditDistance\n    case lunr.QueryLexer.BOOST:\n      return lunr.QueryParser.parseBoost\n    case lunr.QueryLexer.PRESENCE:\n      parser.nextClause()\n      return lunr.QueryParser.parsePresence\n    default:\n      var errorMessage = \"Unexpected lexeme type '\" + nextLexeme.type + \"'\"\n      throw new lunr.QueryParseError (errorMessage, nextLexeme.start, nextLexeme.end)\n  }\n}\n\n  /**\n   * export the module via AMD, CommonJS or as a browser global\n   * Export code from https://github.com/umdjs/umd/blob/master/returnExports.js\n   */\n  ;(function (root, factory) {\n    if (true) {\n      // AMD. Register as an anonymous module.\n      !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :\n\t\t\t\t__WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))\n    } else if (typeof exports === 'object') {\n      /**\n       * Node. Does not work with strict CommonJS, but\n       * only CommonJS-like enviroments that support module.exports,\n       * like Node.\n       */\n      module.exports = factory()\n    } else {\n      // Browser globals (root is window)\n      root.lunr = factory()\n    }\n  }(this, function () {\n    /**\n     * Just return a value to define the module export.\n     * This example returns an object, but the module\n     * can return a function as the exported value.\n     */\n    return lunr\n  }))\n})();\n\n\n/***/ }),\n/* 37 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nvar _Position = __webpack_require__(38);\n\nvar _Position2 = _interopRequireDefault(_Position);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/* ----------------------------------------------------------------------------\n * Module\n * ------------------------------------------------------------------------- */\n\nexports.default = {\n  Position: _Position2.default\n}; /*\n    * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n    *\n    * Permission is hereby granted, free of charge, to any person obtaining a copy\n    * of this software and associated documentation files (the \"Software\"), to\n    * deal in the Software without restriction, including without limitation the\n    * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n    * sell copies of the Software, and to permit persons to whom the Software is\n    * furnished to do so, subject to the following conditions:\n    *\n    * The above copyright notice and this permission notice shall be included in\n    * all copies or substantial portions of the Software.\n    *\n    * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n    * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n    * IN THE SOFTWARE.\n    */\n\n/***/ }),\n/* 38 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\nvar Position = function () {\n\n  /**\n   * Set sidebars to locked state and limit height to parent node\n   *\n   * @constructor\n   *\n   * @property {HTMLElement} el_ - Sidebar\n   * @property {HTMLElement} parent_ - Sidebar container\n   * @property {HTMLElement} header_ - Header\n   * @property {number} height_ - Current sidebar height\n   * @property {number} offset_ - Current page y-offset\n   * @property {boolean} pad_ - Pad when header is fixed\n   *\n   * @param {(string|HTMLElement)} el - Selector or HTML element\n   * @param {(string|HTMLElement)} header - Selector or HTML element\n   */\n  function Position(el, header) {\n    _classCallCheck(this, Position);\n\n    var ref = typeof el === \"string\" ? document.querySelector(el) : el;\n    if (!(ref instanceof HTMLElement) || !(ref.parentNode instanceof HTMLElement)) throw new ReferenceError();\n    this.el_ = ref;\n    this.parent_ = ref.parentNode;\n\n    /* Retrieve header */\n    ref = typeof header === \"string\" ? document.querySelector(header) : header;\n    if (!(ref instanceof HTMLElement)) throw new ReferenceError();\n    this.header_ = ref;\n\n    /* Initialize current height and test whether header is fixed */\n    this.height_ = 0;\n    this.pad_ = window.getComputedStyle(this.header_).position === \"fixed\";\n  }\n\n  /**\n   * Initialize sidebar state\n   */\n\n\n  Position.prototype.setup = function setup() {\n    var top = Array.prototype.reduce.call(this.parent_.children, function (offset, child) {\n      return Math.max(offset, child.offsetTop);\n    }, 0);\n\n    /* Set lock offset for element with largest top offset */\n    this.offset_ = top - (this.pad_ ? this.header_.offsetHeight : 0);\n    this.update();\n  };\n\n  /**\n   * Update locked state and height\n   *\n   * The inner height of the window (= the visible area) is the maximum\n   * possible height for the stretching sidebar. This height must be deducted\n   * by the height of the fixed header (56px). Depending on the page y-offset,\n   * the top offset of the sidebar must be taken into account, as well as the\n   * case where the window is scrolled beyond the sidebar container.\n   *\n   * @param {Event?} ev - Event\n   */\n\n\n  Position.prototype.update = function update(ev) {\n    var offset = window.pageYOffset;\n    var visible = window.innerHeight;\n\n    /* Update offset, in case window is resized */\n    if (ev && ev.type === \"resize\") this.setup();\n\n    /* Set bounds of sidebar container - must be calculated on every run, as\n       the height of the content might change due to loading images etc. */\n    var bounds = {\n      top: this.pad_ ? this.header_.offsetHeight : 0,\n      bottom: this.parent_.offsetTop + this.parent_.offsetHeight\n\n      /* Calculate new offset and height */\n    };var height = visible - bounds.top - Math.max(0, this.offset_ - offset) - Math.max(0, offset + visible - bounds.bottom);\n\n    /* If height changed, update element */\n    if (height !== this.height_) this.el_.style.height = (this.height_ = height) + \"px\";\n\n    /* Sidebar should be locked, as we're below parent offset */\n    if (offset >= this.offset_) {\n      if (this.el_.dataset.mdState !== \"lock\") this.el_.dataset.mdState = \"lock\";\n\n      /* Sidebar should be unlocked, if locked */\n    } else if (this.el_.dataset.mdState === \"lock\") {\n      this.el_.dataset.mdState = \"\";\n    }\n  };\n\n  /**\n   * Reset locked state and height\n   */\n\n\n  Position.prototype.reset = function reset() {\n    this.el_.dataset.mdState = \"\";\n    this.el_.style.height = \"\";\n    this.height_ = 0;\n  };\n\n  return Position;\n}();\n\nexports.default = Position;\n\n/***/ }),\n/* 39 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nvar _Adapter = __webpack_require__(40);\n\nvar _Adapter2 = _interopRequireDefault(_Adapter);\n\nvar _Repository = __webpack_require__(44);\n\nvar _Repository2 = _interopRequireDefault(_Repository);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/* ----------------------------------------------------------------------------\n * Module\n * ------------------------------------------------------------------------- */\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nexports.default = {\n  Adapter: _Adapter2.default,\n  Repository: _Repository2.default\n};\n\n/***/ }),\n/* 40 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nvar _GitHub = __webpack_require__(41);\n\nvar _GitHub2 = _interopRequireDefault(_GitHub);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/* ----------------------------------------------------------------------------\n * Module\n * ------------------------------------------------------------------------- */\n\nexports.default = {\n  GitHub: _GitHub2.default\n}; /*\n    * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n    *\n    * Permission is hereby granted, free of charge, to any person obtaining a copy\n    * of this software and associated documentation files (the \"Software\"), to\n    * deal in the Software without restriction, including without limitation the\n    * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n    * sell copies of the Software, and to permit persons to whom the Software is\n    * furnished to do so, subject to the following conditions:\n    *\n    * The above copyright notice and this permission notice shall be included in\n    * all copies or substantial portions of the Software.\n    *\n    * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n    * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n    * IN THE SOFTWARE.\n    */\n\n/***/ }),\n/* 41 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nvar _Abstract2 = __webpack_require__(42);\n\nvar _Abstract3 = _interopRequireDefault(_Abstract2);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * Permission is hereby granted, free of charge, to any person obtaining a copy\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * of this software and associated documentation files (the \"Software\"), to\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * deal in the Software without restriction, including without limitation the\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * sell copies of the Software, and to permit persons to whom the Software is\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * furnished to do so, subject to the following conditions:\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * The above copyright notice and this permission notice shall be included in\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * all copies or substantial portions of the Software.\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                *\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                * IN THE SOFTWARE.\n                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                */\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\nvar GitHub = function (_Abstract) {\n  _inherits(GitHub, _Abstract);\n\n  /**\n   * Retrieve repository information from GitHub\n   *\n   * @constructor\n   *\n   * @property {string} name_ - Name of the repository\n   *\n   * @param {(string|HTMLAnchorElement)} el - Selector or HTML element\n   */\n  function GitHub(el) {\n    _classCallCheck(this, GitHub);\n\n    /* Extract user (and repository name) from URL, as we have to query for all\n       repositories, to omit 404 errors for private repositories */\n    var _this = _possibleConstructorReturn(this, _Abstract.call(this, el));\n\n    var matches = /^.+github\\.com\\/([^/]+)\\/?([^/]+)?.*$/.exec(_this.base_);\n    if (matches && matches.length === 3) {\n      var user = matches[1],\n          name = matches[2];\n\n      /* Initialize base URL and repository name */\n\n      _this.base_ = \"https://api.github.com/users/\" + user + \"/repos\";\n      _this.name_ = name;\n    }\n    return _this;\n  }\n\n  /**\n   * Fetch relevant repository information from GitHub\n   *\n   * @return {Promise<Array<string>>} Promise returning an array of facts\n   */\n\n\n  GitHub.prototype.fetch_ = function fetch_() {\n    var _this2 = this;\n\n    var paginate = function paginate() {\n      var page = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;\n\n      return fetch(_this2.base_ + \"?per_page=30&page=\" + page).then(function (response) {\n        return response.json();\n      }).then(function (data) {\n        if (!(data instanceof Array)) throw new TypeError();\n\n        /* Display number of stars and forks, if repository is given */\n        if (_this2.name_) {\n          var repo = data.find(function (item) {\n            return item.name === _this2.name_;\n          });\n          if (!repo && data.length === 30) return paginate(page + 1);\n\n          /* If we found a repo, extract the facts */\n          return repo ? [_this2.format_(repo.stargazers_count) + \" Stars\", _this2.format_(repo.forks_count) + \" Forks\"] : [];\n\n          /* Display number of repositories, otherwise */\n        } else {\n          return [data.length + \" Repositories\"];\n        }\n      });\n    };\n\n    /* Paginate through repos */\n    return paginate();\n  };\n\n  return GitHub;\n}(_Abstract3.default);\n\nexports.default = GitHub;\n\n/***/ }),\n/* 42 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nvar _jsCookie = __webpack_require__(43);\n\nvar _jsCookie2 = _interopRequireDefault(_jsCookie);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } /*\n                                                                                                                                                           * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n                                                                                                                                                           *\n                                                                                                                                                           * Permission is hereby granted, free of charge, to any person obtaining a copy\n                                                                                                                                                           * of this software and associated documentation files (the \"Software\"), to\n                                                                                                                                                           * deal in the Software without restriction, including without limitation the\n                                                                                                                                                           * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n                                                                                                                                                           * sell copies of the Software, and to permit persons to whom the Software is\n                                                                                                                                                           * furnished to do so, subject to the following conditions:\n                                                                                                                                                           *\n                                                                                                                                                           * The above copyright notice and this permission notice shall be included in\n                                                                                                                                                           * all copies or substantial portions of the Software.\n                                                                                                                                                           *\n                                                                                                                                                           * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n                                                                                                                                                           * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n                                                                                                                                                           * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n                                                                                                                                                           * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n                                                                                                                                                           * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n                                                                                                                                                           * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n                                                                                                                                                           * IN THE SOFTWARE.\n                                                                                                                                                           */\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\nvar Abstract = function () {\n\n  /**\n   * Retrieve repository information\n   *\n   * @constructor\n   *\n   * @property {HTMLAnchorElement} el_ - Link to repository\n   * @property {string} base_ - API base URL\n   * @property {number} salt_ - Unique identifier\n   *\n   * @param {(string|HTMLAnchorElement)} el - Selector or HTML element\n   */\n  function Abstract(el) {\n    _classCallCheck(this, Abstract);\n\n    var ref = typeof el === \"string\" ? document.querySelector(el) : el;\n    if (!(ref instanceof HTMLAnchorElement)) throw new ReferenceError();\n    this.el_ = ref;\n\n    /* Retrieve base URL */\n    this.base_ = this.el_.href;\n    this.salt_ = this.hash_(this.base_);\n  }\n\n  /**\n   * Retrieve data from Cookie or fetch from respective API\n   *\n   * @return {Promise<Array<string>>} Promise that returns an array of facts\n   */\n\n\n  Abstract.prototype.fetch = function fetch() {\n    var _this = this;\n\n    return new Promise(function (resolve) {\n      var cached = _jsCookie2.default.getJSON(_this.salt_ + \".cache-source\");\n      if (typeof cached !== \"undefined\") {\n        resolve(cached);\n\n        /* If the data is not cached in a cookie, invoke fetch and set\n           a cookie that automatically expires in 15 minutes */\n      } else {\n        _this.fetch_().then(function (data) {\n          _jsCookie2.default.set(_this.salt_ + \".cache-source\", data, { expires: 1 / 96 });\n          resolve(data);\n        });\n      }\n    });\n  };\n\n  /**\n   * Abstract private function that fetches relevant repository information\n   *\n   * @abstract\n   */\n\n\n  Abstract.prototype.fetch_ = function fetch_() {\n    throw new Error(\"fetch_(): Not implemented\");\n  };\n\n  /**\n   * Format a number with suffix\n   *\n   * @param {number} number - Number to format\n   * @return {string} Formatted number\n   */\n\n\n  Abstract.prototype.format_ = function format_(number) {\n    if (number > 10000) return (number / 1000).toFixed(0) + \"k\";else if (number > 1000) return (number / 1000).toFixed(1) + \"k\";\n    return \"\" + number;\n  };\n\n  /**\n   * Simple hash function\n   *\n   * Taken from http://stackoverflow.com/a/7616484/1065584\n   *\n   * @param {string} str - Input string\n   * @return {number} Hashed string\n   */\n\n\n  Abstract.prototype.hash_ = function hash_(str) {\n    var hash = 0;\n    if (str.length === 0) return hash;\n    for (var i = 0, len = str.length; i < len; i++) {\n      hash = (hash << 5) - hash + str.charCodeAt(i);\n      hash |= 0; // Convert to 32bit integer\n    }\n    return hash;\n  };\n\n  return Abstract;\n}();\n\nexports.default = Abstract;\n\n/***/ }),\n/* 43 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n * JavaScript Cookie v2.2.0\n * https://github.com/js-cookie/js-cookie\n *\n * Copyright 2006, 2015 Klaus Hartl & Fagner Brack\n * Released under the MIT license\n */\n;(function (factory) {\n\tvar registeredInModuleLoader = false;\n\tif (true) {\n\t\t!(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :\n\t\t\t\t__WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t\tregisteredInModuleLoader = true;\n\t}\n\tif (true) {\n\t\tmodule.exports = factory();\n\t\tregisteredInModuleLoader = true;\n\t}\n\tif (!registeredInModuleLoader) {\n\t\tvar OldCookies = window.Cookies;\n\t\tvar api = window.Cookies = factory();\n\t\tapi.noConflict = function () {\n\t\t\twindow.Cookies = OldCookies;\n\t\t\treturn api;\n\t\t};\n\t}\n}(function () {\n\tfunction extend () {\n\t\tvar i = 0;\n\t\tvar result = {};\n\t\tfor (; i < arguments.length; i++) {\n\t\t\tvar attributes = arguments[ i ];\n\t\t\tfor (var key in attributes) {\n\t\t\t\tresult[key] = attributes[key];\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\tfunction init (converter) {\n\t\tfunction api (key, value, attributes) {\n\t\t\tvar result;\n\t\t\tif (typeof document === 'undefined') {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Write\n\n\t\t\tif (arguments.length > 1) {\n\t\t\t\tattributes = extend({\n\t\t\t\t\tpath: '/'\n\t\t\t\t}, api.defaults, attributes);\n\n\t\t\t\tif (typeof attributes.expires === 'number') {\n\t\t\t\t\tvar expires = new Date();\n\t\t\t\t\texpires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);\n\t\t\t\t\tattributes.expires = expires;\n\t\t\t\t}\n\n\t\t\t\t// We're using \"expires\" because \"max-age\" is not supported by IE\n\t\t\t\tattributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';\n\n\t\t\t\ttry {\n\t\t\t\t\tresult = JSON.stringify(value);\n\t\t\t\t\tif (/^[\\{\\[]/.test(result)) {\n\t\t\t\t\t\tvalue = result;\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {}\n\n\t\t\t\tif (!converter.write) {\n\t\t\t\t\tvalue = encodeURIComponent(String(value))\n\t\t\t\t\t\t.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);\n\t\t\t\t} else {\n\t\t\t\t\tvalue = converter.write(value, key);\n\t\t\t\t}\n\n\t\t\t\tkey = encodeURIComponent(String(key));\n\t\t\t\tkey = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);\n\t\t\t\tkey = key.replace(/[\\(\\)]/g, escape);\n\n\t\t\t\tvar stringifiedAttributes = '';\n\n\t\t\t\tfor (var attributeName in attributes) {\n\t\t\t\t\tif (!attributes[attributeName]) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tstringifiedAttributes += '; ' + attributeName;\n\t\t\t\t\tif (attributes[attributeName] === true) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tstringifiedAttributes += '=' + attributes[attributeName];\n\t\t\t\t}\n\t\t\t\treturn (document.cookie = key + '=' + value + stringifiedAttributes);\n\t\t\t}\n\n\t\t\t// Read\n\n\t\t\tif (!key) {\n\t\t\t\tresult = {};\n\t\t\t}\n\n\t\t\t// To prevent the for loop in the first place assign an empty array\n\t\t\t// in case there are no cookies at all. Also prevents odd result when\n\t\t\t// calling \"get()\"\n\t\t\tvar cookies = document.cookie ? document.cookie.split('; ') : [];\n\t\t\tvar rdecode = /(%[0-9A-Z]{2})+/g;\n\t\t\tvar i = 0;\n\n\t\t\tfor (; i < cookies.length; i++) {\n\t\t\t\tvar parts = cookies[i].split('=');\n\t\t\t\tvar cookie = parts.slice(1).join('=');\n\n\t\t\t\tif (!this.json && cookie.charAt(0) === '\"') {\n\t\t\t\t\tcookie = cookie.slice(1, -1);\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tvar name = parts[0].replace(rdecode, decodeURIComponent);\n\t\t\t\t\tcookie = converter.read ?\n\t\t\t\t\t\tconverter.read(cookie, name) : converter(cookie, name) ||\n\t\t\t\t\t\tcookie.replace(rdecode, decodeURIComponent);\n\n\t\t\t\t\tif (this.json) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tcookie = JSON.parse(cookie);\n\t\t\t\t\t\t} catch (e) {}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (key === name) {\n\t\t\t\t\t\tresult = cookie;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!key) {\n\t\t\t\t\t\tresult[name] = cookie;\n\t\t\t\t\t}\n\t\t\t\t} catch (e) {}\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\n\t\tapi.set = api;\n\t\tapi.get = function (key) {\n\t\t\treturn api.call(api, key);\n\t\t};\n\t\tapi.getJSON = function () {\n\t\t\treturn api.apply({\n\t\t\t\tjson: true\n\t\t\t}, [].slice.call(arguments));\n\t\t};\n\t\tapi.defaults = {};\n\n\t\tapi.remove = function (key, attributes) {\n\t\t\tapi(key, '', extend(attributes, {\n\t\t\t\texpires: -1\n\t\t\t}));\n\t\t};\n\n\t\tapi.withConverter = init;\n\n\t\treturn api;\n\t}\n\n\treturn init(function () {});\n}));\n\n\n/***/ }),\n/* 44 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(JSX) {\n\nexports.__esModule = true;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\nvar Repository = function () {\n\n  /**\n   * Render repository information\n   *\n   * @constructor\n   *\n   * @property {HTMLElement} el_ - Repository information\n   *\n   * @param {(string|HTMLElement)} el - Selector or HTML element\n   */\n  function Repository(el) {\n    _classCallCheck(this, Repository);\n\n    var ref = typeof el === \"string\" ? document.querySelector(el) : el;\n    if (!(ref instanceof HTMLElement)) throw new ReferenceError();\n    this.el_ = ref;\n  }\n\n  /**\n   * Initialize the repository\n   *\n   * @param {Array<string>} facts - Facts to be rendered\n   */\n\n\n  Repository.prototype.initialize = function initialize(facts) {\n    if (facts.length && this.el_.children.length) this.el_.children[this.el_.children.length - 1].appendChild(JSX.createElement(\n      \"ul\",\n      { \"class\": \"md-source__facts\" },\n      facts.map(function (fact) {\n        return JSX.createElement(\n          \"li\",\n          { \"class\": \"md-source__fact\" },\n          fact\n        );\n      })\n    ));\n\n    /* Finish rendering with animation */\n    this.el_.dataset.mdState = \"done\";\n  };\n\n  return Repository;\n}();\n\nexports.default = Repository;\n/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))\n\n/***/ }),\n/* 45 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nvar _Toggle = __webpack_require__(46);\n\nvar _Toggle2 = _interopRequireDefault(_Toggle);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n/* ----------------------------------------------------------------------------\n * Module\n * ------------------------------------------------------------------------- */\n\nexports.default = {\n  Toggle: _Toggle2.default\n}; /*\n    * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n    *\n    * Permission is hereby granted, free of charge, to any person obtaining a copy\n    * of this software and associated documentation files (the \"Software\"), to\n    * deal in the Software without restriction, including without limitation the\n    * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n    * sell copies of the Software, and to permit persons to whom the Software is\n    * furnished to do so, subject to the following conditions:\n    *\n    * The above copyright notice and this permission notice shall be included in\n    * all copies or substantial portions of the Software.\n    *\n    * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n    * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n    * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n    * IN THE SOFTWARE.\n    */\n\n/***/ }),\n/* 46 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nexports.__esModule = true;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/*\n * Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\nvar Toggle = function () {\n\n  /**\n   * Toggle tabs visibility depending on page y-offset\n   *\n   * @constructor\n   *\n   * @property {HTMLElement} el_ - Content container\n   * @property {number} offset_ - Toggle page-y offset\n   * @property {boolean} active_ - Tabs visibility\n   *\n   * @param {(string|HTMLElement)} el - Selector or HTML element\n   */\n  function Toggle(el) {\n    _classCallCheck(this, Toggle);\n\n    var ref = typeof el === \"string\" ? document.querySelector(el) : el;\n    if (!(ref instanceof Node)) throw new ReferenceError();\n    this.el_ = ref;\n\n    /* Initialize offset and state */\n    this.active_ = false;\n  }\n\n  /**\n   * Update visibility\n   */\n\n\n  Toggle.prototype.update = function update() {\n    var active = window.pageYOffset >= this.el_.children[0].offsetTop + (5 - 48); // TODO: quick hack to enable same handling for hero\n    if (active !== this.active_) this.el_.dataset.mdState = (this.active_ = active) ? \"hidden\" : \"\";\n  };\n\n  /**\n   * Reset visibility\n   */\n\n\n  Toggle.prototype.reset = function reset() {\n    this.el_.dataset.mdState = \"\";\n    this.active_ = false;\n  };\n\n  return Toggle;\n}();\n\nexports.default = Toggle;\n\n/***/ })\n/******/ ])));\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgOTkzNzc5YzciLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9wcm92aWRlcnMvanN4LmpzIiwid2VicGFjazovLy8od2VicGFjaykvYnVpbGRpbi9nbG9iYWwuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3VuZmV0Y2gvZGlzdC91bmZldGNoLmVzLmpzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9FdmVudC9MaXN0ZW5lci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2FwcGxpY2F0aW9uLmpzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvaW1hZ2VzL2ljb25zL2JpdGJ1Y2tldC5zdmciLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9pbWFnZXMvaWNvbnMvZ2l0aHViLnN2ZyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL2ltYWdlcy9pY29ucy9naXRsYWIuc3ZnIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvYXBwbGljYXRpb24uc2Nzcz80NzI4Iiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvYXBwbGljYXRpb24tcGFsZXR0ZS5zY3NzPzRjOWYiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2N1c3RvbS1ldmVudC1wb2x5ZmlsbC9wb2x5ZmlsbC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvdW5mZXRjaC9wb2x5ZmlsbC5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvcHJvbWlzZS1wb2x5ZmlsbC9zcmMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3RpbWVycy1icm93c2VyaWZ5L21haW4uanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3NldGltbWVkaWF0ZS9zZXRJbW1lZGlhdGUuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvcHJvbWlzZS1wb2x5ZmlsbC9zcmMvZmluYWxseS5qcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvY2xpcGJvYXJkL2Rpc3QvY2xpcGJvYXJkLmpzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9mYXN0Y2xpY2svbGliL2Zhc3RjbGljay5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL0V2ZW50LmpzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9FdmVudC9NYXRjaE1lZGlhLmpzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9IZWFkZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL0hlYWRlci9TaGFkb3cuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL0hlYWRlci9UaXRsZS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwvTmF2LmpzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9OYXYvQmx1ci5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwvTmF2L0NvbGxhcHNlLmpzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9OYXYvU2Nyb2xsaW5nLmpzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9TZWFyY2guanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL1NlYXJjaC9Mb2NrLmpzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9TZWFyY2gvUmVzdWx0LmpzeCIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvZXNjYXBlLXN0cmluZy1yZWdleHAvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2x1bnIvbHVuci5qcy1leHBvc2VkIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9sdW5yL2x1bnIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL1NpZGViYXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL1NpZGViYXIvUG9zaXRpb24uanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL1NvdXJjZS5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwvU291cmNlL0FkYXB0ZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL1NvdXJjZS9BZGFwdGVyL0dpdEh1Yi5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwvU291cmNlL0FkYXB0ZXIvQWJzdHJhY3QuanMiLCJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2pzLWNvb2tpZS9zcmMvanMuY29va2llLmpzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9Tb3VyY2UvUmVwb3NpdG9yeS5qc3giLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL1RhYnMuanMiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL1RhYnMvVG9nZ2xlLmpzIl0sIm5hbWVzIjpbImNyZWF0ZUVsZW1lbnQiLCJ0YWciLCJwcm9wZXJ0aWVzIiwiZWwiLCJkb2N1bWVudCIsIkFycmF5IiwicHJvdG90eXBlIiwiZm9yRWFjaCIsImNhbGwiLCJPYmplY3QiLCJrZXlzIiwic2V0QXR0cmlidXRlIiwiYXR0ciIsIml0ZXJhdGVDaGlsZE5vZGVzIiwibm9kZXMiLCJub2RlIiwidGV4dENvbnRlbnQiLCJpc0FycmF5IiwiX19odG1sIiwiaW5uZXJIVE1MIiwiTm9kZSIsImFwcGVuZENoaWxkIiwiY2hpbGRyZW4iLCJMaXN0ZW5lciIsImVscyIsImV2ZW50cyIsImhhbmRsZXIiLCJlbHNfIiwic2xpY2UiLCJxdWVyeVNlbGVjdG9yQWxsIiwiY29uY2F0IiwiaGFuZGxlcl8iLCJ1cGRhdGUiLCJldmVudHNfIiwidXBkYXRlXyIsImV2IiwibGlzdGVuIiwiYWRkRXZlbnRMaXN0ZW5lciIsImV2ZW50Iiwic2V0dXAiLCJ1bmxpc3RlbiIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJyZXNldCIsIndpbmRvdyIsIlByb21pc2UiLCJ0cmFuc2xhdGUiLCJtZXRhIiwiZ2V0RWxlbWVudHNCeU5hbWUiLCJrZXkiLCJIVE1MTWV0YUVsZW1lbnQiLCJSZWZlcmVuY2VFcnJvciIsImNvbnRlbnQiLCJpbml0aWFsaXplIiwiY29uZmlnIiwiTWF0ZXJpYWwiLCJFdmVudCIsImJvZHkiLCJIVE1MRWxlbWVudCIsIkZhc3RDbGljayIsImF0dGFjaCIsIk1vZGVybml6ciIsImFkZFRlc3QiLCJuYXZpZ2F0b3IiLCJ1c2VyQWdlbnQiLCJtYXRjaCIsInRhYmxlcyIsIndyYXAiLCJ0YWJsZSIsIm5leHRTaWJsaW5nIiwicGFyZW50Tm9kZSIsImluc2VydEJlZm9yZSIsIkNsaXBib2FyZCIsImlzU3VwcG9ydGVkIiwiYmxvY2tzIiwiYmxvY2siLCJpbmRleCIsImlkIiwiYnV0dG9uIiwicGFyZW50IiwiY29weSIsIm9uIiwibWVzc2FnZSIsImFjdGlvbiIsInRyaWdnZXIiLCJxdWVyeVNlbGVjdG9yIiwiY2xlYXJTZWxlY3Rpb24iLCJkYXRhc2V0IiwibWRUaW1lciIsImNsZWFyVGltZW91dCIsInBhcnNlSW50IiwiY2xhc3NMaXN0IiwiYWRkIiwic2V0VGltZW91dCIsInJlbW92ZSIsInRvU3RyaW5nIiwiZGV0YWlscyIsInN1bW1hcnkiLCJ0YXJnZXQiLCJoYXNBdHRyaWJ1dGUiLCJyZW1vdmVBdHRyaWJ1dGUiLCJsb2NhdGlvbiIsImhhc2giLCJnZXRFbGVtZW50QnlJZCIsInN1YnN0cmluZyIsIkhUTUxEZXRhaWxzRWxlbWVudCIsIm9wZW4iLCJsb2MiLCJpb3MiLCJzY3JvbGxhYmxlIiwiaXRlbSIsInRvcCIsInNjcm9sbFRvcCIsIm9mZnNldEhlaWdodCIsInNjcm9sbEhlaWdodCIsIkhlYWRlciIsIlNoYWRvdyIsIlRpdGxlIiwiVGFicyIsIlRvZ2dsZSIsIk1hdGNoTWVkaWEiLCJTaWRlYmFyIiwiUG9zaXRpb24iLCJOYXYiLCJCbHVyIiwiY29sbGFwc2libGVzIiwiY29sbGFwc2UiLCJwcmV2aW91c0VsZW1lbnRTaWJsaW5nIiwiQ29sbGFwc2UiLCJTY3JvbGxpbmciLCJTZWFyY2giLCJMb2NrIiwiUmVzdWx0IiwiZmV0Y2giLCJ1cmwiLCJiYXNlIiwidmVyc2lvbiIsImNyZWRlbnRpYWxzIiwidGhlbiIsInJlc3BvbnNlIiwianNvbiIsImRhdGEiLCJkb2NzIiwibWFwIiwiZG9jIiwicXVlcnkiLCJIVE1MSW5wdXRFbGVtZW50IiwiZm9jdXMiLCJ0b2dnbGUiLCJjaGVja2VkIiwiZGlzcGF0Y2hFdmVudCIsIkN1c3RvbUV2ZW50IiwibWV0YUtleSIsImN0cmxLZXkiLCJrZXlDb2RlIiwiYWN0aXZlRWxlbWVudCIsInByZXZlbnREZWZhdWx0IiwiSFRNTExpbmtFbGVtZW50IiwiZ2V0QXR0cmlidXRlIiwiYmx1ciIsImluZGV4T2YiLCJsaW5rcyIsImZpbmQiLCJsaW5rIiwibWRTdGF0ZSIsIk1hdGgiLCJtYXgiLCJsZW5ndGgiLCJzdG9wUHJvcGFnYXRpb24iLCJmb3JtIiwibGFiZWxzIiwibGFiZWwiLCJ0YWJJbmRleCIsInJlc29sdmUiLCJIVE1MQW5jaG9yRWxlbWVudCIsIm1kU291cmNlIiwiU291cmNlIiwiQWRhcHRlciIsIkdpdEh1YiIsInNvdXJjZXMiLCJSZXBvc2l0b3J5Iiwic291cmNlIiwiZmFjdHMiLCJhcHAiLCJsaXN0ZW5lciIsIm1xIiwibWF0Y2hlcyIsIm1lZGlhIiwibWF0Y2hNZWRpYSIsImFkZExpc3RlbmVyIiwiaGVhZGVyIiwicmVmIiwiZWxfIiwiaGVhZGVyXyIsImhlaWdodF8iLCJhY3RpdmVfIiwiY3VycmVudCIsInR5cGUiLCJhY3RpdmUiLCJwYWdlWU9mZnNldCIsIkhUTUxIZWFkaW5nRWxlbWVudCIsInN0eWxlIiwid2lkdGgiLCJvZmZzZXRXaWR0aCIsIm9mZnNldFRvcCIsImluZGV4XyIsIm9mZnNldF8iLCJkaXJfIiwiYW5jaG9yc18iLCJyZWR1Y2UiLCJhbmNob3JzIiwib2Zmc2V0IiwiZGlyIiwiaSIsImdldEJvdW5kaW5nQ2xpZW50UmVjdCIsImhlaWdodCIsImRpc3BsYXkiLCJvdmVyZmxvdyIsIm1heEhlaWdodCIsInJlcXVlc3RBbmltYXRpb25GcmFtZSIsImVuZCIsIm1haW4iLCJ3ZWJraXRPdmVyZmxvd1Njcm9sbGluZyIsInRvZ2dsZXMiLCJwYW5lIiwibmV4dEVsZW1lbnRTaWJsaW5nIiwidGFnTmFtZSIsImxvY2tfIiwic2Nyb2xsVG8iLCJlc2NhcGVIVE1MIiwidGV4dCIsImNyZWF0ZVRleHROb2RlIiwiaHRtbCIsInAiLCJ0cnVuY2F0ZSIsInN0cmluZyIsIm4iLCJsaXN0IiwiZGF0YV8iLCJtZXRhXyIsImxpc3RfIiwibWVzc2FnZV8iLCJwbGFjZWhvbGRlciIsIm5vbmUiLCJvbmUiLCJvdGhlciIsInRva2VuaXplciIsImx1bnIiLCJzZXBhcmF0b3IiLCJsYW5nXyIsInNwbGl0IiwiZmlsdGVyIiwiQm9vbGVhbiIsImxhbmciLCJ0cmltIiwiaW5pdCIsImRvY3NfIiwicGF0aCIsInRpdGxlIiwiZ2V0IiwiZG9uZSIsInJlcGxhY2UiLCJfIiwiY2hhciIsInNldCIsIk1hcCIsInN0YWNrXyIsImZpbHRlcnMiLCJ0cmltbWVyIiwic3RvcFdvcmRGaWx0ZXIiLCJwaXBlbGluZSIsInJlc3VsdCIsIm5hbWUiLCJwdXNoIiwidXNlIiwibXVsdGlMYW5ndWFnZSIsImZpZWxkIiwiYm9vc3QiLCJjb250YWluZXIiLCJzcGxpY2UiLCJyZW5kZXIiLCJ2YWx1ZSIsInZhbHVlXyIsImZpcnN0Q2hpbGQiLCJyZW1vdmVDaGlsZCIsInRvTG93ZXJDYXNlIiwidGVybSIsIndpbGRjYXJkIiwiUXVlcnkiLCJUUkFJTElORyIsIml0ZW1zIiwiUmVnRXhwIiwiaGlnaGxpZ2h0IiwidG9rZW4iLCJhcnRpY2xlIiwic2VjdGlvbnMiLCJzZWN0aW9uIiwic2hpZnQiLCJhbmNob3IiLCJldjIiLCJocmVmIiwic2l6ZSIsInBhcmVudF8iLCJwYWRfIiwiZ2V0Q29tcHV0ZWRTdHlsZSIsInBvc2l0aW9uIiwiY2hpbGQiLCJ2aXNpYmxlIiwiaW5uZXJIZWlnaHQiLCJib3VuZHMiLCJib3R0b20iLCJleGVjIiwiYmFzZV8iLCJ1c2VyIiwibmFtZV8iLCJmZXRjaF8iLCJwYWdpbmF0ZSIsInBhZ2UiLCJUeXBlRXJyb3IiLCJyZXBvIiwiZm9ybWF0XyIsInN0YXJnYXplcnNfY291bnQiLCJmb3Jrc19jb3VudCIsIkFic3RyYWN0Iiwic2FsdF8iLCJoYXNoXyIsImNhY2hlZCIsIkNvb2tpZXMiLCJnZXRKU09OIiwiZXhwaXJlcyIsIkVycm9yIiwibnVtYmVyIiwi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O0FBRUEsS0FBSztBQUNMO0FBQ0E7O0FBRUEsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQzs7Ozs7Ozs7QUN6TEQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixzQkFBc0I7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7O0FB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QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQkFBbUIsUUFBUTtBQUMzQjs7QUFFQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUE7QUFDQTtBQUNBOztBQUVBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG1CQUFtQixPQUFPO0FBQzFCOztBQUVBLEtBQUs7QUFDTDs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLFFBQVE7QUFDM0I7O0FBRUEsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVB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RUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE1BQU07QUFDbEIsY0FBYztBQUNkO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxNQUFNO0FBQ2xCLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSw2QkFBNkI7QUFDekMsY0FBYztBQUNkO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBLFlBQVksTUFBTTtBQUNsQixjQUFjO0FBQ2Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUI7QUFDbkI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxNQUFNO0FBQ2xCLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE1BQU07QUFDbEIsY0FBYztBQUNkO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLFFBQVE7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLFFBQVE7QUFDcEIsWUFBWSxPQUFPLFlBQVk7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7OztBQUdBLEtBQUssSUFB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEIsV0FBVyxXQUFXO0FBQ3RCLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFNBQVM7QUFDcEIsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1DQUFtQyxTQUFTO0FBQzVDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixhQUFhO0FBQ2I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEIsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsU0FBUztBQUM1QztBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1CLFNBQVM7QUFDNUI7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGlCQUFpQixTQUFTO0FBQzFCO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxjQUFjO0FBQ3pCLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixVQUFVO0FBQzdCOztBQUVBLHFCQUFxQixVQUFVO0FBQy9COztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLGlEQUFpRDtBQUNsRTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBLDRCQUE0QixpQkFBaUI7QUFDN0M7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOENBQThDLGFBQWE7QUFDM0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsV0FBVyw0QkFBNEI7QUFDdkMsV0FBVyxjQUFjO0FBQ3pCLFdBQVcsU0FBUztBQUNwQixXQUFXLGNBQWM7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCLGNBQWMsT0FBTztBQUNyQixjQUFjLE9BQU87QUFDckIsY0FBYyxlQUFlO0FBQzdCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsNkRBQTZEO0FBQ3JFO0FBQ0E7QUFDQTtBQUNBLFdBQVcsdUJBQXVCO0FBQ2xDLFlBQVkscUJBQXFCO0FBQ2pDLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFdBQVc7QUFDdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsd0JBQXdCO0FBQ25DLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLHdCQUF3QjtBQUN6QztBQUNBOztBQUVBOztBQUVBLGlCQUFpQiwwQkFBMEI7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7O0FBRUEsbUJBQW1CLGtCQUFrQjtBQUNyQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QiwwQkFBMEI7QUFDakQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEscUJBQXFCLDBCQUEwQjtBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSx1QkFBdUIsMEJBQTBCO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtFQUErRSxlQUFlOztBQUU5RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSx5QkFBeUIsaUNBQWlDO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQiwwQkFBMEI7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsd0JBQXdCO0FBQ3pDOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQiw4QkFBOEI7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsOEJBQThCO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCLGFBQWE7QUFDYjtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCLHVCQUF1QjtBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIsOEJBQThCO0FBQy9DO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGlCQUFpQixvQ0FBb0M7QUFDckQ7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLE9BQU87QUFDckIsY0FBYyxTQUFTO0FBQ3ZCLGNBQWMsT0FBTztBQUNyQixjQUFjLE9BQU87QUFDckIsY0FBYyxPQUFPO0FBQ3JCLGNBQWMsZUFBZTtBQUM3QixjQUFjLGNBQWM7QUFDNUIsY0FBYyxjQUFjO0FBQzVCLGNBQWMsT0FBTztBQUNyQixjQUFjLE9BQU87QUFDckIsY0FBYyxPQUFPO0FBQ3JCLGNBQWMsT0FBTztBQUNyQixjQUFjLE1BQU07QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCLGFBQWEsMEJBQTBCO0FBQ3ZDO0FBQ0EsbUJBQW1CO0FBQ25COztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsZUFBZTtBQUMxQixZQUFZLFdBQVc7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsaUJBQWlCLG1CQUFtQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxtQkFBbUIsa0JBQWtCO0FBQ3JDOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsdUJBQXVCLG1CQUFtQjtBQUMxQztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHFCQUFxQixtQ0FBbUM7QUFDeEQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7O0FBRUEsaUJBQWlCLG9CQUFvQjtBQUNyQztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBLGlCQUFpQixtQkFBbUI7QUFDcEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIscUJBQXFCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBLG1CQUFtQixpQkFBaUI7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsU0FBUztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsT0FBTztBQUNsQixjQUFjLE9BQU87QUFDckIsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLCtDQUErQzs7QUFFL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQix5QkFBeUI7QUFDMUM7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxlQUFlO0FBQzFCLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUEsaUJBQWlCLGtCQUFrQjtBQUNuQztBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxtQkFBbUIsbUJBQW1CO0FBQ3RDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHFCQUFxQixpQkFBaUI7QUFDdEM7O0FBRUE7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBLGlCQUFpQix5QkFBeUI7QUFDMUM7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLGlCQUFpQjtBQUMvQjtBQUNBLCtDQUErQyx1QkFBdUI7QUFDdEU7QUFDQTtBQUNBO0FBQ0EsY0FBYyxvQkFBb0I7QUFDbEMsY0FBYyxTQUFTO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLE9BQU87QUFDckIsY0FBYyxPQUFPO0FBQ3JCLGNBQWMsT0FBTztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQix5Q0FBeUM7QUFDL0Q7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLHlDQUF5QztBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx5QkFBeUIsaUJBQWlCO0FBQzFDLDhCQUE4QixpQkFBaUI7QUFDL0M7QUFDQSxhQUFhLE9BQU87QUFDcEIsY0FBYyxTQUFTO0FBQ3ZCLGNBQWMsT0FBTztBQUNyQixjQUFjLE9BQU87QUFDckIsY0FBYyxRQUFRO0FBQ3RCLGNBQWMsT0FBTztBQUNyQixjQUFjLE9BQU87QUFDckI7O0FBRUE7QUFDQSxXQUFXLHdCQUF3QjtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsa0JBQWtCO0FBQzdCO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLHlCQUF5QjtBQUMxQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMEVBQTBFO0FBQzFFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGdCQUFnQjtBQUMzQixXQUFXLE9BQU87QUFDbEIsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLDBDQUEwQztBQUN6RTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxpQkFBaUIscUNBQXFDO0FBQ3REO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0VBQWtFLHVCQUF1QjtBQUN6Rjs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUFNMkwsTUFBTyxPQUFPM0wsRUFBUCxLQUFjLFFBQWYsR0FDUkMsU0FBU2dGLGFBQVQsQ0FBdUJqRixFQUF2QixDQURRLEdBRVJBLEVBRko7QUFHQSxRQUFJLEVBQUUyTCxlQUFlMUssSUFBakIsQ0FBSixFQUNFLE1BQU0sSUFBSThCLGNBQUosRUFBTjtBQUNGLFNBQUs2SSxHQUFMLEdBQVdELEdBQVg7O0FBRUE7QUFDQSxTQUFLSSxPQUFMLEdBQWUsS0FBZjtBQUNEOztBQUVEOzs7OzttQkFHQWxLLE0scUJBQVM7QUFDUCxRQUFNcUssU0FBUzFKLE9BQU8ySixXQUFQLElBQ2IsS0FBS1AsR0FBTCxDQUFTekssUUFBVCxDQUFrQixDQUFsQixFQUFxQnFMLFNBQXJCLElBQWtDLElBQUksRUFBdEMsQ0FERixDQURPLENBRXFFO0FBQzVFLFFBQUlOLFdBQVcsS0FBS0gsT0FBcEIsRUFDRSxLQUFLSCxHQUFMLENBQVN6RyxPQUFULENBQWlCNkUsT0FBakIsR0FBMkIsQ0FBQyxLQUFLK0IsT0FBTCxHQUFlRyxNQUFoQixJQUEwQixRQUExQixHQUFxQyxFQUFoRTtBQUNILEc7O0FBRUQ7Ozs7O21CQUdBM0osSyxvQkFBUTtBQUNOLFNBQUtxSixHQUFMLENBQVN6RyxPQUFULENBQWlCNkUsT0FBakIsR0FBMkIsRUFBM0I7QUFDQSxTQUFLK0IsT0FBTCxHQUFlLEtBQWY7QUFDRCxHOzs7OztrQkF6Q2tCNUUsTSIsImZpbGUiOiJhc3NldHMvamF2YXNjcmlwdHMvYXBwbGljYXRpb24uanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHtcbiBcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gXHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuIFx0XHRcdFx0Z2V0OiBnZXR0ZXJcbiBcdFx0XHR9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSA2KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyB3ZWJwYWNrL2Jvb3RzdHJhcCA5OTM3NzljNyIsIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbiAqIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4gKiByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3JcbiAqIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4gKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTXG4gKiBJTiBUSEUgU09GVFdBUkUuXG4gKi9cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogTW9kdWxlXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVyc2NvcmUtZGFuZ2xlICovXG5leHBvcnQgZGVmYXVsdCAvKiBKU1ggKi8ge1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuYXRpdmUgRE9NIG5vZGUgZnJvbSBKU1gncyBpbnRlcm1lZGlhdGUgcmVwcmVzZW50YXRpb25cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhZyAtIFRhZyBuYW1lXG4gICAqIEBwYXJhbSB7P09iamVjdH0gcHJvcGVydGllcyAtIFByb3BlcnRpZXNcbiAgICogQHBhcmFtIHtBcnJheTxzdHJpbmcgfCBudW1iZXIgfCB7IF9faHRtbDogc3RyaW5nIH0gfCBBcnJheTxIVE1MRWxlbWVudD4+fVxuICAgKiAgIGNoaWxkcmVuIC0gQ2hpbGQgbm9kZXNcbiAgICogQHJldHVybiB7SFRNTEVsZW1lbnR9IE5hdGl2ZSBET00gbm9kZVxuICAgKi9cbiAgY3JlYXRlRWxlbWVudCh0YWcsIHByb3BlcnRpZXMsIC4uLmNoaWxkcmVuKSB7XG4gICAgY29uc3QgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZylcblxuICAgIC8qIFNldCBhbGwgcHJvcGVydGllcyAqL1xuICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgQXJyYXkucHJvdG90eXBlLmZvckVhY2guY2FsbChPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgYXR0ciA9PiB7XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZShhdHRyLCBwcm9wZXJ0aWVzW2F0dHJdKVxuICAgICAgfSlcblxuICAgIC8qIEl0ZXJhdGUgY2hpbGQgbm9kZXMgKi9cbiAgICBjb25zdCBpdGVyYXRlQ2hpbGROb2RlcyA9IG5vZGVzID0+IHtcbiAgICAgIEFycmF5LnByb3RvdHlwZS5mb3JFYWNoLmNhbGwobm9kZXMsIG5vZGUgPT4ge1xuXG4gICAgICAgIC8qIERpcmVjdGx5IGFwcGVuZCB0ZXh0IGNvbnRlbnQgKi9cbiAgICAgICAgaWYgKHR5cGVvZiBub2RlID09PSBcInN0cmluZ1wiIHx8XG4gICAgICAgICAgICB0eXBlb2Ygbm9kZSA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAgIGVsLnRleHRDb250ZW50ICs9IG5vZGVcblxuICAgICAgICAvKiBSZWN1cnNlLCBpZiB3ZSBnb3QgYW4gYXJyYXkgKi9cbiAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KG5vZGUpKSB7XG4gICAgICAgICAgaXRlcmF0ZUNoaWxkTm9kZXMobm9kZSlcblxuICAgICAgICAvKiBBcHBlbmQgcmF3IEhUTUwgKi9cbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygbm9kZS5fX2h0bWwgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICBlbC5pbm5lckhUTUwgKz0gbm9kZS5fX2h0bWxcblxuICAgICAgICAvKiBBcHBlbmQgcmVndWxhciBub2RlcyAqL1xuICAgICAgICB9IGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiBOb2RlKSB7XG4gICAgICAgICAgZWwuYXBwZW5kQ2hpbGQobm9kZSlcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG5cbiAgICAvKiBJdGVyYXRlIGNoaWxkIG5vZGVzIGFuZCByZXR1cm4gZWxlbWVudCAqL1xuICAgIGl0ZXJhdGVDaGlsZE5vZGVzKGNoaWxkcmVuKVxuICAgIHJldHVybiBlbFxuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL3Byb3ZpZGVycy9qc3guanMiLCJ2YXIgZztcclxuXHJcbi8vIFRoaXMgd29ya3MgaW4gbm9uLXN0cmljdCBtb2RlXHJcbmcgPSAoZnVuY3Rpb24oKSB7XHJcblx0cmV0dXJuIHRoaXM7XHJcbn0pKCk7XHJcblxyXG50cnkge1xyXG5cdC8vIFRoaXMgd29ya3MgaWYgZXZhbCBpcyBhbGxvd2VkIChzZWUgQ1NQKVxyXG5cdGcgPSBnIHx8IEZ1bmN0aW9uKFwicmV0dXJuIHRoaXNcIikoKSB8fCAoMSxldmFsKShcInRoaXNcIik7XHJcbn0gY2F0Y2goZSkge1xyXG5cdC8vIFRoaXMgd29ya3MgaWYgdGhlIHdpbmRvdyByZWZlcmVuY2UgaXMgYXZhaWxhYmxlXHJcblx0aWYodHlwZW9mIHdpbmRvdyA9PT0gXCJvYmplY3RcIilcclxuXHRcdGcgPSB3aW5kb3c7XHJcbn1cclxuXHJcbi8vIGcgY2FuIHN0aWxsIGJlIHVuZGVmaW5lZCwgYnV0IG5vdGhpbmcgdG8gZG8gYWJvdXQgaXQuLi5cclxuLy8gV2UgcmV0dXJuIHVuZGVmaW5lZCwgaW5zdGVhZCBvZiBub3RoaW5nIGhlcmUsIHNvIGl0J3NcclxuLy8gZWFzaWVyIHRvIGhhbmRsZSB0aGlzIGNhc2UuIGlmKCFnbG9iYWwpIHsgLi4ufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBnO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAod2VicGFjaykvYnVpbGRpbi9nbG9iYWwuanNcbi8vIG1vZHVsZSBpZCA9IDFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGluZGV4ID0gdHlwZW9mIGZldGNoPT0nZnVuY3Rpb24nID8gZmV0Y2guYmluZCgpIDogZnVuY3Rpb24odXJsLCBvcHRpb25zKSB7XG5cdG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXHRyZXR1cm4gbmV3IFByb21pc2UoIGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcblx0XHR2YXIgcmVxdWVzdCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuXG5cdFx0cmVxdWVzdC5vcGVuKG9wdGlvbnMubWV0aG9kIHx8ICdnZXQnLCB1cmwsIHRydWUpO1xuXG5cdFx0Zm9yICh2YXIgaSBpbiBvcHRpb25zLmhlYWRlcnMpIHtcblx0XHRcdHJlcXVlc3Quc2V0UmVxdWVzdEhlYWRlcihpLCBvcHRpb25zLmhlYWRlcnNbaV0pO1xuXHRcdH1cblxuXHRcdHJlcXVlc3Qud2l0aENyZWRlbnRpYWxzID0gb3B0aW9ucy5jcmVkZW50aWFscz09J2luY2x1ZGUnO1xuXG5cdFx0cmVxdWVzdC5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRyZXNvbHZlKHJlc3BvbnNlKCkpO1xuXHRcdH07XG5cblx0XHRyZXF1ZXN0Lm9uZXJyb3IgPSByZWplY3Q7XG5cblx0XHRyZXF1ZXN0LnNlbmQob3B0aW9ucy5ib2R5IHx8IG51bGwpO1xuXG5cdFx0ZnVuY3Rpb24gcmVzcG9uc2UoKSB7XG5cdFx0XHR2YXIga2V5cyA9IFtdLFxuXHRcdFx0XHRhbGwgPSBbXSxcblx0XHRcdFx0aGVhZGVycyA9IHt9LFxuXHRcdFx0XHRoZWFkZXI7XG5cblx0XHRcdHJlcXVlc3QuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkucmVwbGFjZSgvXiguKj8pOlteXFxTXFxuXSooW1xcc1xcU10qPykkL2dtLCBmdW5jdGlvbiAobSwga2V5LCB2YWx1ZSkge1xuXHRcdFx0XHRrZXlzLnB1c2goa2V5ID0ga2V5LnRvTG93ZXJDYXNlKCkpO1xuXHRcdFx0XHRhbGwucHVzaChba2V5LCB2YWx1ZV0pO1xuXHRcdFx0XHRoZWFkZXIgPSBoZWFkZXJzW2tleV07XG5cdFx0XHRcdGhlYWRlcnNba2V5XSA9IGhlYWRlciA/IChoZWFkZXIgKyBcIixcIiArIHZhbHVlKSA6IHZhbHVlO1xuXHRcdFx0fSk7XG5cblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdG9rOiAocmVxdWVzdC5zdGF0dXMvMTAwfDApID09IDIsXHRcdC8vIDIwMC0yOTlcblx0XHRcdFx0c3RhdHVzOiByZXF1ZXN0LnN0YXR1cyxcblx0XHRcdFx0c3RhdHVzVGV4dDogcmVxdWVzdC5zdGF0dXNUZXh0LFxuXHRcdFx0XHR1cmw6IHJlcXVlc3QucmVzcG9uc2VVUkwsXG5cdFx0XHRcdGNsb25lOiByZXNwb25zZSxcblx0XHRcdFx0dGV4dDogZnVuY3Rpb24gKCkgeyByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlcXVlc3QucmVzcG9uc2VUZXh0KTsgfSxcblx0XHRcdFx0anNvbjogZnVuY3Rpb24gKCkgeyByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlcXVlc3QucmVzcG9uc2VUZXh0KS50aGVuKEpTT04ucGFyc2UpOyB9LFxuXHRcdFx0XHRibG9iOiBmdW5jdGlvbiAoKSB7IHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IEJsb2IoW3JlcXVlc3QucmVzcG9uc2VdKSk7IH0sXG5cdFx0XHRcdGhlYWRlcnM6IHtcblx0XHRcdFx0XHRrZXlzOiBmdW5jdGlvbiAoKSB7IHJldHVybiBrZXlzOyB9LFxuXHRcdFx0XHRcdGVudHJpZXM6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGFsbDsgfSxcblx0XHRcdFx0XHRnZXQ6IGZ1bmN0aW9uIChuKSB7IHJldHVybiBoZWFkZXJzW24udG9Mb3dlckNhc2UoKV07IH0sXG5cdFx0XHRcdFx0aGFzOiBmdW5jdGlvbiAobikgeyByZXR1cm4gbi50b0xvd2VyQ2FzZSgpIGluIGhlYWRlcnM7IH1cblx0XHRcdFx0fVxuXHRcdFx0fTtcblx0XHR9XG5cdH0pO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgaW5kZXg7XG4vLyMgc291cmNlTWFwcGluZ1VSTD11bmZldGNoLmVzLmpzLm1hcFxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvdW5mZXRjaC9kaXN0L3VuZmV0Y2guZXMuanNcbi8vIG1vZHVsZSBpZCA9IDJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLypcbiAqIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuICogZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbiAqIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuICogc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbiAqIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1NcbiAqIElOIFRIRSBTT0ZUV0FSRS5cbiAqL1xuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBDbGFzc1xuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMaXN0ZW5lciB7XG5cbiAgLyoqXG4gICAqIEdlbmVyaWMgZXZlbnQgbGlzdGVuZXJcbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwcm9wZXJ0eSB7KEFycmF5PEV2ZW50VGFyZ2V0Pil9IGVsc18gLSBFdmVudCB0YXJnZXRzXG4gICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBoYW5kbGVyXy0gRXZlbnQgaGFuZGxlcnNcbiAgICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSBldmVudHNfIC0gRXZlbnQgbmFtZXNcbiAgICogQHByb3BlcnR5IHtGdW5jdGlvbn0gdXBkYXRlXyAtIFVwZGF0ZSBoYW5kbGVyXG4gICAqXG4gICAqIEBwYXJhbSB7PyhzdHJpbmd8RXZlbnRUYXJnZXR8Tm9kZUxpc3Q8RXZlbnRUYXJnZXQ+KX0gZWxzIC1cbiAgICogICBTZWxlY3RvciBvciBFdmVudCB0YXJnZXRzXG4gICAqIEBwYXJhbSB7KHN0cmluZ3xBcnJheTxzdHJpbmc+KX0gZXZlbnRzIC0gRXZlbnQgbmFtZXNcbiAgICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gaGFuZGxlciAtIEhhbmRsZXIgdG8gYmUgaW52b2tlZFxuICAgKi9cbiAgY29uc3RydWN0b3IoZWxzLCBldmVudHMsIGhhbmRsZXIpIHtcbiAgICB0aGlzLmVsc18gPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChcbiAgICAgICh0eXBlb2YgZWxzID09PSBcInN0cmluZ1wiKVxuICAgICAgICA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoZWxzKVxuICAgICAgICA6IFtdLmNvbmNhdChlbHMpKVxuXG4gICAgLyogU2V0IGhhbmRsZXIgYXMgZnVuY3Rpb24gb3IgZGlyZWN0bHkgYXMgb2JqZWN0ICovXG4gICAgdGhpcy5oYW5kbGVyXyA9IHR5cGVvZiBoYW5kbGVyID09PSBcImZ1bmN0aW9uXCJcbiAgICAgID8geyB1cGRhdGU6IGhhbmRsZXIgfVxuICAgICAgOiBoYW5kbGVyXG5cbiAgICAvKiBJbml0aWFsaXplIGV2ZW50IG5hbWVzIGFuZCB1cGRhdGUgaGFuZGxlciAqL1xuICAgIHRoaXMuZXZlbnRzXyA9IFtdLmNvbmNhdChldmVudHMpXG4gICAgdGhpcy51cGRhdGVfID0gZXYgPT4gdGhpcy5oYW5kbGVyXy51cGRhdGUoZXYpXG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXIgbGlzdGVuZXIgZm9yIGFsbCByZWxldmFudCBldmVudHNcbiAgICovXG4gIGxpc3RlbigpIHtcbiAgICB0aGlzLmVsc18uZm9yRWFjaChlbCA9PiB7XG4gICAgICB0aGlzLmV2ZW50c18uZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIHRoaXMudXBkYXRlXywgZmFsc2UpXG4gICAgICB9KVxuICAgIH0pXG5cbiAgICAvKiBFeGVjdXRlIHNldHVwIGhhbmRsZXIsIGlmIGltcGxlbWVudGVkICovXG4gICAgaWYgKHR5cGVvZiB0aGlzLmhhbmRsZXJfLnNldHVwID09PSBcImZ1bmN0aW9uXCIpXG4gICAgICB0aGlzLmhhbmRsZXJfLnNldHVwKClcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnJlZ2lzdGVyIGxpc3RlbmVyIGZvciBhbGwgcmVsZXZhbnQgZXZlbnRzXG4gICAqL1xuICB1bmxpc3RlbigpIHtcbiAgICB0aGlzLmVsc18uZm9yRWFjaChlbCA9PiB7XG4gICAgICB0aGlzLmV2ZW50c18uZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIHRoaXMudXBkYXRlXylcbiAgICAgIH0pXG4gICAgfSlcblxuICAgIC8qIEV4ZWN1dGUgcmVzZXQgaGFuZGxlciwgaWYgaW1wbGVtZW50ZWQgKi9cbiAgICBpZiAodHlwZW9mIHRoaXMuaGFuZGxlcl8ucmVzZXQgPT09IFwiZnVuY3Rpb25cIilcbiAgICAgIHRoaXMuaGFuZGxlcl8ucmVzZXQoKVxuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwvRXZlbnQvTGlzdGVuZXIuanMiLCIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4gKiBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuICogcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4gKiBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuICogRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HU1xuICogSU4gVEhFIFNPRlRXQVJFLlxuICovXG5cbmltcG9ydCBcIi4uL2ltYWdlcy9pY29ucy9iaXRidWNrZXQuc3ZnXCJcbmltcG9ydCBcIi4uL2ltYWdlcy9pY29ucy9naXRodWIuc3ZnXCJcbmltcG9ydCBcIi4uL2ltYWdlcy9pY29ucy9naXRsYWIuc3ZnXCJcblxuaW1wb3J0IFwiLi4vc3R5bGVzaGVldHMvYXBwbGljYXRpb24uc2Nzc1wiXG5pbXBvcnQgXCIuLi9zdHlsZXNoZWV0cy9hcHBsaWNhdGlvbi1wYWxldHRlLnNjc3NcIlxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBQb2x5ZmlsbHNcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuaW1wb3J0IFwiY3VzdG9tLWV2ZW50LXBvbHlmaWxsXCJcbmltcG9ydCBcInVuZmV0Y2gvcG9seWZpbGxcIlxuXG5pbXBvcnQgUHJvbWlzZSBmcm9tIFwicHJvbWlzZS1wb2x5ZmlsbFwiXG53aW5kb3cuUHJvbWlzZSA9IHdpbmRvdy5Qcm9taXNlIHx8IFByb21pc2VcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogRGVwZW5kZW5jaWVzXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbmltcG9ydCBDbGlwYm9hcmQgZnJvbSBcImNsaXBib2FyZFwiXG5pbXBvcnQgRmFzdENsaWNrIGZyb20gXCJmYXN0Y2xpY2tcIlxuXG5pbXBvcnQgTWF0ZXJpYWwgZnJvbSBcIi4vY29tcG9uZW50cy9NYXRlcmlhbFwiXG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEZ1bmN0aW9uc1xuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKipcbiAqIFJldHVybiB0aGUgbWV0YSB0YWcgdmFsdWUgZm9yIHRoZSBnaXZlbiBrZXlcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gTWV0YSBuYW1lXG4gKlxuICogQHJldHVybiB7c3RyaW5nfSBNZXRhIGNvbnRlbnQgdmFsdWVcbiAqL1xuY29uc3QgdHJhbnNsYXRlID0ga2V5ID0+IHtcbiAgY29uc3QgbWV0YSA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlOYW1lKGBsYW5nOiR7a2V5fWApWzBdXG4gIGlmICghKG1ldGEgaW5zdGFuY2VvZiBIVE1MTWV0YUVsZW1lbnQpKVxuICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuICByZXR1cm4gbWV0YS5jb250ZW50XG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEFwcGxpY2F0aW9uXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qKlxuICogSW5pdGlhbGl6ZSBNYXRlcmlhbCBmb3IgTWtEb2NzXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYXRpb25cbiAqL1xuZnVuY3Rpb24gaW5pdGlhbGl6ZShjb25maWcpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBmdW5jLXN0eWxlXG5cbiAgLyogSW5pdGlhbGl6ZSBNb2Rlcm5penIgYW5kIEZhc3RDbGljayAqL1xuICBuZXcgTWF0ZXJpYWwuRXZlbnQuTGlzdGVuZXIoZG9jdW1lbnQsIFwiRE9NQ29udGVudExvYWRlZFwiLCAoKSA9PiB7XG4gICAgaWYgKCEoZG9jdW1lbnQuYm9keSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSlcbiAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuXG4gICAgLyogQXR0YWNoIEZhc3RDbGljayB0byBtaXRpZ2F0ZSAzMDBtcyBkZWxheSBvbiB0b3VjaCBkZXZpY2VzICovXG4gICAgRmFzdENsaWNrLmF0dGFjaChkb2N1bWVudC5ib2R5KVxuXG4gICAgLyogVGVzdCBmb3IgaU9TICovXG4gICAgTW9kZXJuaXpyLmFkZFRlc3QoXCJpb3NcIiwgKCkgPT4ge1xuICAgICAgcmV0dXJuICEhbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvKGlQYWR8aVBob25lfGlQb2QpL2cpXG4gICAgfSlcblxuICAgIC8qIFdyYXAgYWxsIGRhdGEgdGFibGVzIGZvciBiZXR0ZXIgb3ZlcmZsb3cgc2Nyb2xsaW5nICovXG4gICAgY29uc3QgdGFibGVzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcInRhYmxlOm5vdChbY2xhc3NdKVwiKSAgICAgICAgICAgICAgLy8gVE9ETzogdGhpcyBpcyBKU1gsIHdlIHNob3VsZCByZW5hbWUgdGhlIGZpbGVcbiAgICBBcnJheS5wcm90b3R5cGUuZm9yRWFjaC5jYWxsKHRhYmxlcywgdGFibGUgPT4ge1xuICAgICAgY29uc3Qgd3JhcCA9IChcbiAgICAgICAgPGRpdiBjbGFzcz1cIm1kLXR5cGVzZXRfX3Njcm9sbHdyYXBcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibWQtdHlwZXNldF9fdGFibGVcIj48L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICApXG4gICAgICBpZiAodGFibGUubmV4dFNpYmxpbmcpIHtcbiAgICAgICAgdGFibGUucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUod3JhcCwgdGFibGUubmV4dFNpYmxpbmcpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0YWJsZS5wYXJlbnROb2RlLmFwcGVuZENoaWxkKHdyYXApXG4gICAgICB9XG4gICAgICB3cmFwLmNoaWxkcmVuWzBdLmFwcGVuZENoaWxkKHRhYmxlKVxuICAgIH0pXG5cbiAgICAvKiBDbGlwYm9hcmQgaW50ZWdyYXRpb24gKi9cbiAgICBpZiAoQ2xpcGJvYXJkLmlzU3VwcG9ydGVkKCkpIHtcbiAgICAgIGNvbnN0IGJsb2NrcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCIuY29kZWhpbGl0ZSA+IHByZSwgcHJlID4gY29kZVwiKVxuICAgICAgQXJyYXkucHJvdG90eXBlLmZvckVhY2guY2FsbChibG9ja3MsIChibG9jaywgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgaWQgPSBgX19jb2RlXyR7aW5kZXh9YFxuXG4gICAgICAgIC8qIENyZWF0ZSBidXR0b24gd2l0aCBtZXNzYWdlIGNvbnRhaW5lciAqL1xuICAgICAgICBjb25zdCBidXR0b24gPSAoXG4gICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cIm1kLWNsaXBib2FyZFwiIHRpdGxlPXt0cmFuc2xhdGUoXCJjbGlwYm9hcmQuY29weVwiKX1cbiAgICAgICAgICAgIGRhdGEtY2xpcGJvYXJkLXRhcmdldD17YCMke2lkfSBwcmUsICMke2lkfSBjb2RlYH0+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1kLWNsaXBib2FyZF9fbWVzc2FnZVwiPjwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgKVxuXG4gICAgICAgIC8qIExpbmsgdG8gYmxvY2sgYW5kIGluc2VydCBidXR0b24gKi9cbiAgICAgICAgY29uc3QgcGFyZW50ID0gYmxvY2sucGFyZW50Tm9kZVxuICAgICAgICBwYXJlbnQuaWQgPSBpZFxuICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKGJ1dHRvbiwgYmxvY2spXG4gICAgICB9KVxuXG4gICAgICAvKiBJbml0aWFsaXplIENsaXBib2FyZCBsaXN0ZW5lciAqL1xuICAgICAgY29uc3QgY29weSA9IG5ldyBDbGlwYm9hcmQoXCIubWQtY2xpcGJvYXJkXCIpXG5cbiAgICAgIC8qIFN1Y2Nlc3MgaGFuZGxlciAqL1xuICAgICAgY29weS5vbihcInN1Y2Nlc3NcIiwgYWN0aW9uID0+IHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IGFjdGlvbi50cmlnZ2VyLnF1ZXJ5U2VsZWN0b3IoXCIubWQtY2xpcGJvYXJkX19tZXNzYWdlXCIpXG4gICAgICAgIGlmICghKG1lc3NhZ2UgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpXG4gICAgICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG5cbiAgICAgICAgLyogQ2xlYXIgc2VsZWN0aW9uIGFuZCByZXNldCBkZWJvdW5jZSBsb2dpYyAqL1xuICAgICAgICBhY3Rpb24uY2xlYXJTZWxlY3Rpb24oKVxuICAgICAgICBpZiAobWVzc2FnZS5kYXRhc2V0Lm1kVGltZXIpXG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHBhcnNlSW50KG1lc3NhZ2UuZGF0YXNldC5tZFRpbWVyLCAxMCkpXG5cbiAgICAgICAgLyogU2V0IG1lc3NhZ2UgaW5kaWNhdGluZyBzdWNjZXNzIGFuZCBzaG93IGl0ICovXG4gICAgICAgIG1lc3NhZ2UuY2xhc3NMaXN0LmFkZChcIm1kLWNsaXBib2FyZF9fbWVzc2FnZS0tYWN0aXZlXCIpXG4gICAgICAgIG1lc3NhZ2UuaW5uZXJIVE1MID0gdHJhbnNsYXRlKFwiY2xpcGJvYXJkLmNvcGllZFwiKVxuXG4gICAgICAgIC8qIEhpZGUgbWVzc2FnZSBhZnRlciB0d28gc2Vjb25kcyAqL1xuICAgICAgICBtZXNzYWdlLmRhdGFzZXQubWRUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIG1lc3NhZ2UuY2xhc3NMaXN0LnJlbW92ZShcIm1kLWNsaXBib2FyZF9fbWVzc2FnZS0tYWN0aXZlXCIpXG4gICAgICAgICAgbWVzc2FnZS5kYXRhc2V0Lm1kVGltZXIgPSBcIlwiXG4gICAgICAgIH0sIDIwMDApLnRvU3RyaW5nKClcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgLyogUG9seWZpbGwgZGV0YWlscy9zdW1tYXJ5IGZ1bmN0aW9uYWxpdHkgKi9cbiAgICBpZiAoIU1vZGVybml6ci5kZXRhaWxzKSB7XG4gICAgICBjb25zdCBibG9ja3MgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiZGV0YWlscyA+IHN1bW1hcnlcIilcbiAgICAgIEFycmF5LnByb3RvdHlwZS5mb3JFYWNoLmNhbGwoYmxvY2tzLCBzdW1tYXJ5ID0+IHtcbiAgICAgICAgc3VtbWFyeS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgZXYgPT4ge1xuICAgICAgICAgIGNvbnN0IGRldGFpbHMgPSBldi50YXJnZXQucGFyZW50Tm9kZVxuICAgICAgICAgIGlmIChkZXRhaWxzLmhhc0F0dHJpYnV0ZShcIm9wZW5cIikpIHtcbiAgICAgICAgICAgIGRldGFpbHMucmVtb3ZlQXR0cmlidXRlKFwib3BlblwiKVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkZXRhaWxzLnNldEF0dHJpYnV0ZShcIm9wZW5cIiwgXCJcIilcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9KVxuICAgIH1cblxuICAgIC8qIE9wZW4gZGV0YWlscyBhZnRlciBhbmNob3IganVtcCAqL1xuICAgIGNvbnN0IGRldGFpbHMgPSAoKSA9PiB7XG4gICAgICBpZiAoZG9jdW1lbnQubG9jYXRpb24uaGFzaCkge1xuICAgICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGRvY3VtZW50LmxvY2F0aW9uLmhhc2guc3Vic3RyaW5nKDEpKVxuICAgICAgICBpZiAoIWVsKVxuICAgICAgICAgIHJldHVyblxuXG4gICAgICAgIC8qIFdhbGsgdXAgYXMgbG9uZyBhcyB3ZSdyZSBub3QgaW4gYSBkZXRhaWxzIHRhZyAqL1xuICAgICAgICBsZXQgcGFyZW50ID0gZWwucGFyZW50Tm9kZVxuICAgICAgICB3aGlsZSAocGFyZW50ICYmICEocGFyZW50IGluc3RhbmNlb2YgSFRNTERldGFpbHNFbGVtZW50KSlcbiAgICAgICAgICBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZVxuXG4gICAgICAgIC8qIElmIHRoZXJlJ3MgYSBkZXRhaWxzIHRhZywgb3BlbiBpdCAqL1xuICAgICAgICBpZiAocGFyZW50ICYmICFwYXJlbnQub3Blbikge1xuICAgICAgICAgIHBhcmVudC5vcGVuID0gdHJ1ZVxuXG4gICAgICAgICAgLyogRm9yY2UgcmVsb2FkLCBzbyB0aGUgdmlld3BvcnQgcmVwb3NpdGlvbnMgKi9cbiAgICAgICAgICBjb25zdCBsb2MgPSBsb2NhdGlvbi5oYXNoXG4gICAgICAgICAgbG9jYXRpb24uaGFzaCA9IFwiIFwiXG4gICAgICAgICAgbG9jYXRpb24uaGFzaCA9IGxvY1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiaGFzaGNoYW5nZVwiLCBkZXRhaWxzKVxuICAgIGRldGFpbHMoKVxuXG4gICAgLyogRm9yY2UgMXB4IHNjcm9sbCBvZmZzZXQgdG8gdHJpZ2dlciBvdmVyZmxvdyBzY3JvbGxpbmcgKi9cbiAgICBpZiAoTW9kZXJuaXpyLmlvcykge1xuICAgICAgY29uc3Qgc2Nyb2xsYWJsZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1tZC1zY3JvbGxmaXhdXCIpXG4gICAgICBBcnJheS5wcm90b3R5cGUuZm9yRWFjaC5jYWxsKHNjcm9sbGFibGUsIGl0ZW0gPT4ge1xuICAgICAgICBpdGVtLmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaHN0YXJ0XCIsICgpID0+IHtcbiAgICAgICAgICBjb25zdCB0b3AgPSBpdGVtLnNjcm9sbFRvcFxuXG4gICAgICAgICAgLyogV2UncmUgYXQgdGhlIHRvcCBvZiB0aGUgY29udGFpbmVyICovXG4gICAgICAgICAgaWYgKHRvcCA9PT0gMCkge1xuICAgICAgICAgICAgaXRlbS5zY3JvbGxUb3AgPSAxXG5cbiAgICAgICAgICAgIC8qIFdlJ3JlIGF0IHRoZSBib3R0b20gb2YgdGhlIGNvbnRhaW5lciAqL1xuICAgICAgICAgIH0gZWxzZSBpZiAodG9wICsgaXRlbS5vZmZzZXRIZWlnaHQgPT09IGl0ZW0uc2Nyb2xsSGVpZ2h0KSB7XG4gICAgICAgICAgICBpdGVtLnNjcm9sbFRvcCA9IHRvcCAtIDFcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9KVxuICAgIH1cbiAgfSkubGlzdGVuKClcblxuICAvKiBDb21wb25lbnQ6IGhlYWRlciBzaGFkb3cgdG9nZ2xlICovXG4gIG5ldyBNYXRlcmlhbC5FdmVudC5MaXN0ZW5lcih3aW5kb3csIFtcbiAgICBcInNjcm9sbFwiLCBcInJlc2l6ZVwiLCBcIm9yaWVudGF0aW9uY2hhbmdlXCJcbiAgXSwgbmV3IE1hdGVyaWFsLkhlYWRlci5TaGFkb3coXG4gICAgXCJbZGF0YS1tZC1jb21wb25lbnQ9Y29udGFpbmVyXVwiLFxuICAgIFwiW2RhdGEtbWQtY29tcG9uZW50PWhlYWRlcl1cIilcbiAgKS5saXN0ZW4oKVxuXG4gIC8qIENvbXBvbmVudDogaGVhZGVyIHRpdGxlIHRvZ2dsZSAqL1xuICBuZXcgTWF0ZXJpYWwuRXZlbnQuTGlzdGVuZXIod2luZG93LCBbXG4gICAgXCJzY3JvbGxcIiwgXCJyZXNpemVcIiwgXCJvcmllbnRhdGlvbmNoYW5nZVwiXG4gIF0sIG5ldyBNYXRlcmlhbC5IZWFkZXIuVGl0bGUoXG4gICAgXCJbZGF0YS1tZC1jb21wb25lbnQ9dGl0bGVdXCIsXG4gICAgXCIubWQtdHlwZXNldCBoMVwiKVxuICApLmxpc3RlbigpXG5cbiAgLyogQ29tcG9uZW50OiBoZXJvIHZpc2liaWxpdHkgdG9nZ2xlICovXG4gIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtbWQtY29tcG9uZW50PWhlcm9dXCIpKVxuICAgIG5ldyBNYXRlcmlhbC5FdmVudC5MaXN0ZW5lcih3aW5kb3csIFtcbiAgICAgIFwic2Nyb2xsXCIsIFwicmVzaXplXCIsIFwib3JpZW50YXRpb25jaGFuZ2VcIlxuICAgIF0sIG5ldyBNYXRlcmlhbC5UYWJzLlRvZ2dsZShcIltkYXRhLW1kLWNvbXBvbmVudD1oZXJvXVwiKSkubGlzdGVuKClcblxuICAvKiBDb21wb25lbnQ6IHRhYnMgdmlzaWJpbGl0eSB0b2dnbGUgKi9cbiAgaWYgKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1tZC1jb21wb25lbnQ9dGFic11cIikpXG4gICAgbmV3IE1hdGVyaWFsLkV2ZW50Lkxpc3RlbmVyKHdpbmRvdywgW1xuICAgICAgXCJzY3JvbGxcIiwgXCJyZXNpemVcIiwgXCJvcmllbnRhdGlvbmNoYW5nZVwiXG4gICAgXSwgbmV3IE1hdGVyaWFsLlRhYnMuVG9nZ2xlKFwiW2RhdGEtbWQtY29tcG9uZW50PXRhYnNdXCIpKS5saXN0ZW4oKVxuXG4gIC8qIENvbXBvbmVudDogc2lkZWJhciB3aXRoIG5hdmlnYXRpb24gKi9cbiAgbmV3IE1hdGVyaWFsLkV2ZW50Lk1hdGNoTWVkaWEoXCIobWluLXdpZHRoOiAxMjIwcHgpXCIsXG4gICAgbmV3IE1hdGVyaWFsLkV2ZW50Lkxpc3RlbmVyKHdpbmRvdywgW1xuICAgICAgXCJzY3JvbGxcIiwgXCJyZXNpemVcIiwgXCJvcmllbnRhdGlvbmNoYW5nZVwiXG4gICAgXSwgbmV3IE1hdGVyaWFsLlNpZGViYXIuUG9zaXRpb24oXG4gICAgICBcIltkYXRhLW1kLWNvbXBvbmVudD1uYXZpZ2F0aW9uXVwiLFxuICAgICAgXCJbZGF0YS1tZC1jb21wb25lbnQ9aGVhZGVyXVwiKSkpXG5cbiAgLyogQ29tcG9uZW50OiBzaWRlYmFyIHdpdGggdGFibGUgb2YgY29udGVudHMgKG1pc3Npbmcgb24gNDA0IHBhZ2UpICovXG4gIGlmIChkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtbWQtY29tcG9uZW50PXRvY11cIikpXG4gICAgbmV3IE1hdGVyaWFsLkV2ZW50Lk1hdGNoTWVkaWEoXCIobWluLXdpZHRoOiA5NjBweClcIixcbiAgICAgIG5ldyBNYXRlcmlhbC5FdmVudC5MaXN0ZW5lcih3aW5kb3csIFtcbiAgICAgICAgXCJzY3JvbGxcIiwgXCJyZXNpemVcIiwgXCJvcmllbnRhdGlvbmNoYW5nZVwiXG4gICAgICBdLCBuZXcgTWF0ZXJpYWwuU2lkZWJhci5Qb3NpdGlvbihcbiAgICAgICAgXCJbZGF0YS1tZC1jb21wb25lbnQ9dG9jXVwiLFxuICAgICAgICBcIltkYXRhLW1kLWNvbXBvbmVudD1oZWFkZXJdXCIpKSlcblxuICAvKiBDb21wb25lbnQ6IGxpbmsgYmx1cnJpbmcgZm9yIHRhYmxlIG9mIGNvbnRlbnRzICovXG4gIG5ldyBNYXRlcmlhbC5FdmVudC5NYXRjaE1lZGlhKFwiKG1pbi13aWR0aDogOTYwcHgpXCIsXG4gICAgbmV3IE1hdGVyaWFsLkV2ZW50Lkxpc3RlbmVyKHdpbmRvdywgXCJzY3JvbGxcIixcbiAgICAgIG5ldyBNYXRlcmlhbC5OYXYuQmx1cihcIltkYXRhLW1kLWNvbXBvbmVudD10b2NdIFtocmVmXVwiKSkpXG5cbiAgLyogQ29tcG9uZW50OiBjb2xsYXBzaWJsZSBlbGVtZW50cyBmb3IgbmF2aWdhdGlvbiAqL1xuICBjb25zdCBjb2xsYXBzaWJsZXMgPVxuICAgIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1tZC1jb21wb25lbnQ9Y29sbGFwc2libGVdXCIpXG4gIEFycmF5LnByb3RvdHlwZS5mb3JFYWNoLmNhbGwoY29sbGFwc2libGVzLCBjb2xsYXBzZSA9PiB7XG4gICAgbmV3IE1hdGVyaWFsLkV2ZW50Lk1hdGNoTWVkaWEoXCIobWluLXdpZHRoOiAxMjIwcHgpXCIsXG4gICAgICBuZXcgTWF0ZXJpYWwuRXZlbnQuTGlzdGVuZXIoY29sbGFwc2UucHJldmlvdXNFbGVtZW50U2libGluZywgXCJjbGlja1wiLFxuICAgICAgICBuZXcgTWF0ZXJpYWwuTmF2LkNvbGxhcHNlKGNvbGxhcHNlKSkpXG4gIH0pXG5cbiAgLyogQ29tcG9uZW50OiBhY3RpdmUgcGFuZSBtb25pdG9yIGZvciBpT1Mgc2Nyb2xsaW5nIGZpeGVzICovXG4gIG5ldyBNYXRlcmlhbC5FdmVudC5NYXRjaE1lZGlhKFwiKG1heC13aWR0aDogMTIxOXB4KVwiLFxuICAgIG5ldyBNYXRlcmlhbC5FdmVudC5MaXN0ZW5lcihcbiAgICAgIFwiW2RhdGEtbWQtY29tcG9uZW50PW5hdmlnYXRpb25dIFtkYXRhLW1kLXRvZ2dsZV1cIiwgXCJjaGFuZ2VcIixcbiAgICAgIG5ldyBNYXRlcmlhbC5OYXYuU2Nyb2xsaW5nKFwiW2RhdGEtbWQtY29tcG9uZW50PW5hdmlnYXRpb25dIG5hdlwiKSkpXG5cbiAgLyogSW5pdGlhbGl6ZSBzZWFyY2gsIGlmIGF2YWlsYWJsZSAqL1xuICBpZiAoZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIltkYXRhLW1kLWNvbXBvbmVudD1zZWFyY2hdXCIpKSB7XG5cbiAgICAvKiBDb21wb25lbnQ6IHNlYXJjaCBib2R5IGxvY2sgZm9yIG1vYmlsZSAqL1xuICAgIG5ldyBNYXRlcmlhbC5FdmVudC5NYXRjaE1lZGlhKFwiKG1heC13aWR0aDogOTU5cHgpXCIsXG4gICAgICBuZXcgTWF0ZXJpYWwuRXZlbnQuTGlzdGVuZXIoXCJbZGF0YS1tZC10b2dnbGU9c2VhcmNoXVwiLCBcImNoYW5nZVwiLFxuICAgICAgICBuZXcgTWF0ZXJpYWwuU2VhcmNoLkxvY2soXCJbZGF0YS1tZC10b2dnbGU9c2VhcmNoXVwiKSkpXG5cbiAgICAvKiBDb21wb25lbnQ6IHNlYXJjaCByZXN1bHRzICovXG4gICAgbmV3IE1hdGVyaWFsLkV2ZW50Lkxpc3RlbmVyKFwiW2RhdGEtbWQtY29tcG9uZW50PXF1ZXJ5XVwiLCBbXG4gICAgICBcImZvY3VzXCIsIFwia2V5dXBcIiwgXCJjaGFuZ2VcIlxuICAgIF0sIG5ldyBNYXRlcmlhbC5TZWFyY2guUmVzdWx0KFwiW2RhdGEtbWQtY29tcG9uZW50PXJlc3VsdF1cIiwgKCkgPT4ge1xuICAgICAgcmV0dXJuIGZldGNoKGAke2NvbmZpZy51cmwuYmFzZX0vJHtcbiAgICAgICAgY29uZmlnLnZlcnNpb24gPCBcIjAuMTdcIiA/IFwibWtkb2NzXCIgOiBcInNlYXJjaFwiXG4gICAgICB9L3NlYXJjaF9pbmRleC5qc29uYCwge1xuICAgICAgICBjcmVkZW50aWFsczogXCJzYW1lLW9yaWdpblwiXG4gICAgICB9KS50aGVuKHJlc3BvbnNlID0+IHJlc3BvbnNlLmpzb24oKSlcbiAgICAgICAgLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGRhdGEuZG9jcy5tYXAoZG9jID0+IHtcbiAgICAgICAgICAgIGRvYy5sb2NhdGlvbiA9IGAke2NvbmZpZy51cmwuYmFzZX0vJHtkb2MubG9jYXRpb259YFxuICAgICAgICAgICAgcmV0dXJuIGRvY1xuICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgfSkpLmxpc3RlbigpXG5cbiAgICAvKiBMaXN0ZW5lcjogZm9jdXMgaW5wdXQgYWZ0ZXIgZm9ybSByZXNldCAqL1xuICAgIG5ldyBNYXRlcmlhbC5FdmVudC5MaXN0ZW5lcihcIltkYXRhLW1kLWNvbXBvbmVudD1yZXNldF1cIiwgXCJjbGlja1wiLCAoKSA9PiB7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgY29uc3QgcXVlcnkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtbWQtY29tcG9uZW50PXF1ZXJ5XVwiKVxuICAgICAgICBpZiAoIShxdWVyeSBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQpKVxuICAgICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuICAgICAgICBxdWVyeS5mb2N1cygpXG4gICAgICB9LCAxMClcbiAgICB9KS5saXN0ZW4oKVxuXG4gICAgLyogTGlzdGVuZXI6IGZvY3VzIGlucHV0IGFmdGVyIG9wZW5pbmcgc2VhcmNoICovXG4gICAgbmV3IE1hdGVyaWFsLkV2ZW50Lkxpc3RlbmVyKFwiW2RhdGEtbWQtdG9nZ2xlPXNlYXJjaF1cIiwgXCJjaGFuZ2VcIiwgZXYgPT4ge1xuICAgICAgc2V0VGltZW91dCh0b2dnbGUgPT4ge1xuICAgICAgICBpZiAoISh0b2dnbGUgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50KSlcbiAgICAgICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3JcbiAgICAgICAgaWYgKHRvZ2dsZS5jaGVja2VkKSB7XG4gICAgICAgICAgY29uc3QgcXVlcnkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtbWQtY29tcG9uZW50PXF1ZXJ5XVwiKVxuICAgICAgICAgIGlmICghKHF1ZXJ5IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3JcbiAgICAgICAgICBxdWVyeS5mb2N1cygpXG4gICAgICAgIH1cbiAgICAgIH0sIDQwMCwgZXYudGFyZ2V0KVxuICAgIH0pLmxpc3RlbigpXG5cbiAgICAvKiBMaXN0ZW5lcjogb3BlbiBzZWFyY2ggb24gZm9jdXMgKi9cbiAgICBuZXcgTWF0ZXJpYWwuRXZlbnQuTWF0Y2hNZWRpYShcIihtaW4td2lkdGg6IDk2MHB4KVwiLFxuICAgICAgbmV3IE1hdGVyaWFsLkV2ZW50Lkxpc3RlbmVyKFwiW2RhdGEtbWQtY29tcG9uZW50PXF1ZXJ5XVwiLCBcImZvY3VzXCIsICgpID0+IHtcbiAgICAgICAgY29uc3QgdG9nZ2xlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIltkYXRhLW1kLXRvZ2dsZT1zZWFyY2hdXCIpXG4gICAgICAgIGlmICghKHRvZ2dsZSBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQpKVxuICAgICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuICAgICAgICBpZiAoIXRvZ2dsZS5jaGVja2VkKSB7XG4gICAgICAgICAgdG9nZ2xlLmNoZWNrZWQgPSB0cnVlXG4gICAgICAgICAgdG9nZ2xlLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KFwiY2hhbmdlXCIpKVxuICAgICAgICB9XG4gICAgICB9KSlcblxuICAgIC8qIExpc3RlbmVyOiBrZXlib2FyZCBoYW5kbGVycyAqLyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29tcGxleGl0eVxuICAgIG5ldyBNYXRlcmlhbC5FdmVudC5MaXN0ZW5lcih3aW5kb3csIFwia2V5ZG93blwiLCBldiA9PiB7ICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETzogc3BsaXQgdXAgaW50byBjb21wb25lbnQgdG8gcmVkdWNlIGNvbXBsZXhpdHlcbiAgICAgIGNvbnN0IHRvZ2dsZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1tZC10b2dnbGU9c2VhcmNoXVwiKVxuICAgICAgaWYgKCEodG9nZ2xlIGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkpXG4gICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuICAgICAgY29uc3QgcXVlcnkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtbWQtY29tcG9uZW50PXF1ZXJ5XVwiKVxuICAgICAgaWYgKCEocXVlcnkgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50KSlcbiAgICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG5cbiAgICAgIC8qIEFib3J0IGlmIG1ldGEga2V5IChtYWNPUykgb3IgY3RybCBrZXkgKFdpbmRvd3MpIGlzIHByZXNzZWQgKi9cbiAgICAgIGlmIChldi5tZXRhS2V5IHx8IGV2LmN0cmxLZXkpXG4gICAgICAgIHJldHVyblxuXG4gICAgICAvKiBTZWFyY2ggaXMgb3BlbiAqL1xuICAgICAgaWYgKHRvZ2dsZS5jaGVja2VkKSB7XG5cbiAgICAgICAgLyogRW50ZXI6IHByZXZlbnQgZm9ybSBzdWJtaXNzaW9uICovXG4gICAgICAgIGlmIChldi5rZXlDb2RlID09PSAxMykge1xuICAgICAgICAgIGlmIChxdWVyeSA9PT0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCkge1xuICAgICAgICAgICAgZXYucHJldmVudERlZmF1bHQoKVxuXG4gICAgICAgICAgICAvKiBHbyB0byBjdXJyZW50IGFjdGl2ZS9mb2N1c2VkIGxpbmsgKi9cbiAgICAgICAgICAgIGNvbnN0IGZvY3VzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICAgICAgICAgXCJbZGF0YS1tZC1jb21wb25lbnQ9c2VhcmNoXSBbaHJlZl1bZGF0YS1tZC1zdGF0ZT1hY3RpdmVdXCIpXG4gICAgICAgICAgICBpZiAoZm9jdXMgaW5zdGFuY2VvZiBIVE1MTGlua0VsZW1lbnQpIHtcbiAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uID0gZm9jdXMuZ2V0QXR0cmlidXRlKFwiaHJlZlwiKVxuXG4gICAgICAgICAgICAgIC8qIENsb3NlIHNlYXJjaCAqL1xuICAgICAgICAgICAgICB0b2dnbGUuY2hlY2tlZCA9IGZhbHNlXG4gICAgICAgICAgICAgIHRvZ2dsZS5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudChcImNoYW5nZVwiKSlcbiAgICAgICAgICAgICAgcXVlcnkuYmx1cigpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgIC8qIEVzY2FwZSBvciBUYWI6IGNsb3NlIHNlYXJjaCAqL1xuICAgICAgICB9IGVsc2UgaWYgKGV2LmtleUNvZGUgPT09IDkgfHwgZXYua2V5Q29kZSA9PT0gMjcpIHtcbiAgICAgICAgICB0b2dnbGUuY2hlY2tlZCA9IGZhbHNlXG4gICAgICAgICAgdG9nZ2xlLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KFwiY2hhbmdlXCIpKVxuICAgICAgICAgIHF1ZXJ5LmJsdXIoKVxuXG4gICAgICAgIC8qIEhvcml6b250YWwgYXJyb3dzIGFuZCBiYWNrc3BhY2U6IGZvY3VzIGlucHV0ICovXG4gICAgICAgIH0gZWxzZSBpZiAoWzgsIDM3LCAzOV0uaW5kZXhPZihldi5rZXlDb2RlKSAhPT0gLTEpIHtcbiAgICAgICAgICBpZiAocXVlcnkgIT09IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpXG4gICAgICAgICAgICBxdWVyeS5mb2N1cygpXG5cbiAgICAgICAgLyogVmVydGljYWwgYXJyb3dzOiBzZWxlY3QgcHJldmlvdXMgb3IgbmV4dCBzZWFyY2ggcmVzdWx0ICovXG4gICAgICAgIH0gZWxzZSBpZiAoWzM4LCA0MF0uaW5kZXhPZihldi5rZXlDb2RlKSAhPT0gLTEpIHtcbiAgICAgICAgICBjb25zdCBrZXkgPSBldi5rZXlDb2RlXG5cbiAgICAgICAgICAvKiBSZXRyaWV2ZSBhbGwgcmVzdWx0cyAqL1xuICAgICAgICAgIGNvbnN0IGxpbmtzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoXG4gICAgICAgICAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICAgICAgICBcIltkYXRhLW1kLWNvbXBvbmVudD1xdWVyeV0sIFtkYXRhLW1kLWNvbXBvbmVudD1zZWFyY2hdIFtocmVmXVwiKSlcblxuICAgICAgICAgIC8qIFJldHJpZXZlIGN1cnJlbnQgYWN0aXZlL2ZvY3VzZWQgcmVzdWx0ICovXG4gICAgICAgICAgY29uc3QgZm9jdXMgPSBsaW5rcy5maW5kKGxpbmsgPT4ge1xuICAgICAgICAgICAgaWYgKCEobGluayBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSlcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG4gICAgICAgICAgICByZXR1cm4gbGluay5kYXRhc2V0Lm1kU3RhdGUgPT09IFwiYWN0aXZlXCJcbiAgICAgICAgICB9KVxuICAgICAgICAgIGlmIChmb2N1cylcbiAgICAgICAgICAgIGZvY3VzLmRhdGFzZXQubWRTdGF0ZSA9IFwiXCJcblxuICAgICAgICAgIC8qIENhbGN1bGF0ZSBpbmRleCBkZXBlbmRpbmcgb24gZGlyZWN0aW9uLCBhZGQgbGVuZ3RoIHRvIGZvcm0gcmluZyAqL1xuICAgICAgICAgIGNvbnN0IGluZGV4ID0gTWF0aC5tYXgoMCwgKFxuICAgICAgICAgICAgbGlua3MuaW5kZXhPZihmb2N1cykgKyBsaW5rcy5sZW5ndGggKyAoa2V5ID09PSAzOCA/IC0xIDogKzEpXG4gICAgICAgICAgKSAlIGxpbmtzLmxlbmd0aClcblxuICAgICAgICAgIC8qIFNldCBhY3RpdmUgc3RhdGUgYW5kIGZvY3VzICovXG4gICAgICAgICAgaWYgKGxpbmtzW2luZGV4XSkge1xuICAgICAgICAgICAgbGlua3NbaW5kZXhdLmRhdGFzZXQubWRTdGF0ZSA9IFwiYWN0aXZlXCJcbiAgICAgICAgICAgIGxpbmtzW2luZGV4XS5mb2N1cygpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLyogUHJldmVudCBzY3JvbGxpbmcgb2YgcGFnZSAqL1xuICAgICAgICAgIGV2LnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKVxuXG4gICAgICAgICAgLyogUmV0dXJuIGZhbHNlIHByZXZlbnRzIHRoZSBjdXJzb3IgcG9zaXRpb24gZnJvbSBjaGFuZ2luZyAqL1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgIC8qIFNlYXJjaCBpcyBjbG9zZWQgYW5kIHdlJ3JlIG5vdCBpbnNpZGUgYSBmb3JtICovXG4gICAgICB9IGVsc2UgaWYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgJiYgIWRvY3VtZW50LmFjdGl2ZUVsZW1lbnQuZm9ybSkge1xuXG4gICAgICAgIC8qIEYvUzogT3BlbiBzZWFyY2ggaWYgbm90IGluIGlucHV0IGZpZWxkICovXG4gICAgICAgIGlmIChldi5rZXlDb2RlID09PSA3MCB8fCBldi5rZXlDb2RlID09PSA4Mykge1xuICAgICAgICAgIHF1ZXJ5LmZvY3VzKClcbiAgICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KS5saXN0ZW4oKVxuXG4gICAgLyogTGlzdGVuZXI6IGZvY3VzIHF1ZXJ5IGlmIGluIHNlYXJjaCBpcyBvcGVuIGFuZCBjaGFyYWN0ZXIgaXMgdHlwZWQgKi9cbiAgICBuZXcgTWF0ZXJpYWwuRXZlbnQuTGlzdGVuZXIod2luZG93LCBcImtleXByZXNzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHRvZ2dsZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1tZC10b2dnbGU9c2VhcmNoXVwiKVxuICAgICAgaWYgKCEodG9nZ2xlIGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkpXG4gICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuICAgICAgaWYgKHRvZ2dsZS5jaGVja2VkKSB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIltkYXRhLW1kLWNvbXBvbmVudD1xdWVyeV1cIilcbiAgICAgICAgaWYgKCEocXVlcnkgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50KSlcbiAgICAgICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3JcbiAgICAgICAgaWYgKHF1ZXJ5ICE9PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50KVxuICAgICAgICAgIHF1ZXJ5LmZvY3VzKClcbiAgICAgIH1cbiAgICB9KS5saXN0ZW4oKVxuICB9XG5cbiAgLyogTGlzdGVuZXI6IGhhbmRsZSB0YWJiaW5nIGNvbnRleHQgZm9yIGJldHRlciBhY2Nlc3NpYmlsaXR5ICovXG4gIG5ldyBNYXRlcmlhbC5FdmVudC5MaXN0ZW5lcihkb2N1bWVudC5ib2R5LCBcImtleWRvd25cIiwgZXYgPT4ge1xuICAgIGlmIChldi5rZXlDb2RlID09PSA5KSB7XG4gICAgICBjb25zdCBsYWJlbHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgICBcIltkYXRhLW1kLWNvbXBvbmVudD1uYXZpZ2F0aW9uXSAubWQtbmF2X19saW5rW2Zvcl06bm90KFt0YWJpbmRleF0pXCIpXG4gICAgICBBcnJheS5wcm90b3R5cGUuZm9yRWFjaC5jYWxsKGxhYmVscywgbGFiZWwgPT4ge1xuICAgICAgICBpZiAobGFiZWwub2Zmc2V0SGVpZ2h0KVxuICAgICAgICAgIGxhYmVsLnRhYkluZGV4ID0gMFxuICAgICAgfSlcbiAgICB9XG4gIH0pLmxpc3RlbigpXG5cbiAgLyogTGlzdGVuZXI6IHJlc2V0IHRhYmJpbmcgYmVoYXZpb3IgKi9cbiAgbmV3IE1hdGVyaWFsLkV2ZW50Lkxpc3RlbmVyKGRvY3VtZW50LmJvZHksIFwibW91c2Vkb3duXCIsICgpID0+IHtcbiAgICBjb25zdCBsYWJlbHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFxuICAgICAgXCJbZGF0YS1tZC1jb21wb25lbnQ9bmF2aWdhdGlvbl0gLm1kLW5hdl9fbGlua1t0YWJpbmRleF1cIilcbiAgICBBcnJheS5wcm90b3R5cGUuZm9yRWFjaC5jYWxsKGxhYmVscywgbGFiZWwgPT4ge1xuICAgICAgbGFiZWwucmVtb3ZlQXR0cmlidXRlKFwidGFiSW5kZXhcIilcbiAgICB9KVxuICB9KS5saXN0ZW4oKVxuXG4gIGRvY3VtZW50LmJvZHkuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsICgpID0+IHtcbiAgICBpZiAoZG9jdW1lbnQuYm9keS5kYXRhc2V0Lm1kU3RhdGUgPT09IFwidGFiYmluZ1wiKVxuICAgICAgZG9jdW1lbnQuYm9keS5kYXRhc2V0Lm1kU3RhdGUgPSBcIlwiXG4gIH0pXG5cbiAgLyogTGlzdGVuZXI6IGNsb3NlIGRyYXdlciB3aGVuIGFuY2hvciBsaW5rcyBhcmUgY2xpY2tlZCAqL1xuICBuZXcgTWF0ZXJpYWwuRXZlbnQuTWF0Y2hNZWRpYShcIihtYXgtd2lkdGg6IDk1OXB4KVwiLFxuICAgIG5ldyBNYXRlcmlhbC5FdmVudC5MaXN0ZW5lcihcIltkYXRhLW1kLWNvbXBvbmVudD1uYXZpZ2F0aW9uXSBbaHJlZl49JyMnXVwiLFxuICAgICAgXCJjbGlja1wiLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHRvZ2dsZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1tZC10b2dnbGU9ZHJhd2VyXVwiKVxuICAgICAgICBpZiAoISh0b2dnbGUgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50KSlcbiAgICAgICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3JcbiAgICAgICAgaWYgKHRvZ2dsZS5jaGVja2VkKSB7XG4gICAgICAgICAgdG9nZ2xlLmNoZWNrZWQgPSBmYWxzZVxuICAgICAgICAgIHRvZ2dsZS5kaXNwYXRjaEV2ZW50KG5ldyBDdXN0b21FdmVudChcImNoYW5nZVwiKSlcbiAgICAgICAgfVxuICAgICAgfSkpXG5cbiAgLyogUmV0cmlldmUgZmFjdHMgZm9yIHRoZSBnaXZlbiByZXBvc2l0b3J5IHR5cGUgKi9cbiAgOygoKSA9PiB7XG4gICAgY29uc3QgZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtbWQtc291cmNlXVwiKVxuICAgIGlmICghZWwpXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFtdKVxuICAgIGVsc2UgaWYgKCEoZWwgaW5zdGFuY2VvZiBIVE1MQW5jaG9yRWxlbWVudCkpXG4gICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3JcbiAgICBzd2l0Y2ggKGVsLmRhdGFzZXQubWRTb3VyY2UpIHtcbiAgICAgIGNhc2UgXCJnaXRodWJcIjogcmV0dXJuIG5ldyBNYXRlcmlhbC5Tb3VyY2UuQWRhcHRlci5HaXRIdWIoZWwpLmZldGNoKClcbiAgICAgIGRlZmF1bHQ6IHJldHVybiBQcm9taXNlLnJlc29sdmUoW10pXG4gICAgfVxuXG4gIC8qIFJlbmRlciByZXBvc2l0b3J5IGluZm9ybWF0aW9uICovXG4gIH0pKCkudGhlbihmYWN0cyA9PiB7XG4gICAgY29uc3Qgc291cmNlcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1tZC1zb3VyY2VdXCIpXG4gICAgQXJyYXkucHJvdG90eXBlLmZvckVhY2guY2FsbChzb3VyY2VzLCBzb3VyY2UgPT4ge1xuICAgICAgbmV3IE1hdGVyaWFsLlNvdXJjZS5SZXBvc2l0b3J5KHNvdXJjZSlcbiAgICAgICAgLmluaXRpYWxpemUoZmFjdHMpXG4gICAgfSlcbiAgfSlcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogRXhwb3J0c1xuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKiBQcm92aWRlIHRoaXMgZm9yIGRvd253YXJkIGNvbXBhdGliaWxpdHkgZm9yIG5vdyAqL1xuY29uc3QgYXBwID0ge1xuICBpbml0aWFsaXplXG59XG5cbmV4cG9ydCB7XG4gIGFwcFxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9hcHBsaWNhdGlvbi5qcyIsIm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3B1YmxpY19wYXRoX18gKyBcImFzc2V0cy9pbWFnZXMvaWNvbnMvYml0YnVja2V0LnN2Z1wiO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vc3JjL2Fzc2V0cy9pbWFnZXMvaWNvbnMvYml0YnVja2V0LnN2Z1xuLy8gbW9kdWxlIGlkID0gN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19wdWJsaWNfcGF0aF9fICsgXCJhc3NldHMvaW1hZ2VzL2ljb25zL2dpdGh1Yi5zdmdcIjtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9hc3NldHMvaW1hZ2VzL2ljb25zL2dpdGh1Yi5zdmdcbi8vIG1vZHVsZSBpZCA9IDhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcHVibGljX3BhdGhfXyArIFwiYXNzZXRzL2ltYWdlcy9pY29ucy9naXRsYWIuc3ZnXCI7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvYXNzZXRzL2ltYWdlcy9pY29ucy9naXRsYWIuc3ZnXG4vLyBtb2R1bGUgaWQgPSA5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIHJlbW92ZWQgYnkgZXh0cmFjdC10ZXh0LXdlYnBhY2stcGx1Z2luXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2FwcGxpY2F0aW9uLnNjc3Ncbi8vIG1vZHVsZSBpZCA9IDEwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIHJlbW92ZWQgYnkgZXh0cmFjdC10ZXh0LXdlYnBhY2stcGx1Z2luXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2FwcGxpY2F0aW9uLXBhbGV0dGUuc2Nzc1xuLy8gbW9kdWxlIGlkID0gMTFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gUG9seWZpbGwgZm9yIGNyZWF0aW5nIEN1c3RvbUV2ZW50cyBvbiBJRTkvMTAvMTFcblxuLy8gY29kZSBwdWxsZWQgZnJvbTpcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9kNHRvY2NoaW5pL2N1c3RvbWV2ZW50LXBvbHlmaWxsXG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvQ3VzdG9tRXZlbnQjUG9seWZpbGxcblxuKGZ1bmN0aW9uKCkge1xuICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0cnkge1xuICAgIHZhciBjZSA9IG5ldyB3aW5kb3cuQ3VzdG9tRXZlbnQoJ3Rlc3QnLCB7IGNhbmNlbGFibGU6IHRydWUgfSk7XG4gICAgY2UucHJldmVudERlZmF1bHQoKTtcbiAgICBpZiAoY2UuZGVmYXVsdFByZXZlbnRlZCAhPT0gdHJ1ZSkge1xuICAgICAgLy8gSUUgaGFzIHByb2JsZW1zIHdpdGggLnByZXZlbnREZWZhdWx0KCkgb24gY3VzdG9tIGV2ZW50c1xuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yMzM0OTE5MVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgcHJldmVudCBkZWZhdWx0Jyk7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgdmFyIEN1c3RvbUV2ZW50ID0gZnVuY3Rpb24oZXZlbnQsIHBhcmFtcykge1xuICAgICAgdmFyIGV2dCwgb3JpZ1ByZXZlbnQ7XG4gICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge1xuICAgICAgICBidWJibGVzOiBmYWxzZSxcbiAgICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICAgIGRldGFpbDogdW5kZWZpbmVkXG4gICAgICB9O1xuXG4gICAgICBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCgnQ3VzdG9tRXZlbnQnKTtcbiAgICAgIGV2dC5pbml0Q3VzdG9tRXZlbnQoXG4gICAgICAgIGV2ZW50LFxuICAgICAgICBwYXJhbXMuYnViYmxlcyxcbiAgICAgICAgcGFyYW1zLmNhbmNlbGFibGUsXG4gICAgICAgIHBhcmFtcy5kZXRhaWxcbiAgICAgICk7XG4gICAgICBvcmlnUHJldmVudCA9IGV2dC5wcmV2ZW50RGVmYXVsdDtcbiAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBvcmlnUHJldmVudC5jYWxsKHRoaXMpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZGVmYXVsdFByZXZlbnRlZCcsIHtcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdGhpcy5kZWZhdWx0UHJldmVudGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIHJldHVybiBldnQ7XG4gICAgfTtcblxuICAgIEN1c3RvbUV2ZW50LnByb3RvdHlwZSA9IHdpbmRvdy5FdmVudC5wcm90b3R5cGU7XG4gICAgd2luZG93LkN1c3RvbUV2ZW50ID0gQ3VzdG9tRXZlbnQ7IC8vIGV4cG9zZSBkZWZpbml0aW9uIHRvIHdpbmRvd1xuICB9XG59KSgpO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvY3VzdG9tLWV2ZW50LXBvbHlmaWxsL3BvbHlmaWxsLmpzXG4vLyBtb2R1bGUgaWQgPSAxMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJpZiAoIXdpbmRvdy5mZXRjaCkgd2luZG93LmZldGNoID0gcmVxdWlyZSgnLicpLmRlZmF1bHQgfHwgcmVxdWlyZSgnLicpO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvdW5mZXRjaC9wb2x5ZmlsbC5qc1xuLy8gbW9kdWxlIGlkID0gMTNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0IHByb21pc2VGaW5hbGx5IGZyb20gJy4vZmluYWxseSc7XG5cbi8vIFN0b3JlIHNldFRpbWVvdXQgcmVmZXJlbmNlIHNvIHByb21pc2UtcG9seWZpbGwgd2lsbCBiZSB1bmFmZmVjdGVkIGJ5XG4vLyBvdGhlciBjb2RlIG1vZGlmeWluZyBzZXRUaW1lb3V0IChsaWtlIHNpbm9uLnVzZUZha2VUaW1lcnMoKSlcbnZhciBzZXRUaW1lb3V0RnVuYyA9IHNldFRpbWVvdXQ7XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG4vLyBQb2x5ZmlsbCBmb3IgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmRcbmZ1bmN0aW9uIGJpbmQoZm4sIHRoaXNBcmcpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIGZuLmFwcGx5KHRoaXNBcmcsIGFyZ3VtZW50cyk7XG4gIH07XG59XG5cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICovXG5mdW5jdGlvbiBQcm9taXNlKGZuKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBQcm9taXNlKSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdQcm9taXNlcyBtdXN0IGJlIGNvbnN0cnVjdGVkIHZpYSBuZXcnKTtcbiAgaWYgKHR5cGVvZiBmbiAhPT0gJ2Z1bmN0aW9uJykgdGhyb3cgbmV3IFR5cGVFcnJvcignbm90IGEgZnVuY3Rpb24nKTtcbiAgLyoqIEB0eXBlIHshbnVtYmVyfSAqL1xuICB0aGlzLl9zdGF0ZSA9IDA7XG4gIC8qKiBAdHlwZSB7IWJvb2xlYW59ICovXG4gIHRoaXMuX2hhbmRsZWQgPSBmYWxzZTtcbiAgLyoqIEB0eXBlIHtQcm9taXNlfHVuZGVmaW5lZH0gKi9cbiAgdGhpcy5fdmFsdWUgPSB1bmRlZmluZWQ7XG4gIC8qKiBAdHlwZSB7IUFycmF5PCFGdW5jdGlvbj59ICovXG4gIHRoaXMuX2RlZmVycmVkcyA9IFtdO1xuXG4gIGRvUmVzb2x2ZShmbiwgdGhpcyk7XG59XG5cbmZ1bmN0aW9uIGhhbmRsZShzZWxmLCBkZWZlcnJlZCkge1xuICB3aGlsZSAoc2VsZi5fc3RhdGUgPT09IDMpIHtcbiAgICBzZWxmID0gc2VsZi5fdmFsdWU7XG4gIH1cbiAgaWYgKHNlbGYuX3N0YXRlID09PSAwKSB7XG4gICAgc2VsZi5fZGVmZXJyZWRzLnB1c2goZGVmZXJyZWQpO1xuICAgIHJldHVybjtcbiAgfVxuICBzZWxmLl9oYW5kbGVkID0gdHJ1ZTtcbiAgUHJvbWlzZS5faW1tZWRpYXRlRm4oZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNiID0gc2VsZi5fc3RhdGUgPT09IDEgPyBkZWZlcnJlZC5vbkZ1bGZpbGxlZCA6IGRlZmVycmVkLm9uUmVqZWN0ZWQ7XG4gICAgaWYgKGNiID09PSBudWxsKSB7XG4gICAgICAoc2VsZi5fc3RhdGUgPT09IDEgPyByZXNvbHZlIDogcmVqZWN0KShkZWZlcnJlZC5wcm9taXNlLCBzZWxmLl92YWx1ZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciByZXQ7XG4gICAgdHJ5IHtcbiAgICAgIHJldCA9IGNiKHNlbGYuX3ZhbHVlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZGVmZXJyZWQucHJvbWlzZSwgZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJlc29sdmUoZGVmZXJyZWQucHJvbWlzZSwgcmV0KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmUoc2VsZiwgbmV3VmFsdWUpIHtcbiAgdHJ5IHtcbiAgICAvLyBQcm9taXNlIFJlc29sdXRpb24gUHJvY2VkdXJlOiBodHRwczovL2dpdGh1Yi5jb20vcHJvbWlzZXMtYXBsdXMvcHJvbWlzZXMtc3BlYyN0aGUtcHJvbWlzZS1yZXNvbHV0aW9uLXByb2NlZHVyZVxuICAgIGlmIChuZXdWYWx1ZSA9PT0gc2VsZilcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0EgcHJvbWlzZSBjYW5ub3QgYmUgcmVzb2x2ZWQgd2l0aCBpdHNlbGYuJyk7XG4gICAgaWYgKFxuICAgICAgbmV3VmFsdWUgJiZcbiAgICAgICh0eXBlb2YgbmV3VmFsdWUgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBuZXdWYWx1ZSA9PT0gJ2Z1bmN0aW9uJylcbiAgICApIHtcbiAgICAgIHZhciB0aGVuID0gbmV3VmFsdWUudGhlbjtcbiAgICAgIGlmIChuZXdWYWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgc2VsZi5fc3RhdGUgPSAzO1xuICAgICAgICBzZWxmLl92YWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICBmaW5hbGUoc2VsZik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZG9SZXNvbHZlKGJpbmQodGhlbiwgbmV3VmFsdWUpLCBzZWxmKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICBzZWxmLl9zdGF0ZSA9IDE7XG4gICAgc2VsZi5fdmFsdWUgPSBuZXdWYWx1ZTtcbiAgICBmaW5hbGUoc2VsZik7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZWplY3Qoc2VsZiwgZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVqZWN0KHNlbGYsIG5ld1ZhbHVlKSB7XG4gIHNlbGYuX3N0YXRlID0gMjtcbiAgc2VsZi5fdmFsdWUgPSBuZXdWYWx1ZTtcbiAgZmluYWxlKHNlbGYpO1xufVxuXG5mdW5jdGlvbiBmaW5hbGUoc2VsZikge1xuICBpZiAoc2VsZi5fc3RhdGUgPT09IDIgJiYgc2VsZi5fZGVmZXJyZWRzLmxlbmd0aCA9PT0gMCkge1xuICAgIFByb21pc2UuX2ltbWVkaWF0ZUZuKGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCFzZWxmLl9oYW5kbGVkKSB7XG4gICAgICAgIFByb21pc2UuX3VuaGFuZGxlZFJlamVjdGlvbkZuKHNlbGYuX3ZhbHVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBzZWxmLl9kZWZlcnJlZHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBoYW5kbGUoc2VsZiwgc2VsZi5fZGVmZXJyZWRzW2ldKTtcbiAgfVxuICBzZWxmLl9kZWZlcnJlZHMgPSBudWxsO1xufVxuXG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBIYW5kbGVyKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkLCBwcm9taXNlKSB7XG4gIHRoaXMub25GdWxmaWxsZWQgPSB0eXBlb2Ygb25GdWxmaWxsZWQgPT09ICdmdW5jdGlvbicgPyBvbkZ1bGZpbGxlZCA6IG51bGw7XG4gIHRoaXMub25SZWplY3RlZCA9IHR5cGVvZiBvblJlamVjdGVkID09PSAnZnVuY3Rpb24nID8gb25SZWplY3RlZCA6IG51bGw7XG4gIHRoaXMucHJvbWlzZSA9IHByb21pc2U7XG59XG5cbi8qKlxuICogVGFrZSBhIHBvdGVudGlhbGx5IG1pc2JlaGF2aW5nIHJlc29sdmVyIGZ1bmN0aW9uIGFuZCBtYWtlIHN1cmVcbiAqIG9uRnVsZmlsbGVkIGFuZCBvblJlamVjdGVkIGFyZSBvbmx5IGNhbGxlZCBvbmNlLlxuICpcbiAqIE1ha2VzIG5vIGd1YXJhbnRlZXMgYWJvdXQgYXN5bmNocm9ueS5cbiAqL1xuZnVuY3Rpb24gZG9SZXNvbHZlKGZuLCBzZWxmKSB7XG4gIHZhciBkb25lID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgZm4oXG4gICAgICBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICBpZiAoZG9uZSkgcmV0dXJuO1xuICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgICAgcmVzb2x2ZShzZWxmLCB2YWx1ZSk7XG4gICAgICB9LFxuICAgICAgZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgICAgIGlmIChkb25lKSByZXR1cm47XG4gICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICByZWplY3Qoc2VsZiwgcmVhc29uKTtcbiAgICAgIH1cbiAgICApO1xuICB9IGNhdGNoIChleCkge1xuICAgIGlmIChkb25lKSByZXR1cm47XG4gICAgZG9uZSA9IHRydWU7XG4gICAgcmVqZWN0KHNlbGYsIGV4KTtcbiAgfVxufVxuXG5Qcm9taXNlLnByb3RvdHlwZVsnY2F0Y2gnXSA9IGZ1bmN0aW9uKG9uUmVqZWN0ZWQpIHtcbiAgcmV0dXJuIHRoaXMudGhlbihudWxsLCBvblJlamVjdGVkKTtcbn07XG5cblByb21pc2UucHJvdG90eXBlLnRoZW4gPSBmdW5jdGlvbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuICAvLyBAdHMtaWdub3JlXG4gIHZhciBwcm9tID0gbmV3IHRoaXMuY29uc3RydWN0b3Iobm9vcCk7XG5cbiAgaGFuZGxlKHRoaXMsIG5ldyBIYW5kbGVyKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkLCBwcm9tKSk7XG4gIHJldHVybiBwcm9tO1xufTtcblxuUHJvbWlzZS5wcm90b3R5cGVbJ2ZpbmFsbHknXSA9IHByb21pc2VGaW5hbGx5O1xuXG5Qcm9taXNlLmFsbCA9IGZ1bmN0aW9uKGFycikge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgaWYgKCFhcnIgfHwgdHlwZW9mIGFyci5sZW5ndGggPT09ICd1bmRlZmluZWQnKVxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignUHJvbWlzZS5hbGwgYWNjZXB0cyBhbiBhcnJheScpO1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJyKTtcbiAgICBpZiAoYXJncy5sZW5ndGggPT09IDApIHJldHVybiByZXNvbHZlKFtdKTtcbiAgICB2YXIgcmVtYWluaW5nID0gYXJncy5sZW5ndGg7XG5cbiAgICBmdW5jdGlvbiByZXMoaSwgdmFsKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAodmFsICYmICh0eXBlb2YgdmFsID09PSAnb2JqZWN0JyB8fCB0eXBlb2YgdmFsID09PSAnZnVuY3Rpb24nKSkge1xuICAgICAgICAgIHZhciB0aGVuID0gdmFsLnRoZW47XG4gICAgICAgICAgaWYgKHR5cGVvZiB0aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGVuLmNhbGwoXG4gICAgICAgICAgICAgIHZhbCxcbiAgICAgICAgICAgICAgZnVuY3Rpb24odmFsKSB7XG4gICAgICAgICAgICAgICAgcmVzKGksIHZhbCk7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHJlamVjdFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYXJnc1tpXSA9IHZhbDtcbiAgICAgICAgaWYgKC0tcmVtYWluaW5nID09PSAwKSB7XG4gICAgICAgICAgcmVzb2x2ZShhcmdzKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgICAgcmVqZWN0KGV4KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlcyhpLCBhcmdzW2ldKTtcbiAgICB9XG4gIH0pO1xufTtcblxuUHJvbWlzZS5yZXNvbHZlID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUuY29uc3RydWN0b3IgPT09IFByb21pc2UpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSkge1xuICAgIHJlc29sdmUodmFsdWUpO1xuICB9KTtcbn07XG5cblByb21pc2UucmVqZWN0ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHJlamVjdCh2YWx1ZSk7XG4gIH0pO1xufTtcblxuUHJvbWlzZS5yYWNlID0gZnVuY3Rpb24odmFsdWVzKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gdmFsdWVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICB2YWx1ZXNbaV0udGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgIH1cbiAgfSk7XG59O1xuXG4vLyBVc2UgcG9seWZpbGwgZm9yIHNldEltbWVkaWF0ZSBmb3IgcGVyZm9ybWFuY2UgZ2FpbnNcblByb21pc2UuX2ltbWVkaWF0ZUZuID1cbiAgKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09ICdmdW5jdGlvbicgJiZcbiAgICBmdW5jdGlvbihmbikge1xuICAgICAgc2V0SW1tZWRpYXRlKGZuKTtcbiAgICB9KSB8fFxuICBmdW5jdGlvbihmbikge1xuICAgIHNldFRpbWVvdXRGdW5jKGZuLCAwKTtcbiAgfTtcblxuUHJvbWlzZS5fdW5oYW5kbGVkUmVqZWN0aW9uRm4gPSBmdW5jdGlvbiBfdW5oYW5kbGVkUmVqZWN0aW9uRm4oZXJyKSB7XG4gIGlmICh0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCcgJiYgY29uc29sZSkge1xuICAgIGNvbnNvbGUud2FybignUG9zc2libGUgVW5oYW5kbGVkIFByb21pc2UgUmVqZWN0aW9uOicsIGVycik7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tY29uc29sZVxuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBQcm9taXNlO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvcHJvbWlzZS1wb2x5ZmlsbC9zcmMvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDE0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsInZhciBzY29wZSA9ICh0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiICYmIGdsb2JhbCkgfHxcbiAgICAgICAgICAgICh0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiAmJiBzZWxmKSB8fFxuICAgICAgICAgICAgd2luZG93O1xudmFyIGFwcGx5ID0gRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5O1xuXG4vLyBET00gQVBJcywgZm9yIGNvbXBsZXRlbmVzc1xuXG5leHBvcnRzLnNldFRpbWVvdXQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIG5ldyBUaW1lb3V0KGFwcGx5LmNhbGwoc2V0VGltZW91dCwgc2NvcGUsIGFyZ3VtZW50cyksIGNsZWFyVGltZW91dCk7XG59O1xuZXhwb3J0cy5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IFRpbWVvdXQoYXBwbHkuY2FsbChzZXRJbnRlcnZhbCwgc2NvcGUsIGFyZ3VtZW50cyksIGNsZWFySW50ZXJ2YWwpO1xufTtcbmV4cG9ydHMuY2xlYXJUaW1lb3V0ID1cbmV4cG9ydHMuY2xlYXJJbnRlcnZhbCA9IGZ1bmN0aW9uKHRpbWVvdXQpIHtcbiAgaWYgKHRpbWVvdXQpIHtcbiAgICB0aW1lb3V0LmNsb3NlKCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIFRpbWVvdXQoaWQsIGNsZWFyRm4pIHtcbiAgdGhpcy5faWQgPSBpZDtcbiAgdGhpcy5fY2xlYXJGbiA9IGNsZWFyRm47XG59XG5UaW1lb3V0LnByb3RvdHlwZS51bnJlZiA9IFRpbWVvdXQucHJvdG90eXBlLnJlZiA9IGZ1bmN0aW9uKCkge307XG5UaW1lb3V0LnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9jbGVhckZuLmNhbGwoc2NvcGUsIHRoaXMuX2lkKTtcbn07XG5cbi8vIERvZXMgbm90IHN0YXJ0IHRoZSB0aW1lLCBqdXN0IHNldHMgdXAgdGhlIG1lbWJlcnMgbmVlZGVkLlxuZXhwb3J0cy5lbnJvbGwgPSBmdW5jdGlvbihpdGVtLCBtc2Vjcykge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG4gIGl0ZW0uX2lkbGVUaW1lb3V0ID0gbXNlY3M7XG59O1xuXG5leHBvcnRzLnVuZW5yb2xsID0gZnVuY3Rpb24oaXRlbSkge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG4gIGl0ZW0uX2lkbGVUaW1lb3V0ID0gLTE7XG59O1xuXG5leHBvcnRzLl91bnJlZkFjdGl2ZSA9IGV4cG9ydHMuYWN0aXZlID0gZnVuY3Rpb24oaXRlbSkge1xuICBjbGVhclRpbWVvdXQoaXRlbS5faWRsZVRpbWVvdXRJZCk7XG5cbiAgdmFyIG1zZWNzID0gaXRlbS5faWRsZVRpbWVvdXQ7XG4gIGlmIChtc2VjcyA+PSAwKSB7XG4gICAgaXRlbS5faWRsZVRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gb25UaW1lb3V0KCkge1xuICAgICAgaWYgKGl0ZW0uX29uVGltZW91dClcbiAgICAgICAgaXRlbS5fb25UaW1lb3V0KCk7XG4gICAgfSwgbXNlY3MpO1xuICB9XG59O1xuXG4vLyBzZXRpbW1lZGlhdGUgYXR0YWNoZXMgaXRzZWxmIHRvIHRoZSBnbG9iYWwgb2JqZWN0XG5yZXF1aXJlKFwic2V0aW1tZWRpYXRlXCIpO1xuLy8gT24gc29tZSBleG90aWMgZW52aXJvbm1lbnRzLCBpdCdzIG5vdCBjbGVhciB3aGljaCBvYmplY3QgYHNldGltbWVkaWF0ZWAgd2FzXG4vLyBhYmxlIHRvIGluc3RhbGwgb250by4gIFNlYXJjaCBlYWNoIHBvc3NpYmlsaXR5IGluIHRoZSBzYW1lIG9yZGVyIGFzIHRoZVxuLy8gYHNldGltbWVkaWF0ZWAgbGlicmFyeS5cbmV4cG9ydHMuc2V0SW1tZWRpYXRlID0gKHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiICYmIHNlbGYuc2V0SW1tZWRpYXRlKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAodHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBnbG9iYWwuc2V0SW1tZWRpYXRlKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAodGhpcyAmJiB0aGlzLnNldEltbWVkaWF0ZSk7XG5leHBvcnRzLmNsZWFySW1tZWRpYXRlID0gKHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiICYmIHNlbGYuY2xlYXJJbW1lZGlhdGUpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgKHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgJiYgZ2xvYmFsLmNsZWFySW1tZWRpYXRlKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzICYmIHRoaXMuY2xlYXJJbW1lZGlhdGUpO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvdGltZXJzLWJyb3dzZXJpZnkvbWFpbi5qc1xuLy8gbW9kdWxlIGlkID0gMTVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiKGZ1bmN0aW9uIChnbG9iYWwsIHVuZGVmaW5lZCkge1xuICAgIFwidXNlIHN0cmljdFwiO1xuXG4gICAgaWYgKGdsb2JhbC5zZXRJbW1lZGlhdGUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBuZXh0SGFuZGxlID0gMTsgLy8gU3BlYyBzYXlzIGdyZWF0ZXIgdGhhbiB6ZXJvXG4gICAgdmFyIHRhc2tzQnlIYW5kbGUgPSB7fTtcbiAgICB2YXIgY3VycmVudGx5UnVubmluZ0FUYXNrID0gZmFsc2U7XG4gICAgdmFyIGRvYyA9IGdsb2JhbC5kb2N1bWVudDtcbiAgICB2YXIgcmVnaXN0ZXJJbW1lZGlhdGU7XG5cbiAgICBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoY2FsbGJhY2spIHtcbiAgICAgIC8vIENhbGxiYWNrIGNhbiBlaXRoZXIgYmUgYSBmdW5jdGlvbiBvciBhIHN0cmluZ1xuICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGNhbGxiYWNrID0gbmV3IEZ1bmN0aW9uKFwiXCIgKyBjYWxsYmFjayk7XG4gICAgICB9XG4gICAgICAvLyBDb3B5IGZ1bmN0aW9uIGFyZ3VtZW50c1xuICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpICsgMV07XG4gICAgICB9XG4gICAgICAvLyBTdG9yZSBhbmQgcmVnaXN0ZXIgdGhlIHRhc2tcbiAgICAgIHZhciB0YXNrID0geyBjYWxsYmFjazogY2FsbGJhY2ssIGFyZ3M6IGFyZ3MgfTtcbiAgICAgIHRhc2tzQnlIYW5kbGVbbmV4dEhhbmRsZV0gPSB0YXNrO1xuICAgICAgcmVnaXN0ZXJJbW1lZGlhdGUobmV4dEhhbmRsZSk7XG4gICAgICByZXR1cm4gbmV4dEhhbmRsZSsrO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlKGhhbmRsZSkge1xuICAgICAgICBkZWxldGUgdGFza3NCeUhhbmRsZVtoYW5kbGVdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJ1bih0YXNrKSB7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IHRhc2suY2FsbGJhY2s7XG4gICAgICAgIHZhciBhcmdzID0gdGFzay5hcmdzO1xuICAgICAgICBzd2l0Y2ggKGFyZ3MubGVuZ3RoKSB7XG4gICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgY2FsbGJhY2soYXJnc1swXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgY2FsbGJhY2soYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgY2FsbGJhY2soYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGNhbGxiYWNrLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJ1bklmUHJlc2VudChoYW5kbGUpIHtcbiAgICAgICAgLy8gRnJvbSB0aGUgc3BlYzogXCJXYWl0IHVudGlsIGFueSBpbnZvY2F0aW9ucyBvZiB0aGlzIGFsZ29yaXRobSBzdGFydGVkIGJlZm9yZSB0aGlzIG9uZSBoYXZlIGNvbXBsZXRlZC5cIlxuICAgICAgICAvLyBTbyBpZiB3ZSdyZSBjdXJyZW50bHkgcnVubmluZyBhIHRhc2ssIHdlJ2xsIG5lZWQgdG8gZGVsYXkgdGhpcyBpbnZvY2F0aW9uLlxuICAgICAgICBpZiAoY3VycmVudGx5UnVubmluZ0FUYXNrKSB7XG4gICAgICAgICAgICAvLyBEZWxheSBieSBkb2luZyBhIHNldFRpbWVvdXQuIHNldEltbWVkaWF0ZSB3YXMgdHJpZWQgaW5zdGVhZCwgYnV0IGluIEZpcmVmb3ggNyBpdCBnZW5lcmF0ZWQgYVxuICAgICAgICAgICAgLy8gXCJ0b28gbXVjaCByZWN1cnNpb25cIiBlcnJvci5cbiAgICAgICAgICAgIHNldFRpbWVvdXQocnVuSWZQcmVzZW50LCAwLCBoYW5kbGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIHRhc2sgPSB0YXNrc0J5SGFuZGxlW2hhbmRsZV07XG4gICAgICAgICAgICBpZiAodGFzaykge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRseVJ1bm5pbmdBVGFzayA9IHRydWU7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgcnVuKHRhc2spO1xuICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICAgIGNsZWFySW1tZWRpYXRlKGhhbmRsZSk7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRseVJ1bm5pbmdBVGFzayA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGluc3RhbGxOZXh0VGlja0ltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICByZWdpc3RlckltbWVkaWF0ZSA9IGZ1bmN0aW9uKGhhbmRsZSkge1xuICAgICAgICAgICAgcHJvY2Vzcy5uZXh0VGljayhmdW5jdGlvbiAoKSB7IHJ1bklmUHJlc2VudChoYW5kbGUpOyB9KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjYW5Vc2VQb3N0TWVzc2FnZSgpIHtcbiAgICAgICAgLy8gVGhlIHRlc3QgYWdhaW5zdCBgaW1wb3J0U2NyaXB0c2AgcHJldmVudHMgdGhpcyBpbXBsZW1lbnRhdGlvbiBmcm9tIGJlaW5nIGluc3RhbGxlZCBpbnNpZGUgYSB3ZWIgd29ya2VyLFxuICAgICAgICAvLyB3aGVyZSBgZ2xvYmFsLnBvc3RNZXNzYWdlYCBtZWFucyBzb21ldGhpbmcgY29tcGxldGVseSBkaWZmZXJlbnQgYW5kIGNhbid0IGJlIHVzZWQgZm9yIHRoaXMgcHVycG9zZS5cbiAgICAgICAgaWYgKGdsb2JhbC5wb3N0TWVzc2FnZSAmJiAhZ2xvYmFsLmltcG9ydFNjcmlwdHMpIHtcbiAgICAgICAgICAgIHZhciBwb3N0TWVzc2FnZUlzQXN5bmNocm9ub3VzID0gdHJ1ZTtcbiAgICAgICAgICAgIHZhciBvbGRPbk1lc3NhZ2UgPSBnbG9iYWwub25tZXNzYWdlO1xuICAgICAgICAgICAgZ2xvYmFsLm9ubWVzc2FnZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlSXNBc3luY2hyb25vdXMgPSBmYWxzZTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBnbG9iYWwucG9zdE1lc3NhZ2UoXCJcIiwgXCIqXCIpO1xuICAgICAgICAgICAgZ2xvYmFsLm9ubWVzc2FnZSA9IG9sZE9uTWVzc2FnZTtcbiAgICAgICAgICAgIHJldHVybiBwb3N0TWVzc2FnZUlzQXN5bmNocm9ub3VzO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbFBvc3RNZXNzYWdlSW1wbGVtZW50YXRpb24oKSB7XG4gICAgICAgIC8vIEluc3RhbGxzIGFuIGV2ZW50IGhhbmRsZXIgb24gYGdsb2JhbGAgZm9yIHRoZSBgbWVzc2FnZWAgZXZlbnQ6IHNlZVxuICAgICAgICAvLyAqIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuL0RPTS93aW5kb3cucG9zdE1lc3NhZ2VcbiAgICAgICAgLy8gKiBodHRwOi8vd3d3LndoYXR3Zy5vcmcvc3BlY3Mvd2ViLWFwcHMvY3VycmVudC13b3JrL211bHRpcGFnZS9jb21tcy5odG1sI2Nyb3NzRG9jdW1lbnRNZXNzYWdlc1xuXG4gICAgICAgIHZhciBtZXNzYWdlUHJlZml4ID0gXCJzZXRJbW1lZGlhdGUkXCIgKyBNYXRoLnJhbmRvbSgpICsgXCIkXCI7XG4gICAgICAgIHZhciBvbkdsb2JhbE1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LnNvdXJjZSA9PT0gZ2xvYmFsICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIGV2ZW50LmRhdGEgPT09IFwic3RyaW5nXCIgJiZcbiAgICAgICAgICAgICAgICBldmVudC5kYXRhLmluZGV4T2YobWVzc2FnZVByZWZpeCkgPT09IDApIHtcbiAgICAgICAgICAgICAgICBydW5JZlByZXNlbnQoK2V2ZW50LmRhdGEuc2xpY2UobWVzc2FnZVByZWZpeC5sZW5ndGgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICAgICAgICAgIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKFwibWVzc2FnZVwiLCBvbkdsb2JhbE1lc3NhZ2UsIGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsb2JhbC5hdHRhY2hFdmVudChcIm9ubWVzc2FnZVwiLCBvbkdsb2JhbE1lc3NhZ2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVnaXN0ZXJJbW1lZGlhdGUgPSBmdW5jdGlvbihoYW5kbGUpIHtcbiAgICAgICAgICAgIGdsb2JhbC5wb3N0TWVzc2FnZShtZXNzYWdlUHJlZml4ICsgaGFuZGxlLCBcIipcIik7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaW5zdGFsbE1lc3NhZ2VDaGFubmVsSW1wbGVtZW50YXRpb24oKSB7XG4gICAgICAgIHZhciBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgICAgIGNoYW5uZWwucG9ydDEub25tZXNzYWdlID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIHZhciBoYW5kbGUgPSBldmVudC5kYXRhO1xuICAgICAgICAgICAgcnVuSWZQcmVzZW50KGhhbmRsZSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmVnaXN0ZXJJbW1lZGlhdGUgPSBmdW5jdGlvbihoYW5kbGUpIHtcbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoaGFuZGxlKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnN0YWxsUmVhZHlTdGF0ZUNoYW5nZUltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICB2YXIgaHRtbCA9IGRvYy5kb2N1bWVudEVsZW1lbnQ7XG4gICAgICAgIHJlZ2lzdGVySW1tZWRpYXRlID0gZnVuY3Rpb24oaGFuZGxlKSB7XG4gICAgICAgICAgICAvLyBDcmVhdGUgYSA8c2NyaXB0PiBlbGVtZW50OyBpdHMgcmVhZHlzdGF0ZWNoYW5nZSBldmVudCB3aWxsIGJlIGZpcmVkIGFzeW5jaHJvbm91c2x5IG9uY2UgaXQgaXMgaW5zZXJ0ZWRcbiAgICAgICAgICAgIC8vIGludG8gdGhlIGRvY3VtZW50LiBEbyBzbywgdGh1cyBxdWV1aW5nIHVwIHRoZSB0YXNrLiBSZW1lbWJlciB0byBjbGVhbiB1cCBvbmNlIGl0J3MgYmVlbiBjYWxsZWQuXG4gICAgICAgICAgICB2YXIgc2NyaXB0ID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIik7XG4gICAgICAgICAgICBzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJ1bklmUHJlc2VudChoYW5kbGUpO1xuICAgICAgICAgICAgICAgIHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsO1xuICAgICAgICAgICAgICAgIGh0bWwucmVtb3ZlQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgICAgICAgICBzY3JpcHQgPSBudWxsO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGh0bWwuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbnN0YWxsU2V0VGltZW91dEltcGxlbWVudGF0aW9uKCkge1xuICAgICAgICByZWdpc3RlckltbWVkaWF0ZSA9IGZ1bmN0aW9uKGhhbmRsZSkge1xuICAgICAgICAgICAgc2V0VGltZW91dChydW5JZlByZXNlbnQsIDAsIGhhbmRsZSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gSWYgc3VwcG9ydGVkLCB3ZSBzaG91bGQgYXR0YWNoIHRvIHRoZSBwcm90b3R5cGUgb2YgZ2xvYmFsLCBzaW5jZSB0aGF0IGlzIHdoZXJlIHNldFRpbWVvdXQgZXQgYWwuIGxpdmUuXG4gICAgdmFyIGF0dGFjaFRvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihnbG9iYWwpO1xuICAgIGF0dGFjaFRvID0gYXR0YWNoVG8gJiYgYXR0YWNoVG8uc2V0VGltZW91dCA/IGF0dGFjaFRvIDogZ2xvYmFsO1xuXG4gICAgLy8gRG9uJ3QgZ2V0IGZvb2xlZCBieSBlLmcuIGJyb3dzZXJpZnkgZW52aXJvbm1lbnRzLlxuICAgIGlmICh7fS50b1N0cmluZy5jYWxsKGdsb2JhbC5wcm9jZXNzKSA9PT0gXCJbb2JqZWN0IHByb2Nlc3NdXCIpIHtcbiAgICAgICAgLy8gRm9yIE5vZGUuanMgYmVmb3JlIDAuOVxuICAgICAgICBpbnN0YWxsTmV4dFRpY2tJbXBsZW1lbnRhdGlvbigpO1xuXG4gICAgfSBlbHNlIGlmIChjYW5Vc2VQb3N0TWVzc2FnZSgpKSB7XG4gICAgICAgIC8vIEZvciBub24tSUUxMCBtb2Rlcm4gYnJvd3NlcnNcbiAgICAgICAgaW5zdGFsbFBvc3RNZXNzYWdlSW1wbGVtZW50YXRpb24oKTtcblxuICAgIH0gZWxzZSBpZiAoZ2xvYmFsLk1lc3NhZ2VDaGFubmVsKSB7XG4gICAgICAgIC8vIEZvciB3ZWIgd29ya2Vycywgd2hlcmUgc3VwcG9ydGVkXG4gICAgICAgIGluc3RhbGxNZXNzYWdlQ2hhbm5lbEltcGxlbWVudGF0aW9uKCk7XG5cbiAgICB9IGVsc2UgaWYgKGRvYyAmJiBcIm9ucmVhZHlzdGF0ZWNoYW5nZVwiIGluIGRvYy5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpKSB7XG4gICAgICAgIC8vIEZvciBJRSA24oCTOFxuICAgICAgICBpbnN0YWxsUmVhZHlTdGF0ZUNoYW5nZUltcGxlbWVudGF0aW9uKCk7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBGb3Igb2xkZXIgYnJvd3NlcnNcbiAgICAgICAgaW5zdGFsbFNldFRpbWVvdXRJbXBsZW1lbnRhdGlvbigpO1xuICAgIH1cblxuICAgIGF0dGFjaFRvLnNldEltbWVkaWF0ZSA9IHNldEltbWVkaWF0ZTtcbiAgICBhdHRhY2hUby5jbGVhckltbWVkaWF0ZSA9IGNsZWFySW1tZWRpYXRlO1xufSh0eXBlb2Ygc2VsZiA9PT0gXCJ1bmRlZmluZWRcIiA/IHR5cGVvZiBnbG9iYWwgPT09IFwidW5kZWZpbmVkXCIgPyB0aGlzIDogZ2xvYmFsIDogc2VsZikpO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9ub2RlX21vZHVsZXMvc2V0aW1tZWRpYXRlL3NldEltbWVkaWF0ZS5qc1xuLy8gbW9kdWxlIGlkID0gMTZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbi8vIGNhY2hlZCBmcm9tIHdoYXRldmVyIGdsb2JhbCBpcyBwcmVzZW50IHNvIHRoYXQgdGVzdCBydW5uZXJzIHRoYXQgc3R1YiBpdFxuLy8gZG9uJ3QgYnJlYWsgdGhpbmdzLiAgQnV0IHdlIG5lZWQgdG8gd3JhcCBpdCBpbiBhIHRyeSBjYXRjaCBpbiBjYXNlIGl0IGlzXG4vLyB3cmFwcGVkIGluIHN0cmljdCBtb2RlIGNvZGUgd2hpY2ggZG9lc24ndCBkZWZpbmUgYW55IGdsb2JhbHMuICBJdCdzIGluc2lkZSBhXG4vLyBmdW5jdGlvbiBiZWNhdXNlIHRyeS9jYXRjaGVzIGRlb3B0aW1pemUgaW4gY2VydGFpbiBlbmdpbmVzLlxuXG52YXIgY2FjaGVkU2V0VGltZW91dDtcbnZhciBjYWNoZWRDbGVhclRpbWVvdXQ7XG5cbmZ1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG5mdW5jdGlvbiBkZWZhdWx0Q2xlYXJUaW1lb3V0ICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsZWFyVGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuKGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICB9XG59ICgpKVxuZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcbiAgICBpZiAoY2FjaGVkU2V0VGltZW91dCA9PT0gc2V0VGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgLy8gaWYgc2V0VGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZFNldFRpbWVvdXQgPT09IGRlZmF1bHRTZXRUaW1vdXQgfHwgIWNhY2hlZFNldFRpbWVvdXQpICYmIHNldFRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKG51bGwsIGZ1biwgMCk7XG4gICAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvclxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLCBmdW4sIDApO1xuICAgICAgICB9XG4gICAgfVxuXG5cbn1cbmZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpIHtcbiAgICBpZiAoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBkZWZhdWx0Q2xlYXJUaW1lb3V0IHx8ICFjYWNoZWRDbGVhclRpbWVvdXQpICYmIGNsZWFyVGltZW91dCkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfSBjYXRjaCAoZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgIHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCwgbWFya2VyKTtcbiAgICAgICAgfSBjYXRjaCAoZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvci5cbiAgICAgICAgICAgIC8vIFNvbWUgdmVyc2lvbnMgb2YgSS5FLiBoYXZlIGRpZmZlcmVudCBydWxlcyBmb3IgY2xlYXJUaW1lb3V0IHZzIHNldFRpbWVvdXRcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG5cblxufVxudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gcnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kT25jZUxpc3RlbmVyID0gbm9vcDtcblxucHJvY2Vzcy5saXN0ZW5lcnMgPSBmdW5jdGlvbiAobmFtZSkgeyByZXR1cm4gW10gfVxuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qc1xuLy8gbW9kdWxlIGlkID0gMTdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLyoqXG4gKiBAdGhpcyB7UHJvbWlzZX1cbiAqL1xuZnVuY3Rpb24gZmluYWxseUNvbnN0cnVjdG9yKGNhbGxiYWNrKSB7XG4gIHZhciBjb25zdHJ1Y3RvciA9IHRoaXMuY29uc3RydWN0b3I7XG4gIHJldHVybiB0aGlzLnRoZW4oXG4gICAgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiBjb25zdHJ1Y3Rvci5yZXNvbHZlKGNhbGxiYWNrKCkpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgZnVuY3Rpb24ocmVhc29uKSB7XG4gICAgICByZXR1cm4gY29uc3RydWN0b3IucmVzb2x2ZShjYWxsYmFjaygpKS50aGVuKGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gY29uc3RydWN0b3IucmVqZWN0KHJlYXNvbik7XG4gICAgICB9KTtcbiAgICB9XG4gICk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZpbmFsbHlDb25zdHJ1Y3RvcjtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL3Byb21pc2UtcG9seWZpbGwvc3JjL2ZpbmFsbHkuanNcbi8vIG1vZHVsZSBpZCA9IDE4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qIVxuICogY2xpcGJvYXJkLmpzIHYyLjAuNFxuICogaHR0cHM6Ly96ZW5vcm9jaGEuZ2l0aHViLmlvL2NsaXBib2FyZC5qc1xuICogXG4gKiBMaWNlbnNlZCBNSVQgwqkgWmVubyBSb2NoYVxuICovXG4oZnVuY3Rpb24gd2VicGFja1VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24ocm9vdCwgZmFjdG9yeSkge1xuXHRpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcpXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCk7XG5cdGVsc2UgaWYodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKVxuXHRcdGRlZmluZShbXSwgZmFjdG9yeSk7XG5cdGVsc2UgaWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKVxuXHRcdGV4cG9ydHNbXCJDbGlwYm9hcmRKU1wiXSA9IGZhY3RvcnkoKTtcblx0ZWxzZVxuXHRcdHJvb3RbXCJDbGlwYm9hcmRKU1wiXSA9IGZhY3RvcnkoKTtcbn0pKHRoaXMsIGZ1bmN0aW9uKCkge1xucmV0dXJuIC8qKioqKiovIChmdW5jdGlvbihtb2R1bGVzKSB7IC8vIHdlYnBhY2tCb290c3RyYXBcbi8qKioqKiovIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuLyoqKioqKi8gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbi8qKioqKiovIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuLyoqKioqKi9cbi8qKioqKiovIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbi8qKioqKiovIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuLyoqKioqKi8gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG4vKioqKioqLyBcdFx0fVxuLyoqKioqKi8gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4vKioqKioqLyBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuLyoqKioqKi8gXHRcdFx0aTogbW9kdWxlSWQsXG4vKioqKioqLyBcdFx0XHRsOiBmYWxzZSxcbi8qKioqKiovIFx0XHRcdGV4cG9ydHM6IHt9XG4vKioqKioqLyBcdFx0fTtcbi8qKioqKiovXG4vKioqKioqLyBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4vKioqKioqLyBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG4vKioqKioqL1xuLyoqKioqKi8gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbi8qKioqKiovIFx0XHRtb2R1bGUubCA9IHRydWU7XG4vKioqKioqL1xuLyoqKioqKi8gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4vKioqKioqLyBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuLyoqKioqKi8gXHR9XG4vKioqKioqL1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4vKioqKioqLyBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuLyoqKioqKi8gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4vKioqKioqLyBcdFx0fVxuLyoqKioqKi8gXHR9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuLyoqKioqKi8gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSBmdW5jdGlvbihleHBvcnRzKSB7XG4vKioqKioqLyBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4vKioqKioqLyBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcbi8qKioqKiovIFx0XHR9XG4vKioqKioqLyBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8qKioqKiovIFx0fTtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuLyoqKioqKi8gXHQvLyBtb2RlICYgMTogdmFsdWUgaXMgYSBtb2R1bGUgaWQsIHJlcXVpcmUgaXRcbi8qKioqKiovIFx0Ly8gbW9kZSAmIDI6IG1lcmdlIGFsbCBwcm9wZXJ0aWVzIG9mIHZhbHVlIGludG8gdGhlIG5zXG4vKioqKioqLyBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuLyoqKioqKi8gXHQvLyBtb2RlICYgOHwxOiBiZWhhdmUgbGlrZSByZXF1aXJlXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18udCA9IGZ1bmN0aW9uKHZhbHVlLCBtb2RlKSB7XG4vKioqKioqLyBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4vKioqKioqLyBcdFx0aWYobW9kZSAmIDgpIHJldHVybiB2YWx1ZTtcbi8qKioqKiovIFx0XHRpZigobW9kZSAmIDQpICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgJiYgdmFsdWUuX19lc01vZHVsZSkgcmV0dXJuIHZhbHVlO1xuLyoqKioqKi8gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4vKioqKioqLyBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yKG5zKTtcbi8qKioqKiovIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkobnMsICdkZWZhdWx0JywgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdmFsdWUgfSk7XG4vKioqKioqLyBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuLyoqKioqKi8gXHRcdHJldHVybiBucztcbi8qKioqKiovIFx0fTtcbi8qKioqKiovXG4vKioqKioqLyBcdC8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG4vKioqKioqLyBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuLyoqKioqKi8gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuLyoqKioqKi8gXHRcdFx0ZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHsgcmV0dXJuIG1vZHVsZVsnZGVmYXVsdCddOyB9IDpcbi8qKioqKiovIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4vKioqKioqLyBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuLyoqKioqKi8gXHRcdHJldHVybiBnZXR0ZXI7XG4vKioqKioqLyBcdH07XG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGxcbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuLyoqKioqKi9cbi8qKioqKiovIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbi8qKioqKiovIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcbi8qKioqKiovXG4vKioqKioqL1xuLyoqKioqKi8gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbi8qKioqKiovIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gMCk7XG4vKioqKioqLyB9KVxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qKioqKiovIChbXG4vKiAwICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cblwidXNlIHN0cmljdFwiO1xuXG5cbnZhciBfdHlwZW9mID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTtcblxudmFyIF9jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0oKTtcblxudmFyIF9jbGlwYm9hcmRBY3Rpb24gPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDEpO1xuXG52YXIgX2NsaXBib2FyZEFjdGlvbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9jbGlwYm9hcmRBY3Rpb24pO1xuXG52YXIgX3RpbnlFbWl0dGVyID0gX193ZWJwYWNrX3JlcXVpcmVfXygzKTtcblxudmFyIF90aW55RW1pdHRlcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF90aW55RW1pdHRlcik7XG5cbnZhciBfZ29vZExpc3RlbmVyID0gX193ZWJwYWNrX3JlcXVpcmVfXyg0KTtcblxudmFyIF9nb29kTGlzdGVuZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZ29vZExpc3RlbmVyKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxuZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkgeyBpZiAoIXNlbGYpIHsgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkXCIpOyB9IHJldHVybiBjYWxsICYmICh0eXBlb2YgY2FsbCA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgY2FsbCA9PT0gXCJmdW5jdGlvblwiKSA/IGNhbGwgOiBzZWxmOyB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG4vKipcbiAqIEJhc2UgY2xhc3Mgd2hpY2ggdGFrZXMgb25lIG9yIG1vcmUgZWxlbWVudHMsIGFkZHMgZXZlbnQgbGlzdGVuZXJzIHRvIHRoZW0sXG4gKiBhbmQgaW5zdGFudGlhdGVzIGEgbmV3IGBDbGlwYm9hcmRBY3Rpb25gIG9uIGVhY2ggY2xpY2suXG4gKi9cbnZhciBDbGlwYm9hcmQgPSBmdW5jdGlvbiAoX0VtaXR0ZXIpIHtcbiAgICBfaW5oZXJpdHMoQ2xpcGJvYXJkLCBfRW1pdHRlcik7XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xIVE1MRWxlbWVudHxIVE1MQ29sbGVjdGlvbnxOb2RlTGlzdH0gdHJpZ2dlclxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAgICovXG4gICAgZnVuY3Rpb24gQ2xpcGJvYXJkKHRyaWdnZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIENsaXBib2FyZCk7XG5cbiAgICAgICAgdmFyIF90aGlzID0gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4odGhpcywgKENsaXBib2FyZC5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKENsaXBib2FyZCkpLmNhbGwodGhpcykpO1xuXG4gICAgICAgIF90aGlzLnJlc29sdmVPcHRpb25zKG9wdGlvbnMpO1xuICAgICAgICBfdGhpcy5saXN0ZW5DbGljayh0cmlnZ2VyKTtcbiAgICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlZmluZXMgaWYgYXR0cmlidXRlcyB3b3VsZCBiZSByZXNvbHZlZCB1c2luZyBpbnRlcm5hbCBzZXR0ZXIgZnVuY3Rpb25zXG4gICAgICogb3IgY3VzdG9tIGZ1bmN0aW9ucyB0aGF0IHdlcmUgcGFzc2VkIGluIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICAgICAqL1xuXG5cbiAgICBfY3JlYXRlQ2xhc3MoQ2xpcGJvYXJkLCBbe1xuICAgICAgICBrZXk6ICdyZXNvbHZlT3B0aW9ucycsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZXNvbHZlT3B0aW9ucygpIHtcbiAgICAgICAgICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiB7fTtcblxuICAgICAgICAgICAgdGhpcy5hY3Rpb24gPSB0eXBlb2Ygb3B0aW9ucy5hY3Rpb24gPT09ICdmdW5jdGlvbicgPyBvcHRpb25zLmFjdGlvbiA6IHRoaXMuZGVmYXVsdEFjdGlvbjtcbiAgICAgICAgICAgIHRoaXMudGFyZ2V0ID0gdHlwZW9mIG9wdGlvbnMudGFyZ2V0ID09PSAnZnVuY3Rpb24nID8gb3B0aW9ucy50YXJnZXQgOiB0aGlzLmRlZmF1bHRUYXJnZXQ7XG4gICAgICAgICAgICB0aGlzLnRleHQgPSB0eXBlb2Ygb3B0aW9ucy50ZXh0ID09PSAnZnVuY3Rpb24nID8gb3B0aW9ucy50ZXh0IDogdGhpcy5kZWZhdWx0VGV4dDtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyID0gX3R5cGVvZihvcHRpb25zLmNvbnRhaW5lcikgPT09ICdvYmplY3QnID8gb3B0aW9ucy5jb250YWluZXIgOiBkb2N1bWVudC5ib2R5O1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFkZHMgYSBjbGljayBldmVudCBsaXN0ZW5lciB0byB0aGUgcGFzc2VkIHRyaWdnZXIuXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfEhUTUxFbGVtZW50fEhUTUxDb2xsZWN0aW9ufE5vZGVMaXN0fSB0cmlnZ2VyXG4gICAgICAgICAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICdsaXN0ZW5DbGljaycsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBsaXN0ZW5DbGljayh0cmlnZ2VyKSB7XG4gICAgICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICAgICAgdGhpcy5saXN0ZW5lciA9ICgwLCBfZ29vZExpc3RlbmVyMi5kZWZhdWx0KSh0cmlnZ2VyLCAnY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIub25DbGljayhlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlZmluZXMgYSBuZXcgYENsaXBib2FyZEFjdGlvbmAgb24gZWFjaCBjbGljayBldmVudC5cbiAgICAgICAgICogQHBhcmFtIHtFdmVudH0gZVxuICAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnb25DbGljaycsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBvbkNsaWNrKGUpIHtcbiAgICAgICAgICAgIHZhciB0cmlnZ2VyID0gZS5kZWxlZ2F0ZVRhcmdldCB8fCBlLmN1cnJlbnRUYXJnZXQ7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmNsaXBib2FyZEFjdGlvbikge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xpcGJvYXJkQWN0aW9uID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jbGlwYm9hcmRBY3Rpb24gPSBuZXcgX2NsaXBib2FyZEFjdGlvbjIuZGVmYXVsdCh7XG4gICAgICAgICAgICAgICAgYWN0aW9uOiB0aGlzLmFjdGlvbih0cmlnZ2VyKSxcbiAgICAgICAgICAgICAgICB0YXJnZXQ6IHRoaXMudGFyZ2V0KHRyaWdnZXIpLFxuICAgICAgICAgICAgICAgIHRleHQ6IHRoaXMudGV4dCh0cmlnZ2VyKSxcbiAgICAgICAgICAgICAgICBjb250YWluZXI6IHRoaXMuY29udGFpbmVyLFxuICAgICAgICAgICAgICAgIHRyaWdnZXI6IHRyaWdnZXIsXG4gICAgICAgICAgICAgICAgZW1pdHRlcjogdGhpc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVmYXVsdCBgYWN0aW9uYCBsb29rdXAgZnVuY3Rpb24uXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gdHJpZ2dlclxuICAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnZGVmYXVsdEFjdGlvbicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBkZWZhdWx0QWN0aW9uKHRyaWdnZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBnZXRBdHRyaWJ1dGVWYWx1ZSgnYWN0aW9uJywgdHJpZ2dlcik7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVmYXVsdCBgdGFyZ2V0YCBsb29rdXAgZnVuY3Rpb24uXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gdHJpZ2dlclxuICAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnZGVmYXVsdFRhcmdldCcsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBkZWZhdWx0VGFyZ2V0KHRyaWdnZXIpIHtcbiAgICAgICAgICAgIHZhciBzZWxlY3RvciA9IGdldEF0dHJpYnV0ZVZhbHVlKCd0YXJnZXQnLCB0cmlnZ2VyKTtcblxuICAgICAgICAgICAgaWYgKHNlbGVjdG9yKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJldHVybnMgdGhlIHN1cHBvcnQgb2YgdGhlIGdpdmVuIGFjdGlvbiwgb3IgYWxsIGFjdGlvbnMgaWYgbm8gYWN0aW9uIGlzXG4gICAgICAgICAqIGdpdmVuLlxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gW2FjdGlvbl1cbiAgICAgICAgICovXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2RlZmF1bHRUZXh0JyxcblxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWZhdWx0IGB0ZXh0YCBsb29rdXAgZnVuY3Rpb24uXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gdHJpZ2dlclxuICAgICAgICAgKi9cbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGRlZmF1bHRUZXh0KHRyaWdnZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBnZXRBdHRyaWJ1dGVWYWx1ZSgndGV4dCcsIHRyaWdnZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlc3Ryb3kgbGlmZWN5Y2xlLlxuICAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnZGVzdHJveScsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBkZXN0cm95KCkge1xuICAgICAgICAgICAgdGhpcy5saXN0ZW5lci5kZXN0cm95KCk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmNsaXBib2FyZEFjdGlvbikge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xpcGJvYXJkQWN0aW9uLmRlc3Ryb3koKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNsaXBib2FyZEFjdGlvbiA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XSwgW3tcbiAgICAgICAga2V5OiAnaXNTdXBwb3J0ZWQnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gaXNTdXBwb3J0ZWQoKSB7XG4gICAgICAgICAgICB2YXIgYWN0aW9uID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBbJ2NvcHknLCAnY3V0J107XG5cbiAgICAgICAgICAgIHZhciBhY3Rpb25zID0gdHlwZW9mIGFjdGlvbiA9PT0gJ3N0cmluZycgPyBbYWN0aW9uXSA6IGFjdGlvbjtcbiAgICAgICAgICAgIHZhciBzdXBwb3J0ID0gISFkb2N1bWVudC5xdWVyeUNvbW1hbmRTdXBwb3J0ZWQ7XG5cbiAgICAgICAgICAgIGFjdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAoYWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgc3VwcG9ydCA9IHN1cHBvcnQgJiYgISFkb2N1bWVudC5xdWVyeUNvbW1hbmRTdXBwb3J0ZWQoYWN0aW9uKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gc3VwcG9ydDtcbiAgICAgICAgfVxuICAgIH1dKTtcblxuICAgIHJldHVybiBDbGlwYm9hcmQ7XG59KF90aW55RW1pdHRlcjIuZGVmYXVsdCk7XG5cbi8qKlxuICogSGVscGVyIGZ1bmN0aW9uIHRvIHJldHJpZXZlIGF0dHJpYnV0ZSB2YWx1ZS5cbiAqIEBwYXJhbSB7U3RyaW5nfSBzdWZmaXhcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICovXG5cblxuZnVuY3Rpb24gZ2V0QXR0cmlidXRlVmFsdWUoc3VmZml4LCBlbGVtZW50KSB7XG4gICAgdmFyIGF0dHJpYnV0ZSA9ICdkYXRhLWNsaXBib2FyZC0nICsgc3VmZml4O1xuXG4gICAgaWYgKCFlbGVtZW50Lmhhc0F0dHJpYnV0ZShhdHRyaWJ1dGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICByZXR1cm4gZWxlbWVudC5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBDbGlwYm9hcmQ7XG5cbi8qKiovIH0pLFxuLyogMSAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG5cInVzZSBzdHJpY3RcIjtcblxuXG52YXIgX3R5cGVvZiA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcInN5bWJvbFwiID8gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gdHlwZW9mIG9iajsgfSA6IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7IH07XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSBmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KCk7XG5cbnZhciBfc2VsZWN0ID0gX193ZWJwYWNrX3JlcXVpcmVfXygyKTtcblxudmFyIF9zZWxlY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfc2VsZWN0KTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxuLyoqXG4gKiBJbm5lciBjbGFzcyB3aGljaCBwZXJmb3JtcyBzZWxlY3Rpb24gZnJvbSBlaXRoZXIgYHRleHRgIG9yIGB0YXJnZXRgXG4gKiBwcm9wZXJ0aWVzIGFuZCB0aGVuIGV4ZWN1dGVzIGNvcHkgb3IgY3V0IG9wZXJhdGlvbnMuXG4gKi9cbnZhciBDbGlwYm9hcmRBY3Rpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBDbGlwYm9hcmRBY3Rpb24ob3B0aW9ucykge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQ2xpcGJvYXJkQWN0aW9uKTtcblxuICAgICAgICB0aGlzLnJlc29sdmVPcHRpb25zKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLmluaXRTZWxlY3Rpb24oKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIGJhc2UgcHJvcGVydGllcyBwYXNzZWQgZnJvbSBjb25zdHJ1Y3Rvci5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICAgICAqL1xuXG5cbiAgICBfY3JlYXRlQ2xhc3MoQ2xpcGJvYXJkQWN0aW9uLCBbe1xuICAgICAgICBrZXk6ICdyZXNvbHZlT3B0aW9ucycsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZXNvbHZlT3B0aW9ucygpIHtcbiAgICAgICAgICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiB7fTtcblxuICAgICAgICAgICAgdGhpcy5hY3Rpb24gPSBvcHRpb25zLmFjdGlvbjtcbiAgICAgICAgICAgIHRoaXMuY29udGFpbmVyID0gb3B0aW9ucy5jb250YWluZXI7XG4gICAgICAgICAgICB0aGlzLmVtaXR0ZXIgPSBvcHRpb25zLmVtaXR0ZXI7XG4gICAgICAgICAgICB0aGlzLnRhcmdldCA9IG9wdGlvbnMudGFyZ2V0O1xuICAgICAgICAgICAgdGhpcy50ZXh0ID0gb3B0aW9ucy50ZXh0O1xuICAgICAgICAgICAgdGhpcy50cmlnZ2VyID0gb3B0aW9ucy50cmlnZ2VyO1xuXG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkVGV4dCA9ICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY2lkZXMgd2hpY2ggc2VsZWN0aW9uIHN0cmF0ZWd5IGlzIGdvaW5nIHRvIGJlIGFwcGxpZWQgYmFzZWRcbiAgICAgICAgICogb24gdGhlIGV4aXN0ZW5jZSBvZiBgdGV4dGAgYW5kIGB0YXJnZXRgIHByb3BlcnRpZXMuXG4gICAgICAgICAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICdpbml0U2VsZWN0aW9uJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGluaXRTZWxlY3Rpb24oKSB7XG4gICAgICAgICAgICBpZiAodGhpcy50ZXh0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RGYWtlKCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMudGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RUYXJnZXQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgZmFrZSB0ZXh0YXJlYSBlbGVtZW50LCBzZXRzIGl0cyB2YWx1ZSBmcm9tIGB0ZXh0YCBwcm9wZXJ0eSxcbiAgICAgICAgICogYW5kIG1ha2VzIGEgc2VsZWN0aW9uIG9uIGl0LlxuICAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnc2VsZWN0RmFrZScsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZWxlY3RGYWtlKCkge1xuICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICAgICAgdmFyIGlzUlRMID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmdldEF0dHJpYnV0ZSgnZGlyJykgPT0gJ3J0bCc7XG5cbiAgICAgICAgICAgIHRoaXMucmVtb3ZlRmFrZSgpO1xuXG4gICAgICAgICAgICB0aGlzLmZha2VIYW5kbGVyQ2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzLnJlbW92ZUZha2UoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmZha2VIYW5kbGVyID0gdGhpcy5jb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLmZha2VIYW5kbGVyQ2FsbGJhY2spIHx8IHRydWU7XG5cbiAgICAgICAgICAgIHRoaXMuZmFrZUVsZW0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZXh0YXJlYScpO1xuICAgICAgICAgICAgLy8gUHJldmVudCB6b29taW5nIG9uIGlPU1xuICAgICAgICAgICAgdGhpcy5mYWtlRWxlbS5zdHlsZS5mb250U2l6ZSA9ICcxMnB0JztcbiAgICAgICAgICAgIC8vIFJlc2V0IGJveCBtb2RlbFxuICAgICAgICAgICAgdGhpcy5mYWtlRWxlbS5zdHlsZS5ib3JkZXIgPSAnMCc7XG4gICAgICAgICAgICB0aGlzLmZha2VFbGVtLnN0eWxlLnBhZGRpbmcgPSAnMCc7XG4gICAgICAgICAgICB0aGlzLmZha2VFbGVtLnN0eWxlLm1hcmdpbiA9ICcwJztcbiAgICAgICAgICAgIC8vIE1vdmUgZWxlbWVudCBvdXQgb2Ygc2NyZWVuIGhvcml6b250YWxseVxuICAgICAgICAgICAgdGhpcy5mYWtlRWxlbS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgICAgICAgICB0aGlzLmZha2VFbGVtLnN0eWxlW2lzUlRMID8gJ3JpZ2h0JyA6ICdsZWZ0J10gPSAnLTk5OTlweCc7XG4gICAgICAgICAgICAvLyBNb3ZlIGVsZW1lbnQgdG8gdGhlIHNhbWUgcG9zaXRpb24gdmVydGljYWxseVxuICAgICAgICAgICAgdmFyIHlQb3NpdGlvbiA9IHdpbmRvdy5wYWdlWU9mZnNldCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wO1xuICAgICAgICAgICAgdGhpcy5mYWtlRWxlbS5zdHlsZS50b3AgPSB5UG9zaXRpb24gKyAncHgnO1xuXG4gICAgICAgICAgICB0aGlzLmZha2VFbGVtLnNldEF0dHJpYnV0ZSgncmVhZG9ubHknLCAnJyk7XG4gICAgICAgICAgICB0aGlzLmZha2VFbGVtLnZhbHVlID0gdGhpcy50ZXh0O1xuXG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLmZha2VFbGVtKTtcblxuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFRleHQgPSAoMCwgX3NlbGVjdDIuZGVmYXVsdCkodGhpcy5mYWtlRWxlbSk7XG4gICAgICAgICAgICB0aGlzLmNvcHlUZXh0KCk7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogT25seSByZW1vdmVzIHRoZSBmYWtlIGVsZW1lbnQgYWZ0ZXIgYW5vdGhlciBjbGljayBldmVudCwgdGhhdCB3YXlcbiAgICAgICAgICogYSB1c2VyIGNhbiBoaXQgYEN0cmwrQ2AgdG8gY29weSBiZWNhdXNlIHNlbGVjdGlvbiBzdGlsbCBleGlzdHMuXG4gICAgICAgICAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICdyZW1vdmVGYWtlJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbW92ZUZha2UoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5mYWtlSGFuZGxlcikge1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5mYWtlSGFuZGxlckNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICB0aGlzLmZha2VIYW5kbGVyID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLmZha2VIYW5kbGVyQ2FsbGJhY2sgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5mYWtlRWxlbSkge1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGFpbmVyLnJlbW92ZUNoaWxkKHRoaXMuZmFrZUVsZW0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZmFrZUVsZW0gPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNlbGVjdHMgdGhlIGNvbnRlbnQgZnJvbSBlbGVtZW50IHBhc3NlZCBvbiBgdGFyZ2V0YCBwcm9wZXJ0eS5cbiAgICAgICAgICovXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3NlbGVjdFRhcmdldCcsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBzZWxlY3RUYXJnZXQoKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkVGV4dCA9ICgwLCBfc2VsZWN0Mi5kZWZhdWx0KSh0aGlzLnRhcmdldCk7XG4gICAgICAgICAgICB0aGlzLmNvcHlUZXh0KCk7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogRXhlY3V0ZXMgdGhlIGNvcHkgb3BlcmF0aW9uIGJhc2VkIG9uIHRoZSBjdXJyZW50IHNlbGVjdGlvbi5cbiAgICAgICAgICovXG5cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2NvcHlUZXh0JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvcHlUZXh0KCkge1xuICAgICAgICAgICAgdmFyIHN1Y2NlZWRlZCA9IHZvaWQgMDtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBzdWNjZWVkZWQgPSBkb2N1bWVudC5leGVjQ29tbWFuZCh0aGlzLmFjdGlvbik7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBzdWNjZWVkZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5oYW5kbGVSZXN1bHQoc3VjY2VlZGVkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBGaXJlcyBhbiBldmVudCBiYXNlZCBvbiB0aGUgY29weSBvcGVyYXRpb24gcmVzdWx0LlxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHN1Y2NlZWRlZFxuICAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnaGFuZGxlUmVzdWx0JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGhhbmRsZVJlc3VsdChzdWNjZWVkZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZW1pdHRlci5lbWl0KHN1Y2NlZWRlZCA/ICdzdWNjZXNzJyA6ICdlcnJvcicsIHtcbiAgICAgICAgICAgICAgICBhY3Rpb246IHRoaXMuYWN0aW9uLFxuICAgICAgICAgICAgICAgIHRleHQ6IHRoaXMuc2VsZWN0ZWRUZXh0LFxuICAgICAgICAgICAgICAgIHRyaWdnZXI6IHRoaXMudHJpZ2dlcixcbiAgICAgICAgICAgICAgICBjbGVhclNlbGVjdGlvbjogdGhpcy5jbGVhclNlbGVjdGlvbi5iaW5kKHRoaXMpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNb3ZlcyBmb2N1cyBhd2F5IGZyb20gYHRhcmdldGAgYW5kIGJhY2sgdG8gdGhlIHRyaWdnZXIsIHJlbW92ZXMgY3VycmVudCBzZWxlY3Rpb24uXG4gICAgICAgICAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICdjbGVhclNlbGVjdGlvbicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBjbGVhclNlbGVjdGlvbigpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRyaWdnZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXIuZm9jdXMoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgd2luZG93LmdldFNlbGVjdGlvbigpLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNldHMgdGhlIGBhY3Rpb25gIHRvIGJlIHBlcmZvcm1lZCB3aGljaCBjYW4gYmUgZWl0aGVyICdjb3B5JyBvciAnY3V0Jy5cbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGFjdGlvblxuICAgICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnZGVzdHJveScsXG5cblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVzdHJveSBsaWZlY3ljbGUuXG4gICAgICAgICAqL1xuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZGVzdHJveSgpIHtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlRmFrZSgpO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICdhY3Rpb24nLFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIHNldCgpIHtcbiAgICAgICAgICAgIHZhciBhY3Rpb24gPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6ICdjb3B5JztcblxuICAgICAgICAgICAgdGhpcy5fYWN0aW9uID0gYWN0aW9uO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5fYWN0aW9uICE9PSAnY29weScgJiYgdGhpcy5fYWN0aW9uICE9PSAnY3V0Jykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBcImFjdGlvblwiIHZhbHVlLCB1c2UgZWl0aGVyIFwiY29weVwiIG9yIFwiY3V0XCInKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIHRoZSBgYWN0aW9uYCBwcm9wZXJ0eS5cbiAgICAgICAgICogQHJldHVybiB7U3RyaW5nfVxuICAgICAgICAgKi9cbiAgICAgICAgLFxuICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hY3Rpb247XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogU2V0cyB0aGUgYHRhcmdldGAgcHJvcGVydHkgdXNpbmcgYW4gZWxlbWVudFxuICAgICAgICAgKiB0aGF0IHdpbGwgYmUgaGF2ZSBpdHMgY29udGVudCBjb3BpZWQuXG4gICAgICAgICAqIEBwYXJhbSB7RWxlbWVudH0gdGFyZ2V0XG4gICAgICAgICAqL1xuXG4gICAgfSwge1xuICAgICAgICBrZXk6ICd0YXJnZXQnLFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uIHNldCh0YXJnZXQpIHtcbiAgICAgICAgICAgIGlmICh0YXJnZXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGlmICh0YXJnZXQgJiYgKHR5cGVvZiB0YXJnZXQgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKHRhcmdldCkpID09PSAnb2JqZWN0JyAmJiB0YXJnZXQubm9kZVR5cGUgPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuYWN0aW9uID09PSAnY29weScgJiYgdGFyZ2V0Lmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIFwidGFyZ2V0XCIgYXR0cmlidXRlLiBQbGVhc2UgdXNlIFwicmVhZG9ubHlcIiBpbnN0ZWFkIG9mIFwiZGlzYWJsZWRcIiBhdHRyaWJ1dGUnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmFjdGlvbiA9PT0gJ2N1dCcgJiYgKHRhcmdldC5oYXNBdHRyaWJ1dGUoJ3JlYWRvbmx5JykgfHwgdGFyZ2V0Lmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBcInRhcmdldFwiIGF0dHJpYnV0ZS4gWW91IGNhblxcJ3QgY3V0IHRleHQgZnJvbSBlbGVtZW50cyB3aXRoIFwicmVhZG9ubHlcIiBvciBcImRpc2FibGVkXCIgYXR0cmlidXRlcycpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBcInRhcmdldFwiIHZhbHVlLCB1c2UgYSB2YWxpZCBFbGVtZW50Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldHMgdGhlIGB0YXJnZXRgIHByb3BlcnR5LlxuICAgICAgICAgKiBAcmV0dXJuIHtTdHJpbmd8SFRNTEVsZW1lbnR9XG4gICAgICAgICAqL1xuICAgICAgICAsXG4gICAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RhcmdldDtcbiAgICAgICAgfVxuICAgIH1dKTtcblxuICAgIHJldHVybiBDbGlwYm9hcmRBY3Rpb247XG59KCk7XG5cbm1vZHVsZS5leHBvcnRzID0gQ2xpcGJvYXJkQWN0aW9uO1xuXG4vKioqLyB9KSxcbi8qIDIgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuZnVuY3Rpb24gc2VsZWN0KGVsZW1lbnQpIHtcbiAgICB2YXIgc2VsZWN0ZWRUZXh0O1xuXG4gICAgaWYgKGVsZW1lbnQubm9kZU5hbWUgPT09ICdTRUxFQ1QnKSB7XG4gICAgICAgIGVsZW1lbnQuZm9jdXMoKTtcblxuICAgICAgICBzZWxlY3RlZFRleHQgPSBlbGVtZW50LnZhbHVlO1xuICAgIH1cbiAgICBlbHNlIGlmIChlbGVtZW50Lm5vZGVOYW1lID09PSAnSU5QVVQnIHx8IGVsZW1lbnQubm9kZU5hbWUgPT09ICdURVhUQVJFQScpIHtcbiAgICAgICAgdmFyIGlzUmVhZE9ubHkgPSBlbGVtZW50Lmhhc0F0dHJpYnV0ZSgncmVhZG9ubHknKTtcblxuICAgICAgICBpZiAoIWlzUmVhZE9ubHkpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdyZWFkb25seScsICcnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGVsZW1lbnQuc2VsZWN0KCk7XG4gICAgICAgIGVsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UoMCwgZWxlbWVudC52YWx1ZS5sZW5ndGgpO1xuXG4gICAgICAgIGlmICghaXNSZWFkT25seSkge1xuICAgICAgICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ3JlYWRvbmx5Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBzZWxlY3RlZFRleHQgPSBlbGVtZW50LnZhbHVlO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaWYgKGVsZW1lbnQuaGFzQXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnKSkge1xuICAgICAgICAgICAgZWxlbWVudC5mb2N1cygpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICAgICAgdmFyIHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcblxuICAgICAgICByYW5nZS5zZWxlY3ROb2RlQ29udGVudHMoZWxlbWVudCk7XG4gICAgICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICAgICAgc2VsZWN0aW9uLmFkZFJhbmdlKHJhbmdlKTtcblxuICAgICAgICBzZWxlY3RlZFRleHQgPSBzZWxlY3Rpb24udG9TdHJpbmcoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VsZWN0ZWRUZXh0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNlbGVjdDtcblxuXG4vKioqLyB9KSxcbi8qIDMgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuZnVuY3Rpb24gRSAoKSB7XG4gIC8vIEtlZXAgdGhpcyBlbXB0eSBzbyBpdCdzIGVhc2llciB0byBpbmhlcml0IGZyb21cbiAgLy8gKHZpYSBodHRwczovL2dpdGh1Yi5jb20vbGlwc21hY2sgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vc2NvdHRjb3JnYW4vdGlueS1lbWl0dGVyL2lzc3Vlcy8zKVxufVxuXG5FLnByb3RvdHlwZSA9IHtcbiAgb246IGZ1bmN0aW9uIChuYW1lLCBjYWxsYmFjaywgY3R4KSB7XG4gICAgdmFyIGUgPSB0aGlzLmUgfHwgKHRoaXMuZSA9IHt9KTtcblxuICAgIChlW25hbWVdIHx8IChlW25hbWVdID0gW10pKS5wdXNoKHtcbiAgICAgIGZuOiBjYWxsYmFjayxcbiAgICAgIGN0eDogY3R4XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBvbmNlOiBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2ssIGN0eCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBmdW5jdGlvbiBsaXN0ZW5lciAoKSB7XG4gICAgICBzZWxmLm9mZihuYW1lLCBsaXN0ZW5lcik7XG4gICAgICBjYWxsYmFjay5hcHBseShjdHgsIGFyZ3VtZW50cyk7XG4gICAgfTtcblxuICAgIGxpc3RlbmVyLl8gPSBjYWxsYmFja1xuICAgIHJldHVybiB0aGlzLm9uKG5hbWUsIGxpc3RlbmVyLCBjdHgpO1xuICB9LFxuXG4gIGVtaXQ6IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdmFyIGRhdGEgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgdmFyIGV2dEFyciA9ICgodGhpcy5lIHx8ICh0aGlzLmUgPSB7fSkpW25hbWVdIHx8IFtdKS5zbGljZSgpO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIgbGVuID0gZXZ0QXJyLmxlbmd0aDtcblxuICAgIGZvciAoaTsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBldnRBcnJbaV0uZm4uYXBwbHkoZXZ0QXJyW2ldLmN0eCwgZGF0YSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgb2ZmOiBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgZSA9IHRoaXMuZSB8fCAodGhpcy5lID0ge30pO1xuICAgIHZhciBldnRzID0gZVtuYW1lXTtcbiAgICB2YXIgbGl2ZUV2ZW50cyA9IFtdO1xuXG4gICAgaWYgKGV2dHMgJiYgY2FsbGJhY2spIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBldnRzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIGlmIChldnRzW2ldLmZuICE9PSBjYWxsYmFjayAmJiBldnRzW2ldLmZuLl8gIT09IGNhbGxiYWNrKVxuICAgICAgICAgIGxpdmVFdmVudHMucHVzaChldnRzW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZW1vdmUgZXZlbnQgZnJvbSBxdWV1ZSB0byBwcmV2ZW50IG1lbW9yeSBsZWFrXG4gICAgLy8gU3VnZ2VzdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9sYXpkXG4gICAgLy8gUmVmOiBodHRwczovL2dpdGh1Yi5jb20vc2NvdHRjb3JnYW4vdGlueS1lbWl0dGVyL2NvbW1pdC9jNmViZmFhOWJjOTczYjMzZDExMGE4NGEzMDc3NDJiN2NmOTRjOTUzI2NvbW1pdGNvbW1lbnQtNTAyNDkxMFxuXG4gICAgKGxpdmVFdmVudHMubGVuZ3RoKVxuICAgICAgPyBlW25hbWVdID0gbGl2ZUV2ZW50c1xuICAgICAgOiBkZWxldGUgZVtuYW1lXTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEU7XG5cblxuLyoqKi8gfSksXG4vKiA0ICovXG4vKioqLyAoZnVuY3Rpb24obW9kdWxlLCBleHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSB7XG5cbnZhciBpcyA9IF9fd2VicGFja19yZXF1aXJlX18oNSk7XG52YXIgZGVsZWdhdGUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKDYpO1xuXG4vKipcbiAqIFZhbGlkYXRlcyBhbGwgcGFyYW1zIGFuZCBjYWxscyB0aGUgcmlnaHRcbiAqIGxpc3RlbmVyIGZ1bmN0aW9uIGJhc2VkIG9uIGl0cyB0YXJnZXQgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xIVE1MRWxlbWVudHxIVE1MQ29sbGVjdGlvbnxOb2RlTGlzdH0gdGFyZ2V0XG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gbGlzdGVuKHRhcmdldCwgdHlwZSwgY2FsbGJhY2spIHtcbiAgICBpZiAoIXRhcmdldCAmJiAhdHlwZSAmJiAhY2FsbGJhY2spIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHJlcXVpcmVkIGFyZ3VtZW50cycpO1xuICAgIH1cblxuICAgIGlmICghaXMuc3RyaW5nKHR5cGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1NlY29uZCBhcmd1bWVudCBtdXN0IGJlIGEgU3RyaW5nJyk7XG4gICAgfVxuXG4gICAgaWYgKCFpcy5mbihjYWxsYmFjaykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhpcmQgYXJndW1lbnQgbXVzdCBiZSBhIEZ1bmN0aW9uJyk7XG4gICAgfVxuXG4gICAgaWYgKGlzLm5vZGUodGFyZ2V0KSkge1xuICAgICAgICByZXR1cm4gbGlzdGVuTm9kZSh0YXJnZXQsIHR5cGUsIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoaXMubm9kZUxpc3QodGFyZ2V0KSkge1xuICAgICAgICByZXR1cm4gbGlzdGVuTm9kZUxpc3QodGFyZ2V0LCB0eXBlLCBjYWxsYmFjayk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGlzLnN0cmluZyh0YXJnZXQpKSB7XG4gICAgICAgIHJldHVybiBsaXN0ZW5TZWxlY3Rvcih0YXJnZXQsIHR5cGUsIGNhbGxiYWNrKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IG11c3QgYmUgYSBTdHJpbmcsIEhUTUxFbGVtZW50LCBIVE1MQ29sbGVjdGlvbiwgb3IgTm9kZUxpc3QnKTtcbiAgICB9XG59XG5cbi8qKlxuICogQWRkcyBhbiBldmVudCBsaXN0ZW5lciB0byBhIEhUTUwgZWxlbWVudFxuICogYW5kIHJldHVybnMgYSByZW1vdmUgbGlzdGVuZXIgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gbm9kZVxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGxpc3Rlbk5vZGUobm9kZSwgdHlwZSwgY2FsbGJhY2spIHtcbiAgICBub2RlLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgZGVzdHJveTogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBub2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vKipcbiAqIEFkZCBhbiBldmVudCBsaXN0ZW5lciB0byBhIGxpc3Qgb2YgSFRNTCBlbGVtZW50c1xuICogYW5kIHJldHVybnMgYSByZW1vdmUgbGlzdGVuZXIgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHtOb2RlTGlzdHxIVE1MQ29sbGVjdGlvbn0gbm9kZUxpc3RcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBsaXN0ZW5Ob2RlTGlzdChub2RlTGlzdCwgdHlwZSwgY2FsbGJhY2spIHtcbiAgICBBcnJheS5wcm90b3R5cGUuZm9yRWFjaC5jYWxsKG5vZGVMaXN0LCBmdW5jdGlvbihub2RlKSB7XG4gICAgICAgIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBjYWxsYmFjayk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBkZXN0cm95OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIEFycmF5LnByb3RvdHlwZS5mb3JFYWNoLmNhbGwobm9kZUxpc3QsIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgICAgICAgICAgICBub2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogQWRkIGFuIGV2ZW50IGxpc3RlbmVyIHRvIGEgc2VsZWN0b3JcbiAqIGFuZCByZXR1cm5zIGEgcmVtb3ZlIGxpc3RlbmVyIGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWxlY3RvclxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGxpc3RlblNlbGVjdG9yKHNlbGVjdG9yLCB0eXBlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBkZWxlZ2F0ZShkb2N1bWVudC5ib2R5LCBzZWxlY3RvciwgdHlwZSwgY2FsbGJhY2spO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RlbjtcblxuXG4vKioqLyB9KSxcbi8qIDUgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxuLyoqXG4gKiBDaGVjayBpZiBhcmd1bWVudCBpcyBhIEhUTUwgZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsdWVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmV4cG9ydHMubm9kZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWRcbiAgICAgICAgJiYgdmFsdWUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudFxuICAgICAgICAmJiB2YWx1ZS5ub2RlVHlwZSA9PT0gMTtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgYXJndW1lbnQgaXMgYSBsaXN0IG9mIEhUTUwgZWxlbWVudHMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbHVlXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5leHBvcnRzLm5vZGVMaXN0ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICB2YXIgdHlwZSA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG5cbiAgICByZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZFxuICAgICAgICAmJiAodHlwZSA9PT0gJ1tvYmplY3QgTm9kZUxpc3RdJyB8fCB0eXBlID09PSAnW29iamVjdCBIVE1MQ29sbGVjdGlvbl0nKVxuICAgICAgICAmJiAoJ2xlbmd0aCcgaW4gdmFsdWUpXG4gICAgICAgICYmICh2YWx1ZS5sZW5ndGggPT09IDAgfHwgZXhwb3J0cy5ub2RlKHZhbHVlWzBdKSk7XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIGFyZ3VtZW50IGlzIGEgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWx1ZVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZXhwb3J0cy5zdHJpbmcgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnXG4gICAgICAgIHx8IHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nO1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBhcmd1bWVudCBpcyBhIGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWx1ZVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZXhwb3J0cy5mbiA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdmFyIHR5cGUgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuXG4gICAgcmV0dXJuIHR5cGUgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59O1xuXG5cbi8qKiovIH0pLFxuLyogNiAqL1xuLyoqKi8gKGZ1bmN0aW9uKG1vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xuXG52YXIgY2xvc2VzdCA9IF9fd2VicGFja19yZXF1aXJlX18oNyk7XG5cbi8qKlxuICogRGVsZWdhdGVzIGV2ZW50IHRvIGEgc2VsZWN0b3IuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge1N0cmluZ30gc2VsZWN0b3JcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICogQHBhcmFtIHtCb29sZWFufSB1c2VDYXB0dXJlXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIF9kZWxlZ2F0ZShlbGVtZW50LCBzZWxlY3RvciwgdHlwZSwgY2FsbGJhY2ssIHVzZUNhcHR1cmUpIHtcbiAgICB2YXIgbGlzdGVuZXJGbiA9IGxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXJGbiwgdXNlQ2FwdHVyZSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBkZXN0cm95OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lckZuLCB1c2VDYXB0dXJlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBEZWxlZ2F0ZXMgZXZlbnQgdG8gYSBzZWxlY3Rvci5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR8U3RyaW5nfEFycmF5fSBbZWxlbWVudHNdXG4gKiBAcGFyYW0ge1N0cmluZ30gc2VsZWN0b3JcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICogQHBhcmFtIHtCb29sZWFufSB1c2VDYXB0dXJlXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGRlbGVnYXRlKGVsZW1lbnRzLCBzZWxlY3RvciwgdHlwZSwgY2FsbGJhY2ssIHVzZUNhcHR1cmUpIHtcbiAgICAvLyBIYW5kbGUgdGhlIHJlZ3VsYXIgRWxlbWVudCB1c2FnZVxuICAgIGlmICh0eXBlb2YgZWxlbWVudHMuYWRkRXZlbnRMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gX2RlbGVnYXRlLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIEVsZW1lbnQtbGVzcyB1c2FnZSwgaXQgZGVmYXVsdHMgdG8gZ2xvYmFsIGRlbGVnYXRpb25cbiAgICBpZiAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gVXNlIGBkb2N1bWVudGAgYXMgdGhlIGZpcnN0IHBhcmFtZXRlciwgdGhlbiBhcHBseSBhcmd1bWVudHNcbiAgICAgICAgLy8gVGhpcyBpcyBhIHNob3J0IHdheSB0byAudW5zaGlmdCBgYXJndW1lbnRzYCB3aXRob3V0IHJ1bm5pbmcgaW50byBkZW9wdGltaXphdGlvbnNcbiAgICAgICAgcmV0dXJuIF9kZWxlZ2F0ZS5iaW5kKG51bGwsIGRvY3VtZW50KS5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBTZWxlY3Rvci1iYXNlZCB1c2FnZVxuICAgIGlmICh0eXBlb2YgZWxlbWVudHMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGVsZW1lbnRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChlbGVtZW50cyk7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIEFycmF5LWxpa2UgYmFzZWQgdXNhZ2VcbiAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKGVsZW1lbnRzLCBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gX2RlbGVnYXRlKGVsZW1lbnQsIHNlbGVjdG9yLCB0eXBlLCBjYWxsYmFjaywgdXNlQ2FwdHVyZSk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogRmluZHMgY2xvc2VzdCBtYXRjaCBhbmQgaW52b2tlcyBjYWxsYmFjay5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWxlY3RvclxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gbGlzdGVuZXIoZWxlbWVudCwgc2VsZWN0b3IsIHR5cGUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgZS5kZWxlZ2F0ZVRhcmdldCA9IGNsb3Nlc3QoZS50YXJnZXQsIHNlbGVjdG9yKTtcblxuICAgICAgICBpZiAoZS5kZWxlZ2F0ZVRhcmdldCkge1xuICAgICAgICAgICAgY2FsbGJhY2suY2FsbChlbGVtZW50LCBlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkZWxlZ2F0ZTtcblxuXG4vKioqLyB9KSxcbi8qIDcgKi9cbi8qKiovIChmdW5jdGlvbihtb2R1bGUsIGV4cG9ydHMpIHtcblxudmFyIERPQ1VNRU5UX05PREVfVFlQRSA9IDk7XG5cbi8qKlxuICogQSBwb2x5ZmlsbCBmb3IgRWxlbWVudC5tYXRjaGVzKClcbiAqL1xuaWYgKHR5cGVvZiBFbGVtZW50ICE9PSAndW5kZWZpbmVkJyAmJiAhRWxlbWVudC5wcm90b3R5cGUubWF0Y2hlcykge1xuICAgIHZhciBwcm90byA9IEVsZW1lbnQucHJvdG90eXBlO1xuXG4gICAgcHJvdG8ubWF0Y2hlcyA9IHByb3RvLm1hdGNoZXNTZWxlY3RvciB8fFxuICAgICAgICAgICAgICAgICAgICBwcm90by5tb3pNYXRjaGVzU2VsZWN0b3IgfHxcbiAgICAgICAgICAgICAgICAgICAgcHJvdG8ubXNNYXRjaGVzU2VsZWN0b3IgfHxcbiAgICAgICAgICAgICAgICAgICAgcHJvdG8ub01hdGNoZXNTZWxlY3RvciB8fFxuICAgICAgICAgICAgICAgICAgICBwcm90by53ZWJraXRNYXRjaGVzU2VsZWN0b3I7XG59XG5cbi8qKlxuICogRmluZHMgdGhlIGNsb3Nlc3QgcGFyZW50IHRoYXQgbWF0Y2hlcyBhIHNlbGVjdG9yLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtTdHJpbmd9IHNlbGVjdG9yXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gY2xvc2VzdCAoZWxlbWVudCwgc2VsZWN0b3IpIHtcbiAgICB3aGlsZSAoZWxlbWVudCAmJiBlbGVtZW50Lm5vZGVUeXBlICE9PSBET0NVTUVOVF9OT0RFX1RZUEUpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBlbGVtZW50Lm1hdGNoZXMgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgICAgICAgIGVsZW1lbnQubWF0Y2hlcyhzZWxlY3RvcikpIHtcbiAgICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xuICAgIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjbG9zZXN0O1xuXG5cbi8qKiovIH0pXG4vKioqKioqLyBdKTtcbn0pO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2NsaXBib2FyZC9kaXN0L2NsaXBib2FyZC5qc1xuLy8gbW9kdWxlIGlkID0gMTlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiOyhmdW5jdGlvbiAoKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuXHQvKipcblx0ICogQHByZXNlcnZlIEZhc3RDbGljazogcG9seWZpbGwgdG8gcmVtb3ZlIGNsaWNrIGRlbGF5cyBvbiBicm93c2VycyB3aXRoIHRvdWNoIFVJcy5cblx0ICpcblx0ICogQGNvZGluZ3N0YW5kYXJkIGZ0bGFicy1qc3YyXG5cdCAqIEBjb3B5cmlnaHQgVGhlIEZpbmFuY2lhbCBUaW1lcyBMaW1pdGVkIFtBbGwgUmlnaHRzIFJlc2VydmVkXVxuXHQgKiBAbGljZW5zZSBNSVQgTGljZW5zZSAoc2VlIExJQ0VOU0UudHh0KVxuXHQgKi9cblxuXHQvKmpzbGludCBicm93c2VyOnRydWUsIG5vZGU6dHJ1ZSovXG5cdC8qZ2xvYmFsIGRlZmluZSwgRXZlbnQsIE5vZGUqL1xuXG5cblx0LyoqXG5cdCAqIEluc3RhbnRpYXRlIGZhc3QtY2xpY2tpbmcgbGlzdGVuZXJzIG9uIHRoZSBzcGVjaWZpZWQgbGF5ZXIuXG5cdCAqXG5cdCAqIEBjb25zdHJ1Y3RvclxuXHQgKiBAcGFyYW0ge0VsZW1lbnR9IGxheWVyIFRoZSBsYXllciB0byBsaXN0ZW4gb25cblx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zPXt9XSBUaGUgb3B0aW9ucyB0byBvdmVycmlkZSB0aGUgZGVmYXVsdHNcblx0ICovXG5cdGZ1bmN0aW9uIEZhc3RDbGljayhsYXllciwgb3B0aW9ucykge1xuXHRcdHZhciBvbGRPbkNsaWNrO1xuXG5cdFx0b3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cblx0XHQvKipcblx0XHQgKiBXaGV0aGVyIGEgY2xpY2sgaXMgY3VycmVudGx5IGJlaW5nIHRyYWNrZWQuXG5cdFx0ICpcblx0XHQgKiBAdHlwZSBib29sZWFuXG5cdFx0ICovXG5cdFx0dGhpcy50cmFja2luZ0NsaWNrID0gZmFsc2U7XG5cblxuXHRcdC8qKlxuXHRcdCAqIFRpbWVzdGFtcCBmb3Igd2hlbiBjbGljayB0cmFja2luZyBzdGFydGVkLlxuXHRcdCAqXG5cdFx0ICogQHR5cGUgbnVtYmVyXG5cdFx0ICovXG5cdFx0dGhpcy50cmFja2luZ0NsaWNrU3RhcnQgPSAwO1xuXG5cblx0XHQvKipcblx0XHQgKiBUaGUgZWxlbWVudCBiZWluZyB0cmFja2VkIGZvciBhIGNsaWNrLlxuXHRcdCAqXG5cdFx0ICogQHR5cGUgRXZlbnRUYXJnZXRcblx0XHQgKi9cblx0XHR0aGlzLnRhcmdldEVsZW1lbnQgPSBudWxsO1xuXG5cblx0XHQvKipcblx0XHQgKiBYLWNvb3JkaW5hdGUgb2YgdG91Y2ggc3RhcnQgZXZlbnQuXG5cdFx0ICpcblx0XHQgKiBAdHlwZSBudW1iZXJcblx0XHQgKi9cblx0XHR0aGlzLnRvdWNoU3RhcnRYID0gMDtcblxuXG5cdFx0LyoqXG5cdFx0ICogWS1jb29yZGluYXRlIG9mIHRvdWNoIHN0YXJ0IGV2ZW50LlxuXHRcdCAqXG5cdFx0ICogQHR5cGUgbnVtYmVyXG5cdFx0ICovXG5cdFx0dGhpcy50b3VjaFN0YXJ0WSA9IDA7XG5cblxuXHRcdC8qKlxuXHRcdCAqIElEIG9mIHRoZSBsYXN0IHRvdWNoLCByZXRyaWV2ZWQgZnJvbSBUb3VjaC5pZGVudGlmaWVyLlxuXHRcdCAqXG5cdFx0ICogQHR5cGUgbnVtYmVyXG5cdFx0ICovXG5cdFx0dGhpcy5sYXN0VG91Y2hJZGVudGlmaWVyID0gMDtcblxuXG5cdFx0LyoqXG5cdFx0ICogVG91Y2htb3ZlIGJvdW5kYXJ5LCBiZXlvbmQgd2hpY2ggYSBjbGljayB3aWxsIGJlIGNhbmNlbGxlZC5cblx0XHQgKlxuXHRcdCAqIEB0eXBlIG51bWJlclxuXHRcdCAqL1xuXHRcdHRoaXMudG91Y2hCb3VuZGFyeSA9IG9wdGlvbnMudG91Y2hCb3VuZGFyeSB8fCAxMDtcblxuXG5cdFx0LyoqXG5cdFx0ICogVGhlIEZhc3RDbGljayBsYXllci5cblx0XHQgKlxuXHRcdCAqIEB0eXBlIEVsZW1lbnRcblx0XHQgKi9cblx0XHR0aGlzLmxheWVyID0gbGF5ZXI7XG5cblx0XHQvKipcblx0XHQgKiBUaGUgbWluaW11bSB0aW1lIGJldHdlZW4gdGFwKHRvdWNoc3RhcnQgYW5kIHRvdWNoZW5kKSBldmVudHNcblx0XHQgKlxuXHRcdCAqIEB0eXBlIG51bWJlclxuXHRcdCAqL1xuXHRcdHRoaXMudGFwRGVsYXkgPSBvcHRpb25zLnRhcERlbGF5IHx8IDIwMDtcblxuXHRcdC8qKlxuXHRcdCAqIFRoZSBtYXhpbXVtIHRpbWUgZm9yIGEgdGFwXG5cdFx0ICpcblx0XHQgKiBAdHlwZSBudW1iZXJcblx0XHQgKi9cblx0XHR0aGlzLnRhcFRpbWVvdXQgPSBvcHRpb25zLnRhcFRpbWVvdXQgfHwgNzAwO1xuXG5cdFx0aWYgKEZhc3RDbGljay5ub3ROZWVkZWQobGF5ZXIpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gU29tZSBvbGQgdmVyc2lvbnMgb2YgQW5kcm9pZCBkb24ndCBoYXZlIEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kXG5cdFx0ZnVuY3Rpb24gYmluZChtZXRob2QsIGNvbnRleHQpIHtcblx0XHRcdHJldHVybiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ldGhvZC5hcHBseShjb250ZXh0LCBhcmd1bWVudHMpOyB9O1xuXHRcdH1cblxuXG5cdFx0dmFyIG1ldGhvZHMgPSBbJ29uTW91c2UnLCAnb25DbGljaycsICdvblRvdWNoU3RhcnQnLCAnb25Ub3VjaE1vdmUnLCAnb25Ub3VjaEVuZCcsICdvblRvdWNoQ2FuY2VsJ107XG5cdFx0dmFyIGNvbnRleHQgPSB0aGlzO1xuXHRcdGZvciAodmFyIGkgPSAwLCBsID0gbWV0aG9kcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcblx0XHRcdGNvbnRleHRbbWV0aG9kc1tpXV0gPSBiaW5kKGNvbnRleHRbbWV0aG9kc1tpXV0sIGNvbnRleHQpO1xuXHRcdH1cblxuXHRcdC8vIFNldCB1cCBldmVudCBoYW5kbGVycyBhcyByZXF1aXJlZFxuXHRcdGlmIChkZXZpY2VJc0FuZHJvaWQpIHtcblx0XHRcdGxheWVyLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlb3ZlcicsIHRoaXMub25Nb3VzZSwgdHJ1ZSk7XG5cdFx0XHRsYXllci5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB0aGlzLm9uTW91c2UsIHRydWUpO1xuXHRcdFx0bGF5ZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMub25Nb3VzZSwgdHJ1ZSk7XG5cdFx0fVxuXG5cdFx0bGF5ZXIuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLm9uQ2xpY2ssIHRydWUpO1xuXHRcdGxheWVyLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCB0aGlzLm9uVG91Y2hTdGFydCwgZmFsc2UpO1xuXHRcdGxheWVyLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRoaXMub25Ub3VjaE1vdmUsIGZhbHNlKTtcblx0XHRsYXllci5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIHRoaXMub25Ub3VjaEVuZCwgZmFsc2UpO1xuXHRcdGxheWVyLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoY2FuY2VsJywgdGhpcy5vblRvdWNoQ2FuY2VsLCBmYWxzZSk7XG5cblx0XHQvLyBIYWNrIGlzIHJlcXVpcmVkIGZvciBicm93c2VycyB0aGF0IGRvbid0IHN1cHBvcnQgRXZlbnQjc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uIChlLmcuIEFuZHJvaWQgMilcblx0XHQvLyB3aGljaCBpcyBob3cgRmFzdENsaWNrIG5vcm1hbGx5IHN0b3BzIGNsaWNrIGV2ZW50cyBidWJibGluZyB0byBjYWxsYmFja3MgcmVnaXN0ZXJlZCBvbiB0aGUgRmFzdENsaWNrXG5cdFx0Ly8gbGF5ZXIgd2hlbiB0aGV5IGFyZSBjYW5jZWxsZWQuXG5cdFx0aWYgKCFFdmVudC5wcm90b3R5cGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKSB7XG5cdFx0XHRsYXllci5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgY2FsbGJhY2ssIGNhcHR1cmUpIHtcblx0XHRcdFx0dmFyIHJtdiA9IE5vZGUucHJvdG90eXBlLnJlbW92ZUV2ZW50TGlzdGVuZXI7XG5cdFx0XHRcdGlmICh0eXBlID09PSAnY2xpY2snKSB7XG5cdFx0XHRcdFx0cm12LmNhbGwobGF5ZXIsIHR5cGUsIGNhbGxiYWNrLmhpamFja2VkIHx8IGNhbGxiYWNrLCBjYXB0dXJlKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRybXYuY2FsbChsYXllciwgdHlwZSwgY2FsbGJhY2ssIGNhcHR1cmUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0XHRsYXllci5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgY2FsbGJhY2ssIGNhcHR1cmUpIHtcblx0XHRcdFx0dmFyIGFkdiA9IE5vZGUucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXI7XG5cdFx0XHRcdGlmICh0eXBlID09PSAnY2xpY2snKSB7XG5cdFx0XHRcdFx0YWR2LmNhbGwobGF5ZXIsIHR5cGUsIGNhbGxiYWNrLmhpamFja2VkIHx8IChjYWxsYmFjay5oaWphY2tlZCA9IGZ1bmN0aW9uKGV2ZW50KSB7XG5cdFx0XHRcdFx0XHRpZiAoIWV2ZW50LnByb3BhZ2F0aW9uU3RvcHBlZCkge1xuXHRcdFx0XHRcdFx0XHRjYWxsYmFjayhldmVudCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSksIGNhcHR1cmUpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGFkdi5jYWxsKGxheWVyLCB0eXBlLCBjYWxsYmFjaywgY2FwdHVyZSk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Ly8gSWYgYSBoYW5kbGVyIGlzIGFscmVhZHkgZGVjbGFyZWQgaW4gdGhlIGVsZW1lbnQncyBvbmNsaWNrIGF0dHJpYnV0ZSwgaXQgd2lsbCBiZSBmaXJlZCBiZWZvcmVcblx0XHQvLyBGYXN0Q2xpY2sncyBvbkNsaWNrIGhhbmRsZXIuIEZpeCB0aGlzIGJ5IHB1bGxpbmcgb3V0IHRoZSB1c2VyLWRlZmluZWQgaGFuZGxlciBmdW5jdGlvbiBhbmRcblx0XHQvLyBhZGRpbmcgaXQgYXMgbGlzdGVuZXIuXG5cdFx0aWYgKHR5cGVvZiBsYXllci5vbmNsaWNrID09PSAnZnVuY3Rpb24nKSB7XG5cblx0XHRcdC8vIEFuZHJvaWQgYnJvd3NlciBvbiBhdCBsZWFzdCAzLjIgcmVxdWlyZXMgYSBuZXcgcmVmZXJlbmNlIHRvIHRoZSBmdW5jdGlvbiBpbiBsYXllci5vbmNsaWNrXG5cdFx0XHQvLyAtIHRoZSBvbGQgb25lIHdvbid0IHdvcmsgaWYgcGFzc2VkIHRvIGFkZEV2ZW50TGlzdGVuZXIgZGlyZWN0bHkuXG5cdFx0XHRvbGRPbkNsaWNrID0gbGF5ZXIub25jbGljaztcblx0XHRcdGxheWVyLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcblx0XHRcdFx0b2xkT25DbGljayhldmVudCk7XG5cdFx0XHR9LCBmYWxzZSk7XG5cdFx0XHRsYXllci5vbmNsaWNrID0gbnVsbDtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0KiBXaW5kb3dzIFBob25lIDguMSBmYWtlcyB1c2VyIGFnZW50IHN0cmluZyB0byBsb29rIGxpa2UgQW5kcm9pZCBhbmQgaVBob25lLlxuXHQqXG5cdCogQHR5cGUgYm9vbGVhblxuXHQqL1xuXHR2YXIgZGV2aWNlSXNXaW5kb3dzUGhvbmUgPSBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoXCJXaW5kb3dzIFBob25lXCIpID49IDA7XG5cblx0LyoqXG5cdCAqIEFuZHJvaWQgcmVxdWlyZXMgZXhjZXB0aW9ucy5cblx0ICpcblx0ICogQHR5cGUgYm9vbGVhblxuXHQgKi9cblx0dmFyIGRldmljZUlzQW5kcm9pZCA9IG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignQW5kcm9pZCcpID4gMCAmJiAhZGV2aWNlSXNXaW5kb3dzUGhvbmU7XG5cblxuXHQvKipcblx0ICogaU9TIHJlcXVpcmVzIGV4Y2VwdGlvbnMuXG5cdCAqXG5cdCAqIEB0eXBlIGJvb2xlYW5cblx0ICovXG5cdHZhciBkZXZpY2VJc0lPUyA9IC9pUChhZHxob25lfG9kKS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSAmJiAhZGV2aWNlSXNXaW5kb3dzUGhvbmU7XG5cblxuXHQvKipcblx0ICogaU9TIDQgcmVxdWlyZXMgYW4gZXhjZXB0aW9uIGZvciBzZWxlY3QgZWxlbWVudHMuXG5cdCAqXG5cdCAqIEB0eXBlIGJvb2xlYW5cblx0ICovXG5cdHZhciBkZXZpY2VJc0lPUzQgPSBkZXZpY2VJc0lPUyAmJiAoL09TIDRfXFxkKF9cXGQpPy8pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG5cblxuXHQvKipcblx0ICogaU9TIDYuMC03LiogcmVxdWlyZXMgdGhlIHRhcmdldCBlbGVtZW50IHRvIGJlIG1hbnVhbGx5IGRlcml2ZWRcblx0ICpcblx0ICogQHR5cGUgYm9vbGVhblxuXHQgKi9cblx0dmFyIGRldmljZUlzSU9TV2l0aEJhZFRhcmdldCA9IGRldmljZUlzSU9TICYmICgvT1MgWzYtN11fXFxkLykudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcblxuXHQvKipcblx0ICogQmxhY2tCZXJyeSByZXF1aXJlcyBleGNlcHRpb25zLlxuXHQgKlxuXHQgKiBAdHlwZSBib29sZWFuXG5cdCAqL1xuXHR2YXIgZGV2aWNlSXNCbGFja0JlcnJ5MTAgPSBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ0JCMTAnKSA+IDA7XG5cblx0LyoqXG5cdCAqIERldGVybWluZSB3aGV0aGVyIGEgZ2l2ZW4gZWxlbWVudCByZXF1aXJlcyBhIG5hdGl2ZSBjbGljay5cblx0ICpcblx0ICogQHBhcmFtIHtFdmVudFRhcmdldHxFbGVtZW50fSB0YXJnZXQgVGFyZ2V0IERPTSBlbGVtZW50XG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIHRydWUgaWYgdGhlIGVsZW1lbnQgbmVlZHMgYSBuYXRpdmUgY2xpY2tcblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUubmVlZHNDbGljayA9IGZ1bmN0aW9uKHRhcmdldCkge1xuXHRcdHN3aXRjaCAodGFyZ2V0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpIHtcblxuXHRcdC8vIERvbid0IHNlbmQgYSBzeW50aGV0aWMgY2xpY2sgdG8gZGlzYWJsZWQgaW5wdXRzIChpc3N1ZSAjNjIpXG5cdFx0Y2FzZSAnYnV0dG9uJzpcblx0XHRjYXNlICdzZWxlY3QnOlxuXHRcdGNhc2UgJ3RleHRhcmVhJzpcblx0XHRcdGlmICh0YXJnZXQuZGlzYWJsZWQpIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ2lucHV0JzpcblxuXHRcdFx0Ly8gRmlsZSBpbnB1dHMgbmVlZCByZWFsIGNsaWNrcyBvbiBpT1MgNiBkdWUgdG8gYSBicm93c2VyIGJ1ZyAoaXNzdWUgIzY4KVxuXHRcdFx0aWYgKChkZXZpY2VJc0lPUyAmJiB0YXJnZXQudHlwZSA9PT0gJ2ZpbGUnKSB8fCB0YXJnZXQuZGlzYWJsZWQpIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgJ2xhYmVsJzpcblx0XHRjYXNlICdpZnJhbWUnOiAvLyBpT1M4IGhvbWVzY3JlZW4gYXBwcyBjYW4gcHJldmVudCBldmVudHMgYnViYmxpbmcgaW50byBmcmFtZXNcblx0XHRjYXNlICd2aWRlbyc6XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gKC9cXGJuZWVkc2NsaWNrXFxiLykudGVzdCh0YXJnZXQuY2xhc3NOYW1lKTtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBEZXRlcm1pbmUgd2hldGhlciBhIGdpdmVuIGVsZW1lbnQgcmVxdWlyZXMgYSBjYWxsIHRvIGZvY3VzIHRvIHNpbXVsYXRlIGNsaWNrIGludG8gZWxlbWVudC5cblx0ICpcblx0ICogQHBhcmFtIHtFdmVudFRhcmdldHxFbGVtZW50fSB0YXJnZXQgVGFyZ2V0IERPTSBlbGVtZW50XG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIHRydWUgaWYgdGhlIGVsZW1lbnQgcmVxdWlyZXMgYSBjYWxsIHRvIGZvY3VzIHRvIHNpbXVsYXRlIG5hdGl2ZSBjbGljay5cblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUubmVlZHNGb2N1cyA9IGZ1bmN0aW9uKHRhcmdldCkge1xuXHRcdHN3aXRjaCAodGFyZ2V0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpIHtcblx0XHRjYXNlICd0ZXh0YXJlYSc6XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRjYXNlICdzZWxlY3QnOlxuXHRcdFx0cmV0dXJuICFkZXZpY2VJc0FuZHJvaWQ7XG5cdFx0Y2FzZSAnaW5wdXQnOlxuXHRcdFx0c3dpdGNoICh0YXJnZXQudHlwZSkge1xuXHRcdFx0Y2FzZSAnYnV0dG9uJzpcblx0XHRcdGNhc2UgJ2NoZWNrYm94Jzpcblx0XHRcdGNhc2UgJ2ZpbGUnOlxuXHRcdFx0Y2FzZSAnaW1hZ2UnOlxuXHRcdFx0Y2FzZSAncmFkaW8nOlxuXHRcdFx0Y2FzZSAnc3VibWl0Jzpcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBObyBwb2ludCBpbiBhdHRlbXB0aW5nIHRvIGZvY3VzIGRpc2FibGVkIGlucHV0c1xuXHRcdFx0cmV0dXJuICF0YXJnZXQuZGlzYWJsZWQgJiYgIXRhcmdldC5yZWFkT25seTtcblx0XHRkZWZhdWx0OlxuXHRcdFx0cmV0dXJuICgvXFxibmVlZHNmb2N1c1xcYi8pLnRlc3QodGFyZ2V0LmNsYXNzTmFtZSk7XG5cdFx0fVxuXHR9O1xuXG5cblx0LyoqXG5cdCAqIFNlbmQgYSBjbGljayBldmVudCB0byB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnRUYXJnZXR8RWxlbWVudH0gdGFyZ2V0RWxlbWVudFxuXHQgKiBAcGFyYW0ge0V2ZW50fSBldmVudFxuXHQgKi9cblx0RmFzdENsaWNrLnByb3RvdHlwZS5zZW5kQ2xpY2sgPSBmdW5jdGlvbih0YXJnZXRFbGVtZW50LCBldmVudCkge1xuXHRcdHZhciBjbGlja0V2ZW50LCB0b3VjaDtcblxuXHRcdC8vIE9uIHNvbWUgQW5kcm9pZCBkZXZpY2VzIGFjdGl2ZUVsZW1lbnQgbmVlZHMgdG8gYmUgYmx1cnJlZCBvdGhlcndpc2UgdGhlIHN5bnRoZXRpYyBjbGljayB3aWxsIGhhdmUgbm8gZWZmZWN0ICgjMjQpXG5cdFx0aWYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgJiYgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCAhPT0gdGFyZ2V0RWxlbWVudCkge1xuXHRcdFx0ZG9jdW1lbnQuYWN0aXZlRWxlbWVudC5ibHVyKCk7XG5cdFx0fVxuXG5cdFx0dG91Y2ggPSBldmVudC5jaGFuZ2VkVG91Y2hlc1swXTtcblxuXHRcdC8vIFN5bnRoZXNpc2UgYSBjbGljayBldmVudCwgd2l0aCBhbiBleHRyYSBhdHRyaWJ1dGUgc28gaXQgY2FuIGJlIHRyYWNrZWRcblx0XHRjbGlja0V2ZW50ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ01vdXNlRXZlbnRzJyk7XG5cdFx0Y2xpY2tFdmVudC5pbml0TW91c2VFdmVudCh0aGlzLmRldGVybWluZUV2ZW50VHlwZSh0YXJnZXRFbGVtZW50KSwgdHJ1ZSwgdHJ1ZSwgd2luZG93LCAxLCB0b3VjaC5zY3JlZW5YLCB0b3VjaC5zY3JlZW5ZLCB0b3VjaC5jbGllbnRYLCB0b3VjaC5jbGllbnRZLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgMCwgbnVsbCk7XG5cdFx0Y2xpY2tFdmVudC5mb3J3YXJkZWRUb3VjaEV2ZW50ID0gdHJ1ZTtcblx0XHR0YXJnZXRFbGVtZW50LmRpc3BhdGNoRXZlbnQoY2xpY2tFdmVudCk7XG5cdH07XG5cblx0RmFzdENsaWNrLnByb3RvdHlwZS5kZXRlcm1pbmVFdmVudFR5cGUgPSBmdW5jdGlvbih0YXJnZXRFbGVtZW50KSB7XG5cblx0XHQvL0lzc3VlICMxNTk6IEFuZHJvaWQgQ2hyb21lIFNlbGVjdCBCb3ggZG9lcyBub3Qgb3BlbiB3aXRoIGEgc3ludGhldGljIGNsaWNrIGV2ZW50XG5cdFx0aWYgKGRldmljZUlzQW5kcm9pZCAmJiB0YXJnZXRFbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ3NlbGVjdCcpIHtcblx0XHRcdHJldHVybiAnbW91c2Vkb3duJztcblx0XHR9XG5cblx0XHRyZXR1cm4gJ2NsaWNrJztcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fEVsZW1lbnR9IHRhcmdldEVsZW1lbnRcblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUuZm9jdXMgPSBmdW5jdGlvbih0YXJnZXRFbGVtZW50KSB7XG5cdFx0dmFyIGxlbmd0aDtcblxuXHRcdC8vIElzc3VlICMxNjA6IG9uIGlPUyA3LCBzb21lIGlucHV0IGVsZW1lbnRzIChlLmcuIGRhdGUgZGF0ZXRpbWUgbW9udGgpIHRocm93IGEgdmFndWUgVHlwZUVycm9yIG9uIHNldFNlbGVjdGlvblJhbmdlLiBUaGVzZSBlbGVtZW50cyBkb24ndCBoYXZlIGFuIGludGVnZXIgdmFsdWUgZm9yIHRoZSBzZWxlY3Rpb25TdGFydCBhbmQgc2VsZWN0aW9uRW5kIHByb3BlcnRpZXMsIGJ1dCB1bmZvcnR1bmF0ZWx5IHRoYXQgY2FuJ3QgYmUgdXNlZCBmb3IgZGV0ZWN0aW9uIGJlY2F1c2UgYWNjZXNzaW5nIHRoZSBwcm9wZXJ0aWVzIGFsc28gdGhyb3dzIGEgVHlwZUVycm9yLiBKdXN0IGNoZWNrIHRoZSB0eXBlIGluc3RlYWQuIEZpbGVkIGFzIEFwcGxlIGJ1ZyAjMTUxMjI3MjQuXG5cdFx0aWYgKGRldmljZUlzSU9TICYmIHRhcmdldEVsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UgJiYgdGFyZ2V0RWxlbWVudC50eXBlLmluZGV4T2YoJ2RhdGUnKSAhPT0gMCAmJiB0YXJnZXRFbGVtZW50LnR5cGUgIT09ICd0aW1lJyAmJiB0YXJnZXRFbGVtZW50LnR5cGUgIT09ICdtb250aCcpIHtcblx0XHRcdGxlbmd0aCA9IHRhcmdldEVsZW1lbnQudmFsdWUubGVuZ3RoO1xuXHRcdFx0dGFyZ2V0RWxlbWVudC5zZXRTZWxlY3Rpb25SYW5nZShsZW5ndGgsIGxlbmd0aCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRhcmdldEVsZW1lbnQuZm9jdXMoKTtcblx0XHR9XG5cdH07XG5cblxuXHQvKipcblx0ICogQ2hlY2sgd2hldGhlciB0aGUgZ2l2ZW4gdGFyZ2V0IGVsZW1lbnQgaXMgYSBjaGlsZCBvZiBhIHNjcm9sbGFibGUgbGF5ZXIgYW5kIGlmIHNvLCBzZXQgYSBmbGFnIG9uIGl0LlxuXHQgKlxuXHQgKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fEVsZW1lbnR9IHRhcmdldEVsZW1lbnRcblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUudXBkYXRlU2Nyb2xsUGFyZW50ID0gZnVuY3Rpb24odGFyZ2V0RWxlbWVudCkge1xuXHRcdHZhciBzY3JvbGxQYXJlbnQsIHBhcmVudEVsZW1lbnQ7XG5cblx0XHRzY3JvbGxQYXJlbnQgPSB0YXJnZXRFbGVtZW50LmZhc3RDbGlja1Njcm9sbFBhcmVudDtcblxuXHRcdC8vIEF0dGVtcHQgdG8gZGlzY292ZXIgd2hldGhlciB0aGUgdGFyZ2V0IGVsZW1lbnQgaXMgY29udGFpbmVkIHdpdGhpbiBhIHNjcm9sbGFibGUgbGF5ZXIuIFJlLWNoZWNrIGlmIHRoZVxuXHRcdC8vIHRhcmdldCBlbGVtZW50IHdhcyBtb3ZlZCB0byBhbm90aGVyIHBhcmVudC5cblx0XHRpZiAoIXNjcm9sbFBhcmVudCB8fCAhc2Nyb2xsUGFyZW50LmNvbnRhaW5zKHRhcmdldEVsZW1lbnQpKSB7XG5cdFx0XHRwYXJlbnRFbGVtZW50ID0gdGFyZ2V0RWxlbWVudDtcblx0XHRcdGRvIHtcblx0XHRcdFx0aWYgKHBhcmVudEVsZW1lbnQuc2Nyb2xsSGVpZ2h0ID4gcGFyZW50RWxlbWVudC5vZmZzZXRIZWlnaHQpIHtcblx0XHRcdFx0XHRzY3JvbGxQYXJlbnQgPSBwYXJlbnRFbGVtZW50O1xuXHRcdFx0XHRcdHRhcmdldEVsZW1lbnQuZmFzdENsaWNrU2Nyb2xsUGFyZW50ID0gcGFyZW50RWxlbWVudDtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHBhcmVudEVsZW1lbnQgPSBwYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQ7XG5cdFx0XHR9IHdoaWxlIChwYXJlbnRFbGVtZW50KTtcblx0XHR9XG5cblx0XHQvLyBBbHdheXMgdXBkYXRlIHRoZSBzY3JvbGwgdG9wIHRyYWNrZXIgaWYgcG9zc2libGUuXG5cdFx0aWYgKHNjcm9sbFBhcmVudCkge1xuXHRcdFx0c2Nyb2xsUGFyZW50LmZhc3RDbGlja0xhc3RTY3JvbGxUb3AgPSBzY3JvbGxQYXJlbnQuc2Nyb2xsVG9wO1xuXHRcdH1cblx0fTtcblxuXG5cdC8qKlxuXHQgKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fSB0YXJnZXRFbGVtZW50XG5cdCAqIEByZXR1cm5zIHtFbGVtZW50fEV2ZW50VGFyZ2V0fVxuXHQgKi9cblx0RmFzdENsaWNrLnByb3RvdHlwZS5nZXRUYXJnZXRFbGVtZW50RnJvbUV2ZW50VGFyZ2V0ID0gZnVuY3Rpb24oZXZlbnRUYXJnZXQpIHtcblxuXHRcdC8vIE9uIHNvbWUgb2xkZXIgYnJvd3NlcnMgKG5vdGFibHkgU2FmYXJpIG9uIGlPUyA0LjEgLSBzZWUgaXNzdWUgIzU2KSB0aGUgZXZlbnQgdGFyZ2V0IG1heSBiZSBhIHRleHQgbm9kZS5cblx0XHRpZiAoZXZlbnRUYXJnZXQubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFKSB7XG5cdFx0XHRyZXR1cm4gZXZlbnRUYXJnZXQucGFyZW50Tm9kZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZXZlbnRUYXJnZXQ7XG5cdH07XG5cblxuXHQvKipcblx0ICogT24gdG91Y2ggc3RhcnQsIHJlY29yZCB0aGUgcG9zaXRpb24gYW5kIHNjcm9sbCBvZmZzZXQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50XG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxuXHQgKi9cblx0RmFzdENsaWNrLnByb3RvdHlwZS5vblRvdWNoU3RhcnQgPSBmdW5jdGlvbihldmVudCkge1xuXHRcdHZhciB0YXJnZXRFbGVtZW50LCB0b3VjaCwgc2VsZWN0aW9uO1xuXG5cdFx0Ly8gSWdub3JlIG11bHRpcGxlIHRvdWNoZXMsIG90aGVyd2lzZSBwaW5jaC10by16b29tIGlzIHByZXZlbnRlZCBpZiBib3RoIGZpbmdlcnMgYXJlIG9uIHRoZSBGYXN0Q2xpY2sgZWxlbWVudCAoaXNzdWUgIzExMSkuXG5cdFx0aWYgKGV2ZW50LnRhcmdldFRvdWNoZXMubGVuZ3RoID4gMSkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0dGFyZ2V0RWxlbWVudCA9IHRoaXMuZ2V0VGFyZ2V0RWxlbWVudEZyb21FdmVudFRhcmdldChldmVudC50YXJnZXQpO1xuXHRcdHRvdWNoID0gZXZlbnQudGFyZ2V0VG91Y2hlc1swXTtcblxuXHRcdGlmIChkZXZpY2VJc0lPUykge1xuXG5cdFx0XHQvLyBPbmx5IHRydXN0ZWQgZXZlbnRzIHdpbGwgZGVzZWxlY3QgdGV4dCBvbiBpT1MgKGlzc3VlICM0OSlcblx0XHRcdHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcblx0XHRcdGlmIChzZWxlY3Rpb24ucmFuZ2VDb3VudCAmJiAhc2VsZWN0aW9uLmlzQ29sbGFwc2VkKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIWRldmljZUlzSU9TNCkge1xuXG5cdFx0XHRcdC8vIFdlaXJkIHRoaW5ncyBoYXBwZW4gb24gaU9TIHdoZW4gYW4gYWxlcnQgb3IgY29uZmlybSBkaWFsb2cgaXMgb3BlbmVkIGZyb20gYSBjbGljayBldmVudCBjYWxsYmFjayAoaXNzdWUgIzIzKTpcblx0XHRcdFx0Ly8gd2hlbiB0aGUgdXNlciBuZXh0IHRhcHMgYW55d2hlcmUgZWxzZSBvbiB0aGUgcGFnZSwgbmV3IHRvdWNoc3RhcnQgYW5kIHRvdWNoZW5kIGV2ZW50cyBhcmUgZGlzcGF0Y2hlZFxuXHRcdFx0XHQvLyB3aXRoIHRoZSBzYW1lIGlkZW50aWZpZXIgYXMgdGhlIHRvdWNoIGV2ZW50IHRoYXQgcHJldmlvdXNseSB0cmlnZ2VyZWQgdGhlIGNsaWNrIHRoYXQgdHJpZ2dlcmVkIHRoZSBhbGVydC5cblx0XHRcdFx0Ly8gU2FkbHksIHRoZXJlIGlzIGFuIGlzc3VlIG9uIGlPUyA0IHRoYXQgY2F1c2VzIHNvbWUgbm9ybWFsIHRvdWNoIGV2ZW50cyB0byBoYXZlIHRoZSBzYW1lIGlkZW50aWZpZXIgYXMgYW5cblx0XHRcdFx0Ly8gaW1tZWRpYXRlbHkgcHJlY2VlZGluZyB0b3VjaCBldmVudCAoaXNzdWUgIzUyKSwgc28gdGhpcyBmaXggaXMgdW5hdmFpbGFibGUgb24gdGhhdCBwbGF0Zm9ybS5cblx0XHRcdFx0Ly8gSXNzdWUgMTIwOiB0b3VjaC5pZGVudGlmaWVyIGlzIDAgd2hlbiBDaHJvbWUgZGV2IHRvb2xzICdFbXVsYXRlIHRvdWNoIGV2ZW50cycgaXMgc2V0IHdpdGggYW4gaU9TIGRldmljZSBVQSBzdHJpbmcsXG5cdFx0XHRcdC8vIHdoaWNoIGNhdXNlcyBhbGwgdG91Y2ggZXZlbnRzIHRvIGJlIGlnbm9yZWQuIEFzIHRoaXMgYmxvY2sgb25seSBhcHBsaWVzIHRvIGlPUywgYW5kIGlPUyBpZGVudGlmaWVycyBhcmUgYWx3YXlzIGxvbmcsXG5cdFx0XHRcdC8vIHJhbmRvbSBpbnRlZ2VycywgaXQncyBzYWZlIHRvIHRvIGNvbnRpbnVlIGlmIHRoZSBpZGVudGlmaWVyIGlzIDAgaGVyZS5cblx0XHRcdFx0aWYgKHRvdWNoLmlkZW50aWZpZXIgJiYgdG91Y2guaWRlbnRpZmllciA9PT0gdGhpcy5sYXN0VG91Y2hJZGVudGlmaWVyKSB7XG5cdFx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGlzLmxhc3RUb3VjaElkZW50aWZpZXIgPSB0b3VjaC5pZGVudGlmaWVyO1xuXG5cdFx0XHRcdC8vIElmIHRoZSB0YXJnZXQgZWxlbWVudCBpcyBhIGNoaWxkIG9mIGEgc2Nyb2xsYWJsZSBsYXllciAodXNpbmcgLXdlYmtpdC1vdmVyZmxvdy1zY3JvbGxpbmc6IHRvdWNoKSBhbmQ6XG5cdFx0XHRcdC8vIDEpIHRoZSB1c2VyIGRvZXMgYSBmbGluZyBzY3JvbGwgb24gdGhlIHNjcm9sbGFibGUgbGF5ZXJcblx0XHRcdFx0Ly8gMikgdGhlIHVzZXIgc3RvcHMgdGhlIGZsaW5nIHNjcm9sbCB3aXRoIGFub3RoZXIgdGFwXG5cdFx0XHRcdC8vIHRoZW4gdGhlIGV2ZW50LnRhcmdldCBvZiB0aGUgbGFzdCAndG91Y2hlbmQnIGV2ZW50IHdpbGwgYmUgdGhlIGVsZW1lbnQgdGhhdCB3YXMgdW5kZXIgdGhlIHVzZXIncyBmaW5nZXJcblx0XHRcdFx0Ly8gd2hlbiB0aGUgZmxpbmcgc2Nyb2xsIHdhcyBzdGFydGVkLCBjYXVzaW5nIEZhc3RDbGljayB0byBzZW5kIGEgY2xpY2sgZXZlbnQgdG8gdGhhdCBsYXllciAtIHVubGVzcyBhIGNoZWNrXG5cdFx0XHRcdC8vIGlzIG1hZGUgdG8gZW5zdXJlIHRoYXQgYSBwYXJlbnQgbGF5ZXIgd2FzIG5vdCBzY3JvbGxlZCBiZWZvcmUgc2VuZGluZyBhIHN5bnRoZXRpYyBjbGljayAoaXNzdWUgIzQyKS5cblx0XHRcdFx0dGhpcy51cGRhdGVTY3JvbGxQYXJlbnQodGFyZ2V0RWxlbWVudCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dGhpcy50cmFja2luZ0NsaWNrID0gdHJ1ZTtcblx0XHR0aGlzLnRyYWNraW5nQ2xpY2tTdGFydCA9IGV2ZW50LnRpbWVTdGFtcDtcblx0XHR0aGlzLnRhcmdldEVsZW1lbnQgPSB0YXJnZXRFbGVtZW50O1xuXG5cdFx0dGhpcy50b3VjaFN0YXJ0WCA9IHRvdWNoLnBhZ2VYO1xuXHRcdHRoaXMudG91Y2hTdGFydFkgPSB0b3VjaC5wYWdlWTtcblxuXHRcdC8vIFByZXZlbnQgcGhhbnRvbSBjbGlja3Mgb24gZmFzdCBkb3VibGUtdGFwIChpc3N1ZSAjMzYpXG5cdFx0aWYgKChldmVudC50aW1lU3RhbXAgLSB0aGlzLmxhc3RDbGlja1RpbWUpIDwgdGhpcy50YXBEZWxheSkge1xuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBCYXNlZCBvbiBhIHRvdWNobW92ZSBldmVudCBvYmplY3QsIGNoZWNrIHdoZXRoZXIgdGhlIHRvdWNoIGhhcyBtb3ZlZCBwYXN0IGEgYm91bmRhcnkgc2luY2UgaXQgc3RhcnRlZC5cblx0ICpcblx0ICogQHBhcmFtIHtFdmVudH0gZXZlbnRcblx0ICogQHJldHVybnMge2Jvb2xlYW59XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLnRvdWNoSGFzTW92ZWQgPSBmdW5jdGlvbihldmVudCkge1xuXHRcdHZhciB0b3VjaCA9IGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdLCBib3VuZGFyeSA9IHRoaXMudG91Y2hCb3VuZGFyeTtcblxuXHRcdGlmIChNYXRoLmFicyh0b3VjaC5wYWdlWCAtIHRoaXMudG91Y2hTdGFydFgpID4gYm91bmRhcnkgfHwgTWF0aC5hYnModG91Y2gucGFnZVkgLSB0aGlzLnRvdWNoU3RhcnRZKSA+IGJvdW5kYXJ5KSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH07XG5cblxuXHQvKipcblx0ICogVXBkYXRlIHRoZSBsYXN0IHBvc2l0aW9uLlxuXHQgKlxuXHQgKiBAcGFyYW0ge0V2ZW50fSBldmVudFxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUub25Ub3VjaE1vdmUgPSBmdW5jdGlvbihldmVudCkge1xuXHRcdGlmICghdGhpcy50cmFja2luZ0NsaWNrKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHQvLyBJZiB0aGUgdG91Y2ggaGFzIG1vdmVkLCBjYW5jZWwgdGhlIGNsaWNrIHRyYWNraW5nXG5cdFx0aWYgKHRoaXMudGFyZ2V0RWxlbWVudCAhPT0gdGhpcy5nZXRUYXJnZXRFbGVtZW50RnJvbUV2ZW50VGFyZ2V0KGV2ZW50LnRhcmdldCkgfHwgdGhpcy50b3VjaEhhc01vdmVkKGV2ZW50KSkge1xuXHRcdFx0dGhpcy50cmFja2luZ0NsaWNrID0gZmFsc2U7XG5cdFx0XHR0aGlzLnRhcmdldEVsZW1lbnQgPSBudWxsO1xuXHRcdH1cblxuXHRcdHJldHVybiB0cnVlO1xuXHR9O1xuXG5cblx0LyoqXG5cdCAqIEF0dGVtcHQgdG8gZmluZCB0aGUgbGFiZWxsZWQgY29udHJvbCBmb3IgdGhlIGdpdmVuIGxhYmVsIGVsZW1lbnQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnRUYXJnZXR8SFRNTExhYmVsRWxlbWVudH0gbGFiZWxFbGVtZW50XG5cdCAqIEByZXR1cm5zIHtFbGVtZW50fG51bGx9XG5cdCAqL1xuXHRGYXN0Q2xpY2sucHJvdG90eXBlLmZpbmRDb250cm9sID0gZnVuY3Rpb24obGFiZWxFbGVtZW50KSB7XG5cblx0XHQvLyBGYXN0IHBhdGggZm9yIG5ld2VyIGJyb3dzZXJzIHN1cHBvcnRpbmcgdGhlIEhUTUw1IGNvbnRyb2wgYXR0cmlidXRlXG5cdFx0aWYgKGxhYmVsRWxlbWVudC5jb250cm9sICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdHJldHVybiBsYWJlbEVsZW1lbnQuY29udHJvbDtcblx0XHR9XG5cblx0XHQvLyBBbGwgYnJvd3NlcnMgdW5kZXIgdGVzdCB0aGF0IHN1cHBvcnQgdG91Y2ggZXZlbnRzIGFsc28gc3VwcG9ydCB0aGUgSFRNTDUgaHRtbEZvciBhdHRyaWJ1dGVcblx0XHRpZiAobGFiZWxFbGVtZW50Lmh0bWxGb3IpIHtcblx0XHRcdHJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChsYWJlbEVsZW1lbnQuaHRtbEZvcik7XG5cdFx0fVxuXG5cdFx0Ly8gSWYgbm8gZm9yIGF0dHJpYnV0ZSBleGlzdHMsIGF0dGVtcHQgdG8gcmV0cmlldmUgdGhlIGZpcnN0IGxhYmVsbGFibGUgZGVzY2VuZGFudCBlbGVtZW50XG5cdFx0Ly8gdGhlIGxpc3Qgb2Ygd2hpY2ggaXMgZGVmaW5lZCBoZXJlOiBodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sNS9mb3Jtcy5odG1sI2NhdGVnb3J5LWxhYmVsXG5cdFx0cmV0dXJuIGxhYmVsRWxlbWVudC5xdWVyeVNlbGVjdG9yKCdidXR0b24sIGlucHV0Om5vdChbdHlwZT1oaWRkZW5dKSwga2V5Z2VuLCBtZXRlciwgb3V0cHV0LCBwcm9ncmVzcywgc2VsZWN0LCB0ZXh0YXJlYScpO1xuXHR9O1xuXG5cblx0LyoqXG5cdCAqIE9uIHRvdWNoIGVuZCwgZGV0ZXJtaW5lIHdoZXRoZXIgdG8gc2VuZCBhIGNsaWNrIGV2ZW50IGF0IG9uY2UuXG5cdCAqXG5cdCAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50XG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxuXHQgKi9cblx0RmFzdENsaWNrLnByb3RvdHlwZS5vblRvdWNoRW5kID0gZnVuY3Rpb24oZXZlbnQpIHtcblx0XHR2YXIgZm9yRWxlbWVudCwgdHJhY2tpbmdDbGlja1N0YXJ0LCB0YXJnZXRUYWdOYW1lLCBzY3JvbGxQYXJlbnQsIHRvdWNoLCB0YXJnZXRFbGVtZW50ID0gdGhpcy50YXJnZXRFbGVtZW50O1xuXG5cdFx0aWYgKCF0aGlzLnRyYWNraW5nQ2xpY2spIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIFByZXZlbnQgcGhhbnRvbSBjbGlja3Mgb24gZmFzdCBkb3VibGUtdGFwIChpc3N1ZSAjMzYpXG5cdFx0aWYgKChldmVudC50aW1lU3RhbXAgLSB0aGlzLmxhc3RDbGlja1RpbWUpIDwgdGhpcy50YXBEZWxheSkge1xuXHRcdFx0dGhpcy5jYW5jZWxOZXh0Q2xpY2sgPSB0cnVlO1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0aWYgKChldmVudC50aW1lU3RhbXAgLSB0aGlzLnRyYWNraW5nQ2xpY2tTdGFydCkgPiB0aGlzLnRhcFRpbWVvdXQpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIFJlc2V0IHRvIHByZXZlbnQgd3JvbmcgY2xpY2sgY2FuY2VsIG9uIGlucHV0IChpc3N1ZSAjMTU2KS5cblx0XHR0aGlzLmNhbmNlbE5leHRDbGljayA9IGZhbHNlO1xuXG5cdFx0dGhpcy5sYXN0Q2xpY2tUaW1lID0gZXZlbnQudGltZVN0YW1wO1xuXG5cdFx0dHJhY2tpbmdDbGlja1N0YXJ0ID0gdGhpcy50cmFja2luZ0NsaWNrU3RhcnQ7XG5cdFx0dGhpcy50cmFja2luZ0NsaWNrID0gZmFsc2U7XG5cdFx0dGhpcy50cmFja2luZ0NsaWNrU3RhcnQgPSAwO1xuXG5cdFx0Ly8gT24gc29tZSBpT1MgZGV2aWNlcywgdGhlIHRhcmdldEVsZW1lbnQgc3VwcGxpZWQgd2l0aCB0aGUgZXZlbnQgaXMgaW52YWxpZCBpZiB0aGUgbGF5ZXJcblx0XHQvLyBpcyBwZXJmb3JtaW5nIGEgdHJhbnNpdGlvbiBvciBzY3JvbGwsIGFuZCBoYXMgdG8gYmUgcmUtZGV0ZWN0ZWQgbWFudWFsbHkuIE5vdGUgdGhhdFxuXHRcdC8vIGZvciB0aGlzIHRvIGZ1bmN0aW9uIGNvcnJlY3RseSwgaXQgbXVzdCBiZSBjYWxsZWQgKmFmdGVyKiB0aGUgZXZlbnQgdGFyZ2V0IGlzIGNoZWNrZWQhXG5cdFx0Ly8gU2VlIGlzc3VlICM1NzsgYWxzbyBmaWxlZCBhcyByZGFyOi8vMTMwNDg1ODkgLlxuXHRcdGlmIChkZXZpY2VJc0lPU1dpdGhCYWRUYXJnZXQpIHtcblx0XHRcdHRvdWNoID0gZXZlbnQuY2hhbmdlZFRvdWNoZXNbMF07XG5cblx0XHRcdC8vIEluIGNlcnRhaW4gY2FzZXMgYXJndW1lbnRzIG9mIGVsZW1lbnRGcm9tUG9pbnQgY2FuIGJlIG5lZ2F0aXZlLCBzbyBwcmV2ZW50IHNldHRpbmcgdGFyZ2V0RWxlbWVudCB0byBudWxsXG5cdFx0XHR0YXJnZXRFbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludCh0b3VjaC5wYWdlWCAtIHdpbmRvdy5wYWdlWE9mZnNldCwgdG91Y2gucGFnZVkgLSB3aW5kb3cucGFnZVlPZmZzZXQpIHx8IHRhcmdldEVsZW1lbnQ7XG5cdFx0XHR0YXJnZXRFbGVtZW50LmZhc3RDbGlja1Njcm9sbFBhcmVudCA9IHRoaXMudGFyZ2V0RWxlbWVudC5mYXN0Q2xpY2tTY3JvbGxQYXJlbnQ7XG5cdFx0fVxuXG5cdFx0dGFyZ2V0VGFnTmFtZSA9IHRhcmdldEVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdGlmICh0YXJnZXRUYWdOYW1lID09PSAnbGFiZWwnKSB7XG5cdFx0XHRmb3JFbGVtZW50ID0gdGhpcy5maW5kQ29udHJvbCh0YXJnZXRFbGVtZW50KTtcblx0XHRcdGlmIChmb3JFbGVtZW50KSB7XG5cdFx0XHRcdHRoaXMuZm9jdXModGFyZ2V0RWxlbWVudCk7XG5cdFx0XHRcdGlmIChkZXZpY2VJc0FuZHJvaWQpIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0YXJnZXRFbGVtZW50ID0gZm9yRWxlbWVudDtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKHRoaXMubmVlZHNGb2N1cyh0YXJnZXRFbGVtZW50KSkge1xuXG5cdFx0XHQvLyBDYXNlIDE6IElmIHRoZSB0b3VjaCBzdGFydGVkIGEgd2hpbGUgYWdvIChiZXN0IGd1ZXNzIGlzIDEwMG1zIGJhc2VkIG9uIHRlc3RzIGZvciBpc3N1ZSAjMzYpIHRoZW4gZm9jdXMgd2lsbCBiZSB0cmlnZ2VyZWQgYW55d2F5LiBSZXR1cm4gZWFybHkgYW5kIHVuc2V0IHRoZSB0YXJnZXQgZWxlbWVudCByZWZlcmVuY2Ugc28gdGhhdCB0aGUgc3Vic2VxdWVudCBjbGljayB3aWxsIGJlIGFsbG93ZWQgdGhyb3VnaC5cblx0XHRcdC8vIENhc2UgMjogV2l0aG91dCB0aGlzIGV4Y2VwdGlvbiBmb3IgaW5wdXQgZWxlbWVudHMgdGFwcGVkIHdoZW4gdGhlIGRvY3VtZW50IGlzIGNvbnRhaW5lZCBpbiBhbiBpZnJhbWUsIHRoZW4gYW55IGlucHV0dGVkIHRleHQgd29uJ3QgYmUgdmlzaWJsZSBldmVuIHRob3VnaCB0aGUgdmFsdWUgYXR0cmlidXRlIGlzIHVwZGF0ZWQgYXMgdGhlIHVzZXIgdHlwZXMgKGlzc3VlICMzNykuXG5cdFx0XHRpZiAoKGV2ZW50LnRpbWVTdGFtcCAtIHRyYWNraW5nQ2xpY2tTdGFydCkgPiAxMDAgfHwgKGRldmljZUlzSU9TICYmIHdpbmRvdy50b3AgIT09IHdpbmRvdyAmJiB0YXJnZXRUYWdOYW1lID09PSAnaW5wdXQnKSkge1xuXHRcdFx0XHR0aGlzLnRhcmdldEVsZW1lbnQgPSBudWxsO1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuZm9jdXModGFyZ2V0RWxlbWVudCk7XG5cdFx0XHR0aGlzLnNlbmRDbGljayh0YXJnZXRFbGVtZW50LCBldmVudCk7XG5cblx0XHRcdC8vIFNlbGVjdCBlbGVtZW50cyBuZWVkIHRoZSBldmVudCB0byBnbyB0aHJvdWdoIG9uIGlPUyA0LCBvdGhlcndpc2UgdGhlIHNlbGVjdG9yIG1lbnUgd29uJ3Qgb3Blbi5cblx0XHRcdC8vIEFsc28gdGhpcyBicmVha3Mgb3BlbmluZyBzZWxlY3RzIHdoZW4gVm9pY2VPdmVyIGlzIGFjdGl2ZSBvbiBpT1M2LCBpT1M3IChhbmQgcG9zc2libHkgb3RoZXJzKVxuXHRcdFx0aWYgKCFkZXZpY2VJc0lPUyB8fCB0YXJnZXRUYWdOYW1lICE9PSAnc2VsZWN0Jykge1xuXHRcdFx0XHR0aGlzLnRhcmdldEVsZW1lbnQgPSBudWxsO1xuXHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0aWYgKGRldmljZUlzSU9TICYmICFkZXZpY2VJc0lPUzQpIHtcblxuXHRcdFx0Ly8gRG9uJ3Qgc2VuZCBhIHN5bnRoZXRpYyBjbGljayBldmVudCBpZiB0aGUgdGFyZ2V0IGVsZW1lbnQgaXMgY29udGFpbmVkIHdpdGhpbiBhIHBhcmVudCBsYXllciB0aGF0IHdhcyBzY3JvbGxlZFxuXHRcdFx0Ly8gYW5kIHRoaXMgdGFwIGlzIGJlaW5nIHVzZWQgdG8gc3RvcCB0aGUgc2Nyb2xsaW5nICh1c3VhbGx5IGluaXRpYXRlZCBieSBhIGZsaW5nIC0gaXNzdWUgIzQyKS5cblx0XHRcdHNjcm9sbFBhcmVudCA9IHRhcmdldEVsZW1lbnQuZmFzdENsaWNrU2Nyb2xsUGFyZW50O1xuXHRcdFx0aWYgKHNjcm9sbFBhcmVudCAmJiBzY3JvbGxQYXJlbnQuZmFzdENsaWNrTGFzdFNjcm9sbFRvcCAhPT0gc2Nyb2xsUGFyZW50LnNjcm9sbFRvcCkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBQcmV2ZW50IHRoZSBhY3R1YWwgY2xpY2sgZnJvbSBnb2luZyB0aG91Z2ggLSB1bmxlc3MgdGhlIHRhcmdldCBub2RlIGlzIG1hcmtlZCBhcyByZXF1aXJpbmdcblx0XHQvLyByZWFsIGNsaWNrcyBvciBpZiBpdCBpcyBpbiB0aGUgd2hpdGVsaXN0IGluIHdoaWNoIGNhc2Ugb25seSBub24tcHJvZ3JhbW1hdGljIGNsaWNrcyBhcmUgcGVybWl0dGVkLlxuXHRcdGlmICghdGhpcy5uZWVkc0NsaWNrKHRhcmdldEVsZW1lbnQpKSB7XG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0dGhpcy5zZW5kQ2xpY2sodGFyZ2V0RWxlbWVudCwgZXZlbnQpO1xuXHRcdH1cblxuXHRcdHJldHVybiBmYWxzZTtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBPbiB0b3VjaCBjYW5jZWwsIHN0b3AgdHJhY2tpbmcgdGhlIGNsaWNrLlxuXHQgKlxuXHQgKiBAcmV0dXJucyB7dm9pZH1cblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUub25Ub3VjaENhbmNlbCA9IGZ1bmN0aW9uKCkge1xuXHRcdHRoaXMudHJhY2tpbmdDbGljayA9IGZhbHNlO1xuXHRcdHRoaXMudGFyZ2V0RWxlbWVudCA9IG51bGw7XG5cdH07XG5cblxuXHQvKipcblx0ICogRGV0ZXJtaW5lIG1vdXNlIGV2ZW50cyB3aGljaCBzaG91bGQgYmUgcGVybWl0dGVkLlxuXHQgKlxuXHQgKiBAcGFyYW0ge0V2ZW50fSBldmVudFxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUub25Nb3VzZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG5cblx0XHQvLyBJZiBhIHRhcmdldCBlbGVtZW50IHdhcyBuZXZlciBzZXQgKGJlY2F1c2UgYSB0b3VjaCBldmVudCB3YXMgbmV2ZXIgZmlyZWQpIGFsbG93IHRoZSBldmVudFxuXHRcdGlmICghdGhpcy50YXJnZXRFbGVtZW50KSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHRpZiAoZXZlbnQuZm9yd2FyZGVkVG91Y2hFdmVudCkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0Ly8gUHJvZ3JhbW1hdGljYWxseSBnZW5lcmF0ZWQgZXZlbnRzIHRhcmdldGluZyBhIHNwZWNpZmljIGVsZW1lbnQgc2hvdWxkIGJlIHBlcm1pdHRlZFxuXHRcdGlmICghZXZlbnQuY2FuY2VsYWJsZSkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0Ly8gRGVyaXZlIGFuZCBjaGVjayB0aGUgdGFyZ2V0IGVsZW1lbnQgdG8gc2VlIHdoZXRoZXIgdGhlIG1vdXNlIGV2ZW50IG5lZWRzIHRvIGJlIHBlcm1pdHRlZDtcblx0XHQvLyB1bmxlc3MgZXhwbGljaXRseSBlbmFibGVkLCBwcmV2ZW50IG5vbi10b3VjaCBjbGljayBldmVudHMgZnJvbSB0cmlnZ2VyaW5nIGFjdGlvbnMsXG5cdFx0Ly8gdG8gcHJldmVudCBnaG9zdC9kb3VibGVjbGlja3MuXG5cdFx0aWYgKCF0aGlzLm5lZWRzQ2xpY2sodGhpcy50YXJnZXRFbGVtZW50KSB8fCB0aGlzLmNhbmNlbE5leHRDbGljaykge1xuXG5cdFx0XHQvLyBQcmV2ZW50IGFueSB1c2VyLWFkZGVkIGxpc3RlbmVycyBkZWNsYXJlZCBvbiBGYXN0Q2xpY2sgZWxlbWVudCBmcm9tIGJlaW5nIGZpcmVkLlxuXHRcdFx0aWYgKGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbikge1xuXHRcdFx0XHRldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gUGFydCBvZiB0aGUgaGFjayBmb3IgYnJvd3NlcnMgdGhhdCBkb24ndCBzdXBwb3J0IEV2ZW50I3N0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiAoZS5nLiBBbmRyb2lkIDIpXG5cdFx0XHRcdGV2ZW50LnByb3BhZ2F0aW9uU3RvcHBlZCA9IHRydWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENhbmNlbCB0aGUgZXZlbnRcblx0XHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIElmIHRoZSBtb3VzZSBldmVudCBpcyBwZXJtaXR0ZWQsIHJldHVybiB0cnVlIGZvciB0aGUgYWN0aW9uIHRvIGdvIHRocm91Z2guXG5cdFx0cmV0dXJuIHRydWU7XG5cdH07XG5cblxuXHQvKipcblx0ICogT24gYWN0dWFsIGNsaWNrcywgZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyBpcyBhIHRvdWNoLWdlbmVyYXRlZCBjbGljaywgYSBjbGljayBhY3Rpb24gb2NjdXJyaW5nXG5cdCAqIG5hdHVyYWxseSBhZnRlciBhIGRlbGF5IGFmdGVyIGEgdG91Y2ggKHdoaWNoIG5lZWRzIHRvIGJlIGNhbmNlbGxlZCB0byBhdm9pZCBkdXBsaWNhdGlvbiksIG9yXG5cdCAqIGFuIGFjdHVhbCBjbGljayB3aGljaCBzaG91bGQgYmUgcGVybWl0dGVkLlxuXHQgKlxuXHQgKiBAcGFyYW0ge0V2ZW50fSBldmVudFxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUub25DbGljayA9IGZ1bmN0aW9uKGV2ZW50KSB7XG5cdFx0dmFyIHBlcm1pdHRlZDtcblxuXHRcdC8vIEl0J3MgcG9zc2libGUgZm9yIGFub3RoZXIgRmFzdENsaWNrLWxpa2UgbGlicmFyeSBkZWxpdmVyZWQgd2l0aCB0aGlyZC1wYXJ0eSBjb2RlIHRvIGZpcmUgYSBjbGljayBldmVudCBiZWZvcmUgRmFzdENsaWNrIGRvZXMgKGlzc3VlICM0NCkuIEluIHRoYXQgY2FzZSwgc2V0IHRoZSBjbGljay10cmFja2luZyBmbGFnIGJhY2sgdG8gZmFsc2UgYW5kIHJldHVybiBlYXJseS4gVGhpcyB3aWxsIGNhdXNlIG9uVG91Y2hFbmQgdG8gcmV0dXJuIGVhcmx5LlxuXHRcdGlmICh0aGlzLnRyYWNraW5nQ2xpY2spIHtcblx0XHRcdHRoaXMudGFyZ2V0RWxlbWVudCA9IG51bGw7XG5cdFx0XHR0aGlzLnRyYWNraW5nQ2xpY2sgPSBmYWxzZTtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIFZlcnkgb2RkIGJlaGF2aW91ciBvbiBpT1MgKGlzc3VlICMxOCk6IGlmIGEgc3VibWl0IGVsZW1lbnQgaXMgcHJlc2VudCBpbnNpZGUgYSBmb3JtIGFuZCB0aGUgdXNlciBoaXRzIGVudGVyIGluIHRoZSBpT1Mgc2ltdWxhdG9yIG9yIGNsaWNrcyB0aGUgR28gYnV0dG9uIG9uIHRoZSBwb3AtdXAgT1Mga2V5Ym9hcmQgdGhlIGEga2luZCBvZiAnZmFrZScgY2xpY2sgZXZlbnQgd2lsbCBiZSB0cmlnZ2VyZWQgd2l0aCB0aGUgc3VibWl0LXR5cGUgaW5wdXQgZWxlbWVudCBhcyB0aGUgdGFyZ2V0LlxuXHRcdGlmIChldmVudC50YXJnZXQudHlwZSA9PT0gJ3N1Ym1pdCcgJiYgZXZlbnQuZGV0YWlsID09PSAwKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHRwZXJtaXR0ZWQgPSB0aGlzLm9uTW91c2UoZXZlbnQpO1xuXG5cdFx0Ly8gT25seSB1bnNldCB0YXJnZXRFbGVtZW50IGlmIHRoZSBjbGljayBpcyBub3QgcGVybWl0dGVkLiBUaGlzIHdpbGwgZW5zdXJlIHRoYXQgdGhlIGNoZWNrIGZvciAhdGFyZ2V0RWxlbWVudCBpbiBvbk1vdXNlIGZhaWxzIGFuZCB0aGUgYnJvd3NlcidzIGNsaWNrIGRvZXNuJ3QgZ28gdGhyb3VnaC5cblx0XHRpZiAoIXBlcm1pdHRlZCkge1xuXHRcdFx0dGhpcy50YXJnZXRFbGVtZW50ID0gbnVsbDtcblx0XHR9XG5cblx0XHQvLyBJZiBjbGlja3MgYXJlIHBlcm1pdHRlZCwgcmV0dXJuIHRydWUgZm9yIHRoZSBhY3Rpb24gdG8gZ28gdGhyb3VnaC5cblx0XHRyZXR1cm4gcGVybWl0dGVkO1xuXHR9O1xuXG5cblx0LyoqXG5cdCAqIFJlbW92ZSBhbGwgRmFzdENsaWNrJ3MgZXZlbnQgbGlzdGVuZXJzLlxuXHQgKlxuXHQgKiBAcmV0dXJucyB7dm9pZH1cblx0ICovXG5cdEZhc3RDbGljay5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBsYXllciA9IHRoaXMubGF5ZXI7XG5cblx0XHRpZiAoZGV2aWNlSXNBbmRyb2lkKSB7XG5cdFx0XHRsYXllci5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW92ZXInLCB0aGlzLm9uTW91c2UsIHRydWUpO1xuXHRcdFx0bGF5ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlLCB0cnVlKTtcblx0XHRcdGxheWVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm9uTW91c2UsIHRydWUpO1xuXHRcdH1cblxuXHRcdGxheWVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5vbkNsaWNrLCB0cnVlKTtcblx0XHRsYXllci5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgdGhpcy5vblRvdWNoU3RhcnQsIGZhbHNlKTtcblx0XHRsYXllci5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLm9uVG91Y2hNb3ZlLCBmYWxzZSk7XG5cdFx0bGF5ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLm9uVG91Y2hFbmQsIGZhbHNlKTtcblx0XHRsYXllci5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaGNhbmNlbCcsIHRoaXMub25Ub3VjaENhbmNlbCwgZmFsc2UpO1xuXHR9O1xuXG5cblx0LyoqXG5cdCAqIENoZWNrIHdoZXRoZXIgRmFzdENsaWNrIGlzIG5lZWRlZC5cblx0ICpcblx0ICogQHBhcmFtIHtFbGVtZW50fSBsYXllciBUaGUgbGF5ZXIgdG8gbGlzdGVuIG9uXG5cdCAqL1xuXHRGYXN0Q2xpY2subm90TmVlZGVkID0gZnVuY3Rpb24obGF5ZXIpIHtcblx0XHR2YXIgbWV0YVZpZXdwb3J0O1xuXHRcdHZhciBjaHJvbWVWZXJzaW9uO1xuXHRcdHZhciBibGFja2JlcnJ5VmVyc2lvbjtcblx0XHR2YXIgZmlyZWZveFZlcnNpb247XG5cblx0XHQvLyBEZXZpY2VzIHRoYXQgZG9uJ3Qgc3VwcG9ydCB0b3VjaCBkb24ndCBuZWVkIEZhc3RDbGlja1xuXHRcdGlmICh0eXBlb2Ygd2luZG93Lm9udG91Y2hzdGFydCA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIENocm9tZSB2ZXJzaW9uIC0gemVybyBmb3Igb3RoZXIgYnJvd3NlcnNcblx0XHRjaHJvbWVWZXJzaW9uID0gKygvQ2hyb21lXFwvKFswLTldKykvLmV4ZWMobmF2aWdhdG9yLnVzZXJBZ2VudCkgfHwgWywwXSlbMV07XG5cblx0XHRpZiAoY2hyb21lVmVyc2lvbikge1xuXG5cdFx0XHRpZiAoZGV2aWNlSXNBbmRyb2lkKSB7XG5cdFx0XHRcdG1ldGFWaWV3cG9ydCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ21ldGFbbmFtZT12aWV3cG9ydF0nKTtcblxuXHRcdFx0XHRpZiAobWV0YVZpZXdwb3J0KSB7XG5cdFx0XHRcdFx0Ly8gQ2hyb21lIG9uIEFuZHJvaWQgd2l0aCB1c2VyLXNjYWxhYmxlPVwibm9cIiBkb2Vzbid0IG5lZWQgRmFzdENsaWNrIChpc3N1ZSAjODkpXG5cdFx0XHRcdFx0aWYgKG1ldGFWaWV3cG9ydC5jb250ZW50LmluZGV4T2YoJ3VzZXItc2NhbGFibGU9bm8nKSAhPT0gLTEpIHtcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHQvLyBDaHJvbWUgMzIgYW5kIGFib3ZlIHdpdGggd2lkdGg9ZGV2aWNlLXdpZHRoIG9yIGxlc3MgZG9uJ3QgbmVlZCBGYXN0Q2xpY2tcblx0XHRcdFx0XHRpZiAoY2hyb21lVmVyc2lvbiA+IDMxICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxXaWR0aCA8PSB3aW5kb3cub3V0ZXJXaWR0aCkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdC8vIENocm9tZSBkZXNrdG9wIGRvZXNuJ3QgbmVlZCBGYXN0Q2xpY2sgKGlzc3VlICMxNSlcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChkZXZpY2VJc0JsYWNrQmVycnkxMCkge1xuXHRcdFx0YmxhY2tiZXJyeVZlcnNpb24gPSBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9WZXJzaW9uXFwvKFswLTldKilcXC4oWzAtOV0qKS8pO1xuXG5cdFx0XHQvLyBCbGFja0JlcnJ5IDEwLjMrIGRvZXMgbm90IHJlcXVpcmUgRmFzdGNsaWNrIGxpYnJhcnkuXG5cdFx0XHQvLyBodHRwczovL2dpdGh1Yi5jb20vZnRsYWJzL2Zhc3RjbGljay9pc3N1ZXMvMjUxXG5cdFx0XHRpZiAoYmxhY2tiZXJyeVZlcnNpb25bMV0gPj0gMTAgJiYgYmxhY2tiZXJyeVZlcnNpb25bMl0gPj0gMykge1xuXHRcdFx0XHRtZXRhVmlld3BvcnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdtZXRhW25hbWU9dmlld3BvcnRdJyk7XG5cblx0XHRcdFx0aWYgKG1ldGFWaWV3cG9ydCkge1xuXHRcdFx0XHRcdC8vIHVzZXItc2NhbGFibGU9bm8gZWxpbWluYXRlcyBjbGljayBkZWxheS5cblx0XHRcdFx0XHRpZiAobWV0YVZpZXdwb3J0LmNvbnRlbnQuaW5kZXhPZigndXNlci1zY2FsYWJsZT1ubycpICE9PSAtMSkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdC8vIHdpZHRoPWRldmljZS13aWR0aCAob3IgbGVzcyB0aGFuIGRldmljZS13aWR0aCkgZWxpbWluYXRlcyBjbGljayBkZWxheS5cblx0XHRcdFx0XHRpZiAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFdpZHRoIDw9IHdpbmRvdy5vdXRlcldpZHRoKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBJRTEwIHdpdGggLW1zLXRvdWNoLWFjdGlvbjogbm9uZSBvciBtYW5pcHVsYXRpb24sIHdoaWNoIGRpc2FibGVzIGRvdWJsZS10YXAtdG8tem9vbSAoaXNzdWUgIzk3KVxuXHRcdGlmIChsYXllci5zdHlsZS5tc1RvdWNoQWN0aW9uID09PSAnbm9uZScgfHwgbGF5ZXIuc3R5bGUudG91Y2hBY3Rpb24gPT09ICdtYW5pcHVsYXRpb24nKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHQvLyBGaXJlZm94IHZlcnNpb24gLSB6ZXJvIGZvciBvdGhlciBicm93c2Vyc1xuXHRcdGZpcmVmb3hWZXJzaW9uID0gKygvRmlyZWZveFxcLyhbMC05XSspLy5leGVjKG5hdmlnYXRvci51c2VyQWdlbnQpIHx8IFssMF0pWzFdO1xuXG5cdFx0aWYgKGZpcmVmb3hWZXJzaW9uID49IDI3KSB7XG5cdFx0XHQvLyBGaXJlZm94IDI3KyBkb2VzIG5vdCBoYXZlIHRhcCBkZWxheSBpZiB0aGUgY29udGVudCBpcyBub3Qgem9vbWFibGUgLSBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD05MjI4OTZcblxuXHRcdFx0bWV0YVZpZXdwb3J0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignbWV0YVtuYW1lPXZpZXdwb3J0XScpO1xuXHRcdFx0aWYgKG1ldGFWaWV3cG9ydCAmJiAobWV0YVZpZXdwb3J0LmNvbnRlbnQuaW5kZXhPZigndXNlci1zY2FsYWJsZT1ubycpICE9PSAtMSB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsV2lkdGggPD0gd2luZG93Lm91dGVyV2lkdGgpKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIElFMTE6IHByZWZpeGVkIC1tcy10b3VjaC1hY3Rpb24gaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZCBhbmQgaXQncyByZWNvbWVuZGVkIHRvIHVzZSBub24tcHJlZml4ZWQgdmVyc2lvblxuXHRcdC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS93aW5kb3dzL2FwcHMvSGg3NjczMTMuYXNweFxuXHRcdGlmIChsYXllci5zdHlsZS50b3VjaEFjdGlvbiA9PT0gJ25vbmUnIHx8IGxheWVyLnN0eWxlLnRvdWNoQWN0aW9uID09PSAnbWFuaXB1bGF0aW9uJykge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9O1xuXG5cblx0LyoqXG5cdCAqIEZhY3RvcnkgbWV0aG9kIGZvciBjcmVhdGluZyBhIEZhc3RDbGljayBvYmplY3Rcblx0ICpcblx0ICogQHBhcmFtIHtFbGVtZW50fSBsYXllciBUaGUgbGF5ZXIgdG8gbGlzdGVuIG9uXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgdG8gb3ZlcnJpZGUgdGhlIGRlZmF1bHRzXG5cdCAqL1xuXHRGYXN0Q2xpY2suYXR0YWNoID0gZnVuY3Rpb24obGF5ZXIsIG9wdGlvbnMpIHtcblx0XHRyZXR1cm4gbmV3IEZhc3RDbGljayhsYXllciwgb3B0aW9ucyk7XG5cdH07XG5cblxuXHRpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgZGVmaW5lLmFtZCA9PT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuXG5cdFx0Ly8gQU1ELiBSZWdpc3RlciBhcyBhbiBhbm9ueW1vdXMgbW9kdWxlLlxuXHRcdGRlZmluZShmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBGYXN0Q2xpY2s7XG5cdFx0fSk7XG5cdH0gZWxzZSBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIHtcblx0XHRtb2R1bGUuZXhwb3J0cyA9IEZhc3RDbGljay5hdHRhY2g7XG5cdFx0bW9kdWxlLmV4cG9ydHMuRmFzdENsaWNrID0gRmFzdENsaWNrO1xuXHR9IGVsc2Uge1xuXHRcdHdpbmRvdy5GYXN0Q2xpY2sgPSBGYXN0Q2xpY2s7XG5cdH1cbn0oKSk7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy9mYXN0Y2xpY2svbGliL2Zhc3RjbGljay5qc1xuLy8gbW9kdWxlIGlkID0gMjBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLypcbiAqIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuICogZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbiAqIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuICogc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbiAqIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1NcbiAqIElOIFRIRSBTT0ZUV0FSRS5cbiAqL1xuXG5pbXBvcnQgRXZlbnQgZnJvbSBcIi4vTWF0ZXJpYWwvRXZlbnRcIlxuaW1wb3J0IEhlYWRlciBmcm9tIFwiLi9NYXRlcmlhbC9IZWFkZXJcIlxuaW1wb3J0IE5hdiBmcm9tIFwiLi9NYXRlcmlhbC9OYXZcIlxuaW1wb3J0IFNlYXJjaCBmcm9tIFwiLi9NYXRlcmlhbC9TZWFyY2hcIlxuaW1wb3J0IFNpZGViYXIgZnJvbSBcIi4vTWF0ZXJpYWwvU2lkZWJhclwiXG5pbXBvcnQgU291cmNlIGZyb20gXCIuL01hdGVyaWFsL1NvdXJjZVwiXG5pbXBvcnQgVGFicyBmcm9tIFwiLi9NYXRlcmlhbC9UYWJzXCJcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogTW9kdWxlXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgRXZlbnQsXG4gIEhlYWRlcixcbiAgTmF2LFxuICBTZWFyY2gsXG4gIFNpZGViYXIsXG4gIFNvdXJjZSxcbiAgVGFic1xufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsLmpzIiwiLypcbiAqIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuICogZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbiAqIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuICogc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbiAqIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1NcbiAqIElOIFRIRSBTT0ZUV0FSRS5cbiAqL1xuXG5pbXBvcnQgTGlzdGVuZXIgZnJvbSBcIi4vRXZlbnQvTGlzdGVuZXJcIlxuaW1wb3J0IE1hdGNoTWVkaWEgZnJvbSBcIi4vRXZlbnQvTWF0Y2hNZWRpYVwiXG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIE1vZHVsZVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIExpc3RlbmVyLFxuICBNYXRjaE1lZGlhXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwvRXZlbnQuanMiLCIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4gKiBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuICogcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4gKiBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuICogRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HU1xuICogSU4gVEhFIFNPRlRXQVJFLlxuICovXG5cbmltcG9ydCBMaXN0ZW5lciBmcm9tIFwiLi9MaXN0ZW5lclwiIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQ2xhc3NcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWF0Y2hNZWRpYSB7XG5cbiAgLyoqXG4gICAqIE1lZGlhIHF1ZXJ5IGxpc3RlbmVyXG4gICAqXG4gICAqIFRoaXMgY2xhc3MgbGlzdGVucyBmb3Igc3RhdGUgY2hhbmdlcyBvZiBtZWRpYSBxdWVyaWVzIGFuZCBhdXRvbWF0aWNhbGx5XG4gICAqIHN3aXRjaGVzIHRoZSBnaXZlbiBsaXN0ZW5lcnMgb24gb3Igb2ZmLlxuICAgKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICpcbiAgICogQHByb3BlcnR5IHtGdW5jdGlvbn0gaGFuZGxlcl8gLSBNZWRpYSBxdWVyeSBldmVudCBoYW5kbGVyXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBxdWVyeSAtIE1lZGlhIHF1ZXJ5IHRvIHRlc3QgZm9yXG4gICAqIEBwYXJhbSB7TGlzdGVuZXJ9IGxpc3RlbmVyIC0gRXZlbnQgbGlzdGVuZXJcbiAgICovXG4gIGNvbnN0cnVjdG9yKHF1ZXJ5LCBsaXN0ZW5lcikge1xuICAgIHRoaXMuaGFuZGxlcl8gPSBtcSA9PiB7XG4gICAgICBpZiAobXEubWF0Y2hlcylcbiAgICAgICAgbGlzdGVuZXIubGlzdGVuKClcbiAgICAgIGVsc2VcbiAgICAgICAgbGlzdGVuZXIudW5saXN0ZW4oKVxuICAgIH1cblxuICAgIC8qIEluaXRpYWxpemUgbWVkaWEgcXVlcnkgbGlzdGVuZXIgKi9cbiAgICBjb25zdCBtZWRpYSA9IHdpbmRvdy5tYXRjaE1lZGlhKHF1ZXJ5KVxuICAgIG1lZGlhLmFkZExpc3RlbmVyKHRoaXMuaGFuZGxlcl8pXG5cbiAgICAvKiBBbHdheXMgY2hlY2sgYXQgaW5pdGlhbGl6YXRpb24gKi9cbiAgICB0aGlzLmhhbmRsZXJfKG1lZGlhKVxuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwvRXZlbnQvTWF0Y2hNZWRpYS5qcyIsIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbiAqIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4gKiByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3JcbiAqIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4gKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTXG4gKiBJTiBUSEUgU09GVFdBUkUuXG4gKi9cblxuaW1wb3J0IFNoYWRvdyBmcm9tIFwiLi9IZWFkZXIvU2hhZG93XCJcbmltcG9ydCBUaXRsZSBmcm9tIFwiLi9IZWFkZXIvVGl0bGVcIlxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBNb2R1bGVcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuZXhwb3J0IGRlZmF1bHQge1xuICBTaGFkb3csXG4gIFRpdGxlXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwvSGVhZGVyLmpzIiwiLypcbiAqIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuICogZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbiAqIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuICogc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbiAqIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1NcbiAqIElOIFRIRSBTT0ZUV0FSRS5cbiAqL1xuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBDbGFzc1xuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTaGFkb3cge1xuXG4gIC8qKlxuICAgKiBTaG93IG9yIGhpZGUgaGVhZGVyIHNoYWRvdyBkZXBlbmRpbmcgb24gcGFnZSB5LW9mZnNldFxuICAgKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICpcbiAgICogQHByb3BlcnR5IHtIVE1MRWxlbWVudH0gZWxfIC0gQ29udGVudCBjb250YWluZXJcbiAgICogQHByb3BlcnR5IHtIVE1MRWxlbWVudH0gaGVhZGVyXyAtIEhlYWRlclxuICAgKiBAcHJvcGVydHkge251bWJlcn0gaGVpZ2h0XyAtIE9mZnNldCBoZWlnaHQgb2YgcHJldmlvdXMgbm9kZXNcbiAgICogQHByb3BlcnR5IHtib29sZWFufSBhY3RpdmVfIC0gSGVhZGVyIHNoYWRvdyBzdGF0ZVxuICAgKlxuICAgKiBAcGFyYW0geyhzdHJpbmd8SFRNTEVsZW1lbnQpfSBlbCAtIFNlbGVjdG9yIG9yIEhUTUwgZWxlbWVudFxuICAgKiBAcGFyYW0geyhzdHJpbmd8SFRNTEVsZW1lbnQpfSBoZWFkZXIgLSBTZWxlY3RvciBvciBIVE1MIGVsZW1lbnRcbiAgICovXG4gIGNvbnN0cnVjdG9yKGVsLCBoZWFkZXIpIHtcbiAgICBsZXQgcmVmID0gKHR5cGVvZiBlbCA9PT0gXCJzdHJpbmdcIilcbiAgICAgID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbClcbiAgICAgIDogZWxcbiAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkgfHxcbiAgICAgICAgIShyZWYucGFyZW50Tm9kZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSlcbiAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuICAgIHRoaXMuZWxfID0gcmVmLnBhcmVudE5vZGVcblxuICAgIC8qIFJldHJpZXZlIGhlYWRlciAqL1xuICAgIHJlZiA9ICh0eXBlb2YgaGVhZGVyID09PSBcInN0cmluZ1wiKVxuICAgICAgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGhlYWRlcilcbiAgICAgIDogaGVhZGVyXG4gICAgaWYgKCEocmVmIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKVxuICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG4gICAgdGhpcy5oZWFkZXJfID0gcmVmXG5cbiAgICAvKiBJbml0aWFsaXplIGhlaWdodCBhbmQgc3RhdGUgKi9cbiAgICB0aGlzLmhlaWdodF8gPSAwXG4gICAgdGhpcy5hY3RpdmVfID0gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdG90YWwgaGVpZ2h0IG9mIHByZXZpb3VzIG5vZGVzXG4gICAqL1xuICBzZXR1cCgpIHtcbiAgICBsZXQgY3VycmVudCA9IHRoaXMuZWxfXG4gICAgd2hpbGUgKChjdXJyZW50ID0gY3VycmVudC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nKSkge1xuICAgICAgaWYgKCEoY3VycmVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSlcbiAgICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG4gICAgICB0aGlzLmhlaWdodF8gKz0gY3VycmVudC5vZmZzZXRIZWlnaHRcbiAgICB9XG4gICAgdGhpcy51cGRhdGUoKVxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBzaGFkb3cgc3RhdGVcbiAgICpcbiAgICogQHBhcmFtIHtFdmVudH0gZXYgLSBFdmVudFxuICAgKi9cbiAgdXBkYXRlKGV2KSB7XG4gICAgaWYgKGV2ICYmIChldi50eXBlID09PSBcInJlc2l6ZVwiIHx8IGV2LnR5cGUgPT09IFwib3JpZW50YXRpb25jaGFuZ2VcIikpIHtcbiAgICAgIHRoaXMuaGVpZ2h0XyA9IDBcbiAgICAgIHRoaXMuc2V0dXAoKVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBhY3RpdmUgPSB3aW5kb3cucGFnZVlPZmZzZXQgPj0gdGhpcy5oZWlnaHRfXG4gICAgICBpZiAoYWN0aXZlICE9PSB0aGlzLmFjdGl2ZV8pXG4gICAgICAgIHRoaXMuaGVhZGVyXy5kYXRhc2V0Lm1kU3RhdGUgPSAodGhpcy5hY3RpdmVfID0gYWN0aXZlKSA/IFwic2hhZG93XCIgOiBcIlwiXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IHNoYWRvdyBzdGF0ZVxuICAgKi9cbiAgcmVzZXQoKSB7XG4gICAgdGhpcy5oZWFkZXJfLmRhdGFzZXQubWRTdGF0ZSA9IFwiXCJcbiAgICB0aGlzLmhlaWdodF8gPSAwXG4gICAgdGhpcy5hY3RpdmVfID0gZmFsc2VcbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL0hlYWRlci9TaGFkb3cuanMiLCIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4gKiBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuICogcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4gKiBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuICogRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HU1xuICogSU4gVEhFIFNPRlRXQVJFLlxuICovXG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIENsYXNzXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRpdGxlIHtcblxuICAvKipcbiAgICogU3dhcCBoZWFkZXIgdGl0bGUgdG9waWNzIHdoZW4gaGVhZGVyIGlzIHNjcm9sbGVkIHBhc3RcbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwcm9wZXJ0eSB7SFRNTEVsZW1lbnR9IGVsXyAtIEVsZW1lbnRcbiAgICogQHByb3BlcnR5IHtIVE1MRWxlbWVudH0gaGVhZGVyXyAtIEhlYWRlclxuICAgKiBAcHJvcGVydHkge2Jvb2xlYW59IGFjdGl2ZV8gLSBUaXRsZSBzdGF0ZVxuICAgKlxuICAgKiBAcGFyYW0geyhzdHJpbmd8SFRNTEVsZW1lbnQpfSBlbCAtIFNlbGVjdG9yIG9yIEhUTUwgZWxlbWVudFxuICAgKiBAcGFyYW0geyhzdHJpbmd8SFRNTEhlYWRpbmdFbGVtZW50KX0gaGVhZGVyIC0gU2VsZWN0b3Igb3IgSFRNTCBlbGVtZW50XG4gICAqL1xuICBjb25zdHJ1Y3RvcihlbCwgaGVhZGVyKSB7XG4gICAgbGV0IHJlZiA9ICh0eXBlb2YgZWwgPT09IFwic3RyaW5nXCIpXG4gICAgICA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWwpXG4gICAgICA6IGVsXG4gICAgaWYgKCEocmVmIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKVxuICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG4gICAgdGhpcy5lbF8gPSByZWZcblxuICAgIC8qIFJldHJpZXZlIGhlYWRlciAqL1xuICAgIHJlZiA9ICh0eXBlb2YgaGVhZGVyID09PSBcInN0cmluZ1wiKVxuICAgICAgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGhlYWRlcilcbiAgICAgIDogaGVhZGVyXG4gICAgaWYgKCEocmVmIGluc3RhbmNlb2YgSFRNTEhlYWRpbmdFbGVtZW50KSlcbiAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuICAgIHRoaXMuaGVhZGVyXyA9IHJlZlxuXG4gICAgLyogSW5pdGlhbGl6ZSBzdGF0ZSAqL1xuICAgIHRoaXMuYWN0aXZlXyA9IGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogU2V0dXAgdGl0bGUgc3RhdGVcbiAgICovXG4gIHNldHVwKCkge1xuICAgIEFycmF5LnByb3RvdHlwZS5mb3JFYWNoLmNhbGwodGhpcy5lbF8uY2hpbGRyZW4sIG5vZGUgPT4geyAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiB1c2UgY2hpbGROb2RlcyBoZXJlIGZvciBJRT9cbiAgICAgIG5vZGUuc3R5bGUud2lkdGggPSBgJHt0aGlzLmVsXy5vZmZzZXRXaWR0aCAtIDIwfXB4YFxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIHRpdGxlIHN0YXRlXG4gICAqXG4gICAqIEBwYXJhbSB7RXZlbnR9IGV2IC0gRXZlbnRcbiAgICovXG4gIHVwZGF0ZShldikge1xuICAgIGNvbnN0IGFjdGl2ZSA9IHdpbmRvdy5wYWdlWU9mZnNldCA+PSB0aGlzLmhlYWRlcl8ub2Zmc2V0VG9wXG4gICAgaWYgKGFjdGl2ZSAhPT0gdGhpcy5hY3RpdmVfKVxuICAgICAgdGhpcy5lbF8uZGF0YXNldC5tZFN0YXRlID0gKHRoaXMuYWN0aXZlXyA9IGFjdGl2ZSkgPyBcImFjdGl2ZVwiIDogXCJcIlxuXG4gICAgLyogSGFjazogaW5kdWNlIGVsbGlwc2lzIG9uIHRvcGljcyAqL1xuICAgIGlmIChldi50eXBlID09PSBcInJlc2l6ZVwiIHx8IGV2LnR5cGUgPT09IFwib3JpZW50YXRpb25jaGFuZ2VcIikge1xuICAgICAgQXJyYXkucHJvdG90eXBlLmZvckVhY2guY2FsbCh0aGlzLmVsXy5jaGlsZHJlbiwgbm9kZSA9PiB7XG4gICAgICAgIG5vZGUuc3R5bGUud2lkdGggPSBgJHt0aGlzLmVsXy5vZmZzZXRXaWR0aCAtIDIwfXB4YFxuICAgICAgfSlcbiAgICB9XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNldCB0aXRsZSBzdGF0ZVxuICAgKi9cbiAgcmVzZXQoKSB7XG4gICAgdGhpcy5lbF8uZGF0YXNldC5tZFN0YXRlID0gXCJcIlxuICAgIHRoaXMuZWxfLnN0eWxlLndpZHRoID0gXCJcIlxuICAgIHRoaXMuYWN0aXZlXyA9IGZhbHNlXG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9IZWFkZXIvVGl0bGUuanMiLCIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4gKiBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuICogcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4gKiBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuICogRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HU1xuICogSU4gVEhFIFNPRlRXQVJFLlxuICovXG5cbmltcG9ydCBCbHVyIGZyb20gXCIuL05hdi9CbHVyXCJcbmltcG9ydCBDb2xsYXBzZSBmcm9tIFwiLi9OYXYvQ29sbGFwc2VcIlxuaW1wb3J0IFNjcm9sbGluZyBmcm9tIFwiLi9OYXYvU2Nyb2xsaW5nXCJcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogTW9kdWxlXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgQmx1cixcbiAgQ29sbGFwc2UsXG4gIFNjcm9sbGluZ1xufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL05hdi5qcyIsIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbiAqIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4gKiByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3JcbiAqIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4gKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTXG4gKiBJTiBUSEUgU09GVFdBUkUuXG4gKi9cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQ2xhc3NcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQmx1ciB7XG5cbiAgLyoqXG4gICAqIEJsdXIgbGlua3Mgd2l0aGluIHRoZSB0YWJsZSBvZiBjb250ZW50cyBhYm92ZSBjdXJyZW50IHBhZ2UgeS1vZmZzZXRcbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwcm9wZXJ0eSB7Tm9kZUxpc3Q8SFRNTEVsZW1lbnQ+fSBlbHNfIC0gVGFibGUgb2YgY29udGVudHMgbGlua3NcbiAgICogQHByb3BlcnR5IHtBcnJheTxIVE1MRWxlbWVudD59IGFuY2hvcnNfIC0gUmVmZXJlbmNlZCBhbmNob3Igbm9kZXNcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IGluZGV4XyAtIEN1cnJlbnQgbGluayBpbmRleFxuICAgKiBAcHJvcGVydHkge251bWJlcn0gb2Zmc2V0XyAtIEN1cnJlbnQgcGFnZSB5LW9mZnNldFxuICAgKiBAcHJvcGVydHkge2Jvb2xlYW59IGRpcl8gLSBTY3JvbGwgZGlyZWN0aW9uIGNoYW5nZVxuICAgKlxuICAgKiBAcGFyYW0geyhzdHJpbmd8Tm9kZUxpc3Q8SFRNTEVsZW1lbnQ+KX0gZWxzIC0gU2VsZWN0b3Igb3IgSFRNTCBlbGVtZW50c1xuICAgKi9cbiAgY29uc3RydWN0b3IoZWxzKSB7XG4gICAgdGhpcy5lbHNfID0gKHR5cGVvZiBlbHMgPT09IFwic3RyaW5nXCIpXG4gICAgICA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoZWxzKVxuICAgICAgOiBlbHNcblxuICAgIC8qIEluaXRpYWxpemUgaW5kZXggYW5kIHBhZ2UgeS1vZmZzZXQgKi9cbiAgICB0aGlzLmluZGV4XyA9IDBcbiAgICB0aGlzLm9mZnNldF8gPSB3aW5kb3cucGFnZVlPZmZzZXRcblxuICAgIC8qIE5lY2Vzc2FyeSBzdGF0ZSB0byBjb3JyZWN0bHkgcmVzZXQgdGhlIGluZGV4ICovXG4gICAgdGhpcy5kaXJfID0gZmFsc2VcblxuICAgIC8qIEluZGV4IGFuY2hvciBub2RlIG9mZnNldHMgZm9yIGZhc3QgbG9va3VwICovXG4gICAgdGhpcy5hbmNob3JzXyA9IFtdLnJlZHVjZS5jYWxsKHRoaXMuZWxzXywgKGFuY2hvcnMsIGVsKSA9PiB7XG4gICAgICByZXR1cm4gYW5jaG9ycy5jb25jYXQoXG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsLmhhc2guc3Vic3RyaW5nKDEpKSB8fCBbXSlcbiAgICB9LCBbXSlcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGJsdXIgc3RhdGVzXG4gICAqL1xuICBzZXR1cCgpIHtcbiAgICB0aGlzLnVwZGF0ZSgpXG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIGJsdXIgc3RhdGVzXG4gICAqXG4gICAqIERlZHVjdCB0aGUgc3RhdGljIG9mZnNldCBvZiB0aGUgaGVhZGVyICg1NnB4KSBhbmQgc2lkZWJhciBvZmZzZXQgKDI0cHgpLFxuICAgKiBzZWUgX3Blcm1hbGlua3Muc2NzcyBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAgICovXG4gIHVwZGF0ZSgpIHtcbiAgICBjb25zdCBvZmZzZXQgPSB3aW5kb3cucGFnZVlPZmZzZXRcbiAgICBjb25zdCBkaXIgPSB0aGlzLm9mZnNldF8gLSBvZmZzZXQgPCAwXG5cbiAgICAvKiBIYWNrOiByZXNldCBpbmRleCBpZiBkaXJlY3Rpb24gY2hhbmdlZCB0byBjYXRjaCB2ZXJ5IGZhc3Qgc2Nyb2xsaW5nLFxuICAgICAgIGJlY2F1c2Ugb3RoZXJ3aXNlIHdlIHdvdWxkIGhhdmUgdG8gcmVnaXN0ZXIgYSB0aW1lciBhbmQgdGhhdCBzdWNrcyAqL1xuICAgIGlmICh0aGlzLmRpcl8gIT09IGRpcilcbiAgICAgIHRoaXMuaW5kZXhfID0gZGlyXG4gICAgICAgID8gdGhpcy5pbmRleF8gPSAwXG4gICAgICAgIDogdGhpcy5pbmRleF8gPSB0aGlzLmVsc18ubGVuZ3RoIC0gMVxuXG4gICAgLyogRXhpdCB3aGVuIHRoZXJlIGFyZSBubyBhbmNob3JzICovXG4gICAgaWYgKHRoaXMuYW5jaG9yc18ubGVuZ3RoID09PSAwKVxuICAgICAgcmV0dXJuXG5cbiAgICAvKiBTY3JvbGwgZGlyZWN0aW9uIGlzIGRvd24gKi9cbiAgICBpZiAodGhpcy5vZmZzZXRfIDw9IG9mZnNldCkge1xuICAgICAgZm9yIChsZXQgaSA9IHRoaXMuaW5kZXhfICsgMTsgaSA8IHRoaXMuZWxzXy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAodGhpcy5hbmNob3JzX1tpXS5vZmZzZXRUb3AgLSAoNTYgKyAyNCkgPD0gb2Zmc2V0KSB7XG4gICAgICAgICAgaWYgKGkgPiAwKVxuICAgICAgICAgICAgdGhpcy5lbHNfW2kgLSAxXS5kYXRhc2V0Lm1kU3RhdGUgPSBcImJsdXJcIlxuICAgICAgICAgIHRoaXMuaW5kZXhfID0gaVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgIC8qIFNjcm9sbCBkaXJlY3Rpb24gaXMgdXAgKi9cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChsZXQgaSA9IHRoaXMuaW5kZXhfOyBpID49IDA7IGktLSkge1xuICAgICAgICBpZiAodGhpcy5hbmNob3JzX1tpXS5vZmZzZXRUb3AgLSAoNTYgKyAyNCkgPiBvZmZzZXQpIHtcbiAgICAgICAgICBpZiAoaSA+IDApXG4gICAgICAgICAgICB0aGlzLmVsc19baSAtIDFdLmRhdGFzZXQubWRTdGF0ZSA9IFwiXCJcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmluZGV4XyA9IGlcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyogUmVtZW1iZXIgY3VycmVudCBvZmZzZXQgYW5kIGRpcmVjdGlvbiBmb3IgbmV4dCBpdGVyYXRpb24gKi9cbiAgICB0aGlzLm9mZnNldF8gPSBvZmZzZXRcbiAgICB0aGlzLmRpcl8gPSBkaXJcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNldCBibHVyIHN0YXRlc1xuICAgKi9cbiAgcmVzZXQoKSB7XG4gICAgQXJyYXkucHJvdG90eXBlLmZvckVhY2guY2FsbCh0aGlzLmVsc18sIGVsID0+IHtcbiAgICAgIGVsLmRhdGFzZXQubWRTdGF0ZSA9IFwiXCJcbiAgICB9KVxuXG4gICAgLyogUmVzZXQgaW5kZXggYW5kIHBhZ2UgeS1vZmZzZXQgKi9cbiAgICB0aGlzLmluZGV4XyAgPSAwXG4gICAgdGhpcy5vZmZzZXRfID0gd2luZG93LnBhZ2VZT2Zmc2V0XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9OYXYvQmx1ci5qcyIsIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbiAqIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4gKiByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3JcbiAqIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4gKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTXG4gKiBJTiBUSEUgU09GVFdBUkUuXG4gKi9cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQ2xhc3NcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ29sbGFwc2Uge1xuXG4gIC8qKlxuICAgKiBFeHBhbmQgb3IgY29sbGFwc2UgbmF2aWdhdGlvbiBvbiB0b2dnbGVcbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwcm9wZXJ0eSB7SFRNTEVsZW1lbnR9IGVsXyAtIE5hdmlnYXRpb24gbGlzdFxuICAgKlxuICAgKiBAcGFyYW0geyhzdHJpbmd8SFRNTEVsZW1lbnQpfSBlbCAtIFNlbGVjdG9yIG9yIEhUTUwgZWxlbWVudFxuICAgKi9cbiAgY29uc3RydWN0b3IoZWwpIHtcbiAgICBjb25zdCByZWYgPSAodHlwZW9mIGVsID09PSBcInN0cmluZ1wiKVxuICAgICAgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsKVxuICAgICAgOiBlbFxuICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSlcbiAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuICAgIHRoaXMuZWxfID0gcmVmXG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBvdmVyZmxvdyBhbmQgZGlzcGxheSBmb3IgYWNjZXNzaWJpbGl0eVxuICAgKi9cbiAgc2V0dXAoKSB7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuZWxfLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodFxuXG4gICAgLyogSGlkZGVuIGxpbmtzIHNob3VsZCBub3QgYmUgZm9jdXNhYmxlLCBzbyBoaWRlIHRoZW0gd2hlbiB0aGUgbmF2aWdhdGlvblxuICAgICAgIGlzIGNvbGxhcHNlZCBhbmQgc2V0IG92ZXJmbG93IHNvIHRoZSBvdXRsaW5lIGlzIG5vdCBjdXQgb2ZmICovXG4gICAgdGhpcy5lbF8uc3R5bGUuZGlzcGxheSAgPSBjdXJyZW50ID8gXCJibG9ja1wiICAgOiBcIm5vbmVcIlxuICAgIHRoaXMuZWxfLnN0eWxlLm92ZXJmbG93ID0gY3VycmVudCA/IFwidmlzaWJsZVwiIDogXCJoaWRkZW5cIlxuICB9XG5cbiAgLyoqXG4gICAqIEFuaW1hdGUgZXhwYW5kIGFuZCBjb2xsYXBzZSBzbW9vdGhseVxuICAgKlxuICAgKiBJbnRlcm5ldCBFeHBsb3JlciAxMSBpcyB2ZXJ5IHNsb3cgYXQgcmVjb2duaXppbmcgY2hhbmdlcyBvbiB0aGUgZGF0YXNldFxuICAgKiB3aGljaCByZXN1bHRzIGluIHRoZSBtZW51IG5vdCBleHBhbmRpbmcgb3IgY29sbGFwc2luZyBwcm9wZXJseS4gVEhlcmVmb3JlLFxuICAgKiBmb3IgcmVhc29ucyBvZiBjb21wYXRpYmlsaXR5LCB0aGUgYXR0cmlidXRlIGFjY2Vzc29ycyBhcmUgdXNlZC5cbiAgICovXG4gIHVwZGF0ZSgpIHtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5lbF8uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0XG5cbiAgICAvKiBSZXNldCBvdmVyZmxvdyB0byBDU1MgZGVmYXVsdHMgKi9cbiAgICB0aGlzLmVsXy5zdHlsZS5kaXNwbGF5ICA9IFwiYmxvY2tcIlxuICAgIHRoaXMuZWxfLnN0eWxlLm92ZXJmbG93ID0gXCJcIlxuXG4gICAgLyogRXhwYW5kZWQsIHNvIGNvbGxhcHNlICovXG4gICAgaWYgKGN1cnJlbnQpIHtcbiAgICAgIHRoaXMuZWxfLnN0eWxlLm1heEhlaWdodCA9IGAke2N1cnJlbnR9cHhgXG4gICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICB0aGlzLmVsXy5zZXRBdHRyaWJ1dGUoXCJkYXRhLW1kLXN0YXRlXCIsIFwiYW5pbWF0ZVwiKVxuICAgICAgICB0aGlzLmVsXy5zdHlsZS5tYXhIZWlnaHQgPSBcIjBweFwiXG4gICAgICB9KVxuXG4gICAgLyogQ29sbGFwc2VkLCBzbyBleHBhbmQgKi9cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbF8uc2V0QXR0cmlidXRlKFwiZGF0YS1tZC1zdGF0ZVwiLCBcImV4cGFuZFwiKVxuICAgICAgdGhpcy5lbF8uc3R5bGUubWF4SGVpZ2h0ID0gXCJcIlxuXG4gICAgICAvKiBSZWFkIGhlaWdodCBhbmQgdW5zZXQgcHNldWRvLXRvZ2dsZWQgc3RhdGUgKi9cbiAgICAgIGNvbnN0IGhlaWdodCA9IHRoaXMuZWxfLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodFxuICAgICAgdGhpcy5lbF8ucmVtb3ZlQXR0cmlidXRlKFwiZGF0YS1tZC1zdGF0ZVwiKVxuXG4gICAgICAvKiBTZXQgaW5pdGlhbCBzdGF0ZSBhbmQgYW5pbWF0ZSAqL1xuICAgICAgdGhpcy5lbF8uc3R5bGUubWF4SGVpZ2h0ID0gXCIwcHhcIlxuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgdGhpcy5lbF8uc2V0QXR0cmlidXRlKFwiZGF0YS1tZC1zdGF0ZVwiLCBcImFuaW1hdGVcIilcbiAgICAgICAgdGhpcy5lbF8uc3R5bGUubWF4SGVpZ2h0ID0gYCR7aGVpZ2h0fXB4YFxuICAgICAgfSlcbiAgICB9XG5cbiAgICAvKiBSZW1vdmUgc3RhdGUgb24gZW5kIG9mIHRyYW5zaXRpb24gKi9cbiAgICBjb25zdCBlbmQgPSBldiA9PiB7XG4gICAgICBjb25zdCB0YXJnZXQgPSBldi50YXJnZXRcbiAgICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSlcbiAgICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG5cbiAgICAgIC8qIFJlc2V0IGhlaWdodCBhbmQgc3RhdGUgKi9cbiAgICAgIHRhcmdldC5yZW1vdmVBdHRyaWJ1dGUoXCJkYXRhLW1kLXN0YXRlXCIpXG4gICAgICB0YXJnZXQuc3R5bGUubWF4SGVpZ2h0ID0gXCJcIlxuXG4gICAgICAvKiBIaWRkZW4gbGlua3Mgc2hvdWxkIG5vdCBiZSBmb2N1c2FibGUsIHNvIGhpZGUgdGhlbSB3aGVuIHRoZSBuYXZpZ2F0aW9uXG4gICAgICAgICBpcyBjb2xsYXBzZWQgYW5kIHNldCBvdmVyZmxvdyBzbyB0aGUgb3V0bGluZSBpcyBub3QgY3V0IG9mZiAqL1xuICAgICAgdGFyZ2V0LnN0eWxlLmRpc3BsYXkgID0gY3VycmVudCA/IFwibm9uZVwiICAgOiBcImJsb2NrXCJcbiAgICAgIHRhcmdldC5zdHlsZS5vdmVyZmxvdyA9IGN1cnJlbnQgPyBcImhpZGRlblwiIDogXCJ2aXNpYmxlXCJcblxuICAgICAgLyogT25seSBmaXJlIG9uY2UsIHNvIGRpcmVjdGx5IHJlbW92ZSBldmVudCBsaXN0ZW5lciAqL1xuICAgICAgdGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0cmFuc2l0aW9uZW5kXCIsIGVuZClcbiAgICB9XG4gICAgdGhpcy5lbF8uYWRkRXZlbnRMaXN0ZW5lcihcInRyYW5zaXRpb25lbmRcIiwgZW5kLCBmYWxzZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNldCBoZWlnaHQgYW5kIHBzZXVkby10b2dnbGVkIHN0YXRlXG4gICAqL1xuICByZXNldCgpIHtcbiAgICB0aGlzLmVsXy5kYXRhc2V0Lm1kU3RhdGUgPSBcIlwiXG4gICAgdGhpcy5lbF8uc3R5bGUubWF4SGVpZ2h0ID0gXCJcIlxuICAgIHRoaXMuZWxfLnN0eWxlLmRpc3BsYXkgICA9IFwiXCJcbiAgICB0aGlzLmVsXy5zdHlsZS5vdmVyZmxvdyAgPSBcIlwiXG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9OYXYvQ29sbGFwc2UuanMiLCIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4gKiBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuICogcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4gKiBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuICogRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HU1xuICogSU4gVEhFIFNPRlRXQVJFLlxuICovXG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIENsYXNzXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNjcm9sbGluZyB7XG5cbiAgLyoqXG4gICAqIFNldCBvdmVyZmxvdyBzY3JvbGxpbmcgb24gdGhlIGN1cnJlbnQgYWN0aXZlIHBhbmUgKGZvciBpT1MpXG4gICAqXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKlxuICAgKiBAcHJvcGVydHkge0hUTUxFbGVtZW50fSBlbF8gLSBQcmltYXJ5IG5hdmlnYXRpb25cbiAgICpcbiAgICogQHBhcmFtIHsoc3RyaW5nfEhUTUxFbGVtZW50KX0gZWwgLSBTZWxlY3RvciBvciBIVE1MIGVsZW1lbnRcbiAgICovXG4gIGNvbnN0cnVjdG9yKGVsKSB7XG4gICAgY29uc3QgcmVmID0gKHR5cGVvZiBlbCA9PT0gXCJzdHJpbmdcIilcbiAgICAgID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbClcbiAgICAgIDogZWxcbiAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpXG4gICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3JcbiAgICB0aGlzLmVsXyA9IHJlZlxuICB9XG5cbiAgLyoqXG4gICAqIFNldHVwIHBhbmVzXG4gICAqL1xuICBzZXR1cCgpIHtcblxuICAgIC8qIEluaXRpYWxseSBzZXQgb3ZlcmZsb3cgc2Nyb2xsaW5nIG9uIG1haW4gcGFuZSAqL1xuICAgIGNvbnN0IG1haW4gPSB0aGlzLmVsXy5jaGlsZHJlblt0aGlzLmVsXy5jaGlsZHJlbi5sZW5ndGggLSAxXVxuICAgIG1haW4uc3R5bGUud2Via2l0T3ZlcmZsb3dTY3JvbGxpbmcgPSBcInRvdWNoXCJcblxuICAgIC8qIEZpbmQgYWxsIHRvZ2dsZXMgYW5kIGNoZWNrIHdoaWNoIG9uZSBpcyBhY3RpdmUgKi9cbiAgICBjb25zdCB0b2dnbGVzID0gdGhpcy5lbF8ucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLW1kLXRvZ2dsZV1cIilcbiAgICBBcnJheS5wcm90b3R5cGUuZm9yRWFjaC5jYWxsKHRvZ2dsZXMsIHRvZ2dsZSA9PiB7XG4gICAgICBpZiAoISh0b2dnbGUgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50KSlcbiAgICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG4gICAgICBpZiAodG9nZ2xlLmNoZWNrZWQpIHtcblxuICAgICAgICAvKiBGaW5kIGNvcnJlc3BvbmRpbmcgbmF2aWdhdGlvbmFsIHBhbmUgKi9cbiAgICAgICAgbGV0IHBhbmUgPSB0b2dnbGUubmV4dEVsZW1lbnRTaWJsaW5nXG4gICAgICAgIGlmICghKHBhbmUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpXG4gICAgICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG4gICAgICAgIHdoaWxlIChwYW5lLnRhZ05hbWUgIT09IFwiTkFWXCIgJiYgcGFuZS5uZXh0RWxlbWVudFNpYmxpbmcpXG4gICAgICAgICAgcGFuZSA9IHBhbmUubmV4dEVsZW1lbnRTaWJsaW5nXG5cbiAgICAgICAgLyogQ2hlY2sgcmVmZXJlbmNlcyAqL1xuICAgICAgICBpZiAoISh0b2dnbGUucGFyZW50Tm9kZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB8fFxuICAgICAgICAgICAgISh0b2dnbGUucGFyZW50Tm9kZS5wYXJlbnROb2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKVxuICAgICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuXG4gICAgICAgIC8qIEZpbmQgY3VycmVudCBhbmQgcGFyZW50IGxpc3QgZWxlbWVudHMgKi9cbiAgICAgICAgY29uc3QgcGFyZW50ID0gdG9nZ2xlLnBhcmVudE5vZGUucGFyZW50Tm9kZVxuICAgICAgICBjb25zdCB0YXJnZXQgPSBwYW5lLmNoaWxkcmVuW3BhbmUuY2hpbGRyZW4ubGVuZ3RoIC0gMV1cblxuICAgICAgICAvKiBBbHdheXMgcmVzZXQgYWxsIGxpc3RzIHdoZW4gdHJhbnNpdGlvbmluZyAqL1xuICAgICAgICBwYXJlbnQuc3R5bGUud2Via2l0T3ZlcmZsb3dTY3JvbGxpbmcgPSBcIlwiXG4gICAgICAgIHRhcmdldC5zdHlsZS53ZWJraXRPdmVyZmxvd1Njcm9sbGluZyA9IFwidG91Y2hcIlxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIGFjdGl2ZSBwYW5lc1xuICAgKlxuICAgKiBAcGFyYW0ge0V2ZW50fSBldiAtIENoYW5nZSBldmVudFxuICAgKi9cbiAgdXBkYXRlKGV2KSB7XG4gICAgY29uc3QgdGFyZ2V0ID0gZXYudGFyZ2V0XG4gICAgaWYgKCEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKVxuICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG5cbiAgICAvKiBGaW5kIGNvcnJlc3BvbmRpbmcgbmF2aWdhdGlvbmFsIHBhbmUgKi9cbiAgICBsZXQgcGFuZSA9IHRhcmdldC5uZXh0RWxlbWVudFNpYmxpbmdcbiAgICBpZiAoIShwYW5lIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKVxuICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG4gICAgd2hpbGUgKHBhbmUudGFnTmFtZSAhPT0gXCJOQVZcIiAmJiBwYW5lLm5leHRFbGVtZW50U2libGluZylcbiAgICAgIHBhbmUgPSBwYW5lLm5leHRFbGVtZW50U2libGluZ1xuXG4gICAgLyogQ2hlY2sgcmVmZXJlbmNlcyAqL1xuICAgIGlmICghKHRhcmdldC5wYXJlbnROb2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHx8XG4gICAgICAgICEodGFyZ2V0LnBhcmVudE5vZGUucGFyZW50Tm9kZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSlcbiAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuXG4gICAgLyogRmluZCBwYXJlbnQgYW5kIGFjdGl2ZSBwYW5lcyAqL1xuICAgIGNvbnN0IHBhcmVudCA9IHRhcmdldC5wYXJlbnROb2RlLnBhcmVudE5vZGVcbiAgICBjb25zdCBhY3RpdmUgPSBwYW5lLmNoaWxkcmVuW3BhbmUuY2hpbGRyZW4ubGVuZ3RoIC0gMV1cblxuICAgIC8qIEFsd2F5cyByZXNldCBhbGwgbGlzdHMgd2hlbiB0cmFuc2l0aW9uaW5nICovXG4gICAgcGFyZW50LnN0eWxlLndlYmtpdE92ZXJmbG93U2Nyb2xsaW5nID0gXCJcIlxuICAgIGFjdGl2ZS5zdHlsZS53ZWJraXRPdmVyZmxvd1Njcm9sbGluZyA9IFwiXCJcblxuICAgIC8qIFNldCBvdmVyZmxvdyBzY3JvbGxpbmcgb24gcGFyZW50IHBhbmUgKi9cbiAgICBpZiAoIXRhcmdldC5jaGVja2VkKSB7XG4gICAgICBjb25zdCBlbmQgPSAoKSA9PiB7XG4gICAgICAgIGlmIChwYW5lIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICBwYXJlbnQuc3R5bGUud2Via2l0T3ZlcmZsb3dTY3JvbGxpbmcgPSBcInRvdWNoXCJcbiAgICAgICAgICBwYW5lLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0cmFuc2l0aW9uZW5kXCIsIGVuZClcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcGFuZS5hZGRFdmVudExpc3RlbmVyKFwidHJhbnNpdGlvbmVuZFwiLCBlbmQsIGZhbHNlKVxuICAgIH1cblxuICAgIC8qIFNldCBvdmVyZmxvdyBzY3JvbGxpbmcgb24gYWN0aXZlIHBhbmUgKi9cbiAgICBpZiAodGFyZ2V0LmNoZWNrZWQpIHtcbiAgICAgIGNvbnN0IGVuZCA9ICgpID0+IHtcbiAgICAgICAgaWYgKHBhbmUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgIGFjdGl2ZS5zdHlsZS53ZWJraXRPdmVyZmxvd1Njcm9sbGluZyA9IFwidG91Y2hcIlxuICAgICAgICAgIHBhbmUucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRyYW5zaXRpb25lbmRcIiwgZW5kKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBwYW5lLmFkZEV2ZW50TGlzdGVuZXIoXCJ0cmFuc2l0aW9uZW5kXCIsIGVuZCwgZmFsc2UpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IHBhbmVzXG4gICAqL1xuICByZXNldCgpIHtcblxuICAgIC8qIFJlc2V0IG92ZXJmbG93IHNjcm9sbGluZyBvbiBtYWluIHBhbmUgKi9cbiAgICB0aGlzLmVsXy5jaGlsZHJlblsxXS5zdHlsZS53ZWJraXRPdmVyZmxvd1Njcm9sbGluZyA9IFwiXCJcblxuICAgIC8qIEZpbmQgYWxsIHRvZ2dsZXMgYW5kIGNoZWNrIHdoaWNoIG9uZSBpcyBhY3RpdmUgKi9cbiAgICBjb25zdCB0b2dnbGVzID0gdGhpcy5lbF8ucXVlcnlTZWxlY3RvckFsbChcIltkYXRhLW1kLXRvZ2dsZV1cIilcbiAgICBBcnJheS5wcm90b3R5cGUuZm9yRWFjaC5jYWxsKHRvZ2dsZXMsIHRvZ2dsZSA9PiB7XG4gICAgICBpZiAoISh0b2dnbGUgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50KSlcbiAgICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG4gICAgICBpZiAodG9nZ2xlLmNoZWNrZWQpIHtcblxuICAgICAgICAvKiBGaW5kIGNvcnJlc3BvbmRpbmcgbmF2aWdhdGlvbmFsIHBhbmUgKi9cbiAgICAgICAgbGV0IHBhbmUgPSB0b2dnbGUubmV4dEVsZW1lbnRTaWJsaW5nXG4gICAgICAgIGlmICghKHBhbmUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpXG4gICAgICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG4gICAgICAgIHdoaWxlIChwYW5lLnRhZ05hbWUgIT09IFwiTkFWXCIgJiYgcGFuZS5uZXh0RWxlbWVudFNpYmxpbmcpXG4gICAgICAgICAgcGFuZSA9IHBhbmUubmV4dEVsZW1lbnRTaWJsaW5nXG5cbiAgICAgICAgLyogQ2hlY2sgcmVmZXJlbmNlcyAqL1xuICAgICAgICBpZiAoISh0b2dnbGUucGFyZW50Tm9kZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB8fFxuICAgICAgICAgICAgISh0b2dnbGUucGFyZW50Tm9kZS5wYXJlbnROb2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKVxuICAgICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuXG4gICAgICAgIC8qIEZpbmQgcGFyZW50IGFuZCBhY3RpdmUgcGFuZXMgKi9cbiAgICAgICAgY29uc3QgcGFyZW50ID0gdG9nZ2xlLnBhcmVudE5vZGUucGFyZW50Tm9kZVxuICAgICAgICBjb25zdCBhY3RpdmUgPSBwYW5lLmNoaWxkcmVuW3BhbmUuY2hpbGRyZW4ubGVuZ3RoIC0gMV1cblxuICAgICAgICAvKiBBbHdheXMgcmVzZXQgYWxsIGxpc3RzIHdoZW4gdHJhbnNpdGlvbmluZyAqL1xuICAgICAgICBwYXJlbnQuc3R5bGUud2Via2l0T3ZlcmZsb3dTY3JvbGxpbmcgPSBcIlwiXG4gICAgICAgIGFjdGl2ZS5zdHlsZS53ZWJraXRPdmVyZmxvd1Njcm9sbGluZyA9IFwiXCJcbiAgICAgIH1cbiAgICB9KVxuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwvTmF2L1Njcm9sbGluZy5qcyIsIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbiAqIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4gKiByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3JcbiAqIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4gKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTXG4gKiBJTiBUSEUgU09GVFdBUkUuXG4gKi9cblxuaW1wb3J0IExvY2sgZnJvbSBcIi4vU2VhcmNoL0xvY2tcIlxuaW1wb3J0IFJlc3VsdCBmcm9tIFwiLi9TZWFyY2gvUmVzdWx0XCJcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogTW9kdWxlXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgTG9jayxcbiAgUmVzdWx0XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwvU2VhcmNoLmpzIiwiLypcbiAqIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuICogZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbiAqIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuICogc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbiAqIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1NcbiAqIElOIFRIRSBTT0ZUV0FSRS5cbiAqL1xuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBDbGFzc1xuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMb2NrIHtcblxuICAvKipcbiAgICogTG9jayBib2R5IGZvciBmdWxsLXNjcmVlbiBzZWFyY2ggbW9kYWxcbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwcm9wZXJ0eSB7SFRNTElucHV0RWxlbWVudH0gZWxfIC0gTG9jayB0b2dnbGVcbiAgICogQHByb3BlcnR5IHtIVE1MRWxlbWVudH0gbG9ja18gLSBFbGVtZW50IHRvIGxvY2sgKGRvY3VtZW50IGJvZHkpXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBvZmZzZXRfIC0gQ3VycmVudCBwYWdlIHktb2Zmc2V0XG4gICAqXG4gICAqIEBwYXJhbSB7KHN0cmluZ3xIVE1MRWxlbWVudCl9IGVsIC0gU2VsZWN0b3Igb3IgSFRNTCBlbGVtZW50XG4gICAqL1xuICBjb25zdHJ1Y3RvcihlbCkge1xuICAgIGNvbnN0IHJlZiA9ICh0eXBlb2YgZWwgPT09IFwic3RyaW5nXCIpXG4gICAgICA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWwpXG4gICAgICA6IGVsXG4gICAgaWYgKCEocmVmIGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkpXG4gICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3JcbiAgICB0aGlzLmVsXyA9IHJlZlxuXG4gICAgLyogUmV0cmlldmUgZWxlbWVudCB0byBsb2NrICg9IGJvZHkpICovXG4gICAgaWYgKCFkb2N1bWVudC5ib2R5KVxuICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG4gICAgdGhpcy5sb2NrXyA9IGRvY3VtZW50LmJvZHlcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXR1cCBsb2NrZWQgc3RhdGVcbiAgICovXG4gIHNldHVwKCkge1xuICAgIHRoaXMudXBkYXRlKClcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgbG9ja2VkIHN0YXRlXG4gICAqL1xuICB1cGRhdGUoKSB7XG5cbiAgICAvKiBFbnRlcmluZyBzZWFyY2ggbW9kZSAqL1xuICAgIGlmICh0aGlzLmVsXy5jaGVja2VkKSB7XG4gICAgICB0aGlzLm9mZnNldF8gPSB3aW5kb3cucGFnZVlPZmZzZXRcblxuICAgICAgLyogU2Nyb2xsIHRvIHRvcCBhZnRlciB0cmFuc2l0aW9uLCB0byBvbWl0IGZsaWNrZXJpbmcgKi9cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB3aW5kb3cuc2Nyb2xsVG8oMCwgMClcblxuICAgICAgICAvKiBMb2NrIGJvZHkgYWZ0ZXIgZmluaXNoaW5nIHRyYW5zaXRpb24gKi9cbiAgICAgICAgaWYgKHRoaXMuZWxfLmNoZWNrZWQpIHtcbiAgICAgICAgICB0aGlzLmxvY2tfLmRhdGFzZXQubWRTdGF0ZSA9IFwibG9ja1wiXG4gICAgICAgIH1cbiAgICAgIH0sIDQwMClcblxuICAgIC8qIEV4aXRpbmcgc2VhcmNoIG1vZGUgKi9cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sb2NrXy5kYXRhc2V0Lm1kU3RhdGUgPSBcIlwiXG5cbiAgICAgIC8qIFNjcm9sbCB0byBmb3JtZXIgcG9zaXRpb24sIGJ1dCB3YWl0IGZvciAxMDBtcyB0byBwcmV2ZW50IGZsYXNoZXMgb25cbiAgICAgICAgIGlPUy4gQSBzaG9ydCB0aW1lb3V0IHNlZW1zIHRvIGRvIHRoZSB0cmljayAqL1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5vZmZzZXRfICE9PSBcInVuZGVmaW5lZFwiKVxuICAgICAgICAgIHdpbmRvdy5zY3JvbGxUbygwLCB0aGlzLm9mZnNldF8pXG4gICAgICB9LCAxMDApXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IGxvY2tlZCBzdGF0ZSBhbmQgcGFnZSB5LW9mZnNldFxuICAgKi9cbiAgcmVzZXQoKSB7XG4gICAgaWYgKHRoaXMubG9ja18uZGF0YXNldC5tZFN0YXRlID09PSBcImxvY2tcIilcbiAgICAgIHdpbmRvdy5zY3JvbGxUbygwLCB0aGlzLm9mZnNldF8pXG4gICAgdGhpcy5sb2NrXy5kYXRhc2V0Lm1kU3RhdGUgPSBcIlwiXG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9TZWFyY2gvTG9jay5qcyIsIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbiAqIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4gKiByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3JcbiAqIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4gKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTXG4gKiBJTiBUSEUgU09GVFdBUkUuXG4gKi9cblxuaW1wb3J0IGVzY2FwZSBmcm9tIFwiZXNjYXBlLXN0cmluZy1yZWdleHBcIlxuaW1wb3J0IGx1bnIgZnJvbSBcImV4cG9zZS1sb2FkZXI/bHVuciFsdW5yXCJcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogRnVuY3Rpb25zXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qKlxuICogRXNjYXBlIEhUTUwgc3RyaW5nc1xuICpcbiAqIERvY3VtZW50YXRpb24gbWF5IGNvbnRhaW4gY29kZSBKYXZhU2NyaXB0IGNvZGUgc25pcHBldHMgd2hpY2ggd291bGQgZ2V0XG4gKiBleGVjdXRlZCB3aGVuIGluc2VydGVkIGludG8gdGhlIERPTSBhcyBwbGFpbiBIVE1MLlxuICpcbiAqIFNlZSBodHRwczovL2dpdGh1Yi5jb20vc3F1aWRmdW5rL21rZG9jcy1tYXRlcmlhbC9pc3N1ZXMvOTA2XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGh0bWwgLSBIVE1MIHN0cmluZ1xuICpcbiAqIEByZXR1cm4ge3N0cmluZ30gRXNjYXBlZCBIVE1MIHN0cmluZ1xuICovXG5jb25zdCBlc2NhcGVIVE1MID0gaHRtbCA9PiB7XG4gIHZhciB0ZXh0ID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoaHRtbCk7XG4gIHZhciBwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgncCcpO1xuICBwLmFwcGVuZENoaWxkKHRleHQpO1xuICByZXR1cm4gcC5pbm5lckhUTUw7XG59XG5cbi8qKlxuICogVHJ1bmNhdGUgYSBzdHJpbmcgYWZ0ZXIgdGhlIGdpdmVuIG51bWJlciBvZiBjaGFyYWN0ZXJcbiAqXG4gKiBUaGlzIGlzIG5vdCBhIHJlYXNvbmFibGUgYXBwcm9hY2gsIHNpbmNlIHRoZSBzdW1tYXJpZXMga2luZCBvZiBzdWNrLiBJdFxuICogd291bGQgYmUgYmV0dGVyIHRvIGNyZWF0ZSBzb21ldGhpbmcgbW9yZSBpbnRlbGxpZ2VudCwgaGlnaGxpZ2h0aW5nIHRoZVxuICogc2VhcmNoIG9jY3VycmVuY2VzIGFuZCBtYWtpbmcgYSBiZXR0ZXIgc3VtbWFyeSBvdXQgb2YgaXQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyAtIFN0cmluZyB0byBiZSB0cnVuY2F0ZWRcbiAqIEBwYXJhbSB7bnVtYmVyfSBuIC0gTnVtYmVyIG9mIGNoYXJhY3RlcnNcbiAqIEByZXR1cm4ge3N0cmluZ30gVHJ1bmNhdGVkIHN0cmluZ1xuICovXG5jb25zdCB0cnVuY2F0ZSA9IChzdHJpbmcsIG4pID0+IHtcbiAgbGV0IGkgPSBuXG4gIGlmIChzdHJpbmcubGVuZ3RoID4gaSkge1xuICAgIHdoaWxlIChzdHJpbmdbaV0gIT09IFwiIFwiICYmIC0taSA+IDApO1xuICAgIHJldHVybiBgJHtzdHJpbmcuc3Vic3RyaW5nKDAsIGkpfS4uLmBcbiAgfVxuICByZXR1cm4gc3RyaW5nXG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBtZXRhIHRhZyB2YWx1ZSBmb3IgdGhlIGdpdmVuIGtleVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBNZXRhIG5hbWVcbiAqXG4gKiBAcmV0dXJuIHtzdHJpbmd9IE1ldGEgY29udGVudCB2YWx1ZVxuICovXG5jb25zdCB0cmFuc2xhdGUgPSBrZXkgPT4ge1xuICBjb25zdCBtZXRhID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeU5hbWUoYGxhbmc6JHtrZXl9YClbMF1cbiAgaWYgKCEobWV0YSBpbnN0YW5jZW9mIEhUTUxNZXRhRWxlbWVudCkpXG4gICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG4gIHJldHVybiBtZXRhLmNvbnRlbnRcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQ2xhc3NcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmVzdWx0IHtcblxuICAvKipcbiAgICogUGVyZm9ybSBzZWFyY2ggYW5kIHVwZGF0ZSByZXN1bHRzIG9uIGtleWJvYXJkIGV2ZW50c1xuICAgKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICpcbiAgICogQHByb3BlcnR5IHtIVE1MRWxlbWVudH0gZWxfIC0gU2VhcmNoIHJlc3VsdCBjb250YWluZXJcbiAgICogQHByb3BlcnR5IHsoQXJyYXk8T2JqZWN0PnxGdW5jdGlvbil9IGRhdGFfIC0gUmF3IGRvY3VtZW50IGRhdGFcbiAgICogQHByb3BlcnR5IHtPYmplY3R9IGRvY3NfIC0gSW5kZXhlZCBkb2N1bWVudHNcbiAgICogQHByb3BlcnR5IHtIVE1MRWxlbWVudH0gbWV0YV8gLSBTZWFyY2ggbWV0YSBpbmZvcm1hdGlvblxuICAgKiBAcHJvcGVydHkge0hUTUxFbGVtZW50fSBsaXN0XyAtIFNlYXJjaCByZXN1bHQgbGlzdFxuICAgKiBAcHJvcGVydHkge0FycmF5PHN0cmluZz59IGxhbmdfIC0gU2VhcmNoIGxhbmd1YWdlc1xuICAgKiBAcHJvcGVydHkge09iamVjdH0gbWVzc2FnZV8gLSBTZWFyY2ggcmVzdWx0IG1lc3NhZ2VzXG4gICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBpbmRleF8gLSBTZWFyY2ggaW5kZXhcbiAgICogQHByb3BlcnR5IHtBcnJheTxGdW5jdGlvbj59IHN0YWNrXyAtIFNlYXJjaCByZXN1bHQgc3RhY2tcbiAgICogQHByb3BlcnR5IHtzdHJpbmd9IHZhbHVlXyAtIExhc3QgaW5wdXQgdmFsdWVcbiAgICpcbiAgICogQHBhcmFtIHsoc3RyaW5nfEhUTUxFbGVtZW50KX0gZWwgLSBTZWxlY3RvciBvciBIVE1MIGVsZW1lbnRcbiAgICogQHBhcmFtIHsoQXJyYXk8T2JqZWN0PnxGdW5jdGlvbil9IGRhdGEgLSBGdW5jdGlvbiBwcm92aWRpbmcgZGF0YSBvciBhcnJheVxuICAgKi9cbiAgY29uc3RydWN0b3IoZWwsIGRhdGEpIHtcbiAgICBjb25zdCByZWYgPSAodHlwZW9mIGVsID09PSBcInN0cmluZ1wiKVxuICAgICAgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsKVxuICAgICAgOiBlbFxuICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSlcbiAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuICAgIHRoaXMuZWxfID0gcmVmXG5cbiAgICAvKiBSZXRyaWV2ZSBtZXRhZGF0YSBhbmQgbGlzdCBlbGVtZW50ICovXG4gICAgY29uc3QgW21ldGEsIGxpc3RdID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5lbF8uY2hpbGRyZW4pXG5cbiAgICAvKiBTZXQgZGF0YSwgbWV0YWRhdGEgYW5kIGxpc3QgZWxlbWVudHMgKi9cbiAgICB0aGlzLmRhdGFfID0gZGF0YVxuICAgIHRoaXMubWV0YV8gPSBtZXRhXG4gICAgdGhpcy5saXN0XyA9IGxpc3RcblxuICAgIC8qIExvYWQgbWVzc2FnZXMgZm9yIG1ldGFkYXRhIGRpc3BsYXkgKi9cbiAgICB0aGlzLm1lc3NhZ2VfID0ge1xuICAgICAgcGxhY2Vob2xkZXI6IHRoaXMubWV0YV8udGV4dENvbnRlbnQsXG4gICAgICBub25lOiB0cmFuc2xhdGUoXCJzZWFyY2gucmVzdWx0Lm5vbmVcIiksXG4gICAgICBvbmU6IHRyYW5zbGF0ZShcInNlYXJjaC5yZXN1bHQub25lXCIpLFxuICAgICAgb3RoZXI6IHRyYW5zbGF0ZShcInNlYXJjaC5yZXN1bHQub3RoZXJcIilcbiAgICB9XG5cbiAgICAvKiBPdmVycmlkZSB0b2tlbml6ZXIgc2VwYXJhdG9yLCBpZiBnaXZlbiAqL1xuICAgIGNvbnN0IHRva2VuaXplciA9IHRyYW5zbGF0ZShcInNlYXJjaC50b2tlbml6ZXJcIilcbiAgICBpZiAodG9rZW5pemVyLmxlbmd0aClcbiAgICAgIGx1bnIudG9rZW5pemVyLnNlcGFyYXRvciA9IHRva2VuaXplclxuXG4gICAgLyogTG9hZCBzZWFyY2ggbGFuZ3VhZ2VzICovXG4gICAgdGhpcy5sYW5nXyA9IHRyYW5zbGF0ZShcInNlYXJjaC5sYW5ndWFnZVwiKS5zcGxpdChcIixcIilcbiAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgIC5tYXAobGFuZyA9PiBsYW5nLnRyaW0oKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgc2VhcmNoIHJlc3VsdHNcbiAgICpcbiAgICogQHBhcmFtIHtFdmVudH0gZXYgLSBJbnB1dCBvciBmb2N1cyBldmVudFxuICAgKi9cbiAgdXBkYXRlKGV2KSB7XG5cbiAgICAvKiBJbml0aWFsaXplIGluZGV4LCBpZiB0aGlzIGhhcyBub3QgYmUgZG9uZSB5ZXQgKi9cbiAgICBpZiAoZXYudHlwZSA9PT0gXCJmb2N1c1wiICYmICF0aGlzLmluZGV4Xykge1xuXG4gICAgICAvKiBJbml0aWFsaXplIGluZGV4ICovXG4gICAgICBjb25zdCBpbml0ID0gZGF0YSA9PiB7XG5cbiAgICAgICAgLyogUHJlcHJvY2VzcyBhbmQgaW5kZXggc2VjdGlvbnMgYW5kIGRvY3VtZW50cyAqL1xuICAgICAgICB0aGlzLmRvY3NfID0gZGF0YS5yZWR1Y2UoKGRvY3MsIGRvYykgPT4ge1xuICAgICAgICAgIGNvbnN0IFtwYXRoLCBoYXNoXSA9IGRvYy5sb2NhdGlvbi5zcGxpdChcIiNcIilcblxuICAgICAgICAgIC8qIEVzY2FwZSBIVE1MICovXG4gICAgICAgICAgZG9jLnRpdGxlID0gZXNjYXBlSFRNTChkb2MudGl0bGUpXG4gICAgICAgICAgZG9jLnRleHQgID0gZXNjYXBlSFRNTChkb2MudGV4dClcblxuICAgICAgICAgIC8qIEFzc29jaWF0ZSBzZWN0aW9uIHdpdGggcGFyZW50IGRvY3VtZW50ICovXG4gICAgICAgICAgaWYgKGhhc2gpIHtcbiAgICAgICAgICAgIGRvYy5wYXJlbnQgPSBkb2NzLmdldChwYXRoKVxuXG4gICAgICAgICAgICAvKiBPdmVycmlkZSBwYWdlIHRpdGxlIHdpdGggZG9jdW1lbnQgdGl0bGUgaWYgZmlyc3Qgc2VjdGlvbiAqL1xuICAgICAgICAgICAgaWYgKGRvYy5wYXJlbnQgJiYgIWRvYy5wYXJlbnQuZG9uZSkge1xuICAgICAgICAgICAgICBkb2MucGFyZW50LnRpdGxlID0gZG9jLnRpdGxlXG4gICAgICAgICAgICAgIGRvYy5wYXJlbnQudGV4dCAgPSBkb2MudGV4dFxuICAgICAgICAgICAgICBkb2MucGFyZW50LmRvbmUgID0gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8qIFNvbWUgY2xlYW51cCBvbiB0aGUgdGV4dCAqL1xuICAgICAgICAgIGRvYy50ZXh0ID0gZG9jLnRleHRcbiAgICAgICAgICAgIC5yZXBsYWNlKC9cXG4vZywgXCIgXCIpICAgICAgICAgICAgICAgLyogUmVtb3ZlIG5ld2xpbmVzICovXG4gICAgICAgICAgICAucmVwbGFjZSgvXFxzKy9nLCBcIiBcIikgICAgICAgICAgICAgIC8qIENvbXBhY3Qgd2hpdGVzcGFjZSAqL1xuICAgICAgICAgICAgLnJlcGxhY2UoL1xccysoWywuOjshP10pL2csICAgICAgICAgLyogQ29ycmVjdCBwdW5jdHVhdGlvbiAqL1xuICAgICAgICAgICAgICAoXywgY2hhcikgPT4gY2hhcilcblxuICAgICAgICAgIC8qIEluZGV4IHNlY3Rpb25zIGFuZCBkb2N1bWVudHMsIGJ1dCBza2lwIHRvcC1sZXZlbCBoZWFkbGluZSAqL1xuICAgICAgICAgIGlmICghZG9jLnBhcmVudCB8fCBkb2MucGFyZW50LnRpdGxlICE9PSBkb2MudGl0bGUpXG4gICAgICAgICAgICBkb2NzLnNldChkb2MubG9jYXRpb24sIGRvYylcbiAgICAgICAgICByZXR1cm4gZG9jc1xuICAgICAgICB9LCBuZXcgTWFwKVxuXG4gICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWludmFsaWQtdGhpcyAqL1xuICAgICAgICBjb25zdCBkb2NzID0gdGhpcy5kb2NzXyxcbiAgICAgICAgICAgICAgbGFuZyA9IHRoaXMubGFuZ19cblxuICAgICAgICAvKiBDcmVhdGUgc3RhY2sgYW5kIGluZGV4ICovXG4gICAgICAgIHRoaXMuc3RhY2tfID0gW11cbiAgICAgICAgdGhpcy5pbmRleF8gPSBsdW5yKGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGNvbnN0IGZpbHRlcnMgPSB7XG4gICAgICAgICAgICBcInNlYXJjaC5waXBlbGluZS50cmltbWVyXCI6IGx1bnIudHJpbW1lcixcbiAgICAgICAgICAgIFwic2VhcmNoLnBpcGVsaW5lLnN0b3B3b3Jkc1wiOiBsdW5yLnN0b3BXb3JkRmlsdGVyXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLyogRGlzYWJsZSBzdG9wIHdvcmRzIGZpbHRlciBhbmQgdHJpbW1lciwgaWYgZGVzaXJlZCAqL1xuICAgICAgICAgIGNvbnN0IHBpcGVsaW5lID0gT2JqZWN0LmtleXMoZmlsdGVycykucmVkdWNlKChyZXN1bHQsIG5hbWUpID0+IHtcbiAgICAgICAgICAgIGlmICghdHJhbnNsYXRlKG5hbWUpLm1hdGNoKC9eZmFsc2UkL2kpKVxuICAgICAgICAgICAgICByZXN1bHQucHVzaChmaWx0ZXJzW25hbWVdKVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgICAgICAgIH0sIFtdKVxuXG4gICAgICAgICAgLyogUmVtb3ZlIHN0ZW1tZXIsIGFzIGl0IGNyaXBwbGVzIHNlYXJjaCBleHBlcmllbmNlICovXG4gICAgICAgICAgdGhpcy5waXBlbGluZS5yZXNldCgpXG4gICAgICAgICAgaWYgKHBpcGVsaW5lKVxuICAgICAgICAgICAgdGhpcy5waXBlbGluZS5hZGQoLi4ucGlwZWxpbmUpXG5cbiAgICAgICAgICAvKiBTZXQgdXAgYWx0ZXJuYXRlIHNlYXJjaCBsYW5ndWFnZXMgKi9cbiAgICAgICAgICBpZiAobGFuZy5sZW5ndGggPT09IDEgJiYgbGFuZ1swXSAhPT0gXCJlblwiICYmIGx1bnJbbGFuZ1swXV0pIHtcbiAgICAgICAgICAgIHRoaXMudXNlKGx1bnJbbGFuZ1swXV0pXG4gICAgICAgICAgfSBlbHNlIGlmIChsYW5nLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIHRoaXMudXNlKGx1bnIubXVsdGlMYW5ndWFnZSguLi5sYW5nKSlcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvKiBJbmRleCBmaWVsZHMgKi9cbiAgICAgICAgICB0aGlzLmZpZWxkKFwidGl0bGVcIiwgeyBib29zdDogMTAgfSlcbiAgICAgICAgICB0aGlzLmZpZWxkKFwidGV4dFwiKVxuICAgICAgICAgIHRoaXMucmVmKFwibG9jYXRpb25cIilcblxuICAgICAgICAgIC8qIEluZGV4IGRvY3VtZW50cyAqL1xuICAgICAgICAgIGRvY3MuZm9yRWFjaChkb2MgPT4gdGhpcy5hZGQoZG9jKSlcbiAgICAgICAgfSlcblxuICAgICAgICAvKiBSZWdpc3RlciBldmVudCBoYW5kbGVyIGZvciBsYXp5IHJlbmRlcmluZyAqL1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmVsXy5wYXJlbnROb2RlXG4gICAgICAgIGlmICghKGNvbnRhaW5lciBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSlcbiAgICAgICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3JcbiAgICAgICAgY29udGFpbmVyLmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgKCkgPT4ge1xuICAgICAgICAgIHdoaWxlICh0aGlzLnN0YWNrXy5sZW5ndGggJiYgY29udGFpbmVyLnNjcm9sbFRvcCArXG4gICAgICAgICAgICAgIGNvbnRhaW5lci5vZmZzZXRIZWlnaHQgPj0gY29udGFpbmVyLnNjcm9sbEhlaWdodCAtIDE2KVxuICAgICAgICAgICAgdGhpcy5zdGFja18uc3BsaWNlKDAsIDEwKS5mb3JFYWNoKHJlbmRlciA9PiByZW5kZXIoKSlcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIC8qIGVzbGludC1lbmFibGUgbm8taW52YWxpZC10aGlzICovXG5cbiAgICAgIC8qIEluaXRpYWxpemUgaW5kZXggYWZ0ZXIgc2hvcnQgdGltZW91dCB0byBhY2NvdW50IGZvciB0cmFuc2l0aW9uICovXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB0aGlzLmRhdGFfID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICA/IHRoaXMuZGF0YV8oKS50aGVuKGluaXQpXG4gICAgICAgICAgOiBpbml0KHRoaXMuZGF0YV8pXG4gICAgICB9LCAyNTApXG5cbiAgICAvKiBFeGVjdXRlIHNlYXJjaCBvbiBuZXcgaW5wdXQgZXZlbnQgKi9cbiAgICB9IGVsc2UgaWYgKGV2LnR5cGUgPT09IFwiZm9jdXNcIiB8fCBldi50eXBlID09PSBcImtleXVwXCIpIHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2LnRhcmdldFxuICAgICAgaWYgKCEodGFyZ2V0IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkpXG4gICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuXG4gICAgICAvKiBBYm9ydCBlYXJseSwgaWYgaW5kZXggaXMgbm90IGJ1aWxkIG9yIGlucHV0IGhhc24ndCBjaGFuZ2VkICovXG4gICAgICBpZiAoIXRoaXMuaW5kZXhfIHx8IHRhcmdldC52YWx1ZSA9PT0gdGhpcy52YWx1ZV8pXG4gICAgICAgIHJldHVyblxuXG4gICAgICAvKiBDbGVhciBjdXJyZW50IGxpc3QgKi9cbiAgICAgIHdoaWxlICh0aGlzLmxpc3RfLmZpcnN0Q2hpbGQpXG4gICAgICAgIHRoaXMubGlzdF8ucmVtb3ZlQ2hpbGQodGhpcy5saXN0Xy5maXJzdENoaWxkKVxuXG4gICAgICAvKiBBYm9ydCBlYXJseSwgaWYgc2VhcmNoIGlucHV0IGlzIGVtcHR5ICovXG4gICAgICB0aGlzLnZhbHVlXyA9IHRhcmdldC52YWx1ZVxuICAgICAgaWYgKHRoaXMudmFsdWVfLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLm1ldGFfLnRleHRDb250ZW50ID0gdGhpcy5tZXNzYWdlXy5wbGFjZWhvbGRlclxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgLyogUGVyZm9ybSBzZWFyY2ggb24gaW5kZXggYW5kIGdyb3VwIHNlY3Rpb25zIGJ5IGRvY3VtZW50ICovXG4gICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmluZGV4X1xuXG4gICAgICAgIC8qIEFwcGVuZCB0cmFpbGluZyB3aWxkY2FyZCB0byBhbGwgdGVybXMgZm9yIHByZWZpeCBxdWVyeWluZyAqL1xuICAgICAgICAucXVlcnkocXVlcnkgPT4ge1xuICAgICAgICAgIHRoaXMudmFsdWVfLnRvTG93ZXJDYXNlKCkuc3BsaXQoXCIgXCIpXG4gICAgICAgICAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgICAgICAgICAuZm9yRWFjaCh0ZXJtID0+IHtcbiAgICAgICAgICAgICAgcXVlcnkudGVybSh0ZXJtLCB7IHdpbGRjYXJkOiBsdW5yLlF1ZXJ5LndpbGRjYXJkLlRSQUlMSU5HIH0pXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuXG4gICAgICAgIC8qIFByb2Nlc3MgcXVlcnkgcmVzdWx0cyAqL1xuICAgICAgICAucmVkdWNlKChpdGVtcywgaXRlbSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGRvYyA9IHRoaXMuZG9jc18uZ2V0KGl0ZW0ucmVmKVxuICAgICAgICAgIGlmIChkb2MucGFyZW50KSB7XG4gICAgICAgICAgICBjb25zdCByZWYgPSBkb2MucGFyZW50LmxvY2F0aW9uXG4gICAgICAgICAgICBpdGVtcy5zZXQocmVmLCAoaXRlbXMuZ2V0KHJlZikgfHwgW10pLmNvbmNhdChpdGVtKSlcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgcmVmID0gZG9jLmxvY2F0aW9uXG4gICAgICAgICAgICBpdGVtcy5zZXQocmVmLCAoaXRlbXMuZ2V0KHJlZikgfHwgW10pKVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gaXRlbXNcbiAgICAgICAgfSwgbmV3IE1hcClcblxuICAgICAgLyogQXNzZW1ibGUgcmVndWxhciBleHByZXNzaW9ucyBmb3IgbWF0Y2hpbmcgKi9cbiAgICAgIGNvbnN0IHF1ZXJ5ID0gZXNjYXBlKHRoaXMudmFsdWVfLnRyaW0oKSkucmVwbGFjZShcbiAgICAgICAgbmV3IFJlZ0V4cChsdW5yLnRva2VuaXplci5zZXBhcmF0b3IsIFwiaW1nXCIpLCBcInxcIilcbiAgICAgIGNvbnN0IG1hdGNoID1cbiAgICAgICAgbmV3IFJlZ0V4cChgKF58JHtsdW5yLnRva2VuaXplci5zZXBhcmF0b3J9KSgke3F1ZXJ5fSlgLCBcImltZ1wiKVxuICAgICAgY29uc3QgaGlnaGxpZ2h0ID0gKF8sIHNlcGFyYXRvciwgdG9rZW4pID0+XG4gICAgICAgIGAke3NlcGFyYXRvcn08ZW0+JHt0b2tlbn08L2VtPmBcblxuICAgICAgLyogUmVzZXQgc3RhY2sgYW5kIHJlbmRlciByZXN1bHRzICovXG4gICAgICB0aGlzLnN0YWNrXyA9IFtdXG4gICAgICByZXN1bHQuZm9yRWFjaCgoaXRlbXMsIHJlZikgPT4ge1xuICAgICAgICBjb25zdCBkb2MgPSB0aGlzLmRvY3NfLmdldChyZWYpXG5cbiAgICAgICAgLyogUmVuZGVyIGFydGljbGUgKi9cbiAgICAgICAgY29uc3QgYXJ0aWNsZSA9IChcbiAgICAgICAgICA8bGkgY2xhc3M9XCJtZC1zZWFyY2gtcmVzdWx0X19pdGVtXCI+XG4gICAgICAgICAgICA8YSBocmVmPXtkb2MubG9jYXRpb259IHRpdGxlPXtkb2MudGl0bGV9XG4gICAgICAgICAgICAgIGNsYXNzPVwibWQtc2VhcmNoLXJlc3VsdF9fbGlua1wiIHRhYmluZGV4PVwiLTFcIj5cbiAgICAgICAgICAgICAgPGFydGljbGUgY2xhc3M9XCJtZC1zZWFyY2gtcmVzdWx0X19hcnRpY2xlXG4gICAgICAgICAgICAgICAgICAgIG1kLXNlYXJjaC1yZXN1bHRfX2FydGljbGUtLWRvY3VtZW50XCI+XG4gICAgICAgICAgICAgICAgPGgxIGNsYXNzPVwibWQtc2VhcmNoLXJlc3VsdF9fdGl0bGVcIj5cbiAgICAgICAgICAgICAgICAgIHt7IF9faHRtbDogZG9jLnRpdGxlLnJlcGxhY2UobWF0Y2gsIGhpZ2hsaWdodCkgfX1cbiAgICAgICAgICAgICAgICA8L2gxPlxuICAgICAgICAgICAgICAgIHtkb2MudGV4dC5sZW5ndGggP1xuICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtZC1zZWFyY2gtcmVzdWx0X190ZWFzZXJcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgX19odG1sOiBkb2MudGV4dC5yZXBsYWNlKG1hdGNoLCBoaWdobGlnaHQpIH19XG4gICAgICAgICAgICAgICAgICA8L3A+IDoge319XG4gICAgICAgICAgICAgIDwvYXJ0aWNsZT5cbiAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICApXG5cbiAgICAgICAgLyogUmVuZGVyIHNlY3Rpb25zIGZvciBhcnRpY2xlICovXG4gICAgICAgIGNvbnN0IHNlY3Rpb25zID0gaXRlbXMubWFwKGl0ZW0gPT4ge1xuICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzZWN0aW9uID0gdGhpcy5kb2NzXy5nZXQoaXRlbS5yZWYpXG4gICAgICAgICAgICBhcnRpY2xlLmFwcGVuZENoaWxkKFxuICAgICAgICAgICAgICA8YSBocmVmPXtzZWN0aW9uLmxvY2F0aW9ufSB0aXRsZT17c2VjdGlvbi50aXRsZX1cbiAgICAgICAgICAgICAgICBjbGFzcz1cIm1kLXNlYXJjaC1yZXN1bHRfX2xpbmtcIiBkYXRhLW1kLXJlbD1cImFuY2hvclwiXG4gICAgICAgICAgICAgICAgdGFiaW5kZXg9XCItMVwiPlxuICAgICAgICAgICAgICAgIDxhcnRpY2xlIGNsYXNzPVwibWQtc2VhcmNoLXJlc3VsdF9fYXJ0aWNsZVwiPlxuICAgICAgICAgICAgICAgICAgPGgxIGNsYXNzPVwibWQtc2VhcmNoLXJlc3VsdF9fdGl0bGVcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgX19odG1sOiBzZWN0aW9uLnRpdGxlLnJlcGxhY2UobWF0Y2gsIGhpZ2hsaWdodCkgfX1cbiAgICAgICAgICAgICAgICAgIDwvaDE+XG4gICAgICAgICAgICAgICAgICB7c2VjdGlvbi50ZXh0Lmxlbmd0aCA/XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWQtc2VhcmNoLXJlc3VsdF9fdGVhc2VyXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgX19odG1sOiB0cnVuY2F0ZShcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlY3Rpb24udGV4dC5yZXBsYWNlKG1hdGNoLCBoaWdobGlnaHQpLCA0MDApXG4gICAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9wPiA6IHt9fVxuICAgICAgICAgICAgICAgIDwvYXJ0aWNsZT5cbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgKVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICAvKiBQdXNoIGFydGljbGVzIGFuZCBzZWN0aW9uIHJlbmRlcmVycyBvbnRvIHN0YWNrICovXG4gICAgICAgIHRoaXMuc3RhY2tfLnB1c2goKCkgPT4gdGhpcy5saXN0Xy5hcHBlbmRDaGlsZChhcnRpY2xlKSwgLi4uc2VjdGlvbnMpXG4gICAgICB9KVxuXG4gICAgICAvKiBHcmFkdWFsbHkgYWRkIHJlc3VsdHMgYXMgbG9uZyBhcyB0aGUgaGVpZ2h0IG9mIHRoZSBjb250YWluZXIgZ3Jvd3MgKi9cbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuZWxfLnBhcmVudE5vZGVcbiAgICAgIGlmICghKGNvbnRhaW5lciBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSlcbiAgICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG4gICAgICB3aGlsZSAodGhpcy5zdGFja18ubGVuZ3RoICYmXG4gICAgICAgICAgY29udGFpbmVyLm9mZnNldEhlaWdodCA+PSBjb250YWluZXIuc2Nyb2xsSGVpZ2h0IC0gMTYpXG4gICAgICAgICh0aGlzLnN0YWNrXy5zaGlmdCgpKSgpXG5cbiAgICAgIC8qIEJpbmQgY2xpY2sgaGFuZGxlcnMgZm9yIGFuY2hvcnMgKi9cbiAgICAgIGNvbnN0IGFuY2hvcnMgPSB0aGlzLmxpc3RfLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbZGF0YS1tZC1yZWw9YW5jaG9yXVwiKVxuICAgICAgQXJyYXkucHJvdG90eXBlLmZvckVhY2guY2FsbChhbmNob3JzLCBhbmNob3IgPT4ge1xuICAgICAgICBbXCJjbGlja1wiLCBcImtleWRvd25cIl0uZm9yRWFjaChhY3Rpb24gPT4ge1xuICAgICAgICAgIGFuY2hvci5hZGRFdmVudExpc3RlbmVyKGFjdGlvbiwgZXYyID0+IHtcbiAgICAgICAgICAgIGlmIChhY3Rpb24gPT09IFwia2V5ZG93blwiICYmIGV2Mi5rZXlDb2RlICE9PSAxMylcbiAgICAgICAgICAgICAgcmV0dXJuXG5cbiAgICAgICAgICAgIC8qIENsb3NlIHNlYXJjaCAqL1xuICAgICAgICAgICAgY29uc3QgdG9nZ2xlID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIltkYXRhLW1kLXRvZ2dsZT1zZWFyY2hdXCIpXG4gICAgICAgICAgICBpZiAoISh0b2dnbGUgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50KSlcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG4gICAgICAgICAgICBpZiAodG9nZ2xlLmNoZWNrZWQpIHtcbiAgICAgICAgICAgICAgdG9nZ2xlLmNoZWNrZWQgPSBmYWxzZVxuICAgICAgICAgICAgICB0b2dnbGUuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJjaGFuZ2VcIikpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8qIEhhY2s6IHByZXZlbnQgZGVmYXVsdCwgYXMgdGhlIG5hdmlnYXRpb24gbmVlZHMgdG8gYmUgZGVsYXllZCBkdWVcbiAgICAgICAgICAgICAgIHRvIHRoZSBzZWFyY2ggYm9keSBsb2NrIG9uIG1vYmlsZSAqL1xuICAgICAgICAgICAgZXYyLnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICBkb2N1bWVudC5sb2NhdGlvbi5ocmVmID0gYW5jaG9yLmhyZWZcbiAgICAgICAgICAgIH0sIDEwMClcbiAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgICAgfSlcblxuICAgICAgLyogVXBkYXRlIHNlYXJjaCBtZXRhZGF0YSAqL1xuICAgICAgc3dpdGNoIChyZXN1bHQuc2l6ZSkge1xuICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgdGhpcy5tZXRhXy50ZXh0Q29udGVudCA9IHRoaXMubWVzc2FnZV8ubm9uZVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICB0aGlzLm1ldGFfLnRleHRDb250ZW50ID0gdGhpcy5tZXNzYWdlXy5vbmVcbiAgICAgICAgICBicmVha1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRoaXMubWV0YV8udGV4dENvbnRlbnQgPVxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlXy5vdGhlci5yZXBsYWNlKFwiI1wiLCByZXN1bHQuc2l6ZSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9TZWFyY2gvUmVzdWx0LmpzeCIsIid1c2Ugc3RyaWN0JztcblxudmFyIG1hdGNoT3BlcmF0b3JzUmUgPSAvW3xcXFxce30oKVtcXF1eJCsqPy5dL2c7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHN0cikge1xuXHRpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdFeHBlY3RlZCBhIHN0cmluZycpO1xuXHR9XG5cblx0cmV0dXJuIHN0ci5yZXBsYWNlKG1hdGNoT3BlcmF0b3JzUmUsICdcXFxcJCYnKTtcbn07XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL25vZGVfbW9kdWxlcy9lc2NhcGUtc3RyaW5nLXJlZ2V4cC9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gMzRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBnbG9iYWxbXCJsdW5yXCJdID0gcmVxdWlyZShcIi0hLi9sdW5yLmpzXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2V4cG9zZS1sb2FkZXI/bHVuciEuL25vZGVfbW9kdWxlcy9sdW5yL2x1bnIuanMtZXhwb3NlZFxuLy8gbW9kdWxlIGlkID0gMzVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLyoqXG4gKiBsdW5yIC0gaHR0cDovL2x1bnJqcy5jb20gLSBBIGJpdCBsaWtlIFNvbHIsIGJ1dCBtdWNoIHNtYWxsZXIgYW5kIG5vdCBhcyBicmlnaHQgLSAyLjMuNVxuICogQ29weXJpZ2h0IChDKSAyMDE4IE9saXZlciBOaWdodGluZ2FsZVxuICogQGxpY2Vuc2UgTUlUXG4gKi9cblxuOyhmdW5jdGlvbigpe1xuXG4vKipcbiAqIEEgY29udmVuaWVuY2UgZnVuY3Rpb24gZm9yIGNvbmZpZ3VyaW5nIGFuZCBjb25zdHJ1Y3RpbmdcbiAqIGEgbmV3IGx1bnIgSW5kZXguXG4gKlxuICogQSBsdW5yLkJ1aWxkZXIgaW5zdGFuY2UgaXMgY3JlYXRlZCBhbmQgdGhlIHBpcGVsaW5lIHNldHVwXG4gKiB3aXRoIGEgdHJpbW1lciwgc3RvcCB3b3JkIGZpbHRlciBhbmQgc3RlbW1lci5cbiAqXG4gKiBUaGlzIGJ1aWxkZXIgb2JqZWN0IGlzIHlpZWxkZWQgdG8gdGhlIGNvbmZpZ3VyYXRpb24gZnVuY3Rpb25cbiAqIHRoYXQgaXMgcGFzc2VkIGFzIGEgcGFyYW1ldGVyLCBhbGxvd2luZyB0aGUgbGlzdCBvZiBmaWVsZHNcbiAqIGFuZCBvdGhlciBidWlsZGVyIHBhcmFtZXRlcnMgdG8gYmUgY3VzdG9taXNlZC5cbiAqXG4gKiBBbGwgZG9jdW1lbnRzIF9tdXN0XyBiZSBhZGRlZCB3aXRoaW4gdGhlIHBhc3NlZCBjb25maWcgZnVuY3Rpb24uXG4gKlxuICogQGV4YW1wbGVcbiAqIHZhciBpZHggPSBsdW5yKGZ1bmN0aW9uICgpIHtcbiAqICAgdGhpcy5maWVsZCgndGl0bGUnKVxuICogICB0aGlzLmZpZWxkKCdib2R5JylcbiAqICAgdGhpcy5yZWYoJ2lkJylcbiAqXG4gKiAgIGRvY3VtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChkb2MpIHtcbiAqICAgICB0aGlzLmFkZChkb2MpXG4gKiAgIH0sIHRoaXMpXG4gKiB9KVxuICpcbiAqIEBzZWUge0BsaW5rIGx1bnIuQnVpbGRlcn1cbiAqIEBzZWUge0BsaW5rIGx1bnIuUGlwZWxpbmV9XG4gKiBAc2VlIHtAbGluayBsdW5yLnRyaW1tZXJ9XG4gKiBAc2VlIHtAbGluayBsdW5yLnN0b3BXb3JkRmlsdGVyfVxuICogQHNlZSB7QGxpbmsgbHVuci5zdGVtbWVyfVxuICogQG5hbWVzcGFjZSB7ZnVuY3Rpb259IGx1bnJcbiAqL1xudmFyIGx1bnIgPSBmdW5jdGlvbiAoY29uZmlnKSB7XG4gIHZhciBidWlsZGVyID0gbmV3IGx1bnIuQnVpbGRlclxuXG4gIGJ1aWxkZXIucGlwZWxpbmUuYWRkKFxuICAgIGx1bnIudHJpbW1lcixcbiAgICBsdW5yLnN0b3BXb3JkRmlsdGVyLFxuICAgIGx1bnIuc3RlbW1lclxuICApXG5cbiAgYnVpbGRlci5zZWFyY2hQaXBlbGluZS5hZGQoXG4gICAgbHVuci5zdGVtbWVyXG4gIClcblxuICBjb25maWcuY2FsbChidWlsZGVyLCBidWlsZGVyKVxuICByZXR1cm4gYnVpbGRlci5idWlsZCgpXG59XG5cbmx1bnIudmVyc2lvbiA9IFwiMi4zLjVcIlxuLyohXG4gKiBsdW5yLnV0aWxzXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTggT2xpdmVyIE5pZ2h0aW5nYWxlXG4gKi9cblxuLyoqXG4gKiBBIG5hbWVzcGFjZSBjb250YWluaW5nIHV0aWxzIGZvciB0aGUgcmVzdCBvZiB0aGUgbHVuciBsaWJyYXJ5XG4gKiBAbmFtZXNwYWNlIGx1bnIudXRpbHNcbiAqL1xubHVuci51dGlscyA9IHt9XG5cbi8qKlxuICogUHJpbnQgYSB3YXJuaW5nIG1lc3NhZ2UgdG8gdGhlIGNvbnNvbGUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gYmUgcHJpbnRlZC5cbiAqIEBtZW1iZXJPZiBsdW5yLnV0aWxzXG4gKiBAZnVuY3Rpb25cbiAqL1xubHVuci51dGlscy53YXJuID0gKGZ1bmN0aW9uIChnbG9iYWwpIHtcbiAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICBpZiAoZ2xvYmFsLmNvbnNvbGUgJiYgY29uc29sZS53YXJuKSB7XG4gICAgICBjb25zb2xlLndhcm4obWVzc2FnZSlcbiAgICB9XG4gIH1cbiAgLyogZXNsaW50LWVuYWJsZSBuby1jb25zb2xlICovXG59KSh0aGlzKVxuXG4vKipcbiAqIENvbnZlcnQgYW4gb2JqZWN0IHRvIGEgc3RyaW5nLlxuICpcbiAqIEluIHRoZSBjYXNlIG9mIGBudWxsYCBhbmQgYHVuZGVmaW5lZGAgdGhlIGZ1bmN0aW9uIHJldHVybnNcbiAqIHRoZSBlbXB0eSBzdHJpbmcsIGluIGFsbCBvdGhlciBjYXNlcyB0aGUgcmVzdWx0IG9mIGNhbGxpbmdcbiAqIGB0b1N0cmluZ2Agb24gdGhlIHBhc3NlZCBvYmplY3QgaXMgcmV0dXJuZWQuXG4gKlxuICogQHBhcmFtIHtBbnl9IG9iaiBUaGUgb2JqZWN0IHRvIGNvbnZlcnQgdG8gYSBzdHJpbmcuXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFzc2VkIG9iamVjdC5cbiAqIEBtZW1iZXJPZiBsdW5yLnV0aWxzXG4gKi9cbmx1bnIudXRpbHMuYXNTdHJpbmcgPSBmdW5jdGlvbiAob2JqKSB7XG4gIGlmIChvYmogPT09IHZvaWQgMCB8fCBvYmogPT09IG51bGwpIHtcbiAgICByZXR1cm4gXCJcIlxuICB9IGVsc2Uge1xuICAgIHJldHVybiBvYmoudG9TdHJpbmcoKVxuICB9XG59XG5cbi8qKlxuICogQ2xvbmVzIGFuIG9iamVjdC5cbiAqXG4gKiBXaWxsIGNyZWF0ZSBhIGNvcHkgb2YgYW4gZXhpc3Rpbmcgb2JqZWN0IHN1Y2ggdGhhdCBhbnkgbXV0YXRpb25zXG4gKiBvbiB0aGUgY29weSBjYW5ub3QgYWZmZWN0IHRoZSBvcmlnaW5hbC5cbiAqXG4gKiBPbmx5IHNoYWxsb3cgb2JqZWN0cyBhcmUgc3VwcG9ydGVkLCBwYXNzaW5nIGEgbmVzdGVkIG9iamVjdCB0byB0aGlzXG4gKiBmdW5jdGlvbiB3aWxsIGNhdXNlIGEgVHlwZUVycm9yLlxuICpcbiAqIE9iamVjdHMgd2l0aCBwcmltaXRpdmVzLCBhbmQgYXJyYXlzIG9mIHByaW1pdGl2ZXMgYXJlIHN1cHBvcnRlZC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gY2xvbmUuXG4gKiBAcmV0dXJuIHtPYmplY3R9IGEgY2xvbmUgb2YgdGhlIHBhc3NlZCBvYmplY3QuXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IHdoZW4gYSBuZXN0ZWQgb2JqZWN0IGlzIHBhc3NlZC5cbiAqIEBtZW1iZXJPZiBVdGlsc1xuICovXG5sdW5yLnV0aWxzLmNsb25lID0gZnVuY3Rpb24gKG9iaikge1xuICBpZiAob2JqID09PSBudWxsIHx8IG9iaiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIG9ialxuICB9XG5cbiAgdmFyIGNsb25lID0gT2JqZWN0LmNyZWF0ZShudWxsKSxcbiAgICAgIGtleXMgPSBPYmplY3Qua2V5cyhvYmopXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGtleSA9IGtleXNbaV0sXG4gICAgICAgIHZhbCA9IG9ialtrZXldXG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICBjbG9uZVtrZXldID0gdmFsLnNsaWNlKClcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgIHR5cGVvZiB2YWwgPT09ICdudW1iZXInIHx8XG4gICAgICAgIHR5cGVvZiB2YWwgPT09ICdib29sZWFuJykge1xuICAgICAgY2xvbmVba2V5XSA9IHZhbFxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiY2xvbmUgaXMgbm90IGRlZXAgYW5kIGRvZXMgbm90IHN1cHBvcnQgbmVzdGVkIG9iamVjdHNcIilcbiAgfVxuXG4gIHJldHVybiBjbG9uZVxufVxubHVuci5GaWVsZFJlZiA9IGZ1bmN0aW9uIChkb2NSZWYsIGZpZWxkTmFtZSwgc3RyaW5nVmFsdWUpIHtcbiAgdGhpcy5kb2NSZWYgPSBkb2NSZWZcbiAgdGhpcy5maWVsZE5hbWUgPSBmaWVsZE5hbWVcbiAgdGhpcy5fc3RyaW5nVmFsdWUgPSBzdHJpbmdWYWx1ZVxufVxuXG5sdW5yLkZpZWxkUmVmLmpvaW5lciA9IFwiL1wiXG5cbmx1bnIuRmllbGRSZWYuZnJvbVN0cmluZyA9IGZ1bmN0aW9uIChzKSB7XG4gIHZhciBuID0gcy5pbmRleE9mKGx1bnIuRmllbGRSZWYuam9pbmVyKVxuXG4gIGlmIChuID09PSAtMSkge1xuICAgIHRocm93IFwibWFsZm9ybWVkIGZpZWxkIHJlZiBzdHJpbmdcIlxuICB9XG5cbiAgdmFyIGZpZWxkUmVmID0gcy5zbGljZSgwLCBuKSxcbiAgICAgIGRvY1JlZiA9IHMuc2xpY2UobiArIDEpXG5cbiAgcmV0dXJuIG5ldyBsdW5yLkZpZWxkUmVmIChkb2NSZWYsIGZpZWxkUmVmLCBzKVxufVxuXG5sdW5yLkZpZWxkUmVmLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuX3N0cmluZ1ZhbHVlID09IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuX3N0cmluZ1ZhbHVlID0gdGhpcy5maWVsZE5hbWUgKyBsdW5yLkZpZWxkUmVmLmpvaW5lciArIHRoaXMuZG9jUmVmXG4gIH1cblxuICByZXR1cm4gdGhpcy5fc3RyaW5nVmFsdWVcbn1cbi8qIVxuICogbHVuci5TZXRcbiAqIENvcHlyaWdodCAoQykgMjAxOCBPbGl2ZXIgTmlnaHRpbmdhbGVcbiAqL1xuXG4vKipcbiAqIEEgbHVuciBzZXQuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmx1bnIuU2V0ID0gZnVuY3Rpb24gKGVsZW1lbnRzKSB7XG4gIHRoaXMuZWxlbWVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgaWYgKGVsZW1lbnRzKSB7XG4gICAgdGhpcy5sZW5ndGggPSBlbGVtZW50cy5sZW5ndGhcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5lbGVtZW50c1tlbGVtZW50c1tpXV0gPSB0cnVlXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRoaXMubGVuZ3RoID0gMFxuICB9XG59XG5cbi8qKlxuICogQSBjb21wbGV0ZSBzZXQgdGhhdCBjb250YWlucyBhbGwgZWxlbWVudHMuXG4gKlxuICogQHN0YXRpY1xuICogQHJlYWRvbmx5XG4gKiBAdHlwZSB7bHVuci5TZXR9XG4gKi9cbmx1bnIuU2V0LmNvbXBsZXRlID0ge1xuICBpbnRlcnNlY3Q6IGZ1bmN0aW9uIChvdGhlcikge1xuICAgIHJldHVybiBvdGhlclxuICB9LFxuXG4gIHVuaW9uOiBmdW5jdGlvbiAob3RoZXIpIHtcbiAgICByZXR1cm4gb3RoZXJcbiAgfSxcblxuICBjb250YWluczogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cbn1cblxuLyoqXG4gKiBBbiBlbXB0eSBzZXQgdGhhdCBjb250YWlucyBubyBlbGVtZW50cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAcmVhZG9ubHlcbiAqIEB0eXBlIHtsdW5yLlNldH1cbiAqL1xubHVuci5TZXQuZW1wdHkgPSB7XG4gIGludGVyc2VjdDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzXG4gIH0sXG5cbiAgdW5pb246IGZ1bmN0aW9uIChvdGhlcikge1xuICAgIHJldHVybiBvdGhlclxuICB9LFxuXG4gIGNvbnRhaW5zOiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBzZXQgY29udGFpbnMgdGhlIHNwZWNpZmllZCBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IG9iamVjdCAtIE9iamVjdCB3aG9zZSBwcmVzZW5jZSBpbiB0aGlzIHNldCBpcyB0byBiZSB0ZXN0ZWQuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBUcnVlIGlmIHRoaXMgc2V0IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgb2JqZWN0LlxuICovXG5sdW5yLlNldC5wcm90b3R5cGUuY29udGFpbnMgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gIHJldHVybiAhIXRoaXMuZWxlbWVudHNbb2JqZWN0XVxufVxuXG4vKipcbiAqIFJldHVybnMgYSBuZXcgc2V0IGNvbnRhaW5pbmcgb25seSB0aGUgZWxlbWVudHMgdGhhdCBhcmUgcHJlc2VudCBpbiBib3RoXG4gKiB0aGlzIHNldCBhbmQgdGhlIHNwZWNpZmllZCBzZXQuXG4gKlxuICogQHBhcmFtIHtsdW5yLlNldH0gb3RoZXIgLSBzZXQgdG8gaW50ZXJzZWN0IHdpdGggdGhpcyBzZXQuXG4gKiBAcmV0dXJucyB7bHVuci5TZXR9IGEgbmV3IHNldCB0aGF0IGlzIHRoZSBpbnRlcnNlY3Rpb24gb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBzZXQuXG4gKi9cblxubHVuci5TZXQucHJvdG90eXBlLmludGVyc2VjdCA9IGZ1bmN0aW9uIChvdGhlcikge1xuICB2YXIgYSwgYiwgZWxlbWVudHMsIGludGVyc2VjdGlvbiA9IFtdXG5cbiAgaWYgKG90aGVyID09PSBsdW5yLlNldC5jb21wbGV0ZSkge1xuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBpZiAob3RoZXIgPT09IGx1bnIuU2V0LmVtcHR5KSB7XG4gICAgcmV0dXJuIG90aGVyXG4gIH1cblxuICBpZiAodGhpcy5sZW5ndGggPCBvdGhlci5sZW5ndGgpIHtcbiAgICBhID0gdGhpc1xuICAgIGIgPSBvdGhlclxuICB9IGVsc2Uge1xuICAgIGEgPSBvdGhlclxuICAgIGIgPSB0aGlzXG4gIH1cblxuICBlbGVtZW50cyA9IE9iamVjdC5rZXlzKGEuZWxlbWVudHMpXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBlbGVtZW50ID0gZWxlbWVudHNbaV1cbiAgICBpZiAoZWxlbWVudCBpbiBiLmVsZW1lbnRzKSB7XG4gICAgICBpbnRlcnNlY3Rpb24ucHVzaChlbGVtZW50KVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXcgbHVuci5TZXQgKGludGVyc2VjdGlvbilcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbmV3IHNldCBjb21iaW5pbmcgdGhlIGVsZW1lbnRzIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgc2V0LlxuICpcbiAqIEBwYXJhbSB7bHVuci5TZXR9IG90aGVyIC0gc2V0IHRvIHVuaW9uIHdpdGggdGhpcyBzZXQuXG4gKiBAcmV0dXJuIHtsdW5yLlNldH0gYSBuZXcgc2V0IHRoYXQgaXMgdGhlIHVuaW9uIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgc2V0LlxuICovXG5cbmx1bnIuU2V0LnByb3RvdHlwZS51bmlvbiA9IGZ1bmN0aW9uIChvdGhlcikge1xuICBpZiAob3RoZXIgPT09IGx1bnIuU2V0LmNvbXBsZXRlKSB7XG4gICAgcmV0dXJuIGx1bnIuU2V0LmNvbXBsZXRlXG4gIH1cblxuICBpZiAob3RoZXIgPT09IGx1bnIuU2V0LmVtcHR5KSB7XG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHJldHVybiBuZXcgbHVuci5TZXQoT2JqZWN0LmtleXModGhpcy5lbGVtZW50cykuY29uY2F0KE9iamVjdC5rZXlzKG90aGVyLmVsZW1lbnRzKSkpXG59XG4vKipcbiAqIEEgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSBpbnZlcnNlIGRvY3VtZW50IGZyZXF1ZW5jeSBmb3JcbiAqIGEgcG9zdGluZy4gVGhpcyBpcyBzaGFyZWQgYmV0d2VlbiB0aGUgYnVpbGRlciBhbmQgdGhlIGluZGV4XG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7b2JqZWN0fSBwb3N0aW5nIC0gVGhlIHBvc3RpbmcgZm9yIGEgZ2l2ZW4gdGVybVxuICogQHBhcmFtIHtudW1iZXJ9IGRvY3VtZW50Q291bnQgLSBUaGUgdG90YWwgbnVtYmVyIG9mIGRvY3VtZW50cy5cbiAqL1xubHVuci5pZGYgPSBmdW5jdGlvbiAocG9zdGluZywgZG9jdW1lbnRDb3VudCkge1xuICB2YXIgZG9jdW1lbnRzV2l0aFRlcm0gPSAwXG5cbiAgZm9yICh2YXIgZmllbGROYW1lIGluIHBvc3RpbmcpIHtcbiAgICBpZiAoZmllbGROYW1lID09ICdfaW5kZXgnKSBjb250aW51ZSAvLyBJZ25vcmUgdGhlIHRlcm0gaW5kZXgsIGl0cyBub3QgYSBmaWVsZFxuICAgIGRvY3VtZW50c1dpdGhUZXJtICs9IE9iamVjdC5rZXlzKHBvc3RpbmdbZmllbGROYW1lXSkubGVuZ3RoXG4gIH1cblxuICB2YXIgeCA9IChkb2N1bWVudENvdW50IC0gZG9jdW1lbnRzV2l0aFRlcm0gKyAwLjUpIC8gKGRvY3VtZW50c1dpdGhUZXJtICsgMC41KVxuXG4gIHJldHVybiBNYXRoLmxvZygxICsgTWF0aC5hYnMoeCkpXG59XG5cbi8qKlxuICogQSB0b2tlbiB3cmFwcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHRva2VuXG4gKiBhcyBpdCBpcyBwYXNzZWQgdGhyb3VnaCB0aGUgdGV4dCBwcm9jZXNzaW5nIHBpcGVsaW5lLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtzdHJpbmd9IFtzdHI9JyddIC0gVGhlIHN0cmluZyB0b2tlbiBiZWluZyB3cmFwcGVkLlxuICogQHBhcmFtIHtvYmplY3R9IFttZXRhZGF0YT17fV0gLSBNZXRhZGF0YSBhc3NvY2lhdGVkIHdpdGggdGhpcyB0b2tlbi5cbiAqL1xubHVuci5Ub2tlbiA9IGZ1bmN0aW9uIChzdHIsIG1ldGFkYXRhKSB7XG4gIHRoaXMuc3RyID0gc3RyIHx8IFwiXCJcbiAgdGhpcy5tZXRhZGF0YSA9IG1ldGFkYXRhIHx8IHt9XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgdG9rZW4gc3RyaW5nIHRoYXQgaXMgYmVpbmcgd3JhcHBlZCBieSB0aGlzIG9iamVjdC5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICovXG5sdW5yLlRva2VuLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuc3RyXG59XG5cbi8qKlxuICogQSB0b2tlbiB1cGRhdGUgZnVuY3Rpb24gaXMgdXNlZCB3aGVuIHVwZGF0aW5nIG9yIG9wdGlvbmFsbHlcbiAqIHdoZW4gY2xvbmluZyBhIHRva2VuLlxuICpcbiAqIEBjYWxsYmFjayBsdW5yLlRva2VufnVwZGF0ZUZ1bmN0aW9uXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIC0gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdG9rZW4uXG4gKiBAcGFyYW0ge09iamVjdH0gbWV0YWRhdGEgLSBBbGwgbWV0YWRhdGEgYXNzb2NpYXRlZCB3aXRoIHRoaXMgdG9rZW4uXG4gKi9cblxuLyoqXG4gKiBBcHBsaWVzIHRoZSBnaXZlbiBmdW5jdGlvbiB0byB0aGUgd3JhcHBlZCBzdHJpbmcgdG9rZW4uXG4gKlxuICogQGV4YW1wbGVcbiAqIHRva2VuLnVwZGF0ZShmdW5jdGlvbiAoc3RyLCBtZXRhZGF0YSkge1xuICogICByZXR1cm4gc3RyLnRvVXBwZXJDYXNlKClcbiAqIH0pXG4gKlxuICogQHBhcmFtIHtsdW5yLlRva2VufnVwZGF0ZUZ1bmN0aW9ufSBmbiAtIEEgZnVuY3Rpb24gdG8gYXBwbHkgdG8gdGhlIHRva2VuIHN0cmluZy5cbiAqIEByZXR1cm5zIHtsdW5yLlRva2VufVxuICovXG5sdW5yLlRva2VuLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbiAoZm4pIHtcbiAgdGhpcy5zdHIgPSBmbih0aGlzLnN0ciwgdGhpcy5tZXRhZGF0YSlcbiAgcmV0dXJuIHRoaXNcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgY2xvbmUgb2YgdGhpcyB0b2tlbi4gT3B0aW9uYWxseSBhIGZ1bmN0aW9uIGNhbiBiZVxuICogYXBwbGllZCB0byB0aGUgY2xvbmVkIHRva2VuLlxuICpcbiAqIEBwYXJhbSB7bHVuci5Ub2tlbn51cGRhdGVGdW5jdGlvbn0gW2ZuXSAtIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGFwcGx5IHRvIHRoZSBjbG9uZWQgdG9rZW4uXG4gKiBAcmV0dXJucyB7bHVuci5Ub2tlbn1cbiAqL1xubHVuci5Ub2tlbi5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbiAoZm4pIHtcbiAgZm4gPSBmbiB8fCBmdW5jdGlvbiAocykgeyByZXR1cm4gcyB9XG4gIHJldHVybiBuZXcgbHVuci5Ub2tlbiAoZm4odGhpcy5zdHIsIHRoaXMubWV0YWRhdGEpLCB0aGlzLm1ldGFkYXRhKVxufVxuLyohXG4gKiBsdW5yLnRva2VuaXplclxuICogQ29weXJpZ2h0IChDKSAyMDE4IE9saXZlciBOaWdodGluZ2FsZVxuICovXG5cbi8qKlxuICogQSBmdW5jdGlvbiBmb3Igc3BsaXR0aW5nIGEgc3RyaW5nIGludG8gdG9rZW5zIHJlYWR5IHRvIGJlIGluc2VydGVkIGludG9cbiAqIHRoZSBzZWFyY2ggaW5kZXguIFVzZXMgYGx1bnIudG9rZW5pemVyLnNlcGFyYXRvcmAgdG8gc3BsaXQgc3RyaW5ncywgY2hhbmdlXG4gKiB0aGUgdmFsdWUgb2YgdGhpcyBwcm9wZXJ0eSB0byBjaGFuZ2UgaG93IHN0cmluZ3MgYXJlIHNwbGl0IGludG8gdG9rZW5zLlxuICpcbiAqIFRoaXMgdG9rZW5pemVyIHdpbGwgY29udmVydCBpdHMgcGFyYW1ldGVyIHRvIGEgc3RyaW5nIGJ5IGNhbGxpbmcgYHRvU3RyaW5nYCBhbmRcbiAqIHRoZW4gd2lsbCBzcGxpdCB0aGlzIHN0cmluZyBvbiB0aGUgY2hhcmFjdGVyIGluIGBsdW5yLnRva2VuaXplci5zZXBhcmF0b3JgLlxuICogQXJyYXlzIHdpbGwgaGF2ZSB0aGVpciBlbGVtZW50cyBjb252ZXJ0ZWQgdG8gc3RyaW5ncyBhbmQgd3JhcHBlZCBpbiBhIGx1bnIuVG9rZW4uXG4gKlxuICogT3B0aW9uYWwgbWV0YWRhdGEgY2FuIGJlIHBhc3NlZCB0byB0aGUgdG9rZW5pemVyLCB0aGlzIG1ldGFkYXRhIHdpbGwgYmUgY2xvbmVkIGFuZFxuICogYWRkZWQgYXMgbWV0YWRhdGEgdG8gZXZlcnkgdG9rZW4gdGhhdCBpcyBjcmVhdGVkIGZyb20gdGhlIG9iamVjdCB0byBiZSB0b2tlbml6ZWQuXG4gKlxuICogQHN0YXRpY1xuICogQHBhcmFtIHs/KHN0cmluZ3xvYmplY3R8b2JqZWN0W10pfSBvYmogLSBUaGUgb2JqZWN0IHRvIGNvbnZlcnQgaW50byB0b2tlbnNcbiAqIEBwYXJhbSB7P29iamVjdH0gbWV0YWRhdGEgLSBPcHRpb25hbCBtZXRhZGF0YSB0byBhc3NvY2lhdGUgd2l0aCBldmVyeSB0b2tlblxuICogQHJldHVybnMge2x1bnIuVG9rZW5bXX1cbiAqIEBzZWUge0BsaW5rIGx1bnIuUGlwZWxpbmV9XG4gKi9cbmx1bnIudG9rZW5pemVyID0gZnVuY3Rpb24gKG9iaiwgbWV0YWRhdGEpIHtcbiAgaWYgKG9iaiA9PSBudWxsIHx8IG9iaiA9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gW11cbiAgfVxuXG4gIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICByZXR1cm4gb2JqLm1hcChmdW5jdGlvbiAodCkge1xuICAgICAgcmV0dXJuIG5ldyBsdW5yLlRva2VuKFxuICAgICAgICBsdW5yLnV0aWxzLmFzU3RyaW5nKHQpLnRvTG93ZXJDYXNlKCksXG4gICAgICAgIGx1bnIudXRpbHMuY2xvbmUobWV0YWRhdGEpXG4gICAgICApXG4gICAgfSlcbiAgfVxuXG4gIHZhciBzdHIgPSBvYmoudG9TdHJpbmcoKS50cmltKCkudG9Mb3dlckNhc2UoKSxcbiAgICAgIGxlbiA9IHN0ci5sZW5ndGgsXG4gICAgICB0b2tlbnMgPSBbXVxuXG4gIGZvciAodmFyIHNsaWNlRW5kID0gMCwgc2xpY2VTdGFydCA9IDA7IHNsaWNlRW5kIDw9IGxlbjsgc2xpY2VFbmQrKykge1xuICAgIHZhciBjaGFyID0gc3RyLmNoYXJBdChzbGljZUVuZCksXG4gICAgICAgIHNsaWNlTGVuZ3RoID0gc2xpY2VFbmQgLSBzbGljZVN0YXJ0XG5cbiAgICBpZiAoKGNoYXIubWF0Y2gobHVuci50b2tlbml6ZXIuc2VwYXJhdG9yKSB8fCBzbGljZUVuZCA9PSBsZW4pKSB7XG5cbiAgICAgIGlmIChzbGljZUxlbmd0aCA+IDApIHtcbiAgICAgICAgdmFyIHRva2VuTWV0YWRhdGEgPSBsdW5yLnV0aWxzLmNsb25lKG1ldGFkYXRhKSB8fCB7fVxuICAgICAgICB0b2tlbk1ldGFkYXRhW1wicG9zaXRpb25cIl0gPSBbc2xpY2VTdGFydCwgc2xpY2VMZW5ndGhdXG4gICAgICAgIHRva2VuTWV0YWRhdGFbXCJpbmRleFwiXSA9IHRva2Vucy5sZW5ndGhcblxuICAgICAgICB0b2tlbnMucHVzaChcbiAgICAgICAgICBuZXcgbHVuci5Ub2tlbiAoXG4gICAgICAgICAgICBzdHIuc2xpY2Uoc2xpY2VTdGFydCwgc2xpY2VFbmQpLFxuICAgICAgICAgICAgdG9rZW5NZXRhZGF0YVxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgfVxuXG4gICAgICBzbGljZVN0YXJ0ID0gc2xpY2VFbmQgKyAxXG4gICAgfVxuXG4gIH1cblxuICByZXR1cm4gdG9rZW5zXG59XG5cbi8qKlxuICogVGhlIHNlcGFyYXRvciB1c2VkIHRvIHNwbGl0IGEgc3RyaW5nIGludG8gdG9rZW5zLiBPdmVycmlkZSB0aGlzIHByb3BlcnR5IHRvIGNoYW5nZSB0aGUgYmVoYXZpb3VyIG9mXG4gKiBgbHVuci50b2tlbml6ZXJgIGJlaGF2aW91ciB3aGVuIHRva2VuaXppbmcgc3RyaW5ncy4gQnkgZGVmYXVsdCB0aGlzIHNwbGl0cyBvbiB3aGl0ZXNwYWNlIGFuZCBoeXBoZW5zLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBzZWUgbHVuci50b2tlbml6ZXJcbiAqL1xubHVuci50b2tlbml6ZXIuc2VwYXJhdG9yID0gL1tcXHNcXC1dKy9cbi8qIVxuICogbHVuci5QaXBlbGluZVxuICogQ29weXJpZ2h0IChDKSAyMDE4IE9saXZlciBOaWdodGluZ2FsZVxuICovXG5cbi8qKlxuICogbHVuci5QaXBlbGluZXMgbWFpbnRhaW4gYW4gb3JkZXJlZCBsaXN0IG9mIGZ1bmN0aW9ucyB0byBiZSBhcHBsaWVkIHRvIGFsbFxuICogdG9rZW5zIGluIGRvY3VtZW50cyBlbnRlcmluZyB0aGUgc2VhcmNoIGluZGV4IGFuZCBxdWVyaWVzIGJlaW5nIHJhbiBhZ2FpbnN0XG4gKiB0aGUgaW5kZXguXG4gKlxuICogQW4gaW5zdGFuY2Ugb2YgbHVuci5JbmRleCBjcmVhdGVkIHdpdGggdGhlIGx1bnIgc2hvcnRjdXQgd2lsbCBjb250YWluIGFcbiAqIHBpcGVsaW5lIHdpdGggYSBzdG9wIHdvcmQgZmlsdGVyIGFuZCBhbiBFbmdsaXNoIGxhbmd1YWdlIHN0ZW1tZXIuIEV4dHJhXG4gKiBmdW5jdGlvbnMgY2FuIGJlIGFkZGVkIGJlZm9yZSBvciBhZnRlciBlaXRoZXIgb2YgdGhlc2UgZnVuY3Rpb25zIG9yIHRoZXNlXG4gKiBkZWZhdWx0IGZ1bmN0aW9ucyBjYW4gYmUgcmVtb3ZlZC5cbiAqXG4gKiBXaGVuIHJ1biB0aGUgcGlwZWxpbmUgd2lsbCBjYWxsIGVhY2ggZnVuY3Rpb24gaW4gdHVybiwgcGFzc2luZyBhIHRva2VuLCB0aGVcbiAqIGluZGV4IG9mIHRoYXQgdG9rZW4gaW4gdGhlIG9yaWdpbmFsIGxpc3Qgb2YgYWxsIHRva2VucyBhbmQgZmluYWxseSBhIGxpc3Qgb2ZcbiAqIGFsbCB0aGUgb3JpZ2luYWwgdG9rZW5zLlxuICpcbiAqIFRoZSBvdXRwdXQgb2YgZnVuY3Rpb25zIGluIHRoZSBwaXBlbGluZSB3aWxsIGJlIHBhc3NlZCB0byB0aGUgbmV4dCBmdW5jdGlvblxuICogaW4gdGhlIHBpcGVsaW5lLiBUbyBleGNsdWRlIGEgdG9rZW4gZnJvbSBlbnRlcmluZyB0aGUgaW5kZXggdGhlIGZ1bmN0aW9uXG4gKiBzaG91bGQgcmV0dXJuIHVuZGVmaW5lZCwgdGhlIHJlc3Qgb2YgdGhlIHBpcGVsaW5lIHdpbGwgbm90IGJlIGNhbGxlZCB3aXRoXG4gKiB0aGlzIHRva2VuLlxuICpcbiAqIEZvciBzZXJpYWxpc2F0aW9uIG9mIHBpcGVsaW5lcyB0byB3b3JrLCBhbGwgZnVuY3Rpb25zIHVzZWQgaW4gYW4gaW5zdGFuY2Ugb2ZcbiAqIGEgcGlwZWxpbmUgc2hvdWxkIGJlIHJlZ2lzdGVyZWQgd2l0aCBsdW5yLlBpcGVsaW5lLiBSZWdpc3RlcmVkIGZ1bmN0aW9ucyBjYW5cbiAqIHRoZW4gYmUgbG9hZGVkLiBJZiB0cnlpbmcgdG8gbG9hZCBhIHNlcmlhbGlzZWQgcGlwZWxpbmUgdGhhdCB1c2VzIGZ1bmN0aW9uc1xuICogdGhhdCBhcmUgbm90IHJlZ2lzdGVyZWQgYW4gZXJyb3Igd2lsbCBiZSB0aHJvd24uXG4gKlxuICogSWYgbm90IHBsYW5uaW5nIG9uIHNlcmlhbGlzaW5nIHRoZSBwaXBlbGluZSB0aGVuIHJlZ2lzdGVyaW5nIHBpcGVsaW5lIGZ1bmN0aW9uc1xuICogaXMgbm90IG5lY2Vzc2FyeS5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xubHVuci5QaXBlbGluZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5fc3RhY2sgPSBbXVxufVxuXG5sdW5yLlBpcGVsaW5lLnJlZ2lzdGVyZWRGdW5jdGlvbnMgPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbi8qKlxuICogQSBwaXBlbGluZSBmdW5jdGlvbiBtYXBzIGx1bnIuVG9rZW4gdG8gbHVuci5Ub2tlbi4gQSBsdW5yLlRva2VuIGNvbnRhaW5zIHRoZSB0b2tlblxuICogc3RyaW5nIGFzIHdlbGwgYXMgYWxsIGtub3duIG1ldGFkYXRhLiBBIHBpcGVsaW5lIGZ1bmN0aW9uIGNhbiBtdXRhdGUgdGhlIHRva2VuIHN0cmluZ1xuICogb3IgbXV0YXRlIChvciBhZGQpIG1ldGFkYXRhIGZvciBhIGdpdmVuIHRva2VuLlxuICpcbiAqIEEgcGlwZWxpbmUgZnVuY3Rpb24gY2FuIGluZGljYXRlIHRoYXQgdGhlIHBhc3NlZCB0b2tlbiBzaG91bGQgYmUgZGlzY2FyZGVkIGJ5IHJldHVybmluZ1xuICogbnVsbC4gVGhpcyB0b2tlbiB3aWxsIG5vdCBiZSBwYXNzZWQgdG8gYW55IGRvd25zdHJlYW0gcGlwZWxpbmUgZnVuY3Rpb25zIGFuZCB3aWxsIG5vdCBiZVxuICogYWRkZWQgdG8gdGhlIGluZGV4LlxuICpcbiAqIE11bHRpcGxlIHRva2VucyBjYW4gYmUgcmV0dXJuZWQgYnkgcmV0dXJuaW5nIGFuIGFycmF5IG9mIHRva2Vucy4gRWFjaCB0b2tlbiB3aWxsIGJlIHBhc3NlZFxuICogdG8gYW55IGRvd25zdHJlYW0gcGlwZWxpbmUgZnVuY3Rpb25zIGFuZCBhbGwgd2lsbCByZXR1cm5lZCB0b2tlbnMgd2lsbCBiZSBhZGRlZCB0byB0aGUgaW5kZXguXG4gKlxuICogQW55IG51bWJlciBvZiBwaXBlbGluZSBmdW5jdGlvbnMgbWF5IGJlIGNoYWluZWQgdG9nZXRoZXIgdXNpbmcgYSBsdW5yLlBpcGVsaW5lLlxuICpcbiAqIEBpbnRlcmZhY2UgbHVuci5QaXBlbGluZUZ1bmN0aW9uXG4gKiBAcGFyYW0ge2x1bnIuVG9rZW59IHRva2VuIC0gQSB0b2tlbiBmcm9tIHRoZSBkb2N1bWVudCBiZWluZyBwcm9jZXNzZWQuXG4gKiBAcGFyYW0ge251bWJlcn0gaSAtIFRoZSBpbmRleCBvZiB0aGlzIHRva2VuIGluIHRoZSBjb21wbGV0ZSBsaXN0IG9mIHRva2VucyBmb3IgdGhpcyBkb2N1bWVudC9maWVsZC5cbiAqIEBwYXJhbSB7bHVuci5Ub2tlbltdfSB0b2tlbnMgLSBBbGwgdG9rZW5zIGZvciB0aGlzIGRvY3VtZW50L2ZpZWxkLlxuICogQHJldHVybnMgeyg/bHVuci5Ub2tlbnxsdW5yLlRva2VuW10pfVxuICovXG5cbi8qKlxuICogUmVnaXN0ZXIgYSBmdW5jdGlvbiB3aXRoIHRoZSBwaXBlbGluZS5cbiAqXG4gKiBGdW5jdGlvbnMgdGhhdCBhcmUgdXNlZCBpbiB0aGUgcGlwZWxpbmUgc2hvdWxkIGJlIHJlZ2lzdGVyZWQgaWYgdGhlIHBpcGVsaW5lXG4gKiBuZWVkcyB0byBiZSBzZXJpYWxpc2VkLCBvciBhIHNlcmlhbGlzZWQgcGlwZWxpbmUgbmVlZHMgdG8gYmUgbG9hZGVkLlxuICpcbiAqIFJlZ2lzdGVyaW5nIGEgZnVuY3Rpb24gZG9lcyBub3QgYWRkIGl0IHRvIGEgcGlwZWxpbmUsIGZ1bmN0aW9ucyBtdXN0IHN0aWxsIGJlXG4gKiBhZGRlZCB0byBpbnN0YW5jZXMgb2YgdGhlIHBpcGVsaW5lIGZvciB0aGVtIHRvIGJlIHVzZWQgd2hlbiBydW5uaW5nIGEgcGlwZWxpbmUuXG4gKlxuICogQHBhcmFtIHtsdW5yLlBpcGVsaW5lRnVuY3Rpb259IGZuIC0gVGhlIGZ1bmN0aW9uIHRvIGNoZWNrIGZvci5cbiAqIEBwYXJhbSB7U3RyaW5nfSBsYWJlbCAtIFRoZSBsYWJlbCB0byByZWdpc3RlciB0aGlzIGZ1bmN0aW9uIHdpdGhcbiAqL1xubHVuci5QaXBlbGluZS5yZWdpc3RlckZ1bmN0aW9uID0gZnVuY3Rpb24gKGZuLCBsYWJlbCkge1xuICBpZiAobGFiZWwgaW4gdGhpcy5yZWdpc3RlcmVkRnVuY3Rpb25zKSB7XG4gICAgbHVuci51dGlscy53YXJuKCdPdmVyd3JpdGluZyBleGlzdGluZyByZWdpc3RlcmVkIGZ1bmN0aW9uOiAnICsgbGFiZWwpXG4gIH1cblxuICBmbi5sYWJlbCA9IGxhYmVsXG4gIGx1bnIuUGlwZWxpbmUucmVnaXN0ZXJlZEZ1bmN0aW9uc1tmbi5sYWJlbF0gPSBmblxufVxuXG4vKipcbiAqIFdhcm5zIGlmIHRoZSBmdW5jdGlvbiBpcyBub3QgcmVnaXN0ZXJlZCBhcyBhIFBpcGVsaW5lIGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSB7bHVuci5QaXBlbGluZUZ1bmN0aW9ufSBmbiAtIFRoZSBmdW5jdGlvbiB0byBjaGVjayBmb3IuXG4gKiBAcHJpdmF0ZVxuICovXG5sdW5yLlBpcGVsaW5lLndhcm5JZkZ1bmN0aW9uTm90UmVnaXN0ZXJlZCA9IGZ1bmN0aW9uIChmbikge1xuICB2YXIgaXNSZWdpc3RlcmVkID0gZm4ubGFiZWwgJiYgKGZuLmxhYmVsIGluIHRoaXMucmVnaXN0ZXJlZEZ1bmN0aW9ucylcblxuICBpZiAoIWlzUmVnaXN0ZXJlZCkge1xuICAgIGx1bnIudXRpbHMud2FybignRnVuY3Rpb24gaXMgbm90IHJlZ2lzdGVyZWQgd2l0aCBwaXBlbGluZS4gVGhpcyBtYXkgY2F1c2UgcHJvYmxlbXMgd2hlbiBzZXJpYWxpc2luZyB0aGUgaW5kZXguXFxuJywgZm4pXG4gIH1cbn1cblxuLyoqXG4gKiBMb2FkcyBhIHByZXZpb3VzbHkgc2VyaWFsaXNlZCBwaXBlbGluZS5cbiAqXG4gKiBBbGwgZnVuY3Rpb25zIHRvIGJlIGxvYWRlZCBtdXN0IGFscmVhZHkgYmUgcmVnaXN0ZXJlZCB3aXRoIGx1bnIuUGlwZWxpbmUuXG4gKiBJZiBhbnkgZnVuY3Rpb24gZnJvbSB0aGUgc2VyaWFsaXNlZCBkYXRhIGhhcyBub3QgYmVlbiByZWdpc3RlcmVkIHRoZW4gYW5cbiAqIGVycm9yIHdpbGwgYmUgdGhyb3duLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZXJpYWxpc2VkIC0gVGhlIHNlcmlhbGlzZWQgcGlwZWxpbmUgdG8gbG9hZC5cbiAqIEByZXR1cm5zIHtsdW5yLlBpcGVsaW5lfVxuICovXG5sdW5yLlBpcGVsaW5lLmxvYWQgPSBmdW5jdGlvbiAoc2VyaWFsaXNlZCkge1xuICB2YXIgcGlwZWxpbmUgPSBuZXcgbHVuci5QaXBlbGluZVxuXG4gIHNlcmlhbGlzZWQuZm9yRWFjaChmdW5jdGlvbiAoZm5OYW1lKSB7XG4gICAgdmFyIGZuID0gbHVuci5QaXBlbGluZS5yZWdpc3RlcmVkRnVuY3Rpb25zW2ZuTmFtZV1cblxuICAgIGlmIChmbikge1xuICAgICAgcGlwZWxpbmUuYWRkKGZuKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBsb2FkIHVucmVnaXN0ZXJlZCBmdW5jdGlvbjogJyArIGZuTmFtZSlcbiAgICB9XG4gIH0pXG5cbiAgcmV0dXJuIHBpcGVsaW5lXG59XG5cbi8qKlxuICogQWRkcyBuZXcgZnVuY3Rpb25zIHRvIHRoZSBlbmQgb2YgdGhlIHBpcGVsaW5lLlxuICpcbiAqIExvZ3MgYSB3YXJuaW5nIGlmIHRoZSBmdW5jdGlvbiBoYXMgbm90IGJlZW4gcmVnaXN0ZXJlZC5cbiAqXG4gKiBAcGFyYW0ge2x1bnIuUGlwZWxpbmVGdW5jdGlvbltdfSBmdW5jdGlvbnMgLSBBbnkgbnVtYmVyIG9mIGZ1bmN0aW9ucyB0byBhZGQgdG8gdGhlIHBpcGVsaW5lLlxuICovXG5sdW5yLlBpcGVsaW5lLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBmbnMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpXG5cbiAgZm5zLmZvckVhY2goZnVuY3Rpb24gKGZuKSB7XG4gICAgbHVuci5QaXBlbGluZS53YXJuSWZGdW5jdGlvbk5vdFJlZ2lzdGVyZWQoZm4pXG4gICAgdGhpcy5fc3RhY2sucHVzaChmbilcbiAgfSwgdGhpcylcbn1cblxuLyoqXG4gKiBBZGRzIGEgc2luZ2xlIGZ1bmN0aW9uIGFmdGVyIGEgZnVuY3Rpb24gdGhhdCBhbHJlYWR5IGV4aXN0cyBpbiB0aGVcbiAqIHBpcGVsaW5lLlxuICpcbiAqIExvZ3MgYSB3YXJuaW5nIGlmIHRoZSBmdW5jdGlvbiBoYXMgbm90IGJlZW4gcmVnaXN0ZXJlZC5cbiAqXG4gKiBAcGFyYW0ge2x1bnIuUGlwZWxpbmVGdW5jdGlvbn0gZXhpc3RpbmdGbiAtIEEgZnVuY3Rpb24gdGhhdCBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgcGlwZWxpbmUuXG4gKiBAcGFyYW0ge2x1bnIuUGlwZWxpbmVGdW5jdGlvbn0gbmV3Rm4gLSBUaGUgbmV3IGZ1bmN0aW9uIHRvIGFkZCB0byB0aGUgcGlwZWxpbmUuXG4gKi9cbmx1bnIuUGlwZWxpbmUucHJvdG90eXBlLmFmdGVyID0gZnVuY3Rpb24gKGV4aXN0aW5nRm4sIG5ld0ZuKSB7XG4gIGx1bnIuUGlwZWxpbmUud2FybklmRnVuY3Rpb25Ob3RSZWdpc3RlcmVkKG5ld0ZuKVxuXG4gIHZhciBwb3MgPSB0aGlzLl9zdGFjay5pbmRleE9mKGV4aXN0aW5nRm4pXG4gIGlmIChwb3MgPT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBmaW5kIGV4aXN0aW5nRm4nKVxuICB9XG5cbiAgcG9zID0gcG9zICsgMVxuICB0aGlzLl9zdGFjay5zcGxpY2UocG9zLCAwLCBuZXdGbilcbn1cblxuLyoqXG4gKiBBZGRzIGEgc2luZ2xlIGZ1bmN0aW9uIGJlZm9yZSBhIGZ1bmN0aW9uIHRoYXQgYWxyZWFkeSBleGlzdHMgaW4gdGhlXG4gKiBwaXBlbGluZS5cbiAqXG4gKiBMb2dzIGEgd2FybmluZyBpZiB0aGUgZnVuY3Rpb24gaGFzIG5vdCBiZWVuIHJlZ2lzdGVyZWQuXG4gKlxuICogQHBhcmFtIHtsdW5yLlBpcGVsaW5lRnVuY3Rpb259IGV4aXN0aW5nRm4gLSBBIGZ1bmN0aW9uIHRoYXQgYWxyZWFkeSBleGlzdHMgaW4gdGhlIHBpcGVsaW5lLlxuICogQHBhcmFtIHtsdW5yLlBpcGVsaW5lRnVuY3Rpb259IG5ld0ZuIC0gVGhlIG5ldyBmdW5jdGlvbiB0byBhZGQgdG8gdGhlIHBpcGVsaW5lLlxuICovXG5sdW5yLlBpcGVsaW5lLnByb3RvdHlwZS5iZWZvcmUgPSBmdW5jdGlvbiAoZXhpc3RpbmdGbiwgbmV3Rm4pIHtcbiAgbHVuci5QaXBlbGluZS53YXJuSWZGdW5jdGlvbk5vdFJlZ2lzdGVyZWQobmV3Rm4pXG5cbiAgdmFyIHBvcyA9IHRoaXMuX3N0YWNrLmluZGV4T2YoZXhpc3RpbmdGbilcbiAgaWYgKHBvcyA9PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGZpbmQgZXhpc3RpbmdGbicpXG4gIH1cblxuICB0aGlzLl9zdGFjay5zcGxpY2UocG9zLCAwLCBuZXdGbilcbn1cblxuLyoqXG4gKiBSZW1vdmVzIGEgZnVuY3Rpb24gZnJvbSB0aGUgcGlwZWxpbmUuXG4gKlxuICogQHBhcmFtIHtsdW5yLlBpcGVsaW5lRnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byByZW1vdmUgZnJvbSB0aGUgcGlwZWxpbmUuXG4gKi9cbmx1bnIuUGlwZWxpbmUucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uIChmbikge1xuICB2YXIgcG9zID0gdGhpcy5fc3RhY2suaW5kZXhPZihmbilcbiAgaWYgKHBvcyA9PSAtMSkge1xuICAgIHJldHVyblxuICB9XG5cbiAgdGhpcy5fc3RhY2suc3BsaWNlKHBvcywgMSlcbn1cblxuLyoqXG4gKiBSdW5zIHRoZSBjdXJyZW50IGxpc3Qgb2YgZnVuY3Rpb25zIHRoYXQgbWFrZSB1cCB0aGUgcGlwZWxpbmUgYWdhaW5zdCB0aGVcbiAqIHBhc3NlZCB0b2tlbnMuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gdG9rZW5zIFRoZSB0b2tlbnMgdG8gcnVuIHRocm91Z2ggdGhlIHBpcGVsaW5lLlxuICogQHJldHVybnMge0FycmF5fVxuICovXG5sdW5yLlBpcGVsaW5lLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAodG9rZW5zKSB7XG4gIHZhciBzdGFja0xlbmd0aCA9IHRoaXMuX3N0YWNrLmxlbmd0aFxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RhY2tMZW5ndGg7IGkrKykge1xuICAgIHZhciBmbiA9IHRoaXMuX3N0YWNrW2ldXG4gICAgdmFyIG1lbW8gPSBbXVxuXG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCB0b2tlbnMubGVuZ3RoOyBqKyspIHtcbiAgICAgIHZhciByZXN1bHQgPSBmbih0b2tlbnNbal0sIGosIHRva2VucylcblxuICAgICAgaWYgKHJlc3VsdCA9PT0gdm9pZCAwIHx8IHJlc3VsdCA9PT0gJycpIGNvbnRpbnVlXG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCByZXN1bHQubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICBtZW1vLnB1c2gocmVzdWx0W2tdKVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtZW1vLnB1c2gocmVzdWx0KVxuICAgICAgfVxuICAgIH1cblxuICAgIHRva2VucyA9IG1lbW9cbiAgfVxuXG4gIHJldHVybiB0b2tlbnNcbn1cblxuLyoqXG4gKiBDb252ZW5pZW5jZSBtZXRob2QgZm9yIHBhc3NpbmcgYSBzdHJpbmcgdGhyb3VnaCBhIHBpcGVsaW5lIGFuZCBnZXR0aW5nXG4gKiBzdHJpbmdzIG91dC4gVGhpcyBtZXRob2QgdGFrZXMgY2FyZSBvZiB3cmFwcGluZyB0aGUgcGFzc2VkIHN0cmluZyBpbiBhXG4gKiB0b2tlbiBhbmQgbWFwcGluZyB0aGUgcmVzdWx0aW5nIHRva2VucyBiYWNrIHRvIHN0cmluZ3MuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIFRoZSBzdHJpbmcgdG8gcGFzcyB0aHJvdWdoIHRoZSBwaXBlbGluZS5cbiAqIEBwYXJhbSB7P29iamVjdH0gbWV0YWRhdGEgLSBPcHRpb25hbCBtZXRhZGF0YSB0byBhc3NvY2lhdGUgd2l0aCB0aGUgdG9rZW5cbiAqIHBhc3NlZCB0byB0aGUgcGlwZWxpbmUuXG4gKiBAcmV0dXJucyB7c3RyaW5nW119XG4gKi9cbmx1bnIuUGlwZWxpbmUucHJvdG90eXBlLnJ1blN0cmluZyA9IGZ1bmN0aW9uIChzdHIsIG1ldGFkYXRhKSB7XG4gIHZhciB0b2tlbiA9IG5ldyBsdW5yLlRva2VuIChzdHIsIG1ldGFkYXRhKVxuXG4gIHJldHVybiB0aGlzLnJ1bihbdG9rZW5dKS5tYXAoZnVuY3Rpb24gKHQpIHtcbiAgICByZXR1cm4gdC50b1N0cmluZygpXG4gIH0pXG59XG5cbi8qKlxuICogUmVzZXRzIHRoZSBwaXBlbGluZSBieSByZW1vdmluZyBhbnkgZXhpc3RpbmcgcHJvY2Vzc29ycy5cbiAqXG4gKi9cbmx1bnIuUGlwZWxpbmUucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLl9zdGFjayA9IFtdXG59XG5cbi8qKlxuICogUmV0dXJucyBhIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwaXBlbGluZSByZWFkeSBmb3Igc2VyaWFsaXNhdGlvbi5cbiAqXG4gKiBMb2dzIGEgd2FybmluZyBpZiB0aGUgZnVuY3Rpb24gaGFzIG5vdCBiZWVuIHJlZ2lzdGVyZWQuXG4gKlxuICogQHJldHVybnMge0FycmF5fVxuICovXG5sdW5yLlBpcGVsaW5lLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLl9zdGFjay5tYXAoZnVuY3Rpb24gKGZuKSB7XG4gICAgbHVuci5QaXBlbGluZS53YXJuSWZGdW5jdGlvbk5vdFJlZ2lzdGVyZWQoZm4pXG5cbiAgICByZXR1cm4gZm4ubGFiZWxcbiAgfSlcbn1cbi8qIVxuICogbHVuci5WZWN0b3JcbiAqIENvcHlyaWdodCAoQykgMjAxOCBPbGl2ZXIgTmlnaHRpbmdhbGVcbiAqL1xuXG4vKipcbiAqIEEgdmVjdG9yIGlzIHVzZWQgdG8gY29uc3RydWN0IHRoZSB2ZWN0b3Igc3BhY2Ugb2YgZG9jdW1lbnRzIGFuZCBxdWVyaWVzLiBUaGVzZVxuICogdmVjdG9ycyBzdXBwb3J0IG9wZXJhdGlvbnMgdG8gZGV0ZXJtaW5lIHRoZSBzaW1pbGFyaXR5IGJldHdlZW4gdHdvIGRvY3VtZW50cyBvclxuICogYSBkb2N1bWVudCBhbmQgYSBxdWVyeS5cbiAqXG4gKiBOb3JtYWxseSBubyBwYXJhbWV0ZXJzIGFyZSByZXF1aXJlZCBmb3IgaW5pdGlhbGl6aW5nIGEgdmVjdG9yLCBidXQgaW4gdGhlIGNhc2Ugb2ZcbiAqIGxvYWRpbmcgYSBwcmV2aW91c2x5IGR1bXBlZCB2ZWN0b3IgdGhlIHJhdyBlbGVtZW50cyBjYW4gYmUgcHJvdmlkZWQgdG8gdGhlIGNvbnN0cnVjdG9yLlxuICpcbiAqIEZvciBwZXJmb3JtYW5jZSByZWFzb25zIHZlY3RvcnMgYXJlIGltcGxlbWVudGVkIHdpdGggYSBmbGF0IGFycmF5LCB3aGVyZSBhbiBlbGVtZW50c1xuICogaW5kZXggaXMgaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgaXRzIHZhbHVlLiBFLmcuIFtpbmRleCwgdmFsdWUsIGluZGV4LCB2YWx1ZV0uIFRoaXNcbiAqIGFsbG93cyB0aGUgdW5kZXJseWluZyBhcnJheSB0byBiZSBhcyBzcGFyc2UgYXMgcG9zc2libGUgYW5kIHN0aWxsIG9mZmVyIGRlY2VudFxuICogcGVyZm9ybWFuY2Ugd2hlbiBiZWluZyB1c2VkIGZvciB2ZWN0b3IgY2FsY3VsYXRpb25zLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtOdW1iZXJbXX0gW2VsZW1lbnRzXSAtIFRoZSBmbGF0IGxpc3Qgb2YgZWxlbWVudCBpbmRleCBhbmQgZWxlbWVudCB2YWx1ZSBwYWlycy5cbiAqL1xubHVuci5WZWN0b3IgPSBmdW5jdGlvbiAoZWxlbWVudHMpIHtcbiAgdGhpcy5fbWFnbml0dWRlID0gMFxuICB0aGlzLmVsZW1lbnRzID0gZWxlbWVudHMgfHwgW11cbn1cblxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHBvc2l0aW9uIHdpdGhpbiB0aGUgdmVjdG9yIHRvIGluc2VydCBhIGdpdmVuIGluZGV4LlxuICpcbiAqIFRoaXMgaXMgdXNlZCBpbnRlcm5hbGx5IGJ5IGluc2VydCBhbmQgdXBzZXJ0LiBJZiB0aGVyZSBhcmUgZHVwbGljYXRlIGluZGV4ZXMgdGhlblxuICogdGhlIHBvc2l0aW9uIGlzIHJldHVybmVkIGFzIGlmIHRoZSB2YWx1ZSBmb3IgdGhhdCBpbmRleCB3ZXJlIHRvIGJlIHVwZGF0ZWQsIGJ1dCBpdFxuICogaXMgdGhlIGNhbGxlcnMgcmVzcG9uc2liaWxpdHkgdG8gY2hlY2sgd2hldGhlciB0aGVyZSBpcyBhIGR1cGxpY2F0ZSBhdCB0aGF0IGluZGV4XG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGluc2VydElkeCAtIFRoZSBpbmRleCBhdCB3aGljaCB0aGUgZWxlbWVudCBzaG91bGQgYmUgaW5zZXJ0ZWQuXG4gKiBAcmV0dXJucyB7TnVtYmVyfVxuICovXG5sdW5yLlZlY3Rvci5wcm90b3R5cGUucG9zaXRpb25Gb3JJbmRleCA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAvLyBGb3IgYW4gZW1wdHkgdmVjdG9yIHRoZSB0dXBsZSBjYW4gYmUgaW5zZXJ0ZWQgYXQgdGhlIGJlZ2lubmluZ1xuICBpZiAodGhpcy5lbGVtZW50cy5sZW5ndGggPT0gMCkge1xuICAgIHJldHVybiAwXG4gIH1cblxuICB2YXIgc3RhcnQgPSAwLFxuICAgICAgZW5kID0gdGhpcy5lbGVtZW50cy5sZW5ndGggLyAyLFxuICAgICAgc2xpY2VMZW5ndGggPSBlbmQgLSBzdGFydCxcbiAgICAgIHBpdm90UG9pbnQgPSBNYXRoLmZsb29yKHNsaWNlTGVuZ3RoIC8gMiksXG4gICAgICBwaXZvdEluZGV4ID0gdGhpcy5lbGVtZW50c1twaXZvdFBvaW50ICogMl1cblxuICB3aGlsZSAoc2xpY2VMZW5ndGggPiAxKSB7XG4gICAgaWYgKHBpdm90SW5kZXggPCBpbmRleCkge1xuICAgICAgc3RhcnQgPSBwaXZvdFBvaW50XG4gICAgfVxuXG4gICAgaWYgKHBpdm90SW5kZXggPiBpbmRleCkge1xuICAgICAgZW5kID0gcGl2b3RQb2ludFxuICAgIH1cblxuICAgIGlmIChwaXZvdEluZGV4ID09IGluZGV4KSB7XG4gICAgICBicmVha1xuICAgIH1cblxuICAgIHNsaWNlTGVuZ3RoID0gZW5kIC0gc3RhcnRcbiAgICBwaXZvdFBvaW50ID0gc3RhcnQgKyBNYXRoLmZsb29yKHNsaWNlTGVuZ3RoIC8gMilcbiAgICBwaXZvdEluZGV4ID0gdGhpcy5lbGVtZW50c1twaXZvdFBvaW50ICogMl1cbiAgfVxuXG4gIGlmIChwaXZvdEluZGV4ID09IGluZGV4KSB7XG4gICAgcmV0dXJuIHBpdm90UG9pbnQgKiAyXG4gIH1cblxuICBpZiAocGl2b3RJbmRleCA+IGluZGV4KSB7XG4gICAgcmV0dXJuIHBpdm90UG9pbnQgKiAyXG4gIH1cblxuICBpZiAocGl2b3RJbmRleCA8IGluZGV4KSB7XG4gICAgcmV0dXJuIChwaXZvdFBvaW50ICsgMSkgKiAyXG4gIH1cbn1cblxuLyoqXG4gKiBJbnNlcnRzIGFuIGVsZW1lbnQgYXQgYW4gaW5kZXggd2l0aGluIHRoZSB2ZWN0b3IuXG4gKlxuICogRG9lcyBub3QgYWxsb3cgZHVwbGljYXRlcywgd2lsbCB0aHJvdyBhbiBlcnJvciBpZiB0aGVyZSBpcyBhbHJlYWR5IGFuIGVudHJ5XG4gKiBmb3IgdGhpcyBpbmRleC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gaW5zZXJ0SWR4IC0gVGhlIGluZGV4IGF0IHdoaWNoIHRoZSBlbGVtZW50IHNob3VsZCBiZSBpbnNlcnRlZC5cbiAqIEBwYXJhbSB7TnVtYmVyfSB2YWwgLSBUaGUgdmFsdWUgdG8gYmUgaW5zZXJ0ZWQgaW50byB0aGUgdmVjdG9yLlxuICovXG5sdW5yLlZlY3Rvci5wcm90b3R5cGUuaW5zZXJ0ID0gZnVuY3Rpb24gKGluc2VydElkeCwgdmFsKSB7XG4gIHRoaXMudXBzZXJ0KGluc2VydElkeCwgdmFsLCBmdW5jdGlvbiAoKSB7XG4gICAgdGhyb3cgXCJkdXBsaWNhdGUgaW5kZXhcIlxuICB9KVxufVxuXG4vKipcbiAqIEluc2VydHMgb3IgdXBkYXRlcyBhbiBleGlzdGluZyBpbmRleCB3aXRoaW4gdGhlIHZlY3Rvci5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gaW5zZXJ0SWR4IC0gVGhlIGluZGV4IGF0IHdoaWNoIHRoZSBlbGVtZW50IHNob3VsZCBiZSBpbnNlcnRlZC5cbiAqIEBwYXJhbSB7TnVtYmVyfSB2YWwgLSBUaGUgdmFsdWUgdG8gYmUgaW5zZXJ0ZWQgaW50byB0aGUgdmVjdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbn0gZm4gLSBBIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIGZvciB1cGRhdGVzLCB0aGUgZXhpc3RpbmcgdmFsdWUgYW5kIHRoZVxuICogcmVxdWVzdGVkIHZhbHVlIGFyZSBwYXNzZWQgYXMgYXJndW1lbnRzXG4gKi9cbmx1bnIuVmVjdG9yLnByb3RvdHlwZS51cHNlcnQgPSBmdW5jdGlvbiAoaW5zZXJ0SWR4LCB2YWwsIGZuKSB7XG4gIHRoaXMuX21hZ25pdHVkZSA9IDBcbiAgdmFyIHBvc2l0aW9uID0gdGhpcy5wb3NpdGlvbkZvckluZGV4KGluc2VydElkeClcblxuICBpZiAodGhpcy5lbGVtZW50c1twb3NpdGlvbl0gPT0gaW5zZXJ0SWR4KSB7XG4gICAgdGhpcy5lbGVtZW50c1twb3NpdGlvbiArIDFdID0gZm4odGhpcy5lbGVtZW50c1twb3NpdGlvbiArIDFdLCB2YWwpXG4gIH0gZWxzZSB7XG4gICAgdGhpcy5lbGVtZW50cy5zcGxpY2UocG9zaXRpb24sIDAsIGluc2VydElkeCwgdmFsKVxuICB9XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgbWFnbml0dWRlIG9mIHRoaXMgdmVjdG9yLlxuICpcbiAqIEByZXR1cm5zIHtOdW1iZXJ9XG4gKi9cbmx1bnIuVmVjdG9yLnByb3RvdHlwZS5tYWduaXR1ZGUgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLl9tYWduaXR1ZGUpIHJldHVybiB0aGlzLl9tYWduaXR1ZGVcblxuICB2YXIgc3VtT2ZTcXVhcmVzID0gMCxcbiAgICAgIGVsZW1lbnRzTGVuZ3RoID0gdGhpcy5lbGVtZW50cy5sZW5ndGhcblxuICBmb3IgKHZhciBpID0gMTsgaSA8IGVsZW1lbnRzTGVuZ3RoOyBpICs9IDIpIHtcbiAgICB2YXIgdmFsID0gdGhpcy5lbGVtZW50c1tpXVxuICAgIHN1bU9mU3F1YXJlcyArPSB2YWwgKiB2YWxcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9tYWduaXR1ZGUgPSBNYXRoLnNxcnQoc3VtT2ZTcXVhcmVzKVxufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGRvdCBwcm9kdWN0IG9mIHRoaXMgdmVjdG9yIGFuZCBhbm90aGVyIHZlY3Rvci5cbiAqXG4gKiBAcGFyYW0ge2x1bnIuVmVjdG9yfSBvdGhlclZlY3RvciAtIFRoZSB2ZWN0b3IgdG8gY29tcHV0ZSB0aGUgZG90IHByb2R1Y3Qgd2l0aC5cbiAqIEByZXR1cm5zIHtOdW1iZXJ9XG4gKi9cbmx1bnIuVmVjdG9yLnByb3RvdHlwZS5kb3QgPSBmdW5jdGlvbiAob3RoZXJWZWN0b3IpIHtcbiAgdmFyIGRvdFByb2R1Y3QgPSAwLFxuICAgICAgYSA9IHRoaXMuZWxlbWVudHMsIGIgPSBvdGhlclZlY3Rvci5lbGVtZW50cyxcbiAgICAgIGFMZW4gPSBhLmxlbmd0aCwgYkxlbiA9IGIubGVuZ3RoLFxuICAgICAgYVZhbCA9IDAsIGJWYWwgPSAwLFxuICAgICAgaSA9IDAsIGogPSAwXG5cbiAgd2hpbGUgKGkgPCBhTGVuICYmIGogPCBiTGVuKSB7XG4gICAgYVZhbCA9IGFbaV0sIGJWYWwgPSBiW2pdXG4gICAgaWYgKGFWYWwgPCBiVmFsKSB7XG4gICAgICBpICs9IDJcbiAgICB9IGVsc2UgaWYgKGFWYWwgPiBiVmFsKSB7XG4gICAgICBqICs9IDJcbiAgICB9IGVsc2UgaWYgKGFWYWwgPT0gYlZhbCkge1xuICAgICAgZG90UHJvZHVjdCArPSBhW2kgKyAxXSAqIGJbaiArIDFdXG4gICAgICBpICs9IDJcbiAgICAgIGogKz0gMlxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkb3RQcm9kdWN0XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgc2ltaWxhcml0eSBiZXR3ZWVuIHRoaXMgdmVjdG9yIGFuZCBhbm90aGVyIHZlY3Rvci5cbiAqXG4gKiBAcGFyYW0ge2x1bnIuVmVjdG9yfSBvdGhlclZlY3RvciAtIFRoZSBvdGhlciB2ZWN0b3IgdG8gY2FsY3VsYXRlIHRoZVxuICogc2ltaWxhcml0eSB3aXRoLlxuICogQHJldHVybnMge051bWJlcn1cbiAqL1xubHVuci5WZWN0b3IucHJvdG90eXBlLnNpbWlsYXJpdHkgPSBmdW5jdGlvbiAob3RoZXJWZWN0b3IpIHtcbiAgcmV0dXJuIHRoaXMuZG90KG90aGVyVmVjdG9yKSAvIHRoaXMubWFnbml0dWRlKCkgfHwgMFxufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZSB2ZWN0b3IgdG8gYW4gYXJyYXkgb2YgdGhlIGVsZW1lbnRzIHdpdGhpbiB0aGUgdmVjdG9yLlxuICpcbiAqIEByZXR1cm5zIHtOdW1iZXJbXX1cbiAqL1xubHVuci5WZWN0b3IucHJvdG90eXBlLnRvQXJyYXkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBvdXRwdXQgPSBuZXcgQXJyYXkgKHRoaXMuZWxlbWVudHMubGVuZ3RoIC8gMilcblxuICBmb3IgKHZhciBpID0gMSwgaiA9IDA7IGkgPCB0aGlzLmVsZW1lbnRzLmxlbmd0aDsgaSArPSAyLCBqKyspIHtcbiAgICBvdXRwdXRbal0gPSB0aGlzLmVsZW1lbnRzW2ldXG4gIH1cblxuICByZXR1cm4gb3V0cHV0XG59XG5cbi8qKlxuICogQSBKU09OIHNlcmlhbGl6YWJsZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmVjdG9yLlxuICpcbiAqIEByZXR1cm5zIHtOdW1iZXJbXX1cbiAqL1xubHVuci5WZWN0b3IucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuZWxlbWVudHNcbn1cbi8qIGVzbGludC1kaXNhYmxlICovXG4vKiFcbiAqIGx1bnIuc3RlbW1lclxuICogQ29weXJpZ2h0IChDKSAyMDE4IE9saXZlciBOaWdodGluZ2FsZVxuICogSW5jbHVkZXMgY29kZSBmcm9tIC0gaHR0cDovL3RhcnRhcnVzLm9yZy9+bWFydGluL1BvcnRlclN0ZW1tZXIvanMudHh0XG4gKi9cblxuLyoqXG4gKiBsdW5yLnN0ZW1tZXIgaXMgYW4gZW5nbGlzaCBsYW5ndWFnZSBzdGVtbWVyLCB0aGlzIGlzIGEgSmF2YVNjcmlwdFxuICogaW1wbGVtZW50YXRpb24gb2YgdGhlIFBvcnRlclN0ZW1tZXIgdGFrZW4gZnJvbSBodHRwOi8vdGFydGFydXMub3JnL35tYXJ0aW5cbiAqXG4gKiBAc3RhdGljXG4gKiBAaW1wbGVtZW50cyB7bHVuci5QaXBlbGluZUZ1bmN0aW9ufVxuICogQHBhcmFtIHtsdW5yLlRva2VufSB0b2tlbiAtIFRoZSBzdHJpbmcgdG8gc3RlbVxuICogQHJldHVybnMge2x1bnIuVG9rZW59XG4gKiBAc2VlIHtAbGluayBsdW5yLlBpcGVsaW5lfVxuICogQGZ1bmN0aW9uXG4gKi9cbmx1bnIuc3RlbW1lciA9IChmdW5jdGlvbigpe1xuICB2YXIgc3RlcDJsaXN0ID0ge1xuICAgICAgXCJhdGlvbmFsXCIgOiBcImF0ZVwiLFxuICAgICAgXCJ0aW9uYWxcIiA6IFwidGlvblwiLFxuICAgICAgXCJlbmNpXCIgOiBcImVuY2VcIixcbiAgICAgIFwiYW5jaVwiIDogXCJhbmNlXCIsXG4gICAgICBcIml6ZXJcIiA6IFwiaXplXCIsXG4gICAgICBcImJsaVwiIDogXCJibGVcIixcbiAgICAgIFwiYWxsaVwiIDogXCJhbFwiLFxuICAgICAgXCJlbnRsaVwiIDogXCJlbnRcIixcbiAgICAgIFwiZWxpXCIgOiBcImVcIixcbiAgICAgIFwib3VzbGlcIiA6IFwib3VzXCIsXG4gICAgICBcIml6YXRpb25cIiA6IFwiaXplXCIsXG4gICAgICBcImF0aW9uXCIgOiBcImF0ZVwiLFxuICAgICAgXCJhdG9yXCIgOiBcImF0ZVwiLFxuICAgICAgXCJhbGlzbVwiIDogXCJhbFwiLFxuICAgICAgXCJpdmVuZXNzXCIgOiBcIml2ZVwiLFxuICAgICAgXCJmdWxuZXNzXCIgOiBcImZ1bFwiLFxuICAgICAgXCJvdXNuZXNzXCIgOiBcIm91c1wiLFxuICAgICAgXCJhbGl0aVwiIDogXCJhbFwiLFxuICAgICAgXCJpdml0aVwiIDogXCJpdmVcIixcbiAgICAgIFwiYmlsaXRpXCIgOiBcImJsZVwiLFxuICAgICAgXCJsb2dpXCIgOiBcImxvZ1wiXG4gICAgfSxcblxuICAgIHN0ZXAzbGlzdCA9IHtcbiAgICAgIFwiaWNhdGVcIiA6IFwiaWNcIixcbiAgICAgIFwiYXRpdmVcIiA6IFwiXCIsXG4gICAgICBcImFsaXplXCIgOiBcImFsXCIsXG4gICAgICBcImljaXRpXCIgOiBcImljXCIsXG4gICAgICBcImljYWxcIiA6IFwiaWNcIixcbiAgICAgIFwiZnVsXCIgOiBcIlwiLFxuICAgICAgXCJuZXNzXCIgOiBcIlwiXG4gICAgfSxcblxuICAgIGMgPSBcIlteYWVpb3VdXCIsICAgICAgICAgIC8vIGNvbnNvbmFudFxuICAgIHYgPSBcIlthZWlvdXldXCIsICAgICAgICAgIC8vIHZvd2VsXG4gICAgQyA9IGMgKyBcIlteYWVpb3V5XSpcIiwgICAgLy8gY29uc29uYW50IHNlcXVlbmNlXG4gICAgViA9IHYgKyBcIlthZWlvdV0qXCIsICAgICAgLy8gdm93ZWwgc2VxdWVuY2VcblxuICAgIG1ncjAgPSBcIl4oXCIgKyBDICsgXCIpP1wiICsgViArIEMsICAgICAgICAgICAgICAgLy8gW0NdVkMuLi4gaXMgbT4wXG4gICAgbWVxMSA9IFwiXihcIiArIEMgKyBcIik/XCIgKyBWICsgQyArIFwiKFwiICsgViArIFwiKT8kXCIsICAvLyBbQ11WQ1tWXSBpcyBtPTFcbiAgICBtZ3IxID0gXCJeKFwiICsgQyArIFwiKT9cIiArIFYgKyBDICsgViArIEMsICAgICAgIC8vIFtDXVZDVkMuLi4gaXMgbT4xXG4gICAgc192ID0gXCJeKFwiICsgQyArIFwiKT9cIiArIHY7ICAgICAgICAgICAgICAgICAgIC8vIHZvd2VsIGluIHN0ZW1cblxuICB2YXIgcmVfbWdyMCA9IG5ldyBSZWdFeHAobWdyMCk7XG4gIHZhciByZV9tZ3IxID0gbmV3IFJlZ0V4cChtZ3IxKTtcbiAgdmFyIHJlX21lcTEgPSBuZXcgUmVnRXhwKG1lcTEpO1xuICB2YXIgcmVfc192ID0gbmV3IFJlZ0V4cChzX3YpO1xuXG4gIHZhciByZV8xYSA9IC9eKC4rPykoc3N8aSllcyQvO1xuICB2YXIgcmUyXzFhID0gL14oLis/KShbXnNdKXMkLztcbiAgdmFyIHJlXzFiID0gL14oLis/KWVlZCQvO1xuICB2YXIgcmUyXzFiID0gL14oLis/KShlZHxpbmcpJC87XG4gIHZhciByZV8xYl8yID0gLy4kLztcbiAgdmFyIHJlMl8xYl8yID0gLyhhdHxibHxpeikkLztcbiAgdmFyIHJlM18xYl8yID0gbmV3IFJlZ0V4cChcIihbXmFlaW91eWxzel0pXFxcXDEkXCIpO1xuICB2YXIgcmU0XzFiXzIgPSBuZXcgUmVnRXhwKFwiXlwiICsgQyArIHYgKyBcIlteYWVpb3V3eHldJFwiKTtcblxuICB2YXIgcmVfMWMgPSAvXiguKz9bXmFlaW91XSl5JC87XG4gIHZhciByZV8yID0gL14oLis/KShhdGlvbmFsfHRpb25hbHxlbmNpfGFuY2l8aXplcnxibGl8YWxsaXxlbnRsaXxlbGl8b3VzbGl8aXphdGlvbnxhdGlvbnxhdG9yfGFsaXNtfGl2ZW5lc3N8ZnVsbmVzc3xvdXNuZXNzfGFsaXRpfGl2aXRpfGJpbGl0aXxsb2dpKSQvO1xuXG4gIHZhciByZV8zID0gL14oLis/KShpY2F0ZXxhdGl2ZXxhbGl6ZXxpY2l0aXxpY2FsfGZ1bHxuZXNzKSQvO1xuXG4gIHZhciByZV80ID0gL14oLis/KShhbHxhbmNlfGVuY2V8ZXJ8aWN8YWJsZXxpYmxlfGFudHxlbWVudHxtZW50fGVudHxvdXxpc218YXRlfGl0aXxvdXN8aXZlfGl6ZSkkLztcbiAgdmFyIHJlMl80ID0gL14oLis/KShzfHQpKGlvbikkLztcblxuICB2YXIgcmVfNSA9IC9eKC4rPyllJC87XG4gIHZhciByZV81XzEgPSAvbGwkLztcbiAgdmFyIHJlM181ID0gbmV3IFJlZ0V4cChcIl5cIiArIEMgKyB2ICsgXCJbXmFlaW91d3h5XSRcIik7XG5cbiAgdmFyIHBvcnRlclN0ZW1tZXIgPSBmdW5jdGlvbiBwb3J0ZXJTdGVtbWVyKHcpIHtcbiAgICB2YXIgc3RlbSxcbiAgICAgIHN1ZmZpeCxcbiAgICAgIGZpcnN0Y2gsXG4gICAgICByZSxcbiAgICAgIHJlMixcbiAgICAgIHJlMyxcbiAgICAgIHJlNDtcblxuICAgIGlmICh3Lmxlbmd0aCA8IDMpIHsgcmV0dXJuIHc7IH1cblxuICAgIGZpcnN0Y2ggPSB3LnN1YnN0cigwLDEpO1xuICAgIGlmIChmaXJzdGNoID09IFwieVwiKSB7XG4gICAgICB3ID0gZmlyc3RjaC50b1VwcGVyQ2FzZSgpICsgdy5zdWJzdHIoMSk7XG4gICAgfVxuXG4gICAgLy8gU3RlcCAxYVxuICAgIHJlID0gcmVfMWFcbiAgICByZTIgPSByZTJfMWE7XG5cbiAgICBpZiAocmUudGVzdCh3KSkgeyB3ID0gdy5yZXBsYWNlKHJlLFwiJDEkMlwiKTsgfVxuICAgIGVsc2UgaWYgKHJlMi50ZXN0KHcpKSB7IHcgPSB3LnJlcGxhY2UocmUyLFwiJDEkMlwiKTsgfVxuXG4gICAgLy8gU3RlcCAxYlxuICAgIHJlID0gcmVfMWI7XG4gICAgcmUyID0gcmUyXzFiO1xuICAgIGlmIChyZS50ZXN0KHcpKSB7XG4gICAgICB2YXIgZnAgPSByZS5leGVjKHcpO1xuICAgICAgcmUgPSByZV9tZ3IwO1xuICAgICAgaWYgKHJlLnRlc3QoZnBbMV0pKSB7XG4gICAgICAgIHJlID0gcmVfMWJfMjtcbiAgICAgICAgdyA9IHcucmVwbGFjZShyZSxcIlwiKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHJlMi50ZXN0KHcpKSB7XG4gICAgICB2YXIgZnAgPSByZTIuZXhlYyh3KTtcbiAgICAgIHN0ZW0gPSBmcFsxXTtcbiAgICAgIHJlMiA9IHJlX3NfdjtcbiAgICAgIGlmIChyZTIudGVzdChzdGVtKSkge1xuICAgICAgICB3ID0gc3RlbTtcbiAgICAgICAgcmUyID0gcmUyXzFiXzI7XG4gICAgICAgIHJlMyA9IHJlM18xYl8yO1xuICAgICAgICByZTQgPSByZTRfMWJfMjtcbiAgICAgICAgaWYgKHJlMi50ZXN0KHcpKSB7IHcgPSB3ICsgXCJlXCI7IH1cbiAgICAgICAgZWxzZSBpZiAocmUzLnRlc3QodykpIHsgcmUgPSByZV8xYl8yOyB3ID0gdy5yZXBsYWNlKHJlLFwiXCIpOyB9XG4gICAgICAgIGVsc2UgaWYgKHJlNC50ZXN0KHcpKSB7IHcgPSB3ICsgXCJlXCI7IH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTdGVwIDFjIC0gcmVwbGFjZSBzdWZmaXggeSBvciBZIGJ5IGkgaWYgcHJlY2VkZWQgYnkgYSBub24tdm93ZWwgd2hpY2ggaXMgbm90IHRoZSBmaXJzdCBsZXR0ZXIgb2YgdGhlIHdvcmQgKHNvIGNyeSAtPiBjcmksIGJ5IC0+IGJ5LCBzYXkgLT4gc2F5KVxuICAgIHJlID0gcmVfMWM7XG4gICAgaWYgKHJlLnRlc3QodykpIHtcbiAgICAgIHZhciBmcCA9IHJlLmV4ZWModyk7XG4gICAgICBzdGVtID0gZnBbMV07XG4gICAgICB3ID0gc3RlbSArIFwiaVwiO1xuICAgIH1cblxuICAgIC8vIFN0ZXAgMlxuICAgIHJlID0gcmVfMjtcbiAgICBpZiAocmUudGVzdCh3KSkge1xuICAgICAgdmFyIGZwID0gcmUuZXhlYyh3KTtcbiAgICAgIHN0ZW0gPSBmcFsxXTtcbiAgICAgIHN1ZmZpeCA9IGZwWzJdO1xuICAgICAgcmUgPSByZV9tZ3IwO1xuICAgICAgaWYgKHJlLnRlc3Qoc3RlbSkpIHtcbiAgICAgICAgdyA9IHN0ZW0gKyBzdGVwMmxpc3Rbc3VmZml4XTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTdGVwIDNcbiAgICByZSA9IHJlXzM7XG4gICAgaWYgKHJlLnRlc3QodykpIHtcbiAgICAgIHZhciBmcCA9IHJlLmV4ZWModyk7XG4gICAgICBzdGVtID0gZnBbMV07XG4gICAgICBzdWZmaXggPSBmcFsyXTtcbiAgICAgIHJlID0gcmVfbWdyMDtcbiAgICAgIGlmIChyZS50ZXN0KHN0ZW0pKSB7XG4gICAgICAgIHcgPSBzdGVtICsgc3RlcDNsaXN0W3N1ZmZpeF07XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gU3RlcCA0XG4gICAgcmUgPSByZV80O1xuICAgIHJlMiA9IHJlMl80O1xuICAgIGlmIChyZS50ZXN0KHcpKSB7XG4gICAgICB2YXIgZnAgPSByZS5leGVjKHcpO1xuICAgICAgc3RlbSA9IGZwWzFdO1xuICAgICAgcmUgPSByZV9tZ3IxO1xuICAgICAgaWYgKHJlLnRlc3Qoc3RlbSkpIHtcbiAgICAgICAgdyA9IHN0ZW07XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChyZTIudGVzdCh3KSkge1xuICAgICAgdmFyIGZwID0gcmUyLmV4ZWModyk7XG4gICAgICBzdGVtID0gZnBbMV0gKyBmcFsyXTtcbiAgICAgIHJlMiA9IHJlX21ncjE7XG4gICAgICBpZiAocmUyLnRlc3Qoc3RlbSkpIHtcbiAgICAgICAgdyA9IHN0ZW07XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gU3RlcCA1XG4gICAgcmUgPSByZV81O1xuICAgIGlmIChyZS50ZXN0KHcpKSB7XG4gICAgICB2YXIgZnAgPSByZS5leGVjKHcpO1xuICAgICAgc3RlbSA9IGZwWzFdO1xuICAgICAgcmUgPSByZV9tZ3IxO1xuICAgICAgcmUyID0gcmVfbWVxMTtcbiAgICAgIHJlMyA9IHJlM181O1xuICAgICAgaWYgKHJlLnRlc3Qoc3RlbSkgfHwgKHJlMi50ZXN0KHN0ZW0pICYmICEocmUzLnRlc3Qoc3RlbSkpKSkge1xuICAgICAgICB3ID0gc3RlbTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZSA9IHJlXzVfMTtcbiAgICByZTIgPSByZV9tZ3IxO1xuICAgIGlmIChyZS50ZXN0KHcpICYmIHJlMi50ZXN0KHcpKSB7XG4gICAgICByZSA9IHJlXzFiXzI7XG4gICAgICB3ID0gdy5yZXBsYWNlKHJlLFwiXCIpO1xuICAgIH1cblxuICAgIC8vIGFuZCB0dXJuIGluaXRpYWwgWSBiYWNrIHRvIHlcblxuICAgIGlmIChmaXJzdGNoID09IFwieVwiKSB7XG4gICAgICB3ID0gZmlyc3RjaC50b0xvd2VyQ2FzZSgpICsgdy5zdWJzdHIoMSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHc7XG4gIH07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uICh0b2tlbikge1xuICAgIHJldHVybiB0b2tlbi51cGRhdGUocG9ydGVyU3RlbW1lcik7XG4gIH1cbn0pKCk7XG5cbmx1bnIuUGlwZWxpbmUucmVnaXN0ZXJGdW5jdGlvbihsdW5yLnN0ZW1tZXIsICdzdGVtbWVyJylcbi8qIVxuICogbHVuci5zdG9wV29yZEZpbHRlclxuICogQ29weXJpZ2h0IChDKSAyMDE4IE9saXZlciBOaWdodGluZ2FsZVxuICovXG5cbi8qKlxuICogbHVuci5nZW5lcmF0ZVN0b3BXb3JkRmlsdGVyIGJ1aWxkcyBhIHN0b3BXb3JkRmlsdGVyIGZ1bmN0aW9uIGZyb20gdGhlIHByb3ZpZGVkXG4gKiBsaXN0IG9mIHN0b3Agd29yZHMuXG4gKlxuICogVGhlIGJ1aWx0IGluIGx1bnIuc3RvcFdvcmRGaWx0ZXIgaXMgYnVpbHQgdXNpbmcgdGhpcyBnZW5lcmF0b3IgYW5kIGNhbiBiZSB1c2VkXG4gKiB0byBnZW5lcmF0ZSBjdXN0b20gc3RvcFdvcmRGaWx0ZXJzIGZvciBhcHBsaWNhdGlvbnMgb3Igbm9uIEVuZ2xpc2ggbGFuZ3VhZ2VzLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtBcnJheX0gdG9rZW4gVGhlIHRva2VuIHRvIHBhc3MgdGhyb3VnaCB0aGUgZmlsdGVyXG4gKiBAcmV0dXJucyB7bHVuci5QaXBlbGluZUZ1bmN0aW9ufVxuICogQHNlZSBsdW5yLlBpcGVsaW5lXG4gKiBAc2VlIGx1bnIuc3RvcFdvcmRGaWx0ZXJcbiAqL1xubHVuci5nZW5lcmF0ZVN0b3BXb3JkRmlsdGVyID0gZnVuY3Rpb24gKHN0b3BXb3Jkcykge1xuICB2YXIgd29yZHMgPSBzdG9wV29yZHMucmVkdWNlKGZ1bmN0aW9uIChtZW1vLCBzdG9wV29yZCkge1xuICAgIG1lbW9bc3RvcFdvcmRdID0gc3RvcFdvcmRcbiAgICByZXR1cm4gbWVtb1xuICB9LCB7fSlcblxuICByZXR1cm4gZnVuY3Rpb24gKHRva2VuKSB7XG4gICAgaWYgKHRva2VuICYmIHdvcmRzW3Rva2VuLnRvU3RyaW5nKCldICE9PSB0b2tlbi50b1N0cmluZygpKSByZXR1cm4gdG9rZW5cbiAgfVxufVxuXG4vKipcbiAqIGx1bnIuc3RvcFdvcmRGaWx0ZXIgaXMgYW4gRW5nbGlzaCBsYW5ndWFnZSBzdG9wIHdvcmQgbGlzdCBmaWx0ZXIsIGFueSB3b3Jkc1xuICogY29udGFpbmVkIGluIHRoZSBsaXN0IHdpbGwgbm90IGJlIHBhc3NlZCB0aHJvdWdoIHRoZSBmaWx0ZXIuXG4gKlxuICogVGhpcyBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIGluIHRoZSBQaXBlbGluZS4gSWYgdGhlIHRva2VuIGRvZXMgbm90IHBhc3MgdGhlXG4gKiBmaWx0ZXIgdGhlbiB1bmRlZmluZWQgd2lsbCBiZSByZXR1cm5lZC5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBpbXBsZW1lbnRzIHtsdW5yLlBpcGVsaW5lRnVuY3Rpb259XG4gKiBAcGFyYW1zIHtsdW5yLlRva2VufSB0b2tlbiAtIEEgdG9rZW4gdG8gY2hlY2sgZm9yIGJlaW5nIGEgc3RvcCB3b3JkLlxuICogQHJldHVybnMge2x1bnIuVG9rZW59XG4gKiBAc2VlIHtAbGluayBsdW5yLlBpcGVsaW5lfVxuICovXG5sdW5yLnN0b3BXb3JkRmlsdGVyID0gbHVuci5nZW5lcmF0ZVN0b3BXb3JkRmlsdGVyKFtcbiAgJ2EnLFxuICAnYWJsZScsXG4gICdhYm91dCcsXG4gICdhY3Jvc3MnLFxuICAnYWZ0ZXInLFxuICAnYWxsJyxcbiAgJ2FsbW9zdCcsXG4gICdhbHNvJyxcbiAgJ2FtJyxcbiAgJ2Ftb25nJyxcbiAgJ2FuJyxcbiAgJ2FuZCcsXG4gICdhbnknLFxuICAnYXJlJyxcbiAgJ2FzJyxcbiAgJ2F0JyxcbiAgJ2JlJyxcbiAgJ2JlY2F1c2UnLFxuICAnYmVlbicsXG4gICdidXQnLFxuICAnYnknLFxuICAnY2FuJyxcbiAgJ2Nhbm5vdCcsXG4gICdjb3VsZCcsXG4gICdkZWFyJyxcbiAgJ2RpZCcsXG4gICdkbycsXG4gICdkb2VzJyxcbiAgJ2VpdGhlcicsXG4gICdlbHNlJyxcbiAgJ2V2ZXInLFxuICAnZXZlcnknLFxuICAnZm9yJyxcbiAgJ2Zyb20nLFxuICAnZ2V0JyxcbiAgJ2dvdCcsXG4gICdoYWQnLFxuICAnaGFzJyxcbiAgJ2hhdmUnLFxuICAnaGUnLFxuICAnaGVyJyxcbiAgJ2hlcnMnLFxuICAnaGltJyxcbiAgJ2hpcycsXG4gICdob3cnLFxuICAnaG93ZXZlcicsXG4gICdpJyxcbiAgJ2lmJyxcbiAgJ2luJyxcbiAgJ2ludG8nLFxuICAnaXMnLFxuICAnaXQnLFxuICAnaXRzJyxcbiAgJ2p1c3QnLFxuICAnbGVhc3QnLFxuICAnbGV0JyxcbiAgJ2xpa2UnLFxuICAnbGlrZWx5JyxcbiAgJ21heScsXG4gICdtZScsXG4gICdtaWdodCcsXG4gICdtb3N0JyxcbiAgJ211c3QnLFxuICAnbXknLFxuICAnbmVpdGhlcicsXG4gICdubycsXG4gICdub3InLFxuICAnbm90JyxcbiAgJ29mJyxcbiAgJ29mZicsXG4gICdvZnRlbicsXG4gICdvbicsXG4gICdvbmx5JyxcbiAgJ29yJyxcbiAgJ290aGVyJyxcbiAgJ291cicsXG4gICdvd24nLFxuICAncmF0aGVyJyxcbiAgJ3NhaWQnLFxuICAnc2F5JyxcbiAgJ3NheXMnLFxuICAnc2hlJyxcbiAgJ3Nob3VsZCcsXG4gICdzaW5jZScsXG4gICdzbycsXG4gICdzb21lJyxcbiAgJ3RoYW4nLFxuICAndGhhdCcsXG4gICd0aGUnLFxuICAndGhlaXInLFxuICAndGhlbScsXG4gICd0aGVuJyxcbiAgJ3RoZXJlJyxcbiAgJ3RoZXNlJyxcbiAgJ3RoZXknLFxuICAndGhpcycsXG4gICd0aXMnLFxuICAndG8nLFxuICAndG9vJyxcbiAgJ3R3YXMnLFxuICAndXMnLFxuICAnd2FudHMnLFxuICAnd2FzJyxcbiAgJ3dlJyxcbiAgJ3dlcmUnLFxuICAnd2hhdCcsXG4gICd3aGVuJyxcbiAgJ3doZXJlJyxcbiAgJ3doaWNoJyxcbiAgJ3doaWxlJyxcbiAgJ3dobycsXG4gICd3aG9tJyxcbiAgJ3doeScsXG4gICd3aWxsJyxcbiAgJ3dpdGgnLFxuICAnd291bGQnLFxuICAneWV0JyxcbiAgJ3lvdScsXG4gICd5b3VyJ1xuXSlcblxubHVuci5QaXBlbGluZS5yZWdpc3RlckZ1bmN0aW9uKGx1bnIuc3RvcFdvcmRGaWx0ZXIsICdzdG9wV29yZEZpbHRlcicpXG4vKiFcbiAqIGx1bnIudHJpbW1lclxuICogQ29weXJpZ2h0IChDKSAyMDE4IE9saXZlciBOaWdodGluZ2FsZVxuICovXG5cbi8qKlxuICogbHVuci50cmltbWVyIGlzIGEgcGlwZWxpbmUgZnVuY3Rpb24gZm9yIHRyaW1taW5nIG5vbiB3b3JkXG4gKiBjaGFyYWN0ZXJzIGZyb20gdGhlIGJlZ2lubmluZyBhbmQgZW5kIG9mIHRva2VucyBiZWZvcmUgdGhleVxuICogZW50ZXIgdGhlIGluZGV4LlxuICpcbiAqIFRoaXMgaW1wbGVtZW50YXRpb24gbWF5IG5vdCB3b3JrIGNvcnJlY3RseSBmb3Igbm9uIGxhdGluXG4gKiBjaGFyYWN0ZXJzIGFuZCBzaG91bGQgZWl0aGVyIGJlIHJlbW92ZWQgb3IgYWRhcHRlZCBmb3IgdXNlXG4gKiB3aXRoIGxhbmd1YWdlcyB3aXRoIG5vbi1sYXRpbiBjaGFyYWN0ZXJzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBpbXBsZW1lbnRzIHtsdW5yLlBpcGVsaW5lRnVuY3Rpb259XG4gKiBAcGFyYW0ge2x1bnIuVG9rZW59IHRva2VuIFRoZSB0b2tlbiB0byBwYXNzIHRocm91Z2ggdGhlIGZpbHRlclxuICogQHJldHVybnMge2x1bnIuVG9rZW59XG4gKiBAc2VlIGx1bnIuUGlwZWxpbmVcbiAqL1xubHVuci50cmltbWVyID0gZnVuY3Rpb24gKHRva2VuKSB7XG4gIHJldHVybiB0b2tlbi51cGRhdGUoZnVuY3Rpb24gKHMpIHtcbiAgICByZXR1cm4gcy5yZXBsYWNlKC9eXFxXKy8sICcnKS5yZXBsYWNlKC9cXFcrJC8sICcnKVxuICB9KVxufVxuXG5sdW5yLlBpcGVsaW5lLnJlZ2lzdGVyRnVuY3Rpb24obHVuci50cmltbWVyLCAndHJpbW1lcicpXG4vKiFcbiAqIGx1bnIuVG9rZW5TZXRcbiAqIENvcHlyaWdodCAoQykgMjAxOCBPbGl2ZXIgTmlnaHRpbmdhbGVcbiAqL1xuXG4vKipcbiAqIEEgdG9rZW4gc2V0IGlzIHVzZWQgdG8gc3RvcmUgdGhlIHVuaXF1ZSBsaXN0IG9mIGFsbCB0b2tlbnNcbiAqIHdpdGhpbiBhbiBpbmRleC4gVG9rZW4gc2V0cyBhcmUgYWxzbyB1c2VkIHRvIHJlcHJlc2VudCBhblxuICogaW5jb21pbmcgcXVlcnkgdG8gdGhlIGluZGV4LCB0aGlzIHF1ZXJ5IHRva2VuIHNldCBhbmQgaW5kZXhcbiAqIHRva2VuIHNldCBhcmUgdGhlbiBpbnRlcnNlY3RlZCB0byBmaW5kIHdoaWNoIHRva2VucyB0byBsb29rXG4gKiB1cCBpbiB0aGUgaW52ZXJ0ZWQgaW5kZXguXG4gKlxuICogQSB0b2tlbiBzZXQgY2FuIGhvbGQgbXVsdGlwbGUgdG9rZW5zLCBhcyBpbiB0aGUgY2FzZSBvZiB0aGVcbiAqIGluZGV4IHRva2VuIHNldCwgb3IgaXQgY2FuIGhvbGQgYSBzaW5nbGUgdG9rZW4gYXMgaW4gdGhlXG4gKiBjYXNlIG9mIGEgc2ltcGxlIHF1ZXJ5IHRva2VuIHNldC5cbiAqXG4gKiBBZGRpdGlvbmFsbHkgdG9rZW4gc2V0cyBhcmUgdXNlZCB0byBwZXJmb3JtIHdpbGRjYXJkIG1hdGNoaW5nLlxuICogTGVhZGluZywgY29udGFpbmVkIGFuZCB0cmFpbGluZyB3aWxkY2FyZHMgYXJlIHN1cHBvcnRlZCwgYW5kXG4gKiBmcm9tIHRoaXMgZWRpdCBkaXN0YW5jZSBtYXRjaGluZyBjYW4gYWxzbyBiZSBwcm92aWRlZC5cbiAqXG4gKiBUb2tlbiBzZXRzIGFyZSBpbXBsZW1lbnRlZCBhcyBhIG1pbmltYWwgZmluaXRlIHN0YXRlIGF1dG9tYXRhLFxuICogd2hlcmUgYm90aCBjb21tb24gcHJlZml4ZXMgYW5kIHN1ZmZpeGVzIGFyZSBzaGFyZWQgYmV0d2VlbiB0b2tlbnMuXG4gKiBUaGlzIGhlbHBzIHRvIHJlZHVjZSB0aGUgc3BhY2UgdXNlZCBmb3Igc3RvcmluZyB0aGUgdG9rZW4gc2V0LlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5sdW5yLlRva2VuU2V0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLmZpbmFsID0gZmFsc2VcbiAgdGhpcy5lZGdlcyA9IHt9XG4gIHRoaXMuaWQgPSBsdW5yLlRva2VuU2V0Ll9uZXh0SWRcbiAgbHVuci5Ub2tlblNldC5fbmV4dElkICs9IDFcbn1cblxuLyoqXG4gKiBLZWVwcyB0cmFjayBvZiB0aGUgbmV4dCwgYXV0byBpbmNyZW1lbnQsIGlkZW50aWZpZXIgdG8gYXNzaWduXG4gKiB0byBhIG5ldyB0b2tlblNldC5cbiAqXG4gKiBUb2tlblNldHMgcmVxdWlyZSBhIHVuaXF1ZSBpZGVudGlmaWVyIHRvIGJlIGNvcnJlY3RseSBtaW5pbWlzZWQuXG4gKlxuICogQHByaXZhdGVcbiAqL1xubHVuci5Ub2tlblNldC5fbmV4dElkID0gMVxuXG4vKipcbiAqIENyZWF0ZXMgYSBUb2tlblNldCBpbnN0YW5jZSBmcm9tIHRoZSBnaXZlbiBzb3J0ZWQgYXJyYXkgb2Ygd29yZHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmdbXX0gYXJyIC0gQSBzb3J0ZWQgYXJyYXkgb2Ygc3RyaW5ncyB0byBjcmVhdGUgdGhlIHNldCBmcm9tLlxuICogQHJldHVybnMge2x1bnIuVG9rZW5TZXR9XG4gKiBAdGhyb3dzIFdpbGwgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGlucHV0IGFycmF5IGlzIG5vdCBzb3J0ZWQuXG4gKi9cbmx1bnIuVG9rZW5TZXQuZnJvbUFycmF5ID0gZnVuY3Rpb24gKGFycikge1xuICB2YXIgYnVpbGRlciA9IG5ldyBsdW5yLlRva2VuU2V0LkJ1aWxkZXJcblxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gYXJyLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgYnVpbGRlci5pbnNlcnQoYXJyW2ldKVxuICB9XG5cbiAgYnVpbGRlci5maW5pc2goKVxuICByZXR1cm4gYnVpbGRlci5yb290XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIHRva2VuIHNldCBmcm9tIGEgcXVlcnkgY2xhdXNlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gY2xhdXNlIC0gQSBzaW5nbGUgY2xhdXNlIGZyb20gbHVuci5RdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjbGF1c2UudGVybSAtIFRoZSBxdWVyeSBjbGF1c2UgdGVybS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbY2xhdXNlLmVkaXREaXN0YW5jZV0gLSBUaGUgb3B0aW9uYWwgZWRpdCBkaXN0YW5jZSBmb3IgdGhlIHRlcm0uXG4gKiBAcmV0dXJucyB7bHVuci5Ub2tlblNldH1cbiAqL1xubHVuci5Ub2tlblNldC5mcm9tQ2xhdXNlID0gZnVuY3Rpb24gKGNsYXVzZSkge1xuICBpZiAoJ2VkaXREaXN0YW5jZScgaW4gY2xhdXNlKSB7XG4gICAgcmV0dXJuIGx1bnIuVG9rZW5TZXQuZnJvbUZ1enp5U3RyaW5nKGNsYXVzZS50ZXJtLCBjbGF1c2UuZWRpdERpc3RhbmNlKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBsdW5yLlRva2VuU2V0LmZyb21TdHJpbmcoY2xhdXNlLnRlcm0pXG4gIH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgdG9rZW4gc2V0IHJlcHJlc2VudGluZyBhIHNpbmdsZSBzdHJpbmcgd2l0aCBhIHNwZWNpZmllZFxuICogZWRpdCBkaXN0YW5jZS5cbiAqXG4gKiBJbnNlcnRpb25zLCBkZWxldGlvbnMsIHN1YnN0aXR1dGlvbnMgYW5kIHRyYW5zcG9zaXRpb25zIGFyZSBlYWNoXG4gKiB0cmVhdGVkIGFzIGFuIGVkaXQgZGlzdGFuY2Ugb2YgMS5cbiAqXG4gKiBJbmNyZWFzaW5nIHRoZSBhbGxvd2VkIGVkaXQgZGlzdGFuY2Ugd2lsbCBoYXZlIGEgZHJhbWF0aWMgaW1wYWN0XG4gKiBvbiB0aGUgcGVyZm9ybWFuY2Ugb2YgYm90aCBjcmVhdGluZyBhbmQgaW50ZXJzZWN0aW5nIHRoZXNlIFRva2VuU2V0cy5cbiAqIEl0IGlzIGFkdmlzZWQgdG8ga2VlcCB0aGUgZWRpdCBkaXN0YW5jZSBsZXNzIHRoYW4gMy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIC0gVGhlIHN0cmluZyB0byBjcmVhdGUgdGhlIHRva2VuIHNldCBmcm9tLlxuICogQHBhcmFtIHtudW1iZXJ9IGVkaXREaXN0YW5jZSAtIFRoZSBhbGxvd2VkIGVkaXQgZGlzdGFuY2UgdG8gbWF0Y2guXG4gKiBAcmV0dXJucyB7bHVuci5WZWN0b3J9XG4gKi9cbmx1bnIuVG9rZW5TZXQuZnJvbUZ1enp5U3RyaW5nID0gZnVuY3Rpb24gKHN0ciwgZWRpdERpc3RhbmNlKSB7XG4gIHZhciByb290ID0gbmV3IGx1bnIuVG9rZW5TZXRcblxuICB2YXIgc3RhY2sgPSBbe1xuICAgIG5vZGU6IHJvb3QsXG4gICAgZWRpdHNSZW1haW5pbmc6IGVkaXREaXN0YW5jZSxcbiAgICBzdHI6IHN0clxuICB9XVxuXG4gIHdoaWxlIChzdGFjay5sZW5ndGgpIHtcbiAgICB2YXIgZnJhbWUgPSBzdGFjay5wb3AoKVxuXG4gICAgLy8gbm8gZWRpdFxuICAgIGlmIChmcmFtZS5zdHIubGVuZ3RoID4gMCkge1xuICAgICAgdmFyIGNoYXIgPSBmcmFtZS5zdHIuY2hhckF0KDApLFxuICAgICAgICAgIG5vRWRpdE5vZGVcblxuICAgICAgaWYgKGNoYXIgaW4gZnJhbWUubm9kZS5lZGdlcykge1xuICAgICAgICBub0VkaXROb2RlID0gZnJhbWUubm9kZS5lZGdlc1tjaGFyXVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbm9FZGl0Tm9kZSA9IG5ldyBsdW5yLlRva2VuU2V0XG4gICAgICAgIGZyYW1lLm5vZGUuZWRnZXNbY2hhcl0gPSBub0VkaXROb2RlXG4gICAgICB9XG5cbiAgICAgIGlmIChmcmFtZS5zdHIubGVuZ3RoID09IDEpIHtcbiAgICAgICAgbm9FZGl0Tm9kZS5maW5hbCA9IHRydWVcbiAgICAgIH1cblxuICAgICAgc3RhY2sucHVzaCh7XG4gICAgICAgIG5vZGU6IG5vRWRpdE5vZGUsXG4gICAgICAgIGVkaXRzUmVtYWluaW5nOiBmcmFtZS5lZGl0c1JlbWFpbmluZyxcbiAgICAgICAgc3RyOiBmcmFtZS5zdHIuc2xpY2UoMSlcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgLy8gZGVsZXRpb25cbiAgICAvLyBjYW4gb25seSBkbyBhIGRlbGV0aW9uIGlmIHdlIGhhdmUgZW5vdWdoIGVkaXRzIHJlbWFpbmluZ1xuICAgIC8vIGFuZCBpZiB0aGVyZSBhcmUgY2hhcmFjdGVycyBsZWZ0IHRvIGRlbGV0ZSBpbiB0aGUgc3RyaW5nXG4gICAgaWYgKGZyYW1lLmVkaXRzUmVtYWluaW5nID4gMCAmJiBmcmFtZS5zdHIubGVuZ3RoID4gMSkge1xuICAgICAgdmFyIGNoYXIgPSBmcmFtZS5zdHIuY2hhckF0KDEpLFxuICAgICAgICAgIGRlbGV0aW9uTm9kZVxuXG4gICAgICBpZiAoY2hhciBpbiBmcmFtZS5ub2RlLmVkZ2VzKSB7XG4gICAgICAgIGRlbGV0aW9uTm9kZSA9IGZyYW1lLm5vZGUuZWRnZXNbY2hhcl1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0aW9uTm9kZSA9IG5ldyBsdW5yLlRva2VuU2V0XG4gICAgICAgIGZyYW1lLm5vZGUuZWRnZXNbY2hhcl0gPSBkZWxldGlvbk5vZGVcbiAgICAgIH1cblxuICAgICAgaWYgKGZyYW1lLnN0ci5sZW5ndGggPD0gMikge1xuICAgICAgICBkZWxldGlvbk5vZGUuZmluYWwgPSB0cnVlXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGFjay5wdXNoKHtcbiAgICAgICAgICBub2RlOiBkZWxldGlvbk5vZGUsXG4gICAgICAgICAgZWRpdHNSZW1haW5pbmc6IGZyYW1lLmVkaXRzUmVtYWluaW5nIC0gMSxcbiAgICAgICAgICBzdHI6IGZyYW1lLnN0ci5zbGljZSgyKVxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGRlbGV0aW9uXG4gICAgLy8ganVzdCByZW1vdmluZyB0aGUgbGFzdCBjaGFyYWN0ZXIgZnJvbSB0aGUgc3RyXG4gICAgaWYgKGZyYW1lLmVkaXRzUmVtYWluaW5nID4gMCAmJiBmcmFtZS5zdHIubGVuZ3RoID09IDEpIHtcbiAgICAgIGZyYW1lLm5vZGUuZmluYWwgPSB0cnVlXG4gICAgfVxuXG4gICAgLy8gc3Vic3RpdHV0aW9uXG4gICAgLy8gY2FuIG9ubHkgZG8gYSBzdWJzdGl0dXRpb24gaWYgd2UgaGF2ZSBlbm91Z2ggZWRpdHMgcmVtYWluaW5nXG4gICAgLy8gYW5kIGlmIHRoZXJlIGFyZSBjaGFyYWN0ZXJzIGxlZnQgdG8gc3Vic3RpdHV0ZVxuICAgIGlmIChmcmFtZS5lZGl0c1JlbWFpbmluZyA+IDAgJiYgZnJhbWUuc3RyLmxlbmd0aCA+PSAxKSB7XG4gICAgICBpZiAoXCIqXCIgaW4gZnJhbWUubm9kZS5lZGdlcykge1xuICAgICAgICB2YXIgc3Vic3RpdHV0aW9uTm9kZSA9IGZyYW1lLm5vZGUuZWRnZXNbXCIqXCJdXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgc3Vic3RpdHV0aW9uTm9kZSA9IG5ldyBsdW5yLlRva2VuU2V0XG4gICAgICAgIGZyYW1lLm5vZGUuZWRnZXNbXCIqXCJdID0gc3Vic3RpdHV0aW9uTm9kZVxuICAgICAgfVxuXG4gICAgICBpZiAoZnJhbWUuc3RyLmxlbmd0aCA9PSAxKSB7XG4gICAgICAgIHN1YnN0aXR1dGlvbk5vZGUuZmluYWwgPSB0cnVlXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGFjay5wdXNoKHtcbiAgICAgICAgICBub2RlOiBzdWJzdGl0dXRpb25Ob2RlLFxuICAgICAgICAgIGVkaXRzUmVtYWluaW5nOiBmcmFtZS5lZGl0c1JlbWFpbmluZyAtIDEsXG4gICAgICAgICAgc3RyOiBmcmFtZS5zdHIuc2xpY2UoMSlcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBpbnNlcnRpb25cbiAgICAvLyBjYW4gb25seSBkbyBpbnNlcnRpb24gaWYgdGhlcmUgYXJlIGVkaXRzIHJlbWFpbmluZ1xuICAgIGlmIChmcmFtZS5lZGl0c1JlbWFpbmluZyA+IDApIHtcbiAgICAgIGlmIChcIipcIiBpbiBmcmFtZS5ub2RlLmVkZ2VzKSB7XG4gICAgICAgIHZhciBpbnNlcnRpb25Ob2RlID0gZnJhbWUubm9kZS5lZGdlc1tcIipcIl1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBpbnNlcnRpb25Ob2RlID0gbmV3IGx1bnIuVG9rZW5TZXRcbiAgICAgICAgZnJhbWUubm9kZS5lZGdlc1tcIipcIl0gPSBpbnNlcnRpb25Ob2RlXG4gICAgICB9XG5cbiAgICAgIGlmIChmcmFtZS5zdHIubGVuZ3RoID09IDApIHtcbiAgICAgICAgaW5zZXJ0aW9uTm9kZS5maW5hbCA9IHRydWVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YWNrLnB1c2goe1xuICAgICAgICAgIG5vZGU6IGluc2VydGlvbk5vZGUsXG4gICAgICAgICAgZWRpdHNSZW1haW5pbmc6IGZyYW1lLmVkaXRzUmVtYWluaW5nIC0gMSxcbiAgICAgICAgICBzdHI6IGZyYW1lLnN0clxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHRyYW5zcG9zaXRpb25cbiAgICAvLyBjYW4gb25seSBkbyBhIHRyYW5zcG9zaXRpb24gaWYgdGhlcmUgYXJlIGVkaXRzIHJlbWFpbmluZ1xuICAgIC8vIGFuZCB0aGVyZSBhcmUgZW5vdWdoIGNoYXJhY3RlcnMgdG8gdHJhbnNwb3NlXG4gICAgaWYgKGZyYW1lLmVkaXRzUmVtYWluaW5nID4gMCAmJiBmcmFtZS5zdHIubGVuZ3RoID4gMSkge1xuICAgICAgdmFyIGNoYXJBID0gZnJhbWUuc3RyLmNoYXJBdCgwKSxcbiAgICAgICAgICBjaGFyQiA9IGZyYW1lLnN0ci5jaGFyQXQoMSksXG4gICAgICAgICAgdHJhbnNwb3NlTm9kZVxuXG4gICAgICBpZiAoY2hhckIgaW4gZnJhbWUubm9kZS5lZGdlcykge1xuICAgICAgICB0cmFuc3Bvc2VOb2RlID0gZnJhbWUubm9kZS5lZGdlc1tjaGFyQl1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyYW5zcG9zZU5vZGUgPSBuZXcgbHVuci5Ub2tlblNldFxuICAgICAgICBmcmFtZS5ub2RlLmVkZ2VzW2NoYXJCXSA9IHRyYW5zcG9zZU5vZGVcbiAgICAgIH1cblxuICAgICAgaWYgKGZyYW1lLnN0ci5sZW5ndGggPT0gMSkge1xuICAgICAgICB0cmFuc3Bvc2VOb2RlLmZpbmFsID0gdHJ1ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhY2sucHVzaCh7XG4gICAgICAgICAgbm9kZTogdHJhbnNwb3NlTm9kZSxcbiAgICAgICAgICBlZGl0c1JlbWFpbmluZzogZnJhbWUuZWRpdHNSZW1haW5pbmcgLSAxLFxuICAgICAgICAgIHN0cjogY2hhckEgKyBmcmFtZS5zdHIuc2xpY2UoMilcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcm9vdFxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBUb2tlblNldCBmcm9tIGEgc3RyaW5nLlxuICpcbiAqIFRoZSBzdHJpbmcgbWF5IGNvbnRhaW4gb25lIG9yIG1vcmUgd2lsZGNhcmQgY2hhcmFjdGVycyAoKilcbiAqIHRoYXQgd2lsbCBhbGxvdyB3aWxkY2FyZCBtYXRjaGluZyB3aGVuIGludGVyc2VjdGluZyB3aXRoXG4gKiBhbm90aGVyIFRva2VuU2V0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBUaGUgc3RyaW5nIHRvIGNyZWF0ZSBhIFRva2VuU2V0IGZyb20uXG4gKiBAcmV0dXJucyB7bHVuci5Ub2tlblNldH1cbiAqL1xubHVuci5Ub2tlblNldC5mcm9tU3RyaW5nID0gZnVuY3Rpb24gKHN0cikge1xuICB2YXIgbm9kZSA9IG5ldyBsdW5yLlRva2VuU2V0LFxuICAgICAgcm9vdCA9IG5vZGVcblxuICAvKlxuICAgKiBJdGVyYXRlcyB0aHJvdWdoIGFsbCBjaGFyYWN0ZXJzIHdpdGhpbiB0aGUgcGFzc2VkIHN0cmluZ1xuICAgKiBhcHBlbmRpbmcgYSBub2RlIGZvciBlYWNoIGNoYXJhY3Rlci5cbiAgICpcbiAgICogV2hlbiBhIHdpbGRjYXJkIGNoYXJhY3RlciBpcyBmb3VuZCB0aGVuIGEgc2VsZlxuICAgKiByZWZlcmVuY2luZyBlZGdlIGlzIGludHJvZHVjZWQgdG8gY29udGludWFsbHkgbWF0Y2hcbiAgICogYW55IG51bWJlciBvZiBhbnkgY2hhcmFjdGVycy5cbiAgICovXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBzdHIubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICB2YXIgY2hhciA9IHN0cltpXSxcbiAgICAgICAgZmluYWwgPSAoaSA9PSBsZW4gLSAxKVxuXG4gICAgaWYgKGNoYXIgPT0gXCIqXCIpIHtcbiAgICAgIG5vZGUuZWRnZXNbY2hhcl0gPSBub2RlXG4gICAgICBub2RlLmZpbmFsID0gZmluYWxcblxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgbmV4dCA9IG5ldyBsdW5yLlRva2VuU2V0XG4gICAgICBuZXh0LmZpbmFsID0gZmluYWxcblxuICAgICAgbm9kZS5lZGdlc1tjaGFyXSA9IG5leHRcbiAgICAgIG5vZGUgPSBuZXh0XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJvb3Rcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIFRva2VuU2V0IGludG8gYW4gYXJyYXkgb2Ygc3RyaW5nc1xuICogY29udGFpbmVkIHdpdGhpbiB0aGUgVG9rZW5TZXQuXG4gKlxuICogQHJldHVybnMge3N0cmluZ1tdfVxuICovXG5sdW5yLlRva2VuU2V0LnByb3RvdHlwZS50b0FycmF5ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgd29yZHMgPSBbXVxuXG4gIHZhciBzdGFjayA9IFt7XG4gICAgcHJlZml4OiBcIlwiLFxuICAgIG5vZGU6IHRoaXNcbiAgfV1cblxuICB3aGlsZSAoc3RhY2subGVuZ3RoKSB7XG4gICAgdmFyIGZyYW1lID0gc3RhY2sucG9wKCksXG4gICAgICAgIGVkZ2VzID0gT2JqZWN0LmtleXMoZnJhbWUubm9kZS5lZGdlcyksXG4gICAgICAgIGxlbiA9IGVkZ2VzLmxlbmd0aFxuXG4gICAgaWYgKGZyYW1lLm5vZGUuZmluYWwpIHtcbiAgICAgIC8qIEluIFNhZmFyaSwgYXQgdGhpcyBwb2ludCB0aGUgcHJlZml4IGlzIHNvbWV0aW1lcyBjb3JydXB0ZWQsIHNlZTpcbiAgICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9vbGl2ZXJubi9sdW5yLmpzL2lzc3Vlcy8yNzkgQ2FsbGluZyBhbnlcbiAgICAgICAqIFN0cmluZy5wcm90b3R5cGUgbWV0aG9kIGZvcmNlcyBTYWZhcmkgdG8gXCJjYXN0XCIgdGhpcyBzdHJpbmcgdG8gd2hhdFxuICAgICAgICogaXQncyBzdXBwb3NlZCB0byBiZSwgZml4aW5nIHRoZSBidWcuICovXG4gICAgICBmcmFtZS5wcmVmaXguY2hhckF0KDApXG4gICAgICB3b3Jkcy5wdXNoKGZyYW1lLnByZWZpeClcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICB2YXIgZWRnZSA9IGVkZ2VzW2ldXG5cbiAgICAgIHN0YWNrLnB1c2goe1xuICAgICAgICBwcmVmaXg6IGZyYW1lLnByZWZpeC5jb25jYXQoZWRnZSksXG4gICAgICAgIG5vZGU6IGZyYW1lLm5vZGUuZWRnZXNbZWRnZV1cbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHdvcmRzXG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgVG9rZW5TZXQuXG4gKlxuICogVGhpcyBpcyBpbnRlbmRlZCB0byBhbGxvdyBUb2tlblNldHMgdG8gYmUgdXNlZCBhcyBrZXlzXG4gKiBpbiBvYmplY3RzLCBsYXJnZWx5IHRvIGFpZCB0aGUgY29uc3RydWN0aW9uIGFuZCBtaW5pbWlzYXRpb25cbiAqIG9mIGEgVG9rZW5TZXQuIEFzIHN1Y2ggaXQgaXMgbm90IGRlc2lnbmVkIHRvIGJlIGEgaHVtYW5cbiAqIGZyaWVuZGx5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBUb2tlblNldC5cbiAqXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICovXG5sdW5yLlRva2VuU2V0LnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcbiAgLy8gTk9URTogVXNpbmcgT2JqZWN0LmtleXMgaGVyZSBhcyB0aGlzLmVkZ2VzIGlzIHZlcnkgbGlrZWx5XG4gIC8vIHRvIGVudGVyICdoYXNoLW1vZGUnIHdpdGggbWFueSBrZXlzIGJlaW5nIGFkZGVkXG4gIC8vXG4gIC8vIGF2b2lkaW5nIGEgZm9yLWluIGxvb3AgaGVyZSBhcyBpdCBsZWFkcyB0byB0aGUgZnVuY3Rpb25cbiAgLy8gYmVpbmcgZGUtb3B0aW1pc2VkIChhdCBsZWFzdCBpbiBWOCkuIEZyb20gc29tZSBzaW1wbGVcbiAgLy8gYmVuY2htYXJrcyB0aGUgcGVyZm9ybWFuY2UgaXMgY29tcGFyYWJsZSwgYnV0IGFsbG93aW5nXG4gIC8vIFY4IHRvIG9wdGltaXplIG1heSBtZWFuIGVhc3kgcGVyZm9ybWFuY2Ugd2lucyBpbiB0aGUgZnV0dXJlLlxuXG4gIGlmICh0aGlzLl9zdHIpIHtcbiAgICByZXR1cm4gdGhpcy5fc3RyXG4gIH1cblxuICB2YXIgc3RyID0gdGhpcy5maW5hbCA/ICcxJyA6ICcwJyxcbiAgICAgIGxhYmVscyA9IE9iamVjdC5rZXlzKHRoaXMuZWRnZXMpLnNvcnQoKSxcbiAgICAgIGxlbiA9IGxhYmVscy5sZW5ndGhcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgdmFyIGxhYmVsID0gbGFiZWxzW2ldLFxuICAgICAgICBub2RlID0gdGhpcy5lZGdlc1tsYWJlbF1cblxuICAgIHN0ciA9IHN0ciArIGxhYmVsICsgbm9kZS5pZFxuICB9XG5cbiAgcmV0dXJuIHN0clxufVxuXG4vKipcbiAqIFJldHVybnMgYSBuZXcgVG9rZW5TZXQgdGhhdCBpcyB0aGUgaW50ZXJzZWN0aW9uIG9mXG4gKiB0aGlzIFRva2VuU2V0IGFuZCB0aGUgcGFzc2VkIFRva2VuU2V0LlxuICpcbiAqIFRoaXMgaW50ZXJzZWN0aW9uIHdpbGwgdGFrZSBpbnRvIGFjY291bnQgYW55IHdpbGRjYXJkc1xuICogY29udGFpbmVkIHdpdGhpbiB0aGUgVG9rZW5TZXQuXG4gKlxuICogQHBhcmFtIHtsdW5yLlRva2VuU2V0fSBiIC0gQW4gb3RoZXIgVG9rZW5TZXQgdG8gaW50ZXJzZWN0IHdpdGguXG4gKiBAcmV0dXJucyB7bHVuci5Ub2tlblNldH1cbiAqL1xubHVuci5Ub2tlblNldC5wcm90b3R5cGUuaW50ZXJzZWN0ID0gZnVuY3Rpb24gKGIpIHtcbiAgdmFyIG91dHB1dCA9IG5ldyBsdW5yLlRva2VuU2V0LFxuICAgICAgZnJhbWUgPSB1bmRlZmluZWRcblxuICB2YXIgc3RhY2sgPSBbe1xuICAgIHFOb2RlOiBiLFxuICAgIG91dHB1dDogb3V0cHV0LFxuICAgIG5vZGU6IHRoaXNcbiAgfV1cblxuICB3aGlsZSAoc3RhY2subGVuZ3RoKSB7XG4gICAgZnJhbWUgPSBzdGFjay5wb3AoKVxuXG4gICAgLy8gTk9URTogQXMgd2l0aCB0aGUgI3RvU3RyaW5nIG1ldGhvZCwgd2UgYXJlIHVzaW5nXG4gICAgLy8gT2JqZWN0LmtleXMgYW5kIGEgZm9yIGxvb3AgaW5zdGVhZCBvZiBhIGZvci1pbiBsb29wXG4gICAgLy8gYXMgYm90aCBvZiB0aGVzZSBvYmplY3RzIGVudGVyICdoYXNoJyBtb2RlLCBjYXVzaW5nXG4gICAgLy8gdGhlIGZ1bmN0aW9uIHRvIGJlIGRlLW9wdGltaXNlZCBpbiBWOFxuICAgIHZhciBxRWRnZXMgPSBPYmplY3Qua2V5cyhmcmFtZS5xTm9kZS5lZGdlcyksXG4gICAgICAgIHFMZW4gPSBxRWRnZXMubGVuZ3RoLFxuICAgICAgICBuRWRnZXMgPSBPYmplY3Qua2V5cyhmcmFtZS5ub2RlLmVkZ2VzKSxcbiAgICAgICAgbkxlbiA9IG5FZGdlcy5sZW5ndGhcblxuICAgIGZvciAodmFyIHEgPSAwOyBxIDwgcUxlbjsgcSsrKSB7XG4gICAgICB2YXIgcUVkZ2UgPSBxRWRnZXNbcV1cblxuICAgICAgZm9yICh2YXIgbiA9IDA7IG4gPCBuTGVuOyBuKyspIHtcbiAgICAgICAgdmFyIG5FZGdlID0gbkVkZ2VzW25dXG5cbiAgICAgICAgaWYgKG5FZGdlID09IHFFZGdlIHx8IHFFZGdlID09ICcqJykge1xuICAgICAgICAgIHZhciBub2RlID0gZnJhbWUubm9kZS5lZGdlc1tuRWRnZV0sXG4gICAgICAgICAgICAgIHFOb2RlID0gZnJhbWUucU5vZGUuZWRnZXNbcUVkZ2VdLFxuICAgICAgICAgICAgICBmaW5hbCA9IG5vZGUuZmluYWwgJiYgcU5vZGUuZmluYWwsXG4gICAgICAgICAgICAgIG5leHQgPSB1bmRlZmluZWRcblxuICAgICAgICAgIGlmIChuRWRnZSBpbiBmcmFtZS5vdXRwdXQuZWRnZXMpIHtcbiAgICAgICAgICAgIC8vIGFuIGVkZ2UgYWxyZWFkeSBleGlzdHMgZm9yIHRoaXMgY2hhcmFjdGVyXG4gICAgICAgICAgICAvLyBubyBuZWVkIHRvIGNyZWF0ZSBhIG5ldyBub2RlLCBqdXN0IHNldCB0aGUgZmluYWxpdHlcbiAgICAgICAgICAgIC8vIGJpdCB1bmxlc3MgdGhpcyBub2RlIGlzIGFscmVhZHkgZmluYWxcbiAgICAgICAgICAgIG5leHQgPSBmcmFtZS5vdXRwdXQuZWRnZXNbbkVkZ2VdXG4gICAgICAgICAgICBuZXh0LmZpbmFsID0gbmV4dC5maW5hbCB8fCBmaW5hbFxuXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIG5vIGVkZ2UgZXhpc3RzIHlldCwgbXVzdCBjcmVhdGUgb25lXG4gICAgICAgICAgICAvLyBzZXQgdGhlIGZpbmFsaXR5IGJpdCBhbmQgaW5zZXJ0IGl0XG4gICAgICAgICAgICAvLyBpbnRvIHRoZSBvdXRwdXRcbiAgICAgICAgICAgIG5leHQgPSBuZXcgbHVuci5Ub2tlblNldFxuICAgICAgICAgICAgbmV4dC5maW5hbCA9IGZpbmFsXG4gICAgICAgICAgICBmcmFtZS5vdXRwdXQuZWRnZXNbbkVkZ2VdID0gbmV4dFxuICAgICAgICAgIH1cblxuICAgICAgICAgIHN0YWNrLnB1c2goe1xuICAgICAgICAgICAgcU5vZGU6IHFOb2RlLFxuICAgICAgICAgICAgb3V0cHV0OiBuZXh0LFxuICAgICAgICAgICAgbm9kZTogbm9kZVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3V0cHV0XG59XG5sdW5yLlRva2VuU2V0LkJ1aWxkZXIgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMucHJldmlvdXNXb3JkID0gXCJcIlxuICB0aGlzLnJvb3QgPSBuZXcgbHVuci5Ub2tlblNldFxuICB0aGlzLnVuY2hlY2tlZE5vZGVzID0gW11cbiAgdGhpcy5taW5pbWl6ZWROb2RlcyA9IHt9XG59XG5cbmx1bnIuVG9rZW5TZXQuQnVpbGRlci5wcm90b3R5cGUuaW5zZXJ0ID0gZnVuY3Rpb24gKHdvcmQpIHtcbiAgdmFyIG5vZGUsXG4gICAgICBjb21tb25QcmVmaXggPSAwXG5cbiAgaWYgKHdvcmQgPCB0aGlzLnByZXZpb3VzV29yZCkge1xuICAgIHRocm93IG5ldyBFcnJvciAoXCJPdXQgb2Ygb3JkZXIgd29yZCBpbnNlcnRpb25cIilcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgd29yZC5sZW5ndGggJiYgaSA8IHRoaXMucHJldmlvdXNXb3JkLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHdvcmRbaV0gIT0gdGhpcy5wcmV2aW91c1dvcmRbaV0pIGJyZWFrXG4gICAgY29tbW9uUHJlZml4KytcbiAgfVxuXG4gIHRoaXMubWluaW1pemUoY29tbW9uUHJlZml4KVxuXG4gIGlmICh0aGlzLnVuY2hlY2tlZE5vZGVzLmxlbmd0aCA9PSAwKSB7XG4gICAgbm9kZSA9IHRoaXMucm9vdFxuICB9IGVsc2Uge1xuICAgIG5vZGUgPSB0aGlzLnVuY2hlY2tlZE5vZGVzW3RoaXMudW5jaGVja2VkTm9kZXMubGVuZ3RoIC0gMV0uY2hpbGRcbiAgfVxuXG4gIGZvciAodmFyIGkgPSBjb21tb25QcmVmaXg7IGkgPCB3b3JkLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIG5leHROb2RlID0gbmV3IGx1bnIuVG9rZW5TZXQsXG4gICAgICAgIGNoYXIgPSB3b3JkW2ldXG5cbiAgICBub2RlLmVkZ2VzW2NoYXJdID0gbmV4dE5vZGVcblxuICAgIHRoaXMudW5jaGVja2VkTm9kZXMucHVzaCh7XG4gICAgICBwYXJlbnQ6IG5vZGUsXG4gICAgICBjaGFyOiBjaGFyLFxuICAgICAgY2hpbGQ6IG5leHROb2RlXG4gICAgfSlcblxuICAgIG5vZGUgPSBuZXh0Tm9kZVxuICB9XG5cbiAgbm9kZS5maW5hbCA9IHRydWVcbiAgdGhpcy5wcmV2aW91c1dvcmQgPSB3b3JkXG59XG5cbmx1bnIuVG9rZW5TZXQuQnVpbGRlci5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLm1pbmltaXplKDApXG59XG5cbmx1bnIuVG9rZW5TZXQuQnVpbGRlci5wcm90b3R5cGUubWluaW1pemUgPSBmdW5jdGlvbiAoZG93blRvKSB7XG4gIGZvciAodmFyIGkgPSB0aGlzLnVuY2hlY2tlZE5vZGVzLmxlbmd0aCAtIDE7IGkgPj0gZG93blRvOyBpLS0pIHtcbiAgICB2YXIgbm9kZSA9IHRoaXMudW5jaGVja2VkTm9kZXNbaV0sXG4gICAgICAgIGNoaWxkS2V5ID0gbm9kZS5jaGlsZC50b1N0cmluZygpXG5cbiAgICBpZiAoY2hpbGRLZXkgaW4gdGhpcy5taW5pbWl6ZWROb2Rlcykge1xuICAgICAgbm9kZS5wYXJlbnQuZWRnZXNbbm9kZS5jaGFyXSA9IHRoaXMubWluaW1pemVkTm9kZXNbY2hpbGRLZXldXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENhY2hlIHRoZSBrZXkgZm9yIHRoaXMgbm9kZSBzaW5jZVxuICAgICAgLy8gd2Uga25vdyBpdCBjYW4ndCBjaGFuZ2UgYW55bW9yZVxuICAgICAgbm9kZS5jaGlsZC5fc3RyID0gY2hpbGRLZXlcblxuICAgICAgdGhpcy5taW5pbWl6ZWROb2Rlc1tjaGlsZEtleV0gPSBub2RlLmNoaWxkXG4gICAgfVxuXG4gICAgdGhpcy51bmNoZWNrZWROb2Rlcy5wb3AoKVxuICB9XG59XG4vKiFcbiAqIGx1bnIuSW5kZXhcbiAqIENvcHlyaWdodCAoQykgMjAxOCBPbGl2ZXIgTmlnaHRpbmdhbGVcbiAqL1xuXG4vKipcbiAqIEFuIGluZGV4IGNvbnRhaW5zIHRoZSBidWlsdCBpbmRleCBvZiBhbGwgZG9jdW1lbnRzIGFuZCBwcm92aWRlcyBhIHF1ZXJ5IGludGVyZmFjZVxuICogdG8gdGhlIGluZGV4LlxuICpcbiAqIFVzdWFsbHkgaW5zdGFuY2VzIG9mIGx1bnIuSW5kZXggd2lsbCBub3QgYmUgY3JlYXRlZCB1c2luZyB0aGlzIGNvbnN0cnVjdG9yLCBpbnN0ZWFkXG4gKiBsdW5yLkJ1aWxkZXIgc2hvdWxkIGJlIHVzZWQgdG8gY29uc3RydWN0IG5ldyBpbmRleGVzLCBvciBsdW5yLkluZGV4LmxvYWQgc2hvdWxkIGJlXG4gKiB1c2VkIHRvIGxvYWQgcHJldmlvdXNseSBidWlsdCBhbmQgc2VyaWFsaXplZCBpbmRleGVzLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtPYmplY3R9IGF0dHJzIC0gVGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGJ1aWx0IHNlYXJjaCBpbmRleC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBhdHRycy5pbnZlcnRlZEluZGV4IC0gQW4gaW5kZXggb2YgdGVybS9maWVsZCB0byBkb2N1bWVudCByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge09iamVjdDxzdHJpbmcsIGx1bnIuVmVjdG9yPn0gYXR0cnMuZmllbGRWZWN0b3JzIC0gRmllbGQgdmVjdG9yc1xuICogQHBhcmFtIHtsdW5yLlRva2VuU2V0fSBhdHRycy50b2tlblNldCAtIEFuIHNldCBvZiBhbGwgY29ycHVzIHRva2Vucy5cbiAqIEBwYXJhbSB7c3RyaW5nW119IGF0dHJzLmZpZWxkcyAtIFRoZSBuYW1lcyBvZiBpbmRleGVkIGRvY3VtZW50IGZpZWxkcy5cbiAqIEBwYXJhbSB7bHVuci5QaXBlbGluZX0gYXR0cnMucGlwZWxpbmUgLSBUaGUgcGlwZWxpbmUgdG8gdXNlIGZvciBzZWFyY2ggdGVybXMuXG4gKi9cbmx1bnIuSW5kZXggPSBmdW5jdGlvbiAoYXR0cnMpIHtcbiAgdGhpcy5pbnZlcnRlZEluZGV4ID0gYXR0cnMuaW52ZXJ0ZWRJbmRleFxuICB0aGlzLmZpZWxkVmVjdG9ycyA9IGF0dHJzLmZpZWxkVmVjdG9yc1xuICB0aGlzLnRva2VuU2V0ID0gYXR0cnMudG9rZW5TZXRcbiAgdGhpcy5maWVsZHMgPSBhdHRycy5maWVsZHNcbiAgdGhpcy5waXBlbGluZSA9IGF0dHJzLnBpcGVsaW5lXG59XG5cbi8qKlxuICogQSByZXN1bHQgY29udGFpbnMgZGV0YWlscyBvZiBhIGRvY3VtZW50IG1hdGNoaW5nIGEgc2VhcmNoIHF1ZXJ5LlxuICogQHR5cGVkZWYge09iamVjdH0gbHVuci5JbmRleH5SZXN1bHRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByZWYgLSBUaGUgcmVmZXJlbmNlIG9mIHRoZSBkb2N1bWVudCB0aGlzIHJlc3VsdCByZXByZXNlbnRzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IHNjb3JlIC0gQSBudW1iZXIgYmV0d2VlbiAwIGFuZCAxIHJlcHJlc2VudGluZyBob3cgc2ltaWxhciB0aGlzIGRvY3VtZW50IGlzIHRvIHRoZSBxdWVyeS5cbiAqIEBwcm9wZXJ0eSB7bHVuci5NYXRjaERhdGF9IG1hdGNoRGF0YSAtIENvbnRhaW5zIG1ldGFkYXRhIGFib3V0IHRoaXMgbWF0Y2ggaW5jbHVkaW5nIHdoaWNoIHRlcm0ocykgY2F1c2VkIHRoZSBtYXRjaC5cbiAqL1xuXG4vKipcbiAqIEFsdGhvdWdoIGx1bnIgcHJvdmlkZXMgdGhlIGFiaWxpdHkgdG8gY3JlYXRlIHF1ZXJpZXMgdXNpbmcgbHVuci5RdWVyeSwgaXQgYWxzbyBwcm92aWRlcyBhIHNpbXBsZVxuICogcXVlcnkgbGFuZ3VhZ2Ugd2hpY2ggaXRzZWxmIGlzIHBhcnNlZCBpbnRvIGFuIGluc3RhbmNlIG9mIGx1bnIuUXVlcnkuXG4gKlxuICogRm9yIHByb2dyYW1tYXRpY2FsbHkgYnVpbGRpbmcgcXVlcmllcyBpdCBpcyBhZHZpc2VkIHRvIGRpcmVjdGx5IHVzZSBsdW5yLlF1ZXJ5LCB0aGUgcXVlcnkgbGFuZ3VhZ2VcbiAqIGlzIGJlc3QgdXNlZCBmb3IgaHVtYW4gZW50ZXJlZCB0ZXh0IHJhdGhlciB0aGFuIHByb2dyYW0gZ2VuZXJhdGVkIHRleHQuXG4gKlxuICogQXQgaXRzIHNpbXBsZXN0IHF1ZXJpZXMgY2FuIGp1c3QgYmUgYSBzaW5nbGUgdGVybSwgZS5nLiBgaGVsbG9gLCBtdWx0aXBsZSB0ZXJtcyBhcmUgYWxzbyBzdXBwb3J0ZWRcbiAqIGFuZCB3aWxsIGJlIGNvbWJpbmVkIHdpdGggT1IsIGUuZyBgaGVsbG8gd29ybGRgIHdpbGwgbWF0Y2ggZG9jdW1lbnRzIHRoYXQgY29udGFpbiBlaXRoZXIgJ2hlbGxvJ1xuICogb3IgJ3dvcmxkJywgdGhvdWdoIHRob3NlIHRoYXQgY29udGFpbiBib3RoIHdpbGwgcmFuayBoaWdoZXIgaW4gdGhlIHJlc3VsdHMuXG4gKlxuICogV2lsZGNhcmRzIGNhbiBiZSBpbmNsdWRlZCBpbiB0ZXJtcyB0byBtYXRjaCBvbmUgb3IgbW9yZSB1bnNwZWNpZmllZCBjaGFyYWN0ZXJzLCB0aGVzZSB3aWxkY2FyZHMgY2FuXG4gKiBiZSBpbnNlcnRlZCBhbnl3aGVyZSB3aXRoaW4gdGhlIHRlcm0sIGFuZCBtb3JlIHRoYW4gb25lIHdpbGRjYXJkIGNhbiBleGlzdCBpbiBhIHNpbmdsZSB0ZXJtLiBBZGRpbmdcbiAqIHdpbGRjYXJkcyB3aWxsIGluY3JlYXNlIHRoZSBudW1iZXIgb2YgZG9jdW1lbnRzIHRoYXQgd2lsbCBiZSBmb3VuZCBidXQgY2FuIGFsc28gaGF2ZSBhIG5lZ2F0aXZlXG4gKiBpbXBhY3Qgb24gcXVlcnkgcGVyZm9ybWFuY2UsIGVzcGVjaWFsbHkgd2l0aCB3aWxkY2FyZHMgYXQgdGhlIGJlZ2lubmluZyBvZiBhIHRlcm0uXG4gKlxuICogVGVybXMgY2FuIGJlIHJlc3RyaWN0ZWQgdG8gc3BlY2lmaWMgZmllbGRzLCBlLmcuIGB0aXRsZTpoZWxsb2AsIG9ubHkgZG9jdW1lbnRzIHdpdGggdGhlIHRlcm1cbiAqIGhlbGxvIGluIHRoZSB0aXRsZSBmaWVsZCB3aWxsIG1hdGNoIHRoaXMgcXVlcnkuIFVzaW5nIGEgZmllbGQgbm90IHByZXNlbnQgaW4gdGhlIGluZGV4IHdpbGwgbGVhZFxuICogdG8gYW4gZXJyb3IgYmVpbmcgdGhyb3duLlxuICpcbiAqIE1vZGlmaWVycyBjYW4gYWxzbyBiZSBhZGRlZCB0byB0ZXJtcywgbHVuciBzdXBwb3J0cyBlZGl0IGRpc3RhbmNlIGFuZCBib29zdCBtb2RpZmllcnMgb24gdGVybXMuIEEgdGVybVxuICogYm9vc3Qgd2lsbCBtYWtlIGRvY3VtZW50cyBtYXRjaGluZyB0aGF0IHRlcm0gc2NvcmUgaGlnaGVyLCBlLmcuIGBmb29eNWAuIEVkaXQgZGlzdGFuY2UgaXMgYWxzbyBzdXBwb3J0ZWRcbiAqIHRvIHByb3ZpZGUgZnV6enkgbWF0Y2hpbmcsIGUuZy4gJ2hlbGxvfjInIHdpbGwgbWF0Y2ggZG9jdW1lbnRzIHdpdGggaGVsbG8gd2l0aCBhbiBlZGl0IGRpc3RhbmNlIG9mIDIuXG4gKiBBdm9pZCBsYXJnZSB2YWx1ZXMgZm9yIGVkaXQgZGlzdGFuY2UgdG8gaW1wcm92ZSBxdWVyeSBwZXJmb3JtYW5jZS5cbiAqXG4gKiBFYWNoIHRlcm0gYWxzbyBzdXBwb3J0cyBhIHByZXNlbmNlIG1vZGlmaWVyLiBCeSBkZWZhdWx0IGEgdGVybSdzIHByZXNlbmNlIGluIGRvY3VtZW50IGlzIG9wdGlvbmFsLCBob3dldmVyXG4gKiB0aGlzIGNhbiBiZSBjaGFuZ2VkIHRvIGVpdGhlciByZXF1aXJlZCBvciBwcm9oaWJpdGVkLiBGb3IgYSB0ZXJtJ3MgcHJlc2VuY2UgdG8gYmUgcmVxdWlyZWQgaW4gYSBkb2N1bWVudCB0aGVcbiAqIHRlcm0gc2hvdWxkIGJlIHByZWZpeGVkIHdpdGggYSAnKycsIGUuZy4gYCtmb28gYmFyYCBpcyBhIHNlYXJjaCBmb3IgZG9jdW1lbnRzIHRoYXQgbXVzdCBjb250YWluICdmb28nIGFuZFxuICogb3B0aW9uYWxseSBjb250YWluICdiYXInLiBDb252ZXJzZWx5IGEgbGVhZGluZyAnLScgc2V0cyB0aGUgdGVybXMgcHJlc2VuY2UgdG8gcHJvaGliaXRlZCwgaS5lLiBpdCBtdXN0IG5vdFxuICogYXBwZWFyIGluIGEgZG9jdW1lbnQsIGUuZy4gYC1mb28gYmFyYCBpcyBhIHNlYXJjaCBmb3IgZG9jdW1lbnRzIHRoYXQgZG8gbm90IGNvbnRhaW4gJ2ZvbycgYnV0IG1heSBjb250YWluICdiYXInLlxuICpcbiAqIFRvIGVzY2FwZSBzcGVjaWFsIGNoYXJhY3RlcnMgdGhlIGJhY2tzbGFzaCBjaGFyYWN0ZXIgJ1xcJyBjYW4gYmUgdXNlZCwgdGhpcyBhbGxvd3Mgc2VhcmNoZXMgdG8gaW5jbHVkZVxuICogY2hhcmFjdGVycyB0aGF0IHdvdWxkIG5vcm1hbGx5IGJlIGNvbnNpZGVyZWQgbW9kaWZpZXJzLCBlLmcuIGBmb29cXH4yYCB3aWxsIHNlYXJjaCBmb3IgYSB0ZXJtIFwiZm9vfjJcIiBpbnN0ZWFkXG4gKiBvZiBhdHRlbXB0aW5nIHRvIGFwcGx5IGEgYm9vc3Qgb2YgMiB0byB0aGUgc2VhcmNoIHRlcm0gXCJmb29cIi5cbiAqXG4gKiBAdHlwZWRlZiB7c3RyaW5nfSBsdW5yLkluZGV4flF1ZXJ5U3RyaW5nXG4gKiBAZXhhbXBsZSA8Y2FwdGlvbj5TaW1wbGUgc2luZ2xlIHRlcm0gcXVlcnk8L2NhcHRpb24+XG4gKiBoZWxsb1xuICogQGV4YW1wbGUgPGNhcHRpb24+TXVsdGlwbGUgdGVybSBxdWVyeTwvY2FwdGlvbj5cbiAqIGhlbGxvIHdvcmxkXG4gKiBAZXhhbXBsZSA8Y2FwdGlvbj50ZXJtIHNjb3BlZCB0byBhIGZpZWxkPC9jYXB0aW9uPlxuICogdGl0bGU6aGVsbG9cbiAqIEBleGFtcGxlIDxjYXB0aW9uPnRlcm0gd2l0aCBhIGJvb3N0IG9mIDEwPC9jYXB0aW9uPlxuICogaGVsbG9eMTBcbiAqIEBleGFtcGxlIDxjYXB0aW9uPnRlcm0gd2l0aCBhbiBlZGl0IGRpc3RhbmNlIG9mIDI8L2NhcHRpb24+XG4gKiBoZWxsb34yXG4gKiBAZXhhbXBsZSA8Y2FwdGlvbj50ZXJtcyB3aXRoIHByZXNlbmNlIG1vZGlmaWVyczwvY2FwdGlvbj5cbiAqIC1mb28gK2JhciBiYXpcbiAqL1xuXG4vKipcbiAqIFBlcmZvcm1zIGEgc2VhcmNoIGFnYWluc3QgdGhlIGluZGV4IHVzaW5nIGx1bnIgcXVlcnkgc3ludGF4LlxuICpcbiAqIFJlc3VsdHMgd2lsbCBiZSByZXR1cm5lZCBzb3J0ZWQgYnkgdGhlaXIgc2NvcmUsIHRoZSBtb3N0IHJlbGV2YW50IHJlc3VsdHNcbiAqIHdpbGwgYmUgcmV0dXJuZWQgZmlyc3QuICBGb3IgZGV0YWlscyBvbiBob3cgdGhlIHNjb3JlIGlzIGNhbGN1bGF0ZWQsIHBsZWFzZSBzZWVcbiAqIHRoZSB7QGxpbmsgaHR0cHM6Ly9sdW5yanMuY29tL2d1aWRlcy9zZWFyY2hpbmcuaHRtbCNzY29yaW5nfGd1aWRlfS5cbiAqXG4gKiBGb3IgbW9yZSBwcm9ncmFtbWF0aWMgcXVlcnlpbmcgdXNlIGx1bnIuSW5kZXgjcXVlcnkuXG4gKlxuICogQHBhcmFtIHtsdW5yLkluZGV4flF1ZXJ5U3RyaW5nfSBxdWVyeVN0cmluZyAtIEEgc3RyaW5nIGNvbnRhaW5pbmcgYSBsdW5yIHF1ZXJ5LlxuICogQHRocm93cyB7bHVuci5RdWVyeVBhcnNlRXJyb3J9IElmIHRoZSBwYXNzZWQgcXVlcnkgc3RyaW5nIGNhbm5vdCBiZSBwYXJzZWQuXG4gKiBAcmV0dXJucyB7bHVuci5JbmRleH5SZXN1bHRbXX1cbiAqL1xubHVuci5JbmRleC5wcm90b3R5cGUuc2VhcmNoID0gZnVuY3Rpb24gKHF1ZXJ5U3RyaW5nKSB7XG4gIHJldHVybiB0aGlzLnF1ZXJ5KGZ1bmN0aW9uIChxdWVyeSkge1xuICAgIHZhciBwYXJzZXIgPSBuZXcgbHVuci5RdWVyeVBhcnNlcihxdWVyeVN0cmluZywgcXVlcnkpXG4gICAgcGFyc2VyLnBhcnNlKClcbiAgfSlcbn1cblxuLyoqXG4gKiBBIHF1ZXJ5IGJ1aWxkZXIgY2FsbGJhY2sgcHJvdmlkZXMgYSBxdWVyeSBvYmplY3QgdG8gYmUgdXNlZCB0byBleHByZXNzXG4gKiB0aGUgcXVlcnkgdG8gcGVyZm9ybSBvbiB0aGUgaW5kZXguXG4gKlxuICogQGNhbGxiYWNrIGx1bnIuSW5kZXh+cXVlcnlCdWlsZGVyXG4gKiBAcGFyYW0ge2x1bnIuUXVlcnl9IHF1ZXJ5IC0gVGhlIHF1ZXJ5IG9iamVjdCB0byBidWlsZCB1cC5cbiAqIEB0aGlzIGx1bnIuUXVlcnlcbiAqL1xuXG4vKipcbiAqIFBlcmZvcm1zIGEgcXVlcnkgYWdhaW5zdCB0aGUgaW5kZXggdXNpbmcgdGhlIHlpZWxkZWQgbHVuci5RdWVyeSBvYmplY3QuXG4gKlxuICogSWYgcGVyZm9ybWluZyBwcm9ncmFtbWF0aWMgcXVlcmllcyBhZ2FpbnN0IHRoZSBpbmRleCwgdGhpcyBtZXRob2QgaXMgcHJlZmVycmVkXG4gKiBvdmVyIGx1bnIuSW5kZXgjc2VhcmNoIHNvIGFzIHRvIGF2b2lkIHRoZSBhZGRpdGlvbmFsIHF1ZXJ5IHBhcnNpbmcgb3ZlcmhlYWQuXG4gKlxuICogQSBxdWVyeSBvYmplY3QgaXMgeWllbGRlZCB0byB0aGUgc3VwcGxpZWQgZnVuY3Rpb24gd2hpY2ggc2hvdWxkIGJlIHVzZWQgdG9cbiAqIGV4cHJlc3MgdGhlIHF1ZXJ5IHRvIGJlIHJ1biBhZ2FpbnN0IHRoZSBpbmRleC5cbiAqXG4gKiBOb3RlIHRoYXQgYWx0aG91Z2ggdGhpcyBmdW5jdGlvbiB0YWtlcyBhIGNhbGxiYWNrIHBhcmFtZXRlciBpdCBpcyBfbm90XyBhblxuICogYXN5bmNocm9ub3VzIG9wZXJhdGlvbiwgdGhlIGNhbGxiYWNrIGlzIGp1c3QgeWllbGRlZCBhIHF1ZXJ5IG9iamVjdCB0byBiZVxuICogY3VzdG9taXplZC5cbiAqXG4gKiBAcGFyYW0ge2x1bnIuSW5kZXh+cXVlcnlCdWlsZGVyfSBmbiAtIEEgZnVuY3Rpb24gdGhhdCBpcyB1c2VkIHRvIGJ1aWxkIHRoZSBxdWVyeS5cbiAqIEByZXR1cm5zIHtsdW5yLkluZGV4flJlc3VsdFtdfVxuICovXG5sdW5yLkluZGV4LnByb3RvdHlwZS5xdWVyeSA9IGZ1bmN0aW9uIChmbikge1xuICAvLyBmb3IgZWFjaCBxdWVyeSBjbGF1c2VcbiAgLy8gKiBwcm9jZXNzIHRlcm1zXG4gIC8vICogZXhwYW5kIHRlcm1zIGZyb20gdG9rZW4gc2V0XG4gIC8vICogZmluZCBtYXRjaGluZyBkb2N1bWVudHMgYW5kIG1ldGFkYXRhXG4gIC8vICogZ2V0IGRvY3VtZW50IHZlY3RvcnNcbiAgLy8gKiBzY29yZSBkb2N1bWVudHNcblxuICB2YXIgcXVlcnkgPSBuZXcgbHVuci5RdWVyeSh0aGlzLmZpZWxkcyksXG4gICAgICBtYXRjaGluZ0ZpZWxkcyA9IE9iamVjdC5jcmVhdGUobnVsbCksXG4gICAgICBxdWVyeVZlY3RvcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpLFxuICAgICAgdGVybUZpZWxkQ2FjaGUgPSBPYmplY3QuY3JlYXRlKG51bGwpLFxuICAgICAgcmVxdWlyZWRNYXRjaGVzID0gT2JqZWN0LmNyZWF0ZShudWxsKSxcbiAgICAgIHByb2hpYml0ZWRNYXRjaGVzID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuXG4gIC8qXG4gICAqIFRvIHN1cHBvcnQgZmllbGQgbGV2ZWwgYm9vc3RzIGEgcXVlcnkgdmVjdG9yIGlzIGNyZWF0ZWQgcGVyXG4gICAqIGZpZWxkLiBBbiBlbXB0eSB2ZWN0b3IgaXMgZWFnZXJseSBjcmVhdGVkIHRvIHN1cHBvcnQgbmVnYXRlZFxuICAgKiBxdWVyaWVzLlxuICAgKi9cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmZpZWxkcy5sZW5ndGg7IGkrKykge1xuICAgIHF1ZXJ5VmVjdG9yc1t0aGlzLmZpZWxkc1tpXV0gPSBuZXcgbHVuci5WZWN0b3JcbiAgfVxuXG4gIGZuLmNhbGwocXVlcnksIHF1ZXJ5KVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcXVlcnkuY2xhdXNlcy5sZW5ndGg7IGkrKykge1xuICAgIC8qXG4gICAgICogVW5sZXNzIHRoZSBwaXBlbGluZSBoYXMgYmVlbiBkaXNhYmxlZCBmb3IgdGhpcyB0ZXJtLCB3aGljaCBpc1xuICAgICAqIHRoZSBjYXNlIGZvciB0ZXJtcyB3aXRoIHdpbGRjYXJkcywgd2UgbmVlZCB0byBwYXNzIHRoZSBjbGF1c2VcbiAgICAgKiB0ZXJtIHRocm91Z2ggdGhlIHNlYXJjaCBwaXBlbGluZS4gQSBwaXBlbGluZSByZXR1cm5zIGFuIGFycmF5XG4gICAgICogb2YgcHJvY2Vzc2VkIHRlcm1zLiBQaXBlbGluZSBmdW5jdGlvbnMgbWF5IGV4cGFuZCB0aGUgcGFzc2VkXG4gICAgICogdGVybSwgd2hpY2ggbWVhbnMgd2UgbWF5IGVuZCB1cCBwZXJmb3JtaW5nIG11bHRpcGxlIGluZGV4IGxvb2t1cHNcbiAgICAgKiBmb3IgYSBzaW5nbGUgcXVlcnkgdGVybS5cbiAgICAgKi9cbiAgICB2YXIgY2xhdXNlID0gcXVlcnkuY2xhdXNlc1tpXSxcbiAgICAgICAgdGVybXMgPSBudWxsLFxuICAgICAgICBjbGF1c2VNYXRjaGVzID0gbHVuci5TZXQuY29tcGxldGVcblxuICAgIGlmIChjbGF1c2UudXNlUGlwZWxpbmUpIHtcbiAgICAgIHRlcm1zID0gdGhpcy5waXBlbGluZS5ydW5TdHJpbmcoY2xhdXNlLnRlcm0sIHtcbiAgICAgICAgZmllbGRzOiBjbGF1c2UuZmllbGRzXG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICB0ZXJtcyA9IFtjbGF1c2UudGVybV1cbiAgICB9XG5cbiAgICBmb3IgKHZhciBtID0gMDsgbSA8IHRlcm1zLmxlbmd0aDsgbSsrKSB7XG4gICAgICB2YXIgdGVybSA9IHRlcm1zW21dXG5cbiAgICAgIC8qXG4gICAgICAgKiBFYWNoIHRlcm0gcmV0dXJuZWQgZnJvbSB0aGUgcGlwZWxpbmUgbmVlZHMgdG8gdXNlIHRoZSBzYW1lIHF1ZXJ5XG4gICAgICAgKiBjbGF1c2Ugb2JqZWN0LCBlLmcuIHRoZSBzYW1lIGJvb3N0IGFuZCBvciBlZGl0IGRpc3RhbmNlLiBUaGVcbiAgICAgICAqIHNpbXBsZXN0IHdheSB0byBkbyB0aGlzIGlzIHRvIHJlLXVzZSB0aGUgY2xhdXNlIG9iamVjdCBidXQgbXV0YXRlXG4gICAgICAgKiBpdHMgdGVybSBwcm9wZXJ0eS5cbiAgICAgICAqL1xuICAgICAgY2xhdXNlLnRlcm0gPSB0ZXJtXG5cbiAgICAgIC8qXG4gICAgICAgKiBGcm9tIHRoZSB0ZXJtIGluIHRoZSBjbGF1c2Ugd2UgY3JlYXRlIGEgdG9rZW4gc2V0IHdoaWNoIHdpbGwgdGhlblxuICAgICAgICogYmUgdXNlZCB0byBpbnRlcnNlY3QgdGhlIGluZGV4ZXMgdG9rZW4gc2V0IHRvIGdldCBhIGxpc3Qgb2YgdGVybXNcbiAgICAgICAqIHRvIGxvb2t1cCBpbiB0aGUgaW52ZXJ0ZWQgaW5kZXhcbiAgICAgICAqL1xuICAgICAgdmFyIHRlcm1Ub2tlblNldCA9IGx1bnIuVG9rZW5TZXQuZnJvbUNsYXVzZShjbGF1c2UpLFxuICAgICAgICAgIGV4cGFuZGVkVGVybXMgPSB0aGlzLnRva2VuU2V0LmludGVyc2VjdCh0ZXJtVG9rZW5TZXQpLnRvQXJyYXkoKVxuXG4gICAgICAvKlxuICAgICAgICogSWYgYSB0ZXJtIG1hcmtlZCBhcyByZXF1aXJlZCBkb2VzIG5vdCBleGlzdCBpbiB0aGUgdG9rZW5TZXQgaXQgaXNcbiAgICAgICAqIGltcG9zc2libGUgZm9yIHRoZSBzZWFyY2ggdG8gcmV0dXJuIGFueSBtYXRjaGVzLiBXZSBzZXQgYWxsIHRoZSBmaWVsZFxuICAgICAgICogc2NvcGVkIHJlcXVpcmVkIG1hdGNoZXMgc2V0IHRvIGVtcHR5IGFuZCBzdG9wIGV4YW1pbmluZyBhbnkgZnVydGhlclxuICAgICAgICogY2xhdXNlcy5cbiAgICAgICAqL1xuICAgICAgaWYgKGV4cGFuZGVkVGVybXMubGVuZ3RoID09PSAwICYmIGNsYXVzZS5wcmVzZW5jZSA9PT0gbHVuci5RdWVyeS5wcmVzZW5jZS5SRVFVSVJFRCkge1xuICAgICAgICBmb3IgKHZhciBrID0gMDsgayA8IGNsYXVzZS5maWVsZHMubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICB2YXIgZmllbGQgPSBjbGF1c2UuZmllbGRzW2tdXG4gICAgICAgICAgcmVxdWlyZWRNYXRjaGVzW2ZpZWxkXSA9IGx1bnIuU2V0LmVtcHR5XG4gICAgICAgIH1cblxuICAgICAgICBicmVha1xuICAgICAgfVxuXG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGV4cGFuZGVkVGVybXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgLypcbiAgICAgICAgICogRm9yIGVhY2ggdGVybSBnZXQgdGhlIHBvc3RpbmcgYW5kIHRlcm1JbmRleCwgdGhpcyBpcyByZXF1aXJlZCBmb3JcbiAgICAgICAgICogYnVpbGRpbmcgdGhlIHF1ZXJ5IHZlY3Rvci5cbiAgICAgICAgICovXG4gICAgICAgIHZhciBleHBhbmRlZFRlcm0gPSBleHBhbmRlZFRlcm1zW2pdLFxuICAgICAgICAgICAgcG9zdGluZyA9IHRoaXMuaW52ZXJ0ZWRJbmRleFtleHBhbmRlZFRlcm1dLFxuICAgICAgICAgICAgdGVybUluZGV4ID0gcG9zdGluZy5faW5kZXhcblxuICAgICAgICBmb3IgKHZhciBrID0gMDsgayA8IGNsYXVzZS5maWVsZHMubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICAvKlxuICAgICAgICAgICAqIEZvciBlYWNoIGZpZWxkIHRoYXQgdGhpcyBxdWVyeSB0ZXJtIGlzIHNjb3BlZCBieSAoYnkgZGVmYXVsdFxuICAgICAgICAgICAqIGFsbCBmaWVsZHMgYXJlIGluIHNjb3BlKSB3ZSBuZWVkIHRvIGdldCBhbGwgdGhlIGRvY3VtZW50IHJlZnNcbiAgICAgICAgICAgKiB0aGF0IGhhdmUgdGhpcyB0ZXJtIGluIHRoYXQgZmllbGQuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBUaGUgcG9zdGluZyBpcyB0aGUgZW50cnkgaW4gdGhlIGludmVydGVkSW5kZXggZm9yIHRoZSBtYXRjaGluZ1xuICAgICAgICAgICAqIHRlcm0gZnJvbSBhYm92ZS5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICB2YXIgZmllbGQgPSBjbGF1c2UuZmllbGRzW2tdLFxuICAgICAgICAgICAgICBmaWVsZFBvc3RpbmcgPSBwb3N0aW5nW2ZpZWxkXSxcbiAgICAgICAgICAgICAgbWF0Y2hpbmdEb2N1bWVudFJlZnMgPSBPYmplY3Qua2V5cyhmaWVsZFBvc3RpbmcpLFxuICAgICAgICAgICAgICB0ZXJtRmllbGQgPSBleHBhbmRlZFRlcm0gKyBcIi9cIiArIGZpZWxkLFxuICAgICAgICAgICAgICBtYXRjaGluZ0RvY3VtZW50c1NldCA9IG5ldyBsdW5yLlNldChtYXRjaGluZ0RvY3VtZW50UmVmcylcblxuICAgICAgICAgIC8qXG4gICAgICAgICAgICogaWYgdGhlIHByZXNlbmNlIG9mIHRoaXMgdGVybSBpcyByZXF1aXJlZCBlbnN1cmUgdGhhdCB0aGUgbWF0Y2hpbmdcbiAgICAgICAgICAgKiBkb2N1bWVudHMgYXJlIGFkZGVkIHRvIHRoZSBzZXQgb2YgcmVxdWlyZWQgbWF0Y2hlcyBmb3IgdGhpcyBjbGF1c2UuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKi9cbiAgICAgICAgICBpZiAoY2xhdXNlLnByZXNlbmNlID09IGx1bnIuUXVlcnkucHJlc2VuY2UuUkVRVUlSRUQpIHtcbiAgICAgICAgICAgIGNsYXVzZU1hdGNoZXMgPSBjbGF1c2VNYXRjaGVzLnVuaW9uKG1hdGNoaW5nRG9jdW1lbnRzU2V0KVxuXG4gICAgICAgICAgICBpZiAocmVxdWlyZWRNYXRjaGVzW2ZpZWxkXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIHJlcXVpcmVkTWF0Y2hlc1tmaWVsZF0gPSBsdW5yLlNldC5jb21wbGV0ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8qXG4gICAgICAgICAgICogaWYgdGhlIHByZXNlbmNlIG9mIHRoaXMgdGVybSBpcyBwcm9oaWJpdGVkIGVuc3VyZSB0aGF0IHRoZSBtYXRjaGluZ1xuICAgICAgICAgICAqIGRvY3VtZW50cyBhcmUgYWRkZWQgdG8gdGhlIHNldCBvZiBwcm9oaWJpdGVkIG1hdGNoZXMgZm9yIHRoaXMgZmllbGQsXG4gICAgICAgICAgICogY3JlYXRpbmcgdGhhdCBzZXQgaWYgaXQgZG9lcyBub3QgeWV0IGV4aXN0LlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGlmIChjbGF1c2UucHJlc2VuY2UgPT0gbHVuci5RdWVyeS5wcmVzZW5jZS5QUk9ISUJJVEVEKSB7XG4gICAgICAgICAgICBpZiAocHJvaGliaXRlZE1hdGNoZXNbZmllbGRdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgcHJvaGliaXRlZE1hdGNoZXNbZmllbGRdID0gbHVuci5TZXQuZW1wdHlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcHJvaGliaXRlZE1hdGNoZXNbZmllbGRdID0gcHJvaGliaXRlZE1hdGNoZXNbZmllbGRdLnVuaW9uKG1hdGNoaW5nRG9jdW1lbnRzU2V0KVxuXG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogUHJvaGliaXRlZCBtYXRjaGVzIHNob3VsZCBub3QgYmUgcGFydCBvZiB0aGUgcXVlcnkgdmVjdG9yIHVzZWQgZm9yXG4gICAgICAgICAgICAgKiBzaW1pbGFyaXR5IHNjb3JpbmcgYW5kIG5vIG1ldGFkYXRhIHNob3VsZCBiZSBleHRyYWN0ZWQgc28gd2UgY29udGludWVcbiAgICAgICAgICAgICAqIHRvIHRoZSBuZXh0IGZpZWxkXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLypcbiAgICAgICAgICAgKiBUaGUgcXVlcnkgZmllbGQgdmVjdG9yIGlzIHBvcHVsYXRlZCB1c2luZyB0aGUgdGVybUluZGV4IGZvdW5kIGZvclxuICAgICAgICAgICAqIHRoZSB0ZXJtIGFuZCBhIHVuaXQgdmFsdWUgd2l0aCB0aGUgYXBwcm9wcmlhdGUgYm9vc3QgYXBwbGllZC5cbiAgICAgICAgICAgKiBVc2luZyB1cHNlcnQgYmVjYXVzZSB0aGVyZSBjb3VsZCBhbHJlYWR5IGJlIGFuIGVudHJ5IGluIHRoZSB2ZWN0b3JcbiAgICAgICAgICAgKiBmb3IgdGhlIHRlcm0gd2UgYXJlIHdvcmtpbmcgd2l0aC4gSW4gdGhhdCBjYXNlIHdlIGp1c3QgYWRkIHRoZSBzY29yZXNcbiAgICAgICAgICAgKiB0b2dldGhlci5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBxdWVyeVZlY3RvcnNbZmllbGRdLnVwc2VydCh0ZXJtSW5kZXgsIGNsYXVzZS5ib29zdCwgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEgKyBiIH0pXG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBJZiB3ZSd2ZSBhbHJlYWR5IHNlZW4gdGhpcyB0ZXJtLCBmaWVsZCBjb21ibyB0aGVuIHdlJ3ZlIGFscmVhZHkgY29sbGVjdGVkXG4gICAgICAgICAgICogdGhlIG1hdGNoaW5nIGRvY3VtZW50cyBhbmQgbWV0YWRhdGEsIG5vIG5lZWQgdG8gZ28gdGhyb3VnaCBhbGwgdGhhdCBhZ2FpblxuICAgICAgICAgICAqL1xuICAgICAgICAgIGlmICh0ZXJtRmllbGRDYWNoZVt0ZXJtRmllbGRdKSB7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGZvciAodmFyIGwgPSAwOyBsIDwgbWF0Y2hpbmdEb2N1bWVudFJlZnMubGVuZ3RoOyBsKyspIHtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBBbGwgbWV0YWRhdGEgZm9yIHRoaXMgdGVybS9maWVsZC9kb2N1bWVudCB0cmlwbGVcbiAgICAgICAgICAgICAqIGFyZSB0aGVuIGV4dHJhY3RlZCBhbmQgY29sbGVjdGVkIGludG8gYW4gaW5zdGFuY2VcbiAgICAgICAgICAgICAqIG9mIGx1bnIuTWF0Y2hEYXRhIHJlYWR5IHRvIGJlIHJldHVybmVkIGluIHRoZSBxdWVyeVxuICAgICAgICAgICAgICogcmVzdWx0c1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICB2YXIgbWF0Y2hpbmdEb2N1bWVudFJlZiA9IG1hdGNoaW5nRG9jdW1lbnRSZWZzW2xdLFxuICAgICAgICAgICAgICAgIG1hdGNoaW5nRmllbGRSZWYgPSBuZXcgbHVuci5GaWVsZFJlZiAobWF0Y2hpbmdEb2N1bWVudFJlZiwgZmllbGQpLFxuICAgICAgICAgICAgICAgIG1ldGFkYXRhID0gZmllbGRQb3N0aW5nW21hdGNoaW5nRG9jdW1lbnRSZWZdLFxuICAgICAgICAgICAgICAgIGZpZWxkTWF0Y2hcblxuICAgICAgICAgICAgaWYgKChmaWVsZE1hdGNoID0gbWF0Y2hpbmdGaWVsZHNbbWF0Y2hpbmdGaWVsZFJlZl0pID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgbWF0Y2hpbmdGaWVsZHNbbWF0Y2hpbmdGaWVsZFJlZl0gPSBuZXcgbHVuci5NYXRjaERhdGEgKGV4cGFuZGVkVGVybSwgZmllbGQsIG1ldGFkYXRhKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZmllbGRNYXRjaC5hZGQoZXhwYW5kZWRUZXJtLCBmaWVsZCwgbWV0YWRhdGEpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0ZXJtRmllbGRDYWNoZVt0ZXJtRmllbGRdID0gdHJ1ZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSWYgdGhlIHByZXNlbmNlIHdhcyByZXF1aXJlZCB3ZSBuZWVkIHRvIHVwZGF0ZSB0aGUgcmVxdWlyZWRNYXRjaGVzIGZpZWxkIHNldHMuXG4gICAgICogV2UgZG8gdGhpcyBhZnRlciBhbGwgZmllbGRzIGZvciB0aGUgdGVybSBoYXZlIGNvbGxlY3RlZCB0aGVpciBtYXRjaGVzIGJlY2F1c2VcbiAgICAgKiB0aGUgY2xhdXNlIHRlcm1zIHByZXNlbmNlIGlzIHJlcXVpcmVkIGluIF9hbnlfIG9mIHRoZSBmaWVsZHMgbm90IF9hbGxfIG9mIHRoZVxuICAgICAqIGZpZWxkcy5cbiAgICAgKi9cbiAgICBpZiAoY2xhdXNlLnByZXNlbmNlID09PSBsdW5yLlF1ZXJ5LnByZXNlbmNlLlJFUVVJUkVEKSB7XG4gICAgICBmb3IgKHZhciBrID0gMDsgayA8IGNsYXVzZS5maWVsZHMubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgdmFyIGZpZWxkID0gY2xhdXNlLmZpZWxkc1trXVxuICAgICAgICByZXF1aXJlZE1hdGNoZXNbZmllbGRdID0gcmVxdWlyZWRNYXRjaGVzW2ZpZWxkXS5pbnRlcnNlY3QoY2xhdXNlTWF0Y2hlcylcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTmVlZCB0byBjb21iaW5lIHRoZSBmaWVsZCBzY29wZWQgcmVxdWlyZWQgYW5kIHByb2hpYml0ZWRcbiAgICogbWF0Y2hpbmcgZG9jdW1lbnRzIGludG8gYSBnbG9iYWwgc2V0IG9mIHJlcXVpcmVkIGFuZCBwcm9oaWJpdGVkXG4gICAqIG1hdGNoZXNcbiAgICovXG4gIHZhciBhbGxSZXF1aXJlZE1hdGNoZXMgPSBsdW5yLlNldC5jb21wbGV0ZSxcbiAgICAgIGFsbFByb2hpYml0ZWRNYXRjaGVzID0gbHVuci5TZXQuZW1wdHlcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuZmllbGRzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGZpZWxkID0gdGhpcy5maWVsZHNbaV1cblxuICAgIGlmIChyZXF1aXJlZE1hdGNoZXNbZmllbGRdKSB7XG4gICAgICBhbGxSZXF1aXJlZE1hdGNoZXMgPSBhbGxSZXF1aXJlZE1hdGNoZXMuaW50ZXJzZWN0KHJlcXVpcmVkTWF0Y2hlc1tmaWVsZF0pXG4gICAgfVxuXG4gICAgaWYgKHByb2hpYml0ZWRNYXRjaGVzW2ZpZWxkXSkge1xuICAgICAgYWxsUHJvaGliaXRlZE1hdGNoZXMgPSBhbGxQcm9oaWJpdGVkTWF0Y2hlcy51bmlvbihwcm9oaWJpdGVkTWF0Y2hlc1tmaWVsZF0pXG4gICAgfVxuICB9XG5cbiAgdmFyIG1hdGNoaW5nRmllbGRSZWZzID0gT2JqZWN0LmtleXMobWF0Y2hpbmdGaWVsZHMpLFxuICAgICAgcmVzdWx0cyA9IFtdLFxuICAgICAgbWF0Y2hlcyA9IE9iamVjdC5jcmVhdGUobnVsbClcblxuICAvKlxuICAgKiBJZiB0aGUgcXVlcnkgaXMgbmVnYXRlZCAoY29udGFpbnMgb25seSBwcm9oaWJpdGVkIHRlcm1zKVxuICAgKiB3ZSBuZWVkIHRvIGdldCBfYWxsXyBmaWVsZFJlZnMgY3VycmVudGx5IGV4aXN0aW5nIGluIHRoZVxuICAgKiBpbmRleC4gVGhpcyBpcyBvbmx5IGRvbmUgd2hlbiB3ZSBrbm93IHRoYXQgdGhlIHF1ZXJ5IGlzXG4gICAqIGVudGlyZWx5IHByb2hpYml0ZWQgdGVybXMgdG8gYXZvaWQgYW55IGNvc3Qgb2YgZ2V0dGluZyBhbGxcbiAgICogZmllbGRSZWZzIHVubmVjZXNzYXJpbHkuXG4gICAqXG4gICAqIEFkZGl0aW9uYWxseSwgYmxhbmsgTWF0Y2hEYXRhIG11c3QgYmUgY3JlYXRlZCB0byBjb3JyZWN0bHlcbiAgICogcG9wdWxhdGUgdGhlIHJlc3VsdHMuXG4gICAqL1xuICBpZiAocXVlcnkuaXNOZWdhdGVkKCkpIHtcbiAgICBtYXRjaGluZ0ZpZWxkUmVmcyA9IE9iamVjdC5rZXlzKHRoaXMuZmllbGRWZWN0b3JzKVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXRjaGluZ0ZpZWxkUmVmcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIG1hdGNoaW5nRmllbGRSZWYgPSBtYXRjaGluZ0ZpZWxkUmVmc1tpXVxuICAgICAgdmFyIGZpZWxkUmVmID0gbHVuci5GaWVsZFJlZi5mcm9tU3RyaW5nKG1hdGNoaW5nRmllbGRSZWYpXG4gICAgICBtYXRjaGluZ0ZpZWxkc1ttYXRjaGluZ0ZpZWxkUmVmXSA9IG5ldyBsdW5yLk1hdGNoRGF0YVxuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbWF0Y2hpbmdGaWVsZFJlZnMubGVuZ3RoOyBpKyspIHtcbiAgICAvKlxuICAgICAqIEN1cnJlbnRseSB3ZSBoYXZlIGRvY3VtZW50IGZpZWxkcyB0aGF0IG1hdGNoIHRoZSBxdWVyeSwgYnV0IHdlXG4gICAgICogbmVlZCB0byByZXR1cm4gZG9jdW1lbnRzLiBUaGUgbWF0Y2hEYXRhIGFuZCBzY29yZXMgYXJlIGNvbWJpbmVkXG4gICAgICogZnJvbSBtdWx0aXBsZSBmaWVsZHMgYmVsb25naW5nIHRvIHRoZSBzYW1lIGRvY3VtZW50LlxuICAgICAqXG4gICAgICogU2NvcmVzIGFyZSBjYWxjdWxhdGVkIGJ5IGZpZWxkLCB1c2luZyB0aGUgcXVlcnkgdmVjdG9ycyBjcmVhdGVkXG4gICAgICogYWJvdmUsIGFuZCBjb21iaW5lZCBpbnRvIGEgZmluYWwgZG9jdW1lbnQgc2NvcmUgdXNpbmcgYWRkaXRpb24uXG4gICAgICovXG4gICAgdmFyIGZpZWxkUmVmID0gbHVuci5GaWVsZFJlZi5mcm9tU3RyaW5nKG1hdGNoaW5nRmllbGRSZWZzW2ldKSxcbiAgICAgICAgZG9jUmVmID0gZmllbGRSZWYuZG9jUmVmXG5cbiAgICBpZiAoIWFsbFJlcXVpcmVkTWF0Y2hlcy5jb250YWlucyhkb2NSZWYpKSB7XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGlmIChhbGxQcm9oaWJpdGVkTWF0Y2hlcy5jb250YWlucyhkb2NSZWYpKSB7XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIHZhciBmaWVsZFZlY3RvciA9IHRoaXMuZmllbGRWZWN0b3JzW2ZpZWxkUmVmXSxcbiAgICAgICAgc2NvcmUgPSBxdWVyeVZlY3RvcnNbZmllbGRSZWYuZmllbGROYW1lXS5zaW1pbGFyaXR5KGZpZWxkVmVjdG9yKSxcbiAgICAgICAgZG9jTWF0Y2hcblxuICAgIGlmICgoZG9jTWF0Y2ggPSBtYXRjaGVzW2RvY1JlZl0pICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGRvY01hdGNoLnNjb3JlICs9IHNjb3JlXG4gICAgICBkb2NNYXRjaC5tYXRjaERhdGEuY29tYmluZShtYXRjaGluZ0ZpZWxkc1tmaWVsZFJlZl0pXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBtYXRjaCA9IHtcbiAgICAgICAgcmVmOiBkb2NSZWYsXG4gICAgICAgIHNjb3JlOiBzY29yZSxcbiAgICAgICAgbWF0Y2hEYXRhOiBtYXRjaGluZ0ZpZWxkc1tmaWVsZFJlZl1cbiAgICAgIH1cbiAgICAgIG1hdGNoZXNbZG9jUmVmXSA9IG1hdGNoXG4gICAgICByZXN1bHRzLnB1c2gobWF0Y2gpXG4gICAgfVxuICB9XG5cbiAgLypcbiAgICogU29ydCB0aGUgcmVzdWx0cyBvYmplY3RzIGJ5IHNjb3JlLCBoaWdoZXN0IGZpcnN0LlxuICAgKi9cbiAgcmV0dXJuIHJlc3VsdHMuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgIHJldHVybiBiLnNjb3JlIC0gYS5zY29yZVxuICB9KVxufVxuXG4vKipcbiAqIFByZXBhcmVzIHRoZSBpbmRleCBmb3IgSlNPTiBzZXJpYWxpemF0aW9uLlxuICpcbiAqIFRoZSBzY2hlbWEgZm9yIHRoaXMgSlNPTiBibG9iIHdpbGwgYmUgZGVzY3JpYmVkIGluIGFcbiAqIHNlcGFyYXRlIEpTT04gc2NoZW1hIGZpbGUuXG4gKlxuICogQHJldHVybnMge09iamVjdH1cbiAqL1xubHVuci5JbmRleC5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaW52ZXJ0ZWRJbmRleCA9IE9iamVjdC5rZXlzKHRoaXMuaW52ZXJ0ZWRJbmRleClcbiAgICAuc29ydCgpXG4gICAgLm1hcChmdW5jdGlvbiAodGVybSkge1xuICAgICAgcmV0dXJuIFt0ZXJtLCB0aGlzLmludmVydGVkSW5kZXhbdGVybV1dXG4gICAgfSwgdGhpcylcblxuICB2YXIgZmllbGRWZWN0b3JzID0gT2JqZWN0LmtleXModGhpcy5maWVsZFZlY3RvcnMpXG4gICAgLm1hcChmdW5jdGlvbiAocmVmKSB7XG4gICAgICByZXR1cm4gW3JlZiwgdGhpcy5maWVsZFZlY3RvcnNbcmVmXS50b0pTT04oKV1cbiAgICB9LCB0aGlzKVxuXG4gIHJldHVybiB7XG4gICAgdmVyc2lvbjogbHVuci52ZXJzaW9uLFxuICAgIGZpZWxkczogdGhpcy5maWVsZHMsXG4gICAgZmllbGRWZWN0b3JzOiBmaWVsZFZlY3RvcnMsXG4gICAgaW52ZXJ0ZWRJbmRleDogaW52ZXJ0ZWRJbmRleCxcbiAgICBwaXBlbGluZTogdGhpcy5waXBlbGluZS50b0pTT04oKVxuICB9XG59XG5cbi8qKlxuICogTG9hZHMgYSBwcmV2aW91c2x5IHNlcmlhbGl6ZWQgbHVuci5JbmRleFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZXJpYWxpemVkSW5kZXggLSBBIHByZXZpb3VzbHkgc2VyaWFsaXplZCBsdW5yLkluZGV4XG4gKiBAcmV0dXJucyB7bHVuci5JbmRleH1cbiAqL1xubHVuci5JbmRleC5sb2FkID0gZnVuY3Rpb24gKHNlcmlhbGl6ZWRJbmRleCkge1xuICB2YXIgYXR0cnMgPSB7fSxcbiAgICAgIGZpZWxkVmVjdG9ycyA9IHt9LFxuICAgICAgc2VyaWFsaXplZFZlY3RvcnMgPSBzZXJpYWxpemVkSW5kZXguZmllbGRWZWN0b3JzLFxuICAgICAgaW52ZXJ0ZWRJbmRleCA9IE9iamVjdC5jcmVhdGUobnVsbCksXG4gICAgICBzZXJpYWxpemVkSW52ZXJ0ZWRJbmRleCA9IHNlcmlhbGl6ZWRJbmRleC5pbnZlcnRlZEluZGV4LFxuICAgICAgdG9rZW5TZXRCdWlsZGVyID0gbmV3IGx1bnIuVG9rZW5TZXQuQnVpbGRlcixcbiAgICAgIHBpcGVsaW5lID0gbHVuci5QaXBlbGluZS5sb2FkKHNlcmlhbGl6ZWRJbmRleC5waXBlbGluZSlcblxuICBpZiAoc2VyaWFsaXplZEluZGV4LnZlcnNpb24gIT0gbHVuci52ZXJzaW9uKSB7XG4gICAgbHVuci51dGlscy53YXJuKFwiVmVyc2lvbiBtaXNtYXRjaCB3aGVuIGxvYWRpbmcgc2VyaWFsaXNlZCBpbmRleC4gQ3VycmVudCB2ZXJzaW9uIG9mIGx1bnIgJ1wiICsgbHVuci52ZXJzaW9uICsgXCInIGRvZXMgbm90IG1hdGNoIHNlcmlhbGl6ZWQgaW5kZXggJ1wiICsgc2VyaWFsaXplZEluZGV4LnZlcnNpb24gKyBcIidcIilcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc2VyaWFsaXplZFZlY3RvcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgdHVwbGUgPSBzZXJpYWxpemVkVmVjdG9yc1tpXSxcbiAgICAgICAgcmVmID0gdHVwbGVbMF0sXG4gICAgICAgIGVsZW1lbnRzID0gdHVwbGVbMV1cblxuICAgIGZpZWxkVmVjdG9yc1tyZWZdID0gbmV3IGx1bnIuVmVjdG9yKGVsZW1lbnRzKVxuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZXJpYWxpemVkSW52ZXJ0ZWRJbmRleC5sZW5ndGg7IGkrKykge1xuICAgIHZhciB0dXBsZSA9IHNlcmlhbGl6ZWRJbnZlcnRlZEluZGV4W2ldLFxuICAgICAgICB0ZXJtID0gdHVwbGVbMF0sXG4gICAgICAgIHBvc3RpbmcgPSB0dXBsZVsxXVxuXG4gICAgdG9rZW5TZXRCdWlsZGVyLmluc2VydCh0ZXJtKVxuICAgIGludmVydGVkSW5kZXhbdGVybV0gPSBwb3N0aW5nXG4gIH1cblxuICB0b2tlblNldEJ1aWxkZXIuZmluaXNoKClcblxuICBhdHRycy5maWVsZHMgPSBzZXJpYWxpemVkSW5kZXguZmllbGRzXG5cbiAgYXR0cnMuZmllbGRWZWN0b3JzID0gZmllbGRWZWN0b3JzXG4gIGF0dHJzLmludmVydGVkSW5kZXggPSBpbnZlcnRlZEluZGV4XG4gIGF0dHJzLnRva2VuU2V0ID0gdG9rZW5TZXRCdWlsZGVyLnJvb3RcbiAgYXR0cnMucGlwZWxpbmUgPSBwaXBlbGluZVxuXG4gIHJldHVybiBuZXcgbHVuci5JbmRleChhdHRycylcbn1cbi8qIVxuICogbHVuci5CdWlsZGVyXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTggT2xpdmVyIE5pZ2h0aW5nYWxlXG4gKi9cblxuLyoqXG4gKiBsdW5yLkJ1aWxkZXIgcGVyZm9ybXMgaW5kZXhpbmcgb24gYSBzZXQgb2YgZG9jdW1lbnRzIGFuZFxuICogcmV0dXJucyBpbnN0YW5jZXMgb2YgbHVuci5JbmRleCByZWFkeSBmb3IgcXVlcnlpbmcuXG4gKlxuICogQWxsIGNvbmZpZ3VyYXRpb24gb2YgdGhlIGluZGV4IGlzIGRvbmUgdmlhIHRoZSBidWlsZGVyLCB0aGVcbiAqIGZpZWxkcyB0byBpbmRleCwgdGhlIGRvY3VtZW50IHJlZmVyZW5jZSwgdGhlIHRleHQgcHJvY2Vzc2luZ1xuICogcGlwZWxpbmUgYW5kIGRvY3VtZW50IHNjb3JpbmcgcGFyYW1ldGVycyBhcmUgYWxsIHNldCBvbiB0aGVcbiAqIGJ1aWxkZXIgYmVmb3JlIGluZGV4aW5nLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHByb3BlcnR5IHtzdHJpbmd9IF9yZWYgLSBJbnRlcm5hbCByZWZlcmVuY2UgdG8gdGhlIGRvY3VtZW50IHJlZmVyZW5jZSBmaWVsZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IF9maWVsZHMgLSBJbnRlcm5hbCByZWZlcmVuY2UgdG8gdGhlIGRvY3VtZW50IGZpZWxkcyB0byBpbmRleC5cbiAqIEBwcm9wZXJ0eSB7b2JqZWN0fSBpbnZlcnRlZEluZGV4IC0gVGhlIGludmVydGVkIGluZGV4IG1hcHMgdGVybXMgdG8gZG9jdW1lbnQgZmllbGRzLlxuICogQHByb3BlcnR5IHtvYmplY3R9IGRvY3VtZW50VGVybUZyZXF1ZW5jaWVzIC0gS2VlcHMgdHJhY2sgb2YgZG9jdW1lbnQgdGVybSBmcmVxdWVuY2llcy5cbiAqIEBwcm9wZXJ0eSB7b2JqZWN0fSBkb2N1bWVudExlbmd0aHMgLSBLZWVwcyB0cmFjayBvZiB0aGUgbGVuZ3RoIG9mIGRvY3VtZW50cyBhZGRlZCB0byB0aGUgaW5kZXguXG4gKiBAcHJvcGVydHkge2x1bnIudG9rZW5pemVyfSB0b2tlbml6ZXIgLSBGdW5jdGlvbiBmb3Igc3BsaXR0aW5nIHN0cmluZ3MgaW50byB0b2tlbnMgZm9yIGluZGV4aW5nLlxuICogQHByb3BlcnR5IHtsdW5yLlBpcGVsaW5lfSBwaXBlbGluZSAtIFRoZSBwaXBlbGluZSBwZXJmb3JtcyB0ZXh0IHByb2Nlc3Npbmcgb24gdG9rZW5zIGJlZm9yZSBpbmRleGluZy5cbiAqIEBwcm9wZXJ0eSB7bHVuci5QaXBlbGluZX0gc2VhcmNoUGlwZWxpbmUgLSBBIHBpcGVsaW5lIGZvciBwcm9jZXNzaW5nIHNlYXJjaCB0ZXJtcyBiZWZvcmUgcXVlcnlpbmcgdGhlIGluZGV4LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGRvY3VtZW50Q291bnQgLSBLZWVwcyB0cmFjayBvZiB0aGUgdG90YWwgbnVtYmVyIG9mIGRvY3VtZW50cyBpbmRleGVkLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IF9iIC0gQSBwYXJhbWV0ZXIgdG8gY29udHJvbCBmaWVsZCBsZW5ndGggbm9ybWFsaXphdGlvbiwgc2V0dGluZyB0aGlzIHRvIDAgZGlzYWJsZWQgbm9ybWFsaXphdGlvbiwgMSBmdWxseSBub3JtYWxpemVzIGZpZWxkIGxlbmd0aHMsIHRoZSBkZWZhdWx0IHZhbHVlIGlzIDAuNzUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gX2sxIC0gQSBwYXJhbWV0ZXIgdG8gY29udHJvbCBob3cgcXVpY2tseSBhbiBpbmNyZWFzZSBpbiB0ZXJtIGZyZXF1ZW5jeSByZXN1bHRzIGluIHRlcm0gZnJlcXVlbmN5IHNhdHVyYXRpb24sIHRoZSBkZWZhdWx0IHZhbHVlIGlzIDEuMi5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB0ZXJtSW5kZXggLSBBIGNvdW50ZXIgaW5jcmVtZW50ZWQgZm9yIGVhY2ggdW5pcXVlIHRlcm0sIHVzZWQgdG8gaWRlbnRpZnkgYSB0ZXJtcyBwb3NpdGlvbiBpbiB0aGUgdmVjdG9yIHNwYWNlLlxuICogQHByb3BlcnR5IHthcnJheX0gbWV0YWRhdGFXaGl0ZWxpc3QgLSBBIGxpc3Qgb2YgbWV0YWRhdGEga2V5cyB0aGF0IGhhdmUgYmVlbiB3aGl0ZWxpc3RlZCBmb3IgZW50cnkgaW4gdGhlIGluZGV4LlxuICovXG5sdW5yLkJ1aWxkZXIgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuX3JlZiA9IFwiaWRcIlxuICB0aGlzLl9maWVsZHMgPSBPYmplY3QuY3JlYXRlKG51bGwpXG4gIHRoaXMuX2RvY3VtZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbClcbiAgdGhpcy5pbnZlcnRlZEluZGV4ID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuICB0aGlzLmZpZWxkVGVybUZyZXF1ZW5jaWVzID0ge31cbiAgdGhpcy5maWVsZExlbmd0aHMgPSB7fVxuICB0aGlzLnRva2VuaXplciA9IGx1bnIudG9rZW5pemVyXG4gIHRoaXMucGlwZWxpbmUgPSBuZXcgbHVuci5QaXBlbGluZVxuICB0aGlzLnNlYXJjaFBpcGVsaW5lID0gbmV3IGx1bnIuUGlwZWxpbmVcbiAgdGhpcy5kb2N1bWVudENvdW50ID0gMFxuICB0aGlzLl9iID0gMC43NVxuICB0aGlzLl9rMSA9IDEuMlxuICB0aGlzLnRlcm1JbmRleCA9IDBcbiAgdGhpcy5tZXRhZGF0YVdoaXRlbGlzdCA9IFtdXG59XG5cbi8qKlxuICogU2V0cyB0aGUgZG9jdW1lbnQgZmllbGQgdXNlZCBhcyB0aGUgZG9jdW1lbnQgcmVmZXJlbmNlLiBFdmVyeSBkb2N1bWVudCBtdXN0IGhhdmUgdGhpcyBmaWVsZC5cbiAqIFRoZSB0eXBlIG9mIHRoaXMgZmllbGQgaW4gdGhlIGRvY3VtZW50IHNob3VsZCBiZSBhIHN0cmluZywgaWYgaXQgaXMgbm90IGEgc3RyaW5nIGl0IHdpbGwgYmVcbiAqIGNvZXJjZWQgaW50byBhIHN0cmluZyBieSBjYWxsaW5nIHRvU3RyaW5nLlxuICpcbiAqIFRoZSBkZWZhdWx0IHJlZiBpcyAnaWQnLlxuICpcbiAqIFRoZSByZWYgc2hvdWxkIF9ub3RfIGJlIGNoYW5nZWQgZHVyaW5nIGluZGV4aW5nLCBpdCBzaG91bGQgYmUgc2V0IGJlZm9yZSBhbnkgZG9jdW1lbnRzIGFyZVxuICogYWRkZWQgdG8gdGhlIGluZGV4LiBDaGFuZ2luZyBpdCBkdXJpbmcgaW5kZXhpbmcgY2FuIGxlYWQgdG8gaW5jb25zaXN0ZW50IHJlc3VsdHMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHJlZiAtIFRoZSBuYW1lIG9mIHRoZSByZWZlcmVuY2UgZmllbGQgaW4gdGhlIGRvY3VtZW50LlxuICovXG5sdW5yLkJ1aWxkZXIucHJvdG90eXBlLnJlZiA9IGZ1bmN0aW9uIChyZWYpIHtcbiAgdGhpcy5fcmVmID0gcmVmXG59XG5cbi8qKlxuICogQSBmdW5jdGlvbiB0aGF0IGlzIHVzZWQgdG8gZXh0cmFjdCBhIGZpZWxkIGZyb20gYSBkb2N1bWVudC5cbiAqXG4gKiBMdW5yIGV4cGVjdHMgYSBmaWVsZCB0byBiZSBhdCB0aGUgdG9wIGxldmVsIG9mIGEgZG9jdW1lbnQsIGlmIGhvd2V2ZXIgdGhlIGZpZWxkXG4gKiBpcyBkZWVwbHkgbmVzdGVkIHdpdGhpbiBhIGRvY3VtZW50IGFuIGV4dHJhY3RvciBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBleHRyYWN0XG4gKiB0aGUgcmlnaHQgZmllbGQgZm9yIGluZGV4aW5nLlxuICpcbiAqIEBjYWxsYmFjayBmaWVsZEV4dHJhY3RvclxuICogQHBhcmFtIHtvYmplY3R9IGRvYyAtIFRoZSBkb2N1bWVudCBiZWluZyBhZGRlZCB0byB0aGUgaW5kZXguXG4gKiBAcmV0dXJucyB7PyhzdHJpbmd8b2JqZWN0fG9iamVjdFtdKX0gb2JqIC0gVGhlIG9iamVjdCB0aGF0IHdpbGwgYmUgaW5kZXhlZCBmb3IgdGhpcyBmaWVsZC5cbiAqIEBleGFtcGxlIDxjYXB0aW9uPkV4dHJhY3RpbmcgYSBuZXN0ZWQgZmllbGQ8L2NhcHRpb24+XG4gKiBmdW5jdGlvbiAoZG9jKSB7IHJldHVybiBkb2MubmVzdGVkLmZpZWxkIH1cbiAqL1xuXG4vKipcbiAqIEFkZHMgYSBmaWVsZCB0byB0aGUgbGlzdCBvZiBkb2N1bWVudCBmaWVsZHMgdGhhdCB3aWxsIGJlIGluZGV4ZWQuIEV2ZXJ5IGRvY3VtZW50IGJlaW5nXG4gKiBpbmRleGVkIHNob3VsZCBoYXZlIHRoaXMgZmllbGQuIE51bGwgdmFsdWVzIGZvciB0aGlzIGZpZWxkIGluIGluZGV4ZWQgZG9jdW1lbnRzIHdpbGxcbiAqIG5vdCBjYXVzZSBlcnJvcnMgYnV0IHdpbGwgbGltaXQgdGhlIGNoYW5jZSBvZiB0aGF0IGRvY3VtZW50IGJlaW5nIHJldHJpZXZlZCBieSBzZWFyY2hlcy5cbiAqXG4gKiBBbGwgZmllbGRzIHNob3VsZCBiZSBhZGRlZCBiZWZvcmUgYWRkaW5nIGRvY3VtZW50cyB0byB0aGUgaW5kZXguIEFkZGluZyBmaWVsZHMgYWZ0ZXJcbiAqIGEgZG9jdW1lbnQgaGFzIGJlZW4gaW5kZXhlZCB3aWxsIGhhdmUgbm8gZWZmZWN0IG9uIGFscmVhZHkgaW5kZXhlZCBkb2N1bWVudHMuXG4gKlxuICogRmllbGRzIGNhbiBiZSBib29zdGVkIGF0IGJ1aWxkIHRpbWUuIFRoaXMgYWxsb3dzIHRlcm1zIHdpdGhpbiB0aGF0IGZpZWxkIHRvIGhhdmUgbW9yZVxuICogaW1wb3J0YW5jZSB3aGVuIHJhbmtpbmcgc2VhcmNoIHJlc3VsdHMuIFVzZSBhIGZpZWxkIGJvb3N0IHRvIHNwZWNpZnkgdGhhdCBtYXRjaGVzIHdpdGhpblxuICogb25lIGZpZWxkIGFyZSBtb3JlIGltcG9ydGFudCB0aGFuIG90aGVyIGZpZWxkcy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmllbGROYW1lIC0gVGhlIG5hbWUgb2YgYSBmaWVsZCB0byBpbmRleCBpbiBhbGwgZG9jdW1lbnRzLlxuICogQHBhcmFtIHtvYmplY3R9IGF0dHJpYnV0ZXMgLSBPcHRpb25hbCBhdHRyaWJ1dGVzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGZpZWxkLlxuICogQHBhcmFtIHtudW1iZXJ9IFthdHRyaWJ1dGVzLmJvb3N0PTFdIC0gQm9vc3QgYXBwbGllZCB0byBhbGwgdGVybXMgd2l0aGluIHRoaXMgZmllbGQuXG4gKiBAcGFyYW0ge2ZpZWxkRXh0cmFjdG9yfSBbYXR0cmlidXRlcy5leHRyYWN0b3JdIC0gRnVuY3Rpb24gdG8gZXh0cmFjdCBhIGZpZWxkIGZyb20gYSBkb2N1bWVudC5cbiAqIEB0aHJvd3Mge1JhbmdlRXJyb3J9IGZpZWxkTmFtZSBjYW5ub3QgY29udGFpbiB1bnN1cHBvcnRlZCBjaGFyYWN0ZXJzICcvJ1xuICovXG5sdW5yLkJ1aWxkZXIucHJvdG90eXBlLmZpZWxkID0gZnVuY3Rpb24gKGZpZWxkTmFtZSwgYXR0cmlidXRlcykge1xuICBpZiAoL1xcLy8udGVzdChmaWVsZE5hbWUpKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IgKFwiRmllbGQgJ1wiICsgZmllbGROYW1lICsgXCInIGNvbnRhaW5zIGlsbGVnYWwgY2hhcmFjdGVyICcvJ1wiKVxuICB9XG5cbiAgdGhpcy5fZmllbGRzW2ZpZWxkTmFtZV0gPSBhdHRyaWJ1dGVzIHx8IHt9XG59XG5cbi8qKlxuICogQSBwYXJhbWV0ZXIgdG8gdHVuZSB0aGUgYW1vdW50IG9mIGZpZWxkIGxlbmd0aCBub3JtYWxpc2F0aW9uIHRoYXQgaXMgYXBwbGllZCB3aGVuXG4gKiBjYWxjdWxhdGluZyByZWxldmFuY2Ugc2NvcmVzLiBBIHZhbHVlIG9mIDAgd2lsbCBjb21wbGV0ZWx5IGRpc2FibGUgYW55IG5vcm1hbGlzYXRpb25cbiAqIGFuZCBhIHZhbHVlIG9mIDEgd2lsbCBmdWxseSBub3JtYWxpc2UgZmllbGQgbGVuZ3Rocy4gVGhlIGRlZmF1bHQgaXMgMC43NS4gVmFsdWVzIG9mIGJcbiAqIHdpbGwgYmUgY2xhbXBlZCB0byB0aGUgcmFuZ2UgMCAtIDEuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IG51bWJlciAtIFRoZSB2YWx1ZSB0byBzZXQgZm9yIHRoaXMgdHVuaW5nIHBhcmFtZXRlci5cbiAqL1xubHVuci5CdWlsZGVyLnByb3RvdHlwZS5iID0gZnVuY3Rpb24gKG51bWJlcikge1xuICBpZiAobnVtYmVyIDwgMCkge1xuICAgIHRoaXMuX2IgPSAwXG4gIH0gZWxzZSBpZiAobnVtYmVyID4gMSkge1xuICAgIHRoaXMuX2IgPSAxXG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fYiA9IG51bWJlclxuICB9XG59XG5cbi8qKlxuICogQSBwYXJhbWV0ZXIgdGhhdCBjb250cm9scyB0aGUgc3BlZWQgYXQgd2hpY2ggYSByaXNlIGluIHRlcm0gZnJlcXVlbmN5IHJlc3VsdHMgaW4gdGVybVxuICogZnJlcXVlbmN5IHNhdHVyYXRpb24uIFRoZSBkZWZhdWx0IHZhbHVlIGlzIDEuMi4gU2V0dGluZyB0aGlzIHRvIGEgaGlnaGVyIHZhbHVlIHdpbGwgZ2l2ZVxuICogc2xvd2VyIHNhdHVyYXRpb24gbGV2ZWxzLCBhIGxvd2VyIHZhbHVlIHdpbGwgcmVzdWx0IGluIHF1aWNrZXIgc2F0dXJhdGlvbi5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gbnVtYmVyIC0gVGhlIHZhbHVlIHRvIHNldCBmb3IgdGhpcyB0dW5pbmcgcGFyYW1ldGVyLlxuICovXG5sdW5yLkJ1aWxkZXIucHJvdG90eXBlLmsxID0gZnVuY3Rpb24gKG51bWJlcikge1xuICB0aGlzLl9rMSA9IG51bWJlclxufVxuXG4vKipcbiAqIEFkZHMgYSBkb2N1bWVudCB0byB0aGUgaW5kZXguXG4gKlxuICogQmVmb3JlIGFkZGluZyBmaWVsZHMgdG8gdGhlIGluZGV4IHRoZSBpbmRleCBzaG91bGQgaGF2ZSBiZWVuIGZ1bGx5IHNldHVwLCB3aXRoIHRoZSBkb2N1bWVudFxuICogcmVmIGFuZCBhbGwgZmllbGRzIHRvIGluZGV4IGFscmVhZHkgaGF2aW5nIGJlZW4gc3BlY2lmaWVkLlxuICpcbiAqIFRoZSBkb2N1bWVudCBtdXN0IGhhdmUgYSBmaWVsZCBuYW1lIGFzIHNwZWNpZmllZCBieSB0aGUgcmVmIChieSBkZWZhdWx0IHRoaXMgaXMgJ2lkJykgYW5kXG4gKiBpdCBzaG91bGQgaGF2ZSBhbGwgZmllbGRzIGRlZmluZWQgZm9yIGluZGV4aW5nLCB0aG91Z2ggbnVsbCBvciB1bmRlZmluZWQgdmFsdWVzIHdpbGwgbm90XG4gKiBjYXVzZSBlcnJvcnMuXG4gKlxuICogRW50aXJlIGRvY3VtZW50cyBjYW4gYmUgYm9vc3RlZCBhdCBidWlsZCB0aW1lLiBBcHBseWluZyBhIGJvb3N0IHRvIGEgZG9jdW1lbnQgaW5kaWNhdGVzIHRoYXRcbiAqIHRoaXMgZG9jdW1lbnQgc2hvdWxkIHJhbmsgaGlnaGVyIGluIHNlYXJjaCByZXN1bHRzIHRoYW4gb3RoZXIgZG9jdW1lbnRzLlxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBkb2MgLSBUaGUgZG9jdW1lbnQgdG8gYWRkIHRvIHRoZSBpbmRleC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBhdHRyaWJ1dGVzIC0gT3B0aW9uYWwgYXR0cmlidXRlcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBkb2N1bWVudC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXR0cmlidXRlcy5ib29zdD0xXSAtIEJvb3N0IGFwcGxpZWQgdG8gYWxsIHRlcm1zIHdpdGhpbiB0aGlzIGRvY3VtZW50LlxuICovXG5sdW5yLkJ1aWxkZXIucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChkb2MsIGF0dHJpYnV0ZXMpIHtcbiAgdmFyIGRvY1JlZiA9IGRvY1t0aGlzLl9yZWZdLFxuICAgICAgZmllbGRzID0gT2JqZWN0LmtleXModGhpcy5fZmllbGRzKVxuXG4gIHRoaXMuX2RvY3VtZW50c1tkb2NSZWZdID0gYXR0cmlidXRlcyB8fCB7fVxuICB0aGlzLmRvY3VtZW50Q291bnQgKz0gMVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGZpZWxkTmFtZSA9IGZpZWxkc1tpXSxcbiAgICAgICAgZXh0cmFjdG9yID0gdGhpcy5fZmllbGRzW2ZpZWxkTmFtZV0uZXh0cmFjdG9yLFxuICAgICAgICBmaWVsZCA9IGV4dHJhY3RvciA/IGV4dHJhY3Rvcihkb2MpIDogZG9jW2ZpZWxkTmFtZV0sXG4gICAgICAgIHRva2VucyA9IHRoaXMudG9rZW5pemVyKGZpZWxkLCB7XG4gICAgICAgICAgZmllbGRzOiBbZmllbGROYW1lXVxuICAgICAgICB9KSxcbiAgICAgICAgdGVybXMgPSB0aGlzLnBpcGVsaW5lLnJ1bih0b2tlbnMpLFxuICAgICAgICBmaWVsZFJlZiA9IG5ldyBsdW5yLkZpZWxkUmVmIChkb2NSZWYsIGZpZWxkTmFtZSksXG4gICAgICAgIGZpZWxkVGVybXMgPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgICB0aGlzLmZpZWxkVGVybUZyZXF1ZW5jaWVzW2ZpZWxkUmVmXSA9IGZpZWxkVGVybXNcbiAgICB0aGlzLmZpZWxkTGVuZ3Roc1tmaWVsZFJlZl0gPSAwXG5cbiAgICAvLyBzdG9yZSB0aGUgbGVuZ3RoIG9mIHRoaXMgZmllbGQgZm9yIHRoaXMgZG9jdW1lbnRcbiAgICB0aGlzLmZpZWxkTGVuZ3Roc1tmaWVsZFJlZl0gKz0gdGVybXMubGVuZ3RoXG5cbiAgICAvLyBjYWxjdWxhdGUgdGVybSBmcmVxdWVuY2llcyBmb3IgdGhpcyBmaWVsZFxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgdGVybXMubGVuZ3RoOyBqKyspIHtcbiAgICAgIHZhciB0ZXJtID0gdGVybXNbal1cblxuICAgICAgaWYgKGZpZWxkVGVybXNbdGVybV0gPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGZpZWxkVGVybXNbdGVybV0gPSAwXG4gICAgICB9XG5cbiAgICAgIGZpZWxkVGVybXNbdGVybV0gKz0gMVxuXG4gICAgICAvLyBhZGQgdG8gaW52ZXJ0ZWQgaW5kZXhcbiAgICAgIC8vIGNyZWF0ZSBhbiBpbml0aWFsIHBvc3RpbmcgaWYgb25lIGRvZXNuJ3QgZXhpc3RcbiAgICAgIGlmICh0aGlzLmludmVydGVkSW5kZXhbdGVybV0gPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhciBwb3N0aW5nID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuICAgICAgICBwb3N0aW5nW1wiX2luZGV4XCJdID0gdGhpcy50ZXJtSW5kZXhcbiAgICAgICAgdGhpcy50ZXJtSW5kZXggKz0gMVxuXG4gICAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgZmllbGRzLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgcG9zdGluZ1tmaWVsZHNba11dID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pbnZlcnRlZEluZGV4W3Rlcm1dID0gcG9zdGluZ1xuICAgICAgfVxuXG4gICAgICAvLyBhZGQgYW4gZW50cnkgZm9yIHRoaXMgdGVybS9maWVsZE5hbWUvZG9jUmVmIHRvIHRoZSBpbnZlcnRlZEluZGV4XG4gICAgICBpZiAodGhpcy5pbnZlcnRlZEluZGV4W3Rlcm1dW2ZpZWxkTmFtZV1bZG9jUmVmXSA9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5pbnZlcnRlZEluZGV4W3Rlcm1dW2ZpZWxkTmFtZV1bZG9jUmVmXSA9IE9iamVjdC5jcmVhdGUobnVsbClcbiAgICAgIH1cblxuICAgICAgLy8gc3RvcmUgYWxsIHdoaXRlbGlzdGVkIG1ldGFkYXRhIGFib3V0IHRoaXMgdG9rZW4gaW4gdGhlXG4gICAgICAvLyBpbnZlcnRlZCBpbmRleFxuICAgICAgZm9yICh2YXIgbCA9IDA7IGwgPCB0aGlzLm1ldGFkYXRhV2hpdGVsaXN0Lmxlbmd0aDsgbCsrKSB7XG4gICAgICAgIHZhciBtZXRhZGF0YUtleSA9IHRoaXMubWV0YWRhdGFXaGl0ZWxpc3RbbF0sXG4gICAgICAgICAgICBtZXRhZGF0YSA9IHRlcm0ubWV0YWRhdGFbbWV0YWRhdGFLZXldXG5cbiAgICAgICAgaWYgKHRoaXMuaW52ZXJ0ZWRJbmRleFt0ZXJtXVtmaWVsZE5hbWVdW2RvY1JlZl1bbWV0YWRhdGFLZXldID09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRoaXMuaW52ZXJ0ZWRJbmRleFt0ZXJtXVtmaWVsZE5hbWVdW2RvY1JlZl1bbWV0YWRhdGFLZXldID0gW11cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuaW52ZXJ0ZWRJbmRleFt0ZXJtXVtmaWVsZE5hbWVdW2RvY1JlZl1bbWV0YWRhdGFLZXldLnB1c2gobWV0YWRhdGEpXG4gICAgICB9XG4gICAgfVxuXG4gIH1cbn1cblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBhdmVyYWdlIGRvY3VtZW50IGxlbmd0aCBmb3IgdGhpcyBpbmRleFxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmx1bnIuQnVpbGRlci5wcm90b3R5cGUuY2FsY3VsYXRlQXZlcmFnZUZpZWxkTGVuZ3RocyA9IGZ1bmN0aW9uICgpIHtcblxuICB2YXIgZmllbGRSZWZzID0gT2JqZWN0LmtleXModGhpcy5maWVsZExlbmd0aHMpLFxuICAgICAgbnVtYmVyT2ZGaWVsZHMgPSBmaWVsZFJlZnMubGVuZ3RoLFxuICAgICAgYWNjdW11bGF0b3IgPSB7fSxcbiAgICAgIGRvY3VtZW50c1dpdGhGaWVsZCA9IHt9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW1iZXJPZkZpZWxkczsgaSsrKSB7XG4gICAgdmFyIGZpZWxkUmVmID0gbHVuci5GaWVsZFJlZi5mcm9tU3RyaW5nKGZpZWxkUmVmc1tpXSksXG4gICAgICAgIGZpZWxkID0gZmllbGRSZWYuZmllbGROYW1lXG5cbiAgICBkb2N1bWVudHNXaXRoRmllbGRbZmllbGRdIHx8IChkb2N1bWVudHNXaXRoRmllbGRbZmllbGRdID0gMClcbiAgICBkb2N1bWVudHNXaXRoRmllbGRbZmllbGRdICs9IDFcblxuICAgIGFjY3VtdWxhdG9yW2ZpZWxkXSB8fCAoYWNjdW11bGF0b3JbZmllbGRdID0gMClcbiAgICBhY2N1bXVsYXRvcltmaWVsZF0gKz0gdGhpcy5maWVsZExlbmd0aHNbZmllbGRSZWZdXG4gIH1cblxuICB2YXIgZmllbGRzID0gT2JqZWN0LmtleXModGhpcy5fZmllbGRzKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGZpZWxkTmFtZSA9IGZpZWxkc1tpXVxuICAgIGFjY3VtdWxhdG9yW2ZpZWxkTmFtZV0gPSBhY2N1bXVsYXRvcltmaWVsZE5hbWVdIC8gZG9jdW1lbnRzV2l0aEZpZWxkW2ZpZWxkTmFtZV1cbiAgfVxuXG4gIHRoaXMuYXZlcmFnZUZpZWxkTGVuZ3RoID0gYWNjdW11bGF0b3Jcbn1cblxuLyoqXG4gKiBCdWlsZHMgYSB2ZWN0b3Igc3BhY2UgbW9kZWwgb2YgZXZlcnkgZG9jdW1lbnQgdXNpbmcgbHVuci5WZWN0b3JcbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5sdW5yLkJ1aWxkZXIucHJvdG90eXBlLmNyZWF0ZUZpZWxkVmVjdG9ycyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGZpZWxkVmVjdG9ycyA9IHt9LFxuICAgICAgZmllbGRSZWZzID0gT2JqZWN0LmtleXModGhpcy5maWVsZFRlcm1GcmVxdWVuY2llcyksXG4gICAgICBmaWVsZFJlZnNMZW5ndGggPSBmaWVsZFJlZnMubGVuZ3RoLFxuICAgICAgdGVybUlkZkNhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZmllbGRSZWZzTGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZmllbGRSZWYgPSBsdW5yLkZpZWxkUmVmLmZyb21TdHJpbmcoZmllbGRSZWZzW2ldKSxcbiAgICAgICAgZmllbGROYW1lID0gZmllbGRSZWYuZmllbGROYW1lLFxuICAgICAgICBmaWVsZExlbmd0aCA9IHRoaXMuZmllbGRMZW5ndGhzW2ZpZWxkUmVmXSxcbiAgICAgICAgZmllbGRWZWN0b3IgPSBuZXcgbHVuci5WZWN0b3IsXG4gICAgICAgIHRlcm1GcmVxdWVuY2llcyA9IHRoaXMuZmllbGRUZXJtRnJlcXVlbmNpZXNbZmllbGRSZWZdLFxuICAgICAgICB0ZXJtcyA9IE9iamVjdC5rZXlzKHRlcm1GcmVxdWVuY2llcyksXG4gICAgICAgIHRlcm1zTGVuZ3RoID0gdGVybXMubGVuZ3RoXG5cblxuICAgIHZhciBmaWVsZEJvb3N0ID0gdGhpcy5fZmllbGRzW2ZpZWxkTmFtZV0uYm9vc3QgfHwgMSxcbiAgICAgICAgZG9jQm9vc3QgPSB0aGlzLl9kb2N1bWVudHNbZmllbGRSZWYuZG9jUmVmXS5ib29zdCB8fCAxXG5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IHRlcm1zTGVuZ3RoOyBqKyspIHtcbiAgICAgIHZhciB0ZXJtID0gdGVybXNbal0sXG4gICAgICAgICAgdGYgPSB0ZXJtRnJlcXVlbmNpZXNbdGVybV0sXG4gICAgICAgICAgdGVybUluZGV4ID0gdGhpcy5pbnZlcnRlZEluZGV4W3Rlcm1dLl9pbmRleCxcbiAgICAgICAgICBpZGYsIHNjb3JlLCBzY29yZVdpdGhQcmVjaXNpb25cblxuICAgICAgaWYgKHRlcm1JZGZDYWNoZVt0ZXJtXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlkZiA9IGx1bnIuaWRmKHRoaXMuaW52ZXJ0ZWRJbmRleFt0ZXJtXSwgdGhpcy5kb2N1bWVudENvdW50KVxuICAgICAgICB0ZXJtSWRmQ2FjaGVbdGVybV0gPSBpZGZcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlkZiA9IHRlcm1JZGZDYWNoZVt0ZXJtXVxuICAgICAgfVxuXG4gICAgICBzY29yZSA9IGlkZiAqICgodGhpcy5fazEgKyAxKSAqIHRmKSAvICh0aGlzLl9rMSAqICgxIC0gdGhpcy5fYiArIHRoaXMuX2IgKiAoZmllbGRMZW5ndGggLyB0aGlzLmF2ZXJhZ2VGaWVsZExlbmd0aFtmaWVsZE5hbWVdKSkgKyB0ZilcbiAgICAgIHNjb3JlICo9IGZpZWxkQm9vc3RcbiAgICAgIHNjb3JlICo9IGRvY0Jvb3N0XG4gICAgICBzY29yZVdpdGhQcmVjaXNpb24gPSBNYXRoLnJvdW5kKHNjb3JlICogMTAwMCkgLyAxMDAwXG4gICAgICAvLyBDb252ZXJ0cyAxLjIzNDU2Nzg5IHRvIDEuMjM0LlxuICAgICAgLy8gUmVkdWNpbmcgdGhlIHByZWNpc2lvbiBzbyB0aGF0IHRoZSB2ZWN0b3JzIHRha2UgdXAgbGVzc1xuICAgICAgLy8gc3BhY2Ugd2hlbiBzZXJpYWxpc2VkLiBEb2luZyBpdCBub3cgc28gdGhhdCB0aGV5IGJlaGF2ZVxuICAgICAgLy8gdGhlIHNhbWUgYmVmb3JlIGFuZCBhZnRlciBzZXJpYWxpc2F0aW9uLiBBbHNvLCB0aGlzIGlzXG4gICAgICAvLyB0aGUgZmFzdGVzdCBhcHByb2FjaCB0byByZWR1Y2luZyBhIG51bWJlcidzIHByZWNpc2lvbiBpblxuICAgICAgLy8gSmF2YVNjcmlwdC5cblxuICAgICAgZmllbGRWZWN0b3IuaW5zZXJ0KHRlcm1JbmRleCwgc2NvcmVXaXRoUHJlY2lzaW9uKVxuICAgIH1cblxuICAgIGZpZWxkVmVjdG9yc1tmaWVsZFJlZl0gPSBmaWVsZFZlY3RvclxuICB9XG5cbiAgdGhpcy5maWVsZFZlY3RvcnMgPSBmaWVsZFZlY3RvcnNcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgdG9rZW4gc2V0IG9mIGFsbCB0b2tlbnMgaW4gdGhlIGluZGV4IHVzaW5nIGx1bnIuVG9rZW5TZXRcbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5sdW5yLkJ1aWxkZXIucHJvdG90eXBlLmNyZWF0ZVRva2VuU2V0ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnRva2VuU2V0ID0gbHVuci5Ub2tlblNldC5mcm9tQXJyYXkoXG4gICAgT2JqZWN0LmtleXModGhpcy5pbnZlcnRlZEluZGV4KS5zb3J0KClcbiAgKVxufVxuXG4vKipcbiAqIEJ1aWxkcyB0aGUgaW5kZXgsIGNyZWF0aW5nIGFuIGluc3RhbmNlIG9mIGx1bnIuSW5kZXguXG4gKlxuICogVGhpcyBjb21wbGV0ZXMgdGhlIGluZGV4aW5nIHByb2Nlc3MgYW5kIHNob3VsZCBvbmx5IGJlIGNhbGxlZFxuICogb25jZSBhbGwgZG9jdW1lbnRzIGhhdmUgYmVlbiBhZGRlZCB0byB0aGUgaW5kZXguXG4gKlxuICogQHJldHVybnMge2x1bnIuSW5kZXh9XG4gKi9cbmx1bnIuQnVpbGRlci5wcm90b3R5cGUuYnVpbGQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuY2FsY3VsYXRlQXZlcmFnZUZpZWxkTGVuZ3RocygpXG4gIHRoaXMuY3JlYXRlRmllbGRWZWN0b3JzKClcbiAgdGhpcy5jcmVhdGVUb2tlblNldCgpXG5cbiAgcmV0dXJuIG5ldyBsdW5yLkluZGV4KHtcbiAgICBpbnZlcnRlZEluZGV4OiB0aGlzLmludmVydGVkSW5kZXgsXG4gICAgZmllbGRWZWN0b3JzOiB0aGlzLmZpZWxkVmVjdG9ycyxcbiAgICB0b2tlblNldDogdGhpcy50b2tlblNldCxcbiAgICBmaWVsZHM6IE9iamVjdC5rZXlzKHRoaXMuX2ZpZWxkcyksXG4gICAgcGlwZWxpbmU6IHRoaXMuc2VhcmNoUGlwZWxpbmVcbiAgfSlcbn1cblxuLyoqXG4gKiBBcHBsaWVzIGEgcGx1Z2luIHRvIHRoZSBpbmRleCBidWlsZGVyLlxuICpcbiAqIEEgcGx1Z2luIGlzIGEgZnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2l0aCB0aGUgaW5kZXggYnVpbGRlciBhcyBpdHMgY29udGV4dC5cbiAqIFBsdWdpbnMgY2FuIGJlIHVzZWQgdG8gY3VzdG9taXNlIG9yIGV4dGVuZCB0aGUgYmVoYXZpb3VyIG9mIHRoZSBpbmRleFxuICogaW4gc29tZSB3YXkuIEEgcGx1Z2luIGlzIGp1c3QgYSBmdW5jdGlvbiwgdGhhdCBlbmNhcHN1bGF0ZWQgdGhlIGN1c3RvbVxuICogYmVoYXZpb3VyIHRoYXQgc2hvdWxkIGJlIGFwcGxpZWQgd2hlbiBidWlsZGluZyB0aGUgaW5kZXguXG4gKlxuICogVGhlIHBsdWdpbiBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCB3aXRoIHRoZSBpbmRleCBidWlsZGVyIGFzIGl0cyBhcmd1bWVudCwgYWRkaXRpb25hbFxuICogYXJndW1lbnRzIGNhbiBhbHNvIGJlIHBhc3NlZCB3aGVuIGNhbGxpbmcgdXNlLiBUaGUgZnVuY3Rpb24gd2lsbCBiZSBjYWxsZWRcbiAqIHdpdGggdGhlIGluZGV4IGJ1aWxkZXIgYXMgaXRzIGNvbnRleHQuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gcGx1Z2luIFRoZSBwbHVnaW4gdG8gYXBwbHkuXG4gKi9cbmx1bnIuQnVpbGRlci5wcm90b3R5cGUudXNlID0gZnVuY3Rpb24gKGZuKSB7XG4gIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxuICBhcmdzLnVuc2hpZnQodGhpcylcbiAgZm4uYXBwbHkodGhpcywgYXJncylcbn1cbi8qKlxuICogQ29udGFpbnMgYW5kIGNvbGxlY3RzIG1ldGFkYXRhIGFib3V0IGEgbWF0Y2hpbmcgZG9jdW1lbnQuXG4gKiBBIHNpbmdsZSBpbnN0YW5jZSBvZiBsdW5yLk1hdGNoRGF0YSBpcyByZXR1cm5lZCBhcyBwYXJ0IG9mIGV2ZXJ5XG4gKiBsdW5yLkluZGV4flJlc3VsdC5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXJtIC0gVGhlIHRlcm0gdGhpcyBtYXRjaCBkYXRhIGlzIGFzc29jaWF0ZWQgd2l0aFxuICogQHBhcmFtIHtzdHJpbmd9IGZpZWxkIC0gVGhlIGZpZWxkIGluIHdoaWNoIHRoZSB0ZXJtIHdhcyBmb3VuZFxuICogQHBhcmFtIHtvYmplY3R9IG1ldGFkYXRhIC0gVGhlIG1ldGFkYXRhIHJlY29yZGVkIGFib3V0IHRoaXMgdGVybSBpbiB0aGlzIGZpZWxkXG4gKiBAcHJvcGVydHkge29iamVjdH0gbWV0YWRhdGEgLSBBIGNsb25lZCBjb2xsZWN0aW9uIG9mIG1ldGFkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGRvY3VtZW50LlxuICogQHNlZSB7QGxpbmsgbHVuci5JbmRleH5SZXN1bHR9XG4gKi9cbmx1bnIuTWF0Y2hEYXRhID0gZnVuY3Rpb24gKHRlcm0sIGZpZWxkLCBtZXRhZGF0YSkge1xuICB2YXIgY2xvbmVkTWV0YWRhdGEgPSBPYmplY3QuY3JlYXRlKG51bGwpLFxuICAgICAgbWV0YWRhdGFLZXlzID0gT2JqZWN0LmtleXMobWV0YWRhdGEgfHwge30pXG5cbiAgLy8gQ2xvbmluZyB0aGUgbWV0YWRhdGEgdG8gcHJldmVudCB0aGUgb3JpZ2luYWxcbiAgLy8gYmVpbmcgbXV0YXRlZCBkdXJpbmcgbWF0Y2ggZGF0YSBjb21iaW5hdGlvbi5cbiAgLy8gTWV0YWRhdGEgaXMga2VwdCBpbiBhbiBhcnJheSB3aXRoaW4gdGhlIGludmVydGVkXG4gIC8vIGluZGV4IHNvIGNsb25pbmcgdGhlIGRhdGEgY2FuIGJlIGRvbmUgd2l0aFxuICAvLyBBcnJheSNzbGljZVxuICBmb3IgKHZhciBpID0gMDsgaSA8IG1ldGFkYXRhS2V5cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBrZXkgPSBtZXRhZGF0YUtleXNbaV1cbiAgICBjbG9uZWRNZXRhZGF0YVtrZXldID0gbWV0YWRhdGFba2V5XS5zbGljZSgpXG4gIH1cblxuICB0aGlzLm1ldGFkYXRhID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuXG4gIGlmICh0ZXJtICE9PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzLm1ldGFkYXRhW3Rlcm1dID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuICAgIHRoaXMubWV0YWRhdGFbdGVybV1bZmllbGRdID0gY2xvbmVkTWV0YWRhdGFcbiAgfVxufVxuXG4vKipcbiAqIEFuIGluc3RhbmNlIG9mIGx1bnIuTWF0Y2hEYXRhIHdpbGwgYmUgY3JlYXRlZCBmb3IgZXZlcnkgdGVybSB0aGF0IG1hdGNoZXMgYVxuICogZG9jdW1lbnQuIEhvd2V2ZXIgb25seSBvbmUgaW5zdGFuY2UgaXMgcmVxdWlyZWQgaW4gYSBsdW5yLkluZGV4flJlc3VsdC4gVGhpc1xuICogbWV0aG9kIGNvbWJpbmVzIG1ldGFkYXRhIGZyb20gYW5vdGhlciBpbnN0YW5jZSBvZiBsdW5yLk1hdGNoRGF0YSB3aXRoIHRoaXNcbiAqIG9iamVjdHMgbWV0YWRhdGEuXG4gKlxuICogQHBhcmFtIHtsdW5yLk1hdGNoRGF0YX0gb3RoZXJNYXRjaERhdGEgLSBBbm90aGVyIGluc3RhbmNlIG9mIG1hdGNoIGRhdGEgdG8gbWVyZ2Ugd2l0aCB0aGlzIG9uZS5cbiAqIEBzZWUge0BsaW5rIGx1bnIuSW5kZXh+UmVzdWx0fVxuICovXG5sdW5yLk1hdGNoRGF0YS5wcm90b3R5cGUuY29tYmluZSA9IGZ1bmN0aW9uIChvdGhlck1hdGNoRGF0YSkge1xuICB2YXIgdGVybXMgPSBPYmplY3Qua2V5cyhvdGhlck1hdGNoRGF0YS5tZXRhZGF0YSlcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRlcm1zLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHRlcm0gPSB0ZXJtc1tpXSxcbiAgICAgICAgZmllbGRzID0gT2JqZWN0LmtleXMob3RoZXJNYXRjaERhdGEubWV0YWRhdGFbdGVybV0pXG5cbiAgICBpZiAodGhpcy5tZXRhZGF0YVt0ZXJtXSA9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMubWV0YWRhdGFbdGVybV0gPSBPYmplY3QuY3JlYXRlKG51bGwpXG4gICAgfVxuXG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBmaWVsZHMubGVuZ3RoOyBqKyspIHtcbiAgICAgIHZhciBmaWVsZCA9IGZpZWxkc1tqXSxcbiAgICAgICAgICBrZXlzID0gT2JqZWN0LmtleXMob3RoZXJNYXRjaERhdGEubWV0YWRhdGFbdGVybV1bZmllbGRdKVxuXG4gICAgICBpZiAodGhpcy5tZXRhZGF0YVt0ZXJtXVtmaWVsZF0gPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMubWV0YWRhdGFbdGVybV1bZmllbGRdID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuICAgICAgfVxuXG4gICAgICBmb3IgKHZhciBrID0gMDsgayA8IGtleXMubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNba11cblxuICAgICAgICBpZiAodGhpcy5tZXRhZGF0YVt0ZXJtXVtmaWVsZF1ba2V5XSA9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aGlzLm1ldGFkYXRhW3Rlcm1dW2ZpZWxkXVtrZXldID0gb3RoZXJNYXRjaERhdGEubWV0YWRhdGFbdGVybV1bZmllbGRdW2tleV1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLm1ldGFkYXRhW3Rlcm1dW2ZpZWxkXVtrZXldID0gdGhpcy5tZXRhZGF0YVt0ZXJtXVtmaWVsZF1ba2V5XS5jb25jYXQob3RoZXJNYXRjaERhdGEubWV0YWRhdGFbdGVybV1bZmllbGRdW2tleV0pXG4gICAgICAgIH1cblxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEFkZCBtZXRhZGF0YSBmb3IgYSB0ZXJtL2ZpZWxkIHBhaXIgdG8gdGhpcyBpbnN0YW5jZSBvZiBtYXRjaCBkYXRhLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXJtIC0gVGhlIHRlcm0gdGhpcyBtYXRjaCBkYXRhIGlzIGFzc29jaWF0ZWQgd2l0aFxuICogQHBhcmFtIHtzdHJpbmd9IGZpZWxkIC0gVGhlIGZpZWxkIGluIHdoaWNoIHRoZSB0ZXJtIHdhcyBmb3VuZFxuICogQHBhcmFtIHtvYmplY3R9IG1ldGFkYXRhIC0gVGhlIG1ldGFkYXRhIHJlY29yZGVkIGFib3V0IHRoaXMgdGVybSBpbiB0aGlzIGZpZWxkXG4gKi9cbmx1bnIuTWF0Y2hEYXRhLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAodGVybSwgZmllbGQsIG1ldGFkYXRhKSB7XG4gIGlmICghKHRlcm0gaW4gdGhpcy5tZXRhZGF0YSkpIHtcbiAgICB0aGlzLm1ldGFkYXRhW3Rlcm1dID0gT2JqZWN0LmNyZWF0ZShudWxsKVxuICAgIHRoaXMubWV0YWRhdGFbdGVybV1bZmllbGRdID0gbWV0YWRhdGFcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmICghKGZpZWxkIGluIHRoaXMubWV0YWRhdGFbdGVybV0pKSB7XG4gICAgdGhpcy5tZXRhZGF0YVt0ZXJtXVtmaWVsZF0gPSBtZXRhZGF0YVxuICAgIHJldHVyblxuICB9XG5cbiAgdmFyIG1ldGFkYXRhS2V5cyA9IE9iamVjdC5rZXlzKG1ldGFkYXRhKVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbWV0YWRhdGFLZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGtleSA9IG1ldGFkYXRhS2V5c1tpXVxuXG4gICAgaWYgKGtleSBpbiB0aGlzLm1ldGFkYXRhW3Rlcm1dW2ZpZWxkXSkge1xuICAgICAgdGhpcy5tZXRhZGF0YVt0ZXJtXVtmaWVsZF1ba2V5XSA9IHRoaXMubWV0YWRhdGFbdGVybV1bZmllbGRdW2tleV0uY29uY2F0KG1ldGFkYXRhW2tleV0pXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubWV0YWRhdGFbdGVybV1bZmllbGRdW2tleV0gPSBtZXRhZGF0YVtrZXldXG4gICAgfVxuICB9XG59XG4vKipcbiAqIEEgbHVuci5RdWVyeSBwcm92aWRlcyBhIHByb2dyYW1tYXRpYyB3YXkgb2YgZGVmaW5pbmcgcXVlcmllcyB0byBiZSBwZXJmb3JtZWRcbiAqIGFnYWluc3QgYSB7QGxpbmsgbHVuci5JbmRleH0uXG4gKlxuICogUHJlZmVyIGNvbnN0cnVjdGluZyBhIGx1bnIuUXVlcnkgdXNpbmcgdGhlIHtAbGluayBsdW5yLkluZGV4I3F1ZXJ5fSBtZXRob2RcbiAqIHNvIHRoZSBxdWVyeSBvYmplY3QgaXMgcHJlLWluaXRpYWxpemVkIHdpdGggdGhlIHJpZ2h0IGluZGV4IGZpZWxkcy5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwcm9wZXJ0eSB7bHVuci5RdWVyeX5DbGF1c2VbXX0gY2xhdXNlcyAtIEFuIGFycmF5IG9mIHF1ZXJ5IGNsYXVzZXMuXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBhbGxGaWVsZHMgLSBBbiBhcnJheSBvZiBhbGwgYXZhaWxhYmxlIGZpZWxkcyBpbiBhIGx1bnIuSW5kZXguXG4gKi9cbmx1bnIuUXVlcnkgPSBmdW5jdGlvbiAoYWxsRmllbGRzKSB7XG4gIHRoaXMuY2xhdXNlcyA9IFtdXG4gIHRoaXMuYWxsRmllbGRzID0gYWxsRmllbGRzXG59XG5cbi8qKlxuICogQ29uc3RhbnRzIGZvciBpbmRpY2F0aW5nIHdoYXQga2luZCBvZiBhdXRvbWF0aWMgd2lsZGNhcmQgaW5zZXJ0aW9uIHdpbGwgYmUgdXNlZCB3aGVuIGNvbnN0cnVjdGluZyBhIHF1ZXJ5IGNsYXVzZS5cbiAqXG4gKiBUaGlzIGFsbG93cyB3aWxkY2FyZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGJlZ2lubmluZyBhbmQgZW5kIG9mIGEgdGVybSB3aXRob3V0IGhhdmluZyB0byBtYW51YWxseSBkbyBhbnkgc3RyaW5nXG4gKiBjb25jYXRlbmF0aW9uLlxuICpcbiAqIFRoZSB3aWxkY2FyZCBjb25zdGFudHMgY2FuIGJlIGJpdHdpc2UgY29tYmluZWQgdG8gc2VsZWN0IGJvdGggbGVhZGluZyBhbmQgdHJhaWxpbmcgd2lsZGNhcmRzLlxuICpcbiAqIEBjb25zdGFudFxuICogQGRlZmF1bHRcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB3aWxkY2FyZC5OT05FIC0gVGhlIHRlcm0gd2lsbCBoYXZlIG5vIHdpbGRjYXJkcyBpbnNlcnRlZCwgdGhpcyBpcyB0aGUgZGVmYXVsdCBiZWhhdmlvdXJcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB3aWxkY2FyZC5MRUFESU5HIC0gUHJlcGVuZCB0aGUgdGVybSB3aXRoIGEgd2lsZGNhcmQsIHVubGVzcyBhIGxlYWRpbmcgd2lsZGNhcmQgYWxyZWFkeSBleGlzdHNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB3aWxkY2FyZC5UUkFJTElORyAtIEFwcGVuZCBhIHdpbGRjYXJkIHRvIHRoZSB0ZXJtLCB1bmxlc3MgYSB0cmFpbGluZyB3aWxkY2FyZCBhbHJlYWR5IGV4aXN0c1xuICogQHNlZSBsdW5yLlF1ZXJ5fkNsYXVzZVxuICogQHNlZSBsdW5yLlF1ZXJ5I2NsYXVzZVxuICogQHNlZSBsdW5yLlF1ZXJ5I3Rlcm1cbiAqIEBleGFtcGxlIDxjYXB0aW9uPnF1ZXJ5IHRlcm0gd2l0aCB0cmFpbGluZyB3aWxkY2FyZDwvY2FwdGlvbj5cbiAqIHF1ZXJ5LnRlcm0oJ2ZvbycsIHsgd2lsZGNhcmQ6IGx1bnIuUXVlcnkud2lsZGNhcmQuVFJBSUxJTkcgfSlcbiAqIEBleGFtcGxlIDxjYXB0aW9uPnF1ZXJ5IHRlcm0gd2l0aCBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aWxkY2FyZDwvY2FwdGlvbj5cbiAqIHF1ZXJ5LnRlcm0oJ2ZvbycsIHtcbiAqICAgd2lsZGNhcmQ6IGx1bnIuUXVlcnkud2lsZGNhcmQuTEVBRElORyB8IGx1bnIuUXVlcnkud2lsZGNhcmQuVFJBSUxJTkdcbiAqIH0pXG4gKi9cblxubHVuci5RdWVyeS53aWxkY2FyZCA9IG5ldyBTdHJpbmcgKFwiKlwiKVxubHVuci5RdWVyeS53aWxkY2FyZC5OT05FID0gMFxubHVuci5RdWVyeS53aWxkY2FyZC5MRUFESU5HID0gMVxubHVuci5RdWVyeS53aWxkY2FyZC5UUkFJTElORyA9IDJcblxuLyoqXG4gKiBDb25zdGFudHMgZm9yIGluZGljYXRpbmcgd2hhdCBraW5kIG9mIHByZXNlbmNlIGEgdGVybSBtdXN0IGhhdmUgaW4gbWF0Y2hpbmcgZG9jdW1lbnRzLlxuICpcbiAqIEBjb25zdGFudFxuICogQGVudW0ge251bWJlcn1cbiAqIEBzZWUgbHVuci5RdWVyeX5DbGF1c2VcbiAqIEBzZWUgbHVuci5RdWVyeSNjbGF1c2VcbiAqIEBzZWUgbHVuci5RdWVyeSN0ZXJtXG4gKiBAZXhhbXBsZSA8Y2FwdGlvbj5xdWVyeSB0ZXJtIHdpdGggcmVxdWlyZWQgcHJlc2VuY2U8L2NhcHRpb24+XG4gKiBxdWVyeS50ZXJtKCdmb28nLCB7IHByZXNlbmNlOiBsdW5yLlF1ZXJ5LnByZXNlbmNlLlJFUVVJUkVEIH0pXG4gKi9cbmx1bnIuUXVlcnkucHJlc2VuY2UgPSB7XG4gIC8qKlxuICAgKiBUZXJtJ3MgcHJlc2VuY2UgaW4gYSBkb2N1bWVudCBpcyBvcHRpb25hbCwgdGhpcyBpcyB0aGUgZGVmYXVsdCB2YWx1ZS5cbiAgICovXG4gIE9QVElPTkFMOiAxLFxuXG4gIC8qKlxuICAgKiBUZXJtJ3MgcHJlc2VuY2UgaW4gYSBkb2N1bWVudCBpcyByZXF1aXJlZCwgZG9jdW1lbnRzIHRoYXQgZG8gbm90IGNvbnRhaW5cbiAgICogdGhpcyB0ZXJtIHdpbGwgbm90IGJlIHJldHVybmVkLlxuICAgKi9cbiAgUkVRVUlSRUQ6IDIsXG5cbiAgLyoqXG4gICAqIFRlcm0ncyBwcmVzZW5jZSBpbiBhIGRvY3VtZW50IGlzIHByb2hpYml0ZWQsIGRvY3VtZW50cyB0aGF0IGRvIGNvbnRhaW5cbiAgICogdGhpcyB0ZXJtIHdpbGwgbm90IGJlIHJldHVybmVkLlxuICAgKi9cbiAgUFJPSElCSVRFRDogM1xufVxuXG4vKipcbiAqIEEgc2luZ2xlIGNsYXVzZSBpbiBhIHtAbGluayBsdW5yLlF1ZXJ5fSBjb250YWlucyBhIHRlcm0gYW5kIGRldGFpbHMgb24gaG93IHRvXG4gKiBtYXRjaCB0aGF0IHRlcm0gYWdhaW5zdCBhIHtAbGluayBsdW5yLkluZGV4fS5cbiAqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBsdW5yLlF1ZXJ5fkNsYXVzZVxuICogQHByb3BlcnR5IHtzdHJpbmdbXX0gZmllbGRzIC0gVGhlIGZpZWxkcyBpbiBhbiBpbmRleCB0aGlzIGNsYXVzZSBzaG91bGQgYmUgbWF0Y2hlZCBhZ2FpbnN0LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IFtib29zdD0xXSAtIEFueSBib29zdCB0aGF0IHNob3VsZCBiZSBhcHBsaWVkIHdoZW4gbWF0Y2hpbmcgdGhpcyBjbGF1c2UuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW2VkaXREaXN0YW5jZV0gLSBXaGV0aGVyIHRoZSB0ZXJtIHNob3VsZCBoYXZlIGZ1enp5IG1hdGNoaW5nIGFwcGxpZWQsIGFuZCBob3cgZnV6enkgdGhlIG1hdGNoIHNob3VsZCBiZS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3VzZVBpcGVsaW5lXSAtIFdoZXRoZXIgdGhlIHRlcm0gc2hvdWxkIGJlIHBhc3NlZCB0aHJvdWdoIHRoZSBzZWFyY2ggcGlwZWxpbmUuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3dpbGRjYXJkPWx1bnIuUXVlcnkud2lsZGNhcmQuTk9ORV0gLSBXaGV0aGVyIHRoZSB0ZXJtIHNob3VsZCBoYXZlIHdpbGRjYXJkcyBhcHBlbmRlZCBvciBwcmVwZW5kZWQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3ByZXNlbmNlPWx1bnIuUXVlcnkucHJlc2VuY2UuT1BUSU9OQUxdIC0gVGhlIHRlcm1zIHByZXNlbmNlIGluIGFueSBtYXRjaGluZyBkb2N1bWVudHMuXG4gKi9cblxuLyoqXG4gKiBBZGRzIGEge0BsaW5rIGx1bnIuUXVlcnl+Q2xhdXNlfSB0byB0aGlzIHF1ZXJ5LlxuICpcbiAqIFVubGVzcyB0aGUgY2xhdXNlIGNvbnRhaW5zIHRoZSBmaWVsZHMgdG8gYmUgbWF0Y2hlZCBhbGwgZmllbGRzIHdpbGwgYmUgbWF0Y2hlZC4gSW4gYWRkaXRpb25cbiAqIGEgZGVmYXVsdCBib29zdCBvZiAxIGlzIGFwcGxpZWQgdG8gdGhlIGNsYXVzZS5cbiAqXG4gKiBAcGFyYW0ge2x1bnIuUXVlcnl+Q2xhdXNlfSBjbGF1c2UgLSBUaGUgY2xhdXNlIHRvIGFkZCB0byB0aGlzIHF1ZXJ5LlxuICogQHNlZSBsdW5yLlF1ZXJ5fkNsYXVzZVxuICogQHJldHVybnMge2x1bnIuUXVlcnl9XG4gKi9cbmx1bnIuUXVlcnkucHJvdG90eXBlLmNsYXVzZSA9IGZ1bmN0aW9uIChjbGF1c2UpIHtcbiAgaWYgKCEoJ2ZpZWxkcycgaW4gY2xhdXNlKSkge1xuICAgIGNsYXVzZS5maWVsZHMgPSB0aGlzLmFsbEZpZWxkc1xuICB9XG5cbiAgaWYgKCEoJ2Jvb3N0JyBpbiBjbGF1c2UpKSB7XG4gICAgY2xhdXNlLmJvb3N0ID0gMVxuICB9XG5cbiAgaWYgKCEoJ3VzZVBpcGVsaW5lJyBpbiBjbGF1c2UpKSB7XG4gICAgY2xhdXNlLnVzZVBpcGVsaW5lID0gdHJ1ZVxuICB9XG5cbiAgaWYgKCEoJ3dpbGRjYXJkJyBpbiBjbGF1c2UpKSB7XG4gICAgY2xhdXNlLndpbGRjYXJkID0gbHVuci5RdWVyeS53aWxkY2FyZC5OT05FXG4gIH1cblxuICBpZiAoKGNsYXVzZS53aWxkY2FyZCAmIGx1bnIuUXVlcnkud2lsZGNhcmQuTEVBRElORykgJiYgKGNsYXVzZS50ZXJtLmNoYXJBdCgwKSAhPSBsdW5yLlF1ZXJ5LndpbGRjYXJkKSkge1xuICAgIGNsYXVzZS50ZXJtID0gXCIqXCIgKyBjbGF1c2UudGVybVxuICB9XG5cbiAgaWYgKChjbGF1c2Uud2lsZGNhcmQgJiBsdW5yLlF1ZXJ5LndpbGRjYXJkLlRSQUlMSU5HKSAmJiAoY2xhdXNlLnRlcm0uc2xpY2UoLTEpICE9IGx1bnIuUXVlcnkud2lsZGNhcmQpKSB7XG4gICAgY2xhdXNlLnRlcm0gPSBcIlwiICsgY2xhdXNlLnRlcm0gKyBcIipcIlxuICB9XG5cbiAgaWYgKCEoJ3ByZXNlbmNlJyBpbiBjbGF1c2UpKSB7XG4gICAgY2xhdXNlLnByZXNlbmNlID0gbHVuci5RdWVyeS5wcmVzZW5jZS5PUFRJT05BTFxuICB9XG5cbiAgdGhpcy5jbGF1c2VzLnB1c2goY2xhdXNlKVxuXG4gIHJldHVybiB0aGlzXG59XG5cbi8qKlxuICogQSBuZWdhdGVkIHF1ZXJ5IGlzIG9uZSBpbiB3aGljaCBldmVyeSBjbGF1c2UgaGFzIGEgcHJlc2VuY2Ugb2ZcbiAqIHByb2hpYml0ZWQuIFRoZXNlIHF1ZXJpZXMgcmVxdWlyZSBzb21lIHNwZWNpYWwgcHJvY2Vzc2luZyB0byByZXR1cm5cbiAqIHRoZSBleHBlY3RlZCByZXN1bHRzLlxuICpcbiAqIEByZXR1cm5zIGJvb2xlYW5cbiAqL1xubHVuci5RdWVyeS5wcm90b3R5cGUuaXNOZWdhdGVkID0gZnVuY3Rpb24gKCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuY2xhdXNlcy5sZW5ndGg7IGkrKykge1xuICAgIGlmICh0aGlzLmNsYXVzZXNbaV0ucHJlc2VuY2UgIT0gbHVuci5RdWVyeS5wcmVzZW5jZS5QUk9ISUJJVEVEKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuXG4vKipcbiAqIEFkZHMgYSB0ZXJtIHRvIHRoZSBjdXJyZW50IHF1ZXJ5LCB1bmRlciB0aGUgY292ZXJzIHRoaXMgd2lsbCBjcmVhdGUgYSB7QGxpbmsgbHVuci5RdWVyeX5DbGF1c2V9XG4gKiB0byB0aGUgbGlzdCBvZiBjbGF1c2VzIHRoYXQgbWFrZSB1cCB0aGlzIHF1ZXJ5LlxuICpcbiAqIFRoZSB0ZXJtIGlzIHVzZWQgYXMgaXMsIGkuZS4gbm8gdG9rZW5pemF0aW9uIHdpbGwgYmUgcGVyZm9ybWVkIGJ5IHRoaXMgbWV0aG9kLiBJbnN0ZWFkIGNvbnZlcnNpb25cbiAqIHRvIGEgdG9rZW4gb3IgdG9rZW4tbGlrZSBzdHJpbmcgc2hvdWxkIGJlIGRvbmUgYmVmb3JlIGNhbGxpbmcgdGhpcyBtZXRob2QuXG4gKlxuICogVGhlIHRlcm0gd2lsbCBiZSBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcgYnkgY2FsbGluZyBgdG9TdHJpbmdgLiBNdWx0aXBsZSB0ZXJtcyBjYW4gYmUgcGFzc2VkIGFzIGFuXG4gKiBhcnJheSwgZWFjaCB0ZXJtIGluIHRoZSBhcnJheSB3aWxsIHNoYXJlIHRoZSBzYW1lIG9wdGlvbnMuXG4gKlxuICogQHBhcmFtIHtvYmplY3R8b2JqZWN0W119IHRlcm0gLSBUaGUgdGVybShzKSB0byBhZGQgdG8gdGhlIHF1ZXJ5LlxuICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXSAtIEFueSBhZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gYWRkIHRvIHRoZSBxdWVyeSBjbGF1c2UuXG4gKiBAcmV0dXJucyB7bHVuci5RdWVyeX1cbiAqIEBzZWUgbHVuci5RdWVyeSNjbGF1c2VcbiAqIEBzZWUgbHVuci5RdWVyeX5DbGF1c2VcbiAqIEBleGFtcGxlIDxjYXB0aW9uPmFkZGluZyBhIHNpbmdsZSB0ZXJtIHRvIGEgcXVlcnk8L2NhcHRpb24+XG4gKiBxdWVyeS50ZXJtKFwiZm9vXCIpXG4gKiBAZXhhbXBsZSA8Y2FwdGlvbj5hZGRpbmcgYSBzaW5nbGUgdGVybSB0byBhIHF1ZXJ5IGFuZCBzcGVjaWZ5aW5nIHNlYXJjaCBmaWVsZHMsIHRlcm0gYm9vc3QgYW5kIGF1dG9tYXRpYyB0cmFpbGluZyB3aWxkY2FyZDwvY2FwdGlvbj5cbiAqIHF1ZXJ5LnRlcm0oXCJmb29cIiwge1xuICogICBmaWVsZHM6IFtcInRpdGxlXCJdLFxuICogICBib29zdDogMTAsXG4gKiAgIHdpbGRjYXJkOiBsdW5yLlF1ZXJ5LndpbGRjYXJkLlRSQUlMSU5HXG4gKiB9KVxuICogQGV4YW1wbGUgPGNhcHRpb24+dXNpbmcgbHVuci50b2tlbml6ZXIgdG8gY29udmVydCBhIHN0cmluZyB0byB0b2tlbnMgYmVmb3JlIHVzaW5nIHRoZW0gYXMgdGVybXM8L2NhcHRpb24+XG4gKiBxdWVyeS50ZXJtKGx1bnIudG9rZW5pemVyKFwiZm9vIGJhclwiKSlcbiAqL1xubHVuci5RdWVyeS5wcm90b3R5cGUudGVybSA9IGZ1bmN0aW9uICh0ZXJtLCBvcHRpb25zKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHRlcm0pKSB7XG4gICAgdGVybS5mb3JFYWNoKGZ1bmN0aW9uICh0KSB7IHRoaXMudGVybSh0LCBsdW5yLnV0aWxzLmNsb25lKG9wdGlvbnMpKSB9LCB0aGlzKVxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICB2YXIgY2xhdXNlID0gb3B0aW9ucyB8fCB7fVxuICBjbGF1c2UudGVybSA9IHRlcm0udG9TdHJpbmcoKVxuXG4gIHRoaXMuY2xhdXNlKGNsYXVzZSlcblxuICByZXR1cm4gdGhpc1xufVxubHVuci5RdWVyeVBhcnNlRXJyb3IgPSBmdW5jdGlvbiAobWVzc2FnZSwgc3RhcnQsIGVuZCkge1xuICB0aGlzLm5hbWUgPSBcIlF1ZXJ5UGFyc2VFcnJvclwiXG4gIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2VcbiAgdGhpcy5zdGFydCA9IHN0YXJ0XG4gIHRoaXMuZW5kID0gZW5kXG59XG5cbmx1bnIuUXVlcnlQYXJzZUVycm9yLnByb3RvdHlwZSA9IG5ldyBFcnJvclxubHVuci5RdWVyeUxleGVyID0gZnVuY3Rpb24gKHN0cikge1xuICB0aGlzLmxleGVtZXMgPSBbXVxuICB0aGlzLnN0ciA9IHN0clxuICB0aGlzLmxlbmd0aCA9IHN0ci5sZW5ndGhcbiAgdGhpcy5wb3MgPSAwXG4gIHRoaXMuc3RhcnQgPSAwXG4gIHRoaXMuZXNjYXBlQ2hhclBvc2l0aW9ucyA9IFtdXG59XG5cbmx1bnIuUXVlcnlMZXhlci5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RhdGUgPSBsdW5yLlF1ZXJ5TGV4ZXIubGV4VGV4dFxuXG4gIHdoaWxlIChzdGF0ZSkge1xuICAgIHN0YXRlID0gc3RhdGUodGhpcylcbiAgfVxufVxuXG5sdW5yLlF1ZXJ5TGV4ZXIucHJvdG90eXBlLnNsaWNlU3RyaW5nID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3ViU2xpY2VzID0gW10sXG4gICAgICBzbGljZVN0YXJ0ID0gdGhpcy5zdGFydCxcbiAgICAgIHNsaWNlRW5kID0gdGhpcy5wb3NcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuZXNjYXBlQ2hhclBvc2l0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgIHNsaWNlRW5kID0gdGhpcy5lc2NhcGVDaGFyUG9zaXRpb25zW2ldXG4gICAgc3ViU2xpY2VzLnB1c2godGhpcy5zdHIuc2xpY2Uoc2xpY2VTdGFydCwgc2xpY2VFbmQpKVxuICAgIHNsaWNlU3RhcnQgPSBzbGljZUVuZCArIDFcbiAgfVxuXG4gIHN1YlNsaWNlcy5wdXNoKHRoaXMuc3RyLnNsaWNlKHNsaWNlU3RhcnQsIHRoaXMucG9zKSlcbiAgdGhpcy5lc2NhcGVDaGFyUG9zaXRpb25zLmxlbmd0aCA9IDBcblxuICByZXR1cm4gc3ViU2xpY2VzLmpvaW4oJycpXG59XG5cbmx1bnIuUXVlcnlMZXhlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gIHRoaXMubGV4ZW1lcy5wdXNoKHtcbiAgICB0eXBlOiB0eXBlLFxuICAgIHN0cjogdGhpcy5zbGljZVN0cmluZygpLFxuICAgIHN0YXJ0OiB0aGlzLnN0YXJ0LFxuICAgIGVuZDogdGhpcy5wb3NcbiAgfSlcblxuICB0aGlzLnN0YXJ0ID0gdGhpcy5wb3Ncbn1cblxubHVuci5RdWVyeUxleGVyLnByb3RvdHlwZS5lc2NhcGVDaGFyYWN0ZXIgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuZXNjYXBlQ2hhclBvc2l0aW9ucy5wdXNoKHRoaXMucG9zIC0gMSlcbiAgdGhpcy5wb3MgKz0gMVxufVxuXG5sdW5yLlF1ZXJ5TGV4ZXIucHJvdG90eXBlLm5leHQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnBvcyA+PSB0aGlzLmxlbmd0aCkge1xuICAgIHJldHVybiBsdW5yLlF1ZXJ5TGV4ZXIuRU9TXG4gIH1cblxuICB2YXIgY2hhciA9IHRoaXMuc3RyLmNoYXJBdCh0aGlzLnBvcylcbiAgdGhpcy5wb3MgKz0gMVxuICByZXR1cm4gY2hhclxufVxuXG5sdW5yLlF1ZXJ5TGV4ZXIucHJvdG90eXBlLndpZHRoID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5wb3MgLSB0aGlzLnN0YXJ0XG59XG5cbmx1bnIuUXVlcnlMZXhlci5wcm90b3R5cGUuaWdub3JlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zdGFydCA9PSB0aGlzLnBvcykge1xuICAgIHRoaXMucG9zICs9IDFcbiAgfVxuXG4gIHRoaXMuc3RhcnQgPSB0aGlzLnBvc1xufVxuXG5sdW5yLlF1ZXJ5TGV4ZXIucHJvdG90eXBlLmJhY2t1cCA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5wb3MgLT0gMVxufVxuXG5sdW5yLlF1ZXJ5TGV4ZXIucHJvdG90eXBlLmFjY2VwdERpZ2l0UnVuID0gZnVuY3Rpb24gKCkge1xuICB2YXIgY2hhciwgY2hhckNvZGVcblxuICBkbyB7XG4gICAgY2hhciA9IHRoaXMubmV4dCgpXG4gICAgY2hhckNvZGUgPSBjaGFyLmNoYXJDb2RlQXQoMClcbiAgfSB3aGlsZSAoY2hhckNvZGUgPiA0NyAmJiBjaGFyQ29kZSA8IDU4KVxuXG4gIGlmIChjaGFyICE9IGx1bnIuUXVlcnlMZXhlci5FT1MpIHtcbiAgICB0aGlzLmJhY2t1cCgpXG4gIH1cbn1cblxubHVuci5RdWVyeUxleGVyLnByb3RvdHlwZS5tb3JlID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5wb3MgPCB0aGlzLmxlbmd0aFxufVxuXG5sdW5yLlF1ZXJ5TGV4ZXIuRU9TID0gJ0VPUydcbmx1bnIuUXVlcnlMZXhlci5GSUVMRCA9ICdGSUVMRCdcbmx1bnIuUXVlcnlMZXhlci5URVJNID0gJ1RFUk0nXG5sdW5yLlF1ZXJ5TGV4ZXIuRURJVF9ESVNUQU5DRSA9ICdFRElUX0RJU1RBTkNFJ1xubHVuci5RdWVyeUxleGVyLkJPT1NUID0gJ0JPT1NUJ1xubHVuci5RdWVyeUxleGVyLlBSRVNFTkNFID0gJ1BSRVNFTkNFJ1xuXG5sdW5yLlF1ZXJ5TGV4ZXIubGV4RmllbGQgPSBmdW5jdGlvbiAobGV4ZXIpIHtcbiAgbGV4ZXIuYmFja3VwKClcbiAgbGV4ZXIuZW1pdChsdW5yLlF1ZXJ5TGV4ZXIuRklFTEQpXG4gIGxleGVyLmlnbm9yZSgpXG4gIHJldHVybiBsdW5yLlF1ZXJ5TGV4ZXIubGV4VGV4dFxufVxuXG5sdW5yLlF1ZXJ5TGV4ZXIubGV4VGVybSA9IGZ1bmN0aW9uIChsZXhlcikge1xuICBpZiAobGV4ZXIud2lkdGgoKSA+IDEpIHtcbiAgICBsZXhlci5iYWNrdXAoKVxuICAgIGxleGVyLmVtaXQobHVuci5RdWVyeUxleGVyLlRFUk0pXG4gIH1cblxuICBsZXhlci5pZ25vcmUoKVxuXG4gIGlmIChsZXhlci5tb3JlKCkpIHtcbiAgICByZXR1cm4gbHVuci5RdWVyeUxleGVyLmxleFRleHRcbiAgfVxufVxuXG5sdW5yLlF1ZXJ5TGV4ZXIubGV4RWRpdERpc3RhbmNlID0gZnVuY3Rpb24gKGxleGVyKSB7XG4gIGxleGVyLmlnbm9yZSgpXG4gIGxleGVyLmFjY2VwdERpZ2l0UnVuKClcbiAgbGV4ZXIuZW1pdChsdW5yLlF1ZXJ5TGV4ZXIuRURJVF9ESVNUQU5DRSlcbiAgcmV0dXJuIGx1bnIuUXVlcnlMZXhlci5sZXhUZXh0XG59XG5cbmx1bnIuUXVlcnlMZXhlci5sZXhCb29zdCA9IGZ1bmN0aW9uIChsZXhlcikge1xuICBsZXhlci5pZ25vcmUoKVxuICBsZXhlci5hY2NlcHREaWdpdFJ1bigpXG4gIGxleGVyLmVtaXQobHVuci5RdWVyeUxleGVyLkJPT1NUKVxuICByZXR1cm4gbHVuci5RdWVyeUxleGVyLmxleFRleHRcbn1cblxubHVuci5RdWVyeUxleGVyLmxleEVPUyA9IGZ1bmN0aW9uIChsZXhlcikge1xuICBpZiAobGV4ZXIud2lkdGgoKSA+IDApIHtcbiAgICBsZXhlci5lbWl0KGx1bnIuUXVlcnlMZXhlci5URVJNKVxuICB9XG59XG5cbi8vIFRoaXMgbWF0Y2hlcyB0aGUgc2VwYXJhdG9yIHVzZWQgd2hlbiB0b2tlbmlzaW5nIGZpZWxkc1xuLy8gd2l0aGluIGEgZG9jdW1lbnQuIFRoZXNlIHNob3VsZCBtYXRjaCBvdGhlcndpc2UgaXQgaXNcbi8vIG5vdCBwb3NzaWJsZSB0byBzZWFyY2ggZm9yIHNvbWUgdG9rZW5zIHdpdGhpbiBhIGRvY3VtZW50LlxuLy9cbi8vIEl0IGlzIHBvc3NpYmxlIGZvciB0aGUgdXNlciB0byBjaGFuZ2UgdGhlIHNlcGFyYXRvciBvbiB0aGVcbi8vIHRva2VuaXplciBzbyBpdCBfbWlnaHRfIGNsYXNoIHdpdGggYW55IG90aGVyIG9mIHRoZSBzcGVjaWFsXG4vLyBjaGFyYWN0ZXJzIGFscmVhZHkgdXNlZCB3aXRoaW4gdGhlIHNlYXJjaCBzdHJpbmcsIGUuZy4gOi5cbi8vXG4vLyBUaGlzIG1lYW5zIHRoYXQgaXQgaXMgcG9zc2libGUgdG8gY2hhbmdlIHRoZSBzZXBhcmF0b3IgaW5cbi8vIHN1Y2ggYSB3YXkgdGhhdCBtYWtlcyBzb21lIHdvcmRzIHVuc2VhcmNoYWJsZSB1c2luZyBhIHNlYXJjaFxuLy8gc3RyaW5nLlxubHVuci5RdWVyeUxleGVyLnRlcm1TZXBhcmF0b3IgPSBsdW5yLnRva2VuaXplci5zZXBhcmF0b3JcblxubHVuci5RdWVyeUxleGVyLmxleFRleHQgPSBmdW5jdGlvbiAobGV4ZXIpIHtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICB2YXIgY2hhciA9IGxleGVyLm5leHQoKVxuXG4gICAgaWYgKGNoYXIgPT0gbHVuci5RdWVyeUxleGVyLkVPUykge1xuICAgICAgcmV0dXJuIGx1bnIuUXVlcnlMZXhlci5sZXhFT1NcbiAgICB9XG5cbiAgICAvLyBFc2NhcGUgY2hhcmFjdGVyIGlzICdcXCdcbiAgICBpZiAoY2hhci5jaGFyQ29kZUF0KDApID09IDkyKSB7XG4gICAgICBsZXhlci5lc2NhcGVDaGFyYWN0ZXIoKVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAoY2hhciA9PSBcIjpcIikge1xuICAgICAgcmV0dXJuIGx1bnIuUXVlcnlMZXhlci5sZXhGaWVsZFxuICAgIH1cblxuICAgIGlmIChjaGFyID09IFwiflwiKSB7XG4gICAgICBsZXhlci5iYWNrdXAoKVxuICAgICAgaWYgKGxleGVyLndpZHRoKCkgPiAwKSB7XG4gICAgICAgIGxleGVyLmVtaXQobHVuci5RdWVyeUxleGVyLlRFUk0pXG4gICAgICB9XG4gICAgICByZXR1cm4gbHVuci5RdWVyeUxleGVyLmxleEVkaXREaXN0YW5jZVxuICAgIH1cblxuICAgIGlmIChjaGFyID09IFwiXlwiKSB7XG4gICAgICBsZXhlci5iYWNrdXAoKVxuICAgICAgaWYgKGxleGVyLndpZHRoKCkgPiAwKSB7XG4gICAgICAgIGxleGVyLmVtaXQobHVuci5RdWVyeUxleGVyLlRFUk0pXG4gICAgICB9XG4gICAgICByZXR1cm4gbHVuci5RdWVyeUxleGVyLmxleEJvb3N0XG4gICAgfVxuXG4gICAgLy8gXCIrXCIgaW5kaWNhdGVzIHRlcm0gcHJlc2VuY2UgaXMgcmVxdWlyZWRcbiAgICAvLyBjaGVja2luZyBmb3IgbGVuZ3RoIHRvIGVuc3VyZSB0aGF0IG9ubHlcbiAgICAvLyBsZWFkaW5nIFwiK1wiIGFyZSBjb25zaWRlcmVkXG4gICAgaWYgKGNoYXIgPT0gXCIrXCIgJiYgbGV4ZXIud2lkdGgoKSA9PT0gMSkge1xuICAgICAgbGV4ZXIuZW1pdChsdW5yLlF1ZXJ5TGV4ZXIuUFJFU0VOQ0UpXG4gICAgICByZXR1cm4gbHVuci5RdWVyeUxleGVyLmxleFRleHRcbiAgICB9XG5cbiAgICAvLyBcIi1cIiBpbmRpY2F0ZXMgdGVybSBwcmVzZW5jZSBpcyBwcm9oaWJpdGVkXG4gICAgLy8gY2hlY2tpbmcgZm9yIGxlbmd0aCB0byBlbnN1cmUgdGhhdCBvbmx5XG4gICAgLy8gbGVhZGluZyBcIi1cIiBhcmUgY29uc2lkZXJlZFxuICAgIGlmIChjaGFyID09IFwiLVwiICYmIGxleGVyLndpZHRoKCkgPT09IDEpIHtcbiAgICAgIGxleGVyLmVtaXQobHVuci5RdWVyeUxleGVyLlBSRVNFTkNFKVxuICAgICAgcmV0dXJuIGx1bnIuUXVlcnlMZXhlci5sZXhUZXh0XG4gICAgfVxuXG4gICAgaWYgKGNoYXIubWF0Y2gobHVuci5RdWVyeUxleGVyLnRlcm1TZXBhcmF0b3IpKSB7XG4gICAgICByZXR1cm4gbHVuci5RdWVyeUxleGVyLmxleFRlcm1cbiAgICB9XG4gIH1cbn1cblxubHVuci5RdWVyeVBhcnNlciA9IGZ1bmN0aW9uIChzdHIsIHF1ZXJ5KSB7XG4gIHRoaXMubGV4ZXIgPSBuZXcgbHVuci5RdWVyeUxleGVyIChzdHIpXG4gIHRoaXMucXVlcnkgPSBxdWVyeVxuICB0aGlzLmN1cnJlbnRDbGF1c2UgPSB7fVxuICB0aGlzLmxleGVtZUlkeCA9IDBcbn1cblxubHVuci5RdWVyeVBhcnNlci5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMubGV4ZXIucnVuKClcbiAgdGhpcy5sZXhlbWVzID0gdGhpcy5sZXhlci5sZXhlbWVzXG5cbiAgdmFyIHN0YXRlID0gbHVuci5RdWVyeVBhcnNlci5wYXJzZUNsYXVzZVxuXG4gIHdoaWxlIChzdGF0ZSkge1xuICAgIHN0YXRlID0gc3RhdGUodGhpcylcbiAgfVxuXG4gIHJldHVybiB0aGlzLnF1ZXJ5XG59XG5cbmx1bnIuUXVlcnlQYXJzZXIucHJvdG90eXBlLnBlZWtMZXhlbWUgPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB0aGlzLmxleGVtZXNbdGhpcy5sZXhlbWVJZHhdXG59XG5cbmx1bnIuUXVlcnlQYXJzZXIucHJvdG90eXBlLmNvbnN1bWVMZXhlbWUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBsZXhlbWUgPSB0aGlzLnBlZWtMZXhlbWUoKVxuICB0aGlzLmxleGVtZUlkeCArPSAxXG4gIHJldHVybiBsZXhlbWVcbn1cblxubHVuci5RdWVyeVBhcnNlci5wcm90b3R5cGUubmV4dENsYXVzZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNvbXBsZXRlZENsYXVzZSA9IHRoaXMuY3VycmVudENsYXVzZVxuICB0aGlzLnF1ZXJ5LmNsYXVzZShjb21wbGV0ZWRDbGF1c2UpXG4gIHRoaXMuY3VycmVudENsYXVzZSA9IHt9XG59XG5cbmx1bnIuUXVlcnlQYXJzZXIucGFyc2VDbGF1c2UgPSBmdW5jdGlvbiAocGFyc2VyKSB7XG4gIHZhciBsZXhlbWUgPSBwYXJzZXIucGVla0xleGVtZSgpXG5cbiAgaWYgKGxleGVtZSA9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIHN3aXRjaCAobGV4ZW1lLnR5cGUpIHtcbiAgICBjYXNlIGx1bnIuUXVlcnlMZXhlci5QUkVTRU5DRTpcbiAgICAgIHJldHVybiBsdW5yLlF1ZXJ5UGFyc2VyLnBhcnNlUHJlc2VuY2VcbiAgICBjYXNlIGx1bnIuUXVlcnlMZXhlci5GSUVMRDpcbiAgICAgIHJldHVybiBsdW5yLlF1ZXJ5UGFyc2VyLnBhcnNlRmllbGRcbiAgICBjYXNlIGx1bnIuUXVlcnlMZXhlci5URVJNOlxuICAgICAgcmV0dXJuIGx1bnIuUXVlcnlQYXJzZXIucGFyc2VUZXJtXG4gICAgZGVmYXVsdDpcbiAgICAgIHZhciBlcnJvck1lc3NhZ2UgPSBcImV4cGVjdGVkIGVpdGhlciBhIGZpZWxkIG9yIGEgdGVybSwgZm91bmQgXCIgKyBsZXhlbWUudHlwZVxuXG4gICAgICBpZiAobGV4ZW1lLnN0ci5sZW5ndGggPj0gMSkge1xuICAgICAgICBlcnJvck1lc3NhZ2UgKz0gXCIgd2l0aCB2YWx1ZSAnXCIgKyBsZXhlbWUuc3RyICsgXCInXCJcbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IGx1bnIuUXVlcnlQYXJzZUVycm9yIChlcnJvck1lc3NhZ2UsIGxleGVtZS5zdGFydCwgbGV4ZW1lLmVuZClcbiAgfVxufVxuXG5sdW5yLlF1ZXJ5UGFyc2VyLnBhcnNlUHJlc2VuY2UgPSBmdW5jdGlvbiAocGFyc2VyKSB7XG4gIHZhciBsZXhlbWUgPSBwYXJzZXIuY29uc3VtZUxleGVtZSgpXG5cbiAgaWYgKGxleGVtZSA9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIHN3aXRjaCAobGV4ZW1lLnN0cikge1xuICAgIGNhc2UgXCItXCI6XG4gICAgICBwYXJzZXIuY3VycmVudENsYXVzZS5wcmVzZW5jZSA9IGx1bnIuUXVlcnkucHJlc2VuY2UuUFJPSElCSVRFRFxuICAgICAgYnJlYWtcbiAgICBjYXNlIFwiK1wiOlxuICAgICAgcGFyc2VyLmN1cnJlbnRDbGF1c2UucHJlc2VuY2UgPSBsdW5yLlF1ZXJ5LnByZXNlbmNlLlJFUVVJUkVEXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICB2YXIgZXJyb3JNZXNzYWdlID0gXCJ1bnJlY29nbmlzZWQgcHJlc2VuY2Ugb3BlcmF0b3InXCIgKyBsZXhlbWUuc3RyICsgXCInXCJcbiAgICAgIHRocm93IG5ldyBsdW5yLlF1ZXJ5UGFyc2VFcnJvciAoZXJyb3JNZXNzYWdlLCBsZXhlbWUuc3RhcnQsIGxleGVtZS5lbmQpXG4gIH1cblxuICB2YXIgbmV4dExleGVtZSA9IHBhcnNlci5wZWVrTGV4ZW1lKClcblxuICBpZiAobmV4dExleGVtZSA9PSB1bmRlZmluZWQpIHtcbiAgICB2YXIgZXJyb3JNZXNzYWdlID0gXCJleHBlY3RpbmcgdGVybSBvciBmaWVsZCwgZm91bmQgbm90aGluZ1wiXG4gICAgdGhyb3cgbmV3IGx1bnIuUXVlcnlQYXJzZUVycm9yIChlcnJvck1lc3NhZ2UsIGxleGVtZS5zdGFydCwgbGV4ZW1lLmVuZClcbiAgfVxuXG4gIHN3aXRjaCAobmV4dExleGVtZS50eXBlKSB7XG4gICAgY2FzZSBsdW5yLlF1ZXJ5TGV4ZXIuRklFTEQ6XG4gICAgICByZXR1cm4gbHVuci5RdWVyeVBhcnNlci5wYXJzZUZpZWxkXG4gICAgY2FzZSBsdW5yLlF1ZXJ5TGV4ZXIuVEVSTTpcbiAgICAgIHJldHVybiBsdW5yLlF1ZXJ5UGFyc2VyLnBhcnNlVGVybVxuICAgIGRlZmF1bHQ6XG4gICAgICB2YXIgZXJyb3JNZXNzYWdlID0gXCJleHBlY3RpbmcgdGVybSBvciBmaWVsZCwgZm91bmQgJ1wiICsgbmV4dExleGVtZS50eXBlICsgXCInXCJcbiAgICAgIHRocm93IG5ldyBsdW5yLlF1ZXJ5UGFyc2VFcnJvciAoZXJyb3JNZXNzYWdlLCBuZXh0TGV4ZW1lLnN0YXJ0LCBuZXh0TGV4ZW1lLmVuZClcbiAgfVxufVxuXG5sdW5yLlF1ZXJ5UGFyc2VyLnBhcnNlRmllbGQgPSBmdW5jdGlvbiAocGFyc2VyKSB7XG4gIHZhciBsZXhlbWUgPSBwYXJzZXIuY29uc3VtZUxleGVtZSgpXG5cbiAgaWYgKGxleGVtZSA9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmIChwYXJzZXIucXVlcnkuYWxsRmllbGRzLmluZGV4T2YobGV4ZW1lLnN0cikgPT0gLTEpIHtcbiAgICB2YXIgcG9zc2libGVGaWVsZHMgPSBwYXJzZXIucXVlcnkuYWxsRmllbGRzLm1hcChmdW5jdGlvbiAoZikgeyByZXR1cm4gXCInXCIgKyBmICsgXCInXCIgfSkuam9pbignLCAnKSxcbiAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJ1bnJlY29nbmlzZWQgZmllbGQgJ1wiICsgbGV4ZW1lLnN0ciArIFwiJywgcG9zc2libGUgZmllbGRzOiBcIiArIHBvc3NpYmxlRmllbGRzXG5cbiAgICB0aHJvdyBuZXcgbHVuci5RdWVyeVBhcnNlRXJyb3IgKGVycm9yTWVzc2FnZSwgbGV4ZW1lLnN0YXJ0LCBsZXhlbWUuZW5kKVxuICB9XG5cbiAgcGFyc2VyLmN1cnJlbnRDbGF1c2UuZmllbGRzID0gW2xleGVtZS5zdHJdXG5cbiAgdmFyIG5leHRMZXhlbWUgPSBwYXJzZXIucGVla0xleGVtZSgpXG5cbiAgaWYgKG5leHRMZXhlbWUgPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIGVycm9yTWVzc2FnZSA9IFwiZXhwZWN0aW5nIHRlcm0sIGZvdW5kIG5vdGhpbmdcIlxuICAgIHRocm93IG5ldyBsdW5yLlF1ZXJ5UGFyc2VFcnJvciAoZXJyb3JNZXNzYWdlLCBsZXhlbWUuc3RhcnQsIGxleGVtZS5lbmQpXG4gIH1cblxuICBzd2l0Y2ggKG5leHRMZXhlbWUudHlwZSkge1xuICAgIGNhc2UgbHVuci5RdWVyeUxleGVyLlRFUk06XG4gICAgICByZXR1cm4gbHVuci5RdWVyeVBhcnNlci5wYXJzZVRlcm1cbiAgICBkZWZhdWx0OlxuICAgICAgdmFyIGVycm9yTWVzc2FnZSA9IFwiZXhwZWN0aW5nIHRlcm0sIGZvdW5kICdcIiArIG5leHRMZXhlbWUudHlwZSArIFwiJ1wiXG4gICAgICB0aHJvdyBuZXcgbHVuci5RdWVyeVBhcnNlRXJyb3IgKGVycm9yTWVzc2FnZSwgbmV4dExleGVtZS5zdGFydCwgbmV4dExleGVtZS5lbmQpXG4gIH1cbn1cblxubHVuci5RdWVyeVBhcnNlci5wYXJzZVRlcm0gPSBmdW5jdGlvbiAocGFyc2VyKSB7XG4gIHZhciBsZXhlbWUgPSBwYXJzZXIuY29uc3VtZUxleGVtZSgpXG5cbiAgaWYgKGxleGVtZSA9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIHBhcnNlci5jdXJyZW50Q2xhdXNlLnRlcm0gPSBsZXhlbWUuc3RyLnRvTG93ZXJDYXNlKClcblxuICBpZiAobGV4ZW1lLnN0ci5pbmRleE9mKFwiKlwiKSAhPSAtMSkge1xuICAgIHBhcnNlci5jdXJyZW50Q2xhdXNlLnVzZVBpcGVsaW5lID0gZmFsc2VcbiAgfVxuXG4gIHZhciBuZXh0TGV4ZW1lID0gcGFyc2VyLnBlZWtMZXhlbWUoKVxuXG4gIGlmIChuZXh0TGV4ZW1lID09IHVuZGVmaW5lZCkge1xuICAgIHBhcnNlci5uZXh0Q2xhdXNlKClcbiAgICByZXR1cm5cbiAgfVxuXG4gIHN3aXRjaCAobmV4dExleGVtZS50eXBlKSB7XG4gICAgY2FzZSBsdW5yLlF1ZXJ5TGV4ZXIuVEVSTTpcbiAgICAgIHBhcnNlci5uZXh0Q2xhdXNlKClcbiAgICAgIHJldHVybiBsdW5yLlF1ZXJ5UGFyc2VyLnBhcnNlVGVybVxuICAgIGNhc2UgbHVuci5RdWVyeUxleGVyLkZJRUxEOlxuICAgICAgcGFyc2VyLm5leHRDbGF1c2UoKVxuICAgICAgcmV0dXJuIGx1bnIuUXVlcnlQYXJzZXIucGFyc2VGaWVsZFxuICAgIGNhc2UgbHVuci5RdWVyeUxleGVyLkVESVRfRElTVEFOQ0U6XG4gICAgICByZXR1cm4gbHVuci5RdWVyeVBhcnNlci5wYXJzZUVkaXREaXN0YW5jZVxuICAgIGNhc2UgbHVuci5RdWVyeUxleGVyLkJPT1NUOlxuICAgICAgcmV0dXJuIGx1bnIuUXVlcnlQYXJzZXIucGFyc2VCb29zdFxuICAgIGNhc2UgbHVuci5RdWVyeUxleGVyLlBSRVNFTkNFOlxuICAgICAgcGFyc2VyLm5leHRDbGF1c2UoKVxuICAgICAgcmV0dXJuIGx1bnIuUXVlcnlQYXJzZXIucGFyc2VQcmVzZW5jZVxuICAgIGRlZmF1bHQ6XG4gICAgICB2YXIgZXJyb3JNZXNzYWdlID0gXCJVbmV4cGVjdGVkIGxleGVtZSB0eXBlICdcIiArIG5leHRMZXhlbWUudHlwZSArIFwiJ1wiXG4gICAgICB0aHJvdyBuZXcgbHVuci5RdWVyeVBhcnNlRXJyb3IgKGVycm9yTWVzc2FnZSwgbmV4dExleGVtZS5zdGFydCwgbmV4dExleGVtZS5lbmQpXG4gIH1cbn1cblxubHVuci5RdWVyeVBhcnNlci5wYXJzZUVkaXREaXN0YW5jZSA9IGZ1bmN0aW9uIChwYXJzZXIpIHtcbiAgdmFyIGxleGVtZSA9IHBhcnNlci5jb25zdW1lTGV4ZW1lKClcblxuICBpZiAobGV4ZW1lID09IHVuZGVmaW5lZCkge1xuICAgIHJldHVyblxuICB9XG5cbiAgdmFyIGVkaXREaXN0YW5jZSA9IHBhcnNlSW50KGxleGVtZS5zdHIsIDEwKVxuXG4gIGlmIChpc05hTihlZGl0RGlzdGFuY2UpKSB7XG4gICAgdmFyIGVycm9yTWVzc2FnZSA9IFwiZWRpdCBkaXN0YW5jZSBtdXN0IGJlIG51bWVyaWNcIlxuICAgIHRocm93IG5ldyBsdW5yLlF1ZXJ5UGFyc2VFcnJvciAoZXJyb3JNZXNzYWdlLCBsZXhlbWUuc3RhcnQsIGxleGVtZS5lbmQpXG4gIH1cblxuICBwYXJzZXIuY3VycmVudENsYXVzZS5lZGl0RGlzdGFuY2UgPSBlZGl0RGlzdGFuY2VcblxuICB2YXIgbmV4dExleGVtZSA9IHBhcnNlci5wZWVrTGV4ZW1lKClcblxuICBpZiAobmV4dExleGVtZSA9PSB1bmRlZmluZWQpIHtcbiAgICBwYXJzZXIubmV4dENsYXVzZSgpXG4gICAgcmV0dXJuXG4gIH1cblxuICBzd2l0Y2ggKG5leHRMZXhlbWUudHlwZSkge1xuICAgIGNhc2UgbHVuci5RdWVyeUxleGVyLlRFUk06XG4gICAgICBwYXJzZXIubmV4dENsYXVzZSgpXG4gICAgICByZXR1cm4gbHVuci5RdWVyeVBhcnNlci5wYXJzZVRlcm1cbiAgICBjYXNlIGx1bnIuUXVlcnlMZXhlci5GSUVMRDpcbiAgICAgIHBhcnNlci5uZXh0Q2xhdXNlKClcbiAgICAgIHJldHVybiBsdW5yLlF1ZXJ5UGFyc2VyLnBhcnNlRmllbGRcbiAgICBjYXNlIGx1bnIuUXVlcnlMZXhlci5FRElUX0RJU1RBTkNFOlxuICAgICAgcmV0dXJuIGx1bnIuUXVlcnlQYXJzZXIucGFyc2VFZGl0RGlzdGFuY2VcbiAgICBjYXNlIGx1bnIuUXVlcnlMZXhlci5CT09TVDpcbiAgICAgIHJldHVybiBsdW5yLlF1ZXJ5UGFyc2VyLnBhcnNlQm9vc3RcbiAgICBjYXNlIGx1bnIuUXVlcnlMZXhlci5QUkVTRU5DRTpcbiAgICAgIHBhcnNlci5uZXh0Q2xhdXNlKClcbiAgICAgIHJldHVybiBsdW5yLlF1ZXJ5UGFyc2VyLnBhcnNlUHJlc2VuY2VcbiAgICBkZWZhdWx0OlxuICAgICAgdmFyIGVycm9yTWVzc2FnZSA9IFwiVW5leHBlY3RlZCBsZXhlbWUgdHlwZSAnXCIgKyBuZXh0TGV4ZW1lLnR5cGUgKyBcIidcIlxuICAgICAgdGhyb3cgbmV3IGx1bnIuUXVlcnlQYXJzZUVycm9yIChlcnJvck1lc3NhZ2UsIG5leHRMZXhlbWUuc3RhcnQsIG5leHRMZXhlbWUuZW5kKVxuICB9XG59XG5cbmx1bnIuUXVlcnlQYXJzZXIucGFyc2VCb29zdCA9IGZ1bmN0aW9uIChwYXJzZXIpIHtcbiAgdmFyIGxleGVtZSA9IHBhcnNlci5jb25zdW1lTGV4ZW1lKClcblxuICBpZiAobGV4ZW1lID09IHVuZGVmaW5lZCkge1xuICAgIHJldHVyblxuICB9XG5cbiAgdmFyIGJvb3N0ID0gcGFyc2VJbnQobGV4ZW1lLnN0ciwgMTApXG5cbiAgaWYgKGlzTmFOKGJvb3N0KSkge1xuICAgIHZhciBlcnJvck1lc3NhZ2UgPSBcImJvb3N0IG11c3QgYmUgbnVtZXJpY1wiXG4gICAgdGhyb3cgbmV3IGx1bnIuUXVlcnlQYXJzZUVycm9yIChlcnJvck1lc3NhZ2UsIGxleGVtZS5zdGFydCwgbGV4ZW1lLmVuZClcbiAgfVxuXG4gIHBhcnNlci5jdXJyZW50Q2xhdXNlLmJvb3N0ID0gYm9vc3RcblxuICB2YXIgbmV4dExleGVtZSA9IHBhcnNlci5wZWVrTGV4ZW1lKClcblxuICBpZiAobmV4dExleGVtZSA9PSB1bmRlZmluZWQpIHtcbiAgICBwYXJzZXIubmV4dENsYXVzZSgpXG4gICAgcmV0dXJuXG4gIH1cblxuICBzd2l0Y2ggKG5leHRMZXhlbWUudHlwZSkge1xuICAgIGNhc2UgbHVuci5RdWVyeUxleGVyLlRFUk06XG4gICAgICBwYXJzZXIubmV4dENsYXVzZSgpXG4gICAgICByZXR1cm4gbHVuci5RdWVyeVBhcnNlci5wYXJzZVRlcm1cbiAgICBjYXNlIGx1bnIuUXVlcnlMZXhlci5GSUVMRDpcbiAgICAgIHBhcnNlci5uZXh0Q2xhdXNlKClcbiAgICAgIHJldHVybiBsdW5yLlF1ZXJ5UGFyc2VyLnBhcnNlRmllbGRcbiAgICBjYXNlIGx1bnIuUXVlcnlMZXhlci5FRElUX0RJU1RBTkNFOlxuICAgICAgcmV0dXJuIGx1bnIuUXVlcnlQYXJzZXIucGFyc2VFZGl0RGlzdGFuY2VcbiAgICBjYXNlIGx1bnIuUXVlcnlMZXhlci5CT09TVDpcbiAgICAgIHJldHVybiBsdW5yLlF1ZXJ5UGFyc2VyLnBhcnNlQm9vc3RcbiAgICBjYXNlIGx1bnIuUXVlcnlMZXhlci5QUkVTRU5DRTpcbiAgICAgIHBhcnNlci5uZXh0Q2xhdXNlKClcbiAgICAgIHJldHVybiBsdW5yLlF1ZXJ5UGFyc2VyLnBhcnNlUHJlc2VuY2VcbiAgICBkZWZhdWx0OlxuICAgICAgdmFyIGVycm9yTWVzc2FnZSA9IFwiVW5leHBlY3RlZCBsZXhlbWUgdHlwZSAnXCIgKyBuZXh0TGV4ZW1lLnR5cGUgKyBcIidcIlxuICAgICAgdGhyb3cgbmV3IGx1bnIuUXVlcnlQYXJzZUVycm9yIChlcnJvck1lc3NhZ2UsIG5leHRMZXhlbWUuc3RhcnQsIG5leHRMZXhlbWUuZW5kKVxuICB9XG59XG5cbiAgLyoqXG4gICAqIGV4cG9ydCB0aGUgbW9kdWxlIHZpYSBBTUQsIENvbW1vbkpTIG9yIGFzIGEgYnJvd3NlciBnbG9iYWxcbiAgICogRXhwb3J0IGNvZGUgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vdW1kanMvdW1kL2Jsb2IvbWFzdGVyL3JldHVybkV4cG9ydHMuanNcbiAgICovXG4gIDsoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAvLyBBTUQuIFJlZ2lzdGVyIGFzIGFuIGFub255bW91cyBtb2R1bGUuXG4gICAgICBkZWZpbmUoZmFjdG9yeSlcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xuICAgICAgLyoqXG4gICAgICAgKiBOb2RlLiBEb2VzIG5vdCB3b3JrIHdpdGggc3RyaWN0IENvbW1vbkpTLCBidXRcbiAgICAgICAqIG9ubHkgQ29tbW9uSlMtbGlrZSBlbnZpcm9tZW50cyB0aGF0IHN1cHBvcnQgbW9kdWxlLmV4cG9ydHMsXG4gICAgICAgKiBsaWtlIE5vZGUuXG4gICAgICAgKi9cbiAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEJyb3dzZXIgZ2xvYmFscyAocm9vdCBpcyB3aW5kb3cpXG4gICAgICByb290Lmx1bnIgPSBmYWN0b3J5KClcbiAgICB9XG4gIH0odGhpcywgZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqIEp1c3QgcmV0dXJuIGEgdmFsdWUgdG8gZGVmaW5lIHRoZSBtb2R1bGUgZXhwb3J0LlxuICAgICAqIFRoaXMgZXhhbXBsZSByZXR1cm5zIGFuIG9iamVjdCwgYnV0IHRoZSBtb2R1bGVcbiAgICAgKiBjYW4gcmV0dXJuIGEgZnVuY3Rpb24gYXMgdGhlIGV4cG9ydGVkIHZhbHVlLlxuICAgICAqL1xuICAgIHJldHVybiBsdW5yXG4gIH0pKVxufSkoKTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2x1bnIvbHVuci5qc1xuLy8gbW9kdWxlIGlkID0gMzZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLypcbiAqIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuICogZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbiAqIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuICogc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbiAqIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1NcbiAqIElOIFRIRSBTT0ZUV0FSRS5cbiAqL1xuXG5pbXBvcnQgUG9zaXRpb24gZnJvbSBcIi4vU2lkZWJhci9Qb3NpdGlvblwiXG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIE1vZHVsZVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIFBvc2l0aW9uXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwvU2lkZWJhci5qcyIsIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbiAqIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4gKiByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3JcbiAqIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4gKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTXG4gKiBJTiBUSEUgU09GVFdBUkUuXG4gKi9cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQ2xhc3NcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUG9zaXRpb24ge1xuXG4gIC8qKlxuICAgKiBTZXQgc2lkZWJhcnMgdG8gbG9ja2VkIHN0YXRlIGFuZCBsaW1pdCBoZWlnaHQgdG8gcGFyZW50IG5vZGVcbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwcm9wZXJ0eSB7SFRNTEVsZW1lbnR9IGVsXyAtIFNpZGViYXJcbiAgICogQHByb3BlcnR5IHtIVE1MRWxlbWVudH0gcGFyZW50XyAtIFNpZGViYXIgY29udGFpbmVyXG4gICAqIEBwcm9wZXJ0eSB7SFRNTEVsZW1lbnR9IGhlYWRlcl8gLSBIZWFkZXJcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IGhlaWdodF8gLSBDdXJyZW50IHNpZGViYXIgaGVpZ2h0XG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBvZmZzZXRfIC0gQ3VycmVudCBwYWdlIHktb2Zmc2V0XG4gICAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gcGFkXyAtIFBhZCB3aGVuIGhlYWRlciBpcyBmaXhlZFxuICAgKlxuICAgKiBAcGFyYW0geyhzdHJpbmd8SFRNTEVsZW1lbnQpfSBlbCAtIFNlbGVjdG9yIG9yIEhUTUwgZWxlbWVudFxuICAgKiBAcGFyYW0geyhzdHJpbmd8SFRNTEVsZW1lbnQpfSBoZWFkZXIgLSBTZWxlY3RvciBvciBIVE1MIGVsZW1lbnRcbiAgICovXG4gIGNvbnN0cnVjdG9yKGVsLCBoZWFkZXIpIHtcbiAgICBsZXQgcmVmID0gKHR5cGVvZiBlbCA9PT0gXCJzdHJpbmdcIilcbiAgICAgID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbClcbiAgICAgIDogZWxcbiAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkgfHxcbiAgICAgICAgIShyZWYucGFyZW50Tm9kZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSlcbiAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuICAgIHRoaXMuZWxfID0gcmVmXG4gICAgdGhpcy5wYXJlbnRfID0gcmVmLnBhcmVudE5vZGVcblxuICAgIC8qIFJldHJpZXZlIGhlYWRlciAqL1xuICAgIHJlZiA9ICh0eXBlb2YgaGVhZGVyID09PSBcInN0cmluZ1wiKVxuICAgICAgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGhlYWRlcilcbiAgICAgIDogaGVhZGVyXG4gICAgaWYgKCEocmVmIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKVxuICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yXG4gICAgdGhpcy5oZWFkZXJfID0gcmVmXG5cbiAgICAvKiBJbml0aWFsaXplIGN1cnJlbnQgaGVpZ2h0IGFuZCB0ZXN0IHdoZXRoZXIgaGVhZGVyIGlzIGZpeGVkICovXG4gICAgdGhpcy5oZWlnaHRfID0gMFxuICAgIHRoaXMucGFkXyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuaGVhZGVyXykucG9zaXRpb24gPT09IFwiZml4ZWRcIlxuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgc2lkZWJhciBzdGF0ZVxuICAgKi9cbiAgc2V0dXAoKSB7XG4gICAgY29uc3QgdG9wID0gQXJyYXkucHJvdG90eXBlLnJlZHVjZS5jYWxsKFxuICAgICAgdGhpcy5wYXJlbnRfLmNoaWxkcmVuLCAob2Zmc2V0LCBjaGlsZCkgPT4ge1xuICAgICAgICByZXR1cm4gTWF0aC5tYXgob2Zmc2V0LCBjaGlsZC5vZmZzZXRUb3ApXG4gICAgICB9LCAwKVxuXG4gICAgLyogU2V0IGxvY2sgb2Zmc2V0IGZvciBlbGVtZW50IHdpdGggbGFyZ2VzdCB0b3Agb2Zmc2V0ICovXG4gICAgdGhpcy5vZmZzZXRfID0gdG9wIC0gKHRoaXMucGFkXyA/IHRoaXMuaGVhZGVyXy5vZmZzZXRIZWlnaHQgOiAwKVxuICAgIHRoaXMudXBkYXRlKClcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgbG9ja2VkIHN0YXRlIGFuZCBoZWlnaHRcbiAgICpcbiAgICogVGhlIGlubmVyIGhlaWdodCBvZiB0aGUgd2luZG93ICg9IHRoZSB2aXNpYmxlIGFyZWEpIGlzIHRoZSBtYXhpbXVtXG4gICAqIHBvc3NpYmxlIGhlaWdodCBmb3IgdGhlIHN0cmV0Y2hpbmcgc2lkZWJhci4gVGhpcyBoZWlnaHQgbXVzdCBiZSBkZWR1Y3RlZFxuICAgKiBieSB0aGUgaGVpZ2h0IG9mIHRoZSBmaXhlZCBoZWFkZXIgKDU2cHgpLiBEZXBlbmRpbmcgb24gdGhlIHBhZ2UgeS1vZmZzZXQsXG4gICAqIHRoZSB0b3Agb2Zmc2V0IG9mIHRoZSBzaWRlYmFyIG11c3QgYmUgdGFrZW4gaW50byBhY2NvdW50LCBhcyB3ZWxsIGFzIHRoZVxuICAgKiBjYXNlIHdoZXJlIHRoZSB3aW5kb3cgaXMgc2Nyb2xsZWQgYmV5b25kIHRoZSBzaWRlYmFyIGNvbnRhaW5lci5cbiAgICpcbiAgICogQHBhcmFtIHtFdmVudD99IGV2IC0gRXZlbnRcbiAgICovXG4gIHVwZGF0ZShldikge1xuICAgIGNvbnN0IG9mZnNldCAgPSB3aW5kb3cucGFnZVlPZmZzZXRcbiAgICBjb25zdCB2aXNpYmxlID0gd2luZG93LmlubmVySGVpZ2h0XG5cbiAgICAvKiBVcGRhdGUgb2Zmc2V0LCBpbiBjYXNlIHdpbmRvdyBpcyByZXNpemVkICovXG4gICAgaWYgKGV2ICYmIGV2LnR5cGUgPT09IFwicmVzaXplXCIpXG4gICAgICB0aGlzLnNldHVwKClcblxuICAgIC8qIFNldCBib3VuZHMgb2Ygc2lkZWJhciBjb250YWluZXIgLSBtdXN0IGJlIGNhbGN1bGF0ZWQgb24gZXZlcnkgcnVuLCBhc1xuICAgICAgIHRoZSBoZWlnaHQgb2YgdGhlIGNvbnRlbnQgbWlnaHQgY2hhbmdlIGR1ZSB0byBsb2FkaW5nIGltYWdlcyBldGMuICovXG4gICAgY29uc3QgYm91bmRzID0ge1xuICAgICAgdG9wOiB0aGlzLnBhZF8gPyB0aGlzLmhlYWRlcl8ub2Zmc2V0SGVpZ2h0IDogMCxcbiAgICAgIGJvdHRvbTogdGhpcy5wYXJlbnRfLm9mZnNldFRvcCArIHRoaXMucGFyZW50Xy5vZmZzZXRIZWlnaHRcbiAgICB9XG5cbiAgICAvKiBDYWxjdWxhdGUgbmV3IG9mZnNldCBhbmQgaGVpZ2h0ICovXG4gICAgY29uc3QgaGVpZ2h0ID0gdmlzaWJsZSAtIGJvdW5kcy50b3BcbiAgICAgICAgICAgICAgICAgLSBNYXRoLm1heCgwLCB0aGlzLm9mZnNldF8gLSBvZmZzZXQpXG4gICAgICAgICAgICAgICAgIC0gTWF0aC5tYXgoMCwgb2Zmc2V0ICsgdmlzaWJsZSAtIGJvdW5kcy5ib3R0b20pXG5cbiAgICAvKiBJZiBoZWlnaHQgY2hhbmdlZCwgdXBkYXRlIGVsZW1lbnQgKi9cbiAgICBpZiAoaGVpZ2h0ICE9PSB0aGlzLmhlaWdodF8pXG4gICAgICB0aGlzLmVsXy5zdHlsZS5oZWlnaHQgPSBgJHt0aGlzLmhlaWdodF8gPSBoZWlnaHR9cHhgXG5cbiAgICAvKiBTaWRlYmFyIHNob3VsZCBiZSBsb2NrZWQsIGFzIHdlJ3JlIGJlbG93IHBhcmVudCBvZmZzZXQgKi9cbiAgICBpZiAob2Zmc2V0ID49IHRoaXMub2Zmc2V0Xykge1xuICAgICAgaWYgKHRoaXMuZWxfLmRhdGFzZXQubWRTdGF0ZSAhPT0gXCJsb2NrXCIpXG4gICAgICAgIHRoaXMuZWxfLmRhdGFzZXQubWRTdGF0ZSA9IFwibG9ja1wiXG5cbiAgICAvKiBTaWRlYmFyIHNob3VsZCBiZSB1bmxvY2tlZCwgaWYgbG9ja2VkICovXG4gICAgfSBlbHNlIGlmICh0aGlzLmVsXy5kYXRhc2V0Lm1kU3RhdGUgPT09IFwibG9ja1wiKSB7XG4gICAgICB0aGlzLmVsXy5kYXRhc2V0Lm1kU3RhdGUgPSBcIlwiXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IGxvY2tlZCBzdGF0ZSBhbmQgaGVpZ2h0XG4gICAqL1xuICByZXNldCgpIHtcbiAgICB0aGlzLmVsXy5kYXRhc2V0Lm1kU3RhdGUgPSBcIlwiXG4gICAgdGhpcy5lbF8uc3R5bGUuaGVpZ2h0ID0gXCJcIlxuICAgIHRoaXMuaGVpZ2h0XyA9IDBcbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL1NpZGViYXIvUG9zaXRpb24uanMiLCIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4gKiBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuICogcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4gKiBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuICogRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HU1xuICogSU4gVEhFIFNPRlRXQVJFLlxuICovXG5cbmltcG9ydCBBZGFwdGVyIGZyb20gXCIuL1NvdXJjZS9BZGFwdGVyXCJcbmltcG9ydCBSZXBvc2l0b3J5IGZyb20gXCIuL1NvdXJjZS9SZXBvc2l0b3J5XCJcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogTW9kdWxlXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgQWRhcHRlcixcbiAgUmVwb3NpdG9yeVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL1NvdXJjZS5qcyIsIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbiAqIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4gKiByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3JcbiAqIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4gKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTXG4gKiBJTiBUSEUgU09GVFdBUkUuXG4gKi9cblxuaW1wb3J0IEdpdEh1YiBmcm9tIFwiLi9BZGFwdGVyL0dpdEh1YlwiXG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIE1vZHVsZVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIEdpdEh1YlxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9jb21wb25lbnRzL01hdGVyaWFsL1NvdXJjZS9BZGFwdGVyLmpzIiwiLypcbiAqIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuICogZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbiAqIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuICogc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbiAqIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1NcbiAqIElOIFRIRSBTT0ZUV0FSRS5cbiAqL1xuXG5pbXBvcnQgQWJzdHJhY3QgZnJvbSBcIi4vQWJzdHJhY3RcIlxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBDbGFzc1xuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBHaXRIdWIgZXh0ZW5kcyBBYnN0cmFjdCB7XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIHJlcG9zaXRvcnkgaW5mb3JtYXRpb24gZnJvbSBHaXRIdWJcbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBuYW1lXyAtIE5hbWUgb2YgdGhlIHJlcG9zaXRvcnlcbiAgICpcbiAgICogQHBhcmFtIHsoc3RyaW5nfEhUTUxBbmNob3JFbGVtZW50KX0gZWwgLSBTZWxlY3RvciBvciBIVE1MIGVsZW1lbnRcbiAgICovXG4gIGNvbnN0cnVjdG9yKGVsKSB7XG4gICAgc3VwZXIoZWwpXG5cbiAgICAvKiBFeHRyYWN0IHVzZXIgKGFuZCByZXBvc2l0b3J5IG5hbWUpIGZyb20gVVJMLCBhcyB3ZSBoYXZlIHRvIHF1ZXJ5IGZvciBhbGxcbiAgICAgICByZXBvc2l0b3JpZXMsIHRvIG9taXQgNDA0IGVycm9ycyBmb3IgcHJpdmF0ZSByZXBvc2l0b3JpZXMgKi9cbiAgICBjb25zdCBtYXRjaGVzID0gL14uK2dpdGh1YlxcLmNvbVxcLyhbXi9dKylcXC8/KFteL10rKT8uKiQvXG4gICAgICAuZXhlYyh0aGlzLmJhc2VfKVxuICAgIGlmIChtYXRjaGVzICYmIG1hdGNoZXMubGVuZ3RoID09PSAzKSB7XG4gICAgICBjb25zdCBbLCB1c2VyLCBuYW1lXSA9IG1hdGNoZXNcblxuICAgICAgLyogSW5pdGlhbGl6ZSBiYXNlIFVSTCBhbmQgcmVwb3NpdG9yeSBuYW1lICovXG4gICAgICB0aGlzLmJhc2VfID0gYGh0dHBzOi8vYXBpLmdpdGh1Yi5jb20vdXNlcnMvJHt1c2VyfS9yZXBvc2BcbiAgICAgIHRoaXMubmFtZV8gPSBuYW1lXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoIHJlbGV2YW50IHJlcG9zaXRvcnkgaW5mb3JtYXRpb24gZnJvbSBHaXRIdWJcbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZTxBcnJheTxzdHJpbmc+Pn0gUHJvbWlzZSByZXR1cm5pbmcgYW4gYXJyYXkgb2YgZmFjdHNcbiAgICovXG4gIGZldGNoXygpIHtcbiAgICBjb25zdCBwYWdpbmF0ZSA9IChwYWdlID0gMCkgPT4ge1xuICAgICAgcmV0dXJuIGZldGNoKGAke3RoaXMuYmFzZV99P3Blcl9wYWdlPTMwJnBhZ2U9JHtwYWdlfWApXG4gICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHJlc3BvbnNlLmpzb24oKSlcbiAgICAgICAgLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgICAgaWYgKCEoZGF0YSBpbnN0YW5jZW9mIEFycmF5KSlcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3JcblxuICAgICAgICAgIC8qIERpc3BsYXkgbnVtYmVyIG9mIHN0YXJzIGFuZCBmb3JrcywgaWYgcmVwb3NpdG9yeSBpcyBnaXZlbiAqL1xuICAgICAgICAgIGlmICh0aGlzLm5hbWVfKSB7XG4gICAgICAgICAgICBjb25zdCByZXBvID0gZGF0YS5maW5kKGl0ZW0gPT4gaXRlbS5uYW1lID09PSB0aGlzLm5hbWVfKVxuICAgICAgICAgICAgaWYgKCFyZXBvICYmIGRhdGEubGVuZ3RoID09PSAzMClcbiAgICAgICAgICAgICAgcmV0dXJuIHBhZ2luYXRlKHBhZ2UgKyAxKVxuXG4gICAgICAgICAgICAvKiBJZiB3ZSBmb3VuZCBhIHJlcG8sIGV4dHJhY3QgdGhlIGZhY3RzICovXG4gICAgICAgICAgICByZXR1cm4gcmVwb1xuICAgICAgICAgICAgICA/IFtcbiAgICAgICAgICAgICAgICBgJHt0aGlzLmZvcm1hdF8ocmVwby5zdGFyZ2F6ZXJzX2NvdW50KX0gU3RhcnNgLFxuICAgICAgICAgICAgICAgIGAke3RoaXMuZm9ybWF0XyhyZXBvLmZvcmtzX2NvdW50KX0gRm9ya3NgXG4gICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgOiBbXVxuXG4gICAgICAgICAgLyogRGlzcGxheSBudW1iZXIgb2YgcmVwb3NpdG9yaWVzLCBvdGhlcndpc2UgKi9cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgYCR7ZGF0YS5sZW5ndGh9IFJlcG9zaXRvcmllc2BcbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgLyogUGFnaW5hdGUgdGhyb3VnaCByZXBvcyAqL1xuICAgIHJldHVybiBwYWdpbmF0ZSgpXG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9Tb3VyY2UvQWRhcHRlci9HaXRIdWIuanMiLCIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4gKiBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuICogcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4gKiBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuICogRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HU1xuICogSU4gVEhFIFNPRlRXQVJFLlxuICovXG5cbmltcG9ydCBDb29raWVzIGZyb20gXCJqcy1jb29raWVcIlxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBDbGFzc1xuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBYnN0cmFjdCB7XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIHJlcG9zaXRvcnkgaW5mb3JtYXRpb25cbiAgICpcbiAgICogQGNvbnN0cnVjdG9yXG4gICAqXG4gICAqIEBwcm9wZXJ0eSB7SFRNTEFuY2hvckVsZW1lbnR9IGVsXyAtIExpbmsgdG8gcmVwb3NpdG9yeVxuICAgKiBAcHJvcGVydHkge3N0cmluZ30gYmFzZV8gLSBBUEkgYmFzZSBVUkxcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IHNhbHRfIC0gVW5pcXVlIGlkZW50aWZpZXJcbiAgICpcbiAgICogQHBhcmFtIHsoc3RyaW5nfEhUTUxBbmNob3JFbGVtZW50KX0gZWwgLSBTZWxlY3RvciBvciBIVE1MIGVsZW1lbnRcbiAgICovXG4gIGNvbnN0cnVjdG9yKGVsKSB7XG4gICAgY29uc3QgcmVmID0gKHR5cGVvZiBlbCA9PT0gXCJzdHJpbmdcIilcbiAgICAgID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbClcbiAgICAgIDogZWxcbiAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBIVE1MQW5jaG9yRWxlbWVudCkpXG4gICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3JcbiAgICB0aGlzLmVsXyA9IHJlZlxuXG4gICAgLyogUmV0cmlldmUgYmFzZSBVUkwgKi9cbiAgICB0aGlzLmJhc2VfID0gdGhpcy5lbF8uaHJlZlxuICAgIHRoaXMuc2FsdF8gPSB0aGlzLmhhc2hfKHRoaXMuYmFzZV8pXG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgZGF0YSBmcm9tIENvb2tpZSBvciBmZXRjaCBmcm9tIHJlc3BlY3RpdmUgQVBJXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2U8QXJyYXk8c3RyaW5nPj59IFByb21pc2UgdGhhdCByZXR1cm5zIGFuIGFycmF5IG9mIGZhY3RzXG4gICAqL1xuICBmZXRjaCgpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICBjb25zdCBjYWNoZWQgPSBDb29raWVzLmdldEpTT04oYCR7dGhpcy5zYWx0X30uY2FjaGUtc291cmNlYClcbiAgICAgIGlmICh0eXBlb2YgY2FjaGVkICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHJlc29sdmUoY2FjaGVkKVxuXG4gICAgICAvKiBJZiB0aGUgZGF0YSBpcyBub3QgY2FjaGVkIGluIGEgY29va2llLCBpbnZva2UgZmV0Y2ggYW5kIHNldFxuICAgICAgICAgYSBjb29raWUgdGhhdCBhdXRvbWF0aWNhbGx5IGV4cGlyZXMgaW4gMTUgbWludXRlcyAqL1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5mZXRjaF8oKS50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgIENvb2tpZXMuc2V0KGAke3RoaXMuc2FsdF99LmNhY2hlLXNvdXJjZWAsIGRhdGEsIHsgZXhwaXJlczogMSAvIDk2IH0pXG4gICAgICAgICAgcmVzb2x2ZShkYXRhKVxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQWJzdHJhY3QgcHJpdmF0ZSBmdW5jdGlvbiB0aGF0IGZldGNoZXMgcmVsZXZhbnQgcmVwb3NpdG9yeSBpbmZvcm1hdGlvblxuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICovXG4gIGZldGNoXygpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJmZXRjaF8oKTogTm90IGltcGxlbWVudGVkXCIpXG4gIH1cblxuICAvKipcbiAgICogRm9ybWF0IGEgbnVtYmVyIHdpdGggc3VmZml4XG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBudW1iZXIgLSBOdW1iZXIgdG8gZm9ybWF0XG4gICAqIEByZXR1cm4ge3N0cmluZ30gRm9ybWF0dGVkIG51bWJlclxuICAgKi9cbiAgZm9ybWF0XyhudW1iZXIpIHtcbiAgICBpZiAobnVtYmVyID4gMTAwMDApXG4gICAgICByZXR1cm4gYCR7KG51bWJlciAvIDEwMDApLnRvRml4ZWQoMCl9a2BcbiAgICBlbHNlIGlmIChudW1iZXIgPiAxMDAwKVxuICAgICAgcmV0dXJuIGAkeyhudW1iZXIgLyAxMDAwKS50b0ZpeGVkKDEpfWtgXG4gICAgcmV0dXJuIGAke251bWJlcn1gXG4gIH1cblxuICAvKipcbiAgICogU2ltcGxlIGhhc2ggZnVuY3Rpb25cbiAgICpcbiAgICogVGFrZW4gZnJvbSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS83NjE2NDg0LzEwNjU1ODRcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIElucHV0IHN0cmluZ1xuICAgKiBAcmV0dXJuIHtudW1iZXJ9IEhhc2hlZCBzdHJpbmdcbiAgICovXG4gIGhhc2hfKHN0cikge1xuICAgIGxldCBoYXNoID0gMFxuICAgIGlmIChzdHIubGVuZ3RoID09PSAwKSByZXR1cm4gaGFzaFxuICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBzdHIubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGhhc2ggID0gKChoYXNoIDw8IDUpIC0gaGFzaCkgKyBzdHIuY2hhckNvZGVBdChpKVxuICAgICAgaGFzaCB8PSAwIC8vIENvbnZlcnQgdG8gMzJiaXQgaW50ZWdlclxuICAgIH1cbiAgICByZXR1cm4gaGFzaFxuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwvU291cmNlL0FkYXB0ZXIvQWJzdHJhY3QuanMiLCIvKiFcbiAqIEphdmFTY3JpcHQgQ29va2llIHYyLjIuMFxuICogaHR0cHM6Ly9naXRodWIuY29tL2pzLWNvb2tpZS9qcy1jb29raWVcbiAqXG4gKiBDb3B5cmlnaHQgMjAwNiwgMjAxNSBLbGF1cyBIYXJ0bCAmIEZhZ25lciBCcmFja1xuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXG4gKi9cbjsoZnVuY3Rpb24gKGZhY3RvcnkpIHtcblx0dmFyIHJlZ2lzdGVyZWRJbk1vZHVsZUxvYWRlciA9IGZhbHNlO1xuXHRpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0ZGVmaW5lKGZhY3RvcnkpO1xuXHRcdHJlZ2lzdGVyZWRJbk1vZHVsZUxvYWRlciA9IHRydWU7XG5cdH1cblx0aWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRcdHJlZ2lzdGVyZWRJbk1vZHVsZUxvYWRlciA9IHRydWU7XG5cdH1cblx0aWYgKCFyZWdpc3RlcmVkSW5Nb2R1bGVMb2FkZXIpIHtcblx0XHR2YXIgT2xkQ29va2llcyA9IHdpbmRvdy5Db29raWVzO1xuXHRcdHZhciBhcGkgPSB3aW5kb3cuQ29va2llcyA9IGZhY3RvcnkoKTtcblx0XHRhcGkubm9Db25mbGljdCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHdpbmRvdy5Db29raWVzID0gT2xkQ29va2llcztcblx0XHRcdHJldHVybiBhcGk7XG5cdFx0fTtcblx0fVxufShmdW5jdGlvbiAoKSB7XG5cdGZ1bmN0aW9uIGV4dGVuZCAoKSB7XG5cdFx0dmFyIGkgPSAwO1xuXHRcdHZhciByZXN1bHQgPSB7fTtcblx0XHRmb3IgKDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dmFyIGF0dHJpYnV0ZXMgPSBhcmd1bWVudHNbIGkgXTtcblx0XHRcdGZvciAodmFyIGtleSBpbiBhdHRyaWJ1dGVzKSB7XG5cdFx0XHRcdHJlc3VsdFtrZXldID0gYXR0cmlidXRlc1trZXldO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0ZnVuY3Rpb24gaW5pdCAoY29udmVydGVyKSB7XG5cdFx0ZnVuY3Rpb24gYXBpIChrZXksIHZhbHVlLCBhdHRyaWJ1dGVzKSB7XG5cdFx0XHR2YXIgcmVzdWx0O1xuXHRcdFx0aWYgKHR5cGVvZiBkb2N1bWVudCA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBXcml0ZVxuXG5cdFx0XHRpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcblx0XHRcdFx0YXR0cmlidXRlcyA9IGV4dGVuZCh7XG5cdFx0XHRcdFx0cGF0aDogJy8nXG5cdFx0XHRcdH0sIGFwaS5kZWZhdWx0cywgYXR0cmlidXRlcyk7XG5cblx0XHRcdFx0aWYgKHR5cGVvZiBhdHRyaWJ1dGVzLmV4cGlyZXMgPT09ICdudW1iZXInKSB7XG5cdFx0XHRcdFx0dmFyIGV4cGlyZXMgPSBuZXcgRGF0ZSgpO1xuXHRcdFx0XHRcdGV4cGlyZXMuc2V0TWlsbGlzZWNvbmRzKGV4cGlyZXMuZ2V0TWlsbGlzZWNvbmRzKCkgKyBhdHRyaWJ1dGVzLmV4cGlyZXMgKiA4NjRlKzUpO1xuXHRcdFx0XHRcdGF0dHJpYnV0ZXMuZXhwaXJlcyA9IGV4cGlyZXM7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBXZSdyZSB1c2luZyBcImV4cGlyZXNcIiBiZWNhdXNlIFwibWF4LWFnZVwiIGlzIG5vdCBzdXBwb3J0ZWQgYnkgSUVcblx0XHRcdFx0YXR0cmlidXRlcy5leHBpcmVzID0gYXR0cmlidXRlcy5leHBpcmVzID8gYXR0cmlidXRlcy5leHBpcmVzLnRvVVRDU3RyaW5nKCkgOiAnJztcblxuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdHJlc3VsdCA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcblx0XHRcdFx0XHRpZiAoL15bXFx7XFxbXS8udGVzdChyZXN1bHQpKSB7XG5cdFx0XHRcdFx0XHR2YWx1ZSA9IHJlc3VsdDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gY2F0Y2ggKGUpIHt9XG5cblx0XHRcdFx0aWYgKCFjb252ZXJ0ZXIud3JpdGUpIHtcblx0XHRcdFx0XHR2YWx1ZSA9IGVuY29kZVVSSUNvbXBvbmVudChTdHJpbmcodmFsdWUpKVxuXHRcdFx0XHRcdFx0LnJlcGxhY2UoLyUoMjN8MjR8MjZ8MkJ8M0F8M0N8M0V8M0R8MkZ8M0Z8NDB8NUJ8NUR8NUV8NjB8N0J8N0R8N0MpL2csIGRlY29kZVVSSUNvbXBvbmVudCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBjb252ZXJ0ZXIud3JpdGUodmFsdWUsIGtleSk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRrZXkgPSBlbmNvZGVVUklDb21wb25lbnQoU3RyaW5nKGtleSkpO1xuXHRcdFx0XHRrZXkgPSBrZXkucmVwbGFjZSgvJSgyM3wyNHwyNnwyQnw1RXw2MHw3QykvZywgZGVjb2RlVVJJQ29tcG9uZW50KTtcblx0XHRcdFx0a2V5ID0ga2V5LnJlcGxhY2UoL1tcXChcXCldL2csIGVzY2FwZSk7XG5cblx0XHRcdFx0dmFyIHN0cmluZ2lmaWVkQXR0cmlidXRlcyA9ICcnO1xuXG5cdFx0XHRcdGZvciAodmFyIGF0dHJpYnV0ZU5hbWUgaW4gYXR0cmlidXRlcykge1xuXHRcdFx0XHRcdGlmICghYXR0cmlidXRlc1thdHRyaWJ1dGVOYW1lXSkge1xuXHRcdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHN0cmluZ2lmaWVkQXR0cmlidXRlcyArPSAnOyAnICsgYXR0cmlidXRlTmFtZTtcblx0XHRcdFx0XHRpZiAoYXR0cmlidXRlc1thdHRyaWJ1dGVOYW1lXSA9PT0gdHJ1ZSkge1xuXHRcdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHN0cmluZ2lmaWVkQXR0cmlidXRlcyArPSAnPScgKyBhdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiAoZG9jdW1lbnQuY29va2llID0ga2V5ICsgJz0nICsgdmFsdWUgKyBzdHJpbmdpZmllZEF0dHJpYnV0ZXMpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZWFkXG5cblx0XHRcdGlmICgha2V5KSB7XG5cdFx0XHRcdHJlc3VsdCA9IHt9O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBUbyBwcmV2ZW50IHRoZSBmb3IgbG9vcCBpbiB0aGUgZmlyc3QgcGxhY2UgYXNzaWduIGFuIGVtcHR5IGFycmF5XG5cdFx0XHQvLyBpbiBjYXNlIHRoZXJlIGFyZSBubyBjb29raWVzIGF0IGFsbC4gQWxzbyBwcmV2ZW50cyBvZGQgcmVzdWx0IHdoZW5cblx0XHRcdC8vIGNhbGxpbmcgXCJnZXQoKVwiXG5cdFx0XHR2YXIgY29va2llcyA9IGRvY3VtZW50LmNvb2tpZSA/IGRvY3VtZW50LmNvb2tpZS5zcGxpdCgnOyAnKSA6IFtdO1xuXHRcdFx0dmFyIHJkZWNvZGUgPSAvKCVbMC05QS1aXXsyfSkrL2c7XG5cdFx0XHR2YXIgaSA9IDA7XG5cblx0XHRcdGZvciAoOyBpIDwgY29va2llcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHR2YXIgcGFydHMgPSBjb29raWVzW2ldLnNwbGl0KCc9Jyk7XG5cdFx0XHRcdHZhciBjb29raWUgPSBwYXJ0cy5zbGljZSgxKS5qb2luKCc9Jyk7XG5cblx0XHRcdFx0aWYgKCF0aGlzLmpzb24gJiYgY29va2llLmNoYXJBdCgwKSA9PT0gJ1wiJykge1xuXHRcdFx0XHRcdGNvb2tpZSA9IGNvb2tpZS5zbGljZSgxLCAtMSk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdHZhciBuYW1lID0gcGFydHNbMF0ucmVwbGFjZShyZGVjb2RlLCBkZWNvZGVVUklDb21wb25lbnQpO1xuXHRcdFx0XHRcdGNvb2tpZSA9IGNvbnZlcnRlci5yZWFkID9cblx0XHRcdFx0XHRcdGNvbnZlcnRlci5yZWFkKGNvb2tpZSwgbmFtZSkgOiBjb252ZXJ0ZXIoY29va2llLCBuYW1lKSB8fFxuXHRcdFx0XHRcdFx0Y29va2llLnJlcGxhY2UocmRlY29kZSwgZGVjb2RlVVJJQ29tcG9uZW50KTtcblxuXHRcdFx0XHRcdGlmICh0aGlzLmpzb24pIHtcblx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdGNvb2tpZSA9IEpTT04ucGFyc2UoY29va2llKTtcblx0XHRcdFx0XHRcdH0gY2F0Y2ggKGUpIHt9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0aWYgKGtleSA9PT0gbmFtZSkge1xuXHRcdFx0XHRcdFx0cmVzdWx0ID0gY29va2llO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0aWYgKCFrZXkpIHtcblx0XHRcdFx0XHRcdHJlc3VsdFtuYW1lXSA9IGNvb2tpZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gY2F0Y2ggKGUpIHt9XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fVxuXG5cdFx0YXBpLnNldCA9IGFwaTtcblx0XHRhcGkuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0cmV0dXJuIGFwaS5jYWxsKGFwaSwga2V5KTtcblx0XHR9O1xuXHRcdGFwaS5nZXRKU09OID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIGFwaS5hcHBseSh7XG5cdFx0XHRcdGpzb246IHRydWVcblx0XHRcdH0sIFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKSk7XG5cdFx0fTtcblx0XHRhcGkuZGVmYXVsdHMgPSB7fTtcblxuXHRcdGFwaS5yZW1vdmUgPSBmdW5jdGlvbiAoa2V5LCBhdHRyaWJ1dGVzKSB7XG5cdFx0XHRhcGkoa2V5LCAnJywgZXh0ZW5kKGF0dHJpYnV0ZXMsIHtcblx0XHRcdFx0ZXhwaXJlczogLTFcblx0XHRcdH0pKTtcblx0XHR9O1xuXG5cdFx0YXBpLndpdGhDb252ZXJ0ZXIgPSBpbml0O1xuXG5cdFx0cmV0dXJuIGFwaTtcblx0fVxuXG5cdHJldHVybiBpbml0KGZ1bmN0aW9uICgpIHt9KTtcbn0pKTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbm9kZV9tb2R1bGVzL2pzLWNvb2tpZS9zcmMvanMuY29va2llLmpzXG4vLyBtb2R1bGUgaWQgPSA0M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvXG4gKiBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuICogcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4gKiBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuICogRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HU1xuICogSU4gVEhFIFNPRlRXQVJFLlxuICovXG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIENsYXNzXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlcG9zaXRvcnkge1xuXG4gIC8qKlxuICAgKiBSZW5kZXIgcmVwb3NpdG9yeSBpbmZvcm1hdGlvblxuICAgKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICpcbiAgICogQHByb3BlcnR5IHtIVE1MRWxlbWVudH0gZWxfIC0gUmVwb3NpdG9yeSBpbmZvcm1hdGlvblxuICAgKlxuICAgKiBAcGFyYW0geyhzdHJpbmd8SFRNTEVsZW1lbnQpfSBlbCAtIFNlbGVjdG9yIG9yIEhUTUwgZWxlbWVudFxuICAgKi9cbiAgY29uc3RydWN0b3IoZWwpIHtcbiAgICBjb25zdCByZWYgPSAodHlwZW9mIGVsID09PSBcInN0cmluZ1wiKVxuICAgICAgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsKVxuICAgICAgOiBlbFxuICAgIGlmICghKHJlZiBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSlcbiAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuICAgIHRoaXMuZWxfID0gcmVmXG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSB0aGUgcmVwb3NpdG9yeVxuICAgKlxuICAgKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IGZhY3RzIC0gRmFjdHMgdG8gYmUgcmVuZGVyZWRcbiAgICovXG4gIGluaXRpYWxpemUoZmFjdHMpIHtcbiAgICBpZiAoZmFjdHMubGVuZ3RoICYmIHRoaXMuZWxfLmNoaWxkcmVuLmxlbmd0aClcbiAgICAgIHRoaXMuZWxfLmNoaWxkcmVuW3RoaXMuZWxfLmNoaWxkcmVuLmxlbmd0aCAtIDFdLmFwcGVuZENoaWxkKFxuICAgICAgICA8dWwgY2xhc3M9XCJtZC1zb3VyY2VfX2ZhY3RzXCI+XG4gICAgICAgICAge2ZhY3RzLm1hcChmYWN0ID0+IDxsaSBjbGFzcz1cIm1kLXNvdXJjZV9fZmFjdFwiPntmYWN0fTwvbGk+KX1cbiAgICAgICAgPC91bD5cbiAgICAgIClcblxuICAgIC8qIEZpbmlzaCByZW5kZXJpbmcgd2l0aCBhbmltYXRpb24gKi9cbiAgICB0aGlzLmVsXy5kYXRhc2V0Lm1kU3RhdGUgPSBcImRvbmVcIlxuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwvU291cmNlL1JlcG9zaXRvcnkuanN4IiwiLypcbiAqIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuICogZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbiAqIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuICogc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbiAqIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1NcbiAqIElOIFRIRSBTT0ZUV0FSRS5cbiAqL1xuXG5pbXBvcnQgVG9nZ2xlIGZyb20gXCIuL1RhYnMvVG9nZ2xlXCJcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogTW9kdWxlXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgVG9nZ2xlXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL2NvbXBvbmVudHMvTWF0ZXJpYWwvVGFicy5qcyIsIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbiAqIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4gKiByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3JcbiAqIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4gKiBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTXG4gKiBJTiBUSEUgU09GVFdBUkUuXG4gKi9cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQ2xhc3NcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVG9nZ2xlIHtcblxuICAvKipcbiAgICogVG9nZ2xlIHRhYnMgdmlzaWJpbGl0eSBkZXBlbmRpbmcgb24gcGFnZSB5LW9mZnNldFxuICAgKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICpcbiAgICogQHByb3BlcnR5IHtIVE1MRWxlbWVudH0gZWxfIC0gQ29udGVudCBjb250YWluZXJcbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IG9mZnNldF8gLSBUb2dnbGUgcGFnZS15IG9mZnNldFxuICAgKiBAcHJvcGVydHkge2Jvb2xlYW59IGFjdGl2ZV8gLSBUYWJzIHZpc2liaWxpdHlcbiAgICpcbiAgICogQHBhcmFtIHsoc3RyaW5nfEhUTUxFbGVtZW50KX0gZWwgLSBTZWxlY3RvciBvciBIVE1MIGVsZW1lbnRcbiAgICovXG4gIGNvbnN0cnVjdG9yKGVsKSB7XG4gICAgY29uc3QgcmVmID0gKHR5cGVvZiBlbCA9PT0gXCJzdHJpbmdcIilcbiAgICAgID8gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbClcbiAgICAgIDogZWxcbiAgICBpZiAoIShyZWYgaW5zdGFuY2VvZiBOb2RlKSlcbiAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvclxuICAgIHRoaXMuZWxfID0gcmVmXG5cbiAgICAvKiBJbml0aWFsaXplIG9mZnNldCBhbmQgc3RhdGUgKi9cbiAgICB0aGlzLmFjdGl2ZV8gPSBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSB2aXNpYmlsaXR5XG4gICAqL1xuICB1cGRhdGUoKSB7XG4gICAgY29uc3QgYWN0aXZlID0gd2luZG93LnBhZ2VZT2Zmc2V0ID49XG4gICAgICB0aGlzLmVsXy5jaGlsZHJlblswXS5vZmZzZXRUb3AgKyAoNSAtIDQ4KSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IHF1aWNrIGhhY2sgdG8gZW5hYmxlIHNhbWUgaGFuZGxpbmcgZm9yIGhlcm9cbiAgICBpZiAoYWN0aXZlICE9PSB0aGlzLmFjdGl2ZV8pXG4gICAgICB0aGlzLmVsXy5kYXRhc2V0Lm1kU3RhdGUgPSAodGhpcy5hY3RpdmVfID0gYWN0aXZlKSA/IFwiaGlkZGVuXCIgOiBcIlwiXG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgdmlzaWJpbGl0eVxuICAgKi9cbiAgcmVzZXQoKSB7XG4gICAgdGhpcy5lbF8uZGF0YXNldC5tZFN0YXRlID0gXCJcIlxuICAgIHRoaXMuYWN0aXZlXyA9IGZhbHNlXG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvamF2YXNjcmlwdHMvY29tcG9uZW50cy9NYXRlcmlhbC9UYWJzL1RvZ2dsZS5qcyJdLCJzb3VyY2VSb290IjoiIn0="
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.da.js",
    "content": "!function(e,r){\"function\"==typeof define&&define.amd?define(r):\"object\"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===e.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var r,m,i;e.da=function(){this.pipeline.reset(),this.pipeline.add(e.da.trimmer,e.da.stopWordFilter,e.da.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.da.stemmer))},e.da.wordCharacters=\"A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤﬀ-ﬆＡ-Ｚａ-ｚ\",e.da.trimmer=e.trimmerSupport.generateTrimmer(e.da.wordCharacters),e.Pipeline.registerFunction(e.da.trimmer,\"trimmer-da\"),e.da.stemmer=(r=e.stemmerSupport.Among,m=e.stemmerSupport.SnowballProgram,i=new function(){var i,t,n,s=[new r(\"hed\",-1,1),new r(\"ethed\",0,1),new r(\"ered\",-1,1),new r(\"e\",-1,1),new r(\"erede\",3,1),new r(\"ende\",3,1),new r(\"erende\",5,1),new r(\"ene\",3,1),new r(\"erne\",3,1),new r(\"ere\",3,1),new r(\"en\",-1,1),new r(\"heden\",10,1),new r(\"eren\",10,1),new r(\"er\",-1,1),new r(\"heder\",13,1),new r(\"erer\",13,1),new r(\"s\",-1,2),new r(\"heds\",16,1),new r(\"es\",16,1),new r(\"endes\",18,1),new r(\"erendes\",19,1),new r(\"enes\",18,1),new r(\"ernes\",18,1),new r(\"eres\",18,1),new r(\"ens\",16,1),new r(\"hedens\",24,1),new r(\"erens\",24,1),new r(\"ers\",16,1),new r(\"ets\",16,1),new r(\"erets\",28,1),new r(\"et\",-1,1),new r(\"eret\",30,1)],o=[new r(\"gd\",-1,-1),new r(\"dt\",-1,-1),new r(\"gt\",-1,-1),new r(\"kt\",-1,-1)],a=[new r(\"ig\",-1,1),new r(\"lig\",0,1),new r(\"elig\",1,1),new r(\"els\",-1,1),new r(\"løst\",-1,2)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],u=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],c=new m;function l(){var e,r=c.limit-c.cursor;c.cursor>=t&&(e=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,c.find_among_b(o,4)?(c.bra=c.cursor,c.limit_backward=e,c.cursor=c.limit-r,c.cursor>c.limit_backward&&(c.cursor--,c.bra=c.cursor,c.slice_del())):c.limit_backward=e)}this.setCurrent=function(e){c.setCurrent(e)},this.getCurrent=function(){return c.getCurrent()},this.stem=function(){var e,r=c.cursor;return function(){var e,r=c.cursor+3;if(t=c.limit,0<=r&&r<=c.limit){for(i=r;;){if(e=c.cursor,c.in_grouping(d,97,248)){c.cursor=e;break}if((c.cursor=e)>=c.limit)return;c.cursor++}for(;!c.out_grouping(d,97,248);){if(c.cursor>=c.limit)return;c.cursor++}(t=c.cursor)<i&&(t=i)}}(),c.limit_backward=r,c.cursor=c.limit,function(){var e,r;if(c.cursor>=t&&(r=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,e=c.find_among_b(s,32),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del();break;case 2:c.in_grouping_b(u,97,229)&&c.slice_del()}}(),c.cursor=c.limit,l(),c.cursor=c.limit,function(){var e,r,i,n=c.limit-c.cursor;if(c.ket=c.cursor,c.eq_s_b(2,\"st\")&&(c.bra=c.cursor,c.eq_s_b(2,\"ig\")&&c.slice_del()),c.cursor=c.limit-n,c.cursor>=t&&(r=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,e=c.find_among_b(a,5),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del(),i=c.limit-c.cursor,l(),c.cursor=c.limit-i;break;case 2:c.slice_from(\"løs\")}}(),c.cursor=c.limit,c.cursor>=t&&(e=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,c.out_grouping_b(d,97,248)?(c.bra=c.cursor,n=c.slice_to(n),c.limit_backward=e,c.eq_v_b(n)&&c.slice_del()):c.limit_backward=e),!0}},function(e){return\"function\"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.da.stemmer,\"stemmer-da\"),e.da.stopWordFilter=e.generateStopWordFilter(\"ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været\".split(\" \")),e.Pipeline.registerFunction(e.da.stopWordFilter,\"stopWordFilter-da\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.de.js",
    "content": "!function(e,r){\"function\"==typeof define&&define.amd?define(r):\"object\"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===e.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var _,p,r;e.de=function(){this.pipeline.reset(),this.pipeline.add(e.de.trimmer,e.de.stopWordFilter,e.de.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.de.stemmer))},e.de.wordCharacters=\"A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤﬀ-ﬆＡ-Ｚａ-ｚ\",e.de.trimmer=e.trimmerSupport.generateTrimmer(e.de.wordCharacters),e.Pipeline.registerFunction(e.de.trimmer,\"trimmer-de\"),e.de.stemmer=(_=e.stemmerSupport.Among,p=e.stemmerSupport.SnowballProgram,r=new function(){var r,n,i,s=[new _(\"\",-1,6),new _(\"U\",0,2),new _(\"Y\",0,1),new _(\"ä\",0,3),new _(\"ö\",0,4),new _(\"ü\",0,5)],o=[new _(\"e\",-1,2),new _(\"em\",-1,1),new _(\"en\",-1,2),new _(\"ern\",-1,1),new _(\"er\",-1,1),new _(\"s\",-1,3),new _(\"es\",5,2)],c=[new _(\"en\",-1,1),new _(\"er\",-1,1),new _(\"st\",-1,2),new _(\"est\",2,1)],u=[new _(\"ig\",-1,1),new _(\"lich\",-1,1)],a=[new _(\"end\",-1,1),new _(\"ig\",-1,2),new _(\"ung\",-1,1),new _(\"lich\",-1,3),new _(\"isch\",-1,2),new _(\"ik\",-1,2),new _(\"heit\",-1,3),new _(\"keit\",-1,4)],t=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8],d=[117,30,5],l=[117,30,4],m=new p;function h(e,r,n){return!(!m.eq_s(1,e)||(m.ket=m.cursor,!m.in_grouping(t,97,252)))&&(m.slice_from(r),m.cursor=n,!0)}function w(){for(;!m.in_grouping(t,97,252);){if(m.cursor>=m.limit)return!0;m.cursor++}for(;!m.out_grouping(t,97,252);){if(m.cursor>=m.limit)return!0;m.cursor++}return!1}function f(){return i<=m.cursor}function b(){return n<=m.cursor}this.setCurrent=function(e){m.setCurrent(e)},this.getCurrent=function(){return m.getCurrent()},this.stem=function(){var e=m.cursor;return function(){for(var e,r,n,i,s=m.cursor;;)if(e=m.cursor,m.bra=e,m.eq_s(1,\"ß\"))m.ket=m.cursor,m.slice_from(\"ss\");else{if(e>=m.limit)break;m.cursor=e+1}for(m.cursor=s;;)for(r=m.cursor;;){if(n=m.cursor,m.in_grouping(t,97,252)){if(i=m.cursor,m.bra=i,h(\"u\",\"U\",n))break;if(m.cursor=i,h(\"y\",\"Y\",n))break}if(n>=m.limit)return m.cursor=r;m.cursor=n+1}}(),m.cursor=e,function(){i=m.limit,n=i;var e=m.cursor+3;0<=e&&e<=m.limit&&(r=e,w()||((i=m.cursor)<r&&(i=r),w()||(n=m.cursor)))}(),m.limit_backward=e,m.cursor=m.limit,function(){var e,r,n,i,s=m.limit-m.cursor;if(m.ket=m.cursor,(e=m.find_among_b(o,7))&&(m.bra=m.cursor,f()))switch(e){case 1:m.slice_del();break;case 2:m.slice_del(),m.ket=m.cursor,m.eq_s_b(1,\"s\")&&(m.bra=m.cursor,m.eq_s_b(3,\"nis\")&&m.slice_del());break;case 3:m.in_grouping_b(d,98,116)&&m.slice_del()}if(m.cursor=m.limit-s,m.ket=m.cursor,(e=m.find_among_b(c,4))&&(m.bra=m.cursor,f()))switch(e){case 1:m.slice_del();break;case 2:if(m.in_grouping_b(l,98,116)){var t=m.cursor-3;m.limit_backward<=t&&t<=m.limit&&(m.cursor=t,m.slice_del())}}if(m.cursor=m.limit-s,m.ket=m.cursor,(e=m.find_among_b(a,8))&&(m.bra=m.cursor,b()))switch(e){case 1:m.slice_del(),m.ket=m.cursor,m.eq_s_b(2,\"ig\")&&(m.bra=m.cursor,r=m.limit-m.cursor,m.eq_s_b(1,\"e\")||(m.cursor=m.limit-r,b()&&m.slice_del()));break;case 2:n=m.limit-m.cursor,m.eq_s_b(1,\"e\")||(m.cursor=m.limit-n,m.slice_del());break;case 3:if(m.slice_del(),m.ket=m.cursor,i=m.limit-m.cursor,!m.eq_s_b(2,\"er\")&&(m.cursor=m.limit-i,!m.eq_s_b(2,\"en\")))break;m.bra=m.cursor,f()&&m.slice_del();break;case 4:m.slice_del(),m.ket=m.cursor,(e=m.find_among_b(u,2))&&(m.bra=m.cursor,b()&&1==e&&m.slice_del())}}(),m.cursor=m.limit_backward,function(){for(var e,r;;){if(r=m.cursor,m.bra=r,!(e=m.find_among(s,6)))return;switch(m.ket=m.cursor,e){case 1:m.slice_from(\"y\");break;case 2:case 5:m.slice_from(\"u\");break;case 3:m.slice_from(\"a\");break;case 4:m.slice_from(\"o\");break;case 6:if(m.cursor>=m.limit)return;m.cursor++}}}(),!0}},function(e){return\"function\"==typeof e.update?e.update(function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}):(r.setCurrent(e),r.stem(),r.getCurrent())}),e.Pipeline.registerFunction(e.de.stemmer,\"stemmer-de\"),e.de.stopWordFilter=e.generateStopWordFilter(\"aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über\".split(\" \")),e.Pipeline.registerFunction(e.de.stopWordFilter,\"stopWordFilter-de\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.du.js",
    "content": "!function(r,e){\"function\"==typeof define&&define.amd?define(e):\"object\"==typeof exports?module.exports=e():e()(r.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===r.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var v,q,e;r.du=function(){this.pipeline.reset(),this.pipeline.add(r.du.trimmer,r.du.stopWordFilter,r.du.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(r.du.stemmer))},r.du.wordCharacters=\"A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤﬀ-ﬆＡ-Ｚａ-ｚ\",r.du.trimmer=r.trimmerSupport.generateTrimmer(r.du.wordCharacters),r.Pipeline.registerFunction(r.du.trimmer,\"trimmer-du\"),r.du.stemmer=(v=r.stemmerSupport.Among,q=r.stemmerSupport.SnowballProgram,e=new function(){var e,i,u,o=[new v(\"\",-1,6),new v(\"á\",0,1),new v(\"ä\",0,1),new v(\"é\",0,2),new v(\"ë\",0,2),new v(\"í\",0,3),new v(\"ï\",0,3),new v(\"ó\",0,4),new v(\"ö\",0,4),new v(\"ú\",0,5),new v(\"ü\",0,5)],n=[new v(\"\",-1,3),new v(\"I\",0,2),new v(\"Y\",0,1)],t=[new v(\"dd\",-1,-1),new v(\"kk\",-1,-1),new v(\"tt\",-1,-1)],c=[new v(\"ene\",-1,2),new v(\"se\",-1,3),new v(\"en\",-1,2),new v(\"heden\",2,1),new v(\"s\",-1,3)],a=[new v(\"end\",-1,1),new v(\"ig\",-1,2),new v(\"ing\",-1,1),new v(\"lijk\",-1,3),new v(\"baar\",-1,4),new v(\"bar\",-1,5)],l=[new v(\"aa\",-1,-1),new v(\"ee\",-1,-1),new v(\"oo\",-1,-1),new v(\"uu\",-1,-1)],m=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],d=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],f=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],_=new q;function s(r){return(_.cursor=r)>=_.limit||(_.cursor++,!1)}function w(){for(;!_.in_grouping(m,97,232);){if(_.cursor>=_.limit)return!0;_.cursor++}for(;!_.out_grouping(m,97,232);){if(_.cursor>=_.limit)return!0;_.cursor++}return!1}function b(){return i<=_.cursor}function p(){return e<=_.cursor}function g(){var r=_.limit-_.cursor;_.find_among_b(t,3)&&(_.cursor=_.limit-r,_.ket=_.cursor,_.cursor>_.limit_backward&&(_.cursor--,_.bra=_.cursor,_.slice_del()))}function h(){var r;u=!1,_.ket=_.cursor,_.eq_s_b(1,\"e\")&&(_.bra=_.cursor,b()&&(r=_.limit-_.cursor,_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-r,_.slice_del(),u=!0,g())))}function k(){var r;b()&&(r=_.limit-_.cursor,_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-r,_.eq_s_b(3,\"gem\")||(_.cursor=_.limit-r,_.slice_del(),g())))}this.setCurrent=function(r){_.setCurrent(r)},this.getCurrent=function(){return _.getCurrent()},this.stem=function(){var r=_.cursor;return function(){for(var r,e,i,n=_.cursor;;){if(_.bra=_.cursor,r=_.find_among(o,11))switch(_.ket=_.cursor,r){case 1:_.slice_from(\"a\");continue;case 2:_.slice_from(\"e\");continue;case 3:_.slice_from(\"i\");continue;case 4:_.slice_from(\"o\");continue;case 5:_.slice_from(\"u\");continue;case 6:if(_.cursor>=_.limit)break;_.cursor++;continue}break}for(_.cursor=n,_.bra=n,_.eq_s(1,\"y\")?(_.ket=_.cursor,_.slice_from(\"Y\")):_.cursor=n;;)if(e=_.cursor,_.in_grouping(m,97,232)){if(i=_.cursor,_.bra=i,_.eq_s(1,\"i\"))_.ket=_.cursor,_.in_grouping(m,97,232)&&(_.slice_from(\"I\"),_.cursor=e);else if(_.cursor=i,_.eq_s(1,\"y\"))_.ket=_.cursor,_.slice_from(\"Y\"),_.cursor=e;else if(s(e))break}else if(s(e))break}(),_.cursor=r,i=_.limit,e=i,w()||((i=_.cursor)<3&&(i=3),w()||(e=_.cursor)),_.limit_backward=r,_.cursor=_.limit,function(){var r,e,i,n,o,t,s=_.limit-_.cursor;if(_.ket=_.cursor,r=_.find_among_b(c,5))switch(_.bra=_.cursor,r){case 1:b()&&_.slice_from(\"heid\");break;case 2:k();break;case 3:b()&&_.out_grouping_b(f,97,232)&&_.slice_del()}if(_.cursor=_.limit-s,h(),_.cursor=_.limit-s,_.ket=_.cursor,_.eq_s_b(4,\"heid\")&&(_.bra=_.cursor,p()&&(e=_.limit-_.cursor,_.eq_s_b(1,\"c\")||(_.cursor=_.limit-e,_.slice_del(),_.ket=_.cursor,_.eq_s_b(2,\"en\")&&(_.bra=_.cursor,k())))),_.cursor=_.limit-s,_.ket=_.cursor,r=_.find_among_b(a,6))switch(_.bra=_.cursor,r){case 1:if(p()){if(_.slice_del(),i=_.limit-_.cursor,_.ket=_.cursor,_.eq_s_b(2,\"ig\")&&(_.bra=_.cursor,p()&&(n=_.limit-_.cursor,!_.eq_s_b(1,\"e\")))){_.cursor=_.limit-n,_.slice_del();break}_.cursor=_.limit-i,g()}break;case 2:p()&&(o=_.limit-_.cursor,_.eq_s_b(1,\"e\")||(_.cursor=_.limit-o,_.slice_del()));break;case 3:p()&&(_.slice_del(),h());break;case 4:p()&&_.slice_del();break;case 5:p()&&u&&_.slice_del()}_.cursor=_.limit-s,_.out_grouping_b(d,73,232)&&(t=_.limit-_.cursor,_.find_among_b(l,4)&&_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-t,_.ket=_.cursor,_.cursor>_.limit_backward&&(_.cursor--,_.bra=_.cursor,_.slice_del())))}(),_.cursor=_.limit_backward,function(){for(var r;;)if(_.bra=_.cursor,r=_.find_among(n,3))switch(_.ket=_.cursor,r){case 1:_.slice_from(\"y\");break;case 2:_.slice_from(\"i\");break;case 3:if(_.cursor>=_.limit)return;_.cursor++}}(),!0}},function(r){return\"function\"==typeof r.update?r.update(function(r){return e.setCurrent(r),e.stem(),e.getCurrent()}):(e.setCurrent(r),e.stem(),e.getCurrent())}),r.Pipeline.registerFunction(r.du.stemmer,\"stemmer-du\"),r.du.stopWordFilter=r.generateStopWordFilter(\" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou\".split(\" \")),r.Pipeline.registerFunction(r.du.stopWordFilter,\"stopWordFilter-du\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.es.js",
    "content": "!function(e,s){\"function\"==typeof define&&define.amd?define(s):\"object\"==typeof exports?module.exports=s():s()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===e.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var C,P,s;e.es=function(){this.pipeline.reset(),this.pipeline.add(e.es.trimmer,e.es.stopWordFilter,e.es.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.es.stemmer))},e.es.wordCharacters=\"A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤﬀ-ﬆＡ-Ｚａ-ｚ\",e.es.trimmer=e.trimmerSupport.generateTrimmer(e.es.wordCharacters),e.Pipeline.registerFunction(e.es.trimmer,\"trimmer-es\"),e.es.stemmer=(C=e.stemmerSupport.Among,P=e.stemmerSupport.SnowballProgram,s=new function(){var r,n,i,a=[new C(\"\",-1,6),new C(\"á\",0,1),new C(\"é\",0,2),new C(\"í\",0,3),new C(\"ó\",0,4),new C(\"ú\",0,5)],t=[new C(\"la\",-1,-1),new C(\"sela\",0,-1),new C(\"le\",-1,-1),new C(\"me\",-1,-1),new C(\"se\",-1,-1),new C(\"lo\",-1,-1),new C(\"selo\",5,-1),new C(\"las\",-1,-1),new C(\"selas\",7,-1),new C(\"les\",-1,-1),new C(\"los\",-1,-1),new C(\"selos\",10,-1),new C(\"nos\",-1,-1)],o=[new C(\"ando\",-1,6),new C(\"iendo\",-1,6),new C(\"yendo\",-1,7),new C(\"ándo\",-1,2),new C(\"iéndo\",-1,1),new C(\"ar\",-1,6),new C(\"er\",-1,6),new C(\"ir\",-1,6),new C(\"ár\",-1,3),new C(\"ér\",-1,4),new C(\"ír\",-1,5)],s=[new C(\"ic\",-1,-1),new C(\"ad\",-1,-1),new C(\"os\",-1,-1),new C(\"iv\",-1,1)],u=[new C(\"able\",-1,1),new C(\"ible\",-1,1),new C(\"ante\",-1,1)],w=[new C(\"ic\",-1,1),new C(\"abil\",-1,1),new C(\"iv\",-1,1)],c=[new C(\"ica\",-1,1),new C(\"ancia\",-1,2),new C(\"encia\",-1,5),new C(\"adora\",-1,2),new C(\"osa\",-1,1),new C(\"ista\",-1,1),new C(\"iva\",-1,9),new C(\"anza\",-1,1),new C(\"logía\",-1,3),new C(\"idad\",-1,8),new C(\"able\",-1,1),new C(\"ible\",-1,1),new C(\"ante\",-1,2),new C(\"mente\",-1,7),new C(\"amente\",13,6),new C(\"ación\",-1,2),new C(\"ución\",-1,4),new C(\"ico\",-1,1),new C(\"ismo\",-1,1),new C(\"oso\",-1,1),new C(\"amiento\",-1,1),new C(\"imiento\",-1,1),new C(\"ivo\",-1,9),new C(\"ador\",-1,2),new C(\"icas\",-1,1),new C(\"ancias\",-1,2),new C(\"encias\",-1,5),new C(\"adoras\",-1,2),new C(\"osas\",-1,1),new C(\"istas\",-1,1),new C(\"ivas\",-1,9),new C(\"anzas\",-1,1),new C(\"logías\",-1,3),new C(\"idades\",-1,8),new C(\"ables\",-1,1),new C(\"ibles\",-1,1),new C(\"aciones\",-1,2),new C(\"uciones\",-1,4),new C(\"adores\",-1,2),new C(\"antes\",-1,2),new C(\"icos\",-1,1),new C(\"ismos\",-1,1),new C(\"osos\",-1,1),new C(\"amientos\",-1,1),new C(\"imientos\",-1,1),new C(\"ivos\",-1,9)],m=[new C(\"ya\",-1,1),new C(\"ye\",-1,1),new C(\"yan\",-1,1),new C(\"yen\",-1,1),new C(\"yeron\",-1,1),new C(\"yendo\",-1,1),new C(\"yo\",-1,1),new C(\"yas\",-1,1),new C(\"yes\",-1,1),new C(\"yais\",-1,1),new C(\"yamos\",-1,1),new C(\"yó\",-1,1)],l=[new C(\"aba\",-1,2),new C(\"ada\",-1,2),new C(\"ida\",-1,2),new C(\"ara\",-1,2),new C(\"iera\",-1,2),new C(\"ía\",-1,2),new C(\"aría\",5,2),new C(\"ería\",5,2),new C(\"iría\",5,2),new C(\"ad\",-1,2),new C(\"ed\",-1,2),new C(\"id\",-1,2),new C(\"ase\",-1,2),new C(\"iese\",-1,2),new C(\"aste\",-1,2),new C(\"iste\",-1,2),new C(\"an\",-1,2),new C(\"aban\",16,2),new C(\"aran\",16,2),new C(\"ieran\",16,2),new C(\"ían\",16,2),new C(\"arían\",20,2),new C(\"erían\",20,2),new C(\"irían\",20,2),new C(\"en\",-1,1),new C(\"asen\",24,2),new C(\"iesen\",24,2),new C(\"aron\",-1,2),new C(\"ieron\",-1,2),new C(\"arán\",-1,2),new C(\"erán\",-1,2),new C(\"irán\",-1,2),new C(\"ado\",-1,2),new C(\"ido\",-1,2),new C(\"ando\",-1,2),new C(\"iendo\",-1,2),new C(\"ar\",-1,2),new C(\"er\",-1,2),new C(\"ir\",-1,2),new C(\"as\",-1,2),new C(\"abas\",39,2),new C(\"adas\",39,2),new C(\"idas\",39,2),new C(\"aras\",39,2),new C(\"ieras\",39,2),new C(\"ías\",39,2),new C(\"arías\",45,2),new C(\"erías\",45,2),new C(\"irías\",45,2),new C(\"es\",-1,1),new C(\"ases\",49,2),new C(\"ieses\",49,2),new C(\"abais\",-1,2),new C(\"arais\",-1,2),new C(\"ierais\",-1,2),new C(\"íais\",-1,2),new C(\"aríais\",55,2),new C(\"eríais\",55,2),new C(\"iríais\",55,2),new C(\"aseis\",-1,2),new C(\"ieseis\",-1,2),new C(\"asteis\",-1,2),new C(\"isteis\",-1,2),new C(\"áis\",-1,2),new C(\"éis\",-1,1),new C(\"aréis\",64,2),new C(\"eréis\",64,2),new C(\"iréis\",64,2),new C(\"ados\",-1,2),new C(\"idos\",-1,2),new C(\"amos\",-1,2),new C(\"ábamos\",70,2),new C(\"áramos\",70,2),new C(\"iéramos\",70,2),new C(\"íamos\",70,2),new C(\"aríamos\",74,2),new C(\"eríamos\",74,2),new C(\"iríamos\",74,2),new C(\"emos\",-1,1),new C(\"aremos\",78,2),new C(\"eremos\",78,2),new C(\"iremos\",78,2),new C(\"ásemos\",78,2),new C(\"iésemos\",78,2),new C(\"imos\",-1,2),new C(\"arás\",-1,2),new C(\"erás\",-1,2),new C(\"irás\",-1,2),new C(\"ís\",-1,2),new C(\"ará\",-1,2),new C(\"erá\",-1,2),new C(\"irá\",-1,2),new C(\"aré\",-1,2),new C(\"eré\",-1,2),new C(\"iré\",-1,2),new C(\"ió\",-1,2)],d=[new C(\"a\",-1,1),new C(\"e\",-1,2),new C(\"o\",-1,1),new C(\"os\",-1,1),new C(\"á\",-1,1),new C(\"é\",-1,2),new C(\"í\",-1,1),new C(\"ó\",-1,1)],b=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,4,10],f=new P;function _(){if(f.out_grouping(b,97,252)){for(;!f.in_grouping(b,97,252);){if(f.cursor>=f.limit)return!0;f.cursor++}return!1}return!0}function h(){var e,s=f.cursor;if(function(){if(f.in_grouping(b,97,252)){var e=f.cursor;if(_()){if(f.cursor=e,!f.in_grouping(b,97,252))return!0;for(;!f.out_grouping(b,97,252);){if(f.cursor>=f.limit)return!0;f.cursor++}}return!1}return!0}()){if(f.cursor=s,!f.out_grouping(b,97,252))return;if(e=f.cursor,_()){if(f.cursor=e,!f.in_grouping(b,97,252)||f.cursor>=f.limit)return;f.cursor++}}i=f.cursor}function v(){for(;!f.in_grouping(b,97,252);){if(f.cursor>=f.limit)return!1;f.cursor++}for(;!f.out_grouping(b,97,252);){if(f.cursor>=f.limit)return!1;f.cursor++}return!0}function p(){return i<=f.cursor}function g(){return r<=f.cursor}function k(e,s){if(!g())return!0;f.slice_del(),f.ket=f.cursor;var r=f.find_among_b(e,s);return r&&(f.bra=f.cursor,1==r&&g()&&f.slice_del()),!1}function y(e){return!g()||(f.slice_del(),f.ket=f.cursor,f.eq_s_b(2,e)&&(f.bra=f.cursor,g()&&f.slice_del()),!1)}function q(){var e;if(f.ket=f.cursor,e=f.find_among_b(c,46)){switch(f.bra=f.cursor,e){case 1:if(!g())return!1;f.slice_del();break;case 2:if(y(\"ic\"))return!1;break;case 3:if(!g())return!1;f.slice_from(\"log\");break;case 4:if(!g())return!1;f.slice_from(\"u\");break;case 5:if(!g())return!1;f.slice_from(\"ente\");break;case 6:if(!(n<=f.cursor))return!1;f.slice_del(),f.ket=f.cursor,(e=f.find_among_b(s,4))&&(f.bra=f.cursor,g()&&(f.slice_del(),1==e&&(f.ket=f.cursor,f.eq_s_b(2,\"at\")&&(f.bra=f.cursor,g()&&f.slice_del()))));break;case 7:if(k(u,3))return!1;break;case 8:if(k(w,3))return!1;break;case 9:if(y(\"at\"))return!1}return!0}return!1}this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var e,s=f.cursor;return e=f.cursor,i=f.limit,r=n=i,h(),f.cursor=e,v()&&(n=f.cursor,v()&&(r=f.cursor)),f.limit_backward=s,f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,f.find_among_b(t,13)&&(f.bra=f.cursor,(e=f.find_among_b(o,11))&&p()))switch(e){case 1:f.bra=f.cursor,f.slice_from(\"iendo\");break;case 2:f.bra=f.cursor,f.slice_from(\"ando\");break;case 3:f.bra=f.cursor,f.slice_from(\"ar\");break;case 4:f.bra=f.cursor,f.slice_from(\"er\");break;case 5:f.bra=f.cursor,f.slice_from(\"ir\");break;case 6:f.slice_del();break;case 7:f.eq_s_b(1,\"u\")&&f.slice_del()}}(),f.cursor=f.limit,q()||(f.cursor=f.limit,function(){var e,s;if(f.cursor>=i&&(s=f.limit_backward,f.limit_backward=i,f.ket=f.cursor,e=f.find_among_b(m,12),f.limit_backward=s,e)){if(f.bra=f.cursor,1==e){if(!f.eq_s_b(1,\"u\"))return!1;f.slice_del()}return!0}return!1}()||(f.cursor=f.limit,function(){var e,s,r,n;if(f.cursor>=i&&(s=f.limit_backward,f.limit_backward=i,f.ket=f.cursor,e=f.find_among_b(l,96),f.limit_backward=s,e))switch(f.bra=f.cursor,e){case 1:r=f.limit-f.cursor,f.eq_s_b(1,\"u\")?(n=f.limit-f.cursor,f.eq_s_b(1,\"g\")?f.cursor=f.limit-n:f.cursor=f.limit-r):f.cursor=f.limit-r,f.bra=f.cursor;case 2:f.slice_del()}}())),f.cursor=f.limit,function(){var e,s;if(f.ket=f.cursor,e=f.find_among_b(d,8))switch(f.bra=f.cursor,e){case 1:p()&&f.slice_del();break;case 2:p()&&(f.slice_del(),f.ket=f.cursor,f.eq_s_b(1,\"u\")&&(f.bra=f.cursor,s=f.limit-f.cursor,f.eq_s_b(1,\"g\")&&(f.cursor=f.limit-s,p()&&f.slice_del())))}}(),f.cursor=f.limit_backward,function(){for(var e;;){if(f.bra=f.cursor,e=f.find_among(a,6))switch(f.ket=f.cursor,e){case 1:f.slice_from(\"a\");continue;case 2:f.slice_from(\"e\");continue;case 3:f.slice_from(\"i\");continue;case 4:f.slice_from(\"o\");continue;case 5:f.slice_from(\"u\");continue;case 6:if(f.cursor>=f.limit)break;f.cursor++;continue}break}}(),!0}},function(e){return\"function\"==typeof e.update?e.update(function(e){return s.setCurrent(e),s.stem(),s.getCurrent()}):(s.setCurrent(e),s.stem(),s.getCurrent())}),e.Pipeline.registerFunction(e.es.stemmer,\"stemmer-es\"),e.es.stopWordFilter=e.generateStopWordFilter(\"a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos\".split(\" \")),e.Pipeline.registerFunction(e.es.stopWordFilter,\"stopWordFilter-es\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.fi.js",
    "content": "!function(i,e){\"function\"==typeof define&&define.amd?define(e):\"object\"==typeof exports?module.exports=e():e()(i.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===i.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var v,C,e;i.fi=function(){this.pipeline.reset(),this.pipeline.add(i.fi.trimmer,i.fi.stopWordFilter,i.fi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(i.fi.stemmer))},i.fi.wordCharacters=\"A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤﬀ-ﬆＡ-Ｚａ-ｚ\",i.fi.trimmer=i.trimmerSupport.generateTrimmer(i.fi.wordCharacters),i.Pipeline.registerFunction(i.fi.trimmer,\"trimmer-fi\"),i.fi.stemmer=(v=i.stemmerSupport.Among,C=i.stemmerSupport.SnowballProgram,e=new function(){var n,t,l,o,r=[new v(\"pa\",-1,1),new v(\"sti\",-1,2),new v(\"kaan\",-1,1),new v(\"han\",-1,1),new v(\"kin\",-1,1),new v(\"hän\",-1,1),new v(\"kään\",-1,1),new v(\"ko\",-1,1),new v(\"pä\",-1,1),new v(\"kö\",-1,1)],s=[new v(\"lla\",-1,-1),new v(\"na\",-1,-1),new v(\"ssa\",-1,-1),new v(\"ta\",-1,-1),new v(\"lta\",3,-1),new v(\"sta\",3,-1)],a=[new v(\"llä\",-1,-1),new v(\"nä\",-1,-1),new v(\"ssä\",-1,-1),new v(\"tä\",-1,-1),new v(\"ltä\",3,-1),new v(\"stä\",3,-1)],u=[new v(\"lle\",-1,-1),new v(\"ine\",-1,-1)],c=[new v(\"nsa\",-1,3),new v(\"mme\",-1,3),new v(\"nne\",-1,3),new v(\"ni\",-1,2),new v(\"si\",-1,1),new v(\"an\",-1,4),new v(\"en\",-1,6),new v(\"än\",-1,5),new v(\"nsä\",-1,3)],i=[new v(\"aa\",-1,-1),new v(\"ee\",-1,-1),new v(\"ii\",-1,-1),new v(\"oo\",-1,-1),new v(\"uu\",-1,-1),new v(\"ää\",-1,-1),new v(\"öö\",-1,-1)],m=[new v(\"a\",-1,8),new v(\"lla\",0,-1),new v(\"na\",0,-1),new v(\"ssa\",0,-1),new v(\"ta\",0,-1),new v(\"lta\",4,-1),new v(\"sta\",4,-1),new v(\"tta\",4,9),new v(\"lle\",-1,-1),new v(\"ine\",-1,-1),new v(\"ksi\",-1,-1),new v(\"n\",-1,7),new v(\"han\",11,1),new v(\"den\",11,-1,q),new v(\"seen\",11,-1,j),new v(\"hen\",11,2),new v(\"tten\",11,-1,q),new v(\"hin\",11,3),new v(\"siin\",11,-1,q),new v(\"hon\",11,4),new v(\"hän\",11,5),new v(\"hön\",11,6),new v(\"ä\",-1,8),new v(\"llä\",22,-1),new v(\"nä\",22,-1),new v(\"ssä\",22,-1),new v(\"tä\",22,-1),new v(\"ltä\",26,-1),new v(\"stä\",26,-1),new v(\"ttä\",26,9)],w=[new v(\"eja\",-1,-1),new v(\"mma\",-1,1),new v(\"imma\",1,-1),new v(\"mpa\",-1,1),new v(\"impa\",3,-1),new v(\"mmi\",-1,1),new v(\"immi\",5,-1),new v(\"mpi\",-1,1),new v(\"impi\",7,-1),new v(\"ejä\",-1,-1),new v(\"mmä\",-1,1),new v(\"immä\",10,-1),new v(\"mpä\",-1,1),new v(\"impä\",12,-1)],_=[new v(\"i\",-1,-1),new v(\"j\",-1,-1)],k=[new v(\"mma\",-1,1),new v(\"imma\",0,-1)],b=[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],e=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],f=[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],h=new C;function p(){for(var i;i=h.cursor,!h.in_grouping(d,97,246);){if((h.cursor=i)>=h.limit)return!0;h.cursor++}for(h.cursor=i;!h.out_grouping(d,97,246);){if(h.cursor>=h.limit)return!0;h.cursor++}return!1}function g(){var i,e;if(h.cursor>=o)if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,i=h.find_among_b(r,10)){switch(h.bra=h.cursor,h.limit_backward=e,i){case 1:if(!h.in_grouping_b(f,97,246))return;break;case 2:if(!(l<=h.cursor))return}h.slice_del()}else h.limit_backward=e}function j(){return h.find_among_b(i,7)}function q(){return h.eq_s_b(1,\"i\")&&h.in_grouping_b(e,97,246)}this.setCurrent=function(i){h.setCurrent(i)},this.getCurrent=function(){return h.getCurrent()},this.stem=function(){var i,e=h.cursor;return o=h.limit,l=o,p()||(o=h.cursor,p()||(l=h.cursor)),n=!1,h.limit_backward=e,h.cursor=h.limit,g(),h.cursor=h.limit,function(){var i,e,r;if(h.cursor>=o)if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,i=h.find_among_b(c,9))switch(h.bra=h.cursor,h.limit_backward=e,i){case 1:r=h.limit-h.cursor,h.eq_s_b(1,\"k\")||(h.cursor=h.limit-r,h.slice_del());break;case 2:h.slice_del(),h.ket=h.cursor,h.eq_s_b(3,\"kse\")&&(h.bra=h.cursor,h.slice_from(\"ksi\"));break;case 3:h.slice_del();break;case 4:h.find_among_b(s,6)&&h.slice_del();break;case 5:h.find_among_b(a,6)&&h.slice_del();break;case 6:h.find_among_b(u,2)&&h.slice_del()}else h.limit_backward=e}(),h.cursor=h.limit,function(){var i,e,r;if(h.cursor>=o)if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,i=h.find_among_b(m,30)){switch(h.bra=h.cursor,h.limit_backward=e,i){case 1:if(!h.eq_s_b(1,\"a\"))return;break;case 2:case 9:if(!h.eq_s_b(1,\"e\"))return;break;case 3:if(!h.eq_s_b(1,\"i\"))return;break;case 4:if(!h.eq_s_b(1,\"o\"))return;break;case 5:if(!h.eq_s_b(1,\"ä\"))return;break;case 6:if(!h.eq_s_b(1,\"ö\"))return;break;case 7:if(r=h.limit-h.cursor,!j()&&(h.cursor=h.limit-r,!h.eq_s_b(2,\"ie\"))){h.cursor=h.limit-r;break}if(h.cursor=h.limit-r,h.cursor<=h.limit_backward){h.cursor=h.limit-r;break}h.cursor--,h.bra=h.cursor;break;case 8:if(!h.in_grouping_b(d,97,246)||!h.out_grouping_b(d,97,246))return}h.slice_del(),n=!0}else h.limit_backward=e}(),h.cursor=h.limit,function(){var i,e,r;if(h.cursor>=l)if(e=h.limit_backward,h.limit_backward=l,h.ket=h.cursor,i=h.find_among_b(w,14)){if(h.bra=h.cursor,h.limit_backward=e,1==i){if(r=h.limit-h.cursor,h.eq_s_b(2,\"po\"))return;h.cursor=h.limit-r}h.slice_del()}else h.limit_backward=e}(),h.cursor=h.limit,h.cursor=(n?h.cursor>=o&&(i=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,h.find_among_b(_,2)?(h.bra=h.cursor,h.limit_backward=i,h.slice_del()):h.limit_backward=i):(h.cursor=h.limit,function(){var i,e,r,n,t,s;if(h.cursor>=o){if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,h.eq_s_b(1,\"t\")&&(h.bra=h.cursor,r=h.limit-h.cursor,h.in_grouping_b(d,97,246)&&(h.cursor=h.limit-r,h.slice_del(),h.limit_backward=e,n=h.limit-h.cursor,h.cursor>=l&&(h.cursor=l,t=h.limit_backward,h.limit_backward=h.cursor,h.cursor=h.limit-n,h.ket=h.cursor,i=h.find_among_b(k,2))))){if(h.bra=h.cursor,h.limit_backward=t,1==i){if(s=h.limit-h.cursor,h.eq_s_b(2,\"po\"))return;h.cursor=h.limit-s}return h.slice_del()}h.limit_backward=e}}()),h.limit),function(){var i,e,r,n;if(h.cursor>=o){for(i=h.limit_backward,h.limit_backward=o,e=h.limit-h.cursor,j()&&(h.cursor=h.limit-e,h.ket=h.cursor,h.cursor>h.limit_backward&&(h.cursor--,h.bra=h.cursor,h.slice_del())),h.cursor=h.limit-e,h.ket=h.cursor,h.in_grouping_b(b,97,228)&&(h.bra=h.cursor,h.out_grouping_b(d,97,246)&&h.slice_del()),h.cursor=h.limit-e,h.ket=h.cursor,h.eq_s_b(1,\"j\")&&(h.bra=h.cursor,r=h.limit-h.cursor,h.eq_s_b(1,\"o\")?h.slice_del():(h.cursor=h.limit-r,h.eq_s_b(1,\"u\")&&h.slice_del())),h.cursor=h.limit-e,h.ket=h.cursor,h.eq_s_b(1,\"o\")&&(h.bra=h.cursor,h.eq_s_b(1,\"j\")&&h.slice_del()),h.cursor=h.limit-e,h.limit_backward=i;;){if(n=h.limit-h.cursor,h.out_grouping_b(d,97,246)){h.cursor=h.limit-n;break}if(h.cursor=h.limit-n,h.cursor<=h.limit_backward)return;h.cursor--}h.ket=h.cursor,h.cursor>h.limit_backward&&(h.cursor--,h.bra=h.cursor,t=h.slice_to(),h.eq_v_b(t)&&h.slice_del())}}(),!0}},function(i){return\"function\"==typeof i.update?i.update(function(i){return e.setCurrent(i),e.stem(),e.getCurrent()}):(e.setCurrent(i),e.stem(),e.getCurrent())}),i.Pipeline.registerFunction(i.fi.stemmer,\"stemmer-fi\"),i.fi.stopWordFilter=i.generateStopWordFilter(\"ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli\".split(\" \")),i.Pipeline.registerFunction(i.fi.stopWordFilter,\"stopWordFilter-fi\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.fr.js",
    "content": "!function(e,r){\"function\"==typeof define&&define.amd?define(r):\"object\"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===e.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var r,y,s;e.fr=function(){this.pipeline.reset(),this.pipeline.add(e.fr.trimmer,e.fr.stopWordFilter,e.fr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.fr.stemmer))},e.fr.wordCharacters=\"A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤﬀ-ﬆＡ-Ｚａ-ｚ\",e.fr.trimmer=e.trimmerSupport.generateTrimmer(e.fr.wordCharacters),e.Pipeline.registerFunction(e.fr.trimmer,\"trimmer-fr\"),e.fr.stemmer=(r=e.stemmerSupport.Among,y=e.stemmerSupport.SnowballProgram,s=new function(){var s,i,t,n=[new r(\"col\",-1,-1),new r(\"par\",-1,-1),new r(\"tap\",-1,-1)],u=[new r(\"\",-1,4),new r(\"I\",0,1),new r(\"U\",0,2),new r(\"Y\",0,3)],o=[new r(\"iqU\",-1,3),new r(\"abl\",-1,3),new r(\"Ièr\",-1,4),new r(\"ièr\",-1,4),new r(\"eus\",-1,2),new r(\"iv\",-1,1)],c=[new r(\"ic\",-1,2),new r(\"abil\",-1,1),new r(\"iv\",-1,3)],a=[new r(\"iqUe\",-1,1),new r(\"atrice\",-1,2),new r(\"ance\",-1,1),new r(\"ence\",-1,5),new r(\"logie\",-1,3),new r(\"able\",-1,1),new r(\"isme\",-1,1),new r(\"euse\",-1,11),new r(\"iste\",-1,1),new r(\"ive\",-1,8),new r(\"if\",-1,8),new r(\"usion\",-1,4),new r(\"ation\",-1,2),new r(\"ution\",-1,4),new r(\"ateur\",-1,2),new r(\"iqUes\",-1,1),new r(\"atrices\",-1,2),new r(\"ances\",-1,1),new r(\"ences\",-1,5),new r(\"logies\",-1,3),new r(\"ables\",-1,1),new r(\"ismes\",-1,1),new r(\"euses\",-1,11),new r(\"istes\",-1,1),new r(\"ives\",-1,8),new r(\"ifs\",-1,8),new r(\"usions\",-1,4),new r(\"ations\",-1,2),new r(\"utions\",-1,4),new r(\"ateurs\",-1,2),new r(\"ments\",-1,15),new r(\"ements\",30,6),new r(\"issements\",31,12),new r(\"ités\",-1,7),new r(\"ment\",-1,15),new r(\"ement\",34,6),new r(\"issement\",35,12),new r(\"amment\",34,13),new r(\"emment\",34,14),new r(\"aux\",-1,10),new r(\"eaux\",39,9),new r(\"eux\",-1,1),new r(\"ité\",-1,7)],l=[new r(\"ira\",-1,1),new r(\"ie\",-1,1),new r(\"isse\",-1,1),new r(\"issante\",-1,1),new r(\"i\",-1,1),new r(\"irai\",4,1),new r(\"ir\",-1,1),new r(\"iras\",-1,1),new r(\"ies\",-1,1),new r(\"îmes\",-1,1),new r(\"isses\",-1,1),new r(\"issantes\",-1,1),new r(\"îtes\",-1,1),new r(\"is\",-1,1),new r(\"irais\",13,1),new r(\"issais\",13,1),new r(\"irions\",-1,1),new r(\"issions\",-1,1),new r(\"irons\",-1,1),new r(\"issons\",-1,1),new r(\"issants\",-1,1),new r(\"it\",-1,1),new r(\"irait\",21,1),new r(\"issait\",21,1),new r(\"issant\",-1,1),new r(\"iraIent\",-1,1),new r(\"issaIent\",-1,1),new r(\"irent\",-1,1),new r(\"issent\",-1,1),new r(\"iront\",-1,1),new r(\"ît\",-1,1),new r(\"iriez\",-1,1),new r(\"issiez\",-1,1),new r(\"irez\",-1,1),new r(\"issez\",-1,1)],w=[new r(\"a\",-1,3),new r(\"era\",0,2),new r(\"asse\",-1,3),new r(\"ante\",-1,3),new r(\"ée\",-1,2),new r(\"ai\",-1,3),new r(\"erai\",5,2),new r(\"er\",-1,2),new r(\"as\",-1,3),new r(\"eras\",8,2),new r(\"âmes\",-1,3),new r(\"asses\",-1,3),new r(\"antes\",-1,3),new r(\"âtes\",-1,3),new r(\"ées\",-1,2),new r(\"ais\",-1,3),new r(\"erais\",15,2),new r(\"ions\",-1,1),new r(\"erions\",17,2),new r(\"assions\",17,3),new r(\"erons\",-1,2),new r(\"ants\",-1,3),new r(\"és\",-1,2),new r(\"ait\",-1,3),new r(\"erait\",23,2),new r(\"ant\",-1,3),new r(\"aIent\",-1,3),new r(\"eraIent\",26,2),new r(\"èrent\",-1,2),new r(\"assent\",-1,3),new r(\"eront\",-1,2),new r(\"ât\",-1,3),new r(\"ez\",-1,2),new r(\"iez\",32,2),new r(\"eriez\",33,2),new r(\"assiez\",33,3),new r(\"erez\",32,2),new r(\"é\",-1,2)],f=[new r(\"e\",-1,3),new r(\"Ière\",0,2),new r(\"ière\",0,2),new r(\"ion\",-1,1),new r(\"Ier\",-1,2),new r(\"ier\",-1,2),new r(\"ë\",-1,4)],m=[new r(\"ell\",-1,-1),new r(\"eill\",-1,-1),new r(\"enn\",-1,-1),new r(\"onn\",-1,-1),new r(\"ett\",-1,-1)],_=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5],b=[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128],d=new y;function k(e,r,s){return!(!d.eq_s(1,e)||(d.ket=d.cursor,!d.in_grouping(_,97,251)))&&(d.slice_from(r),d.cursor=s,!0)}function p(e,r,s){return!!d.eq_s(1,e)&&(d.ket=d.cursor,d.slice_from(r),d.cursor=s,!0)}function g(){for(;!d.in_grouping(_,97,251);){if(d.cursor>=d.limit)return!0;d.cursor++}for(;!d.out_grouping(_,97,251);){if(d.cursor>=d.limit)return!0;d.cursor++}return!1}function q(){return t<=d.cursor}function v(){return i<=d.cursor}function h(){return s<=d.cursor}function z(){if(!function(){var e,r;if(d.ket=d.cursor,e=d.find_among_b(a,43)){switch(d.bra=d.cursor,e){case 1:if(!h())return!1;d.slice_del();break;case 2:if(!h())return!1;d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,\"ic\")&&(d.bra=d.cursor,h()?d.slice_del():d.slice_from(\"iqU\"));break;case 3:if(!h())return!1;d.slice_from(\"log\");break;case 4:if(!h())return!1;d.slice_from(\"u\");break;case 5:if(!h())return!1;d.slice_from(\"ent\");break;case 6:if(!q())return!1;if(d.slice_del(),d.ket=d.cursor,e=d.find_among_b(o,6))switch(d.bra=d.cursor,e){case 1:h()&&(d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,\"at\")&&(d.bra=d.cursor,h()&&d.slice_del()));break;case 2:h()?d.slice_del():v()&&d.slice_from(\"eux\");break;case 3:h()&&d.slice_del();break;case 4:q()&&d.slice_from(\"i\")}break;case 7:if(!h())return!1;if(d.slice_del(),d.ket=d.cursor,e=d.find_among_b(c,3))switch(d.bra=d.cursor,e){case 1:h()?d.slice_del():d.slice_from(\"abl\");break;case 2:h()?d.slice_del():d.slice_from(\"iqU\");break;case 3:h()&&d.slice_del()}break;case 8:if(!h())return!1;if(d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,\"at\")&&(d.bra=d.cursor,h()&&(d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,\"ic\")))){d.bra=d.cursor,h()?d.slice_del():d.slice_from(\"iqU\");break}break;case 9:d.slice_from(\"eau\");break;case 10:if(!v())return!1;d.slice_from(\"al\");break;case 11:if(h())d.slice_del();else{if(!v())return!1;d.slice_from(\"eux\")}break;case 12:if(!v()||!d.out_grouping_b(_,97,251))return!1;d.slice_del();break;case 13:return q()&&d.slice_from(\"ant\"),!1;case 14:return q()&&d.slice_from(\"ent\"),!1;case 15:return r=d.limit-d.cursor,d.in_grouping_b(_,97,251)&&q()&&(d.cursor=d.limit-r,d.slice_del()),!1}return!0}return!1}()&&(d.cursor=d.limit,!function(){var e,r;if(d.cursor<t)return!1;if(r=d.limit_backward,d.limit_backward=t,d.ket=d.cursor,!(e=d.find_among_b(l,35)))return d.limit_backward=r,!1;if(d.bra=d.cursor,1==e){if(!d.out_grouping_b(_,97,251))return d.limit_backward=r,!1;d.slice_del()}return d.limit_backward=r,!0}()&&(d.cursor=d.limit,!function(){var e,r,s;if(d.cursor<t)return!1;if(r=d.limit_backward,d.limit_backward=t,d.ket=d.cursor,!(e=d.find_among_b(w,38)))return d.limit_backward=r,!1;switch(d.bra=d.cursor,e){case 1:if(!h())return d.limit_backward=r,!1;d.slice_del();break;case 2:d.slice_del();break;case 3:d.slice_del(),s=d.limit-d.cursor,d.ket=d.cursor,d.eq_s_b(1,\"e\")?(d.bra=d.cursor,d.slice_del()):d.cursor=d.limit-s}return d.limit_backward=r,!0}())))return d.cursor=d.limit,void function(){var e,r,s,i,n=d.limit-d.cursor;if(d.ket=d.cursor,d.eq_s_b(1,\"s\")?(d.bra=d.cursor,r=d.limit-d.cursor,d.out_grouping_b(b,97,232)?(d.cursor=d.limit-r,d.slice_del()):d.cursor=d.limit-n):d.cursor=d.limit-n,d.cursor>=t){if(s=d.limit_backward,d.limit_backward=t,d.ket=d.cursor,e=d.find_among_b(f,7))switch(d.bra=d.cursor,e){case 1:if(h()){if(i=d.limit-d.cursor,!d.eq_s_b(1,\"s\")&&(d.cursor=d.limit-i,!d.eq_s_b(1,\"t\")))break;d.slice_del()}break;case 2:d.slice_from(\"i\");break;case 3:d.slice_del();break;case 4:d.eq_s_b(2,\"gu\")&&d.slice_del()}d.limit_backward=s}}();d.cursor=d.limit,d.ket=d.cursor,d.eq_s_b(1,\"Y\")?(d.bra=d.cursor,d.slice_from(\"i\")):(d.cursor=d.limit,d.eq_s_b(1,\"ç\")&&(d.bra=d.cursor,d.slice_from(\"c\")))}this.setCurrent=function(e){d.setCurrent(e)},this.getCurrent=function(){return d.getCurrent()},this.stem=function(){var e,r=d.cursor;return function(){for(var e,r;;){if(e=d.cursor,d.in_grouping(_,97,251)){if(d.bra=d.cursor,r=d.cursor,k(\"u\",\"U\",e))continue;if(d.cursor=r,k(\"i\",\"I\",e))continue;if(d.cursor=r,p(\"y\",\"Y\",e))continue}if(d.cursor=e,!k(\"y\",\"Y\",d.bra=e)){if(d.cursor=e,d.eq_s(1,\"q\")&&(d.bra=d.cursor,p(\"u\",\"U\",e)))continue;if((d.cursor=e)>=d.limit)return;d.cursor++}}}(),d.cursor=r,function(){var e=d.cursor;if(t=d.limit,s=i=t,d.in_grouping(_,97,251)&&d.in_grouping(_,97,251)&&d.cursor<d.limit)d.cursor++;else if(d.cursor=e,!d.find_among(n,3)){d.cursor=e;do{if(d.cursor>=d.limit){d.cursor=t;break}d.cursor++}while(!d.in_grouping(_,97,251))}t=d.cursor,d.cursor=e,g()||(i=d.cursor,g()||(s=d.cursor))}(),d.limit_backward=r,d.cursor=d.limit,z(),d.cursor=d.limit,e=d.limit-d.cursor,d.find_among_b(m,5)&&(d.cursor=d.limit-e,d.ket=d.cursor,d.cursor>d.limit_backward&&(d.cursor--,d.bra=d.cursor,d.slice_del())),d.cursor=d.limit,function(){for(var e,r=1;d.out_grouping_b(_,97,251);)r--;if(r<=0){if(d.ket=d.cursor,e=d.limit-d.cursor,!d.eq_s_b(1,\"é\")&&(d.cursor=d.limit-e,!d.eq_s_b(1,\"è\")))return;d.bra=d.cursor,d.slice_from(\"e\")}}(),d.cursor=d.limit_backward,function(){for(var e,r;r=d.cursor,d.bra=r,e=d.find_among(u,4);)switch(d.ket=d.cursor,e){case 1:d.slice_from(\"i\");break;case 2:d.slice_from(\"u\");break;case 3:d.slice_from(\"y\");break;case 4:if(d.cursor>=d.limit)return;d.cursor++}}(),!0}},function(e){return\"function\"==typeof e.update?e.update(function(e){return s.setCurrent(e),s.stem(),s.getCurrent()}):(s.setCurrent(e),s.stem(),s.getCurrent())}),e.Pipeline.registerFunction(e.fr.stemmer,\"stemmer-fr\"),e.fr.stopWordFilter=e.generateStopWordFilter(\"ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes\".split(\" \")),e.Pipeline.registerFunction(e.fr.stopWordFilter,\"stopWordFilter-fr\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.hu.js",
    "content": "!function(e,n){\"function\"==typeof define&&define.amd?define(n):\"object\"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===e.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var p,_,n;e.hu=function(){this.pipeline.reset(),this.pipeline.add(e.hu.trimmer,e.hu.stopWordFilter,e.hu.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hu.stemmer))},e.hu.wordCharacters=\"A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤﬀ-ﬆＡ-Ｚａ-ｚ\",e.hu.trimmer=e.trimmerSupport.generateTrimmer(e.hu.wordCharacters),e.Pipeline.registerFunction(e.hu.trimmer,\"trimmer-hu\"),e.hu.stemmer=(p=e.stemmerSupport.Among,_=e.stemmerSupport.SnowballProgram,n=new function(){var r,i=[new p(\"cs\",-1,-1),new p(\"dzs\",-1,-1),new p(\"gy\",-1,-1),new p(\"ly\",-1,-1),new p(\"ny\",-1,-1),new p(\"sz\",-1,-1),new p(\"ty\",-1,-1),new p(\"zs\",-1,-1)],n=[new p(\"á\",-1,1),new p(\"é\",-1,2)],a=[new p(\"bb\",-1,-1),new p(\"cc\",-1,-1),new p(\"dd\",-1,-1),new p(\"ff\",-1,-1),new p(\"gg\",-1,-1),new p(\"jj\",-1,-1),new p(\"kk\",-1,-1),new p(\"ll\",-1,-1),new p(\"mm\",-1,-1),new p(\"nn\",-1,-1),new p(\"pp\",-1,-1),new p(\"rr\",-1,-1),new p(\"ccs\",-1,-1),new p(\"ss\",-1,-1),new p(\"zzs\",-1,-1),new p(\"tt\",-1,-1),new p(\"vv\",-1,-1),new p(\"ggy\",-1,-1),new p(\"lly\",-1,-1),new p(\"nny\",-1,-1),new p(\"tty\",-1,-1),new p(\"ssz\",-1,-1),new p(\"zz\",-1,-1)],t=[new p(\"al\",-1,1),new p(\"el\",-1,2)],e=[new p(\"ba\",-1,-1),new p(\"ra\",-1,-1),new p(\"be\",-1,-1),new p(\"re\",-1,-1),new p(\"ig\",-1,-1),new p(\"nak\",-1,-1),new p(\"nek\",-1,-1),new p(\"val\",-1,-1),new p(\"vel\",-1,-1),new p(\"ul\",-1,-1),new p(\"nál\",-1,-1),new p(\"nél\",-1,-1),new p(\"ból\",-1,-1),new p(\"ról\",-1,-1),new p(\"tól\",-1,-1),new p(\"bõl\",-1,-1),new p(\"rõl\",-1,-1),new p(\"tõl\",-1,-1),new p(\"ül\",-1,-1),new p(\"n\",-1,-1),new p(\"an\",19,-1),new p(\"ban\",20,-1),new p(\"en\",19,-1),new p(\"ben\",22,-1),new p(\"képpen\",22,-1),new p(\"on\",19,-1),new p(\"ön\",19,-1),new p(\"képp\",-1,-1),new p(\"kor\",-1,-1),new p(\"t\",-1,-1),new p(\"at\",29,-1),new p(\"et\",29,-1),new p(\"ként\",29,-1),new p(\"anként\",32,-1),new p(\"enként\",32,-1),new p(\"onként\",32,-1),new p(\"ot\",29,-1),new p(\"ért\",29,-1),new p(\"öt\",29,-1),new p(\"hez\",-1,-1),new p(\"hoz\",-1,-1),new p(\"höz\",-1,-1),new p(\"vá\",-1,-1),new p(\"vé\",-1,-1)],s=[new p(\"án\",-1,2),new p(\"én\",-1,1),new p(\"ánként\",-1,3)],c=[new p(\"stul\",-1,2),new p(\"astul\",0,1),new p(\"ástul\",0,3),new p(\"stül\",-1,2),new p(\"estül\",3,1),new p(\"éstül\",3,4)],w=[new p(\"á\",-1,1),new p(\"é\",-1,2)],o=[new p(\"k\",-1,7),new p(\"ak\",0,4),new p(\"ek\",0,6),new p(\"ok\",0,5),new p(\"ák\",0,1),new p(\"ék\",0,2),new p(\"ök\",0,3)],l=[new p(\"éi\",-1,7),new p(\"áéi\",0,6),new p(\"ééi\",0,5),new p(\"é\",-1,9),new p(\"ké\",3,4),new p(\"aké\",4,1),new p(\"eké\",4,1),new p(\"oké\",4,1),new p(\"áké\",4,3),new p(\"éké\",4,2),new p(\"öké\",4,1),new p(\"éé\",3,8)],u=[new p(\"a\",-1,18),new p(\"ja\",0,17),new p(\"d\",-1,16),new p(\"ad\",2,13),new p(\"ed\",2,13),new p(\"od\",2,13),new p(\"ád\",2,14),new p(\"éd\",2,15),new p(\"öd\",2,13),new p(\"e\",-1,18),new p(\"je\",9,17),new p(\"nk\",-1,4),new p(\"unk\",11,1),new p(\"ánk\",11,2),new p(\"énk\",11,3),new p(\"ünk\",11,1),new p(\"uk\",-1,8),new p(\"juk\",16,7),new p(\"ájuk\",17,5),new p(\"ük\",-1,8),new p(\"jük\",19,7),new p(\"éjük\",20,6),new p(\"m\",-1,12),new p(\"am\",22,9),new p(\"em\",22,9),new p(\"om\",22,9),new p(\"ám\",22,10),new p(\"ém\",22,11),new p(\"o\",-1,18),new p(\"á\",-1,19),new p(\"é\",-1,20)],m=[new p(\"id\",-1,10),new p(\"aid\",0,9),new p(\"jaid\",1,6),new p(\"eid\",0,9),new p(\"jeid\",3,6),new p(\"áid\",0,7),new p(\"éid\",0,8),new p(\"i\",-1,15),new p(\"ai\",7,14),new p(\"jai\",8,11),new p(\"ei\",7,14),new p(\"jei\",10,11),new p(\"ái\",7,12),new p(\"éi\",7,13),new p(\"itek\",-1,24),new p(\"eitek\",14,21),new p(\"jeitek\",15,20),new p(\"éitek\",14,23),new p(\"ik\",-1,29),new p(\"aik\",18,26),new p(\"jaik\",19,25),new p(\"eik\",18,26),new p(\"jeik\",21,25),new p(\"áik\",18,27),new p(\"éik\",18,28),new p(\"ink\",-1,20),new p(\"aink\",25,17),new p(\"jaink\",26,16),new p(\"eink\",25,17),new p(\"jeink\",28,16),new p(\"áink\",25,18),new p(\"éink\",25,19),new p(\"aitok\",-1,21),new p(\"jaitok\",32,20),new p(\"áitok\",-1,22),new p(\"im\",-1,5),new p(\"aim\",35,4),new p(\"jaim\",36,1),new p(\"eim\",35,4),new p(\"jeim\",38,1),new p(\"áim\",35,2),new p(\"éim\",35,3)],k=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14],f=new _;function b(){return r<=f.cursor}function d(){var e=f.limit-f.cursor;return!!f.find_among_b(a,23)&&(f.cursor=f.limit-e,!0)}function g(){if(f.cursor>f.limit_backward){f.cursor--,f.ket=f.cursor;var e=f.cursor-1;f.limit_backward<=e&&e<=f.limit&&(f.cursor=e,f.bra=e,f.slice_del())}}function h(){f.ket=f.cursor,f.find_among_b(e,44)&&(f.bra=f.cursor,b()&&(f.slice_del(),function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(n,2))&&(f.bra=f.cursor,b()))switch(e){case 1:f.slice_from(\"a\");break;case 2:f.slice_from(\"e\")}}()))}this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var e=f.cursor;return function(){var e,n=f.cursor;if(r=f.limit,f.in_grouping(k,97,252))for(;;){if(e=f.cursor,f.out_grouping(k,97,252))return f.cursor=e,f.find_among(i,8)||(f.cursor=e)<f.limit&&f.cursor++,r=f.cursor;if((f.cursor=e)>=f.limit)return r=e;f.cursor++}if(f.cursor=n,f.out_grouping(k,97,252)){for(;!f.in_grouping(k,97,252);){if(f.cursor>=f.limit)return;f.cursor++}r=f.cursor}}(),f.limit_backward=e,f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(t,2))&&(f.bra=f.cursor,b())){if((1==e||2==e)&&!d())return;f.slice_del(),g()}}(),f.cursor=f.limit,h(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(s,3))&&(f.bra=f.cursor,b()))switch(e){case 1:f.slice_from(\"e\");break;case 2:case 3:f.slice_from(\"a\")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(c,6))&&(f.bra=f.cursor,b()))switch(e){case 1:case 2:f.slice_del();break;case 3:f.slice_from(\"a\");break;case 4:f.slice_from(\"e\")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(w,2))&&(f.bra=f.cursor,b())){if((1==e||2==e)&&!d())return;f.slice_del(),g()}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(l,12))&&(f.bra=f.cursor,b()))switch(e){case 1:case 4:case 7:case 9:f.slice_del();break;case 2:case 5:case 8:f.slice_from(\"e\");break;case 3:case 6:f.slice_from(\"a\")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(u,31))&&(f.bra=f.cursor,b()))switch(e){case 1:case 4:case 7:case 8:case 9:case 12:case 13:case 16:case 17:case 18:f.slice_del();break;case 2:case 5:case 10:case 14:case 19:f.slice_from(\"a\");break;case 3:case 6:case 11:case 15:case 20:f.slice_from(\"e\")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(m,42))&&(f.bra=f.cursor,b()))switch(e){case 1:case 4:case 5:case 6:case 9:case 10:case 11:case 14:case 15:case 16:case 17:case 20:case 21:case 24:case 25:case 26:case 29:f.slice_del();break;case 2:case 7:case 12:case 18:case 22:case 27:f.slice_from(\"a\");break;case 3:case 8:case 13:case 19:case 23:case 28:f.slice_from(\"e\")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(o,7))&&(f.bra=f.cursor,b()))switch(e){case 1:f.slice_from(\"a\");break;case 2:f.slice_from(\"e\");break;case 3:case 4:case 5:case 6:case 7:f.slice_del()}}(),!0}},function(e){return\"function\"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}),e.Pipeline.registerFunction(e.hu.stemmer,\"stemmer-hu\"),e.hu.stopWordFilter=e.generateStopWordFilter(\"a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra\".split(\" \")),e.Pipeline.registerFunction(e.hu.stopWordFilter,\"stopWordFilter-hu\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.it.js",
    "content": "!function(e,r){\"function\"==typeof define&&define.amd?define(r):\"object\"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===e.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var z,P,r;e.it=function(){this.pipeline.reset(),this.pipeline.add(e.it.trimmer,e.it.stopWordFilter,e.it.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.it.stemmer))},e.it.wordCharacters=\"A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤﬀ-ﬆＡ-Ｚａ-ｚ\",e.it.trimmer=e.trimmerSupport.generateTrimmer(e.it.wordCharacters),e.Pipeline.registerFunction(e.it.trimmer,\"trimmer-it\"),e.it.stemmer=(z=e.stemmerSupport.Among,P=e.stemmerSupport.SnowballProgram,r=new function(){var o,t,s,a=[new z(\"\",-1,7),new z(\"qu\",0,6),new z(\"á\",0,1),new z(\"é\",0,2),new z(\"í\",0,3),new z(\"ó\",0,4),new z(\"ú\",0,5)],u=[new z(\"\",-1,3),new z(\"I\",0,1),new z(\"U\",0,2)],c=[new z(\"la\",-1,-1),new z(\"cela\",0,-1),new z(\"gliela\",0,-1),new z(\"mela\",0,-1),new z(\"tela\",0,-1),new z(\"vela\",0,-1),new z(\"le\",-1,-1),new z(\"cele\",6,-1),new z(\"gliele\",6,-1),new z(\"mele\",6,-1),new z(\"tele\",6,-1),new z(\"vele\",6,-1),new z(\"ne\",-1,-1),new z(\"cene\",12,-1),new z(\"gliene\",12,-1),new z(\"mene\",12,-1),new z(\"sene\",12,-1),new z(\"tene\",12,-1),new z(\"vene\",12,-1),new z(\"ci\",-1,-1),new z(\"li\",-1,-1),new z(\"celi\",20,-1),new z(\"glieli\",20,-1),new z(\"meli\",20,-1),new z(\"teli\",20,-1),new z(\"veli\",20,-1),new z(\"gli\",20,-1),new z(\"mi\",-1,-1),new z(\"si\",-1,-1),new z(\"ti\",-1,-1),new z(\"vi\",-1,-1),new z(\"lo\",-1,-1),new z(\"celo\",31,-1),new z(\"glielo\",31,-1),new z(\"melo\",31,-1),new z(\"telo\",31,-1),new z(\"velo\",31,-1)],w=[new z(\"ando\",-1,1),new z(\"endo\",-1,1),new z(\"ar\",-1,2),new z(\"er\",-1,2),new z(\"ir\",-1,2)],r=[new z(\"ic\",-1,-1),new z(\"abil\",-1,-1),new z(\"os\",-1,-1),new z(\"iv\",-1,1)],n=[new z(\"ic\",-1,1),new z(\"abil\",-1,1),new z(\"iv\",-1,1)],i=[new z(\"ica\",-1,1),new z(\"logia\",-1,3),new z(\"osa\",-1,1),new z(\"ista\",-1,1),new z(\"iva\",-1,9),new z(\"anza\",-1,1),new z(\"enza\",-1,5),new z(\"ice\",-1,1),new z(\"atrice\",7,1),new z(\"iche\",-1,1),new z(\"logie\",-1,3),new z(\"abile\",-1,1),new z(\"ibile\",-1,1),new z(\"usione\",-1,4),new z(\"azione\",-1,2),new z(\"uzione\",-1,4),new z(\"atore\",-1,2),new z(\"ose\",-1,1),new z(\"ante\",-1,1),new z(\"mente\",-1,1),new z(\"amente\",19,7),new z(\"iste\",-1,1),new z(\"ive\",-1,9),new z(\"anze\",-1,1),new z(\"enze\",-1,5),new z(\"ici\",-1,1),new z(\"atrici\",25,1),new z(\"ichi\",-1,1),new z(\"abili\",-1,1),new z(\"ibili\",-1,1),new z(\"ismi\",-1,1),new z(\"usioni\",-1,4),new z(\"azioni\",-1,2),new z(\"uzioni\",-1,4),new z(\"atori\",-1,2),new z(\"osi\",-1,1),new z(\"anti\",-1,1),new z(\"amenti\",-1,6),new z(\"imenti\",-1,6),new z(\"isti\",-1,1),new z(\"ivi\",-1,9),new z(\"ico\",-1,1),new z(\"ismo\",-1,1),new z(\"oso\",-1,1),new z(\"amento\",-1,6),new z(\"imento\",-1,6),new z(\"ivo\",-1,9),new z(\"ità\",-1,8),new z(\"istà\",-1,1),new z(\"istè\",-1,1),new z(\"istì\",-1,1)],l=[new z(\"isca\",-1,1),new z(\"enda\",-1,1),new z(\"ata\",-1,1),new z(\"ita\",-1,1),new z(\"uta\",-1,1),new z(\"ava\",-1,1),new z(\"eva\",-1,1),new z(\"iva\",-1,1),new z(\"erebbe\",-1,1),new z(\"irebbe\",-1,1),new z(\"isce\",-1,1),new z(\"ende\",-1,1),new z(\"are\",-1,1),new z(\"ere\",-1,1),new z(\"ire\",-1,1),new z(\"asse\",-1,1),new z(\"ate\",-1,1),new z(\"avate\",16,1),new z(\"evate\",16,1),new z(\"ivate\",16,1),new z(\"ete\",-1,1),new z(\"erete\",20,1),new z(\"irete\",20,1),new z(\"ite\",-1,1),new z(\"ereste\",-1,1),new z(\"ireste\",-1,1),new z(\"ute\",-1,1),new z(\"erai\",-1,1),new z(\"irai\",-1,1),new z(\"isci\",-1,1),new z(\"endi\",-1,1),new z(\"erei\",-1,1),new z(\"irei\",-1,1),new z(\"assi\",-1,1),new z(\"ati\",-1,1),new z(\"iti\",-1,1),new z(\"eresti\",-1,1),new z(\"iresti\",-1,1),new z(\"uti\",-1,1),new z(\"avi\",-1,1),new z(\"evi\",-1,1),new z(\"ivi\",-1,1),new z(\"isco\",-1,1),new z(\"ando\",-1,1),new z(\"endo\",-1,1),new z(\"Yamo\",-1,1),new z(\"iamo\",-1,1),new z(\"avamo\",-1,1),new z(\"evamo\",-1,1),new z(\"ivamo\",-1,1),new z(\"eremo\",-1,1),new z(\"iremo\",-1,1),new z(\"assimo\",-1,1),new z(\"ammo\",-1,1),new z(\"emmo\",-1,1),new z(\"eremmo\",54,1),new z(\"iremmo\",54,1),new z(\"immo\",-1,1),new z(\"ano\",-1,1),new z(\"iscano\",58,1),new z(\"avano\",58,1),new z(\"evano\",58,1),new z(\"ivano\",58,1),new z(\"eranno\",-1,1),new z(\"iranno\",-1,1),new z(\"ono\",-1,1),new z(\"iscono\",65,1),new z(\"arono\",65,1),new z(\"erono\",65,1),new z(\"irono\",65,1),new z(\"erebbero\",-1,1),new z(\"irebbero\",-1,1),new z(\"assero\",-1,1),new z(\"essero\",-1,1),new z(\"issero\",-1,1),new z(\"ato\",-1,1),new z(\"ito\",-1,1),new z(\"uto\",-1,1),new z(\"avo\",-1,1),new z(\"evo\",-1,1),new z(\"ivo\",-1,1),new z(\"ar\",-1,1),new z(\"ir\",-1,1),new z(\"erà\",-1,1),new z(\"irà\",-1,1),new z(\"erò\",-1,1),new z(\"irò\",-1,1)],m=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2,1],f=[17,65,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2],v=[17],b=new P;function d(e,r,n){return!(!b.eq_s(1,e)||(b.ket=b.cursor,!b.in_grouping(m,97,249)))&&(b.slice_from(r),b.cursor=n,!0)}function _(e){if(b.cursor=e,!b.in_grouping(m,97,249))return!1;for(;!b.out_grouping(m,97,249);){if(b.cursor>=b.limit)return!1;b.cursor++}return!0}function g(){var e,r=b.cursor;if(!function(){if(b.in_grouping(m,97,249)){var e=b.cursor;if(b.out_grouping(m,97,249)){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return _(e);b.cursor++}return!0}return _(e)}return!1}()){if(b.cursor=r,!b.out_grouping(m,97,249))return;if(e=b.cursor,b.out_grouping(m,97,249)){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return b.cursor=e,void(b.in_grouping(m,97,249)&&b.cursor<b.limit&&b.cursor++);b.cursor++}return void(s=b.cursor)}if(b.cursor=e,!b.in_grouping(m,97,249)||b.cursor>=b.limit)return;b.cursor++}s=b.cursor}function p(){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return!1;b.cursor++}for(;!b.out_grouping(m,97,249);){if(b.cursor>=b.limit)return!1;b.cursor++}return!0}function k(){return s<=b.cursor}function h(){return o<=b.cursor}function q(){var e;if(b.ket=b.cursor,!(e=b.find_among_b(i,51)))return!1;switch(b.bra=b.cursor,e){case 1:if(!h())return!1;b.slice_del();break;case 2:if(!h())return!1;b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,\"ic\")&&(b.bra=b.cursor,h()&&b.slice_del());break;case 3:if(!h())return!1;b.slice_from(\"log\");break;case 4:if(!h())return!1;b.slice_from(\"u\");break;case 5:if(!h())return!1;b.slice_from(\"ente\");break;case 6:if(!k())return!1;b.slice_del();break;case 7:if(!(t<=b.cursor))return!1;b.slice_del(),b.ket=b.cursor,(e=b.find_among_b(r,4))&&(b.bra=b.cursor,h()&&(b.slice_del(),1==e&&(b.ket=b.cursor,b.eq_s_b(2,\"at\")&&(b.bra=b.cursor,h()&&b.slice_del()))));break;case 8:if(!h())return!1;b.slice_del(),b.ket=b.cursor,(e=b.find_among_b(n,3))&&(b.bra=b.cursor,1==e&&h()&&b.slice_del());break;case 9:if(!h())return!1;b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,\"at\")&&(b.bra=b.cursor,h()&&(b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,\"ic\")&&(b.bra=b.cursor,h()&&b.slice_del())))}return!0}function C(){var e;e=b.limit-b.cursor,b.ket=b.cursor,b.in_grouping_b(f,97,242)&&(b.bra=b.cursor,k()&&(b.slice_del(),b.ket=b.cursor,b.eq_s_b(1,\"i\")&&(b.bra=b.cursor,k())))?b.slice_del():b.cursor=b.limit-e,b.ket=b.cursor,b.eq_s_b(1,\"h\")&&(b.bra=b.cursor,b.in_grouping_b(v,99,103)&&k()&&b.slice_del())}this.setCurrent=function(e){b.setCurrent(e)},this.getCurrent=function(){return b.getCurrent()},this.stem=function(){var e,r,n,i=b.cursor;return function(){for(var e,r,n,i,o=b.cursor;;){if(b.bra=b.cursor,e=b.find_among(a,7))switch(b.ket=b.cursor,e){case 1:b.slice_from(\"à\");continue;case 2:b.slice_from(\"è\");continue;case 3:b.slice_from(\"ì\");continue;case 4:b.slice_from(\"ò\");continue;case 5:b.slice_from(\"ù\");continue;case 6:b.slice_from(\"qU\");continue;case 7:if(b.cursor>=b.limit)break;b.cursor++;continue}break}for(b.cursor=o;;)for(r=b.cursor;;){if(n=b.cursor,b.in_grouping(m,97,249)){if(b.bra=b.cursor,i=b.cursor,d(\"u\",\"U\",n))break;if(b.cursor=i,d(\"i\",\"I\",n))break}if(b.cursor=n,b.cursor>=b.limit)return b.cursor=r;b.cursor++}}(),b.cursor=i,e=b.cursor,s=b.limit,o=t=s,g(),b.cursor=e,p()&&(t=b.cursor,p()&&(o=b.cursor)),b.limit_backward=i,b.cursor=b.limit,function(){var e;if(b.ket=b.cursor,b.find_among_b(c,37)&&(b.bra=b.cursor,(e=b.find_among_b(w,5))&&k()))switch(e){case 1:b.slice_del();break;case 2:b.slice_from(\"e\")}}(),b.cursor=b.limit,q()||(b.cursor=b.limit,b.cursor>=s&&(n=b.limit_backward,b.limit_backward=s,b.ket=b.cursor,(r=b.find_among_b(l,87))&&(b.bra=b.cursor,1==r&&b.slice_del()),b.limit_backward=n)),b.cursor=b.limit,C(),b.cursor=b.limit_backward,function(){for(var e;b.bra=b.cursor,e=b.find_among(u,3);)switch(b.ket=b.cursor,e){case 1:b.slice_from(\"i\");break;case 2:b.slice_from(\"u\");break;case 3:if(b.cursor>=b.limit)return;b.cursor++}}(),!0}},function(e){return\"function\"==typeof e.update?e.update(function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}):(r.setCurrent(e),r.stem(),r.getCurrent())}),e.Pipeline.registerFunction(e.it.stemmer,\"stemmer-it\"),e.it.stopWordFilter=e.generateStopWordFilter(\"a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è\".split(\" \")),e.Pipeline.registerFunction(e.it.stopWordFilter,\"stopWordFilter-it\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.jp.js",
    "content": "!function(e,r){\"function\"==typeof define&&define.amd?define(r):\"object\"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(n){if(void 0===n)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===n.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var i=\"2\"==n.version[0];n.jp=function(){this.pipeline.reset(),this.pipeline.add(n.jp.stopWordFilter,n.jp.stemmer),i?this.tokenizer=n.jp.tokenizer:(n.tokenizer&&(n.tokenizer=n.jp.tokenizer),this.tokenizerFn&&(this.tokenizerFn=n.jp.tokenizer))};var o=new n.TinySegmenter;n.jp.tokenizer=function(e){if(!arguments.length||null==e||null==e)return[];if(Array.isArray(e))return e.map(function(e){return i?new n.Token(e.toLowerCase()):e.toLowerCase()});for(var r=e.toString().toLowerCase().replace(/^\\s+/,\"\"),t=r.length-1;0<=t;t--)if(/\\S/.test(r.charAt(t))){r=r.substring(0,t+1);break}return o.segment(r).filter(function(e){return!!e}).map(function(e){return i?new n.Token(e):e})},n.jp.stemmer=function(e){return e},n.Pipeline.registerFunction(n.jp.stemmer,\"stemmer-jp\"),n.jp.wordCharacters=\"一二三四五六七八九十百千万億兆一-龠々〆ヵヶぁ-んァ-ヴーｱ-ﾝﾞa-zA-Zａ-ｚＡ-Ｚ0-9０-９\",n.jp.stopWordFilter=function(e){if(-1===n.jp.stopWordFilter.stopWords.indexOf(i?e.toString():e))return e},n.jp.stopWordFilter=n.generateStopWordFilter(\"これ それ あれ この その あの ここ そこ あそこ こちら どこ だれ なに なん 何 私 貴方 貴方方 我々 私達 あの人 あのかた 彼女 彼 です あります おります います は が の に を で え から まで より も どの と し それで しかし\".split(\" \")),n.Pipeline.registerFunction(n.jp.stopWordFilter,\"stopWordFilter-jp\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.multi.js",
    "content": "!function(e,i){\"function\"==typeof define&&define.amd?define(i):\"object\"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(o){o.multiLanguage=function(){for(var e=Array.prototype.slice.call(arguments),i=e.join(\"-\"),t=\"\",r=[],n=[],s=0;s<e.length;++s)\"en\"==e[s]?(t+=\"\\\\w\",r.unshift(o.stopWordFilter),r.push(o.stemmer),n.push(o.stemmer)):(t+=o[e[s]].wordCharacters,r.unshift(o[e[s]].stopWordFilter),r.push(o[e[s]].stemmer),n.push(o[e[s]].stemmer));var p=o.trimmerSupport.generateTrimmer(t);return o.Pipeline.registerFunction(p,\"lunr-multi-trimmer-\"+i),r.unshift(p),function(){this.pipeline.reset(),this.pipeline.add.apply(this.pipeline,r),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add.apply(this.searchPipeline,n))}}}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.no.js",
    "content": "!function(e,r){\"function\"==typeof define&&define.amd?define(r):\"object\"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===e.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var r,n,i;e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters=\"A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤﬀ-ﬆＡ-Ｚａ-ｚ\",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,\"trimmer-no\"),e.no.stemmer=(r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){var o,s,a=[new r(\"a\",-1,1),new r(\"e\",-1,1),new r(\"ede\",1,1),new r(\"ande\",1,1),new r(\"ende\",1,1),new r(\"ane\",1,1),new r(\"ene\",1,1),new r(\"hetene\",6,1),new r(\"erte\",1,3),new r(\"en\",-1,1),new r(\"heten\",9,1),new r(\"ar\",-1,1),new r(\"er\",-1,1),new r(\"heter\",12,1),new r(\"s\",-1,2),new r(\"as\",14,1),new r(\"es\",14,1),new r(\"edes\",16,1),new r(\"endes\",16,1),new r(\"enes\",16,1),new r(\"hetenes\",19,1),new r(\"ens\",14,1),new r(\"hetens\",21,1),new r(\"ers\",14,1),new r(\"ets\",14,1),new r(\"et\",-1,1),new r(\"het\",25,1),new r(\"ert\",-1,3),new r(\"ast\",-1,1)],m=[new r(\"dt\",-1,-1),new r(\"vt\",-1,-1)],l=[new r(\"leg\",-1,1),new r(\"eleg\",0,1),new r(\"ig\",-1,1),new r(\"eig\",2,1),new r(\"lig\",2,1),new r(\"elig\",4,1),new r(\"els\",-1,1),new r(\"lov\",-1,1),new r(\"elov\",7,1),new r(\"slov\",7,1),new r(\"hetslov\",9,1)],u=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],d=[119,125,149,1],c=new n;this.setCurrent=function(e){c.setCurrent(e)},this.getCurrent=function(){return c.getCurrent()},this.stem=function(){var e,r,n,i,t=c.cursor;return function(){var e,r=c.cursor+3;if(s=c.limit,0<=r||r<=c.limit){for(o=r;;){if(e=c.cursor,c.in_grouping(u,97,248)){c.cursor=e;break}if(e>=c.limit)return;c.cursor=e+1}for(;!c.out_grouping(u,97,248);){if(c.cursor>=c.limit)return;c.cursor++}(s=c.cursor)<o&&(s=o)}}(),c.limit_backward=t,c.cursor=c.limit,function(){var e,r,n;if(c.cursor>=s&&(r=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,e=c.find_among_b(a,29),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del();break;case 2:n=c.limit-c.cursor,c.in_grouping_b(d,98,122)?c.slice_del():(c.cursor=c.limit-n,c.eq_s_b(1,\"k\")&&c.out_grouping_b(u,97,248)&&c.slice_del());break;case 3:c.slice_from(\"er\")}}(),c.cursor=c.limit,r=c.limit-c.cursor,c.cursor>=s&&(e=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,c.find_among_b(m,2)?(c.bra=c.cursor,c.limit_backward=e,c.cursor=c.limit-r,c.cursor>c.limit_backward&&(c.cursor--,c.bra=c.cursor,c.slice_del())):c.limit_backward=e),c.cursor=c.limit,c.cursor>=s&&(i=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,(n=c.find_among_b(l,11))?(c.bra=c.cursor,c.limit_backward=i,1==n&&c.slice_del()):c.limit_backward=i),!0}},function(e){return\"function\"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.no.stemmer,\"stemmer-no\"),e.no.stopWordFilter=e.generateStopWordFilter(\"alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å\".split(\" \")),e.Pipeline.registerFunction(e.no.stopWordFilter,\"stopWordFilter-no\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.pt.js",
    "content": "!function(e,r){\"function\"==typeof define&&define.amd?define(r):\"object\"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===e.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var j,C,r;e.pt=function(){this.pipeline.reset(),this.pipeline.add(e.pt.trimmer,e.pt.stopWordFilter,e.pt.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.pt.stemmer))},e.pt.wordCharacters=\"A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤﬀ-ﬆＡ-Ｚａ-ｚ\",e.pt.trimmer=e.trimmerSupport.generateTrimmer(e.pt.wordCharacters),e.Pipeline.registerFunction(e.pt.trimmer,\"trimmer-pt\"),e.pt.stemmer=(j=e.stemmerSupport.Among,C=e.stemmerSupport.SnowballProgram,r=new function(){var s,n,i,o=[new j(\"\",-1,3),new j(\"ã\",0,1),new j(\"õ\",0,2)],a=[new j(\"\",-1,3),new j(\"a~\",0,1),new j(\"o~\",0,2)],r=[new j(\"ic\",-1,-1),new j(\"ad\",-1,-1),new j(\"os\",-1,-1),new j(\"iv\",-1,1)],t=[new j(\"ante\",-1,1),new j(\"avel\",-1,1),new j(\"ível\",-1,1)],u=[new j(\"ic\",-1,1),new j(\"abil\",-1,1),new j(\"iv\",-1,1)],w=[new j(\"ica\",-1,1),new j(\"ância\",-1,1),new j(\"ência\",-1,4),new j(\"ira\",-1,9),new j(\"adora\",-1,1),new j(\"osa\",-1,1),new j(\"ista\",-1,1),new j(\"iva\",-1,8),new j(\"eza\",-1,1),new j(\"logía\",-1,2),new j(\"idade\",-1,7),new j(\"ante\",-1,1),new j(\"mente\",-1,6),new j(\"amente\",12,5),new j(\"ável\",-1,1),new j(\"ível\",-1,1),new j(\"ución\",-1,3),new j(\"ico\",-1,1),new j(\"ismo\",-1,1),new j(\"oso\",-1,1),new j(\"amento\",-1,1),new j(\"imento\",-1,1),new j(\"ivo\",-1,8),new j(\"aça~o\",-1,1),new j(\"ador\",-1,1),new j(\"icas\",-1,1),new j(\"ências\",-1,4),new j(\"iras\",-1,9),new j(\"adoras\",-1,1),new j(\"osas\",-1,1),new j(\"istas\",-1,1),new j(\"ivas\",-1,8),new j(\"ezas\",-1,1),new j(\"logías\",-1,2),new j(\"idades\",-1,7),new j(\"uciones\",-1,3),new j(\"adores\",-1,1),new j(\"antes\",-1,1),new j(\"aço~es\",-1,1),new j(\"icos\",-1,1),new j(\"ismos\",-1,1),new j(\"osos\",-1,1),new j(\"amentos\",-1,1),new j(\"imentos\",-1,1),new j(\"ivos\",-1,8)],m=[new j(\"ada\",-1,1),new j(\"ida\",-1,1),new j(\"ia\",-1,1),new j(\"aria\",2,1),new j(\"eria\",2,1),new j(\"iria\",2,1),new j(\"ara\",-1,1),new j(\"era\",-1,1),new j(\"ira\",-1,1),new j(\"ava\",-1,1),new j(\"asse\",-1,1),new j(\"esse\",-1,1),new j(\"isse\",-1,1),new j(\"aste\",-1,1),new j(\"este\",-1,1),new j(\"iste\",-1,1),new j(\"ei\",-1,1),new j(\"arei\",16,1),new j(\"erei\",16,1),new j(\"irei\",16,1),new j(\"am\",-1,1),new j(\"iam\",20,1),new j(\"ariam\",21,1),new j(\"eriam\",21,1),new j(\"iriam\",21,1),new j(\"aram\",20,1),new j(\"eram\",20,1),new j(\"iram\",20,1),new j(\"avam\",20,1),new j(\"em\",-1,1),new j(\"arem\",29,1),new j(\"erem\",29,1),new j(\"irem\",29,1),new j(\"assem\",29,1),new j(\"essem\",29,1),new j(\"issem\",29,1),new j(\"ado\",-1,1),new j(\"ido\",-1,1),new j(\"ando\",-1,1),new j(\"endo\",-1,1),new j(\"indo\",-1,1),new j(\"ara~o\",-1,1),new j(\"era~o\",-1,1),new j(\"ira~o\",-1,1),new j(\"ar\",-1,1),new j(\"er\",-1,1),new j(\"ir\",-1,1),new j(\"as\",-1,1),new j(\"adas\",47,1),new j(\"idas\",47,1),new j(\"ias\",47,1),new j(\"arias\",50,1),new j(\"erias\",50,1),new j(\"irias\",50,1),new j(\"aras\",47,1),new j(\"eras\",47,1),new j(\"iras\",47,1),new j(\"avas\",47,1),new j(\"es\",-1,1),new j(\"ardes\",58,1),new j(\"erdes\",58,1),new j(\"irdes\",58,1),new j(\"ares\",58,1),new j(\"eres\",58,1),new j(\"ires\",58,1),new j(\"asses\",58,1),new j(\"esses\",58,1),new j(\"isses\",58,1),new j(\"astes\",58,1),new j(\"estes\",58,1),new j(\"istes\",58,1),new j(\"is\",-1,1),new j(\"ais\",71,1),new j(\"eis\",71,1),new j(\"areis\",73,1),new j(\"ereis\",73,1),new j(\"ireis\",73,1),new j(\"áreis\",73,1),new j(\"éreis\",73,1),new j(\"íreis\",73,1),new j(\"ásseis\",73,1),new j(\"ésseis\",73,1),new j(\"ísseis\",73,1),new j(\"áveis\",73,1),new j(\"íeis\",73,1),new j(\"aríeis\",84,1),new j(\"eríeis\",84,1),new j(\"iríeis\",84,1),new j(\"ados\",-1,1),new j(\"idos\",-1,1),new j(\"amos\",-1,1),new j(\"áramos\",90,1),new j(\"éramos\",90,1),new j(\"íramos\",90,1),new j(\"ávamos\",90,1),new j(\"íamos\",90,1),new j(\"aríamos\",95,1),new j(\"eríamos\",95,1),new j(\"iríamos\",95,1),new j(\"emos\",-1,1),new j(\"aremos\",99,1),new j(\"eremos\",99,1),new j(\"iremos\",99,1),new j(\"ássemos\",99,1),new j(\"êssemos\",99,1),new j(\"íssemos\",99,1),new j(\"imos\",-1,1),new j(\"armos\",-1,1),new j(\"ermos\",-1,1),new j(\"irmos\",-1,1),new j(\"ámos\",-1,1),new j(\"arás\",-1,1),new j(\"erás\",-1,1),new j(\"irás\",-1,1),new j(\"eu\",-1,1),new j(\"iu\",-1,1),new j(\"ou\",-1,1),new j(\"ará\",-1,1),new j(\"erá\",-1,1),new j(\"irá\",-1,1)],c=[new j(\"a\",-1,1),new j(\"i\",-1,1),new j(\"o\",-1,1),new j(\"os\",-1,1),new j(\"á\",-1,1),new j(\"í\",-1,1),new j(\"ó\",-1,1)],l=[new j(\"e\",-1,1),new j(\"ç\",-1,2),new j(\"é\",-1,1),new j(\"ê\",-1,1)],f=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],d=new C;function v(){if(d.out_grouping(f,97,250)){for(;!d.in_grouping(f,97,250);){if(d.cursor>=d.limit)return!0;d.cursor++}return!1}return!0}function p(){var e,r,s=d.cursor;if(d.in_grouping(f,97,250))if(e=d.cursor,v()){if(d.cursor=e,function(){if(d.in_grouping(f,97,250))for(;!d.out_grouping(f,97,250);){if(d.cursor>=d.limit)return!1;d.cursor++}return i=d.cursor,!0}())return}else i=d.cursor;if(d.cursor=s,d.out_grouping(f,97,250)){if(r=d.cursor,v()){if(d.cursor=r,!d.in_grouping(f,97,250)||d.cursor>=d.limit)return;d.cursor++}i=d.cursor}}function _(){for(;!d.in_grouping(f,97,250);){if(d.cursor>=d.limit)return!1;d.cursor++}for(;!d.out_grouping(f,97,250);){if(d.cursor>=d.limit)return!1;d.cursor++}return!0}function h(){return i<=d.cursor}function b(){return s<=d.cursor}function g(){var e;if(d.ket=d.cursor,!(e=d.find_among_b(w,45)))return!1;switch(d.bra=d.cursor,e){case 1:if(!b())return!1;d.slice_del();break;case 2:if(!b())return!1;d.slice_from(\"log\");break;case 3:if(!b())return!1;d.slice_from(\"u\");break;case 4:if(!b())return!1;d.slice_from(\"ente\");break;case 5:if(!(n<=d.cursor))return!1;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(r,4))&&(d.bra=d.cursor,b()&&(d.slice_del(),1==e&&(d.ket=d.cursor,d.eq_s_b(2,\"at\")&&(d.bra=d.cursor,b()&&d.slice_del()))));break;case 6:if(!b())return!1;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(t,3))&&(d.bra=d.cursor,1==e&&b()&&d.slice_del());break;case 7:if(!b())return!1;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(u,3))&&(d.bra=d.cursor,1==e&&b()&&d.slice_del());break;case 8:if(!b())return!1;d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,\"at\")&&(d.bra=d.cursor,b()&&d.slice_del());break;case 9:if(!h()||!d.eq_s_b(1,\"e\"))return!1;d.slice_from(\"ir\")}return!0}function k(e,r){if(d.eq_s_b(1,e)){d.bra=d.cursor;var s=d.limit-d.cursor;if(d.eq_s_b(1,r))return d.cursor=d.limit-s,h()&&d.slice_del(),!1}return!0}function q(){if(!g()&&(d.cursor=d.limit,!function(){var e,r;if(d.cursor>=i){if(r=d.limit_backward,d.limit_backward=i,d.ket=d.cursor,e=d.find_among_b(m,120))return d.bra=d.cursor,1==e&&d.slice_del(),d.limit_backward=r,!0;d.limit_backward=r}return!1}()))return d.cursor=d.limit,d.ket=d.cursor,void((e=d.find_among_b(c,7))&&(d.bra=d.cursor,1==e&&h()&&d.slice_del()));var e;d.cursor=d.limit,d.ket=d.cursor,d.eq_s_b(1,\"i\")&&(d.bra=d.cursor,d.eq_s_b(1,\"c\")&&(d.cursor=d.limit,h()&&d.slice_del()))}this.setCurrent=function(e){d.setCurrent(e)},this.getCurrent=function(){return d.getCurrent()},this.stem=function(){var e,r=d.cursor;return function(){for(var e;;){if(d.bra=d.cursor,e=d.find_among(o,3))switch(d.ket=d.cursor,e){case 1:d.slice_from(\"a~\");continue;case 2:d.slice_from(\"o~\");continue;case 3:if(d.cursor>=d.limit)break;d.cursor++;continue}break}}(),d.cursor=r,e=d.cursor,i=d.limit,s=n=i,p(),d.cursor=e,_()&&(n=d.cursor,_()&&(s=d.cursor)),d.limit_backward=r,d.cursor=d.limit,q(),d.cursor=d.limit,function(){var e;if(d.ket=d.cursor,e=d.find_among_b(l,4))switch(d.bra=d.cursor,e){case 1:h()&&(d.slice_del(),d.ket=d.cursor,d.limit,d.cursor,k(\"u\",\"g\")&&k(\"i\",\"c\"));break;case 2:d.slice_from(\"c\")}}(),d.cursor=d.limit_backward,function(){for(var e;;){if(d.bra=d.cursor,e=d.find_among(a,3))switch(d.ket=d.cursor,e){case 1:d.slice_from(\"ã\");continue;case 2:d.slice_from(\"õ\");continue;case 3:if(d.cursor>=d.limit)break;d.cursor++;continue}break}}(),!0}},function(e){return\"function\"==typeof e.update?e.update(function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}):(r.setCurrent(e),r.stem(),r.getCurrent())}),e.Pipeline.registerFunction(e.pt.stemmer,\"stemmer-pt\"),e.pt.stopWordFilter=e.generateStopWordFilter(\"a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos\".split(\" \")),e.Pipeline.registerFunction(e.pt.stopWordFilter,\"stopWordFilter-pt\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.ro.js",
    "content": "!function(e,i){\"function\"==typeof define&&define.amd?define(i):\"object\"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===e.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var h,z,i;e.ro=function(){this.pipeline.reset(),this.pipeline.add(e.ro.trimmer,e.ro.stopWordFilter,e.ro.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ro.stemmer))},e.ro.wordCharacters=\"A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤﬀ-ﬆＡ-Ｚａ-ｚ\",e.ro.trimmer=e.trimmerSupport.generateTrimmer(e.ro.wordCharacters),e.Pipeline.registerFunction(e.ro.trimmer,\"trimmer-ro\"),e.ro.stemmer=(h=e.stemmerSupport.Among,z=e.stemmerSupport.SnowballProgram,i=new function(){var r,n,t,a,o=[new h(\"\",-1,3),new h(\"I\",0,1),new h(\"U\",0,2)],s=[new h(\"ea\",-1,3),new h(\"aţia\",-1,7),new h(\"aua\",-1,2),new h(\"iua\",-1,4),new h(\"aţie\",-1,7),new h(\"ele\",-1,3),new h(\"ile\",-1,5),new h(\"iile\",6,4),new h(\"iei\",-1,4),new h(\"atei\",-1,6),new h(\"ii\",-1,4),new h(\"ului\",-1,1),new h(\"ul\",-1,1),new h(\"elor\",-1,3),new h(\"ilor\",-1,4),new h(\"iilor\",14,4)],c=[new h(\"icala\",-1,4),new h(\"iciva\",-1,4),new h(\"ativa\",-1,5),new h(\"itiva\",-1,6),new h(\"icale\",-1,4),new h(\"aţiune\",-1,5),new h(\"iţiune\",-1,6),new h(\"atoare\",-1,5),new h(\"itoare\",-1,6),new h(\"ătoare\",-1,5),new h(\"icitate\",-1,4),new h(\"abilitate\",-1,1),new h(\"ibilitate\",-1,2),new h(\"ivitate\",-1,3),new h(\"icive\",-1,4),new h(\"ative\",-1,5),new h(\"itive\",-1,6),new h(\"icali\",-1,4),new h(\"atori\",-1,5),new h(\"icatori\",18,4),new h(\"itori\",-1,6),new h(\"ători\",-1,5),new h(\"icitati\",-1,4),new h(\"abilitati\",-1,1),new h(\"ivitati\",-1,3),new h(\"icivi\",-1,4),new h(\"ativi\",-1,5),new h(\"itivi\",-1,6),new h(\"icităi\",-1,4),new h(\"abilităi\",-1,1),new h(\"ivităi\",-1,3),new h(\"icităţi\",-1,4),new h(\"abilităţi\",-1,1),new h(\"ivităţi\",-1,3),new h(\"ical\",-1,4),new h(\"ator\",-1,5),new h(\"icator\",35,4),new h(\"itor\",-1,6),new h(\"ător\",-1,5),new h(\"iciv\",-1,4),new h(\"ativ\",-1,5),new h(\"itiv\",-1,6),new h(\"icală\",-1,4),new h(\"icivă\",-1,4),new h(\"ativă\",-1,5),new h(\"itivă\",-1,6)],u=[new h(\"ica\",-1,1),new h(\"abila\",-1,1),new h(\"ibila\",-1,1),new h(\"oasa\",-1,1),new h(\"ata\",-1,1),new h(\"ita\",-1,1),new h(\"anta\",-1,1),new h(\"ista\",-1,3),new h(\"uta\",-1,1),new h(\"iva\",-1,1),new h(\"ic\",-1,1),new h(\"ice\",-1,1),new h(\"abile\",-1,1),new h(\"ibile\",-1,1),new h(\"isme\",-1,3),new h(\"iune\",-1,2),new h(\"oase\",-1,1),new h(\"ate\",-1,1),new h(\"itate\",17,1),new h(\"ite\",-1,1),new h(\"ante\",-1,1),new h(\"iste\",-1,3),new h(\"ute\",-1,1),new h(\"ive\",-1,1),new h(\"ici\",-1,1),new h(\"abili\",-1,1),new h(\"ibili\",-1,1),new h(\"iuni\",-1,2),new h(\"atori\",-1,1),new h(\"osi\",-1,1),new h(\"ati\",-1,1),new h(\"itati\",30,1),new h(\"iti\",-1,1),new h(\"anti\",-1,1),new h(\"isti\",-1,3),new h(\"uti\",-1,1),new h(\"işti\",-1,3),new h(\"ivi\",-1,1),new h(\"ităi\",-1,1),new h(\"oşi\",-1,1),new h(\"ităţi\",-1,1),new h(\"abil\",-1,1),new h(\"ibil\",-1,1),new h(\"ism\",-1,3),new h(\"ator\",-1,1),new h(\"os\",-1,1),new h(\"at\",-1,1),new h(\"it\",-1,1),new h(\"ant\",-1,1),new h(\"ist\",-1,3),new h(\"ut\",-1,1),new h(\"iv\",-1,1),new h(\"ică\",-1,1),new h(\"abilă\",-1,1),new h(\"ibilă\",-1,1),new h(\"oasă\",-1,1),new h(\"ată\",-1,1),new h(\"ită\",-1,1),new h(\"antă\",-1,1),new h(\"istă\",-1,3),new h(\"ută\",-1,1),new h(\"ivă\",-1,1)],w=[new h(\"ea\",-1,1),new h(\"ia\",-1,1),new h(\"esc\",-1,1),new h(\"ăsc\",-1,1),new h(\"ind\",-1,1),new h(\"ând\",-1,1),new h(\"are\",-1,1),new h(\"ere\",-1,1),new h(\"ire\",-1,1),new h(\"âre\",-1,1),new h(\"se\",-1,2),new h(\"ase\",10,1),new h(\"sese\",10,2),new h(\"ise\",10,1),new h(\"use\",10,1),new h(\"âse\",10,1),new h(\"eşte\",-1,1),new h(\"ăşte\",-1,1),new h(\"eze\",-1,1),new h(\"ai\",-1,1),new h(\"eai\",19,1),new h(\"iai\",19,1),new h(\"sei\",-1,2),new h(\"eşti\",-1,1),new h(\"ăşti\",-1,1),new h(\"ui\",-1,1),new h(\"ezi\",-1,1),new h(\"âi\",-1,1),new h(\"aşi\",-1,1),new h(\"seşi\",-1,2),new h(\"aseşi\",29,1),new h(\"seseşi\",29,2),new h(\"iseşi\",29,1),new h(\"useşi\",29,1),new h(\"âseşi\",29,1),new h(\"işi\",-1,1),new h(\"uşi\",-1,1),new h(\"âşi\",-1,1),new h(\"aţi\",-1,2),new h(\"eaţi\",38,1),new h(\"iaţi\",38,1),new h(\"eţi\",-1,2),new h(\"iţi\",-1,2),new h(\"âţi\",-1,2),new h(\"arăţi\",-1,1),new h(\"serăţi\",-1,2),new h(\"aserăţi\",45,1),new h(\"seserăţi\",45,2),new h(\"iserăţi\",45,1),new h(\"userăţi\",45,1),new h(\"âserăţi\",45,1),new h(\"irăţi\",-1,1),new h(\"urăţi\",-1,1),new h(\"ârăţi\",-1,1),new h(\"am\",-1,1),new h(\"eam\",54,1),new h(\"iam\",54,1),new h(\"em\",-1,2),new h(\"asem\",57,1),new h(\"sesem\",57,2),new h(\"isem\",57,1),new h(\"usem\",57,1),new h(\"âsem\",57,1),new h(\"im\",-1,2),new h(\"âm\",-1,2),new h(\"ăm\",-1,2),new h(\"arăm\",65,1),new h(\"serăm\",65,2),new h(\"aserăm\",67,1),new h(\"seserăm\",67,2),new h(\"iserăm\",67,1),new h(\"userăm\",67,1),new h(\"âserăm\",67,1),new h(\"irăm\",65,1),new h(\"urăm\",65,1),new h(\"ârăm\",65,1),new h(\"au\",-1,1),new h(\"eau\",76,1),new h(\"iau\",76,1),new h(\"indu\",-1,1),new h(\"ându\",-1,1),new h(\"ez\",-1,1),new h(\"ească\",-1,1),new h(\"ară\",-1,1),new h(\"seră\",-1,2),new h(\"aseră\",84,1),new h(\"seseră\",84,2),new h(\"iseră\",84,1),new h(\"useră\",84,1),new h(\"âseră\",84,1),new h(\"iră\",-1,1),new h(\"ură\",-1,1),new h(\"âră\",-1,1),new h(\"ează\",-1,1)],i=[new h(\"a\",-1,1),new h(\"e\",-1,1),new h(\"ie\",1,1),new h(\"i\",-1,1),new h(\"ă\",-1,1)],m=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,32,0,0,4],l=new z;function f(e,i){l.eq_s(1,e)&&(l.ket=l.cursor,l.in_grouping(m,97,259)&&l.slice_from(i))}function p(){if(l.out_grouping(m,97,259)){for(;!l.in_grouping(m,97,259);){if(l.cursor>=l.limit)return!0;l.cursor++}return!1}return!0}function d(){var e,i,r=l.cursor;if(l.in_grouping(m,97,259)){if(e=l.cursor,!p())return void(a=l.cursor);if(l.cursor=e,!function(){if(l.in_grouping(m,97,259))for(;!l.out_grouping(m,97,259);){if(l.cursor>=l.limit)return!0;l.cursor++}return!1}())return void(a=l.cursor)}l.cursor=r,l.out_grouping(m,97,259)&&(i=l.cursor,p()&&(l.cursor=i,l.in_grouping(m,97,259)&&l.cursor<l.limit&&l.cursor++),a=l.cursor)}function b(){for(;!l.in_grouping(m,97,259);){if(l.cursor>=l.limit)return!1;l.cursor++}for(;!l.out_grouping(m,97,259);){if(l.cursor>=l.limit)return!1;l.cursor++}return!0}function v(){return t<=l.cursor}function _(){var e,i=l.limit-l.cursor;if(l.ket=l.cursor,(e=l.find_among_b(c,46))&&(l.bra=l.cursor,v())){switch(e){case 1:l.slice_from(\"abil\");break;case 2:l.slice_from(\"ibil\");break;case 3:l.slice_from(\"iv\");break;case 4:l.slice_from(\"ic\");break;case 5:l.slice_from(\"at\");break;case 6:l.slice_from(\"it\")}return r=!0,l.cursor=l.limit-i,!0}return!1}function g(){var e,i;for(r=!1;;)if(i=l.limit-l.cursor,!_()){l.cursor=l.limit-i;break}if(l.ket=l.cursor,(e=l.find_among_b(u,62))&&(l.bra=l.cursor,n<=l.cursor)){switch(e){case 1:l.slice_del();break;case 2:l.eq_s_b(1,\"ţ\")&&(l.bra=l.cursor,l.slice_from(\"t\"));break;case 3:l.slice_from(\"ist\")}r=!0}}function k(){var e;l.ket=l.cursor,(e=l.find_among_b(i,5))&&(l.bra=l.cursor,a<=l.cursor&&1==e&&l.slice_del())}this.setCurrent=function(e){l.setCurrent(e)},this.getCurrent=function(){return l.getCurrent()},this.stem=function(){var e,i=l.cursor;return function(){for(var e,i;e=l.cursor,l.in_grouping(m,97,259)&&(i=l.cursor,l.bra=i,f(\"u\",\"U\"),l.cursor=i,f(\"i\",\"I\")),l.cursor=e,!(l.cursor>=l.limit);)l.cursor++}(),l.cursor=i,e=l.cursor,a=l.limit,n=t=a,d(),l.cursor=e,b()&&(t=l.cursor,b()&&(n=l.cursor)),l.limit_backward=i,l.cursor=l.limit,function(){var e,i;if(l.ket=l.cursor,(e=l.find_among_b(s,16))&&(l.bra=l.cursor,v()))switch(e){case 1:l.slice_del();break;case 2:l.slice_from(\"a\");break;case 3:l.slice_from(\"e\");break;case 4:l.slice_from(\"i\");break;case 5:i=l.limit-l.cursor,l.eq_s_b(2,\"ab\")||(l.cursor=l.limit-i,l.slice_from(\"i\"));break;case 6:l.slice_from(\"at\");break;case 7:l.slice_from(\"aţi\")}}(),l.cursor=l.limit,g(),l.cursor=l.limit,r||(l.cursor=l.limit,function(){var e,i,r;if(l.cursor>=a){if(i=l.limit_backward,l.limit_backward=a,l.ket=l.cursor,e=l.find_among_b(w,94))switch(l.bra=l.cursor,e){case 1:if(r=l.limit-l.cursor,!l.out_grouping_b(m,97,259)&&(l.cursor=l.limit-r,!l.eq_s_b(1,\"u\")))break;case 2:l.slice_del()}l.limit_backward=i}}(),l.cursor=l.limit),k(),l.cursor=l.limit_backward,function(){for(var e;;){if(l.bra=l.cursor,e=l.find_among(o,3))switch(l.ket=l.cursor,e){case 1:l.slice_from(\"i\");continue;case 2:l.slice_from(\"u\");continue;case 3:if(l.cursor>=l.limit)break;l.cursor++;continue}break}}(),!0}},function(e){return\"function\"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.ro.stemmer,\"stemmer-ro\"),e.ro.stopWordFilter=e.generateStopWordFilter(\"acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în  înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie\".split(\" \")),e.Pipeline.registerFunction(e.ro.stopWordFilter,\"stopWordFilter-ro\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.ru.js",
    "content": "!function(e,n){\"function\"==typeof define&&define.amd?define(n):\"object\"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===e.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var h,g,n;e.ru=function(){this.pipeline.reset(),this.pipeline.add(e.ru.trimmer,e.ru.stopWordFilter,e.ru.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ru.stemmer))},e.ru.wordCharacters=\"Ѐ-҄҇-ԯᴫᵸⷠ-ⷿꙀ-ꚟ︮︯\",e.ru.trimmer=e.trimmerSupport.generateTrimmer(e.ru.wordCharacters),e.Pipeline.registerFunction(e.ru.trimmer,\"trimmer-ru\"),e.ru.stemmer=(h=e.stemmerSupport.Among,g=e.stemmerSupport.SnowballProgram,n=new function(){var n,e,r=[new h(\"в\",-1,1),new h(\"ив\",0,2),new h(\"ыв\",0,2),new h(\"вши\",-1,1),new h(\"ивши\",3,2),new h(\"ывши\",3,2),new h(\"вшись\",-1,1),new h(\"ившись\",6,2),new h(\"ывшись\",6,2)],t=[new h(\"ее\",-1,1),new h(\"ие\",-1,1),new h(\"ое\",-1,1),new h(\"ые\",-1,1),new h(\"ими\",-1,1),new h(\"ыми\",-1,1),new h(\"ей\",-1,1),new h(\"ий\",-1,1),new h(\"ой\",-1,1),new h(\"ый\",-1,1),new h(\"ем\",-1,1),new h(\"им\",-1,1),new h(\"ом\",-1,1),new h(\"ым\",-1,1),new h(\"его\",-1,1),new h(\"ого\",-1,1),new h(\"ему\",-1,1),new h(\"ому\",-1,1),new h(\"их\",-1,1),new h(\"ых\",-1,1),new h(\"ею\",-1,1),new h(\"ою\",-1,1),new h(\"ую\",-1,1),new h(\"юю\",-1,1),new h(\"ая\",-1,1),new h(\"яя\",-1,1)],w=[new h(\"ем\",-1,1),new h(\"нн\",-1,1),new h(\"вш\",-1,1),new h(\"ивш\",2,2),new h(\"ывш\",2,2),new h(\"щ\",-1,1),new h(\"ющ\",5,1),new h(\"ующ\",6,2)],i=[new h(\"сь\",-1,1),new h(\"ся\",-1,1)],u=[new h(\"ла\",-1,1),new h(\"ила\",0,2),new h(\"ыла\",0,2),new h(\"на\",-1,1),new h(\"ена\",3,2),new h(\"ете\",-1,1),new h(\"ите\",-1,2),new h(\"йте\",-1,1),new h(\"ейте\",7,2),new h(\"уйте\",7,2),new h(\"ли\",-1,1),new h(\"или\",10,2),new h(\"ыли\",10,2),new h(\"й\",-1,1),new h(\"ей\",13,2),new h(\"уй\",13,2),new h(\"л\",-1,1),new h(\"ил\",16,2),new h(\"ыл\",16,2),new h(\"ем\",-1,1),new h(\"им\",-1,2),new h(\"ым\",-1,2),new h(\"н\",-1,1),new h(\"ен\",22,2),new h(\"ло\",-1,1),new h(\"ило\",24,2),new h(\"ыло\",24,2),new h(\"но\",-1,1),new h(\"ено\",27,2),new h(\"нно\",27,1),new h(\"ет\",-1,1),new h(\"ует\",30,2),new h(\"ит\",-1,2),new h(\"ыт\",-1,2),new h(\"ют\",-1,1),new h(\"уют\",34,2),new h(\"ят\",-1,2),new h(\"ны\",-1,1),new h(\"ены\",37,2),new h(\"ть\",-1,1),new h(\"ить\",39,2),new h(\"ыть\",39,2),new h(\"ешь\",-1,1),new h(\"ишь\",-1,2),new h(\"ю\",-1,2),new h(\"ую\",44,2)],s=[new h(\"а\",-1,1),new h(\"ев\",-1,1),new h(\"ов\",-1,1),new h(\"е\",-1,1),new h(\"ие\",3,1),new h(\"ье\",3,1),new h(\"и\",-1,1),new h(\"еи\",6,1),new h(\"ии\",6,1),new h(\"ами\",6,1),new h(\"ями\",6,1),new h(\"иями\",10,1),new h(\"й\",-1,1),new h(\"ей\",12,1),new h(\"ией\",13,1),new h(\"ий\",12,1),new h(\"ой\",12,1),new h(\"ам\",-1,1),new h(\"ем\",-1,1),new h(\"ием\",18,1),new h(\"ом\",-1,1),new h(\"ям\",-1,1),new h(\"иям\",21,1),new h(\"о\",-1,1),new h(\"у\",-1,1),new h(\"ах\",-1,1),new h(\"ях\",-1,1),new h(\"иях\",26,1),new h(\"ы\",-1,1),new h(\"ь\",-1,1),new h(\"ю\",-1,1),new h(\"ию\",30,1),new h(\"ью\",30,1),new h(\"я\",-1,1),new h(\"ия\",33,1),new h(\"ья\",33,1)],o=[new h(\"ост\",-1,1),new h(\"ость\",-1,1)],c=[new h(\"ейше\",-1,1),new h(\"н\",-1,2),new h(\"ейш\",-1,1),new h(\"ь\",-1,3)],m=[33,65,8,232],l=new g;function f(){for(;!l.in_grouping(m,1072,1103);){if(l.cursor>=l.limit)return!1;l.cursor++}return!0}function a(){for(;!l.out_grouping(m,1072,1103);){if(l.cursor>=l.limit)return!1;l.cursor++}return!0}function p(e,n){var r,t;if(l.ket=l.cursor,r=l.find_among_b(e,n)){switch(l.bra=l.cursor,r){case 1:if(t=l.limit-l.cursor,!l.eq_s_b(1,\"а\")&&(l.cursor=l.limit-t,!l.eq_s_b(1,\"я\")))return!1;case 2:l.slice_del()}return!0}return!1}function d(e,n){var r;return l.ket=l.cursor,!!(r=l.find_among_b(e,n))&&(l.bra=l.cursor,1==r&&l.slice_del(),!0)}function _(){return!!d(t,26)&&(p(w,8),!0)}function b(){var e;l.ket=l.cursor,(e=l.find_among_b(o,2))&&(l.bra=l.cursor,n<=l.cursor&&1==e&&l.slice_del())}this.setCurrent=function(e){l.setCurrent(e)},this.getCurrent=function(){return l.getCurrent()},this.stem=function(){return e=l.limit,n=e,f()&&(e=l.cursor,a()&&f()&&a()&&(n=l.cursor)),l.cursor=l.limit,!(l.cursor<e)&&(l.limit_backward=e,p(r,9)||(l.cursor=l.limit,d(i,2)||(l.cursor=l.limit),_()||(l.cursor=l.limit,p(u,46)||(l.cursor=l.limit,d(s,36)))),l.cursor=l.limit,l.ket=l.cursor,l.eq_s_b(1,\"и\")?(l.bra=l.cursor,l.slice_del()):l.cursor=l.limit,b(),l.cursor=l.limit,function(){var e;if(l.ket=l.cursor,e=l.find_among_b(c,4))switch(l.bra=l.cursor,e){case 1:if(l.slice_del(),l.ket=l.cursor,!l.eq_s_b(1,\"н\"))break;l.bra=l.cursor;case 2:if(!l.eq_s_b(1,\"н\"))break;case 3:l.slice_del()}}(),!0)}},function(e){return\"function\"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}),e.Pipeline.registerFunction(e.ru.stemmer,\"stemmer-ru\"),e.ru.stopWordFilter=e.generateStopWordFilter(\"алло без близко более больше будем будет будете будешь будто буду будут будь бы бывает бывь был была были было быть в важная важное важные важный вам вами вас ваш ваша ваше ваши вверх вдали вдруг ведь везде весь вниз внизу во вокруг вон восемнадцатый восемнадцать восемь восьмой вот впрочем времени время все всегда всего всем всеми всему всех всею всю всюду вся всё второй вы г где говорил говорит год года году да давно даже далеко дальше даром два двадцатый двадцать две двенадцатый двенадцать двух девятнадцатый девятнадцать девятый девять действительно дел день десятый десять для до довольно долго должно другая другие других друго другое другой е его ее ей ему если есть еще ещё ею её ж же жизнь за занят занята занято заняты затем зато зачем здесь значит и из или им именно иметь ими имя иногда их к каждая каждое каждые каждый кажется как какая какой кем когда кого ком кому конечно которая которого которой которые который которых кроме кругом кто куда лет ли лишь лучше люди м мало между меля менее меньше меня миллионов мимо мира мне много многочисленная многочисленное многочисленные многочисленный мной мною мог могут мож может можно можхо мои мой мор мочь моя моё мы на наверху над надо назад наиболее наконец нам нами нас начала наш наша наше наши не него недавно недалеко нее ней нельзя нем немного нему непрерывно нередко несколько нет нею неё ни нибудь ниже низко никогда никуда ними них ничего но ну нужно нх о об оба обычно один одиннадцатый одиннадцать однажды однако одного одной около он она они оно опять особенно от отовсюду отсюда очень первый перед по под пожалуйста позже пока пор пора после посреди потом потому почему почти прекрасно при про просто против процентов пятнадцатый пятнадцать пятый пять раз разве рано раньше рядом с сам сама сами самим самими самих само самого самой самом самому саму свое своего своей свои своих свою сеаой себе себя сегодня седьмой сейчас семнадцатый семнадцать семь сих сказал сказала сказать сколько слишком сначала снова со собой собою совсем спасибо стал суть т та так такая также такие такое такой там твой твоя твоё те тебе тебя тем теми теперь тех то тобой тобою тогда того тоже только том тому тот тою третий три тринадцатый тринадцать ту туда тут ты тысяч у уж уже уметь хорошо хотеть хоть хотя хочешь часто чаще чего человек чем чему через четвертый четыре четырнадцатый четырнадцать что чтоб чтобы чуть шестнадцатый шестнадцать шестой шесть эта эти этим этими этих это этого этой этом этому этот эту я \\ufeffа\".split(\" \")),e.Pipeline.registerFunction(e.ru.stopWordFilter,\"stopWordFilter-ru\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.stemmer.support.js",
    "content": "!function(r,t){\"function\"==typeof define&&define.amd?define(t):\"object\"==typeof exports?module.exports=t():t()(r.lunr)}(this,function(){return function(r){r.stemmerSupport={Among:function(r,t,i,s){if(this.toCharArray=function(r){for(var t=r.length,i=new Array(t),s=0;s<t;s++)i[s]=r.charCodeAt(s);return i},!r&&\"\"!=r||!t&&0!=t||!i)throw\"Bad Among initialisation: s:\"+r+\", substring_i: \"+t+\", result: \"+i;this.s_size=r.length,this.s=this.toCharArray(r),this.substring_i=t,this.result=i,this.method=s},SnowballProgram:function(){var b;return{bra:0,ket:0,limit:0,cursor:0,limit_backward:0,setCurrent:function(r){b=r,this.cursor=0,this.limit=r.length,this.limit_backward=0,this.bra=this.cursor,this.ket=this.limit},getCurrent:function(){var r=b;return b=null,r},in_grouping:function(r,t,i){if(this.cursor<this.limit){var s=b.charCodeAt(this.cursor);if(s<=i&&t<=s&&r[(s-=t)>>3]&1<<(7&s))return this.cursor++,!0}return!1},in_grouping_b:function(r,t,i){if(this.cursor>this.limit_backward){var s=b.charCodeAt(this.cursor-1);if(s<=i&&t<=s&&r[(s-=t)>>3]&1<<(7&s))return this.cursor--,!0}return!1},out_grouping:function(r,t,i){if(this.cursor<this.limit){var s=b.charCodeAt(this.cursor);if(i<s||s<t)return this.cursor++,!0;if(!(r[(s-=t)>>3]&1<<(7&s)))return this.cursor++,!0}return!1},out_grouping_b:function(r,t,i){if(this.cursor>this.limit_backward){var s=b.charCodeAt(this.cursor-1);if(i<s||s<t)return this.cursor--,!0;if(!(r[(s-=t)>>3]&1<<(7&s)))return this.cursor--,!0}return!1},eq_s:function(r,t){if(this.limit-this.cursor<r)return!1;for(var i=0;i<r;i++)if(b.charCodeAt(this.cursor+i)!=t.charCodeAt(i))return!1;return this.cursor+=r,!0},eq_s_b:function(r,t){if(this.cursor-this.limit_backward<r)return!1;for(var i=0;i<r;i++)if(b.charCodeAt(this.cursor-r+i)!=t.charCodeAt(i))return!1;return this.cursor-=r,!0},find_among:function(r,t){for(var i=0,s=t,e=this.cursor,n=this.limit,u=0,o=0,h=!1;;){for(var c=i+(s-i>>1),a=0,f=u<o?u:o,l=r[c],_=f;_<l.s_size;_++){if(e+f==n){a=-1;break}if(a=b.charCodeAt(e+f)-l.s[_])break;f++}if(a<0?(s=c,o=f):(i=c,u=f),s-i<=1){if(0<i||s==i||h)break;h=!0}}for(;;){if(u>=(l=r[i]).s_size){if(this.cursor=e+l.s_size,!l.method)return l.result;var m=l.method();if(this.cursor=e+l.s_size,m)return l.result}if((i=l.substring_i)<0)return 0}},find_among_b:function(r,t){for(var i=0,s=t,e=this.cursor,n=this.limit_backward,u=0,o=0,h=!1;;){for(var c=i+(s-i>>1),a=0,f=u<o?u:o,l=(_=r[c]).s_size-1-f;0<=l;l--){if(e-f==n){a=-1;break}if(a=b.charCodeAt(e-1-f)-_.s[l])break;f++}if(a<0?(s=c,o=f):(i=c,u=f),s-i<=1){if(0<i||s==i||h)break;h=!0}}for(;;){var _;if(u>=(_=r[i]).s_size){if(this.cursor=e-_.s_size,!_.method)return _.result;var m=_.method();if(this.cursor=e-_.s_size,m)return _.result}if((i=_.substring_i)<0)return 0}},replace_s:function(r,t,i){var s=i.length-(t-r);return b=b.substring(0,r)+i+b.substring(t),this.limit+=s,this.cursor>=t?this.cursor+=s:this.cursor>r&&(this.cursor=r),s},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>b.length)throw\"faulty slice operation\"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from(\"\")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),b.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp(\"^[^\"+r+\"]+\"),i=new RegExp(\"[^\"+r+\"]+$\");return function(r){return\"function\"==typeof r.update?r.update(function(r){return r.replace(t,\"\").replace(i,\"\")}):r.replace(t,\"\").replace(i,\"\")}}}}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.sv.js",
    "content": "!function(e,r){\"function\"==typeof define&&define.amd?define(r):\"object\"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===e.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var r,l,n;e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters=\"A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤﬀ-ﬆＡ-Ｚａ-ｚ\",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,\"trimmer-sv\"),e.sv.stemmer=(r=e.stemmerSupport.Among,l=e.stemmerSupport.SnowballProgram,n=new function(){var n,t,i=[new r(\"a\",-1,1),new r(\"arna\",0,1),new r(\"erna\",0,1),new r(\"heterna\",2,1),new r(\"orna\",0,1),new r(\"ad\",-1,1),new r(\"e\",-1,1),new r(\"ade\",6,1),new r(\"ande\",6,1),new r(\"arne\",6,1),new r(\"are\",6,1),new r(\"aste\",6,1),new r(\"en\",-1,1),new r(\"anden\",12,1),new r(\"aren\",12,1),new r(\"heten\",12,1),new r(\"ern\",-1,1),new r(\"ar\",-1,1),new r(\"er\",-1,1),new r(\"heter\",18,1),new r(\"or\",-1,1),new r(\"s\",-1,2),new r(\"as\",21,1),new r(\"arnas\",22,1),new r(\"ernas\",22,1),new r(\"ornas\",22,1),new r(\"es\",21,1),new r(\"ades\",26,1),new r(\"andes\",26,1),new r(\"ens\",21,1),new r(\"arens\",29,1),new r(\"hetens\",29,1),new r(\"erns\",21,1),new r(\"at\",-1,1),new r(\"andet\",-1,1),new r(\"het\",-1,1),new r(\"ast\",-1,1)],s=[new r(\"dd\",-1,-1),new r(\"gd\",-1,-1),new r(\"nn\",-1,-1),new r(\"dt\",-1,-1),new r(\"gt\",-1,-1),new r(\"kt\",-1,-1),new r(\"tt\",-1,-1)],a=[new r(\"ig\",-1,1),new r(\"lig\",0,1),new r(\"els\",-1,1),new r(\"fullt\",-1,3),new r(\"löst\",-1,2)],o=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],u=[119,127,149],m=new l;this.setCurrent=function(e){m.setCurrent(e)},this.getCurrent=function(){return m.getCurrent()},this.stem=function(){var e,r=m.cursor;return function(){var e,r=m.cursor+3;if(t=m.limit,0<=r||r<=m.limit){for(n=r;;){if(e=m.cursor,m.in_grouping(o,97,246)){m.cursor=e;break}if(m.cursor=e,m.cursor>=m.limit)return;m.cursor++}for(;!m.out_grouping(o,97,246);){if(m.cursor>=m.limit)return;m.cursor++}(t=m.cursor)<n&&(t=n)}}(),m.limit_backward=r,m.cursor=m.limit,function(){var e,r=m.limit_backward;if(m.cursor>=t&&(m.limit_backward=t,m.cursor=m.limit,m.ket=m.cursor,e=m.find_among_b(i,37),m.limit_backward=r,e))switch(m.bra=m.cursor,e){case 1:m.slice_del();break;case 2:m.in_grouping_b(u,98,121)&&m.slice_del()}}(),m.cursor=m.limit,e=m.limit_backward,m.cursor>=t&&(m.limit_backward=t,m.cursor=m.limit,m.find_among_b(s,7)&&(m.cursor=m.limit,m.ket=m.cursor,m.cursor>m.limit_backward&&(m.bra=--m.cursor,m.slice_del())),m.limit_backward=e),m.cursor=m.limit,function(){var e,r;if(m.cursor>=t){if(r=m.limit_backward,m.limit_backward=t,m.cursor=m.limit,m.ket=m.cursor,e=m.find_among_b(a,5))switch(m.bra=m.cursor,e){case 1:m.slice_del();break;case 2:m.slice_from(\"lös\");break;case 3:m.slice_from(\"full\")}m.limit_backward=r}}(),!0}},function(e){return\"function\"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}),e.Pipeline.registerFunction(e.sv.stemmer,\"stemmer-sv\"),e.sv.stopWordFilter=e.generateStopWordFilter(\"alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över\".split(\" \")),e.Pipeline.registerFunction(e.sv.stopWordFilter,\"stopWordFilter-sv\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/lunr.tr.js",
    "content": "!function(r,i){\"function\"==typeof define&&define.amd?define(i):\"object\"==typeof exports?module.exports=i():i()(r.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error(\"Lunr is not present. Please include / require Lunr before this script.\");if(void 0===r.stemmerSupport)throw new Error(\"Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.\");var mr,dr,i;r.tr=function(){this.pipeline.reset(),this.pipeline.add(r.tr.trimmer,r.tr.stopWordFilter,r.tr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(r.tr.stemmer))},r.tr.wordCharacters=\"A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤﬀ-ﬆＡ-Ｚａ-ｚ\",r.tr.trimmer=r.trimmerSupport.generateTrimmer(r.tr.wordCharacters),r.Pipeline.registerFunction(r.tr.trimmer,\"trimmer-tr\"),r.tr.stemmer=(mr=r.stemmerSupport.Among,dr=r.stemmerSupport.SnowballProgram,i=new function(){var t,r=[new mr(\"m\",-1,-1),new mr(\"n\",-1,-1),new mr(\"miz\",-1,-1),new mr(\"niz\",-1,-1),new mr(\"muz\",-1,-1),new mr(\"nuz\",-1,-1),new mr(\"müz\",-1,-1),new mr(\"nüz\",-1,-1),new mr(\"mız\",-1,-1),new mr(\"nız\",-1,-1)],i=[new mr(\"leri\",-1,-1),new mr(\"ları\",-1,-1)],e=[new mr(\"ni\",-1,-1),new mr(\"nu\",-1,-1),new mr(\"nü\",-1,-1),new mr(\"nı\",-1,-1)],n=[new mr(\"in\",-1,-1),new mr(\"un\",-1,-1),new mr(\"ün\",-1,-1),new mr(\"ın\",-1,-1)],u=[new mr(\"a\",-1,-1),new mr(\"e\",-1,-1)],o=[new mr(\"na\",-1,-1),new mr(\"ne\",-1,-1)],s=[new mr(\"da\",-1,-1),new mr(\"ta\",-1,-1),new mr(\"de\",-1,-1),new mr(\"te\",-1,-1)],c=[new mr(\"nda\",-1,-1),new mr(\"nde\",-1,-1)],l=[new mr(\"dan\",-1,-1),new mr(\"tan\",-1,-1),new mr(\"den\",-1,-1),new mr(\"ten\",-1,-1)],a=[new mr(\"ndan\",-1,-1),new mr(\"nden\",-1,-1)],m=[new mr(\"la\",-1,-1),new mr(\"le\",-1,-1)],d=[new mr(\"ca\",-1,-1),new mr(\"ce\",-1,-1)],f=[new mr(\"im\",-1,-1),new mr(\"um\",-1,-1),new mr(\"üm\",-1,-1),new mr(\"ım\",-1,-1)],b=[new mr(\"sin\",-1,-1),new mr(\"sun\",-1,-1),new mr(\"sün\",-1,-1),new mr(\"sın\",-1,-1)],w=[new mr(\"iz\",-1,-1),new mr(\"uz\",-1,-1),new mr(\"üz\",-1,-1),new mr(\"ız\",-1,-1)],_=[new mr(\"siniz\",-1,-1),new mr(\"sunuz\",-1,-1),new mr(\"sünüz\",-1,-1),new mr(\"sınız\",-1,-1)],k=[new mr(\"lar\",-1,-1),new mr(\"ler\",-1,-1)],p=[new mr(\"niz\",-1,-1),new mr(\"nuz\",-1,-1),new mr(\"nüz\",-1,-1),new mr(\"nız\",-1,-1)],g=[new mr(\"dir\",-1,-1),new mr(\"tir\",-1,-1),new mr(\"dur\",-1,-1),new mr(\"tur\",-1,-1),new mr(\"dür\",-1,-1),new mr(\"tür\",-1,-1),new mr(\"dır\",-1,-1),new mr(\"tır\",-1,-1)],y=[new mr(\"casına\",-1,-1),new mr(\"cesine\",-1,-1)],z=[new mr(\"di\",-1,-1),new mr(\"ti\",-1,-1),new mr(\"dik\",-1,-1),new mr(\"tik\",-1,-1),new mr(\"duk\",-1,-1),new mr(\"tuk\",-1,-1),new mr(\"dük\",-1,-1),new mr(\"tük\",-1,-1),new mr(\"dık\",-1,-1),new mr(\"tık\",-1,-1),new mr(\"dim\",-1,-1),new mr(\"tim\",-1,-1),new mr(\"dum\",-1,-1),new mr(\"tum\",-1,-1),new mr(\"düm\",-1,-1),new mr(\"tüm\",-1,-1),new mr(\"dım\",-1,-1),new mr(\"tım\",-1,-1),new mr(\"din\",-1,-1),new mr(\"tin\",-1,-1),new mr(\"dun\",-1,-1),new mr(\"tun\",-1,-1),new mr(\"dün\",-1,-1),new mr(\"tün\",-1,-1),new mr(\"dın\",-1,-1),new mr(\"tın\",-1,-1),new mr(\"du\",-1,-1),new mr(\"tu\",-1,-1),new mr(\"dü\",-1,-1),new mr(\"tü\",-1,-1),new mr(\"dı\",-1,-1),new mr(\"tı\",-1,-1)],h=[new mr(\"sa\",-1,-1),new mr(\"se\",-1,-1),new mr(\"sak\",-1,-1),new mr(\"sek\",-1,-1),new mr(\"sam\",-1,-1),new mr(\"sem\",-1,-1),new mr(\"san\",-1,-1),new mr(\"sen\",-1,-1)],v=[new mr(\"miş\",-1,-1),new mr(\"muş\",-1,-1),new mr(\"müş\",-1,-1),new mr(\"mış\",-1,-1)],q=[new mr(\"b\",-1,1),new mr(\"c\",-1,2),new mr(\"d\",-1,3),new mr(\"ğ\",-1,4)],C=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,1],P=[1,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,1],F=[65],S=[65],W=[[\"a\",[1,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],97,305],[\"e\",[17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130],101,252],[\"ı\",[1,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],97,305],[\"i\",[17],101,105],[\"o\",F,111,117],[\"ö\",S,246,252],[\"u\",F,111,117]],L=new dr;function x(r,i,e){for(;;){var n=L.limit-L.cursor;if(L.in_grouping_b(r,i,e)){L.cursor=L.limit-n;break}if(L.cursor=L.limit-n,L.cursor<=L.limit_backward)return!1;L.cursor--}return!0}function A(){var r,i;r=L.limit-L.cursor,x(C,97,305);for(var e=0;e<W.length;e++){i=L.limit-L.cursor;var n=W[e];if(L.eq_s_b(1,n[0])&&x(n[1],n[2],n[3]))return L.cursor=L.limit-r,!0;L.cursor=L.limit-i}return L.cursor=L.limit-i,!(!L.eq_s_b(1,\"ü\")||!x(S,246,252))&&(L.cursor=L.limit-r,!0)}function E(r,i){var e,n=L.limit-L.cursor;return r()&&(L.cursor=L.limit-n,L.cursor>L.limit_backward&&(L.cursor--,e=L.limit-L.cursor,i()))?(L.cursor=L.limit-e,!0):(L.cursor=L.limit-n,r()?(L.cursor=L.limit-n,!1):(L.cursor=L.limit-n,!(L.cursor<=L.limit_backward)&&(L.cursor--,!!i()&&(L.cursor=L.limit-n,!0))))}function j(r){return E(r,function(){return L.in_grouping_b(C,97,305)})}function T(){return j(function(){return L.eq_s_b(1,\"n\")})}function Z(){return j(function(){return L.eq_s_b(1,\"y\")})}function B(){return L.find_among_b(r,10)&&E(function(){return L.in_grouping_b(P,105,305)},function(){return L.out_grouping_b(C,97,305)})}function D(){return A()&&L.in_grouping_b(P,105,305)&&j(function(){return L.eq_s_b(1,\"s\")})}function G(){return L.find_among_b(i,2)}function H(){return A()&&L.find_among_b(n,4)&&T()}function I(){return A()&&L.find_among_b(s,4)}function J(){return A()&&L.find_among_b(c,2)}function K(){return A()&&L.find_among_b(f,4)&&Z()}function M(){return A()&&L.find_among_b(b,4)}function N(){return A()&&L.find_among_b(w,4)&&Z()}function O(){return L.find_among_b(_,4)}function Q(){return A()&&L.find_among_b(k,2)}function R(){return A()&&L.find_among_b(g,8)}function U(){return A()&&L.find_among_b(z,32)&&Z()}function V(){return L.find_among_b(h,8)&&Z()}function X(){return A()&&L.find_among_b(v,4)&&Z()}function Y(){var r=L.limit-L.cursor;return!(X()||(L.cursor=L.limit-r,U()||(L.cursor=L.limit-r,V()||(L.cursor=L.limit-r,L.eq_s_b(3,\"ken\")&&Z()))))}function $(){if(L.find_among_b(y,2)){var r=L.limit-L.cursor;if(O()||(L.cursor=L.limit-r,Q()||(L.cursor=L.limit-r,K()||(L.cursor=L.limit-r,M()||(L.cursor=L.limit-r,N()||(L.cursor=L.limit-r))))),X())return!1}return!0}function rr(){if(!A()||!L.find_among_b(p,4))return!0;var r=L.limit-L.cursor;return!U()&&(L.cursor=L.limit-r,!V())}function ir(){var r,i,e,n=L.limit-L.cursor;if(L.ket=L.cursor,t=!0,Y()&&(L.cursor=L.limit-n,$()&&(L.cursor=L.limit-n,function(){if(Q()){L.bra=L.cursor,L.slice_del();var r=L.limit-L.cursor;return L.ket=L.cursor,R()||(L.cursor=L.limit-r,U()||(L.cursor=L.limit-r,V()||(L.cursor=L.limit-r,X()||(L.cursor=L.limit-r)))),t=!1}return!0}()&&(L.cursor=L.limit-n,rr()&&(L.cursor=L.limit-n,e=L.limit-L.cursor,!(O()||(L.cursor=L.limit-e,N()||(L.cursor=L.limit-e,M()||(L.cursor=L.limit-e,K()))))||(L.bra=L.cursor,L.slice_del(),i=L.limit-L.cursor,L.ket=L.cursor,X()||(L.cursor=L.limit-i),0)))))){if(L.cursor=L.limit-n,!R())return;L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,r=L.limit-L.cursor,O()||(L.cursor=L.limit-r,Q()||(L.cursor=L.limit-r,K()||(L.cursor=L.limit-r,M()||(L.cursor=L.limit-r,N()||(L.cursor=L.limit-r))))),X()||(L.cursor=L.limit-r)}L.bra=L.cursor,L.slice_del()}function er(){var r,i,e,n;if(L.ket=L.cursor,L.eq_s_b(2,\"ki\")){if(r=L.limit-L.cursor,I())return L.bra=L.cursor,L.slice_del(),i=L.limit-L.cursor,L.ket=L.cursor,Q()?(L.bra=L.cursor,L.slice_del(),er()):(L.cursor=L.limit-i,B()&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er()))),!0;if(L.cursor=L.limit-r,H()){if(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,e=L.limit-L.cursor,G())L.bra=L.cursor,L.slice_del();else{if(L.cursor=L.limit-e,L.ket=L.cursor,!B()&&(L.cursor=L.limit-e,!D()&&(L.cursor=L.limit-e,!er())))return!0;L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())}return!0}if(L.cursor=L.limit-r,J()){if(n=L.limit-L.cursor,G())L.bra=L.cursor,L.slice_del();else if(L.cursor=L.limit-n,D())L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er());else if(L.cursor=L.limit-n,!er())return!1;return!0}}return!1}function nr(r){if(L.ket=L.cursor,!J()&&(L.cursor=L.limit-r,!A()||!L.find_among_b(o,2)))return!1;var i=L.limit-L.cursor;if(G())L.bra=L.cursor,L.slice_del();else if(L.cursor=L.limit-i,D())L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er());else if(L.cursor=L.limit-i,!er())return!1;return!0}function tr(r){if(L.ket=L.cursor,!(A()&&L.find_among_b(a,2)||(L.cursor=L.limit-r,A()&&L.find_among_b(e,4))))return!1;var i=L.limit-L.cursor;return!(!D()&&(L.cursor=L.limit-i,!G()))&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er()),!0)}function ur(){var r,i=L.limit-L.cursor;return L.ket=L.cursor,!!(H()||(L.cursor=L.limit-i,A()&&L.find_among_b(m,2)&&Z()))&&(L.bra=L.cursor,L.slice_del(),r=L.limit-L.cursor,L.ket=L.cursor,!(!Q()||(L.bra=L.cursor,L.slice_del(),!er()))||(L.cursor=L.limit-r,L.ket=L.cursor,(B()||(L.cursor=L.limit-r,D()||(L.cursor=L.limit-r,er())))&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())),!0))}function or(){var r,i,e=L.limit-L.cursor;if(L.ket=L.cursor,!(I()||(L.cursor=L.limit-e,A()&&L.in_grouping_b(P,105,305)&&Z()||(L.cursor=L.limit-e,A()&&L.find_among_b(u,2)&&Z()))))return!1;if(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,r=L.limit-L.cursor,B())L.bra=L.cursor,L.slice_del(),i=L.limit-L.cursor,L.ket=L.cursor,Q()||(L.cursor=L.limit-i);else if(L.cursor=L.limit-r,!Q())return!0;return L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,er(),!0}function sr(){var r,i,e=L.limit-L.cursor;if(L.ket=L.cursor,Q())return L.bra=L.cursor,L.slice_del(),void er();if(L.cursor=L.limit-e,L.ket=L.cursor,A()&&L.find_among_b(d,2)&&T())if(L.bra=L.cursor,L.slice_del(),r=L.limit-L.cursor,L.ket=L.cursor,G())L.bra=L.cursor,L.slice_del();else{if(L.cursor=L.limit-r,L.ket=L.cursor,!B()&&(L.cursor=L.limit-r,!D())){if(L.cursor=L.limit-r,L.ket=L.cursor,!Q())return;if(L.bra=L.cursor,L.slice_del(),!er())return}L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())}else if(L.cursor=L.limit-e,!nr(e)&&(L.cursor=L.limit-e,!tr(e))){if(L.cursor=L.limit-e,L.ket=L.cursor,A()&&L.find_among_b(l,4))return L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,i=L.limit-L.cursor,void(B()?(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())):(L.cursor=L.limit-i,Q()?(L.bra=L.cursor,L.slice_del()):L.cursor=L.limit-i,er()));if(L.cursor=L.limit-e,!ur()){if(L.cursor=L.limit-e,G())return L.bra=L.cursor,void L.slice_del();L.cursor=L.limit-e,er()||(L.cursor=L.limit-e,or()||(L.cursor=L.limit-e,L.ket=L.cursor,(B()||(L.cursor=L.limit-e,D()))&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er()))))}}}function cr(r,i,e){if(L.cursor=L.limit-r,function(){for(;;){var r=L.limit-L.cursor;if(L.in_grouping_b(C,97,305)){L.cursor=L.limit-r;break}if(L.cursor=L.limit-r,L.cursor<=L.limit_backward)return!1;L.cursor--}return!0}()){var n=L.limit-L.cursor;if(!L.eq_s_b(1,i)&&(L.cursor=L.limit-n,!L.eq_s_b(1,e)))return!0;L.cursor=L.limit-r;var t=L.cursor;return L.insert(L.cursor,L.cursor,e),L.cursor=t,!1}return!0}function lr(r,i,e){for(;!L.eq_s(i,e);){if(L.cursor>=L.limit)return!0;L.cursor++}return i!=L.limit||(L.cursor=r,!1)}function ar(){var r,i,e=L.cursor;return!(!lr(r=L.cursor,2,\"ad\")||!lr(L.cursor=r,5,\"soyad\"))&&(L.limit_backward=e,L.cursor=L.limit,i=L.limit-L.cursor,(L.eq_s_b(1,\"d\")||(L.cursor=L.limit-i,L.eq_s_b(1,\"g\")))&&cr(i,\"a\",\"ı\")&&cr(i,\"e\",\"i\")&&cr(i,\"o\",\"u\")&&cr(i,\"ö\",\"ü\"),L.cursor=L.limit,function(){var r;if(L.ket=L.cursor,r=L.find_among_b(q,4))switch(L.bra=L.cursor,r){case 1:L.slice_from(\"p\");break;case 2:L.slice_from(\"ç\");break;case 3:L.slice_from(\"t\");break;case 4:L.slice_from(\"k\")}}(),!0)}this.setCurrent=function(r){L.setCurrent(r)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){return!!(function(){for(var r,i=L.cursor,e=2;;){for(r=L.cursor;!L.in_grouping(C,97,305);){if(L.cursor>=L.limit)return L.cursor=r,!(0<e||(L.cursor=i,0));L.cursor++}e--}}()&&(L.limit_backward=L.cursor,L.cursor=L.limit,ir(),L.cursor=L.limit,t&&(sr(),L.cursor=L.limit_backward,ar())))}},function(r){return\"function\"==typeof r.update?r.update(function(r){return i.setCurrent(r),i.stem(),i.getCurrent()}):(i.setCurrent(r),i.stem(),i.getCurrent())}),r.Pipeline.registerFunction(r.tr.stemmer,\"stemmer-tr\"),r.tr.stopWordFilter=r.generateStopWordFilter(\"acaba altmış altı ama ancak arada aslında ayrıca bana bazı belki ben benden beni benim beri beş bile bin bir biri birkaç birkez birçok birşey birşeyi biz bizden bize bizi bizim bu buna bunda bundan bunlar bunları bunların bunu bunun burada böyle böylece da daha dahi de defa değil diye diğer doksan dokuz dolayı dolayısıyla dört edecek eden ederek edilecek ediliyor edilmesi ediyor elli en etmesi etti ettiği ettiğini eğer gibi göre halen hangi hatta hem henüz hep hepsi her herhangi herkesin hiç hiçbir iki ile ilgili ise itibaren itibariyle için işte kadar karşın katrilyon kendi kendilerine kendini kendisi kendisine kendisini kez ki kim kimden kime kimi kimse kırk milyar milyon mu mü mı nasıl ne neden nedenle nerde nerede nereye niye niçin o olan olarak oldu olduklarını olduğu olduğunu olmadı olmadığı olmak olması olmayan olmaz olsa olsun olup olur olursa oluyor on ona ondan onlar onlardan onları onların onu onun otuz oysa pek rağmen sadece sanki sekiz seksen sen senden seni senin siz sizden sizi sizin tarafından trilyon tüm var vardı ve veya ya yani yapacak yapmak yaptı yaptıkları yaptığı yaptığını yapılan yapılması yapıyor yedi yerine yetmiş yine yirmi yoksa yüz zaten çok çünkü öyle üzere üç şey şeyden şeyi şeyler şu şuna şunda şundan şunları şunu şöyle\".split(\" \")),r.Pipeline.registerFunction(r.tr.stopWordFilter,\"stopWordFilter-tr\")}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/lunr/tinyseg.js",
    "content": "!function(_,t){\"function\"==typeof define&&define.amd?define(t):\"object\"==typeof exports?module.exports=t():t()(_.lunr)}(this,function(){return function(_){function t(){var _={\"[一二三四五六七八九十百千万億兆]\":\"M\",\"[一-龠々〆ヵヶ]\":\"H\",\"[ぁ-ん]\":\"I\",\"[ァ-ヴーｱ-ﾝﾞｰ]\":\"K\",\"[a-zA-Zａ-ｚＡ-Ｚ]\":\"A\",\"[0-9０-９]\":\"N\"};for(var t in this.chartype_=[],_){var H=new RegExp;H.compile(t),this.chartype_.push([H,_[t]])}return this.BIAS__=-332,this.BC1__={HH:6,II:2461,KH:406,OH:-1378},this.BC2__={AA:-3267,AI:2744,AN:-878,HH:-4070,HM:-1711,HN:4012,HO:3761,IA:1327,IH:-1184,II:-1332,IK:1721,IO:5492,KI:3831,KK:-8741,MH:-3132,MK:3334,OO:-2920},this.BC3__={HH:996,HI:626,HK:-721,HN:-1307,HO:-836,IH:-301,KK:2762,MK:1079,MM:4034,OA:-1652,OH:266},this.BP1__={BB:295,OB:304,OO:-125,UB:352},this.BP2__={BO:60,OO:-1762},this.BQ1__={BHH:1150,BHM:1521,BII:-1158,BIM:886,BMH:1208,BNH:449,BOH:-91,BOO:-2597,OHI:451,OIH:-296,OKA:1851,OKH:-1020,OKK:904,OOO:2965},this.BQ2__={BHH:118,BHI:-1159,BHM:466,BIH:-919,BKK:-1720,BKO:864,OHH:-1139,OHM:-181,OIH:153,UHI:-1146},this.BQ3__={BHH:-792,BHI:2664,BII:-299,BKI:419,BMH:937,BMM:8335,BNN:998,BOH:775,OHH:2174,OHM:439,OII:280,OKH:1798,OKI:-793,OKO:-2242,OMH:-2402,OOO:11699},this.BQ4__={BHH:-3895,BIH:3761,BII:-4654,BIK:1348,BKK:-1806,BMI:-3385,BOO:-12396,OAH:926,OHH:266,OHK:-2036,ONN:-973},this.BW1__={\",と\":660,\",同\":727,\"B1あ\":1404,\"B1同\":542,\"、と\":660,\"、同\":727,\"」と\":1682,\"あっ\":1505,\"いう\":1743,\"いっ\":-2055,\"いる\":672,\"うし\":-4817,\"うん\":665,\"から\":3472,\"がら\":600,\"こう\":-790,\"こと\":2083,\"こん\":-1262,\"さら\":-4143,\"さん\":4573,\"した\":2641,\"して\":1104,\"すで\":-3399,\"そこ\":1977,\"それ\":-871,\"たち\":1122,\"ため\":601,\"った\":3463,\"つい\":-802,\"てい\":805,\"てき\":1249,\"でき\":1127,\"です\":3445,\"では\":844,\"とい\":-4915,\"とみ\":1922,\"どこ\":3887,\"ない\":5713,\"なっ\":3015,\"など\":7379,\"なん\":-1113,\"にし\":2468,\"には\":1498,\"にも\":1671,\"に対\":-912,\"の一\":-501,\"の中\":741,\"ませ\":2448,\"まで\":1711,\"まま\":2600,\"まる\":-2155,\"やむ\":-1947,\"よっ\":-2565,\"れた\":2369,\"れで\":-913,\"をし\":1860,\"を見\":731,\"亡く\":-1886,\"京都\":2558,\"取り\":-2784,\"大き\":-2604,\"大阪\":1497,\"平方\":-2314,\"引き\":-1336,\"日本\":-195,\"本当\":-2423,\"毎日\":-2113,\"目指\":-724,\"Ｂ１あ\":1404,\"Ｂ１同\":542,\"｣と\":1682},this.BW2__={\"..\":-11822,11:-669,\"――\":-5730,\"−−\":-13175,\"いう\":-1609,\"うか\":2490,\"かし\":-1350,\"かも\":-602,\"から\":-7194,\"かれ\":4612,\"がい\":853,\"がら\":-3198,\"きた\":1941,\"くな\":-1597,\"こと\":-8392,\"この\":-4193,\"させ\":4533,\"され\":13168,\"さん\":-3977,\"しい\":-1819,\"しか\":-545,\"した\":5078,\"して\":972,\"しな\":939,\"その\":-3744,\"たい\":-1253,\"たた\":-662,\"ただ\":-3857,\"たち\":-786,\"たと\":1224,\"たは\":-939,\"った\":4589,\"って\":1647,\"っと\":-2094,\"てい\":6144,\"てき\":3640,\"てく\":2551,\"ては\":-3110,\"ても\":-3065,\"でい\":2666,\"でき\":-1528,\"でし\":-3828,\"です\":-4761,\"でも\":-4203,\"とい\":1890,\"とこ\":-1746,\"とと\":-2279,\"との\":720,\"とみ\":5168,\"とも\":-3941,\"ない\":-2488,\"なが\":-1313,\"など\":-6509,\"なの\":2614,\"なん\":3099,\"にお\":-1615,\"にし\":2748,\"にな\":2454,\"によ\":-7236,\"に対\":-14943,\"に従\":-4688,\"に関\":-11388,\"のか\":2093,\"ので\":-7059,\"のに\":-6041,\"のの\":-6125,\"はい\":1073,\"はが\":-1033,\"はず\":-2532,\"ばれ\":1813,\"まし\":-1316,\"まで\":-6621,\"まれ\":5409,\"めて\":-3153,\"もい\":2230,\"もの\":-10713,\"らか\":-944,\"らし\":-1611,\"らに\":-1897,\"りし\":651,\"りま\":1620,\"れた\":4270,\"れて\":849,\"れば\":4114,\"ろう\":6067,\"われ\":7901,\"を通\":-11877,\"んだ\":728,\"んな\":-4115,\"一人\":602,\"一方\":-1375,\"一日\":970,\"一部\":-1051,\"上が\":-4479,\"会社\":-1116,\"出て\":2163,\"分の\":-7758,\"同党\":970,\"同日\":-913,\"大阪\":-2471,\"委員\":-1250,\"少な\":-1050,\"年度\":-8669,\"年間\":-1626,\"府県\":-2363,\"手権\":-1982,\"新聞\":-4066,\"日新\":-722,\"日本\":-7068,\"日米\":3372,\"曜日\":-601,\"朝鮮\":-2355,\"本人\":-2697,\"東京\":-1543,\"然と\":-1384,\"社会\":-1276,\"立て\":-990,\"第に\":-1612,\"米国\":-4268,\"１１\":-669},this.BW3__={\"あた\":-2194,\"あり\":719,\"ある\":3846,\"い.\":-1185,\"い。\":-1185,\"いい\":5308,\"いえ\":2079,\"いく\":3029,\"いた\":2056,\"いっ\":1883,\"いる\":5600,\"いわ\":1527,\"うち\":1117,\"うと\":4798,\"えと\":1454,\"か.\":2857,\"か。\":2857,\"かけ\":-743,\"かっ\":-4098,\"かに\":-669,\"から\":6520,\"かり\":-2670,\"が,\":1816,\"が、\":1816,\"がき\":-4855,\"がけ\":-1127,\"がっ\":-913,\"がら\":-4977,\"がり\":-2064,\"きた\":1645,\"けど\":1374,\"こと\":7397,\"この\":1542,\"ころ\":-2757,\"さい\":-714,\"さを\":976,\"し,\":1557,\"し、\":1557,\"しい\":-3714,\"した\":3562,\"して\":1449,\"しな\":2608,\"しま\":1200,\"す.\":-1310,\"す。\":-1310,\"する\":6521,\"ず,\":3426,\"ず、\":3426,\"ずに\":841,\"そう\":428,\"た.\":8875,\"た。\":8875,\"たい\":-594,\"たの\":812,\"たり\":-1183,\"たる\":-853,\"だ.\":4098,\"だ。\":4098,\"だっ\":1004,\"った\":-4748,\"って\":300,\"てい\":6240,\"てお\":855,\"ても\":302,\"です\":1437,\"でに\":-1482,\"では\":2295,\"とう\":-1387,\"とし\":2266,\"との\":541,\"とも\":-3543,\"どう\":4664,\"ない\":1796,\"なく\":-903,\"など\":2135,\"に,\":-1021,\"に、\":-1021,\"にし\":1771,\"にな\":1906,\"には\":2644,\"の,\":-724,\"の、\":-724,\"の子\":-1e3,\"は,\":1337,\"は、\":1337,\"べき\":2181,\"まし\":1113,\"ます\":6943,\"まっ\":-1549,\"まで\":6154,\"まれ\":-793,\"らし\":1479,\"られ\":6820,\"るる\":3818,\"れ,\":854,\"れ、\":854,\"れた\":1850,\"れて\":1375,\"れば\":-3246,\"れる\":1091,\"われ\":-605,\"んだ\":606,\"んで\":798,\"カ月\":990,\"会議\":860,\"入り\":1232,\"大会\":2217,\"始め\":1681,\"市\":965,\"新聞\":-5055,\"日,\":974,\"日、\":974,\"社会\":2024,\"ｶ月\":990},this.TC1__={AAA:1093,HHH:1029,HHM:580,HII:998,HOH:-390,HOM:-331,IHI:1169,IOH:-142,IOI:-1015,IOM:467,MMH:187,OOI:-1832},this.TC2__={HHO:2088,HII:-1023,HMM:-1154,IHI:-1965,KKH:703,OII:-2649},this.TC3__={AAA:-294,HHH:346,HHI:-341,HII:-1088,HIK:731,HOH:-1486,IHH:128,IHI:-3041,IHO:-1935,IIH:-825,IIM:-1035,IOI:-542,KHH:-1216,KKA:491,KKH:-1217,KOK:-1009,MHH:-2694,MHM:-457,MHO:123,MMH:-471,NNH:-1689,NNO:662,OHO:-3393},this.TC4__={HHH:-203,HHI:1344,HHK:365,HHM:-122,HHN:182,HHO:669,HIH:804,HII:679,HOH:446,IHH:695,IHO:-2324,IIH:321,III:1497,IIO:656,IOO:54,KAK:4845,KKA:3386,KKK:3065,MHH:-405,MHI:201,MMH:-241,MMM:661,MOM:841},this.TQ1__={BHHH:-227,BHHI:316,BHIH:-132,BIHH:60,BIII:1595,BNHH:-744,BOHH:225,BOOO:-908,OAKK:482,OHHH:281,OHIH:249,OIHI:200,OIIH:-68},this.TQ2__={BIHH:-1401,BIII:-1033,BKAK:-543,BOOO:-5591},this.TQ3__={BHHH:478,BHHM:-1073,BHIH:222,BHII:-504,BIIH:-116,BIII:-105,BMHI:-863,BMHM:-464,BOMH:620,OHHH:346,OHHI:1729,OHII:997,OHMH:481,OIHH:623,OIIH:1344,OKAK:2792,OKHH:587,OKKA:679,OOHH:110,OOII:-685},this.TQ4__={BHHH:-721,BHHM:-3604,BHII:-966,BIIH:-607,BIII:-2181,OAAA:-2763,OAKK:180,OHHH:-294,OHHI:2446,OHHO:480,OHIH:-1573,OIHH:1935,OIHI:-493,OIIH:626,OIII:-4007,OKAK:-8156},this.TW1__={\"につい\":-4681,\"東京都\":2026},this.TW2__={\"ある程\":-2049,\"いった\":-1256,\"ころが\":-2434,\"しょう\":3873,\"その後\":-4430,\"だって\":-1049,\"ていた\":1833,\"として\":-4657,\"ともに\":-4517,\"もので\":1882,\"一気に\":-792,\"初めて\":-1512,\"同時に\":-8097,\"大きな\":-1255,\"対して\":-2721,\"社会党\":-3216},this.TW3__={\"いただ\":-1734,\"してい\":1314,\"として\":-4314,\"につい\":-5483,\"にとっ\":-5989,\"に当た\":-6247,\"ので,\":-727,\"ので、\":-727,\"のもの\":-600,\"れから\":-3752,\"十二月\":-2287},this.TW4__={\"いう.\":8576,\"いう。\":8576,\"からな\":-2348,\"してい\":2958,\"たが,\":1516,\"たが、\":1516,\"ている\":1538,\"という\":1349,\"ました\":5543,\"ません\":1097,\"ようと\":-4258,\"よると\":5865},this.UC1__={A:484,K:93,M:645,O:-505},this.UC2__={A:819,H:1059,I:409,M:3987,N:5775,O:646},this.UC3__={A:-1370,I:2311},this.UC4__={A:-2643,H:1809,I:-1032,K:-3450,M:3565,N:3876,O:6646},this.UC5__={H:313,I:-1238,K:-799,M:539,O:-831},this.UC6__={H:-506,I:-253,K:87,M:247,O:-387},this.UP1__={O:-214},this.UP2__={B:69,O:935},this.UP3__={B:189},this.UQ1__={BH:21,BI:-12,BK:-99,BN:142,BO:-56,OH:-95,OI:477,OK:410,OO:-2422},this.UQ2__={BH:216,BI:113,OK:1759},this.UQ3__={BA:-479,BH:42,BI:1913,BK:-7198,BM:3160,BN:6427,BO:14761,OI:-827,ON:-3212},this.UW1__={\",\":156,\"、\":156,\"「\":-463,\"あ\":-941,\"う\":-127,\"が\":-553,\"き\":121,\"こ\":505,\"で\":-201,\"と\":-547,\"ど\":-123,\"に\":-789,\"の\":-185,\"は\":-847,\"も\":-466,\"や\":-470,\"よ\":182,\"ら\":-292,\"り\":208,\"れ\":169,\"を\":-446,\"ん\":-137,\"・\":-135,\"主\":-402,\"京\":-268,\"区\":-912,\"午\":871,\"国\":-460,\"大\":561,\"委\":729,\"市\":-411,\"日\":-141,\"理\":361,\"生\":-408,\"県\":-386,\"都\":-718,\"｢\":-463,\"･\":-135},this.UW2__={\",\":-829,\"、\":-829,\"〇\":892,\"「\":-645,\"」\":3145,\"あ\":-538,\"い\":505,\"う\":134,\"お\":-502,\"か\":1454,\"が\":-856,\"く\":-412,\"こ\":1141,\"さ\":878,\"ざ\":540,\"し\":1529,\"す\":-675,\"せ\":300,\"そ\":-1011,\"た\":188,\"だ\":1837,\"つ\":-949,\"て\":-291,\"で\":-268,\"と\":-981,\"ど\":1273,\"な\":1063,\"に\":-1764,\"の\":130,\"は\":-409,\"ひ\":-1273,\"べ\":1261,\"ま\":600,\"も\":-1263,\"や\":-402,\"よ\":1639,\"り\":-579,\"る\":-694,\"れ\":571,\"を\":-2516,\"ん\":2095,\"ア\":-587,\"カ\":306,\"キ\":568,\"ッ\":831,\"三\":-758,\"不\":-2150,\"世\":-302,\"中\":-968,\"主\":-861,\"事\":492,\"人\":-123,\"会\":978,\"保\":362,\"入\":548,\"初\":-3025,\"副\":-1566,\"北\":-3414,\"区\":-422,\"大\":-1769,\"天\":-865,\"太\":-483,\"子\":-1519,\"学\":760,\"実\":1023,\"小\":-2009,\"市\":-813,\"年\":-1060,\"強\":1067,\"手\":-1519,\"揺\":-1033,\"政\":1522,\"文\":-1355,\"新\":-1682,\"日\":-1815,\"明\":-1462,\"最\":-630,\"朝\":-1843,\"本\":-1650,\"東\":-931,\"果\":-665,\"次\":-2378,\"民\":-180,\"気\":-1740,\"理\":752,\"発\":529,\"目\":-1584,\"相\":-242,\"県\":-1165,\"立\":-763,\"第\":810,\"米\":509,\"自\":-1353,\"行\":838,\"西\":-744,\"見\":-3874,\"調\":1010,\"議\":1198,\"込\":3041,\"開\":1758,\"間\":-1257,\"｢\":-645,\"｣\":3145,\"ｯ\":831,\"ｱ\":-587,\"ｶ\":306,\"ｷ\":568},this.UW3__={\",\":4889,1:-800,\"−\":-1723,\"、\":4889,\"々\":-2311,\"〇\":5827,\"」\":2670,\"〓\":-3573,\"あ\":-2696,\"い\":1006,\"う\":2342,\"え\":1983,\"お\":-4864,\"か\":-1163,\"が\":3271,\"く\":1004,\"け\":388,\"げ\":401,\"こ\":-3552,\"ご\":-3116,\"さ\":-1058,\"し\":-395,\"す\":584,\"せ\":3685,\"そ\":-5228,\"た\":842,\"ち\":-521,\"っ\":-1444,\"つ\":-1081,\"て\":6167,\"で\":2318,\"と\":1691,\"ど\":-899,\"な\":-2788,\"に\":2745,\"の\":4056,\"は\":4555,\"ひ\":-2171,\"ふ\":-1798,\"へ\":1199,\"ほ\":-5516,\"ま\":-4384,\"み\":-120,\"め\":1205,\"も\":2323,\"や\":-788,\"よ\":-202,\"ら\":727,\"り\":649,\"る\":5905,\"れ\":2773,\"わ\":-1207,\"を\":6620,\"ん\":-518,\"ア\":551,\"グ\":1319,\"ス\":874,\"ッ\":-1350,\"ト\":521,\"ム\":1109,\"ル\":1591,\"ロ\":2201,\"ン\":278,\"・\":-3794,\"一\":-1619,\"下\":-1759,\"世\":-2087,\"両\":3815,\"中\":653,\"主\":-758,\"予\":-1193,\"二\":974,\"人\":2742,\"今\":792,\"他\":1889,\"以\":-1368,\"低\":811,\"何\":4265,\"作\":-361,\"保\":-2439,\"元\":4858,\"党\":3593,\"全\":1574,\"公\":-3030,\"六\":755,\"共\":-1880,\"円\":5807,\"再\":3095,\"分\":457,\"初\":2475,\"別\":1129,\"前\":2286,\"副\":4437,\"力\":365,\"動\":-949,\"務\":-1872,\"化\":1327,\"北\":-1038,\"区\":4646,\"千\":-2309,\"午\":-783,\"協\":-1006,\"口\":483,\"右\":1233,\"各\":3588,\"合\":-241,\"同\":3906,\"和\":-837,\"員\":4513,\"国\":642,\"型\":1389,\"場\":1219,\"外\":-241,\"妻\":2016,\"学\":-1356,\"安\":-423,\"実\":-1008,\"家\":1078,\"小\":-513,\"少\":-3102,\"州\":1155,\"市\":3197,\"平\":-1804,\"年\":2416,\"広\":-1030,\"府\":1605,\"度\":1452,\"建\":-2352,\"当\":-3885,\"得\":1905,\"思\":-1291,\"性\":1822,\"戸\":-488,\"指\":-3973,\"政\":-2013,\"教\":-1479,\"数\":3222,\"文\":-1489,\"新\":1764,\"日\":2099,\"旧\":5792,\"昨\":-661,\"時\":-1248,\"曜\":-951,\"最\":-937,\"月\":4125,\"期\":360,\"李\":3094,\"村\":364,\"東\":-805,\"核\":5156,\"森\":2438,\"業\":484,\"氏\":2613,\"民\":-1694,\"決\":-1073,\"法\":1868,\"海\":-495,\"無\":979,\"物\":461,\"特\":-3850,\"生\":-273,\"用\":914,\"町\":1215,\"的\":7313,\"直\":-1835,\"省\":792,\"県\":6293,\"知\":-1528,\"私\":4231,\"税\":401,\"立\":-960,\"第\":1201,\"米\":7767,\"系\":3066,\"約\":3663,\"級\":1384,\"統\":-4229,\"総\":1163,\"線\":1255,\"者\":6457,\"能\":725,\"自\":-2869,\"英\":785,\"見\":1044,\"調\":-562,\"財\":-733,\"費\":1777,\"車\":1835,\"軍\":1375,\"込\":-1504,\"通\":-1136,\"選\":-681,\"郎\":1026,\"郡\":4404,\"部\":1200,\"金\":2163,\"長\":421,\"開\":-1432,\"間\":1302,\"関\":-1282,\"雨\":2009,\"電\":-1045,\"非\":2066,\"駅\":1620,\"１\":-800,\"｣\":2670,\"･\":-3794,\"ｯ\":-1350,\"ｱ\":551,\"ｸﾞ\":1319,\"ｽ\":874,\"ﾄ\":521,\"ﾑ\":1109,\"ﾙ\":1591,\"ﾛ\":2201,\"ﾝ\":278},this.UW4__={\",\":3930,\".\":3508,\"―\":-4841,\"、\":3930,\"。\":3508,\"〇\":4999,\"「\":1895,\"」\":3798,\"〓\":-5156,\"あ\":4752,\"い\":-3435,\"う\":-640,\"え\":-2514,\"お\":2405,\"か\":530,\"が\":6006,\"き\":-4482,\"ぎ\":-3821,\"く\":-3788,\"け\":-4376,\"げ\":-4734,\"こ\":2255,\"ご\":1979,\"さ\":2864,\"し\":-843,\"じ\":-2506,\"す\":-731,\"ず\":1251,\"せ\":181,\"そ\":4091,\"た\":5034,\"だ\":5408,\"ち\":-3654,\"っ\":-5882,\"つ\":-1659,\"て\":3994,\"で\":7410,\"と\":4547,\"な\":5433,\"に\":6499,\"ぬ\":1853,\"ね\":1413,\"の\":7396,\"は\":8578,\"ば\":1940,\"ひ\":4249,\"び\":-4134,\"ふ\":1345,\"へ\":6665,\"べ\":-744,\"ほ\":1464,\"ま\":1051,\"み\":-2082,\"む\":-882,\"め\":-5046,\"も\":4169,\"ゃ\":-2666,\"や\":2795,\"ょ\":-1544,\"よ\":3351,\"ら\":-2922,\"り\":-9726,\"る\":-14896,\"れ\":-2613,\"ろ\":-4570,\"わ\":-1783,\"を\":13150,\"ん\":-2352,\"カ\":2145,\"コ\":1789,\"セ\":1287,\"ッ\":-724,\"ト\":-403,\"メ\":-1635,\"ラ\":-881,\"リ\":-541,\"ル\":-856,\"ン\":-3637,\"・\":-4371,\"ー\":-11870,\"一\":-2069,\"中\":2210,\"予\":782,\"事\":-190,\"井\":-1768,\"人\":1036,\"以\":544,\"会\":950,\"体\":-1286,\"作\":530,\"側\":4292,\"先\":601,\"党\":-2006,\"共\":-1212,\"内\":584,\"円\":788,\"初\":1347,\"前\":1623,\"副\":3879,\"力\":-302,\"動\":-740,\"務\":-2715,\"化\":776,\"区\":4517,\"協\":1013,\"参\":1555,\"合\":-1834,\"和\":-681,\"員\":-910,\"器\":-851,\"回\":1500,\"国\":-619,\"園\":-1200,\"地\":866,\"場\":-1410,\"塁\":-2094,\"士\":-1413,\"多\":1067,\"大\":571,\"子\":-4802,\"学\":-1397,\"定\":-1057,\"寺\":-809,\"小\":1910,\"屋\":-1328,\"山\":-1500,\"島\":-2056,\"川\":-2667,\"市\":2771,\"年\":374,\"庁\":-4556,\"後\":456,\"性\":553,\"感\":916,\"所\":-1566,\"支\":856,\"改\":787,\"政\":2182,\"教\":704,\"文\":522,\"方\":-856,\"日\":1798,\"時\":1829,\"最\":845,\"月\":-9066,\"木\":-485,\"来\":-442,\"校\":-360,\"業\":-1043,\"氏\":5388,\"民\":-2716,\"気\":-910,\"沢\":-939,\"済\":-543,\"物\":-735,\"率\":672,\"球\":-1267,\"生\":-1286,\"産\":-1101,\"田\":-2900,\"町\":1826,\"的\":2586,\"目\":922,\"省\":-3485,\"県\":2997,\"空\":-867,\"立\":-2112,\"第\":788,\"米\":2937,\"系\":786,\"約\":2171,\"経\":1146,\"統\":-1169,\"総\":940,\"線\":-994,\"署\":749,\"者\":2145,\"能\":-730,\"般\":-852,\"行\":-792,\"規\":792,\"警\":-1184,\"議\":-244,\"谷\":-1e3,\"賞\":730,\"車\":-1481,\"軍\":1158,\"輪\":-1433,\"込\":-3370,\"近\":929,\"道\":-1291,\"選\":2596,\"郎\":-4866,\"都\":1192,\"野\":-1100,\"銀\":-2213,\"長\":357,\"間\":-2344,\"院\":-2297,\"際\":-2604,\"電\":-878,\"領\":-1659,\"題\":-792,\"館\":-1984,\"首\":1749,\"高\":2120,\"｢\":1895,\"｣\":3798,\"･\":-4371,\"ｯ\":-724,\"ｰ\":-11870,\"ｶ\":2145,\"ｺ\":1789,\"ｾ\":1287,\"ﾄ\":-403,\"ﾒ\":-1635,\"ﾗ\":-881,\"ﾘ\":-541,\"ﾙ\":-856,\"ﾝ\":-3637},this.UW5__={\",\":465,\".\":-299,1:-514,E2:-32768,\"]\":-2762,\"、\":465,\"。\":-299,\"「\":363,\"あ\":1655,\"い\":331,\"う\":-503,\"え\":1199,\"お\":527,\"か\":647,\"が\":-421,\"き\":1624,\"ぎ\":1971,\"く\":312,\"げ\":-983,\"さ\":-1537,\"し\":-1371,\"す\":-852,\"だ\":-1186,\"ち\":1093,\"っ\":52,\"つ\":921,\"て\":-18,\"で\":-850,\"と\":-127,\"ど\":1682,\"な\":-787,\"に\":-1224,\"の\":-635,\"は\":-578,\"べ\":1001,\"み\":502,\"め\":865,\"ゃ\":3350,\"ょ\":854,\"り\":-208,\"る\":429,\"れ\":504,\"わ\":419,\"を\":-1264,\"ん\":327,\"イ\":241,\"ル\":451,\"ン\":-343,\"中\":-871,\"京\":722,\"会\":-1153,\"党\":-654,\"務\":3519,\"区\":-901,\"告\":848,\"員\":2104,\"大\":-1296,\"学\":-548,\"定\":1785,\"嵐\":-1304,\"市\":-2991,\"席\":921,\"年\":1763,\"思\":872,\"所\":-814,\"挙\":1618,\"新\":-1682,\"日\":218,\"月\":-4353,\"査\":932,\"格\":1356,\"機\":-1508,\"氏\":-1347,\"田\":240,\"町\":-3912,\"的\":-3149,\"相\":1319,\"省\":-1052,\"県\":-4003,\"研\":-997,\"社\":-278,\"空\":-813,\"統\":1955,\"者\":-2233,\"表\":663,\"語\":-1073,\"議\":1219,\"選\":-1018,\"郎\":-368,\"長\":786,\"間\":1191,\"題\":2368,\"館\":-689,\"１\":-514,\"Ｅ２\":-32768,\"｢\":363,\"ｲ\":241,\"ﾙ\":451,\"ﾝ\":-343},this.UW6__={\",\":227,\".\":808,1:-270,E1:306,\"、\":227,\"。\":808,\"あ\":-307,\"う\":189,\"か\":241,\"が\":-73,\"く\":-121,\"こ\":-200,\"じ\":1782,\"す\":383,\"た\":-428,\"っ\":573,\"て\":-1014,\"で\":101,\"と\":-105,\"な\":-253,\"に\":-149,\"の\":-417,\"は\":-236,\"も\":-206,\"り\":187,\"る\":-135,\"を\":195,\"ル\":-673,\"ン\":-496,\"一\":-277,\"中\":201,\"件\":-800,\"会\":624,\"前\":302,\"区\":1792,\"員\":-1212,\"委\":798,\"学\":-960,\"市\":887,\"広\":-695,\"後\":535,\"業\":-697,\"相\":753,\"社\":-507,\"福\":974,\"空\":-822,\"者\":1811,\"連\":463,\"郎\":1082,\"１\":-270,\"Ｅ１\":306,\"ﾙ\":-673,\"ﾝ\":-496},this}t.prototype.ctype_=function(_){for(var t in this.chartype_)if(_.match(this.chartype_[t][0]))return this.chartype_[t][1];return\"O\"},t.prototype.ts_=function(_){return _||0},t.prototype.segment=function(_){if(null==_||null==_||\"\"==_)return[];var t=[],H=[\"B3\",\"B2\",\"B1\"],s=[\"O\",\"O\",\"O\"],h=_.split(\"\");for(K=0;K<h.length;++K)H.push(h[K]),s.push(this.ctype_(h[K]));H.push(\"E1\"),H.push(\"E2\"),H.push(\"E3\"),s.push(\"O\"),s.push(\"O\"),s.push(\"O\");for(var i=H[3],I=\"U\",O=\"U\",B=\"U\",K=4;K<H.length-3;++K){var M=this.BIAS__,e=H[K-3],U=H[K-2],r=H[K-1],n=H[K],A=H[K+1],p=H[K+2],u=s[K-3],C=s[K-2],W=s[K-1],o=s[K],T=s[K+1],Q=s[K+2];M+=this.ts_(this.UP1__[I]),M+=this.ts_(this.UP2__[O]),M+=this.ts_(this.UP3__[B]),M+=this.ts_(this.BP1__[I+O]),M+=this.ts_(this.BP2__[O+B]),M+=this.ts_(this.UW1__[e]),M+=this.ts_(this.UW2__[U]),M+=this.ts_(this.UW3__[r]),M+=this.ts_(this.UW4__[n]),M+=this.ts_(this.UW5__[A]),M+=this.ts_(this.UW6__[p]),M+=this.ts_(this.BW1__[U+r]),M+=this.ts_(this.BW2__[r+n]),M+=this.ts_(this.BW3__[n+A]),M+=this.ts_(this.TW1__[e+U+r]),M+=this.ts_(this.TW2__[U+r+n]),M+=this.ts_(this.TW3__[r+n+A]),M+=this.ts_(this.TW4__[n+A+p]),M+=this.ts_(this.UC1__[u]),M+=this.ts_(this.UC2__[C]),M+=this.ts_(this.UC3__[W]),M+=this.ts_(this.UC4__[o]),M+=this.ts_(this.UC5__[T]),M+=this.ts_(this.UC6__[Q]),M+=this.ts_(this.BC1__[C+W]),M+=this.ts_(this.BC2__[W+o]),M+=this.ts_(this.BC3__[o+T]),M+=this.ts_(this.TC1__[u+C+W]),M+=this.ts_(this.TC2__[C+W+o]),M+=this.ts_(this.TC3__[W+o+T]),M+=this.ts_(this.TC4__[o+T+Q]),M+=this.ts_(this.UQ1__[I+u]),M+=this.ts_(this.UQ2__[O+C]),M+=this.ts_(this.UQ3__[B+W]),M+=this.ts_(this.BQ1__[O+C+W]),M+=this.ts_(this.BQ2__[O+W+o]),M+=this.ts_(this.BQ3__[B+C+W]),M+=this.ts_(this.BQ4__[B+W+o]),M+=this.ts_(this.TQ1__[O+u+C+W]),M+=this.ts_(this.TQ2__[O+C+W+o]),M+=this.ts_(this.TQ3__[B+u+C+W]);var N=\"O\";0<(M+=this.ts_(this.TQ4__[B+C+W+o]))&&(t.push(i),i=\"\",N=\"B\"),I=O,O=B,B=N,i+=H[K]}return t.push(i),t},_.TinySegmenter=t}});"
  },
  {
    "path": "SecurityPaper-themes/assets/javascripts/modernizr.js",
    "content": "(function(e, a) { for(var i in a) e[i] = a[i]; }(window, /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 4);\n/******/ })\n/************************************************************************/\n/******/ ({\n\n/***/ 4:\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n__webpack_require__(5);\n\n/***/ }),\n\n/***/ 5:\n/***/ (function(module, exports) {\n\n;(function(window){\n/*! modernizr 3.6.0 (Custom Build) | MIT *\n * https://modernizr.com/download/?-checked-csstransforms3d-dataset-details-fetch-json-svg-target-addtest-setclasses !*/\n!function(e,t,n){function r(e,t){return typeof e===t}function o(){var e,t,n,o,i,s,a;for(var l in C)if(C.hasOwnProperty(l)){if(e=[],t=C[l],t.name&&(e.push(t.name.toLowerCase()),t.options&&t.options.aliases&&t.options.aliases.length))for(n=0;n<t.options.aliases.length;n++)e.push(t.options.aliases[n].toLowerCase());for(o=r(t.fn,\"function\")?t.fn():t.fn,i=0;i<e.length;i++)s=e[i],a=s.split(\".\"),1===a.length?Modernizr[a[0]]=o:(!Modernizr[a[0]]||Modernizr[a[0]]instanceof Boolean||(Modernizr[a[0]]=new Boolean(Modernizr[a[0]])),Modernizr[a[0]][a[1]]=o),b.push((o?\"\":\"no-\")+a.join(\"-\"))}}function i(e){var t=T.className,n=Modernizr._config.classPrefix||\"\";if(x&&(t=t.baseVal),Modernizr._config.enableJSClass){var r=new RegExp(\"(^|\\\\s)\"+n+\"no-js(\\\\s|$)\");t=t.replace(r,\"$1\"+n+\"js$2\")}Modernizr._config.enableClasses&&(t+=\" \"+n+e.join(\" \"+n),x?T.className.baseVal=t:T.className=t)}function s(e,t){if(\"object\"==typeof e)for(var n in e)w(e,n)&&s(n,e[n]);else{e=e.toLowerCase();var r=e.split(\".\"),o=Modernizr[r[0]];if(2==r.length&&(o=o[r[1]]),\"undefined\"!=typeof o)return Modernizr;t=\"function\"==typeof t?t():t,1==r.length?Modernizr[r[0]]=t:(!Modernizr[r[0]]||Modernizr[r[0]]instanceof Boolean||(Modernizr[r[0]]=new Boolean(Modernizr[r[0]])),Modernizr[r[0]][r[1]]=t),i([(t&&0!=t?\"\":\"no-\")+r.join(\"-\")]),Modernizr._trigger(e,t)}return Modernizr}function a(){return\"function\"!=typeof t.createElement?t.createElement(arguments[0]):x?t.createElementNS.call(t,\"http://www.w3.org/2000/svg\",arguments[0]):t.createElement.apply(t,arguments)}function l(){var e=t.body;return e||(e=a(x?\"svg\":\"body\"),e.fake=!0),e}function u(e,n,r,o){var i,s,u,f,c=\"modernizr\",d=a(\"div\"),p=l();if(parseInt(r,10))for(;r--;)u=a(\"div\"),u.id=o?o[r]:c+(r+1),d.appendChild(u);return i=a(\"style\"),i.type=\"text/css\",i.id=\"s\"+c,(p.fake?p:d).appendChild(i),p.appendChild(d),i.styleSheet?i.styleSheet.cssText=e:i.appendChild(t.createTextNode(e)),d.id=c,p.fake&&(p.style.background=\"\",p.style.overflow=\"hidden\",f=T.style.overflow,T.style.overflow=\"hidden\",T.appendChild(p)),s=n(d,e),p.fake?(p.parentNode.removeChild(p),T.style.overflow=f,T.offsetHeight):d.parentNode.removeChild(d),!!s}function f(e,t){return!!~(\"\"+e).indexOf(t)}function c(e){return e.replace(/([A-Z])/g,function(e,t){return\"-\"+t.toLowerCase()}).replace(/^ms-/,\"-ms-\")}function d(t,n,r){var o;if(\"getComputedStyle\"in e){o=getComputedStyle.call(e,t,n);var i=e.console;if(null!==o)r&&(o=o.getPropertyValue(r));else if(i){var s=i.error?\"error\":\"log\";i[s].call(i,\"getComputedStyle returning null, its possible modernizr test results are inaccurate\")}}else o=!n&&t.currentStyle&&t.currentStyle[r];return o}function p(t,r){var o=t.length;if(\"CSS\"in e&&\"supports\"in e.CSS){for(;o--;)if(e.CSS.supports(c(t[o]),r))return!0;return!1}if(\"CSSSupportsRule\"in e){for(var i=[];o--;)i.push(\"(\"+c(t[o])+\":\"+r+\")\");return i=i.join(\" or \"),u(\"@supports (\"+i+\") { #modernizr { position: absolute; } }\",function(e){return\"absolute\"==d(e,null,\"position\")})}return n}function m(e){return e.replace(/([a-z])-([a-z])/g,function(e,t,n){return t+n.toUpperCase()}).replace(/^-/,\"\")}function h(e,t,o,i){function s(){u&&(delete E.style,delete E.modElem)}if(i=r(i,\"undefined\")?!1:i,!r(o,\"undefined\")){var l=p(e,o);if(!r(l,\"undefined\"))return l}for(var u,c,d,h,g,y=[\"modernizr\",\"tspan\",\"samp\"];!E.style&&y.length;)u=!0,E.modElem=a(y.shift()),E.style=E.modElem.style;for(d=e.length,c=0;d>c;c++)if(h=e[c],g=E.style[h],f(h,\"-\")&&(h=m(h)),E.style[h]!==n){if(i||r(o,\"undefined\"))return s(),\"pfx\"==t?h:!0;try{E.style[h]=o}catch(v){}if(E.style[h]!=g)return s(),\"pfx\"==t?h:!0}return s(),!1}function g(e,t){return function(){return e.apply(t,arguments)}}function y(e,t,n){var o;for(var i in e)if(e[i]in t)return n===!1?e[i]:(o=t[e[i]],r(o,\"function\")?g(o,n||t):o);return!1}function v(e,t,n,o,i){var s=e.charAt(0).toUpperCase()+e.slice(1),a=(e+\" \"+k.join(s+\" \")+s).split(\" \");return r(t,\"string\")||r(t,\"undefined\")?h(a,t,o,i):(a=(e+\" \"+A.join(s+\" \")+s).split(\" \"),y(a,t,n))}function S(e,t,r){return v(e,n,n,t,r)}var C=[],_={_version:\"3.6.0\",_config:{classPrefix:\"\",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,t){var n=this;setTimeout(function(){t(n[e])},0)},addTest:function(e,t,n){C.push({name:e,fn:t,options:n})},addAsyncTest:function(e){C.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=_,Modernizr=new Modernizr;var w,b=[],T=t.documentElement,x=\"svg\"===T.nodeName.toLowerCase();!function(){var e={}.hasOwnProperty;w=r(e,\"undefined\")||r(e.call,\"undefined\")?function(e,t){return t in e&&r(e.constructor.prototype[t],\"undefined\")}:function(t,n){return e.call(t,n)}}(),_._l={},_.on=function(e,t){this._l[e]||(this._l[e]=[]),this._l[e].push(t),Modernizr.hasOwnProperty(e)&&setTimeout(function(){Modernizr._trigger(e,Modernizr[e])},0)},_._trigger=function(e,t){if(this._l[e]){var n=this._l[e];setTimeout(function(){var e,r;for(e=0;e<n.length;e++)(r=n[e])(t)},0),delete this._l[e]}},Modernizr._q.push(function(){_.addTest=s}),Modernizr.addTest(\"json\",\"JSON\"in e&&\"parse\"in JSON&&\"stringify\"in JSON),Modernizr.addTest(\"svg\",!!t.createElementNS&&!!t.createElementNS(\"http://www.w3.org/2000/svg\",\"svg\").createSVGRect);var z=_.testStyles=u;Modernizr.addTest(\"checked\",function(){return z(\"#modernizr {position:absolute} #modernizr input {margin-left:10px} #modernizr :checked {margin-left:20px;display:block}\",function(e){var t=a(\"input\");return t.setAttribute(\"type\",\"checkbox\"),t.setAttribute(\"checked\",\"checked\"),e.appendChild(t),20===t.offsetLeft})}),Modernizr.addTest(\"target\",function(){var t=e.document;if(!(\"querySelectorAll\"in t))return!1;try{return t.querySelectorAll(\":target\"),!0}catch(n){return!1}}),Modernizr.addTest(\"dataset\",function(){var e=a(\"div\");return e.setAttribute(\"data-a-b\",\"c\"),!(!e.dataset||\"c\"!==e.dataset.aB)}),Modernizr.addTest(\"details\",function(){var e,t=a(\"details\");return\"open\"in t?(z(\"#modernizr details{display:block}\",function(n){n.appendChild(t),t.innerHTML=\"<summary>a</summary>b\",e=t.offsetHeight,t.open=!0,e=e!=t.offsetHeight}),e):!1}),Modernizr.addTest(\"fetch\",\"fetch\"in e);var N=\"Moz O ms Webkit\",k=_._config.usePrefixes?N.split(\" \"):[];_._cssomPrefixes=k;var P={elem:a(\"modernizr\")};Modernizr._q.push(function(){delete P.elem});var E={style:P.elem.style};Modernizr._q.unshift(function(){delete E.style});var A=_._config.usePrefixes?N.toLowerCase().split(\" \"):[];_._domPrefixes=A,_.testAllProps=v,_.testAllProps=S;var j=\"CSS\"in e&&\"supports\"in e.CSS,O=\"supportsCSS\"in e;Modernizr.addTest(\"supports\",j||O),Modernizr.addTest(\"csstransforms3d\",function(){return!!S(\"perspective\",\"1px\",!0)}),o(),i(b),delete _.addTest,delete _.addAsyncTest;for(var q=0;q<Modernizr._q.length;q++)Modernizr._q[q]();e.Modernizr=Modernizr}(window,document);\nmodule.exports = window.Modernizr;\n})(window);\n\n/***/ })\n\n/******/ })));\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgOTkzNzc5YzciLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9qYXZhc2NyaXB0cy9tb2Rlcm5penIuanMiLCJ3ZWJwYWNrOi8vLy4vLm1vZGVybml6ci1hdXRvcmMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBMkIsMEJBQTBCLEVBQUU7QUFDdkQseUNBQWlDLGVBQWU7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOERBQXNELCtEQUErRDs7QUFFckg7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7Ozs7OztBQ3ZDQSx1Qjs7Ozs7OztBQ3RCQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBLGlCQUFpQixnQkFBZ0Isb0JBQW9CLGFBQWEsa0JBQWtCLHVDQUF1QyxxSEFBcUgsMkJBQTJCLCtDQUErQyx5Q0FBeUMsV0FBVyx5TkFBeU4sY0FBYyxzREFBc0QscURBQXFELDZDQUE2Qyw2QkFBNkIsZ0dBQWdHLGdCQUFnQix1REFBdUQsS0FBSyxrQkFBa0IscUNBQXFDLG1FQUFtRSxxUEFBcVAsaUJBQWlCLGFBQWEsZ0xBQWdMLGFBQWEsYUFBYSw0Q0FBNEMsb0JBQW9CLDJDQUEyQyx1QkFBdUIsSUFBSSxpREFBaUQsb1pBQW9aLGdCQUFnQiwyQkFBMkIsY0FBYywwQ0FBMEMsMEJBQTBCLHlCQUF5QixrQkFBa0IsTUFBTSwyQkFBMkIsK0JBQStCLGdCQUFnQix5Q0FBeUMsV0FBVyw0QkFBNEIsb0dBQW9HLDZDQUE2QyxTQUFTLGdCQUFnQixlQUFlLGtDQUFrQyxLQUFLLElBQUksdUNBQXVDLFNBQVMsMEJBQTBCLGFBQWEsSUFBSSwrQkFBK0IsOENBQThDLGFBQWEsb0JBQW9CLEVBQUUsRUFBRSxjQUFjLHVDQUF1QyxFQUFFLFNBQVMsY0FBYyxvREFBb0QseUJBQXlCLG1CQUFtQixvQkFBb0IsYUFBYSxxQ0FBcUMsOENBQThDLGFBQWEsOEJBQThCLGlEQUFpRCxtQkFBbUIscURBQXFELG1CQUFtQixJQUFJLDhEQUE4RCxnREFBZ0QsSUFBSSxhQUFhLFVBQVUsMENBQTBDLGNBQWMsZ0JBQWdCLGtCQUFrQiw2QkFBNkIsa0JBQWtCLE1BQU0sc0ZBQXNGLFNBQVMsc0JBQXNCLGdGQUFnRixrR0FBa0csa0JBQWtCLG9CQUFvQixZQUFZLDBCQUEwQixnRUFBZ0Usd0JBQXdCLFdBQVcsc0JBQXNCLFFBQVEsSUFBSSx5QkFBeUIsUUFBUSxzQkFBc0IsRUFBRSwwQkFBMEIsUUFBUSxlQUFlLEdBQUcsd0JBQXdCLDhDQUE4QyxrRUFBa0UsWUFBWSxRQUFRLGdCQUFnQix3REFBd0QseURBQXlELGVBQWUsb0JBQW9CLFVBQVUsb0JBQW9CLGtHQUFrRyxtQ0FBbUMsSUFBSSwwQkFBMEIsZUFBZSxpQkFBaUIsc0JBQXNCLFFBQVEsUUFBUSxXQUFXLGdCQUFnQix1QkFBdUIsOEJBQThCLFlBQVksK0xBQStMLHFCQUFxQix1Q0FBdUMsc0JBQXNCLGtCQUFrQixtQkFBbUIsaUJBQWlCLHNCQUFzQixpQkFBaUIsY0FBYyxjQUFjLGlCQUFpQixnSEFBZ0gsRUFBRSx3Q0FBd0MsaUJBQWlCLHNDQUFzQyxJQUFJLHdDQUF3QyxTQUFTLFVBQVUseUNBQXlDLGVBQWUsd0VBQXdFLHlDQUF5QyxxQkFBcUIsd0NBQXdDLGNBQWMsY0FBYyxvR0FBb0csUUFBUSx5Q0FBeUMsZ0VBQWdFLG1CQUFtQixPQUFPLHFCQUFxQiw2QkFBNkIsY0FBYyxFQUFFLE9BQU8sb0JBQW9CLGdDQUFnQyxlQUFlLEVBQUUsMERBQTBELG1EQUFtRCx3REFBd0Qsa0ZBQWtGLGtDQUFrQyxrREFBa0QsWUFBWSxzQkFBc0Isc0JBQXNCLHNCQUFzQjtBQUNqaE47QUFDQSxDQUFDLFUiLCJmaWxlIjoiYXNzZXRzL2phdmFzY3JpcHRzL21vZGVybml6ci5qcyIsInNvdXJjZXNDb250ZW50IjpbIiBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbiBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XG5cbiBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbiBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKSB7XG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG4gXHRcdH1cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGk6IG1vZHVsZUlkLFxuIFx0XHRcdGw6IGZhbHNlLFxuIFx0XHRcdGV4cG9ydHM6IHt9XG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuXG4gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbiBcdH1cblxuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbiBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cbiBcdC8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIGhhcm1vbnkgZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4gXHRcdGlmKCFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywgbmFtZSkpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgbmFtZSwge1xuIFx0XHRcdFx0Y29uZmlndXJhYmxlOiBmYWxzZSxcbiBcdFx0XHRcdGVudW1lcmFibGU6IHRydWUsXG4gXHRcdFx0XHRnZXQ6IGdldHRlclxuIFx0XHRcdH0pO1xuIFx0XHR9XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG4gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbiBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IDQpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIHdlYnBhY2svYm9vdHN0cmFwIDk5Mzc3OWM3IiwiLypcbiAqIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuICogZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbiAqIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuICogc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbiAqIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1NcbiAqIElOIFRIRSBTT0ZUV0FSRS5cbiAqL1xuXG5pbXBvcnQgXCIuLi8uLi8uLi8ubW9kZXJuaXpyLWF1dG9yY1wiXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL2phdmFzY3JpcHRzL21vZGVybml6ci5qcyIsIjsoZnVuY3Rpb24od2luZG93KXtcbi8qISBtb2Rlcm5penIgMy42LjAgKEN1c3RvbSBCdWlsZCkgfCBNSVQgKlxuICogaHR0cHM6Ly9tb2Rlcm5penIuY29tL2Rvd25sb2FkLz8tY2hlY2tlZC1jc3N0cmFuc2Zvcm1zM2QtZGF0YXNldC1kZXRhaWxzLWZldGNoLWpzb24tc3ZnLXRhcmdldC1hZGR0ZXN0LXNldGNsYXNzZXMgISovXG4hZnVuY3Rpb24oZSx0LG4pe2Z1bmN0aW9uIHIoZSx0KXtyZXR1cm4gdHlwZW9mIGU9PT10fWZ1bmN0aW9uIG8oKXt2YXIgZSx0LG4sbyxpLHMsYTtmb3IodmFyIGwgaW4gQylpZihDLmhhc093blByb3BlcnR5KGwpKXtpZihlPVtdLHQ9Q1tsXSx0Lm5hbWUmJihlLnB1c2godC5uYW1lLnRvTG93ZXJDYXNlKCkpLHQub3B0aW9ucyYmdC5vcHRpb25zLmFsaWFzZXMmJnQub3B0aW9ucy5hbGlhc2VzLmxlbmd0aCkpZm9yKG49MDtuPHQub3B0aW9ucy5hbGlhc2VzLmxlbmd0aDtuKyspZS5wdXNoKHQub3B0aW9ucy5hbGlhc2VzW25dLnRvTG93ZXJDYXNlKCkpO2ZvcihvPXIodC5mbixcImZ1bmN0aW9uXCIpP3QuZm4oKTp0LmZuLGk9MDtpPGUubGVuZ3RoO2krKylzPWVbaV0sYT1zLnNwbGl0KFwiLlwiKSwxPT09YS5sZW5ndGg/TW9kZXJuaXpyW2FbMF1dPW86KCFNb2Rlcm5penJbYVswXV18fE1vZGVybml6clthWzBdXWluc3RhbmNlb2YgQm9vbGVhbnx8KE1vZGVybml6clthWzBdXT1uZXcgQm9vbGVhbihNb2Rlcm5penJbYVswXV0pKSxNb2Rlcm5penJbYVswXV1bYVsxXV09byksYi5wdXNoKChvP1wiXCI6XCJuby1cIikrYS5qb2luKFwiLVwiKSl9fWZ1bmN0aW9uIGkoZSl7dmFyIHQ9VC5jbGFzc05hbWUsbj1Nb2Rlcm5penIuX2NvbmZpZy5jbGFzc1ByZWZpeHx8XCJcIjtpZih4JiYodD10LmJhc2VWYWwpLE1vZGVybml6ci5fY29uZmlnLmVuYWJsZUpTQ2xhc3Mpe3ZhciByPW5ldyBSZWdFeHAoXCIoXnxcXFxccylcIituK1wibm8tanMoXFxcXHN8JClcIik7dD10LnJlcGxhY2UocixcIiQxXCIrbitcImpzJDJcIil9TW9kZXJuaXpyLl9jb25maWcuZW5hYmxlQ2xhc3NlcyYmKHQrPVwiIFwiK24rZS5qb2luKFwiIFwiK24pLHg/VC5jbGFzc05hbWUuYmFzZVZhbD10OlQuY2xhc3NOYW1lPXQpfWZ1bmN0aW9uIHMoZSx0KXtpZihcIm9iamVjdFwiPT10eXBlb2YgZSlmb3IodmFyIG4gaW4gZSl3KGUsbikmJnMobixlW25dKTtlbHNle2U9ZS50b0xvd2VyQ2FzZSgpO3ZhciByPWUuc3BsaXQoXCIuXCIpLG89TW9kZXJuaXpyW3JbMF1dO2lmKDI9PXIubGVuZ3RoJiYobz1vW3JbMV1dKSxcInVuZGVmaW5lZFwiIT10eXBlb2YgbylyZXR1cm4gTW9kZXJuaXpyO3Q9XCJmdW5jdGlvblwiPT10eXBlb2YgdD90KCk6dCwxPT1yLmxlbmd0aD9Nb2Rlcm5penJbclswXV09dDooIU1vZGVybml6cltyWzBdXXx8TW9kZXJuaXpyW3JbMF1daW5zdGFuY2VvZiBCb29sZWFufHwoTW9kZXJuaXpyW3JbMF1dPW5ldyBCb29sZWFuKE1vZGVybml6cltyWzBdXSkpLE1vZGVybml6cltyWzBdXVtyWzFdXT10KSxpKFsodCYmMCE9dD9cIlwiOlwibm8tXCIpK3Iuam9pbihcIi1cIildKSxNb2Rlcm5penIuX3RyaWdnZXIoZSx0KX1yZXR1cm4gTW9kZXJuaXpyfWZ1bmN0aW9uIGEoKXtyZXR1cm5cImZ1bmN0aW9uXCIhPXR5cGVvZiB0LmNyZWF0ZUVsZW1lbnQ/dC5jcmVhdGVFbGVtZW50KGFyZ3VtZW50c1swXSk6eD90LmNyZWF0ZUVsZW1lbnROUy5jYWxsKHQsXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLGFyZ3VtZW50c1swXSk6dC5jcmVhdGVFbGVtZW50LmFwcGx5KHQsYXJndW1lbnRzKX1mdW5jdGlvbiBsKCl7dmFyIGU9dC5ib2R5O3JldHVybiBlfHwoZT1hKHg/XCJzdmdcIjpcImJvZHlcIiksZS5mYWtlPSEwKSxlfWZ1bmN0aW9uIHUoZSxuLHIsbyl7dmFyIGkscyx1LGYsYz1cIm1vZGVybml6clwiLGQ9YShcImRpdlwiKSxwPWwoKTtpZihwYXJzZUludChyLDEwKSlmb3IoO3ItLTspdT1hKFwiZGl2XCIpLHUuaWQ9bz9vW3JdOmMrKHIrMSksZC5hcHBlbmRDaGlsZCh1KTtyZXR1cm4gaT1hKFwic3R5bGVcIiksaS50eXBlPVwidGV4dC9jc3NcIixpLmlkPVwic1wiK2MsKHAuZmFrZT9wOmQpLmFwcGVuZENoaWxkKGkpLHAuYXBwZW5kQ2hpbGQoZCksaS5zdHlsZVNoZWV0P2kuc3R5bGVTaGVldC5jc3NUZXh0PWU6aS5hcHBlbmRDaGlsZCh0LmNyZWF0ZVRleHROb2RlKGUpKSxkLmlkPWMscC5mYWtlJiYocC5zdHlsZS5iYWNrZ3JvdW5kPVwiXCIscC5zdHlsZS5vdmVyZmxvdz1cImhpZGRlblwiLGY9VC5zdHlsZS5vdmVyZmxvdyxULnN0eWxlLm92ZXJmbG93PVwiaGlkZGVuXCIsVC5hcHBlbmRDaGlsZChwKSkscz1uKGQsZSkscC5mYWtlPyhwLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQocCksVC5zdHlsZS5vdmVyZmxvdz1mLFQub2Zmc2V0SGVpZ2h0KTpkLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZCksISFzfWZ1bmN0aW9uIGYoZSx0KXtyZXR1cm4hIX4oXCJcIitlKS5pbmRleE9mKHQpfWZ1bmN0aW9uIGMoZSl7cmV0dXJuIGUucmVwbGFjZSgvKFtBLVpdKS9nLGZ1bmN0aW9uKGUsdCl7cmV0dXJuXCItXCIrdC50b0xvd2VyQ2FzZSgpfSkucmVwbGFjZSgvXm1zLS8sXCItbXMtXCIpfWZ1bmN0aW9uIGQodCxuLHIpe3ZhciBvO2lmKFwiZ2V0Q29tcHV0ZWRTdHlsZVwiaW4gZSl7bz1nZXRDb21wdXRlZFN0eWxlLmNhbGwoZSx0LG4pO3ZhciBpPWUuY29uc29sZTtpZihudWxsIT09bylyJiYobz1vLmdldFByb3BlcnR5VmFsdWUocikpO2Vsc2UgaWYoaSl7dmFyIHM9aS5lcnJvcj9cImVycm9yXCI6XCJsb2dcIjtpW3NdLmNhbGwoaSxcImdldENvbXB1dGVkU3R5bGUgcmV0dXJuaW5nIG51bGwsIGl0cyBwb3NzaWJsZSBtb2Rlcm5penIgdGVzdCByZXN1bHRzIGFyZSBpbmFjY3VyYXRlXCIpfX1lbHNlIG89IW4mJnQuY3VycmVudFN0eWxlJiZ0LmN1cnJlbnRTdHlsZVtyXTtyZXR1cm4gb31mdW5jdGlvbiBwKHQscil7dmFyIG89dC5sZW5ndGg7aWYoXCJDU1NcImluIGUmJlwic3VwcG9ydHNcImluIGUuQ1NTKXtmb3IoO28tLTspaWYoZS5DU1Muc3VwcG9ydHMoYyh0W29dKSxyKSlyZXR1cm4hMDtyZXR1cm4hMX1pZihcIkNTU1N1cHBvcnRzUnVsZVwiaW4gZSl7Zm9yKHZhciBpPVtdO28tLTspaS5wdXNoKFwiKFwiK2ModFtvXSkrXCI6XCIrcitcIilcIik7cmV0dXJuIGk9aS5qb2luKFwiIG9yIFwiKSx1KFwiQHN1cHBvcnRzIChcIitpK1wiKSB7ICNtb2Rlcm5penIgeyBwb3NpdGlvbjogYWJzb2x1dGU7IH0gfVwiLGZ1bmN0aW9uKGUpe3JldHVyblwiYWJzb2x1dGVcIj09ZChlLG51bGwsXCJwb3NpdGlvblwiKX0pfXJldHVybiBufWZ1bmN0aW9uIG0oZSl7cmV0dXJuIGUucmVwbGFjZSgvKFthLXpdKS0oW2Etel0pL2csZnVuY3Rpb24oZSx0LG4pe3JldHVybiB0K24udG9VcHBlckNhc2UoKX0pLnJlcGxhY2UoL14tLyxcIlwiKX1mdW5jdGlvbiBoKGUsdCxvLGkpe2Z1bmN0aW9uIHMoKXt1JiYoZGVsZXRlIEUuc3R5bGUsZGVsZXRlIEUubW9kRWxlbSl9aWYoaT1yKGksXCJ1bmRlZmluZWRcIik/ITE6aSwhcihvLFwidW5kZWZpbmVkXCIpKXt2YXIgbD1wKGUsbyk7aWYoIXIobCxcInVuZGVmaW5lZFwiKSlyZXR1cm4gbH1mb3IodmFyIHUsYyxkLGgsZyx5PVtcIm1vZGVybml6clwiLFwidHNwYW5cIixcInNhbXBcIl07IUUuc3R5bGUmJnkubGVuZ3RoOyl1PSEwLEUubW9kRWxlbT1hKHkuc2hpZnQoKSksRS5zdHlsZT1FLm1vZEVsZW0uc3R5bGU7Zm9yKGQ9ZS5sZW5ndGgsYz0wO2Q+YztjKyspaWYoaD1lW2NdLGc9RS5zdHlsZVtoXSxmKGgsXCItXCIpJiYoaD1tKGgpKSxFLnN0eWxlW2hdIT09bil7aWYoaXx8cihvLFwidW5kZWZpbmVkXCIpKXJldHVybiBzKCksXCJwZnhcIj09dD9oOiEwO3RyeXtFLnN0eWxlW2hdPW99Y2F0Y2godil7fWlmKEUuc3R5bGVbaF0hPWcpcmV0dXJuIHMoKSxcInBmeFwiPT10P2g6ITB9cmV0dXJuIHMoKSwhMX1mdW5jdGlvbiBnKGUsdCl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGUuYXBwbHkodCxhcmd1bWVudHMpfX1mdW5jdGlvbiB5KGUsdCxuKXt2YXIgbztmb3IodmFyIGkgaW4gZSlpZihlW2ldaW4gdClyZXR1cm4gbj09PSExP2VbaV06KG89dFtlW2ldXSxyKG8sXCJmdW5jdGlvblwiKT9nKG8sbnx8dCk6byk7cmV0dXJuITF9ZnVuY3Rpb24gdihlLHQsbixvLGkpe3ZhciBzPWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkrZS5zbGljZSgxKSxhPShlK1wiIFwiK2suam9pbihzK1wiIFwiKStzKS5zcGxpdChcIiBcIik7cmV0dXJuIHIodCxcInN0cmluZ1wiKXx8cih0LFwidW5kZWZpbmVkXCIpP2goYSx0LG8saSk6KGE9KGUrXCIgXCIrQS5qb2luKHMrXCIgXCIpK3MpLnNwbGl0KFwiIFwiKSx5KGEsdCxuKSl9ZnVuY3Rpb24gUyhlLHQscil7cmV0dXJuIHYoZSxuLG4sdCxyKX12YXIgQz1bXSxfPXtfdmVyc2lvbjpcIjMuNi4wXCIsX2NvbmZpZzp7Y2xhc3NQcmVmaXg6XCJcIixlbmFibGVDbGFzc2VzOiEwLGVuYWJsZUpTQ2xhc3M6ITAsdXNlUHJlZml4ZXM6ITB9LF9xOltdLG9uOmZ1bmN0aW9uKGUsdCl7dmFyIG49dGhpcztzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dChuW2VdKX0sMCl9LGFkZFRlc3Q6ZnVuY3Rpb24oZSx0LG4pe0MucHVzaCh7bmFtZTplLGZuOnQsb3B0aW9uczpufSl9LGFkZEFzeW5jVGVzdDpmdW5jdGlvbihlKXtDLnB1c2goe25hbWU6bnVsbCxmbjplfSl9fSxNb2Rlcm5penI9ZnVuY3Rpb24oKXt9O01vZGVybml6ci5wcm90b3R5cGU9XyxNb2Rlcm5penI9bmV3IE1vZGVybml6cjt2YXIgdyxiPVtdLFQ9dC5kb2N1bWVudEVsZW1lbnQseD1cInN2Z1wiPT09VC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpOyFmdW5jdGlvbigpe3ZhciBlPXt9Lmhhc093blByb3BlcnR5O3c9cihlLFwidW5kZWZpbmVkXCIpfHxyKGUuY2FsbCxcInVuZGVmaW5lZFwiKT9mdW5jdGlvbihlLHQpe3JldHVybiB0IGluIGUmJnIoZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGVbdF0sXCJ1bmRlZmluZWRcIil9OmZ1bmN0aW9uKHQsbil7cmV0dXJuIGUuY2FsbCh0LG4pfX0oKSxfLl9sPXt9LF8ub249ZnVuY3Rpb24oZSx0KXt0aGlzLl9sW2VdfHwodGhpcy5fbFtlXT1bXSksdGhpcy5fbFtlXS5wdXNoKHQpLE1vZGVybml6ci5oYXNPd25Qcm9wZXJ0eShlKSYmc2V0VGltZW91dChmdW5jdGlvbigpe01vZGVybml6ci5fdHJpZ2dlcihlLE1vZGVybml6cltlXSl9LDApfSxfLl90cmlnZ2VyPWZ1bmN0aW9uKGUsdCl7aWYodGhpcy5fbFtlXSl7dmFyIG49dGhpcy5fbFtlXTtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dmFyIGUscjtmb3IoZT0wO2U8bi5sZW5ndGg7ZSsrKShyPW5bZV0pKHQpfSwwKSxkZWxldGUgdGhpcy5fbFtlXX19LE1vZGVybml6ci5fcS5wdXNoKGZ1bmN0aW9uKCl7Xy5hZGRUZXN0PXN9KSxNb2Rlcm5penIuYWRkVGVzdChcImpzb25cIixcIkpTT05cImluIGUmJlwicGFyc2VcImluIEpTT04mJlwic3RyaW5naWZ5XCJpbiBKU09OKSxNb2Rlcm5penIuYWRkVGVzdChcInN2Z1wiLCEhdC5jcmVhdGVFbGVtZW50TlMmJiEhdC5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLFwic3ZnXCIpLmNyZWF0ZVNWR1JlY3QpO3ZhciB6PV8udGVzdFN0eWxlcz11O01vZGVybml6ci5hZGRUZXN0KFwiY2hlY2tlZFwiLGZ1bmN0aW9uKCl7cmV0dXJuIHooXCIjbW9kZXJuaXpyIHtwb3NpdGlvbjphYnNvbHV0ZX0gI21vZGVybml6ciBpbnB1dCB7bWFyZ2luLWxlZnQ6MTBweH0gI21vZGVybml6ciA6Y2hlY2tlZCB7bWFyZ2luLWxlZnQ6MjBweDtkaXNwbGF5OmJsb2NrfVwiLGZ1bmN0aW9uKGUpe3ZhciB0PWEoXCJpbnB1dFwiKTtyZXR1cm4gdC5zZXRBdHRyaWJ1dGUoXCJ0eXBlXCIsXCJjaGVja2JveFwiKSx0LnNldEF0dHJpYnV0ZShcImNoZWNrZWRcIixcImNoZWNrZWRcIiksZS5hcHBlbmRDaGlsZCh0KSwyMD09PXQub2Zmc2V0TGVmdH0pfSksTW9kZXJuaXpyLmFkZFRlc3QoXCJ0YXJnZXRcIixmdW5jdGlvbigpe3ZhciB0PWUuZG9jdW1lbnQ7aWYoIShcInF1ZXJ5U2VsZWN0b3JBbGxcImluIHQpKXJldHVybiExO3RyeXtyZXR1cm4gdC5xdWVyeVNlbGVjdG9yQWxsKFwiOnRhcmdldFwiKSwhMH1jYXRjaChuKXtyZXR1cm4hMX19KSxNb2Rlcm5penIuYWRkVGVzdChcImRhdGFzZXRcIixmdW5jdGlvbigpe3ZhciBlPWEoXCJkaXZcIik7cmV0dXJuIGUuc2V0QXR0cmlidXRlKFwiZGF0YS1hLWJcIixcImNcIiksISghZS5kYXRhc2V0fHxcImNcIiE9PWUuZGF0YXNldC5hQil9KSxNb2Rlcm5penIuYWRkVGVzdChcImRldGFpbHNcIixmdW5jdGlvbigpe3ZhciBlLHQ9YShcImRldGFpbHNcIik7cmV0dXJuXCJvcGVuXCJpbiB0Pyh6KFwiI21vZGVybml6ciBkZXRhaWxze2Rpc3BsYXk6YmxvY2t9XCIsZnVuY3Rpb24obil7bi5hcHBlbmRDaGlsZCh0KSx0LmlubmVySFRNTD1cIjxzdW1tYXJ5PmE8L3N1bW1hcnk+YlwiLGU9dC5vZmZzZXRIZWlnaHQsdC5vcGVuPSEwLGU9ZSE9dC5vZmZzZXRIZWlnaHR9KSxlKTohMX0pLE1vZGVybml6ci5hZGRUZXN0KFwiZmV0Y2hcIixcImZldGNoXCJpbiBlKTt2YXIgTj1cIk1veiBPIG1zIFdlYmtpdFwiLGs9Xy5fY29uZmlnLnVzZVByZWZpeGVzP04uc3BsaXQoXCIgXCIpOltdO18uX2Nzc29tUHJlZml4ZXM9azt2YXIgUD17ZWxlbTphKFwibW9kZXJuaXpyXCIpfTtNb2Rlcm5penIuX3EucHVzaChmdW5jdGlvbigpe2RlbGV0ZSBQLmVsZW19KTt2YXIgRT17c3R5bGU6UC5lbGVtLnN0eWxlfTtNb2Rlcm5penIuX3EudW5zaGlmdChmdW5jdGlvbigpe2RlbGV0ZSBFLnN0eWxlfSk7dmFyIEE9Xy5fY29uZmlnLnVzZVByZWZpeGVzP04udG9Mb3dlckNhc2UoKS5zcGxpdChcIiBcIik6W107Xy5fZG9tUHJlZml4ZXM9QSxfLnRlc3RBbGxQcm9wcz12LF8udGVzdEFsbFByb3BzPVM7dmFyIGo9XCJDU1NcImluIGUmJlwic3VwcG9ydHNcImluIGUuQ1NTLE89XCJzdXBwb3J0c0NTU1wiaW4gZTtNb2Rlcm5penIuYWRkVGVzdChcInN1cHBvcnRzXCIsanx8TyksTW9kZXJuaXpyLmFkZFRlc3QoXCJjc3N0cmFuc2Zvcm1zM2RcIixmdW5jdGlvbigpe3JldHVybiEhUyhcInBlcnNwZWN0aXZlXCIsXCIxcHhcIiwhMCl9KSxvKCksaShiKSxkZWxldGUgXy5hZGRUZXN0LGRlbGV0ZSBfLmFkZEFzeW5jVGVzdDtmb3IodmFyIHE9MDtxPE1vZGVybml6ci5fcS5sZW5ndGg7cSsrKU1vZGVybml6ci5fcVtxXSgpO2UuTW9kZXJuaXpyPU1vZGVybml6cn0od2luZG93LGRvY3VtZW50KTtcbm1vZHVsZS5leHBvcnRzID0gd2luZG93Lk1vZGVybml6cjtcbn0pKHdpbmRvdyk7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi8ubW9kZXJuaXpyLWF1dG9yY1xuLy8gbW9kdWxlIGlkID0gNVxuLy8gbW9kdWxlIGNodW5rcyA9IDEiXSwic291cmNlUm9vdCI6IiJ9"
  },
  {
    "path": "SecurityPaper-themes/assets/stylesheets/application-palette.css",
    "content": "button[data-md-color-primary],\nbutton[data-md-color-accent] {\n  width: 13rem;\n  margin-bottom: 0.4rem;\n  padding: 2.4rem 0.8rem 0.4rem;\n  transition: background-color 0.25s, opacity          0.25s;\n  border-radius: 0.2rem;\n  color: white;\n  font-size: 1.28rem;\n  text-align: left;\n  cursor: pointer; }\n  button[data-md-color-primary]:hover,\n  button[data-md-color-accent]:hover {\n    opacity: 0.75; }\n\nbutton[data-md-color-primary=\"red\"] {\n  background-color: #ef5350; }\n\n[data-md-color-primary=\"red\"] .md-typeset a {\n  color: #ef5350; }\n\n[data-md-color-primary=\"red\"] .md-header {\n  background-color: #ef5350; }\n\n[data-md-color-primary=\"red\"] .md-hero {\n  background-color: #ef5350; }\n\n[data-md-color-primary=\"red\"] .md-nav__link:active,\n[data-md-color-primary=\"red\"] .md-nav__link--active {\n  color: #ef5350; }\n\n[data-md-color-primary=\"red\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"pink\"] {\n  background-color: #e91e63; }\n\n[data-md-color-primary=\"pink\"] .md-typeset a {\n  color: #e91e63; }\n\n[data-md-color-primary=\"pink\"] .md-header {\n  background-color: #e91e63; }\n\n[data-md-color-primary=\"pink\"] .md-hero {\n  background-color: #e91e63; }\n\n[data-md-color-primary=\"pink\"] .md-nav__link:active,\n[data-md-color-primary=\"pink\"] .md-nav__link--active {\n  color: #e91e63; }\n\n[data-md-color-primary=\"pink\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"purple\"] {\n  background-color: #ab47bc; }\n\n[data-md-color-primary=\"purple\"] .md-typeset a {\n  color: #ab47bc; }\n\n[data-md-color-primary=\"purple\"] .md-header {\n  background-color: #ab47bc; }\n\n[data-md-color-primary=\"purple\"] .md-hero {\n  background-color: #ab47bc; }\n\n[data-md-color-primary=\"purple\"] .md-nav__link:active,\n[data-md-color-primary=\"purple\"] .md-nav__link--active {\n  color: #ab47bc; }\n\n[data-md-color-primary=\"purple\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"deep-purple\"] {\n  background-color: #7e57c2; }\n\n[data-md-color-primary=\"deep-purple\"] .md-typeset a {\n  color: #7e57c2; }\n\n[data-md-color-primary=\"deep-purple\"] .md-header {\n  background-color: #7e57c2; }\n\n[data-md-color-primary=\"deep-purple\"] .md-hero {\n  background-color: #7e57c2; }\n\n[data-md-color-primary=\"deep-purple\"] .md-nav__link:active,\n[data-md-color-primary=\"deep-purple\"] .md-nav__link--active {\n  color: #7e57c2; }\n\n[data-md-color-primary=\"deep-purple\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"indigo\"] {\n  background-color: #3f51b5; }\n\n[data-md-color-primary=\"indigo\"] .md-typeset a {\n  color: #3f51b5; }\n\n[data-md-color-primary=\"indigo\"] .md-header {\n  background-color: #3f51b5; }\n\n[data-md-color-primary=\"indigo\"] .md-hero {\n  background-color: #3f51b5; }\n\n[data-md-color-primary=\"indigo\"] .md-nav__link:active,\n[data-md-color-primary=\"indigo\"] .md-nav__link--active {\n  color: #3f51b5; }\n\n[data-md-color-primary=\"indigo\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"blue\"] {\n  background-color: #2196f3; }\n\n[data-md-color-primary=\"blue\"] .md-typeset a {\n  color: #2196f3; }\n\n[data-md-color-primary=\"blue\"] .md-header {\n  background-color: #2196f3; }\n\n[data-md-color-primary=\"blue\"] .md-hero {\n  background-color: #2196f3; }\n\n[data-md-color-primary=\"blue\"] .md-nav__link:active,\n[data-md-color-primary=\"blue\"] .md-nav__link--active {\n  color: #2196f3; }\n\n[data-md-color-primary=\"blue\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"light-blue\"] {\n  background-color: #0c92f1; }\n\n[data-md-color-primary=\"light-blue\"] .md-typeset a {\n  color: #0c92f1; }\n\n[data-md-color-primary=\"light-blue\"] .md-header {\n  background-color: #0c92f1; }\n\n[data-md-color-primary=\"light-blue\"] .md-hero {\n  background-color: #0c92f1; }\n\n[data-md-color-primary=\"light-blue\"] .md-nav__link:active,\n[data-md-color-primary=\"light-blue\"] .md-nav__link--active {\n  color: #0c92f1; }\n\n[data-md-color-primary=\"light-blue\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"cyan\"] {\n  background-color: #00bcd4; }\n\n[data-md-color-primary=\"cyan\"] .md-typeset a {\n  color: #00bcd4; }\n\n[data-md-color-primary=\"cyan\"] .md-header {\n  background-color: #00bcd4; }\n\n[data-md-color-primary=\"cyan\"] .md-hero {\n  background-color: #00bcd4; }\n\n[data-md-color-primary=\"cyan\"] .md-nav__link:active,\n[data-md-color-primary=\"cyan\"] .md-nav__link--active {\n  color: #00bcd4; }\n\n[data-md-color-primary=\"cyan\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"teal\"] {\n  background-color: #009688; }\n\n[data-md-color-primary=\"teal\"] .md-typeset a {\n  color: #009688; }\n\n[data-md-color-primary=\"teal\"] .md-header {\n  background-color: #009688; }\n\n[data-md-color-primary=\"teal\"] .md-hero {\n  background-color: #009688; }\n\n[data-md-color-primary=\"teal\"] .md-nav__link:active,\n[data-md-color-primary=\"teal\"] .md-nav__link--active {\n  color: #009688; }\n\n[data-md-color-primary=\"teal\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"green\"] {\n  background-color: #4caf50; }\n\n[data-md-color-primary=\"green\"] .md-typeset a {\n  color: #4caf50; }\n\n[data-md-color-primary=\"green\"] .md-header {\n  background-color: #4caf50; }\n\n[data-md-color-primary=\"green\"] .md-hero {\n  background-color: #4caf50; }\n\n[data-md-color-primary=\"green\"] .md-nav__link:active,\n[data-md-color-primary=\"green\"] .md-nav__link--active {\n  color: #4caf50; }\n\n[data-md-color-primary=\"green\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"light-green\"] {\n  background-color: #7cb342; }\n\n[data-md-color-primary=\"light-green\"] .md-typeset a {\n  color: #7cb342; }\n\n[data-md-color-primary=\"light-green\"] .md-header {\n  background-color: #7cb342; }\n\n[data-md-color-primary=\"light-green\"] .md-hero {\n  background-color: #7cb342; }\n\n[data-md-color-primary=\"light-green\"] .md-nav__link:active,\n[data-md-color-primary=\"light-green\"] .md-nav__link--active {\n  color: #7cb342; }\n\n[data-md-color-primary=\"light-green\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"lime\"] {\n  background-color: #c0ca33; }\n\n[data-md-color-primary=\"lime\"] .md-typeset a {\n  color: #c0ca33; }\n\n[data-md-color-primary=\"lime\"] .md-header {\n  background-color: #c0ca33; }\n\n[data-md-color-primary=\"lime\"] .md-hero {\n  background-color: #c0ca33; }\n\n[data-md-color-primary=\"lime\"] .md-nav__link:active,\n[data-md-color-primary=\"lime\"] .md-nav__link--active {\n  color: #c0ca33; }\n\n[data-md-color-primary=\"lime\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"yellow\"] {\n  background-color: #f9a825; }\n\n[data-md-color-primary=\"yellow\"] .md-typeset a {\n  color: #f9a825; }\n\n[data-md-color-primary=\"yellow\"] .md-header {\n  background-color: #f9a825; }\n\n[data-md-color-primary=\"yellow\"] .md-hero {\n  background-color: #f9a825; }\n\n[data-md-color-primary=\"yellow\"] .md-nav__link:active,\n[data-md-color-primary=\"yellow\"] .md-nav__link--active {\n  color: #f9a825; }\n\n[data-md-color-primary=\"yellow\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"amber\"] {\n  background-color: #ffa000; }\n\n[data-md-color-primary=\"amber\"] .md-typeset a {\n  color: #ffa000; }\n\n[data-md-color-primary=\"amber\"] .md-header {\n  background-color: #ffa000; }\n\n[data-md-color-primary=\"amber\"] .md-hero {\n  background-color: #ffa000; }\n\n[data-md-color-primary=\"amber\"] .md-nav__link:active,\n[data-md-color-primary=\"amber\"] .md-nav__link--active {\n  color: #ffa000; }\n\n[data-md-color-primary=\"amber\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"orange\"] {\n  background-color: #fb8c00; }\n\n[data-md-color-primary=\"orange\"] .md-typeset a {\n  color: #fb8c00; }\n\n[data-md-color-primary=\"orange\"] .md-header {\n  background-color: #fb8c00; }\n\n[data-md-color-primary=\"orange\"] .md-hero {\n  background-color: #fb8c00; }\n\n[data-md-color-primary=\"orange\"] .md-nav__link:active,\n[data-md-color-primary=\"orange\"] .md-nav__link--active {\n  color: #fb8c00; }\n\n[data-md-color-primary=\"orange\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"deep-orange\"] {\n  background-color: #ff7043; }\n\n[data-md-color-primary=\"deep-orange\"] .md-typeset a {\n  color: #ff7043; }\n\n[data-md-color-primary=\"deep-orange\"] .md-header {\n  background-color: #ff7043; }\n\n[data-md-color-primary=\"deep-orange\"] .md-hero {\n  background-color: #ff7043; }\n\n[data-md-color-primary=\"deep-orange\"] .md-nav__link:active,\n[data-md-color-primary=\"deep-orange\"] .md-nav__link--active {\n  color: #ff7043; }\n\n[data-md-color-primary=\"deep-orange\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"brown\"] {\n  background-color: #795548; }\n\n[data-md-color-primary=\"brown\"] .md-typeset a {\n  color: #795548; }\n\n[data-md-color-primary=\"brown\"] .md-header {\n  background-color: #795548; }\n\n[data-md-color-primary=\"brown\"] .md-hero {\n  background-color: #795548; }\n\n[data-md-color-primary=\"brown\"] .md-nav__link:active,\n[data-md-color-primary=\"brown\"] .md-nav__link--active {\n  color: #795548; }\n\n[data-md-color-primary=\"brown\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"grey\"] {\n  background-color: #757575; }\n\n[data-md-color-primary=\"grey\"] .md-typeset a {\n  color: #757575; }\n\n[data-md-color-primary=\"grey\"] .md-header {\n  background-color: #757575; }\n\n[data-md-color-primary=\"grey\"] .md-hero {\n  background-color: #757575; }\n\n[data-md-color-primary=\"grey\"] .md-nav__link:active,\n[data-md-color-primary=\"grey\"] .md-nav__link--active {\n  color: #757575; }\n\n[data-md-color-primary=\"grey\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"blue-grey\"] {\n  background-color: #546e7a; }\n\n[data-md-color-primary=\"blue-grey\"] .md-typeset a {\n  color: #546e7a; }\n\n[data-md-color-primary=\"blue-grey\"] .md-header {\n  background-color: #546e7a; }\n\n[data-md-color-primary=\"blue-grey\"] .md-hero {\n  background-color: #546e7a; }\n\n[data-md-color-primary=\"blue-grey\"] .md-nav__link:active,\n[data-md-color-primary=\"blue-grey\"] .md-nav__link--active {\n  color: #546e7a; }\n\n[data-md-color-primary=\"blue-grey\"] .md-nav__item--nested > .md-nav__link {\n  color: inherit; }\n\nbutton[data-md-color-primary=\"white\"] {\n  background-color: white;\n  color: rgba(0, 0, 0, 0.87);\n  box-shadow: 0 0 0.1rem rgba(0, 0, 0, 0.54) inset; }\n\n[data-md-color-primary=\"white\"] .md-header {\n  background-color: white;\n  color: rgba(0, 0, 0, 0.87); }\n\n[data-md-color-primary=\"white\"] .md-hero {\n  background-color: white;\n  color: rgba(0, 0, 0, 0.87); }\n  [data-md-color-primary=\"white\"] .md-hero--expand {\n    border-bottom: 0.1rem solid rgba(0, 0, 0, 0.07); }\n\nbutton[data-md-color-accent=\"red\"] {\n  background-color: #ff1744; }\n\n[data-md-color-accent=\"red\"] .md-typeset a:hover,\n[data-md-color-accent=\"red\"] .md-typeset a:active {\n  color: #ff1744; }\n\n[data-md-color-accent=\"red\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"red\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #ff1744; }\n\n[data-md-color-accent=\"red\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"red\"] .md-typeset .md-clipboard:active::before {\n  color: #ff1744; }\n\n[data-md-color-accent=\"red\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"red\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #ff1744; }\n\n[data-md-color-accent=\"red\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"red\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"red\"] .md-typeset [id] .headerlink:focus {\n  color: #ff1744; }\n\n[data-md-color-accent=\"red\"] .md-nav__link:focus,\n[data-md-color-accent=\"red\"] .md-nav__link:hover {\n  color: #ff1744; }\n\n[data-md-color-accent=\"red\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #ff1744; }\n\n[data-md-color-accent=\"red\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"red\"] .md-search-result__link:hover {\n  background-color: rgba(255, 23, 68, 0.1); }\n\n[data-md-color-accent=\"red\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #ff1744; }\n\n[data-md-color-accent=\"red\"] .md-source-file:hover::before {\n  background-color: #ff1744; }\n\nbutton[data-md-color-accent=\"pink\"] {\n  background-color: #f50057; }\n\n[data-md-color-accent=\"pink\"] .md-typeset a:hover,\n[data-md-color-accent=\"pink\"] .md-typeset a:active {\n  color: #f50057; }\n\n[data-md-color-accent=\"pink\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"pink\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #f50057; }\n\n[data-md-color-accent=\"pink\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"pink\"] .md-typeset .md-clipboard:active::before {\n  color: #f50057; }\n\n[data-md-color-accent=\"pink\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"pink\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #f50057; }\n\n[data-md-color-accent=\"pink\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"pink\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"pink\"] .md-typeset [id] .headerlink:focus {\n  color: #f50057; }\n\n[data-md-color-accent=\"pink\"] .md-nav__link:focus,\n[data-md-color-accent=\"pink\"] .md-nav__link:hover {\n  color: #f50057; }\n\n[data-md-color-accent=\"pink\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #f50057; }\n\n[data-md-color-accent=\"pink\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"pink\"] .md-search-result__link:hover {\n  background-color: rgba(245, 0, 87, 0.1); }\n\n[data-md-color-accent=\"pink\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #f50057; }\n\n[data-md-color-accent=\"pink\"] .md-source-file:hover::before {\n  background-color: #f50057; }\n\nbutton[data-md-color-accent=\"purple\"] {\n  background-color: #e040fb; }\n\n[data-md-color-accent=\"purple\"] .md-typeset a:hover,\n[data-md-color-accent=\"purple\"] .md-typeset a:active {\n  color: #e040fb; }\n\n[data-md-color-accent=\"purple\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"purple\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #e040fb; }\n\n[data-md-color-accent=\"purple\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"purple\"] .md-typeset .md-clipboard:active::before {\n  color: #e040fb; }\n\n[data-md-color-accent=\"purple\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"purple\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #e040fb; }\n\n[data-md-color-accent=\"purple\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"purple\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"purple\"] .md-typeset [id] .headerlink:focus {\n  color: #e040fb; }\n\n[data-md-color-accent=\"purple\"] .md-nav__link:focus,\n[data-md-color-accent=\"purple\"] .md-nav__link:hover {\n  color: #e040fb; }\n\n[data-md-color-accent=\"purple\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #e040fb; }\n\n[data-md-color-accent=\"purple\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"purple\"] .md-search-result__link:hover {\n  background-color: rgba(224, 64, 251, 0.1); }\n\n[data-md-color-accent=\"purple\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #e040fb; }\n\n[data-md-color-accent=\"purple\"] .md-source-file:hover::before {\n  background-color: #e040fb; }\n\nbutton[data-md-color-accent=\"deep-purple\"] {\n  background-color: #7c4dff; }\n\n[data-md-color-accent=\"deep-purple\"] .md-typeset a:hover,\n[data-md-color-accent=\"deep-purple\"] .md-typeset a:active {\n  color: #7c4dff; }\n\n[data-md-color-accent=\"deep-purple\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"deep-purple\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #7c4dff; }\n\n[data-md-color-accent=\"deep-purple\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"deep-purple\"] .md-typeset .md-clipboard:active::before {\n  color: #7c4dff; }\n\n[data-md-color-accent=\"deep-purple\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"deep-purple\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #7c4dff; }\n\n[data-md-color-accent=\"deep-purple\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"deep-purple\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"deep-purple\"] .md-typeset [id] .headerlink:focus {\n  color: #7c4dff; }\n\n[data-md-color-accent=\"deep-purple\"] .md-nav__link:focus,\n[data-md-color-accent=\"deep-purple\"] .md-nav__link:hover {\n  color: #7c4dff; }\n\n[data-md-color-accent=\"deep-purple\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #7c4dff; }\n\n[data-md-color-accent=\"deep-purple\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"deep-purple\"] .md-search-result__link:hover {\n  background-color: rgba(124, 77, 255, 0.1); }\n\n[data-md-color-accent=\"deep-purple\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #7c4dff; }\n\n[data-md-color-accent=\"deep-purple\"] .md-source-file:hover::before {\n  background-color: #7c4dff; }\n\nbutton[data-md-color-accent=\"indigo\"] {\n  background-color: #536dfe; }\n\n[data-md-color-accent=\"indigo\"] .md-typeset a:hover,\n[data-md-color-accent=\"indigo\"] .md-typeset a:active {\n  color: #536dfe; }\n\n[data-md-color-accent=\"indigo\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"indigo\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #536dfe; }\n\n[data-md-color-accent=\"indigo\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"indigo\"] .md-typeset .md-clipboard:active::before {\n  color: #536dfe; }\n\n[data-md-color-accent=\"indigo\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"indigo\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #536dfe; }\n\n[data-md-color-accent=\"indigo\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"indigo\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"indigo\"] .md-typeset [id] .headerlink:focus {\n  color: #536dfe; }\n\n[data-md-color-accent=\"indigo\"] .md-nav__link:focus,\n[data-md-color-accent=\"indigo\"] .md-nav__link:hover {\n  color: #536dfe; }\n\n[data-md-color-accent=\"indigo\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #536dfe; }\n\n[data-md-color-accent=\"indigo\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"indigo\"] .md-search-result__link:hover {\n  background-color: rgba(83, 109, 254, 0.1); }\n\n[data-md-color-accent=\"indigo\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #536dfe; }\n\n[data-md-color-accent=\"indigo\"] .md-source-file:hover::before {\n  background-color: #536dfe; }\n\nbutton[data-md-color-accent=\"blue\"] {\n  background-color: #448aff; }\n\n[data-md-color-accent=\"blue\"] .md-typeset a:hover,\n[data-md-color-accent=\"blue\"] .md-typeset a:active {\n  color: #448aff; }\n\n[data-md-color-accent=\"blue\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"blue\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #448aff; }\n\n[data-md-color-accent=\"blue\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"blue\"] .md-typeset .md-clipboard:active::before {\n  color: #448aff; }\n\n[data-md-color-accent=\"blue\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"blue\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #448aff; }\n\n[data-md-color-accent=\"blue\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"blue\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"blue\"] .md-typeset [id] .headerlink:focus {\n  color: #448aff; }\n\n[data-md-color-accent=\"blue\"] .md-nav__link:focus,\n[data-md-color-accent=\"blue\"] .md-nav__link:hover {\n  color: #448aff; }\n\n[data-md-color-accent=\"blue\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #448aff; }\n\n[data-md-color-accent=\"blue\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"blue\"] .md-search-result__link:hover {\n  background-color: rgba(68, 138, 255, 0.1); }\n\n[data-md-color-accent=\"blue\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #448aff; }\n\n[data-md-color-accent=\"blue\"] .md-source-file:hover::before {\n  background-color: #448aff; }\n\nbutton[data-md-color-accent=\"light-blue\"] {\n  background-color: #0091ea; }\n\n[data-md-color-accent=\"light-blue\"] .md-typeset a:hover,\n[data-md-color-accent=\"light-blue\"] .md-typeset a:active {\n  color: #0091ea; }\n\n[data-md-color-accent=\"light-blue\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"light-blue\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #0091ea; }\n\n[data-md-color-accent=\"light-blue\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"light-blue\"] .md-typeset .md-clipboard:active::before {\n  color: #0091ea; }\n\n[data-md-color-accent=\"light-blue\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"light-blue\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #0091ea; }\n\n[data-md-color-accent=\"light-blue\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"light-blue\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"light-blue\"] .md-typeset [id] .headerlink:focus {\n  color: #0091ea; }\n\n[data-md-color-accent=\"light-blue\"] .md-nav__link:focus,\n[data-md-color-accent=\"light-blue\"] .md-nav__link:hover {\n  color: #0091ea; }\n\n[data-md-color-accent=\"light-blue\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #0091ea; }\n\n[data-md-color-accent=\"light-blue\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"light-blue\"] .md-search-result__link:hover {\n  background-color: rgba(0, 145, 234, 0.1); }\n\n[data-md-color-accent=\"light-blue\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #0091ea; }\n\n[data-md-color-accent=\"light-blue\"] .md-source-file:hover::before {\n  background-color: #0091ea; }\n\nbutton[data-md-color-accent=\"cyan\"] {\n  background-color: #00b8d4; }\n\n[data-md-color-accent=\"cyan\"] .md-typeset a:hover,\n[data-md-color-accent=\"cyan\"] .md-typeset a:active {\n  color: #00b8d4; }\n\n[data-md-color-accent=\"cyan\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"cyan\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #00b8d4; }\n\n[data-md-color-accent=\"cyan\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"cyan\"] .md-typeset .md-clipboard:active::before {\n  color: #00b8d4; }\n\n[data-md-color-accent=\"cyan\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"cyan\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #00b8d4; }\n\n[data-md-color-accent=\"cyan\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"cyan\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"cyan\"] .md-typeset [id] .headerlink:focus {\n  color: #00b8d4; }\n\n[data-md-color-accent=\"cyan\"] .md-nav__link:focus,\n[data-md-color-accent=\"cyan\"] .md-nav__link:hover {\n  color: #00b8d4; }\n\n[data-md-color-accent=\"cyan\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #00b8d4; }\n\n[data-md-color-accent=\"cyan\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"cyan\"] .md-search-result__link:hover {\n  background-color: rgba(0, 184, 212, 0.1); }\n\n[data-md-color-accent=\"cyan\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #00b8d4; }\n\n[data-md-color-accent=\"cyan\"] .md-source-file:hover::before {\n  background-color: #00b8d4; }\n\nbutton[data-md-color-accent=\"teal\"] {\n  background-color: #00bfa5; }\n\n[data-md-color-accent=\"teal\"] .md-typeset a:hover,\n[data-md-color-accent=\"teal\"] .md-typeset a:active {\n  color: #00bfa5; }\n\n[data-md-color-accent=\"teal\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"teal\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #00bfa5; }\n\n[data-md-color-accent=\"teal\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"teal\"] .md-typeset .md-clipboard:active::before {\n  color: #00bfa5; }\n\n[data-md-color-accent=\"teal\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"teal\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #00bfa5; }\n\n[data-md-color-accent=\"teal\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"teal\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"teal\"] .md-typeset [id] .headerlink:focus {\n  color: #00bfa5; }\n\n[data-md-color-accent=\"teal\"] .md-nav__link:focus,\n[data-md-color-accent=\"teal\"] .md-nav__link:hover {\n  color: #00bfa5; }\n\n[data-md-color-accent=\"teal\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #00bfa5; }\n\n[data-md-color-accent=\"teal\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"teal\"] .md-search-result__link:hover {\n  background-color: rgba(0, 191, 165, 0.1); }\n\n[data-md-color-accent=\"teal\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #00bfa5; }\n\n[data-md-color-accent=\"teal\"] .md-source-file:hover::before {\n  background-color: #00bfa5; }\n\nbutton[data-md-color-accent=\"green\"] {\n  background-color: #00c853; }\n\n[data-md-color-accent=\"green\"] .md-typeset a:hover,\n[data-md-color-accent=\"green\"] .md-typeset a:active {\n  color: #00c853; }\n\n[data-md-color-accent=\"green\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"green\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #00c853; }\n\n[data-md-color-accent=\"green\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"green\"] .md-typeset .md-clipboard:active::before {\n  color: #00c853; }\n\n[data-md-color-accent=\"green\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"green\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #00c853; }\n\n[data-md-color-accent=\"green\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"green\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"green\"] .md-typeset [id] .headerlink:focus {\n  color: #00c853; }\n\n[data-md-color-accent=\"green\"] .md-nav__link:focus,\n[data-md-color-accent=\"green\"] .md-nav__link:hover {\n  color: #00c853; }\n\n[data-md-color-accent=\"green\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #00c853; }\n\n[data-md-color-accent=\"green\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"green\"] .md-search-result__link:hover {\n  background-color: rgba(0, 200, 83, 0.1); }\n\n[data-md-color-accent=\"green\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #00c853; }\n\n[data-md-color-accent=\"green\"] .md-source-file:hover::before {\n  background-color: #00c853; }\n\nbutton[data-md-color-accent=\"light-green\"] {\n  background-color: #64dd17; }\n\n[data-md-color-accent=\"light-green\"] .md-typeset a:hover,\n[data-md-color-accent=\"light-green\"] .md-typeset a:active {\n  color: #64dd17; }\n\n[data-md-color-accent=\"light-green\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"light-green\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #64dd17; }\n\n[data-md-color-accent=\"light-green\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"light-green\"] .md-typeset .md-clipboard:active::before {\n  color: #64dd17; }\n\n[data-md-color-accent=\"light-green\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"light-green\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #64dd17; }\n\n[data-md-color-accent=\"light-green\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"light-green\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"light-green\"] .md-typeset [id] .headerlink:focus {\n  color: #64dd17; }\n\n[data-md-color-accent=\"light-green\"] .md-nav__link:focus,\n[data-md-color-accent=\"light-green\"] .md-nav__link:hover {\n  color: #64dd17; }\n\n[data-md-color-accent=\"light-green\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #64dd17; }\n\n[data-md-color-accent=\"light-green\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"light-green\"] .md-search-result__link:hover {\n  background-color: rgba(100, 221, 23, 0.1); }\n\n[data-md-color-accent=\"light-green\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #64dd17; }\n\n[data-md-color-accent=\"light-green\"] .md-source-file:hover::before {\n  background-color: #64dd17; }\n\nbutton[data-md-color-accent=\"lime\"] {\n  background-color: #aeea00; }\n\n[data-md-color-accent=\"lime\"] .md-typeset a:hover,\n[data-md-color-accent=\"lime\"] .md-typeset a:active {\n  color: #aeea00; }\n\n[data-md-color-accent=\"lime\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"lime\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #aeea00; }\n\n[data-md-color-accent=\"lime\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"lime\"] .md-typeset .md-clipboard:active::before {\n  color: #aeea00; }\n\n[data-md-color-accent=\"lime\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"lime\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #aeea00; }\n\n[data-md-color-accent=\"lime\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"lime\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"lime\"] .md-typeset [id] .headerlink:focus {\n  color: #aeea00; }\n\n[data-md-color-accent=\"lime\"] .md-nav__link:focus,\n[data-md-color-accent=\"lime\"] .md-nav__link:hover {\n  color: #aeea00; }\n\n[data-md-color-accent=\"lime\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #aeea00; }\n\n[data-md-color-accent=\"lime\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"lime\"] .md-search-result__link:hover {\n  background-color: rgba(174, 234, 0, 0.1); }\n\n[data-md-color-accent=\"lime\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #aeea00; }\n\n[data-md-color-accent=\"lime\"] .md-source-file:hover::before {\n  background-color: #aeea00; }\n\nbutton[data-md-color-accent=\"yellow\"] {\n  background-color: #ffd600; }\n\n[data-md-color-accent=\"yellow\"] .md-typeset a:hover,\n[data-md-color-accent=\"yellow\"] .md-typeset a:active {\n  color: #ffd600; }\n\n[data-md-color-accent=\"yellow\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"yellow\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #ffd600; }\n\n[data-md-color-accent=\"yellow\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"yellow\"] .md-typeset .md-clipboard:active::before {\n  color: #ffd600; }\n\n[data-md-color-accent=\"yellow\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"yellow\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #ffd600; }\n\n[data-md-color-accent=\"yellow\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"yellow\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"yellow\"] .md-typeset [id] .headerlink:focus {\n  color: #ffd600; }\n\n[data-md-color-accent=\"yellow\"] .md-nav__link:focus,\n[data-md-color-accent=\"yellow\"] .md-nav__link:hover {\n  color: #ffd600; }\n\n[data-md-color-accent=\"yellow\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #ffd600; }\n\n[data-md-color-accent=\"yellow\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"yellow\"] .md-search-result__link:hover {\n  background-color: rgba(255, 214, 0, 0.1); }\n\n[data-md-color-accent=\"yellow\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #ffd600; }\n\n[data-md-color-accent=\"yellow\"] .md-source-file:hover::before {\n  background-color: #ffd600; }\n\nbutton[data-md-color-accent=\"amber\"] {\n  background-color: #ffab00; }\n\n[data-md-color-accent=\"amber\"] .md-typeset a:hover,\n[data-md-color-accent=\"amber\"] .md-typeset a:active {\n  color: #ffab00; }\n\n[data-md-color-accent=\"amber\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"amber\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #ffab00; }\n\n[data-md-color-accent=\"amber\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"amber\"] .md-typeset .md-clipboard:active::before {\n  color: #ffab00; }\n\n[data-md-color-accent=\"amber\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"amber\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #ffab00; }\n\n[data-md-color-accent=\"amber\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"amber\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"amber\"] .md-typeset [id] .headerlink:focus {\n  color: #ffab00; }\n\n[data-md-color-accent=\"amber\"] .md-nav__link:focus,\n[data-md-color-accent=\"amber\"] .md-nav__link:hover {\n  color: #ffab00; }\n\n[data-md-color-accent=\"amber\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #ffab00; }\n\n[data-md-color-accent=\"amber\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"amber\"] .md-search-result__link:hover {\n  background-color: rgba(255, 171, 0, 0.1); }\n\n[data-md-color-accent=\"amber\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #ffab00; }\n\n[data-md-color-accent=\"amber\"] .md-source-file:hover::before {\n  background-color: #ffab00; }\n\nbutton[data-md-color-accent=\"orange\"] {\n  background-color: #ff9100; }\n\n[data-md-color-accent=\"orange\"] .md-typeset a:hover,\n[data-md-color-accent=\"orange\"] .md-typeset a:active {\n  color: #ff9100; }\n\n[data-md-color-accent=\"orange\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"orange\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #ff9100; }\n\n[data-md-color-accent=\"orange\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"orange\"] .md-typeset .md-clipboard:active::before {\n  color: #ff9100; }\n\n[data-md-color-accent=\"orange\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"orange\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #ff9100; }\n\n[data-md-color-accent=\"orange\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"orange\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"orange\"] .md-typeset [id] .headerlink:focus {\n  color: #ff9100; }\n\n[data-md-color-accent=\"orange\"] .md-nav__link:focus,\n[data-md-color-accent=\"orange\"] .md-nav__link:hover {\n  color: #ff9100; }\n\n[data-md-color-accent=\"orange\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #ff9100; }\n\n[data-md-color-accent=\"orange\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"orange\"] .md-search-result__link:hover {\n  background-color: rgba(255, 145, 0, 0.1); }\n\n[data-md-color-accent=\"orange\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #ff9100; }\n\n[data-md-color-accent=\"orange\"] .md-source-file:hover::before {\n  background-color: #ff9100; }\n\nbutton[data-md-color-accent=\"deep-orange\"] {\n  background-color: #ff6e40; }\n\n[data-md-color-accent=\"deep-orange\"] .md-typeset a:hover,\n[data-md-color-accent=\"deep-orange\"] .md-typeset a:active {\n  color: #ff6e40; }\n\n[data-md-color-accent=\"deep-orange\"] .md-typeset pre code::-webkit-scrollbar-thumb:hover,\n[data-md-color-accent=\"deep-orange\"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover {\n  background-color: #ff6e40; }\n\n[data-md-color-accent=\"deep-orange\"] .md-typeset .md-clipboard:hover::before,\n[data-md-color-accent=\"deep-orange\"] .md-typeset .md-clipboard:active::before {\n  color: #ff6e40; }\n\n[data-md-color-accent=\"deep-orange\"] .md-typeset .footnote li:hover .footnote-backref:hover,\n[data-md-color-accent=\"deep-orange\"] .md-typeset .footnote li:target .footnote-backref {\n  color: #ff6e40; }\n\n[data-md-color-accent=\"deep-orange\"] .md-typeset [id]:hover .headerlink:hover,\n[data-md-color-accent=\"deep-orange\"] .md-typeset [id]:target .headerlink,\n[data-md-color-accent=\"deep-orange\"] .md-typeset [id] .headerlink:focus {\n  color: #ff6e40; }\n\n[data-md-color-accent=\"deep-orange\"] .md-nav__link:focus,\n[data-md-color-accent=\"deep-orange\"] .md-nav__link:hover {\n  color: #ff6e40; }\n\n[data-md-color-accent=\"deep-orange\"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #ff6e40; }\n\n[data-md-color-accent=\"deep-orange\"] .md-search-result__link[data-md-state=\"active\"], [data-md-color-accent=\"deep-orange\"] .md-search-result__link:hover {\n  background-color: rgba(255, 110, 64, 0.1); }\n\n[data-md-color-accent=\"deep-orange\"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n  background-color: #ff6e40; }\n\n[data-md-color-accent=\"deep-orange\"] .md-source-file:hover::before {\n  background-color: #ff6e40; }\n\n@media only screen and (max-width: 59.9375em) {\n  [data-md-color-primary=\"red\"] .md-nav__source {\n    background-color: rgba(190, 66, 64, 0.9675); }\n  [data-md-color-primary=\"pink\"] .md-nav__source {\n    background-color: rgba(185, 24, 79, 0.9675); }\n  [data-md-color-primary=\"purple\"] .md-nav__source {\n    background-color: rgba(136, 57, 150, 0.9675); }\n  [data-md-color-primary=\"deep-purple\"] .md-nav__source {\n    background-color: rgba(100, 69, 154, 0.9675); }\n  [data-md-color-primary=\"indigo\"] .md-nav__source {\n    background-color: rgba(50, 64, 144, 0.9675); }\n  [data-md-color-primary=\"blue\"] .md-nav__source {\n    background-color: rgba(26, 119, 193, 0.9675); }\n  [data-md-color-primary=\"light-blue\"] .md-nav__source {\n    background-color: rgba(2, 134, 194, 0.9675); }\n  [data-md-color-primary=\"cyan\"] .md-nav__source {\n    background-color: rgba(0, 150, 169, 0.9675); }\n  [data-md-color-primary=\"teal\"] .md-nav__source {\n    background-color: rgba(0, 119, 108, 0.9675); }\n  [data-md-color-primary=\"green\"] .md-nav__source {\n    background-color: rgba(60, 139, 64, 0.9675); }\n  [data-md-color-primary=\"light-green\"] .md-nav__source {\n    background-color: rgba(99, 142, 53, 0.9675); }\n  [data-md-color-primary=\"lime\"] .md-nav__source {\n    background-color: rgba(153, 161, 41, 0.9675); }\n  [data-md-color-primary=\"yellow\"] .md-nav__source {\n    background-color: rgba(198, 134, 29, 0.9675); }\n  [data-md-color-primary=\"amber\"] .md-nav__source {\n    background-color: rgba(203, 127, 0, 0.9675); }\n  [data-md-color-primary=\"orange\"] .md-nav__source {\n    background-color: rgba(200, 111, 0, 0.9675); }\n  [data-md-color-primary=\"deep-orange\"] .md-nav__source {\n    background-color: rgba(203, 89, 53, 0.9675); }\n  [data-md-color-primary=\"brown\"] .md-nav__source {\n    background-color: rgba(96, 68, 57, 0.9675); }\n  [data-md-color-primary=\"grey\"] .md-nav__source {\n    background-color: rgba(93, 93, 93, 0.9675); }\n  [data-md-color-primary=\"blue-grey\"] .md-nav__source {\n    background-color: rgba(67, 88, 97, 0.9675); }\n  [data-md-color-primary=\"white\"] .md-nav__source {\n    background-color: rgba(0, 0, 0, 0.07);\n    color: rgba(0, 0, 0, 0.87); } }\n\n@media only screen and (max-width: 76.1875em) {\n  html [data-md-color-primary=\"red\"] .md-nav--primary .md-nav__title--site {\n    background-color: #ef5350; }\n  html [data-md-color-primary=\"pink\"] .md-nav--primary .md-nav__title--site {\n    background-color: #e91e63; }\n  html [data-md-color-primary=\"purple\"] .md-nav--primary .md-nav__title--site {\n    background-color: #ab47bc; }\n  html [data-md-color-primary=\"deep-purple\"] .md-nav--primary .md-nav__title--site {\n    background-color: #7e57c2; }\n  html [data-md-color-primary=\"indigo\"] .md-nav--primary .md-nav__title--site {\n    background-color: #3f51b5; }\n  html [data-md-color-primary=\"blue\"] .md-nav--primary .md-nav__title--site {\n    background-color: #2196f3; }\n  html [data-md-color-primary=\"light-blue\"] .md-nav--primary .md-nav__title--site {\n    background-color: #0c92f1; }\n  html [data-md-color-primary=\"cyan\"] .md-nav--primary .md-nav__title--site {\n    background-color: #00bcd4; }\n  html [data-md-color-primary=\"teal\"] .md-nav--primary .md-nav__title--site {\n    background-color: #009688; }\n  html [data-md-color-primary=\"green\"] .md-nav--primary .md-nav__title--site {\n    background-color: #4caf50; }\n  html [data-md-color-primary=\"light-green\"] .md-nav--primary .md-nav__title--site {\n    background-color: #7cb342; }\n  html [data-md-color-primary=\"lime\"] .md-nav--primary .md-nav__title--site {\n    background-color: #c0ca33; }\n  html [data-md-color-primary=\"yellow\"] .md-nav--primary .md-nav__title--site {\n    background-color: #f9a825; }\n  html [data-md-color-primary=\"amber\"] .md-nav--primary .md-nav__title--site {\n    background-color: #ffa000; }\n  html [data-md-color-primary=\"orange\"] .md-nav--primary .md-nav__title--site {\n    background-color: #fb8c00; }\n  html [data-md-color-primary=\"deep-orange\"] .md-nav--primary .md-nav__title--site {\n    background-color: #ff7043; }\n  html [data-md-color-primary=\"brown\"] .md-nav--primary .md-nav__title--site {\n    background-color: #795548; }\n  html [data-md-color-primary=\"grey\"] .md-nav--primary .md-nav__title--site {\n    background-color: #757575; }\n  html [data-md-color-primary=\"blue-grey\"] .md-nav--primary .md-nav__title--site {\n    background-color: #546e7a; }\n  html [data-md-color-primary=\"white\"] .md-nav--primary .md-nav__title--site {\n    background-color: white;\n    color: rgba(0, 0, 0, 0.87); }\n  [data-md-color-primary=\"white\"] .md-hero {\n    border-bottom: 0.1rem solid rgba(0, 0, 0, 0.07); } }\n\n@media only screen and (min-width: 76.25em) {\n  [data-md-color-primary=\"red\"] .md-tabs {\n    background-color: #ef5350; }\n  [data-md-color-primary=\"pink\"] .md-tabs {\n    background-color: #e91e63; }\n  [data-md-color-primary=\"purple\"] .md-tabs {\n    background-color: #ab47bc; }\n  [data-md-color-primary=\"deep-purple\"] .md-tabs {\n    background-color: #7e57c2; }\n  [data-md-color-primary=\"indigo\"] .md-tabs {\n    background-color: #3f51b5; }\n  [data-md-color-primary=\"blue\"] .md-tabs {\n    background-color: #2196f3; }\n  [data-md-color-primary=\"light-blue\"] .md-tabs {\n    background-color: #0c92f1; }\n  [data-md-color-primary=\"cyan\"] .md-tabs {\n    background-color: #00bcd4; }\n  [data-md-color-primary=\"teal\"] .md-tabs {\n    background-color: #009688; }\n  [data-md-color-primary=\"green\"] .md-tabs {\n    background-color: #4caf50; }\n  [data-md-color-primary=\"light-green\"] .md-tabs {\n    background-color: #7cb342; }\n  [data-md-color-primary=\"lime\"] .md-tabs {\n    background-color: #c0ca33; }\n  [data-md-color-primary=\"yellow\"] .md-tabs {\n    background-color: #f9a825; }\n  [data-md-color-primary=\"amber\"] .md-tabs {\n    background-color: #ffa000; }\n  [data-md-color-primary=\"orange\"] .md-tabs {\n    background-color: #fb8c00; }\n  [data-md-color-primary=\"deep-orange\"] .md-tabs {\n    background-color: #ff7043; }\n  [data-md-color-primary=\"brown\"] .md-tabs {\n    background-color: #795548; }\n  [data-md-color-primary=\"grey\"] .md-tabs {\n    background-color: #757575; }\n  [data-md-color-primary=\"blue-grey\"] .md-tabs {\n    background-color: #546e7a; }\n  [data-md-color-primary=\"white\"] .md-tabs {\n    border-bottom: 0.1rem solid rgba(0, 0, 0, 0.07);\n    background-color: white;\n    color: rgba(0, 0, 0, 0.87); } }\n\n@media only screen and (min-width: 60em) {\n  [data-md-color-primary=\"white\"] .md-search__input {\n    background-color: rgba(0, 0, 0, 0.07); }\n    [data-md-color-primary=\"white\"] .md-search__input::-webkit-input-placeholder {\n      color: rgba(0, 0, 0, 0.54); }\n    [data-md-color-primary=\"white\"] .md-search__input:-ms-input-placeholder {\n      color: rgba(0, 0, 0, 0.54); }\n    [data-md-color-primary=\"white\"] .md-search__input::-ms-input-placeholder {\n      color: rgba(0, 0, 0, 0.54); }\n    [data-md-color-primary=\"white\"] .md-search__input::placeholder {\n      color: rgba(0, 0, 0, 0.54); } }\n\n/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2FwcGxpY2F0aW9uLXBhbGV0dGUuc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL19jb25maWcuc2NzcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvbW9kdWxhcnNjYWxlLXNhc3Mvc3R5bGVzaGVldHMvbW9kdWxhcnNjYWxlL19mdW5jdGlvbi5zY3NzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9tYXRlcmlhbC1kZXNpZ24tY29sb3IvbWF0ZXJpYWwtY29sb3Iuc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2hlbHBlcnMvX2JyZWFrLnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBNENBOztFQUVFLGFBQVk7RUFDWixzQkFBcUI7RUFDckIsOEJBQTZCO0VBQzdCLDJEQUV3QjtFQUN4QixzQkFBcUI7RUFDckIsYUNrQndEO0VEakJ4RCxtQkV4Q29DO0VGeUNwQyxpQkFBZ0I7RUFDaEIsZ0JBQWUsRUFNaEI7RUFsQkQ7O0lBZ0JJLGNBQWEsRUFDZDs7QUEyQkQ7RUFDRSwwQkd0Q2EsRUh1Q2Q7O0FBeEVIO0VBK0VNLGVHOUNXLEVIK0NaOztBQTdFTDtFQWlGTSwwQkduRFcsRUhvRFo7O0FBL0VMO0VBbUZNLDBCR3hEVyxFSHlEWjs7QUFqRkw7O0VBc0ZNLGVHOURXLEVIK0RaOztBQW5GTDtFQXVGTSxlQUFjLEVBQ2Y7O0FBL0JIO0VBQ0UsMEJHR2EsRUhGZDs7QUF6Q0g7RUFnRE0sZUdMVyxFSE1aOztBQTlDTDtFQWtETSwwQkdWVyxFSFdaOztBQWhETDtFQW9ETSwwQkdmVyxFSGdCWjs7QUFsREw7O0VBdURNLGVHckJXLEVIc0JaOztBQXBETDtFQXdETSxlQUFjLEVBQ2Y7O0FBL0JIO0VBQ0UsMEJHMENhLEVIekNkOztBQVZIO0VBaUJNLGVHa0NXLEVIakNaOztBQWZMO0VBbUJNLDBCRzZCVyxFSDVCWjs7QUFq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RSwwQkdKUyxFSEtWO0VBRkQ7SUFDRSwwQkdvQ1MsRUhuQ1Y7RUFGRDtJQUNFLDBCRzZFUyxFSDVFVjtFQUZEO0lBQ0UsMEJHcUhTLEVIcEhWO0VBRkQ7SUFDRSwwQkc2SlMsRUg1SlY7RUFGRDtJQUNFLDBCR3FNUyxFSHBNVjtFQUZEO0lBQ0UsMEJHNk9TLEVINU9WO0VBRkQ7SUFDRSwwQkdxUlMsRUhwUlY7RUFGRDtJQUNFLDBCRzhUUyxFSDdUVjtFQUZEO0lBQ0UsMEJHc1dTLEVIcldWO0VBRkQ7SUFDRSwwQkdnWlMsRUgvWVY7RUFGRDtJQUNFLDBCR3ViUyxFSHRiVjtFQUZEO0lBQ0UsMEJHOGRTLEVIN2RWO0VBRkQ7SUFDRSwwQkdvZ0JTLEVIbmdCVjtFQUZEO0lBQ0UsMEJHNmlCUyxFSDVpQlY7RUFGRDtJQUNFLDBCRzhrQlMsRUg3a0JWO0VBRkQ7SUFDRSwwQkc4bUJTLEVIN21CVjtFQXFFSDtJQUNFLHdCQ3ZJb0Q7SUR3SXBELDJCQy9JcUQsRURnSnREO0VBMGFIO0lBdGFJLGdEQ2pKcUQsRURrSnRELEVBN0VFOztBSXFGSDtFSmxMRjtJQXFHTSwwQkc3RlMsRUg4RlY7RUF2RUw7SUFzRU0sMEJHcERTLEVIcURWO0VBeENMO0lBdUNNLDBCR2JTLEVIY1Y7RUFUTDtJQVFNLDBCRzJCUyxFSDFCVjtFQXNCTDtJQXZCTSwwQkdvRVMsRUhuRVY7RUFxREw7SUF0RE0sMEJHNEdTLEVIM0dWO0VBb0ZMO0lBckZNLDBCR29KUyxFSG5KVjtFQW1ITDtJQXBITSwwQkc0TFMsRUgzTFY7RUFrSkw7SUFuSk0sMEJHb09TLEVIbk9WO0VBaUxMO0lBbExNLDBCRzRRUyxFSDNRVjtFQWdOTDtJQWpOTSwwQkdxVFMsRUhwVFY7RUErT0w7SUFoUE0sMEJHNlZTLEVINVZWO0VBOFFMO0lBL1FNLDBCR3VZUyxFSHRZVjtFQTZTTDtJQTlTTSwwQkc4YVMsRUg3YVY7RUE0VUw7SUE3VU0sMEJHcWRTLEVIcGRWO0VBMldMO0lBNVdNLDBCRzJmUyxFSDFmVjtFQTBZTDtJQTNZTSwwQkdvaUJTLEVIbmlCVjtFQXlhTDtJQTFhTSwwQkdxa0JTLEVIcGtCVjtFQXdjTDtJQXpjTSwwQkdxbUJTLEVIcG1CVjtFQTZlTDtJQWphSSxnREMxSnFEO0lEMkpyRCx3QkN2Sm9EO0lEd0pwRCwyQkMvSnFELEVEZ0t0RCxFQS9FRTs7QUk0RUg7RUpvWkY7SUFqYkksc0NDN0hxRCxFRG1JdEQ7SUE2YUQ7TUEvYUksMkJDbkltRCxFRG9JcEQ7SUE4YUg7TUEvYUksMkJDbkltRCxFRG9JcEQ7SUE4YUg7TUEvYUksMkJDbkltRCxFRG9JcEQ7SUE4YUg7TUEvYUksMkJDbkltRCxFRG9JcEQiLCJmaWxlIjoiYXNzZXRzL3N0eWxlc2hlZXRzL2FwcGxpY2F0aW9uLXBhbGV0dGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLy8vL1xuLy8vIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbi8vL1xuLy8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLFxuLy8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb25cbi8vLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSxcbi8vLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGVcbi8vLyBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy8vXG4vLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vL1xuLy8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTExcbi8vLyBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4vLy8gRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUlxuLy8vIERFQUxJTkdTXG4vLy8vXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIERlcGVuZGVuY2llc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5AaW1wb3J0IFwibW9kdWxhcnNjYWxlXCI7XG5AaW1wb3J0IFwibWF0ZXJpYWwtY29sb3JcIjtcbkBpbXBvcnQgXCJtYXRlcmlhbC1zaGFkb3dzXCI7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIExvY2FsIGltcG9ydHNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuQGltcG9ydCBcImhlbHBlcnMvYnJlYWtcIjtcbkBpbXBvcnQgXCJoZWxwZXJzL3B4MmVtXCI7XG5cbkBpbXBvcnQgXCJjb25maWdcIjtcblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUnVsZXNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gQ29sb3IgdGlsZSBmb3IgcHJlc2VudGF0aW9uIGluIHRoZW1lIGRvY3VtZW50YXRpb25cbmJ1dHRvbltkYXRhLW1kLWNvbG9yLXByaW1hcnldLFxuYnV0dG9uW2RhdGEtbWQtY29sb3ItYWNjZW50XSB7XG4gIHdpZHRoOiAxM3JlbTtcbiAgbWFyZ2luLWJvdHRvbTogMC40cmVtO1xuICBwYWRkaW5nOiAyLjRyZW0gMC44cmVtIDAuNHJlbTtcbiAgdHJhbnNpdGlvbjpcbiAgICBiYWNrZ3JvdW5kLWNvbG9yIDAuMjVzLFxuICAgIG9wYWNpdHkgICAgICAgICAgMC4yNXM7XG4gIGJvcmRlci1yYWRpdXM6IDAuMnJlbTtcbiAgY29sb3I6ICRtZC1jb2xvci13aGl0ZTtcbiAgZm9udC1zaXplOiBtcygtMSk7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG4gIGN1cnNvcjogcG9pbnRlcjtcblxuICAvLyBIb3ZlcmVkIGNvbG9yIHRpbGVcbiAgJjpob3ZlciB7XG4gICAgb3BhY2l0eTogMC43NTtcbiAgfVxufVxuXG4vLyBCdWlsZCBwcmltYXJ5IGNvbG9yc1xuQGVhY2ggJG5hbWUsICRjb2xvciBpbiAoXG4gIFwicmVkXCI6ICAgICAgICAgJGNsci1yZWQtNDAwLFxuICBcInBpbmtcIjogICAgICAgICRjbHItcGluay01MDAsXG4gIFwicHVycGxlXCI6ICAgICAgJGNsci1wdXJwbGUtNDAwLFxuICBcImRlZXAtcHVycGxlXCI6ICRjbHItZGVlcC1wdXJwbGUtNDAwLFxuICBcImluZGlnb1wiOiAgICAgICRjbHItaW5kaWdvLTUwMCxcbiAgXCJibHVlXCI6ICAgICAgICAkY2xyLWJsdWUtNTAwLFxuICBcImxpZ2h0LWJsdWVcIjogICRjbHItbGlnaHQtYmx1ZS01MDAsXG4gIFwiY3lhblwiOiAgICAgICAgJGNsci1jeWFuLTUwMCxcbiAgXCJ0ZWFsXCI6ICAgICAgICAkY2xyLXRlYWwtNTAwLFxuICBcImdyZWVuXCI6ICAgICAgICRjbHItZ3JlZW4tNTAwLFxuICBcImxpZ2h0LWdyZWVuXCI6ICRjbHItbGlnaHQtZ3JlZW4tNjAwLFxuICBcImxpbWVcIjogICAgICAgICRjbHItbGltZS02MDAsXG4gIFwieWVsbG93XCI6ICAgICAgJGNsci15ZWxsb3ctODAwLFxuICBcImFtYmVyXCI6ICAgICAgICRjbHItYW1iZXItNzAwLFxuICBcIm9yYW5nZVwiOiAgICAgICRjbHItb3JhbmdlLTYwMCxcbiAgXCJkZWVwLW9yYW5nZVwiOiAkY2xyLWRlZXAtb3JhbmdlLTQwMCxcbiAgXCJicm93blwiOiAgICAgICAkY2xyLWJyb3duLTUwMCxcbiAgXCJncmV5XCI6ICAgICAgICAkY2xyLWdyZXktNjAwLFxuICBcImJsdWUtZ3JleVwiOiAgICRjbHItYmx1ZS1ncmV5LTYwMFxuKSB7XG5cbiAgLy8gQ29sb3IgdGlsZSBmb3IgcHJlc2VudGF0aW9uIGluIHRoZW1lIGRvY3VtZW50YXRpb25cbiAgYnV0dG9uW2RhdGEtbWQtY29sb3ItcHJpbWFyeT1cIiN7JG5hbWV9XCJdIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3I7XG4gIH1cblxuICAvLyBDb2xvciBwYWxldHRlXG4gIFtkYXRhLW1kLWNvbG9yLXByaW1hcnk9XCIjeyRuYW1lfVwiXSB7XG5cbiAgICAvLyBMaW5rcyBpbiB0eXBlc2V0dGVkIGNvbnRlbnRcbiAgICAubWQtdHlwZXNldCBhIHtcbiAgICAgIGNvbG9yOiAkY29sb3I7XG4gICAgfVxuXG4gICAgLy8gQXBwbGljYXRpb24gaGVhZGVyIChzdGF5cyBhbHdheXMgb24gdG9wKVxuICAgIC5tZC1oZWFkZXIge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yO1xuICAgIH1cblxuICAgIC8vIEhlcm8gdGVhc2VyXG4gICAgLm1kLWhlcm8ge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yO1xuICAgIH1cblxuICAgIC8vIEN1cnJlbnQgb3IgYWN0aXZlIGxpbmtcbiAgICAubWQtbmF2X19saW5rOmFjdGl2ZSxcbiAgICAubWQtbmF2X19saW5rLS1hY3RpdmUge1xuICAgICAgY29sb3I6ICRjb2xvcjtcbiAgICB9XG5cbiAgICAvLyBSZXNldCBhY3RpdmUgY29sb3IgZm9yIG5lc3RlZCBsaXN0IHRpdGxlc1xuICAgIC5tZC1uYXZfX2l0ZW0tLW5lc3RlZCA+IC5tZC1uYXZfX2xpbmsge1xuICAgICAgY29sb3I6IGluaGVyaXQ7XG4gICAgfVxuXG4gICAgLy8gW3RhYmxldCBwb3J0cmFpdCAtXTogTGF5ZXJlZCBuYXZpZ2F0aW9uXG4gICAgQGluY2x1ZGUgYnJlYWstdG8tZGV2aWNlKHRhYmxldCBwb3J0cmFpdCkge1xuXG4gICAgICAvLyBSZXBvc2l0b3J5IGNvbnRhaW5pbmcgc291cmNlXG4gICAgICAubWQtbmF2X19zb3VyY2Uge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBtaXgoJGNvbG9yLCAkbWQtY29sb3ItYmxhY2ssIDc1JSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gW3RhYmxldCAtXTogTGF5ZXJlZCBuYXZpZ2F0aW9uXG4gICAgQGluY2x1ZGUgYnJlYWstdG8tZGV2aWNlKHRhYmxldCkge1xuXG4gICAgICAvLyBTaXRlIHRpdGxlIGluIG1haW4gbmF2aWdhdGlvblxuICAgICAgaHRtbCAmIC5tZC1uYXYtLXByaW1hcnkgLm1kLW5hdl9fdGl0bGUtLXNpdGUge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3I7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gW3NjcmVlbiArXTogU2V0IGJhY2tncm91bmQgY29sb3IgZm9yIHRhYnNcbiAgICBAaW5jbHVkZSBicmVhay1mcm9tLWRldmljZShzY3JlZW4pIHtcblxuICAgICAgLy8gVGFicyB3aXRoIG91dGxpbmVcbiAgICAgIC5tZC10YWJzIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogJGNvbG9yO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vLyBDb2xvciB0aWxlIGZvciBwcmVzZW50YXRpb24gaW4gdGhlbWUgZG9jdW1lbnRhdGlvblxuYnV0dG9uW2RhdGEtbWQtY29sb3ItcHJpbWFyeT1cIndoaXRlXCJdIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogJG1kLWNvbG9yLXdoaXRlO1xuICBjb2xvcjogJG1kLWNvbG9yLWJsYWNrO1xuICBib3gtc2hhZG93OiAwIDAgMC4xcmVtICRtZC1jb2xvci1ibGFjay0tbGlnaHQgaW5zZXQ7XG59XG5cbi8vIE92ZXJyaWRlcyBmb3Igd2hpdGUgY29sb3JcbltkYXRhLW1kLWNvbG9yLXByaW1hcnk9XCJ3aGl0ZVwiXSB7XG5cbiAgLy8gQXBwbGljYXRpb24gaGVhZGVyIChzdGF5cyBhbHdheXMgb24gdG9wKVxuICAubWQtaGVhZGVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQtY29sb3Itd2hpdGU7XG4gICAgY29sb3I6ICRtZC1jb2xvci1ibGFjaztcbiAgfVxuXG4gIC8vIEhlcm8gdGVhc2VyXG4gIC5tZC1oZXJvIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQtY29sb3Itd2hpdGU7XG4gICAgY29sb3I6ICRtZC1jb2xvci1ibGFjaztcblxuICAgIC8vIEFkZCBhIGJvcmRlciBpZiB0aGVyZSBhcmUgbm8gdGFic1xuICAgICYtLWV4cGFuZCB7XG4gICAgICBib3JkZXItYm90dG9tOiAwLjFyZW0gc29saWQgJG1kLWNvbG9yLWJsYWNrLS1saWdodGVzdDtcbiAgICB9XG4gIH1cblxuICAvLyBbdGFibGV0IHBvcnRyYWl0IC1dOiBMYXllcmVkIG5hdmlnYXRpb25cbiAgQGluY2x1ZGUgYnJlYWstdG8tZGV2aWNlKHRhYmxldCBwb3J0cmFpdCkge1xuXG4gICAgLy8gUmVwb3NpdG9yeSBjb250YWluaW5nIHNvdXJjZVxuICAgIC5tZC1uYXZfX3NvdXJjZSB7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQtY29sb3ItYmxhY2stLWxpZ2h0ZXN0O1xuICAgICAgY29sb3I6ICRtZC1jb2xvci1ibGFjaztcbiAgICB9XG4gIH1cblxuICAvLyBbdGFibGV0IHBvcnRyYWl0ICtdOiBDaGFuZ2UgY29sb3Igb2Ygc2VhcmNoIGlucHV0XG4gIEBpbmNsdWRlIGJyZWFrLWZyb20tZGV2aWNlKHRhYmxldCBsYW5kc2NhcGUpIHtcblxuICAgIC8vIFNlYXJjaCBpbnB1dFxuICAgIC5tZC1zZWFyY2hfX2lucHV0IHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2xvci1ibGFjay0tbGlnaHRlc3Q7XG5cbiAgICAgIC8vIFNlYXJjaCBpbnB1dCBwbGFjZWhvbGRlclxuICAgICAgJjo6cGxhY2Vob2xkZXIge1xuICAgICAgICBjb2xvcjogJG1kLWNvbG9yLWJsYWNrLS1saWdodDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBbdGFibGV0IC1dOiBMYXllcmVkIG5hdmlnYXRpb25cbiAgQGluY2x1ZGUgYnJlYWstdG8tZGV2aWNlKHRhYmxldCkge1xuXG4gICAgLy8gU2l0ZSB0aXRsZSBpbiBtYWluIG5hdmlnYXRpb25cbiAgICBodG1sICYgLm1kLW5hdi0tcHJpbWFyeSAubWQtbmF2X190aXRsZS0tc2l0ZSB7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQtY29sb3Itd2hpdGU7XG4gICAgICBjb2xvcjogJG1kLWNvbG9yLWJsYWNrO1xuICAgIH1cblxuICAgIC8vIEhlcm8gdGVhc2VyXG4gICAgLm1kLWhlcm8ge1xuICAgICAgYm9yZGVyLWJvdHRvbTogMC4xcmVtIHNvbGlkICRtZC1jb2xvci1ibGFjay0tbGlnaHRlc3Q7XG4gICAgfVxuICB9XG5cbiAgLy8gW3NjcmVlbiArXTogU2V0IGJhY2tncm91bmQgY29sb3IgZm9yIHRhYnNcbiAgQGluY2x1ZGUgYnJlYWstZnJvbS1kZXZpY2Uoc2NyZWVuKSB7XG5cbiAgICAvLyBUYWJzIHdpdGggb3V0bGluZVxuICAgIC5tZC10YWJzIHtcbiAgICAgIGJvcmRlci1ib3R0b206IDAuMXJlbSBzb2xpZCAkbWQtY29sb3ItYmxhY2stLWxpZ2h0ZXN0O1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogJG1kLWNvbG9yLXdoaXRlO1xuICAgICAgY29sb3I6ICRtZC1jb2xvci1ibGFjaztcbiAgICB9XG4gIH1cbn1cblxuLy8gQnVpbGQgYWNjZW50IGNvbG9yc1xuQGVhY2ggJG5hbWUsICRjb2xvciBpbiAoXG4gIFwicmVkXCI6ICAgICAgICAgJGNsci1yZWQtYTQwMCxcbiAgXCJwaW5rXCI6ICAgICAgICAkY2xyLXBpbmstYTQwMCxcbiAgXCJwdXJwbGVcIjogICAgICAkY2xyLXB1cnBsZS1hMjAwLFxuICBcImRlZXAtcHVycGxlXCI6ICRjbHItZGVlcC1wdXJwbGUtYTIwMCxcbiAgXCJpbmRpZ29cIjogICAgICAkY2xyLWluZGlnby1hMjAwLFxuICBcImJsdWVcIjogICAgICAgICRjbHItYmx1ZS1hMjAwLFxuICBcImxpZ2h0LWJsdWVcIjogICRjbHItbGlnaHQtYmx1ZS1hNzAwLFxuICBcImN5YW5cIjogICAgICAgICRjbHItY3lhbi1hNzAwLFxuICBcInRlYWxcIjogICAgICAgICRjbHItdGVhbC1hNzAwLFxuICBcImdyZWVuXCI6ICAgICAgICRjbHItZ3JlZW4tYTcwMCxcbiAgXCJsaWdodC1ncmVlblwiOiAkY2xyLWxpZ2h0LWdyZWVuLWE3MDAsXG4gIFwibGltZVwiOiAgICAgICAgJGNsci1saW1lLWE3MDAsXG4gIFwieWVsbG93XCI6ICAgICAgJGNsci15ZWxsb3ctYTcwMCxcbiAgXCJhbWJlclwiOiAgICAgICAkY2xyLWFtYmVyLWE3MDAsXG4gIFwib3JhbmdlXCI6ICAgICAgJGNsci1vcmFuZ2UtYTQwMCxcbiAgXCJkZWVwLW9yYW5nZVwiOiAkY2xyLWRlZXAtb3JhbmdlLWEyMDBcbikge1xuXG4gIC8vIENvbG9yIHRpbGUgZm9yIHByZXNlbnRhdGlvbiBpbiB0aGVtZSBkb2N1bWVudGF0aW9uXG4gIGJ1dHRvbltkYXRhLW1kLWNvbG9yLWFjY2VudD1cIiN7JG5hbWV9XCJdIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3I7XG4gIH1cblxuICAvLyBDb2xvciBwYWxldHRlXG4gIFtkYXRhLW1kLWNvbG9yLWFjY2VudD1cIiN7JG5hbWV9XCJdIHtcblxuICAgIC8vIFR5cGVzZXR0ZWQgY29udGVudFxuICAgIC5tZC10eXBlc2V0IHtcblxuICAgICAgLy8gSG92ZXJlZCBhbmQgYWN0aXZlIGxpbmtzXG4gICAgICBhOmhvdmVyLFxuICAgICAgYTphY3RpdmUge1xuICAgICAgICBjb2xvcjogJGNvbG9yO1xuICAgICAgfVxuXG4gICAgICAvLyBIb3ZlcmVkIHNjcm9sbGJhciB0aHVtYlxuICAgICAgcHJlIGNvZGU6Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1iOmhvdmVyLFxuICAgICAgLmNvZGVoaWxpdGUgcHJlOjotd2Via2l0LXNjcm9sbGJhci10aHVtYjpob3ZlciB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcjtcbiAgICAgIH1cblxuICAgICAgLy8gQ29weSB0byBjbGlwYm9hcmQgYWN0aXZlIGljb25cbiAgICAgIC5tZC1jbGlwYm9hcmQ6aG92ZXI6OmJlZm9yZSxcbiAgICAgIC5tZC1jbGlwYm9hcmQ6YWN0aXZlOjpiZWZvcmUge1xuICAgICAgICBjb2xvcjogJGNvbG9yO1xuICAgICAgfVxuXG4gICAgICAvLyBBY3RpdmUgb3IgdGFyZ2V0ZWQgYmFjayByZWZlcmVuY2VcbiAgICAgIC5mb290bm90ZSBsaTpob3ZlciAgLmZvb3Rub3RlLWJhY2tyZWY6aG92ZXIsXG4gICAgICAuZm9vdG5vdGUgbGk6dGFyZ2V0IC5mb290bm90ZS1iYWNrcmVmIHtcbiAgICAgICAgY29sb3I6ICRjb2xvcjtcbiAgICAgIH1cblxuICAgICAgLy8gQWN0aXZlLCB0YXJnZXRlZCBvciBmb2N1c2VkIHBlcm1hbGlua1xuICAgICAgW2lkXTpob3ZlciAgLmhlYWRlcmxpbms6aG92ZXIsXG4gICAgICBbaWRdOnRhcmdldCAuaGVhZGVybGluayxcbiAgICAgIFtpZF0gLmhlYWRlcmxpbms6Zm9jdXMge1xuICAgICAgICBjb2xvcjogJGNvbG9yO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEZvY3VzZWQgb3IgaG92ZXJlZCBsaW5rXG4gICAgLm1kLW5hdl9fbGluazpmb2N1cyxcbiAgICAubWQtbmF2X19saW5rOmhvdmVyIHtcbiAgICAgIGNvbG9yOiAkY29sb3I7XG4gICAgfVxuXG4gICAgLy8gU2VhcmNoIGNvbnRhaW5lciBzY3JvbGxiYXIgdGh1bWJcbiAgICAubWQtc2VhcmNoX19zY3JvbGx3cmFwOjotd2Via2l0LXNjcm9sbGJhci10aHVtYjpob3ZlciB7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3I7XG4gICAgfVxuXG4gICAgLy8gU2VhcmNoIHJlc3VsdCBsaW5rXG4gICAgLm1kLXNlYXJjaC1yZXN1bHRfX2xpbmsge1xuXG4gICAgICAvLyBBY3RpdmUgb3IgaG92ZXJlZCBsaW5rXG4gICAgICAmW2RhdGEtbWQtc3RhdGU9XCJhY3RpdmVcIl0sXG4gICAgICAmOmhvdmVyIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnRpemUoJGNvbG9yLCAwLjkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFdyYXBwZXIgZm9yIHNjcm9sbGluZyBvbiBvdmVyZmxvd1xuICAgIC5tZC1zaWRlYmFyX19zY3JvbGx3cmFwOjotd2Via2l0LXNjcm9sbGJhci10aHVtYjpob3ZlciB7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkY29sb3I7XG4gICAgfVxuXG4gICAgLy8gU291cmNlIGZpbGUgaWNvblxuICAgIC5tZC1zb3VyY2UtZmlsZTpob3Zlcjo6YmVmb3JlIHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2xvcjtcbiAgICB9XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvYXBwbGljYXRpb24tcGFsZXR0ZS5zY3NzIiwiLy8vL1xuLy8vIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbi8vL1xuLy8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLFxuLy8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb25cbi8vLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSxcbi8vLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGVcbi8vLyBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy8vXG4vLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vL1xuLy8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTExcbi8vLyBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4vLy8gRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUlxuLy8vIERFQUxJTkdTXG4vLy8vXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFZhcmlhYmxlczogdHlwb2dyYXBoeVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBNb2R1bGFyIHR5cG9ncmFwaGljIHNjYWxlXG4kbXMtYmFzZTogMS42cmVtO1xuJG1zLXJhdGlvOiAkbWFqb3ItdGhpcmQ7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFZhcmlhYmxlczogYnJlYWtwb2ludHNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gc3R5bGVsaW50LWRpc2FibGUgdW5pdC13aGl0ZWxpc3RcblxuLy8gRGV2aWNlLXNwZWNpZmljIGJyZWFrcG9pbnRzXG4kYnJlYWstZGV2aWNlczogKFxuICBtb2JpbGU6IChcbiAgICBwb3J0cmFpdDogIHB4MmVtKDIyMHB4KSAgcHgyZW0oNDc5cHgpLFxuICAgIGxhbmRzY2FwZTogcHgyZW0oNDgwcHgpICBweDJlbSg3MTlweClcbiAgKSxcbiAgdGFibGV0OiAoXG4gICAgcG9ydHJhaXQ6ICBweDJlbSg3MjBweCkgIHB4MmVtKDk1OXB4KSxcbiAgICBsYW5kc2NhcGU6IHB4MmVtKDk2MHB4KSAgcHgyZW0oMTIxOXB4KVxuICApLFxuICBzY3JlZW46IChcbiAgICBzbWFsbDogICAgIHB4MmVtKDEyMjBweCkgcHgyZW0oMTU5OXB4KSxcbiAgICBtZWRpdW06ICAgIHB4MmVtKDE2MDBweCkgcHgyZW0oMTk5OXB4KSxcbiAgICBsYXJnZTogICAgIHB4MmVtKDIwMDBweClcbiAgKVxuKTtcblxuLy8gc3R5bGVsaW50LWVuYWJsZSB1bml0LXdoaXRlbGlzdFxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBWYXJpYWJsZXM6IGJhc2UgY29sb3JzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIFByaW1hcnkgYW5kIGFjY2VudCBjb2xvcnNcbiRtZC1jb2xvci1wcmltYXJ5OiAgICAgICAgICAgICAgICAgICAgJGNsci1pbmRpZ28tNTAwICFkZWZhdWx0O1xuJG1kLWNvbG9yLWFjY2VudDogICAgICAgICAgICAgICAgICAgICAkY2xyLWluZGlnby1hMjAwICFkZWZhdWx0O1xuXG4vLyBTaGFkZXMgb2YgYmxhY2tcbiRtZC1jb2xvci1ibGFjazogICAgICAgICAgICAgICAgICAgICAgaHNsYSgwLCAwJSwgMCUsIDAuODcpICFkZWZhdWx0O1xuJG1kLWNvbG9yLWJsYWNrLS1saWdodDogICAgICAgICAgICAgICBoc2xhKDAsIDAlLCAwJSwgMC41NCkgIWRlZmF1bHQ7XG4kbWQtY29sb3ItYmxhY2stLWxpZ2h0ZXI6ICAgICAgICAgICAgIGhzbGEoMCwgMCUsIDAlLCAwLjI2KSAhZGVmYXVsdDtcbiRtZC1jb2xvci1ibGFjay0tbGlnaHRlc3Q6ICAgICAgICAgICAgaHNsYSgwLCAwJSwgMCUsIDAuMDcpICFkZWZhdWx0O1xuJG1kLWNvbG9yLWJsYWNrLS10cmFuc3BhcmVudDogICAgICAgICBoc2xhKDAsIDAlLCAwJSwgMCkgIWRlZmF1bHQ7XG5cbi8vIFNoYWRlcyBvZiB3aGl0ZVxuJG1kLWNvbG9yLXdoaXRlOiAgICAgICAgICAgICAgICAgICAgICBoc2xhKDAsIDAlLCAxMDAlLCAxKSAhZGVmYXVsdDtcbiRtZC1jb2xvci13aGl0ZS0tbGlnaHQ6ICAgICAgICAgICAgICAgaHNsYSgwLCAwJSwgMTAwJSwgMC43KSAhZGVmYXVsdDtcbiRtZC1jb2xvci13aGl0ZS0tbGlnaHRlcjogICAgICAgICAgICAgaHNsYSgwLCAwJSwgMTAwJSwgMC4zKSAhZGVmYXVsdDtcbiRtZC1jb2xvci13aGl0ZS0tbGlnaHRlc3Q6ICAgICAgICAgICAgaHNsYSgwLCAwJSwgMTAwJSwgMC4xMikgIWRlZmF1bHQ7XG4kbWQtY29sb3Itd2hpdGUtLXRyYW5zcGFyZW50OiAgICAgICAgIGhzbGEoMCwgMCUsIDEwMCUsIDApICFkZWZhdWx0O1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBWYXJpYWJsZXM6IHNpemluZyBhbmQgc3BhY2luZ1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBJY29uc1xuJG1kLWljb24tc2l6ZTogICAgICAgICAgICAgICAgICAgICAgICAkbXMtYmFzZSAqIDEuNTtcbiRtZC1pY29uLXBhZGRpbmc6ICAgICAgICAgICAgICAgICAgICAgJG1zLWJhc2UgKiAwLjU7XG4kbWQtaWNvbi1tYXJnaW46ICAgICAgICAgICAgICAgICAgICAgICRtcy1iYXNlICogMC4yNTtcblxuLy8gQ29kZSBibG9ja3NcbiRtZC1jb2RlLWJhY2tncm91bmQ6ICAgICAgICAgICAgICAgICAgaHNsYSgwLCAwJSwgOTIuNSUsIDAuNSk7XG4kbWQtY29kZS1jb2xvcjogICAgICAgICAgICAgICAgICAgICAgICMzNzQ3NEY7XG5cbi8vIEtleXN0cm9rZXNcbiRtZC1rZXlib2FyZC1iYWNrZ3JvdW5kOiAgICAgICAgICAgICAgI0ZDRkNGQztcbiRtZC1rZXlib2FyZC1jb2xvcjogICAgICAgICAgICAgICAgICAgIzU1NTU1NTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvX2NvbmZpZy5zY3NzIiwiQGZ1bmN0aW9uIG1zLWZ1bmN0aW9uKCR2OiAwLCAkYmFzZTogZmFsc2UsICRyYXRpbzogZmFsc2UsICR0aHJlYWQ6IGZhbHNlLCAkc2V0dGluZ3M6ICRtb2R1bGFyc2NhbGUpIHtcblxuICAvLyBQYXJzZSBzZXR0aW5nc1xuICAkbXMtc2V0dGluZ3M6IG1zLXNldHRpbmdzKCRiYXNlLCRyYXRpbywkdGhyZWFkLCRzZXR0aW5ncyk7XG4gICRiYXNlOiBudGgoJG1zLXNldHRpbmdzLCAxKTtcbiAgJHJhdGlvOiBudGgoJG1zLXNldHRpbmdzLCAyKTtcblxuICAvLyBSZW5kZXIgdGFyZ2V0IHZhbHVlcyBmcm9tIHNldHRpbmdzLlxuICBAaWYgdW5pdCgkcmF0aW8pICE9ICcnIHtcbiAgICAkcmF0aW86IG1zLXRhcmdldCgkcmF0aW8sJGJhc2UpXG4gIH1cblxuICAvLyBGYXN0IGNhbGMgaWYgbm90IG11bHRpIHN0cmFuZGVkXG4gIEBpZihsZW5ndGgoJGJhc2UpID09IDEpIHtcbiAgICBAcmV0dXJuIG1zLXBvdygkcmF0aW8sICR2KSAqICRiYXNlO1xuICB9XG5cbiAgLy8gQ3JlYXRlIG5ldyBiYXNlIGFycmF5XG4gICRtcy1iYXNlczogbnRoKCRiYXNlLDEpO1xuXG4gIC8vIE5vcm1hbGl6ZSBiYXNlIHZhbHVlc1xuICBAZm9yICRpIGZyb20gMiB0aHJvdWdoIGxlbmd0aCgkYmFzZSkge1xuICAgIC8vIGluaXRpYWwgYmFzZSB2YWx1ZVxuICAgICRtcy1iYXNlOiBudGgoJGJhc2UsJGkpO1xuICAgIC8vIElmIHRoZSBiYXNlIGlzIGJpZ2dlciB0aGFuIHRoZSBtYWluIGJhc2VcbiAgICBAaWYoJG1zLWJhc2UgPiBudGgoJGJhc2UsMSkpIHtcbiAgICAgIC8vIGRpdmlkZSB0aGUgdmFsdWUgdW50aWwgaXQgYWxpZ25zIHdpdGggbWFpbiBiYXNlLlxuICAgICAgQHdoaWxlKCRtcy1iYXNlID4gbnRoKCRiYXNlLDEpKSB7XG4gICAgICAgICRtcy1iYXNlOiAkbXMtYmFzZSAvICRyYXRpbztcbiAgICAgIH1cbiAgICAgICRtcy1iYXNlOiAkbXMtYmFzZSAqICRyYXRpbztcbiAgICB9XG4gICAgLy8gSWYgdGhlIGJhc2UgaXMgc21hbGxlciB0aGFuIHRoZSBtYWluIGJhc2UuXG4gICAgQGVsc2UgaWYgKCRtcy1iYXNlIDwgbnRoKCRiYXNlLDEpKSB7XG4gICAgICAvLyBwdW1wIHVwIHRoZSB2YWx1ZSB1bnRpbCBpdCBhbGlnbnMgd2l0aCBtYWluIGJhc2UuXG4gICAgICBAd2hpbGUgJG1zLWJhc2UgPCBudGgoJGJhc2UsMSkge1xuICAgICAgICAkbXMtYmFzZTogJG1zLWJhc2UgKiAkcmF0aW87XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFB1c2ggaW50byBuZXcgYXJyYXlcbiAgICAkbXMtYmFzZXM6IGFwcGVuZCgkbXMtYmFzZXMsJG1zLWJhc2UpO1xuICB9XG5cbiAgLy8gU29ydCBhcnJheSBmcm9tIHNtYWxsZXN0IHRvIGxhcmdlc3QuXG4gICRtcy1iYXNlczogbXMtc29ydCgkbXMtYmFzZXMpO1xuXG4gIC8vIEZpbmQgc3RlcCB0byB1c2UgaW4gY2FsY3VsYXRpb25cbiAgJHZ0ZXA6IGZsb29yKCR2IC8gbGVuZ3RoKCRtcy1iYXNlcykpO1xuICAvLyBGaW5kIGJhc2UgdG8gdXNlIGluIGNhbGN1bGF0aW9uXG4gICRtcy1iYXNlOiByb3VuZCgoJHYgLyBsZW5ndGgoJG1zLWJhc2VzKSAtICR2dGVwKSAqIGxlbmd0aCgkbXMtYmFzZXMpKSArIDE7XG5cbiAgQHJldHVybiBtcy1wb3coJHJhdGlvLCAkdnRlcCkgKiBudGgoJG1zLWJhc2VzLCRtcy1iYXNlKTtcbn1cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9ub2RlX21vZHVsZXMvbW9kdWxhcnNjYWxlLXNhc3Mvc3R5bGVzaGVldHMvbW9kdWxhcnNjYWxlL19mdW5jdGlvbi5zY3NzIiwiLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vXG4vLyBOYW1lOiAgICAgICAgVUkgQ29sb3IgUGFsZXR0ZVxuLy8gRGVzY3JpcHRpb246IFRoZSBjb2xvciBwYWxldHRlIG9mIG1hdGVyaWFsIGRlc2lnbi5cbi8vIFZlcnNpb246ICAgICAyLjMuMVxuLy9cbi8vIEF1dGhvcjogICAgICBEZW5pcyBNYWxpbm9jaGtpblxuLy8gR2l0OiAgICAgICAgIGh0dHBzOi8vZ2l0aHViLmNvbS9tcm1sbmMvbWF0ZXJpYWwtY29sb3Jcbi8vXG4vLyB0d2l0dGVyOiAgICAgQG1ybWxuY1xuLy9cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cblxuLy9cbi8vIExpc3Qgb2YgYmFzZSBjb2xvcnNcbi8vXG5cbi8vICRjbHItcmVkXG4vLyAkY2xyLXBpbmtcbi8vICRjbHItcHVycGxlXG4vLyAkY2xyLWRlZXAtcHVycGxlXG4vLyAkY2xyLWluZGlnb1xuLy8gJGNsci1ibHVlXG4vLyAkY2xyLWxpZ2h0LWJsdWVcbi8vICRjbHItY3lhblxuLy8gJGNsci10ZWFsXG4vLyAkY2xyLWdyZWVuXG4vLyAkY2xyLWxpZ2h0LWdyZWVuXG4vLyAkY2xyLWxpbWVcbi8vICRjbHIteWVsbG93XG4vLyAkY2xyLWFtYmVyXG4vLyAkY2xyLW9yYW5nZVxuLy8gJGNsci1kZWVwLW9yYW5nZVxuLy8gJGNsci1icm93blxuLy8gJGNsci1ncmV5XG4vLyAkY2xyLWJsdWUtZ3JleVxuLy8gJGNsci1ibGFja1xuLy8gJGNsci13aGl0ZVxuXG5cbi8vXG4vLyBSZWRcbi8vXG5cbiRjbHItcmVkLWxpc3Q6IChcbiAgXCJiYXNlXCI6ICNmNDQzMzYsXG4gIFwiNTBcIjogICAjZmZlYmVlLFxuICBcIjEwMFwiOiAgI2ZmY2RkMixcbiAgXCIyMDBcIjogICNlZjlhOWEsXG4gIFwiMzAwXCI6ICAjZTU3MzczLFxuICBcIjQwMFwiOiAgI2VmNTM1MCxcbiAgXCI1MDBcIjogICNmNDQzMzYsXG4gIFwiNjAwXCI6ICAjZTUzOTM1LFxuICBcIjcwMFwiOiAgI2QzMmYyZixcbiAgXCI4MDBcIjogICNjNjI4MjgsXG4gIFwiOTAwXCI6ICAjYjcxYzFjLFxuICBcImExMDBcIjogI2ZmOGE4MCxcbiAgXCJhMjAwXCI6ICNmZjUyNTIsXG4gIFwiYTQwMFwiOiAjZmYxNzQ0LFxuICBcImE3MDBcIjogI2Q1MDAwMFxuKTtcblxuJGNsci1yZWQ6ICAgICAgbWFwLWdldCgkY2xyLXJlZC1saXN0LCBcImJhc2VcIik7XG5cbiRjbHItcmVkLTUwOiAgIG1hcC1nZXQoJGNsci1yZWQtbGlzdCwgXCI1MFwiKTtcbiRjbHItcmVkLTEwMDogIG1hcC1nZXQoJGNsci1yZWQtbGlzdCwgXCIxMDBcIik7XG4kY2xyLXJlZC0yMDA6ICBtYXAtZ2V0KCRjbHItcmVkLWxpc3QsIFwiMjAwXCIpO1xuJGNsci1yZWQtMzAwOiAgbWFwLWdldCgkY2xyLXJlZC1saXN0LCBcIjMwMFwiKTtcbiRjbHItcmVkLTQwMDogIG1hcC1nZXQoJGNsci1yZWQtbGlzdCwgXCI0MDBcIik7XG4kY2xyLXJlZC01MDA6ICBtYXAtZ2V0KCRjbHItcmVkLWxpc3QsIFwiNTAwXCIpO1xuJGNsci1yZWQtNjAwOiAgbWFwLWdldCgkY2xyLXJlZC1saXN0LCBcIjYwMFwiKTtcbiRjbHItcmVkLTcwMDogIG1hcC1nZXQoJGNsci1yZWQtbGlzdCwgXCI3MDBcIik7XG4kY2xyLXJlZC04MDA6ICBtYXAtZ2V0KCRjbHItcmVkLWxpc3QsIFwiODAwXCIpO1xuJGNsci1yZWQtOTAwOiAgbWFwLWdldCgkY2xyLXJlZC1saXN0LCBcIjkwMFwiKTtcbiRjbHItcmVkLWExMDA6IG1hcC1nZXQoJGNsci1yZWQtbGlzdCwgXCJhMTAwXCIpO1xuJGNsci1yZWQtYTIwMDogbWFwLWdldCgkY2xyLXJlZC1saXN0LCBcImEyMDBcIik7XG4kY2xyLXJlZC1hNDAwOiBtYXAtZ2V0KCRjbHItcmVkLWxpc3QsIFwiYTQwMFwiKTtcbiRjbHItcmVkLWE3MDA6IG1hcC1nZXQoJGNsci1yZWQtbGlzdCwgXCJhNzAwXCIpO1xuXG5cbi8vXG4vLyBQaW5rXG4vL1xuXG4kY2xyLXBpbmstbGlzdDogKFxuICBcImJhc2VcIjogI2U5MWU2MyxcbiAgXCI1MFwiOiAgICNmY2U0ZWMsXG4gIFwiMTAwXCI6ICAjZjhiYmQwLFxuICBcIjIwMFwiOiAgI2Y0OGZiMSxcbiAgXCIzMDBcIjogICNmMDYyOTIsXG4gIFwiNDAwXCI6ICAjZWM0MDdhLFxuICBcIjUwMFwiOiAgI2U5MWU2MyxcbiAgXCI2MDBcIjogICNkODFiNjAsXG4gIFwiNzAwXCI6ICAjYzIxODViLFxuICBcIjgwMFwiOiAgI2FkMTQ1NyxcbiAgXCI5MDBcIjogICM4ODBlNGYsXG4gIFwiYTEwMFwiOiAjZmY4MGFiLFxuICBcImEyMDBcIjogI2ZmNDA4MSxcbiAgXCJhNDAwXCI6ICNmNTAwNTcsXG4gIFwiYTcwMFwiOiAjYzUxMTYyXG4pO1xuXG4kY2xyLXBpbms6ICAgICAgbWFwLWdldCgkY2xyLXBpbmstbGlzdCwgXCJiYXNlXCIpO1xuXG4kY2xyLXBpbmstNTA6ICAgbWFwLWdldCgkY2xyLXBpbmstbGlzdCwgXCI1MFwiKTtcbiRjbHItcGluay0xMDA6ICBtYXAtZ2V0KCRjbHItcGluay1saXN0LCBcIjEwMFwiKTtcbiRjbHItcGluay0yMDA6ICBtYXAtZ2V0KCRjbHItcGluay1saXN0LCBcIjIwMFwiKTtcbiRjbHItcGluay0zMDA6ICBtYXAtZ2V0KCRjbHItcGluay1saXN0LCBcIjMwMFwiKTtcbiRjbHItcGluay00MDA6ICBtYXAtZ2V0KCRjbHItcGluay1saXN0LCBcIjQwMFwiKTtcbiRjbHItcGluay01MDA6ICBtYXAtZ2V0KCRjbHItcGluay1saXN0LCBcIjUwMFwiKTtcbiRjbHItcGluay02MDA6ICBtYXAtZ2V0KCRjbHItcGluay1saXN0LCBcIjYwMFwiKTtcbiRjbHItcGluay03MDA6ICBtYXAtZ2V0KCRjbHItcGluay1saXN0LCBcIjcwMFwiKTtcbiRjbHItcGluay04MDA6ICBtYXAtZ2V0KCRjbHItcGluay1saXN0LCBcIjgwMFwiKTtcbiRjbHItcGluay05MDA6ICBtYXAtZ2V0KCRjbHItcGluay1saXN0LCBcIjkwMFwiKTtcbiRjbHItcGluay1hMTAwOiBtYXAtZ2V0KCRjbHItcGluay1saXN0LCBcImExMDBcIik7XG4kY2xyLXBpbmstYTIwMDogbWFwLWdldCgkY2xyLXBpbmstbGlzdCwgXCJhMjAwXCIpO1xuJGNsci1waW5rLWE0MDA6IG1hcC1nZXQoJGNsci1waW5rLWxpc3QsIFwiYTQwMFwiKTtcbiRjbHItcGluay1hNzAwOiBtYXAtZ2V0KCRjbHItcGluay1saXN0LCBcImE3MDBcIik7XG5cblxuLy9cbi8vIFB1cnBsZVxuLy9cblxuJGNsci1wdXJwbGUtbGlzdDogKFxuICBcImJhc2VcIjogIzljMjdiMCxcbiAgXCI1MFwiOiAgICNmM2U1ZjUsXG4gIFwiMTAwXCI6ICAjZTFiZWU3LFxuICBcIjIwMFwiOiAgI2NlOTNkOCxcbiAgXCIzMDBcIjogICNiYTY4YzgsXG4gIFwiNDAwXCI6ICAjYWI0N2JjLFxuICBcIjUwMFwiOiAgIzljMjdiMCxcbiAgXCI2MDBcIjogICM4ZTI0YWEsXG4gIFwiNzAwXCI6ICAjN2IxZmEyLFxuICBcIjgwMFwiOiAgIzZhMWI5YSxcbiAgXCI5MDBcIjogICM0YTE0OGMsXG4gIFwiYTEwMFwiOiAjZWE4MGZjLFxuICBcImEyMDBcIjogI2UwNDBmYixcbiAgXCJhNDAwXCI6ICNkNTAwZjksXG4gIFwiYTcwMFwiOiAjYWEwMGZmXG4pO1xuXG4kY2xyLXB1cnBsZTogICAgICBtYXAtZ2V0KCRjbHItcHVycGxlLWxpc3QsIFwiYmFzZVwiKTtcblxuJGNsci1wdXJwbGUtNTA6ICAgbWFwLWdldCgkY2xyLXB1cnBsZS1saXN0LCBcIjUwXCIpO1xuJGNsci1wdXJwbGUtMTAwOiAgbWFwLWdldCgkY2xyLXB1cnBsZS1saXN0LCBcIjEwMFwiKTtcbiRjbHItcHVycGxlLTIwMDogIG1hcC1nZXQoJGNsci1wdXJwbGUtbGlzdCwgXCIyMDBcIik7XG4kY2xyLXB1cnBsZS0zMDA6ICBtYXAtZ2V0KCRjbHItcHVycGxlLWxpc3QsIFwiMzAwXCIpO1xuJGNsci1wdXJwbGUtNDAwOiAgbWFwLWdldCgkY2xyLXB1cnBsZS1saXN0LCBcIjQwMFwiKTtcbiRjbHItcHVycGxlLTUwMDogIG1hcC1nZXQoJGNsci1wdXJwbGUtbGlzdCwgXCI1MDBcIik7XG4kY2xyLXB1cnBsZS02MDA6ICBtYXAtZ2V0KCRjbHItcHVycGxlLWxpc3QsIFwiNjAwXCIpO1xuJGNsci1wdXJwbGUtNzAwOiAgbWFwLWdldCgkY2xyLXB1cnBsZS1saXN0LCBcIjcwMFwiKTtcbiRjbHItcHVycGxlLTgwMDogIG1hcC1nZXQoJGNsci1wdXJwbGUtbGlzdCwgXCI4MDBcIik7XG4kY2xyLXB1cnBsZS05MDA6ICBtYXAtZ2V0KCRjbHItcHVycGxlLWxpc3QsIFwiOTAwXCIpO1xuJGNsci1wdXJwbGUtYTEwMDogbWFwLWdldCgkY2xyLXB1cnBsZS1saXN0LCBcImExMDBcIik7XG4kY2xyLXB1cnBsZS1hMjAwOiBtYXAtZ2V0KCRjbHItcHVycGxlLWxpc3QsIFwiYTIwMFwiKTtcbiRjbHItcHVycGxlLWE0MDA6IG1hcC1nZXQoJGNsci1wdXJwbGUtbGlzdCwgXCJhNDAwXCIpO1xuJGNsci1wdXJwbGUtYTcwMDogbWFwLWdldCgkY2xyLXB1cnBsZS1saXN0LCBcImE3MDBcIik7XG5cblxuLy9cbi8vIERlZXAgcHVycGxlXG4vL1xuXG4kY2xyLWRlZXAtcHVycGxlLWxpc3Q6IChcbiAgXCJiYXNlXCI6ICM2NzNhYjcsXG4gIFwiNTBcIjogICAjZWRlN2Y2LFxuICBcIjEwMFwiOiAgI2QxYzRlOSxcbiAgXCIyMDBcIjogICNiMzlkZGIsXG4gIFwiMzAwXCI6ICAjOTU3NWNkLFxuICBcIjQwMFwiOiAgIzdlNTdjMixcbiAgXCI1MDBcIjogICM2NzNhYjcsXG4gIFwiNjAwXCI6ICAjNWUzNWIxLFxuICBcIjcwMFwiOiAgIzUxMmRhOCxcbiAgXCI4MDBcIjogICM0NTI3YTAsXG4gIFwiOTAwXCI6ICAjMzExYjkyLFxuICBcImExMDBcIjogI2IzODhmZixcbiAgXCJhMjAwXCI6ICM3YzRkZmYsXG4gIFwiYTQwMFwiOiAjNjUxZmZmLFxuICBcImE3MDBcIjogIzYyMDBlYVxuKTtcblxuJGNsci1kZWVwLXB1cnBsZTogICAgICBtYXAtZ2V0KCRjbHItZGVlcC1wdXJwbGUtbGlzdCwgXCJiYXNlXCIpO1xuXG4kY2xyLWRlZXAtcHVycGxlLTUwOiAgIG1hcC1nZXQoJGNsci1kZWVwLXB1cnBsZS1saXN0LCBcIjUwXCIpO1xuJGNsci1kZWVwLXB1cnBsZS0xMDA6ICBtYXAtZ2V0KCRjbHItZGVlcC1wdXJwbGUtbGlzdCwgXCIxMDBcIik7XG4kY2xyLWRlZXAtcHVycGxlLTIwMDogIG1hcC1nZXQoJGNsci1kZWVwLXB1cnBsZS1saXN0LCBcIjIwMFwiKTtcbiRjbHItZGVlcC1wdXJwbGUtMzAwOiAgbWFwLWdldCgkY2xyLWRlZXAtcHVycGxlLWxpc3QsIFwiMzAwXCIpO1xuJGNsci1kZWVwLXB1cnBsZS00MDA6ICBtYXAtZ2V0KCRjbHItZGVlcC1wdXJwbGUtbGlzdCwgXCI0MDBcIik7XG4kY2xyLWRlZXAtcHVycGxlLTUwMDogIG1hcC1nZXQoJGNsci1kZWVwLXB1cnBsZS1saXN0LCBcIjUwMFwiKTtcbiRjbHItZGVlcC1wdXJwbGUtNjAwOiAgbWFwLWdldCgkY2xyLWRlZXAtcHVycGxlLWxpc3QsIFwiNjAwXCIpO1xuJGNsci1kZWVwLXB1cnBsZS03MDA6ICBtYXAtZ2V0KCRjbHItZGVlcC1wdXJwbGUtbGlzdCwgXCI3MDBcIik7XG4kY2xyLWRlZXAtcHVycGxlLTgwMDogIG1hcC1nZXQoJGNsci1kZWVwLXB1cnBsZS1saXN0LCBcIjgwMFwiKTtcbiRjbHItZGVlcC1wdXJwbGUtOTAwOiAgbWFwLWdldCgkY2xyLWRlZXAtcHVycGxlLWxpc3QsIFwiOTAwXCIpO1xuJGNsci1kZWVwLXB1cnBsZS1hMTAwOiBtYXAtZ2V0KCRjbHItZGVlcC1wdXJwbGUtbGlzdCwgXCJhMTAwXCIpO1xuJGNsci1kZWVwLXB1cnBsZS1hMjAwOiBtYXAtZ2V0KCRjbHItZGVlcC1wdXJwbGUtbGlzdCwgXCJhMjAwXCIpO1xuJGNsci1kZWVwLXB1cnBsZS1hNDAwOiBtYXAtZ2V0KCRjbHItZGVlcC1wdXJwbGUtbGlzdCwgXCJhNDAwXCIpO1xuJGNsci1kZWVwLXB1cnBsZS1hNzAwOiBtYXAtZ2V0KCRjbHItZGVlcC1wdXJwbGUtbGlzdCwgXCJhNzAwXCIpO1xuXG5cbi8vXG4vLyBJbmRpZ29cbi8vXG5cbiRjbHItaW5kaWdvLWxpc3Q6IChcbiAgXCJiYXNlXCI6ICMzZjUxYjUsXG4gIFwiNTBcIjogICAjZThlYWY2LFxuICBcIjEwMFwiOiAgI2M1Y2FlOSxcbiAgXCIyMDBcIjogICM5ZmE4ZGEsXG4gIFwiMzAwXCI6ICAjNzk4NmNiLFxuICBcIjQwMFwiOiAgIzVjNmJjMCxcbiAgXCI1MDBcIjogICMzZjUxYjUsXG4gIFwiNjAwXCI6ICAjMzk0OWFiLFxuICBcIjcwMFwiOiAgIzMwM2Y5ZixcbiAgXCI4MDBcIjogICMyODM1OTMsXG4gIFwiOTAwXCI6ICAjMWEyMzdlLFxuICBcImExMDBcIjogIzhjOWVmZixcbiAgXCJhMjAwXCI6ICM1MzZkZmUsXG4gIFwiYTQwMFwiOiAjM2Q1YWZlLFxuICBcImE3MDBcIjogIzMwNGZmZVxuKTtcblxuJGNsci1pbmRpZ286ICAgICAgbWFwLWdldCgkY2xyLWluZGlnby1saXN0LCBcImJhc2VcIik7XG5cbiRjbHItaW5kaWdvLTUwOiAgIG1hcC1nZXQoJGNsci1pbmRpZ28tbGlzdCwgXCI1MFwiKTtcbiRjbHItaW5kaWdvLTEwMDogIG1hcC1nZXQoJGNsci1pbmRpZ28tbGlzdCwgXCIxMDBcIik7XG4kY2xyLWluZGlnby0yMDA6ICBtYXAtZ2V0KCRjbHItaW5kaWdvLWxpc3QsIFwiMjAwXCIpO1xuJGNsci1pbmRpZ28tMzAwOiAgbWFwLWdldCgkY2xyLWluZGlnby1saXN0LCBcIjMwMFwiKTtcbiRjbHItaW5kaWdvLTQwMDogIG1hcC1nZXQoJGNsci1pbmRpZ28tbGlzdCwgXCI0MDBcIik7XG4kY2xyLWluZGlnby01MDA6ICBtYXAtZ2V0KCRjbHItaW5kaWdvLWxpc3QsIFwiNTAwXCIpO1xuJGNsci1pbmRpZ28tNjAwOiAgbWFwLWdldCgkY2xyLWluZGlnby1saXN0LCBcIjYwMFwiKTtcbiRjbHItaW5kaWdvLTcwMDogIG1hcC1nZXQoJGNsci1pbmRpZ28tbGlzdCwgXCI3MDBcIik7XG4kY2xyLWluZGlnby04MDA6ICBtYXAtZ2V0KCRjbHItaW5kaWdvLWxpc3QsIFwiODAwXCIpO1xuJGNsci1pbmRpZ28tOTAwOiAgbWFwLWdldCgkY2xyLWluZGlnby1saXN0LCBcIjkwMFwiKTtcbiRjbHItaW5kaWdvLWExMDA6IG1hcC1nZXQoJGNsci1pbmRpZ28tbGlzdCwgXCJhMTAwXCIpO1xuJGNsci1pbmRpZ28tYTIwMDogbWFwLWdldCgkY2xyLWluZGlnby1saXN0LCBcImEyMDBcIik7XG4kY2xyLWluZGlnby1hNDAwOiBtYXAtZ2V0KCRjbHItaW5kaWdvLWxpc3QsIFwiYTQwMFwiKTtcbiRjbHItaW5kaWdvLWE3MDA6IG1hcC1nZXQoJGNsci1pbmRpZ28tbGlzdCwgXCJhNzAwXCIpO1xuXG5cbi8vXG4vLyBCbHVlXG4vL1xuXG4kY2xyLWJsdWUtbGlzdDogKFxuICBcImJhc2VcIjogIzIxOTZmMyxcbiAgXCI1MFwiOiAgICNlM2YyZmQsXG4gIFwiMTAwXCI6ICAjYmJkZWZiLFxuICBcIjIwMFwiOiAgIzkwY2FmOSxcbiAgXCIzMDBcIjogICM2NGI1ZjYsXG4gIFwiNDAwXCI6ICAjNDJhNWY1LFxuICBcIjUwMFwiOiAgIzIxOTZmMyxcbiAgXCI2MDBcIjogICMxZTg4ZTUsXG4gIFwiNzAwXCI6ICAjMTk3NmQyLFxuICBcIjgwMFwiOiAgIzE1NjVjMCxcbiAgXCI5MDBcIjogICMwZDQ3YTEsXG4gIFwiYTEwMFwiOiAjODJiMWZmLFxuICBcImEyMDBcIjogIzQ0OGFmZixcbiAgXCJhNDAwXCI6ICMyOTc5ZmYsXG4gIFwiYTcwMFwiOiAjMjk2MmZmXG4pO1xuXG4kY2xyLWJsdWU6ICAgICAgbWFwLWdldCgkY2xyLWJsdWUtbGlzdCwgXCJiYXNlXCIpO1xuXG4kY2xyLWJsdWUtNTA6ICAgbWFwLWdldCgkY2xyLWJsdWUtbGlzdCwgXCI1MFwiKTtcbiRjbHItYmx1ZS0xMDA6ICBtYXAtZ2V0KCRjbHItYmx1ZS1saXN0LCBcIjEwMFwiKTtcbiRjbHItYmx1ZS0yMDA6ICBtYXAtZ2V0KCRjbHItYmx1ZS1saXN0LCBcIjIwMFwiKTtcbiRjbHItYmx1ZS0zMDA6ICBtYXAtZ2V0KCRjbHItYmx1ZS1saXN0LCBcIjMwMFwiKTtcbiRjbHItYmx1ZS00MDA6ICBtYXAtZ2V0KCRjbHItYmx1ZS1saXN0LCBcIjQwMFwiKTtcbiRjbHItYmx1ZS01MDA6ICBtYXAtZ2V0KCRjbHItYmx1ZS1saXN0LCBcIjUwMFwiKTtcbiRjbHItYmx1ZS02MDA6ICBtYXAtZ2V0KCRjbHItYmx1ZS1saXN0LCBcIjYwMFwiKTtcbiRjbHItYmx1ZS03MDA6ICBtYXAtZ2V0KCRjbHItYmx1ZS1saXN0LCBcIjcwMFwiKTtcbiRjbHItYmx1ZS04MDA6ICBtYXAtZ2V0KCRjbHItYmx1ZS1saXN0LCBcIjgwMFwiKTtcbiRjbHItYmx1ZS05MDA6ICBtYXAtZ2V0KCRjbHItYmx1ZS1saXN0LCBcIjkwMFwiKTtcbiRjbHItYmx1ZS1hMTAwOiBtYXAtZ2V0KCRjbHItYmx1ZS1saXN0LCBcImExMDBcIik7XG4kY2xyLWJsdWUtYTIwMDogbWFwLWdldCgkY2xyLWJsdWUtbGlzdCwgXCJhMjAwXCIpO1xuJGNsci1ibHVlLWE0MDA6IG1hcC1nZXQoJGNsci1ibHVlLWxpc3QsIFwiYTQwMFwiKTtcbiRjbHItYmx1ZS1hNzAwOiBtYXAtZ2V0KCRjbHItYmx1ZS1saXN0LCBcImE3MDBcIik7XG5cblxuLy9cbi8vIExpZ2h0IEJsdWVcbi8vXG5cbiRjbHItbGlnaHQtYmx1ZS1saXN0OiAoXG4gIFwiYmFzZVwiOiAjMDNhOWY0LFxuICBcIjUwXCI6ICAgI2UxZjVmZSxcbiAgXCIxMDBcIjogICNiM2U1ZmMsXG4gIFwiMjAwXCI6ICAjODFkNGZhLFxuICBcIjMwMFwiOiAgIzRmYzNmNyxcbiAgXCI0MDBcIjogICMyOWI2ZjYsXG4gIFwiNTAwXCI6ICAjMDNhOWY0LFxuICBcIjYwMFwiOiAgIzAzOWJlNSxcbiAgXCI3MDBcIjogICMwMjg4ZDEsXG4gIFwiODAwXCI6ICAjMDI3N2JkLFxuICBcIjkwMFwiOiAgIzAxNTc5YixcbiAgXCJhMTAwXCI6ICM4MGQ4ZmYsXG4gIFwiYTIwMFwiOiAjNDBjNGZmLFxuICBcImE0MDBcIjogIzAwYjBmZixcbiAgXCJhNzAwXCI6ICMwMDkxZWFcbik7XG5cbiRjbHItbGlnaHQtYmx1ZTogICAgICBtYXAtZ2V0KCRjbHItbGlnaHQtYmx1ZS1saXN0LCBcImJhc2VcIik7XG5cbiRjbHItbGlnaHQtYmx1ZS01MDogICBtYXAtZ2V0KCRjbHItbGlnaHQtYmx1ZS1saXN0LCBcIjUwXCIpO1xuJGNsci1saWdodC1ibHVlLTEwMDogIG1hcC1nZXQoJGNsci1saWdodC1ibHVlLWxpc3QsIFwiMTAwXCIpO1xuJGNsci1saWdodC1ibHVlLTIwMDogIG1hcC1nZXQoJGNsci1saWdodC1ibHVlLWxpc3QsIFwiMjAwXCIpO1xuJGNsci1saWdodC1ibHVlLTMwMDogIG1hcC1nZXQoJGNsci1saWdodC1ibHVlLWxpc3QsIFwiMzAwXCIpO1xuJGNsci1saWdodC1ibHVlLTQwMDogIG1hcC1nZXQoJGNsci1saWdodC1ibHVlLWxpc3QsIFwiNDAwXCIpO1xuJGNsci1saWdodC1ibHVlLTUwMDogIG1hcC1nZXQoJGNsci1saWdodC1ibHVlLWxpc3QsIFwiNTAwXCIpO1xuJGNsci1saWdodC1ibHVlLTYwMDogIG1hcC1nZXQoJGNsci1saWdodC1ibHVlLWxpc3QsIFwiNjAwXCIpO1xuJGNsci1saWdodC1ibHVlLTcwMDogIG1hcC1nZXQoJGNsci1saWdodC1ibHVlLWxpc3QsIFwiNzAwXCIpO1xuJGNsci1saWdodC1ibHVlLTgwMDogIG1hcC1nZXQoJGNsci1saWdodC1ibHVlLWxpc3QsIFwiODAwXCIpO1xuJGNsci1saWdodC1ibHVlLTkwMDogIG1hcC1nZXQoJGNsci1saWdodC1ibHVlLWxpc3QsIFwiOTAwXCIpO1xuJGNsci1saWdodC1ibHVlLWExMDA6IG1hcC1nZXQoJGNsci1saWdodC1ibHVlLWxpc3QsIFwiYTEwMFwiKTtcbiRjbHItbGlnaHQtYmx1ZS1hMjAwOiBtYXAtZ2V0KCRjbHItbGlnaHQtYmx1ZS1saXN0LCBcImEyMDBcIik7XG4kY2xyLWxpZ2h0LWJsdWUtYTQwMDogbWFwLWdldCgkY2xyLWxpZ2h0LWJsdWUtbGlzdCwgXCJhNDAwXCIpO1xuJGNsci1saWdodC1ibHVlLWE3MDA6IG1hcC1nZXQoJGNsci1saWdodC1ibHVlLWxpc3QsIFwiYTcwMFwiKTtcblxuXG4vL1xuLy8gQ3lhblxuLy9cblxuJGNsci1jeWFuLWxpc3Q6IChcbiAgXCJiYXNlXCI6ICMwMGJjZDQsXG4gIFwiNTBcIjogICAjZTBmN2ZhLFxuICBcIjEwMFwiOiAgI2IyZWJmMixcbiAgXCIyMDBcIjogICM4MGRlZWEsXG4gIFwiMzAwXCI6ICAjNGRkMGUxLFxuICBcIjQwMFwiOiAgIzI2YzZkYSxcbiAgXCI1MDBcIjogICMwMGJjZDQsXG4gIFwiNjAwXCI6ICAjMDBhY2MxLFxuICBcIjcwMFwiOiAgIzAwOTdhNyxcbiAgXCI4MDBcIjogICMwMDgzOGYsXG4gIFwiOTAwXCI6ICAjMDA2MDY0LFxuICBcImExMDBcIjogIzg0ZmZmZixcbiAgXCJhMjAwXCI6ICMxOGZmZmYsXG4gIFwiYTQwMFwiOiAjMDBlNWZmLFxuICBcImE3MDBcIjogIzAwYjhkNFxuKTtcblxuJGNsci1jeWFuOiAgICAgIG1hcC1nZXQoJGNsci1jeWFuLWxpc3QsIFwiYmFzZVwiKTtcblxuJGNsci1jeWFuLTUwOiAgIG1hcC1nZXQoJGNsci1jeWFuLWxpc3QsIFwiNTBcIik7XG4kY2xyLWN5YW4tMTAwOiAgbWFwLWdldCgkY2xyLWN5YW4tbGlzdCwgXCIxMDBcIik7XG4kY2xyLWN5YW4tMjAwOiAgbWFwLWdldCgkY2xyLWN5YW4tbGlzdCwgXCIyMDBcIik7XG4kY2xyLWN5YW4tMzAwOiAgbWFwLWdldCgkY2xyLWN5YW4tbGlzdCwgXCIzMDBcIik7XG4kY2xyLWN5YW4tNDAwOiAgbWFwLWdldCgkY2xyLWN5YW4tbGlzdCwgXCI0MDBcIik7XG4kY2xyLWN5YW4tNTAwOiAgbWFwLWdldCgkY2xyLWN5YW4tbGlzdCwgXCI1MDBcIik7XG4kY2xyLWN5YW4tNjAwOiAgbWFwLWdldCgkY2xyLWN5YW4tbGlzdCwgXCI2MDBcIik7XG4kY2xyLWN5YW4tNzAwOiAgbWFwLWdldCgkY2xyLWN5YW4tbGlzdCwgXCI3MDBcIik7XG4kY2xyLWN5YW4tODAwOiAgbWFwLWdldCgkY2xyLWN5YW4tbGlzdCwgXCI4MDBcIik7XG4kY2xyLWN5YW4tOTAwOiAgbWFwLWdldCgkY2xyLWN5YW4tbGlzdCwgXCI5MDBcIik7XG4kY2xyLWN5YW4tYTEwMDogbWFwLWdldCgkY2xyLWN5YW4tbGlzdCwgXCJhMTAwXCIpO1xuJGNsci1jeWFuLWEyMDA6IG1hcC1nZXQoJGNsci1jeWFuLWxpc3QsIFwiYTIwMFwiKTtcbiRjbHItY3lhbi1hNDAwOiBtYXAtZ2V0KCRjbHItY3lhbi1saXN0LCBcImE0MDBcIik7XG4kY2xyLWN5YW4tYTcwMDogbWFwLWdldCgkY2xyLWN5YW4tbGlzdCwgXCJhNzAwXCIpO1xuXG5cbi8vXG4vLyBUZWFsXG4vL1xuXG4kY2xyLXRlYWwtbGlzdDogKFxuICBcImJhc2VcIjogIzAwOTY4OCxcbiAgXCI1MFwiOiAgICNlMGYyZjEsXG4gIFwiMTAwXCI6ICAjYjJkZmRiLFxuICBcIjIwMFwiOiAgIzgwY2JjNCxcbiAgXCIzMDBcIjogICM0ZGI2YWMsXG4gIFwiNDAwXCI6ICAjMjZhNjlhLFxuICBcIjUwMFwiOiAgIzAwOTY4OCxcbiAgXCI2MDBcIjogICMwMDg5N2IsXG4gIFwiNzAwXCI6ICAjMDA3OTZiLFxuICBcIjgwMFwiOiAgIzAwNjk1YyxcbiAgXCI5MDBcIjogICMwMDRkNDAsXG4gIFwiYTEwMFwiOiAjYTdmZmViLFxuICBcImEyMDBcIjogIzY0ZmZkYSxcbiAgXCJhNDAwXCI6ICMxZGU5YjYsXG4gIFwiYTcwMFwiOiAjMDBiZmE1XG4pO1xuXG4kY2xyLXRlYWw6ICAgICAgbWFwLWdldCgkY2xyLXRlYWwtbGlzdCwgXCJiYXNlXCIpO1xuXG4kY2xyLXRlYWwtNTA6ICAgbWFwLWdldCgkY2xyLXRlYWwtbGlzdCwgXCI1MFwiKTtcbiRjbHItdGVhbC0xMDA6ICBtYXAtZ2V0KCRjbHItdGVhbC1saXN0LCBcIjEwMFwiKTtcbiRjbHItdGVhbC0yMDA6ICBtYXAtZ2V0KCRjbHItdGVhbC1saXN0LCBcIjIwMFwiKTtcbiRjbHItdGVhbC0zMDA6ICBtYXAtZ2V0KCRjbHItdGVhbC1saXN0LCBcIjMwMFwiKTtcbiRjbHItdGVhbC00MDA6ICBtYXAtZ2V0KCRjbHItdGVhbC1saXN0LCBcIjQwMFwiKTtcbiRjbHItdGVhbC01MDA6ICBtYXAtZ2V0KCRjbHItdGVhbC1saXN0LCBcIjUwMFwiKTtcbiRjbHItdGVhbC02MDA6ICBtYXAtZ2V0KCRjbHItdGVhbC1saXN0LCBcIjYwMFwiKTtcbiRjbHItdGVhbC03MDA6ICBtYXAtZ2V0KCRjbHItdGVhbC1saXN0LCBcIjcwMFwiKTtcbiRjbHItdGVhbC04MDA6ICBtYXAtZ2V0KCRjbHItdGVhbC1saXN0LCBcIjgwMFwiKTtcbiRjbHItdGVhbC05MDA6ICBtYXAtZ2V0KCRjbHItdGVhbC1saXN0LCBcIjkwMFwiKTtcbiRjbHItdGVhbC1hMTAwOiBtYXAtZ2V0KCRjbHItdGVhbC1saXN0LCBcImExMDBcIik7XG4kY2xyLXRlYWwtYTIwMDogbWFwLWdldCgkY2xyLXRlYWwtbGlzdCwgXCJhMjAwXCIpO1xuJGNsci10ZWFsLWE0MDA6IG1hcC1nZXQoJGNsci10ZWFsLWxpc3QsIFwiYTQwMFwiKTtcbiRjbHItdGVhbC1hNzAwOiBtYXAtZ2V0KCRjbHItdGVhbC1saXN0LCBcImE3MDBcIik7XG5cblxuLy9cbi8vIEdyZWVuXG4vL1xuXG4kY2xyLWdyZWVuLWxpc3Q6IChcbiAgXCJiYXNlXCI6ICM0Y2FmNTAsXG4gIFwiNTBcIjogICAjZThmNWU5LFxuICBcIjEwMFwiOiAgI2M4ZTZjOSxcbiAgXCIyMDBcIjogICNhNWQ2YTcsXG4gIFwiMzAwXCI6ICAjODFjNzg0LFxuICBcIjQwMFwiOiAgIzY2YmI2YSxcbiAgXCI1MDBcIjogICM0Y2FmNTAsXG4gIFwiNjAwXCI6ICAjNDNhMDQ3LFxuICBcIjcwMFwiOiAgIzM4OGUzYyxcbiAgXCI4MDBcIjogICMyZTdkMzIsXG4gIFwiOTAwXCI6ICAjMWI1ZTIwLFxuICBcImExMDBcIjogI2I5ZjZjYSxcbiAgXCJhMjAwXCI6ICM2OWYwYWUsXG4gIFwiYTQwMFwiOiAjMDBlNjc2LFxuICBcImE3MDBcIjogIzAwYzg1M1xuKTtcblxuJGNsci1ncmVlbjogICAgICBtYXAtZ2V0KCRjbHItZ3JlZW4tbGlzdCwgXCJiYXNlXCIpO1xuXG4kY2xyLWdyZWVuLTUwOiAgIG1hcC1nZXQoJGNsci1ncmVlbi1saXN0LCBcIjUwXCIpO1xuJGNsci1ncmVlbi0xMDA6ICBtYXAtZ2V0KCRjbHItZ3JlZW4tbGlzdCwgXCIxMDBcIik7XG4kY2xyLWdyZWVuLTIwMDogIG1hcC1nZXQoJGNsci1ncmVlbi1saXN0LCBcIjIwMFwiKTtcbiRjbHItZ3JlZW4tMzAwOiAgbWFwLWdldCgkY2xyLWdyZWVuLWxpc3QsIFwiMzAwXCIpO1xuJGNsci1ncmVlbi00MDA6ICBtYXAtZ2V0KCRjbHItZ3JlZW4tbGlzdCwgXCI0MDBcIik7XG4kY2xyLWdyZWVuLTUwMDogIG1hcC1nZXQoJGNsci1ncmVlbi1saXN0LCBcIjUwMFwiKTtcbiRjbHItZ3JlZW4tNjAwOiAgbWFwLWdldCgkY2xyLWdyZWVuLWxpc3QsIFwiNjAwXCIpO1xuJGNsci1ncmVlbi03MDA6ICBtYXAtZ2V0KCRjbHItZ3JlZW4tbGlzdCwgXCI3MDBcIik7XG4kY2xyLWdyZWVuLTgwMDogIG1hcC1nZXQoJGNsci1ncmVlbi1saXN0LCBcIjgwMFwiKTtcbiRjbHItZ3JlZW4tOTAwOiAgbWFwLWdldCgkY2xyLWdyZWVuLWxpc3QsIFwiOTAwXCIpO1xuJGNsci1ncmVlbi1hMTAwOiBtYXAtZ2V0KCRjbHItZ3JlZW4tbGlzdCwgXCJhMTAwXCIpO1xuJGNsci1ncmVlbi1hMjAwOiBtYXAtZ2V0KCRjbHItZ3JlZW4tbGlzdCwgXCJhMjAwXCIpO1xuJGNsci1ncmVlbi1hNDAwOiBtYXAtZ2V0KCRjbHItZ3JlZW4tbGlzdCwgXCJhNDAwXCIpO1xuJGNsci1ncmVlbi1hNzAwOiBtYXAtZ2V0KCRjbHItZ3JlZW4tbGlzdCwgXCJhNzAwXCIpO1xuXG5cbi8vXG4vLyBMaWdodCBncmVlblxuLy9cblxuJGNsci1saWdodC1ncmVlbi1saXN0OiAoXG4gIFwiYmFzZVwiOiAjOGJjMzRhLFxuICBcIjUwXCI6ICAgI2YxZjhlOSxcbiAgXCIxMDBcIjogICNkY2VkYzgsXG4gIFwiMjAwXCI6ICAjYzVlMWE1LFxuICBcIjMwMFwiOiAgI2FlZDU4MSxcbiAgXCI0MDBcIjogICM5Y2NjNjUsXG4gIFwiNTAwXCI6ICAjOGJjMzRhLFxuICBcIjYwMFwiOiAgIzdjYjM0MixcbiAgXCI3MDBcIjogICM2ODlmMzgsXG4gIFwiODAwXCI6ICAjNTU4YjJmLFxuICBcIjkwMFwiOiAgIzMzNjkxZSxcbiAgXCJhMTAwXCI6ICNjY2ZmOTAsXG4gIFwiYTIwMFwiOiAjYjJmZjU5LFxuICBcImE0MDBcIjogIzc2ZmYwMyxcbiAgXCJhNzAwXCI6ICM2NGRkMTdcbik7XG5cbiRjbHItbGlnaHQtZ3JlZW46ICAgICAgbWFwLWdldCgkY2xyLWxpZ2h0LWdyZWVuLWxpc3QsIFwiYmFzZVwiKTtcblxuJGNsci1saWdodC1ncmVlbi01MDogICBtYXAtZ2V0KCRjbHItbGlnaHQtZ3JlZW4tbGlzdCwgXCI1MFwiKTtcbiRjbHItbGlnaHQtZ3JlZW4tMTAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWdyZWVuLWxpc3QsIFwiMTAwXCIpO1xuJGNsci1saWdodC1ncmVlbi0yMDA6ICBtYXAtZ2V0KCRjbHItbGlnaHQtZ3JlZW4tbGlzdCwgXCIyMDBcIik7XG4kY2xyLWxpZ2h0LWdyZWVuLTMwMDogIG1hcC1nZXQoJGNsci1saWdodC1ncmVlbi1saXN0LCBcIjMwMFwiKTtcbiRjbHItbGlnaHQtZ3JlZW4tNDAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWdyZWVuLWxpc3QsIFwiNDAwXCIpO1xuJGNsci1saWdodC1ncmVlbi01MDA6ICBtYXAtZ2V0KCRjbHItbGlnaHQtZ3JlZW4tbGlzdCwgXCI1MDBcIik7XG4kY2xyLWxpZ2h0LWdyZWVuLTYwMDogIG1hcC1nZXQoJGNsci1saWdodC1ncmVlbi1saXN0LCBcIjYwMFwiKTtcbiRjbHItbGlnaHQtZ3JlZW4tNzAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWdyZWVuLWxpc3QsIFwiNzAwXCIpO1xuJGNsci1saWdodC1ncmVlbi04MDA6ICBtYXAtZ2V0KCRjbHItbGlnaHQtZ3JlZW4tbGlzdCwgXCI4MDBcIik7XG4kY2xyLWxpZ2h0LWdyZWVuLTkwMDogIG1hcC1nZXQoJGNsci1saWdodC1ncmVlbi1saXN0LCBcIjkwMFwiKTtcbiRjbHItbGlnaHQtZ3JlZW4tYTEwMDogbWFwLWdldCgkY2xyLWxpZ2h0LWdyZWVuLWxpc3QsIFwiYTEwMFwiKTtcbiRjbHItbGlnaHQtZ3JlZW4tYTIwMDogbWFwLWdldCgkY2xyLWxpZ2h0LWdyZWVuLWxpc3QsIFwiYTIwMFwiKTtcbiRjbHItbGlnaHQtZ3JlZW4tYTQwMDogbWFwLWdldCgkY2xyLWxpZ2h0LWdyZWVuLWxpc3QsIFwiYTQwMFwiKTtcbiRjbHItbGlnaHQtZ3JlZW4tYTcwMDogbWFwLWdldCgkY2xyLWxpZ2h0LWdyZWVuLWxpc3QsIFwiYTcwMFwiKTtcblxuXG4vL1xuLy8gTGltZVxuLy9cblxuJGNsci1saW1lLWxpc3Q6IChcbiAgXCJiYXNlXCI6ICNjZGRjMzksXG4gIFwiNTBcIjogICAjZjlmYmU3LFxuICBcIjEwMFwiOiAgI2YwZjRjMyxcbiAgXCIyMDBcIjogICNlNmVlOWMsXG4gIFwiMzAwXCI6ICAjZGNlNzc1LFxuICBcIjQwMFwiOiAgI2Q0ZTE1NyxcbiAgXCI1MDBcIjogICNjZGRjMzksXG4gIFwiNjAwXCI6ICAjYzBjYTMzLFxuICBcIjcwMFwiOiAgI2FmYjQyYixcbiAgXCI4MDBcIjogICM5ZTlkMjQsXG4gIFwiOTAwXCI6ICAjODI3NzE3LFxuICBcImExMDBcIjogI2Y0ZmY4MSxcbiAgXCJhMjAwXCI6ICNlZWZmNDEsXG4gIFwiYTQwMFwiOiAjYzZmZjAwLFxuICBcImE3MDBcIjogI2FlZWEwMFxuKTtcblxuJGNsci1saW1lOiAgICAgIG1hcC1nZXQoJGNsci1saW1lLWxpc3QsIFwiYmFzZVwiKTtcblxuJGNsci1saW1lLTUwOiAgIG1hcC1nZXQoJGNsci1saW1lLWxpc3QsIFwiNTBcIik7XG4kY2xyLWxpbWUtMTAwOiAgbWFwLWdldCgkY2xyLWxpbWUtbGlzdCwgXCIxMDBcIik7XG4kY2xyLWxpbWUtMjAwOiAgbWFwLWdldCgkY2xyLWxpbWUtbGlzdCwgXCIyMDBcIik7XG4kY2xyLWxpbWUtMzAwOiAgbWFwLWdldCgkY2xyLWxpbWUtbGlzdCwgXCIzMDBcIik7XG4kY2xyLWxpbWUtNDAwOiAgbWFwLWdldCgkY2xyLWxpbWUtbGlzdCwgXCI0MDBcIik7XG4kY2xyLWxpbWUtNTAwOiAgbWFwLWdldCgkY2xyLWxpbWUtbGlzdCwgXCI1MDBcIik7XG4kY2xyLWxpbWUtNjAwOiAgbWFwLWdldCgkY2xyLWxpbWUtbGlzdCwgXCI2MDBcIik7XG4kY2xyLWxpbWUtNzAwOiAgbWFwLWdldCgkY2xyLWxpbWUtbGlzdCwgXCI3MDBcIik7XG4kY2xyLWxpbWUtODAwOiAgbWFwLWdldCgkY2xyLWxpbWUtbGlzdCwgXCI4MDBcIik7XG4kY2xyLWxpbWUtOTAwOiAgbWFwLWdldCgkY2xyLWxpbWUtbGlzdCwgXCI5MDBcIik7XG4kY2xyLWxpbWUtYTEwMDogbWFwLWdldCgkY2xyLWxpbWUtbGlzdCwgXCJhMTAwXCIpO1xuJGNsci1saW1lLWEyMDA6IG1hcC1nZXQoJGNsci1saW1lLWxpc3QsIFwiYTIwMFwiKTtcbiRjbHItbGltZS1hNDAwOiBtYXAtZ2V0KCRjbHItbGltZS1saXN0LCBcImE0MDBcIik7XG4kY2xyLWxpbWUtYTcwMDogbWFwLWdldCgkY2xyLWxpbWUtbGlzdCwgXCJhNzAwXCIpO1xuXG5cbi8vXG4vLyBZZWxsb3dcbi8vXG5cbiRjbHIteWVsbG93LWxpc3Q6IChcbiAgXCJiYXNlXCI6ICNmZmViM2IsXG4gIFwiNTBcIjogICAjZmZmZGU3LFxuICBcIjEwMFwiOiAgI2ZmZjljNCxcbiAgXCIyMDBcIjogICNmZmY1OWQsXG4gIFwiMzAwXCI6ICAjZmZmMTc2LFxuICBcIjQwMFwiOiAgI2ZmZWU1OCxcbiAgXCI1MDBcIjogICNmZmViM2IsXG4gIFwiNjAwXCI6ICAjZmRkODM1LFxuICBcIjcwMFwiOiAgI2ZiYzAyZCxcbiAgXCI4MDBcIjogICNmOWE4MjUsXG4gIFwiOTAwXCI6ICAjZjU3ZjE3LFxuICBcImExMDBcIjogI2ZmZmY4ZCxcbiAgXCJhMjAwXCI6ICNmZmZmMDAsXG4gIFwiYTQwMFwiOiAjZmZlYTAwLFxuICBcImE3MDBcIjogI2ZmZDYwMFxuKTtcblxuJGNsci15ZWxsb3c6ICAgICAgbWFwLWdldCgkY2xyLXllbGxvdy1saXN0LCBcImJhc2VcIik7XG5cbiRjbHIteWVsbG93LTUwOiAgIG1hcC1nZXQoJGNsci15ZWxsb3ctbGlzdCwgXCI1MFwiKTtcbiRjbHIteWVsbG93LTEwMDogIG1hcC1nZXQoJGNsci15ZWxsb3ctbGlzdCwgXCIxMDBcIik7XG4kY2xyLXllbGxvdy0yMDA6ICBtYXAtZ2V0KCRjbHIteWVsbG93LWxpc3QsIFwiMjAwXCIpO1xuJGNsci15ZWxsb3ctMzAwOiAgbWFwLWdldCgkY2xyLXllbGxvdy1saXN0LCBcIjMwMFwiKTtcbiRjbHIteWVsbG93LTQwMDogIG1hcC1nZXQoJGNsci15ZWxsb3ctbGlzdCwgXCI0MDBcIik7XG4kY2xyLXllbGxvdy01MDA6ICBtYXAtZ2V0KCRjbHIteWVsbG93LWxpc3QsIFwiNTAwXCIpO1xuJGNsci15ZWxsb3ctNjAwOiAgbWFwLWdldCgkY2xyLXllbGxvdy1saXN0LCBcIjYwMFwiKTtcbiRjbHIteWVsbG93LTcwMDogIG1hcC1nZXQoJGNsci15ZWxsb3ctbGlzdCwgXCI3MDBcIik7XG4kY2xyLXllbGxvdy04MDA6ICBtYXAtZ2V0KCRjbHIteWVsbG93LWxpc3QsIFwiODAwXCIpO1xuJGNsci15ZWxsb3ctOTAwOiAgbWFwLWdldCgkY2xyLXllbGxvdy1saXN0LCBcIjkwMFwiKTtcbiRjbHIteWVsbG93LWExMDA6IG1hcC1nZXQoJGNsci15ZWxsb3ctbGlzdCwgXCJhMTAwXCIpO1xuJGNsci15ZWxsb3ctYTIwMDogbWFwLWdldCgkY2xyLXllbGxvdy1saXN0LCBcImEyMDBcIik7XG4kY2xyLXllbGxvdy1hNDAwOiBtYXAtZ2V0KCRjbHIteWVsbG93LWxpc3QsIFwiYTQwMFwiKTtcbiRjbHIteWVsbG93LWE3MDA6IG1hcC1nZXQoJGNsci15ZWxsb3ctbGlzdCwgXCJhNzAwXCIpO1xuXG5cbi8vXG4vLyBhbWJlclxuLy9cblxuJGNsci1hbWJlci1saXN0OiAoXG4gIFwiYmFzZVwiOiAjZmZjMTA3LFxuICBcIjUwXCI6ICAgI2ZmZjhlMSxcbiAgXCIxMDBcIjogICNmZmVjYjMsXG4gIFwiMjAwXCI6ICAjZmZlMDgyLFxuICBcIjMwMFwiOiAgI2ZmZDU0ZixcbiAgXCI0MDBcIjogICNmZmNhMjgsXG4gIFwiNTAwXCI6ICAjZmZjMTA3LFxuICBcIjYwMFwiOiAgI2ZmYjMwMCxcbiAgXCI3MDBcIjogICNmZmEwMDAsXG4gIFwiODAwXCI6ICAjZmY4ZjAwLFxuICBcIjkwMFwiOiAgI2ZmNmYwMCxcbiAgXCJhMTAwXCI6ICNmZmU1N2YsXG4gIFwiYTIwMFwiOiAjZmZkNzQwLFxuICBcImE0MDBcIjogI2ZmYzQwMCxcbiAgXCJhNzAwXCI6ICNmZmFiMDBcbik7XG5cbiRjbHItYW1iZXI6ICAgICAgbWFwLWdldCgkY2xyLWFtYmVyLWxpc3QsIFwiYmFzZVwiKTtcblxuJGNsci1hbWJlci01MDogICBtYXAtZ2V0KCRjbHItYW1iZXItbGlzdCwgXCI1MFwiKTtcbiRjbHItYW1iZXItMTAwOiAgbWFwLWdldCgkY2xyLWFtYmVyLWxpc3QsIFwiMTAwXCIpO1xuJGNsci1hbWJlci0yMDA6ICBtYXAtZ2V0KCRjbHItYW1iZXItbGlzdCwgXCIyMDBcIik7XG4kY2xyLWFtYmVyLTMwMDogIG1hcC1nZXQoJGNsci1hbWJlci1saXN0LCBcIjMwMFwiKTtcbiRjbHItYW1iZXItNDAwOiAgbWFwLWdldCgkY2xyLWFtYmVyLWxpc3QsIFwiNDAwXCIpO1xuJGNsci1hbWJlci01MDA6ICBtYXAtZ2V0KCRjbHItYW1iZXItbGlzdCwgXCI1MDBcIik7XG4kY2xyLWFtYmVyLTYwMDogIG1hcC1nZXQoJGNsci1hbWJlci1saXN0LCBcIjYwMFwiKTtcbiRjbHItYW1iZXItNzAwOiAgbWFwLWdldCgkY2xyLWFtYmVyLWxpc3QsIFwiNzAwXCIpO1xuJGNsci1hbWJlci04MDA6ICBtYXAtZ2V0KCRjbHItYW1iZXItbGlzdCwgXCI4MDBcIik7XG4kY2xyLWFtYmVyLTkwMDogIG1hcC1nZXQoJGNsci1hbWJlci1saXN0LCBcIjkwMFwiKTtcbiRjbHItYW1iZXItYTEwMDogbWFwLWdldCgkY2xyLWFtYmVyLWxpc3QsIFwiYTEwMFwiKTtcbiRjbHItYW1iZXItYTIwMDogbWFwLWdldCgkY2xyLWFtYmVyLWxpc3QsIFwiYTIwMFwiKTtcbiRjbHItYW1iZXItYTQwMDogbWFwLWdldCgkY2xyLWFtYmVyLWxpc3QsIFwiYTQwMFwiKTtcbiRjbHItYW1iZXItYTcwMDogbWFwLWdldCgkY2xyLWFtYmVyLWxpc3QsIFwiYTcwMFwiKTtcblxuXG4vL1xuLy8gT3JhbmdlXG4vL1xuXG4kY2xyLW9yYW5nZS1saXN0OiAoXG4gIFwiYmFzZVwiOiAjZmY5ODAwLFxuICBcIjUwXCI6ICAgI2ZmZjNlMCxcbiAgXCIxMDBcIjogICNmZmUwYjIsXG4gIFwiMjAwXCI6ICAjZmZjYzgwLFxuICBcIjMwMFwiOiAgI2ZmYjc0ZCxcbiAgXCI0MDBcIjogICNmZmE3MjYsXG4gIFwiNTAwXCI6ICAjZmY5ODAwLFxuICBcIjYwMFwiOiAgI2ZiOGMwMCxcbiAgXCI3MDBcIjogICNmNTdjMDAsXG4gIFwiODAwXCI6ICAjZWY2YzAwLFxuICBcIjkwMFwiOiAgI2U2NTEwMCxcbiAgXCJhMTAwXCI6ICNmZmQxODAsXG4gIFwiYTIwMFwiOiAjZmZhYjQwLFxuICBcImE0MDBcIjogI2ZmOTEwMCxcbiAgXCJhNzAwXCI6ICNmZjZkMDBcbik7XG5cbiRjbHItb3JhbmdlOiAgICAgIG1hcC1nZXQoJGNsci1vcmFuZ2UtbGlzdCwgXCJiYXNlXCIpO1xuXG4kY2xyLW9yYW5nZS01MDogICBtYXAtZ2V0KCRjbHItb3JhbmdlLWxpc3QsIFwiNTBcIik7XG4kY2xyLW9yYW5nZS0xMDA6ICBtYXAtZ2V0KCRjbHItb3JhbmdlLWxpc3QsIFwiMTAwXCIpO1xuJGNsci1vcmFuZ2UtMjAwOiAgbWFwLWdldCgkY2xyLW9yYW5nZS1saXN0LCBcIjIwMFwiKTtcbiRjbHItb3JhbmdlLTMwMDogIG1hcC1nZXQoJGNsci1vcmFuZ2UtbGlzdCwgXCIzMDBcIik7XG4kY2xyLW9yYW5nZS00MDA6ICBtYXAtZ2V0KCRjbHItb3JhbmdlLWxpc3QsIFwiNDAwXCIpO1xuJGNsci1vcmFuZ2UtNTAwOiAgbWFwLWdldCgkY2xyLW9yYW5nZS1saXN0LCBcIjUwMFwiKTtcbiRjbHItb3JhbmdlLTYwMDogIG1hcC1nZXQoJGNsci1vcmFuZ2UtbGlzdCwgXCI2MDBcIik7XG4kY2xyLW9yYW5nZS03MDA6ICBtYXAtZ2V0KCRjbHItb3JhbmdlLWxpc3QsIFwiNzAwXCIpO1xuJGNsci1vcmFuZ2UtODAwOiAgbWFwLWdldCgkY2xyLW9yYW5nZS1saXN0LCBcIjgwMFwiKTtcbiRjbHItb3JhbmdlLTkwMDogIG1hcC1nZXQoJGNsci1vcmFuZ2UtbGlzdCwgXCI5MDBcIik7XG4kY2xyLW9yYW5nZS1hMTAwOiBtYXAtZ2V0KCRjbHItb3JhbmdlLWxpc3QsIFwiYTEwMFwiKTtcbiRjbHItb3JhbmdlLWEyMDA6IG1hcC1nZXQoJGNsci1vcmFuZ2UtbGlzdCwgXCJhMjAwXCIpO1xuJGNsci1vcmFuZ2UtYTQwMDogbWFwLWdldCgkY2xyLW9yYW5nZS1saXN0LCBcImE0MDBcIik7XG4kY2xyLW9yYW5nZS1hNzAwOiBtYXAtZ2V0KCRjbHItb3JhbmdlLWxpc3QsIFwiYTcwMFwiKTtcblxuXG4vL1xuLy8gRGVlcCBvcmFuZ2Vcbi8vXG5cbiRjbHItZGVlcC1vcmFuZ2UtbGlzdDogKFxuICBcImJhc2VcIjogI2ZmNTcyMixcbiAgXCI1MFwiOiAgICNmYmU5ZTcsXG4gIFwiMTAwXCI6ICAjZmZjY2JjLFxuICBcIjIwMFwiOiAgI2ZmYWI5MSxcbiAgXCIzMDBcIjogICNmZjhhNjUsXG4gIFwiNDAwXCI6ICAjZmY3MDQzLFxuICBcIjUwMFwiOiAgI2ZmNTcyMixcbiAgXCI2MDBcIjogICNmNDUxMWUsXG4gIFwiNzAwXCI6ICAjZTY0YTE5LFxuICBcIjgwMFwiOiAgI2Q4NDMxNSxcbiAgXCI5MDBcIjogICNiZjM2MGMsXG4gIFwiYTEwMFwiOiAjZmY5ZTgwLFxuICBcImEyMDBcIjogI2ZmNmU0MCxcbiAgXCJhNDAwXCI6ICNmZjNkMDAsXG4gIFwiYTcwMFwiOiAjZGQyYzAwXG4pO1xuXG4kY2xyLWRlZXAtb3JhbmdlOiAgICAgIG1hcC1nZXQoJGNsci1kZWVwLW9yYW5nZS1saXN0LCBcImJhc2VcIik7XG5cbiRjbHItZGVlcC1vcmFuZ2UtNTA6ICAgbWFwLWdldCgkY2xyLWRlZXAtb3JhbmdlLWxpc3QsIFwiNTBcIik7XG4kY2xyLWRlZXAtb3JhbmdlLTEwMDogIG1hcC1nZXQoJGNsci1kZWVwLW9yYW5nZS1saXN0LCBcIjEwMFwiKTtcbiRjbHItZGVlcC1vcmFuZ2UtMjAwOiAgbWFwLWdldCgkY2xyLWRlZXAtb3JhbmdlLWxpc3QsIFwiMjAwXCIpO1xuJGNsci1kZWVwLW9yYW5nZS0zMDA6ICBtYXAtZ2V0KCRjbHItZGVlcC1vcmFuZ2UtbGlzdCwgXCIzMDBcIik7XG4kY2xyLWRlZXAtb3JhbmdlLTQwMDogIG1hcC1nZXQoJGNsci1kZWVwLW9yYW5nZS1saXN0LCBcIjQwMFwiKTtcbiRjbHItZGVlcC1vcmFuZ2UtNTAwOiAgbWFwLWdldCgkY2xyLWRlZXAtb3JhbmdlLWxpc3QsIFwiNTAwXCIpO1xuJGNsci1kZWVwLW9yYW5nZS02MDA6ICBtYXAtZ2V0KCRjbHItZGVlcC1vcmFuZ2UtbGlzdCwgXCI2MDBcIik7XG4kY2xyLWRlZXAtb3JhbmdlLTcwMDogIG1hcC1nZXQoJGNsci1kZWVwLW9yYW5nZS1saXN0LCBcIjcwMFwiKTtcbiRjbHItZGVlcC1vcmFuZ2UtODAwOiAgbWFwLWdldCgkY2xyLWRlZXAtb3JhbmdlLWxpc3QsIFwiODAwXCIpO1xuJGNsci1kZWVwLW9yYW5nZS05MDA6ICBtYXAtZ2V0KCRjbHItZGVlcC1vcmFuZ2UtbGlzdCwgXCI5MDBcIik7XG4kY2xyLWRlZXAtb3JhbmdlLWExMDA6IG1hcC1nZXQoJGNsci1kZWVwLW9yYW5nZS1saXN0LCBcImExMDBcIik7XG4kY2xyLWRlZXAtb3JhbmdlLWEyMDA6IG1hcC1nZXQoJGNsci1kZWVwLW9yYW5nZS1saXN0LCBcImEyMDBcIik7XG4kY2xyLWRlZXAtb3JhbmdlLWE0MDA6IG1hcC1nZXQoJGNsci1kZWVwLW9yYW5nZS1saXN0LCBcImE0MDBcIik7XG4kY2xyLWRlZXAtb3JhbmdlLWE3MDA6IG1hcC1nZXQoJGNsci1kZWVwLW9yYW5nZS1saXN0LCBcImE3MDBcIik7XG5cblxuLy9cbi8vIEJyb3duXG4vL1xuXG4kY2xyLWJyb3duLWxpc3Q6IChcbiAgXCJiYXNlXCI6ICM3OTU1NDgsXG4gIFwiNTBcIjogICAjZWZlYmU5LFxuICBcIjEwMFwiOiAgI2Q3Y2NjOCxcbiAgXCIyMDBcIjogICNiY2FhYTQsXG4gIFwiMzAwXCI6ICAjYTE4ODdmLFxuICBcIjQwMFwiOiAgIzhkNmU2MyxcbiAgXCI1MDBcIjogICM3OTU1NDgsXG4gIFwiNjAwXCI6ICAjNmQ0YzQxLFxuICBcIjcwMFwiOiAgIzVkNDAzNyxcbiAgXCI4MDBcIjogICM0ZTM0MmUsXG4gIFwiOTAwXCI6ICAjM2UyNzIzLFxuKTtcblxuJGNsci1icm93bjogICAgIG1hcC1nZXQoJGNsci1icm93bi1saXN0LCBcImJhc2VcIik7XG5cbiRjbHItYnJvd24tNTA6ICBtYXAtZ2V0KCRjbHItYnJvd24tbGlzdCwgXCI1MFwiKTtcbiRjbHItYnJvd24tMTAwOiBtYXAtZ2V0KCRjbHItYnJvd24tbGlzdCwgXCIxMDBcIik7XG4kY2xyLWJyb3duLTIwMDogbWFwLWdldCgkY2xyLWJyb3duLWxpc3QsIFwiMjAwXCIpO1xuJGNsci1icm93bi0zMDA6IG1hcC1nZXQoJGNsci1icm93bi1saXN0LCBcIjMwMFwiKTtcbiRjbHItYnJvd24tNDAwOiBtYXAtZ2V0KCRjbHItYnJvd24tbGlzdCwgXCI0MDBcIik7XG4kY2xyLWJyb3duLTUwMDogbWFwLWdldCgkY2xyLWJyb3duLWxpc3QsIFwiNTAwXCIpO1xuJGNsci1icm93bi02MDA6IG1hcC1nZXQoJGNsci1icm93bi1saXN0LCBcIjYwMFwiKTtcbiRjbHItYnJvd24tNzAwOiBtYXAtZ2V0KCRjbHItYnJvd24tbGlzdCwgXCI3MDBcIik7XG4kY2xyLWJyb3duLTgwMDogbWFwLWdldCgkY2xyLWJyb3duLWxpc3QsIFwiODAwXCIpO1xuJGNsci1icm93bi05MDA6IG1hcC1nZXQoJGNsci1icm93bi1saXN0LCBcIjkwMFwiKTtcblxuXG4vL1xuLy8gR3JleVxuLy9cblxuJGNsci1ncmV5LWxpc3Q6IChcbiAgXCJiYXNlXCI6ICM5ZTllOWUsXG4gIFwiNTBcIjogICAjZmFmYWZhLFxuICBcIjEwMFwiOiAgI2Y1ZjVmNSxcbiAgXCIyMDBcIjogICNlZWVlZWUsXG4gIFwiMzAwXCI6ICAjZTBlMGUwLFxuICBcIjQwMFwiOiAgI2JkYmRiZCxcbiAgXCI1MDBcIjogICM5ZTllOWUsXG4gIFwiNjAwXCI6ICAjNzU3NTc1LFxuICBcIjcwMFwiOiAgIzYxNjE2MSxcbiAgXCI4MDBcIjogICM0MjQyNDIsXG4gIFwiOTAwXCI6ICAjMjEyMTIxLFxuKTtcblxuJGNsci1ncmV5OiAgICAgbWFwLWdldCgkY2xyLWdyZXktbGlzdCwgXCJiYXNlXCIpO1xuXG4kY2xyLWdyZXktNTA6ICBtYXAtZ2V0KCRjbHItZ3JleS1saXN0LCBcIjUwXCIpO1xuJGNsci1ncmV5LTEwMDogbWFwLWdldCgkY2xyLWdyZXktbGlzdCwgXCIxMDBcIik7XG4kY2xyLWdyZXktMjAwOiBtYXAtZ2V0KCRjbHItZ3JleS1saXN0LCBcIjIwMFwiKTtcbiRjbHItZ3JleS0zMDA6IG1hcC1nZXQoJGNsci1ncmV5LWxpc3QsIFwiMzAwXCIpO1xuJGNsci1ncmV5LTQwMDogbWFwLWdldCgkY2xyLWdyZXktbGlzdCwgXCI0MDBcIik7XG4kY2xyLWdyZXktNTAwOiBtYXAtZ2V0KCRjbHItZ3JleS1saXN0LCBcIjUwMFwiKTtcbiRjbHItZ3JleS02MDA6IG1hcC1nZXQoJGNsci1ncmV5LWxpc3QsIFwiNjAwXCIpO1xuJGNsci1ncmV5LTcwMDogbWFwLWdldCgkY2xyLWdyZXktbGlzdCwgXCI3MDBcIik7XG4kY2xyLWdyZXktODAwOiBtYXAtZ2V0KCRjbHItZ3JleS1saXN0LCBcIjgwMFwiKTtcbiRjbHItZ3JleS05MDA6IG1hcC1nZXQoJGNsci1ncmV5LWxpc3QsIFwiOTAwXCIpO1xuXG5cbi8vXG4vLyBCbHVlIGdyZXlcbi8vXG5cbiRjbHItYmx1ZS1ncmV5LWxpc3Q6IChcbiAgXCJiYXNlXCI6ICM2MDdkOGIsXG4gIFwiNTBcIjogICAjZWNlZmYxLFxuICBcIjEwMFwiOiAgI2NmZDhkYyxcbiAgXCIyMDBcIjogICNiMGJlYzUsXG4gIFwiMzAwXCI6ICAjOTBhNGFlLFxuICBcIjQwMFwiOiAgIzc4OTA5YyxcbiAgXCI1MDBcIjogICM2MDdkOGIsXG4gIFwiNjAwXCI6ICAjNTQ2ZTdhLFxuICBcIjcwMFwiOiAgIzQ1NWE2NCxcbiAgXCI4MDBcIjogICMzNzQ3NGYsXG4gIFwiOTAwXCI6ICAjMjYzMjM4LFxuKTtcblxuJGNsci1ibHVlLWdyZXk6ICAgICBtYXAtZ2V0KCRjbHItYmx1ZS1ncmV5LWxpc3QsIFwiYmFzZVwiKTtcblxuJGNsci1ibHVlLWdyZXktNTA6ICBtYXAtZ2V0KCRjbHItYmx1ZS1ncmV5LWxpc3QsIFwiNTBcIik7XG4kY2xyLWJsdWUtZ3JleS0xMDA6IG1hcC1nZXQoJGNsci1ibHVlLWdyZXktbGlzdCwgXCIxMDBcIik7XG4kY2xyLWJsdWUtZ3JleS0yMDA6IG1hcC1nZXQoJGNsci1ibHVlLWdyZXktbGlzdCwgXCIyMDBcIik7XG4kY2xyLWJsdWUtZ3JleS0zMDA6IG1hcC1nZXQoJGNsci1ibHVlLWdyZXktbGlzdCwgXCIzMDBcIik7XG4kY2xyLWJsdWUtZ3JleS00MDA6IG1hcC1nZXQoJGNsci1ibHVlLWdyZXktbGlzdCwgXCI0MDBcIik7XG4kY2xyLWJsdWUtZ3JleS01MDA6IG1hcC1nZXQoJGNsci1ibHVlLWdyZXktbGlzdCwgXCI1MDBcIik7XG4kY2xyLWJsdWUtZ3JleS02MDA6IG1hcC1nZXQoJGNsci1ibHVlLWdyZXktbGlzdCwgXCI2MDBcIik7XG4kY2xyLWJsdWUtZ3JleS03MDA6IG1hcC1nZXQoJGNsci1ibHVlLWdyZXktbGlzdCwgXCI3MDBcIik7XG4kY2xyLWJsdWUtZ3JleS04MDA6IG1hcC1nZXQoJGNsci1ibHVlLWdyZXktbGlzdCwgXCI4MDBcIik7XG4kY2xyLWJsdWUtZ3JleS05MDA6IG1hcC1nZXQoJGNsci1ibHVlLWdyZXktbGlzdCwgXCI5MDBcIik7XG5cblxuLy9cbi8vIEJsYWNrXG4vL1xuXG4kY2xyLWJsYWNrLWxpc3Q6IChcbiAgXCJiYXNlXCI6ICMwMDBcbik7XG5cbiRjbHItYmxhY2s6IG1hcC1nZXQoJGNsci1ibGFjay1saXN0LCBcImJhc2VcIik7XG5cblxuLy9cbi8vIFdoaXRlXG4vL1xuXG4kY2xyLXdoaXRlLWxpc3Q6IChcbiAgXCJiYXNlXCI6ICNmZmZcbik7XG5cbiRjbHItd2hpdGU6IG1hcC1nZXQoJGNsci13aGl0ZS1saXN0LCBcImJhc2VcIik7XG5cblxuLy9cbi8vIExpc3QgZm9yIGFsbCBDb2xvcnMgZm9yIGxvb3Bpbmdcbi8vXG5cbiRjbHItbGlzdC1hbGw6IChcbiAgXCJyZWRcIjogICAgICAgICAkY2xyLXJlZC1saXN0LFxuICBcInBpbmtcIjogICAgICAgICRjbHItcGluay1saXN0LFxuICBcInB1cnBsZVwiOiAgICAgICRjbHItcHVycGxlLWxpc3QsXG4gIFwiZGVlcC1wdXJwbGVcIjogJGNsci1kZWVwLXB1cnBsZS1saXN0LFxuICBcImluZGlnb1wiOiAgICAgICRjbHItaW5kaWdvLWxpc3QsXG4gIFwiYmx1ZVwiOiAgICAgICAgJGNsci1ibHVlLWxpc3QsXG4gIFwibGlnaHQtYmx1ZVwiOiAgJGNsci1saWdodC1ibHVlLWxpc3QsXG4gIFwiY3lhblwiOiAgICAgICAgJGNsci1jeWFuLWxpc3QsXG4gIFwidGVhbFwiOiAgICAgICAgJGNsci10ZWFsLWxpc3QsXG4gIFwiZ3JlZW5cIjogICAgICAgJGNsci1ncmVlbi1saXN0LFxuICBcImxpZ2h0LWdyZWVuXCI6ICRjbHItbGlnaHQtZ3JlZW4tbGlzdCxcbiAgXCJsaW1lXCI6ICAgICAgICAkY2xyLWxpbWUtbGlzdCxcbiAgXCJ5ZWxsb3dcIjogICAgICAkY2xyLXllbGxvdy1saXN0LFxuICBcImFtYmVyXCI6ICAgICAgICRjbHItYW1iZXItbGlzdCxcbiAgXCJvcmFuZ2VcIjogICAgICAkY2xyLW9yYW5nZS1saXN0LFxuICBcImRlZXAtb3JhbmdlXCI6ICRjbHItZGVlcC1vcmFuZ2UtbGlzdCxcbiAgXCJicm93blwiOiAgICAgICAkY2xyLWJyb3duLWxpc3QsXG4gIFwiZ3JleVwiOiAgICAgICAgJGNsci1ncmV5LWxpc3QsXG4gIFwiYmx1ZS1ncmV5XCI6ICAgJGNsci1ibHVlLWdyZXktbGlzdCxcbiAgXCJibGFja1wiOiAgICAgICAkY2xyLWJsYWNrLWxpc3QsXG4gIFwid2hpdGVcIjogICAgICAgJGNsci13aGl0ZS1saXN0XG4pO1xuXG5cbi8vXG4vLyBUeXBvZ3JhcGh5XG4vL1xuXG4kY2xyLXVpLWRpc3BsYXktNDogJGNsci1ncmV5LTYwMDtcbiRjbHItdWktZGlzcGxheS0zOiAkY2xyLWdyZXktNjAwO1xuJGNsci11aS1kaXNwbGF5LTI6ICRjbHItZ3JleS02MDA7XG4kY2xyLXVpLWRpc3BsYXktMTogJGNsci1ncmV5LTYwMDtcbiRjbHItdWktaGVhZGxpbmU6ICAkY2xyLWdyZXktOTAwO1xuJGNsci11aS10aXRsZTogICAgICRjbHItZ3JleS05MDA7XG4kY2xyLXVpLXN1YmhlYWQtMTogJGNsci1ncmV5LTkwMDtcbiRjbHItdWktYm9keS0yOiAgICAkY2xyLWdyZXktOTAwO1xuJGNsci11aS1ib2R5LTE6ICAgICRjbHItZ3JleS05MDA7XG4kY2xyLXVpLWNhcHRpb246ICAgJGNsci1ncmV5LTYwMDtcbiRjbHItdWktbWVudTogICAgICAkY2xyLWdyZXktOTAwO1xuJGNsci11aS1idXR0b246ICAgICRjbHItZ3JleS05MDA7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9ub2RlX21vZHVsZXMvbWF0ZXJpYWwtZGVzaWduLWNvbG9yL21hdGVyaWFsLWNvbG9yLnNjc3MiLCIvLy8vXG4vLy8gQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuLy8vXG4vLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksXG4vLy8gdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvblxuLy8vIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLFxuLy8vIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZVxuLy8vIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vLy9cbi8vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy8vXG4vLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTFxuLy8vIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbi8vLyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSXG4vLy8gREVBTElOR1Ncbi8vLy9cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVmFyaWFibGVzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vL1xuLy8vIERldmljZS1zcGVjaWZpYyBicmVha3BvaW50c1xuLy8vXG4vLy8gQGV4YW1wbGVcbi8vLyAgICRicmVhay1kZXZpY2VzOiAoXG4vLy8gICAgIG1vYmlsZTogKFxuLy8vICAgICAgIHBvcnRyYWl0OiAgMjIwcHggIDQ3OXB4LFxuLy8vICAgICAgIGxhbmRzY2FwZTogNDgwcHggIDcxOXB4XG4vLy8gICAgICksXG4vLy8gICAgIHRhYmxldDogKFxuLy8vICAgICAgIHBvcnRyYWl0OiAgNzIwcHggIDk1OXB4LFxuLy8vICAgICAgIGxhbmRzY2FwZTogOTYwcHggIDEyMTlweFxuLy8vICAgICApLFxuLy8vICAgICBzY3JlZW46IChcbi8vLyAgICAgICBzbWFsbDogICAgIDEyMjBweCAxNTk5cHgsXG4vLy8gICAgICAgbWVkaXVtOiAgICAxNjAwcHggMTk5OXB4LFxuLy8vICAgICAgIGxhcmdlOiAgICAgMjAwMHB4XG4vLy8gICAgIClcbi8vLyAgICk7XG4vLy9cbi8vLyBAZ3JvdXAgIGhlbHBlcnNcbi8vLyBAYWNjZXNzIHByaXZhdGVcbi8vLyBAdHlwZSAgIE1hcFxuLy8vXG4kYnJlYWstZGV2aWNlczogKCkgIWRlZmF1bHQ7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEhlbHBlcnNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8vXG4vLy8gQ2hvb3NlIG1pbmltdW0gYW5kIG1heGltdW0gZGV2aWNlIHdpZHRoc1xuLy8vXG4vLy8gQGdyb3VwICBoZWxwZXJzXG4vLy8gQGFjY2VzcyBwcml2YXRlXG4vLy8gQHBhcmFtICB7TWFwfSAgJGRldmljZXMgTWFwIG9mIGRldmljZXNcbi8vLyBAcmV0dXJuIHtMaXN0fSAgICAgICAgICBNaW5pbXVtIGFuZCBtYXhpbXVtIHdpZHRoXG4vLy9cbkBmdW5jdGlvbiBicmVhay1zZWxlY3QtbWluLW1heCgkZGV2aWNlcykge1xuICAkbWluOiAxMDAwMDAwO1xuICAkbWF4OiAwO1xuICBAZWFjaCAka2V5LCAkdmFsdWUgaW4gJGRldmljZXMge1xuICAgIEB3aGlsZSB0eXBlLW9mKCR2YWx1ZSkgPT0gbWFwIHtcbiAgICAgICR2YWx1ZTogYnJlYWstc2VsZWN0LW1pbi1tYXgoJHZhbHVlKTtcbiAgICB9XG4gICAgQGlmIHR5cGUtb2YoJHZhbHVlKSA9PSBsaXN0IHtcbiAgICAgIEBlYWNoICRudW1iZXIgaW4gJHZhbHVlIHtcbiAgICAgICAgQGlmIHR5cGUtb2YoJG51bWJlcikgPT0gbnVtYmVyIHtcbiAgICAgICAgICAkbWluOiBtaW4oJG51bWJlciwgJG1pbik7XG4gICAgICAgICAgQGlmICRtYXggIT0gbnVsbCB7XG4gICAgICAgICAgICAkbWF4OiBtYXgoJG51bWJlciwgJG1heCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICBAZXJyb3IgXCJJbnZhbGlkIG51bWJlcjogI3skbnVtYmVyfVwiO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBAZWxzZWlmIHR5cGUtb2YoJHZhbHVlKSA9PSBudW1iZXIge1xuICAgICAgJG1pbjogbWluKCR2YWx1ZSwgJG1pbik7XG4gICAgICAkbWF4OiBudWxsO1xuICAgIH0gQGVsc2Uge1xuICAgICAgQGVycm9yIFwiSW52YWxpZCB2YWx1ZTogI3skdmFsdWV9XCI7XG4gICAgfVxuICB9XG4gIEByZXR1cm4gJG1pbiwgJG1heDtcbn1cblxuLy8vXG4vLy8gU2VsZWN0IG1pbmltdW0gYW5kIG1heGltdW0gd2lkdGhzIGZvciBhIGRldmljZSBicmVha3BvaW50XG4vLy9cbi8vLyBAZ3JvdXAgIGhlbHBlcnNcbi8vLyBAYWNjZXNzIHByaXZhdGVcbi8vLyBAcGFyYW0gIHtTdHJpbmd9ICRkZXZpY2UgRGV2aWNlXG4vLy8gQHJldHVybiB7TGlzdH0gICAgICAgICAgIE1pbmltdW0gYW5kIG1heGltdW0gd2lkdGhcbi8vL1xuQGZ1bmN0aW9uIGJyZWFrLXNlbGVjdC1kZXZpY2UoJGRldmljZSkge1xuICAkY3VycmVudDogJGJyZWFrLWRldmljZXM7XG4gIEBmb3IgJG4gZnJvbSAxIHRocm91Z2ggbGVuZ3RoKCRkZXZpY2UpIHtcbiAgICBAaWYgdHlwZS1vZigkY3VycmVudCkgPT0gbWFwIHtcbiAgICAgICRjdXJyZW50OiBtYXAtZ2V0KCRjdXJyZW50LCBudGgoJGRldmljZSwgJG4pKTtcbiAgICB9IEBlbHNlIHtcbiAgICAgIEBlcnJvciBcIkludmFsaWQgZGV2aWNlIG1hcDogI3skZGV2aWNlc31cIjtcbiAgICB9XG4gIH1cbiAgQGlmIHR5cGUtb2YoJGN1cnJlbnQpID09IGxpc3Qgb3IgdHlwZS1vZigkY3VycmVudCkgPT0gbnVtYmVyIHtcbiAgICAkY3VycmVudDogKGRlZmF1bHQ6ICRjdXJyZW50KTtcbiAgfVxuICBAcmV0dXJuIGJyZWFrLXNlbGVjdC1taW4tbWF4KCRjdXJyZW50KTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gTWl4aW5zXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vL1xuLy8vIEEgbWluaW11bS1tYXhpbXVtIG1lZGlhIHF1ZXJ5IGJyZWFrcG9pbnRcbi8vL1xuLy8vIEBncm91cCAgaGVscGVyc1xuLy8vIEBhY2Nlc3MgcHVibGljXG4vLy8gQHBhcmFtICB7TnVtYmVyfExpc3R9ICRicmVha3BvaW50IE51bWJlciBvciBudW1iZXIgcGFpclxuLy8vXG5AbWl4aW4gYnJlYWstYXQoJGJyZWFrcG9pbnQpIHtcbiAgQGlmIHR5cGUtb2YoJGJyZWFrcG9pbnQpID09IG51bWJlciB7XG4gICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAkYnJlYWtwb2ludCkge1xuICAgICAgQGNvbnRlbnQ7XG4gICAgfVxuICB9IEBlbHNlaWYgdHlwZS1vZigkYnJlYWtwb2ludCkgPT0gbGlzdCB7XG4gICAgJG1pbjogbnRoKCRicmVha3BvaW50LCAxKTtcbiAgICAkbWF4OiBudGgoJGJyZWFrcG9pbnQsIDIpO1xuICAgIEBpZiB0eXBlLW9mKCRtaW4pID09IG51bWJlciBhbmQgdHlwZS1vZigkbWF4KSA9PSBudW1iZXIge1xuICAgICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAkbWluKSBhbmQgKG1heC13aWR0aDogJG1heCkge1xuICAgICAgICBAY29udGVudDtcbiAgICAgIH1cbiAgICB9IEBlbHNlIHtcbiAgICAgIEBlcnJvciBcIkludmFsaWQgYnJlYWtwb2ludDogI3skYnJlYWtwb2ludH1cIjtcbiAgICB9XG4gIH0gQGVsc2Uge1xuICAgIEBlcnJvciBcIkludmFsaWQgYnJlYWtwb2ludDogI3skYnJlYWtwb2ludH1cIjtcbiAgfVxufVxuXG4vLy9cbi8vLyBBbiBvcmllbnRhdGlvbiBtZWRpYSBxdWVyeSBicmVha3BvaW50XG4vLy9cbi8vLyBAZ3JvdXAgIGhlbHBlcnNcbi8vLyBAYWNjZXNzIHB1YmxpY1xuLy8vIEBwYXJhbSAge1N0cmluZ30gJGJyZWFrcG9pbnQgT3JpZW50YXRpb25cbi8vL1xuQG1peGluIGJyZWFrLWF0LW9yaWVudGF0aW9uKCRicmVha3BvaW50KSB7XG4gIEBpZiB0eXBlLW9mKCRicmVha3BvaW50KSA9PSBzdHJpbmcge1xuICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG9yaWVudGF0aW9uOiAkYnJlYWtwb2ludCkge1xuICAgICAgQGNvbnRlbnQ7XG4gICAgfVxuICB9IEBlbHNlIHtcbiAgICBAZXJyb3IgXCJJbnZhbGlkIGJyZWFrcG9pbnQ6ICN7JGJyZWFrcG9pbnR9XCI7XG4gIH1cbn1cblxuLy8vXG4vLy8gQSBtYXhpbXVtLWFzcGVjdC1yYXRpbyBtZWRpYSBxdWVyeSBicmVha3BvaW50XG4vLy9cbi8vLyBAZ3JvdXAgIGhlbHBlcnNcbi8vLyBAYWNjZXNzIHB1YmxpY1xuLy8vIEBwYXJhbSAge051bWJlcn0gJGJyZWFrcG9pbnQgUmF0aW9cbi8vL1xuQG1peGluIGJyZWFrLWF0LXJhdGlvKCRicmVha3BvaW50KSB7XG4gIEBpZiB0eXBlLW9mKCRicmVha3BvaW50KSA9PSBudW1iZXIge1xuICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1heC1hc3BlY3QtcmF0aW86ICRicmVha3BvaW50KSB7XG4gICAgICBAY29udGVudDtcbiAgICB9XG4gIH0gQGVsc2Uge1xuICAgIEBlcnJvciBcIkludmFsaWQgYnJlYWtwb2ludDogI3skYnJlYWtwb2ludH1cIjtcbiAgfVxufVxuXG4vLy9cbi8vLyBBIG1pbmltdW0tbWF4aW11bSBtZWRpYSBxdWVyeSBkZXZpY2UgYnJlYWtwb2ludFxuLy8vXG4vLy8gQGdyb3VwICBoZWxwZXJzXG4vLy8gQGFjY2VzcyBwdWJsaWNcbi8vLyBAcGFyYW0gIHtTdHJpbmd8TGlzdH0gJGJyZWFrcG9pbnQgRGV2aWNlXG4vLy9cbkBtaXhpbiBicmVhay1hdC1kZXZpY2UoJGRldmljZSkge1xuICBAaWYgdHlwZS1vZigkZGV2aWNlKSA9PSBzdHJpbmcge1xuICAgICRkZXZpY2U6ICRkZXZpY2UsO1xuICB9XG4gIEBpZiB0eXBlLW9mKCRkZXZpY2UpID09IGxpc3Qge1xuICAgICRicmVha3BvaW50OiBicmVhay1zZWxlY3QtZGV2aWNlKCRkZXZpY2UpO1xuICAgIEBpZiBudGgoJGJyZWFrcG9pbnQsIDIpICE9IG51bGwge1xuICAgICAgJG1pbjogbnRoKCRicmVha3BvaW50LCAxKTtcbiAgICAgICRtYXg6IG50aCgkYnJlYWtwb2ludCwgMik7XG4gICAgICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6ICRtaW4pIGFuZCAobWF4LXdpZHRoOiAkbWF4KSB7XG4gICAgICAgIEBjb250ZW50O1xuICAgICAgfVxuICAgIH0gQGVsc2Uge1xuICAgICAgQGVycm9yIFwiSW52YWxpZCBkZXZpY2U6ICN7JGRldmljZX1cIjtcbiAgICB9XG4gIH0gQGVsc2Uge1xuICAgIEBlcnJvciBcIkludmFsaWQgZGV2aWNlOiAjeyRkZXZpY2V9XCI7XG4gIH1cbn1cblxuLy8vXG4vLy8gQSBtaW5pbXVtIG1lZGlhIHF1ZXJ5IGRldmljZSBicmVha3BvaW50XG4vLy9cbi8vLyBAZ3JvdXAgIGhlbHBlcnNcbi8vLyBAYWNjZXNzIHB1YmxpY1xuLy8vIEBwYXJhbSAge1N0cmluZ3xMaXN0fSAkYnJlYWtwb2ludCBEZXZpY2Vcbi8vL1xuQG1peGluIGJyZWFrLWZyb20tZGV2aWNlKCRkZXZpY2UpIHtcbiAgQGlmIHR5cGUtb2YoJGRldmljZSkgPT0gc3RyaW5nIHtcbiAgICAkZGV2aWNlOiAkZGV2aWNlLDtcbiAgfVxuICBAaWYgdHlwZS1vZigkZGV2aWNlKSA9PSBsaXN0IHtcbiAgICAkYnJlYWtwb2ludDogYnJlYWstc2VsZWN0LWRldmljZSgkZGV2aWNlKTtcbiAgICAkbWluOiBudGgoJGJyZWFrcG9pbnQsIDEpO1xuICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogJG1pbikge1xuICAgICAgQGNvbnRlbnQ7XG4gICAgfVxuICB9IEBlbHNlIHtcbiAgICBAZXJyb3IgXCJJbnZhbGlkIGRldmljZTogI3skZGV2aWNlfVwiO1xuICB9XG59XG5cbi8vL1xuLy8vIEEgbWF4aW11bSBtZWRpYSBxdWVyeSBkZXZpY2UgYnJlYWtwb2ludFxuLy8vXG4vLy8gQGdyb3VwICBoZWxwZXJzXG4vLy8gQGFjY2VzcyBwdWJsaWNcbi8vLyBAcGFyYW0gIHtTdHJpbmd8TGlzdH0gJGJyZWFrcG9pbnQgRGV2aWNlXG4vLy9cbkBtaXhpbiBicmVhay10by1kZXZpY2UoJGRldmljZSkge1xuICBAaWYgdHlwZS1vZigkZGV2aWNlKSA9PSBzdHJpbmcge1xuICAgICRkZXZpY2U6ICRkZXZpY2UsO1xuICB9XG4gIEBpZiB0eXBlLW9mKCRkZXZpY2UpID09IGxpc3Qge1xuICAgICRicmVha3BvaW50OiBicmVhay1zZWxlY3QtZGV2aWNlKCRkZXZpY2UpO1xuICAgICRtYXg6IG50aCgkYnJlYWtwb2ludCwgMik7XG4gICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkbWF4KSB7XG4gICAgICBAY29udGVudDtcbiAgICB9XG4gIH0gQGVsc2Uge1xuICAgIEBlcnJvciBcIkludmFsaWQgZGV2aWNlOiAjeyRkZXZpY2V9XCI7XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvaGVscGVycy9fYnJlYWsuc2NzcyJdLCJzb3VyY2VSb290IjoiIn0=*/"
  },
  {
    "path": "SecurityPaper-themes/assets/stylesheets/application.css",
    "content": "@charset \"UTF-8\";\nhtml {\n  box-sizing: border-box; }\n\n*,\n*::before,\n*::after {\n  box-sizing: inherit; }\n\nhtml {\n  -webkit-text-size-adjust: none;\n     -moz-text-size-adjust: none;\n      -ms-text-size-adjust: none;\n          text-size-adjust: none; }\n\nbody {\n  margin: 0; }\n\nhr {\n  overflow: visible;\n  box-sizing: content-box; }\n\na {\n  -webkit-text-decoration-skip: objects; }\n\na,\nbutton,\nlabel,\ninput {\n  -webkit-tap-highlight-color: transparent; }\n\na {\n  color: inherit;\n  text-decoration: none; }\n\nsmall {\n  font-size: 80%; }\n\nsub,\nsup {\n  position: relative;\n  font-size: 80%;\n  line-height: 0;\n  vertical-align: baseline; }\n\nsub {\n  bottom: -0.25em; }\n\nsup {\n  top: -0.5em; }\n\nimg {\n  border-style: none; }\n\ntable {\n  border-collapse: separate;\n  border-spacing: 0; }\n\ntd,\nth {\n  font-weight: normal;\n  vertical-align: top; }\n\nbutton {\n  margin: 0;\n  padding: 0;\n  border: 0;\n  outline-style: none;\n  background: transparent;\n  font-size: inherit; }\n\ninput {\n  border: 0;\n  outline: 0; }\n\n.md-icon, .md-clipboard::before, .md-nav__title::before, .md-nav__button, .md-nav__link::after, .md-search-result__article--document::before, .md-source-file::before, .md-typeset .admonition > .admonition-title::before, .md-typeset details > .admonition-title::before, .md-typeset .admonition > summary::before, .md-typeset details > summary::before, .md-typeset .footnote-backref, .md-typeset .critic.comment::before, .md-typeset summary::after, .md-typeset .task-list-control .task-list-indicator::before {\n  font-family: \"Material Icons\";\n  font-style: normal;\n  font-variant: normal;\n  font-weight: normal;\n  line-height: 1;\n  text-transform: none;\n  white-space: nowrap;\n  speak: none;\n  word-wrap: normal;\n  direction: ltr; }\n  .md-content__icon, .md-header-nav__button, .md-footer-nav__button, .md-nav__title::before, .md-nav__button, .md-search-result__article--document::before {\n    display: inline-block;\n    margin: 0.4rem;\n    padding: 0.8rem;\n    font-size: 2.4rem;\n    cursor: pointer; }\n\n.md-icon--arrow-back::before {\n  content: \"\\E5C4\"; }\n\n.md-icon--arrow-forward::before {\n  content: \"\\E5C8\"; }\n\n.md-icon--menu::before {\n  content: \"\\E5D2\"; }\n\n.md-icon--search::before {\n  content: \"\\E8B6\"; }\n\n[dir=\"rtl\"] .md-icon--arrow-back::before {\n  content: \"\\E5C8\"; }\n\n[dir=\"rtl\"] .md-icon--arrow-forward::before {\n  content: \"\\E5C4\"; }\n\nbody {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale; }\n\nbody,\ninput {\n  color: rgba(0, 0, 0, 0.87);\n  -webkit-font-feature-settings: \"kern\", \"liga\";\n          font-feature-settings: \"kern\", \"liga\";\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif; }\n\npre,\ncode,\nkbd {\n  color: rgba(0, 0, 0, 0.87);\n  -webkit-font-feature-settings: \"kern\";\n          font-feature-settings: \"kern\";\n  font-family: \"Courier New\", Courier, monospace; }\n\n.md-typeset {\n  font-size: 1.6rem;\n  line-height: 1.6;\n  -webkit-print-color-adjust: exact; }\n  .md-typeset p,\n  .md-typeset ul,\n  .md-typeset ol,\n  .md-typeset blockquote {\n    margin: 1em 0; }\n  .md-typeset h1 {\n    margin: 0 0 4rem;\n    color: rgba(0, 0, 0, 0.54);\n    font-size: 3.125rem;\n    font-weight: 300;\n    letter-spacing: -0.01em;\n    line-height: 1.3; }\n  .md-typeset h2 {\n    margin: 4rem 0 1.6rem;\n    font-size: 2.5rem;\n    font-weight: 300;\n    letter-spacing: -0.01em;\n    line-height: 1.4; }\n  .md-typeset h3 {\n    margin: 3.2rem 0 1.6rem;\n    font-size: 2rem;\n    font-weight: 400;\n    letter-spacing: -0.01em;\n    line-height: 1.5; }\n  .md-typeset h2 + h3 {\n    margin-top: 1.6rem; }\n  .md-typeset h4 {\n    margin: 1.6rem 0;\n    font-size: 1.6rem;\n    font-weight: 700;\n    letter-spacing: -0.01em; }\n  .md-typeset h5,\n  .md-typeset h6 {\n    margin: 1.6rem 0;\n    color: rgba(0, 0, 0, 0.54);\n    font-size: 1.28rem;\n    font-weight: 700;\n    letter-spacing: -0.01em; }\n  .md-typeset h5 {\n    text-transform: uppercase; }\n  .md-typeset hr {\n    margin: 1.5em 0;\n    border-bottom: 0.1rem dotted rgba(0, 0, 0, 0.26); }\n  .md-typeset a {\n    color: #3f51b5;\n    word-break: break-word; }\n    .md-typeset a, .md-typeset a::before {\n      transition: color 0.125s; }\n    .md-typeset a:hover, .md-typeset a:active {\n      color: #536dfe; }\n  .md-typeset code,\n  .md-typeset pre {\n    background-color: rgba(236, 236, 236, 0.5);\n    color: #37474F;\n    font-size: 85%;\n    direction: ltr; }\n  .md-typeset code {\n    margin: 0 0.29412em;\n    padding: 0.07353em 0;\n    border-radius: 0.2rem;\n    box-shadow: 0.29412em 0 0 rgba(236, 236, 236, 0.5), -0.29412em 0 0 rgba(236, 236, 236, 0.5);\n    word-break: break-word;\n    -webkit-box-decoration-break: clone;\n            box-decoration-break: clone; }\n  .md-typeset h1 code,\n  .md-typeset h2 code,\n  .md-typeset h3 code,\n  .md-typeset h4 code,\n  .md-typeset h5 code,\n  .md-typeset h6 code {\n    margin: 0;\n    background-color: transparent;\n    box-shadow: none; }\n  .md-typeset a > code {\n    margin: inherit;\n    padding: inherit;\n    border-radius: none;\n    background-color: inherit;\n    color: inherit;\n    box-shadow: none; }\n  .md-typeset pre {\n    position: relative;\n    margin: 1em 0;\n    border-radius: 0.2rem;\n    line-height: 1.4;\n    -webkit-overflow-scrolling: touch; }\n    .md-typeset pre > code {\n      display: block;\n      margin: 0;\n      padding: 1.05rem 1.2rem;\n      background-color: transparent;\n      font-size: inherit;\n      box-shadow: none;\n      -webkit-box-decoration-break: none;\n              box-decoration-break: none;\n      overflow: auto; }\n      .md-typeset pre > code::-webkit-scrollbar {\n        width: 0.4rem;\n        height: 0.4rem; }\n      .md-typeset pre > code::-webkit-scrollbar-thumb {\n        background-color: rgba(0, 0, 0, 0.26); }\n        .md-typeset pre > code::-webkit-scrollbar-thumb:hover {\n          background-color: #536dfe; }\n  .md-typeset kbd {\n    padding: 0 0.29412em;\n    border: 0.1rem solid #c9c9c9;\n    border-radius: 0.3rem;\n    border-bottom-color: #bcbcbc;\n    background-color: #FCFCFC;\n    color: #555555;\n    font-size: 85%;\n    box-shadow: 0 0.1rem 0 #b0b0b0;\n    word-break: break-word; }\n  .md-typeset mark {\n    margin: 0 0.25em;\n    padding: 0.0625em 0;\n    border-radius: 0.2rem;\n    background-color: rgba(255, 235, 59, 0.5);\n    box-shadow: 0.25em 0 0 rgba(255, 235, 59, 0.5), -0.25em 0 0 rgba(255, 235, 59, 0.5);\n    word-break: break-word;\n    -webkit-box-decoration-break: clone;\n            box-decoration-break: clone; }\n  .md-typeset abbr {\n    border-bottom: 0.1rem dotted rgba(0, 0, 0, 0.54);\n    text-decoration: none;\n    cursor: help; }\n  .md-typeset small {\n    opacity: 0.75; }\n  .md-typeset sup,\n  .md-typeset sub {\n    margin-left: 0.07812em; }\n    [dir=\"rtl\"] .md-typeset sup, [dir=\"rtl\"]\n    .md-typeset sub {\n      margin-right: 0.07812em;\n      margin-left: initial; }\n  .md-typeset blockquote {\n    padding-left: 1.2rem;\n    border-left: 0.4rem solid rgba(0, 0, 0, 0.26);\n    color: rgba(0, 0, 0, 0.54); }\n    [dir=\"rtl\"] .md-typeset blockquote {\n      padding-right: 1.2rem;\n      padding-left: initial;\n      border-right: 0.4rem solid rgba(0, 0, 0, 0.26);\n      border-left: initial; }\n  .md-typeset ul {\n    list-style-type: disc; }\n  .md-typeset ul,\n  .md-typeset ol {\n    margin-left: 0.625em;\n    padding: 0; }\n    [dir=\"rtl\"] .md-typeset ul, [dir=\"rtl\"]\n    .md-typeset ol {\n      margin-right: 0.625em;\n      margin-left: initial; }\n    .md-typeset ul ol,\n    .md-typeset ol ol {\n      list-style-type: lower-alpha; }\n      .md-typeset ul ol ol,\n      .md-typeset ol ol ol {\n        list-style-type: lower-roman; }\n    .md-typeset ul li,\n    .md-typeset ol li {\n      margin-bottom: 0.5em;\n      margin-left: 1.25em; }\n      [dir=\"rtl\"] .md-typeset ul li, [dir=\"rtl\"]\n      .md-typeset ol li {\n        margin-right: 1.25em;\n        margin-left: initial; }\n      .md-typeset ul li p,\n      .md-typeset ul li blockquote,\n      .md-typeset ol li p,\n      .md-typeset ol li blockquote {\n        margin: 0.5em 0; }\n      .md-typeset ul li:last-child,\n      .md-typeset ol li:last-child {\n        margin-bottom: 0; }\n      .md-typeset ul li ul,\n      .md-typeset ul li ol,\n      .md-typeset ol li ul,\n      .md-typeset ol li ol {\n        margin: 0.5em 0 0.5em 0.625em; }\n        [dir=\"rtl\"] .md-typeset ul li ul, [dir=\"rtl\"]\n        .md-typeset ul li ol, [dir=\"rtl\"]\n        .md-typeset ol li ul, [dir=\"rtl\"]\n        .md-typeset ol li ol {\n          margin-right: 0.625em;\n          margin-left: initial; }\n  .md-typeset dd {\n    margin: 1em 0 1em 1.875em; }\n    [dir=\"rtl\"] .md-typeset dd {\n      margin-right: 1.875em;\n      margin-left: initial; }\n  .md-typeset iframe,\n  .md-typeset img,\n  .md-typeset svg {\n    max-width: 100%; }\n  .md-typeset table:not([class]) {\n    box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);\n    display: inline-block;\n    max-width: 100%;\n    border-radius: 0.2rem;\n    font-size: 1.28rem;\n    overflow: auto;\n    -webkit-overflow-scrolling: touch; }\n    .md-typeset table:not([class]) + * {\n      margin-top: 1.5em; }\n    .md-typeset table:not([class]) th:not([align]),\n    .md-typeset table:not([class]) td:not([align]) {\n      text-align: left; }\n      [dir=\"rtl\"] .md-typeset table:not([class]) th:not([align]), [dir=\"rtl\"]\n      .md-typeset table:not([class]) td:not([align]) {\n        text-align: right; }\n    .md-typeset table:not([class]) th {\n      min-width: 10rem;\n      padding: 1.2rem 1.6rem;\n      background-color: rgba(0, 0, 0, 0.54);\n      color: white;\n      vertical-align: top; }\n    .md-typeset table:not([class]) td {\n      padding: 1.2rem 1.6rem;\n      border-top: 0.1rem solid rgba(0, 0, 0, 0.07);\n      vertical-align: top; }\n    .md-typeset table:not([class]) tr:first-child td {\n      border-top: 0; }\n    .md-typeset table:not([class]) a {\n      word-break: normal; }\n  .md-typeset__scrollwrap {\n    margin: 1em -1.6rem;\n    overflow-x: auto;\n    -webkit-overflow-scrolling: touch; }\n  .md-typeset .md-typeset__table {\n    display: inline-block;\n    margin-bottom: 0.5em;\n    padding: 0 1.6rem; }\n    .md-typeset .md-typeset__table table {\n      display: table;\n      width: 100%;\n      margin: 0;\n      overflow: hidden; }\n\nhtml {\n  height: 100%;\n  font-size: 62.5%;\n  overflow-x: hidden; }\n\nbody {\n  position: relative;\n  height: 100%; }\n\nhr {\n  display: block;\n  height: 0.1rem;\n  padding: 0;\n  border: 0; }\n\n.md-svg {\n  display: none; }\n\n.md-grid {\n  max-width: 122rem;\n  margin-right: auto;\n  margin-left: auto; }\n\n.md-container,\n.md-main {\n  overflow: auto; }\n\n.md-container {\n  display: table;\n  width: 100%;\n  height: 100%;\n  padding-top: 4.8rem;\n  table-layout: fixed; }\n\n.md-main {\n  display: table-row;\n  height: 100%; }\n  .md-main__inner {\n    height: 100%;\n    padding-top: 3rem;\n    padding-bottom: 0.1rem; }\n\n.md-toggle {\n  display: none; }\n\n.md-overlay {\n  position: fixed;\n  top: 0;\n  width: 0;\n  height: 0;\n  transition: width   0s 0.25s, height  0s 0.25s, opacity 0.25s;\n  background-color: rgba(0, 0, 0, 0.54);\n  opacity: 0;\n  z-index: 3; }\n\n.md-flex {\n  display: table; }\n  .md-flex__cell {\n    display: table-cell;\n    position: relative;\n    vertical-align: top; }\n    .md-flex__cell--shrink {\n      width: 0%; }\n    .md-flex__cell--stretch {\n      display: table;\n      width: 100%;\n      table-layout: fixed; }\n  .md-flex__ellipsis {\n    display: table-cell;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n    overflow: hidden; }\n\n.md-skip {\n  position: fixed;\n  width: 0.1rem;\n  height: 0.1rem;\n  margin: 1rem;\n  padding: 0.6rem 1rem;\n  clip: rect(0.1rem);\n  -webkit-transform: translateY(0.8rem);\n          transform: translateY(0.8rem);\n  border-radius: 0.2rem;\n  background-color: rgba(0, 0, 0, 0.87);\n  color: white;\n  font-size: 1.28rem;\n  opacity: 0;\n  overflow: hidden; }\n  .md-skip:focus {\n    width: auto;\n    height: auto;\n    clip: auto;\n    -webkit-transform: translateX(0);\n            transform: translateX(0);\n    transition: opacity 0.175s 0.075s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n    transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.175s 0.075s;\n    transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.175s 0.075s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n    opacity: 1;\n    z-index: 10; }\n\n@page {\n  margin: 25mm; }\n\nul, ul li {\n  margin: 0;\n  padding: 0;\n  list-style: none; }\n\n.about {\n  margin-top: 50px; }\n\n.about-list {\n  overflow: hidden; }\n\n.about-list li {\n  float: left;\n  margin: 1px;\n  width: 200px;\n  height: 280px;\n  padding: 20px 15px;\n  border: 1px solid #f0f0f0;\n  border-radius: 3px;\n  box-shadow: -1px 0px 10px #e4e4e4;\n  -webkit-box-shadow: -1px 0px 10px #e4e4e4;\n  transition: all .3s;\n  -webkit-transition: all .3s; }\n\n.about-list li:hover {\n  box-shadow: -1px 0px 15px #dbdbdb;\n  -webkit-box-shadow: -1px 0px 15px #dbdbdb; }\n\n.about-list .picture {\n  display: block;\n  overflow: hidden;\n  margin: auto;\n  width: 168px;\n  height: 168px;\n  border-radius: 3px; }\n\n.about-list .desc {\n  margin: 0; }\n\n.about-list .desc dt {\n  margin: 10px 0 5px;\n  font-weight: bold; }\n\n.about-list .desc dd {\n  display: -webkit-box;\n  margin: 0;\n  overflow: hidden;\n  font-size: .8em;\n  line-height: 1.4em;\n  text-overflow: ellipsis;\n  -webkit-line-clamp: 3;\n  color: #888;\n  width: 100%; }\n\n.md-clipboard {\n  position: absolute;\n  top: 0.6rem;\n  right: 0.6rem;\n  width: 2.8rem;\n  height: 2.8rem;\n  border-radius: 0.2rem;\n  font-size: 1.6rem;\n  cursor: pointer;\n  z-index: 1;\n  -webkit-backface-visibility: hidden;\n          backface-visibility: hidden; }\n  .md-clipboard::before {\n    transition: color   0.25s, opacity 0.25s;\n    color: rgba(0, 0, 0, 0.07);\n    content: \"\\E14D\"; }\n    pre:hover .md-clipboard::before,\n    .codehilite:hover .md-clipboard::before,\n    .md-typeset .highlight:hover .md-clipboard::before {\n      color: rgba(0, 0, 0, 0.54); }\n  .md-clipboard:focus::before, .md-clipboard:hover::before {\n    color: #536dfe; }\n  .md-clipboard__message {\n    display: block;\n    position: absolute;\n    top: 0;\n    right: 3.4rem;\n    padding: 0.6rem 1rem;\n    -webkit-transform: translateX(0.8rem);\n            transform: translateX(0.8rem);\n    transition: opacity 0.175s, -webkit-transform 0.25s cubic-bezier(0.9, 0.1, 0.9, 0);\n    transition: transform 0.25s cubic-bezier(0.9, 0.1, 0.9, 0), opacity 0.175s;\n    transition: transform 0.25s cubic-bezier(0.9, 0.1, 0.9, 0), opacity 0.175s, -webkit-transform 0.25s cubic-bezier(0.9, 0.1, 0.9, 0);\n    border-radius: 0.2rem;\n    background-color: rgba(0, 0, 0, 0.54);\n    color: white;\n    font-size: 1.28rem;\n    white-space: nowrap;\n    opacity: 0;\n    pointer-events: none; }\n    .md-clipboard__message--active {\n      -webkit-transform: translateX(0);\n              transform: translateX(0);\n      transition: opacity 0.175s 0.075s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n      transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.175s 0.075s;\n      transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.175s 0.075s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n      opacity: 1;\n      pointer-events: initial; }\n    .md-clipboard__message::before {\n      content: attr(aria-label); }\n    .md-clipboard__message::after {\n      display: block;\n      position: absolute;\n      top: 50%;\n      right: -0.4rem;\n      width: 0;\n      margin-top: -0.4rem;\n      border-width: 0.4rem 0 0.4rem 0.4rem;\n      border-style: solid;\n      border-color: transparent rgba(0, 0, 0, 0.54);\n      content: \"\"; }\n\n.md-content__inner {\n  margin: 0 1.6rem 2.4rem;\n  padding-top: 1.2rem; }\n  .md-content__inner::before {\n    display: block;\n    height: 0.8rem;\n    content: \"\"; }\n  .md-content__inner > :last-child {\n    margin-bottom: 0; }\n\n.md-content__icon {\n  position: relative;\n  margin: 0.8rem 0;\n  padding: 0;\n  float: right; }\n  .md-typeset .md-content__icon {\n    color: rgba(0, 0, 0, 0.26); }\n\n.md-header {\n  position: fixed;\n  top: 0;\n  right: 0;\n  left: 0;\n  height: 4.8rem;\n  transition: background-color 0.25s, color 0.25s;\n  background-color: #3f51b5;\n  color: white;\n  box-shadow: none;\n  z-index: 2;\n  -webkit-backface-visibility: hidden;\n          backface-visibility: hidden; }\n  .no-js .md-header {\n    transition: none;\n    box-shadow: none; }\n  .md-header[data-md-state=\"shadow\"] {\n    transition: background-color 0.25s, color 0.25s, box-shadow 0.25s;\n    box-shadow: 0 0 0.4rem rgba(0, 0, 0, 0.1), 0 0.4rem 0.8rem rgba(0, 0, 0, 0.2); }\n\n.md-header-nav {\n  padding: 0 0.4rem; }\n  .md-header-nav__button {\n    position: relative;\n    transition: opacity 0.25s;\n    z-index: 1; }\n    .md-header-nav__button:hover {\n      opacity: 0.7; }\n    .md-header-nav__button.md-logo * {\n      display: block; }\n    .no-js .md-header-nav__button.md-icon--search {\n      display: none; }\n  .md-header-nav__topic {\n    display: block;\n    position: absolute;\n    transition: opacity 0.15s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1);\n    transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s;\n    transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1);\n    text-overflow: ellipsis;\n    white-space: nowrap;\n    overflow: hidden; }\n    .md-header-nav__topic + .md-header-nav__topic {\n      -webkit-transform: translateX(2.5rem);\n              transform: translateX(2.5rem);\n      transition: opacity 0.15s, -webkit-transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1);\n      transition: transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), opacity 0.15s;\n      transition: transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), opacity 0.15s, -webkit-transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1);\n      opacity: 0;\n      z-index: -1;\n      pointer-events: none; }\n      [dir=\"rtl\"] .md-header-nav__topic + .md-header-nav__topic {\n        -webkit-transform: translateX(-2.5rem);\n                transform: translateX(-2.5rem); }\n    .no-js .md-header-nav__topic {\n      position: initial; }\n    .no-js .md-header-nav__topic + .md-header-nav__topic {\n      display: none; }\n  .md-header-nav__title {\n    padding: 0 2rem;\n    font-size: 1.8rem;\n    line-height: 4.8rem; }\n    .md-header-nav__title[data-md-state=\"active\"] .md-header-nav__topic {\n      -webkit-transform: translateX(-2.5rem);\n              transform: translateX(-2.5rem);\n      transition: opacity 0.15s, -webkit-transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1);\n      transition: transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), opacity 0.15s;\n      transition: transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), opacity 0.15s, -webkit-transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1);\n      opacity: 0;\n      z-index: -1;\n      pointer-events: none; }\n      [dir=\"rtl\"] .md-header-nav__title[data-md-state=\"active\"] .md-header-nav__topic {\n        -webkit-transform: translateX(2.5rem);\n                transform: translateX(2.5rem); }\n      .md-header-nav__title[data-md-state=\"active\"] .md-header-nav__topic + .md-header-nav__topic {\n        -webkit-transform: translateX(0);\n                transform: translateX(0);\n        transition: opacity 0.15s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1);\n        transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s;\n        transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1);\n        opacity: 1;\n        z-index: 0;\n        pointer-events: initial; }\n  .md-header-nav__source {\n    display: none; }\n\n.md-hero {\n  transition: background 0.25s;\n  background-color: #3f51b5;\n  color: white;\n  font-size: 2rem;\n  overflow: hidden; }\n  .md-hero__inner {\n    margin-top: 2rem;\n    padding: 1.6rem 1.6rem 0.8rem;\n    transition: opacity 0.25s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1);\n    transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s;\n    transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1);\n    transition-delay: 0.1s; }\n    [data-md-state=\"hidden\"] .md-hero__inner {\n      pointer-events: none;\n      -webkit-transform: translateY(1.25rem);\n              transform: translateY(1.25rem);\n      transition: opacity   0.1s 0s, -webkit-transform 0s   0.4s;\n      transition: transform 0s   0.4s, opacity   0.1s 0s;\n      transition: transform 0s   0.4s, opacity   0.1s 0s, -webkit-transform 0s   0.4s;\n      opacity: 0; }\n    .md-hero--expand .md-hero__inner {\n      margin-bottom: 2.4rem; }\n\n.md-footer-nav {\n  background-color: rgba(0, 0, 0, 0.87);\n  color: white; }\n  .md-footer-nav__inner {\n    padding: 0.4rem;\n    overflow: auto; }\n  .md-footer-nav__link {\n    padding-top: 2.8rem;\n    padding-bottom: 0.8rem;\n    transition: opacity 0.25s; }\n    .md-footer-nav__link:hover {\n      opacity: 0.7; }\n    .md-footer-nav__link--prev {\n      width: 25%;\n      float: left; }\n      [dir=\"rtl\"] .md-footer-nav__link--prev {\n        float: right; }\n    .md-footer-nav__link--next {\n      width: 75%;\n      float: right;\n      text-align: right; }\n      [dir=\"rtl\"] .md-footer-nav__link--next {\n        float: left;\n        text-align: left; }\n  .md-footer-nav__button {\n    transition: background 0.25s; }\n  .md-footer-nav__title {\n    position: relative;\n    padding: 0 2rem;\n    font-size: 1.8rem;\n    line-height: 4.8rem; }\n  .md-footer-nav__direction {\n    position: absolute;\n    right: 0;\n    left: 0;\n    margin-top: -2rem;\n    padding: 0 2rem;\n    color: rgba(255, 255, 255, 0.7);\n    font-size: 1.5rem; }\n\n.md-footer-meta {\n  background-color: rgba(0, 0, 0, 0.895); }\n  .md-footer-meta__inner {\n    padding: 0.4rem;\n    overflow: auto; }\n  html .md-footer-meta.md-typeset a {\n    color: rgba(255, 255, 255, 0.7); }\n    html .md-footer-meta.md-typeset a:focus, html .md-footer-meta.md-typeset a:hover {\n      color: white; }\n\n.md-footer-copyright {\n  margin: 0 1.2rem;\n  padding: 0.8rem 0;\n  color: rgba(255, 255, 255, 0.3);\n  font-size: 1.28rem; }\n  .md-footer-copyright__highlight {\n    color: rgba(255, 255, 255, 0.7); }\n\n.md-footer-social {\n  margin: 0 0.8rem;\n  padding: 0.4rem 0 1.2rem; }\n  .md-footer-social__link {\n    display: inline-block;\n    width: 3.2rem;\n    height: 3.2rem;\n    font-size: 1.6rem;\n    text-align: center; }\n    .md-footer-social__link::before {\n      line-height: 1.9; }\n\n.md-nav {\n  font-size: 1.4rem;\n  line-height: 1.3; }\n  .md-nav__title {\n    display: block;\n    padding: 0 1.2rem;\n    font-weight: 700;\n    text-overflow: ellipsis;\n    overflow: hidden; }\n    .md-nav__title::before {\n      display: none;\n      content: \"\\E5C4\"; }\n      [dir=\"rtl\"] .md-nav__title::before {\n        content: \"\\E5C8\"; }\n    .md-nav__title .md-nav__button {\n      display: none; }\n  .md-nav__list {\n    margin: 0;\n    padding: 0;\n    list-style: none; }\n  .md-nav__item {\n    padding: 0 1.2rem; }\n    .md-nav__item:last-child {\n      padding-bottom: 1.2rem; }\n    .md-nav__item .md-nav__item {\n      padding-right: 0; }\n      [dir=\"rtl\"] .md-nav__item .md-nav__item {\n        padding-right: 1.2rem;\n        padding-left: 0; }\n      .md-nav__item .md-nav__item:last-child {\n        padding-bottom: 0; }\n  .md-nav__button img {\n    width: 100%;\n    height: auto; }\n  .md-nav__link {\n    display: block;\n    margin-top: 0.625em;\n    transition: color 0.125s;\n    text-overflow: ellipsis;\n    cursor: pointer;\n    overflow: hidden; }\n    .md-nav__item--nested > .md-nav__link::after {\n      content: \"\\E313\"; }\n    html .md-nav__link[for=\"__toc\"] {\n      display: none; }\n      html .md-nav__link[for=\"__toc\"] ~ .md-nav {\n        display: none; }\n      html .md-nav__link[for=\"__toc\"] + .md-nav__link::after {\n        display: none; }\n    .md-nav__link[data-md-state=\"blur\"] {\n      color: rgba(0, 0, 0, 0.54); }\n    .md-nav__link:active, .md-nav__link--active {\n      color: #3f51b5; }\n    .md-nav__item--nested > .md-nav__link {\n      color: inherit; }\n    .md-nav__link:focus, .md-nav__link:hover {\n      color: #536dfe; }\n  .md-nav__source {\n    display: none; }\n\n.no-js .md-search {\n  display: none; }\n\n.md-search__overlay {\n  opacity: 0;\n  z-index: 1; }\n\n.md-search__form {\n  position: relative; }\n\n.md-search__input {\n  position: relative;\n  padding: 0 4.4rem 0 7.2rem;\n  text-overflow: ellipsis;\n  z-index: 2; }\n  [dir=\"rtl\"] .md-search__input {\n    padding: 0 7.2rem 0 4.4rem; }\n  .md-search__input::-webkit-input-placeholder {\n    transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); }\n  .md-search__input:-ms-input-placeholder {\n    transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); }\n  .md-search__input::-ms-input-placeholder {\n    transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); }\n  .md-search__input::placeholder {\n    transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); }\n  .md-search__input ~ .md-search__icon, .md-search__input::-webkit-input-placeholder {\n    color: rgba(0, 0, 0, 0.54); }\n  .md-search__input ~ .md-search__icon, .md-search__input:-ms-input-placeholder {\n    color: rgba(0, 0, 0, 0.54); }\n  .md-search__input ~ .md-search__icon, .md-search__input::-ms-input-placeholder {\n    color: rgba(0, 0, 0, 0.54); }\n  .md-search__input ~ .md-search__icon, .md-search__input::placeholder {\n    color: rgba(0, 0, 0, 0.54); }\n  .md-search__input::-ms-clear {\n    display: none; }\n\n.md-search__icon {\n  position: absolute;\n  transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s;\n  font-size: 2.4rem;\n  cursor: pointer;\n  z-index: 2; }\n  .md-search__icon:hover {\n    opacity: 0.7; }\n  .md-search__icon[for=\"__search\"] {\n    top: 0.6rem;\n    left: 1rem; }\n    [dir=\"rtl\"] .md-search__icon[for=\"__search\"] {\n      right: 1rem;\n      left: initial; }\n    .md-search__icon[for=\"__search\"]::before {\n      content: \"\\E8B6\"; }\n  .md-search__icon[type=\"reset\"] {\n    top: 0.6rem;\n    right: 1rem;\n    -webkit-transform: scale(0.125);\n            transform: scale(0.125);\n    transition: opacity 0.15s, -webkit-transform 0.15s cubic-bezier(0.1, 0.7, 0.1, 1);\n    transition: transform 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s;\n    transition: transform 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s, -webkit-transform 0.15s cubic-bezier(0.1, 0.7, 0.1, 1);\n    opacity: 0; }\n    [dir=\"rtl\"] .md-search__icon[type=\"reset\"] {\n      right: initial;\n      left: 1rem; }\n    [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__input:valid ~ .md-search__icon[type=\"reset\"] {\n      -webkit-transform: scale(1);\n              transform: scale(1);\n      opacity: 1; }\n      [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__input:valid ~ .md-search__icon[type=\"reset\"]:hover {\n        opacity: 0.7; }\n\n.md-search__output {\n  position: absolute;\n  width: 100%;\n  border-radius: 0 0 0.2rem 0.2rem;\n  overflow: hidden;\n  z-index: 1; }\n\n.md-search__scrollwrap {\n  height: 100%;\n  background-color: white;\n  box-shadow: 0 0.1rem 0 rgba(0, 0, 0, 0.07) inset;\n  overflow-y: auto;\n  -webkit-overflow-scrolling: touch; }\n\n.md-search-result {\n  color: rgba(0, 0, 0, 0.87);\n  word-break: break-word; }\n  .md-search-result__meta {\n    padding: 0 1.6rem;\n    background-color: rgba(0, 0, 0, 0.07);\n    color: rgba(0, 0, 0, 0.54);\n    font-size: 1.28rem;\n    line-height: 3.6rem; }\n  .md-search-result__list {\n    margin: 0;\n    padding: 0;\n    border-top: 0.1rem solid rgba(0, 0, 0, 0.07);\n    list-style: none; }\n  .md-search-result__item {\n    box-shadow: 0 -0.1rem 0 rgba(0, 0, 0, 0.07); }\n  .md-search-result__link {\n    display: block;\n    transition: background 0.25s;\n    outline: 0;\n    overflow: hidden; }\n    .md-search-result__link[data-md-state=\"active\"], .md-search-result__link:hover {\n      background-color: rgba(83, 109, 254, 0.1); }\n      .md-search-result__link[data-md-state=\"active\"] .md-search-result__article::before, .md-search-result__link:hover .md-search-result__article::before {\n        opacity: 0.7; }\n    .md-search-result__link:last-child .md-search-result__teaser {\n      margin-bottom: 1.2rem; }\n  .md-search-result__article {\n    position: relative;\n    padding: 0 1.6rem;\n    overflow: auto; }\n    .md-search-result__article--document::before {\n      position: absolute;\n      left: 0;\n      margin: 0.2rem;\n      transition: opacity 0.25s;\n      color: rgba(0, 0, 0, 0.54);\n      content: \"\\E880\"; }\n      [dir=\"rtl\"] .md-search-result__article--document::before {\n        right: 0;\n        left: initial; }\n    .md-search-result__article--document .md-search-result__title {\n      margin: 1.1rem 0;\n      font-size: 1.6rem;\n      font-weight: 400;\n      line-height: 1.4; }\n  .md-search-result__title {\n    margin: 0.5em 0;\n    font-size: 1.28rem;\n    font-weight: 700;\n    line-height: 1.4; }\n  .md-search-result__teaser {\n    display: -webkit-box;\n    max-height: 3.3rem;\n    margin: 0.5em 0;\n    color: rgba(0, 0, 0, 0.54);\n    font-size: 1.28rem;\n    line-height: 1.4;\n    text-overflow: ellipsis;\n    overflow: hidden;\n    -webkit-line-clamp: 2; }\n  .md-search-result em {\n    font-style: normal;\n    font-weight: 700;\n    text-decoration: underline; }\n\n.md-sidebar {\n  position: absolute;\n  width: 24.2rem;\n  padding: 2.4rem 0;\n  overflow: hidden; }\n  .md-sidebar[data-md-state=\"lock\"] {\n    position: fixed;\n    top: 4.8rem; }\n  .md-sidebar--secondary {\n    display: none; }\n  .md-sidebar__scrollwrap {\n    max-height: 100%;\n    margin: 0 0.4rem;\n    overflow-y: auto;\n    -webkit-backface-visibility: hidden;\n            backface-visibility: hidden; }\n    .md-sidebar__scrollwrap::-webkit-scrollbar {\n      width: 0.4rem;\n      height: 0.4rem; }\n    .md-sidebar__scrollwrap::-webkit-scrollbar-thumb {\n      background-color: rgba(0, 0, 0, 0.26); }\n      .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover {\n        background-color: #536dfe; }\n\n@-webkit-keyframes md-source__facts--done {\n  0% {\n    height: 0; }\n  100% {\n    height: 1.3rem; } }\n\n@keyframes md-source__facts--done {\n  0% {\n    height: 0; }\n  100% {\n    height: 1.3rem; } }\n\n@-webkit-keyframes md-source__fact--done {\n  0% {\n    -webkit-transform: translateY(100%);\n            transform: translateY(100%);\n    opacity: 0; }\n  50% {\n    opacity: 0; }\n  100% {\n    -webkit-transform: translateY(0%);\n            transform: translateY(0%);\n    opacity: 1; } }\n\n@keyframes md-source__fact--done {\n  0% {\n    -webkit-transform: translateY(100%);\n            transform: translateY(100%);\n    opacity: 0; }\n  50% {\n    opacity: 0; }\n  100% {\n    -webkit-transform: translateY(0%);\n            transform: translateY(0%);\n    opacity: 1; } }\n\n.md-source {\n  display: block;\n  padding-right: 1.2rem;\n  transition: opacity 0.25s;\n  font-size: 1.3rem;\n  line-height: 1.2;\n  white-space: nowrap; }\n  [dir=\"rtl\"] .md-source {\n    padding-right: initial;\n    padding-left: 1.2rem; }\n  .md-source:hover {\n    opacity: 0.7; }\n  .md-source::after {\n    display: inline-block;\n    height: 4.8rem;\n    content: \"\";\n    vertical-align: middle; }\n  .md-source__icon {\n    display: inline-block;\n    width: 4.8rem;\n    height: 4.8rem;\n    content: \"\";\n    vertical-align: middle; }\n    .md-source__icon svg {\n      width: 2.4rem;\n      height: 2.4rem;\n      margin-top: 1.2rem;\n      margin-left: 1.2rem; }\n      [dir=\"rtl\"] .md-source__icon svg {\n        margin-right: 1.2rem;\n        margin-left: initial; }\n    .md-source__icon + .md-source__repository {\n      margin-left: -4.4rem;\n      padding-left: 4rem; }\n      [dir=\"rtl\"] .md-source__icon + .md-source__repository {\n        margin-right: -4.4rem;\n        margin-left: initial;\n        padding-right: 4rem;\n        padding-left: initial; }\n  .md-source__repository {\n    display: inline-block;\n    max-width: 100%;\n    margin-left: 1.2rem;\n    font-weight: 700;\n    text-overflow: ellipsis;\n    overflow: hidden;\n    vertical-align: middle; }\n  .md-source__facts {\n    margin: 0;\n    padding: 0;\n    font-size: 1.1rem;\n    font-weight: 700;\n    list-style-type: none;\n    opacity: 0.75;\n    overflow: hidden; }\n    [data-md-state=\"done\"] .md-source__facts {\n      -webkit-animation: md-source__facts--done 0.25s ease-in;\n              animation: md-source__facts--done 0.25s ease-in; }\n  .md-source__fact {\n    float: left; }\n    [dir=\"rtl\"] .md-source__fact {\n      float: right; }\n    [data-md-state=\"done\"] .md-source__fact {\n      -webkit-animation: md-source__fact--done 0.4s ease-out;\n              animation: md-source__fact--done 0.4s ease-out; }\n    .md-source__fact::before {\n      margin: 0 0.2rem;\n      content: \"\\B7\"; }\n    .md-source__fact:first-child::before {\n      display: none; }\n\n.md-source-file {\n  display: inline-block;\n  margin: 1em 0.5em 1em 0;\n  padding-right: 0.5rem;\n  border-radius: 0.2rem;\n  background-color: rgba(0, 0, 0, 0.07);\n  font-size: 1.28rem;\n  list-style-type: none;\n  cursor: pointer;\n  overflow: hidden; }\n  .md-source-file::before {\n    display: inline-block;\n    margin-right: 0.5rem;\n    padding: 0.5rem;\n    background-color: rgba(0, 0, 0, 0.26);\n    color: white;\n    font-size: 1.6rem;\n    content: \"\\E86F\";\n    vertical-align: middle; }\n  html .md-source-file {\n    transition: background 0.4s, color 0.4s, box-shadow 0.4s cubic-bezier(0.4, 0, 0.2, 1); }\n    html .md-source-file::before {\n      transition: inherit; }\n  html body .md-typeset .md-source-file {\n    color: rgba(0, 0, 0, 0.54); }\n  .md-source-file:hover {\n    box-shadow: 0 0 8px rgba(0, 0, 0, 0.18), 0 8px 16px rgba(0, 0, 0, 0.36); }\n    .md-source-file:hover::before {\n      background-color: #536dfe; }\n\n.md-tabs {\n  width: 100%;\n  transition: background 0.25s;\n  background-color: #3f51b5;\n  color: white;\n  overflow: auto; }\n  .md-tabs__list {\n    margin: 0;\n    margin-left: 0.4rem;\n    padding: 0;\n    list-style: none;\n    white-space: nowrap; }\n  .md-tabs__item {\n    display: inline-block;\n    height: 4.8rem;\n    padding-right: 1.2rem;\n    padding-left: 1.2rem; }\n  .md-tabs__link {\n    display: block;\n    margin-top: 1.6rem;\n    transition: opacity 0.25s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1);\n    transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s;\n    transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1);\n    font-size: 1.4rem;\n    opacity: 0.7; }\n    .md-tabs__link--active, .md-tabs__link:hover {\n      color: inherit;\n      opacity: 1; }\n    .md-tabs__item:nth-child(2) .md-tabs__link {\n      transition-delay: 0.02s; }\n    .md-tabs__item:nth-child(3) .md-tabs__link {\n      transition-delay: 0.04s; }\n    .md-tabs__item:nth-child(4) .md-tabs__link {\n      transition-delay: 0.06s; }\n    .md-tabs__item:nth-child(5) .md-tabs__link {\n      transition-delay: 0.08s; }\n    .md-tabs__item:nth-child(6) .md-tabs__link {\n      transition-delay: 0.1s; }\n    .md-tabs__item:nth-child(7) .md-tabs__link {\n      transition-delay: 0.12s; }\n    .md-tabs__item:nth-child(8) .md-tabs__link {\n      transition-delay: 0.14s; }\n    .md-tabs__item:nth-child(9) .md-tabs__link {\n      transition-delay: 0.16s; }\n    .md-tabs__item:nth-child(10) .md-tabs__link {\n      transition-delay: 0.18s; }\n    .md-tabs__item:nth-child(11) .md-tabs__link {\n      transition-delay: 0.2s; }\n    .md-tabs__item:nth-child(12) .md-tabs__link {\n      transition-delay: 0.22s; }\n    .md-tabs__item:nth-child(13) .md-tabs__link {\n      transition-delay: 0.24s; }\n    .md-tabs__item:nth-child(14) .md-tabs__link {\n      transition-delay: 0.26s; }\n    .md-tabs__item:nth-child(15) .md-tabs__link {\n      transition-delay: 0.28s; }\n    .md-tabs__item:nth-child(16) .md-tabs__link {\n      transition-delay: 0.3s; }\n  .md-tabs[data-md-state=\"hidden\"] {\n    pointer-events: none; }\n    .md-tabs[data-md-state=\"hidden\"] .md-tabs__link {\n      -webkit-transform: translateY(50%);\n              transform: translateY(50%);\n      transition: color     0.25s, opacity   0.1s, -webkit-transform 0s 0.4s;\n      transition: color     0.25s, transform 0s 0.4s, opacity   0.1s;\n      transition: color     0.25s, transform 0s 0.4s, opacity   0.1s, -webkit-transform 0s 0.4s;\n      opacity: 0; }\n\n.md-typeset .admonition, .md-typeset details {\n  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);\n  position: relative;\n  margin: 1.5625em 0;\n  padding: 0 1.2rem;\n  border-left: 0.4rem solid #448aff;\n  border-radius: 0.2rem;\n  font-size: 1.28rem;\n  overflow: auto; }\n  [dir=\"rtl\"] .md-typeset .admonition, [dir=\"rtl\"] .md-typeset details {\n    border-right: 0.4rem solid #448aff;\n    border-left: none; }\n  html .md-typeset .admonition > :last-child, html .md-typeset details > :last-child {\n    margin-bottom: 1.2rem; }\n  .md-typeset .admonition .admonition, .md-typeset details .admonition, .md-typeset .admonition details, .md-typeset details details {\n    margin: 1em 0; }\n  .md-typeset .admonition > .admonition-title, .md-typeset details > .admonition-title, .md-typeset .admonition > summary, .md-typeset details > summary {\n    margin: 0 -1.2rem;\n    padding: 0.8rem 1.2rem 0.8rem 4rem;\n    border-bottom: 0.1rem solid rgba(68, 138, 255, 0.1);\n    background-color: rgba(68, 138, 255, 0.1);\n    font-weight: 700; }\n    [dir=\"rtl\"] .md-typeset .admonition > .admonition-title, [dir=\"rtl\"] .md-typeset details > .admonition-title, [dir=\"rtl\"] .md-typeset .admonition > summary, [dir=\"rtl\"] .md-typeset details > summary {\n      padding: 0.8rem 4rem 0.8rem 1.2rem; }\n    .md-typeset .admonition > .admonition-title:last-child, .md-typeset details > .admonition-title:last-child, .md-typeset .admonition > summary:last-child, .md-typeset details > summary:last-child {\n      margin-bottom: 0; }\n    .md-typeset .admonition > .admonition-title::before, .md-typeset details > .admonition-title::before, .md-typeset .admonition > summary::before, .md-typeset details > summary::before {\n      position: absolute;\n      left: 1.2rem;\n      color: #448aff;\n      font-size: 2rem;\n      content: \"\\E3C9\"; }\n      [dir=\"rtl\"] .md-typeset .admonition > .admonition-title::before, [dir=\"rtl\"] .md-typeset details > .admonition-title::before, [dir=\"rtl\"] .md-typeset .admonition > summary::before, [dir=\"rtl\"] .md-typeset details > summary::before {\n        right: 1.2rem;\n        left: initial; }\n  .md-typeset .admonition.summary, .md-typeset details.summary, .md-typeset .admonition.tldr, .md-typeset details.tldr, .md-typeset .admonition.abstract, .md-typeset details.abstract {\n    border-left-color: #00b0ff; }\n    [dir=\"rtl\"] .md-typeset .admonition.summary, [dir=\"rtl\"] .md-typeset details.summary, [dir=\"rtl\"] .md-typeset .admonition.tldr, [dir=\"rtl\"] .md-typeset details.tldr, [dir=\"rtl\"] .md-typeset .admonition.abstract, [dir=\"rtl\"] .md-typeset details.abstract {\n      border-right-color: #00b0ff; }\n    .md-typeset .admonition.summary > .admonition-title, .md-typeset details.summary > .admonition-title, .md-typeset .admonition.tldr > .admonition-title, .md-typeset details.tldr > .admonition-title, .md-typeset .admonition.summary > summary, .md-typeset details.summary > summary, .md-typeset .admonition.tldr > summary, .md-typeset details.tldr > summary, .md-typeset .admonition.abstract > .admonition-title, .md-typeset details.abstract > .admonition-title, .md-typeset .admonition.abstract > summary, .md-typeset details.abstract > summary {\n      border-bottom-color: 0.1rem solid rgba(0, 176, 255, 0.1);\n      background-color: rgba(0, 176, 255, 0.1); }\n      .md-typeset .admonition.summary > .admonition-title::before, .md-typeset details.summary > .admonition-title::before, .md-typeset .admonition.tldr > .admonition-title::before, .md-typeset details.tldr > .admonition-title::before, .md-typeset .admonition.summary > summary::before, .md-typeset details.summary > summary::before, .md-typeset .admonition.tldr > summary::before, .md-typeset details.tldr > summary::before, .md-typeset .admonition.abstract > .admonition-title::before, .md-typeset details.abstract > .admonition-title::before, .md-typeset .admonition.abstract > summary::before, .md-typeset details.abstract > summary::before {\n        color: #00b0ff;\n        content: \"\\E8D2\"; }\n  .md-typeset .admonition.todo, .md-typeset details.todo, .md-typeset .admonition.info, .md-typeset details.info {\n    border-left-color: #00b8d4; }\n    [dir=\"rtl\"] .md-typeset .admonition.todo, [dir=\"rtl\"] .md-typeset details.todo, [dir=\"rtl\"] .md-typeset .admonition.info, [dir=\"rtl\"] .md-typeset details.info {\n      border-right-color: #00b8d4; }\n    .md-typeset .admonition.todo > .admonition-title, .md-typeset details.todo > .admonition-title, .md-typeset .admonition.todo > summary, .md-typeset details.todo > summary, .md-typeset .admonition.info > .admonition-title, .md-typeset details.info > .admonition-title, .md-typeset .admonition.info > summary, .md-typeset details.info > summary {\n      border-bottom-color: 0.1rem solid rgba(0, 184, 212, 0.1);\n      background-color: rgba(0, 184, 212, 0.1); }\n      .md-typeset .admonition.todo > .admonition-title::before, .md-typeset details.todo > .admonition-title::before, .md-typeset .admonition.todo > summary::before, .md-typeset details.todo > summary::before, .md-typeset .admonition.info > .admonition-title::before, .md-typeset details.info > .admonition-title::before, .md-typeset .admonition.info > summary::before, .md-typeset details.info > summary::before {\n        color: #00b8d4;\n        content: \"\\E88E\"; }\n  .md-typeset .admonition.hint, .md-typeset details.hint, .md-typeset .admonition.important, .md-typeset details.important, .md-typeset .admonition.tip, .md-typeset details.tip {\n    border-left-color: #00bfa5; }\n    [dir=\"rtl\"] .md-typeset .admonition.hint, [dir=\"rtl\"] .md-typeset details.hint, [dir=\"rtl\"] .md-typeset .admonition.important, [dir=\"rtl\"] .md-typeset details.important, [dir=\"rtl\"] .md-typeset .admonition.tip, [dir=\"rtl\"] .md-typeset details.tip {\n      border-right-color: #00bfa5; }\n    .md-typeset .admonition.hint > .admonition-title, .md-typeset details.hint > .admonition-title, .md-typeset .admonition.important > .admonition-title, .md-typeset details.important > .admonition-title, .md-typeset .admonition.hint > summary, .md-typeset details.hint > summary, .md-typeset .admonition.important > summary, .md-typeset details.important > summary, .md-typeset .admonition.tip > .admonition-title, .md-typeset details.tip > .admonition-title, .md-typeset .admonition.tip > summary, .md-typeset details.tip > summary {\n      border-bottom-color: 0.1rem solid rgba(0, 191, 165, 0.1);\n      background-color: rgba(0, 191, 165, 0.1); }\n      .md-typeset .admonition.hint > .admonition-title::before, .md-typeset details.hint > .admonition-title::before, .md-typeset .admonition.important > .admonition-title::before, .md-typeset details.important > .admonition-title::before, .md-typeset .admonition.hint > summary::before, .md-typeset details.hint > summary::before, .md-typeset .admonition.important > summary::before, .md-typeset details.important > summary::before, .md-typeset .admonition.tip > .admonition-title::before, .md-typeset details.tip > .admonition-title::before, .md-typeset .admonition.tip > summary::before, .md-typeset details.tip > summary::before {\n        color: #00bfa5;\n        content: \"\\E80E\"; }\n  .md-typeset .admonition.check, .md-typeset details.check, .md-typeset .admonition.done, .md-typeset details.done, .md-typeset .admonition.success, .md-typeset details.success {\n    border-left-color: #00c853; }\n    [dir=\"rtl\"] .md-typeset .admonition.check, [dir=\"rtl\"] .md-typeset details.check, [dir=\"rtl\"] .md-typeset .admonition.done, [dir=\"rtl\"] .md-typeset details.done, [dir=\"rtl\"] .md-typeset .admonition.success, [dir=\"rtl\"] .md-typeset details.success {\n      border-right-color: #00c853; }\n    .md-typeset .admonition.check > .admonition-title, .md-typeset details.check > .admonition-title, .md-typeset .admonition.done > .admonition-title, .md-typeset details.done > .admonition-title, .md-typeset .admonition.check > summary, .md-typeset details.check > summary, .md-typeset .admonition.done > summary, .md-typeset details.done > summary, .md-typeset .admonition.success > .admonition-title, .md-typeset details.success > .admonition-title, .md-typeset .admonition.success > summary, .md-typeset details.success > summary {\n      border-bottom-color: 0.1rem solid rgba(0, 200, 83, 0.1);\n      background-color: rgba(0, 200, 83, 0.1); }\n      .md-typeset .admonition.check > .admonition-title::before, .md-typeset details.check > .admonition-title::before, .md-typeset .admonition.done > .admonition-title::before, .md-typeset details.done > .admonition-title::before, .md-typeset .admonition.check > summary::before, .md-typeset details.check > summary::before, .md-typeset .admonition.done > summary::before, .md-typeset details.done > summary::before, .md-typeset .admonition.success > .admonition-title::before, .md-typeset details.success > .admonition-title::before, .md-typeset .admonition.success > summary::before, .md-typeset details.success > summary::before {\n        color: #00c853;\n        content: \"\\E876\"; }\n  .md-typeset .admonition.help, .md-typeset details.help, .md-typeset .admonition.faq, .md-typeset details.faq, .md-typeset .admonition.question, .md-typeset details.question {\n    border-left-color: #64dd17; }\n    [dir=\"rtl\"] .md-typeset .admonition.help, [dir=\"rtl\"] .md-typeset details.help, [dir=\"rtl\"] .md-typeset .admonition.faq, [dir=\"rtl\"] .md-typeset details.faq, [dir=\"rtl\"] .md-typeset .admonition.question, [dir=\"rtl\"] .md-typeset details.question {\n      border-right-color: #64dd17; }\n    .md-typeset .admonition.help > .admonition-title, .md-typeset details.help > .admonition-title, .md-typeset .admonition.faq > .admonition-title, .md-typeset details.faq > .admonition-title, .md-typeset .admonition.help > summary, .md-typeset details.help > summary, .md-typeset .admonition.faq > summary, .md-typeset details.faq > summary, .md-typeset .admonition.question > .admonition-title, .md-typeset details.question > .admonition-title, .md-typeset .admonition.question > summary, .md-typeset details.question > summary {\n      border-bottom-color: 0.1rem solid rgba(100, 221, 23, 0.1);\n      background-color: rgba(100, 221, 23, 0.1); }\n      .md-typeset .admonition.help > .admonition-title::before, .md-typeset details.help > .admonition-title::before, .md-typeset .admonition.faq > .admonition-title::before, .md-typeset details.faq > .admonition-title::before, .md-typeset .admonition.help > summary::before, .md-typeset details.help > summary::before, .md-typeset .admonition.faq > summary::before, .md-typeset details.faq > summary::before, .md-typeset .admonition.question > .admonition-title::before, .md-typeset details.question > .admonition-title::before, .md-typeset .admonition.question > summary::before, .md-typeset details.question > summary::before {\n        color: #64dd17;\n        content: \"\\E887\"; }\n  .md-typeset .admonition.caution, .md-typeset details.caution, .md-typeset .admonition.attention, .md-typeset details.attention, .md-typeset .admonition.warning, .md-typeset details.warning {\n    border-left-color: #ff9100; }\n    [dir=\"rtl\"] .md-typeset .admonition.caution, [dir=\"rtl\"] .md-typeset details.caution, [dir=\"rtl\"] .md-typeset .admonition.attention, [dir=\"rtl\"] .md-typeset details.attention, [dir=\"rtl\"] .md-typeset .admonition.warning, [dir=\"rtl\"] .md-typeset details.warning {\n      border-right-color: #ff9100; }\n    .md-typeset .admonition.caution > .admonition-title, .md-typeset details.caution > .admonition-title, .md-typeset .admonition.attention > .admonition-title, .md-typeset details.attention > .admonition-title, .md-typeset .admonition.caution > summary, .md-typeset details.caution > summary, .md-typeset .admonition.attention > summary, .md-typeset details.attention > summary, .md-typeset .admonition.warning > .admonition-title, .md-typeset details.warning > .admonition-title, .md-typeset .admonition.warning > summary, .md-typeset details.warning > summary {\n      border-bottom-color: 0.1rem solid rgba(255, 145, 0, 0.1);\n      background-color: rgba(255, 145, 0, 0.1); }\n      .md-typeset .admonition.caution > .admonition-title::before, .md-typeset details.caution > .admonition-title::before, .md-typeset .admonition.attention > .admonition-title::before, .md-typeset details.attention > .admonition-title::before, .md-typeset .admonition.caution > summary::before, .md-typeset details.caution > summary::before, .md-typeset .admonition.attention > summary::before, .md-typeset details.attention > summary::before, .md-typeset .admonition.warning > .admonition-title::before, .md-typeset details.warning > .admonition-title::before, .md-typeset .admonition.warning > summary::before, .md-typeset details.warning > summary::before {\n        color: #ff9100;\n        content: \"\\E002\"; }\n  .md-typeset .admonition.fail, .md-typeset details.fail, .md-typeset .admonition.missing, .md-typeset details.missing, .md-typeset .admonition.failure, .md-typeset details.failure {\n    border-left-color: #ff5252; }\n    [dir=\"rtl\"] .md-typeset .admonition.fail, [dir=\"rtl\"] .md-typeset details.fail, [dir=\"rtl\"] .md-typeset .admonition.missing, [dir=\"rtl\"] .md-typeset details.missing, [dir=\"rtl\"] .md-typeset .admonition.failure, [dir=\"rtl\"] .md-typeset details.failure {\n      border-right-color: #ff5252; }\n    .md-typeset .admonition.fail > .admonition-title, .md-typeset details.fail > .admonition-title, .md-typeset .admonition.missing > .admonition-title, .md-typeset details.missing > .admonition-title, .md-typeset .admonition.fail > summary, .md-typeset details.fail > summary, .md-typeset .admonition.missing > summary, .md-typeset details.missing > summary, .md-typeset .admonition.failure > .admonition-title, .md-typeset details.failure > .admonition-title, .md-typeset .admonition.failure > summary, .md-typeset details.failure > summary {\n      border-bottom-color: 0.1rem solid rgba(255, 82, 82, 0.1);\n      background-color: rgba(255, 82, 82, 0.1); }\n      .md-typeset .admonition.fail > .admonition-title::before, .md-typeset details.fail > .admonition-title::before, .md-typeset .admonition.missing > .admonition-title::before, .md-typeset details.missing > .admonition-title::before, .md-typeset .admonition.fail > summary::before, .md-typeset details.fail > summary::before, .md-typeset .admonition.missing > summary::before, .md-typeset details.missing > summary::before, .md-typeset .admonition.failure > .admonition-title::before, .md-typeset details.failure > .admonition-title::before, .md-typeset .admonition.failure > summary::before, .md-typeset details.failure > summary::before {\n        color: #ff5252;\n        content: \"\\E14C\"; }\n  .md-typeset .admonition.error, .md-typeset details.error, .md-typeset .admonition.danger, .md-typeset details.danger {\n    border-left-color: #ff1744; }\n    [dir=\"rtl\"] .md-typeset .admonition.error, [dir=\"rtl\"] .md-typeset details.error, [dir=\"rtl\"] .md-typeset .admonition.danger, [dir=\"rtl\"] .md-typeset details.danger {\n      border-right-color: #ff1744; }\n    .md-typeset .admonition.error > .admonition-title, .md-typeset details.error > .admonition-title, .md-typeset .admonition.error > summary, .md-typeset details.error > summary, .md-typeset .admonition.danger > .admonition-title, .md-typeset details.danger > .admonition-title, .md-typeset .admonition.danger > summary, .md-typeset details.danger > summary {\n      border-bottom-color: 0.1rem solid rgba(255, 23, 68, 0.1);\n      background-color: rgba(255, 23, 68, 0.1); }\n      .md-typeset .admonition.error > .admonition-title::before, .md-typeset details.error > .admonition-title::before, .md-typeset .admonition.error > summary::before, .md-typeset details.error > summary::before, .md-typeset .admonition.danger > .admonition-title::before, .md-typeset details.danger > .admonition-title::before, .md-typeset .admonition.danger > summary::before, .md-typeset details.danger > summary::before {\n        color: #ff1744;\n        content: \"\\E3E7\"; }\n  .md-typeset .admonition.bug, .md-typeset details.bug {\n    border-left-color: #f50057; }\n    [dir=\"rtl\"] .md-typeset .admonition.bug, [dir=\"rtl\"] .md-typeset details.bug {\n      border-right-color: #f50057; }\n    .md-typeset .admonition.bug > .admonition-title, .md-typeset details.bug > .admonition-title, .md-typeset .admonition.bug > summary, .md-typeset details.bug > summary {\n      border-bottom-color: 0.1rem solid rgba(245, 0, 87, 0.1);\n      background-color: rgba(245, 0, 87, 0.1); }\n      .md-typeset .admonition.bug > .admonition-title::before, .md-typeset details.bug > .admonition-title::before, .md-typeset .admonition.bug > summary::before, .md-typeset details.bug > summary::before {\n        color: #f50057;\n        content: \"\\E868\"; }\n  .md-typeset .admonition.example, .md-typeset details.example {\n    border-left-color: #651fff; }\n    [dir=\"rtl\"] .md-typeset .admonition.example, [dir=\"rtl\"] .md-typeset details.example {\n      border-right-color: #651fff; }\n    .md-typeset .admonition.example > .admonition-title, .md-typeset details.example > .admonition-title, .md-typeset .admonition.example > summary, .md-typeset details.example > summary {\n      border-bottom-color: 0.1rem solid rgba(101, 31, 255, 0.1);\n      background-color: rgba(101, 31, 255, 0.1); }\n      .md-typeset .admonition.example > .admonition-title::before, .md-typeset details.example > .admonition-title::before, .md-typeset .admonition.example > summary::before, .md-typeset details.example > summary::before {\n        color: #651fff;\n        content: \"\\E242\"; }\n  .md-typeset .admonition.cite, .md-typeset details.cite, .md-typeset .admonition.quote, .md-typeset details.quote {\n    border-left-color: #9e9e9e; }\n    [dir=\"rtl\"] .md-typeset .admonition.cite, [dir=\"rtl\"] .md-typeset details.cite, [dir=\"rtl\"] .md-typeset .admonition.quote, [dir=\"rtl\"] .md-typeset details.quote {\n      border-right-color: #9e9e9e; }\n    .md-typeset .admonition.cite > .admonition-title, .md-typeset details.cite > .admonition-title, .md-typeset .admonition.cite > summary, .md-typeset details.cite > summary, .md-typeset .admonition.quote > .admonition-title, .md-typeset details.quote > .admonition-title, .md-typeset .admonition.quote > summary, .md-typeset details.quote > summary {\n      border-bottom-color: 0.1rem solid rgba(158, 158, 158, 0.1);\n      background-color: rgba(158, 158, 158, 0.1); }\n      .md-typeset .admonition.cite > .admonition-title::before, .md-typeset details.cite > .admonition-title::before, .md-typeset .admonition.cite > summary::before, .md-typeset details.cite > summary::before, .md-typeset .admonition.quote > .admonition-title::before, .md-typeset details.quote > .admonition-title::before, .md-typeset .admonition.quote > summary::before, .md-typeset details.quote > summary::before {\n        color: #9e9e9e;\n        content: \"\\E244\"; }\n\n.codehilite .o, .md-typeset .highlight .o {\n  color: inherit; }\n\n.codehilite .ow, .md-typeset .highlight .ow {\n  color: inherit; }\n\n.codehilite .ge, .md-typeset .highlight .ge {\n  color: #000000; }\n\n.codehilite .gr, .md-typeset .highlight .gr {\n  color: #AA0000; }\n\n.codehilite .gh, .md-typeset .highlight .gh {\n  color: #999999; }\n\n.codehilite .go, .md-typeset .highlight .go {\n  color: #888888; }\n\n.codehilite .gp, .md-typeset .highlight .gp {\n  color: #555555; }\n\n.codehilite .gs, .md-typeset .highlight .gs {\n  color: inherit; }\n\n.codehilite .gu, .md-typeset .highlight .gu {\n  color: #AAAAAA; }\n\n.codehilite .gt, .md-typeset .highlight .gt {\n  color: #AA0000; }\n\n.codehilite .gd, .md-typeset .highlight .gd {\n  background-color: #FFDDDD; }\n\n.codehilite .gi, .md-typeset .highlight .gi {\n  background-color: #DDFFDD; }\n\n.codehilite .k, .md-typeset .highlight .k {\n  color: #3B78E7; }\n\n.codehilite .kc, .md-typeset .highlight .kc {\n  color: #A71D5D; }\n\n.codehilite .kd, .md-typeset .highlight .kd {\n  color: #3B78E7; }\n\n.codehilite .kn, .md-typeset .highlight .kn {\n  color: #3B78E7; }\n\n.codehilite .kp, .md-typeset .highlight .kp {\n  color: #A71D5D; }\n\n.codehilite .kr, .md-typeset .highlight .kr {\n  color: #3E61A2; }\n\n.codehilite .kt, .md-typeset .highlight .kt {\n  color: #3E61A2; }\n\n.codehilite .c, .md-typeset .highlight .c {\n  color: #999999; }\n\n.codehilite .cm, .md-typeset .highlight .cm {\n  color: #999999; }\n\n.codehilite .cp, .md-typeset .highlight .cp {\n  color: #666666; }\n\n.codehilite .c1, .md-typeset .highlight .c1 {\n  color: #999999; }\n\n.codehilite .ch, .md-typeset .highlight .ch {\n  color: #999999; }\n\n.codehilite .cs, .md-typeset .highlight .cs {\n  color: #999999; }\n\n.codehilite .na, .md-typeset .highlight .na {\n  color: #C2185B; }\n\n.codehilite .nb, .md-typeset .highlight .nb {\n  color: #C2185B; }\n\n.codehilite .bp, .md-typeset .highlight .bp {\n  color: #3E61A2; }\n\n.codehilite .nc, .md-typeset .highlight .nc {\n  color: #C2185B; }\n\n.codehilite .no, .md-typeset .highlight .no {\n  color: #3E61A2; }\n\n.codehilite .nd, .md-typeset .highlight .nd {\n  color: #666666; }\n\n.codehilite .ni, .md-typeset .highlight .ni {\n  color: #666666; }\n\n.codehilite .ne, .md-typeset .highlight .ne {\n  color: #C2185B; }\n\n.codehilite .nf, .md-typeset .highlight .nf {\n  color: #C2185B; }\n\n.codehilite .nl, .md-typeset .highlight .nl {\n  color: #3B5179; }\n\n.codehilite .nn, .md-typeset .highlight .nn {\n  color: #EC407A; }\n\n.codehilite .nt, .md-typeset .highlight .nt {\n  color: #3B78E7; }\n\n.codehilite .nv, .md-typeset .highlight .nv {\n  color: #3E61A2; }\n\n.codehilite .vc, .md-typeset .highlight .vc {\n  color: #3E61A2; }\n\n.codehilite .vg, .md-typeset .highlight .vg {\n  color: #3E61A2; }\n\n.codehilite .vi, .md-typeset .highlight .vi {\n  color: #3E61A2; }\n\n.codehilite .nx, .md-typeset .highlight .nx {\n  color: #EC407A; }\n\n.codehilite .m, .md-typeset .highlight .m {\n  color: #E74C3C; }\n\n.codehilite .mf, .md-typeset .highlight .mf {\n  color: #E74C3C; }\n\n.codehilite .mh, .md-typeset .highlight .mh {\n  color: #E74C3C; }\n\n.codehilite .mi, .md-typeset .highlight .mi {\n  color: #E74C3C; }\n\n.codehilite .il, .md-typeset .highlight .il {\n  color: #E74C3C; }\n\n.codehilite .mo, .md-typeset .highlight .mo {\n  color: #E74C3C; }\n\n.codehilite .s, .md-typeset .highlight .s {\n  color: #0D904F; }\n\n.codehilite .sb, .md-typeset .highlight .sb {\n  color: #0D904F; }\n\n.codehilite .sc, .md-typeset .highlight .sc {\n  color: #0D904F; }\n\n.codehilite .sd, .md-typeset .highlight .sd {\n  color: #999999; }\n\n.codehilite .s2, .md-typeset .highlight .s2 {\n  color: #0D904F; }\n\n.codehilite .se, .md-typeset .highlight .se {\n  color: #183691; }\n\n.codehilite .sh, .md-typeset .highlight .sh {\n  color: #183691; }\n\n.codehilite .si, .md-typeset .highlight .si {\n  color: #183691; }\n\n.codehilite .sx, .md-typeset .highlight .sx {\n  color: #183691; }\n\n.codehilite .sr, .md-typeset .highlight .sr {\n  color: #009926; }\n\n.codehilite .s1, .md-typeset .highlight .s1 {\n  color: #0D904F; }\n\n.codehilite .ss, .md-typeset .highlight .ss {\n  color: #0D904F; }\n\n.codehilite .err, .md-typeset .highlight .err {\n  color: #A61717; }\n\n.codehilite .w, .md-typeset .highlight .w {\n  color: transparent; }\n\n.codehilite .hll, .md-typeset .highlight .hll {\n  display: block;\n  margin: 0 -1.2rem;\n  padding: 0 1.2rem;\n  background-color: rgba(255, 235, 59, 0.5); }\n\n.md-typeset .codehilite, .md-typeset .highlight {\n  position: relative;\n  margin: 1em 0;\n  padding: 0;\n  border-radius: 0.2rem;\n  background-color: rgba(236, 236, 236, 0.5);\n  color: #37474F;\n  line-height: 1.4;\n  -webkit-overflow-scrolling: touch; }\n  .md-typeset .codehilite pre, .md-typeset .highlight pre,\n  .md-typeset .codehilite code,\n  .md-typeset .highlight code {\n    display: block;\n    margin: 0;\n    padding: 1.05rem 1.2rem;\n    background-color: transparent;\n    overflow: auto;\n    vertical-align: top; }\n    .md-typeset .codehilite pre::-webkit-scrollbar, .md-typeset .highlight pre::-webkit-scrollbar,\n    .md-typeset .codehilite code::-webkit-scrollbar,\n    .md-typeset .highlight code::-webkit-scrollbar {\n      width: 0.4rem;\n      height: 0.4rem; }\n    .md-typeset .codehilite pre::-webkit-scrollbar-thumb, .md-typeset .highlight pre::-webkit-scrollbar-thumb,\n    .md-typeset .codehilite code::-webkit-scrollbar-thumb,\n    .md-typeset .highlight code::-webkit-scrollbar-thumb {\n      background-color: rgba(0, 0, 0, 0.26); }\n      .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover, .md-typeset .highlight pre::-webkit-scrollbar-thumb:hover,\n      .md-typeset .codehilite code::-webkit-scrollbar-thumb:hover,\n      .md-typeset .highlight code::-webkit-scrollbar-thumb:hover {\n        background-color: #536dfe; }\n\n.md-typeset pre.codehilite, .md-typeset pre.highlight {\n  overflow: visible; }\n  .md-typeset pre.codehilite code, .md-typeset pre.highlight code {\n    display: block;\n    padding: 1.05rem 1.2rem;\n    overflow: auto; }\n\n.md-typeset .codehilitetable, .md-typeset .highlighttable {\n  display: block;\n  margin: 1em 0;\n  border-radius: 0.2em;\n  font-size: 1.6rem;\n  overflow: hidden; }\n  .md-typeset .codehilitetable tbody, .md-typeset .highlighttable tbody,\n  .md-typeset .codehilitetable td,\n  .md-typeset .highlighttable td {\n    display: block;\n    padding: 0; }\n  .md-typeset .codehilitetable tr, .md-typeset .highlighttable tr {\n    display: flex; }\n  .md-typeset .codehilitetable .codehilite, .md-typeset .highlighttable .codehilite, .md-typeset .codehilitetable .highlight, .md-typeset .highlighttable .highlight,\n  .md-typeset .codehilitetable .linenodiv,\n  .md-typeset .highlighttable .linenodiv {\n    margin: 0;\n    border-radius: 0; }\n  \n  .md-typeset .codehilitetable .linenodiv,\n  .md-typeset .highlighttable .linenodiv {\n    padding: 1.05rem 1.2rem; }\n  .md-typeset .codehilitetable .linenos, .md-typeset .highlighttable .linenos {\n    background-color: rgba(0, 0, 0, 0.07);\n    color: rgba(0, 0, 0, 0.26);\n    -webkit-user-select: none;\n       -moz-user-select: none;\n        -ms-user-select: none;\n            user-select: none; }\n    .md-typeset .codehilitetable .linenos pre, .md-typeset .highlighttable .linenos pre {\n      margin: 0;\n      padding: 0;\n      background-color: transparent;\n      color: inherit;\n      text-align: right; }\n  .md-typeset .codehilitetable .code, .md-typeset .highlighttable .code {\n    flex: 1;\n    overflow: hidden; }\n\n.md-typeset > .codehilitetable, .md-typeset > .highlighttable {\n  box-shadow: none; }\n\n.md-typeset [id^=\"fnref:\"] {\n  display: inline-block; }\n  .md-typeset [id^=\"fnref:\"]:target {\n    margin-top: -7.6rem;\n    padding-top: 7.6rem;\n    pointer-events: none; }\n\n.md-typeset [id^=\"fn:\"]::before {\n  display: none;\n  height: 0;\n  content: \"\"; }\n\n.md-typeset [id^=\"fn:\"]:target::before {\n  display: block;\n  margin-top: -7rem;\n  padding-top: 7rem;\n  pointer-events: none; }\n\n.md-typeset .footnote {\n  color: rgba(0, 0, 0, 0.54);\n  font-size: 1.28rem; }\n  .md-typeset .footnote ol {\n    margin-left: 0; }\n  .md-typeset .footnote li {\n    transition: color 0.25s; }\n    .md-typeset .footnote li:target {\n      color: rgba(0, 0, 0, 0.87); }\n    .md-typeset .footnote li :first-child {\n      margin-top: 0; }\n    .md-typeset .footnote li:hover .footnote-backref,\n    .md-typeset .footnote li:target .footnote-backref {\n      -webkit-transform: translateX(0);\n              transform: translateX(0);\n      opacity: 1; }\n    .md-typeset .footnote li:hover .footnote-backref:hover,\n    .md-typeset .footnote li:target .footnote-backref {\n      color: #536dfe; }\n\n.md-typeset .footnote-ref {\n  display: inline-block;\n  pointer-events: initial; }\n  .md-typeset .footnote-ref::before {\n    display: inline;\n    margin: 0 0.2em;\n    border-left: 0.1rem solid rgba(0, 0, 0, 0.26);\n    font-size: 1.25em;\n    content: \"\";\n    vertical-align: -0.5rem; }\n\n.md-typeset .footnote-backref {\n  display: inline-block;\n  -webkit-transform: translateX(0.5rem);\n          transform: translateX(0.5rem);\n  transition: color     0.25s, opacity   0.125s 0.125s, -webkit-transform 0.25s  0.125s;\n  transition: transform 0.25s  0.125s, color     0.25s, opacity   0.125s 0.125s;\n  transition: transform 0.25s  0.125s, color     0.25s, opacity   0.125s 0.125s, -webkit-transform 0.25s  0.125s;\n  color: rgba(0, 0, 0, 0.26);\n  font-size: 0;\n  opacity: 0;\n  vertical-align: text-bottom; }\n  [dir=\"rtl\"] .md-typeset .footnote-backref {\n    -webkit-transform: translateX(-0.5rem);\n            transform: translateX(-0.5rem); }\n  .md-typeset .footnote-backref::before {\n    display: inline-block;\n    font-size: 1.6rem;\n    content: \"\\E31B\"; }\n    [dir=\"rtl\"] .md-typeset .footnote-backref::before {\n      -webkit-transform: scaleX(-1);\n              transform: scaleX(-1); }\n\n.md-typeset .headerlink {\n  display: inline-block;\n  margin-left: 1rem;\n  -webkit-transform: translate(0, 0.5rem);\n          transform: translate(0, 0.5rem);\n  transition: color     0.25s, opacity   0.125s 0.25s, -webkit-transform 0.25s  0.25s;\n  transition: transform 0.25s  0.25s, color     0.25s, opacity   0.125s 0.25s;\n  transition: transform 0.25s  0.25s, color     0.25s, opacity   0.125s 0.25s, -webkit-transform 0.25s  0.25s;\n  opacity: 0; }\n  [dir=\"rtl\"] .md-typeset .headerlink {\n    margin-right: 1rem;\n    margin-left: initial; }\n  html body .md-typeset .headerlink {\n    color: rgba(0, 0, 0, 0.26); }\n\n.md-typeset h1[id]::before {\n  display: block;\n  margin-top: -0.9rem;\n  padding-top: 0.9rem;\n  content: \"\"; }\n\n.md-typeset h1[id]:target::before {\n  margin-top: -6.9rem;\n  padding-top: 6.9rem; }\n\n.md-typeset h1[id]:hover .headerlink,\n.md-typeset h1[id]:target .headerlink,\n.md-typeset h1[id] .headerlink:focus {\n  -webkit-transform: translate(0, 0);\n          transform: translate(0, 0);\n  opacity: 1; }\n\n.md-typeset h1[id]:hover .headerlink:hover,\n.md-typeset h1[id]:target .headerlink,\n.md-typeset h1[id] .headerlink:focus {\n  color: #536dfe; }\n\n.md-typeset h2[id]::before {\n  display: block;\n  margin-top: -0.8rem;\n  padding-top: 0.8rem;\n  content: \"\"; }\n\n.md-typeset h2[id]:target::before {\n  margin-top: -6.8rem;\n  padding-top: 6.8rem; }\n\n.md-typeset h2[id]:hover .headerlink,\n.md-typeset h2[id]:target .headerlink,\n.md-typeset h2[id] .headerlink:focus {\n  -webkit-transform: translate(0, 0);\n          transform: translate(0, 0);\n  opacity: 1; }\n\n.md-typeset h2[id]:hover .headerlink:hover,\n.md-typeset h2[id]:target .headerlink,\n.md-typeset h2[id] .headerlink:focus {\n  color: #536dfe; }\n\n.md-typeset h3[id]::before {\n  display: block;\n  margin-top: -0.9rem;\n  padding-top: 0.9rem;\n  content: \"\"; }\n\n.md-typeset h3[id]:target::before {\n  margin-top: -6.9rem;\n  padding-top: 6.9rem; }\n\n.md-typeset h3[id]:hover .headerlink,\n.md-typeset h3[id]:target .headerlink,\n.md-typeset h3[id] .headerlink:focus {\n  -webkit-transform: translate(0, 0);\n          transform: translate(0, 0);\n  opacity: 1; }\n\n.md-typeset h3[id]:hover .headerlink:hover,\n.md-typeset h3[id]:target .headerlink,\n.md-typeset h3[id] .headerlink:focus {\n  color: #536dfe; }\n\n.md-typeset h4[id]::before {\n  display: block;\n  margin-top: -0.9rem;\n  padding-top: 0.9rem;\n  content: \"\"; }\n\n.md-typeset h4[id]:target::before {\n  margin-top: -6.9rem;\n  padding-top: 6.9rem; }\n\n.md-typeset h4[id]:hover .headerlink,\n.md-typeset h4[id]:target .headerlink,\n.md-typeset h4[id] .headerlink:focus {\n  -webkit-transform: translate(0, 0);\n          transform: translate(0, 0);\n  opacity: 1; }\n\n.md-typeset h4[id]:hover .headerlink:hover,\n.md-typeset h4[id]:target .headerlink,\n.md-typeset h4[id] .headerlink:focus {\n  color: #536dfe; }\n\n.md-typeset h5[id]::before {\n  display: block;\n  margin-top: -1.1rem;\n  padding-top: 1.1rem;\n  content: \"\"; }\n\n.md-typeset h5[id]:target::before {\n  margin-top: -7.1rem;\n  padding-top: 7.1rem; }\n\n.md-typeset h5[id]:hover .headerlink,\n.md-typeset h5[id]:target .headerlink,\n.md-typeset h5[id] .headerlink:focus {\n  -webkit-transform: translate(0, 0);\n          transform: translate(0, 0);\n  opacity: 1; }\n\n.md-typeset h5[id]:hover .headerlink:hover,\n.md-typeset h5[id]:target .headerlink,\n.md-typeset h5[id] .headerlink:focus {\n  color: #536dfe; }\n\n.md-typeset h6[id]::before {\n  display: block;\n  margin-top: -1.1rem;\n  padding-top: 1.1rem;\n  content: \"\"; }\n\n.md-typeset h6[id]:target::before {\n  margin-top: -7.1rem;\n  padding-top: 7.1rem; }\n\n.md-typeset h6[id]:hover .headerlink,\n.md-typeset h6[id]:target .headerlink,\n.md-typeset h6[id] .headerlink:focus {\n  -webkit-transform: translate(0, 0);\n          transform: translate(0, 0);\n  opacity: 1; }\n\n.md-typeset h6[id]:hover .headerlink:hover,\n.md-typeset h6[id]:target .headerlink,\n.md-typeset h6[id] .headerlink:focus {\n  color: #536dfe; }\n\n.md-typeset .MJXc-display {\n  margin: 0.75em 0;\n  padding: 0.75em 0;\n  overflow: auto;\n  -webkit-overflow-scrolling: touch; }\n\n.md-typeset .MathJax_CHTML {\n  outline: 0; }\n\n.md-typeset del.critic,\n.md-typeset ins.critic,\n.md-typeset .critic.comment {\n  margin: 0 0.25em;\n  padding: 0.0625em 0;\n  border-radius: 0.2rem;\n  -webkit-box-decoration-break: clone;\n          box-decoration-break: clone; }\n\n.md-typeset del.critic {\n  background-color: #FFDDDD;\n  box-shadow: 0.25em 0 0 #FFDDDD, -0.25em 0 0 #FFDDDD; }\n\n.md-typeset ins.critic {\n  background-color: #DDFFDD;\n  box-shadow: 0.25em 0 0 #DDFFDD, -0.25em 0 0 #DDFFDD; }\n\n.md-typeset .critic.comment {\n  background-color: rgba(236, 236, 236, 0.5);\n  color: #37474F;\n  box-shadow: 0.25em 0 0 rgba(236, 236, 236, 0.5), -0.25em 0 0 rgba(236, 236, 236, 0.5); }\n  .md-typeset .critic.comment::before {\n    padding-right: 0.125em;\n    color: rgba(0, 0, 0, 0.26);\n    content: \"\\E0B7\";\n    vertical-align: -0.125em; }\n\n.md-typeset .critic.block {\n  display: block;\n  margin: 1em 0;\n  padding-right: 1.6rem;\n  padding-left: 1.6rem;\n  box-shadow: none; }\n  .md-typeset .critic.block :first-child {\n    margin-top: 0.5em; }\n  .md-typeset .critic.block :last-child {\n    margin-bottom: 0.5em; }\n\n.md-typeset details {\n  display: block;\n  padding-top: 0; }\n  .md-typeset details[open] > summary::after {\n    -webkit-transform: rotate(180deg);\n            transform: rotate(180deg); }\n  .md-typeset details:not([open]) {\n    padding-bottom: 0; }\n    .md-typeset details:not([open]) > summary {\n      border-bottom: none; }\n  .md-typeset details summary {\n    padding-right: 4rem; }\n    [dir=\"rtl\"] .md-typeset details summary {\n      padding-left: 4rem; }\n  .no-details .md-typeset details:not([open]) > * {\n    display: none; }\n  .no-details .md-typeset details:not([open]) summary {\n    display: block; }\n\n.md-typeset summary {\n  display: block;\n  outline: none;\n  cursor: pointer; }\n  .md-typeset summary::-webkit-details-marker {\n    display: none; }\n  .md-typeset summary::after {\n    position: absolute;\n    top: 0.8rem;\n    right: 1.2rem;\n    color: rgba(0, 0, 0, 0.26);\n    font-size: 2rem;\n    content: \"\\E313\"; }\n    [dir=\"rtl\"] .md-typeset summary::after {\n      right: initial;\n      left: 1.2rem; }\n\n.md-typeset .emojione {\n  width: 2rem;\n  vertical-align: text-top; }\n\n.md-typeset code.codehilite, .md-typeset code.highlight {\n  margin: 0 0.29412em;\n  padding: 0.07353em 0; }\n\n.md-typeset .superfences-content {\n  display: none;\n  order: 99;\n  width: 100%;\n  background-color: white; }\n  .md-typeset .superfences-content > * {\n    margin: 0;\n    border-radius: 0; }\n\n.md-typeset .superfences-tabs {\n  display: flex;\n  position: relative;\n  flex-wrap: wrap;\n  margin: 1em 0;\n  border: 0.1rem solid rgba(0, 0, 0, 0.07);\n  border-radius: 0.2em; }\n  .md-typeset .superfences-tabs > input {\n    display: none; }\n    .md-typeset .superfences-tabs > input:checked + label {\n      font-weight: 700; }\n      .md-typeset .superfences-tabs > input:checked + label + .superfences-content {\n        display: block; }\n  .md-typeset .superfences-tabs > label {\n    width: auto;\n    padding: 1.2rem 1.2rem;\n    transition: color 0.125s;\n    font-size: 1.28rem;\n    cursor: pointer; }\n    html .md-typeset .superfences-tabs > label:hover {\n      color: #536dfe; }\n\n.md-typeset .task-list-item {\n  position: relative;\n  list-style-type: none; }\n  .md-typeset .task-list-item [type=\"checkbox\"] {\n    position: absolute;\n    top: 0.45em;\n    left: -2em; }\n    [dir=\"rtl\"] .md-typeset .task-list-item [type=\"checkbox\"] {\n      right: -2em;\n      left: initial; }\n\n.md-typeset .task-list-control .task-list-indicator::before {\n  position: absolute;\n  top: 0.15em;\n  left: -1.25em;\n  color: rgba(0, 0, 0, 0.26);\n  font-size: 1.25em;\n  content: \"\\E835\";\n  vertical-align: -0.25em; }\n  [dir=\"rtl\"] .md-typeset .task-list-control .task-list-indicator::before {\n    right: -1.25em;\n    left: initial; }\n\n.md-typeset .task-list-control [type=\"checkbox\"]:checked + .task-list-indicator::before {\n  content: \"\\E834\"; }\n\n.md-typeset .task-list-control [type=\"checkbox\"] {\n  opacity: 0;\n  z-index: -1; }\n\n@media print {\n      .md-typeset a::after {\n        color: rgba(0, 0, 0, 0.54);\n        content: \" [\" attr(href) \"]\"; }\n      .md-typeset code,\n      .md-typeset pre {\n        white-space: pre-wrap; }\n      .md-typeset code {\n        box-shadow: none;\n        -webkit-box-decoration-break: initial;\n                box-decoration-break: initial; }\n    .md-clipboard {\n      display: none; }\n    .md-content__icon {\n      display: none; }\n    .md-header {\n      display: none; }\n  .md-footer {\n    display: none; }\n    .md-sidebar {\n      display: none; }\n    .md-tabs {\n      display: none; }\n    .md-typeset .headerlink {\n      display: none; } }\n\n@media only screen and (max-width: 44.9375em) {\n      .md-typeset pre {\n        margin: 1em -1.6rem;\n        border-radius: 0; }\n        .md-typeset pre > code {\n          padding: 1.05rem 1.6rem; }\n        .md-footer-nav__link--prev .md-footer-nav__title {\n          display: none; }\n      .md-search-result__teaser {\n        max-height: 5rem;\n        -webkit-line-clamp: 3; }\n    .codehilite .hll, .md-typeset .highlight .hll {\n      margin: 0 -1.6rem;\n      padding: 0 1.6rem; }\n  .md-typeset > .codehilite, .md-typeset > .highlight {\n    margin: 1em -1.6rem;\n    border-radius: 0; }\n    .md-typeset > .codehilite pre, .md-typeset > .highlight pre,\n    .md-typeset > .codehilite code,\n    .md-typeset > .highlight code {\n      padding: 1.05rem 1.6rem; }\n    .md-typeset > .codehilitetable, .md-typeset > .highlighttable {\n      margin: 1em -1.6rem;\n      border-radius: 0; }\n      .md-typeset > .codehilitetable .codehilite > pre, .md-typeset > .highlighttable .codehilite > pre, .md-typeset > .codehilitetable .highlight > pre, .md-typeset > .highlighttable .highlight > pre,\n      .md-typeset > .codehilitetable .codehilite > code,\n      .md-typeset > .highlighttable .codehilite > code,\n      .md-typeset > .codehilitetable .highlight > code,\n      .md-typeset > .highlighttable .highlight > code,\n      .md-typeset > .codehilitetable .linenodiv,\n      .md-typeset > .highlighttable .linenodiv {\n        padding: 1rem 1.6rem; }\n  .md-typeset > p > .MJXc-display {\n    margin: 0.75em -1.6rem;\n    padding: 0.25em 1.6rem; }\n  .md-typeset > .superfences-tabs {\n    margin: 1em -1.6rem;\n    border: 0;\n    border-top: 0.1rem solid rgba(0, 0, 0, 0.07);\n    border-radius: 0; }\n    .md-typeset > .superfences-tabs pre,\n    .md-typeset > .superfences-tabs code {\n      padding: 1.05rem 1.6rem; } }\n\n@media only screen and (min-width: 100em) {\n    html {\n      font-size: 68.75%; } }\n\n@media only screen and (min-width: 125em) {\n    html {\n      font-size: 75%; } }\n\n@media only screen and (max-width: 59.9375em) {\n    body[data-md-state=\"lock\"] {\n      overflow: hidden; }\n      .ios body[data-md-state=\"lock\"] .md-container {\n        display: none; }\n    html .md-nav__link[for=\"__toc\"] {\n      display: block;\n      padding-right: 4.8rem; }\n      html .md-nav__link[for=\"__toc\"]::after {\n        color: inherit;\n        content: \"\\E8DE\"; }\n      html .md-nav__link[for=\"__toc\"] + .md-nav__link {\n        display: none; }\n      html .md-nav__link[for=\"__toc\"] ~ .md-nav {\n        display: flex; }\n    html [dir=\"rtl\"] .md-nav__link {\n      padding-right: 1.6rem;\n      padding-left: 4.8rem; }\n    .md-nav__source {\n      display: block;\n      padding: 0 0.4rem;\n      background-color: rgba(50, 64, 144, 0.9675);\n      color: white; }\n    .md-search__overlay {\n      position: absolute;\n      top: 0.4rem;\n      left: 0.4rem;\n      width: 3.6rem;\n      height: 3.6rem;\n      -webkit-transform-origin: center;\n              transform-origin: center;\n      transition: opacity   0.2s 0.2s, -webkit-transform 0.3s 0.1s;\n      transition: transform 0.3s 0.1s, opacity   0.2s 0.2s;\n      transition: transform 0.3s 0.1s, opacity   0.2s 0.2s, -webkit-transform 0.3s 0.1s;\n      border-radius: 2rem;\n      background-color: white;\n      overflow: hidden;\n      pointer-events: none; }\n      [dir=\"rtl\"] .md-search__overlay {\n        right: 0.4rem;\n        left: initial; }\n      [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__overlay {\n        transition: opacity   0.1s, -webkit-transform 0.4s;\n        transition: transform 0.4s, opacity   0.1s;\n        transition: transform 0.4s, opacity   0.1s, -webkit-transform 0.4s;\n        opacity: 1; }\n  .md-search__inner {\n    position: fixed;\n    top: 0;\n    left: 100%;\n    width: 100%;\n    height: 100%;\n    -webkit-transform: translateX(5%);\n            transform: translateX(5%);\n    transition: right 0s 0.3s, left 0s 0.3s, opacity 0.15s 0.15s, -webkit-transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1);\n    transition: right 0s 0.3s, left 0s 0.3s, transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.15s 0.15s;\n    transition: right 0s 0.3s, left 0s 0.3s, transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.15s 0.15s, -webkit-transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1);\n    opacity: 0;\n    z-index: 2; }\n    [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__inner {\n      left: 0;\n      -webkit-transform: translateX(0);\n              transform: translateX(0);\n      transition: right 0s 0s, left 0s 0s, opacity 0.15s 0.15s, -webkit-transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1);\n      transition: right 0s 0s, left 0s 0s, transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s 0.15s;\n      transition: right 0s 0s, left 0s 0s, transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s 0.15s, -webkit-transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1);\n      opacity: 1; }\n      [dir=\"rtl\"] [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__inner {\n        right: 0;\n        left: initial; }\n    html [dir=\"rtl\"] .md-search__inner {\n      right: 100%;\n      left: initial;\n      -webkit-transform: translateX(-5%);\n              transform: translateX(-5%); }\n    .md-search__input {\n      width: 100%;\n      height: 4.8rem;\n      font-size: 1.8rem; }\n      .md-search__icon[for=\"__search\"] {\n        top: 1.2rem;\n        left: 1.6rem; }\n        .md-search__icon[for=\"__search\"][for=\"__search\"]::before {\n          content: \"\\E5C4\"; }\n          [dir=\"rtl\"] .md-search__icon[for=\"__search\"][for=\"__search\"]::before {\n            content: \"\\E5C8\"; }\n      .md-search__icon[type=\"reset\"] {\n        top: 1.2rem;\n        right: 1.6rem; }\n    .md-search__output {\n      top: 4.8rem;\n      bottom: 0; }\n        .md-search-result__article--document::before {\n          display: none; } }\n\n@media only screen and (max-width: 76.1875em) {\n    [data-md-toggle=\"drawer\"]:checked ~ .md-overlay {\n      width: 100%;\n      height: 100%;\n      transition: width   0s, height  0s, opacity 0.25s;\n      opacity: 1; }\n      .md-header-nav__button.md-icon--home, .md-header-nav__button.md-logo {\n        display: none; }\n      .md-hero__inner {\n        margin-top: 4.8rem;\n        margin-bottom: 2.4rem; }\n    .md-nav {\n      background-color: white; }\n      .md-nav--primary,\n      .md-nav--primary .md-nav {\n        display: flex;\n        position: absolute;\n        top: 0;\n        right: 0;\n        left: 0;\n        flex-direction: column;\n        height: 100%;\n        z-index: 1; }\n      .md-nav--primary .md-nav__title,\n      .md-nav--primary .md-nav__item {\n        font-size: 1.6rem;\n        line-height: 1.5; }\n      html .md-nav--primary .md-nav__title {\n        position: relative;\n        height: 11.2rem;\n        padding: 6rem 1.6rem 0.4rem;\n        background-color: rgba(0, 0, 0, 0.07);\n        color: rgba(0, 0, 0, 0.54);\n        font-weight: 400;\n        line-height: 4.8rem;\n        white-space: nowrap;\n        cursor: pointer; }\n        html .md-nav--primary .md-nav__title::before {\n          display: block;\n          position: absolute;\n          top: 0.4rem;\n          left: 0.4rem;\n          width: 4rem;\n          height: 4rem;\n          color: rgba(0, 0, 0, 0.54); }\n        html .md-nav--primary .md-nav__title ~ .md-nav__list {\n          background-color: white;\n          box-shadow: 0 0.1rem 0 rgba(0, 0, 0, 0.07) inset; }\n          html .md-nav--primary .md-nav__title ~ .md-nav__list > .md-nav__item:first-child {\n            border-top: 0; }\n        html .md-nav--primary .md-nav__title--site {\n          position: relative;\n          background-color: #3f51b5;\n          color: white; }\n          html .md-nav--primary .md-nav__title--site .md-nav__button {\n            display: block;\n            position: absolute;\n            top: 0.4rem;\n            left: 0.4rem;\n            width: 6.4rem;\n            height: 6.4rem;\n            font-size: 4.8rem; }\n          html .md-nav--primary .md-nav__title--site::before {\n            display: none; }\n      html [dir=\"rtl\"] .md-nav--primary .md-nav__title::before {\n        right: 0.4rem;\n        left: initial; }\n      html [dir=\"rtl\"] .md-nav--primary .md-nav__title--site .md-nav__button {\n        right: 0.4rem;\n        left: initial; }\n      .md-nav--primary .md-nav__list {\n        flex: 1;\n        overflow-y: auto; }\n      .md-nav--primary .md-nav__item {\n        padding: 0;\n        border-top: 0.1rem solid rgba(0, 0, 0, 0.07); }\n        [dir=\"rtl\"] .md-nav--primary .md-nav__item {\n          padding: 0; }\n        .md-nav--primary .md-nav__item--nested > .md-nav__link {\n          padding-right: 4.8rem; }\n          [dir=\"rtl\"] .md-nav--primary .md-nav__item--nested > .md-nav__link {\n            padding-right: 1.6rem;\n            padding-left: 4.8rem; }\n          .md-nav--primary .md-nav__item--nested > .md-nav__link::after {\n            content: \"\\E315\"; }\n            [dir=\"rtl\"] .md-nav--primary .md-nav__item--nested > .md-nav__link::after {\n              content: \"\\E314\"; }\n      .md-nav--primary .md-nav__link {\n        position: relative;\n        margin-top: 0;\n        padding: 1.2rem 1.6rem; }\n        .md-nav--primary .md-nav__link::after {\n          position: absolute;\n          top: 50%;\n          right: 1.2rem;\n          margin-top: -1.2rem;\n          color: inherit;\n          font-size: 2.4rem; }\n          [dir=\"rtl\"] .md-nav--primary .md-nav__link::after {\n            right: initial;\n            left: 1.2rem; }\n      .md-nav--primary .md-nav--secondary .md-nav__link {\n        position: static; }\n      .md-nav--primary .md-nav--secondary .md-nav {\n        position: static;\n        background-color: transparent; }\n        .md-nav--primary .md-nav--secondary .md-nav .md-nav__link {\n          padding-left: 2.8rem; }\n          [dir=\"rtl\"] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link {\n            padding-right: 2.8rem;\n            padding-left: initial; }\n        .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link {\n          padding-left: 4rem; }\n          [dir=\"rtl\"] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link {\n            padding-right: 4rem;\n            padding-left: initial; }\n        .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link {\n          padding-left: 5.2rem; }\n          [dir=\"rtl\"] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link {\n            padding-right: 5.2rem;\n            padding-left: initial; }\n        .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link {\n          padding-left: 6.4rem; }\n          [dir=\"rtl\"] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link {\n            padding-right: 6.4rem;\n            padding-left: initial; }\n      .md-nav__toggle ~ .md-nav {\n        display: flex;\n        -webkit-transform: translateX(100%);\n                transform: translateX(100%);\n        transition: opacity 0.125s 0.05s, -webkit-transform 0.25s cubic-bezier(0.8, 0, 0.6, 1);\n        transition: transform 0.25s cubic-bezier(0.8, 0, 0.6, 1), opacity 0.125s 0.05s;\n        transition: transform 0.25s cubic-bezier(0.8, 0, 0.6, 1), opacity 0.125s 0.05s, -webkit-transform 0.25s cubic-bezier(0.8, 0, 0.6, 1);\n        opacity: 0; }\n        [dir=\"rtl\"] .md-nav__toggle ~ .md-nav {\n          -webkit-transform: translateX(-100%);\n                  transform: translateX(-100%); }\n        .no-csstransforms3d .md-nav__toggle ~ .md-nav {\n          display: none; }\n      .md-nav__toggle:checked ~ .md-nav {\n        -webkit-transform: translateX(0);\n                transform: translateX(0);\n        transition: opacity 0.125s 0.125s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n        transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.125s 0.125s;\n        transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.125s 0.125s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n        opacity: 1; }\n        .no-csstransforms3d .md-nav__toggle:checked ~ .md-nav {\n          display: flex; }\n    .md-sidebar--primary {\n      position: fixed;\n      top: 0;\n      left: -24.2rem;\n      width: 24.2rem;\n      height: 100%;\n      -webkit-transform: translateX(0);\n              transform: translateX(0);\n      transition: box-shadow 0.25s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n      transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.25s;\n      transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.25s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n      background-color: white;\n      z-index: 3; }\n      [dir=\"rtl\"] .md-sidebar--primary {\n        right: -24.2rem;\n        left: initial; }\n      .no-csstransforms3d .md-sidebar--primary {\n        display: none; }\n      [data-md-toggle=\"drawer\"]:checked ~ .md-container .md-sidebar--primary {\n        box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.4);\n        -webkit-transform: translateX(24.2rem);\n                transform: translateX(24.2rem); }\n        [dir=\"rtl\"] [data-md-toggle=\"drawer\"]:checked ~ .md-container .md-sidebar--primary {\n          -webkit-transform: translateX(-24.2rem);\n                  transform: translateX(-24.2rem); }\n        .no-csstransforms3d [data-md-toggle=\"drawer\"]:checked ~ .md-container .md-sidebar--primary {\n          display: block; }\n      .md-sidebar--primary .md-sidebar__scrollwrap {\n        overflow: hidden; }\n      .md-sidebar--primary .md-sidebar__scrollwrap {\n        position: absolute;\n        top: 0;\n        right: 0;\n        bottom: 0;\n        left: 0;\n        margin: 0; }\n    .md-tabs {\n      display: none; } }\n\n@media only screen and (min-width: 60em) {\n  .md-content {\n    margin-right: 24.2rem; }\n    [dir=\"rtl\"] .md-content {\n      margin-right: initial;\n      margin-left: 24.2rem; }\n      .md-header-nav__button.md-icon--search {\n        display: none; }\n      .md-header-nav__source {\n        display: block;\n        width: 23rem;\n        max-width: 23rem;\n        margin-left: 2.8rem;\n        padding-right: 1.2rem; }\n        [dir=\"rtl\"] .md-header-nav__source {\n          margin-right: 2.8rem;\n          margin-left: initial;\n          padding-right: initial;\n          padding-left: 1.2rem; }\n  .md-search {\n    padding: 0.4rem; }\n    .md-search__overlay {\n      position: fixed;\n      top: 0;\n      left: 0;\n      width: 0;\n      height: 0;\n      transition: width   0s 0.25s, height  0s 0.25s, opacity 0.25s;\n      background-color: rgba(0, 0, 0, 0.54);\n      cursor: pointer; }\n      [dir=\"rtl\"] .md-search__overlay {\n        right: 0;\n        left: initial; }\n      [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__overlay {\n        width: 100%;\n        height: 100%;\n        transition: width   0s, height  0s, opacity 0.25s;\n        opacity: 1; }\n  .md-search__inner {\n    position: relative;\n    width: 23rem;\n    padding: 0.2rem 0;\n    float: right;\n    transition: width 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); }\n    [dir=\"rtl\"] .md-search__inner {\n      float: left; }\n    .md-search__form {\n      border-radius: 0.2rem; }\n    .md-search__input {\n      width: 100%;\n      height: 3.6rem;\n      padding-left: 4.4rem;\n      transition: background-color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1), color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1);\n      border-radius: 0.2rem;\n      background-color: rgba(0, 0, 0, 0.26);\n      color: inherit;\n      font-size: 1.6rem; }\n      [dir=\"rtl\"] .md-search__input {\n        padding-right: 4.4rem; }\n      .md-search__input + .md-search__icon {\n        color: inherit; }\n      .md-search__input::-webkit-input-placeholder {\n        color: rgba(255, 255, 255, 0.7); }\n      .md-search__input:-ms-input-placeholder {\n        color: rgba(255, 255, 255, 0.7); }\n      .md-search__input::-ms-input-placeholder {\n        color: rgba(255, 255, 255, 0.7); }\n      .md-search__input::placeholder {\n        color: rgba(255, 255, 255, 0.7); }\n      .md-search__input:hover {\n        background-color: rgba(255, 255, 255, 0.12); }\n      [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__input {\n        border-radius: 0.2rem 0.2rem 0 0;\n        background-color: white;\n        color: rgba(0, 0, 0, 0.87);\n        text-overflow: none; }\n        [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__input + .md-search__icon, [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__input::-webkit-input-placeholder {\n          color: rgba(0, 0, 0, 0.54); }\n        [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__input + .md-search__icon, [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__input:-ms-input-placeholder {\n          color: rgba(0, 0, 0, 0.54); }\n        [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__input + .md-search__icon, [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__input::-ms-input-placeholder {\n          color: rgba(0, 0, 0, 0.54); }\n        [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__input + .md-search__icon, [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__input::placeholder {\n          color: rgba(0, 0, 0, 0.54); }\n    .md-search__output {\n      top: 3.8rem;\n      transition: opacity 0.4s;\n      opacity: 0; }\n      [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__output {\n        box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12), 0 3px 5px -1px rgba(0, 0, 0, 0.4);\n        opacity: 1; }\n    .md-search__scrollwrap {\n      max-height: 0; }\n      [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__scrollwrap {\n        max-height: 75vh; }\n      .md-search__scrollwrap::-webkit-scrollbar {\n        width: 0.4rem;\n        height: 0.4rem; }\n      .md-search__scrollwrap::-webkit-scrollbar-thumb {\n        background-color: rgba(0, 0, 0, 0.26); }\n        .md-search__scrollwrap::-webkit-scrollbar-thumb:hover {\n          background-color: #536dfe; }\n      .md-search-result__meta {\n        padding-left: 4.4rem; }\n        [dir=\"rtl\"] .md-search-result__meta {\n          padding-right: 4.4rem;\n          padding-left: initial; }\n      .md-search-result__article {\n        padding-left: 4.4rem; }\n        [dir=\"rtl\"] .md-search-result__article {\n          padding-right: 4.4rem;\n          padding-left: 1.6rem; }\n      .md-sidebar--secondary {\n        display: block;\n        margin-left: 100%;\n        -webkit-transform: translate(-100%, 0);\n                transform: translate(-100%, 0); }\n        [dir=\"rtl\"] .md-sidebar--secondary {\n          margin-right: 100%;\n          margin-left: initial;\n          -webkit-transform: translate(100%, 0);\n                  transform: translate(100%, 0); } }\n\n@media only screen and (min-width: 76.25em) {\n  .md-content {\n    margin-left: 24.2rem; }\n    [dir=\"rtl\"] .md-content {\n      margin-right: 24.2rem; }\n    .md-content__inner {\n      margin-right: 2.4rem;\n      margin-left: 2.4rem; }\n      .md-header-nav__button.md-icon--menu {\n        display: none; }\n    .md-nav[data-md-state=\"animate\"] {\n      transition: max-height 0.25s cubic-bezier(0.86, 0, 0.07, 1); }\n    .md-nav__toggle ~ .md-nav {\n      max-height: 0;\n      overflow: hidden; }\n      .no-js .md-nav__toggle ~ .md-nav {\n        display: none; }\n    .md-nav__toggle:checked ~ .md-nav, .md-nav[data-md-state=\"expand\"] {\n      max-height: 100%; }\n      .no-js .md-nav__toggle:checked ~ .md-nav, .no-js .md-nav[data-md-state=\"expand\"] {\n        display: block; }\n    .md-nav__item--nested > .md-nav > .md-nav__title {\n      display: none; }\n    .md-nav__item--nested > .md-nav__link::after {\n      display: inline-block;\n      -webkit-transform-origin: 0.45em 0.45em;\n              transform-origin: 0.45em 0.45em;\n      -webkit-transform-style: preserve-3d;\n              transform-style: preserve-3d;\n      vertical-align: -0.125em; }\n      .js .md-nav__item--nested > .md-nav__link::after {\n        transition: -webkit-transform 0.4s;\n        transition: transform 0.4s;\n        transition: transform 0.4s, -webkit-transform 0.4s; }\n    .md-nav__item--nested .md-nav__toggle:checked ~ .md-nav__link::after {\n      -webkit-transform: rotateX(180deg);\n              transform: rotateX(180deg); }\n  [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__inner {\n    width: 68.8rem; }\n    .md-search__scrollwrap {\n      width: 68.8rem; }\n      .md-sidebar--secondary {\n        margin-left: 122rem; }\n        [dir=\"rtl\"] .md-sidebar--secondary {\n          margin-right: 122rem;\n          margin-left: initial; }\n    .md-tabs ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--nested {\n      font-size: 0;\n      visibility: hidden; }\n    .md-tabs--active ~ .md-main .md-nav--primary .md-nav__title {\n      display: block;\n      padding: 0; }\n    .md-tabs--active ~ .md-main .md-nav--primary .md-nav__title--site {\n      display: none; }\n    .no-js .md-tabs--active ~ .md-main .md-nav--primary .md-nav {\n      display: block; }\n    .md-tabs--active ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item {\n      font-size: 0;\n      visibility: hidden; }\n      .md-tabs--active ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--nested {\n        display: none;\n        font-size: 1.4rem;\n        overflow: auto;\n        visibility: visible; }\n        .md-tabs--active ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--nested > .md-nav__link {\n          display: none; }\n      .md-tabs--active ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--active {\n        display: block; }\n    .md-tabs--active ~ .md-main .md-nav[data-md-level=\"1\"] {\n      max-height: initial;\n      overflow: visible; }\n      .md-tabs--active ~ .md-main .md-nav[data-md-level=\"1\"] > .md-nav__list > .md-nav__item {\n        padding-left: 0; }\n      .md-tabs--active ~ .md-main .md-nav[data-md-level=\"1\"] .md-nav .md-nav__title {\n        display: none; } }\n\n@media only screen and (min-width: 45em) {\n      .md-footer-nav__link {\n        width: 50%; }\n    .md-footer-copyright {\n      max-width: 75%;\n      float: left; }\n      [dir=\"rtl\"] .md-footer-copyright {\n        float: right; }\n    .md-footer-social {\n      padding: 1.2rem 0;\n      float: right; }\n      [dir=\"rtl\"] .md-footer-social {\n        float: left; } }\n\n@media only screen and (max-width: 29.9375em) {\n    [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__overlay {\n      -webkit-transform: scale(45);\n              transform: scale(45); } }\n\n@media only screen and (min-width: 30em) and (max-width: 44.9375em) {\n    [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__overlay {\n      -webkit-transform: scale(60);\n              transform: scale(60); } }\n\n@media only screen and (min-width: 45em) and (max-width: 59.9375em) {\n    [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__overlay {\n      -webkit-transform: scale(75);\n              transform: scale(75); } }\n\n@media only screen and (min-width: 60em) and (max-width: 76.1875em) {\n  [data-md-toggle=\"search\"]:checked ~ .md-header .md-search__inner {\n    width: 46.8rem; }\n    .md-search__scrollwrap {\n      width: 46.8rem; }\n      .md-search-result__teaser {\n        max-height: 5rem;\n        -webkit-line-clamp: 3; } }\n\n/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2FwcGxpY2F0aW9uLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9iYXNlL19yZXNldC5zY3NzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvYmFzZS9faWNvbnMuc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL19jb25maWcuc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2Jhc2UvX3R5cGVzZXQuc2NzcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvbW9kdWxhcnNjYWxlLXNhc3Mvc3R5bGVzaGVldHMvbW9kdWxhcnNjYWxlL19mdW5jdGlvbi5zY3NzIiwid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9tYXRlcmlhbC1kZXNpZ24tY29sb3IvbWF0ZXJpYWwtY29sb3Iuc2NzcyIsIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvbWF0ZXJpYWwtc2hhZG93cy9tYXRlcmlhbC1zaGFkb3dzLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9sYXlvdXQvX2Jhc2Uuc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2xheW91dC9fY2xpcGJvYXJkLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9sYXlvdXQvX2NvbnRlbnQuc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2xheW91dC9faGVhZGVyLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9sYXlvdXQvX2hlcm8uc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2xheW91dC9fZm9vdGVyLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9sYXlvdXQvX25hdi5zY3NzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvbGF5b3V0L19zZWFyY2guc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2xheW91dC9fc2lkZWJhci5zY3NzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvbGF5b3V0L19zb3VyY2Uuc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2xheW91dC9fdGFicy5zY3NzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvZXh0ZW5zaW9ucy9fYWRtb25pdGlvbi5zY3NzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvZXh0ZW5zaW9ucy9fY29kZWhpbGl0ZS5zY3NzIiwid2VicGFjazovLy8uL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvZXh0ZW5zaW9ucy9fZm9vdG5vdGVzLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9leHRlbnNpb25zL19wZXJtYWxpbmtzLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9leHRlbnNpb25zL3B5bWRvd24vX2FyaXRobWF0ZXguc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2V4dGVuc2lvbnMvcHltZG93bi9fY3JpdGljLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9leHRlbnNpb25zL3B5bWRvd24vX2RldGFpbHMuc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2V4dGVuc2lvbnMvcHltZG93bi9fZW1vamkuc2NzcyIsIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2V4dGVuc2lvbnMvcHltZG93bi9faW5saW5laGlsaXRlLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9leHRlbnNpb25zL3B5bWRvd24vX3N1cGVyZmVuY2VzLnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9leHRlbnNpb25zL3B5bWRvd24vX3Rhc2tsaXN0LnNjc3MiLCJ3ZWJwYWNrOi8vLy4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9oZWxwZXJzL19icmVhay5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlCQUFpQjtBQzZCakI7RUFDRSx1QkFBc0IsRUFDdkI7O0FBR0Q7OztFQUdFLG9CQUFtQixFQUNwQjs7QUFURDtFQWFFLCtCQUFzQjtLQUF0Qiw0QkFBc0I7TUFBdEIsMkJBQXNCO1VBQXRCLHVCQUFzQixFQUN2Qjs7QUFHRDtFQUNFLFVBQVMsRUFDVjs7QUFHRDtFQUNFLGtCQUFpQjtFQUNqQix3QkFBdUIsRUFDeEI7O0FBR0Q7RUFDRSxzQ0FBcUMsRUFDdEM7O0FBR0Q7Ozs7RUFJRSx5Q0FBd0MsRUFDekM7O0FBVkQ7RUFjRSxlQUFjO0VBQ2Qsc0JBQXFCLEVBQ3RCOztBQUdEO0VBQ0UsZUFBYyxFQUNmOztBQUdEOztFQUVFLG1CQUFrQjtFQUNsQixlQUFjO0VBQ2QsZUFBYztFQUNkLHlCQUF3QixFQUN6Qjs7QUFHRDtFQUNFLGdCQUFlLEVBQ2hCOztBQUdEO0VBQ0UsWUFBVyxFQUNaOztBQUdEO0VBQ0UsbUJBQWtCLEVBQ25COztBQUdEO0VBQ0UsMEJBQXlCO0VBQ3pCLGtCQUFpQixFQUNsQjs7QUFHRDs7RUFFRSxvQkFBbUI7RUFDbkIsb0JBQW1CLEVBQ3BCOztBQUdEO0VBQ0UsVUFBUztFQUNULFdBQVU7RUFDVixVQUFTO0VBQ1Qsb0JBQW1CO0VBQ25CLHdCQUF1QjtFQUN2QixtQkFBa0IsRUFDbkI7O0FBR0Q7RUFDRSxVQUFTO0VBQ1QsV0FBVSxFQUNYOztBQ3RHRDtFQUNFLDhCQUE2QjtFQUM3QixtQkFBa0I7RUFDbEIscUJBQW9CO0VBQ3BCLG9CQUFtQjtFQUNuQixlQUFjO0VBQ2QscUJBQW9CO0VBQ3BCLG9CQUFt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Q08sZUFBYyxFQUNmO0lBMUNOO01BZ0RHLG9CQUFtQjtNQUNuQixrQkFBaUIsRUFXbEI7TUE1REY7UUFxREssZ0JBQWUsRUFDaEI7TUF0REo7UUEwREssY0FBYSxFQUNkLEVSOUhKOztBb0I4S0Q7TWpCOUtGO1FBT0ksV0FBVSxFQXdDYjtJQW9ESDtNQVFJLGVBQWM7TUFDZCxZQUFXLEVBWWQ7TWJncUJLO1FheHFCQSxhQUFZLEVBQ2I7SUFVTDtNQU1JLGtCQUFpQjtNQUNqQixhQUFZLEVBcUJmO01iNm9CSztRYTlwQkEsWUFBVyxFQUNaLEVBeEZGOztBaUJxSkM7STlCazNCQTtNZTdnQ0ksNkJBQW9CO2NBQXBCLHFCQUFvQixFQVl2Qjs7QWVnR0M7STlCbzZCRjtNZTNnQ0ksNkJBQW9CO2NBQXBCLHFCQUFvQixFQU92Qjs7QWVnR0M7STlCdTZCRjtNZXpnQ0ksNkJBQW9CO2NBQXBCLHFCQUFvQixFQUV2Qjs7QWVnR0M7RTlCKzlCSjtJZTU5Qk0sZUFBYyxFQU9qQjtJQW1OSDtNQVNJLGVBQWMsRUFpQ2pCO01BaUlEO1FBb0JJLGlCQUFnQjtRQUNoQixzQkFBcUIsRUFFeEIsRUFyWkUiLCJmaWxlIjoiYXNzZXRzL3N0eWxlc2hlZXRzL2FwcGxpY2F0aW9uLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIkBjaGFyc2V0IFwiVVRGLThcIjtcbmh0bWwge1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94OyB9XG5cbiosXG4qOjpiZWZvcmUsXG4qOjphZnRlciB7XG4gIGJveC1zaXppbmc6IGluaGVyaXQ7IH1cblxuaHRtbCB7XG4gIHRleHQtc2l6ZS1hZGp1c3Q6IG5vbmU7IH1cblxuYm9keSB7XG4gIG1hcmdpbjogMDsgfVxuXG5ociB7XG4gIG92ZXJmbG93OiB2aXNpYmxlO1xuICBib3gtc2l6aW5nOiBjb250ZW50LWJveDsgfVxuXG5hIHtcbiAgLXdlYmtpdC10ZXh0LWRlY29yYXRpb24tc2tpcDogb2JqZWN0czsgfVxuXG5hLFxuYnV0dG9uLFxubGFiZWwsXG5pbnB1dCB7XG4gIC13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjogdHJhbnNwYXJlbnQ7IH1cblxuYSB7XG4gIGNvbG9yOiBpbmhlcml0O1xuICB0ZXh0LWRlY29yYXRpb246IG5vbmU7IH1cblxuc21hbGwge1xuICBmb250LXNpemU6IDgwJTsgfVxuXG5zdWIsXG5zdXAge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGZvbnQtc2l6ZTogODAlO1xuICBsaW5lLWhlaWdodDogMDtcbiAgdmVydGljYWwtYWxpZ246IGJhc2VsaW5lOyB9XG5cbnN1YiB7XG4gIGJvdHRvbTogLTAuMjVlbTsgfVxuXG5zdXAge1xuICB0b3A6IC0wLjVlbTsgfVxuXG5pbWcge1xuICBib3JkZXItc3R5bGU6IG5vbmU7IH1cblxudGFibGUge1xuICBib3JkZXItY29sbGFwc2U6IHNlcGFyYXRlO1xuICBib3JkZXItc3BhY2luZzogMDsgfVxuXG50ZCxcbnRoIHtcbiAgZm9udC13ZWlnaHQ6IG5vcm1hbDtcbiAgdmVydGljYWwtYWxpZ246IHRvcDsgfVxuXG5idXR0b24ge1xuICBtYXJnaW46IDA7XG4gIHBhZGRpbmc6IDA7XG4gIGJvcmRlcjogMDtcbiAgb3V0bGluZS1zdHlsZTogbm9uZTtcbiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gIGZvbnQtc2l6ZTogaW5oZXJpdDsgfVxuXG5pbnB1dCB7XG4gIGJvcmRlcjogMDtcbiAgb3V0bGluZTogMDsgfVxuXG4ubWQtaWNvbiwgLm1kLWNsaXBib2FyZDo6YmVmb3JlLCAubWQtbmF2X190aXRsZTo6YmVmb3JlLCAubWQtbmF2X19idXR0b24sIC5tZC1uYXZfX2xpbms6OmFmdGVyLCAubWQtc2VhcmNoLXJlc3VsdF9fYXJ0aWNsZS0tZG9jdW1lbnQ6OmJlZm9yZSwgLm1kLXNvdXJjZS1maWxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscyA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCBkZXRhaWxzID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCAuZm9vdG5vdGUtYmFja3JlZiwgLm1kLXR5cGVzZXQgLmNyaXRpYy5jb21tZW50OjpiZWZvcmUsIC5tZC10eXBlc2V0IHN1bW1hcnk6OmFmdGVyLCAubWQtdHlwZXNldCAudGFzay1saXN0LWNvbnRyb2wgLnRhc2stbGlzdC1pbmRpY2F0b3I6OmJlZm9yZSB7XG4gIGZvbnQtZmFtaWx5OiBcIk1hdGVyaWFsIEljb25zXCI7XG4gIGZvbnQtc3R5bGU6IG5vcm1hbDtcbiAgZm9udC12YXJpYW50OiBub3JtYWw7XG4gIGZvbnQtd2VpZ2h0OiBub3JtYWw7XG4gIGxpbmUtaGVpZ2h0OiAxO1xuICB0ZXh0LXRyYW5zZm9ybTogbm9uZTtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgc3BlYWs6IG5vbmU7XG4gIHdvcmQtd3JhcDogbm9ybWFsO1xuICBkaXJlY3Rpb246IGx0cjsgfVxuICAubWQtY29udGVudF9faWNvbiwgLm1kLWhlYWRlci1uYXZfX2J1dHRvbiwgLm1kLWZvb3Rlci1uYXZfX2J1dHRvbiwgLm1kLW5hdl9fdGl0bGU6OmJlZm9yZSwgLm1kLW5hdl9fYnV0dG9uLCAubWQtc2VhcmNoLXJlc3VsdF9fYXJ0aWNsZS0tZG9jdW1lbnQ6OmJlZm9yZSB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIG1hcmdpbjogMC40cmVtO1xuICAgIHBhZGRpbmc6IDAuOHJlbTtcbiAgICBmb250LXNpemU6IDIuNHJlbTtcbiAgICBjdXJzb3I6IHBvaW50ZXI7IH1cblxuLm1kLWljb24tLWFycm93LWJhY2s6OmJlZm9yZSB7XG4gIGNvbnRlbnQ6IFwi7peEXCI7IH1cblxuLm1kLWljb24tLWFycm93LWZvcndhcmQ6OmJlZm9yZSB7XG4gIGNvbnRlbnQ6IFwi7peIXCI7IH1cblxuLm1kLWljb24tLW1lbnU6OmJlZm9yZSB7XG4gIGNvbnRlbnQ6IFwi7peSXCI7IH1cblxuLm1kLWljb24tLXNlYXJjaDo6YmVmb3JlIHtcbiAgY29udGVudDogXCLuorZcIjsgfVxuXG5bZGlyPVwicnRsXCJdIC5tZC1pY29uLS1hcnJvdy1iYWNrOjpiZWZvcmUge1xuICBjb250ZW50OiBcIu6XiFwiOyB9XG5cbltkaXI9XCJydGxcIl0gLm1kLWljb24tLWFycm93LWZvcndhcmQ6OmJlZm9yZSB7XG4gIGNvbnRlbnQ6IFwi7peEXCI7IH1cblxuYm9keSB7XG4gIC13ZWJraXQtZm9udC1zbW9vdGhpbmc6IGFudGlhbGlhc2VkO1xuICAtbW96LW9zeC1mb250LXNtb290aGluZzogZ3JheXNjYWxlOyB9XG5cbmJvZHksXG5pbnB1dCB7XG4gIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuODcpO1xuICBmb250LWZlYXR1cmUtc2V0dGluZ3M6IFwia2VyblwiLCBcImxpZ2FcIjtcbiAgZm9udC1mYW1pbHk6IFwiSGVsdmV0aWNhIE5ldWVcIiwgSGVsdmV0aWNhLCBBcmlhbCwgc2Fucy1zZXJpZjsgfVxuXG5wcmUsXG5jb2RlLFxua2JkIHtcbiAgY29sb3I6IHJnYmEoMCwgMCwgMCwgMC44Nyk7XG4gIGZvbnQtZmVhdHVyZS1zZXR0aW5nczogXCJrZXJuXCI7XG4gIGZvbnQtZmFtaWx5OiBcIkNvdXJpZXIgTmV3XCIsIENvdXJpZXIsIG1vbm9zcGFjZTsgfVxuXG4ubWQtdHlwZXNldCB7XG4gIGZvbnQtc2l6ZTogMS42cmVtO1xuICBsaW5lLWhlaWdodDogMS42O1xuICAtd2Via2l0LXByaW50LWNvbG9yLWFkanVzdDogZXhhY3Q7IH1cbiAgLm1kLXR5cGVzZXQgcCxcbiAgLm1kLXR5cGVzZXQgdWwsXG4gIC5tZC10eXBlc2V0IG9sLFxuICAubWQtdHlwZXNldCBibG9ja3F1b3RlIHtcbiAgICBtYXJnaW46IDFlbSAwOyB9XG4gIC5tZC10eXBlc2V0IGgxIHtcbiAgICBtYXJnaW46IDAgMCA0cmVtO1xuICAgIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuNTQpO1xuICAgIGZvbnQtc2l6ZTogMy4xMjVyZW07XG4gICAgZm9udC13ZWlnaHQ6IDMwMDtcbiAgICBsZXR0ZXItc3BhY2luZzogLTAuMDFlbTtcbiAgICBsaW5lLWhlaWdodDogMS4zOyB9XG4gIC5tZC10eXBlc2V0IGgyIHtcbiAgICBtYXJnaW46IDRyZW0gMCAxLjZyZW07XG4gICAgZm9udC1zaXplOiAyLjVyZW07XG4gICAgZm9udC13ZWlnaHQ6IDMwMDtcbiAgICBsZXR0ZXItc3BhY2luZzogLTAuMDFlbTtcbiAgICBsaW5lLWhlaWdodDogMS40OyB9XG4gIC5tZC10eXBlc2V0IGgzIHtcbiAgICBtYXJnaW46IDMuMnJlbSAwIDEuNnJlbTtcbiAgICBmb250LXNpemU6IDJyZW07XG4gICAgZm9udC13ZWlnaHQ6IDQwMDtcbiAgICBsZXR0ZXItc3BhY2luZzogLTAuMDFlbTtcbiAgICBsaW5lLWhlaWdodDogMS41OyB9XG4gIC5tZC10eXBlc2V0IGgyICsgaDMge1xuICAgIG1hcmdpbi10b3A6IDEuNnJlbTsgfVxuICAubWQtdHlwZXNldCBoNCB7XG4gICAgbWFyZ2luOiAxLjZyZW0gMDtcbiAgICBmb250LXNpemU6IDEuNnJlbTtcbiAgICBmb250LXdlaWdodDogNzAwO1xuICAgIGxldHRlci1zcGFjaW5nOiAtMC4wMWVtOyB9XG4gIC5tZC10eXBlc2V0IGg1LFxuICAubWQtdHlwZXNldCBoNiB7XG4gICAgbWFyZ2luOiAxLjZyZW0gMDtcbiAgICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjU0KTtcbiAgICBmb250LXNpemU6IDEuMjhyZW07XG4gICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICBsZXR0ZXItc3BhY2luZzogLTAuMDFlbTsgfVxuICAubWQtdHlwZXNldCBoNSB7XG4gICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTsgfVxuICAubWQtdHlwZXNldCBociB7XG4gICAgbWFyZ2luOiAxLjVlbSAwO1xuICAgIGJvcmRlci1ib3R0b206IDAuMXJlbSBkb3R0ZWQgcmdiYSgwLCAwLCAwLCAwLjI2KTsgfVxuICAubWQtdHlwZXNldCBhIHtcbiAgICBjb2xvcjogIzNmNTFiNTtcbiAgICB3b3JkLWJyZWFrOiBicmVhay13b3JkOyB9XG4gICAgLm1kLXR5cGVzZXQgYSwgLm1kLXR5cGVzZXQgYTo6YmVmb3JlIHtcbiAgICAgIHRyYW5zaXRpb246IGNvbG9yIDAuMTI1czsgfVxuICAgIC5tZC10eXBlc2V0IGE6aG92ZXIsIC5tZC10eXBlc2V0IGE6YWN0aXZlIHtcbiAgICAgIGNvbG9yOiAjNTM2ZGZlOyB9XG4gICAgQG1lZGlhIHByaW50IHtcbiAgICAgIC5tZC10eXBlc2V0IGE6OmFmdGVyIHtcbiAgICAgICAgY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41NCk7XG4gICAgICAgIGNvbnRlbnQ6IFwiIFtcIiBhdHRyKGhyZWYpIFwiXVwiOyB9IH1cbiAgLm1kLXR5cGVzZXQgY29kZSxcbiAgLm1kLXR5cGVzZXQgcHJlIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDIzNiwgMjM2LCAyMzYsIDAuNSk7XG4gICAgY29sb3I6ICMzNzQ3NEY7XG4gICAgZm9udC1zaXplOiA4NSU7XG4gICAgZGlyZWN0aW9uOiBsdHI7IH1cbiAgICBAbWVkaWEgcHJpbnQge1xuICAgICAgLm1kLXR5cGVzZXQgY29kZSxcbiAgICAgIC5tZC10eXBlc2V0IHByZSB7XG4gICAgICAgIHdoaXRlLXNwYWNlOiBwcmUtd3JhcDsgfSB9XG4gIC5tZC10eXBlc2V0IGNvZGUge1xuICAgIG1hcmdpbjogMCAwLjI5NDEyZW07XG4gICAgcGFkZGluZzogMC4wNzM1M2VtIDA7XG4gICAgYm9yZGVyLXJhZGl1czogMC4ycmVtO1xuICAgIGJveC1zaGFkb3c6IDAuMjk0MTJlbSAwIDAgcmdiYSgyMzYsIDIzNiwgMjM2LCAwLjUpLCAtMC4yOTQxMmVtIDAgMCByZ2JhKDIzNiwgMjM2LCAyMzYsIDAuNSk7XG4gICAgd29yZC1icmVhazogYnJlYWstd29yZDtcbiAgICBib3gtZGVjb3JhdGlvbi1icmVhazogY2xvbmU7IH1cbiAgICBAbWVkaWEgcHJpbnQge1xuICAgICAgLm1kLXR5cGVzZXQgY29kZSB7XG4gICAgICAgIGJveC1zaGFkb3c6IG5vbmU7XG4gICAgICAgIGJveC1kZWNvcmF0aW9uLWJyZWFrOiBpbml0aWFsOyB9IH1cbiAgLm1kLXR5cGVzZXQgaDEgY29kZSxcbiAgLm1kLXR5cGVzZXQgaDIgY29kZSxcbiAgLm1kLXR5cGVzZXQgaDMgY29kZSxcbiAgLm1kLXR5cGVzZXQgaDQgY29kZSxcbiAgLm1kLXR5cGVzZXQgaDUgY29kZSxcbiAgLm1kLXR5cGVzZXQgaDYgY29kZSB7XG4gICAgbWFyZ2luOiAwO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuICAgIGJveC1zaGFkb3c6IG5vbmU7IH1cbiAgLm1kLXR5cGVzZXQgYSA+IGNvZGUge1xuICAgIG1hcmdpbjogaW5oZXJpdDtcbiAgICBwYWRkaW5nOiBpbmhlcml0O1xuICAgIGJvcmRlci1yYWRpdXM6IG5vbmU7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogaW5oZXJpdDtcbiAgICBjb2xvcjogaW5oZXJpdDtcbiAgICBib3gtc2hhZG93OiBub25lOyB9XG4gIC5tZC10eXBlc2V0IHByZSB7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIG1hcmdpbjogMWVtIDA7XG4gICAgYm9yZGVyLXJhZGl1czogMC4ycmVtO1xuICAgIGxpbmUtaGVpZ2h0OiAxLjQ7XG4gICAgLXdlYmtpdC1vdmVyZmxvdy1zY3JvbGxpbmc6IHRvdWNoOyB9XG4gICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA0NC45Mzc1ZW0pIHtcbiAgICAgIC5tZC10eXBlc2V0IHByZSB7XG4gICAgICAgIG1hcmdpbjogMWVtIC0xLjZyZW07XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDA7IH0gfVxuICAgIC5tZC10eXBlc2V0IHByZSA+IGNvZGUge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICBtYXJnaW46IDA7XG4gICAgICBwYWRkaW5nOiAxLjA1cmVtIDEuMnJlbTtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuICAgICAgZm9udC1zaXplOiBpbmhlcml0O1xuICAgICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICAgIGJveC1kZWNvcmF0aW9uLWJyZWFrOiBub25lO1xuICAgICAgb3ZlcmZsb3c6IGF1dG87IH1cbiAgICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1heC13aWR0aDogNDQuOTM3NWVtKSB7XG4gICAgICAgIC5tZC10eXBlc2V0IHByZSA+IGNvZGUge1xuICAgICAgICAgIHBhZGRpbmc6IDEuMDVyZW0gMS42cmVtOyB9IH1cbiAgICAgIC5tZC10eXBlc2V0IHByZSA+IGNvZGU6Oi13ZWJraXQtc2Nyb2xsYmFyIHtcbiAgICAgICAgd2lkdGg6IDAuNHJlbTtcbiAgICAgICAgaGVpZ2h0OiAwLjRyZW07IH1cbiAgICAgIC5tZC10eXBlc2V0IHByZSA+IGNvZGU6Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1iIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjI2KTsgfVxuICAgICAgICAubWQtdHlwZXNldCBwcmUgPiBjb2RlOjotd2Via2l0LXNjcm9sbGJhci10aHVtYjpob3ZlciB7XG4gICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogIzUzNmRmZTsgfVxuICAubWQtdHlwZXNldCBrYmQge1xuICAgIHBhZGRpbmc6IDAgMC4yOTQxMmVtO1xuICAgIGJvcmRlcjogMC4xcmVtIHNvbGlkICNjOWM5Yzk7XG4gICAgYm9yZGVyLXJhZGl1czogMC4zcmVtO1xuICAgIGJvcmRlci1ib3R0b20tY29sb3I6ICNiY2JjYmM7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI0ZDRkNGQztcbiAgICBjb2xvcjogIzU1NTU1NTtcbiAgICBmb250LXNpemU6IDg1JTtcbiAgICBib3gtc2hhZG93OiAwIDAuMXJlbSAwICNiMGIwYjA7XG4gICAgd29yZC1icmVhazogYnJlYWstd29yZDsgfVxuICAubWQtdHlwZXNldCBtYXJrIHtcbiAgICBtYXJnaW46IDAgMC4yNWVtO1xuICAgIHBhZGRpbmc6IDAuMDYyNWVtIDA7XG4gICAgYm9yZGVyLXJhZGl1czogMC4ycmVtO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjU1LCAyMzUsIDU5LCAwLjUpO1xuICAgIGJveC1zaGFkb3c6IDAuMjVlbSAwIDAgcmdiYSgyNTUsIDIzNSwgNTksIDAuNSksIC0wLjI1ZW0gMCAwIHJnYmEoMjU1LCAyMzUsIDU5LCAwLjUpO1xuICAgIHdvcmQtYnJlYWs6IGJyZWFrLXdvcmQ7XG4gICAgYm94LWRlY29yYXRpb24tYnJlYWs6IGNsb25lOyB9XG4gIC5tZC10eXBlc2V0IGFiYnIge1xuICAgIGJvcmRlci1ib3R0b206IDAuMXJlbSBkb3R0ZWQgcmdiYSgwLCAwLCAwLCAwLjU0KTtcbiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XG4gICAgY3Vyc29yOiBoZWxwOyB9XG4gIC5tZC10eXBlc2V0IHNtYWxsIHtcbiAgICBvcGFjaXR5OiAwLjc1OyB9XG4gIC5tZC10eXBlc2V0IHN1cCxcbiAgLm1kLXR5cGVzZXQgc3ViIHtcbiAgICBtYXJnaW4tbGVmdDogMC4wNzgxMmVtOyB9XG4gICAgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCBzdXAsIFtkaXI9XCJydGxcIl1cbiAgICAubWQtdHlwZXNldCBzdWIge1xuICAgICAgbWFyZ2luLXJpZ2h0OiAwLjA3ODEyZW07XG4gICAgICBtYXJnaW4tbGVmdDogaW5pdGlhbDsgfVxuICAubWQtdHlwZXNldCBibG9ja3F1b3RlIHtcbiAgICBwYWRkaW5nLWxlZnQ6IDEuMnJlbTtcbiAgICBib3JkZXItbGVmdDogMC40cmVtIHNvbGlkIHJnYmEoMCwgMCwgMCwgMC4yNik7XG4gICAgY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41NCk7IH1cbiAgICBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IGJsb2NrcXVvdGUge1xuICAgICAgcGFkZGluZy1yaWdodDogMS4ycmVtO1xuICAgICAgcGFkZGluZy1sZWZ0OiBpbml0aWFsO1xuICAgICAgYm9yZGVyLXJpZ2h0OiAwLjRyZW0gc29saWQgcmdiYSgwLCAwLCAwLCAwLjI2KTtcbiAgICAgIGJvcmRlci1sZWZ0OiBpbml0aWFsOyB9XG4gIC5tZC10eXBlc2V0IHVsIHtcbiAgICBsaXN0LXN0eWxlLXR5cGU6IGRpc2M7IH1cbiAgLm1kLXR5cGVzZXQgdWwsXG4gIC5tZC10eXBlc2V0IG9sIHtcbiAgICBtYXJnaW4tbGVmdDogMC42MjVlbTtcbiAgICBwYWRkaW5nOiAwOyB9XG4gICAgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCB1bCwgW2Rpcj1cInJ0bFwiXVxuICAgIC5tZC10eXBlc2V0IG9sIHtcbiAgICAgIG1hcmdpbi1yaWdodDogMC42MjVlbTtcbiAgICAgIG1hcmdpbi1sZWZ0OiBpbml0aWFsOyB9XG4gICAgLm1kLXR5cGVzZXQgdWwgb2wsXG4gICAgLm1kLXR5cGVzZXQgb2wgb2wge1xuICAgICAgbGlzdC1zdHlsZS10eXBlOiBsb3dlci1hbHBoYTsgfVxuICAgICAgLm1kLXR5cGVzZXQgdWwgb2wgb2wsXG4gICAgICAubWQtdHlwZXNldCBvbCBvbCBvbCB7XG4gICAgICAgIGxpc3Qtc3R5bGUtdHlwZTogbG93ZXItcm9tYW47IH1cbiAgICAubWQtdHlwZXNldCB1bCBsaSxcbiAgICAubWQtdHlwZXNldCBvbCBsaSB7XG4gICAgICBtYXJnaW4tYm90dG9tOiAwLjVlbTtcbiAgICAgIG1hcmdpbi1sZWZ0OiAxLjI1ZW07IH1cbiAgICAgIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgdWwgbGksIFtkaXI9XCJydGxcIl1cbiAgICAgIC5tZC10eXBlc2V0IG9sIGxpIHtcbiAgICAgICAgbWFyZ2luLXJpZ2h0OiAxLjI1ZW07XG4gICAgICAgIG1hcmdpbi1sZWZ0OiBpbml0aWFsOyB9XG4gICAgICAubWQtdHlwZXNldCB1bCBsaSBwLFxuICAgICAgLm1kLXR5cGVzZXQgdWwgbGkgYmxvY2txdW90ZSxcbiAgICAgIC5tZC10eXBlc2V0IG9sIGxpIHAsXG4gICAgICAubWQtdHlwZXNldCBvbCBsaSBibG9ja3F1b3RlIHtcbiAgICAgICAgbWFyZ2luOiAwLjVlbSAwOyB9XG4gICAgICAubWQtdHlwZXNldCB1bCBsaTpsYXN0LWNoaWxkLFxuICAgICAgLm1kLXR5cGVzZXQgb2wgbGk6bGFzdC1jaGlsZCB7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IDA7IH1cbiAgICAgIC5tZC10eXBlc2V0IHVsIGxpIHVsLFxuICAgICAgLm1kLXR5cGVzZXQgdWwgbGkgb2wsXG4gICAgICAubWQtdHlwZXNldCBvbCBsaSB1bCxcbiAgICAgIC5tZC10eXBlc2V0IG9sIGxpIG9sIHtcbiAgICAgICAgbWFyZ2luOiAwLjVlbSAwIDAuNWVtIDAuNjI1ZW07IH1cbiAgICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCB1bCBsaSB1bCwgW2Rpcj1cInJ0bFwiXVxuICAgICAgICAubWQtdHlwZXNldCB1bCBsaSBvbCwgW2Rpcj1cInJ0bFwiXVxuICAgICAgICAubWQtdHlwZXNldCBvbCBsaSB1bCwgW2Rpcj1cInJ0bFwiXVxuICAgICAgICAubWQtdHlwZXNldCBvbCBsaSBvbCB7XG4gICAgICAgICAgbWFyZ2luLXJpZ2h0OiAwLjYyNWVtO1xuICAgICAgICAgIG1hcmdpbi1sZWZ0OiBpbml0aWFsOyB9XG4gIC5tZC10eXBlc2V0IGRkIHtcbiAgICBtYXJnaW46IDFlbSAwIDFlbSAxLjg3NWVtOyB9XG4gICAgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCBkZCB7XG4gICAgICBtYXJnaW4tcmlnaHQ6IDEuODc1ZW07XG4gICAgICBtYXJnaW4tbGVmdDogaW5pdGlhbDsgfVxuICAubWQtdHlwZXNldCBpZnJhbWUsXG4gIC5tZC10eXBlc2V0IGltZyxcbiAgLm1kLXR5cGVzZXQgc3ZnIHtcbiAgICBtYXgtd2lkdGg6IDEwMCU7IH1cbiAgLm1kLXR5cGVzZXQgdGFibGU6bm90KFtjbGFzc10pIHtcbiAgICBib3gtc2hhZG93OiAwIDJweCAycHggMCByZ2JhKDAsIDAsIDAsIDAuMTQpLCAwIDFweCA1cHggMCByZ2JhKDAsIDAsIDAsIDAuMTIpLCAwIDNweCAxcHggLTJweCByZ2JhKDAsIDAsIDAsIDAuMik7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIG1heC13aWR0aDogMTAwJTtcbiAgICBib3JkZXItcmFkaXVzOiAwLjJyZW07XG4gICAgZm9udC1zaXplOiAxLjI4cmVtO1xuICAgIG92ZXJmbG93OiBhdXRvO1xuICAgIC13ZWJraXQtb3ZlcmZsb3ctc2Nyb2xsaW5nOiB0b3VjaDsgfVxuICAgIC5tZC10eXBlc2V0IHRhYmxlOm5vdChbY2xhc3NdKSArICoge1xuICAgICAgbWFyZ2luLXRvcDogMS41ZW07IH1cbiAgICAubWQtdHlwZXNldCB0YWJsZTpub3QoW2NsYXNzXSkgdGg6bm90KFthbGlnbl0pLFxuICAgIC5tZC10eXBlc2V0IHRhYmxlOm5vdChbY2xhc3NdKSB0ZDpub3QoW2FsaWduXSkge1xuICAgICAgdGV4dC1hbGlnbjogbGVmdDsgfVxuICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCB0YWJsZTpub3QoW2NsYXNzXSkgdGg6bm90KFthbGlnbl0pLCBbZGlyPVwicnRsXCJdXG4gICAgICAubWQtdHlwZXNldCB0YWJsZTpub3QoW2NsYXNzXSkgdGQ6bm90KFthbGlnbl0pIHtcbiAgICAgICAgdGV4dC1hbGlnbjogcmlnaHQ7IH1cbiAgICAubWQtdHlwZXNldCB0YWJsZTpub3QoW2NsYXNzXSkgdGgge1xuICAgICAgbWluLXdpZHRoOiAxMHJlbTtcbiAgICAgIHBhZGRpbmc6IDEuMnJlbSAxLjZyZW07XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuNTQpO1xuICAgICAgY29sb3I6IHdoaXRlO1xuICAgICAgdmVydGljYWwtYWxpZ246IHRvcDsgfVxuICAgIC5tZC10eXBlc2V0IHRhYmxlOm5vdChbY2xhc3NdKSB0ZCB7XG4gICAgICBwYWRkaW5nOiAxLjJyZW0gMS42cmVtO1xuICAgICAgYm9yZGVyLXRvcDogMC4xcmVtIHNvbGlkIHJnYmEoMCwgMCwgMCwgMC4wNyk7XG4gICAgICB2ZXJ0aWNhbC1hbGlnbjogdG9wOyB9XG4gICAgLm1kLXR5cGVzZXQgdGFibGU6bm90KFtjbGFzc10pIHRyOmZpcnN0LWNoaWxkIHRkIHtcbiAgICAgIGJvcmRlci10b3A6IDA7IH1cbiAgICAubWQtdHlwZXNldCB0YWJsZTpub3QoW2NsYXNzXSkgYSB7XG4gICAgICB3b3JkLWJyZWFrOiBub3JtYWw7IH1cbiAgLm1kLXR5cGVzZXRfX3Njcm9sbHdyYXAge1xuICAgIG1hcmdpbjogMWVtIC0xLjZyZW07XG4gICAgb3ZlcmZsb3cteDogYXV0bztcbiAgICAtd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzogdG91Y2g7IH1cbiAgLm1kLXR5cGVzZXQgLm1kLXR5cGVzZXRfX3RhYmxlIHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgbWFyZ2luLWJvdHRvbTogMC41ZW07XG4gICAgcGFkZGluZzogMCAxLjZyZW07IH1cbiAgICAubWQtdHlwZXNldCAubWQtdHlwZXNldF9fdGFibGUgdGFibGUge1xuICAgICAgZGlzcGxheTogdGFibGU7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIG1hcmdpbjogMDtcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47IH1cblxuaHRtbCB7XG4gIGhlaWdodDogMTAwJTtcbiAgZm9udC1zaXplOiA2Mi41JTtcbiAgb3ZlcmZsb3cteDogaGlkZGVuOyB9XG4gIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogMTAwZW0pIHtcbiAgICBodG1sIHtcbiAgICAgIGZvbnQtc2l6ZTogNjguNzUlOyB9IH1cbiAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAxMjVlbSkge1xuICAgIGh0bWwge1xuICAgICAgZm9udC1zaXplOiA3NSU7IH0gfVxuXG5ib2R5IHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBoZWlnaHQ6IDEwMCU7IH1cbiAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA1OS45Mzc1ZW0pIHtcbiAgICBib2R5W2RhdGEtbWQtc3RhdGU9XCJsb2NrXCJdIHtcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47IH1cbiAgICAgIC5pb3MgYm9keVtkYXRhLW1kLXN0YXRlPVwibG9ja1wiXSAubWQtY29udGFpbmVyIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTsgfSB9XG5cbmhyIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIGhlaWdodDogMC4xcmVtO1xuICBwYWRkaW5nOiAwO1xuICBib3JkZXI6IDA7IH1cblxuLm1kLXN2ZyB7XG4gIGRpc3BsYXk6IG5vbmU7IH1cblxuLm1kLWdyaWQge1xuICBtYXgtd2lkdGg6IDEyMnJlbTtcbiAgbWFyZ2luLXJpZ2h0OiBhdXRvO1xuICBtYXJnaW4tbGVmdDogYXV0bzsgfVxuXG4ubWQtY29udGFpbmVyLFxuLm1kLW1haW4ge1xuICBvdmVyZmxvdzogYXV0bzsgfVxuXG4ubWQtY29udGFpbmVyIHtcbiAgZGlzcGxheTogdGFibGU7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG4gIHBhZGRpbmctdG9wOiA0LjhyZW07XG4gIHRhYmxlLWxheW91dDogZml4ZWQ7IH1cblxuLm1kLW1haW4ge1xuICBkaXNwbGF5OiB0YWJsZS1yb3c7XG4gIGhlaWdodDogMTAwJTsgfVxuICAubWQtbWFpbl9faW5uZXIge1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBwYWRkaW5nLXRvcDogM3JlbTtcbiAgICBwYWRkaW5nLWJvdHRvbTogMC4xcmVtOyB9XG5cbi5tZC10b2dnbGUge1xuICBkaXNwbGF5OiBub25lOyB9XG5cbi5tZC1vdmVybGF5IHtcbiAgcG9zaXRpb246IGZpeGVkO1xuICB0b3A6IDA7XG4gIHdpZHRoOiAwO1xuICBoZWlnaHQ6IDA7XG4gIHRyYW5zaXRpb246IHdpZHRoICAgMHMgMC4yNXMsIGhlaWdodCAgMHMgMC4yNXMsIG9wYWNpdHkgMC4yNXM7XG4gIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41NCk7XG4gIG9wYWNpdHk6IDA7XG4gIHotaW5kZXg6IDM7IH1cbiAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA3Ni4xODc1ZW0pIHtcbiAgICBbZGF0YS1tZC10b2dnbGU9XCJkcmF3ZXJcIl06Y2hlY2tlZCB+IC5tZC1vdmVybGF5IHtcbiAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgdHJhbnNpdGlvbjogd2lkdGggICAwcywgaGVpZ2h0ICAwcywgb3BhY2l0eSAwLjI1cztcbiAgICAgIG9wYWNpdHk6IDE7IH0gfVxuXG4ubWQtZmxleCB7XG4gIGRpc3BsYXk6IHRhYmxlOyB9XG4gIC5tZC1mbGV4X19jZWxsIHtcbiAgICBkaXNwbGF5OiB0YWJsZS1jZWxsO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICB2ZXJ0aWNhbC1hbGlnbjogdG9wOyB9XG4gICAgLm1kLWZsZXhfX2NlbGwtLXNocmluayB7XG4gICAgICB3aWR0aDogMCU7IH1cbiAgICAubWQtZmxleF9fY2VsbC0tc3RyZXRjaCB7XG4gICAgICBkaXNwbGF5OiB0YWJsZTtcbiAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgdGFibGUtbGF5b3V0OiBmaXhlZDsgfVxuICAubWQtZmxleF9fZWxsaXBzaXMge1xuICAgIGRpc3BsYXk6IHRhYmxlLWNlbGw7XG4gICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICBvdmVyZmxvdzogaGlkZGVuOyB9XG5cbi5tZC1za2lwIHtcbiAgcG9zaXRpb246IGZpeGVkO1xuICB3aWR0aDogMC4xcmVtO1xuICBoZWlnaHQ6IDAuMXJlbTtcbiAgbWFyZ2luOiAxcmVtO1xuICBwYWRkaW5nOiAwLjZyZW0gMXJlbTtcbiAgY2xpcDogcmVjdCgwLjFyZW0pO1xuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoMC44cmVtKTtcbiAgYm9yZGVyLXJhZGl1czogMC4ycmVtO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuODcpO1xuICBjb2xvcjogd2hpdGU7XG4gIGZvbnQtc2l6ZTogMS4yOHJlbTtcbiAgb3BhY2l0eTogMDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjsgfVxuICAubWQtc2tpcDpmb2N1cyB7XG4gICAgd2lkdGg6IGF1dG87XG4gICAgaGVpZ2h0OiBhdXRvO1xuICAgIGNsaXA6IGF1dG87XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDApO1xuICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjI1cyBjdWJpYy1iZXppZXIoMC40LCAwLCAwLjIsIDEpLCBvcGFjaXR5IDAuMTc1cyAwLjA3NXM7XG4gICAgb3BhY2l0eTogMTtcbiAgICB6LWluZGV4OiAxMDsgfVxuXG5AcGFnZSB7XG4gIG1hcmdpbjogMjVtbTsgfVxuXG51bCwgdWwgbGkge1xuICBtYXJnaW46IDA7XG4gIHBhZGRpbmc6IDA7XG4gIGxpc3Qtc3R5bGU6IG5vbmU7IH1cblxuLmFib3V0IHtcbiAgbWFyZ2luLXRvcDogNTBweDsgfVxuXG4uYWJvdXQtbGlzdCB7XG4gIG92ZXJmbG93OiBoaWRkZW47IH1cblxuLmFib3V0LWxpc3QgbGkge1xuICBmbG9hdDogbGVmdDtcbiAgbWFyZ2luOiAxcHg7XG4gIHdpZHRoOiAxNjhweDtcbiAgaGVpZ2h0OiAyODBweDtcbiAgcGFkZGluZzogMjBweCAxNXB4O1xuICBib3JkZXI6IDFweCBzb2xpZCAjZjBmMGYwO1xuICBib3JkZXItcmFkaXVzOiAzcHg7XG4gIGJveC1zaGFkb3c6IC0xcHggMHB4IDEwcHggI2U0ZTRlNDtcbiAgLXdlYmtpdC1ib3gtc2hhZG93OiAtMXB4IDBweCAxMHB4ICNlNGU0ZTQ7XG4gIHRyYW5zaXRpb246IGFsbCAuM3M7XG4gIC13ZWJraXQtdHJhbnNpdGlvbjogYWxsIC4zczsgfVxuXG4uYWJvdXQtbGlzdCBsaTpob3ZlciB7XG4gIGJveC1zaGFkb3c6IC0xcHggMHB4IDE1cHggI2RiZGJkYjtcbiAgLXdlYmtpdC1ib3gtc2hhZG93OiAtMXB4IDBweCAxNXB4ICNkYmRiZGI7IH1cblxuLmFib3V0LWxpc3QgLnBpY3R1cmUge1xuICBkaXNwbGF5OiBibG9jaztcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgbWFyZ2luOiBhdXRvO1xuICB3aWR0aDogMTY4cHg7XG4gIGhlaWdodDogMTY4cHg7XG4gIGJvcmRlci1yYWRpdXM6IDNweDsgfVxuXG4uYWJvdXQtbGlzdCAuZGVzYyB7XG4gIG1hcmdpbjogMDsgfVxuXG4uYWJvdXQtbGlzdCAuZGVzYyBkdCB7XG4gIG1hcmdpbjogMTBweCAwIDVweDtcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7IH1cblxuLmFib3V0LWxpc3QgLmRlc2MgZGQge1xuICBkaXNwbGF5OiAtd2Via2l0LWJveDtcbiAgbWFyZ2luOiAwO1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICBmb250LXNpemU6IC44ZW07XG4gIGxpbmUtaGVpZ2h0OiAxLjRlbTtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIC13ZWJraXQtbGluZS1jbGFtcDogMztcbiAgLXdlYmtpdC1ib3gtb3JpZW50OiB2ZXJ0aWNhbDtcbiAgY29sb3I6ICM4ODg7XG4gIHdpZHRoOiAxMDAlOyB9XG5cbi5tZC1jbGlwYm9hcmQge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMC42cmVtO1xuICByaWdodDogMC42cmVtO1xuICB3aWR0aDogMi44cmVtO1xuICBoZWlnaHQ6IDIuOHJlbTtcbiAgYm9yZGVyLXJhZGl1czogMC4ycmVtO1xuICBmb250LXNpemU6IDEuNnJlbTtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICB6LWluZGV4OiAxO1xuICBiYWNrZmFjZS12aXNpYmlsaXR5OiBoaWRkZW47IH1cbiAgQG1lZGlhIHByaW50IHtcbiAgICAubWQtY2xpcGJvYXJkIHtcbiAgICAgIGRpc3BsYXk6IG5vbmU7IH0gfVxuICAubWQtY2xpcGJvYXJkOjpiZWZvcmUge1xuICAgIHRyYW5zaXRpb246IGNvbG9yICAgMC4yNXMsIG9wYWNpdHkgMC4yNXM7XG4gICAgY29sb3I6IHJnYmEoMCwgMCwgMCwgMC4wNyk7XG4gICAgY29udGVudDogXCJcXEUxNERcIjsgfVxuICAgIHByZTpob3ZlciAubWQtY2xpcGJvYXJkOjpiZWZvcmUsXG4gICAgLmNvZGVoaWxpdGU6aG92ZXIgLm1kLWNsaXBib2FyZDo6YmVmb3JlLFxuICAgIC5tZC10eXBlc2V0IC5oaWdobGlnaHQ6aG92ZXIgLm1kLWNsaXBib2FyZDo6YmVmb3JlIHtcbiAgICAgIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuNTQpOyB9XG4gIC5tZC1jbGlwYm9hcmQ6Zm9jdXM6OmJlZm9yZSwgLm1kLWNsaXBib2FyZDpob3Zlcjo6YmVmb3JlIHtcbiAgICBjb2xvcjogIzUzNmRmZTsgfVxuICAubWQtY2xpcGJvYXJkX19tZXNzYWdlIHtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiAwO1xuICAgIHJpZ2h0OiAzLjRyZW07XG4gICAgcGFkZGluZzogMC42cmVtIDFyZW07XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDAuOHJlbSk7XG4gICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuMjVzIGN1YmljLWJlemllcigwLjksIDAuMSwgMC45LCAwKSwgb3BhY2l0eSAwLjE3NXM7XG4gICAgYm9yZGVyLXJhZGl1czogMC4ycmVtO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41NCk7XG4gICAgY29sb3I6IHdoaXRlO1xuICAgIGZvbnQtc2l6ZTogMS4yOHJlbTtcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgIG9wYWNpdHk6IDA7XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7IH1cbiAgICAubWQtY2xpcGJvYXJkX19tZXNzYWdlLS1hY3RpdmUge1xuICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDApO1xuICAgICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuMjVzIGN1YmljLWJlemllcigwLjQsIDAsIDAuMiwgMSksIG9wYWNpdHkgMC4xNzVzIDAuMDc1cztcbiAgICAgIG9wYWNpdHk6IDE7XG4gICAgICBwb2ludGVyLWV2ZW50czogaW5pdGlhbDsgfVxuICAgIC5tZC1jbGlwYm9hcmRfX21lc3NhZ2U6OmJlZm9yZSB7XG4gICAgICBjb250ZW50OiBhdHRyKGFyaWEtbGFiZWwpOyB9XG4gICAgLm1kLWNsaXBib2FyZF9fbWVzc2FnZTo6YWZ0ZXIge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICB0b3A6IDUwJTtcbiAgICAgIHJpZ2h0OiAtMC40cmVtO1xuICAgICAgd2lkdGg6IDA7XG4gICAgICBtYXJnaW4tdG9wOiAtMC40cmVtO1xuICAgICAgYm9yZGVyLXdpZHRoOiAwLjRyZW0gMCAwLjRyZW0gMC40cmVtO1xuICAgICAgYm9yZGVyLXN0eWxlOiBzb2xpZDtcbiAgICAgIGJvcmRlci1jb2xvcjogdHJhbnNwYXJlbnQgcmdiYSgwLCAwLCAwLCAwLjU0KTtcbiAgICAgIGNvbnRlbnQ6IFwiXCI7IH1cblxuQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA2MGVtKSB7XG4gIC5tZC1jb250ZW50IHtcbiAgICBtYXJnaW4tcmlnaHQ6IDI0LjJyZW07IH1cbiAgICBbZGlyPVwicnRsXCJdIC5tZC1jb250ZW50IHtcbiAgICAgIG1hcmdpbi1yaWdodDogaW5pdGlhbDtcbiAgICAgIG1hcmdpbi1sZWZ0OiAyNC4ycmVtOyB9IH1cblxuQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA3Ni4yNWVtKSB7XG4gIC5tZC1jb250ZW50IHtcbiAgICBtYXJnaW4tbGVmdDogMjQuMnJlbTsgfVxuICAgIFtkaXI9XCJydGxcIl0gLm1kLWNvbnRlbnQge1xuICAgICAgbWFyZ2luLXJpZ2h0OiAyNC4ycmVtOyB9IH1cblxuLm1kLWNvbnRlbnRfX2lubmVyIHtcbiAgbWFyZ2luOiAwIDEuNnJlbSAyLjRyZW07XG4gIHBhZGRpbmctdG9wOiAxLjJyZW07IH1cbiAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA3Ni4yNWVtKSB7XG4gICAgLm1kLWNvbnRlbnRfX2lubmVyIHtcbiAgICAgIG1hcmdpbi1yaWdodDogMi40cmVtO1xuICAgICAgbWFyZ2luLWxlZnQ6IDIuNHJlbTsgfSB9XG4gIC5tZC1jb250ZW50X19pbm5lcjo6YmVmb3JlIHtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBoZWlnaHQ6IDAuOHJlbTtcbiAgICBjb250ZW50OiBcIlwiOyB9XG4gIC5tZC1jb250ZW50X19pbm5lciA+IDpsYXN0LWNoaWxkIHtcbiAgICBtYXJnaW4tYm90dG9tOiAwOyB9XG5cbi5tZC1jb250ZW50X19pY29uIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBtYXJnaW46IDAuOHJlbSAwO1xuICBwYWRkaW5nOiAwO1xuICBmbG9hdDogcmlnaHQ7IH1cbiAgLm1kLXR5cGVzZXQgLm1kLWNvbnRlbnRfX2ljb24ge1xuICAgIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuMjYpOyB9XG4gIEBtZWRpYSBwcmludCB7XG4gICAgLm1kLWNvbnRlbnRfX2ljb24ge1xuICAgICAgZGlzcGxheTogbm9uZTsgfSB9XG5cbi5tZC1oZWFkZXIge1xuICBwb3NpdGlvbjogZml4ZWQ7XG4gIHRvcDogMDtcbiAgcmlnaHQ6IDA7XG4gIGxlZnQ6IDA7XG4gIGhlaWdodDogNC44cmVtO1xuICB0cmFuc2l0aW9uOiBiYWNrZ3JvdW5kLWNvbG9yIDAuMjVzLCBjb2xvciAwLjI1cztcbiAgYmFja2dyb3VuZC1jb2xvcjogIzNmNTFiNTtcbiAgY29sb3I6IHdoaXRlO1xuICBib3gtc2hhZG93OiBub25lO1xuICB6LWluZGV4OiAyO1xuICBiYWNrZmFjZS12aXNpYmlsaXR5OiBoaWRkZW47IH1cbiAgLm5vLWpzIC5tZC1oZWFkZXIge1xuICAgIHRyYW5zaXRpb246IG5vbmU7XG4gICAgYm94LXNoYWRvdzogbm9uZTsgfVxuICAubWQtaGVhZGVyW2RhdGEtbWQtc3RhdGU9XCJzaGFkb3dcIl0ge1xuICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQtY29sb3IgMC4yNXMsIGNvbG9yIDAuMjVzLCBib3gtc2hhZG93IDAuMjVzO1xuICAgIGJveC1zaGFkb3c6IDAgMCAwLjRyZW0gcmdiYSgwLCAwLCAwLCAwLjEpLCAwIDAuNHJlbSAwLjhyZW0gcmdiYSgwLCAwLCAwLCAwLjIpOyB9XG4gIEBtZWRpYSBwcmludCB7XG4gICAgLm1kLWhlYWRlciB7XG4gICAgICBkaXNwbGF5OiBub25lOyB9IH1cblxuLm1kLWhlYWRlci1uYXYge1xuICBwYWRkaW5nOiAwIDAuNHJlbTsgfVxuICAubWQtaGVhZGVyLW5hdl9fYnV0dG9uIHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgdHJhbnNpdGlvbjogb3BhY2l0eSAwLjI1cztcbiAgICB6LWluZGV4OiAxOyB9XG4gICAgLm1kLWhlYWRlci1uYXZfX2J1dHRvbjpob3ZlciB7XG4gICAgICBvcGFjaXR5OiAwLjc7IH1cbiAgICAubWQtaGVhZGVyLW5hdl9fYnV0dG9uLm1kLWxvZ28gKiB7XG4gICAgICBkaXNwbGF5OiBibG9jazsgfVxuICAgIC5uby1qcyAubWQtaGVhZGVyLW5hdl9fYnV0dG9uLm1kLWljb24tLXNlYXJjaCB7XG4gICAgICBkaXNwbGF5OiBub25lOyB9XG4gICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA2MGVtKSB7XG4gICAgICAubWQtaGVhZGVyLW5hdl9fYnV0dG9uLm1kLWljb24tLXNlYXJjaCB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7IH0gfVxuICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1heC13aWR0aDogNzYuMTg3NWVtKSB7XG4gICAgICAubWQtaGVhZGVyLW5hdl9fYnV0dG9uLm1kLWljb24tLWhvbWUsIC5tZC1oZWFkZXItbmF2X19idXR0b24ubWQtbG9nbyB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7IH0gfVxuICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNzYuMjVlbSkge1xuICAgICAgLm1kLWhlYWRlci1uYXZfX2J1dHRvbi5tZC1pY29uLS1tZW51IHtcbiAgICAgICAgZGlzcGxheTogbm9uZTsgfSB9XG4gIC5tZC1oZWFkZXItbmF2X190b3BpYyB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjRzIGN1YmljLWJlemllcigwLjEsIDAuNywgMC4xLCAxKSwgb3BhY2l0eSAwLjE1cztcbiAgICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgIG92ZXJmbG93OiBoaWRkZW47IH1cbiAgICAubWQtaGVhZGVyLW5hdl9fdG9waWMgKyAubWQtaGVhZGVyLW5hdl9fdG9waWMge1xuICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDIuNXJlbSk7XG4gICAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC40cyBjdWJpYy1iZXppZXIoMSwgMC43LCAwLjEsIDAuMSksIG9wYWNpdHkgMC4xNXM7XG4gICAgICBvcGFjaXR5OiAwO1xuICAgICAgei1pbmRleDogLTE7XG4gICAgICBwb2ludGVyLWV2ZW50czogbm9uZTsgfVxuICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtaGVhZGVyLW5hdl9fdG9waWMgKyAubWQtaGVhZGVyLW5hdl9fdG9waWMge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTIuNXJlbSk7IH1cbiAgICAubm8tanMgLm1kLWhlYWRlci1uYXZfX3RvcGljIHtcbiAgICAgIHBvc2l0aW9uOiBpbml0aWFsOyB9XG4gICAgLm5vLWpzIC5tZC1oZWFkZXItbmF2X190b3BpYyArIC5tZC1oZWFkZXItbmF2X190b3BpYyB7XG4gICAgICBkaXNwbGF5OiBub25lOyB9XG4gIC5tZC1oZWFkZXItbmF2X190aXRsZSB7XG4gICAgcGFkZGluZzogMCAycmVtO1xuICAgIGZvbnQtc2l6ZTogMS44cmVtO1xuICAgIGxpbmUtaGVpZ2h0OiA0LjhyZW07IH1cbiAgICAubWQtaGVhZGVyLW5hdl9fdGl0bGVbZGF0YS1tZC1zdGF0ZT1cImFjdGl2ZVwiXSAubWQtaGVhZGVyLW5hdl9fdG9waWMge1xuICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKC0yLjVyZW0pO1xuICAgICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuNHMgY3ViaWMtYmV6aWVyKDEsIDAuNywgMC4xLCAwLjEpLCBvcGFjaXR5IDAuMTVzO1xuICAgICAgb3BhY2l0eTogMDtcbiAgICAgIHotaW5kZXg6IC0xO1xuICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7IH1cbiAgICAgIFtkaXI9XCJydGxcIl0gLm1kLWhlYWRlci1uYXZfX3RpdGxlW2RhdGEtbWQtc3RhdGU9XCJhY3RpdmVcIl0gLm1kLWhlYWRlci1uYXZfX3RvcGljIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDIuNXJlbSk7IH1cbiAgICAgIC5tZC1oZWFkZXItbmF2X190aXRsZVtkYXRhLW1kLXN0YXRlPVwiYWN0aXZlXCJdIC5tZC1oZWFkZXItbmF2X190b3BpYyArIC5tZC1oZWFkZXItbmF2X190b3BpYyB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgwKTtcbiAgICAgICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuNHMgY3ViaWMtYmV6aWVyKDAuMSwgMC43LCAwLjEsIDEpLCBvcGFjaXR5IDAuMTVzO1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgICB6LWluZGV4OiAwO1xuICAgICAgICBwb2ludGVyLWV2ZW50czogaW5pdGlhbDsgfVxuICAubWQtaGVhZGVyLW5hdl9fc291cmNlIHtcbiAgICBkaXNwbGF5OiBub25lOyB9XG4gICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA2MGVtKSB7XG4gICAgICAubWQtaGVhZGVyLW5hdl9fc291cmNlIHtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgIHdpZHRoOiAyM3JlbTtcbiAgICAgICAgbWF4LXdpZHRoOiAyM3JlbTtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IDIuOHJlbTtcbiAgICAgICAgcGFkZGluZy1yaWdodDogMS4ycmVtOyB9XG4gICAgICAgIFtkaXI9XCJydGxcIl0gLm1kLWhlYWRlci1uYXZfX3NvdXJjZSB7XG4gICAgICAgICAgbWFyZ2luLXJpZ2h0OiAyLjhyZW07XG4gICAgICAgICAgbWFyZ2luLWxlZnQ6IGluaXRpYWw7XG4gICAgICAgICAgcGFkZGluZy1yaWdodDogaW5pdGlhbDtcbiAgICAgICAgICBwYWRkaW5nLWxlZnQ6IDEuMnJlbTsgfSB9XG5cbi5tZC1oZXJvIHtcbiAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCAwLjI1cztcbiAgYmFja2dyb3VuZC1jb2xvcjogIzNmNTFiNTtcbiAgY29sb3I6IHdoaXRlO1xuICBmb250LXNpemU6IDJyZW07XG4gIG92ZXJmbG93OiBoaWRkZW47IH1cbiAgLm1kLWhlcm9fX2lubmVyIHtcbiAgICBtYXJnaW4tdG9wOiAycmVtO1xuICAgIHBhZGRpbmc6IDEuNnJlbSAxLjZyZW0gMC44cmVtO1xuICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjRzIGN1YmljLWJlemllcigwLjEsIDAuNywgMC4xLCAxKSwgb3BhY2l0eSAwLjI1cztcbiAgICB0cmFuc2l0aW9uLWRlbGF5OiAwLjFzOyB9XG4gICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA3Ni4xODc1ZW0pIHtcbiAgICAgIC5tZC1oZXJvX19pbm5lciB7XG4gICAgICAgIG1hcmdpbi10b3A6IDQuOHJlbTtcbiAgICAgICAgbWFyZ2luLWJvdHRvbTogMi40cmVtOyB9IH1cbiAgICBbZGF0YS1tZC1zdGF0ZT1cImhpZGRlblwiXSAubWQtaGVyb19faW5uZXIge1xuICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoMS4yNXJlbSk7XG4gICAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMHMgICAwLjRzLCBvcGFjaXR5ICAgMC4xcyAwcztcbiAgICAgIG9wYWNpdHk6IDA7IH1cbiAgICAubWQtaGVyby0tZXhwYW5kIC5tZC1oZXJvX19pbm5lciB7XG4gICAgICBtYXJnaW4tYm90dG9tOiAyLjRyZW07IH1cblxuQG1lZGlhIHByaW50IHtcbiAgLm1kLWZvb3RlciB7XG4gICAgZGlzcGxheTogbm9uZTsgfSB9XG5cbi5tZC1mb290ZXItbmF2IHtcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjg3KTtcbiAgY29sb3I6IHdoaXRlOyB9XG4gIC5tZC1mb290ZXItbmF2X19pbm5lciB7XG4gICAgcGFkZGluZzogMC40cmVtO1xuICAgIG92ZXJmbG93OiBhdXRvOyB9XG4gIC5tZC1mb290ZXItbmF2X19saW5rIHtcbiAgICBwYWRkaW5nLXRvcDogMi44cmVtO1xuICAgIHBhZGRpbmctYm90dG9tOiAwLjhyZW07XG4gICAgdHJhbnNpdGlvbjogb3BhY2l0eSAwLjI1czsgfVxuICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNDVlbSkge1xuICAgICAgLm1kLWZvb3Rlci1uYXZfX2xpbmsge1xuICAgICAgICB3aWR0aDogNTAlOyB9IH1cbiAgICAubWQtZm9vdGVyLW5hdl9fbGluazpob3ZlciB7XG4gICAgICBvcGFjaXR5OiAwLjc7IH1cbiAgICAubWQtZm9vdGVyLW5hdl9fbGluay0tcHJldiB7XG4gICAgICB3aWR0aDogMjUlO1xuICAgICAgZmxvYXQ6IGxlZnQ7IH1cbiAgICAgIFtkaXI9XCJydGxcIl0gLm1kLWZvb3Rlci1uYXZfX2xpbmstLXByZXYge1xuICAgICAgICBmbG9hdDogcmlnaHQ7IH1cbiAgICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1heC13aWR0aDogNDQuOTM3NWVtKSB7XG4gICAgICAgIC5tZC1mb290ZXItbmF2X19saW5rLS1wcmV2IC5tZC1mb290ZXItbmF2X190aXRsZSB7XG4gICAgICAgICAgZGlzcGxheTogbm9uZTsgfSB9XG4gICAgLm1kLWZvb3Rlci1uYXZfX2xpbmstLW5leHQge1xuICAgICAgd2lkdGg6IDc1JTtcbiAgICAgIGZsb2F0OiByaWdodDtcbiAgICAgIHRleHQtYWxpZ246IHJpZ2h0OyB9XG4gICAgICBbZGlyPVwicnRsXCJdIC5tZC1mb290ZXItbmF2X19saW5rLS1uZXh0IHtcbiAgICAgICAgZmxvYXQ6IGxlZnQ7XG4gICAgICAgIHRleHQtYWxpZ246IGxlZnQ7IH1cbiAgLm1kLWZvb3Rlci1uYXZfX2J1dHRvbiB7XG4gICAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCAwLjI1czsgfVxuICAubWQtZm9vdGVyLW5hdl9fdGl0bGUge1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBwYWRkaW5nOiAwIDJyZW07XG4gICAgZm9udC1zaXplOiAxLjhyZW07XG4gICAgbGluZS1oZWlnaHQ6IDQuOHJlbTsgfVxuICAubWQtZm9vdGVyLW5hdl9fZGlyZWN0aW9uIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgcmlnaHQ6IDA7XG4gICAgbGVmdDogMDtcbiAgICBtYXJnaW4tdG9wOiAtMnJlbTtcbiAgICBwYWRkaW5nOiAwIDJyZW07XG4gICAgY29sb3I6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC43KTtcbiAgICBmb250LXNpemU6IDEuNXJlbTsgfVxuXG4ubWQtZm9vdGVyLW1ldGEge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuODk1KTsgfVxuICAubWQtZm9vdGVyLW1ldGFfX2lubmVyIHtcbiAgICBwYWRkaW5nOiAwLjRyZW07XG4gICAgb3ZlcmZsb3c6IGF1dG87IH1cbiAgaHRtbCAubWQtZm9vdGVyLW1ldGEubWQtdHlwZXNldCBhIHtcbiAgICBjb2xvcjogcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjcpOyB9XG4gICAgaHRtbCAubWQtZm9vdGVyLW1ldGEubWQtdHlwZXNldCBhOmZvY3VzLCBodG1sIC5tZC1mb290ZXItbWV0YS5tZC10eXBlc2V0IGE6aG92ZXIge1xuICAgICAgY29sb3I6IHdoaXRlOyB9XG5cbi5tZC1mb290ZXItY29weXJpZ2h0IHtcbiAgbWFyZ2luOiAwIDEuMnJlbTtcbiAgcGFkZGluZzogMC44cmVtIDA7XG4gIGNvbG9yOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMyk7XG4gIGZvbnQtc2l6ZTogMS4yOHJlbTsgfVxuICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDQ1ZW0pIHtcbiAgICAubWQtZm9vdGVyLWNvcHlyaWdodCB7XG4gICAgICBtYXgtd2lkdGg6IDc1JTtcbiAgICAgIGZsb2F0OiBsZWZ0OyB9XG4gICAgICBbZGlyPVwicnRsXCJdIC5tZC1mb290ZXItY29weXJpZ2h0IHtcbiAgICAgICAgZmxvYXQ6IHJpZ2h0OyB9IH1cbiAgLm1kLWZvb3Rlci1jb3B5cmlnaHRfX2hpZ2hsaWdodCB7XG4gICAgY29sb3I6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC43KTsgfVxuXG4ubWQtZm9vdGVyLXNvY2lhbCB7XG4gIG1hcmdpbjogMCAwLjhyZW07XG4gIHBhZGRpbmc6IDAuNHJlbSAwIDEuMnJlbTsgfVxuICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDQ1ZW0pIHtcbiAgICAubWQtZm9vdGVyLXNvY2lhbCB7XG4gICAgICBwYWRkaW5nOiAxLjJyZW0gMDtcbiAgICAgIGZsb2F0OiByaWdodDsgfVxuICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtZm9vdGVyLXNvY2lhbCB7XG4gICAgICAgIGZsb2F0OiBsZWZ0OyB9IH1cbiAgLm1kLWZvb3Rlci1zb2NpYWxfX2xpbmsge1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICB3aWR0aDogMy4ycmVtO1xuICAgIGhlaWdodDogMy4ycmVtO1xuICAgIGZvbnQtc2l6ZTogMS42cmVtO1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjsgfVxuICAgIC5tZC1mb290ZXItc29jaWFsX19saW5rOjpiZWZvcmUge1xuICAgICAgbGluZS1oZWlnaHQ6IDEuOTsgfVxuXG4ubWQtbmF2IHtcbiAgZm9udC1zaXplOiAxLjRyZW07XG4gIGxpbmUtaGVpZ2h0OiAxLjM7IH1cbiAgLm1kLW5hdl9fdGl0bGUge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIHBhZGRpbmc6IDAgMS4ycmVtO1xuICAgIGZvbnQtd2VpZ2h0OiA3MDA7XG4gICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjsgfVxuICAgIC5tZC1uYXZfX3RpdGxlOjpiZWZvcmUge1xuICAgICAgZGlzcGxheTogbm9uZTtcbiAgICAgIGNvbnRlbnQ6IFwiXFxFNUM0XCI7IH1cbiAgICAgIFtkaXI9XCJydGxcIl0gLm1kLW5hdl9fdGl0bGU6OmJlZm9yZSB7XG4gICAgICAgIGNvbnRlbnQ6IFwiXFxFNUM4XCI7IH1cbiAgICAubWQtbmF2X190aXRsZSAubWQtbmF2X19idXR0b24ge1xuICAgICAgZGlzcGxheTogbm9uZTsgfVxuICAubWQtbmF2X19saXN0IHtcbiAgICBtYXJnaW46IDA7XG4gICAgcGFkZGluZzogMDtcbiAgICBsaXN0LXN0eWxlOiBub25lOyB9XG4gIC5tZC1uYXZfX2l0ZW0ge1xuICAgIHBhZGRpbmc6IDAgMS4ycmVtOyB9XG4gICAgLm1kLW5hdl9faXRlbTpsYXN0LWNoaWxkIHtcbiAgICAgIHBhZGRpbmctYm90dG9tOiAxLjJyZW07IH1cbiAgICAubWQtbmF2X19pdGVtIC5tZC1uYXZfX2l0ZW0ge1xuICAgICAgcGFkZGluZy1yaWdodDogMDsgfVxuICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtbmF2X19pdGVtIC5tZC1uYXZfX2l0ZW0ge1xuICAgICAgICBwYWRkaW5nLXJpZ2h0OiAxLjJyZW07XG4gICAgICAgIHBhZGRpbmctbGVmdDogMDsgfVxuICAgICAgLm1kLW5hdl9faXRlbSAubWQtbmF2X19pdGVtOmxhc3QtY2hpbGQge1xuICAgICAgICBwYWRkaW5nLWJvdHRvbTogMDsgfVxuICAubWQtbmF2X19idXR0b24gaW1nIHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IGF1dG87IH1cbiAgLm1kLW5hdl9fbGluayB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgbWFyZ2luLXRvcDogMC42MjVlbTtcbiAgICB0cmFuc2l0aW9uOiBjb2xvciAwLjEyNXM7XG4gICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIG92ZXJmbG93OiBoaWRkZW47IH1cbiAgICAubWQtbmF2X19pdGVtLS1uZXN0ZWQgPiAubWQtbmF2X19saW5rOjphZnRlciB7XG4gICAgICBjb250ZW50OiBcIlxcRTMxM1wiOyB9XG4gICAgaHRtbCAubWQtbmF2X19saW5rW2Zvcj1cIl9fdG9jXCJdIHtcbiAgICAgIGRpc3BsYXk6IG5vbmU7IH1cbiAgICAgIGh0bWwgLm1kLW5hdl9fbGlua1tmb3I9XCJfX3RvY1wiXSB+IC5tZC1uYXYge1xuICAgICAgICBkaXNwbGF5OiBub25lOyB9XG4gICAgICBodG1sIC5tZC1uYXZfX2xpbmtbZm9yPVwiX190b2NcIl0gKyAubWQtbmF2X19saW5rOjphZnRlciB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7IH1cbiAgICAubWQtbmF2X19saW5rW2RhdGEtbWQtc3RhdGU9XCJibHVyXCJdIHtcbiAgICAgIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuNTQpOyB9XG4gICAgLm1kLW5hdl9fbGluazphY3RpdmUsIC5tZC1uYXZfX2xpbmstLWFjdGl2ZSB7XG4gICAgICBjb2xvcjogIzNmNTFiNTsgfVxuICAgIC5tZC1uYXZfX2l0ZW0tLW5lc3RlZCA+IC5tZC1uYXZfX2xpbmsge1xuICAgICAgY29sb3I6IGluaGVyaXQ7IH1cbiAgICAubWQtbmF2X19saW5rOmZvY3VzLCAubWQtbmF2X19saW5rOmhvdmVyIHtcbiAgICAgIGNvbG9yOiAjNTM2ZGZlOyB9XG4gIC5tZC1uYXZfX3NvdXJjZSB7XG4gICAgZGlzcGxheTogbm9uZTsgfVxuICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDc2LjE4NzVlbSkge1xuICAgIC5tZC1uYXYge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7IH1cbiAgICAgIC5tZC1uYXYtLXByaW1hcnksXG4gICAgICAubWQtbmF2LS1wcmltYXJ5IC5tZC1uYXYge1xuICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIHRvcDogMDtcbiAgICAgICAgcmlnaHQ6IDA7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgIGhlaWdodDogMTAwJTtcbiAgICAgICAgei1pbmRleDogMTsgfVxuICAgICAgLm1kLW5hdi0tcHJpbWFyeSAubWQtbmF2X190aXRsZSxcbiAgICAgIC5tZC1uYXYtLXByaW1hcnkgLm1kLW5hdl9faXRlbSB7XG4gICAgICAgIGZvbnQtc2l6ZTogMS42cmVtO1xuICAgICAgICBsaW5lLWhlaWdodDogMS41OyB9XG4gICAgICBodG1sIC5tZC1uYXYtLXByaW1hcnkgLm1kLW5hdl9fdGl0bGUge1xuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIGhlaWdodDogMTEuMnJlbTtcbiAgICAgICAgcGFkZGluZzogNnJlbSAxLjZyZW0gMC40cmVtO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuMDcpO1xuICAgICAgICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjU0KTtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDQwMDtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDQuOHJlbTtcbiAgICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICAgICAgY3Vyc29yOiBwb2ludGVyOyB9XG4gICAgICAgIGh0bWwgLm1kLW5hdi0tcHJpbWFyeSAubWQtbmF2X190aXRsZTo6YmVmb3JlIHtcbiAgICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgdG9wOiAwLjRyZW07XG4gICAgICAgICAgbGVmdDogMC40cmVtO1xuICAgICAgICAgIHdpZHRoOiA0cmVtO1xuICAgICAgICAgIGhlaWdodDogNHJlbTtcbiAgICAgICAgICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjU0KTsgfVxuICAgICAgICBodG1sIC5tZC1uYXYtLXByaW1hcnkgLm1kLW5hdl9fdGl0bGUgfiAubWQtbmF2X19saXN0IHtcbiAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTtcbiAgICAgICAgICBib3gtc2hhZG93OiAwIDAuMXJlbSAwIHJnYmEoMCwgMCwgMCwgMC4wNykgaW5zZXQ7IH1cbiAgICAgICAgICBodG1sIC5tZC1uYXYtLXByaW1hcnkgLm1kLW5hdl9fdGl0bGUgfiAubWQtbmF2X19saXN0ID4gLm1kLW5hdl9faXRlbTpmaXJzdC1jaGlsZCB7XG4gICAgICAgICAgICBib3JkZXItdG9wOiAwOyB9XG4gICAgICAgIGh0bWwgLm1kLW5hdi0tcHJpbWFyeSAubWQtbmF2X190aXRsZS0tc2l0ZSB7XG4gICAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6ICMzZjUxYjU7XG4gICAgICAgICAgY29sb3I6IHdoaXRlOyB9XG4gICAgICAgICAgaHRtbCAubWQtbmF2LS1wcmltYXJ5IC5tZC1uYXZfX3RpdGxlLS1zaXRlIC5tZC1uYXZfX2J1dHRvbiB7XG4gICAgICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgICAgIHRvcDogMC40cmVtO1xuICAgICAgICAgICAgbGVmdDogMC40cmVtO1xuICAgICAgICAgICAgd2lkdGg6IDYuNHJlbTtcbiAgICAgICAgICAgIGhlaWdodDogNi40cmVtO1xuICAgICAgICAgICAgZm9udC1zaXplOiA0LjhyZW07IH1cbiAgICAgICAgICBodG1sIC5tZC1uYXYtLXByaW1hcnkgLm1kLW5hdl9fdGl0bGUtLXNpdGU6OmJlZm9yZSB7XG4gICAgICAgICAgICBkaXNwbGF5OiBub25lOyB9XG4gICAgICBodG1sIFtkaXI9XCJydGxcIl0gLm1kLW5hdi0tcHJpbWFyeSAubWQtbmF2X190aXRsZTo6YmVmb3JlIHtcbiAgICAgICAgcmlnaHQ6IDAuNHJlbTtcbiAgICAgICAgbGVmdDogaW5pdGlhbDsgfVxuICAgICAgaHRtbCBbZGlyPVwicnRsXCJdIC5tZC1uYXYtLXByaW1hcnkgLm1kLW5hdl9fdGl0bGUtLXNpdGUgLm1kLW5hdl9fYnV0dG9uIHtcbiAgICAgICAgcmlnaHQ6IDAuNHJlbTtcbiAgICAgICAgbGVmdDogaW5pdGlhbDsgfVxuICAgICAgLm1kLW5hdi0tcHJpbWFyeSAubWQtbmF2X19saXN0IHtcbiAgICAgICAgZmxleDogMTtcbiAgICAgICAgb3ZlcmZsb3cteTogYXV0bzsgfVxuICAgICAgLm1kLW5hdi0tcHJpbWFyeSAubWQtbmF2X19pdGVtIHtcbiAgICAgICAgcGFkZGluZzogMDtcbiAgICAgICAgYm9yZGVyLXRvcDogMC4xcmVtIHNvbGlkIHJnYmEoMCwgMCwgMCwgMC4wNyk7IH1cbiAgICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtbmF2LS1wcmltYXJ5IC5tZC1uYXZfX2l0ZW0ge1xuICAgICAgICAgIHBhZGRpbmc6IDA7IH1cbiAgICAgICAgLm1kLW5hdi0tcHJpbWFyeSAubWQtbmF2X19pdGVtLS1uZXN0ZWQgPiAubWQtbmF2X19saW5rIHtcbiAgICAgICAgICBwYWRkaW5nLXJpZ2h0OiA0LjhyZW07IH1cbiAgICAgICAgICBbZGlyPVwicnRsXCJdIC5tZC1uYXYtLXByaW1hcnkgLm1kLW5hdl9faXRlbS0tbmVzdGVkID4gLm1kLW5hdl9fbGluayB7XG4gICAgICAgICAgICBwYWRkaW5nLXJpZ2h0OiAxLjZyZW07XG4gICAgICAgICAgICBwYWRkaW5nLWxlZnQ6IDQuOHJlbTsgfVxuICAgICAgICAgIC5tZC1uYXYtLXByaW1hcnkgLm1kLW5hdl9faXRlbS0tbmVzdGVkID4gLm1kLW5hdl9fbGluazo6YWZ0ZXIge1xuICAgICAgICAgICAgY29udGVudDogXCJcXEUzMTVcIjsgfVxuICAgICAgICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtbmF2LS1wcmltYXJ5IC5tZC1uYXZfX2l0ZW0tLW5lc3RlZCA+IC5tZC1uYXZfX2xpbms6OmFmdGVyIHtcbiAgICAgICAgICAgICAgY29udGVudDogXCJcXEUzMTRcIjsgfVxuICAgICAgLm1kLW5hdi0tcHJpbWFyeSAubWQtbmF2X19saW5rIHtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICBtYXJnaW4tdG9wOiAwO1xuICAgICAgICBwYWRkaW5nOiAxLjJyZW0gMS42cmVtOyB9XG4gICAgICAgIC5tZC1uYXYtLXByaW1hcnkgLm1kLW5hdl9fbGluazo6YWZ0ZXIge1xuICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgICB0b3A6IDUwJTtcbiAgICAgICAgICByaWdodDogMS4ycmVtO1xuICAgICAgICAgIG1hcmdpbi10b3A6IC0xLjJyZW07XG4gICAgICAgICAgY29sb3I6IGluaGVyaXQ7XG4gICAgICAgICAgZm9udC1zaXplOiAyLjRyZW07IH1cbiAgICAgICAgICBbZGlyPVwicnRsXCJdIC5tZC1uYXYtLXByaW1hcnkgLm1kLW5hdl9fbGluazo6YWZ0ZXIge1xuICAgICAgICAgICAgcmlnaHQ6IGluaXRpYWw7XG4gICAgICAgICAgICBsZWZ0OiAxLjJyZW07IH1cbiAgICAgIC5tZC1uYXYtLXByaW1hcnkgLm1kLW5hdi0tc2Vjb25kYXJ5IC5tZC1uYXZfX2xpbmsge1xuICAgICAgICBwb3NpdGlvbjogc3RhdGljOyB9XG4gICAgICAubWQtbmF2LS1wcmltYXJ5IC5tZC1uYXYtLXNlY29uZGFyeSAubWQtbmF2IHtcbiAgICAgICAgcG9zaXRpb246IHN0YXRpYztcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7IH1cbiAgICAgICAgLm1kLW5hdi0tcHJpbWFyeSAubWQtbmF2LS1zZWNvbmRhcnkgLm1kLW5hdiAubWQtbmF2X19saW5rIHtcbiAgICAgICAgICBwYWRkaW5nLWxlZnQ6IDIuOHJlbTsgfVxuICAgICAgICAgIFtkaXI9XCJydGxcIl0gLm1kLW5hdi0tcHJpbWFyeSAubWQtbmF2LS1zZWNvbmRhcnkgLm1kLW5hdiAubWQtbmF2X19saW5rIHtcbiAgICAgICAgICAgIHBhZGRpbmctcmlnaHQ6IDIuOHJlbTtcbiAgICAgICAgICAgIHBhZGRpbmctbGVmdDogaW5pdGlhbDsgfVxuICAgICAgICAubWQtbmF2LS1wcmltYXJ5IC5tZC1uYXYtLXNlY29uZGFyeSAubWQtbmF2IC5tZC1uYXYgLm1kLW5hdl9fbGluayB7XG4gICAgICAgICAgcGFkZGluZy1sZWZ0OiA0cmVtOyB9XG4gICAgICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtbmF2LS1wcmltYXJ5IC5tZC1uYXYtLXNlY29uZGFyeSAubWQtbmF2IC5tZC1uYXYgLm1kLW5hdl9fbGluayB7XG4gICAgICAgICAgICBwYWRkaW5nLXJpZ2h0OiA0cmVtO1xuICAgICAgICAgICAgcGFkZGluZy1sZWZ0OiBpbml0aWFsOyB9XG4gICAgICAgIC5tZC1uYXYtLXByaW1hcnkgLm1kLW5hdi0tc2Vjb25kYXJ5IC5tZC1uYXYgLm1kLW5hdiAubWQtbmF2IC5tZC1uYXZfX2xpbmsge1xuICAgICAgICAgIHBhZGRpbmctbGVmdDogNS4ycmVtOyB9XG4gICAgICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtbmF2LS1wcmltYXJ5IC5tZC1uYXYtLXNlY29uZGFyeSAubWQtbmF2IC5tZC1uYXYgLm1kLW5hdiAubWQtbmF2X19saW5rIHtcbiAgICAgICAgICAgIHBhZGRpbmctcmlnaHQ6IDUuMnJlbTtcbiAgICAgICAgICAgIHBhZGRpbmctbGVmdDogaW5pdGlhbDsgfVxuICAgICAgICAubWQtbmF2LS1wcmltYXJ5IC5tZC1uYXYtLXNlY29uZGFyeSAubWQtbmF2IC5tZC1uYXYgLm1kLW5hdiAubWQtbmF2IC5tZC1uYXZfX2xpbmsge1xuICAgICAgICAgIHBhZGRpbmctbGVmdDogNi40cmVtOyB9XG4gICAgICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtbmF2LS1wcmltYXJ5IC5tZC1uYXYtLXNlY29uZGFyeSAubWQtbmF2IC5tZC1uYXYgLm1kLW5hdiAubWQtbmF2IC5tZC1uYXZfX2xpbmsge1xuICAgICAgICAgICAgcGFkZGluZy1yaWdodDogNi40cmVtO1xuICAgICAgICAgICAgcGFkZGluZy1sZWZ0OiBpbml0aWFsOyB9XG4gICAgICAubWQtbmF2X190b2dnbGUgfiAubWQtbmF2IHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDEwMCUpO1xuICAgICAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC4yNXMgY3ViaWMtYmV6aWVyKDAuOCwgMCwgMC42LCAxKSwgb3BhY2l0eSAwLjEyNXMgMC4wNXM7XG4gICAgICAgIG9wYWNpdHk6IDA7IH1cbiAgICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtbmF2X190b2dnbGUgfiAubWQtbmF2IHtcbiAgICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTEwMCUpOyB9XG4gICAgICAgIC5uby1jc3N0cmFuc2Zvcm1zM2QgLm1kLW5hdl9fdG9nZ2xlIH4gLm1kLW5hdiB7XG4gICAgICAgICAgZGlzcGxheTogbm9uZTsgfVxuICAgICAgLm1kLW5hdl9fdG9nZ2xlOmNoZWNrZWQgfiAubWQtbmF2IHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDApO1xuICAgICAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC4yNXMgY3ViaWMtYmV6aWVyKDAuNCwgMCwgMC4yLCAxKSwgb3BhY2l0eSAwLjEyNXMgMC4xMjVzO1xuICAgICAgICBvcGFjaXR5OiAxOyB9XG4gICAgICAgIC5uby1jc3N0cmFuc2Zvcm1zM2QgLm1kLW5hdl9fdG9nZ2xlOmNoZWNrZWQgfiAubWQtbmF2IHtcbiAgICAgICAgICBkaXNwbGF5OiBmbGV4OyB9IH1cbiAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA1OS45Mzc1ZW0pIHtcbiAgICBodG1sIC5tZC1uYXZfX2xpbmtbZm9yPVwiX190b2NcIl0ge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICBwYWRkaW5nLXJpZ2h0OiA0LjhyZW07IH1cbiAgICAgIGh0bWwgLm1kLW5hdl9fbGlua1tmb3I9XCJfX3RvY1wiXTo6YWZ0ZXIge1xuICAgICAgICBjb2xvcjogaW5oZXJpdDtcbiAgICAgICAgY29udGVudDogXCJcXEU4REVcIjsgfVxuICAgICAgaHRtbCAubWQtbmF2X19saW5rW2Zvcj1cIl9fdG9jXCJdICsgLm1kLW5hdl9fbGluayB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7IH1cbiAgICAgIGh0bWwgLm1kLW5hdl9fbGlua1tmb3I9XCJfX3RvY1wiXSB+IC5tZC1uYXYge1xuICAgICAgICBkaXNwbGF5OiBmbGV4OyB9XG4gICAgaHRtbCBbZGlyPVwicnRsXCJdIC5tZC1uYXZfX2xpbmsge1xuICAgICAgcGFkZGluZy1yaWdodDogMS42cmVtO1xuICAgICAgcGFkZGluZy1sZWZ0OiA0LjhyZW07IH1cbiAgICAubWQtbmF2X19zb3VyY2Uge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICBwYWRkaW5nOiAwIDAuNHJlbTtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoNTAsIDY0LCAxNDQsIDAuOTY3NSk7XG4gICAgICBjb2xvcjogd2hpdGU7IH0gfVxuICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDc2LjI1ZW0pIHtcbiAgICAubWQtbmF2W2RhdGEtbWQtc3RhdGU9XCJhbmltYXRlXCJdIHtcbiAgICAgIHRyYW5zaXRpb246IG1heC1oZWlnaHQgMC4yNXMgY3ViaWMtYmV6aWVyKDAuODYsIDAsIDAuMDcsIDEpOyB9XG4gICAgLm1kLW5hdl9fdG9nZ2xlIH4gLm1kLW5hdiB7XG4gICAgICBtYXgtaGVpZ2h0OiAwO1xuICAgICAgb3ZlcmZsb3c6IGhpZGRlbjsgfVxuICAgICAgLm5vLWpzIC5tZC1uYXZfX3RvZ2dsZSB+IC5tZC1uYXYge1xuICAgICAgICBkaXNwbGF5OiBub25lOyB9XG4gICAgLm1kLW5hdl9fdG9nZ2xlOmNoZWNrZWQgfiAubWQtbmF2LCAubWQtbmF2W2RhdGEtbWQtc3RhdGU9XCJleHBhbmRcIl0ge1xuICAgICAgbWF4LWhlaWdodDogMTAwJTsgfVxuICAgICAgLm5vLWpzIC5tZC1uYXZfX3RvZ2dsZTpjaGVja2VkIH4gLm1kLW5hdiwgLm5vLWpzIC5tZC1uYXZbZGF0YS1tZC1zdGF0ZT1cImV4cGFuZFwiXSB7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrOyB9XG4gICAgLm1kLW5hdl9faXRlbS0tbmVzdGVkID4gLm1kLW5hdiA+IC5tZC1uYXZfX3RpdGxlIHtcbiAgICAgIGRpc3BsYXk6IG5vbmU7IH1cbiAgICAubWQtbmF2X19pdGVtLS1uZXN0ZWQgPiAubWQtbmF2X19saW5rOjphZnRlciB7XG4gICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgICB0cmFuc2Zvcm0tb3JpZ2luOiAwLjQ1ZW0gMC40NWVtO1xuICAgICAgdHJhbnNmb3JtLXN0eWxlOiBwcmVzZXJ2ZS0zZDtcbiAgICAgIHZlcnRpY2FsLWFsaWduOiAtMC4xMjVlbTsgfVxuICAgICAgLmpzIC5tZC1uYXZfX2l0ZW0tLW5lc3RlZCA+IC5tZC1uYXZfX2xpbms6OmFmdGVyIHtcbiAgICAgICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuNHM7IH1cbiAgICAubWQtbmF2X19pdGVtLS1uZXN0ZWQgLm1kLW5hdl9fdG9nZ2xlOmNoZWNrZWQgfiAubWQtbmF2X19saW5rOjphZnRlciB7XG4gICAgICB0cmFuc2Zvcm06IHJvdGF0ZVgoMTgwZGVnKTsgfSB9XG5cbi5uby1qcyAubWQtc2VhcmNoIHtcbiAgZGlzcGxheTogbm9uZTsgfVxuXG5AbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDYwZW0pIHtcbiAgLm1kLXNlYXJjaCB7XG4gICAgcGFkZGluZzogMC40cmVtOyB9IH1cblxuLm1kLXNlYXJjaF9fb3ZlcmxheSB7XG4gIG9wYWNpdHk6IDA7XG4gIHotaW5kZXg6IDE7IH1cbiAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA1OS45Mzc1ZW0pIHtcbiAgICAubWQtc2VhcmNoX19vdmVybGF5IHtcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgIHRvcDogMC40cmVtO1xuICAgICAgbGVmdDogMC40cmVtO1xuICAgICAgd2lkdGg6IDMuNnJlbTtcbiAgICAgIGhlaWdodDogMy42cmVtO1xuICAgICAgdHJhbnNmb3JtLW9yaWdpbjogY2VudGVyO1xuICAgICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuM3MgMC4xcywgb3BhY2l0eSAgIDAuMnMgMC4ycztcbiAgICAgIGJvcmRlci1yYWRpdXM6IDJyZW07XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTtcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICBwb2ludGVyLWV2ZW50czogbm9uZTsgfVxuICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtc2VhcmNoX19vdmVybGF5IHtcbiAgICAgICAgcmlnaHQ6IDAuNHJlbTtcbiAgICAgICAgbGVmdDogaW5pdGlhbDsgfVxuICAgICAgW2RhdGEtbWQtdG9nZ2xlPVwic2VhcmNoXCJdOmNoZWNrZWQgfiAubWQtaGVhZGVyIC5tZC1zZWFyY2hfX292ZXJsYXkge1xuICAgICAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC40cywgb3BhY2l0eSAgIDAuMXM7XG4gICAgICAgIG9wYWNpdHk6IDE7IH0gfVxuICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDI5LjkzNzVlbSkge1xuICAgIFtkYXRhLW1kLXRvZ2dsZT1cInNlYXJjaFwiXTpjaGVja2VkIH4gLm1kLWhlYWRlciAubWQtc2VhcmNoX19vdmVybGF5IHtcbiAgICAgIHRyYW5zZm9ybTogc2NhbGUoNDUpOyB9IH1cbiAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAzMGVtKSBhbmQgKG1heC13aWR0aDogNDQuOTM3NWVtKSB7XG4gICAgW2RhdGEtbWQtdG9nZ2xlPVwic2VhcmNoXCJdOmNoZWNrZWQgfiAubWQtaGVhZGVyIC5tZC1zZWFyY2hfX292ZXJsYXkge1xuICAgICAgdHJhbnNmb3JtOiBzY2FsZSg2MCk7IH0gfVxuICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDQ1ZW0pIGFuZCAobWF4LXdpZHRoOiA1OS45Mzc1ZW0pIHtcbiAgICBbZGF0YS1tZC10b2dnbGU9XCJzZWFyY2hcIl06Y2hlY2tlZCB+IC5tZC1oZWFkZXIgLm1kLXNlYXJjaF9fb3ZlcmxheSB7XG4gICAgICB0cmFuc2Zvcm06IHNjYWxlKDc1KTsgfSB9XG4gIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNjBlbSkge1xuICAgIC5tZC1zZWFyY2hfX292ZXJsYXkge1xuICAgICAgcG9zaXRpb246IGZpeGVkO1xuICAgICAgdG9wOiAwO1xuICAgICAgbGVmdDogMDtcbiAgICAgIHdpZHRoOiAwO1xuICAgICAgaGVpZ2h0OiAwO1xuICAgICAgdHJhbnNpdGlvbjogd2lkdGggICAwcyAwLjI1cywgaGVpZ2h0ICAwcyAwLjI1cywgb3BhY2l0eSAwLjI1cztcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41NCk7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7IH1cbiAgICAgIFtkaXI9XCJydGxcIl0gLm1kLXNlYXJjaF9fb3ZlcmxheSB7XG4gICAgICAgIHJpZ2h0OiAwO1xuICAgICAgICBsZWZ0OiBpbml0aWFsOyB9XG4gICAgICBbZGF0YS1tZC10b2dnbGU9XCJzZWFyY2hcIl06Y2hlY2tlZCB+IC5tZC1oZWFkZXIgLm1kLXNlYXJjaF9fb3ZlcmxheSB7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIHRyYW5zaXRpb246IHdpZHRoICAgMHMsIGhlaWdodCAgMHMsIG9wYWNpdHkgMC4yNXM7XG4gICAgICAgIG9wYWNpdHk6IDE7IH0gfVxuXG5AbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDU5LjkzNzVlbSkge1xuICAubWQtc2VhcmNoX19pbm5lciB7XG4gICAgcG9zaXRpb246IGZpeGVkO1xuICAgIHRvcDogMDtcbiAgICBsZWZ0OiAxMDAlO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoNSUpO1xuICAgIHRyYW5zaXRpb246IHJpZ2h0IDBzIDAuM3MsIGxlZnQgMHMgMC4zcywgdHJhbnNmb3JtIDAuMTVzIDAuMTVzIGN1YmljLWJlemllcigwLjQsIDAsIDAuMiwgMSksIG9wYWNpdHkgMC4xNXMgMC4xNXM7XG4gICAgb3BhY2l0eTogMDtcbiAgICB6LWluZGV4OiAyOyB9XG4gICAgW2RhdGEtbWQtdG9nZ2xlPVwic2VhcmNoXCJdOmNoZWNrZWQgfiAubWQtaGVhZGVyIC5tZC1zZWFyY2hfX2lubmVyIHtcbiAgICAgIGxlZnQ6IDA7XG4gICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMCk7XG4gICAgICB0cmFuc2l0aW9uOiByaWdodCAwcyAwcywgbGVmdCAwcyAwcywgdHJhbnNmb3JtIDAuMTVzIDAuMTVzIGN1YmljLWJlemllcigwLjEsIDAuNywgMC4xLCAxKSwgb3BhY2l0eSAwLjE1cyAwLjE1cztcbiAgICAgIG9wYWNpdHk6IDE7IH1cbiAgICAgIFtkaXI9XCJydGxcIl0gW2RhdGEtbWQtdG9nZ2xlPVwic2VhcmNoXCJdOmNoZWNrZWQgfiAubWQtaGVhZGVyIC5tZC1zZWFyY2hfX2lubmVyIHtcbiAgICAgICAgcmlnaHQ6IDA7XG4gICAgICAgIGxlZnQ6IGluaXRpYWw7IH1cbiAgICBodG1sIFtkaXI9XCJydGxcIl0gLm1kLXNlYXJjaF9faW5uZXIge1xuICAgICAgcmlnaHQ6IDEwMCU7XG4gICAgICBsZWZ0OiBpbml0aWFsO1xuICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKC01JSk7IH0gfVxuXG5AbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDYwZW0pIHtcbiAgLm1kLXNlYXJjaF9faW5uZXIge1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICB3aWR0aDogMjNyZW07XG4gICAgcGFkZGluZzogMC4ycmVtIDA7XG4gICAgZmxvYXQ6IHJpZ2h0O1xuICAgIHRyYW5zaXRpb246IHdpZHRoIDAuMjVzIGN1YmljLWJlemllcigwLjEsIDAuNywgMC4xLCAxKTsgfVxuICAgIFtkaXI9XCJydGxcIl0gLm1kLXNlYXJjaF9faW5uZXIge1xuICAgICAgZmxvYXQ6IGxlZnQ7IH0gfVxuXG5AbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDYwZW0pIGFuZCAobWF4LXdpZHRoOiA3Ni4xODc1ZW0pIHtcbiAgW2RhdGEtbWQtdG9nZ2xlPVwic2VhcmNoXCJdOmNoZWNrZWQgfiAubWQtaGVhZGVyIC5tZC1zZWFyY2hfX2lubmVyIHtcbiAgICB3aWR0aDogNDYuOHJlbTsgfSB9XG5cbkBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNzYuMjVlbSkge1xuICBbZGF0YS1tZC10b2dnbGU9XCJzZWFyY2hcIl06Y2hlY2tlZCB+IC5tZC1oZWFkZXIgLm1kLXNlYXJjaF9faW5uZXIge1xuICAgIHdpZHRoOiA2OC44cmVtOyB9IH1cblxuLm1kLXNlYXJjaF9fZm9ybSB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTsgfVxuICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDYwZW0pIHtcbiAgICAubWQtc2VhcmNoX19mb3JtIHtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDAuMnJlbTsgfSB9XG5cbi5tZC1zZWFyY2hfX2lucHV0IHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBwYWRkaW5nOiAwIDQuNHJlbSAwIDcuMnJlbTtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIHotaW5kZXg6IDI7IH1cbiAgW2Rpcj1cInJ0bFwiXSAubWQtc2VhcmNoX19pbnB1dCB7XG4gICAgcGFkZGluZzogMCA3LjJyZW0gMCA0LjRyZW07IH1cbiAgLm1kLXNlYXJjaF9faW5wdXQ6OnBsYWNlaG9sZGVyIHtcbiAgICB0cmFuc2l0aW9uOiBjb2xvciAwLjI1cyBjdWJpYy1iZXppZXIoMC4xLCAwLjcsIDAuMSwgMSk7IH1cbiAgLm1kLXNlYXJjaF9faW5wdXQgfiAubWQtc2VhcmNoX19pY29uLCAubWQtc2VhcmNoX19pbnB1dDo6cGxhY2Vob2xkZXIge1xuICAgIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuNTQpOyB9XG4gIC5tZC1zZWFyY2hfX2lucHV0OjotbXMtY2xlYXIge1xuICAgIGRpc3BsYXk6IG5vbmU7IH1cbiAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA1OS45Mzc1ZW0pIHtcbiAgICAubWQtc2VhcmNoX19pbnB1dCB7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIGhlaWdodDogNC44cmVtO1xuICAgICAgZm9udC1zaXplOiAxLjhyZW07IH0gfVxuICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDYwZW0pIHtcbiAgICAubWQtc2VhcmNoX19pbnB1dCB7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIGhlaWdodDogMy42cmVtO1xuICAgICAgcGFkZGluZy1sZWZ0OiA0LjRyZW07XG4gICAgICB0cmFuc2l0aW9uOiBiYWNrZ3JvdW5kLWNvbG9yIDAuMjVzIGN1YmljLWJlemllcigwLjEsIDAuNywgMC4xLCAxKSwgY29sb3IgMC4yNXMgY3ViaWMtYmV6aWVyKDAuMSwgMC43LCAwLjEsIDEpO1xuICAgICAgYm9yZGVyLXJhZGl1czogMC4ycmVtO1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjI2KTtcbiAgICAgIGNvbG9yOiBpbmhlcml0O1xuICAgICAgZm9udC1zaXplOiAxLjZyZW07IH1cbiAgICAgIFtkaXI9XCJydGxcIl0gLm1kLXNlYXJjaF9faW5wdXQge1xuICAgICAgICBwYWRkaW5nLXJpZ2h0OiA0LjRyZW07IH1cbiAgICAgIC5tZC1zZWFyY2hfX2lucHV0ICsgLm1kLXNlYXJjaF9faWNvbiB7XG4gICAgICAgIGNvbG9yOiBpbmhlcml0OyB9XG4gICAgICAubWQtc2VhcmNoX19pbnB1dDo6cGxhY2Vob2xkZXIge1xuICAgICAgICBjb2xvcjogcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjcpOyB9XG4gICAgICAubWQtc2VhcmNoX19pbnB1dDpob3ZlciB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4xMik7IH1cbiAgICAgIFtkYXRhLW1kLXRvZ2dsZT1cInNlYXJjaFwiXTpjaGVja2VkIH4gLm1kLWhlYWRlciAubWQtc2VhcmNoX19pbnB1dCB7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDAuMnJlbSAwLjJyZW0gMCAwO1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTtcbiAgICAgICAgY29sb3I6IHJnYmEoMCwgMCwgMCwgMC44Nyk7XG4gICAgICAgIHRleHQtb3ZlcmZsb3c6IG5vbmU7IH1cbiAgICAgICAgW2RhdGEtbWQtdG9nZ2xlPVwic2VhcmNoXCJdOmNoZWNrZWQgfiAubWQtaGVhZGVyIC5tZC1zZWFyY2hfX2lucHV0ICsgLm1kLXNlYXJjaF9faWNvbiwgW2RhdGEtbWQtdG9nZ2xlPVwic2VhcmNoXCJdOmNoZWNrZWQgfiAubWQtaGVhZGVyIC5tZC1zZWFyY2hfX2lucHV0OjpwbGFjZWhvbGRlciB7XG4gICAgICAgICAgY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41NCk7IH0gfVxuXG4ubWQtc2VhcmNoX19pY29uIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0cmFuc2l0aW9uOiBjb2xvciAwLjI1cyBjdWJpYy1iZXppZXIoMC4xLCAwLjcsIDAuMSwgMSksIG9wYWNpdHkgMC4yNXM7XG4gIGZvbnQtc2l6ZTogMi40cmVtO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIHotaW5kZXg6IDI7IH1cbiAgLm1kLXNlYXJjaF9faWNvbjpob3ZlciB7XG4gICAgb3BhY2l0eTogMC43OyB9XG4gIC5tZC1zZWFyY2hfX2ljb25bZm9yPVwiX19zZWFyY2hcIl0ge1xuICAgIHRvcDogMC42cmVtO1xuICAgIGxlZnQ6IDFyZW07IH1cbiAgICBbZGlyPVwicnRsXCJdIC5tZC1zZWFyY2hfX2ljb25bZm9yPVwiX19zZWFyY2hcIl0ge1xuICAgICAgcmlnaHQ6IDFyZW07XG4gICAgICBsZWZ0OiBpbml0aWFsOyB9XG4gICAgLm1kLXNlYXJjaF9faWNvbltmb3I9XCJfX3NlYXJjaFwiXTo6YmVmb3JlIHtcbiAgICAgIGNvbnRlbnQ6IFwiXFxFOEI2XCI7IH1cbiAgICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDU5LjkzNzVlbSkge1xuICAgICAgLm1kLXNlYXJjaF9faWNvbltmb3I9XCJfX3NlYXJjaFwiXSB7XG4gICAgICAgIHRvcDogMS4ycmVtO1xuICAgICAgICBsZWZ0OiAxLjZyZW07IH1cbiAgICAgICAgLm1kLXNlYXJjaF9faWNvbltmb3I9XCJfX3NlYXJjaFwiXVtmb3I9XCJfX3NlYXJjaFwiXTo6YmVmb3JlIHtcbiAgICAgICAgICBjb250ZW50OiBcIlxcRTVDNFwiOyB9XG4gICAgICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtc2VhcmNoX19pY29uW2Zvcj1cIl9fc2VhcmNoXCJdW2Zvcj1cIl9fc2VhcmNoXCJdOjpiZWZvcmUge1xuICAgICAgICAgICAgY29udGVudDogXCJcXEU1QzhcIjsgfSB9XG4gIC5tZC1zZWFyY2hfX2ljb25bdHlwZT1cInJlc2V0XCJdIHtcbiAgICB0b3A6IDAuNnJlbTtcbiAgICByaWdodDogMXJlbTtcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDAuMTI1KTtcbiAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC4xNXMgY3ViaWMtYmV6aWVyKDAuMSwgMC43LCAwLjEsIDEpLCBvcGFjaXR5IDAuMTVzO1xuICAgIG9wYWNpdHk6IDA7IH1cbiAgICBbZGlyPVwicnRsXCJdIC5tZC1zZWFyY2hfX2ljb25bdHlwZT1cInJlc2V0XCJdIHtcbiAgICAgIHJpZ2h0OiBpbml0aWFsO1xuICAgICAgbGVmdDogMXJlbTsgfVxuICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1heC13aWR0aDogNTkuOTM3NWVtKSB7XG4gICAgICAubWQtc2VhcmNoX19pY29uW3R5cGU9XCJyZXNldFwiXSB7XG4gICAgICAgIHRvcDogMS4ycmVtO1xuICAgICAgICByaWdodDogMS42cmVtOyB9IH1cbiAgICBbZGF0YS1tZC10b2dnbGU9XCJzZWFyY2hcIl06Y2hlY2tlZCB+IC5tZC1oZWFkZXIgLm1kLXNlYXJjaF9faW5wdXQ6dmFsaWQgfiAubWQtc2VhcmNoX19pY29uW3R5cGU9XCJyZXNldFwiXSB7XG4gICAgICB0cmFuc2Zvcm06IHNjYWxlKDEpO1xuICAgICAgb3BhY2l0eTogMTsgfVxuICAgICAgW2RhdGEtbWQtdG9nZ2xlPVwic2VhcmNoXCJdOmNoZWNrZWQgfiAubWQtaGVhZGVyIC5tZC1zZWFyY2hfX2lucHV0OnZhbGlkIH4gLm1kLXNlYXJjaF9faWNvblt0eXBlPVwicmVzZXRcIl06aG92ZXIge1xuICAgICAgICBvcGFjaXR5OiAwLjc7IH1cblxuLm1kLXNlYXJjaF9fb3V0cHV0IHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB3aWR0aDogMTAwJTtcbiAgYm9yZGVyLXJhZGl1czogMCAwIDAuMnJlbSAwLjJyZW07XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHotaW5kZXg6IDE7IH1cbiAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA1OS45Mzc1ZW0pIHtcbiAgICAubWQtc2VhcmNoX19vdXRwdXQge1xuICAgICAgdG9wOiA0LjhyZW07XG4gICAgICBib3R0b206IDA7IH0gfVxuICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDYwZW0pIHtcbiAgICAubWQtc2VhcmNoX19vdXRwdXQge1xuICAgICAgdG9wOiAzLjhyZW07XG4gICAgICB0cmFuc2l0aW9uOiBvcGFjaXR5IDAuNHM7XG4gICAgICBvcGFjaXR5OiAwOyB9XG4gICAgICBbZGF0YS1tZC10b2dnbGU9XCJzZWFyY2hcIl06Y2hlY2tlZCB+IC5tZC1oZWFkZXIgLm1kLXNlYXJjaF9fb3V0cHV0IHtcbiAgICAgICAgYm94LXNoYWRvdzogMCA2cHggMTBweCAwIHJnYmEoMCwgMCwgMCwgMC4xNCksIDAgMXB4IDE4cHggMCByZ2JhKDAsIDAsIDAsIDAuMTIpLCAwIDNweCA1cHggLTFweCByZ2JhKDAsIDAsIDAsIDAuNCk7XG4gICAgICAgIG9wYWNpdHk6IDE7IH0gfVxuXG4ubWQtc2VhcmNoX19zY3JvbGx3cmFwIHtcbiAgaGVpZ2h0OiAxMDAlO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTtcbiAgYm94LXNoYWRvdzogMCAwLjFyZW0gMCByZ2JhKDAsIDAsIDAsIDAuMDcpIGluc2V0O1xuICBvdmVyZmxvdy15OiBhdXRvO1xuICAtd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzogdG91Y2g7IH1cbiAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA2MGVtKSBhbmQgKG1heC13aWR0aDogNzYuMTg3NWVtKSB7XG4gICAgLm1kLXNlYXJjaF9fc2Nyb2xsd3JhcCB7XG4gICAgICB3aWR0aDogNDYuOHJlbTsgfSB9XG4gIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNzYuMjVlbSkge1xuICAgIC5tZC1zZWFyY2hfX3Njcm9sbHdyYXAge1xuICAgICAgd2lkdGg6IDY4LjhyZW07IH0gfVxuICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDYwZW0pIHtcbiAgICAubWQtc2VhcmNoX19zY3JvbGx3cmFwIHtcbiAgICAgIG1heC1oZWlnaHQ6IDA7IH1cbiAgICAgIFtkYXRhLW1kLXRvZ2dsZT1cInNlYXJjaFwiXTpjaGVja2VkIH4gLm1kLWhlYWRlciAubWQtc2VhcmNoX19zY3JvbGx3cmFwIHtcbiAgICAgICAgbWF4LWhlaWdodDogNzV2aDsgfVxuICAgICAgLm1kLXNlYXJjaF9fc2Nyb2xsd3JhcDo6LXdlYmtpdC1zY3JvbGxiYXIge1xuICAgICAgICB3aWR0aDogMC40cmVtO1xuICAgICAgICBoZWlnaHQ6IDAuNHJlbTsgfVxuICAgICAgLm1kLXNlYXJjaF9fc2Nyb2xsd3JhcDo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWIge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuMjYpOyB9XG4gICAgICAgIC5tZC1zZWFyY2hfX3Njcm9sbHdyYXA6Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1iOmhvdmVyIHtcbiAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjNTM2ZGZlOyB9IH1cblxuLm1kLXNlYXJjaC1yZXN1bHQge1xuICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjg3KTtcbiAgd29yZC1icmVhazogYnJlYWstd29yZDsgfVxuICAubWQtc2VhcmNoLXJlc3VsdF9fbWV0YSB7XG4gICAgcGFkZGluZzogMCAxLjZyZW07XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjA3KTtcbiAgICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjU0KTtcbiAgICBmb250LXNpemU6IDEuMjhyZW07XG4gICAgbGluZS1oZWlnaHQ6IDMuNnJlbTsgfVxuICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNjBlbSkge1xuICAgICAgLm1kLXNlYXJjaC1yZXN1bHRfX21ldGEge1xuICAgICAgICBwYWRkaW5nLWxlZnQ6IDQuNHJlbTsgfVxuICAgICAgICBbZGlyPVwicnRsXCJdIC5tZC1zZWFyY2gtcmVzdWx0X19tZXRhIHtcbiAgICAgICAgICBwYWRkaW5nLXJpZ2h0OiA0LjRyZW07XG4gICAgICAgICAgcGFkZGluZy1sZWZ0OiBpbml0aWFsOyB9IH1cbiAgLm1kLXNlYXJjaC1yZXN1bHRfX2xpc3Qge1xuICAgIG1hcmdpbjogMDtcbiAgICBwYWRkaW5nOiAwO1xuICAgIGJvcmRlci10b3A6IDAuMXJlbSBzb2xpZCByZ2JhKDAsIDAsIDAsIDAuMDcpO1xuICAgIGxpc3Qtc3R5bGU6IG5vbmU7IH1cbiAgLm1kLXNlYXJjaC1yZXN1bHRfX2l0ZW0ge1xuICAgIGJveC1zaGFkb3c6IDAgLTAuMXJlbSAwIHJnYmEoMCwgMCwgMCwgMC4wNyk7IH1cbiAgLm1kLXNlYXJjaC1yZXN1bHRfX2xpbmsge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQgMC4yNXM7XG4gICAgb3V0bGluZTogMDtcbiAgICBvdmVyZmxvdzogaGlkZGVuOyB9XG4gICAgLm1kLXNlYXJjaC1yZXN1bHRfX2xpbmtbZGF0YS1tZC1zdGF0ZT1cImFjdGl2ZVwiXSwgLm1kLXNlYXJjaC1yZXN1bHRfX2xpbms6aG92ZXIge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSg4MywgMTA5LCAyNTQsIDAuMSk7IH1cbiAgICAgIC5tZC1zZWFyY2gtcmVzdWx0X19saW5rW2RhdGEtbWQtc3RhdGU9XCJhY3RpdmVcIl0gLm1kLXNlYXJjaC1yZXN1bHRfX2FydGljbGU6OmJlZm9yZSwgLm1kLXNlYXJjaC1yZXN1bHRfX2xpbms6aG92ZXIgLm1kLXNlYXJjaC1yZXN1bHRfX2FydGljbGU6OmJlZm9yZSB7XG4gICAgICAgIG9wYWNpdHk6IDAuNzsgfVxuICAgIC5tZC1zZWFyY2gtcmVzdWx0X19saW5rOmxhc3QtY2hpbGQgLm1kLXNlYXJjaC1yZXN1bHRfX3RlYXNlciB7XG4gICAgICBtYXJnaW4tYm90dG9tOiAxLjJyZW07IH1cbiAgLm1kLXNlYXJjaC1yZXN1bHRfX2FydGljbGUge1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBwYWRkaW5nOiAwIDEuNnJlbTtcbiAgICBvdmVyZmxvdzogYXV0bzsgfVxuICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNjBlbSkge1xuICAgICAgLm1kLXNlYXJjaC1yZXN1bHRfX2FydGljbGUge1xuICAgICAgICBwYWRkaW5nLWxlZnQ6IDQuNHJlbTsgfVxuICAgICAgICBbZGlyPVwicnRsXCJdIC5tZC1zZWFyY2gtcmVzdWx0X19hcnRpY2xlIHtcbiAgICAgICAgICBwYWRkaW5nLXJpZ2h0OiA0LjRyZW07XG4gICAgICAgICAgcGFkZGluZy1sZWZ0OiAxLjZyZW07IH0gfVxuICAgIC5tZC1zZWFyY2gtcmVzdWx0X19hcnRpY2xlLS1kb2N1bWVudDo6YmVmb3JlIHtcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgIGxlZnQ6IDA7XG4gICAgICBtYXJnaW46IDAuMnJlbTtcbiAgICAgIHRyYW5zaXRpb246IG9wYWNpdHkgMC4yNXM7XG4gICAgICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjU0KTtcbiAgICAgIGNvbnRlbnQ6IFwiXFxFODgwXCI7IH1cbiAgICAgIFtkaXI9XCJydGxcIl0gLm1kLXNlYXJjaC1yZXN1bHRfX2FydGljbGUtLWRvY3VtZW50OjpiZWZvcmUge1xuICAgICAgICByaWdodDogMDtcbiAgICAgICAgbGVmdDogaW5pdGlhbDsgfVxuICAgICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA1OS45Mzc1ZW0pIHtcbiAgICAgICAgLm1kLXNlYXJjaC1yZXN1bHRfX2FydGljbGUtLWRvY3VtZW50OjpiZWZvcmUge1xuICAgICAgICAgIGRpc3BsYXk6IG5vbmU7IH0gfVxuICAgIC5tZC1zZWFyY2gtcmVzdWx0X19hcnRpY2xlLS1kb2N1bWVudCAubWQtc2VhcmNoLXJlc3VsdF9fdGl0bGUge1xuICAgICAgbWFyZ2luOiAxLjFyZW0gMDtcbiAgICAgIGZvbnQtc2l6ZTogMS42cmVtO1xuICAgICAgZm9udC13ZWlnaHQ6IDQwMDtcbiAgICAgIGxpbmUtaGVpZ2h0OiAxLjQ7IH1cbiAgLm1kLXNlYXJjaC1yZXN1bHRfX3RpdGxlIHtcbiAgICBtYXJnaW46IDAuNWVtIDA7XG4gICAgZm9udC1zaXplOiAxLjI4cmVtO1xuICAgIGZvbnQtd2VpZ2h0OiA3MDA7XG4gICAgbGluZS1oZWlnaHQ6IDEuNDsgfVxuICAubWQtc2VhcmNoLXJlc3VsdF9fdGVhc2VyIHtcbiAgICBkaXNwbGF5OiAtd2Via2l0LWJveDtcbiAgICBtYXgtaGVpZ2h0OiAzLjNyZW07XG4gICAgbWFyZ2luOiAwLjVlbSAwO1xuICAgIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuNTQpO1xuICAgIGZvbnQtc2l6ZTogMS4yOHJlbTtcbiAgICBsaW5lLWhlaWdodDogMS40O1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgLXdlYmtpdC1ib3gtb3JpZW50OiB2ZXJ0aWNhbDtcbiAgICAtd2Via2l0LWxpbmUtY2xhbXA6IDI7IH1cbiAgICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDQ0LjkzNzVlbSkge1xuICAgICAgLm1kLXNlYXJjaC1yZXN1bHRfX3RlYXNlciB7XG4gICAgICAgIG1heC1oZWlnaHQ6IDVyZW07XG4gICAgICAgIC13ZWJraXQtbGluZS1jbGFtcDogMzsgfSB9XG4gICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA2MGVtKSBhbmQgKG1heC13aWR0aDogNzYuMTg3NWVtKSB7XG4gICAgICAubWQtc2VhcmNoLXJlc3VsdF9fdGVhc2VyIHtcbiAgICAgICAgbWF4LWhlaWdodDogNXJlbTtcbiAgICAgICAgLXdlYmtpdC1saW5lLWNsYW1wOiAzOyB9IH1cbiAgLm1kLXNlYXJjaC1yZXN1bHQgZW0ge1xuICAgIGZvbnQtc3R5bGU6IG5vcm1hbDtcbiAgICBmb250LXdlaWdodDogNzAwO1xuICAgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lOyB9XG5cbi5tZC1zaWRlYmFyIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB3aWR0aDogMjQuMnJlbTtcbiAgcGFkZGluZzogMi40cmVtIDA7XG4gIG92ZXJmbG93OiBoaWRkZW47IH1cbiAgQG1lZGlhIHByaW50IHtcbiAgICAubWQtc2lkZWJhciB7XG4gICAgICBkaXNwbGF5OiBub25lOyB9IH1cbiAgLm1kLXNpZGViYXJbZGF0YS1tZC1zdGF0ZT1cImxvY2tcIl0ge1xuICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICB0b3A6IDQuOHJlbTsgfVxuICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDc2LjE4NzVlbSkge1xuICAgIC5tZC1zaWRlYmFyLS1wcmltYXJ5IHtcbiAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgIHRvcDogMDtcbiAgICAgIGxlZnQ6IC0yNC4ycmVtO1xuICAgICAgd2lkdGg6IDI0LjJyZW07XG4gICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMCk7XG4gICAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC4yNXMgY3ViaWMtYmV6aWVyKDAuNCwgMCwgMC4yLCAxKSwgYm94LXNoYWRvdyAwLjI1cztcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlO1xuICAgICAgei1pbmRleDogMzsgfVxuICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtc2lkZWJhci0tcHJpbWFyeSB7XG4gICAgICAgIHJpZ2h0OiAtMjQuMnJlbTtcbiAgICAgICAgbGVmdDogaW5pdGlhbDsgfVxuICAgICAgLm5vLWNzc3RyYW5zZm9ybXMzZCAubWQtc2lkZWJhci0tcHJpbWFyeSB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7IH1cbiAgICAgIFtkYXRhLW1kLXRvZ2dsZT1cImRyYXdlclwiXTpjaGVja2VkIH4gLm1kLWNvbnRhaW5lciAubWQtc2lkZWJhci0tcHJpbWFyeSB7XG4gICAgICAgIGJveC1zaGFkb3c6IDAgOHB4IDEwcHggMXB4IHJnYmEoMCwgMCwgMCwgMC4xNCksIDAgM3B4IDE0cHggMnB4IHJnYmEoMCwgMCwgMCwgMC4xMiksIDAgNXB4IDVweCAtM3B4IHJnYmEoMCwgMCwgMCwgMC40KTtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDI0LjJyZW0pOyB9XG4gICAgICAgIFtkaXI9XCJydGxcIl0gW2RhdGEtbWQtdG9nZ2xlPVwiZHJhd2VyXCJdOmNoZWNrZWQgfiAubWQtY29udGFpbmVyIC5tZC1zaWRlYmFyLS1wcmltYXJ5IHtcbiAgICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTI0LjJyZW0pOyB9XG4gICAgICAgIC5uby1jc3N0cmFuc2Zvcm1zM2QgW2RhdGEtbWQtdG9nZ2xlPVwiZHJhd2VyXCJdOmNoZWNrZWQgfiAubWQtY29udGFpbmVyIC5tZC1zaWRlYmFyLS1wcmltYXJ5IHtcbiAgICAgICAgICBkaXNwbGF5OiBibG9jazsgfVxuICAgICAgLm1kLXNpZGViYXItLXByaW1hcnkgLm1kLXNpZGViYXJfX3Njcm9sbHdyYXAge1xuICAgICAgICBvdmVyZmxvdzogaGlkZGVuOyB9IH1cbiAgLm1kLXNpZGViYXItLXNlY29uZGFyeSB7XG4gICAgZGlzcGxheTogbm9uZTsgfVxuICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNjBlbSkge1xuICAgICAgLm1kLXNpZGViYXItLXNlY29uZGFyeSB7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICBtYXJnaW4tbGVmdDogMTAwJTtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTEwMCUsIDApOyB9XG4gICAgICAgIFtkaXI9XCJydGxcIl0gLm1kLXNpZGViYXItLXNlY29uZGFyeSB7XG4gICAgICAgICAgbWFyZ2luLXJpZ2h0OiAxMDAlO1xuICAgICAgICAgIG1hcmdpbi1sZWZ0OiBpbml0aWFsO1xuICAgICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlKDEwMCUsIDApOyB9IH1cbiAgICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDc2LjI1ZW0pIHtcbiAgICAgIC5tZC1zaWRlYmFyLS1zZWNvbmRhcnkge1xuICAgICAgICBtYXJnaW4tbGVmdDogMTIycmVtOyB9XG4gICAgICAgIFtkaXI9XCJydGxcIl0gLm1kLXNpZGViYXItLXNlY29uZGFyeSB7XG4gICAgICAgICAgbWFyZ2luLXJpZ2h0OiAxMjJyZW07XG4gICAgICAgICAgbWFyZ2luLWxlZnQ6IGluaXRpYWw7IH0gfVxuICAubWQtc2lkZWJhcl9fc2Nyb2xsd3JhcCB7XG4gICAgbWF4LWhlaWdodDogMTAwJTtcbiAgICBtYXJnaW46IDAgMC40cmVtO1xuICAgIG92ZXJmbG93LXk6IGF1dG87XG4gICAgYmFja2ZhY2UtdmlzaWJpbGl0eTogaGlkZGVuOyB9XG4gICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA3Ni4xODc1ZW0pIHtcbiAgICAgIC5tZC1zaWRlYmFyLS1wcmltYXJ5IC5tZC1zaWRlYmFyX19zY3JvbGx3cmFwIHtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICB0b3A6IDA7XG4gICAgICAgIHJpZ2h0OiAwO1xuICAgICAgICBib3R0b206IDA7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIG1hcmdpbjogMDsgfSB9XG4gICAgLm1kLXNpZGViYXJfX3Njcm9sbHdyYXA6Oi13ZWJraXQtc2Nyb2xsYmFyIHtcbiAgICAgIHdpZHRoOiAwLjRyZW07XG4gICAgICBoZWlnaHQ6IDAuNHJlbTsgfVxuICAgIC5tZC1zaWRlYmFyX19zY3JvbGx3cmFwOjotd2Via2l0LXNjcm9sbGJhci10aHVtYiB7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuMjYpOyB9XG4gICAgICAubWQtc2lkZWJhcl9fc2Nyb2xsd3JhcDo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWI6aG92ZXIge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjNTM2ZGZlOyB9XG5cbkBrZXlmcmFtZXMgbWQtc291cmNlX19mYWN0cy0tZG9uZSB7XG4gIDAlIHtcbiAgICBoZWlnaHQ6IDA7IH1cbiAgMTAwJSB7XG4gICAgaGVpZ2h0OiAxLjNyZW07IH0gfVxuXG5Aa2V5ZnJhbWVzIG1kLXNvdXJjZV9fZmFjdC0tZG9uZSB7XG4gIDAlIHtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoMTAwJSk7XG4gICAgb3BhY2l0eTogMDsgfVxuICA1MCUge1xuICAgIG9wYWNpdHk6IDA7IH1cbiAgMTAwJSB7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDAlKTtcbiAgICBvcGFjaXR5OiAxOyB9IH1cblxuLm1kLXNvdXJjZSB7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBwYWRkaW5nLXJpZ2h0OiAxLjJyZW07XG4gIHRyYW5zaXRpb246IG9wYWNpdHkgMC4yNXM7XG4gIGZvbnQtc2l6ZTogMS4zcmVtO1xuICBsaW5lLWhlaWdodDogMS4yO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwOyB9XG4gIFtkaXI9XCJydGxcIl0gLm1kLXNvdXJjZSB7XG4gICAgcGFkZGluZy1yaWdodDogaW5pdGlhbDtcbiAgICBwYWRkaW5nLWxlZnQ6IDEuMnJlbTsgfVxuICAubWQtc291cmNlOmhvdmVyIHtcbiAgICBvcGFjaXR5OiAwLjc7IH1cbiAgLm1kLXNvdXJjZTo6YWZ0ZXIge1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICBoZWlnaHQ6IDQuOHJlbTtcbiAgICBjb250ZW50OiBcIlwiO1xuICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7IH1cbiAgLm1kLXNvdXJjZV9faWNvbiB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIHdpZHRoOiA0LjhyZW07XG4gICAgaGVpZ2h0OiA0LjhyZW07XG4gICAgY29udGVudDogXCJcIjtcbiAgICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlOyB9XG4gICAgLm1kLXNvdXJjZV9faWNvbiBzdmcge1xuICAgICAgd2lkdGg6IDIuNHJlbTtcbiAgICAgIGhlaWdodDogMi40cmVtO1xuICAgICAgbWFyZ2luLXRvcDogMS4ycmVtO1xuICAgICAgbWFyZ2luLWxlZnQ6IDEuMnJlbTsgfVxuICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtc291cmNlX19pY29uIHN2ZyB7XG4gICAgICAgIG1hcmdpbi1yaWdodDogMS4ycmVtO1xuICAgICAgICBtYXJnaW4tbGVmdDogaW5pdGlhbDsgfVxuICAgIC5tZC1zb3VyY2VfX2ljb24gKyAubWQtc291cmNlX19yZXBvc2l0b3J5IHtcbiAgICAgIG1hcmdpbi1sZWZ0OiAtNC40cmVtO1xuICAgICAgcGFkZGluZy1sZWZ0OiA0cmVtOyB9XG4gICAgICBbZGlyPVwicnRsXCJdIC5tZC1zb3VyY2VfX2ljb24gKyAubWQtc291cmNlX19yZXBvc2l0b3J5IHtcbiAgICAgICAgbWFyZ2luLXJpZ2h0OiAtNC40cmVtO1xuICAgICAgICBtYXJnaW4tbGVmdDogaW5pdGlhbDtcbiAgICAgICAgcGFkZGluZy1yaWdodDogNHJlbTtcbiAgICAgICAgcGFkZGluZy1sZWZ0OiBpbml0aWFsOyB9XG4gIC5tZC1zb3VyY2VfX3JlcG9zaXRvcnkge1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICBtYXgtd2lkdGg6IDEwMCU7XG4gICAgbWFyZ2luLWxlZnQ6IDEuMnJlbTtcbiAgICBmb250LXdlaWdodDogNzAwO1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgdmVydGljYWwtYWxpZ246IG1pZGRsZTsgfVxuICAubWQtc291cmNlX19mYWN0cyB7XG4gICAgbWFyZ2luOiAwO1xuICAgIHBhZGRpbmc6IDA7XG4gICAgZm9udC1zaXplOiAxLjFyZW07XG4gICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICBsaXN0LXN0eWxlLXR5cGU6IG5vbmU7XG4gICAgb3BhY2l0eTogMC43NTtcbiAgICBvdmVyZmxvdzogaGlkZGVuOyB9XG4gICAgW2RhdGEtbWQtc3RhdGU9XCJkb25lXCJdIC5tZC1zb3VyY2VfX2ZhY3RzIHtcbiAgICAgIGFuaW1hdGlvbjogbWQtc291cmNlX19mYWN0cy0tZG9uZSAwLjI1cyBlYXNlLWluOyB9XG4gIC5tZC1zb3VyY2VfX2ZhY3Qge1xuICAgIGZsb2F0OiBsZWZ0OyB9XG4gICAgW2Rpcj1cInJ0bFwiXSAubWQtc291cmNlX19mYWN0IHtcbiAgICAgIGZsb2F0OiByaWdodDsgfVxuICAgIFtkYXRhLW1kLXN0YXRlPVwiZG9uZVwiXSAubWQtc291cmNlX19mYWN0IHtcbiAgICAgIGFuaW1hdGlvbjogbWQtc291cmNlX19mYWN0LS1kb25lIDAuNHMgZWFzZS1vdXQ7IH1cbiAgICAubWQtc291cmNlX19mYWN0OjpiZWZvcmUge1xuICAgICAgbWFyZ2luOiAwIDAuMnJlbTtcbiAgICAgIGNvbnRlbnQ6IFwiXFwwMEI3XCI7IH1cbiAgICAubWQtc291cmNlX19mYWN0OmZpcnN0LWNoaWxkOjpiZWZvcmUge1xuICAgICAgZGlzcGxheTogbm9uZTsgfVxuXG4ubWQtc291cmNlLWZpbGUge1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIG1hcmdpbjogMWVtIDAuNWVtIDFlbSAwO1xuICBwYWRkaW5nLXJpZ2h0OiAwLjVyZW07XG4gIGJvcmRlci1yYWRpdXM6IDAuMnJlbTtcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjA3KTtcbiAgZm9udC1zaXplOiAxLjI4cmVtO1xuICBsaXN0LXN0eWxlLXR5cGU6IG5vbmU7XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgb3ZlcmZsb3c6IGhpZGRlbjsgfVxuICAubWQtc291cmNlLWZpbGU6OmJlZm9yZSB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIG1hcmdpbi1yaWdodDogMC41cmVtO1xuICAgIHBhZGRpbmc6IDAuNXJlbTtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuMjYpO1xuICAgIGNvbG9yOiB3aGl0ZTtcbiAgICBmb250LXNpemU6IDEuNnJlbTtcbiAgICBjb250ZW50OiBcIlxcRTg2RlwiO1xuICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7IH1cbiAgaHRtbCAubWQtc291cmNlLWZpbGUge1xuICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQgMC40cywgY29sb3IgMC40cywgYm94LXNoYWRvdyAwLjRzIGN1YmljLWJlemllcigwLjQsIDAsIDAuMiwgMSk7IH1cbiAgICBodG1sIC5tZC1zb3VyY2UtZmlsZTo6YmVmb3JlIHtcbiAgICAgIHRyYW5zaXRpb246IGluaGVyaXQ7IH1cbiAgaHRtbCBib2R5IC5tZC10eXBlc2V0IC5tZC1zb3VyY2UtZmlsZSB7XG4gICAgY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41NCk7IH1cbiAgLm1kLXNvdXJjZS1maWxlOmhvdmVyIHtcbiAgICBib3gtc2hhZG93OiAwIDAgOHB4IHJnYmEoMCwgMCwgMCwgMC4xOCksIDAgOHB4IDE2cHggcmdiYSgwLCAwLCAwLCAwLjM2KTsgfVxuICAgIC5tZC1zb3VyY2UtZmlsZTpob3Zlcjo6YmVmb3JlIHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICM1MzZkZmU7IH1cblxuLm1kLXRhYnMge1xuICB3aWR0aDogMTAwJTtcbiAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCAwLjI1cztcbiAgYmFja2dyb3VuZC1jb2xvcjogIzNmNTFiNTtcbiAgY29sb3I6IHdoaXRlO1xuICBvdmVyZmxvdzogYXV0bzsgfVxuICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDc2LjE4NzVlbSkge1xuICAgIC5tZC10YWJzIHtcbiAgICAgIGRpc3BsYXk6IG5vbmU7IH0gfVxuICBAbWVkaWEgcHJpbnQge1xuICAgIC5tZC10YWJzIHtcbiAgICAgIGRpc3BsYXk6IG5vbmU7IH0gfVxuICAubWQtdGFic19fbGlzdCB7XG4gICAgbWFyZ2luOiAwO1xuICAgIG1hcmdpbi1sZWZ0OiAwLjRyZW07XG4gICAgcGFkZGluZzogMDtcbiAgICBsaXN0LXN0eWxlOiBub25lO1xuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7IH1cbiAgLm1kLXRhYnNfX2l0ZW0ge1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICBoZWlnaHQ6IDQuOHJlbTtcbiAgICBwYWRkaW5nLXJpZ2h0OiAxLjJyZW07XG4gICAgcGFkZGluZy1sZWZ0OiAxLjJyZW07IH1cbiAgLm1kLXRhYnNfX2xpbmsge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIG1hcmdpbi10b3A6IDEuNnJlbTtcbiAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC40cyBjdWJpYy1iZXppZXIoMC4xLCAwLjcsIDAuMSwgMSksIG9wYWNpdHkgMC4yNXM7XG4gICAgZm9udC1zaXplOiAxLjRyZW07XG4gICAgb3BhY2l0eTogMC43OyB9XG4gICAgLm1kLXRhYnNfX2xpbmstLWFjdGl2ZSwgLm1kLXRhYnNfX2xpbms6aG92ZXIge1xuICAgICAgY29sb3I6IGluaGVyaXQ7XG4gICAgICBvcGFjaXR5OiAxOyB9XG4gICAgLm1kLXRhYnNfX2l0ZW06bnRoLWNoaWxkKDIpIC5tZC10YWJzX19saW5rIHtcbiAgICAgIHRyYW5zaXRpb24tZGVsYXk6IDAuMDJzOyB9XG4gICAgLm1kLXRhYnNfX2l0ZW06bnRoLWNoaWxkKDMpIC5tZC10YWJzX19saW5rIHtcbiAgICAgIHRyYW5zaXRpb24tZGVsYXk6IDAuMDRzOyB9XG4gICAgLm1kLXRhYnNfX2l0ZW06bnRoLWNoaWxkKDQpIC5tZC10YWJzX19saW5rIHtcbiAgICAgIHRyYW5zaXRpb24tZGVsYXk6IDAuMDZzOyB9XG4gICAgLm1kLXRhYnNfX2l0ZW06bnRoLWNoaWxkKDUpIC5tZC10YWJzX19saW5rIHtcbiAgICAgIHRyYW5zaXRpb24tZGVsYXk6IDAuMDhzOyB9XG4gICAgLm1kLXRhYnNfX2l0ZW06bnRoLWNoaWxkKDYpIC5tZC10YWJzX19saW5rIHtcbiAgICAgIHRyYW5zaXRpb24tZGVsYXk6IDAuMXM7IH1cbiAgICAubWQtdGFic19faXRlbTpudGgtY2hpbGQoNykgLm1kLXRhYnNfX2xpbmsge1xuICAgICAgdHJhbnNpdGlvbi1kZWxheTogMC4xMnM7IH1cbiAgICAubWQtdGFic19faXRlbTpudGgtY2hpbGQoOCkgLm1kLXRhYnNfX2xpbmsge1xuICAgICAgdHJhbnNpdGlvbi1kZWxheTogMC4xNHM7IH1cbiAgICAubWQtdGFic19faXRlbTpudGgtY2hpbGQoOSkgLm1kLXRhYnNfX2xpbmsge1xuICAgICAgdHJhbnNpdGlvbi1kZWxheTogMC4xNnM7IH1cbiAgICAubWQtdGFic19faXRlbTpudGgtY2hpbGQoMTApIC5tZC10YWJzX19saW5rIHtcbiAgICAgIHRyYW5zaXRpb24tZGVsYXk6IDAuMThzOyB9XG4gICAgLm1kLXRhYnNfX2l0ZW06bnRoLWNoaWxkKDExKSAubWQtdGFic19fbGluayB7XG4gICAgICB0cmFuc2l0aW9uLWRlbGF5OiAwLjJzOyB9XG4gICAgLm1kLXRhYnNfX2l0ZW06bnRoLWNoaWxkKDEyKSAubWQtdGFic19fbGluayB7XG4gICAgICB0cmFuc2l0aW9uLWRlbGF5OiAwLjIyczsgfVxuICAgIC5tZC10YWJzX19pdGVtOm50aC1jaGlsZCgxMykgLm1kLXRhYnNfX2xpbmsge1xuICAgICAgdHJhbnNpdGlvbi1kZWxheTogMC4yNHM7IH1cbiAgICAubWQtdGFic19faXRlbTpudGgtY2hpbGQoMTQpIC5tZC10YWJzX19saW5rIHtcbiAgICAgIHRyYW5zaXRpb24tZGVsYXk6IDAuMjZzOyB9XG4gICAgLm1kLXRhYnNfX2l0ZW06bnRoLWNoaWxkKDE1KSAubWQtdGFic19fbGluayB7XG4gICAgICB0cmFuc2l0aW9uLWRlbGF5OiAwLjI4czsgfVxuICAgIC5tZC10YWJzX19pdGVtOm50aC1jaGlsZCgxNikgLm1kLXRhYnNfX2xpbmsge1xuICAgICAgdHJhbnNpdGlvbi1kZWxheTogMC4zczsgfVxuICAubWQtdGFic1tkYXRhLW1kLXN0YXRlPVwiaGlkZGVuXCJdIHtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTsgfVxuICAgIC5tZC10YWJzW2RhdGEtbWQtc3RhdGU9XCJoaWRkZW5cIl0gLm1kLXRhYnNfX2xpbmsge1xuICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDUwJSk7XG4gICAgICB0cmFuc2l0aW9uOiBjb2xvciAgICAgMC4yNXMsIHRyYW5zZm9ybSAwcyAwLjRzLCBvcGFjaXR5ICAgMC4xcztcbiAgICAgIG9wYWNpdHk6IDA7IH1cbiAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA3Ni4yNWVtKSB7XG4gICAgLm1kLXRhYnMgfiAubWQtbWFpbiAubWQtbmF2LS1wcmltYXJ5ID4gLm1kLW5hdl9fbGlzdCA+IC5tZC1uYXZfX2l0ZW0tLW5lc3RlZCB7XG4gICAgICBmb250LXNpemU6IDA7XG4gICAgICB2aXNpYmlsaXR5OiBoaWRkZW47IH1cbiAgICAubWQtdGFicy0tYWN0aXZlIH4gLm1kLW1haW4gLm1kLW5hdi0tcHJpbWFyeSAubWQtbmF2X190aXRsZSB7XG4gICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgIHBhZGRpbmc6IDA7IH1cbiAgICAubWQtdGFicy0tYWN0aXZlIH4gLm1kLW1haW4gLm1kLW5hdi0tcHJpbWFyeSAubWQtbmF2X190aXRsZS0tc2l0ZSB7XG4gICAgICBkaXNwbGF5OiBub25lOyB9XG4gICAgLm5vLWpzIC5tZC10YWJzLS1hY3RpdmUgfiAubWQtbWFpbiAubWQtbmF2LS1wcmltYXJ5IC5tZC1uYXYge1xuICAgICAgZGlzcGxheTogYmxvY2s7IH1cbiAgICAubWQtdGFicy0tYWN0aXZlIH4gLm1kLW1haW4gLm1kLW5hdi0tcHJpbWFyeSA+IC5tZC1uYXZfX2xpc3QgPiAubWQtbmF2X19pdGVtIHtcbiAgICAgIGZvbnQtc2l6ZTogMDtcbiAgICAgIHZpc2liaWxpdHk6IGhpZGRlbjsgfVxuICAgICAgLm1kLXRhYnMtLWFjdGl2ZSB+IC5tZC1tYWluIC5tZC1uYXYtLXByaW1hcnkgPiAubWQtbmF2X19saXN0ID4gLm1kLW5hdl9faXRlbS0tbmVzdGVkIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICAgICAgZm9udC1zaXplOiAxLjRyZW07XG4gICAgICAgIG92ZXJmbG93OiBhdXRvO1xuICAgICAgICB2aXNpYmlsaXR5OiB2aXNpYmxlOyB9XG4gICAgICAgIC5tZC10YWJzLS1hY3RpdmUgfiAubWQtbWFpbiAubWQtbmF2LS1wcmltYXJ5ID4gLm1kLW5hdl9fbGlzdCA+IC5tZC1uYXZfX2l0ZW0tLW5lc3RlZCA+IC5tZC1uYXZfX2xpbmsge1xuICAgICAgICAgIGRpc3BsYXk6IG5vbmU7IH1cbiAgICAgIC5tZC10YWJzLS1hY3RpdmUgfiAubWQtbWFpbiAubWQtbmF2LS1wcmltYXJ5ID4gLm1kLW5hdl9fbGlzdCA+IC5tZC1uYXZfX2l0ZW0tLWFjdGl2ZSB7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrOyB9XG4gICAgLm1kLXRhYnMtLWFjdGl2ZSB+IC5tZC1tYWluIC5tZC1uYXZbZGF0YS1tZC1sZXZlbD1cIjFcIl0ge1xuICAgICAgbWF4LWhlaWdodDogaW5pdGlhbDtcbiAgICAgIG92ZXJmbG93OiB2aXNpYmxlOyB9XG4gICAgICAubWQtdGFicy0tYWN0aXZlIH4gLm1kLW1haW4gLm1kLW5hdltkYXRhLW1kLWxldmVsPVwiMVwiXSA+IC5tZC1uYXZfX2xpc3QgPiAubWQtbmF2X19pdGVtIHtcbiAgICAgICAgcGFkZGluZy1sZWZ0OiAwOyB9XG4gICAgICAubWQtdGFicy0tYWN0aXZlIH4gLm1kLW1haW4gLm1kLW5hdltkYXRhLW1kLWxldmVsPVwiMVwiXSAubWQtbmF2IC5tZC1uYXZfX3RpdGxlIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTsgfSB9XG5cbi5tZC10eXBlc2V0IC5hZG1vbml0aW9uLCAubWQtdHlwZXNldCBkZXRhaWxzIHtcbiAgYm94LXNoYWRvdzogMCAycHggMnB4IDAgcmdiYSgwLCAwLCAwLCAwLjE0KSwgMCAxcHggNXB4IDAgcmdiYSgwLCAwLCAwLCAwLjEyKSwgMCAzcHggMXB4IC0ycHggcmdiYSgwLCAwLCAwLCAwLjIpO1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIG1hcmdpbjogMS41NjI1ZW0gMDtcbiAgcGFkZGluZzogMCAxLjJyZW07XG4gIGJvcmRlci1sZWZ0OiAwLjRyZW0gc29saWQgIzQ0OGFmZjtcbiAgYm9yZGVyLXJhZGl1czogMC4ycmVtO1xuICBmb250LXNpemU6IDEuMjhyZW07XG4gIG92ZXJmbG93OiBhdXRvOyB9XG4gIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24sIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgZGV0YWlscyB7XG4gICAgYm9yZGVyLXJpZ2h0OiAwLjRyZW0gc29saWQgIzQ0OGFmZjtcbiAgICBib3JkZXItbGVmdDogbm9uZTsgfVxuICBodG1sIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uID4gOmxhc3QtY2hpbGQsIGh0bWwgLm1kLXR5cGVzZXQgZGV0YWlscyA+IDpsYXN0LWNoaWxkIHtcbiAgICBtYXJnaW4tYm90dG9tOiAxLjJyZW07IH1cbiAgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24gLmFkbW9uaXRpb24sIC5tZC10eXBlc2V0IGRldGFpbHMgLmFkbW9uaXRpb24sIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uIGRldGFpbHMsIC5tZC10eXBlc2V0IGRldGFpbHMgZGV0YWlscyB7XG4gICAgbWFyZ2luOiAxZW0gMDsgfVxuICAubWQtdHlwZXNldCAuYWRtb25pdGlvbiA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCBkZXRhaWxzID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uID4gc3VtbWFyeSwgLm1kLXR5cGVzZXQgZGV0YWlscyA+IHN1bW1hcnkge1xuICAgIG1hcmdpbjogMCAtMS4ycmVtO1xuICAgIHBhZGRpbmc6IDAuOHJlbSAxLjJyZW0gMC44cmVtIDRyZW07XG4gICAgYm9yZGVyLWJvdHRvbTogMC4xcmVtIHNvbGlkIHJnYmEoNjgsIDEzOCwgMjU1LCAwLjEpO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoNjgsIDEzOCwgMjU1LCAwLjEpO1xuICAgIGZvbnQtd2VpZ2h0OiA3MDA7IH1cbiAgICBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uID4gLmFkbW9uaXRpb24tdGl0bGUsIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgZGV0YWlscyA+IC5hZG1vbml0aW9uLXRpdGxlLCBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uID4gc3VtbWFyeSwgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCBkZXRhaWxzID4gc3VtbWFyeSB7XG4gICAgICBwYWRkaW5nOiAwLjhyZW0gNHJlbSAwLjhyZW0gMS4ycmVtOyB9XG4gICAgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24gPiAuYWRtb25pdGlvbi10aXRsZTpsYXN0LWNoaWxkLCAubWQtdHlwZXNldCBkZXRhaWxzID4gLmFkbW9uaXRpb24tdGl0bGU6bGFzdC1jaGlsZCwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24gPiBzdW1tYXJ5Omxhc3QtY2hpbGQsIC5tZC10eXBlc2V0IGRldGFpbHMgPiBzdW1tYXJ5Omxhc3QtY2hpbGQge1xuICAgICAgbWFyZ2luLWJvdHRvbTogMDsgfVxuICAgIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscyA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCBkZXRhaWxzID4gc3VtbWFyeTo6YmVmb3JlIHtcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgIGxlZnQ6IDEuMnJlbTtcbiAgICAgIGNvbG9yOiAjNDQ4YWZmO1xuICAgICAgZm9udC1zaXplOiAycmVtO1xuICAgICAgY29udGVudDogXCJcXEUzQzlcIjsgfVxuICAgICAgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCAuYWRtb25pdGlvbiA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgZGV0YWlscyA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24gPiBzdW1tYXJ5OjpiZWZvcmUsIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgZGV0YWlscyA+IHN1bW1hcnk6OmJlZm9yZSB7XG4gICAgICAgIHJpZ2h0OiAxLjJyZW07XG4gICAgICAgIGxlZnQ6IGluaXRpYWw7IH1cbiAgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uc3VtbWFyeSwgLm1kLXR5cGVzZXQgZGV0YWlscy5zdW1tYXJ5LCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi50bGRyLCAubWQtdHlwZXNldCBkZXRhaWxzLnRsZHIsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmFic3RyYWN0LCAubWQtdHlwZXNldCBkZXRhaWxzLmFic3RyYWN0IHtcbiAgICBib3JkZXItbGVmdC1jb2xvcjogIzAwYjBmZjsgfVxuICAgIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uc3VtbWFyeSwgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCBkZXRhaWxzLnN1bW1hcnksIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24udGxkciwgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCBkZXRhaWxzLnRsZHIsIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uYWJzdHJhY3QsIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgZGV0YWlscy5hYnN0cmFjdCB7XG4gICAgICBib3JkZXItcmlnaHQtY29sb3I6ICMwMGIwZmY7IH1cbiAgICAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5zdW1tYXJ5ID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IGRldGFpbHMuc3VtbWFyeSA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi50bGRyID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IGRldGFpbHMudGxkciA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5zdW1tYXJ5ID4gc3VtbWFyeSwgLm1kLXR5cGVzZXQgZGV0YWlscy5zdW1tYXJ5ID4gc3VtbWFyeSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24udGxkciA+IHN1bW1hcnksIC5tZC10eXBlc2V0IGRldGFpbHMudGxkciA+IHN1bW1hcnksIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmFic3RyYWN0ID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IGRldGFpbHMuYWJzdHJhY3QgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uYWJzdHJhY3QgPiBzdW1tYXJ5LCAubWQtdHlwZXNldCBkZXRhaWxzLmFic3RyYWN0ID4gc3VtbWFyeSB7XG4gICAgICBib3JkZXItYm90dG9tLWNvbG9yOiAwLjFyZW0gc29saWQgcmdiYSgwLCAxNzYsIDI1NSwgMC4xKTtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMTc2LCAyNTUsIDAuMSk7IH1cbiAgICAgIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLnN1bW1hcnkgPiAuYWRtb25pdGlvbi10aXRsZTo6YmVmb3JlLCAubWQtdHlwZXNldCBkZXRhaWxzLnN1bW1hcnkgPiAuYWRtb25pdGlvbi10aXRsZTo6YmVmb3JlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi50bGRyID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy50bGRyID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uc3VtbWFyeSA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5zdW1tYXJ5ID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi50bGRyID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCBkZXRhaWxzLnRsZHIgPiBzdW1tYXJ5OjpiZWZvcmUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmFic3RyYWN0ID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5hYnN0cmFjdCA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmFic3RyYWN0ID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCBkZXRhaWxzLmFic3RyYWN0ID4gc3VtbWFyeTo6YmVmb3JlIHtcbiAgICAgICAgY29sb3I6ICMwMGIwZmY7XG4gICAgICAgIGNvbnRlbnQ6IFwi7qOSXCI7IH1cbiAgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24udG9kbywgLm1kLXR5cGVzZXQgZGV0YWlscy50b2RvLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5pbmZvLCAubWQtdHlwZXNldCBkZXRhaWxzLmluZm8ge1xuICAgIGJvcmRlci1sZWZ0LWNvbG9yOiAjMDBiOGQ0OyB9XG4gICAgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCAuYWRtb25pdGlvbi50b2RvLCBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IGRldGFpbHMudG9kbywgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5pbmZvLCBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IGRldGFpbHMuaW5mbyB7XG4gICAgICBib3JkZXItcmlnaHQtY29sb3I6ICMwMGI4ZDQ7IH1cbiAgICAubWQtdHlwZXNldCAuYWRtb25pdGlvbi50b2RvID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IGRldGFpbHMudG9kbyA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi50b2RvID4gc3VtbWFyeSwgLm1kLXR5cGVzZXQgZGV0YWlscy50b2RvID4gc3VtbWFyeSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uaW5mbyA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCBkZXRhaWxzLmluZm8gPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uaW5mbyA+IHN1bW1hcnksIC5tZC10eXBlc2V0IGRldGFpbHMuaW5mbyA+IHN1bW1hcnkge1xuICAgICAgYm9yZGVyLWJvdHRvbS1jb2xvcjogMC4xcmVtIHNvbGlkIHJnYmEoMCwgMTg0LCAyMTIsIDAuMSk7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsIDE4NCwgMjEyLCAwLjEpOyB9XG4gICAgICAubWQtdHlwZXNldCAuYWRtb25pdGlvbi50b2RvID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy50b2RvID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24udG9kbyA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy50b2RvID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5pbmZvID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5pbmZvID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uaW5mbyA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5pbmZvID4gc3VtbWFyeTo6YmVmb3JlIHtcbiAgICAgICAgY29sb3I6ICMwMGI4ZDQ7XG4gICAgICAgIGNvbnRlbnQ6IFwi7qKOXCI7IH1cbiAgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uaGludCwgLm1kLXR5cGVzZXQgZGV0YWlscy5oaW50LCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5pbXBvcnRhbnQsIC5tZC10eXBlc2V0IGRldGFpbHMuaW1wb3J0YW50LCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi50aXAsIC5tZC10eXBlc2V0IGRldGFpbHMudGlwIHtcbiAgICBib3JkZXItbGVmdC1jb2xvcjogIzAwYmZhNTsgfVxuICAgIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uaGludCwgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCBkZXRhaWxzLmhpbnQsIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uaW1wb3J0YW50LCBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IGRldGFpbHMuaW1wb3J0YW50LCBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLnRpcCwgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCBkZXRhaWxzLnRpcCB7XG4gICAgICBib3JkZXItcmlnaHQtY29sb3I6ICMwMGJmYTU7IH1cbiAgICAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5oaW50ID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IGRldGFpbHMuaGludCA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5pbXBvcnRhbnQgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5pbXBvcnRhbnQgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uaGludCA+IHN1bW1hcnksIC5tZC10eXBlc2V0IGRldGFpbHMuaGludCA+IHN1bW1hcnksIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmltcG9ydGFudCA+IHN1bW1hcnksIC5tZC10eXBlc2V0IGRldGFpbHMuaW1wb3J0YW50ID4gc3VtbWFyeSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24udGlwID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IGRldGFpbHMudGlwID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLnRpcCA+IHN1bW1hcnksIC5tZC10eXBlc2V0IGRldGFpbHMudGlwID4gc3VtbWFyeSB7XG4gICAgICBib3JkZXItYm90dG9tLWNvbG9yOiAwLjFyZW0gc29saWQgcmdiYSgwLCAxOTEsIDE2NSwgMC4xKTtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMTkxLCAxNjUsIDAuMSk7IH1cbiAgICAgIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmhpbnQgPiAuYWRtb25pdGlvbi10aXRsZTo6YmVmb3JlLCAubWQtdHlwZXNldCBkZXRhaWxzLmhpbnQgPiAuYWRtb25pdGlvbi10aXRsZTo6YmVmb3JlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5pbXBvcnRhbnQgPiAuYWRtb25pdGlvbi10aXRsZTo6YmVmb3JlLCAubWQtdHlwZXNldCBkZXRhaWxzLmltcG9ydGFudCA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmhpbnQgPiBzdW1tYXJ5OjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMuaGludCA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uaW1wb3J0YW50ID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCBkZXRhaWxzLmltcG9ydGFudCA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24udGlwID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy50aXAgPiAuYWRtb25pdGlvbi10aXRsZTo6YmVmb3JlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi50aXAgPiBzdW1tYXJ5OjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMudGlwID4gc3VtbWFyeTo6YmVmb3JlIHtcbiAgICAgICAgY29sb3I6ICMwMGJmYTU7XG4gICAgICAgIGNvbnRlbnQ6IFwi7qCOXCI7IH1cbiAgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uY2hlY2ssIC5tZC10eXBlc2V0IGRldGFpbHMuY2hlY2ssIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmRvbmUsIC5tZC10eXBlc2V0IGRldGFpbHMuZG9uZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uc3VjY2VzcywgLm1kLXR5cGVzZXQgZGV0YWlscy5zdWNjZXNzIHtcbiAgICBib3JkZXItbGVmdC1jb2xvcjogIzAwYzg1MzsgfVxuICAgIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uY2hlY2ssIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgZGV0YWlscy5jaGVjaywgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5kb25lLCBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IGRldGFpbHMuZG9uZSwgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5zdWNjZXNzLCBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IGRldGFpbHMuc3VjY2VzcyB7XG4gICAgICBib3JkZXItcmlnaHQtY29sb3I6ICMwMGM4NTM7IH1cbiAgICAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5jaGVjayA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCBkZXRhaWxzLmNoZWNrID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmRvbmUgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5kb25lID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmNoZWNrID4gc3VtbWFyeSwgLm1kLXR5cGVzZXQgZGV0YWlscy5jaGVjayA+IHN1bW1hcnksIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmRvbmUgPiBzdW1tYXJ5LCAubWQtdHlwZXNldCBkZXRhaWxzLmRvbmUgPiBzdW1tYXJ5LCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5zdWNjZXNzID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IGRldGFpbHMuc3VjY2VzcyA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5zdWNjZXNzID4gc3VtbWFyeSwgLm1kLXR5cGVzZXQgZGV0YWlscy5zdWNjZXNzID4gc3VtbWFyeSB7XG4gICAgICBib3JkZXItYm90dG9tLWNvbG9yOiAwLjFyZW0gc29saWQgcmdiYSgwLCAyMDAsIDgzLCAwLjEpO1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAyMDAsIDgzLCAwLjEpOyB9XG4gICAgICAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5jaGVjayA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMuY2hlY2sgPiAuYWRtb25pdGlvbi10aXRsZTo6YmVmb3JlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5kb25lID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5kb25lID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uY2hlY2sgPiBzdW1tYXJ5OjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMuY2hlY2sgPiBzdW1tYXJ5OjpiZWZvcmUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmRvbmUgPiBzdW1tYXJ5OjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMuZG9uZSA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uc3VjY2VzcyA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMuc3VjY2VzcyA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLnN1Y2Nlc3MgPiBzdW1tYXJ5OjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMuc3VjY2VzcyA+IHN1bW1hcnk6OmJlZm9yZSB7XG4gICAgICAgIGNvbG9yOiAjMDBjODUzO1xuICAgICAgICBjb250ZW50OiBcIu6htlwiOyB9XG4gIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmhlbHAsIC5tZC10eXBlc2V0IGRldGFpbHMuaGVscCwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uZmFxLCAubWQtdHlwZXNldCBkZXRhaWxzLmZhcSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24ucXVlc3Rpb24sIC5tZC10eXBlc2V0IGRldGFpbHMucXVlc3Rpb24ge1xuICAgIGJvcmRlci1sZWZ0LWNvbG9yOiAjNjRkZDE3OyB9XG4gICAgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5oZWxwLCBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IGRldGFpbHMuaGVscCwgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5mYXEsIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgZGV0YWlscy5mYXEsIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24ucXVlc3Rpb24sIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgZGV0YWlscy5xdWVzdGlvbiB7XG4gICAgICBib3JkZXItcmlnaHQtY29sb3I6ICM2NGRkMTc7IH1cbiAgICAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5oZWxwID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IGRldGFpbHMuaGVscCA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5mYXEgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5mYXEgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uaGVscCA+IHN1bW1hcnksIC5tZC10eXBlc2V0IGRldGFpbHMuaGVscCA+IHN1bW1hcnksIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmZhcSA+IHN1bW1hcnksIC5tZC10eXBlc2V0IGRldGFpbHMuZmFxID4gc3VtbWFyeSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24ucXVlc3Rpb24gPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5xdWVzdGlvbiA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5xdWVzdGlvbiA+IHN1bW1hcnksIC5tZC10eXBlc2V0IGRldGFpbHMucXVlc3Rpb24gPiBzdW1tYXJ5IHtcbiAgICAgIGJvcmRlci1ib3R0b20tY29sb3I6IDAuMXJlbSBzb2xpZCByZ2JhKDEwMCwgMjIxLCAyMywgMC4xKTtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMTAwLCAyMjEsIDIzLCAwLjEpOyB9XG4gICAgICAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5oZWxwID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5oZWxwID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uZmFxID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5mYXEgPiAuYWRtb25pdGlvbi10aXRsZTo6YmVmb3JlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5oZWxwID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCBkZXRhaWxzLmhlbHAgPiBzdW1tYXJ5OjpiZWZvcmUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmZhcSA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5mYXEgPiBzdW1tYXJ5OjpiZWZvcmUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLnF1ZXN0aW9uID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5xdWVzdGlvbiA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLnF1ZXN0aW9uID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCBkZXRhaWxzLnF1ZXN0aW9uID4gc3VtbWFyeTo6YmVmb3JlIHtcbiAgICAgICAgY29sb3I6ICM2NGRkMTc7XG4gICAgICAgIGNvbnRlbnQ6IFwi7qKHXCI7IH1cbiAgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uY2F1dGlvbiwgLm1kLXR5cGVzZXQgZGV0YWlscy5jYXV0aW9uLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5hdHRlbnRpb24sIC5tZC10eXBlc2V0IGRldGFpbHMuYXR0ZW50aW9uLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi53YXJuaW5nLCAubWQtdHlwZXNldCBkZXRhaWxzLndhcm5pbmcge1xuICAgIGJvcmRlci1sZWZ0LWNvbG9yOiAjZmY5MTAwOyB9XG4gICAgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5jYXV0aW9uLCBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IGRldGFpbHMuY2F1dGlvbiwgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5hdHRlbnRpb24sIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgZGV0YWlscy5hdHRlbnRpb24sIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24ud2FybmluZywgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCBkZXRhaWxzLndhcm5pbmcge1xuICAgICAgYm9yZGVyLXJpZ2h0LWNvbG9yOiAjZmY5MTAwOyB9XG4gICAgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uY2F1dGlvbiA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCBkZXRhaWxzLmNhdXRpb24gPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uYXR0ZW50aW9uID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IGRldGFpbHMuYXR0ZW50aW9uID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmNhdXRpb24gPiBzdW1tYXJ5LCAubWQtdHlwZXNldCBkZXRhaWxzLmNhdXRpb24gPiBzdW1tYXJ5LCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5hdHRlbnRpb24gPiBzdW1tYXJ5LCAubWQtdHlwZXNldCBkZXRhaWxzLmF0dGVudGlvbiA+IHN1bW1hcnksIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLndhcm5pbmcgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgZGV0YWlscy53YXJuaW5nID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLndhcm5pbmcgPiBzdW1tYXJ5LCAubWQtdHlwZXNldCBkZXRhaWxzLndhcm5pbmcgPiBzdW1tYXJ5IHtcbiAgICAgIGJvcmRlci1ib3R0b20tY29sb3I6IDAuMXJlbSBzb2xpZCByZ2JhKDI1NSwgMTQ1LCAwLCAwLjEpO1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyNTUsIDE0NSwgMCwgMC4xKTsgfVxuICAgICAgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uY2F1dGlvbiA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMuY2F1dGlvbiA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmF0dGVudGlvbiA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMuYXR0ZW50aW9uID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uY2F1dGlvbiA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5jYXV0aW9uID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5hdHRlbnRpb24gPiBzdW1tYXJ5OjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMuYXR0ZW50aW9uID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi53YXJuaW5nID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy53YXJuaW5nID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24ud2FybmluZyA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy53YXJuaW5nID4gc3VtbWFyeTo6YmVmb3JlIHtcbiAgICAgICAgY29sb3I6ICNmZjkxMDA7XG4gICAgICAgIGNvbnRlbnQ6IFwi7oCCXCI7IH1cbiAgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uZmFpbCwgLm1kLXR5cGVzZXQgZGV0YWlscy5mYWlsLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5taXNzaW5nLCAubWQtdHlwZXNldCBkZXRhaWxzLm1pc3NpbmcsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmZhaWx1cmUsIC5tZC10eXBlc2V0IGRldGFpbHMuZmFpbHVyZSB7XG4gICAgYm9yZGVyLWxlZnQtY29sb3I6ICNmZjUyNTI7IH1cbiAgICBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmZhaWwsIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgZGV0YWlscy5mYWlsLCBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLm1pc3NpbmcsIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgZGV0YWlscy5taXNzaW5nLCBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmZhaWx1cmUsIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgZGV0YWlscy5mYWlsdXJlIHtcbiAgICAgIGJvcmRlci1yaWdodC1jb2xvcjogI2ZmNTI1MjsgfVxuICAgIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmZhaWwgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5mYWlsID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLm1pc3NpbmcgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5taXNzaW5nID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmZhaWwgPiBzdW1tYXJ5LCAubWQtdHlwZXNldCBkZXRhaWxzLmZhaWwgPiBzdW1tYXJ5LCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5taXNzaW5nID4gc3VtbWFyeSwgLm1kLXR5cGVzZXQgZGV0YWlscy5taXNzaW5nID4gc3VtbWFyeSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uZmFpbHVyZSA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCBkZXRhaWxzLmZhaWx1cmUgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uZmFpbHVyZSA+IHN1bW1hcnksIC5tZC10eXBlc2V0IGRldGFpbHMuZmFpbHVyZSA+IHN1bW1hcnkge1xuICAgICAgYm9yZGVyLWJvdHRvbS1jb2xvcjogMC4xcmVtIHNvbGlkIHJnYmEoMjU1LCA4MiwgODIsIDAuMSk7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgODIsIDgyLCAwLjEpOyB9XG4gICAgICAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5mYWlsID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5mYWlsID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24ubWlzc2luZyA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMubWlzc2luZyA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmZhaWwgPiBzdW1tYXJ5OjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMuZmFpbCA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24ubWlzc2luZyA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5taXNzaW5nID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5mYWlsdXJlID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5mYWlsdXJlID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uZmFpbHVyZSA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5mYWlsdXJlID4gc3VtbWFyeTo6YmVmb3JlIHtcbiAgICAgICAgY29sb3I6ICNmZjUyNTI7XG4gICAgICAgIGNvbnRlbnQ6IFwi7oWMXCI7IH1cbiAgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uZXJyb3IsIC5tZC10eXBlc2V0IGRldGFpbHMuZXJyb3IsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmRhbmdlciwgLm1kLXR5cGVzZXQgZGV0YWlscy5kYW5nZXIge1xuICAgIGJvcmRlci1sZWZ0LWNvbG9yOiAjZmYxNzQ0OyB9XG4gICAgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5lcnJvciwgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCBkZXRhaWxzLmVycm9yLCBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmRhbmdlciwgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCBkZXRhaWxzLmRhbmdlciB7XG4gICAgICBib3JkZXItcmlnaHQtY29sb3I6ICNmZjE3NDQ7IH1cbiAgICAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5lcnJvciA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCBkZXRhaWxzLmVycm9yID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmVycm9yID4gc3VtbWFyeSwgLm1kLXR5cGVzZXQgZGV0YWlscy5lcnJvciA+IHN1bW1hcnksIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmRhbmdlciA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCBkZXRhaWxzLmRhbmdlciA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5kYW5nZXIgPiBzdW1tYXJ5LCAubWQtdHlwZXNldCBkZXRhaWxzLmRhbmdlciA+IHN1bW1hcnkge1xuICAgICAgYm9yZGVyLWJvdHRvbS1jb2xvcjogMC4xcmVtIHNvbGlkIHJnYmEoMjU1LCAyMywgNjgsIDAuMSk7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgMjMsIDY4LCAwLjEpOyB9XG4gICAgICAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5lcnJvciA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMuZXJyb3IgPiAuYWRtb25pdGlvbi10aXRsZTo6YmVmb3JlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5lcnJvciA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5lcnJvciA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uZGFuZ2VyID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5kYW5nZXIgPiAuYWRtb25pdGlvbi10aXRsZTo6YmVmb3JlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5kYW5nZXIgPiBzdW1tYXJ5OjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMuZGFuZ2VyID4gc3VtbWFyeTo6YmVmb3JlIHtcbiAgICAgICAgY29sb3I6ICNmZjE3NDQ7XG4gICAgICAgIGNvbnRlbnQ6IFwi7o+nXCI7IH1cbiAgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uYnVnLCAubWQtdHlwZXNldCBkZXRhaWxzLmJ1ZyB7XG4gICAgYm9yZGVyLWxlZnQtY29sb3I6ICNmNTAwNTc7IH1cbiAgICBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmJ1ZywgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCBkZXRhaWxzLmJ1ZyB7XG4gICAgICBib3JkZXItcmlnaHQtY29sb3I6ICNmNTAwNTc7IH1cbiAgICAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5idWcgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5idWcgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uYnVnID4gc3VtbWFyeSwgLm1kLXR5cGVzZXQgZGV0YWlscy5idWcgPiBzdW1tYXJ5IHtcbiAgICAgIGJvcmRlci1ib3R0b20tY29sb3I6IDAuMXJlbSBzb2xpZCByZ2JhKDI0NSwgMCwgODcsIDAuMSk7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI0NSwgMCwgODcsIDAuMSk7IH1cbiAgICAgIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmJ1ZyA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMuYnVnID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uYnVnID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCBkZXRhaWxzLmJ1ZyA+IHN1bW1hcnk6OmJlZm9yZSB7XG4gICAgICAgIGNvbG9yOiAjZjUwMDU3O1xuICAgICAgICBjb250ZW50OiBcIu6hqFwiOyB9XG4gIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmV4YW1wbGUsIC5tZC10eXBlc2V0IGRldGFpbHMuZXhhbXBsZSB7XG4gICAgYm9yZGVyLWxlZnQtY29sb3I6ICM2NTFmZmY7IH1cbiAgICBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmV4YW1wbGUsIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgZGV0YWlscy5leGFtcGxlIHtcbiAgICAgIGJvcmRlci1yaWdodC1jb2xvcjogIzY1MWZmZjsgfVxuICAgIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmV4YW1wbGUgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5leGFtcGxlID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmV4YW1wbGUgPiBzdW1tYXJ5LCAubWQtdHlwZXNldCBkZXRhaWxzLmV4YW1wbGUgPiBzdW1tYXJ5IHtcbiAgICAgIGJvcmRlci1ib3R0b20tY29sb3I6IDAuMXJlbSBzb2xpZCByZ2JhKDEwMSwgMzEsIDI1NSwgMC4xKTtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMTAxLCAzMSwgMjU1LCAwLjEpOyB9XG4gICAgICAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5leGFtcGxlID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5leGFtcGxlID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uZXhhbXBsZSA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5leGFtcGxlID4gc3VtbWFyeTo6YmVmb3JlIHtcbiAgICAgICAgY29sb3I6ICM2NTFmZmY7XG4gICAgICAgIGNvbnRlbnQ6IFwi7omCXCI7IH1cbiAgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uY2l0ZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5jaXRlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5xdW90ZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5xdW90ZSB7XG4gICAgYm9yZGVyLWxlZnQtY29sb3I6ICM5ZTllOWU7IH1cbiAgICBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLmNpdGUsIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgZGV0YWlscy5jaXRlLCBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLnF1b3RlLCBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IGRldGFpbHMucXVvdGUge1xuICAgICAgYm9yZGVyLXJpZ2h0LWNvbG9yOiAjOWU5ZTllOyB9XG4gICAgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uY2l0ZSA+IC5hZG1vbml0aW9uLXRpdGxlLCAubWQtdHlwZXNldCBkZXRhaWxzLmNpdGUgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uY2l0ZSA+IHN1bW1hcnksIC5tZC10eXBlc2V0IGRldGFpbHMuY2l0ZSA+IHN1bW1hcnksIC5tZC10eXBlc2V0IC5hZG1vbml0aW9uLnF1b3RlID4gLmFkbW9uaXRpb24tdGl0bGUsIC5tZC10eXBlc2V0IGRldGFpbHMucXVvdGUgPiAuYWRtb25pdGlvbi10aXRsZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24ucXVvdGUgPiBzdW1tYXJ5LCAubWQtdHlwZXNldCBkZXRhaWxzLnF1b3RlID4gc3VtbWFyeSB7XG4gICAgICBib3JkZXItYm90dG9tLWNvbG9yOiAwLjFyZW0gc29saWQgcmdiYSgxNTgsIDE1OCwgMTU4LCAwLjEpO1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgxNTgsIDE1OCwgMTU4LCAwLjEpOyB9XG4gICAgICAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5jaXRlID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5jaXRlID4gLmFkbW9uaXRpb24tdGl0bGU6OmJlZm9yZSwgLm1kLXR5cGVzZXQgLmFkbW9uaXRpb24uY2l0ZSA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5jaXRlID4gc3VtbWFyeTo6YmVmb3JlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5xdW90ZSA+IC5hZG1vbml0aW9uLXRpdGxlOjpiZWZvcmUsIC5tZC10eXBlc2V0IGRldGFpbHMucXVvdGUgPiAuYWRtb25pdGlvbi10aXRsZTo6YmVmb3JlLCAubWQtdHlwZXNldCAuYWRtb25pdGlvbi5xdW90ZSA+IHN1bW1hcnk6OmJlZm9yZSwgLm1kLXR5cGVzZXQgZGV0YWlscy5xdW90ZSA+IHN1bW1hcnk6OmJlZm9yZSB7XG4gICAgICAgIGNvbG9yOiAjOWU5ZTllO1xuICAgICAgICBjb250ZW50OiBcIu6JhFwiOyB9XG5cbi5jb2RlaGlsaXRlIC5vLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5vIHtcbiAgY29sb3I6IGluaGVyaXQ7IH1cblxuLmNvZGVoaWxpdGUgLm93LCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5vdyB7XG4gIGNvbG9yOiBpbmhlcml0OyB9XG5cbi5jb2RlaGlsaXRlIC5nZSwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAuZ2Uge1xuICBjb2xvcjogIzAwMDAwMDsgfVxuXG4uY29kZWhpbGl0ZSAuZ3IsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLmdyIHtcbiAgY29sb3I6ICNBQTAwMDA7IH1cblxuLmNvZGVoaWxpdGUgLmdoLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5naCB7XG4gIGNvbG9yOiAjOTk5OTk5OyB9XG5cbi5jb2RlaGlsaXRlIC5nbywgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAuZ28ge1xuICBjb2xvcjogIzg4ODg4ODsgfVxuXG4uY29kZWhpbGl0ZSAuZ3AsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLmdwIHtcbiAgY29sb3I6ICM1NTU1NTU7IH1cblxuLmNvZGVoaWxpdGUgLmdzLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5ncyB7XG4gIGNvbG9yOiBpbmhlcml0OyB9XG5cbi5jb2RlaGlsaXRlIC5ndSwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAuZ3Uge1xuICBjb2xvcjogI0FBQUFBQTsgfVxuXG4uY29kZWhpbGl0ZSAuZ3QsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLmd0IHtcbiAgY29sb3I6ICNBQTAwMDA7IH1cblxuLmNvZGVoaWxpdGUgLmdkLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5nZCB7XG4gIGJhY2tncm91bmQtY29sb3I6ICNGRkREREQ7IH1cblxuLmNvZGVoaWxpdGUgLmdpLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5naSB7XG4gIGJhY2tncm91bmQtY29sb3I6ICNEREZGREQ7IH1cblxuLmNvZGVoaWxpdGUgLmssIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLmsge1xuICBjb2xvcjogIzNCNzhFNzsgfVxuXG4uY29kZWhpbGl0ZSAua2MsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLmtjIHtcbiAgY29sb3I6ICNBNzFENUQ7IH1cblxuLmNvZGVoaWxpdGUgLmtkLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5rZCB7XG4gIGNvbG9yOiAjM0I3OEU3OyB9XG5cbi5jb2RlaGlsaXRlIC5rbiwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAua24ge1xuICBjb2xvcjogIzNCNzhFNzsgfVxuXG4uY29kZWhpbGl0ZSAua3AsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLmtwIHtcbiAgY29sb3I6ICNBNzFENUQ7IH1cblxuLmNvZGVoaWxpdGUgLmtyLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5rciB7XG4gIGNvbG9yOiAjM0U2MUEyOyB9XG5cbi5jb2RlaGlsaXRlIC5rdCwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAua3Qge1xuICBjb2xvcjogIzNFNjFBMjsgfVxuXG4uY29kZWhpbGl0ZSAuYywgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAuYyB7XG4gIGNvbG9yOiAjOTk5OTk5OyB9XG5cbi5jb2RlaGlsaXRlIC5jbSwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAuY20ge1xuICBjb2xvcjogIzk5OTk5OTsgfVxuXG4uY29kZWhpbGl0ZSAuY3AsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLmNwIHtcbiAgY29sb3I6ICM2NjY2NjY7IH1cblxuLmNvZGVoaWxpdGUgLmMxLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5jMSB7XG4gIGNvbG9yOiAjOTk5OTk5OyB9XG5cbi5jb2RlaGlsaXRlIC5jaCwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAuY2gge1xuICBjb2xvcjogIzk5OTk5OTsgfVxuXG4uY29kZWhpbGl0ZSAuY3MsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLmNzIHtcbiAgY29sb3I6ICM5OTk5OTk7IH1cblxuLmNvZGVoaWxpdGUgLm5hLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5uYSB7XG4gIGNvbG9yOiAjQzIxODVCOyB9XG5cbi5jb2RlaGlsaXRlIC5uYiwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAubmIge1xuICBjb2xvcjogI0MyMTg1QjsgfVxuXG4uY29kZWhpbGl0ZSAuYnAsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLmJwIHtcbiAgY29sb3I6ICMzRTYxQTI7IH1cblxuLmNvZGVoaWxpdGUgLm5jLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5uYyB7XG4gIGNvbG9yOiAjQzIxODVCOyB9XG5cbi5jb2RlaGlsaXRlIC5ubywgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAubm8ge1xuICBjb2xvcjogIzNFNjFBMjsgfVxuXG4uY29kZWhpbGl0ZSAubmQsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLm5kIHtcbiAgY29sb3I6ICM2NjY2NjY7IH1cblxuLmNvZGVoaWxpdGUgLm5pLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5uaSB7XG4gIGNvbG9yOiAjNjY2NjY2OyB9XG5cbi5jb2RlaGlsaXRlIC5uZSwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAubmUge1xuICBjb2xvcjogI0MyMTg1QjsgfVxuXG4uY29kZWhpbGl0ZSAubmYsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLm5mIHtcbiAgY29sb3I6ICNDMjE4NUI7IH1cblxuLmNvZGVoaWxpdGUgLm5sLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5ubCB7XG4gIGNvbG9yOiAjM0I1MTc5OyB9XG5cbi5jb2RlaGlsaXRlIC5ubiwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAubm4ge1xuICBjb2xvcjogI0VDNDA3QTsgfVxuXG4uY29kZWhpbGl0ZSAubnQsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLm50IHtcbiAgY29sb3I6ICMzQjc4RTc7IH1cblxuLmNvZGVoaWxpdGUgLm52LCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5udiB7XG4gIGNvbG9yOiAjM0U2MUEyOyB9XG5cbi5jb2RlaGlsaXRlIC52YywgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAudmMge1xuICBjb2xvcjogIzNFNjFBMjsgfVxuXG4uY29kZWhpbGl0ZSAudmcsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLnZnIHtcbiAgY29sb3I6ICMzRTYxQTI7IH1cblxuLmNvZGVoaWxpdGUgLnZpLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC52aSB7XG4gIGNvbG9yOiAjM0U2MUEyOyB9XG5cbi5jb2RlaGlsaXRlIC5ueCwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAubngge1xuICBjb2xvcjogI0VDNDA3QTsgfVxuXG4uY29kZWhpbGl0ZSAubSwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAubSB7XG4gIGNvbG9yOiAjRTc0QzNDOyB9XG5cbi5jb2RlaGlsaXRlIC5tZiwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAubWYge1xuICBjb2xvcjogI0U3NEMzQzsgfVxuXG4uY29kZWhpbGl0ZSAubWgsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLm1oIHtcbiAgY29sb3I6ICNFNzRDM0M7IH1cblxuLmNvZGVoaWxpdGUgLm1pLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5taSB7XG4gIGNvbG9yOiAjRTc0QzNDOyB9XG5cbi5jb2RlaGlsaXRlIC5pbCwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAuaWwge1xuICBjb2xvcjogI0U3NEMzQzsgfVxuXG4uY29kZWhpbGl0ZSAubW8sIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLm1vIHtcbiAgY29sb3I6ICNFNzRDM0M7IH1cblxuLmNvZGVoaWxpdGUgLnMsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLnMge1xuICBjb2xvcjogIzBEOTA0RjsgfVxuXG4uY29kZWhpbGl0ZSAuc2IsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLnNiIHtcbiAgY29sb3I6ICMwRDkwNEY7IH1cblxuLmNvZGVoaWxpdGUgLnNjLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5zYyB7XG4gIGNvbG9yOiAjMEQ5MDRGOyB9XG5cbi5jb2RlaGlsaXRlIC5zZCwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAuc2Qge1xuICBjb2xvcjogIzk5OTk5OTsgfVxuXG4uY29kZWhpbGl0ZSAuczIsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLnMyIHtcbiAgY29sb3I6ICMwRDkwNEY7IH1cblxuLmNvZGVoaWxpdGUgLnNlLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5zZSB7XG4gIGNvbG9yOiAjMTgzNjkxOyB9XG5cbi5jb2RlaGlsaXRlIC5zaCwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAuc2gge1xuICBjb2xvcjogIzE4MzY5MTsgfVxuXG4uY29kZWhpbGl0ZSAuc2ksIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLnNpIHtcbiAgY29sb3I6ICMxODM2OTE7IH1cblxuLmNvZGVoaWxpdGUgLnN4LCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5zeCB7XG4gIGNvbG9yOiAjMTgzNjkxOyB9XG5cbi5jb2RlaGlsaXRlIC5zciwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAuc3Ige1xuICBjb2xvcjogIzAwOTkyNjsgfVxuXG4uY29kZWhpbGl0ZSAuczEsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLnMxIHtcbiAgY29sb3I6ICMwRDkwNEY7IH1cblxuLmNvZGVoaWxpdGUgLnNzLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC5zcyB7XG4gIGNvbG9yOiAjMEQ5MDRGOyB9XG5cbi5jb2RlaGlsaXRlIC5lcnIsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLmVyciB7XG4gIGNvbG9yOiAjQTYxNzE3OyB9XG5cbi5jb2RlaGlsaXRlIC53LCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IC53IHtcbiAgY29sb3I6IHRyYW5zcGFyZW50OyB9XG5cbi5jb2RlaGlsaXRlIC5obGwsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgLmhsbCB7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBtYXJnaW46IDAgLTEuMnJlbTtcbiAgcGFkZGluZzogMCAxLjJyZW07XG4gIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjU1LCAyMzUsIDU5LCAwLjUpOyB9XG4gIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1heC13aWR0aDogNDQuOTM3NWVtKSB7XG4gICAgLmNvZGVoaWxpdGUgLmhsbCwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCAuaGxsIHtcbiAgICAgIG1hcmdpbjogMCAtMS42cmVtO1xuICAgICAgcGFkZGluZzogMCAxLjZyZW07IH0gfVxuXG4ubWQtdHlwZXNldCAuY29kZWhpbGl0ZSwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgbWFyZ2luOiAxZW0gMDtcbiAgcGFkZGluZzogMDtcbiAgYm9yZGVyLXJhZGl1czogMC4ycmVtO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDIzNiwgMjM2LCAyMzYsIDAuNSk7XG4gIGNvbG9yOiAjMzc0NzRGO1xuICBsaW5lLWhlaWdodDogMS40O1xuICAtd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzogdG91Y2g7IH1cbiAgLm1kLXR5cGVzZXQgLmNvZGVoaWxpdGUgcHJlLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IHByZSxcbiAgLm1kLXR5cGVzZXQgLmNvZGVoaWxpdGUgY29kZSxcbiAgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCBjb2RlIHtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBtYXJnaW46IDA7XG4gICAgcGFkZGluZzogMS4wNXJlbSAxLjJyZW07XG4gICAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gICAgb3ZlcmZsb3c6IGF1dG87XG4gICAgdmVydGljYWwtYWxpZ246IHRvcDsgfVxuICAgIC5tZC10eXBlc2V0IC5jb2RlaGlsaXRlIHByZTo6LXdlYmtpdC1zY3JvbGxiYXIsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgcHJlOjotd2Via2l0LXNjcm9sbGJhcixcbiAgICAubWQtdHlwZXNldCAuY29kZWhpbGl0ZSBjb2RlOjotd2Via2l0LXNjcm9sbGJhcixcbiAgICAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IGNvZGU6Oi13ZWJraXQtc2Nyb2xsYmFyIHtcbiAgICAgIHdpZHRoOiAwLjRyZW07XG4gICAgICBoZWlnaHQ6IDAuNHJlbTsgfVxuICAgIC5tZC10eXBlc2V0IC5jb2RlaGlsaXRlIHByZTo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWIsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgcHJlOjotd2Via2l0LXNjcm9sbGJhci10aHVtYixcbiAgICAubWQtdHlwZXNldCAuY29kZWhpbGl0ZSBjb2RlOjotd2Via2l0LXNjcm9sbGJhci10aHVtYixcbiAgICAubWQtdHlwZXNldCAuaGlnaGxpZ2h0IGNvZGU6Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1iIHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC4yNik7IH1cbiAgICAgIC5tZC10eXBlc2V0IC5jb2RlaGlsaXRlIHByZTo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWI6aG92ZXIsIC5tZC10eXBlc2V0IC5oaWdobGlnaHQgcHJlOjotd2Via2l0LXNjcm9sbGJhci10aHVtYjpob3ZlcixcbiAgICAgIC5tZC10eXBlc2V0IC5jb2RlaGlsaXRlIGNvZGU6Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1iOmhvdmVyLFxuICAgICAgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodCBjb2RlOjotd2Via2l0LXNjcm9sbGJhci10aHVtYjpob3ZlciB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6ICM1MzZkZmU7IH1cblxuLm1kLXR5cGVzZXQgcHJlLmNvZGVoaWxpdGUsIC5tZC10eXBlc2V0IHByZS5oaWdobGlnaHQge1xuICBvdmVyZmxvdzogdmlzaWJsZTsgfVxuICAubWQtdHlwZXNldCBwcmUuY29kZWhpbGl0ZSBjb2RlLCAubWQtdHlwZXNldCBwcmUuaGlnaGxpZ2h0IGNvZGUge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIHBhZGRpbmc6IDEuMDVyZW0gMS4ycmVtO1xuICAgIG92ZXJmbG93OiBhdXRvOyB9XG5cbi5tZC10eXBlc2V0IC5jb2RlaGlsaXRldGFibGUsIC5tZC10eXBlc2V0IC5oaWdobGlnaHR0YWJsZSB7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBtYXJnaW46IDFlbSAwO1xuICBib3JkZXItcmFkaXVzOiAwLjJlbTtcbiAgZm9udC1zaXplOiAxLjZyZW07XG4gIG92ZXJmbG93OiBoaWRkZW47IH1cbiAgLm1kLXR5cGVzZXQgLmNvZGVoaWxpdGV0YWJsZSB0Ym9keSwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodHRhYmxlIHRib2R5LFxuICAubWQtdHlwZXNldCAuY29kZWhpbGl0ZXRhYmxlIHRkLFxuICAubWQtdHlwZXNldCAuaGlnaGxpZ2h0dGFibGUgdGQge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIHBhZGRpbmc6IDA7IH1cbiAgLm1kLXR5cGVzZXQgLmNvZGVoaWxpdGV0YWJsZSB0ciwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodHRhYmxlIHRyIHtcbiAgICBkaXNwbGF5OiBmbGV4OyB9XG4gIC5tZC10eXBlc2V0IC5jb2RlaGlsaXRldGFibGUgLmNvZGVoaWxpdGUsIC5tZC10eXBlc2V0IC5oaWdobGlnaHR0YWJsZSAuY29kZWhpbGl0ZSwgLm1kLXR5cGVzZXQgLmNvZGVoaWxpdGV0YWJsZSAuaGlnaGxpZ2h0LCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0dGFibGUgLmhpZ2hsaWdodCxcbiAgLm1kLXR5cGVzZXQgLmNvZGVoaWxpdGV0YWJsZSAubGluZW5vZGl2LFxuICAubWQtdHlwZXNldCAuaGlnaGxpZ2h0dGFibGUgLmxpbmVub2RpdiB7XG4gICAgbWFyZ2luOiAwO1xuICAgIGJvcmRlci1yYWRpdXM6IDA7IH1cbiAgXG4gIC5tZC10eXBlc2V0IC5jb2RlaGlsaXRldGFibGUgLmxpbmVub2RpdixcbiAgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodHRhYmxlIC5saW5lbm9kaXYge1xuICAgIHBhZGRpbmc6IDEuMDVyZW0gMS4ycmVtOyB9XG4gIC5tZC10eXBlc2V0IC5jb2RlaGlsaXRldGFibGUgLmxpbmVub3MsIC5tZC10eXBlc2V0IC5oaWdobGlnaHR0YWJsZSAubGluZW5vcyB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjA3KTtcbiAgICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjI2KTtcbiAgICB1c2VyLXNlbGVjdDogbm9uZTsgfVxuICAgIC5tZC10eXBlc2V0IC5jb2RlaGlsaXRldGFibGUgLmxpbmVub3MgcHJlLCAubWQtdHlwZXNldCAuaGlnaGxpZ2h0dGFibGUgLmxpbmVub3MgcHJlIHtcbiAgICAgIG1hcmdpbjogMDtcbiAgICAgIHBhZGRpbmc6IDA7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICAgIGNvbG9yOiBpbmhlcml0O1xuICAgICAgdGV4dC1hbGlnbjogcmlnaHQ7IH1cbiAgLm1kLXR5cGVzZXQgLmNvZGVoaWxpdGV0YWJsZSAuY29kZSwgLm1kLXR5cGVzZXQgLmhpZ2hsaWdodHRhYmxlIC5jb2RlIHtcbiAgICBmbGV4OiAxO1xuICAgIG92ZXJmbG93OiBoaWRkZW47IH1cblxuQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA0NC45Mzc1ZW0pIHtcbiAgLm1kLXR5cGVzZXQgPiAuY29kZWhpbGl0ZSwgLm1kLXR5cGVzZXQgPiAuaGlnaGxpZ2h0IHtcbiAgICBtYXJnaW46IDFlbSAtMS42cmVtO1xuICAgIGJvcmRlci1yYWRpdXM6IDA7IH1cbiAgICAubWQtdHlwZXNldCA+IC5jb2RlaGlsaXRlIHByZSwgLm1kLXR5cGVzZXQgPiAuaGlnaGxpZ2h0IHByZSxcbiAgICAubWQtdHlwZXNldCA+IC5jb2RlaGlsaXRlIGNvZGUsXG4gICAgLm1kLXR5cGVzZXQgPiAuaGlnaGxpZ2h0IGNvZGUge1xuICAgICAgcGFkZGluZzogMS4wNXJlbSAxLjZyZW07IH0gfVxuXG4ubWQtdHlwZXNldCA+IC5jb2RlaGlsaXRldGFibGUsIC5tZC10eXBlc2V0ID4gLmhpZ2hsaWdodHRhYmxlIHtcbiAgYm94LXNoYWRvdzogbm9uZTsgfVxuICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDQ0LjkzNzVlbSkge1xuICAgIC5tZC10eXBlc2V0ID4gLmNvZGVoaWxpdGV0YWJsZSwgLm1kLXR5cGVzZXQgPiAuaGlnaGxpZ2h0dGFibGUge1xuICAgICAgbWFyZ2luOiAxZW0gLTEuNnJlbTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDA7IH1cbiAgICAgIC5tZC10eXBlc2V0ID4gLmNvZGVoaWxpdGV0YWJsZSAuY29kZWhpbGl0ZSA+IHByZSwgLm1kLXR5cGVzZXQgPiAuaGlnaGxpZ2h0dGFibGUgLmNvZGVoaWxpdGUgPiBwcmUsIC5tZC10eXBlc2V0ID4gLmNvZGVoaWxpdGV0YWJsZSAuaGlnaGxpZ2h0ID4gcHJlLCAubWQtdHlwZXNldCA+IC5oaWdobGlnaHR0YWJsZSAuaGlnaGxpZ2h0ID4gcHJlLFxuICAgICAgLm1kLXR5cGVzZXQgPiAuY29kZWhpbGl0ZXRhYmxlIC5jb2RlaGlsaXRlID4gY29kZSxcbiAgICAgIC5tZC10eXBlc2V0ID4gLmhpZ2hsaWdodHRhYmxlIC5jb2RlaGlsaXRlID4gY29kZSxcbiAgICAgIC5tZC10eXBlc2V0ID4gLmNvZGVoaWxpdGV0YWJsZSAuaGlnaGxpZ2h0ID4gY29kZSxcbiAgICAgIC5tZC10eXBlc2V0ID4gLmhpZ2hsaWdodHRhYmxlIC5oaWdobGlnaHQgPiBjb2RlLFxuICAgICAgLm1kLXR5cGVzZXQgPiAuY29kZWhpbGl0ZXRhYmxlIC5saW5lbm9kaXYsXG4gICAgICAubWQtdHlwZXNldCA+IC5oaWdobGlnaHR0YWJsZSAubGluZW5vZGl2IHtcbiAgICAgICAgcGFkZGluZzogMXJlbSAxLjZyZW07IH0gfVxuXG4ubWQtdHlwZXNldCBbaWRePVwiZm5yZWY6XCJdIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrOyB9XG4gIC5tZC10eXBlc2V0IFtpZF49XCJmbnJlZjpcIl06dGFyZ2V0IHtcbiAgICBtYXJnaW4tdG9wOiAtNy42cmVtO1xuICAgIHBhZGRpbmctdG9wOiA3LjZyZW07XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7IH1cblxuLm1kLXR5cGVzZXQgW2lkXj1cImZuOlwiXTo6YmVmb3JlIHtcbiAgZGlzcGxheTogbm9uZTtcbiAgaGVpZ2h0OiAwO1xuICBjb250ZW50OiBcIlwiOyB9XG5cbi5tZC10eXBlc2V0IFtpZF49XCJmbjpcIl06dGFyZ2V0OjpiZWZvcmUge1xuICBkaXNwbGF5OiBibG9jaztcbiAgbWFyZ2luLXRvcDogLTdyZW07XG4gIHBhZGRpbmctdG9wOiA3cmVtO1xuICBwb2ludGVyLWV2ZW50czogbm9uZTsgfVxuXG4ubWQtdHlwZXNldCAuZm9vdG5vdGUge1xuICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjU0KTtcbiAgZm9udC1zaXplOiAxLjI4cmVtOyB9XG4gIC5tZC10eXBlc2V0IC5mb290bm90ZSBvbCB7XG4gICAgbWFyZ2luLWxlZnQ6IDA7IH1cbiAgLm1kLXR5cGVzZXQgLmZvb3Rub3RlIGxpIHtcbiAgICB0cmFuc2l0aW9uOiBjb2xvciAwLjI1czsgfVxuICAgIC5tZC10eXBlc2V0IC5mb290bm90ZSBsaTp0YXJnZXQge1xuICAgICAgY29sb3I6IHJnYmEoMCwgMCwgMCwgMC44Nyk7IH1cbiAgICAubWQtdHlwZXNldCAuZm9vdG5vdGUgbGkgOmZpcnN0LWNoaWxkIHtcbiAgICAgIG1hcmdpbi10b3A6IDA7IH1cbiAgICAubWQtdHlwZXNldCAuZm9vdG5vdGUgbGk6aG92ZXIgLmZvb3Rub3RlLWJhY2tyZWYsXG4gICAgLm1kLXR5cGVzZXQgLmZvb3Rub3RlIGxpOnRhcmdldCAuZm9vdG5vdGUtYmFja3JlZiB7XG4gICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMCk7XG4gICAgICBvcGFjaXR5OiAxOyB9XG4gICAgLm1kLXR5cGVzZXQgLmZvb3Rub3RlIGxpOmhvdmVyIC5mb290bm90ZS1iYWNrcmVmOmhvdmVyLFxuICAgIC5tZC10eXBlc2V0IC5mb290bm90ZSBsaTp0YXJnZXQgLmZvb3Rub3RlLWJhY2tyZWYge1xuICAgICAgY29sb3I6ICM1MzZkZmU7IH1cblxuLm1kLXR5cGVzZXQgLmZvb3Rub3RlLXJlZiB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgcG9pbnRlci1ldmVudHM6IGluaXRpYWw7IH1cbiAgLm1kLXR5cGVzZXQgLmZvb3Rub3RlLXJlZjo6YmVmb3JlIHtcbiAgICBkaXNwbGF5OiBpbmxpbmU7XG4gICAgbWFyZ2luOiAwIDAuMmVtO1xuICAgIGJvcmRlci1sZWZ0OiAwLjFyZW0gc29saWQgcmdiYSgwLCAwLCAwLCAwLjI2KTtcbiAgICBmb250LXNpemU6IDEuMjVlbTtcbiAgICBjb250ZW50OiBcIlwiO1xuICAgIHZlcnRpY2FsLWFsaWduOiAtMC41cmVtOyB9XG5cbi5tZC10eXBlc2V0IC5mb290bm90ZS1iYWNrcmVmIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMC41cmVtKTtcbiAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuMjVzICAwLjEyNXMsIGNvbG9yICAgICAwLjI1cywgb3BhY2l0eSAgIDAuMTI1cyAwLjEyNXM7XG4gIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuMjYpO1xuICBmb250LXNpemU6IDA7XG4gIG9wYWNpdHk6IDA7XG4gIHZlcnRpY2FsLWFsaWduOiB0ZXh0LWJvdHRvbTsgfVxuICBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IC5mb290bm90ZS1iYWNrcmVmIHtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTAuNXJlbSk7IH1cbiAgLm1kLXR5cGVzZXQgLmZvb3Rub3RlLWJhY2tyZWY6OmJlZm9yZSB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIGZvbnQtc2l6ZTogMS42cmVtO1xuICAgIGNvbnRlbnQ6IFwiXFxFMzFCXCI7IH1cbiAgICBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IC5mb290bm90ZS1iYWNrcmVmOjpiZWZvcmUge1xuICAgICAgdHJhbnNmb3JtOiBzY2FsZVgoLTEpOyB9XG5cbi5tZC10eXBlc2V0IC5oZWFkZXJsaW5rIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICBtYXJnaW4tbGVmdDogMXJlbTtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMCwgMC41cmVtKTtcbiAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDAuMjVzICAwLjI1cywgY29sb3IgICAgIDAuMjVzLCBvcGFjaXR5ICAgMC4xMjVzIDAuMjVzO1xuICBvcGFjaXR5OiAwOyB9XG4gIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgLmhlYWRlcmxpbmsge1xuICAgIG1hcmdpbi1yaWdodDogMXJlbTtcbiAgICBtYXJnaW4tbGVmdDogaW5pdGlhbDsgfVxuICBodG1sIGJvZHkgLm1kLXR5cGVzZXQgLmhlYWRlcmxpbmsge1xuICAgIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuMjYpOyB9XG4gIEBtZWRpYSBwcmludCB7XG4gICAgLm1kLXR5cGVzZXQgLmhlYWRlcmxpbmsge1xuICAgICAgZGlzcGxheTogbm9uZTsgfSB9XG5cbi5tZC10eXBlc2V0IGgxW2lkXTo6YmVmb3JlIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIG1hcmdpbi10b3A6IC0wLjlyZW07XG4gIHBhZGRpbmctdG9wOiAwLjlyZW07XG4gIGNvbnRlbnQ6IFwiXCI7IH1cblxuLm1kLXR5cGVzZXQgaDFbaWRdOnRhcmdldDo6YmVmb3JlIHtcbiAgbWFyZ2luLXRvcDogLTYuOXJlbTtcbiAgcGFkZGluZy10b3A6IDYuOXJlbTsgfVxuXG4ubWQtdHlwZXNldCBoMVtpZF06aG92ZXIgLmhlYWRlcmxpbmssXG4ubWQtdHlwZXNldCBoMVtpZF06dGFyZ2V0IC5oZWFkZXJsaW5rLFxuLm1kLXR5cGVzZXQgaDFbaWRdIC5oZWFkZXJsaW5rOmZvY3VzIHtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMCwgMCk7XG4gIG9wYWNpdHk6IDE7IH1cblxuLm1kLXR5cGVzZXQgaDFbaWRdOmhvdmVyIC5oZWFkZXJsaW5rOmhvdmVyLFxuLm1kLXR5cGVzZXQgaDFbaWRdOnRhcmdldCAuaGVhZGVybGluayxcbi5tZC10eXBlc2V0IGgxW2lkXSAuaGVhZGVybGluazpmb2N1cyB7XG4gIGNvbG9yOiAjNTM2ZGZlOyB9XG5cbi5tZC10eXBlc2V0IGgyW2lkXTo6YmVmb3JlIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIG1hcmdpbi10b3A6IC0wLjhyZW07XG4gIHBhZGRpbmctdG9wOiAwLjhyZW07XG4gIGNvbnRlbnQ6IFwiXCI7IH1cblxuLm1kLXR5cGVzZXQgaDJbaWRdOnRhcmdldDo6YmVmb3JlIHtcbiAgbWFyZ2luLXRvcDogLTYuOHJlbTtcbiAgcGFkZGluZy10b3A6IDYuOHJlbTsgfVxuXG4ubWQtdHlwZXNldCBoMltpZF06aG92ZXIgLmhlYWRlcmxpbmssXG4ubWQtdHlwZXNldCBoMltpZF06dGFyZ2V0IC5oZWFkZXJsaW5rLFxuLm1kLXR5cGVzZXQgaDJbaWRdIC5oZWFkZXJsaW5rOmZvY3VzIHtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMCwgMCk7XG4gIG9wYWNpdHk6IDE7IH1cblxuLm1kLXR5cGVzZXQgaDJbaWRdOmhvdmVyIC5oZWFkZXJsaW5rOmhvdmVyLFxuLm1kLXR5cGVzZXQgaDJbaWRdOnRhcmdldCAuaGVhZGVybGluayxcbi5tZC10eXBlc2V0IGgyW2lkXSAuaGVhZGVybGluazpmb2N1cyB7XG4gIGNvbG9yOiAjNTM2ZGZlOyB9XG5cbi5tZC10eXBlc2V0IGgzW2lkXTo6YmVmb3JlIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIG1hcmdpbi10b3A6IC0wLjlyZW07XG4gIHBhZGRpbmctdG9wOiAwLjlyZW07XG4gIGNvbnRlbnQ6IFwiXCI7IH1cblxuLm1kLXR5cGVzZXQgaDNbaWRdOnRhcmdldDo6YmVmb3JlIHtcbiAgbWFyZ2luLXRvcDogLTYuOXJlbTtcbiAgcGFkZGluZy10b3A6IDYuOXJlbTsgfVxuXG4ubWQtdHlwZXNldCBoM1tpZF06aG92ZXIgLmhlYWRlcmxpbmssXG4ubWQtdHlwZXNldCBoM1tpZF06dGFyZ2V0IC5oZWFkZXJsaW5rLFxuLm1kLXR5cGVzZXQgaDNbaWRdIC5oZWFkZXJsaW5rOmZvY3VzIHtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMCwgMCk7XG4gIG9wYWNpdHk6IDE7IH1cblxuLm1kLXR5cGVzZXQgaDNbaWRdOmhvdmVyIC5oZWFkZXJsaW5rOmhvdmVyLFxuLm1kLXR5cGVzZXQgaDNbaWRdOnRhcmdldCAuaGVhZGVybGluayxcbi5tZC10eXBlc2V0IGgzW2lkXSAuaGVhZGVybGluazpmb2N1cyB7XG4gIGNvbG9yOiAjNTM2ZGZlOyB9XG5cbi5tZC10eXBlc2V0IGg0W2lkXTo6YmVmb3JlIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIG1hcmdpbi10b3A6IC0wLjlyZW07XG4gIHBhZGRpbmctdG9wOiAwLjlyZW07XG4gIGNvbnRlbnQ6IFwiXCI7IH1cblxuLm1kLXR5cGVzZXQgaDRbaWRdOnRhcmdldDo6YmVmb3JlIHtcbiAgbWFyZ2luLXRvcDogLTYuOXJlbTtcbiAgcGFkZGluZy10b3A6IDYuOXJlbTsgfVxuXG4ubWQtdHlwZXNldCBoNFtpZF06aG92ZXIgLmhlYWRlcmxpbmssXG4ubWQtdHlwZXNldCBoNFtpZF06dGFyZ2V0IC5oZWFkZXJsaW5rLFxuLm1kLXR5cGVzZXQgaDRbaWRdIC5oZWFkZXJsaW5rOmZvY3VzIHtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMCwgMCk7XG4gIG9wYWNpdHk6IDE7IH1cblxuLm1kLXR5cGVzZXQgaDRbaWRdOmhvdmVyIC5oZWFkZXJsaW5rOmhvdmVyLFxuLm1kLXR5cGVzZXQgaDRbaWRdOnRhcmdldCAuaGVhZGVybGluayxcbi5tZC10eXBlc2V0IGg0W2lkXSAuaGVhZGVybGluazpmb2N1cyB7XG4gIGNvbG9yOiAjNTM2ZGZlOyB9XG5cbi5tZC10eXBlc2V0IGg1W2lkXTo6YmVmb3JlIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIG1hcmdpbi10b3A6IC0xLjFyZW07XG4gIHBhZGRpbmctdG9wOiAxLjFyZW07XG4gIGNvbnRlbnQ6IFwiXCI7IH1cblxuLm1kLXR5cGVzZXQgaDVbaWRdOnRhcmdldDo6YmVmb3JlIHtcbiAgbWFyZ2luLXRvcDogLTcuMXJlbTtcbiAgcGFkZGluZy10b3A6IDcuMXJlbTsgfVxuXG4ubWQtdHlwZXNldCBoNVtpZF06aG92ZXIgLmhlYWRlcmxpbmssXG4ubWQtdHlwZXNldCBoNVtpZF06dGFyZ2V0IC5oZWFkZXJsaW5rLFxuLm1kLXR5cGVzZXQgaDVbaWRdIC5oZWFkZXJsaW5rOmZvY3VzIHtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMCwgMCk7XG4gIG9wYWNpdHk6IDE7IH1cblxuLm1kLXR5cGVzZXQgaDVbaWRdOmhvdmVyIC5oZWFkZXJsaW5rOmhvdmVyLFxuLm1kLXR5cGVzZXQgaDVbaWRdOnRhcmdldCAuaGVhZGVybGluayxcbi5tZC10eXBlc2V0IGg1W2lkXSAuaGVhZGVybGluazpmb2N1cyB7XG4gIGNvbG9yOiAjNTM2ZGZlOyB9XG5cbi5tZC10eXBlc2V0IGg2W2lkXTo6YmVmb3JlIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIG1hcmdpbi10b3A6IC0xLjFyZW07XG4gIHBhZGRpbmctdG9wOiAxLjFyZW07XG4gIGNvbnRlbnQ6IFwiXCI7IH1cblxuLm1kLXR5cGVzZXQgaDZbaWRdOnRhcmdldDo6YmVmb3JlIHtcbiAgbWFyZ2luLXRvcDogLTcuMXJlbTtcbiAgcGFkZGluZy10b3A6IDcuMXJlbTsgfVxuXG4ubWQtdHlwZXNldCBoNltpZF06aG92ZXIgLmhlYWRlcmxpbmssXG4ubWQtdHlwZXNldCBoNltpZF06dGFyZ2V0IC5oZWFkZXJsaW5rLFxuLm1kLXR5cGVzZXQgaDZbaWRdIC5oZWFkZXJsaW5rOmZvY3VzIHtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMCwgMCk7XG4gIG9wYWNpdHk6IDE7IH1cblxuLm1kLXR5cGVzZXQgaDZbaWRdOmhvdmVyIC5oZWFkZXJsaW5rOmhvdmVyLFxuLm1kLXR5cGVzZXQgaDZbaWRdOnRhcmdldCAuaGVhZGVybGluayxcbi5tZC10eXBlc2V0IGg2W2lkXSAuaGVhZGVybGluazpmb2N1cyB7XG4gIGNvbG9yOiAjNTM2ZGZlOyB9XG5cbi5tZC10eXBlc2V0IC5NSlhjLWRpc3BsYXkge1xuICBtYXJnaW46IDAuNzVlbSAwO1xuICBwYWRkaW5nOiAwLjc1ZW0gMDtcbiAgb3ZlcmZsb3c6IGF1dG87XG4gIC13ZWJraXQtb3ZlcmZsb3ctc2Nyb2xsaW5nOiB0b3VjaDsgfVxuXG5AbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDQ0LjkzNzVlbSkge1xuICAubWQtdHlwZXNldCA+IHAgPiAuTUpYYy1kaXNwbGF5IHtcbiAgICBtYXJnaW46IDAuNzVlbSAtMS42cmVtO1xuICAgIHBhZGRpbmc6IDAuMjVlbSAxLjZyZW07IH0gfVxuXG4ubWQtdHlwZXNldCAuTWF0aEpheF9DSFRNTCB7XG4gIG91dGxpbmU6IDA7IH1cblxuLm1kLXR5cGVzZXQgZGVsLmNyaXRpYyxcbi5tZC10eXBlc2V0IGlucy5jcml0aWMsXG4ubWQtdHlwZXNldCAuY3JpdGljLmNvbW1lbnQge1xuICBtYXJnaW46IDAgMC4yNWVtO1xuICBwYWRkaW5nOiAwLjA2MjVlbSAwO1xuICBib3JkZXItcmFkaXVzOiAwLjJyZW07XG4gIGJveC1kZWNvcmF0aW9uLWJyZWFrOiBjbG9uZTsgfVxuXG4ubWQtdHlwZXNldCBkZWwuY3JpdGljIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogI0ZGRERERDtcbiAgYm94LXNoYWRvdzogMC4yNWVtIDAgMCAjRkZERERELCAtMC4yNWVtIDAgMCAjRkZEREREOyB9XG5cbi5tZC10eXBlc2V0IGlucy5jcml0aWMge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjRERGRkREO1xuICBib3gtc2hhZG93OiAwLjI1ZW0gMCAwICNEREZGREQsIC0wLjI1ZW0gMCAwICNEREZGREQ7IH1cblxuLm1kLXR5cGVzZXQgLmNyaXRpYy5jb21tZW50IHtcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyMzYsIDIzNiwgMjM2LCAwLjUpO1xuICBjb2xvcjogIzM3NDc0RjtcbiAgYm94LXNoYWRvdzogMC4yNWVtIDAgMCByZ2JhKDIzNiwgMjM2LCAyMzYsIDAuNSksIC0wLjI1ZW0gMCAwIHJnYmEoMjM2LCAyMzYsIDIzNiwgMC41KTsgfVxuICAubWQtdHlwZXNldCAuY3JpdGljLmNvbW1lbnQ6OmJlZm9yZSB7XG4gICAgcGFkZGluZy1yaWdodDogMC4xMjVlbTtcbiAgICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjI2KTtcbiAgICBjb250ZW50OiBcIlxcRTBCN1wiO1xuICAgIHZlcnRpY2FsLWFsaWduOiAtMC4xMjVlbTsgfVxuXG4ubWQtdHlwZXNldCAuY3JpdGljLmJsb2NrIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIG1hcmdpbjogMWVtIDA7XG4gIHBhZGRpbmctcmlnaHQ6IDEuNnJlbTtcbiAgcGFkZGluZy1sZWZ0OiAxLjZyZW07XG4gIGJveC1zaGFkb3c6IG5vbmU7IH1cbiAgLm1kLXR5cGVzZXQgLmNyaXRpYy5ibG9jayA6Zmlyc3QtY2hpbGQge1xuICAgIG1hcmdpbi10b3A6IDAuNWVtOyB9XG4gIC5tZC10eXBlc2V0IC5jcml0aWMuYmxvY2sgOmxhc3QtY2hpbGQge1xuICAgIG1hcmdpbi1ib3R0b206IDAuNWVtOyB9XG5cbi5tZC10eXBlc2V0IGRldGFpbHMge1xuICBkaXNwbGF5OiBibG9jaztcbiAgcGFkZGluZy10b3A6IDA7IH1cbiAgLm1kLXR5cGVzZXQgZGV0YWlsc1tvcGVuXSA+IHN1bW1hcnk6OmFmdGVyIHtcbiAgICB0cmFuc2Zvcm06IHJvdGF0ZSgxODBkZWcpOyB9XG4gIC5tZC10eXBlc2V0IGRldGFpbHM6bm90KFtvcGVuXSkge1xuICAgIHBhZGRpbmctYm90dG9tOiAwOyB9XG4gICAgLm1kLXR5cGVzZXQgZGV0YWlsczpub3QoW29wZW5dKSA+IHN1bW1hcnkge1xuICAgICAgYm9yZGVyLWJvdHRvbTogbm9uZTsgfVxuICAubWQtdHlwZXNldCBkZXRhaWxzIHN1bW1hcnkge1xuICAgIHBhZGRpbmctcmlnaHQ6IDRyZW07IH1cbiAgICBbZGlyPVwicnRsXCJdIC5tZC10eXBlc2V0IGRldGFpbHMgc3VtbWFyeSB7XG4gICAgICBwYWRkaW5nLWxlZnQ6IDRyZW07IH1cbiAgLm5vLWRldGFpbHMgLm1kLXR5cGVzZXQgZGV0YWlsczpub3QoW29wZW5dKSA+ICoge1xuICAgIGRpc3BsYXk6IG5vbmU7IH1cbiAgLm5vLWRldGFpbHMgLm1kLXR5cGVzZXQgZGV0YWlsczpub3QoW29wZW5dKSBzdW1tYXJ5IHtcbiAgICBkaXNwbGF5OiBibG9jazsgfVxuXG4ubWQtdHlwZXNldCBzdW1tYXJ5IHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIG91dGxpbmU6IG5vbmU7XG4gIGN1cnNvcjogcG9pbnRlcjsgfVxuICAubWQtdHlwZXNldCBzdW1tYXJ5Ojotd2Via2l0LWRldGFpbHMtbWFya2VyIHtcbiAgICBkaXNwbGF5OiBub25lOyB9XG4gIC5tZC10eXBlc2V0IHN1bW1hcnk6OmFmdGVyIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiAwLjhyZW07XG4gICAgcmlnaHQ6IDEuMnJlbTtcbiAgICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjI2KTtcbiAgICBmb250LXNpemU6IDJyZW07XG4gICAgY29udGVudDogXCJcXEUzMTNcIjsgfVxuICAgIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgc3VtbWFyeTo6YWZ0ZXIge1xuICAgICAgcmlnaHQ6IGluaXRpYWw7XG4gICAgICBsZWZ0OiAxLjJyZW07IH1cblxuLm1kLXR5cGVzZXQgLmVtb2ppb25lIHtcbiAgd2lkdGg6IDJyZW07XG4gIHZlcnRpY2FsLWFsaWduOiB0ZXh0LXRvcDsgfVxuXG4ubWQtdHlwZXNldCBjb2RlLmNvZGVoaWxpdGUsIC5tZC10eXBlc2V0IGNvZGUuaGlnaGxpZ2h0IHtcbiAgbWFyZ2luOiAwIDAuMjk0MTJlbTtcbiAgcGFkZGluZzogMC4wNzM1M2VtIDA7IH1cblxuLm1kLXR5cGVzZXQgLnN1cGVyZmVuY2VzLWNvbnRlbnQge1xuICBkaXNwbGF5OiBub25lO1xuICBvcmRlcjogOTk7XG4gIHdpZHRoOiAxMDAlO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTsgfVxuICAubWQtdHlwZXNldCAuc3VwZXJmZW5jZXMtY29udGVudCA+ICoge1xuICAgIG1hcmdpbjogMDtcbiAgICBib3JkZXItcmFkaXVzOiAwOyB9XG5cbi5tZC10eXBlc2V0IC5zdXBlcmZlbmNlcy10YWJzIHtcbiAgZGlzcGxheTogZmxleDtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBmbGV4LXdyYXA6IHdyYXA7XG4gIG1hcmdpbjogMWVtIDA7XG4gIGJvcmRlcjogMC4xcmVtIHNvbGlkIHJnYmEoMCwgMCwgMCwgMC4wNyk7XG4gIGJvcmRlci1yYWRpdXM6IDAuMmVtOyB9XG4gIC5tZC10eXBlc2V0IC5zdXBlcmZlbmNlcy10YWJzID4gaW5wdXQge1xuICAgIGRpc3BsYXk6IG5vbmU7IH1cbiAgICAubWQtdHlwZXNldCAuc3VwZXJmZW5jZXMtdGFicyA+IGlucHV0OmNoZWNrZWQgKyBsYWJlbCB7XG4gICAgICBmb250LXdlaWdodDogNzAwOyB9XG4gICAgICAubWQtdHlwZXNldCAuc3VwZXJmZW5jZXMtdGFicyA+IGlucHV0OmNoZWNrZWQgKyBsYWJlbCArIC5zdXBlcmZlbmNlcy1jb250ZW50IHtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7IH1cbiAgLm1kLXR5cGVzZXQgLnN1cGVyZmVuY2VzLXRhYnMgPiBsYWJlbCB7XG4gICAgd2lkdGg6IGF1dG87XG4gICAgcGFkZGluZzogMS4ycmVtIDEuMnJlbTtcbiAgICB0cmFuc2l0aW9uOiBjb2xvciAwLjEyNXM7XG4gICAgZm9udC1zaXplOiAxLjI4cmVtO1xuICAgIGN1cnNvcjogcG9pbnRlcjsgfVxuICAgIGh0bWwgLm1kLXR5cGVzZXQgLnN1cGVyZmVuY2VzLXRhYnMgPiBsYWJlbDpob3ZlciB7XG4gICAgICBjb2xvcjogIzUzNmRmZTsgfVxuXG5AbWVkaWEgb25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDQ0LjkzNzVlbSkge1xuICAubWQtdHlwZXNldCA+IC5zdXBlcmZlbmNlcy10YWJzIHtcbiAgICBtYXJnaW46IDFlbSAtMS42cmVtO1xuICAgIGJvcmRlcjogMDtcbiAgICBib3JkZXItdG9wOiAwLjFyZW0gc29saWQgcmdiYSgwLCAwLCAwLCAwLjA3KTtcbiAgICBib3JkZXItcmFkaXVzOiAwOyB9XG4gICAgLm1kLXR5cGVzZXQgPiAuc3VwZXJmZW5jZXMtdGFicyBwcmUsXG4gICAgLm1kLXR5cGVzZXQgPiAuc3VwZXJmZW5jZXMtdGFicyBjb2RlIHtcbiAgICAgIHBhZGRpbmc6IDEuMDVyZW0gMS42cmVtOyB9IH1cblxuLm1kLXR5cGVzZXQgLnRhc2stbGlzdC1pdGVtIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBsaXN0LXN0eWxlLXR5cGU6IG5vbmU7IH1cbiAgLm1kLXR5cGVzZXQgLnRhc2stbGlzdC1pdGVtIFt0eXBlPVwiY2hlY2tib3hcIl0ge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDAuNDVlbTtcbiAgICBsZWZ0OiAtMmVtOyB9XG4gICAgW2Rpcj1cInJ0bFwiXSAubWQtdHlwZXNldCAudGFzay1saXN0LWl0ZW0gW3R5cGU9XCJjaGVja2JveFwiXSB7XG4gICAgICByaWdodDogLTJlbTtcbiAgICAgIGxlZnQ6IGluaXRpYWw7IH1cblxuLm1kLXR5cGVzZXQgLnRhc2stbGlzdC1jb250cm9sIC50YXNrLWxpc3QtaW5kaWNhdG9yOjpiZWZvcmUge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMC4xNWVtO1xuICBsZWZ0OiAtMS4yNWVtO1xuICBjb2xvcjogcmdiYSgwLCAwLCAwLCAwLjI2KTtcbiAgZm9udC1zaXplOiAxLjI1ZW07XG4gIGNvbnRlbnQ6IFwiXFxFODM1XCI7XG4gIHZlcnRpY2FsLWFsaWduOiAtMC4yNWVtOyB9XG4gIFtkaXI9XCJydGxcIl0gLm1kLXR5cGVzZXQgLnRhc2stbGlzdC1jb250cm9sIC50YXNrLWxpc3QtaW5kaWNhdG9yOjpiZWZvcmUge1xuICAgIHJpZ2h0OiAtMS4yNWVtO1xuICAgIGxlZnQ6IGluaXRpYWw7IH1cblxuLm1kLXR5cGVzZXQgLnRhc2stbGlzdC1jb250cm9sIFt0eXBlPVwiY2hlY2tib3hcIl06Y2hlY2tlZCArIC50YXNrLWxpc3QtaW5kaWNhdG9yOjpiZWZvcmUge1xuICBjb250ZW50OiBcIlxcRTgzNFwiOyB9XG5cbi5tZC10eXBlc2V0IC50YXNrLWxpc3QtY29udHJvbCBbdHlwZT1cImNoZWNrYm94XCJdIHtcbiAgb3BhY2l0eTogMDtcbiAgei1pbmRleDogLTE7IH1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvYXBwbGljYXRpb24uc2NzcyIsIi8vLy9cbi8vLyBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4vLy9cbi8vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSxcbi8vLyB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uXG4vLy8gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsXG4vLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlXG4vLy8gU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vL1xuLy8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vLy9cbi8vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMXG4vLy8gVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuLy8vIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVJcbi8vLyBERUFMSU5HU1xuLy8vL1xuXG4vLyBzdHlsZWxpbnQtZGlzYWJsZSBuby1kdXBsaWNhdGUtc2VsZWN0b3JzXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIEVuZm9yY2UgY29ycmVjdCBib3ggbW9kZWxcbmh0bWwge1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xufVxuXG4vLyBBbGwgZWxlbWVudHMgc2hhbGwgaW5oZXJpdCB0aGUgZG9jdW1lbnQgZGVmYXVsdFxuKixcbio6OmJlZm9yZSxcbio6OmFmdGVyIHtcbiAgYm94LXNpemluZzogaW5oZXJpdDtcbn1cblxuLy8gUHJldmVudCBhZGp1c3RtZW50cyBvZiBmb250IHNpemUgYWZ0ZXIgb3JpZW50YXRpb24gY2hhbmdlcyBpbiBJRSBhbmQgaU9TXG5odG1sIHtcbiAgdGV4dC1zaXplLWFkanVzdDogbm9uZTtcbn1cblxuLy8gUmVtb3ZlIG1hcmdpbiBpbiBhbGwgYnJvd3NlcnNcbmJvZHkge1xuICBtYXJnaW46IDA7XG59XG5cbi8vIFJlc2V0IGhvcml6b250YWwgcnVsZXMgaW4gRkZcbmhyIHtcbiAgb3ZlcmZsb3c6IHZpc2libGU7XG4gIGJveC1zaXppbmc6IGNvbnRlbnQtYm94O1xufVxuXG4vLyBSZW1vdmUgZ2FwcyBpbiB1bmRlcmxpbmVkIGxpbmtzIGluIGlPUyA+PSA4IGFuZCBTYWZhcmkgPj0gOFxuYSB7XG4gIC13ZWJraXQtdGV4dC1kZWNvcmF0aW9uLXNraXA6IG9iamVjdHM7XG59XG5cbi8vIFJlc2V0IHRhcCBvdXRsaW5lcyBvbiBpT1MgYW5kIEFuZHJvaWRcbmEsXG5idXR0b24sXG5sYWJlbCxcbmlucHV0IHtcbiAgLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yOiB0cmFuc3BhcmVudDtcbn1cblxuLy8gUmVzZXQgbGluayBzdHlsZXNcbmEge1xuICBjb2xvcjogaW5oZXJpdDtcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xufVxuXG4vLyBOb3JtYWxpemUgZm9udC1zaXplIGluIGFsbCBicm93c2Vyc1xuc21hbGwge1xuICBmb250LXNpemU6IDgwJTtcbn1cblxuLy8gUHJldmVudCBzdWJzY3JpcHQgYW5kIHN1cGVyc2NyaXB0IGZyb20gYWZmZWN0aW5nIGxpbmUtaGVpZ2h0XG5zdWIsXG5zdXAge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGZvbnQtc2l6ZTogODAlO1xuICBsaW5lLWhlaWdodDogMDtcbiAgdmVydGljYWwtYWxpZ246IGJhc2VsaW5lO1xufVxuXG4vLyBDb3JyZWN0IHN1YnNjcmlwdCBvZmZzZXRcbnN1YiB7XG4gIGJvdHRvbTogLTAuMjVlbTtcbn1cblxuLy8gQ29ycmVjdCBzdXBlcnNjcmlwdCBvZmZzZXRcbnN1cCB7XG4gIHRvcDogLTAuNWVtO1xufVxuXG4vLyBSZW1vdmUgYm9yZGVycyBvbiBpbWFnZXNcbmltZyB7XG4gIGJvcmRlci1zdHlsZTogbm9uZTtcbn1cblxuLy8gUmVzZXQgdGFibGUgc3R5bGVzXG50YWJsZSB7XG4gIGJvcmRlci1jb2xsYXBzZTogc2VwYXJhdGU7XG4gIGJvcmRlci1zcGFjaW5nOiAwO1xufVxuXG4vLyBSZXNldCB0YWJsZSBjZWxsIHN0eWxlc1xudGQsXG50aCB7XG4gIGZvbnQtd2VpZ2h0OiBub3JtYWw7XG4gIHZlcnRpY2FsLWFsaWduOiB0b3A7XG59XG5cbi8vIFJlc2V0IChuYXRpdmUpIGJ1dHRvbiBzdHlsZXNcbmJ1dHRvbiB7XG4gIG1hcmdpbjogMDtcbiAgcGFkZGluZzogMDtcbiAgYm9yZGVyOiAwO1xuICBvdXRsaW5lLXN0eWxlOiBub25lO1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgZm9udC1zaXplOiBpbmhlcml0O1xufVxuXG4vLyBSZXNldCAobmF0aXZlKSBpbnB1dCBzdHlsZXNcbmlucHV0IHtcbiAgYm9yZGVyOiAwO1xuICBvdXRsaW5lOiAwO1xufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9iYXNlL19yZXNldC5zY3NzIiwiLy8vL1xuLy8vIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbi8vL1xuLy8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLFxuLy8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb25cbi8vLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSxcbi8vLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGVcbi8vLyBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy8vXG4vLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vL1xuLy8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTExcbi8vLyBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4vLy8gRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUlxuLy8vIERFQUxJTkdTXG4vLy8vXG5cbi8vIHN0eWxlbGludC1kaXNhYmxlIGZvbnQtZmFtaWx5LW5vLW1pc3NpbmctZ2VuZXJpYy1mYW1pbHkta2V5d29yZFxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBSdWxlc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBJY29uIHBsYWNlaG9sZGVyc1xuJW1kLWljb24ge1xuICBmb250LWZhbWlseTogXCJNYXRlcmlhbCBJY29uc1wiO1xuICBmb250LXN0eWxlOiBub3JtYWw7XG4gIGZvbnQtdmFyaWFudDogbm9ybWFsO1xuICBmb250LXdlaWdodDogbm9ybWFsO1xuICBsaW5lLWhlaWdodDogMTtcbiAgdGV4dC10cmFuc2Zvcm06IG5vbmU7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIHNwZWFrOiBub25lO1xuICB3b3JkLXdyYXA6IG5vcm1hbDtcbiAgZGlyZWN0aW9uOiBsdHI7XG5cbiAgLy8gSWNvbiByZW5kZXJlZCBhcyBidXR0b25cbiAgJl9fYnV0dG9uIHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgbWFyZ2luOiAkbWQtaWNvbi1tYXJnaW47XG4gICAgcGFkZGluZzogJG1kLWljb24tcGFkZGluZztcbiAgICBmb250LXNpemU6ICRtZC1pY29uLXNpemU7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICB9XG59XG5cbi8vIFJlcHJlc2VudGF0aW9uYWwgY2xhc3Nlc1xuLm1kLWljb24ge1xuICBAZXh0ZW5kICVtZC1pY29uO1xuXG4gIC8vIEJ1aWxkIHJlcHJlc2VudGF0aW9uYWwgY2xhc3Nlc1xuICBAZWFjaCAkbGlnYXR1cmUsICRuYW1lIGluIChcbiAgICBcIlxcRTVDNFwiOiBcImFycm93LWJhY2tcIiwgLy8gYXJyb3dfYmFja1xuICAgIFwiXFxFNUM4XCI6IFwiYXJyb3ctZm9yd2FyZFwiLCAvLyBhcnJvd19mb3J3YXJkXG4gICAgXCJcXEU1RDJcIjogXCJtZW51XCIsIC8vIG1lbnVcbiAgICBcIlxcRThCNlwiOiBcInNlYXJjaFwiIC8vIHNlYXJjaFxuICApIHtcbiAgICAmLS0jeyRuYW1lfTo6YmVmb3JlIHtcbiAgICAgIGNvbnRlbnQ6ICRsaWdhdHVyZTtcbiAgICB9XG4gIH1cblxuICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgW2Rpcj1cInJ0bFwiXSAmIHtcblxuICAgIC8vIEZsaXAgbGlnYXR1cmVzIGZvciBhcnJvd3NcbiAgICBAZWFjaCAkbGlnYXR1cmUsICRuYW1lIGluIChcbiAgICAgIFwiXFxFNUM4XCI6IFwiYXJyb3ctYmFja1wiLCAvLyBhcnJvd19mb3J3YXJkXG4gICAgICBcIlxcRTVDNFwiOiBcImFycm93LWZvcndhcmRcIiAvLyBhcnJvd19iYWNrXG4gICAgKSB7XG4gICAgICAmLS0jeyRuYW1lfTo6YmVmb3JlIHtcbiAgICAgICAgY29udGVudDogJGxpZ2F0dXJlO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9iYXNlL19pY29ucy5zY3NzIiwiLy8vL1xuLy8vIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbi8vL1xuLy8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLFxuLy8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb25cbi8vLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSxcbi8vLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGVcbi8vLyBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy8vXG4vLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vL1xuLy8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTExcbi8vLyBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4vLy8gRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUlxuLy8vIERFQUxJTkdTXG4vLy8vXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFZhcmlhYmxlczogdHlwb2dyYXBoeVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBNb2R1bGFyIHR5cG9ncmFwaGljIHNjYWxlXG4kbXMtYmFzZTogMS42cmVtO1xuJG1zLXJhdGlvOiAkbWFqb3ItdGhpcmQ7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFZhcmlhYmxlczogYnJlYWtwb2ludHNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gc3R5bGVsaW50LWRpc2FibGUgdW5pdC13aGl0ZWxpc3RcblxuLy8gRGV2aWNlLXNwZWNpZmljIGJyZWFrcG9pbnRzXG4kYnJlYWstZGV2aWNlczogKFxuICBtb2JpbGU6IChcbiAgICBwb3J0cmFpdDogIHB4MmVtKDIyMHB4KSAgcHgyZW0oNDc5cHgpLFxuICAgIGxhbmRzY2FwZTogcHgyZW0oNDgwcHgpICBweDJlbSg3MTlweClcbiAgKSxcbiAgdGFibGV0OiAoXG4gICAgcG9ydHJhaXQ6ICBweDJlbSg3MjBweCkgIHB4MmVtKDk1OXB4KSxcbiAgICBsYW5kc2NhcGU6IHB4MmVtKDk2MHB4KSAgcHgyZW0oMTIxOXB4KVxuICApLFxuICBzY3JlZW46IChcbiAgICBzbWFsbDogICAgIHB4MmVtKDEyMjBweCkgcHgyZW0oMTU5OXB4KSxcbiAgICBtZWRpdW06ICAgIHB4MmVtKDE2MDBweCkgcHgyZW0oMTk5OXB4KSxcbiAgICBsYXJnZTogICAgIHB4MmVtKDIwMDBweClcbiAgKVxuKTtcblxuLy8gc3R5bGVsaW50LWVuYWJsZSB1bml0LXdoaXRlbGlzdFxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBWYXJpYWJsZXM6IGJhc2UgY29sb3JzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIFByaW1hcnkgYW5kIGFjY2VudCBjb2xvcnNcbiRtZC1jb2xvci1wcmltYXJ5OiAgICAgICAgICAgICAgICAgICAgJGNsci1pbmRpZ28tNTAwICFkZWZhdWx0O1xuJG1kLWNvbG9yLWFjY2VudDogICAgICAgICAgICAgICAgICAgICAkY2xyLWluZGlnby1hMjAwICFkZWZhdWx0O1xuXG4vLyBTaGFkZXMgb2YgYmxhY2tcbiRtZC1jb2xvci1ibGFjazogICAgICAgICAgICAgICAgICAgICAgaHNsYSgwLCAwJSwgMCUsIDAuODcpICFkZWZhdWx0O1xuJG1kLWNvbG9yLWJsYWNrLS1saWdodDogICAgICAgICAgICAgICBoc2xhKDAsIDAlLCAwJSwgMC41NCkgIWRlZmF1bHQ7XG4kbWQtY29sb3ItYmxhY2stLWxpZ2h0ZXI6ICAgICAgICAgICAgIGhzbGEoMCwgMCUsIDAlLCAwLjI2KSAhZGVmYXVsdDtcbiRtZC1jb2xvci1ibGFjay0tbGlnaHRlc3Q6ICAgICAgICAgICAgaHNsYSgwLCAwJSwgMCUsIDAuMDcpICFkZWZhdWx0O1xuJG1kLWNvbG9yLWJsYWNrLS10cmFuc3BhcmVudDogICAgICAgICBoc2xhKDAsIDAlLCAwJSwgMCkgIWRlZmF1bHQ7XG5cbi8vIFNoYWRlcyBvZiB3aGl0ZVxuJG1kLWNvbG9yLXdoaXRlOiAgICAgICAgICAgICAgICAgICAgICBoc2xhKDAsIDAlLCAxMDAlLCAxKSAhZGVmYXVsdDtcbiRtZC1jb2xvci13aGl0ZS0tbGlnaHQ6ICAgICAgICAgICAgICAgaHNsYSgwLCAwJSwgMTAwJSwgMC43KSAhZGVmYXVsdDtcbiRtZC1jb2xvci13aGl0ZS0tbGlnaHRlcjogICAgICAgICAgICAgaHNsYSgwLCAwJSwgMTAwJSwgMC4zKSAhZGVmYXVsdDtcbiRtZC1jb2xvci13aGl0ZS0tbGlnaHRlc3Q6ICAgICAgICAgICAgaHNsYSgwLCAwJSwgMTAwJSwgMC4xMikgIWRlZmF1bHQ7XG4kbWQtY29sb3Itd2hpdGUtLXRyYW5zcGFyZW50OiAgICAgICAgIGhzbGEoMCwgMCUsIDEwMCUsIDApICFkZWZhdWx0O1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBWYXJpYWJsZXM6IHNpemluZyBhbmQgc3BhY2luZ1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBJY29uc1xuJG1kLWljb24tc2l6ZTogICAgICAgICAgICAgICAgICAgICAgICAkbXMtYmFzZSAqIDEuNTtcbiRtZC1pY29uLXBhZGRpbmc6ICAgICAgICAgICAgICAgICAgICAgJG1zLWJhc2UgKiAwLjU7XG4kbWQtaWNvbi1tYXJnaW46ICAgICAgICAgICAgICAgICAgICAgICRtcy1iYXNlICogMC4yNTtcblxuLy8gQ29kZSBibG9ja3NcbiRtZC1jb2RlLWJhY2tncm91bmQ6ICAgICAgICAgICAgICAgICAgaHNsYSgwLCAwJSwgOTIuNSUsIDAuNSk7XG4kbWQtY29kZS1jb2xvcjogICAgICAgICAgICAgICAgICAgICAgICMzNzQ3NEY7XG5cbi8vIEtleXN0cm9rZXNcbiRtZC1rZXlib2FyZC1iYWNrZ3JvdW5kOiAgICAgICAgICAgICAgI0ZDRkNGQztcbiRtZC1rZXlib2FyZC1jb2xvcjogICAgICAgICAgICAgICAgICAgIzU1NTU1NTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvX2NvbmZpZy5zY3NzIiwiLy8vL1xuLy8vIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbi8vL1xuLy8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLFxuLy8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb25cbi8vLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSxcbi8vLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGVcbi8vLyBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy8vXG4vLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vL1xuLy8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTExcbi8vLyBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4vLy8gRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUlxuLy8vIERFQUxJTkdTXG4vLy8vXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzOiBmb250IGRlZmluaXRpb25zXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIEVuYWJsZSBmb250LXNtb290aGluZyBpbiBXZWJraXQgYW5kIEZGXG5ib2R5IHtcbiAgLXdlYmtpdC1mb250LXNtb290aGluZzogYW50aWFsaWFzZWQ7XG4gIC1tb3otb3N4LWZvbnQtc21vb3RoaW5nOiBncmF5c2NhbGU7XG59XG5cbi8vIERlZmF1bHQgZm9udHNcbmJvZHksXG5pbnB1dCB7XG4gIGNvbG9yOiAkbWQtY29sb3ItYmxhY2s7XG4gIGZvbnQtZmVhdHVyZS1zZXR0aW5nczogXCJrZXJuXCIsIFwibGlnYVwiO1xuICBmb250LWZhbWlseTogXCJIZWx2ZXRpY2EgTmV1ZVwiLCBIZWx2ZXRpY2EsIEFyaWFsLCBzYW5zLXNlcmlmO1xufVxuXG4vLyBQcm9wb3J0aW9uYWxseSBzcGFjZWQgZm9udHNcbnByZSxcbmNvZGUsXG5rYmQge1xuICBjb2xvcjogJG1kLWNvbG9yLWJsYWNrO1xuICBmb250LWZlYXR1cmUtc2V0dGluZ3M6IFwia2VyblwiO1xuICBmb250LWZhbWlseTogXCJDb3VyaWVyIE5ld1wiLCBDb3VyaWVyLCBtb25vc3BhY2U7XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzOiB0eXBlc2V0dGVkIGNvbnRlbnRcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gQ29udGVudCB0aGF0IGlzIHR5cGVzZXQgLSBpZiBwb3NzaWJsZSwgYWxsIG1hcmdpbnMsIHBhZGRpbmdzIGFuZCBmb250IHNpemVzXG4vLyBzaG91bGQgYmUgc2V0IGluIGVtcywgc28gbmVzdGVkIGJsb2NrcyAoZS5nLiBBZG1vbml0aW9uKSByZW5kZXIgY29ycmVjdGx5LFxuLy8gZXhjZXB0IGhlYWRsaW5lcyB0aGF0IHNob3VsZCBvbmx5IGFwcGVhciBvbiB0aGUgdG9wIGxldmVsIGFuZCBuZWVkIHRvIGhhdmVcbi8vIGNvbnNpc3RlbnQgc3BhY2luZyBkdWUgdG8gbGF5b3V0IGNvbnN0cmFpbnRzLlxuLm1kLXR5cGVzZXQge1xuICBmb250LXNpemU6IG1zKDApO1xuICBsaW5lLWhlaWdodDogMS42O1xuXG4gIC8vIENvbG9ycyBzaG91bGQgYmUga2VwdCB3aGVuIHByaW50aW5nXG4gIC13ZWJraXQtcHJpbnQtY29sb3ItYWRqdXN0OiBleGFjdDtcblxuICAvLyBEZWZhdWx0IHNwYWNpbmdcbiAgcCxcbiAgdWwsXG4gIG9sLFxuICBibG9ja3F1b3RlIHtcbiAgICBtYXJnaW46IDFlbSAwO1xuICB9XG5cbiAgLy8gMXN0IGxldmVsIGhlYWRsaW5lXG4gIGgxIHtcbiAgICBtYXJnaW46IDAgMCA0cmVtO1xuICAgIGNvbG9yOiAkbWQtY29sb3ItYmxhY2stLWxpZ2h0O1xuICAgIGZvbnQtc2l6ZTogbXMoMyk7XG4gICAgZm9udC13ZWlnaHQ6IDMwMDtcbiAgICBsZXR0ZXItc3BhY2luZzogLTAuMDFlbTtcbiAgICBsaW5lLWhlaWdodDogMS4zO1xuICB9XG5cbiAgLy8gMm5kIGxldmVsIGhlYWRsaW5lXG4gIGgyIHtcbiAgICBtYXJnaW46IDRyZW0gMCAxLjZyZW07XG4gICAgZm9udC1zaXplOiBtcygyKTtcbiAgICBmb250LXdlaWdodDogMzAwO1xuICAgIGxldHRlci1zcGFjaW5nOiAtMC4wMWVtO1xuICAgIGxpbmUtaGVpZ2h0OiAxLjQ7XG4gIH1cblxuICAvLyAzcmQgbGV2ZWwgaGVhZGxpbmVcbiAgaDMge1xuICAgIG1hcmdpbjogMy4ycmVtIDAgMS42cmVtO1xuICAgIGZvbnQtc2l6ZTogbXMoMSk7XG4gICAgZm9udC13ZWlnaHQ6IDQwMDtcbiAgICBsZXR0ZXItc3BhY2luZzogLTAuMDFlbTtcbiAgICBsaW5lLWhlaWdodDogMS41O1xuICB9XG5cbiAgLy8gM3JkIGxldmVsIGhlYWRsaW5lIGZvbGxvd2luZyBhbiAybmQgbGV2ZWwgaGVhZGxpbmVcbiAgaDIgKyBoMyB7XG4gICAgbWFyZ2luLXRvcDogMS42cmVtO1xuICB9XG5cbiAgLy8gNHRoIGxldmVsIGhlYWRsaW5lXG4gIGg0IHtcbiAgICBtYXJnaW46IDEuNnJlbSAwO1xuICAgIGZvbnQtc2l6ZTogbXMoMCk7XG4gICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICBsZXR0ZXItc3BhY2luZzogLTAuMDFlbTtcbiAgfVxuXG4gIC8vIDV0aCBhbmQgNnRoIGxldmVsIGhlYWRsaW5lXG4gIGg1LFxuICBoNiB7XG4gICAgbWFyZ2luOiAxLjZyZW0gMDtcbiAgICBjb2xvcjogJG1kLWNvbG9yLWJsYWNrLS1saWdodDtcbiAgICBmb250LXNpemU6IG1zKC0xKTtcbiAgICBmb250LXdlaWdodDogNzAwO1xuICAgIGxldHRlci1zcGFjaW5nOiAtMC4wMWVtO1xuICB9XG5cbiAgLy8gT3ZlcnJpZGVzIGZvciA1dGggbGV2ZWwgaGVhZGxpbmVcbiAgaDUge1xuICAgIHRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7XG4gIH1cblxuICAvLyBIb3Jpem9udGFsIHNlcGFyYXRvcnNcbiAgaHIge1xuICAgIG1hcmdpbjogMS41ZW0gMDtcbiAgICBib3JkZXItYm90dG9tOiAwLjFyZW0gZG90dGVkICRtZC1jb2xvci1ibGFjay0tbGlnaHRlcjtcbiAgfVxuXG4gIC8vIExpbmtzXG4gIGEge1xuICAgIGNvbG9yOiAkbWQtY29sb3ItcHJpbWFyeTtcbiAgICB3b3JkLWJyZWFrOiBicmVhay13b3JkO1xuXG4gICAgLy8gQWxzbyBlbmFibGUgY29sb3IgdHJhbnNpdGlvbiBvbiBwc2V1ZG8gZWxlbWVudHNcbiAgICAmLFxuICAgICY6OmJlZm9yZSB7XG4gICAgICB0cmFuc2l0aW9uOiBjb2xvciAwLjEyNXM7XG4gICAgfVxuXG4gICAgLy8gSG92ZXJlZCBhbmQgYWN0aXZlIGxpbmtzXG4gICAgJjpob3ZlcixcbiAgICAmOmFjdGl2ZSB7XG4gICAgICBjb2xvcjogJG1kLWNvbG9yLWFjY2VudDtcbiAgICB9XG5cbiAgICAvLyBBZGQgVVJMcyBmb3IgcHJpbnRcbiAgICBAbWVkaWEgcHJpbnQge1xuXG4gICAgICAvLyBTaG93IGxpbmsgVVJMXG4gICAgICAmOjphZnRlciB7XG4gICAgICAgIGNvbG9yOiAkbWQtY29sb3ItYmxhY2stLWxpZ2h0O1xuICAgICAgICBjb250ZW50OiBcIiBbXCIgYXR0cihocmVmKSBcIl1cIjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBDb2RlIGJsb2Nrc1xuICBjb2RlLFxuICBwcmUge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2RlLWJhY2tncm91bmQ7XG4gICAgY29sb3I6ICRtZC1jb2RlLWNvbG9yO1xuICAgIGZvbnQtc2l6ZTogODUlO1xuICAgIGRpcmVjdGlvbjogbHRyO1xuXG4gICAgLy8gV3JhcCB0ZXh0IGFuZCBoaWRlIHNjb2xsYmFyc1xuICAgIEBtZWRpYSBwcmludCB7XG4gICAgICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7XG4gICAgfVxuICB9XG5cbiAgLy8gSW5saW5lIGNvZGUgYmxvY2tzLCBjb3JyZWN0IHJlbGF0aXZlIGVtcyBmb3Igc21hbGxlciBmb250IHNpemVcbiAgY29kZSB7XG4gICAgJGNvcnJlY3Q6IDEgLyAwLjg1O1xuXG4gICAgbWFyZ2luOiAwIDAuMjVlbSAqICRjb3JyZWN0O1xuICAgIHBhZGRpbmc6IDAuMDYyNWVtICogJGNvcnJlY3QgMDtcbiAgICBib3JkZXItcmFkaXVzOiAwLjJyZW07XG4gICAgYm94LXNoYWRvdzpcbiAgICAgICswLjI1ZW0gKiAkY29ycmVjdCAwIDAgJG1kLWNvZGUtYmFja2dyb3VuZCxcbiAgICAgIC0wLjI1ZW0gKiAkY29ycmVjdCAwIDAgJG1kLWNvZGUtYmFja2dyb3VuZDtcbiAgICB3b3JkLWJyZWFrOiBicmVhay13b3JkO1xuICAgIGJveC1kZWNvcmF0aW9uLWJyZWFrOiBjbG9uZTtcblxuICAgIC8vIFJlbW92ZSBib3gtc2hhZG93cyBmb3IgcHJpbnRcbiAgICBAbWVkaWEgcHJpbnQge1xuICAgICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICAgIGJveC1kZWNvcmF0aW9uLWJyZWFrOiBpbml0aWFsO1xuICAgIH1cbiAgfVxuXG4gIC8vIERpc2FibGUgY29udGFpbmluZyBibG9jayBpbnNpZGUgaGVhZGxpbmVzXG4gIGgxIGNvZGUsXG4gIGgyIGNvZGUsXG4gIGgzIGNvZGUsXG4gIGg0IGNvZGUsXG4gIGg1IGNvZGUsXG4gIGg2IGNvZGUge1xuICAgIG1hcmdpbjogMDtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICBib3gtc2hhZG93OiBub25lO1xuICB9XG5cbiAgLy8gUmVzZXQgY29kZSBpZiBpdCdzIGluc2lkZSBhIGxpbmtcbiAgYSA+IGNvZGUge1xuICAgIG1hcmdpbjogaW5oZXJpdDtcbiAgICBwYWRkaW5nOiBpbmhlcml0O1xuICAgIGJvcmRlci1yYWRpdXM6IG5vbmU7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogaW5oZXJpdDtcbiAgICBjb2xvcjogaW5oZXJpdDtcbiAgICBib3gtc2hhZG93OiBub25lO1xuICB9XG5cbiAgLy8gVW5mb3JtYXR0ZWQgY29kZSBibG9ja3NcbiAgcHJlIHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgbWFyZ2luOiAxZW0gMDtcbiAgICBib3JkZXItcmFkaXVzOiAwLjJyZW07XG4gICAgbGluZS1oZWlnaHQ6IDEuNDtcbiAgICAtd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzogdG91Y2g7XG5cbiAgICAvLyBbbW9iaWxlIC1dOiBTdHJldGNoIHRvIHdob2xlIHdpZHRoXG4gICAgQGluY2x1ZGUgYnJlYWstdG8tZGV2aWNlKG1vYmlsZSkge1xuICAgICAgbWFyZ2luOiAxZW0gLTEuNnJlbTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDA7XG4gICAgfVxuXG4gICAgLy8gQWN0dWFsIGNvbnRhaW5lciB3aXRoIGNvZGUsIG92ZXJmbG93aW5nXG4gICAgPiBjb2RlIHtcbiAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgbWFyZ2luOiAwO1xuICAgICAgcGFkZGluZzogMS4wNXJlbSAxLjJyZW07XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgICAgIGZvbnQtc2l6ZTogaW5oZXJpdDtcbiAgICAgIGJveC1zaGFkb3c6IG5vbmU7XG4gICAgICBib3gtZGVjb3JhdGlvbi1icmVhazogbm9uZTtcbiAgICAgIG92ZXJmbG93OiBhdXRvO1xuXG4gICAgICAvLyBbbW9iaWxlIC1dOiBJbmNyZWFzZSBwYWRkaW5nIHRvIG1hdGNoIHRleHRcbiAgICAgIEBpbmNsdWRlIGJyZWFrLXRvLWRldmljZShtb2JpbGUpIHtcbiAgICAgICAgcGFkZGluZzogMS4wNXJlbSAxLjZyZW07XG4gICAgICB9XG5cbiAgICAgIC8vIE92ZXJyaWRlIG5hdGl2ZSBzY3JvbGxiYXIgc3R5bGVzXG4gICAgICAmOjotd2Via2l0LXNjcm9sbGJhciB7XG4gICAgICAgIHdpZHRoOiAwLjRyZW07XG4gICAgICAgIGhlaWdodDogMC40cmVtO1xuICAgICAgfVxuXG4gICAgICAvLyBTdHlsZSBzY3JvbGxiYXIgdGh1bWJcbiAgICAgICY6Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1iIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogJG1kLWNvbG9yLWJsYWNrLS1saWdodGVyO1xuXG4gICAgICAgIC8vIEhvdmVyZWQgc2Nyb2xsYmFyIHRodW1iXG4gICAgICAgICY6aG92ZXIge1xuICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2xvci1hY2NlbnQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBLZXlzdHJva2VzXG4gIGtiZCB7XG4gICAgJGNvcnJlY3Q6IDEgLyAwLjg1O1xuXG4gICAgcGFkZGluZzogMCAwLjI1ZW0gKiAkY29ycmVjdDtcbiAgICBib3JkZXI6IDAuMXJlbSBzb2xpZCBkYXJrZW4oJG1kLWtleWJvYXJkLWJhY2tncm91bmQsIDIwJSk7XG4gICAgYm9yZGVyLXJhZGl1czogMC4zcmVtO1xuICAgIGJvcmRlci1ib3R0b20tY29sb3I6IGRhcmtlbigkbWQta2V5Ym9hcmQtYmFja2dyb3VuZCwgMjUlKTtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQta2V5Ym9hcmQtYmFja2dyb3VuZDtcbiAgICBjb2xvcjogJG1kLWtleWJvYXJkLWNvbG9yO1xuICAgIGZvbnQtc2l6ZTogODUlO1xuICAgIGJveC1zaGFkb3c6IDAgMC4xcmVtIDAgZGFya2VuKCRtZC1rZXlib2FyZC1iYWNrZ3JvdW5kLCAzMCUpO1xuICAgIHdvcmQtYnJlYWs6IGJyZWFrLXdvcmQ7XG4gIH1cblxuICAvLyBUZXh0IGhpZ2hsaWdodGluZyBtYXJrZXJcbiAgbWFyayB7XG4gICAgbWFyZ2luOiAwIDAuMjVlbTtcbiAgICBwYWRkaW5nOiAwLjA2MjVlbSAwO1xuICAgIGJvcmRlci1yYWRpdXM6IDAuMnJlbTtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudGl6ZSgkY2xyLXllbGxvdy01MDAsIDAuNSk7XG4gICAgYm94LXNoYWRvdzpcbiAgICAgICswLjI1ZW0gMCAwIHRyYW5zcGFyZW50aXplKCRjbHIteWVsbG93LTUwMCwgMC41KSxcbiAgICAgIC0wLjI1ZW0gMCAwIHRyYW5zcGFyZW50aXplKCRjbHIteWVsbG93LTUwMCwgMC41KTtcbiAgICB3b3JkLWJyZWFrOiBicmVhay13b3JkO1xuICAgIGJveC1kZWNvcmF0aW9uLWJyZWFrOiBjbG9uZTtcbiAgfVxuXG4gIC8vIEFiYnJldmlhdGlvbnNcbiAgYWJiciB7XG4gICAgYm9yZGVyLWJvdHRvbTogMC4xcmVtIGRvdHRlZCAkbWQtY29sb3ItYmxhY2stLWxpZ2h0O1xuICAgIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcbiAgICBjdXJzb3I6IGhlbHA7XG4gIH1cblxuICAvLyBTbWFsbCB0ZXh0XG4gIHNtYWxsIHtcbiAgICBvcGFjaXR5OiAwLjc1O1xuICB9XG5cbiAgLy8gU3VwZXJzY3JpcHQgYW5kIHN1YnNjcmlwdFxuICBzdXAsXG4gIHN1YiB7XG4gICAgbWFyZ2luLWxlZnQ6IDAuMDYyNWVtICogMSAvIDAuODtcblxuICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICBtYXJnaW4tcmlnaHQ6IDAuMDYyNWVtICogMSAvIDAuODtcbiAgICAgIG1hcmdpbi1sZWZ0OiBpbml0aWFsO1xuICAgIH1cbiAgfVxuXG4gIC8vIEJsb2NrcXVvdGVzLCBwb3NzaWJseSBuZXN0ZWRcbiAgYmxvY2txdW90ZSB7XG4gICAgcGFkZGluZy1sZWZ0OiAxLjJyZW07XG4gICAgYm9yZGVyLWxlZnQ6IDAuNHJlbSBzb2xpZCAkbWQtY29sb3ItYmxhY2stLWxpZ2h0ZXI7XG4gICAgY29sb3I6ICRtZC1jb2xvci1ibGFjay0tbGlnaHQ7XG5cbiAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgcGFkZGluZy1yaWdodDogMS4ycmVtO1xuICAgICAgcGFkZGluZy1sZWZ0OiBpbml0aWFsO1xuICAgICAgYm9yZGVyLXJpZ2h0OiAwLjRyZW0gc29saWQgJG1kLWNvbG9yLWJsYWNrLS1saWdodGVyO1xuICAgICAgYm9yZGVyLWxlZnQ6IGluaXRpYWw7XG4gICAgfVxuICB9XG5cbiAgLy8gVW5vcmRlcmVkIGxpc3RzXG4gIHVsIHtcbiAgICBsaXN0LXN0eWxlLXR5cGU6IGRpc2M7XG4gIH1cblxuICAvLyBVbm9yZGVyZWQgYW5kIG9yZGVyZWQgbGlzdHNcbiAgdWwsXG4gIG9sIHtcbiAgICBtYXJnaW4tbGVmdDogMC42MjVlbTtcbiAgICBwYWRkaW5nOiAwO1xuXG4gICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgIG1hcmdpbi1yaWdodDogMC42MjVlbTtcbiAgICAgIG1hcmdpbi1sZWZ0OiBpbml0aWFsO1xuICAgIH1cblxuICAgIC8vIE5lc3RlZCBvcmRlcmVkIGxpc3RzXG4gICAgb2wge1xuICAgICAgbGlzdC1zdHlsZS10eXBlOiBsb3dlci1hbHBoYTtcblxuICAgICAgLy8gVHJpcGx5IG5lc3RlZCBvcmRlcmVkIGxpc3RcbiAgICAgIG9sIHtcbiAgICAgICAgbGlzdC1zdHlsZS10eXBlOiBsb3dlci1yb21hbjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBMaXN0IGVsZW1lbnRzXG4gICAgbGkge1xuICAgICAgbWFyZ2luLWJvdHRvbTogMC41ZW07XG4gICAgICBtYXJnaW4tbGVmdDogMS4yNWVtO1xuXG4gICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICAgIG1hcmdpbi1yaWdodDogMS4yNWVtO1xuICAgICAgICBtYXJnaW4tbGVmdDogaW5pdGlhbDtcbiAgICAgIH1cblxuICAgICAgLy8gRGVjcmVhc2UgdmVydGljYWwgc3BhY2luZ1xuICAgICAgcCxcbiAgICAgIGJsb2NrcXVvdGUge1xuICAgICAgICBtYXJnaW46IDAuNWVtIDA7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlbW92ZSBtYXJnaW4gb24gbGFzdCBlbGVtZW50XG4gICAgICAmOmxhc3QtY2hpbGQge1xuICAgICAgICBtYXJnaW4tYm90dG9tOiAwO1xuICAgICAgfVxuXG4gICAgICAvLyBOZXN0ZWQgbGlzdHNcbiAgICAgIHVsLFxuICAgICAgb2wge1xuICAgICAgICBtYXJnaW46IDAuNWVtIDAgMC41ZW0gMC42MjVlbTtcblxuICAgICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgICAgICBtYXJnaW4tcmlnaHQ6IDAuNjI1ZW07XG4gICAgICAgICAgbWFyZ2luLWxlZnQ6IGluaXRpYWw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBEZWZpbml0aW9uIGxpc3RzXG4gIGRkIHtcbiAgICBtYXJnaW46IDFlbSAwIDFlbSAxLjg3NWVtO1xuXG4gICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgIG1hcmdpbi1yaWdodDogMS44NzVlbTtcbiAgICAgIG1hcmdpbi1sZWZ0OiBpbml0aWFsO1xuICAgIH1cbiAgfVxuXG4gIC8vIExpbWl0IHdpZHRoIHRvIGNvbnRhaW5lclxuICBpZnJhbWUsXG4gIGltZyxcbiAgc3ZnIHtcbiAgICBtYXgtd2lkdGg6IDEwMCU7XG4gIH1cblxuICAvLyBEYXRhIHRhYmxlc1xuICB0YWJsZTpub3QoW2NsYXNzXSkge1xuICAgIEBpbmNsdWRlIHotZGVwdGgoMik7XG5cbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgbWF4LXdpZHRoOiAxMDAlO1xuICAgIGJvcmRlci1yYWRpdXM6IDAuMnJlbTtcbiAgICBmb250LXNpemU6IG1zKC0xKTtcbiAgICBvdmVyZmxvdzogYXV0bztcbiAgICAtd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzogdG91Y2g7XG5cbiAgICAvLyBEdWUgdG8gbWFyZ2luIGNvbGxhcHNlIGJlY2F1c2Ugb2YgdGhlIG5lY2Vzc2FyeSBpbmxpbmUtYmxvY2sgaGFjaywgd2VcbiAgICAvLyBjYW5ub3QgaW5jcmVhc2UgdGhlIGJvdHRvbSBtYXJnaW4gb24gdGhlIHRhYmxlLCBzbyB3ZSBqdXN0IGluY3JlYXNlIHRoZVxuICAgIC8vIHRvcCBtYXJnaW4gb24gdGhlIGZvbGxvd2luZyBlbGVtZW50XG4gICAgJiArICoge1xuICAgICAgbWFyZ2luLXRvcDogMS41ZW07XG4gICAgfVxuXG4gICAgLy8gVGFibGUgaGVhZGluZ3MgYW5kIGNlbGxzXG4gICAgdGg6bm90KFthbGlnbl0pLFxuICAgIHRkOm5vdChbYWxpZ25dKSB7XG4gICAgICB0ZXh0LWFsaWduOiBsZWZ0O1xuXG4gICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICAgIHRleHQtYWxpZ246IHJpZ2h0O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRhYmxlIGhlYWRpbmdzXG4gICAgdGgge1xuICAgICAgbWluLXdpZHRoOiAxMHJlbTtcbiAgICAgIHBhZGRpbmc6IDEuMnJlbSAxLjZyZW07XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQtY29sb3ItYmxhY2stLWxpZ2h0O1xuICAgICAgY29sb3I6ICRtZC1jb2xvci13aGl0ZTtcbiAgICAgIHZlcnRpY2FsLWFsaWduOiB0b3A7XG4gICAgfVxuXG4gICAgLy8gVGFibGUgY2VsbHNcbiAgICB0ZCB7XG4gICAgICBwYWRkaW5nOiAxLjJyZW0gMS42cmVtO1xuICAgICAgYm9yZGVyLXRvcDogMC4xcmVtIHNvbGlkICRtZC1jb2xvci1ibGFjay0tbGlnaHRlc3Q7XG4gICAgICB2ZXJ0aWNhbC1hbGlnbjogdG9wO1xuICAgIH1cblxuICAgIC8vIFJlbW92ZSB0b3AgYm9yZGVyIG9uIGZpcnN0IHJvd1xuICAgIHRyOmZpcnN0LWNoaWxkIHRkIHtcbiAgICAgIGJvcmRlci10b3A6IDA7XG4gICAgfVxuXG4gICAgLy8gRG8gbm90IHdyYXAgbGlua3MgaW4gdGFibGVzXG4gICAgYSB7XG4gICAgICB3b3JkLWJyZWFrOiBub3JtYWw7XG4gICAgfVxuICB9XG5cbiAgLy8gV3JhcHBlciBmb3Igc2Nyb2xsaW5nIG9uIG92ZXJmbG93XG4gICZfX3Njcm9sbHdyYXAge1xuICAgIG1hcmdpbjogMWVtIC0xLjZyZW07XG4gICAgb3ZlcmZsb3cteDogYXV0bztcbiAgICAtd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzogdG91Y2g7XG4gIH1cblxuICAvLyBEYXRhIHRhYmxlIHdyYXBwZXIsIGluIGNhc2UgSmF2YVNjcmlwdCBpcyBhdmFpbGFibGVcbiAgLm1kLXR5cGVzZXRfX3RhYmxlIHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgbWFyZ2luLWJvdHRvbTogMC41ZW07XG4gICAgcGFkZGluZzogMCAxLjZyZW07XG5cbiAgICAvLyBEYXRhIHRhYmxlc1xuICAgIHRhYmxlIHtcbiAgICAgIGRpc3BsYXk6IHRhYmxlO1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBtYXJnaW46IDA7XG4gICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9iYXNlL190eXBlc2V0LnNjc3MiLCJAZnVuY3Rpb24gbXMtZnVuY3Rpb24oJHY6IDAsICRiYXNlOiBmYWxzZSwgJHJhdGlvOiBmYWxzZSwgJHRocmVhZDogZmFsc2UsICRzZXR0aW5nczogJG1vZHVsYXJzY2FsZSkge1xuXG4gIC8vIFBhcnNlIHNldHRpbmdzXG4gICRtcy1zZXR0aW5nczogbXMtc2V0dGluZ3MoJGJhc2UsJHJhdGlvLCR0aHJlYWQsJHNldHRpbmdzKTtcbiAgJGJhc2U6IG50aCgkbXMtc2V0dGluZ3MsIDEpO1xuICAkcmF0aW86IG50aCgkbXMtc2V0dGluZ3MsIDIpO1xuXG4gIC8vIFJlbmRlciB0YXJnZXQgdmFsdWVzIGZyb20gc2V0dGluZ3MuXG4gIEBpZiB1bml0KCRyYXRpbykgIT0gJycge1xuICAgICRyYXRpbzogbXMtdGFyZ2V0KCRyYXRpbywkYmFzZSlcbiAgfVxuXG4gIC8vIEZhc3QgY2FsYyBpZiBub3QgbXVsdGkgc3RyYW5kZWRcbiAgQGlmKGxlbmd0aCgkYmFzZSkgPT0gMSkge1xuICAgIEByZXR1cm4gbXMtcG93KCRyYXRpbywgJHYpICogJGJhc2U7XG4gIH1cblxuICAvLyBDcmVhdGUgbmV3IGJhc2UgYXJyYXlcbiAgJG1zLWJhc2VzOiBudGgoJGJhc2UsMSk7XG5cbiAgLy8gTm9ybWFsaXplIGJhc2UgdmFsdWVzXG4gIEBmb3IgJGkgZnJvbSAyIHRocm91Z2ggbGVuZ3RoKCRiYXNlKSB7XG4gICAgLy8gaW5pdGlhbCBiYXNlIHZhbHVlXG4gICAgJG1zLWJhc2U6IG50aCgkYmFzZSwkaSk7XG4gICAgLy8gSWYgdGhlIGJhc2UgaXMgYmlnZ2VyIHRoYW4gdGhlIG1haW4gYmFzZVxuICAgIEBpZigkbXMtYmFzZSA+IG50aCgkYmFzZSwxKSkge1xuICAgICAgLy8gZGl2aWRlIHRoZSB2YWx1ZSB1bnRpbCBpdCBhbGlnbnMgd2l0aCBtYWluIGJhc2UuXG4gICAgICBAd2hpbGUoJG1zLWJhc2UgPiBudGgoJGJhc2UsMSkpIHtcbiAgICAgICAgJG1zLWJhc2U6ICRtcy1iYXNlIC8gJHJhdGlvO1xuICAgICAgfVxuICAgICAgJG1zLWJhc2U6ICRtcy1iYXNlICogJHJhdGlvO1xuICAgIH1cbiAgICAvLyBJZiB0aGUgYmFzZSBpcyBzbWFsbGVyIHRoYW4gdGhlIG1haW4gYmFzZS5cbiAgICBAZWxzZSBpZiAoJG1zLWJhc2UgPCBudGgoJGJhc2UsMSkpIHtcbiAgICAgIC8vIHB1bXAgdXAgdGhlIHZhbHVlIHVudGlsIGl0IGFsaWducyB3aXRoIG1haW4gYmFzZS5cbiAgICAgIEB3aGlsZSAkbXMtYmFzZSA8IG50aCgkYmFzZSwxKSB7XG4gICAgICAgICRtcy1iYXNlOiAkbXMtYmFzZSAqICRyYXRpbztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gUHVzaCBpbnRvIG5ldyBhcnJheVxuICAgICRtcy1iYXNlczogYXBwZW5kKCRtcy1iYXNlcywkbXMtYmFzZSk7XG4gIH1cblxuICAvLyBTb3J0IGFycmF5IGZyb20gc21hbGxlc3QgdG8gbGFyZ2VzdC5cbiAgJG1zLWJhc2VzOiBtcy1zb3J0KCRtcy1iYXNlcyk7XG5cbiAgLy8gRmluZCBzdGVwIHRvIHVzZSBpbiBjYWxjdWxhdGlvblxuICAkdnRlcDogZmxvb3IoJHYgLyBsZW5ndGgoJG1zLWJhc2VzKSk7XG4gIC8vIEZpbmQgYmFzZSB0byB1c2UgaW4gY2FsY3VsYXRpb25cbiAgJG1zLWJhc2U6IHJvdW5kKCgkdiAvIGxlbmd0aCgkbXMtYmFzZXMpIC0gJHZ0ZXApICogbGVuZ3RoKCRtcy1iYXNlcykpICsgMTtcblxuICBAcmV0dXJuIG1zLXBvdygkcmF0aW8sICR2dGVwKSAqIG50aCgkbXMtYmFzZXMsJG1zLWJhc2UpO1xufVxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL25vZGVfbW9kdWxlcy9tb2R1bGFyc2NhbGUtc2Fzcy9zdHlsZXNoZWV0cy9tb2R1bGFyc2NhbGUvX2Z1bmN0aW9uLnNjc3MiLCIvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy9cbi8vIE5hbWU6ICAgICAgICBVSSBDb2xvciBQYWxldHRlXG4vLyBEZXNjcmlwdGlvbjogVGhlIGNvbG9yIHBhbGV0dGUgb2YgbWF0ZXJpYWwgZGVzaWduLlxuLy8gVmVyc2lvbjogICAgIDIuMy4xXG4vL1xuLy8gQXV0aG9yOiAgICAgIERlbmlzIE1hbGlub2Noa2luXG4vLyBHaXQ6ICAgICAgICAgaHR0cHM6Ly9naXRodWIuY29tL21ybWxuYy9tYXRlcmlhbC1jb2xvclxuLy9cbi8vIHR3aXR0ZXI6ICAgICBAbXJtbG5jXG4vL1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuXG4vL1xuLy8gTGlzdCBvZiBiYXNlIGNvbG9yc1xuLy9cblxuLy8gJGNsci1yZWRcbi8vICRjbHItcGlua1xuLy8gJGNsci1wdXJwbGVcbi8vICRjbHItZGVlcC1wdXJwbGVcbi8vICRjbHItaW5kaWdvXG4vLyAkY2xyLWJsdWVcbi8vICRjbHItbGlnaHQtYmx1ZVxuLy8gJGNsci1jeWFuXG4vLyAkY2xyLXRlYWxcbi8vICRjbHItZ3JlZW5cbi8vICRjbHItbGlnaHQtZ3JlZW5cbi8vICRjbHItbGltZVxuLy8gJGNsci15ZWxsb3dcbi8vICRjbHItYW1iZXJcbi8vICRjbHItb3JhbmdlXG4vLyAkY2xyLWRlZXAtb3JhbmdlXG4vLyAkY2xyLWJyb3duXG4vLyAkY2xyLWdyZXlcbi8vICRjbHItYmx1ZS1ncmV5XG4vLyAkY2xyLWJsYWNrXG4vLyAkY2xyLXdoaXRlXG5cblxuLy9cbi8vIFJlZFxuLy9cblxuJGNsci1yZWQtbGlzdDogKFxuICBcImJhc2VcIjogI2Y0NDMzNixcbiAgXCI1MFwiOiAgICNmZmViZWUsXG4gIFwiMTAwXCI6ICAjZmZjZGQyLFxuICBcIjIwMFwiOiAgI2VmOWE5YSxcbiAgXCIzMDBcIjogICNlNTczNzMsXG4gIFwiNDAwXCI6ICAjZWY1MzUwLFxuICBcIjUwMFwiOiAgI2Y0NDMzNixcbiAgXCI2MDBcIjogICNlNTM5MzUsXG4gIFwiNzAwXCI6ICAjZDMyZjJmLFxuICBcIjgwMFwiOiAgI2M2MjgyOCxcbiAgXCI5MDBcIjogICNiNzFjMWMsXG4gIFwiYTEwMFwiOiAjZmY4YTgwLFxuICBcImEyMDBcIjogI2ZmNTI1MixcbiAgXCJhNDAwXCI6ICNmZjE3NDQsXG4gIFwiYTcwMFwiOiAjZDUwMDAwXG4pO1xuXG4kY2xyLXJlZDogICAgICBtYXAtZ2V0KCRjbHItcmVkLWxpc3QsIFwiYmFzZVwiKTtcblxuJGNsci1yZWQtNTA6ICAgbWFwLWdldCgkY2xyLXJlZC1saXN0LCBcIjUwXCIpO1xuJGNsci1yZWQtMTAwOiAgbWFwLWdldCgkY2xyLXJlZC1saXN0LCBcIjEwMFwiKTtcbiRjbHItcmVkLTIwMDogIG1hcC1nZXQoJGNsci1yZWQtbGlzdCwgXCIyMDBcIik7XG4kY2xyLXJlZC0zMDA6ICBtYXAtZ2V0KCRjbHItcmVkLWxpc3QsIFwiMzAwXCIpO1xuJGNsci1yZWQtNDAwOiAgbWFwLWdldCgkY2xyLXJlZC1saXN0LCBcIjQwMFwiKTtcbiRjbHItcmVkLTUwMDogIG1hcC1nZXQoJGNsci1yZWQtbGlzdCwgXCI1MDBcIik7XG4kY2xyLXJlZC02MDA6ICBtYXAtZ2V0KCRjbHItcmVkLWxpc3QsIFwiNjAwXCIpO1xuJGNsci1yZWQtNzAwOiAgbWFwLWdldCgkY2xyLXJlZC1saXN0LCBcIjcwMFwiKTtcbiRjbHItcmVkLTgwMDogIG1hcC1nZXQoJGNsci1yZWQtbGlzdCwgXCI4MDBcIik7XG4kY2xyLXJlZC05MDA6ICBtYXAtZ2V0KCRjbHItcmVkLWxpc3QsIFwiOTAwXCIpO1xuJGNsci1yZWQtYTEwMDogbWFwLWdldCgkY2xyLXJlZC1saXN0LCBcImExMDBcIik7XG4kY2xyLXJlZC1hMjAwOiBtYXAtZ2V0KCRjbHItcmVkLWxpc3QsIFwiYTIwMFwiKTtcbiRjbHItcmVkLWE0MDA6IG1hcC1nZXQoJGNsci1yZWQtbGlzdCwgXCJhNDAwXCIpO1xuJGNsci1yZWQtYTcwMDogbWFwLWdldCgkY2xyLXJlZC1saXN0LCBcImE3MDBcIik7XG5cblxuLy9cbi8vIFBpbmtcbi8vXG5cbiRjbHItcGluay1saXN0OiAoXG4gIFwiYmFzZVwiOiAjZTkxZTYzLFxuICBcIjUwXCI6ICAgI2ZjZTRlYyxcbiAgXCIxMDBcIjogICNmOGJiZDAsXG4gIFwiMjAwXCI6ICAjZjQ4ZmIxLFxuICBcIjMwMFwiOiAgI2YwNjI5MixcbiAgXCI0MDBcIjogICNlYzQwN2EsXG4gIFwiNTAwXCI6ICAjZTkxZTYzLFxuICBcIjYwMFwiOiAgI2Q4MWI2MCxcbiAgXCI3MDBcIjogICNjMjE4NWIsXG4gIFwiODAwXCI6ICAjYWQxNDU3LFxuICBcIjkwMFwiOiAgIzg4MGU0ZixcbiAgXCJhMTAwXCI6ICNmZjgwYWIsXG4gIFwiYTIwMFwiOiAjZmY0MDgxLFxuICBcImE0MDBcIjogI2Y1MDA1NyxcbiAgXCJhNzAwXCI6ICNjNTExNjJcbik7XG5cbiRjbHItcGluazogICAgICBtYXAtZ2V0KCRjbHItcGluay1saXN0LCBcImJhc2VcIik7XG5cbiRjbHItcGluay01MDogICBtYXAtZ2V0KCRjbHItcGluay1saXN0LCBcIjUwXCIpO1xuJGNsci1waW5rLTEwMDogIG1hcC1nZXQoJGNsci1waW5rLWxpc3QsIFwiMTAwXCIpO1xuJGNsci1waW5rLTIwMDogIG1hcC1nZXQoJGNsci1waW5rLWxpc3QsIFwiMjAwXCIpO1xuJGNsci1waW5rLTMwMDogIG1hcC1nZXQoJGNsci1waW5rLWxpc3QsIFwiMzAwXCIpO1xuJGNsci1waW5rLTQwMDogIG1hcC1nZXQoJGNsci1waW5rLWxpc3QsIFwiNDAwXCIpO1xuJGNsci1waW5rLTUwMDogIG1hcC1nZXQoJGNsci1waW5rLWxpc3QsIFwiNTAwXCIpO1xuJGNsci1waW5rLTYwMDogIG1hcC1nZXQoJGNsci1waW5rLWxpc3QsIFwiNjAwXCIpO1xuJGNsci1waW5rLTcwMDogIG1hcC1nZXQoJGNsci1waW5rLWxpc3QsIFwiNzAwXCIpO1xuJGNsci1waW5rLTgwMDogIG1hcC1nZXQoJGNsci1waW5rLWxpc3QsIFwiODAwXCIpO1xuJGNsci1waW5rLTkwMDogIG1hcC1nZXQoJGNsci1waW5rLWxpc3QsIFwiOTAwXCIpO1xuJGNsci1waW5rLWExMDA6IG1hcC1nZXQoJGNsci1waW5rLWxpc3QsIFwiYTEwMFwiKTtcbiRjbHItcGluay1hMjAwOiBtYXAtZ2V0KCRjbHItcGluay1saXN0LCBcImEyMDBcIik7XG4kY2xyLXBpbmstYTQwMDogbWFwLWdldCgkY2xyLXBpbmstbGlzdCwgXCJhNDAwXCIpO1xuJGNsci1waW5rLWE3MDA6IG1hcC1nZXQoJGNsci1waW5rLWxpc3QsIFwiYTcwMFwiKTtcblxuXG4vL1xuLy8gUHVycGxlXG4vL1xuXG4kY2xyLXB1cnBsZS1saXN0OiAoXG4gIFwiYmFzZVwiOiAjOWMyN2IwLFxuICBcIjUwXCI6ICAgI2YzZTVmNSxcbiAgXCIxMDBcIjogICNlMWJlZTcsXG4gIFwiMjAwXCI6ICAjY2U5M2Q4LFxuICBcIjMwMFwiOiAgI2JhNjhjOCxcbiAgXCI0MDBcIjogICNhYjQ3YmMsXG4gIFwiNTAwXCI6ICAjOWMyN2IwLFxuICBcIjYwMFwiOiAgIzhlMjRhYSxcbiAgXCI3MDBcIjogICM3YjFmYTIsXG4gIFwiODAwXCI6ICAjNmExYjlhLFxuICBcIjkwMFwiOiAgIzRhMTQ4YyxcbiAgXCJhMTAwXCI6ICNlYTgwZmMsXG4gIFwiYTIwMFwiOiAjZTA0MGZiLFxuICBcImE0MDBcIjogI2Q1MDBmOSxcbiAgXCJhNzAwXCI6ICNhYTAwZmZcbik7XG5cbiRjbHItcHVycGxlOiAgICAgIG1hcC1nZXQoJGNsci1wdXJwbGUtbGlzdCwgXCJiYXNlXCIpO1xuXG4kY2xyLXB1cnBsZS01MDogICBtYXAtZ2V0KCRjbHItcHVycGxlLWxpc3QsIFwiNTBcIik7XG4kY2xyLXB1cnBsZS0xMDA6ICBtYXAtZ2V0KCRjbHItcHVycGxlLWxpc3QsIFwiMTAwXCIpO1xuJGNsci1wdXJwbGUtMjAwOiAgbWFwLWdldCgkY2xyLXB1cnBsZS1saXN0LCBcIjIwMFwiKTtcbiRjbHItcHVycGxlLTMwMDogIG1hcC1nZXQoJGNsci1wdXJwbGUtbGlzdCwgXCIzMDBcIik7XG4kY2xyLXB1cnBsZS00MDA6ICBtYXAtZ2V0KCRjbHItcHVycGxlLWxpc3QsIFwiNDAwXCIpO1xuJGNsci1wdXJwbGUtNTAwOiAgbWFwLWdldCgkY2xyLXB1cnBsZS1saXN0LCBcIjUwMFwiKTtcbiRjbHItcHVycGxlLTYwMDogIG1hcC1nZXQoJGNsci1wdXJwbGUtbGlzdCwgXCI2MDBcIik7XG4kY2xyLXB1cnBsZS03MDA6ICBtYXAtZ2V0KCRjbHItcHVycGxlLWxpc3QsIFwiNzAwXCIpO1xuJGNsci1wdXJwbGUtODAwOiAgbWFwLWdldCgkY2xyLXB1cnBsZS1saXN0LCBcIjgwMFwiKTtcbiRjbHItcHVycGxlLTkwMDogIG1hcC1nZXQoJGNsci1wdXJwbGUtbGlzdCwgXCI5MDBcIik7XG4kY2xyLXB1cnBsZS1hMTAwOiBtYXAtZ2V0KCRjbHItcHVycGxlLWxpc3QsIFwiYTEwMFwiKTtcbiRjbHItcHVycGxlLWEyMDA6IG1hcC1nZXQoJGNsci1wdXJwbGUtbGlzdCwgXCJhMjAwXCIpO1xuJGNsci1wdXJwbGUtYTQwMDogbWFwLWdldCgkY2xyLXB1cnBsZS1saXN0LCBcImE0MDBcIik7XG4kY2xyLXB1cnBsZS1hNzAwOiBtYXAtZ2V0KCRjbHItcHVycGxlLWxpc3QsIFwiYTcwMFwiKTtcblxuXG4vL1xuLy8gRGVlcCBwdXJwbGVcbi8vXG5cbiRjbHItZGVlcC1wdXJwbGUtbGlzdDogKFxuICBcImJhc2VcIjogIzY3M2FiNyxcbiAgXCI1MFwiOiAgICNlZGU3ZjYsXG4gIFwiMTAwXCI6ICAjZDFjNGU5LFxuICBcIjIwMFwiOiAgI2IzOWRkYixcbiAgXCIzMDBcIjogICM5NTc1Y2QsXG4gIFwiNDAwXCI6ICAjN2U1N2MyLFxuICBcIjUwMFwiOiAgIzY3M2FiNyxcbiAgXCI2MDBcIjogICM1ZTM1YjEsXG4gIFwiNzAwXCI6ICAjNTEyZGE4LFxuICBcIjgwMFwiOiAgIzQ1MjdhMCxcbiAgXCI5MDBcIjogICMzMTFiOTIsXG4gIFwiYTEwMFwiOiAjYjM4OGZmLFxuICBcImEyMDBcIjogIzdjNGRmZixcbiAgXCJhNDAwXCI6ICM2NTFmZmYsXG4gIFwiYTcwMFwiOiAjNjIwMGVhXG4pO1xuXG4kY2xyLWRlZXAtcHVycGxlOiAgICAgIG1hcC1nZXQoJGNsci1kZWVwLXB1cnBsZS1saXN0LCBcImJhc2VcIik7XG5cbiRjbHItZGVlcC1wdXJwbGUtNTA6ICAgbWFwLWdldCgkY2xyLWRlZXAtcHVycGxlLWxpc3QsIFwiNTBcIik7XG4kY2xyLWRlZXAtcHVycGxlLTEwMDogIG1hcC1nZXQoJGNsci1kZWVwLXB1cnBsZS1saXN0LCBcIjEwMFwiKTtcbiRjbHItZGVlcC1wdXJwbGUtMjAwOiAgbWFwLWdldCgkY2xyLWRlZXAtcHVycGxlLWxpc3QsIFwiMjAwXCIpO1xuJGNsci1kZWVwLXB1cnBsZS0zMDA6ICBtYXAtZ2V0KCRjbHItZGVlcC1wdXJwbGUtbGlzdCwgXCIzMDBcIik7XG4kY2xyLWRlZXAtcHVycGxlLTQwMDogIG1hcC1nZXQoJGNsci1kZWVwLXB1cnBsZS1saXN0LCBcIjQwMFwiKTtcbiRjbHItZGVlcC1wdXJwbGUtNTAwOiAgbWFwLWdldCgkY2xyLWRlZXAtcHVycGxlLWxpc3QsIFwiNTAwXCIpO1xuJGNsci1kZWVwLXB1cnBsZS02MDA6ICBtYXAtZ2V0KCRjbHItZGVlcC1wdXJwbGUtbGlzdCwgXCI2MDBcIik7XG4kY2xyLWRlZXAtcHVycGxlLTcwMDogIG1hcC1nZXQoJGNsci1kZWVwLXB1cnBsZS1saXN0LCBcIjcwMFwiKTtcbiRjbHItZGVlcC1wdXJwbGUtODAwOiAgbWFwLWdldCgkY2xyLWRlZXAtcHVycGxlLWxpc3QsIFwiODAwXCIpO1xuJGNsci1kZWVwLXB1cnBsZS05MDA6ICBtYXAtZ2V0KCRjbHItZGVlcC1wdXJwbGUtbGlzdCwgXCI5MDBcIik7XG4kY2xyLWRlZXAtcHVycGxlLWExMDA6IG1hcC1nZXQoJGNsci1kZWVwLXB1cnBsZS1saXN0LCBcImExMDBcIik7XG4kY2xyLWRlZXAtcHVycGxlLWEyMDA6IG1hcC1nZXQoJGNsci1kZWVwLXB1cnBsZS1saXN0LCBcImEyMDBcIik7XG4kY2xyLWRlZXAtcHVycGxlLWE0MDA6IG1hcC1nZXQoJGNsci1kZWVwLXB1cnBsZS1saXN0LCBcImE0MDBcIik7XG4kY2xyLWRlZXAtcHVycGxlLWE3MDA6IG1hcC1nZXQoJGNsci1kZWVwLXB1cnBsZS1saXN0LCBcImE3MDBcIik7XG5cblxuLy9cbi8vIEluZGlnb1xuLy9cblxuJGNsci1pbmRpZ28tbGlzdDogKFxuICBcImJhc2VcIjogIzNmNTFiNSxcbiAgXCI1MFwiOiAgICNlOGVhZjYsXG4gIFwiMTAwXCI6ICAjYzVjYWU5LFxuICBcIjIwMFwiOiAgIzlmYThkYSxcbiAgXCIzMDBcIjogICM3OTg2Y2IsXG4gIFwiNDAwXCI6ICAjNWM2YmMwLFxuICBcIjUwMFwiOiAgIzNmNTFiNSxcbiAgXCI2MDBcIjogICMzOTQ5YWIsXG4gIFwiNzAwXCI6ICAjMzAzZjlmLFxuICBcIjgwMFwiOiAgIzI4MzU5MyxcbiAgXCI5MDBcIjogICMxYTIzN2UsXG4gIFwiYTEwMFwiOiAjOGM5ZWZmLFxuICBcImEyMDBcIjogIzUzNmRmZSxcbiAgXCJhNDAwXCI6ICMzZDVhZmUsXG4gIFwiYTcwMFwiOiAjMzA0ZmZlXG4pO1xuXG4kY2xyLWluZGlnbzogICAgICBtYXAtZ2V0KCRjbHItaW5kaWdvLWxpc3QsIFwiYmFzZVwiKTtcblxuJGNsci1pbmRpZ28tNTA6ICAgbWFwLWdldCgkY2xyLWluZGlnby1saXN0LCBcIjUwXCIpO1xuJGNsci1pbmRpZ28tMTAwOiAgbWFwLWdldCgkY2xyLWluZGlnby1saXN0LCBcIjEwMFwiKTtcbiRjbHItaW5kaWdvLTIwMDogIG1hcC1nZXQoJGNsci1pbmRpZ28tbGlzdCwgXCIyMDBcIik7XG4kY2xyLWluZGlnby0zMDA6ICBtYXAtZ2V0KCRjbHItaW5kaWdvLWxpc3QsIFwiMzAwXCIpO1xuJGNsci1pbmRpZ28tNDAwOiAgbWFwLWdldCgkY2xyLWluZGlnby1saXN0LCBcIjQwMFwiKTtcbiRjbHItaW5kaWdvLTUwMDogIG1hcC1nZXQoJGNsci1pbmRpZ28tbGlzdCwgXCI1MDBcIik7XG4kY2xyLWluZGlnby02MDA6ICBtYXAtZ2V0KCRjbHItaW5kaWdvLWxpc3QsIFwiNjAwXCIpO1xuJGNsci1pbmRpZ28tNzAwOiAgbWFwLWdldCgkY2xyLWluZGlnby1saXN0LCBcIjcwMFwiKTtcbiRjbHItaW5kaWdvLTgwMDogIG1hcC1nZXQoJGNsci1pbmRpZ28tbGlzdCwgXCI4MDBcIik7XG4kY2xyLWluZGlnby05MDA6ICBtYXAtZ2V0KCRjbHItaW5kaWdvLWxpc3QsIFwiOTAwXCIpO1xuJGNsci1pbmRpZ28tYTEwMDogbWFwLWdldCgkY2xyLWluZGlnby1saXN0LCBcImExMDBcIik7XG4kY2xyLWluZGlnby1hMjAwOiBtYXAtZ2V0KCRjbHItaW5kaWdvLWxpc3QsIFwiYTIwMFwiKTtcbiRjbHItaW5kaWdvLWE0MDA6IG1hcC1nZXQoJGNsci1pbmRpZ28tbGlzdCwgXCJhNDAwXCIpO1xuJGNsci1pbmRpZ28tYTcwMDogbWFwLWdldCgkY2xyLWluZGlnby1saXN0LCBcImE3MDBcIik7XG5cblxuLy9cbi8vIEJsdWVcbi8vXG5cbiRjbHItYmx1ZS1saXN0OiAoXG4gIFwiYmFzZVwiOiAjMjE5NmYzLFxuICBcIjUwXCI6ICAgI2UzZjJmZCxcbiAgXCIxMDBcIjogICNiYmRlZmIsXG4gIFwiMjAwXCI6ICAjOTBjYWY5LFxuICBcIjMwMFwiOiAgIzY0YjVmNixcbiAgXCI0MDBcIjogICM0MmE1ZjUsXG4gIFwiNTAwXCI6ICAjMjE5NmYzLFxuICBcIjYwMFwiOiAgIzFlODhlNSxcbiAgXCI3MDBcIjogICMxOTc2ZDIsXG4gIFwiODAwXCI6ICAjMTU2NWMwLFxuICBcIjkwMFwiOiAgIzBkNDdhMSxcbiAgXCJhMTAwXCI6ICM4MmIxZmYsXG4gIFwiYTIwMFwiOiAjNDQ4YWZmLFxuICBcImE0MDBcIjogIzI5NzlmZixcbiAgXCJhNzAwXCI6ICMyOTYyZmZcbik7XG5cbiRjbHItYmx1ZTogICAgICBtYXAtZ2V0KCRjbHItYmx1ZS1saXN0LCBcImJhc2VcIik7XG5cbiRjbHItYmx1ZS01MDogICBtYXAtZ2V0KCRjbHItYmx1ZS1saXN0LCBcIjUwXCIpO1xuJGNsci1ibHVlLTEwMDogIG1hcC1nZXQoJGNsci1ibHVlLWxpc3QsIFwiMTAwXCIpO1xuJGNsci1ibHVlLTIwMDogIG1hcC1nZXQoJGNsci1ibHVlLWxpc3QsIFwiMjAwXCIpO1xuJGNsci1ibHVlLTMwMDogIG1hcC1nZXQoJGNsci1ibHVlLWxpc3QsIFwiMzAwXCIpO1xuJGNsci1ibHVlLTQwMDogIG1hcC1nZXQoJGNsci1ibHVlLWxpc3QsIFwiNDAwXCIpO1xuJGNsci1ibHVlLTUwMDogIG1hcC1nZXQoJGNsci1ibHVlLWxpc3QsIFwiNTAwXCIpO1xuJGNsci1ibHVlLTYwMDogIG1hcC1nZXQoJGNsci1ibHVlLWxpc3QsIFwiNjAwXCIpO1xuJGNsci1ibHVlLTcwMDogIG1hcC1nZXQoJGNsci1ibHVlLWxpc3QsIFwiNzAwXCIpO1xuJGNsci1ibHVlLTgwMDogIG1hcC1nZXQoJGNsci1ibHVlLWxpc3QsIFwiODAwXCIpO1xuJGNsci1ibHVlLTkwMDogIG1hcC1nZXQoJGNsci1ibHVlLWxpc3QsIFwiOTAwXCIpO1xuJGNsci1ibHVlLWExMDA6IG1hcC1nZXQoJGNsci1ibHVlLWxpc3QsIFwiYTEwMFwiKTtcbiRjbHItYmx1ZS1hMjAwOiBtYXAtZ2V0KCRjbHItYmx1ZS1saXN0LCBcImEyMDBcIik7XG4kY2xyLWJsdWUtYTQwMDogbWFwLWdldCgkY2xyLWJsdWUtbGlzdCwgXCJhNDAwXCIpO1xuJGNsci1ibHVlLWE3MDA6IG1hcC1nZXQoJGNsci1ibHVlLWxpc3QsIFwiYTcwMFwiKTtcblxuXG4vL1xuLy8gTGlnaHQgQmx1ZVxuLy9cblxuJGNsci1saWdodC1ibHVlLWxpc3Q6IChcbiAgXCJiYXNlXCI6ICMwM2E5ZjQsXG4gIFwiNTBcIjogICAjZTFmNWZlLFxuICBcIjEwMFwiOiAgI2IzZTVmYyxcbiAgXCIyMDBcIjogICM4MWQ0ZmEsXG4gIFwiMzAwXCI6ICAjNGZjM2Y3LFxuICBcIjQwMFwiOiAgIzI5YjZmNixcbiAgXCI1MDBcIjogICMwM2E5ZjQsXG4gIFwiNjAwXCI6ICAjMDM5YmU1LFxuICBcIjcwMFwiOiAgIzAyODhkMSxcbiAgXCI4MDBcIjogICMwMjc3YmQsXG4gIFwiOTAwXCI6ICAjMDE1NzliLFxuICBcImExMDBcIjogIzgwZDhmZixcbiAgXCJhMjAwXCI6ICM0MGM0ZmYsXG4gIFwiYTQwMFwiOiAjMDBiMGZmLFxuICBcImE3MDBcIjogIzAwOTFlYVxuKTtcblxuJGNsci1saWdodC1ibHVlOiAgICAgIG1hcC1nZXQoJGNsci1saWdodC1ibHVlLWxpc3QsIFwiYmFzZVwiKTtcblxuJGNsci1saWdodC1ibHVlLTUwOiAgIG1hcC1nZXQoJGNsci1saWdodC1ibHVlLWxpc3QsIFwiNTBcIik7XG4kY2xyLWxpZ2h0LWJsdWUtMTAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWJsdWUtbGlzdCwgXCIxMDBcIik7XG4kY2xyLWxpZ2h0LWJsdWUtMjAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWJsdWUtbGlzdCwgXCIyMDBcIik7XG4kY2xyLWxpZ2h0LWJsdWUtMzAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWJsdWUtbGlzdCwgXCIzMDBcIik7XG4kY2xyLWxpZ2h0LWJsdWUtNDAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWJsdWUtbGlzdCwgXCI0MDBcIik7XG4kY2xyLWxpZ2h0LWJsdWUtNTAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWJsdWUtbGlzdCwgXCI1MDBcIik7XG4kY2xyLWxpZ2h0LWJsdWUtNjAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWJsdWUtbGlzdCwgXCI2MDBcIik7XG4kY2xyLWxpZ2h0LWJsdWUtNzAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWJsdWUtbGlzdCwgXCI3MDBcIik7XG4kY2xyLWxpZ2h0LWJsdWUtODAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWJsdWUtbGlzdCwgXCI4MDBcIik7XG4kY2xyLWxpZ2h0LWJsdWUtOTAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWJsdWUtbGlzdCwgXCI5MDBcIik7XG4kY2xyLWxpZ2h0LWJsdWUtYTEwMDogbWFwLWdldCgkY2xyLWxpZ2h0LWJsdWUtbGlzdCwgXCJhMTAwXCIpO1xuJGNsci1saWdodC1ibHVlLWEyMDA6IG1hcC1nZXQoJGNsci1saWdodC1ibHVlLWxpc3QsIFwiYTIwMFwiKTtcbiRjbHItbGlnaHQtYmx1ZS1hNDAwOiBtYXAtZ2V0KCRjbHItbGlnaHQtYmx1ZS1saXN0LCBcImE0MDBcIik7XG4kY2xyLWxpZ2h0LWJsdWUtYTcwMDogbWFwLWdldCgkY2xyLWxpZ2h0LWJsdWUtbGlzdCwgXCJhNzAwXCIpO1xuXG5cbi8vXG4vLyBDeWFuXG4vL1xuXG4kY2xyLWN5YW4tbGlzdDogKFxuICBcImJhc2VcIjogIzAwYmNkNCxcbiAgXCI1MFwiOiAgICNlMGY3ZmEsXG4gIFwiMTAwXCI6ICAjYjJlYmYyLFxuICBcIjIwMFwiOiAgIzgwZGVlYSxcbiAgXCIzMDBcIjogICM0ZGQwZTEsXG4gIFwiNDAwXCI6ICAjMjZjNmRhLFxuICBcIjUwMFwiOiAgIzAwYmNkNCxcbiAgXCI2MDBcIjogICMwMGFjYzEsXG4gIFwiNzAwXCI6ICAjMDA5N2E3LFxuICBcIjgwMFwiOiAgIzAwODM4ZixcbiAgXCI5MDBcIjogICMwMDYwNjQsXG4gIFwiYTEwMFwiOiAjODRmZmZmLFxuICBcImEyMDBcIjogIzE4ZmZmZixcbiAgXCJhNDAwXCI6ICMwMGU1ZmYsXG4gIFwiYTcwMFwiOiAjMDBiOGQ0XG4pO1xuXG4kY2xyLWN5YW46ICAgICAgbWFwLWdldCgkY2xyLWN5YW4tbGlzdCwgXCJiYXNlXCIpO1xuXG4kY2xyLWN5YW4tNTA6ICAgbWFwLWdldCgkY2xyLWN5YW4tbGlzdCwgXCI1MFwiKTtcbiRjbHItY3lhbi0xMDA6ICBtYXAtZ2V0KCRjbHItY3lhbi1saXN0LCBcIjEwMFwiKTtcbiRjbHItY3lhbi0yMDA6ICBtYXAtZ2V0KCRjbHItY3lhbi1saXN0LCBcIjIwMFwiKTtcbiRjbHItY3lhbi0zMDA6ICBtYXAtZ2V0KCRjbHItY3lhbi1saXN0LCBcIjMwMFwiKTtcbiRjbHItY3lhbi00MDA6ICBtYXAtZ2V0KCRjbHItY3lhbi1saXN0LCBcIjQwMFwiKTtcbiRjbHItY3lhbi01MDA6ICBtYXAtZ2V0KCRjbHItY3lhbi1saXN0LCBcIjUwMFwiKTtcbiRjbHItY3lhbi02MDA6ICBtYXAtZ2V0KCRjbHItY3lhbi1saXN0LCBcIjYwMFwiKTtcbiRjbHItY3lhbi03MDA6ICBtYXAtZ2V0KCRjbHItY3lhbi1saXN0LCBcIjcwMFwiKTtcbiRjbHItY3lhbi04MDA6ICBtYXAtZ2V0KCRjbHItY3lhbi1saXN0LCBcIjgwMFwiKTtcbiRjbHItY3lhbi05MDA6ICBtYXAtZ2V0KCRjbHItY3lhbi1saXN0LCBcIjkwMFwiKTtcbiRjbHItY3lhbi1hMTAwOiBtYXAtZ2V0KCRjbHItY3lhbi1saXN0LCBcImExMDBcIik7XG4kY2xyLWN5YW4tYTIwMDogbWFwLWdldCgkY2xyLWN5YW4tbGlzdCwgXCJhMjAwXCIpO1xuJGNsci1jeWFuLWE0MDA6IG1hcC1nZXQoJGNsci1jeWFuLWxpc3QsIFwiYTQwMFwiKTtcbiRjbHItY3lhbi1hNzAwOiBtYXAtZ2V0KCRjbHItY3lhbi1saXN0LCBcImE3MDBcIik7XG5cblxuLy9cbi8vIFRlYWxcbi8vXG5cbiRjbHItdGVhbC1saXN0OiAoXG4gIFwiYmFzZVwiOiAjMDA5Njg4LFxuICBcIjUwXCI6ICAgI2UwZjJmMSxcbiAgXCIxMDBcIjogICNiMmRmZGIsXG4gIFwiMjAwXCI6ICAjODBjYmM0LFxuICBcIjMwMFwiOiAgIzRkYjZhYyxcbiAgXCI0MDBcIjogICMyNmE2OWEsXG4gIFwiNTAwXCI6ICAjMDA5Njg4LFxuICBcIjYwMFwiOiAgIzAwODk3YixcbiAgXCI3MDBcIjogICMwMDc5NmIsXG4gIFwiODAwXCI6ICAjMDA2OTVjLFxuICBcIjkwMFwiOiAgIzAwNGQ0MCxcbiAgXCJhMTAwXCI6ICNhN2ZmZWIsXG4gIFwiYTIwMFwiOiAjNjRmZmRhLFxuICBcImE0MDBcIjogIzFkZTliNixcbiAgXCJhNzAwXCI6ICMwMGJmYTVcbik7XG5cbiRjbHItdGVhbDogICAgICBtYXAtZ2V0KCRjbHItdGVhbC1saXN0LCBcImJhc2VcIik7XG5cbiRjbHItdGVhbC01MDogICBtYXAtZ2V0KCRjbHItdGVhbC1saXN0LCBcIjUwXCIpO1xuJGNsci10ZWFsLTEwMDogIG1hcC1nZXQoJGNsci10ZWFsLWxpc3QsIFwiMTAwXCIpO1xuJGNsci10ZWFsLTIwMDogIG1hcC1nZXQoJGNsci10ZWFsLWxpc3QsIFwiMjAwXCIpO1xuJGNsci10ZWFsLTMwMDogIG1hcC1nZXQoJGNsci10ZWFsLWxpc3QsIFwiMzAwXCIpO1xuJGNsci10ZWFsLTQwMDogIG1hcC1nZXQoJGNsci10ZWFsLWxpc3QsIFwiNDAwXCIpO1xuJGNsci10ZWFsLTUwMDogIG1hcC1nZXQoJGNsci10ZWFsLWxpc3QsIFwiNTAwXCIpO1xuJGNsci10ZWFsLTYwMDogIG1hcC1nZXQoJGNsci10ZWFsLWxpc3QsIFwiNjAwXCIpO1xuJGNsci10ZWFsLTcwMDogIG1hcC1nZXQoJGNsci10ZWFsLWxpc3QsIFwiNzAwXCIpO1xuJGNsci10ZWFsLTgwMDogIG1hcC1nZXQoJGNsci10ZWFsLWxpc3QsIFwiODAwXCIpO1xuJGNsci10ZWFsLTkwMDogIG1hcC1nZXQoJGNsci10ZWFsLWxpc3QsIFwiOTAwXCIpO1xuJGNsci10ZWFsLWExMDA6IG1hcC1nZXQoJGNsci10ZWFsLWxpc3QsIFwiYTEwMFwiKTtcbiRjbHItdGVhbC1hMjAwOiBtYXAtZ2V0KCRjbHItdGVhbC1saXN0LCBcImEyMDBcIik7XG4kY2xyLXRlYWwtYTQwMDogbWFwLWdldCgkY2xyLXRlYWwtbGlzdCwgXCJhNDAwXCIpO1xuJGNsci10ZWFsLWE3MDA6IG1hcC1nZXQoJGNsci10ZWFsLWxpc3QsIFwiYTcwMFwiKTtcblxuXG4vL1xuLy8gR3JlZW5cbi8vXG5cbiRjbHItZ3JlZW4tbGlzdDogKFxuICBcImJhc2VcIjogIzRjYWY1MCxcbiAgXCI1MFwiOiAgICNlOGY1ZTksXG4gIFwiMTAwXCI6ICAjYzhlNmM5LFxuICBcIjIwMFwiOiAgI2E1ZDZhNyxcbiAgXCIzMDBcIjogICM4MWM3ODQsXG4gIFwiNDAwXCI6ICAjNjZiYjZhLFxuICBcIjUwMFwiOiAgIzRjYWY1MCxcbiAgXCI2MDBcIjogICM0M2EwNDcsXG4gIFwiNzAwXCI6ICAjMzg4ZTNjLFxuICBcIjgwMFwiOiAgIzJlN2QzMixcbiAgXCI5MDBcIjogICMxYjVlMjAsXG4gIFwiYTEwMFwiOiAjYjlmNmNhLFxuICBcImEyMDBcIjogIzY5ZjBhZSxcbiAgXCJhNDAwXCI6ICMwMGU2NzYsXG4gIFwiYTcwMFwiOiAjMDBjODUzXG4pO1xuXG4kY2xyLWdyZWVuOiAgICAgIG1hcC1nZXQoJGNsci1ncmVlbi1saXN0LCBcImJhc2VcIik7XG5cbiRjbHItZ3JlZW4tNTA6ICAgbWFwLWdldCgkY2xyLWdyZWVuLWxpc3QsIFwiNTBcIik7XG4kY2xyLWdyZWVuLTEwMDogIG1hcC1nZXQoJGNsci1ncmVlbi1saXN0LCBcIjEwMFwiKTtcbiRjbHItZ3JlZW4tMjAwOiAgbWFwLWdldCgkY2xyLWdyZWVuLWxpc3QsIFwiMjAwXCIpO1xuJGNsci1ncmVlbi0zMDA6ICBtYXAtZ2V0KCRjbHItZ3JlZW4tbGlzdCwgXCIzMDBcIik7XG4kY2xyLWdyZWVuLTQwMDogIG1hcC1nZXQoJGNsci1ncmVlbi1saXN0LCBcIjQwMFwiKTtcbiRjbHItZ3JlZW4tNTAwOiAgbWFwLWdldCgkY2xyLWdyZWVuLWxpc3QsIFwiNTAwXCIpO1xuJGNsci1ncmVlbi02MDA6ICBtYXAtZ2V0KCRjbHItZ3JlZW4tbGlzdCwgXCI2MDBcIik7XG4kY2xyLWdyZWVuLTcwMDogIG1hcC1nZXQoJGNsci1ncmVlbi1saXN0LCBcIjcwMFwiKTtcbiRjbHItZ3JlZW4tODAwOiAgbWFwLWdldCgkY2xyLWdyZWVuLWxpc3QsIFwiODAwXCIpO1xuJGNsci1ncmVlbi05MDA6ICBtYXAtZ2V0KCRjbHItZ3JlZW4tbGlzdCwgXCI5MDBcIik7XG4kY2xyLWdyZWVuLWExMDA6IG1hcC1nZXQoJGNsci1ncmVlbi1saXN0LCBcImExMDBcIik7XG4kY2xyLWdyZWVuLWEyMDA6IG1hcC1nZXQoJGNsci1ncmVlbi1saXN0LCBcImEyMDBcIik7XG4kY2xyLWdyZWVuLWE0MDA6IG1hcC1nZXQoJGNsci1ncmVlbi1saXN0LCBcImE0MDBcIik7XG4kY2xyLWdyZWVuLWE3MDA6IG1hcC1nZXQoJGNsci1ncmVlbi1saXN0LCBcImE3MDBcIik7XG5cblxuLy9cbi8vIExpZ2h0IGdyZWVuXG4vL1xuXG4kY2xyLWxpZ2h0LWdyZWVuLWxpc3Q6IChcbiAgXCJiYXNlXCI6ICM4YmMzNGEsXG4gIFwiNTBcIjogICAjZjFmOGU5LFxuICBcIjEwMFwiOiAgI2RjZWRjOCxcbiAgXCIyMDBcIjogICNjNWUxYTUsXG4gIFwiMzAwXCI6ICAjYWVkNTgxLFxuICBcIjQwMFwiOiAgIzljY2M2NSxcbiAgXCI1MDBcIjogICM4YmMzNGEsXG4gIFwiNjAwXCI6ICAjN2NiMzQyLFxuICBcIjcwMFwiOiAgIzY4OWYzOCxcbiAgXCI4MDBcIjogICM1NThiMmYsXG4gIFwiOTAwXCI6ICAjMzM2OTFlLFxuICBcImExMDBcIjogI2NjZmY5MCxcbiAgXCJhMjAwXCI6ICNiMmZmNTksXG4gIFwiYTQwMFwiOiAjNzZmZjAzLFxuICBcImE3MDBcIjogIzY0ZGQxN1xuKTtcblxuJGNsci1saWdodC1ncmVlbjogICAgICBtYXAtZ2V0KCRjbHItbGlnaHQtZ3JlZW4tbGlzdCwgXCJiYXNlXCIpO1xuXG4kY2xyLWxpZ2h0LWdyZWVuLTUwOiAgIG1hcC1nZXQoJGNsci1saWdodC1ncmVlbi1saXN0LCBcIjUwXCIpO1xuJGNsci1saWdodC1ncmVlbi0xMDA6ICBtYXAtZ2V0KCRjbHItbGlnaHQtZ3JlZW4tbGlzdCwgXCIxMDBcIik7XG4kY2xyLWxpZ2h0LWdyZWVuLTIwMDogIG1hcC1nZXQoJGNsci1saWdodC1ncmVlbi1saXN0LCBcIjIwMFwiKTtcbiRjbHItbGlnaHQtZ3JlZW4tMzAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWdyZWVuLWxpc3QsIFwiMzAwXCIpO1xuJGNsci1saWdodC1ncmVlbi00MDA6ICBtYXAtZ2V0KCRjbHItbGlnaHQtZ3JlZW4tbGlzdCwgXCI0MDBcIik7XG4kY2xyLWxpZ2h0LWdyZWVuLTUwMDogIG1hcC1nZXQoJGNsci1saWdodC1ncmVlbi1saXN0LCBcIjUwMFwiKTtcbiRjbHItbGlnaHQtZ3JlZW4tNjAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWdyZWVuLWxpc3QsIFwiNjAwXCIpO1xuJGNsci1saWdodC1ncmVlbi03MDA6ICBtYXAtZ2V0KCRjbHItbGlnaHQtZ3JlZW4tbGlzdCwgXCI3MDBcIik7XG4kY2xyLWxpZ2h0LWdyZWVuLTgwMDogIG1hcC1nZXQoJGNsci1saWdodC1ncmVlbi1saXN0LCBcIjgwMFwiKTtcbiRjbHItbGlnaHQtZ3JlZW4tOTAwOiAgbWFwLWdldCgkY2xyLWxpZ2h0LWdyZWVuLWxpc3QsIFwiOTAwXCIpO1xuJGNsci1saWdodC1ncmVlbi1hMTAwOiBtYXAtZ2V0KCRjbHItbGlnaHQtZ3JlZW4tbGlzdCwgXCJhMTAwXCIpO1xuJGNsci1saWdodC1ncmVlbi1hMjAwOiBtYXAtZ2V0KCRjbHItbGlnaHQtZ3JlZW4tbGlzdCwgXCJhMjAwXCIpO1xuJGNsci1saWdodC1ncmVlbi1hNDAwOiBtYXAtZ2V0KCRjbHItbGlnaHQtZ3JlZW4tbGlzdCwgXCJhNDAwXCIpO1xuJGNsci1saWdodC1ncmVlbi1hNzAwOiBtYXAtZ2V0KCRjbHItbGlnaHQtZ3JlZW4tbGlzdCwgXCJhNzAwXCIpO1xuXG5cbi8vXG4vLyBMaW1lXG4vL1xuXG4kY2xyLWxpbWUtbGlzdDogKFxuICBcImJhc2VcIjogI2NkZGMzOSxcbiAgXCI1MFwiOiAgICNmOWZiZTcsXG4gIFwiMTAwXCI6ICAjZjBmNGMzLFxuICBcIjIwMFwiOiAgI2U2ZWU5YyxcbiAgXCIzMDBcIjogICNkY2U3NzUsXG4gIFwiNDAwXCI6ICAjZDRlMTU3LFxuICBcIjUwMFwiOiAgI2NkZGMzOSxcbiAgXCI2MDBcIjogICNjMGNhMzMsXG4gIFwiNzAwXCI6ICAjYWZiNDJiLFxuICBcIjgwMFwiOiAgIzllOWQyNCxcbiAgXCI5MDBcIjogICM4Mjc3MTcsXG4gIFwiYTEwMFwiOiAjZjRmZjgxLFxuICBcImEyMDBcIjogI2VlZmY0MSxcbiAgXCJhNDAwXCI6ICNjNmZmMDAsXG4gIFwiYTcwMFwiOiAjYWVlYTAwXG4pO1xuXG4kY2xyLWxpbWU6ICAgICAgbWFwLWdldCgkY2xyLWxpbWUtbGlzdCwgXCJiYXNlXCIpO1xuXG4kY2xyLWxpbWUtNTA6ICAgbWFwLWdldCgkY2xyLWxpbWUtbGlzdCwgXCI1MFwiKTtcbiRjbHItbGltZS0xMDA6ICBtYXAtZ2V0KCRjbHItbGltZS1saXN0LCBcIjEwMFwiKTtcbiRjbHItbGltZS0yMDA6ICBtYXAtZ2V0KCRjbHItbGltZS1saXN0LCBcIjIwMFwiKTtcbiRjbHItbGltZS0zMDA6ICBtYXAtZ2V0KCRjbHItbGltZS1saXN0LCBcIjMwMFwiKTtcbiRjbHItbGltZS00MDA6ICBtYXAtZ2V0KCRjbHItbGltZS1saXN0LCBcIjQwMFwiKTtcbiRjbHItbGltZS01MDA6ICBtYXAtZ2V0KCRjbHItbGltZS1saXN0LCBcIjUwMFwiKTtcbiRjbHItbGltZS02MDA6ICBtYXAtZ2V0KCRjbHItbGltZS1saXN0LCBcIjYwMFwiKTtcbiRjbHItbGltZS03MDA6ICBtYXAtZ2V0KCRjbHItbGltZS1saXN0LCBcIjcwMFwiKTtcbiRjbHItbGltZS04MDA6ICBtYXAtZ2V0KCRjbHItbGltZS1saXN0LCBcIjgwMFwiKTtcbiRjbHItbGltZS05MDA6ICBtYXAtZ2V0KCRjbHItbGltZS1saXN0LCBcIjkwMFwiKTtcbiRjbHItbGltZS1hMTAwOiBtYXAtZ2V0KCRjbHItbGltZS1saXN0LCBcImExMDBcIik7XG4kY2xyLWxpbWUtYTIwMDogbWFwLWdldCgkY2xyLWxpbWUtbGlzdCwgXCJhMjAwXCIpO1xuJGNsci1saW1lLWE0MDA6IG1hcC1nZXQoJGNsci1saW1lLWxpc3QsIFwiYTQwMFwiKTtcbiRjbHItbGltZS1hNzAwOiBtYXAtZ2V0KCRjbHItbGltZS1saXN0LCBcImE3MDBcIik7XG5cblxuLy9cbi8vIFllbGxvd1xuLy9cblxuJGNsci15ZWxsb3ctbGlzdDogKFxuICBcImJhc2VcIjogI2ZmZWIzYixcbiAgXCI1MFwiOiAgICNmZmZkZTcsXG4gIFwiMTAwXCI6ICAjZmZmOWM0LFxuICBcIjIwMFwiOiAgI2ZmZjU5ZCxcbiAgXCIzMDBcIjogICNmZmYxNzYsXG4gIFwiNDAwXCI6ICAjZmZlZTU4LFxuICBcIjUwMFwiOiAgI2ZmZWIzYixcbiAgXCI2MDBcIjogICNmZGQ4MzUsXG4gIFwiNzAwXCI6ICAjZmJjMDJkLFxuICBcIjgwMFwiOiAgI2Y5YTgyNSxcbiAgXCI5MDBcIjogICNmNTdmMTcsXG4gIFwiYTEwMFwiOiAjZmZmZjhkLFxuICBcImEyMDBcIjogI2ZmZmYwMCxcbiAgXCJhNDAwXCI6ICNmZmVhMDAsXG4gIFwiYTcwMFwiOiAjZmZkNjAwXG4pO1xuXG4kY2xyLXllbGxvdzogICAgICBtYXAtZ2V0KCRjbHIteWVsbG93LWxpc3QsIFwiYmFzZVwiKTtcblxuJGNsci15ZWxsb3ctNTA6ICAgbWFwLWdldCgkY2xyLXllbGxvdy1saXN0LCBcIjUwXCIpO1xuJGNsci15ZWxsb3ctMTAwOiAgbWFwLWdldCgkY2xyLXllbGxvdy1saXN0LCBcIjEwMFwiKTtcbiRjbHIteWVsbG93LTIwMDogIG1hcC1nZXQoJGNsci15ZWxsb3ctbGlzdCwgXCIyMDBcIik7XG4kY2xyLXllbGxvdy0zMDA6ICBtYXAtZ2V0KCRjbHIteWVsbG93LWxpc3QsIFwiMzAwXCIpO1xuJGNsci15ZWxsb3ctNDAwOiAgbWFwLWdldCgkY2xyLXllbGxvdy1saXN0LCBcIjQwMFwiKTtcbiRjbHIteWVsbG93LTUwMDogIG1hcC1nZXQoJGNsci15ZWxsb3ctbGlzdCwgXCI1MDBcIik7XG4kY2xyLXllbGxvdy02MDA6ICBtYXAtZ2V0KCRjbHIteWVsbG93LWxpc3QsIFwiNjAwXCIpO1xuJGNsci15ZWxsb3ctNzAwOiAgbWFwLWdldCgkY2xyLXllbGxvdy1saXN0LCBcIjcwMFwiKTtcbiRjbHIteWVsbG93LTgwMDogIG1hcC1nZXQoJGNsci15ZWxsb3ctbGlzdCwgXCI4MDBcIik7XG4kY2xyLXllbGxvdy05MDA6ICBtYXAtZ2V0KCRjbHIteWVsbG93LWxpc3QsIFwiOTAwXCIpO1xuJGNsci15ZWxsb3ctYTEwMDogbWFwLWdldCgkY2xyLXllbGxvdy1saXN0LCBcImExMDBcIik7XG4kY2xyLXllbGxvdy1hMjAwOiBtYXAtZ2V0KCRjbHIteWVsbG93LWxpc3QsIFwiYTIwMFwiKTtcbiRjbHIteWVsbG93LWE0MDA6IG1hcC1nZXQoJGNsci15ZWxsb3ctbGlzdCwgXCJhNDAwXCIpO1xuJGNsci15ZWxsb3ctYTcwMDogbWFwLWdldCgkY2xyLXllbGxvdy1saXN0LCBcImE3MDBcIik7XG5cblxuLy9cbi8vIGFtYmVyXG4vL1xuXG4kY2xyLWFtYmVyLWxpc3Q6IChcbiAgXCJiYXNlXCI6ICNmZmMxMDcsXG4gIFwiNTBcIjogICAjZmZmOGUxLFxuICBcIjEwMFwiOiAgI2ZmZWNiMyxcbiAgXCIyMDBcIjogICNmZmUwODIsXG4gIFwiMzAwXCI6ICAjZmZkNTRmLFxuICBcIjQwMFwiOiAgI2ZmY2EyOCxcbiAgXCI1MDBcIjogICNmZmMxMDcsXG4gIFwiNjAwXCI6ICAjZmZiMzAwLFxuICBcIjcwMFwiOiAgI2ZmYTAwMCxcbiAgXCI4MDBcIjogICNmZjhmMDAsXG4gIFwiOTAwXCI6ICAjZmY2ZjAwLFxuICBcImExMDBcIjogI2ZmZTU3ZixcbiAgXCJhMjAwXCI6ICNmZmQ3NDAsXG4gIFwiYTQwMFwiOiAjZmZjNDAwLFxuICBcImE3MDBcIjogI2ZmYWIwMFxuKTtcblxuJGNsci1hbWJlcjogICAgICBtYXAtZ2V0KCRjbHItYW1iZXItbGlzdCwgXCJiYXNlXCIpO1xuXG4kY2xyLWFtYmVyLTUwOiAgIG1hcC1nZXQoJGNsci1hbWJlci1saXN0LCBcIjUwXCIpO1xuJGNsci1hbWJlci0xMDA6ICBtYXAtZ2V0KCRjbHItYW1iZXItbGlzdCwgXCIxMDBcIik7XG4kY2xyLWFtYmVyLTIwMDogIG1hcC1nZXQoJGNsci1hbWJlci1saXN0LCBcIjIwMFwiKTtcbiRjbHItYW1iZXItMzAwOiAgbWFwLWdldCgkY2xyLWFtYmVyLWxpc3QsIFwiMzAwXCIpO1xuJGNsci1hbWJlci00MDA6ICBtYXAtZ2V0KCRjbHItYW1iZXItbGlzdCwgXCI0MDBcIik7XG4kY2xyLWFtYmVyLTUwMDogIG1hcC1nZXQoJGNsci1hbWJlci1saXN0LCBcIjUwMFwiKTtcbiRjbHItYW1iZXItNjAwOiAgbWFwLWdldCgkY2xyLWFtYmVyLWxpc3QsIFwiNjAwXCIpO1xuJGNsci1hbWJlci03MDA6ICBtYXAtZ2V0KCRjbHItYW1iZXItbGlzdCwgXCI3MDBcIik7XG4kY2xyLWFtYmVyLTgwMDogIG1hcC1nZXQoJGNsci1hbWJlci1saXN0LCBcIjgwMFwiKTtcbiRjbHItYW1iZXItOTAwOiAgbWFwLWdldCgkY2xyLWFtYmVyLWxpc3QsIFwiOTAwXCIpO1xuJGNsci1hbWJlci1hMTAwOiBtYXAtZ2V0KCRjbHItYW1iZXItbGlzdCwgXCJhMTAwXCIpO1xuJGNsci1hbWJlci1hMjAwOiBtYXAtZ2V0KCRjbHItYW1iZXItbGlzdCwgXCJhMjAwXCIpO1xuJGNsci1hbWJlci1hNDAwOiBtYXAtZ2V0KCRjbHItYW1iZXItbGlzdCwgXCJhNDAwXCIpO1xuJGNsci1hbWJlci1hNzAwOiBtYXAtZ2V0KCRjbHItYW1iZXItbGlzdCwgXCJhNzAwXCIpO1xuXG5cbi8vXG4vLyBPcmFuZ2Vcbi8vXG5cbiRjbHItb3JhbmdlLWxpc3Q6IChcbiAgXCJiYXNlXCI6ICNmZjk4MDAsXG4gIFwiNTBcIjogICAjZmZmM2UwLFxuICBcIjEwMFwiOiAgI2ZmZTBiMixcbiAgXCIyMDBcIjogICNmZmNjODAsXG4gIFwiMzAwXCI6ICAjZmZiNzRkLFxuICBcIjQwMFwiOiAgI2ZmYTcyNixcbiAgXCI1MDBcIjogICNmZjk4MDAsXG4gIFwiNjAwXCI6ICAjZmI4YzAwLFxuICBcIjcwMFwiOiAgI2Y1N2MwMCxcbiAgXCI4MDBcIjogICNlZjZjMDAsXG4gIFwiOTAwXCI6ICAjZTY1MTAwLFxuICBcImExMDBcIjogI2ZmZDE4MCxcbiAgXCJhMjAwXCI6ICNmZmFiNDAsXG4gIFwiYTQwMFwiOiAjZmY5MTAwLFxuICBcImE3MDBcIjogI2ZmNmQwMFxuKTtcblxuJGNsci1vcmFuZ2U6ICAgICAgbWFwLWdldCgkY2xyLW9yYW5nZS1saXN0LCBcImJhc2VcIik7XG5cbiRjbHItb3JhbmdlLTUwOiAgIG1hcC1nZXQoJGNsci1vcmFuZ2UtbGlzdCwgXCI1MFwiKTtcbiRjbHItb3JhbmdlLTEwMDogIG1hcC1nZXQoJGNsci1vcmFuZ2UtbGlzdCwgXCIxMDBcIik7XG4kY2xyLW9yYW5nZS0yMDA6ICBtYXAtZ2V0KCRjbHItb3JhbmdlLWxpc3QsIFwiMjAwXCIpO1xuJGNsci1vcmFuZ2UtMzAwOiAgbWFwLWdldCgkY2xyLW9yYW5nZS1saXN0LCBcIjMwMFwiKTtcbiRjbHItb3JhbmdlLTQwMDogIG1hcC1nZXQoJGNsci1vcmFuZ2UtbGlzdCwgXCI0MDBcIik7XG4kY2xyLW9yYW5nZS01MDA6ICBtYXAtZ2V0KCRjbHItb3JhbmdlLWxpc3QsIFwiNTAwXCIpO1xuJGNsci1vcmFuZ2UtNjAwOiAgbWFwLWdldCgkY2xyLW9yYW5nZS1saXN0LCBcIjYwMFwiKTtcbiRjbHItb3JhbmdlLTcwMDogIG1hcC1nZXQoJGNsci1vcmFuZ2UtbGlzdCwgXCI3MDBcIik7XG4kY2xyLW9yYW5nZS04MDA6ICBtYXAtZ2V0KCRjbHItb3JhbmdlLWxpc3QsIFwiODAwXCIpO1xuJGNsci1vcmFuZ2UtOTAwOiAgbWFwLWdldCgkY2xyLW9yYW5nZS1saXN0LCBcIjkwMFwiKTtcbiRjbHItb3JhbmdlLWExMDA6IG1hcC1nZXQoJGNsci1vcmFuZ2UtbGlzdCwgXCJhMTAwXCIpO1xuJGNsci1vcmFuZ2UtYTIwMDogbWFwLWdldCgkY2xyLW9yYW5nZS1saXN0LCBcImEyMDBcIik7XG4kY2xyLW9yYW5nZS1hNDAwOiBtYXAtZ2V0KCRjbHItb3JhbmdlLWxpc3QsIFwiYTQwMFwiKTtcbiRjbHItb3JhbmdlLWE3MDA6IG1hcC1nZXQoJGNsci1vcmFuZ2UtbGlzdCwgXCJhNzAwXCIpO1xuXG5cbi8vXG4vLyBEZWVwIG9yYW5nZVxuLy9cblxuJGNsci1kZWVwLW9yYW5nZS1saXN0OiAoXG4gIFwiYmFzZVwiOiAjZmY1NzIyLFxuICBcIjUwXCI6ICAgI2ZiZTllNyxcbiAgXCIxMDBcIjogICNmZmNjYmMsXG4gIFwiMjAwXCI6ICAjZmZhYjkxLFxuICBcIjMwMFwiOiAgI2ZmOGE2NSxcbiAgXCI0MDBcIjogICNmZjcwNDMsXG4gIFwiNTAwXCI6ICAjZmY1NzIyLFxuICBcIjYwMFwiOiAgI2Y0NTExZSxcbiAgXCI3MDBcIjogICNlNjRhMTksXG4gIFwiODAwXCI6ICAjZDg0MzE1LFxuICBcIjkwMFwiOiAgI2JmMzYwYyxcbiAgXCJhMTAwXCI6ICNmZjllODAsXG4gIFwiYTIwMFwiOiAjZmY2ZTQwLFxuICBcImE0MDBcIjogI2ZmM2QwMCxcbiAgXCJhNzAwXCI6ICNkZDJjMDBcbik7XG5cbiRjbHItZGVlcC1vcmFuZ2U6ICAgICAgbWFwLWdldCgkY2xyLWRlZXAtb3JhbmdlLWxpc3QsIFwiYmFzZVwiKTtcblxuJGNsci1kZWVwLW9yYW5nZS01MDogICBtYXAtZ2V0KCRjbHItZGVlcC1vcmFuZ2UtbGlzdCwgXCI1MFwiKTtcbiRjbHItZGVlcC1vcmFuZ2UtMTAwOiAgbWFwLWdldCgkY2xyLWRlZXAtb3JhbmdlLWxpc3QsIFwiMTAwXCIpO1xuJGNsci1kZWVwLW9yYW5nZS0yMDA6ICBtYXAtZ2V0KCRjbHItZGVlcC1vcmFuZ2UtbGlzdCwgXCIyMDBcIik7XG4kY2xyLWRlZXAtb3JhbmdlLTMwMDogIG1hcC1nZXQoJGNsci1kZWVwLW9yYW5nZS1saXN0LCBcIjMwMFwiKTtcbiRjbHItZGVlcC1vcmFuZ2UtNDAwOiAgbWFwLWdldCgkY2xyLWRlZXAtb3JhbmdlLWxpc3QsIFwiNDAwXCIpO1xuJGNsci1kZWVwLW9yYW5nZS01MDA6ICBtYXAtZ2V0KCRjbHItZGVlcC1vcmFuZ2UtbGlzdCwgXCI1MDBcIik7XG4kY2xyLWRlZXAtb3JhbmdlLTYwMDogIG1hcC1nZXQoJGNsci1kZWVwLW9yYW5nZS1saXN0LCBcIjYwMFwiKTtcbiRjbHItZGVlcC1vcmFuZ2UtNzAwOiAgbWFwLWdldCgkY2xyLWRlZXAtb3JhbmdlLWxpc3QsIFwiNzAwXCIpO1xuJGNsci1kZWVwLW9yYW5nZS04MDA6ICBtYXAtZ2V0KCRjbHItZGVlcC1vcmFuZ2UtbGlzdCwgXCI4MDBcIik7XG4kY2xyLWRlZXAtb3JhbmdlLTkwMDogIG1hcC1nZXQoJGNsci1kZWVwLW9yYW5nZS1saXN0LCBcIjkwMFwiKTtcbiRjbHItZGVlcC1vcmFuZ2UtYTEwMDogbWFwLWdldCgkY2xyLWRlZXAtb3JhbmdlLWxpc3QsIFwiYTEwMFwiKTtcbiRjbHItZGVlcC1vcmFuZ2UtYTIwMDogbWFwLWdldCgkY2xyLWRlZXAtb3JhbmdlLWxpc3QsIFwiYTIwMFwiKTtcbiRjbHItZGVlcC1vcmFuZ2UtYTQwMDogbWFwLWdldCgkY2xyLWRlZXAtb3JhbmdlLWxpc3QsIFwiYTQwMFwiKTtcbiRjbHItZGVlcC1vcmFuZ2UtYTcwMDogbWFwLWdldCgkY2xyLWRlZXAtb3JhbmdlLWxpc3QsIFwiYTcwMFwiKTtcblxuXG4vL1xuLy8gQnJvd25cbi8vXG5cbiRjbHItYnJvd24tbGlzdDogKFxuICBcImJhc2VcIjogIzc5NTU0OCxcbiAgXCI1MFwiOiAgICNlZmViZTksXG4gIFwiMTAwXCI6ICAjZDdjY2M4LFxuICBcIjIwMFwiOiAgI2JjYWFhNCxcbiAgXCIzMDBcIjogICNhMTg4N2YsXG4gIFwiNDAwXCI6ICAjOGQ2ZTYzLFxuICBcIjUwMFwiOiAgIzc5NTU0OCxcbiAgXCI2MDBcIjogICM2ZDRjNDEsXG4gIFwiNzAwXCI6ICAjNWQ0MDM3LFxuICBcIjgwMFwiOiAgIzRlMzQyZSxcbiAgXCI5MDBcIjogICMzZTI3MjMsXG4pO1xuXG4kY2xyLWJyb3duOiAgICAgbWFwLWdldCgkY2xyLWJyb3duLWxpc3QsIFwiYmFzZVwiKTtcblxuJGNsci1icm93bi01MDogIG1hcC1nZXQoJGNsci1icm93bi1saXN0LCBcIjUwXCIpO1xuJGNsci1icm93bi0xMDA6IG1hcC1nZXQoJGNsci1icm93bi1saXN0LCBcIjEwMFwiKTtcbiRjbHItYnJvd24tMjAwOiBtYXAtZ2V0KCRjbHItYnJvd24tbGlzdCwgXCIyMDBcIik7XG4kY2xyLWJyb3duLTMwMDogbWFwLWdldCgkY2xyLWJyb3duLWxpc3QsIFwiMzAwXCIpO1xuJGNsci1icm93bi00MDA6IG1hcC1nZXQoJGNsci1icm93bi1saXN0LCBcIjQwMFwiKTtcbiRjbHItYnJvd24tNTAwOiBtYXAtZ2V0KCRjbHItYnJvd24tbGlzdCwgXCI1MDBcIik7XG4kY2xyLWJyb3duLTYwMDogbWFwLWdldCgkY2xyLWJyb3duLWxpc3QsIFwiNjAwXCIpO1xuJGNsci1icm93bi03MDA6IG1hcC1nZXQoJGNsci1icm93bi1saXN0LCBcIjcwMFwiKTtcbiRjbHItYnJvd24tODAwOiBtYXAtZ2V0KCRjbHItYnJvd24tbGlzdCwgXCI4MDBcIik7XG4kY2xyLWJyb3duLTkwMDogbWFwLWdldCgkY2xyLWJyb3duLWxpc3QsIFwiOTAwXCIpO1xuXG5cbi8vXG4vLyBHcmV5XG4vL1xuXG4kY2xyLWdyZXktbGlzdDogKFxuICBcImJhc2VcIjogIzllOWU5ZSxcbiAgXCI1MFwiOiAgICNmYWZhZmEsXG4gIFwiMTAwXCI6ICAjZjVmNWY1LFxuICBcIjIwMFwiOiAgI2VlZWVlZSxcbiAgXCIzMDBcIjogICNlMGUwZTAsXG4gIFwiNDAwXCI6ICAjYmRiZGJkLFxuICBcIjUwMFwiOiAgIzllOWU5ZSxcbiAgXCI2MDBcIjogICM3NTc1NzUsXG4gIFwiNzAwXCI6ICAjNjE2MTYxLFxuICBcIjgwMFwiOiAgIzQyNDI0MixcbiAgXCI5MDBcIjogICMyMTIxMjEsXG4pO1xuXG4kY2xyLWdyZXk6ICAgICBtYXAtZ2V0KCRjbHItZ3JleS1saXN0LCBcImJhc2VcIik7XG5cbiRjbHItZ3JleS01MDogIG1hcC1nZXQoJGNsci1ncmV5LWxpc3QsIFwiNTBcIik7XG4kY2xyLWdyZXktMTAwOiBtYXAtZ2V0KCRjbHItZ3JleS1saXN0LCBcIjEwMFwiKTtcbiRjbHItZ3JleS0yMDA6IG1hcC1nZXQoJGNsci1ncmV5LWxpc3QsIFwiMjAwXCIpO1xuJGNsci1ncmV5LTMwMDogbWFwLWdldCgkY2xyLWdyZXktbGlzdCwgXCIzMDBcIik7XG4kY2xyLWdyZXktNDAwOiBtYXAtZ2V0KCRjbHItZ3JleS1saXN0LCBcIjQwMFwiKTtcbiRjbHItZ3JleS01MDA6IG1hcC1nZXQoJGNsci1ncmV5LWxpc3QsIFwiNTAwXCIpO1xuJGNsci1ncmV5LTYwMDogbWFwLWdldCgkY2xyLWdyZXktbGlzdCwgXCI2MDBcIik7XG4kY2xyLWdyZXktNzAwOiBtYXAtZ2V0KCRjbHItZ3JleS1saXN0LCBcIjcwMFwiKTtcbiRjbHItZ3JleS04MDA6IG1hcC1nZXQoJGNsci1ncmV5LWxpc3QsIFwiODAwXCIpO1xuJGNsci1ncmV5LTkwMDogbWFwLWdldCgkY2xyLWdyZXktbGlzdCwgXCI5MDBcIik7XG5cblxuLy9cbi8vIEJsdWUgZ3JleVxuLy9cblxuJGNsci1ibHVlLWdyZXktbGlzdDogKFxuICBcImJhc2VcIjogIzYwN2Q4YixcbiAgXCI1MFwiOiAgICNlY2VmZjEsXG4gIFwiMTAwXCI6ICAjY2ZkOGRjLFxuICBcIjIwMFwiOiAgI2IwYmVjNSxcbiAgXCIzMDBcIjogICM5MGE0YWUsXG4gIFwiNDAwXCI6ICAjNzg5MDljLFxuICBcIjUwMFwiOiAgIzYwN2Q4YixcbiAgXCI2MDBcIjogICM1NDZlN2EsXG4gIFwiNzAwXCI6ICAjNDU1YTY0LFxuICBcIjgwMFwiOiAgIzM3NDc0ZixcbiAgXCI5MDBcIjogICMyNjMyMzgsXG4pO1xuXG4kY2xyLWJsdWUtZ3JleTogICAgIG1hcC1nZXQoJGNsci1ibHVlLWdyZXktbGlzdCwgXCJiYXNlXCIpO1xuXG4kY2xyLWJsdWUtZ3JleS01MDogIG1hcC1nZXQoJGNsci1ibHVlLWdyZXktbGlzdCwgXCI1MFwiKTtcbiRjbHItYmx1ZS1ncmV5LTEwMDogbWFwLWdldCgkY2xyLWJsdWUtZ3JleS1saXN0LCBcIjEwMFwiKTtcbiRjbHItYmx1ZS1ncmV5LTIwMDogbWFwLWdldCgkY2xyLWJsdWUtZ3JleS1saXN0LCBcIjIwMFwiKTtcbiRjbHItYmx1ZS1ncmV5LTMwMDogbWFwLWdldCgkY2xyLWJsdWUtZ3JleS1saXN0LCBcIjMwMFwiKTtcbiRjbHItYmx1ZS1ncmV5LTQwMDogbWFwLWdldCgkY2xyLWJsdWUtZ3JleS1saXN0LCBcIjQwMFwiKTtcbiRjbHItYmx1ZS1ncmV5LTUwMDogbWFwLWdldCgkY2xyLWJsdWUtZ3JleS1saXN0LCBcIjUwMFwiKTtcbiRjbHItYmx1ZS1ncmV5LTYwMDogbWFwLWdldCgkY2xyLWJsdWUtZ3JleS1saXN0LCBcIjYwMFwiKTtcbiRjbHItYmx1ZS1ncmV5LTcwMDogbWFwLWdldCgkY2xyLWJsdWUtZ3JleS1saXN0LCBcIjcwMFwiKTtcbiRjbHItYmx1ZS1ncmV5LTgwMDogbWFwLWdldCgkY2xyLWJsdWUtZ3JleS1saXN0LCBcIjgwMFwiKTtcbiRjbHItYmx1ZS1ncmV5LTkwMDogbWFwLWdldCgkY2xyLWJsdWUtZ3JleS1saXN0LCBcIjkwMFwiKTtcblxuXG4vL1xuLy8gQmxhY2tcbi8vXG5cbiRjbHItYmxhY2stbGlzdDogKFxuICBcImJhc2VcIjogIzAwMFxuKTtcblxuJGNsci1ibGFjazogbWFwLWdldCgkY2xyLWJsYWNrLWxpc3QsIFwiYmFzZVwiKTtcblxuXG4vL1xuLy8gV2hpdGVcbi8vXG5cbiRjbHItd2hpdGUtbGlzdDogKFxuICBcImJhc2VcIjogI2ZmZlxuKTtcblxuJGNsci13aGl0ZTogbWFwLWdldCgkY2xyLXdoaXRlLWxpc3QsIFwiYmFzZVwiKTtcblxuXG4vL1xuLy8gTGlzdCBmb3IgYWxsIENvbG9ycyBmb3IgbG9vcGluZ1xuLy9cblxuJGNsci1saXN0LWFsbDogKFxuICBcInJlZFwiOiAgICAgICAgICRjbHItcmVkLWxpc3QsXG4gIFwicGlua1wiOiAgICAgICAgJGNsci1waW5rLWxpc3QsXG4gIFwicHVycGxlXCI6ICAgICAgJGNsci1wdXJwbGUtbGlzdCxcbiAgXCJkZWVwLXB1cnBsZVwiOiAkY2xyLWRlZXAtcHVycGxlLWxpc3QsXG4gIFwiaW5kaWdvXCI6ICAgICAgJGNsci1pbmRpZ28tbGlzdCxcbiAgXCJibHVlXCI6ICAgICAgICAkY2xyLWJsdWUtbGlzdCxcbiAgXCJsaWdodC1ibHVlXCI6ICAkY2xyLWxpZ2h0LWJsdWUtbGlzdCxcbiAgXCJjeWFuXCI6ICAgICAgICAkY2xyLWN5YW4tbGlzdCxcbiAgXCJ0ZWFsXCI6ICAgICAgICAkY2xyLXRlYWwtbGlzdCxcbiAgXCJncmVlblwiOiAgICAgICAkY2xyLWdyZWVuLWxpc3QsXG4gIFwibGlnaHQtZ3JlZW5cIjogJGNsci1saWdodC1ncmVlbi1saXN0LFxuICBcImxpbWVcIjogICAgICAgICRjbHItbGltZS1saXN0LFxuICBcInllbGxvd1wiOiAgICAgICRjbHIteWVsbG93LWxpc3QsXG4gIFwiYW1iZXJcIjogICAgICAgJGNsci1hbWJlci1saXN0LFxuICBcIm9yYW5nZVwiOiAgICAgICRjbHItb3JhbmdlLWxpc3QsXG4gIFwiZGVlcC1vcmFuZ2VcIjogJGNsci1kZWVwLW9yYW5nZS1saXN0LFxuICBcImJyb3duXCI6ICAgICAgICRjbHItYnJvd24tbGlzdCxcbiAgXCJncmV5XCI6ICAgICAgICAkY2xyLWdyZXktbGlzdCxcbiAgXCJibHVlLWdyZXlcIjogICAkY2xyLWJsdWUtZ3JleS1saXN0LFxuICBcImJsYWNrXCI6ICAgICAgICRjbHItYmxhY2stbGlzdCxcbiAgXCJ3aGl0ZVwiOiAgICAgICAkY2xyLXdoaXRlLWxpc3Rcbik7XG5cblxuLy9cbi8vIFR5cG9ncmFwaHlcbi8vXG5cbiRjbHItdWktZGlzcGxheS00OiAkY2xyLWdyZXktNjAwO1xuJGNsci11aS1kaXNwbGF5LTM6ICRjbHItZ3JleS02MDA7XG4kY2xyLXVpLWRpc3BsYXktMjogJGNsci1ncmV5LTYwMDtcbiRjbHItdWktZGlzcGxheS0xOiAkY2xyLWdyZXktNjAwO1xuJGNsci11aS1oZWFkbGluZTogICRjbHItZ3JleS05MDA7XG4kY2xyLXVpLXRpdGxlOiAgICAgJGNsci1ncmV5LTkwMDtcbiRjbHItdWktc3ViaGVhZC0xOiAkY2xyLWdyZXktOTAwO1xuJGNsci11aS1ib2R5LTI6ICAgICRjbHItZ3JleS05MDA7XG4kY2xyLXVpLWJvZHktMTogICAgJGNsci1ncmV5LTkwMDtcbiRjbHItdWktY2FwdGlvbjogICAkY2xyLWdyZXktNjAwO1xuJGNsci11aS1tZW51OiAgICAgICRjbHItZ3JleS05MDA7XG4kY2xyLXVpLWJ1dHRvbjogICAgJGNsci1ncmV5LTkwMDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL25vZGVfbW9kdWxlcy9tYXRlcmlhbC1kZXNpZ24tY29sb3IvbWF0ZXJpYWwtY29sb3Iuc2NzcyIsIi8vXG4vLyBOYW1lOiAgICAgICAgICAgTWF0ZXJpYWwgU2hhZG93c1xuLy8gRGVzY3JpcHRpb246ICAgIE1peGlucyBmb3IgTWF0ZXJpYWwgRGVzaWduIFNoYWRvd3MuXG4vLyBWZXJzaW9uOiAgICAgICAgMy4wLjFcbi8vXG4vLyBBdXRob3I6ICAgICAgICAgRGVuaXMgTWFsaW5vY2hraW5cbi8vIEdpdDogICAgICAgICAgICBodHRwczovL2dpdGh1Yi5jb20vbXJtbG5jL21hdGVyaWFsLXNoYWRvd3Ncbi8vXG4vLyB0d2l0dGVyOiAgICAgICAgQG1ybWxuY1xuLy9cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cbi8vIE1peGluc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbkBtaXhpbiB6LWRlcHRoLXRyYW5zaXRpb24oKSB7XG4gIHRyYW5zaXRpb246IGJveC1zaGFkb3cgLjI4cyBjdWJpYy1iZXppZXIoLjQsIDAsIC4yLCAxKTtcbn1cblxuQG1peGluIHotZGVwdGgtZm9jdXMoKSB7XG4gIGJveC1zaGFkb3c6IDAgMCA4cHggcmdiYSgwLCAwLCAwLCAuMTgpLCAwIDhweCAxNnB4IHJnYmEoMCwgMCwgMCwgLjM2KTtcbn1cblxuQG1peGluIHotZGVwdGgtMmRwKCkge1xuICBib3gtc2hhZG93OiAwIDJweCAycHggMCByZ2JhKDAsIDAsIDAsIC4xNCksXG4gICAgICAgICAgICAgIDAgMXB4IDVweCAwIHJnYmEoMCwgMCwgMCwgLjEyKSxcbiAgICAgICAgICAgICAgMCAzcHggMXB4IC0ycHggcmdiYSgwLCAwLCAwLCAuMik7XG59XG5cbkBtaXhpbiB6LWRlcHRoLTNkcCgpIHtcbiAgYm94LXNoYWRvdzogMCAzcHggNHB4IDAgcmdiYSgwLCAwLCAwLCAuMTQpLFxuICAgICAgICAgICAgICAwIDFweCA4cHggMCByZ2JhKDAsIDAsIDAsIC4xMiksXG4gICAgICAgICAgICAgIDAgM3B4IDNweCAtMnB4IHJnYmEoMCwgMCwgMCwgLjQpO1xufVxuXG5AbWl4aW4gei1kZXB0aC00ZHAoKSB7XG4gIGJveC1zaGFkb3c6IDAgNHB4IDVweCAwIHJnYmEoMCwgMCwgMCwgLjE0KSxcbiAgICAgICAgICAgICAgMCAxcHggMTBweCAwIHJnYmEoMCwgMCwgMCwgLjEyKSxcbiAgICAgICAgICAgICAgMCAycHggNHB4IC0xcHggcmdiYSgwLCAwLCAwLCAuNCk7XG59XG5cbkBtaXhpbiB6LWRlcHRoLTZkcCgpIHtcbiAgYm94LXNoYWRvdzogMCA2cHggMTBweCAwIHJnYmEoMCwgMCwgMCwgLjE0KSxcbiAgICAgICAgICAgICAgMCAxcHggMThweCAwIHJnYmEoMCwgMCwgMCwgLjEyKSxcbiAgICAgICAgICAgICAgMCAzcHggNXB4IC0xcHggcmdiYSgwLCAwLCAwLCAuNCk7XG59XG5cbkBtaXhpbiB6LWRlcHRoLThkcCgpIHtcbiAgYm94LXNoYWRvdzogMCA4cHggMTBweCAxcHggcmdiYSgwLCAwLCAwLCAuMTQpLFxuICAgICAgICAgICAgICAwIDNweCAxNHB4IDJweCByZ2JhKDAsIDAsIDAsIC4xMiksXG4gICAgICAgICAgICAgIDAgNXB4IDVweCAtM3B4IHJnYmEoMCwgMCwgMCwgLjQpO1xufVxuXG5AbWl4aW4gei1kZXB0aC0xNmRwKCkge1xuICBib3gtc2hhZG93OiAwIDE2cHggMjRweCAycHggcmdiYSgwLCAwLCAwLCAuMTQpLFxuICAgICAgICAgICAgICAwICA2cHggMzBweCA1cHggcmdiYSgwLCAwLCAwLCAuMTIpLFxuICAgICAgICAgICAgICAwICA4cHggMTBweCAtNXB4IHJnYmEoMCwgMCwgMCwgLjQpO1xufVxuXG5AbWl4aW4gei1kZXB0aC0yNGRwKCkge1xuICBib3gtc2hhZG93OiAwICA5cHggNDZweCAgOHB4IHJnYmEoMCwgMCwgMCwgLjE0KSxcbiAgICAgICAgICAgICAgMCAyNHB4IDM4cHggIDNweCByZ2JhKDAsIDAsIDAsIC4xMiksXG4gICAgICAgICAgICAgIDAgMTFweCAxNXB4IC03cHggcmdiYSgwLCAwLCAwLCAuNCk7XG59XG5cbkBtaXhpbiB6LWRlcHRoKCRkcDogMikge1xuICBAaWYgJGRwID09IDIge1xuICAgIEBpbmNsdWRlIHotZGVwdGgtMmRwKCk7XG4gIH0gQGVsc2UgaWYgJGRwID09IDMge1xuICAgIEBpbmNsdWRlIHotZGVwdGgtM2RwKCk7XG4gIH0gQGVsc2UgaWYgJGRwID09IDQge1xuICAgIEBpbmNsdWRlIHotZGVwdGgtNGRwKCk7XG4gIH0gQGVsc2UgaWYgJGRwID09IDYge1xuICAgIEBpbmNsdWRlIHotZGVwdGgtNmRwKCk7XG4gIH0gQGVsc2UgaWYgJGRwID09IDgge1xuICAgIEBpbmNsdWRlIHotZGVwdGgtOGRwKCk7XG4gIH0gQGVsc2UgaWYgJGRwID09IDE2IHtcbiAgICBAaW5jbHVkZSB6LWRlcHRoLTE2ZHAoKTtcbiAgfSBAZWxzZSBpZiAkZHAgPT0gMjQge1xuICAgIEBpbmNsdWRlIHotZGVwdGgtMjRkcCgpO1xuICB9XG59XG5cblxuLy8gQ2xhc3MgZ2VuZXJhdG9yXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuQG1peGluIHotZGVwdGgtY2xhc3NlcygkdHJhbnNpdGlvbjogZmFsc2UsICRmb2N1czogZmFsc2UpIHtcbiAgQGlmICR0cmFuc2l0aW9uID09IHRydWUge1xuICAgICYtdHJhbnNpdGlvbiB7XG4gICAgICBAaW5jbHVkZSB6LWRlcHRoLXRyYW5zaXRpb24oKTtcbiAgICB9XG4gIH1cblxuICBAaWYgJGZvY3VzID09IHRydWUge1xuICAgICYtZm9jdXMge1xuICAgICAgQGluY2x1ZGUgei1kZXB0aC1mb2N1cygpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFRoZSBhdmFpbGFibGUgdmFsdWVzIGZvciB0aGUgc2hhZG93IGRlcHRoXG4gIEBlYWNoICRkZXB0aCBpbiAyLCAzLCA0LCA2LCA4LCAxNiwgMjQge1xuICAgICYtI3skZGVwdGh9ZHAge1xuICAgICAgQGluY2x1ZGUgei1kZXB0aCgkZGVwdGgpO1xuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vbm9kZV9tb2R1bGVzL21hdGVyaWFsLXNoYWRvd3MvbWF0ZXJpYWwtc2hhZG93cy5zY3NzIiwiLy8vL1xuLy8vIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbi8vL1xuLy8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLFxuLy8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb25cbi8vLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSxcbi8vLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGVcbi8vLyBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy8vXG4vLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vL1xuLy8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTExcbi8vLyBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4vLy8gRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUlxuLy8vIERFQUxJTkdTXG4vLy8vXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFZhcmlhYmxlc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBBY3RpdmUgKHRvZ2dsZWQpIGRyYXdlclxuJG1kLXRvZ2dsZV9fZHJhd2VyLS1jaGVja2VkOlxuICBcIltkYXRhLW1kLXRvZ2dsZT1cXFwiZHJhd2VyXFxcIl06Y2hlY2tlZCB+XCI7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzOiBiYXNlIGdyaWQgYW5kIGNvbnRhaW5lcnNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gU3RyZXRjaCBjb250YWluZXIgdG8gdmlld3BvcnQgYW5kIHNldCBiYXNlIGZvbnQtc2l6ZSB0byAxMHB4IGZvciBzaW1wbGVcbi8vIGNhbGN1bGF0aW9ucyBiYXNlIG9uIHJlbGF0aXZlIGVtcyAocmVtcylcbmh0bWwge1xuICBoZWlnaHQ6IDEwMCU7XG4gIGZvbnQtc2l6ZTogNjIuNSU7XG4gIC8vIEhhY2s6IHNvbWUgYnJvd3NlcnMgb24gc29tZSBvcGVyYXRpbmcgc3lzdGVtcyBkb24ndCBhY2NvdW50IGZvciBzY3JvbGxcbiAgLy8gYmFycyB3aGVuIGZpcmluZyBtZWRpYSBxdWVyaWVzLCBzbyB3ZSBuZWVkIHRvIGRvIHRoaXMgZm9yIHNhZmV0eS4gVGhpc1xuICAvLyBjdXJyZW50bHkgaW1wYWN0cyB0aGUgdGFibGUgb2YgY29udGVudHMgY29tcG9uZW50IGJldHdlZW4gMTIyMCBhbmQgMTIzNHB4XG4gIC8vIGFuZCBpcyB0byBjdXJyZW50IGtub3dsZWRnZSBub3QgZml4YWJsZS5cbiAgb3ZlcmZsb3cteDogaGlkZGVuO1xuXG4gIC8vIFtzY3JlZW4gbWVkaXVtICtdOiBTZXQgYmFzZSBmb250LXNpemUgdG8gMTFweFxuICBAaW5jbHVkZSBicmVhay1mcm9tLWRldmljZShzY3JlZW4gbWVkaXVtKSB7XG4gICAgZm9udC1zaXplOiA2OC43NSU7XG4gIH1cblxuICAvLyBbc2NyZWVuIGxhcmdlICtdOiBTZXQgYmFzZSBmb250LXNpemUgdG8gMTJweFxuICBAaW5jbHVkZSBicmVhay1mcm9tLWRldmljZShzY3JlZW4gbGFyZ2UpIHtcbiAgICBmb250LXNpemU6IDc1JTtcbiAgfVxufVxuXG4vLyBTdHJldGNoIGJvZHkgdG8gY29udGFpbmVyIGFuZCBsZWF2ZSByb29tIGZvciBmb290ZXJcbmJvZHkge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGhlaWdodDogMTAwJTtcblxuICAvLyBbdGFibGV0IHBvcnRyYWl0IC1dOiBMb2NrIGJvZHkgdG8gZGlzYWJsZSBzY3JvbGwgYnViYmxpbmdcbiAgQGluY2x1ZGUgYnJlYWstdG8tZGV2aWNlKHRhYmxldCBwb3J0cmFpdCkge1xuXG4gICAgLy8gTG9jayBib2R5IHRvIHZpZXdwb3J0IGhlaWdodCAoZS5nLiBpbiBzZWFyY2ggbW9kZSlcbiAgICAmW2RhdGEtbWQtc3RhdGU9XCJsb2NrXCJdIHtcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47XG5cbiAgICAgIC8vIEhpZGUgY29udGFpbmVyIG9uIGlPUywgb3IgdGhlIGJvZHkgd2lsbCBub3QgYmUgbG9ja2VkIGNvcnJlY3RseVxuICAgICAgLmlvcyAmIC5tZC1jb250YWluZXIge1xuICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vLyBIb3Jpem9udGFsIHNlcGFyYXRvcnNcbmhyIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIGhlaWdodDogMC4xcmVtO1xuICBwYWRkaW5nOiAwO1xuICBib3JkZXI6IDA7XG59XG5cbi8vIElubGluZSBTVkcgY29udGFpbmVyXG4ubWQtc3ZnIHtcbiAgZGlzcGxheTogbm9uZTtcbn1cblxuLy8gVGVtcGxhdGUtd2lkZSBncmlkXG4ubWQtZ3JpZCB7XG4gIG1heC13aWR0aDogMTIycmVtO1xuICBtYXJnaW4tcmlnaHQ6IGF1dG87XG4gIG1hcmdpbi1sZWZ0OiBhdXRvO1xufVxuXG4vLyBQcmV2ZW50IGNvbGxhcHNlIG9mIG1hcmdpbiB3aGVuIHNldHRpbmcgbWFyZ2luIG9uIGNoaWxkIGVsZW1lbnRcbi5tZC1jb250YWluZXIsXG4ubWQtbWFpbiB7XG4gIG92ZXJmbG93OiBhdXRvO1xufVxuXG4vLyBDb250ZW50IHdyYXBwZXIgLSB1c2UgZGlzcGxheTogdGFibGUgdG8gbWFrZSB2YXJpYWJsZS1oZWlnaHQgc3RpY2t5IGZvb3RlcnNcbi8vIHdvcmsgYW5kIGZpeGVkIHRhYmxlLWxheW91dCBmb3IgSUUsIHNlZSBodHRwOi8vYml0Lmx5LzJoWm9oWExcbi5tZC1jb250YWluZXIge1xuICBkaXNwbGF5OiB0YWJsZTtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogMTAwJTtcbiAgcGFkZGluZy10b3A6IDQuOHJlbTtcbiAgdGFibGUtbGF5b3V0OiBmaXhlZDtcbn1cblxuLy8gVGhlIG1haW4gY29udGVudCBzaG91bGQgc3RyZXRjaCB0byBtYXhpbXVtIGhlaWdodCBpbiB0aGUgdGFibGVcbi5tZC1tYWluIHtcbiAgZGlzcGxheTogdGFibGUtcm93O1xuICBoZWlnaHQ6IDEwMCU7XG5cbiAgLy8gSW5jcmVhc2UgdG9wIHNwYWNpbmcgb2YgY29udGVudCBhcmVhIHRvIGdpdmUgdHlwb2dyYXBoeSBtb3JlIHJvb21cbiAgJl9faW5uZXIge1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBwYWRkaW5nLXRvcDogMi40cmVtICsgMC42cmVtO1xuICAgIC8vIEhhY2s6IGluZHVjZSBtYXJnaW4tY29sbGFwc2UsIGJlY2F1c2Ugb3RoZXJ3aXNlIHRoZSBzaWRlYmFyIGhlaWdodCBpc1xuICAgIC8vIG5vdCBjYWxjdWxhdGVkIGNvcnJlY3RseSBhbmQgdGhlIG92ZXJmbG93IHByb3BlcnR5IG9uIHRoaXMgZWxlbWVudCBtdXN0XG4gICAgLy8gYmUgbGVmdCBpbiBpbml0aWFsIHN0YXRlIGZvciB0YXJnZXR0ZWQgbGluayBvZmZzZXRzIHRvIHdvcmsgcHJvcGVybHlcbiAgICBwYWRkaW5nLWJvdHRvbTogMC4xcmVtO1xuICB9XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzOiBuYXZpZ2F0aW9uYWwgZWxlbWVudHNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gVG9nZ2xlIGNoZWNrYm94XG4ubWQtdG9nZ2xlIHtcbiAgZGlzcGxheTogbm9uZTtcbn1cblxuLy8gT3ZlcmxheSBiZWxvdyBleHBhbmRlZCBkcmF3ZXJcbi5tZC1vdmVybGF5IHtcbiAgcG9zaXRpb246IGZpeGVkO1xuICB0b3A6IDA7XG4gIHdpZHRoOiAwO1xuICBoZWlnaHQ6IDA7XG4gIHRyYW5zaXRpb246XG4gICAgd2lkdGggICAwcyAwLjI1cyxcbiAgICBoZWlnaHQgIDBzIDAuMjVzLFxuICAgIG9wYWNpdHkgMC4yNXM7XG4gIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2xvci1ibGFjay0tbGlnaHQ7XG4gIG9wYWNpdHk6IDA7XG4gIHotaW5kZXg6IDM7XG5cbiAgLy8gW3RhYmxldCAtXTogVHJpZ2dlciBvdmVybGF5XG4gIEBpbmNsdWRlIGJyZWFrLXRvLWRldmljZSh0YWJsZXQpIHtcblxuICAgIC8vIEV4cGFuZGVkIGRyYXdlclxuICAgICN7JG1kLXRvZ2dsZV9fZHJhd2VyLS1jaGVja2VkfSAmIHtcbiAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgdHJhbnNpdGlvbjpcbiAgICAgICAgd2lkdGggICAwcyxcbiAgICAgICAgaGVpZ2h0ICAwcyxcbiAgICAgICAgb3BhY2l0eSAwLjI1cztcbiAgICAgIG9wYWNpdHk6IDE7XG4gICAgfVxuICB9XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzOiBmbGV4aWJsZSBlbGVtZW50cywgaW1wbGVtZW50ZWQgd2l0aCB0YWJsZSBsYXlvdXRcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gRmxleGlibGUgbGF5b3V0IGNvbnRhaW5lclxuLm1kLWZsZXgge1xuICBkaXNwbGF5OiB0YWJsZTtcblxuICAvLyBGbGV4aWJsZSBsYXlvdXQgY29udGFpbmVyIGNlbGwvZWxlbWVudFxuICAmX19jZWxsIHtcbiAgICBkaXNwbGF5OiB0YWJsZS1jZWxsO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICB2ZXJ0aWNhbC1hbGlnbjogdG9wO1xuXG4gICAgLy8gU2hyaW5rIHRvIG1pbmltdW0gd2lkdGhcbiAgICAmLS1zaHJpbmsge1xuICAgICAgd2lkdGg6IDAlO1xuICAgIH1cblxuICAgIC8vIFN0cmV0Y2ggdG8gbWF4aW11bSB3aWR0aFxuICAgICYtLXN0cmV0Y2gge1xuICAgICAgZGlzcGxheTogdGFibGU7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIHRhYmxlLWxheW91dDogZml4ZWQ7XG4gICAgfVxuICB9XG5cbiAgLy8gQXBwbHkgZWxsaXBzaXMgaW4gY2FzZSBvZiBvdmVyZmxvd2luZyB0ZXh0XG4gICZfX2VsbGlwc2lzIHtcbiAgICBkaXNwbGF5OiB0YWJsZS1jZWxsO1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgfVxufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBSdWxlczogc2tpcCBsaW5rXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIFNraXAgbGlua1xuLm1kLXNraXAge1xuICBwb3NpdGlvbjogZml4ZWQ7XG4gIHdpZHRoOiAwLjFyZW07XG4gIGhlaWdodDogMC4xcmVtO1xuICBtYXJnaW46IDFyZW07XG4gIHBhZGRpbmc6IDAuNnJlbSAxcmVtO1xuICBjbGlwOiByZWN0KDAuMXJlbSk7XG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgwLjhyZW0pO1xuICBib3JkZXItcmFkaXVzOiAwLjJyZW07XG4gIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2xvci1ibGFjaztcbiAgY29sb3I6ICRtZC1jb2xvci13aGl0ZTtcbiAgZm9udC1zaXplOiBtcygtMSk7XG4gIG9wYWNpdHk6IDA7XG4gIG92ZXJmbG93OiBoaWRkZW47XG5cbiAgLy8gU2hvdyBza2lwIGxpbmsgb24gZm9jdXNcbiAgJjpmb2N1cyB7XG4gICAgd2lkdGg6IGF1dG87XG4gICAgaGVpZ2h0OiBhdXRvO1xuICAgIGNsaXA6IGF1dG87XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDApO1xuICAgIHRyYW5zaXRpb246XG4gICAgICB0cmFuc2Zvcm0gMC4yNXMgY3ViaWMtYmV6aWVyKDAuNCwgMCwgMC4yLCAxKSxcbiAgICAgIG9wYWNpdHkgICAwLjE3NXMgMC4wNzVzO1xuICAgIG9wYWNpdHk6IDE7XG4gICAgei1pbmRleDogMTA7XG4gIH1cbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUnVsZXM6IHByaW50IHN0eWxlc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBBZGQgbWFyZ2lucyB0byBwYWdlXG5AcGFnZSB7XG4gIG1hcmdpbjogMjVtbTtcbn1cblxudWwsIHVsIGxpIHtcbiAgbWFyZ2luOiAwO1xuICBwYWRkaW5nOiAwO1xuICBsaXN0LXN0eWxlOiBub25lOyB9XG5cbi5hYm91dCB7XG4gIG1hcmdpbi10b3A6IDUwcHg7IH1cblxuLmFib3V0LWxpc3Qge1xuICBvdmVyZmxvdzogaGlkZGVuOyB9XG5cbi5hYm91dC1saXN0IGxpIHtcbiAgZmxvYXQ6IGxlZnQ7XG4gIG1hcmdpbjogMXB4O1xuICB3aWR0aDogMTY4cHg7XG4gIGhlaWdodDogMjgwcHg7XG4gIHBhZGRpbmc6IDIwcHggMTVweDtcbiAgYm9yZGVyOiAxcHggc29saWQgI2YwZjBmMDtcbiAgYm9yZGVyLXJhZGl1czogM3B4O1xuICBib3gtc2hhZG93OiAtMXB4IDBweCAxMHB4ICNlNGU0ZTQ7XG4gIC13ZWJraXQtYm94LXNoYWRvdzogLTFweCAwcHggMTBweCAjZTRlNGU0O1xuICB0cmFuc2l0aW9uOiBhbGwgLjNzO1xuICAtd2Via2l0LXRyYW5zaXRpb246IGFsbCAuM3M7IH1cblxuLmFib3V0LWxpc3QgbGk6aG92ZXIge1xuICBib3gtc2hhZG93OiAtMXB4IDBweCAxNXB4ICNkYmRiZGI7XG4gIC13ZWJraXQtYm94LXNoYWRvdzogLTFweCAwcHggMTVweCAjZGJkYmRiOyB9XG5cbi5hYm91dC1saXN0IC5waWN0dXJlIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIG1hcmdpbjogYXV0bztcbiAgd2lkdGg6IDE2OHB4O1xuICBoZWlnaHQ6IDE2OHB4O1xuICBib3JkZXItcmFkaXVzOiAzcHg7IH1cblxuLmFib3V0LWxpc3QgLmRlc2Mge1xuICBtYXJnaW46IDA7IH1cblxuLmFib3V0LWxpc3QgLmRlc2MgZHQge1xuICBtYXJnaW46IDEwcHggMCA1cHg7XG4gIGZvbnQtd2VpZ2h0OiBib2xkOyB9XG5cbi5hYm91dC1saXN0IC5kZXNjIGRkIHtcbiAgZGlzcGxheTogLXdlYmtpdC1ib3g7XG4gIG1hcmdpbjogMDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgZm9udC1zaXplOiAuOGVtO1xuICBsaW5lLWhlaWdodDogMS40ZW07XG4gIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAtd2Via2l0LWxpbmUtY2xhbXA6IDM7XG4gIC13ZWJraXQtYm94LW9yaWVudDogdmVydGljYWw7XG4gIGNvbG9yOiAjODg4O1xuICB3aWR0aDogMTAwJTsgfVxuXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2xheW91dC9fYmFzZS5zY3NzIiwiLy8vL1xuLy8vIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbi8vL1xuLy8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLFxuLy8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb25cbi8vLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSxcbi8vLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGVcbi8vLyBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy8vXG4vLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vL1xuLy8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTExcbi8vLyBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4vLy8gRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUlxuLy8vIERFQUxJTkdTXG4vLy8vXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIENvcHkgdG8gY2xpcGJvYXJkXG4ubWQtY2xpcGJvYXJkIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IDAuNnJlbTtcbiAgcmlnaHQ6IDAuNnJlbTtcbiAgd2lkdGg6IDIuOHJlbTtcbiAgaGVpZ2h0OiAyLjhyZW07XG4gIGJvcmRlci1yYWRpdXM6IDAuMnJlbTtcbiAgZm9udC1zaXplOiAxLjZyZW07XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgei1pbmRleDogMTtcbiAgLy8gSGFjazogcHV0IGV2ZXJ5dGhpbmcgb24gdGhlIEdQVSB0byBvbWl0IGZsaWNrZXJpbmdcbiAgYmFja2ZhY2UtdmlzaWJpbGl0eTogaGlkZGVuO1xuXG4gIC8vIEhpZGUgZm9yIHByaW50XG4gIEBtZWRpYSBwcmludCB7XG4gICAgZGlzcGxheTogbm9uZTtcbiAgfVxuXG4gIC8vIEljb25cbiAgJjo6YmVmb3JlIHtcbiAgICBAZXh0ZW5kICVtZC1pY29uO1xuXG4gICAgdHJhbnNpdGlvbjpcbiAgICAgIGNvbG9yICAgMC4yNXMsXG4gICAgICBvcGFjaXR5IDAuMjVzO1xuICAgIGNvbG9yOiAkbWQtY29sb3ItYmxhY2stLWxpZ2h0ZXN0O1xuICAgIGNvbnRlbnQ6IFwiXFxFMTREXCI7IC8vIGNvbnRlbnRfY29weVxuXG4gICAgLy8gU2hvdyBvbiBjb250YWluZXIgaG92ZXJcbiAgICBwcmU6aG92ZXIgJixcbiAgICAuY29kZWhpbGl0ZTpob3ZlciAmIHtcbiAgICAgIGNvbG9yOiAkbWQtY29sb3ItYmxhY2stLWxpZ2h0O1xuICAgIH1cbiAgfVxuXG4gIC8vIEZvY3VzZWQgb3IgaG92ZXJlZCBpY29uXG4gICY6Zm9jdXM6OmJlZm9yZSxcbiAgJjpob3Zlcjo6YmVmb3JlIHtcbiAgICBjb2xvcjogJG1kLWNvbG9yLWFjY2VudDtcbiAgfVxuXG4gIC8vIE1lc3NhZ2VcbiAgJl9fbWVzc2FnZSB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRvcDogMDtcbiAgICByaWdodDogMy40cmVtO1xuICAgIHBhZGRpbmc6IDAuNnJlbSAxcmVtO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgwLjhyZW0pO1xuICAgIHRyYW5zaXRpb246XG4gICAgICB0cmFuc2Zvcm0gMC4yNXMgY3ViaWMtYmV6aWVyKDAuOSwgMC4xLCAwLjksIDApLFxuICAgICAgb3BhY2l0eSAgIDAuMTc1cztcbiAgICBib3JkZXItcmFkaXVzOiAwLjJyZW07XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJG1kLWNvbG9yLWJsYWNrLS1saWdodDtcbiAgICBjb2xvcjogJG1kLWNvbG9yLXdoaXRlO1xuICAgIGZvbnQtc2l6ZTogbXMoLTEpO1xuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgb3BhY2l0eTogMDtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcblxuICAgIC8vIEFjdGl2ZSBtZXNzYWdlXG4gICAgJi0tYWN0aXZlIHtcbiAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgwKTtcbiAgICAgIHRyYW5zaXRpb246XG4gICAgICAgIHRyYW5zZm9ybSAwLjI1cyBjdWJpYy1iZXppZXIoMC40LCAwLCAwLjIsIDEpLFxuICAgICAgICBvcGFjaXR5ICAgMC4xNzVzIDAuMDc1cztcbiAgICAgIG9wYWNpdHk6IDE7XG4gICAgICBwb2ludGVyLWV2ZW50czogaW5pdGlhbDtcbiAgICB9XG5cbiAgICAvLyBJbmplY3QgY29udGVudCBmcm9tIEFSSUEgbGFiZWxcbiAgICAmOjpiZWZvcmUge1xuICAgICAgY29udGVudDogYXR0cihhcmlhLWxhYmVsKTtcbiAgICB9XG5cbiAgICAvLyBQYWludCBhIG5pY2Ugc3BlZWNoIGJ1YmJsZVxuICAgICY6OmFmdGVyIHtcbiAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgdG9wOiA1MCU7XG4gICAgICByaWdodDogLTAuNHJlbTtcbiAgICAgIHdpZHRoOiAwO1xuICAgICAgbWFyZ2luLXRvcDogLTAuNHJlbTtcbiAgICAgIGJvcmRlci13aWR0aDogMC40cmVtIDAgMC40cmVtIDAuNHJlbTtcbiAgICAgIGJvcmRlci1zdHlsZTogc29saWQ7XG4gICAgICBib3JkZXItY29sb3I6IHRyYW5zcGFyZW50ICRtZC1jb2xvci1ibGFjay0tbGlnaHQ7XG4gICAgICBjb250ZW50OiBcIlwiO1xuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9sYXlvdXQvX2NsaXBib2FyZC5zY3NzIiwiLy8vL1xuLy8vIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbi8vL1xuLy8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLFxuLy8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb25cbi8vLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSxcbi8vLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGVcbi8vLyBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy8vXG4vLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vL1xuLy8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTExcbi8vLyBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4vLy8gRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUlxuLy8vIERFQUxJTkdTXG4vLy8vXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIENvbnRlbnQgY29udGFpbmVyXG4ubWQtY29udGVudCB7XG5cbiAgLy8gW3RhYmxldCBsYW5kc2NhcGUgK106IEFkZCBzcGFjZSBmb3IgdGFibGUgb2YgY29udGVudHNcbiAgQGluY2x1ZGUgYnJlYWstZnJvbS1kZXZpY2UodGFibGV0IGxhbmRzY2FwZSkge1xuICAgIG1hcmdpbi1yaWdodDogMjQuMnJlbTtcblxuICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICBtYXJnaW4tcmlnaHQ6IGluaXRpYWw7XG4gICAgICBtYXJnaW4tbGVmdDogMjQuMnJlbTtcbiAgICB9XG4gIH1cblxuICAvLyBbc2NyZWVuICtdOiBBZGQgc3BhY2UgZm9yIHRhYmxlIG9mIGNvbnRlbnRzXG4gIEBpbmNsdWRlIGJyZWFrLWZyb20tZGV2aWNlKHNjcmVlbikge1xuICAgIG1hcmdpbi1sZWZ0OiAyNC4ycmVtO1xuXG4gICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgIG1hcmdpbi1yaWdodDogMjQuMnJlbTtcbiAgICB9XG4gIH1cblxuICAvLyBEZWZpbmUgc3BhY2luZ1xuICAmX19pbm5lciB7XG4gICAgbWFyZ2luOiAwIDEuNnJlbSAyLjRyZW07XG4gICAgcGFkZGluZy10b3A6IDEuMnJlbTtcblxuICAgIC8vIFtzY3JlZW4gK106IEluY3JlYXNlIGhvcml6b250YWwgc3BhY2luZ1xuICAgIEBpbmNsdWRlIGJyZWFrLWZyb20tZGV2aWNlKHNjcmVlbikge1xuICAgICAgbWFyZ2luLXJpZ2h0OiAyLjRyZW07XG4gICAgICBtYXJnaW4tbGVmdDogMi40cmVtO1xuICAgIH1cblxuICAgIC8vIEhhY2s6IGFkZCBwc2V1ZG8gZWxlbWVudCBmb3Igc3BhY2luZywgYXMgdGhlIG92ZXJmbG93IG9mIHRoZSBjb250ZW50XG4gICAgLy8gY29udGFpbmVyIG1heSBub3QgYmUgaGlkZGVuIGR1ZSB0byBhbiBpbW1pbmVudCBvZmZzZXQgZXJyb3Igb24gdGFyZ2V0c1xuICAgICY6OmJlZm9yZSB7XG4gICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgIGhlaWdodDogMC44cmVtO1xuICAgICAgY29udGVudDogXCJcIjtcbiAgICB9XG5cbiAgICAvLyBIYWNrOiByZW1vdmUgYm90dG9tIHNwYWNpbmcgb2YgbGFzdCBlbGVtZW50LCBkdWUgdG8gbWFyZ2luIGNvbGxhcHNlXG4gICAgPiA6bGFzdC1jaGlsZCB7XG4gICAgICBtYXJnaW4tYm90dG9tOiAwO1xuICAgIH1cbiAgfVxuXG4gIC8vIEljb25zXG4gICZfX2ljb24ge1xuICAgIEBleHRlbmQgJW1kLWljb25fX2J1dHRvbjtcblxuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBtYXJnaW46IDAuOHJlbSAwO1xuICAgIHBhZGRpbmc6IDA7XG4gICAgZmxvYXQ6IHJpZ2h0O1xuXG4gICAgLy8gT3ZlcnJpZGUgZGVmYXVsdCBsaW5rIGNvbG9yIGZvciBpY29uc1xuICAgIC5tZC10eXBlc2V0ICYge1xuICAgICAgY29sb3I6ICRtZC1jb2xvci1ibGFjay0tbGlnaHRlcjtcbiAgICB9XG5cbiAgICAvLyBIaWRlIGZvciBwcmludFxuICAgIEBtZWRpYSBwcmludCB7XG4gICAgICBkaXNwbGF5OiBub25lO1xuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9sYXlvdXQvX2NvbnRlbnQuc2NzcyIsIi8vLy9cbi8vLyBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4vLy9cbi8vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSxcbi8vLyB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uXG4vLy8gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsXG4vLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlXG4vLy8gU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vL1xuLy8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vLy9cbi8vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMXG4vLy8gVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuLy8vIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVJcbi8vLyBERUFMSU5HU1xuLy8vL1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBSdWxlc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBBcHBsaWNhdGlvbiBoZWFkZXIgKHN0YXlzIGFsd2F5cyBvbiB0b3ApXG4ubWQtaGVhZGVyIHtcbiAgcG9zaXRpb246IGZpeGVkO1xuICB0b3A6IDA7XG4gIHJpZ2h0OiAwO1xuICBsZWZ0OiAwO1xuICBoZWlnaHQ6IDQuOHJlbTtcbiAgdHJhbnNpdGlvbjpcbiAgICBiYWNrZ3JvdW5kLWNvbG9yIDAuMjVzLFxuICAgIGNvbG9yIDAuMjVzO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQtY29sb3ItcHJpbWFyeTtcbiAgY29sb3I6ICRtZC1jb2xvci13aGl0ZTtcbiAgYm94LXNoYWRvdzogbm9uZTtcbiAgei1pbmRleDogMjtcbiAgLy8gSGFjazogcHV0dGluZyB0aGUgaGVhZGVyIG9uIHRoZSBHUFUgYXZvaWRzIHVubmVjZXNzYXJ5IHJlcGFpbnRzXG4gIGJhY2tmYWNlLXZpc2liaWxpdHk6IGhpZGRlbjtcblxuICAvLyBBbHdheXMgc2hvdyBzaGFkb3csIGluIGNhc2UgSmF2YVNjcmlwdCBpcyBub3QgYXZhaWxhYmxlXG4gIC5uby1qcyAmIHtcbiAgICB0cmFuc2l0aW9uOiBub25lO1xuICAgIGJveC1zaGFkb3c6IG5vbmU7XG4gIH1cblxuICAvLyBTaG93IGFuZCBhbmltYXRlIHNoYWRvd1xuICAmW2RhdGEtbWQtc3RhdGU9XCJzaGFkb3dcIl0ge1xuICAgIHRyYW5zaXRpb246XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yIDAuMjVzLFxuICAgICAgY29sb3IgMC4yNXMsXG4gICAgICBib3gtc2hhZG93IDAuMjVzO1xuICAgIGJveC1zaGFkb3c6XG4gICAgICAwIDAgICAgICAwLjRyZW0gcmdiYSgwLCAwLCAwLCAwLjEpLFxuICAgICAgMCAwLjRyZW0gMC44cmVtIHJnYmEoMCwgMCwgMCwgMC4yKTtcbiAgfVxuXG4gIC8vIEhpZGUgZm9yIHByaW50XG4gIEBtZWRpYSBwcmludCB7XG4gICAgZGlzcGxheTogbm9uZTtcbiAgfVxufVxuXG4vLyBOYXZpZ2F0aW9uIHdpdGhpbiBoZWFkZXJcbi5tZC1oZWFkZXItbmF2IHtcbiAgcGFkZGluZzogMCAwLjRyZW07XG5cbiAgLy8gSWNvbiBidXR0b25zXG4gICZfX2J1dHRvbiB7XG4gICAgQGV4dGVuZCAlbWQtaWNvbl9fYnV0dG9uO1xuXG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHRyYW5zaXRpb246IG9wYWNpdHkgMC4yNXM7XG4gICAgei1pbmRleDogMTtcblxuICAgIC8vIEhvdmVyZWQgaWNvblxuICAgICY6aG92ZXIge1xuICAgICAgb3BhY2l0eTogMC43O1xuICAgIH1cblxuICAgIC8vIFNldCBjb3JyZWN0IGRpc3BsYXkgb24gaW1hZ2Ugb3IgaWNvblxuICAgICYubWQtbG9nbyAqIHtcbiAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIH1cblxuICAgIC8vIEhpZGUgc2VhcmNoIGljb24sIGlmIEphdmFTY3JpcHQgaXMgbm90IGF2YWlsYWJsZS5cbiAgICAubm8tanMgJi5tZC1pY29uLS1zZWFyY2gge1xuICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG5cbiAgICAvLyBbdGFibGV0IGxhbmRzY2FwZSArXTogSGlkZSB0aGUgc2VhcmNoIGljb25cbiAgICBAaW5jbHVkZSBicmVhay1mcm9tLWRldmljZSh0YWJsZXQgbGFuZHNjYXBlKSB7XG5cbiAgICAgIC8vIFNlYXJjaCBpY29uXG4gICAgICAmLm1kLWljb24tLXNlYXJjaCB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gW3RhYmxldCAtXTogSGlkZSB0aGUgaG9tZSBpY29uIG9yIGxvZ29cbiAgICBAaW5jbHVkZSBicmVhay10by1kZXZpY2UodGFibGV0KSB7XG5cbiAgICAgIC8vIEhvbWUgaWNvbiBvciBsb2dvXG4gICAgICAmLm1kLWljb24tLWhvbWUsXG4gICAgICAmLm1kLWxvZ28ge1xuICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFtzY3JlZW4gK106IEhpZGUgdGhlIG1lbnUgaWNvblxuICAgIEBpbmNsdWRlIGJyZWFrLWZyb20tZGV2aWNlKHNjcmVlbikge1xuXG4gICAgICAvLyBNZW51IGljb25cbiAgICAgICYubWQtaWNvbi0tbWVudSB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gSGVhZGVyIHRvcGljc1xuICAmX190b3BpYyB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRyYW5zaXRpb246XG4gICAgICB0cmFuc2Zvcm0gMC40cyBjdWJpYy1iZXppZXIoMC4xLCAwLjcsIDAuMSwgMSksXG4gICAgICBvcGFjaXR5ICAgMC4xNXM7XG4gICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuXG4gICAgLy8gUGFnZSB0aXRsZVxuICAgICYgKyAmIHtcbiAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgyLjVyZW0pO1xuICAgICAgdHJhbnNpdGlvbjpcbiAgICAgICAgdHJhbnNmb3JtIDAuNHMgY3ViaWMtYmV6aWVyKDEsIDAuNywgMC4xLCAwLjEpLFxuICAgICAgICBvcGFjaXR5ICAgMC4xNXM7XG4gICAgICBvcGFjaXR5OiAwO1xuICAgICAgei1pbmRleDogLTE7XG4gICAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcblxuICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTIuNXJlbSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSW5kdWNlIGVsbGlwc2lzLCBpZiBubyBKYXZhU2NyaXB0IGlzIGF2YWlsYWJsZVxuICAgIC5uby1qcyAmIHtcbiAgICAgIHBvc2l0aW9uOiBpbml0aWFsO1xuICAgIH1cblxuICAgIC8vIEhpZGUgcGFnZSB0aXRsZSBhcyBpdCBpcyBpbnZpc2libGUgYW55d2F5IGFuZCB3aWxsIG92ZXJmbG93IHRoZSBoZWFkZXJcbiAgICAubm8tanMgJiArICYge1xuICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG4gIH1cblxuICAvLyBIZWFkZXIgdGl0bGUgLSBzZXQgbGluZSBoZWlnaHQgdG8gbWF0Y2ggaWNvbiBmb3IgY29ycmVjdCBhbGlnbm1lbnRcbiAgJl9fdGl0bGUge1xuICAgIHBhZGRpbmc6IDAgMnJlbTtcbiAgICBmb250LXNpemU6IDEuOHJlbTtcbiAgICBsaW5lLWhlaWdodDogNC44cmVtO1xuXG4gICAgLy8gU2hvdyBwYWdlIHRpdGxlXG4gICAgJltkYXRhLW1kLXN0YXRlPVwiYWN0aXZlXCJdIC5tZC1oZWFkZXItbmF2X190b3BpYyB7XG4gICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTIuNXJlbSk7XG4gICAgICB0cmFuc2l0aW9uOlxuICAgICAgICB0cmFuc2Zvcm0gMC40cyBjdWJpYy1iZXppZXIoMSwgMC43LCAwLjEsIDAuMSksXG4gICAgICAgIG9wYWNpdHkgICAwLjE1cztcbiAgICAgIG9wYWNpdHk6IDA7XG4gICAgICB6LWluZGV4OiAtMTtcbiAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuXG4gICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgyLjVyZW0pO1xuICAgICAgfVxuXG4gICAgICAvLyBQYWdlIHRpdGxlXG4gICAgICAmICsgLm1kLWhlYWRlci1uYXZfX3RvcGljIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDApO1xuICAgICAgICB0cmFuc2l0aW9uOlxuICAgICAgICAgIHRyYW5zZm9ybSAwLjRzIGN1YmljLWJlemllcigwLjEsIDAuNywgMC4xLCAxKSxcbiAgICAgICAgICBvcGFjaXR5ICAgMC4xNXM7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICAgIHotaW5kZXg6IDA7XG4gICAgICAgIHBvaW50ZXItZXZlbnRzOiBpbml0aWFsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFJlcG9zaXRvcnkgY29udGFpbmluZyBzb3VyY2VcbiAgJl9fc291cmNlIHtcbiAgICBkaXNwbGF5OiBub25lO1xuXG4gICAgLy8gW3RhYmxldCBsYW5kc2NhcGUgK106IFNob3cgdGhlIHJlcG9zaXN0b3J5IGZyb20gdGFibGV0XG4gICAgQGluY2x1ZGUgYnJlYWstZnJvbS1kZXZpY2UodGFibGV0IGxhbmRzY2FwZSkge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICB3aWR0aDogMjNyZW07XG4gICAgICBtYXgtd2lkdGg6IDIzcmVtO1xuICAgICAgbWFyZ2luLWxlZnQ6IDIuOHJlbTtcbiAgICAgIHBhZGRpbmctcmlnaHQ6IDEuMnJlbTtcblxuICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICBtYXJnaW4tcmlnaHQ6IDIuOHJlbTtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IGluaXRpYWw7XG4gICAgICAgIHBhZGRpbmctcmlnaHQ6IGluaXRpYWw7XG4gICAgICAgIHBhZGRpbmctbGVmdDogMS4ycmVtO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9sYXlvdXQvX2hlYWRlci5zY3NzIiwiLy8vL1xuLy8vIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbi8vL1xuLy8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLFxuLy8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb25cbi8vLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSxcbi8vLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGVcbi8vLyBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy8vXG4vLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vL1xuLy8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTExcbi8vLyBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4vLy8gRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUlxuLy8vIERFQUxJTkdTXG4vLy8vXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIEhlcm8gdGVhc2VyXG4ubWQtaGVybyB7XG4gIHRyYW5zaXRpb246IGJhY2tncm91bmQgMC4yNXM7XG4gIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2xvci1wcmltYXJ5O1xuICBjb2xvcjogJG1kLWNvbG9yLXdoaXRlO1xuICBmb250LXNpemU6IG1zKDEpO1xuICBvdmVyZmxvdzogaGlkZGVuO1xuXG4gIC8vIElubmVyIHdyYXBwZXJcbiAgJl9faW5uZXIge1xuICAgIG1hcmdpbi10b3A6IDJyZW07XG4gICAgcGFkZGluZzogMS42cmVtIDEuNnJlbSAwLjhyZW07XG4gICAgdHJhbnNpdGlvbjpcbiAgICAgIHRyYW5zZm9ybSAwLjRzIGN1YmljLWJlemllcigwLjEsIDAuNywgMC4xLCAxKSxcbiAgICAgIG9wYWNpdHkgICAwLjI1cztcbiAgICB0cmFuc2l0aW9uLWRlbGF5OiAwLjFzO1xuXG4gICAgLy8gW3RhYmxldCAtXTogQ29tcGVuc2F0ZSBmb3IgbWlzc2luZyB0YWJzXG4gICAgQGluY2x1ZGUgYnJlYWstdG8tZGV2aWNlKHRhYmxldCkge1xuICAgICAgbWFyZ2luLXRvcDogNC44cmVtO1xuICAgICAgbWFyZ2luLWJvdHRvbTogMi40cmVtO1xuICAgIH1cblxuICAgIC8vIEZhZGUtb3V0IHRhYnMgYmFja2dyb3VuZCB1cG9uIHNjcm9sbGluZ1xuICAgIFtkYXRhLW1kLXN0YXRlPVwiaGlkZGVuXCJdICYge1xuICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoMS4yNXJlbSk7XG4gICAgICB0cmFuc2l0aW9uOlxuICAgICAgICB0cmFuc2Zvcm0gMHMgICAwLjRzLFxuICAgICAgICBvcGFjaXR5ICAgMC4xcyAwcztcbiAgICAgIG9wYWNpdHk6IDA7XG4gICAgfVxuXG4gICAgLy8gQWRqdXN0IGJvdHRvbSBzcGFjaW5nIGlmIHRoZXJlIGFyZSBubyB0YWJzXG4gICAgLm1kLWhlcm8tLWV4cGFuZCAmIHtcbiAgICAgIG1hcmdpbi1ib3R0b206IDIuNHJlbTtcbiAgICB9XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvbGF5b3V0L19oZXJvLnNjc3MiLCIvLy8vXG4vLy8gQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuLy8vXG4vLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksXG4vLy8gdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvblxuLy8vIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLFxuLy8vIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZVxuLy8vIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vLy9cbi8vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy8vXG4vLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTFxuLy8vIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbi8vLyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSXG4vLy8gREVBTElOR1Ncbi8vLy9cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUnVsZXNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gQXBwbGljYXRpb24gZm9vdGVyXG4ubWQtZm9vdGVyIHtcblxuICAvLyBIaWRlIGZvciBwcmludFxuICBAbWVkaWEgcHJpbnQge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1cbn1cblxuLy8gTmF2aWdhdGlvbiB3aXRoaW4gZm9vdGVyXG4ubWQtZm9vdGVyLW5hdiB7XG4gIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2xvci1ibGFjaztcbiAgY29sb3I6ICRtZC1jb2xvci13aGl0ZTtcblxuICAvLyBTZXQgc3BhY2luZ1xuICAmX19pbm5lciB7XG4gICAgcGFkZGluZzogMC40cmVtO1xuICAgIG92ZXJmbG93OiBhdXRvO1xuICB9XG5cbiAgLy8gTGlua3MgdG8gcHJldmlvdXMgYW5kIG5leHQgcGFnZVxuICAmX19saW5rIHtcbiAgICBwYWRkaW5nLXRvcDogMi44cmVtO1xuICAgIHBhZGRpbmctYm90dG9tOiAwLjhyZW07XG4gICAgdHJhbnNpdGlvbjogb3BhY2l0eSAwLjI1cztcblxuICAgIC8vIFt0YWJsZXQgK106IFNldCBwcm9wb3J0aW9uYWwgd2lkdGhcbiAgICBAaW5jbHVkZSBicmVhay1mcm9tLWRldmljZSh0YWJsZXQpIHtcbiAgICAgIHdpZHRoOiA1MCU7XG4gICAgfVxuXG4gICAgLy8gSG92ZXJlZCBsaW5rXG4gICAgJjpob3ZlciB7XG4gICAgICBvcGFjaXR5OiAwLjc7XG4gICAgfVxuXG4gICAgLy8gTGluayB0byBwcmV2aW91cyBwYWdlXG4gICAgJi0tcHJldiB7XG4gICAgICB3aWR0aDogMjUlO1xuICAgICAgZmxvYXQ6IGxlZnQ7XG5cbiAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgICAgZmxvYXQ6IHJpZ2h0O1xuICAgICAgfVxuXG4gICAgICAvLyBUaXRsZVxuICAgICAgLm1kLWZvb3Rlci1uYXZfX3RpdGxlIHtcblxuICAgICAgICAvLyBbbW9iaWxlIC1dOiBIaWRlIHRpdGxlIGZvciBwcmV2aW91cyBwYWdlXG4gICAgICAgIEBpbmNsdWRlIGJyZWFrLXRvLWRldmljZShtb2JpbGUpIHtcbiAgICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gTGluayB0byBuZXh0IHBhZ2VcbiAgICAmLS1uZXh0IHtcbiAgICAgIHdpZHRoOiA3NSU7XG4gICAgICBmbG9hdDogcmlnaHQ7XG4gICAgICB0ZXh0LWFsaWduOiByaWdodDtcblxuICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICBmbG9hdDogbGVmdDtcbiAgICAgICAgdGV4dC1hbGlnbjogbGVmdDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBJY29uIGJ1dHRvbnNcbiAgJl9fYnV0dG9uIHtcbiAgICBAZXh0ZW5kICVtZC1pY29uX19idXR0b247XG5cbiAgICB0cmFuc2l0aW9uOiBiYWNrZ3JvdW5kIDAuMjVzO1xuICB9XG5cbiAgLy8gTGluayB0aXRsZSAtIHNldCBsaW5lIGhlaWdodCB0byBtYXRjaCBpY29uIGZvciBjb3JyZWN0IGFsaWdubWVudFxuICAmX190aXRsZSB7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHBhZGRpbmc6IDAgMnJlbTtcbiAgICBmb250LXNpemU6IDEuOHJlbTtcbiAgICBsaW5lLWhlaWdodDogNC44cmVtO1xuICB9XG5cbiAgLy8gTGluayBkaXJlY3Rpb25cbiAgJl9fZGlyZWN0aW9uIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgcmlnaHQ6IDA7XG4gICAgbGVmdDogMDtcbiAgICBtYXJnaW4tdG9wOiAtMnJlbTtcbiAgICBwYWRkaW5nOiAwIDJyZW07XG4gICAgY29sb3I6ICRtZC1jb2xvci13aGl0ZS0tbGlnaHQ7XG4gICAgZm9udC1zaXplOiAxLjVyZW07XG4gIH1cbn1cblxuLy8gTm9uLW5hdmlnYXRpb25hbCBpbmZvcm1hdGlvblxuLm1kLWZvb3Rlci1tZXRhIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogb3BhY2lmeSgkbWQtY29sb3ItYmxhY2ssIDAuMDI1KTtcblxuICAvLyBTZXQgc3BhY2luZ1xuICAmX19pbm5lciB7XG4gICAgcGFkZGluZzogMC40cmVtO1xuICAgIG92ZXJmbG93OiBhdXRvO1xuICB9XG5cbiAgLy8gVXNlIGEgZGVjZW50IGNvbG9yIGZvciBub24taG92ZXJlZCBsaW5rcyBhbmQgZW5zdXJlIHNwZWNpZmljaXR5XG4gIGh0bWwgJi5tZC10eXBlc2V0IGEge1xuICAgIGNvbG9yOiAkbWQtY29sb3Itd2hpdGUtLWxpZ2h0O1xuXG4gICAgLy8gRm9jdXNlZCBvciBob3ZlcmVkIGxpbmtcbiAgICAmOmZvY3VzLFxuICAgICY6aG92ZXIge1xuICAgICAgY29sb3I6ICRtZC1jb2xvci13aGl0ZTtcbiAgICB9XG4gIH1cbn1cblxuLy8gQ29weXJpZ2h0IGFuZCB0aGVtZSBpbmZvcm1hdGlvblxuLm1kLWZvb3Rlci1jb3B5cmlnaHQge1xuICBtYXJnaW46IDAgMS4ycmVtO1xuICBwYWRkaW5nOiAwLjhyZW0gMDtcbiAgY29sb3I6ICRtZC1jb2xvci13aGl0ZS0tbGlnaHRlcjtcbiAgZm9udC1zaXplOiBtcygtMSk7XG5cbiAgLy8gW3RhYmxldCBwb3J0cmFpdCArXTogU2hvdyBuZXh0IHRvIHNvY2lhbCBtZWRpYSBsaW5rc1xuICBAaW5jbHVkZSBicmVhay1mcm9tLWRldmljZSh0YWJsZXQgcG9ydHJhaXQpIHtcbiAgICBtYXgtd2lkdGg6IDc1JTtcbiAgICBmbG9hdDogbGVmdDtcblxuICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICBmbG9hdDogcmlnaHQ7XG4gICAgfVxuICB9XG5cbiAgLy8gSGlnaGxpZ2h0IGNvcHlyaWdodCBpbmZvcm1hdGlvblxuICAmX19oaWdobGlnaHQge1xuICAgIGNvbG9yOiAkbWQtY29sb3Itd2hpdGUtLWxpZ2h0O1xuICB9XG59XG5cbi8vIFNvY2lhbCBtZWRpYSBsaW5rc1xuLm1kLWZvb3Rlci1zb2NpYWwge1xuICBtYXJnaW46IDAgMC44cmVtO1xuICBwYWRkaW5nOiAwLjRyZW0gMCAxLjJyZW07XG5cbiAgLy8gW3RhYmxldCBwb3J0cmFpdCArXTogU2hvdyBuZXh0IHRvIGNvcHlyaWdodCBpbmZvcm1hdGlvblxuICBAaW5jbHVkZSBicmVhay1mcm9tLWRldmljZSh0YWJsZXQgcG9ydHJhaXQpIHtcbiAgICBwYWRkaW5nOiAxLjJyZW0gMDtcbiAgICBmbG9hdDogcmlnaHQ7XG5cbiAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgZmxvYXQ6IGxlZnQ7XG4gICAgfVxuICB9XG5cbiAgLy8gTGluayB3aXRoIGljb25cbiAgJl9fbGluayB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIHdpZHRoOiAzLjJyZW07XG4gICAgaGVpZ2h0OiAzLjJyZW07XG4gICAgZm9udC1zaXplOiAxLjZyZW07XG4gICAgdGV4dC1hbGlnbjogY2VudGVyO1xuXG4gICAgLy8gQWRqdXN0IGxpbmUtaGVpZ2h0IHRvIG1hdGNoIGhlaWdodCBmb3IgY29ycmVjdCBhbGlnbm1lbnRcbiAgICAmOjpiZWZvcmUge1xuICAgICAgbGluZS1oZWlnaHQ6IDEuOTtcbiAgICB9XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvbGF5b3V0L19mb290ZXIuc2NzcyIsIi8vLy9cbi8vLyBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4vLy9cbi8vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSxcbi8vLyB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uXG4vLy8gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsXG4vLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlXG4vLy8gU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vL1xuLy8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vLy9cbi8vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMXG4vLy8gVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuLy8vIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVJcbi8vLyBERUFMSU5HU1xuLy8vL1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBSdWxlc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBOYXZpZ2F0aW9uIGNvbnRhaW5lclxuLm1kLW5hdiB7XG4gIGZvbnQtc2l6ZTogMS40cmVtO1xuICBsaW5lLWhlaWdodDogMS4zO1xuXG4gIC8vIExpc3QgdGl0bGVcbiAgJl9fdGl0bGUge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIHBhZGRpbmc6IDAgMS4ycmVtO1xuICAgIGZvbnQtd2VpZ2h0OiA3MDA7XG4gICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcblxuICAgIC8vIEljb24sIGhpZGRlbiBieSBkZWZhdWx0XG4gICAgJjo6YmVmb3JlIHtcbiAgICAgIEBleHRlbmQgJW1kLWljb24sICVtZC1pY29uX19idXR0b247XG5cbiAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgICBjb250ZW50OiBcIlxcRTVDNFwiOyAvLyBhcnJvd19iYWNrXG5cbiAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgICAgY29udGVudDogXCJcXEU1QzhcIjsgLy8gYXJyb3dfZm9yd2FyZFxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEhpZGUgYnV0dG9uIGJ5IGRlZmF1bHRcbiAgICAubWQtbmF2X19idXR0b24ge1xuICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG4gIH1cblxuICAvLyBMaXN0IG9mIGl0ZW1zXG4gICZfX2xpc3Qge1xuICAgIG1hcmdpbjogMDtcbiAgICBwYWRkaW5nOiAwO1xuICAgIGxpc3Qtc3R5bGU6IG5vbmU7XG4gIH1cblxuICAvLyBMaXN0IGl0ZW1cbiAgJl9faXRlbSB7XG4gICAgcGFkZGluZzogMCAxLjJyZW07XG5cbiAgICAvLyBBZGQgYm90dG9tIHNwYWNpbmcgdG8gbGFzdCBpdGVtXG4gICAgJjpsYXN0LWNoaWxkIHtcbiAgICAgIHBhZGRpbmctYm90dG9tOiAxLjJyZW07XG4gICAgfVxuXG4gICAgLy8gMm5kKyBsZXZlbCBpdGVtc1xuICAgICYgJiB7XG4gICAgICBwYWRkaW5nLXJpZ2h0OiAwO1xuXG4gICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICAgIHBhZGRpbmctcmlnaHQ6IDEuMnJlbTtcbiAgICAgICAgcGFkZGluZy1sZWZ0OiAwO1xuICAgICAgfVxuXG4gICAgICAvLyBSZW1vdmUgYm90dG9tIHNwYWNpbmcgZm9yIG5lc3RlZCBpdGVtc1xuICAgICAgJjpsYXN0LWNoaWxkIHtcbiAgICAgICAgcGFkZGluZy1ib3R0b206IDA7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gQnV0dG9uIHdpdGggbG9nb1xuICAmX19idXR0b24ge1xuICAgIEBleHRlbmQgJW1kLWljb24sICVtZC1pY29uX19idXR0b247XG5cbiAgICAvLyBTdHJldGNoIGltYWdlXG4gICAgaW1nIHtcbiAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgaGVpZ2h0OiBhdXRvO1xuICAgIH1cbiAgfVxuXG4gIC8vIExpbmsgaW5zaWRlIGl0ZW1cbiAgJl9fbGluayB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgbWFyZ2luLXRvcDogMC42MjVlbTtcbiAgICB0cmFuc2l0aW9uOiBjb2xvciAwLjEyNXM7XG4gICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG5cbiAgICAvLyBJY29uXG4gICAgJjo6YWZ0ZXIge1xuICAgICAgQGV4dGVuZCAlbWQtaWNvbjtcblxuICAgICAgLy8gSXRlbSBjb250YWlucyBhIG5lc3RlZCBsaXN0XG4gICAgICAubWQtbmF2X19pdGVtLS1uZXN0ZWQgPiAmIHtcbiAgICAgICAgY29udGVudDogXCJcXEUzMTNcIjsgLy8ga2V5Ym9hcmRfYXJyb3dfZG93blxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEhpZGUgbGluayB0byB0YWJsZSBvZiBjb250ZW50cyBieSBkZWZhdWx0IC0gdGhpcyB3aWxsIG9ubHkgbWF0Y2ggdGhlXG4gICAgLy8gdGFibGUgb2YgY29udGVudHMgaW5zaWRlIHRoZSBkcmF3ZXIgYmVsb3cgYW5kIGluY2x1ZGluZyB0YWJsZXQgcG9ydHJhaXRcbiAgICBodG1sICZbZm9yPVwiX190b2NcIl0ge1xuICAgICAgZGlzcGxheTogbm9uZTtcblxuICAgICAgLy8gSGlkZSB0YWJsZSBvZiBjb250ZW50cyBieSBkZWZhdWx0XG4gICAgICAmIH4gLm1kLW5hdiB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgICB9XG5cbiAgICAgIC8vIEhpZGUgaWNvbiBmb3IgY3VycmVudCBpdGVtXG4gICAgICArIC5tZC1uYXZfX2xpbms6OmFmdGVyIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBCbHVycmVkIGxpbmtcbiAgICAmW2RhdGEtbWQtc3RhdGU9XCJibHVyXCJdIHtcbiAgICAgIGNvbG9yOiAkbWQtY29sb3ItYmxhY2stLWxpZ2h0O1xuICAgIH1cblxuICAgIC8vIEFjdGl2ZSBsaW5rXG4gICAgJjphY3RpdmUsXG4gICAgJi0tYWN0aXZlIHtcbiAgICAgIGNvbG9yOiAkbWQtY29sb3ItcHJpbWFyeTtcbiAgICB9XG5cbiAgICAvLyBSZXNldCBhY3RpdmUgY29sb3IgZm9yIG5lc3RlZCBsaXN0IHRpdGxlc1xuICAgIC5tZC1uYXZfX2l0ZW0tLW5lc3RlZCA+ICYge1xuICAgICAgY29sb3I6IGluaGVyaXQ7XG4gICAgfVxuXG4gICAgLy8gRm9jdXNlZCBvciBob3ZlcmVkIGxpbmtcbiAgICAmOmZvY3VzLFxuICAgICY6aG92ZXIge1xuICAgICAgY29sb3I6ICRtZC1jb2xvci1hY2NlbnQ7XG4gICAgfVxuICB9XG5cbiAgLy8gUmVwb3NpdG9yeSBjb250YWluaW5nIHNvdXJjZVxuICAmX19zb3VyY2Uge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1cblxuICAvLyBbdGFibGV0IC1dOiBMYXllcmVkIG5hdmlnYXRpb25cbiAgQGluY2x1ZGUgYnJlYWstdG8tZGV2aWNlKHRhYmxldCkge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2xvci13aGl0ZTtcblxuICAgIC8vIFN0cmV0Y2ggcHJpbWFyeSBuYXZpZ2F0aW9uIHRvIGRyYXdlclxuICAgICYtLXByaW1hcnksXG4gICAgJi0tcHJpbWFyeSAubWQtbmF2IHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICB0b3A6IDA7XG4gICAgICByaWdodDogMDtcbiAgICAgIGxlZnQ6IDA7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgei1pbmRleDogMTtcbiAgICB9XG5cbiAgICAvLyBBZGp1c3Qgc3R5bGVzIGZvciBwcmltYXJ5IG5hdmlnYXRpb25cbiAgICAmLS1wcmltYXJ5IHtcblxuICAgICAgLy8gTGlzdCB0aXRsZSBhbmQgaXRlbVxuICAgICAgLm1kLW5hdl9fdGl0bGUsXG4gICAgICAubWQtbmF2X19pdGVtIHtcbiAgICAgICAgZm9udC1zaXplOiAxLjZyZW07XG4gICAgICAgIGxpbmUtaGVpZ2h0OiAxLjU7XG4gICAgICB9XG5cbiAgICAgIC8vIExpc3QgdGl0bGUgLSBoaWdoZXIgc3BlY2lmaWNpdHkgaXMgbmVjZXNzYXJ5IHRvIGVuc3VyZSB0aGF0IHRoZSB0aXRsZVxuICAgICAgLy8gaW5zaWRlIHRoZSBkcmF3ZXIgaXMgYWx3YXlzIHN0eWxlZCBhY2NvcmRpbmdseVxuICAgICAgaHRtbCAmIC5tZC1uYXZfX3RpdGxlIHtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICBoZWlnaHQ6IDExLjJyZW07XG4gICAgICAgIHBhZGRpbmc6IDZyZW0gMS42cmVtIDAuNHJlbTtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogJG1kLWNvbG9yLWJsYWNrLS1saWdodGVzdDtcbiAgICAgICAgY29sb3I6ICRtZC1jb2xvci1ibGFjay0tbGlnaHQ7XG4gICAgICAgIGZvbnQtd2VpZ2h0OiA0MDA7XG4gICAgICAgIGxpbmUtaGVpZ2h0OiA0LjhyZW07XG4gICAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgICAgIGN1cnNvcjogcG9pbnRlcjtcblxuICAgICAgICAvLyBJY29uXG4gICAgICAgICY6OmJlZm9yZSB7XG4gICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICAgIHRvcDogMC40cmVtO1xuICAgICAgICAgIGxlZnQ6IDAuNHJlbTtcbiAgICAgICAgICB3aWR0aDogNHJlbTtcbiAgICAgICAgICBoZWlnaHQ6IDRyZW07XG4gICAgICAgICAgY29sb3I6ICRtZC1jb2xvci1ibGFjay0tbGlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBNYWluIGxpc3RzXG4gICAgICAgIH4gLm1kLW5hdl9fbGlzdCB7XG4gICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogJG1kLWNvbG9yLXdoaXRlO1xuICAgICAgICAgIGJveC1zaGFkb3c6IDAgMC4xcmVtIDAgJG1kLWNvbG9yLWJsYWNrLS1saWdodGVzdCBpbnNldDtcblxuICAgICAgICAgIC8vIFJlbW92ZSBib3JkZXIgZm9yIGZpcnN0IGxpc3QgaXRlbVxuICAgICAgICAgICYgPiAubWQtbmF2X19pdGVtOmZpcnN0LWNoaWxkIHtcbiAgICAgICAgICAgIGJvcmRlci10b3A6IDA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2l0ZSB0aXRsZSBpbiBtYWluIG5hdmlnYXRpb25cbiAgICAgICAgJi0tc2l0ZSB7XG4gICAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2xvci1wcmltYXJ5O1xuICAgICAgICAgIGNvbG9yOiAkbWQtY29sb3Itd2hpdGU7XG5cbiAgICAgICAgICAvLyBTaXRlIGxvZ29cbiAgICAgICAgICAubWQtbmF2X19idXR0b24ge1xuICAgICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgICB0b3A6IDAuNHJlbTtcbiAgICAgICAgICAgIGxlZnQ6IDAuNHJlbTtcbiAgICAgICAgICAgIHdpZHRoOiA2LjRyZW07XG4gICAgICAgICAgICBoZWlnaHQ6IDYuNHJlbTtcbiAgICAgICAgICAgIGZvbnQtc2l6ZTogNC44cmVtO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIEhpZGUgYmFjayBhcnJvdyBpY29uXG4gICAgICAgICAgJjo6YmVmb3JlIHtcbiAgICAgICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgaHRtbCBbZGlyPVwicnRsXCJdICYgLm1kLW5hdl9fdGl0bGUge1xuXG4gICAgICAgIC8vIEljb25cbiAgICAgICAgJjo6YmVmb3JlIHtcbiAgICAgICAgICByaWdodDogMC40cmVtO1xuICAgICAgICAgIGxlZnQ6IGluaXRpYWw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTaXRlIHRpdGxlIGluIG1haW4gbmF2aWdhdGlvblxuICAgICAgICAmLS1zaXRlIC5tZC1uYXZfX2J1dHRvbiB7XG4gICAgICAgICAgcmlnaHQ6IDAuNHJlbTtcbiAgICAgICAgICBsZWZ0OiBpbml0aWFsO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIExpc3Qgb2YgaXRlbXNcbiAgICAgIC5tZC1uYXZfX2xpc3Qge1xuICAgICAgICBmbGV4OiAxO1xuICAgICAgICBvdmVyZmxvdy15OiBhdXRvO1xuICAgICAgfVxuXG4gICAgICAvLyBMaXN0IGl0ZW1cbiAgICAgIC5tZC1uYXZfX2l0ZW0ge1xuICAgICAgICBwYWRkaW5nOiAwO1xuICAgICAgICBib3JkZXItdG9wOiAwLjFyZW0gc29saWQgJG1kLWNvbG9yLWJsYWNrLS1saWdodGVzdDtcblxuICAgICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgICAgICBwYWRkaW5nOiAwO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSW5jcmVhc2Ugc3BhY2luZyB0byBhY2NvdW50IGZvciBpY29uXG4gICAgICAgICYtLW5lc3RlZCA+IC5tZC1uYXZfX2xpbmsge1xuICAgICAgICAgIHBhZGRpbmctcmlnaHQ6IDQuOHJlbTtcblxuICAgICAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICAgICAgICBwYWRkaW5nLXJpZ2h0OiAxLjZyZW07XG4gICAgICAgICAgICBwYWRkaW5nLWxlZnQ6IDQuOHJlbTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBSZXBsYWNlIGljb24gd2l0aCByaWdodCBhcnJvd1xuICAgICAgICAgICY6OmFmdGVyIHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFwiXFxFMzE1XCI7IC8vIGtleWJvYXJkX2Fycm93X3JpZ2h0XG5cbiAgICAgICAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgICAgICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgICAgICAgICAgY29udGVudDogXCJcXEUzMTRcIjsgLy8ga2V5Ym9hcmRfYXJyb3dfbGVmdFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBMaW5rIGluc2lkZSBpdGVtXG4gICAgICAubWQtbmF2X19saW5rIHtcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgICAgICBtYXJnaW4tdG9wOiAwO1xuICAgICAgICBwYWRkaW5nOiAxLjJyZW0gMS42cmVtO1xuXG4gICAgICAgIC8vIFJvdGF0ZSBpY29uXG4gICAgICAgICY6OmFmdGVyIHtcbiAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgdG9wOiA1MCU7XG4gICAgICAgICAgcmlnaHQ6IDEuMnJlbTtcbiAgICAgICAgICBtYXJnaW4tdG9wOiAtMS4ycmVtO1xuICAgICAgICAgIGNvbG9yOiBpbmhlcml0O1xuICAgICAgICAgIGZvbnQtc2l6ZTogMi40cmVtO1xuXG4gICAgICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICAgICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgICAgICAgIHJpZ2h0OiBpbml0aWFsO1xuICAgICAgICAgICAgbGVmdDogMS4ycmVtO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBUYWJsZSBvZiBjb250ZW50cyBpbnNpZGUgbmF2aWdhdGlvblxuICAgICAgLm1kLW5hdi0tc2Vjb25kYXJ5IHtcblxuICAgICAgICAvLyBTZXQgbGlua3MgdG8gc3RhdGljIHRvIGF2b2lkIHVubmVjZXNzYXJ5IGxheWVyaW5nXG4gICAgICAgIC5tZC1uYXZfX2xpbmsge1xuICAgICAgICAgIHBvc2l0aW9uOiBzdGF0aWM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgbmVzdGVkIG5hdmlnYXRpb24gZm9yIHRhYmxlIG9mIGNvbnRlbnRzIHRvIHN0YXRpY1xuICAgICAgICAubWQtbmF2IHtcbiAgICAgICAgICBwb3NpdGlvbjogc3RhdGljO1xuICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xuXG4gICAgICAgICAgLy8gM3JkIGxldmVsIGxpbmtcbiAgICAgICAgICAubWQtbmF2X19saW5rIHtcbiAgICAgICAgICAgIHBhZGRpbmctbGVmdDogMi44cmVtO1xuXG4gICAgICAgICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgICAgICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICAgICAgICAgIHBhZGRpbmctcmlnaHQ6IDIuOHJlbTtcbiAgICAgICAgICAgICAgcGFkZGluZy1sZWZ0OiBpbml0aWFsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIDR0aCBsZXZlbCBsaW5rXG4gICAgICAgICAgLm1kLW5hdiAubWQtbmF2X19saW5rIHtcbiAgICAgICAgICAgIHBhZGRpbmctbGVmdDogNHJlbTtcblxuICAgICAgICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICAgICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICAgICAgICBwYWRkaW5nLXJpZ2h0OiA0cmVtO1xuICAgICAgICAgICAgICBwYWRkaW5nLWxlZnQ6IGluaXRpYWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gNXRoIGxldmVsIGxpbmtcbiAgICAgICAgICAubWQtbmF2IC5tZC1uYXYgLm1kLW5hdl9fbGluayB7XG4gICAgICAgICAgICBwYWRkaW5nLWxlZnQ6IDUuMnJlbTtcblxuICAgICAgICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICAgICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICAgICAgICBwYWRkaW5nLXJpZ2h0OiA1LjJyZW07XG4gICAgICAgICAgICAgIHBhZGRpbmctbGVmdDogaW5pdGlhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyA2dGggbGV2ZWwgbGlua1xuICAgICAgICAgIC5tZC1uYXYgLm1kLW5hdiAubWQtbmF2IC5tZC1uYXZfX2xpbmsge1xuICAgICAgICAgICAgcGFkZGluZy1sZWZ0OiA2LjRyZW07XG5cbiAgICAgICAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgICAgICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgICAgICAgICAgcGFkZGluZy1yaWdodDogNi40cmVtO1xuICAgICAgICAgICAgICBwYWRkaW5nLWxlZnQ6IGluaXRpYWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSGlkZSBuZXN0ZWQgbmF2aWdhdGlvbiBieSBkZWZhdWx0XG4gICAgLm1kLW5hdl9fdG9nZ2xlIH4gJiB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDEwMCUpO1xuICAgICAgdHJhbnNpdGlvbjpcbiAgICAgICAgdHJhbnNmb3JtIDAuMjVzIGN1YmljLWJlemllcigwLjgsIDAsIDAuNiwgMSksXG4gICAgICAgIG9wYWNpdHkgICAwLjEyNXMgMC4wNXM7XG4gICAgICBvcGFjaXR5OiAwO1xuXG4gICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtMTAwJSk7XG4gICAgICB9XG5cbiAgICAgIC8vIEp1c3QgaGlkZSBuYXZpZ2F0aW9uLCBpZiBicm93c2VyIGRvZXNuJ3Qgc3VwcG9ydHMgM0QgdHJhbnNmb3Jtc1xuICAgICAgLm5vLWNzc3RyYW5zZm9ybXMzZCAmIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBFeHBhbmQgbmVzdGVkIG5hdmlnYXRpb24sIGlmIHRvZ2dsZSBpcyBjaGVja2VkXG4gICAgLm1kLW5hdl9fdG9nZ2xlOmNoZWNrZWQgfiAmIHtcbiAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgwKTtcbiAgICAgIHRyYW5zaXRpb246XG4gICAgICAgIHRyYW5zZm9ybSAwLjI1cyBjdWJpYy1iZXppZXIoMC40LCAwLCAwLjIsIDEpLFxuICAgICAgICBvcGFjaXR5ICAgMC4xMjVzIDAuMTI1cztcbiAgICAgIG9wYWNpdHk6IDE7XG5cbiAgICAgIC8vIEp1c3Qgc2hvdyBuYXZpZ2F0aW9uLCBpZiBicm93c2VyIGRvZXNuJ3Qgc3VwcG9ydHMgM0QgdHJhbnNmb3Jtc1xuICAgICAgLm5vLWNzc3RyYW5zZm9ybXMzZCAmIHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBbdGFibGV0IHBvcnRyYWl0IC1dOiBTaG93IHRhYmxlIG9mIGNvbnRlbnRzIGluIGRyYXdlclxuICBAaW5jbHVkZSBicmVhay10by1kZXZpY2UodGFibGV0IHBvcnRyYWl0KSB7XG5cbiAgICAvLyBTaG93IGxpbmsgdG8gdGFibGUgb2YgY29udGVudHMgLSBoaWdoZXIgc3BlY2lmaWNpdHkgaXMgbmVjZXNzYXJ5IHRvXG4gICAgLy8gZGlzcGxheSB0aGUgdGFibGUgb2YgY29udGVudHMgaW5zaWRlIHRoZSBkcmF3ZXJcbiAgICBodG1sICZfX2xpbmtbZm9yPVwiX190b2NcIl0ge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICBwYWRkaW5nLXJpZ2h0OiA0LjhyZW07XG5cbiAgICAgIC8vIFVucm90YXRlIGljb24gZm9yIHRhYmxlIG9mIGNvbnRlbnRzXG4gICAgICAmOjphZnRlciB7XG4gICAgICAgIGNvbG9yOiBpbmhlcml0O1xuICAgICAgICBjb250ZW50OiBcIlxcRThERVwiOyAvLyB0b2NcbiAgICAgIH1cblxuICAgICAgLy8gSGlkZSBsaW5rIHRvIGN1cnJlbnQgaXRlbVxuICAgICAgKyAubWQtbmF2X19saW5rIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICAgIH1cblxuICAgICAgLy8gU2hvdyB0YWJsZSBvZiBjb250ZW50c1xuICAgICAgJiB+IC5tZC1uYXYge1xuICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgIGh0bWwgW2Rpcj1cInJ0bFwiXSAmX19saW5rIHtcbiAgICAgIHBhZGRpbmctcmlnaHQ6IDEuNnJlbTtcbiAgICAgIHBhZGRpbmctbGVmdDogNC44cmVtO1xuICAgIH1cblxuICAgIC8vIFJlcG9zaXRvcnkgY29udGFpbmluZyBzb3VyY2VcbiAgICAmX19zb3VyY2Uge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICBwYWRkaW5nOiAwIDAuNHJlbTtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IG1peCgkbWQtY29sb3ItcHJpbWFyeSwgJG1kLWNvbG9yLWJsYWNrLCA3NSUpO1xuICAgICAgY29sb3I6ICRtZC1jb2xvci13aGl0ZTtcbiAgICB9XG4gIH1cblxuICAvLyBbc2NyZWVuICtdOiBUcmVlLWxpa2UgbmF2aWdhdGlvblxuICBAaW5jbHVkZSBicmVhay1mcm9tLWRldmljZShzY3JlZW4pIHtcblxuICAgIC8vIEFuaW1hdGlvbiBpcyBvbmx5IHBvc3NpYmxlIGlmIEphdmFTY3JpcHQgaXMgYXZhaWxhYmxlLCBhcyB0aGUgbWF4LWhlaWdodFxuICAgIC8vIHByb3BlcnR5IG11c3QgYmUgY2FsY3VsYXRlZCBiZWZvcmUgdHJhbnNpdGlvbmluZ1xuICAgICZbZGF0YS1tZC1zdGF0ZT1cImFuaW1hdGVcIl0ge1xuICAgICAgdHJhbnNpdGlvbjogbWF4LWhlaWdodCAwLjI1cyBjdWJpYy1iZXppZXIoMC44NiwgMCwgMC4wNywgMSk7XG4gICAgfVxuXG4gICAgLy8gSGlkZSBuZXN0ZWQgbmF2aWdhdGlvbiBieSBkZWZhdWx0XG4gICAgLm1kLW5hdl9fdG9nZ2xlIH4gJiB7XG4gICAgICBtYXgtaGVpZ2h0OiAwO1xuICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcblxuICAgICAgLy8gSnVzdCBoaWRlIGxpbmtzIGZvciBhY2Nlc3NpYmlsaXR5IGlmIEphdmFTY3JpcHQgaXMgbm90IGF2YWlsYWJsZVxuICAgICAgLm5vLWpzICYge1xuICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEV4cGFuZCBuZXN0ZWQgbmF2aWdhdGlvbiwgaWYgdG9nZ2xlIGlzIGNoZWNrZWRcbiAgICAubWQtbmF2X190b2dnbGU6Y2hlY2tlZCB+ICYsXG4gICAgJltkYXRhLW1kLXN0YXRlPVwiZXhwYW5kXCJdIHtcbiAgICAgIG1heC1oZWlnaHQ6IDEwMCU7XG5cbiAgICAgIC8vIEp1c3Qgc2hvdyBmb3IgYWNjZXNzaWJpbGl0eSBsaW5rcyBpZiBKYXZhU2NyaXB0IGlzIG5vdCBhdmFpbGFibGVcbiAgICAgIC5uby1qcyAmIHtcbiAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSGlkZSB0aXRsZXMgZm9yIG5lc3RlZCBuYXZpZ2F0aW9uXG4gICAgJl9faXRlbS0tbmVzdGVkID4gLm1kLW5hdiA+ICZfX3RpdGxlIHtcbiAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgfVxuXG4gICAgLy8gTGluayBpbnNpZGUgaXRlbSAtIGlkZWFsbHkgdGhlIGxpbmsgZGlzcGxheSBtZXRob2Qgd291bGQgYmUgc2V0IHRvXG4gICAgLy8gaW5saW5lIG9uIHNjcmVlbiwgYnV0IHRoaXMgZG9lc24ndCB3b3JrIHdpdGggdGV4dCBlbGxpcHNpc1xuICAgICZfX2xpbmsge1xuXG4gICAgICAvLyBJdGVtIGNvbnRhaW5zIGEgbmVzdGVkIGxpc3RcbiAgICAgIC5tZC1uYXZfX2l0ZW0tLW5lc3RlZCA+ICY6OmFmdGVyIHtcbiAgICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgICAgICB0cmFuc2Zvcm0tb3JpZ2luOiAwLjQ1ZW0gMC40NWVtO1xuICAgICAgICB0cmFuc2Zvcm0tc3R5bGU6IHByZXNlcnZlLTNkO1xuICAgICAgICB2ZXJ0aWNhbC1hbGlnbjogLTAuMTI1ZW07XG5cbiAgICAgICAgLy8gT25seSBhbmltYXRlIGljb24gd2hlbiBKYXZhU2NyaXB0IGlzIGF2YWlsYWJsZSwgYXMgdGhlIGhlaWdodCBjYW5cbiAgICAgICAgLy8gbm90IGJlIGFuaW1hdGVkIGFueXdheSwgYW5kIGJldHRlciBubyBmdW4gdGhhbiBoYWxmIHRoZSBmdW5cbiAgICAgICAgLmpzICYge1xuICAgICAgICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjRzO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFJvdGF0ZSBpY29uIGZvciBleHBhbmRlZCBsaXN0c1xuICAgICAgLm1kLW5hdl9faXRlbS0tbmVzdGVkIC5tZC1uYXZfX3RvZ2dsZTpjaGVja2VkIH4gJjo6YWZ0ZXIge1xuICAgICAgICB0cmFuc2Zvcm06IHJvdGF0ZVgoMTgwZGVnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvbGF5b3V0L19uYXYuc2NzcyIsIi8vLy9cbi8vLyBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4vLy9cbi8vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSxcbi8vLyB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uXG4vLy8gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsXG4vLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlXG4vLy8gU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vL1xuLy8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vLy9cbi8vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMXG4vLy8gVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuLy8vIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVJcbi8vLyBERUFMSU5HU1xuLy8vL1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBWYXJpYWJsZXNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gQWN0aXZlICh0b2dnbGVkKSBzZWFyY2hcbiRtZC10b2dnbGVfX3NlYXJjaC0tY2hlY2tlZDpcbiAgXCJbZGF0YS1tZC10b2dnbGU9XFxcInNlYXJjaFxcXCJdOmNoZWNrZWQgfiAubWQtaGVhZGVyXCI7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIFNlYXJjaCBjb250YWluZXJcbi5tZC1zZWFyY2gge1xuXG4gIC8vIEhpZGUgc2VhcmNoLCBpZiBKYXZhU2NyaXB0IGlzIG5vdCBhdmFpbGFibGUuXG4gIC5uby1qcyAmIHtcbiAgICBkaXNwbGF5OiBub25lO1xuICB9XG5cbiAgLy8gW3RhYmxldCBsYW5kc2NhcGUgK106IEhlYWRlci1lbWJlZGRlZCBzZWFyY2hcbiAgQGluY2x1ZGUgYnJlYWstZnJvbS1kZXZpY2UodGFibGV0IGxhbmRzY2FwZSkge1xuICAgIHBhZGRpbmc6IDAuNHJlbTtcbiAgfVxuXG4gIC8vIFNlYXJjaCBtb2RhbCBvdmVybGF5XG4gICZfX292ZXJsYXkge1xuICAgIG9wYWNpdHk6IDA7XG4gICAgei1pbmRleDogMTtcblxuICAgIC8vIFt0YWJsZXQgcG9ydHJhaXQgLV06IEZ1bGwtc2NyZWVuIHNlYXJjaCBiYXJcbiAgICBAaW5jbHVkZSBicmVhay10by1kZXZpY2UodGFibGV0IHBvcnRyYWl0KSB7XG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICB0b3A6IDAuNHJlbTtcbiAgICAgIGxlZnQ6IDAuNHJlbTtcbiAgICAgIHdpZHRoOiAzLjZyZW07XG4gICAgICBoZWlnaHQ6IDMuNnJlbTtcbiAgICAgIHRyYW5zZm9ybS1vcmlnaW46IGNlbnRlcjtcbiAgICAgIHRyYW5zaXRpb246XG4gICAgICAgIHRyYW5zZm9ybSAwLjNzIDAuMXMsXG4gICAgICAgIG9wYWNpdHkgICAwLjJzIDAuMnM7XG4gICAgICBib3JkZXItcmFkaXVzOiAycmVtO1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogJG1kLWNvbG9yLXdoaXRlO1xuICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuXG4gICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICAgIHJpZ2h0OiAwLjRyZW07XG4gICAgICAgIGxlZnQ6IGluaXRpYWw7XG4gICAgICB9XG5cbiAgICAgIC8vIEV4cGFuZGVkIG92ZXJsYXlcbiAgICAgICN7JG1kLXRvZ2dsZV9fc2VhcmNoLS1jaGVja2VkfSAmIHtcbiAgICAgICAgdHJhbnNpdGlvbjpcbiAgICAgICAgICB0cmFuc2Zvcm0gMC40cyxcbiAgICAgICAgICBvcGFjaXR5ICAgMC4xcztcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTZXQgc2NhbGUgZmFjdG9yc1xuICAgICN7JG1kLXRvZ2dsZV9fc2VhcmNoLS1jaGVja2VkfSAmIHtcblxuICAgICAgLy8gW21vYmlsZSBwb3J0cmFpdCAtXTogU2NhbGUgdXAgNDUgdGltZXNcbiAgICAgIEBpbmNsdWRlIGJyZWFrLXRvLWRldmljZShtb2JpbGUgcG9ydHJhaXQpIHtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZSg0NSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFttb2JpbGUgbGFuZHNjYXBlXTogU2NhbGUgdXAgNjAgdGltZXNcbiAgICAgIEBpbmNsdWRlIGJyZWFrLWF0LWRldmljZShtb2JpbGUgbGFuZHNjYXBlKSB7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGUoNjApO1xuICAgICAgfVxuXG4gICAgICAvLyBbdGFibGV0IHBvcnRyYWl0XTogU2NhbGUgdXAgNzUgdGltZXNcbiAgICAgIEBpbmNsdWRlIGJyZWFrLWF0LWRldmljZSh0YWJsZXQgcG9ydHJhaXQpIHtcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZSg3NSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gW3RhYmxldCBsYW5kc2NhcGUgK106IE92ZXJsYXkgZm9yIGJldHRlciBmb2N1cyBvbiBzZWFyY2hcbiAgICBAaW5jbHVkZSBicmVhay1mcm9tLWRldmljZSh0YWJsZXQgbGFuZHNjYXBlKSB7XG4gICAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgICB0b3A6IDA7XG4gICAgICBsZWZ0OiAwO1xuICAgICAgd2lkdGg6IDA7XG4gICAgICBoZWlnaHQ6IDA7XG4gICAgICB0cmFuc2l0aW9uOlxuICAgICAgICB3aWR0aCAgIDBzIDAuMjVzLFxuICAgICAgICBoZWlnaHQgIDBzIDAuMjVzLFxuICAgICAgICBvcGFjaXR5IDAuMjVzO1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogJG1kLWNvbG9yLWJsYWNrLS1saWdodDtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcblxuICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICByaWdodDogMDtcbiAgICAgICAgbGVmdDogaW5pdGlhbDtcbiAgICAgIH1cblxuICAgICAgLy8gRXhwYW5kZWQgb3ZlcmxheVxuICAgICAgI3skbWQtdG9nZ2xlX19zZWFyY2gtLWNoZWNrZWR9ICYge1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICB0cmFuc2l0aW9uOlxuICAgICAgICAgIHdpZHRoICAgMHMsXG4gICAgICAgICAgaGVpZ2h0ICAwcyxcbiAgICAgICAgICBvcGFjaXR5IDAuMjVzO1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFNlYXJjaCBtb2RhbCB3cmFwcGVyXG4gICZfX2lubmVyIHtcblxuICAgIC8vIFt0YWJsZXQgcG9ydHJhaXQgLV06IFB1dCBzZWFyY2ggbW9kYWwgb2ZmLWNhbnZhcyBieSBkZWZhdWx0XG4gICAgQGluY2x1ZGUgYnJlYWstdG8tZGV2aWNlKHRhYmxldCBwb3J0cmFpdCkge1xuICAgICAgcG9zaXRpb246IGZpeGVkO1xuICAgICAgdG9wOiAwO1xuICAgICAgbGVmdDogMTAwJTtcbiAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDUlKTtcbiAgICAgIHRyYW5zaXRpb246XG4gICAgICAgIHJpZ2h0ICAgICAwcyAgICAwLjNzLFxuICAgICAgICBsZWZ0ICAgICAgMHMgICAgMC4zcyxcbiAgICAgICAgdHJhbnNmb3JtIDAuMTVzIDAuMTVzIGN1YmljLWJlemllcigwLjQsIDAsIDAuMiwgMSksXG4gICAgICAgIG9wYWNpdHkgICAwLjE1cyAwLjE1cztcbiAgICAgIG9wYWNpdHk6IDA7XG4gICAgICB6LWluZGV4OiAyO1xuXG4gICAgICAvLyBBY3RpdmUgc2VhcmNoIG1vZGFsXG4gICAgICAjeyRtZC10b2dnbGVfX3NlYXJjaC0tY2hlY2tlZH0gJiB7XG4gICAgICAgIGxlZnQ6IDA7XG4gICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgwKTtcbiAgICAgICAgdHJhbnNpdGlvbjpcbiAgICAgICAgICByaWdodCAgICAgMHMgICAgMHMsXG4gICAgICAgICAgbGVmdCAgICAgIDBzICAgIDBzLFxuICAgICAgICAgIHRyYW5zZm9ybSAwLjE1cyAwLjE1cyBjdWJpYy1iZXppZXIoMC4xLCAwLjcsIDAuMSwgMSksXG4gICAgICAgICAgb3BhY2l0eSAgIDAuMTVzIDAuMTVzO1xuICAgICAgICBvcGFjaXR5OiAxO1xuXG4gICAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICAgIHJpZ2h0OiAwO1xuICAgICAgICAgIGxlZnQ6IGluaXRpYWw7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICBodG1sIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICAgIHJpZ2h0OiAxMDAlO1xuICAgICAgICBsZWZ0OiBpbml0aWFsO1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTUlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBbdGFibGV0IGxhbmRzY2FwZSArXTogSGVhZGVyLWVtYmVkZGVkIHNlYXJjaFxuICAgIEBpbmNsdWRlIGJyZWFrLWZyb20tZGV2aWNlKHRhYmxldCBsYW5kc2NhcGUpIHtcbiAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgIHdpZHRoOiAyM3JlbTtcbiAgICAgIHBhZGRpbmc6IDAuMnJlbSAwO1xuICAgICAgZmxvYXQ6IHJpZ2h0O1xuICAgICAgdHJhbnNpdGlvbjogd2lkdGggMC4yNXMgY3ViaWMtYmV6aWVyKDAuMSwgMC43LCAwLjEsIDEpO1xuXG4gICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICAgIGZsb2F0OiBsZWZ0O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFNldCBtYXhpbXVtIHdpZHRoXG4gICAgI3skbWQtdG9nZ2xlX19zZWFyY2gtLWNoZWNrZWR9ICYge1xuXG4gICAgICAvLyBbdGFibGV0IGxhbmRzY2FwZV06IERvIG5vdCBvdmVybGF5IHRpdGxlXG4gICAgICBAaW5jbHVkZSBicmVhay1hdC1kZXZpY2UodGFibGV0IGxhbmRzY2FwZSkge1xuICAgICAgICB3aWR0aDogNDYuOHJlbTtcbiAgICAgIH1cblxuICAgICAgLy8gW3NjcmVlbiArXTogTWF0Y2ggY29udGVudCB3aWR0aFxuICAgICAgQGluY2x1ZGUgYnJlYWstZnJvbS1kZXZpY2Uoc2NyZWVuKSB7XG4gICAgICAgIHdpZHRoOiA2OC44cmVtO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFNlYXJjaCBmb3JtXG4gICZfX2Zvcm0ge1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcblxuICAgIC8vIFt0YWJsZXQgbGFuZHNjYXBlICtdOiBIZWFkZXItZW1iZWRkZWQgc2VhcmNoXG4gICAgQGluY2x1ZGUgYnJlYWstZnJvbS1kZXZpY2UodGFibGV0IGxhbmRzY2FwZSkge1xuICAgICAgYm9yZGVyLXJhZGl1czogMC4ycmVtO1xuICAgIH1cbiAgfVxuXG4gIC8vIFNlYXJjaCBpbnB1dFxuICAmX19pbnB1dCB7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHBhZGRpbmc6IDAgNC40cmVtIDAgNy4ycmVtO1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgIHotaW5kZXg6IDI7XG5cbiAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgcGFkZGluZzogMCA3LjJyZW0gMCA0LjRyZW07XG4gICAgfVxuXG4gICAgLy8gVHJhbnNpdGlvbiBvbiBwbGFjZWhvbGRlclxuICAgICY6OnBsYWNlaG9sZGVyIHtcbiAgICAgIHRyYW5zaXRpb246IGNvbG9yIDAuMjVzIGN1YmljLWJlemllcigwLjEsIDAuNywgMC4xLCAxKTtcbiAgICB9XG5cbiAgICAvLyBQbGFjZWhvbGRlciBhbmQgaWNvbiBjb2xvciBpbiBhY3RpdmUgc3RhdGVcbiAgICB+IC5tZC1zZWFyY2hfX2ljb24sXG4gICAgJjo6cGxhY2Vob2xkZXIge1xuICAgICAgY29sb3I6ICRtZC1jb2xvci1ibGFjay0tbGlnaHQ7XG4gICAgfVxuXG4gICAgLy8gUmVtb3ZlIHRoZSBcInhcIiByZW5kZXJlZCBieSBJbnRlcm5ldCBFeHBsb3JlclxuICAgICY6Oi1tcy1jbGVhciB7XG4gICAgICBkaXNwbGF5OiBub25lO1xuICAgIH1cblxuICAgIC8vIFt0YWJsZXQgcG9ydHJhaXQgLV06IEZ1bGwtc2NyZWVuIHNlYXJjaCBiYXJcbiAgICBAaW5jbHVkZSBicmVhay10by1kZXZpY2UodGFibGV0IHBvcnRyYWl0KSB7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIGhlaWdodDogNC44cmVtO1xuICAgICAgZm9udC1zaXplOiAxLjhyZW07XG4gICAgfVxuXG4gICAgLy8gW3RhYmxldCBsYW5kc2NhcGUgK106IEhlYWRlci1lbWJlZGRlZCBzZWFyY2hcbiAgICBAaW5jbHVkZSBicmVhay1mcm9tLWRldmljZSh0YWJsZXQgbGFuZHNjYXBlKSB7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIGhlaWdodDogMy42cmVtO1xuICAgICAgcGFkZGluZy1sZWZ0OiA0LjRyZW07XG4gICAgICB0cmFuc2l0aW9uOlxuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yIDAuMjVzIGN1YmljLWJlemllcigwLjEsIDAuNywgMC4xLCAxKSxcbiAgICAgICAgY29sb3IgICAgICAgICAgICAwLjI1cyBjdWJpYy1iZXppZXIoMC4xLCAwLjcsIDAuMSwgMSk7XG4gICAgICBib3JkZXItcmFkaXVzOiAwLjJyZW07XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQtY29sb3ItYmxhY2stLWxpZ2h0ZXI7XG4gICAgICBjb2xvcjogaW5oZXJpdDtcbiAgICAgIGZvbnQtc2l6ZTogbXMoMCk7XG5cbiAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgICAgcGFkZGluZy1yaWdodDogNC40cmVtO1xuICAgICAgfVxuXG4gICAgICAvLyBJY29uIGNvbG9yXG4gICAgICArIC5tZC1zZWFyY2hfX2ljb24ge1xuICAgICAgICBjb2xvcjogaW5oZXJpdDtcbiAgICAgIH1cblxuICAgICAgLy8gUGxhY2Vob2xkZXIgY29sb3JcbiAgICAgICY6OnBsYWNlaG9sZGVyIHtcbiAgICAgICAgY29sb3I6ICRtZC1jb2xvci13aGl0ZS0tbGlnaHQ7XG4gICAgICB9XG5cbiAgICAgIC8vIEhvdmVyZWQgc2VhcmNoIGZpZWxkXG4gICAgICAmOmhvdmVyIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogJG1kLWNvbG9yLXdoaXRlLS1saWdodGVzdDtcbiAgICAgIH1cblxuICAgICAgLy8gU2V0IGxpZ2h0IGJhY2tncm91bmQgb24gYWN0aXZlIHNlYXJjaCBmaWVsZFxuICAgICAgI3skbWQtdG9nZ2xlX19zZWFyY2gtLWNoZWNrZWR9ICYge1xuICAgICAgICBib3JkZXItcmFkaXVzOiAwLjJyZW0gMC4ycmVtIDAgMDtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogJG1kLWNvbG9yLXdoaXRlO1xuICAgICAgICBjb2xvcjogJG1kLWNvbG9yLWJsYWNrO1xuICAgICAgICB0ZXh0LW92ZXJmbG93OiBub25lO1xuXG4gICAgICAgIC8vIFBsYWNlaG9sZGVyIGFuZCBpY29uIGNvbG9yIGluIGFjdGl2ZSBzdGF0ZVxuICAgICAgICArIC5tZC1zZWFyY2hfX2ljb24sXG4gICAgICAgICY6OnBsYWNlaG9sZGVyIHtcbiAgICAgICAgICBjb2xvcjogJG1kLWNvbG9yLWJsYWNrLS1saWdodDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIEljb25zXG4gICZfX2ljb24ge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0cmFuc2l0aW9uOlxuICAgICAgY29sb3IgICAwLjI1cyBjdWJpYy1iZXppZXIoMC4xLCAwLjcsIDAuMSwgMSksXG4gICAgICBvcGFjaXR5IDAuMjVzO1xuICAgIGZvbnQtc2l6ZTogJG1kLWljb24tc2l6ZTtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgei1pbmRleDogMjtcblxuICAgIC8vIEhvdmVyZWQgaWNvblxuICAgICY6aG92ZXIge1xuICAgICAgb3BhY2l0eTogMC43O1xuICAgIH1cblxuICAgIC8vIFNlYXJjaCBpY29uXG4gICAgJltmb3I9XCJfX3NlYXJjaFwiXSB7XG4gICAgICB0b3A6IDAuNnJlbTtcbiAgICAgIGxlZnQ6IDFyZW07XG5cbiAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgICAgcmlnaHQ6IDFyZW07XG4gICAgICAgIGxlZnQ6IGluaXRpYWw7XG4gICAgICB9XG5cbiAgICAgIC8vIFNldCBzZWFyY2ggaWNvbiBvbiBwc2V1ZG8gY2xhc3MsIHNvIGl0IGNhbiBiZSBvdmVycmlkZGVuIGZvciBtb2JpbGVcbiAgICAgIC8vIGFuZCB0YWJsZXQgd2hlbiB0aGUgc2VhcmNoIGlzIHJlbmRlcmVkIGluIGFuIG92ZXJsYXlcbiAgICAgICY6OmJlZm9yZSB7XG4gICAgICAgIGNvbnRlbnQ6IFwiXFxFOEI2XCI7IC8vIHNlYXJjaFxuICAgICAgfVxuXG4gICAgICAvLyBbdGFibGV0IHBvcnRyYWl0IC1dOiBGdWxsLXNjcmVlbiBzZWFyY2ggYmFyXG4gICAgICBAaW5jbHVkZSBicmVhay10by1kZXZpY2UodGFibGV0IHBvcnRyYWl0KSB7XG4gICAgICAgIHRvcDogMS4ycmVtO1xuICAgICAgICBsZWZ0OiAxLjZyZW07XG5cbiAgICAgICAgLy8gU2hvdyBiYWNrIGFycm93IGluc3RlYWQgb2Ygc2VhcmNoIGljb25cbiAgICAgICAgJltmb3I9XCJfX3NlYXJjaFwiXTo6YmVmb3JlIHtcbiAgICAgICAgICBjb250ZW50OiBcIlxcRTVDNFwiOyAvLyBhcnJvd19iYWNrXG5cbiAgICAgICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICAgICAgY29udGVudDogXCJcXEU1QzhcIjsgLy8gYXJyb3dfZm9yd2FyZFxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJlc2V0IGJ1dHRvblxuICAgICZbdHlwZT1cInJlc2V0XCJdIHtcbiAgICAgIHRvcDogMC42cmVtO1xuICAgICAgcmlnaHQ6IDFyZW07XG4gICAgICB0cmFuc2Zvcm06IHNjYWxlKDAuMTI1KTtcbiAgICAgIHRyYW5zaXRpb246XG4gICAgICAgIHRyYW5zZm9ybSAwLjE1cyBjdWJpYy1iZXppZXIoMC4xLCAwLjcsIDAuMSwgMSksXG4gICAgICAgIG9wYWNpdHkgICAwLjE1cztcbiAgICAgIG9wYWNpdHk6IDA7XG5cbiAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgICAgcmlnaHQ6IGluaXRpYWw7XG4gICAgICAgIGxlZnQ6IDFyZW07XG4gICAgICB9XG5cbiAgICAgIC8vIFt0YWJsZXQgcG9ydHJhaXQgLV06IEZ1bGwtc2NyZWVuIHNlYXJjaCBiYXJcbiAgICAgIEBpbmNsdWRlIGJyZWFrLXRvLWRldmljZSh0YWJsZXQgcG9ydHJhaXQpIHtcbiAgICAgICAgdG9wOiAxLjJyZW07XG4gICAgICAgIHJpZ2h0OiAxLjZyZW07XG4gICAgICB9XG5cbiAgICAgIC8vIFNob3cgcmVzZXQgYnV0dG9uIGlmIHNlYXJjaCBpcyBhY3RpdmUgYW5kIGlucHV0IG5vbi1lbXB0eVxuICAgICAgI3skbWQtdG9nZ2xlX19zZWFyY2gtLWNoZWNrZWR9IC5tZC1zZWFyY2hfX2lucHV0OnZhbGlkIH4gJiB7XG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGUoMSk7XG4gICAgICAgIG9wYWNpdHk6IDE7XG5cbiAgICAgICAgLy8gSG92ZXJlZCBpY29uXG4gICAgICAgICY6aG92ZXIge1xuICAgICAgICAgIG9wYWNpdHk6IDAuNztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFNlYXJjaCBvdXRwdXQgY29udGFpbmVyXG4gICZfX291dHB1dCB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGJvcmRlci1yYWRpdXM6IDAgMCAwLjJyZW0gMC4ycmVtO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgei1pbmRleDogMTtcblxuICAgIC8vIFt0YWJsZXQgcG9ydHJhaXQgLV06IEZ1bGwtc2NyZWVuIHNlYXJjaCBiYXJcbiAgICBAaW5jbHVkZSBicmVhay10by1kZXZpY2UodGFibGV0IHBvcnRyYWl0KSB7XG4gICAgICB0b3A6IDQuOHJlbTtcbiAgICAgIGJvdHRvbTogMDtcbiAgICB9XG5cbiAgICAvLyBbdGFibGV0IGxhbmRzY2FwZSArXTogSGVhZGVyLWVtYmVkZGVkIHNlYXJjaFxuICAgIEBpbmNsdWRlIGJyZWFrLWZyb20tZGV2aWNlKHRhYmxldCBsYW5kc2NhcGUpIHtcbiAgICAgIHRvcDogMy44cmVtO1xuICAgICAgdHJhbnNpdGlvbjogb3BhY2l0eSAwLjRzO1xuICAgICAgb3BhY2l0eTogMDtcblxuICAgICAgLy8gU2hvdyBzZWFyY2ggb3V0cHV0IGluIGFjdGl2ZSBzdGF0ZVxuICAgICAgI3skbWQtdG9nZ2xlX19zZWFyY2gtLWNoZWNrZWR9ICYge1xuICAgICAgICBAaW5jbHVkZSB6LWRlcHRoKDYpO1xuXG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gV3JhcHBlciBmb3Igc2Nyb2xsaW5nIG9uIG92ZXJmbG93XG4gICZfX3Njcm9sbHdyYXAge1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQtY29sb3Itd2hpdGU7XG4gICAgYm94LXNoYWRvdzogMCAwLjFyZW0gMCAkbWQtY29sb3ItYmxhY2stLWxpZ2h0ZXN0IGluc2V0O1xuICAgIG92ZXJmbG93LXk6IGF1dG87XG4gICAgLXdlYmtpdC1vdmVyZmxvdy1zY3JvbGxpbmc6IHRvdWNoO1xuXG4gICAgLy8gW3RhYmxldCBsYW5kc2NhcGVdOiBTZXQgYWJzb2x1dGUgd2lkdGggdG8gb21pdCB1bm5lY2Vzc2FyeSByZWZsb3dcbiAgICBAaW5jbHVkZSBicmVhay1hdC1kZXZpY2UodGFibGV0IGxhbmRzY2FwZSkge1xuICAgICAgd2lkdGg6IDQ2LjhyZW07XG4gICAgfVxuXG4gICAgLy8gW3NjcmVlbiArXTogU2V0IGFic29sdXRlIHdpZHRoIHRvIG9taXQgdW5uZWNlc3NhcnkgcmVmbG93XG4gICAgQGluY2x1ZGUgYnJlYWstZnJvbS1kZXZpY2Uoc2NyZWVuKSB7XG4gICAgICB3aWR0aDogNjguOHJlbTtcbiAgICB9XG5cbiAgICAvLyBbdGFibGV0IGxhbmRzY2FwZSArXTogTGltaXQgaGVpZ2h0IHRvIHZpZXdwb3J0XG4gICAgQGluY2x1ZGUgYnJlYWstZnJvbS1kZXZpY2UodGFibGV0IGxhbmRzY2FwZSkge1xuICAgICAgbWF4LWhlaWdodDogMDtcblxuICAgICAgLy8gRXhwYW5kIGluIGFjdGl2ZSBzdGF0ZVxuICAgICAgI3skbWQtdG9nZ2xlX19zZWFyY2gtLWNoZWNrZWR9ICYge1xuICAgICAgICBtYXgtaGVpZ2h0OiA3NXZoO1xuICAgICAgfVxuXG4gICAgICAvLyBPdmVycmlkZSBuYXRpdmUgc2Nyb2xsYmFyIHN0eWxlc1xuICAgICAgJjo6LXdlYmtpdC1zY3JvbGxiYXIge1xuICAgICAgICB3aWR0aDogMC40cmVtO1xuICAgICAgICBoZWlnaHQ6IDAuNHJlbTtcbiAgICAgIH1cblxuICAgICAgLy8gU3R5bGUgc2Nyb2xsYmFyIHRodW1iXG4gICAgICAmOjotd2Via2l0LXNjcm9sbGJhci10aHVtYiB7XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2xvci1ibGFjay0tbGlnaHRlcjtcblxuICAgICAgICAvLyBIb3ZlcmVkIHNjcm9sbGJhciB0aHVtYlxuICAgICAgICAmOmhvdmVyIHtcbiAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQtY29sb3ItYWNjZW50O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8vIFNlYXJjaCByZXN1bHRcbi5tZC1zZWFyY2gtcmVzdWx0IHtcbiAgY29sb3I6ICRtZC1jb2xvci1ibGFjaztcbiAgd29yZC1icmVhazogYnJlYWstd29yZDtcblxuICAvLyBTZWFyY2ggbWV0YWRhdGFcbiAgJl9fbWV0YSB7XG4gICAgcGFkZGluZzogMCAxLjZyZW07XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJG1kLWNvbG9yLWJsYWNrLS1saWdodGVzdDtcbiAgICBjb2xvcjogJG1kLWNvbG9yLWJsYWNrLS1saWdodDtcbiAgICBmb250LXNpemU6IG1zKC0xKTtcbiAgICBsaW5lLWhlaWdodDogMy42cmVtO1xuXG4gICAgLy8gW3RhYmxldCBsYW5kc2NhcGUgK106IEluY3JlYXNlIGxlZnQgaW5kZW50XG4gICAgQGluY2x1ZGUgYnJlYWstZnJvbS1kZXZpY2UodGFibGV0IGxhbmRzY2FwZSkge1xuICAgICAgcGFkZGluZy1sZWZ0OiA0LjRyZW07XG5cbiAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgICAgcGFkZGluZy1yaWdodDogNC40cmVtO1xuICAgICAgICBwYWRkaW5nLWxlZnQ6IGluaXRpYWw7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gTGlzdCBvZiBpdGVtc1xuICAmX19saXN0IHtcbiAgICBtYXJnaW46IDA7XG4gICAgcGFkZGluZzogMDtcbiAgICBib3JkZXItdG9wOiAwLjFyZW0gc29saWQgJG1kLWNvbG9yLWJsYWNrLS1saWdodGVzdDtcbiAgICBsaXN0LXN0eWxlOiBub25lO1xuICB9XG5cbiAgLy8gTGlzdCBpdGVtXG4gICZfX2l0ZW0ge1xuICAgIGJveC1zaGFkb3c6IDAgLTAuMXJlbSAwICRtZC1jb2xvci1ibGFjay0tbGlnaHRlc3Q7XG4gIH1cblxuICAvLyBMaW5rIGluc2lkZSBpdGVtXG4gICZfX2xpbmsge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQgMC4yNXM7XG4gICAgb3V0bGluZTogMDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuXG4gICAgLy8gQWN0aXZlIG9yIGhvdmVyZWQgbGlua1xuICAgICZbZGF0YS1tZC1zdGF0ZT1cImFjdGl2ZVwiXSxcbiAgICAmOmhvdmVyIHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50aXplKCRtZC1jb2xvci1hY2NlbnQsIDAuOSk7XG5cbiAgICAgIC8vIFNsaWdodGx5IHRyYW5zcGFyZW50IGljb25cbiAgICAgIC5tZC1zZWFyY2gtcmVzdWx0X19hcnRpY2xlOjpiZWZvcmUge1xuICAgICAgICBvcGFjaXR5OiAwLjc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWRkIGEgbGl0dGxlIHNwYWNpbmcgb24gdGhlIHRlYXNlciBvZiB0aGUgbGFzdCBsaW5rXG4gICAgJjpsYXN0LWNoaWxkIC5tZC1zZWFyY2gtcmVzdWx0X190ZWFzZXIge1xuICAgICAgbWFyZ2luLWJvdHRvbTogMS4ycmVtO1xuICAgIH1cbiAgfVxuXG4gIC8vIEFydGljbGUgLSBkb2N1bWVudCBvciBzZWN0aW9uXG4gICZfX2FydGljbGUge1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBwYWRkaW5nOiAwIDEuNnJlbTtcbiAgICBvdmVyZmxvdzogYXV0bztcblxuICAgIC8vIFt0YWJsZXQgbGFuZHNjYXBlICtdOiBJbmNyZWFzZSBsZWZ0IGluZGVudFxuICAgIEBpbmNsdWRlIGJyZWFrLWZyb20tZGV2aWNlKHRhYmxldCBsYW5kc2NhcGUpIHtcbiAgICAgIHBhZGRpbmctbGVmdDogNC40cmVtO1xuXG4gICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICAgIHBhZGRpbmctcmlnaHQ6IDQuNHJlbTtcbiAgICAgICAgcGFkZGluZy1sZWZ0OiAxLjZyZW07XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRG9jdW1lbnRcbiAgICAmLS1kb2N1bWVudCB7XG5cbiAgICAgIC8vIEljb25cbiAgICAgICY6OmJlZm9yZSB7XG4gICAgICAgIEBleHRlbmQgJW1kLWljb24sICVtZC1pY29uX19idXR0b247XG5cbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICBsZWZ0OiAwO1xuICAgICAgICBtYXJnaW46IDAuMnJlbTtcbiAgICAgICAgdHJhbnNpdGlvbjogb3BhY2l0eSAwLjI1cztcbiAgICAgICAgY29sb3I6ICRtZC1jb2xvci1ibGFjay0tbGlnaHQ7XG4gICAgICAgIGNvbnRlbnQ6IFwiXFxFODgwXCI7IC8vIGZpbmRfaW5fcGFnZVxuXG4gICAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICAgIHJpZ2h0OiAwO1xuICAgICAgICAgIGxlZnQ6IGluaXRpYWw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBbdGFibGV0IHBvcnRyYWl0IC1dOiBIaWRlIHBhZ2UgaWNvblxuICAgICAgICBAaW5jbHVkZSBicmVhay10by1kZXZpY2UodGFibGV0IHBvcnRyYWl0KSB7XG4gICAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBUaXRsZVxuICAgICAgLm1kLXNlYXJjaC1yZXN1bHRfX3RpdGxlIHtcbiAgICAgICAgbWFyZ2luOiAxLjFyZW0gMDtcbiAgICAgICAgZm9udC1zaXplOiBtcygwKTtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDQwMDtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDEuNDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBUaXRsZVxuICAmX190aXRsZSB7XG4gICAgbWFyZ2luOiAwLjVlbSAwO1xuICAgIGZvbnQtc2l6ZTogbXMoLTEpO1xuICAgIGZvbnQtd2VpZ2h0OiA3MDA7XG4gICAgbGluZS1oZWlnaHQ6IDEuNDtcbiAgfVxuXG4gIC8vIHN0eWxlbGludC1kaXNhYmxlIHZhbHVlLW5vLXZlbmRvci1wcmVmaXgsIHByb3BlcnR5LW5vLXZlbmRvci1wcmVmaXhcblxuICAvLyBUZWFzZXJcbiAgJl9fdGVhc2VyIHtcbiAgICBkaXNwbGF5OiAtd2Via2l0LWJveDtcbiAgICBtYXgtaGVpZ2h0OiAzLjNyZW07XG4gICAgbWFyZ2luOiAwLjVlbSAwO1xuICAgIGNvbG9yOiAkbWQtY29sb3ItYmxhY2stLWxpZ2h0O1xuICAgIGZvbnQtc2l6ZTogbXMoLTEpO1xuICAgIGxpbmUtaGVpZ2h0OiAxLjQ7XG4gICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAtd2Via2l0LWJveC1vcmllbnQ6IHZlcnRpY2FsO1xuICAgIC13ZWJraXQtbGluZS1jbGFtcDogMjtcblxuICAgIC8vIFttb2JpbGUgLV06IEluY3JlYXNlIG51bWJlciBvZiBsaW5lc1xuICAgIEBpbmNsdWRlIGJyZWFrLXRvLWRldmljZShtb2JpbGUpIHtcbiAgICAgIG1heC1oZWlnaHQ6IDVyZW07XG4gICAgICAtd2Via2l0LWxpbmUtY2xhbXA6IDM7XG4gICAgfVxuXG4gICAgLy8gW3RhYmxldCBsYW5kc2NhcGVdOiBJbmNyZWFzZSBudW1iZXIgb2YgbGluZXNcbiAgICBAaW5jbHVkZSBicmVhay1hdC1kZXZpY2UodGFibGV0IGxhbmRzY2FwZSkge1xuICAgICAgbWF4LWhlaWdodDogNXJlbTtcbiAgICAgIC13ZWJraXQtbGluZS1jbGFtcDogMztcbiAgICB9XG4gIH1cblxuICAvLyBzdHlsZWxpbnQtZW5hYmxlIHZhbHVlLW5vLXZlbmRvci1wcmVmaXgsIHByb3BlcnR5LW5vLXZlbmRvci1wcmVmaXhcblxuICAvLyBTZWFyY2ggdGVybSBoaWdobGlnaHRpbmdcbiAgZW0ge1xuICAgIGZvbnQtc3R5bGU6IG5vcm1hbDtcbiAgICBmb250LXdlaWdodDogNzAwO1xuICAgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO1xuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2xheW91dC9fc2VhcmNoLnNjc3MiLCIvLy8vXG4vLy8gQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuLy8vXG4vLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksXG4vLy8gdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvblxuLy8vIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLFxuLy8vIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZVxuLy8vIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vLy9cbi8vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy8vXG4vLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTFxuLy8vIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbi8vLyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSXG4vLy8gREVBTElOR1Ncbi8vLy9cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVmFyaWFibGVzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIEFjdGl2ZSAodG9nZ2xlZCkgZHJhd2VyXG4kbWQtdG9nZ2xlX19kcmF3ZXItLWNoZWNrZWQ6XG4gIFwiW2RhdGEtbWQtdG9nZ2xlPVxcXCJkcmF3ZXJcXFwiXTpjaGVja2VkIH4gLm1kLWNvbnRhaW5lclwiO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBSdWxlc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBTaWRlYmFyIGNvbnRhaW5lclxuLm1kLXNpZGViYXIge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHdpZHRoOiAyNC4ycmVtO1xuICBwYWRkaW5nOiAyLjRyZW0gMDtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcblxuICAvLyBIaWRlIGZvciBwcmludFxuICBAbWVkaWEgcHJpbnQge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gIH1cblxuICAvLyBMb2NrIHNpZGViYXIgdG8gY29udGFpbmVyIGhlaWdodCAoYWNjb3VudCBmb3IgZml4ZWQgaGVhZGVyKVxuICAmW2RhdGEtbWQtc3RhdGU9XCJsb2NrXCJdIHtcbiAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgdG9wOiA0LjhyZW07XG4gIH1cblxuICAvLyBbdGFibGV0IC1dOiBDb252ZXJ0IG5hdmlnYXRpb24gdG8gZHJhd2VyXG4gIEBpbmNsdWRlIGJyZWFrLXRvLWRldmljZSh0YWJsZXQpIHtcblxuICAgIC8vIFJlbmRlciBwcmltYXJ5IHNpZGViYXIgYXMgYSBzbGlkZW91dCBjb250YWluZXJcbiAgICAmLS1wcmltYXJ5IHtcbiAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgIHRvcDogMDtcbiAgICAgIGxlZnQ6IC0yNC4ycmVtO1xuICAgICAgd2lkdGg6IDI0LjJyZW07XG4gICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMCk7XG4gICAgICB0cmFuc2l0aW9uOlxuICAgICAgICB0cmFuc2Zvcm0gIDAuMjVzIGN1YmljLWJlemllcigwLjQsIDAsIDAuMiwgMSksXG4gICAgICAgIGJveC1zaGFkb3cgMC4yNXM7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQtY29sb3Itd2hpdGU7XG4gICAgICB6LWluZGV4OiAzO1xuXG4gICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICAgIHJpZ2h0OiAtMjQuMnJlbTtcbiAgICAgICAgbGVmdDogaW5pdGlhbDtcbiAgICAgIH1cblxuICAgICAgLy8gSnVzdCBoaWRlIGRyYXdlciwgaWYgYnJvd3NlciBkb2Vzbid0IHN1cHBvcnQgM0QgdHJhbnNmb3Jtc1xuICAgICAgLm5vLWNzc3RyYW5zZm9ybXMzZCAmIHtcbiAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICAgIH1cblxuICAgICAgLy8gRXhwYW5kZWQgZHJhd2VyXG4gICAgICAjeyRtZC10b2dnbGVfX2RyYXdlci0tY2hlY2tlZH0gJiB7XG4gICAgICAgIEBpbmNsdWRlIHotZGVwdGgoOCk7XG5cbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDI0LjJyZW0pO1xuXG4gICAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtMjQuMnJlbSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBKdXN0IHNob3cgZHJhd2VyLCBpZiBicm93c2VyIGRvZXNuJ3Qgc3VwcG9ydCAzRCB0cmFuc2Zvcm1zXG4gICAgICAgIC5uby1jc3N0cmFuc2Zvcm1zM2QgJiB7XG4gICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gSGlkZSBvdmVyZmxvdyBmb3IgbmVzdGVkIG5hdmlnYXRpb25cbiAgICAgIC5tZC1zaWRlYmFyX19zY3JvbGx3cmFwIHtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBTZWNvbmRhcnkgc2lkZWJhciB3aXRoIHRhYmxlIG9mIGNvbnRlbnRzXG4gICYtLXNlY29uZGFyeSB7XG4gICAgZGlzcGxheTogbm9uZTtcblxuICAgIC8vIFt0YWJsZXQgbGFuZHNjYXBlICtdOiBTaG93IHRhYmxlIG9mIGNvbnRlbnRzIG5leHQgdG8gYm9keSBjb3B5XG4gICAgQGluY2x1ZGUgYnJlYWstZnJvbS1kZXZpY2UodGFibGV0IGxhbmRzY2FwZSkge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICBtYXJnaW4tbGVmdDogMTAwJTtcbiAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlKC0xMDAlLCAwKTtcblxuICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICBtYXJnaW4tcmlnaHQ6IDEwMCU7XG4gICAgICAgIG1hcmdpbi1sZWZ0OiBpbml0aWFsO1xuICAgICAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgxMDAlLCAwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBbc2NyZWVuICtdOiBMaW1pdCB0byBncmlkXG4gICAgQGluY2x1ZGUgYnJlYWstZnJvbS1kZXZpY2Uoc2NyZWVuKSB7XG4gICAgICBtYXJnaW4tbGVmdDogMTIycmVtO1xuXG4gICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICAgIG1hcmdpbi1yaWdodDogMTIycmVtO1xuICAgICAgICBtYXJnaW4tbGVmdDogaW5pdGlhbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBXcmFwcGVyIGZvciBzY3JvbGxpbmcgb24gb3ZlcmZsb3dcbiAgJl9fc2Nyb2xsd3JhcCB7XG4gICAgbWF4LWhlaWdodDogMTAwJTtcbiAgICBtYXJnaW46IDAgMC40cmVtO1xuICAgIG92ZXJmbG93LXk6IGF1dG87XG4gICAgLy8gSGFjazogcHV0dGluZyB0aGUgc2Nyb2xsIHdyYXBwZXIgb24gdGhlIEdQVSBtYXNzaXZlbHkgcmVkdWNlcyBqaXR0ZXJcbiAgICAvLyB3aGVuIGxvY2tpbmcgdGhlIHNpZGViYXJzIGludG8gcGxhY2VcbiAgICBiYWNrZmFjZS12aXNpYmlsaXR5OiBoaWRkZW47XG5cbiAgICAvLyBbdGFibGV0IC1dOiBBZGp1c3QgbWFyZ2luc1xuICAgIEBpbmNsdWRlIGJyZWFrLXRvLWRldmljZSh0YWJsZXQpIHtcblxuICAgICAgLy8gU3RyZXRjaCBzY3JvbGx3cmFwIGZvciBwcmltYXJ5IHNpZGViYXJcbiAgICAgIC5tZC1zaWRlYmFyLS1wcmltYXJ5ICYge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIHRvcDogMDtcbiAgICAgICAgcmlnaHQ6IDA7XG4gICAgICAgIGJvdHRvbTogMDtcbiAgICAgICAgbGVmdDogMDtcbiAgICAgICAgbWFyZ2luOiAwO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIE92ZXJyaWRlIG5hdGl2ZSBzY3JvbGxiYXIgc3R5bGVzXG4gICAgJjo6LXdlYmtpdC1zY3JvbGxiYXIge1xuICAgICAgd2lkdGg6IDAuNHJlbTtcbiAgICAgIGhlaWdodDogMC40cmVtO1xuICAgIH1cblxuICAgIC8vIFN0eWxlIHNjcm9sbGJhciB0aHVtYlxuICAgICY6Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1iIHtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2xvci1ibGFjay0tbGlnaHRlcjtcblxuICAgICAgLy8gSG92ZXJlZCBzY3JvbGxiYXIgdGh1bWJcbiAgICAgICY6aG92ZXIge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQtY29sb3ItYWNjZW50O1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9sYXlvdXQvX3NpZGViYXIuc2NzcyIsIi8vLy9cbi8vLyBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4vLy9cbi8vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSxcbi8vLyB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uXG4vLy8gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsXG4vLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlXG4vLy8gU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vL1xuLy8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vLy9cbi8vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMXG4vLy8gVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuLy8vIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVJcbi8vLyBERUFMSU5HU1xuLy8vL1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBLZXlmcmFtZXNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gU2hvdyBzb3VyY2UgZmFjdHNcbkBrZXlmcmFtZXMgbWQtc291cmNlX19mYWN0cy0tZG9uZSB7XG4gIDAlIHtcbiAgICBoZWlnaHQ6IDA7XG4gIH1cblxuICAxMDAlIHtcbiAgICBoZWlnaHQ6IDEuM3JlbTtcbiAgfVxufVxuXG4vLyBTaG93IHNvdXJjZSBmYWN0XG5Aa2V5ZnJhbWVzIG1kLXNvdXJjZV9fZmFjdC0tZG9uZSB7XG4gIDAlIHtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoMTAwJSk7XG4gICAgb3BhY2l0eTogMDtcbiAgfVxuXG4gIDUwJSB7XG4gICAgb3BhY2l0eTogMDtcbiAgfVxuXG4gIDEwMCUge1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgwJSk7XG4gICAgb3BhY2l0eTogMTtcbiAgfVxufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBSdWxlc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBTb3VyY2UgY29udGFpbmVyXG4ubWQtc291cmNlIHtcbiAgZGlzcGxheTogYmxvY2s7XG4gIHBhZGRpbmctcmlnaHQ6IDEuMnJlbTtcbiAgdHJhbnNpdGlvbjogb3BhY2l0eSAwLjI1cztcbiAgZm9udC1zaXplOiAxLjNyZW07XG4gIGxpbmUtaGVpZ2h0OiAxLjI7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG5cbiAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgcGFkZGluZy1yaWdodDogaW5pdGlhbDtcbiAgICBwYWRkaW5nLWxlZnQ6IDEuMnJlbTtcbiAgfVxuXG4gIC8vIEhvdmVyZWQgc291cmNlIGNvbnRhaW5lclxuICAmOmhvdmVyIHtcbiAgICBvcGFjaXR5OiAwLjc7XG4gIH1cblxuICAvLyBOZWNlc3NhcnkgZm9yIHZlcnRpY2FsIGFsaWdubWVudFxuICAmOjphZnRlciB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIGhlaWdodDogNC44cmVtO1xuICAgIGNvbnRlbnQ6IFwiXCI7XG4gICAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbiAgfVxuXG4gIC8vIFJlcG9zaXRvcnkgcGxhdGZvcm0gaWNvblxuICAmX19pY29uIHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgd2lkdGg6IDQuOHJlbTtcbiAgICBoZWlnaHQ6IDQuOHJlbTtcbiAgICBjb250ZW50OiBcIlwiO1xuICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG5cbiAgICAvLyBBbGlnbiBTVkcsIGRvIG5vdCBzY2FsZSwgYXMgdGhpcyB3aWxsIGluY3VyIHN0cmFuZ2UgZm9ybWF0dGluZyBidWdzXG4gICAgLy8gaW4gSW50ZXJuZXQgRXhwbG9yZXIgYW5kIEVkZ2VcbiAgICBzdmcge1xuICAgICAgd2lkdGg6IDIuNHJlbTtcbiAgICAgIGhlaWdodDogMi40cmVtO1xuICAgICAgbWFyZ2luLXRvcDogMS4ycmVtO1xuICAgICAgbWFyZ2luLWxlZnQ6IDEuMnJlbTtcblxuICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICBtYXJnaW4tcmlnaHQ6IDEuMnJlbTtcbiAgICAgICAgbWFyZ2luLWxlZnQ6IGluaXRpYWw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ29ycmVjdCBhbGlnbm1lbnQsIGlmIGljb24gaXMgcHJlc2VudFxuICAgICsgLm1kLXNvdXJjZV9fcmVwb3NpdG9yeSB7XG4gICAgICBtYXJnaW4tbGVmdDogLTQuNHJlbTtcbiAgICAgIHBhZGRpbmctbGVmdDogNHJlbTtcblxuICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICBtYXJnaW4tcmlnaHQ6IC00LjRyZW07XG4gICAgICAgIG1hcmdpbi1sZWZ0OiBpbml0aWFsO1xuICAgICAgICBwYWRkaW5nLXJpZ2h0OiA0cmVtO1xuICAgICAgICBwYWRkaW5nLWxlZnQ6IGluaXRpYWw7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gUmVwb3NpdG9yeSBuYW1lXG4gICZfX3JlcG9zaXRvcnkge1xuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICBtYXgtd2lkdGg6IDEwMCU7XG4gICAgbWFyZ2luLWxlZnQ6IDEuMnJlbTtcbiAgICBmb250LXdlaWdodDogNzAwO1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbiAgfVxuXG4gIC8vIFNvdXJjZSBmYWN0cyAoc3RhdGlzdGljcyBldGMuKVxuICAmX19mYWN0cyB7XG4gICAgbWFyZ2luOiAwO1xuICAgIHBhZGRpbmc6IDA7XG4gICAgZm9udC1zaXplOiAxLjFyZW07XG4gICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICBsaXN0LXN0eWxlLXR5cGU6IG5vbmU7XG4gICAgb3BhY2l0eTogMC43NTtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuXG4gICAgLy8gU2hvdyBhZnRlciB0aGUgZGF0YSB3YXMgbG9hZGVkXG4gICAgW2RhdGEtbWQtc3RhdGU9XCJkb25lXCJdICYge1xuICAgICAgYW5pbWF0aW9uOiBtZC1zb3VyY2VfX2ZhY3RzLS1kb25lIDAuMjVzIGVhc2UtaW47XG4gICAgfVxuICB9XG5cbiAgLy8gRmFjdFxuICAmX19mYWN0IHtcbiAgICBmbG9hdDogbGVmdDtcblxuICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICBmbG9hdDogcmlnaHQ7XG4gICAgfVxuXG4gICAgLy8gU2hvdyBhZnRlciB0aGUgZGF0YSB3YXMgbG9hZGVkXG4gICAgW2RhdGEtbWQtc3RhdGU9XCJkb25lXCJdICYge1xuICAgICAgYW5pbWF0aW9uOiBtZC1zb3VyY2VfX2ZhY3QtLWRvbmUgMC40cyBlYXNlLW91dDtcbiAgICB9XG5cbiAgICAvLyBNaWRkbGUgZG90IGJlZm9yZSBmYWN0XG4gICAgJjo6YmVmb3JlIHtcbiAgICAgIG1hcmdpbjogMCAwLjJyZW07XG4gICAgICBjb250ZW50OiBcIlxcMDBCN1wiO1xuICAgIH1cblxuICAgIC8vIFJlbW92ZSBtaWRkbGUgZG90IG9uIGZpcnN0IGZhY3RcbiAgICAmOmZpcnN0LWNoaWxkOjpiZWZvcmUge1xuICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG4gIH1cbn1cblxuLy8gU291cmNlIGZpbGVcbi5tZC1zb3VyY2UtZmlsZSB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgbWFyZ2luOiAxZW0gMC41ZW0gMWVtIDA7XG4gIHBhZGRpbmctcmlnaHQ6IDAuNXJlbTtcbiAgYm9yZGVyLXJhZGl1czogMC4ycmVtO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQtY29sb3ItYmxhY2stLWxpZ2h0ZXN0O1xuICBmb250LXNpemU6IG1zKC0xKTtcbiAgbGlzdC1zdHlsZS10eXBlOiBub25lO1xuICBjdXJzb3I6IHBvaW50ZXI7XG4gIG92ZXJmbG93OiBoaWRkZW47XG5cbiAgLy8gSWNvblxuICAmOjpiZWZvcmUge1xuICAgIEBleHRlbmQgJW1kLWljb247XG5cbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgbWFyZ2luLXJpZ2h0OiAwLjVyZW07XG4gICAgcGFkZGluZzogMC41cmVtO1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2xvci1ibGFjay0tbGlnaHRlcjtcbiAgICBjb2xvcjogJG1kLWNvbG9yLXdoaXRlO1xuICAgIGZvbnQtc2l6ZTogbXMoMCk7XG4gICAgY29udGVudDogXCJcXEU4NkZcIjsgLy8gY29kZVxuICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gIH1cblxuICAvLyBTb21lIHByb3BlcnRpZXMgbmVlZCB0byBiZSBzZXQgd2l0aCBoaWdoZXIgc3BlY2lmaWNpdHkgZHVlIHRvIHRoZSBkZWZhdWx0XG4gIC8vIHN0eWxpbmcgb2YgdGV4dCBsaW5rcyBpbnNpZGUgdHlwZXNldHRlZCBjb250ZW50XG4gIGh0bWwgJiB7XG4gICAgdHJhbnNpdGlvbjpcbiAgICAgIGJhY2tncm91bmQgMC40cyxcbiAgICAgIGNvbG9yICAgICAgMC40cyxcbiAgICAgIGJveC1zaGFkb3cgMC40cyBjdWJpYy1iZXppZXIoMC40LCAwLCAwLjIsIDEpO1xuXG4gICAgLy8gSWNvblxuICAgICY6OmJlZm9yZSB7XG4gICAgICB0cmFuc2l0aW9uOiBpbmhlcml0O1xuICAgIH1cbiAgfVxuXG4gIC8vIENvbG9yIG5lZWRzIGV2ZW4gaGlnaGVyIHNwZWNpZml0eSBiZWNhdXNlIGN1c3RvbSBjb2xvciBwYWxldHRlcyBhcmUgc2V0XG4gIC8vIHVzaW5nIHRoZSBib2R5IGFuZCBvdmVycmlkZSB0ZXh0IGxpbmtzIGluc2lkZSB0eXBlc2V0dGVkIGNvbnRlbnRcbiAgaHRtbCBib2R5IC5tZC10eXBlc2V0ICYge1xuICAgIGNvbG9yOiAkbWQtY29sb3ItYmxhY2stLWxpZ2h0O1xuICB9XG5cbiAgLy8gSG92ZXJlZCBzb3VyY2UgZmlsZVxuICAmOmhvdmVyIHtcbiAgICBAaW5jbHVkZSB6LWRlcHRoLWZvY3VzO1xuXG4gICAgLy8gSWNvblxuICAgICY6OmJlZm9yZSB7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQtY29sb3ItYWNjZW50O1xuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9sYXlvdXQvX3NvdXJjZS5zY3NzIiwiLy8vL1xuLy8vIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbi8vL1xuLy8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLFxuLy8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb25cbi8vLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSxcbi8vLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGVcbi8vLyBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy8vXG4vLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vL1xuLy8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTExcbi8vLyBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4vLy8gRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUlxuLy8vIERFQUxJTkdTXG4vLy8vXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIFRhYnMgd2l0aCBvdXRsaW5lXG4ubWQtdGFicyB7XG4gIHdpZHRoOiAxMDAlO1xuICB0cmFuc2l0aW9uOiBiYWNrZ3JvdW5kIDAuMjVzO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAkbWQtY29sb3ItcHJpbWFyeTtcbiAgY29sb3I6ICRtZC1jb2xvci13aGl0ZTtcbiAgb3ZlcmZsb3c6IGF1dG87XG5cbiAgLy8gW3RhYmxldCAtXTogSGlkZSB0YWJzIGZvciB0YWJsZXQgYW5kIGJlbG93LCBhcyB0aGV5IGRvbid0IG1ha2UgYW55IHNlbnNlXG4gIEBpbmNsdWRlIGJyZWFrLXRvLWRldmljZSh0YWJsZXQpIHtcbiAgICBkaXNwbGF5OiBub25lO1xuICB9XG5cbiAgLy8gSGlkZSBmb3IgcHJpbnRcbiAgQG1lZGlhIHByaW50IHtcbiAgICBkaXNwbGF5OiBub25lO1xuICB9XG5cbiAgLy8gTGlzdCBvZiBpdGVtc1xuICAmX19saXN0IHtcbiAgICBtYXJnaW46IDA7XG4gICAgbWFyZ2luLWxlZnQ6IDAuNHJlbTtcbiAgICBwYWRkaW5nOiAwO1xuICAgIGxpc3Qtc3R5bGU6IG5vbmU7XG4gICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgfVxuXG4gIC8vIExpc3QgaXRlbVxuICAmX19pdGVtIHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgaGVpZ2h0OiA0LjhyZW07XG4gICAgcGFkZGluZy1yaWdodDogMS4ycmVtO1xuICAgIHBhZGRpbmctbGVmdDogMS4ycmVtO1xuICB9XG5cbiAgLy8gTGluayBpbnNpZGUgaXRlbSAtIGNvdWxkIGJlIGRlZmluZWQgYXMgYmxvY2sgZWxlbWVudHMgYW5kIGFsaWduZWQgdmlhXG4gIC8vIGxpbmUgaGVpZ2h0LCBidXQgdGhpcyB3b3VsZCBpbXBseSBtb3JlIHJlcGFpbnRzIHdoZW4gc2Nyb2xsaW5nXG4gICZfX2xpbmsge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIG1hcmdpbi10b3A6IDEuNnJlbTtcbiAgICB0cmFuc2l0aW9uOlxuICAgICAgdHJhbnNmb3JtIDAuNHMgY3ViaWMtYmV6aWVyKDAuMSwgMC43LCAwLjEsIDEpLFxuICAgICAgb3BhY2l0eSAgIDAuMjVzO1xuICAgIGZvbnQtc2l6ZTogMS40cmVtO1xuICAgIG9wYWNpdHk6IDAuNztcblxuICAgIC8vIEFjdGl2ZSBvciBob3ZlcmVkIGxpbmtcbiAgICAmLS1hY3RpdmUsXG4gICAgJjpob3ZlciB7XG4gICAgICBjb2xvcjogaW5oZXJpdDtcbiAgICAgIG9wYWNpdHk6IDE7XG4gICAgfVxuXG4gICAgLy8gRGVsYXkgdHJhbnNpdGlvbnMgYnkgYSBzbWFsbCBhbW91bnRcbiAgICBAZm9yICRpIGZyb20gMiB0aHJvdWdoIDE2IHtcbiAgICAgIC5tZC10YWJzX19pdGVtOm50aC1jaGlsZCgjeyRpfSkgJiB7XG4gICAgICAgIHRyYW5zaXRpb24tZGVsYXk6IDAuMDJzICogKCRpIC0gMSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gRmFkZS1vdXQgdGFicyBiYWNrZ3JvdW5kIHVwb24gc2Nyb2xsaW5nXG4gICZbZGF0YS1tZC1zdGF0ZT1cImhpZGRlblwiXSB7XG4gICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG5cbiAgICAvLyBIaWRlIHRhYnMgdXBvbiBzY3JvbGxpbmcgLSBkaXNhYmxlIHRyYW5zaXRpb24gdG8gbWluaW1pemVzIHJlcGFpbnRzIHdoaWx0ZVxuICAgIC8vIHNjcm9sbGluZyBkb3duLCB3aGlsZSBzY3JvbGxpbmcgdXAgc2VlbXMgdG8gYmUgb2theVxuICAgIC5tZC10YWJzX19saW5rIHtcbiAgICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSg1MCUpO1xuICAgICAgdHJhbnNpdGlvbjpcbiAgICAgICAgY29sb3IgICAgIDAuMjVzLFxuICAgICAgICB0cmFuc2Zvcm0gMHMgMC40cyxcbiAgICAgICAgb3BhY2l0eSAgIDAuMXM7XG4gICAgICBvcGFjaXR5OiAwO1xuICAgIH1cbiAgfVxuXG4gIC8vIFtzY3JlZW4gK106IEFkanVzdCBtYWluIG5hdmlnYXRpb24gc3R5bGVzXG4gIEBpbmNsdWRlIGJyZWFrLWZyb20tZGV2aWNlKHNjcmVlbikge1xuXG4gICAgLy8gSGlkZSAxc3QgbGV2ZWwgbmVzdGVkIGl0ZW1zLCBhcyB0aGV5IGFyZSBsaXN0ZWQgaW4gdGhlIHRhYnMgYnkgc2V0dGluZ1xuICAgIC8vIGZvbnQtc2l6ZSB0byB6ZXJvLCBhcyB3ZSBuZWVkIHRvIHByZXNlcnZlIGJvdHRvbSBwYWRkaW5nXG4gICAgfiAubWQtbWFpbiAubWQtbmF2LS1wcmltYXJ5ID4gLm1kLW5hdl9fbGlzdCA+IC5tZC1uYXZfX2l0ZW0tLW5lc3RlZCB7XG4gICAgICBmb250LXNpemU6IDA7XG4gICAgICB2aXNpYmlsaXR5OiBoaWRkZW47XG4gICAgfVxuXG4gICAgLy8gV2UncmUgb24gdGhlIDJuZCsgbGV2ZWxcbiAgICAmLS1hY3RpdmUgfiAubWQtbWFpbiB7XG5cbiAgICAgIC8vIEFkanVzdCAxc3QgbGV2ZWwgc3R5bGVzXG4gICAgICAubWQtbmF2LS1wcmltYXJ5IHtcblxuICAgICAgICAvLyBTaG93IHRpdGxlIGFuZCByZW1vdmUgc3BhY2luZ1xuICAgICAgICAubWQtbmF2X190aXRsZSB7XG4gICAgICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICAgICAgcGFkZGluZzogMDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEhpZGUgc2l0ZSB0aXRsZVxuICAgICAgICAubWQtbmF2X190aXRsZS0tc2l0ZSB7XG4gICAgICAgICAgZGlzcGxheTogbm9uZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNob3cgMXN0IGxldmVsIG5hdmlnYXRpb24gYWx3YXlzIGV4cGFuZGVkXG4gICAgICAgIC5uby1qcyAmIC5tZC1uYXYge1xuICAgICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGlkZSAxc3QgbGV2ZWwgbm9ybWFsIGl0ZW1zXG4gICAgICAgICYgPiAubWQtbmF2X19saXN0ID4gLm1kLW5hdl9faXRlbSB7XG4gICAgICAgICAgZm9udC1zaXplOiAwO1xuICAgICAgICAgIHZpc2liaWxpdHk6IGhpZGRlbjtcblxuICAgICAgICAgIC8vIFJlc2V0IGZvbnQtc2l6ZSBmb3IgbmVzdGVkIGl0ZW1zIGFuZCBpbmR1Y2UgbWFyZ2luIGNvbGxhcHNlXG4gICAgICAgICAgJi0tbmVzdGVkIHtcbiAgICAgICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgICAgICAgICBmb250LXNpemU6IDEuNHJlbTtcbiAgICAgICAgICAgIG92ZXJmbG93OiBhdXRvO1xuICAgICAgICAgICAgdmlzaWJpbGl0eTogdmlzaWJsZTtcblxuICAgICAgICAgICAgLy8gSGlkZSBuZXN0ZWQgbGlua3NcbiAgICAgICAgICAgID4gLm1kLW5hdl9fbGluayB7XG4gICAgICAgICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gU2hvdyAxc3QgbGV2ZWwgYWN0aXZlIG5lc3RlZCBpdGVtc1xuICAgICAgICAgICYtLWFjdGl2ZSB7XG4gICAgICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQWx3YXlzIGV4cGFuZCBuZXN0ZWQgbmF2aWdhdGlvbiBvbiAybmQgbGV2ZWxcbiAgICAgIC5tZC1uYXZbZGF0YS1tZC1sZXZlbD1cIjFcIl0ge1xuICAgICAgICBtYXgtaGVpZ2h0OiBpbml0aWFsO1xuICAgICAgICBvdmVyZmxvdzogdmlzaWJsZTtcblxuICAgICAgICAvLyBSZW1vdmUgbGVmdCBzcGFjaW5nIG9uIDJuZCBsZXZlbCBpdGVtc1xuICAgICAgICA+IC5tZC1uYXZfX2xpc3QgPiAubWQtbmF2X19pdGVtIHtcbiAgICAgICAgICBwYWRkaW5nLWxlZnQ6IDA7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIaWRlIHRpdGxlcyBmcm9tIDJuZCBsZXZlbCBvblxuICAgICAgICAubWQtbmF2IC5tZC1uYXZfX3RpdGxlIHtcbiAgICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2xheW91dC9fdGFicy5zY3NzIiwiLy8vL1xuLy8vIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbi8vL1xuLy8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLFxuLy8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb25cbi8vLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSxcbi8vLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGVcbi8vLyBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy8vXG4vLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vL1xuLy8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTExcbi8vLyBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4vLy8gRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUlxuLy8vIERFQUxJTkdTXG4vLy8vXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIFNjb3BlZCBpbiB0eXBlc2V0dGVkIGNvbnRlbnQgdG8gbWF0Y2ggc3BlY2lmaWNpdHkgb2YgcmVndWxhciBjb250ZW50XG4ubWQtdHlwZXNldCB7XG5cbiAgLy8gQWRtb25pdGlvbiBleHRlbnNpb25cbiAgLmFkbW9uaXRpb24ge1xuICAgIEBpbmNsdWRlIHotZGVwdGgoMik7XG5cbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgbWFyZ2luOiAxLjU2MjVlbSAwO1xuICAgIHBhZGRpbmc6IDAgMS4ycmVtO1xuICAgIGJvcmRlci1sZWZ0OiAwLjRyZW0gc29saWQgJGNsci1ibHVlLWEyMDA7XG4gICAgYm9yZGVyLXJhZGl1czogMC4ycmVtO1xuICAgIGZvbnQtc2l6ZTogbXMoLTEpO1xuICAgIG92ZXJmbG93OiBhdXRvO1xuXG4gICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgW2Rpcj1cInJ0bFwiXSAmIHtcbiAgICAgIGJvcmRlci1yaWdodDogMC40cmVtIHNvbGlkICRjbHItYmx1ZS1hMjAwO1xuICAgICAgYm9yZGVyLWxlZnQ6IG5vbmU7XG4gICAgfVxuXG4gICAgLy8gQWRqdXN0IHNwYWNpbmcgb24gbGFzdCBlbGVtZW50XG4gICAgaHRtbCAmID4gOmxhc3QtY2hpbGQge1xuICAgICAgbWFyZ2luLWJvdHRvbTogMS4ycmVtO1xuICAgIH1cblxuICAgIC8vIEFkanVzdCBtYXJnaW4gZm9yIG5lc3RlZCBhZG1vbml0aW9uIGJsb2Nrc1xuICAgIC5hZG1vbml0aW9uIHtcbiAgICAgIG1hcmdpbjogMWVtIDA7XG4gICAgfVxuXG4gICAgLy8gVGl0bGVcbiAgICA+IC5hZG1vbml0aW9uLXRpdGxlIHtcbiAgICAgIG1hcmdpbjogMCAtMS4ycmVtO1xuICAgICAgcGFkZGluZzogMC44cmVtIDEuMnJlbSAwLjhyZW0gNHJlbTtcbiAgICAgIGJvcmRlci1ib3R0b206IDAuMXJlbSBzb2xpZCB0cmFuc3BhcmVudGl6ZSgkY2xyLWJsdWUtYTIwMCwgMC45KTtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50aXplKCRjbHItYmx1ZS1hMjAwLCAwLjkpO1xuICAgICAgZm9udC13ZWlnaHQ6IDcwMDtcblxuICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICBwYWRkaW5nOiAwLjhyZW0gNHJlbSAwLjhyZW0gMS4ycmVtO1xuICAgICAgfVxuXG4gICAgICAvLyBSZXNldCBzcGFjaW5nLCBpZiB0aXRsZSBpcyB0aGUgb25seSBlbGVtZW50XG4gICAgICAmOmxhc3QtY2hpbGQge1xuICAgICAgICBtYXJnaW4tYm90dG9tOiAwO1xuICAgICAgfVxuXG4gICAgICAvLyBJY29uXG4gICAgICAmOjpiZWZvcmUge1xuICAgICAgICBAZXh0ZW5kICVtZC1pY29uO1xuXG4gICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgbGVmdDogMS4ycmVtO1xuICAgICAgICBjb2xvcjogJGNsci1ibHVlLWEyMDA7XG4gICAgICAgIGZvbnQtc2l6ZTogMnJlbTtcbiAgICAgICAgY29udGVudDogXCJcXEUzQzlcIjsgLy8gZWRpdFxuXG4gICAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICAgIHJpZ2h0OiAxLjJyZW07XG4gICAgICAgICAgbGVmdDogaW5pdGlhbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEJ1aWxkIHJlcHJlc2VudGF0aW9uYWwgY2xhc3Nlc1xuICAgIEBlYWNoICRuYW1lcywgJGFwcGVhcmFuY2UgaW4gKFxuICAgICAgYWJzdHJhY3Qgc3VtbWFyeSB0bGRyOiAkY2xyLWxpZ2h0LWJsdWUtYTQwMCBcIlxcRThEMlwiLCAvLyBzdWJqZWN0XG4gICAgICBpbmZvIHRvZG86ICRjbHItY3lhbi1hNzAwIFwiXFxFODhFXCIsIC8vIGluZm9cbiAgICAgIHRpcCBoaW50IGltcG9ydGFudCA6ICRjbHItdGVhbC1hNzAwIFwiXFxFODBFXCIsIC8vIHdoYXRzaG90XG4gICAgICBzdWNjZXNzIGNoZWNrIGRvbmU6ICRjbHItZ3JlZW4tYTcwMCBcIlxcRTg3NlwiLCAvLyBkb25lXG4gICAgICBxdWVzdGlvbiBoZWxwIGZhcTogJGNsci1saWdodC1ncmVlbi1hNzAwIFwiXFxFODg3XCIsIC8vIGhlbHBcbiAgICAgIHdhcm5pbmcgY2F1dGlvbiBhdHRlbnRpb246ICRjbHItb3JhbmdlLWE0MDAgXCJcXEUwMDJcIiwgLy8gd2FybmluZ1xuICAgICAgZmFpbHVyZSBmYWlsIG1pc3Npbmc6ICRjbHItcmVkLWEyMDAgXCJcXEUxNENcIiwgLy8gY2xlYXJcbiAgICAgIGRhbmdlciBlcnJvcjogJGNsci1yZWQtYTQwMCBcIlxcRTNFN1wiLCAvLyBmbGFzaF9vblxuICAgICAgYnVnOiAkY2xyLXBpbmstYTQwMCBcIlxcRTg2OFwiLCAvLyBidWdfcmVwb3J0XG4gICAgICBleGFtcGxlOiAkY2xyLWRlZXAtcHVycGxlLWE0MDAgXCJcXEUyNDJcIiwgLy8gZm9ybWF0X2xpc3RfbnVtYmVyZWRcbiAgICAgIHF1b3RlIGNpdGU6ICRjbHItZ3JleSBcIlxcRTI0NFwiIC8vIGZvcm1hdF9xdW90ZVxuICAgICkge1xuICAgICAgJHRpbnQ6IG50aCgkYXBwZWFyYW5jZSwgMSk7XG4gICAgICAkaWNvbjogbnRoKCRhcHBlYXJhbmNlLCAyKTtcblxuICAgICAgLy8gRGVmaW5lIGJhc2UgY2xhc3NcbiAgICAgICYlI3tudGgoJG5hbWVzLCAxKX0sXG4gICAgICAmLiN7bnRoKCRuYW1lcywgMSl9IHtcbiAgICAgICAgYm9yZGVyLWxlZnQtY29sb3I6ICR0aW50O1xuXG4gICAgICAgIC8vIEFkanVzdCBmb3IgUlRMIGxhbmd1YWdlc1xuICAgICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICAgIGJvcmRlci1yaWdodC1jb2xvcjogJHRpbnQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUaXRsZVxuICAgICAgICA+IC5hZG1vbml0aW9uLXRpdGxlIHtcbiAgICAgICAgICBib3JkZXItYm90dG9tLWNvbG9yOiAwLjFyZW0gc29saWQgdHJhbnNwYXJlbnRpemUoJHRpbnQsIDAuOSk7XG4gICAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnRpemUoJHRpbnQsIDAuOSk7XG5cbiAgICAgICAgICAvLyBJY29uXG4gICAgICAgICAgJjo6YmVmb3JlIHtcbiAgICAgICAgICAgIGNvbG9yOiAkdGludDtcbiAgICAgICAgICAgIGNvbnRlbnQ6ICRpY29uO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBEZWZpbmUgc3lub255bXMgZm9yIGJhc2UgY2xhc3NcbiAgICAgIEBpZiBsZW5ndGgoJG5hbWVzKSA+IDEge1xuICAgICAgICBAZm9yICRuIGZyb20gMiB0aHJvdWdoIGxlbmd0aCgkbmFtZXMpIHtcbiAgICAgICAgICAmLiN7bnRoKCRuYW1lcywgJG4pfSB7XG4gICAgICAgICAgICBAZXh0ZW5kIC5hZG1vbml0aW9uJSN7bnRoKCRuYW1lcywgMSl9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9leHRlbnNpb25zL19hZG1vbml0aW9uLnNjc3MiLCIvLy8vXG4vLy8gQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuLy8vXG4vLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksXG4vLy8gdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvblxuLy8vIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLFxuLy8vIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZVxuLy8vIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vLy9cbi8vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy8vXG4vLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTFxuLy8vIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbi8vLyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSXG4vLy8gREVBTElOR1Ncbi8vLy9cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVmFyaWFibGVzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIE9wZXJhdG9yc1xuJGNvZGVoaWxpdGUtb3BlcmF0b3I6IGluaGVyaXQ7XG4kY29kZWhpbGl0ZS1vcGVyYXRvci13b3JkOiBpbmhlcml0O1xuXG4vLyBHZW5lcmljc1xuJGNvZGVoaWxpdGUtZ2VuZXJpYy1lbXBoOiAjMDAwMDAwO1xuJGNvZGVoaWxpdGUtZ2VuZXJpYy1lcnJvcjogI0FBMDAwMDtcbiRjb2RlaGlsaXRlLWdlbmVyaWMtaGVhZGluZzogIzk5OTk5OTtcbiRjb2RlaGlsaXRlLWdlbmVyaWMtb3V0cHV0OiAjODg4ODg4O1xuJGNvZGVoaWxpdGUtZ2VuZXJpYy1wcm9tcHQ6ICM1NTU1NTU7XG4kY29kZWhpbGl0ZS1nZW5lcmljLXN0cm9uZzogaW5oZXJpdDtcbiRjb2RlaGlsaXRlLWdlbmVyaWMtc3ViaGVhZGluZzogI0FBQUFBQTtcbiRjb2RlaGlsaXRlLWdlbmVyaWMtdHJhY2ViYWNrOiAjQUEwMDAwO1xuXG4vLyBEaWZmc1xuJGNvZGVoaWxpdGUtZGlmZi1kZWxldGVkOiAjRkZEREREO1xuJGNvZGVoaWxpdGUtZGlmZi1pbnNlcnRlZDogI0RERkZERDtcblxuLy8gS2V5d29yZHNcbiRjb2RlaGlsaXRlLWtleXdvcmQ6ICMzQjc4RTc7XG4kY29kZWhpbGl0ZS1rZXl3b3JkLWNvbnN0YW50OiAjQTcxRDVEO1xuJGNvZGVoaWxpdGUta2V5d29yZC1kZWNsYXJhdGlvbjogIzNCNzhFNztcbiRjb2RlaGlsaXRlLWtleXdvcmQtbmFtZXNwYWNlOiAjM0I3OEU3O1xuJGNvZGVoaWxpdGUta2V5d29yZC1wc2V1ZG86ICNBNzFENUQ7XG4kY29kZWhpbGl0ZS1rZXl3b3JkLXJlc2VydmVkOiAjM0U2MUEyO1xuJGNvZGVoaWxpdGUta2V5d29yZC10eXBlOiAjM0U2MUEyO1xuXG4vLyBDb21tZW50c1xuJGNvZGVoaWxpdGUtY29tbWVudDogIzk5OTk5OTtcbiRjb2RlaGlsaXRlLWNvbW1lbnQtbXVsdGlsaW5lOiAjOTk5OTk5O1xuJGNvZGVoaWxpdGUtY29tbWVudC1wcmVwcm9jOiAjNjY2NjY2O1xuJGNvZGVoaWxpdGUtY29tbWVudC1zaW5nbGU6ICM5OTk5OTk7XG4kY29kZWhpbGl0ZS1jb21tZW50LXNoZWJhbmc6ICM5OTk5OTk7XG4kY29kZWhpbGl0ZS1jb21tZW50LXNwZWNpYWw6ICM5OTk5OTk7XG5cbi8vIE5hbWVzXG4kY29kZWhpbGl0ZS1uYW1lLWF0dHJpYnV0ZTogI0MyMTg1QjtcbiRjb2RlaGlsaXRlLW5hbWUtYnVpbHRpbjogI0MyMTg1QjtcbiRjb2RlaGlsaXRlLW5hbWUtYnVpbHRpbi1wc2V1ZG86ICMzRTYxQTI7XG4kY29kZWhpbGl0ZS1uYW1lLWNsYXNzOiAjQzIxODVCO1xuJGNvZGVoaWxpdGUtbmFtZS1jb25zdGFudDogIzNFNjFBMjtcbiRjb2RlaGlsaXRlLW5hbWUtZGVjb3JhdG9yOiAjNjY2NjY2O1xuJGNvZGVoaWxpdGUtbmFtZS1lbnRpdHk6ICM2NjY2NjY7XG4kY29kZWhpbGl0ZS1uYW1lLWV4Y2VwdGlvbjogI0MyMTg1QjtcbiRjb2RlaGlsaXRlLW5hbWUtZnVuY3Rpb246ICNDMjE4NUI7XG4kY29kZWhpbGl0ZS1uYW1lLWxhYmVsOiAjM0I1MTc5O1xuJGNvZGVoaWxpdGUtbmFtZS1uYW1lc3BhY2U6ICNFQzQwN0E7XG4kY29kZWhpbGl0ZS1uYW1lLXRhZzogIzNCNzhFNztcbiRjb2RlaGlsaXRlLW5hbWUtdmFyaWFibGU6ICMzRTYxQTI7XG4kY29kZWhpbGl0ZS1uYW1lLXZhcmlhYmxlLWNsYXNzOiAjM0U2MUEyO1xuJGNvZGVoaWxpdGUtbmFtZS12YXJpYWJsZS1pbnN0YW5jZTogIzNFNjFBMjtcbiRjb2RlaGlsaXRlLW5hbWUtdmFyaWFibGUtZ2xvYmFsOiAjM0U2MUEyO1xuJGNvZGVoaWxpdGUtbmFtZS1leHRlbnNpb246ICNFQzQwN0E7XG5cbi8vIE51bWJlcnNcbiRjb2RlaGlsaXRlLWxpdGVyYWwtbnVtYmVyOiAjRTc0QzNDO1xuJGNvZGVoaWxpdGUtbGl0ZXJhbC1udW1iZXItZmxvYXQ6ICNFNzRDM0M7XG4kY29kZWhpbGl0ZS1saXRlcmFsLW51bWJlci1oZXg6ICNFNzRDM0M7XG4kY29kZWhpbGl0ZS1saXRlcmFsLW51bWJlci1pbnRlZ2VyOiAjRTc0QzNDO1xuJGNvZGVoaWxpdGUtbGl0ZXJhbC1udW1iZXItaW50ZWdlci1sb25nOiAjRTc0QzNDO1xuJGNvZGVoaWxpdGUtbGl0ZXJhbC1udW1iZXItb2N0OiAjRTc0QzNDO1xuXG4vLyBTdHJpbmdzXG4kY29kZWhpbGl0ZS1saXRlcmFsLXN0cmluZzogIzBEOTA0RjtcbiRjb2RlaGlsaXRlLWxpdGVyYWwtc3RyaW5nLWJhY2t0aWNrczogIzBEOTA0RjtcbiRjb2RlaGlsaXRlLWxpdGVyYWwtc3RyaW5nLWNoYXI6ICMwRDkwNEY7XG4kY29kZWhpbGl0ZS1saXRlcmFsLXN0cmluZy1kb2M6ICM5OTk5OTk7XG4kY29kZWhpbGl0ZS1saXRlcmFsLXN0cmluZy1kb3VibGU6ICMwRDkwNEY7XG4kY29kZWhpbGl0ZS1saXRlcmFsLXN0cmluZy1lc2NhcGU6ICMxODM2OTE7XG4kY29kZWhpbGl0ZS1saXRlcmFsLXN0cmluZy1oZXJlZG9jOiAjMTgzNjkxO1xuJGNvZGVoaWxpdGUtbGl0ZXJhbC1zdHJpbmctaW50ZXJwb2w6ICMxODM2OTE7XG4kY29kZWhpbGl0ZS1saXRlcmFsLXN0cmluZy1vdGhlcjogIzE4MzY5MTtcbiRjb2RlaGlsaXRlLWxpdGVyYWwtc3RyaW5nLXJlZ2V4OiAjMDA5OTI2O1xuJGNvZGVoaWxpdGUtbGl0ZXJhbC1zdHJpbmctc2luZ2xlOiAjMEQ5MDRGO1xuJGNvZGVoaWxpdGUtbGl0ZXJhbC1zdHJpbmctc3ltYm9sOiAjMEQ5MDRGO1xuXG4vLyBNaXNjZWxsYW5lb3VzXG4kY29kZWhpbGl0ZS1lcnJvcjogI0E2MTcxNztcbiRjb2RlaGlsaXRlLXdoaXRlc3BhY2U6IHRyYW5zcGFyZW50O1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBSdWxlczogc3ludGF4IGhpZ2hsaWdodGluZ1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBDb2RlaGlsaXRlIGV4dGVuc2lvblxuLmNvZGVoaWxpdGUge1xuXG4gIC8vIE9wZXJhdG9yc1xuICAubyAgeyBjb2xvcjogJGNvZGVoaWxpdGUtb3BlcmF0b3I7IH1cbiAgLm93IHsgY29sb3I6ICRjb2RlaGlsaXRlLW9wZXJhdG9yLXdvcmQ7IH1cblxuICAvLyBHZW5lcmljc1xuICAuZ2UgeyBjb2xvcjogJGNvZGVoaWxpdGUtZ2VuZXJpYy1lbXBoOyB9XG4gIC5nciB7IGNvbG9yOiAkY29kZWhpbGl0ZS1nZW5lcmljLWVycm9yOyB9XG4gIC5naCB7IGNvbG9yOiAkY29kZWhpbGl0ZS1nZW5lcmljLWhlYWRpbmc7IH1cbiAgLmdvIHsgY29sb3I6ICRjb2RlaGlsaXRlLWdlbmVyaWMtb3V0cHV0OyB9XG4gIC5ncCB7IGNvbG9yOiAkY29kZWhpbGl0ZS1nZW5lcmljLXByb21wdDsgfVxuICAuZ3MgeyBjb2xvcjogJGNvZGVoaWxpdGUtZ2VuZXJpYy1zdHJvbmc7IH1cbiAgLmd1IHsgY29sb3I6ICRjb2RlaGlsaXRlLWdlbmVyaWMtc3ViaGVhZGluZzsgfVxuICAuZ3QgeyBjb2xvcjogJGNvZGVoaWxpdGUtZ2VuZXJpYy10cmFjZWJhY2s7IH1cblxuICAvLyBEaWZmc1xuICAuZ2QgeyBiYWNrZ3JvdW5kLWNvbG9yOiAkY29kZWhpbGl0ZS1kaWZmLWRlbGV0ZWQ7IH1cbiAgLmdpIHsgYmFja2dyb3VuZC1jb2xvcjogJGNvZGVoaWxpdGUtZGlmZi1pbnNlcnRlZDsgfVxuXG4gIC8vIEtleXdvcmRzXG4gIC5rICB7IGNvbG9yOiAkY29kZWhpbGl0ZS1rZXl3b3JkOyB9XG4gIC5rYyB7IGNvbG9yOiAkY29kZWhpbGl0ZS1rZXl3b3JkLWNvbnN0YW50OyB9XG4gIC5rZCB7IGNvbG9yOiAkY29kZWhpbGl0ZS1rZXl3b3JkLWRlY2xhcmF0aW9uOyB9XG4gIC5rbiB7IGNvbG9yOiAkY29kZWhpbGl0ZS1rZXl3b3JkLW5hbWVzcGFjZTsgfVxuICAua3AgeyBjb2xvcjogJGNvZGVoaWxpdGUta2V5d29yZC1wc2V1ZG87IH1cbiAgLmtyIHsgY29sb3I6ICRjb2RlaGlsaXRlLWtleXdvcmQtcmVzZXJ2ZWQ7IH1cbiAgLmt0IHsgY29sb3I6ICRjb2RlaGlsaXRlLWtleXdvcmQtdHlwZTsgfVxuXG4gIC8vIENvbW1lbnRzXG4gIC5jICB7IGNvbG9yOiAkY29kZWhpbGl0ZS1jb21tZW50OyB9XG4gIC5jbSB7IGNvbG9yOiAkY29kZWhpbGl0ZS1jb21tZW50LW11bHRpbGluZTsgfVxuICAuY3AgeyBjb2xvcjogJGNvZGVoaWxpdGUtY29tbWVudC1wcmVwcm9jOyB9XG4gIC5jMSB7IGNvbG9yOiAkY29kZWhpbGl0ZS1jb21tZW50LXNpbmdsZTsgfVxuICAuY2ggeyBjb2xvcjogJGNvZGVoaWxpdGUtY29tbWVudC1zaGViYW5nOyB9XG4gIC5jcyB7IGNvbG9yOiAkY29kZWhpbGl0ZS1jb21tZW50LXNwZWNpYWw7IH1cblxuICAvLyBOYW1lc1xuICAubmEgeyBjb2xvcjogJGNvZGVoaWxpdGUtbmFtZS1hdHRyaWJ1dGU7IH1cbiAgLm5iIHsgY29sb3I6ICRjb2RlaGlsaXRlLW5hbWUtYnVpbHRpbjsgfVxuICAuYnAgeyBjb2xvcjogJGNvZGVoaWxpdGUtbmFtZS1idWlsdGluLXBzZXVkbzsgfVxuICAubmMgeyBjb2xvcjogJGNvZGVoaWxpdGUtbmFtZS1jbGFzczsgfVxuICAubm8geyBjb2xvcjogJGNvZGVoaWxpdGUtbmFtZS1jb25zdGFudDsgfVxuICAubmQgeyBjb2xvcjogJGNvZGVoaWxpdGUtbmFtZS1lbnRpdHk7IH1cbiAgLm5pIHsgY29sb3I6ICRjb2RlaGlsaXRlLW5hbWUtZW50aXR5OyB9XG4gIC5uZSB7IGNvbG9yOiAkY29kZWhpbGl0ZS1uYW1lLWV4Y2VwdGlvbjsgfVxuICAubmYgeyBjb2xvcjogJGNvZGVoaWxpdGUtbmFtZS1mdW5jdGlvbjsgfVxuICAubmwgeyBjb2xvcjogJGNvZGVoaWxpdGUtbmFtZS1sYWJlbDsgfVxuICAubm4geyBjb2xvcjogJGNvZGVoaWxpdGUtbmFtZS1uYW1lc3BhY2U7IH1cbiAgLm50IHsgY29sb3I6ICRjb2RlaGlsaXRlLW5hbWUtdGFnOyB9XG4gIC5udiB7IGNvbG9yOiAkY29kZWhpbGl0ZS1uYW1lLXZhcmlhYmxlOyB9XG4gIC52YyB7IGNvbG9yOiAkY29kZWhpbGl0ZS1uYW1lLXZhcmlhYmxlLWNsYXNzOyB9XG4gIC52ZyB7IGNvbG9yOiAkY29kZWhpbGl0ZS1uYW1lLXZhcmlhYmxlLWdsb2JhbDsgfVxuICAudmkgeyBjb2xvcjogJGNvZGVoaWxpdGUtbmFtZS12YXJpYWJsZS1pbnN0YW5jZTsgfVxuICAubnggeyBjb2xvcjogJGNvZGVoaWxpdGUtbmFtZS1leHRlbnNpb247IH1cblxuICAvLyBOdW1iZXJzXG4gIC5tICB7IGNvbG9yOiAkY29kZWhpbGl0ZS1saXRlcmFsLW51bWJlcjsgfVxuICAubWYgeyBjb2xvcjogJGNvZGVoaWxpdGUtbGl0ZXJhbC1udW1iZXItZmxvYXQ7IH1cbiAgLm1oIHsgY29sb3I6ICRjb2RlaGlsaXRlLWxpdGVyYWwtbnVtYmVyLWhleDsgfVxuICAubWkgeyBjb2xvcjogJGNvZGVoaWxpdGUtbGl0ZXJhbC1udW1iZXItaW50ZWdlcjsgfVxuICAuaWwgeyBjb2xvcjogJGNvZGVoaWxpdGUtbGl0ZXJhbC1udW1iZXItaW50ZWdlci1sb25nOyB9XG4gIC5tbyB7IGNvbG9yOiAkY29kZWhpbGl0ZS1saXRlcmFsLW51bWJlci1vY3Q7IH1cblxuICAvLyBTdHJpbmdzXG4gIC5zICB7IGNvbG9yOiAkY29kZWhpbGl0ZS1saXRlcmFsLXN0cmluZzsgfVxuICAuc2IgeyBjb2xvcjogJGNvZGVoaWxpdGUtbGl0ZXJhbC1zdHJpbmctYmFja3RpY2tzOyB9XG4gIC5zYyB7IGNvbG9yOiAkY29kZWhpbGl0ZS1saXRlcmFsLXN0cmluZy1jaGFyOyB9XG4gIC5zZCB7IGNvbG9yOiAkY29kZWhpbGl0ZS1saXRlcmFsLXN0cmluZy1kb2M7IH1cbiAgLnMyIHsgY29sb3I6ICRjb2RlaGlsaXRlLWxpdGVyYWwtc3RyaW5nLWRvdWJsZTsgfVxuICAuc2UgeyBjb2xvcjogJGNvZGVoaWxpdGUtbGl0ZXJhbC1zdHJpbmctZXNjYXBlOyB9XG4gIC5zaCB7IGNvbG9yOiAkY29kZWhpbGl0ZS1saXRlcmFsLXN0cmluZy1oZXJlZG9jOyB9XG4gIC5zaSB7IGNvbG9yOiAkY29kZWhpbGl0ZS1saXRlcmFsLXN0cmluZy1pbnRlcnBvbDsgfVxuICAuc3ggeyBjb2xvcjogJGNvZGVoaWxpdGUtbGl0ZXJhbC1zdHJpbmctb3RoZXI7IH1cbiAgLnNyIHsgY29sb3I6ICRjb2RlaGlsaXRlLWxpdGVyYWwtc3RyaW5nLXJlZ2V4OyB9XG4gIC5zMSB7IGNvbG9yOiAkY29kZWhpbGl0ZS1saXRlcmFsLXN0cmluZy1zaW5nbGU7IH1cbiAgLnNzIHsgY29sb3I6ICRjb2RlaGlsaXRlLWxpdGVyYWwtc3RyaW5nLXN5bWJvbDsgfVxuXG4gIC8vIE1pc2NlbGxhbmVvdXNcbiAgLmVyciB7IGNvbG9yOiAkY29kZWhpbGl0ZS1lcnJvcjsgfVxuICAudyB7IGNvbG9yOiAkY29kZWhpbGl0ZS13aGl0ZXNwYWNlOyB9XG5cbiAgLy8gSGlnaGxpZ2h0ZWQgbGluZXNcbiAgLmhsbCB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgbWFyZ2luOiAwIC0xLjJyZW07XG4gICAgcGFkZGluZzogMCAxLjJyZW07XG4gICAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnRpemUoJGNsci15ZWxsb3ctNTAwLCAwLjUpO1xuXG4gICAgLy8gW21vYmlsZSAtXTogU3RyZXRjaCB0byB3aG9sZSB3aWR0aFxuICAgIEBpbmNsdWRlIGJyZWFrLXRvLWRldmljZShtb2JpbGUpIHtcbiAgICAgIG1hcmdpbjogMCAtMS42cmVtO1xuICAgICAgcGFkZGluZzogMCAxLjZyZW07XG4gICAgfVxuICB9XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzOiBsYXlvdXRcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gU2NvcGVkIGluIHR5cGVzZXR0ZWQgY29udGVudCB0byBtYXRjaCBzcGVjaWZpY2l0eSBvZiByZWd1bGFyIGNvbnRlbnRcbi5tZC10eXBlc2V0IHtcblxuICAvLyBJZiBjb2RlIGJsb2NrcyBhcmUgd3JhcHBlZCB3aXRoIGNvZGVoaWxpdGUsIHRoZSBzdHlsZXMgbXVzdCBiZSBhZGp1c3RlZFxuICAvLyBzbyB0aGUgbWFya2VyIHN0cmV0Y2hlcyB0byB0aGUgd2hvbGUgd2lkdGggYW5kIHRoZSBwYWRkaW5nIGlzIHJlc3BlY3RlZFxuICAuY29kZWhpbGl0ZSB7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIG1hcmdpbjogMWVtIDA7XG4gICAgcGFkZGluZzogMDtcbiAgICBib3JkZXItcmFkaXVzOiAwLjJyZW07XG4gICAgYmFja2dyb3VuZC1jb2xvcjogJG1kLWNvZGUtYmFja2dyb3VuZDtcbiAgICBjb2xvcjogJG1kLWNvZGUtY29sb3I7XG4gICAgbGluZS1oZWlnaHQ6IDEuNDtcbiAgICAtd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzogdG91Y2g7XG5cbiAgICAvLyBBY3R1YWwgY29udGFpbmVyIHdpdGggY29kZSwgb3ZlcmZsb3dpbmdcbiAgICBwcmUsXG4gICAgY29kZSB7XG4gICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgIG1hcmdpbjogMDtcbiAgICAgIHBhZGRpbmc6IDEuMDVyZW0gMS4ycmVtO1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gICAgICBvdmVyZmxvdzogYXV0bztcbiAgICAgIHZlcnRpY2FsLWFsaWduOiB0b3A7XG5cbiAgICAgIC8vIE92ZXJyaWRlIG5hdGl2ZSBzY3JvbGxiYXIgc3R5bGVzXG4gICAgICAmOjotd2Via2l0LXNjcm9sbGJhciB7XG4gICAgICAgIHdpZHRoOiAwLjRyZW07XG4gICAgICAgIGhlaWdodDogMC40cmVtO1xuICAgICAgfVxuXG4gICAgICAvLyBTdHlsZSBzY3JvbGxiYXIgdGh1bWJcbiAgICAgICY6Oi13ZWJraXQtc2Nyb2xsYmFyLXRodW1iIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogJG1kLWNvbG9yLWJsYWNrLS1saWdodGVyO1xuXG4gICAgICAgIC8vIEhvdmVyZWQgc2Nyb2xsYmFyIHRodW1iXG4gICAgICAgICY6aG92ZXIge1xuICAgICAgICAgIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2xvci1hY2NlbnQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBJZiBub3QgdXNpbmcgUHlnbWVudHMsIGNvZGUgd2lsbCBiZSB1bmRlciBwcmUgPiBjb2RlXG4gIHByZS5jb2RlaGlsaXRlIHtcbiAgICBvdmVyZmxvdzogdmlzaWJsZTtcblxuICAgIC8vIEFjdHVhbCBjb250YWluZXIgd2l0aCBjb2RlLCBvdmVyZmxvd2luZ1xuICAgIGNvZGUge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICBwYWRkaW5nOiAxLjA1cmVtIDEuMnJlbTtcbiAgICAgIG92ZXJmbG93OiBhdXRvO1xuICAgIH1cbiAgfVxuXG4gIC8vIEJsb2NrIHdpdGggbGluZSBudW1iZXJzXG4gIC5jb2RlaGlsaXRldGFibGUge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIG1hcmdpbjogMWVtIDA7XG4gICAgYm9yZGVyLXJhZGl1czogMC4yZW07XG4gICAgZm9udC1zaXplOiBtcygwKTtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuXG4gICAgLy8gU2V0IHRhYmxlIGVsZW1lbnRzIHRvIGJsb2NrIGxheW91dCwgYmVjYXVzZSBvdGhlcndpc2UgdGhlIHdob2xlIGZsZXhib3hcbiAgICAvLyBoYWNraW5nIHdvbid0IHdvcmsgY29ycmVjdGx5XG4gICAgdGJvZHksXG4gICAgdGQge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICBwYWRkaW5nOiAwO1xuICAgIH1cblxuICAgIC8vIFdlIG5lZWQgdG8gdXNlIGZsZXhib3ggbGF5b3V0LCBiZWNhdXNlIG90aGVyd2lzZSBpdCdzIG5vdCBwb3NzaWJsZSB0b1xuICAgIC8vIG1ha2UgdGhlIGNvZGUgY29udGFpbmVyIHNjcm9sbCB3aGlsZSBrZWVwaW5nIHRoZSBsaW5lIG51bWJlcnMgc3RhdGljXG4gICAgdHIge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICB9XG5cbiAgICAvLyBUaGUgcHJlIHRhZ3MgYXJlIG5lc3RlZCBpbnNpZGUgYSB0YWJsZSwgc28gd2UgbmVlZCB0byByZW1vdmUgdGhlXG4gICAgLy8gbWFyZ2luIGJlY2F1c2UgaXQgY29sbGFwc2VzIGJlbG93IGFsbCB0aGUgb3ZlcmZsb3dzXG4gICAgLmNvZGVoaWxpdGUsXG4gICAgLmxpbmVub2RpdiB7XG4gICAgICBtYXJnaW46IDA7XG4gICAgICBib3JkZXItcmFkaXVzOiAwO1xuICAgIH1cblxuICAgIC8vIEFkZCBzcGFjaW5nIHRvIGxpbmUgbnVtYmVyIGNvbnRhaW5lclxuICAgIC5saW5lbm9kaXYge1xuICAgICAgcGFkZGluZzogMS4wNXJlbSAxLjJyZW07XG4gICAgfVxuXG4gICAgLy8gRGlzYWJsZSB1c2VyIHNlbGVjdGlvbiwgc28gY29kZSBjYW4gYmUgZWFzaWx5IGNvcGllZCB3aXRob3V0XG4gICAgLy8gYWNjaWRlbnRhbGx5IGFsc28gY29weWluZyB0aGUgbGluZSBudW1iZXJzXG4gICAgLmxpbmVub3Mge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogJG1kLWNvbG9yLWJsYWNrLS1saWdodGVzdDtcbiAgICAgIGNvbG9yOiAkbWQtY29sb3ItYmxhY2stLWxpZ2h0ZXI7XG4gICAgICB1c2VyLXNlbGVjdDogbm9uZTtcblxuICAgICAgLy8gUmVzZXQgc3BhY2luZ3NcbiAgICAgIHByZSB7XG4gICAgICAgIG1hcmdpbjogMDtcbiAgICAgICAgcGFkZGluZzogMDtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gICAgICAgIGNvbG9yOiBpbmhlcml0O1xuICAgICAgICB0ZXh0LWFsaWduOiByaWdodDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBUaGUgdGFibGUgY2VsbCBjb250YWluaW5nIHRoZSBjb2RlIGNvbnRhaW5lciB3cmFwcGVyIGFuZCBjb2RlIHNob3VsZFxuICAgIC8vIHN0cmV0Y2ggaG9yaXpvbnRhbGx5IHRvIHRoZSByZW1haW5pbmcgc3BhY2VcbiAgICAuY29kZSB7XG4gICAgICBmbGV4OiAxO1xuICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICB9XG4gIH1cblxuICAvLyBGdWxsLXdpZHRoIGNvbnRhaW5lclxuICA+IC5jb2RlaGlsaXRlIHtcblxuICAgIC8vIFttb2JpbGUgLV06IFN0cmV0Y2ggdG8gd2hvbGUgd2lkdGhcbiAgICBAaW5jbHVkZSBicmVhay10by1kZXZpY2UobW9iaWxlKSB7XG4gICAgICBtYXJnaW46IDFlbSAtMS42cmVtO1xuICAgICAgYm9yZGVyLXJhZGl1czogMDtcblxuICAgICAgLy8gQWN0dWFsIGNvbnRhaW5lciB3aXRoIGNvZGUsIG92ZXJmbG93aW5nXG4gICAgICBwcmUsXG4gICAgICBjb2RlIHtcbiAgICAgICAgcGFkZGluZzogMS4wNXJlbSAxLjZyZW07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gRnVsbC13aWR0aCBjb250YWluZXIgb24gdG9wLWxldmVsXG4gID4gLmNvZGVoaWxpdGV0YWJsZSB7XG4gICAgYm94LXNoYWRvdzogbm9uZTtcblxuICAgIC8vIFttb2JpbGUgLV06IFN0cmV0Y2ggdG8gd2hvbGUgd2lkdGhcbiAgICBAaW5jbHVkZSBicmVhay10by1kZXZpY2UobW9iaWxlKSB7XG4gICAgICBtYXJnaW46IDFlbSAtMS42cmVtO1xuICAgICAgYm9yZGVyLXJhZGl1czogMDtcblxuICAgICAgLy8gSW5jcmVhc2Ugc3BhY2luZ1xuICAgICAgLmNvZGVoaWxpdGUgPiBwcmUsXG4gICAgICAuY29kZWhpbGl0ZSA+IGNvZGUsXG4gICAgICAubGluZW5vZGl2IHtcbiAgICAgICAgcGFkZGluZzogMXJlbSAxLjZyZW07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gV2hlbiBweW1kb3dueC5zdXBlcmZlbmNlcyBpcyBlbmFibGVkIGJ1dCBjb2RlaGlsaXRlIGlzIGRpc2FibGVkLFxuICAvLyBweW1kb3dueC5oaWdobGlnaHQgd2lsbCBiZSB1c2VkLiBXaGVuIHRoaXMgaGFwcGVucywgdGhlIG91dGVyXG4gIC8vIGNvbnRhaW5lciBhbmQgdGFibGVzIGdldCB0aGlzIGNsYXNzIG5hbWVzIGJ5IGRlZmF1bHQuXG4gIC5oaWdobGlnaHQge1xuICAgIEBleHRlbmQgLmNvZGVoaWxpdGU7XG4gIH1cblxuICAvLyBTYW1lIGFzIGFib3ZlLCBidXQgZm9yIGNvZGUgYmxvY2tzIHdpdGggbGluZSBudW1iZXJzIGVuYWJsZWRcbiAgLmhpZ2hsaWdodHRhYmxlIHtcbiAgICBAZXh0ZW5kIC5jb2RlaGlsaXRldGFibGU7XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvZXh0ZW5zaW9ucy9fY29kZWhpbGl0ZS5zY3NzIiwiLy8vL1xuLy8vIENvcHlyaWdodCAoYykgMjAxNi0yMDE4IE1hcnRpbiBEb25hdGggPG1hcnRpbi5kb25hdGhAc3F1aWRmdW5rLmNvbT5cbi8vL1xuLy8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLFxuLy8vIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb25cbi8vLyB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSxcbi8vLyBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGVcbi8vLyBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy8vXG4vLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vLyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vL1xuLy8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTExcbi8vLyBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuLy8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4vLy8gRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUlxuLy8vIERFQUxJTkdTXG4vLy8vXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIFNjb3BlZCBpbiB0eXBlc2V0dGVkIGNvbnRlbnQgdG8gbWF0Y2ggc3BlY2lmaWNpdHkgb2YgcmVndWxhciBjb250ZW50XG4ubWQtdHlwZXNldCB7XG5cbiAgLy8gQWxsIGZvb3Rub3RlIHJlZmVyZW5jZXNcbiAgW2lkXj1cImZucmVmOlwiXSB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuXG4gICAgLy8gVGFyZ2V0ZWQgYW5jaG9yXG4gICAgJjp0YXJnZXQge1xuICAgICAgbWFyZ2luLXRvcDogLSg0LjhyZW0gKyAxLjJyZW0gKyAxLjZyZW0pO1xuICAgICAgcGFkZGluZy10b3A6ICg0LjhyZW0gKyAxLjJyZW0gKyAxLjZyZW0pO1xuICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG4gICAgfVxuICB9XG5cbiAgLy8gQWxsIGZvb3Rub3RlIGJhY2sgcmVmZXJlbmNlc1xuICBbaWRePVwiZm46XCJdIHtcblxuICAgIC8vIEFkZCBzcGFjaW5nIHRvIGFuY2hvciBmb3Igb2Zmc2V0XG4gICAgJjo6YmVmb3JlIHtcbiAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgICBoZWlnaHQ6IDA7XG4gICAgICBjb250ZW50OiBcIlwiO1xuICAgIH1cblxuICAgIC8vIFRhcmdldGVkIGFuY2hvclxuICAgICY6dGFyZ2V0OjpiZWZvcmUge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgICBtYXJnaW4tdG9wOiAtKDQuOHJlbSArIDEuMnJlbSArIDFyZW0pO1xuICAgICAgcGFkZGluZy10b3A6ICg0LjhyZW0gKyAxLjJyZW0gKyAxcmVtKTtcbiAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgIH1cbiAgfVxuXG4gIC8vIEZvb3Rub3RlcyBleHRlbnNpb25cbiAgLmZvb3Rub3RlIHtcbiAgICBjb2xvcjogJG1kLWNvbG9yLWJsYWNrLS1saWdodDtcbiAgICBmb250LXNpemU6IG1zKC0xKTtcblxuICAgIC8vIFJlbW92ZSBhZGRpdGlvbmFsIHNwYWNpbmcgb24gZm9vdG5vdGVzXG4gICAgb2wge1xuICAgICAgbWFyZ2luLWxlZnQ6IDA7XG4gICAgfVxuXG4gICAgLy8gRm9vdG5vdGVcbiAgICBsaSB7XG4gICAgICB0cmFuc2l0aW9uOiBjb2xvciAwLjI1cztcblxuICAgICAgLy8gRGFya2VuIGNvbG9yIGZvciB0YXJnZXRlZCBmb290bm90ZVxuICAgICAgJjp0YXJnZXQge1xuICAgICAgICBjb2xvcjogJG1kLWNvbG9yLWJsYWNrO1xuICAgICAgfVxuXG4gICAgICAvLyBSZW1vdmUgc3BhY2luZyBvbiBmaXJzdCBlbGVtZW50XG4gICAgICA6Zmlyc3QtY2hpbGQge1xuICAgICAgICBtYXJnaW4tdG9wOiAwO1xuICAgICAgfVxuXG4gICAgICAvLyBNYWtlIGJhY2sgcmVmZXJlbmNlcyB2aXNpYmxlIG9uIGhvdmVyXG4gICAgICAmOmhvdmVyICAuZm9vdG5vdGUtYmFja3JlZixcbiAgICAgICY6dGFyZ2V0IC5mb290bm90ZS1iYWNrcmVmIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDApO1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgICAgfVxuXG4gICAgICAvLyBBY3RpdmUgb3IgdGFyZ2V0ZWQgYmFjayByZWZlcmVuY2VcbiAgICAgICY6aG92ZXIgIC5mb290bm90ZS1iYWNrcmVmOmhvdmVyLFxuICAgICAgJjp0YXJnZXQgLmZvb3Rub3RlLWJhY2tyZWYge1xuICAgICAgICBjb2xvcjogJG1kLWNvbG9yLWFjY2VudDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBGb290bm90ZSByZWZlcmVuY2VcbiAgLmZvb3Rub3RlLXJlZiB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIHBvaW50ZXItZXZlbnRzOiBpbml0aWFsO1xuXG4gICAgLy8gUmVuZGVyIGEgdGhpbiBsaW5lIGJlZm9yZSBmb290bm90ZVxuICAgICY6OmJlZm9yZSB7XG4gICAgICBkaXNwbGF5OiBpbmxpbmU7XG4gICAgICBtYXJnaW46IDAgMC4yZW07XG4gICAgICBib3JkZXItbGVmdDogMC4xcmVtIHNvbGlkICRtZC1jb2xvci1ibGFjay0tbGlnaHRlcjtcbiAgICAgIGZvbnQtc2l6ZTogMS4yNWVtO1xuICAgICAgY29udGVudDogXCJcIjtcbiAgICAgIHZlcnRpY2FsLWFsaWduOiAtMC41cmVtO1xuICAgIH1cbiAgfVxuXG4gIC8vIEZvb3Rub3RlIGJhY2sgcmVmZXJlbmNlXG4gIC5mb290bm90ZS1iYWNrcmVmIHtcbiAgICBAZXh0ZW5kICVtZC1pY29uO1xuXG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgwLjVyZW0pO1xuICAgIHRyYW5zaXRpb246XG4gICAgICB0cmFuc2Zvcm0gMC4yNXMgIDAuMTI1cyxcbiAgICAgIGNvbG9yICAgICAwLjI1cyxcbiAgICAgIG9wYWNpdHkgICAwLjEyNXMgMC4xMjVzO1xuICAgIGNvbG9yOiAkbWQtY29sb3ItYmxhY2stLWxpZ2h0ZXI7XG4gICAgLy8gSGFjazogcmVtb3ZlIFVuaWNvZGUgYXJyb3cgZm9yIGljb25cbiAgICBmb250LXNpemU6IDA7XG4gICAgb3BhY2l0eTogMDtcbiAgICB2ZXJ0aWNhbC1hbGlnbjogdGV4dC1ib3R0b207XG5cbiAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKC0wLjVyZW0pO1xuICAgIH1cblxuICAgIC8vIEJhY2sgcmVmZXJlbmNlIGljb25cbiAgICAmOjpiZWZvcmUge1xuICAgICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgICAgZm9udC1zaXplOiAxLjZyZW07XG4gICAgICBjb250ZW50OiBcIlxcRTMxQlwiOyAvLyBrZXlib2FyZF9yZXR1cm5cblxuICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICB0cmFuc2Zvcm06IHNjYWxlWCgtMSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvZXh0ZW5zaW9ucy9fZm9vdG5vdGVzLnNjc3MiLCIvLy8vXG4vLy8gQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuLy8vXG4vLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksXG4vLy8gdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvblxuLy8vIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLFxuLy8vIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZVxuLy8vIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vLy9cbi8vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy8vXG4vLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTFxuLy8vIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbi8vLyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSXG4vLy8gREVBTElOR1Ncbi8vLy9cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUnVsZXNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gU2NvcGVkIGluIHR5cGVzZXR0ZWQgY29udGVudCB0byBtYXRjaCBzcGVjaWZpY2l0eSBvZiByZWd1bGFyIGNvbnRlbnRcbi5tZC10eXBlc2V0IHtcblxuICAvLyBQZXJtYWxpbmtzIGV4dGVuc2lvblxuICAuaGVhZGVybGluayB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIG1hcmdpbi1sZWZ0OiAxcmVtO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlKDAsIDAuNXJlbSk7XG4gICAgdHJhbnNpdGlvbjpcbiAgICAgIHRyYW5zZm9ybSAwLjI1cyAgMC4yNXMsXG4gICAgICBjb2xvciAgICAgMC4yNXMsXG4gICAgICBvcGFjaXR5ICAgMC4xMjVzIDAuMjVzO1xuICAgIG9wYWNpdHk6IDA7XG5cbiAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgbWFyZ2luLXJpZ2h0OiAxcmVtO1xuICAgICAgbWFyZ2luLWxlZnQ6IGluaXRpYWw7XG4gICAgfVxuXG4gICAgLy8gSGlnaGVyIHNwZWNpZmljaXR5IGZvciBjb2xvciBkdWUgdG8gcGFsZXR0ZXMgaW50ZWdyYXRpb25cbiAgICBodG1sIGJvZHkgJiB7XG4gICAgICBjb2xvcjogJG1kLWNvbG9yLWJsYWNrLS1saWdodGVyO1xuICAgIH1cblxuICAgIC8vIEhpZGUgZm9yIHByaW50XG4gICAgQG1lZGlhIHByaW50IHtcbiAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgfVxuICB9XG5cbiAgLy8gQ29ycmVjdCBhbmNob3Igb2Zmc2V0IGZvciBsaW5rIGJsdXJyaW5nXG4gIEBlYWNoICRsZXZlbCwgJGRlbHRhIGluIChcbiAgICBoMTogMC45cmVtLFxuICAgIGgyOiAwLjhyZW0sXG4gICAgaDM6IDAuOXJlbSxcbiAgICBoNDogMC45cmVtLFxuICAgIGg1OiAxLjFyZW0sXG4gICAgaDY6IDEuMXJlbVxuICApIHtcbiAgICAjeyRsZXZlbH1baWRdIHtcblxuICAgICAgLy8gVW4tdGFyZ2V0ZWQgYW5jaG9yXG4gICAgICAmOjpiZWZvcmUge1xuICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgbWFyZ2luLXRvcDogLSRkZWx0YTtcbiAgICAgICAgcGFkZGluZy10b3A6ICRkZWx0YTtcbiAgICAgICAgY29udGVudDogXCJcIjtcbiAgICAgIH1cblxuICAgICAgLy8gVGFyZ2V0ZWQgYW5jaG9yICg0OHB4IGZyb20gaGVhZGVyLCAxMnB4IGZyb20gc2lkZWJhciBvZmZzZXQpXG4gICAgICAmOnRhcmdldDo6YmVmb3JlIHtcbiAgICAgICAgbWFyZ2luLXRvcDogLSg0LjhyZW0gKyAxLjJyZW0gKyAkZGVsdGEpO1xuICAgICAgICBwYWRkaW5nLXRvcDogKDQuOHJlbSArIDEuMnJlbSArICRkZWx0YSk7XG4gICAgICB9XG5cbiAgICAgIC8vIE1ha2UgcGVybWFsaW5rIHZpc2libGUgb24gaG92ZXJcbiAgICAgICY6aG92ZXIgIC5oZWFkZXJsaW5rLFxuICAgICAgJjp0YXJnZXQgLmhlYWRlcmxpbmssXG4gICAgICAmIC5oZWFkZXJsaW5rOmZvY3VzIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMCwgMCk7XG4gICAgICAgIG9wYWNpdHk6IDE7XG4gICAgICB9XG5cbiAgICAgIC8vIEFjdGl2ZSBvciB0YXJnZXRlZCBwZXJtYWxpbmtcbiAgICAgICY6aG92ZXIgIC5oZWFkZXJsaW5rOmhvdmVyLFxuICAgICAgJjp0YXJnZXQgLmhlYWRlcmxpbmssXG4gICAgICAmIC5oZWFkZXJsaW5rOmZvY3VzIHtcbiAgICAgICAgY29sb3I6ICRtZC1jb2xvci1hY2NlbnQ7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2V4dGVuc2lvbnMvX3Blcm1hbGlua3Muc2NzcyIsIi8vLy9cbi8vLyBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4vLy9cbi8vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSxcbi8vLyB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uXG4vLy8gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsXG4vLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlXG4vLy8gU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vL1xuLy8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vLy9cbi8vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMXG4vLy8gVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuLy8vIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVJcbi8vLyBERUFMSU5HU1xuLy8vL1xuXG4vLyBzdHlsZWxpbnQtZGlzYWJsZSBzZWxlY3Rvci1jbGFzcy1wYXR0ZXJuXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJ1bGVzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vIFNjb3BlZCBpbiB0eXBlc2V0dGVkIGNvbnRlbnQgdG8gbWF0Y2ggc3BlY2lmaWNpdHkgb2YgcmVndWxhciBjb250ZW50XG4ubWQtdHlwZXNldCB7XG5cbiAgLy8gTWF0aEpheCBpbnRlZ3JhdGlvbiAtIGFkZCBwYWRkaW5nIHRvIG9taXQgdmVydGljYWwgc2Nyb2xsYmFyXG4gIC5NSlhjLWRpc3BsYXkge1xuICAgIG1hcmdpbjogMC43NWVtIDA7XG4gICAgcGFkZGluZzogMC43NWVtIDA7XG4gICAgb3ZlcmZsb3c6IGF1dG87XG4gICAgLXdlYmtpdC1vdmVyZmxvdy1zY3JvbGxpbmc6IHRvdWNoO1xuICB9XG5cbiAgLy8gU3RyZXRjaCB0b3AtbGV2ZWwgY29udGFpbmVyc1xuICA+IHAgPiAuTUpYYy1kaXNwbGF5IHtcblxuICAgIC8vIFttb2JpbGUgLV06IFN0cmV0Y2ggdG8gd2hvbGUgd2lkdGhcbiAgICBAaW5jbHVkZSBicmVhay10by1kZXZpY2UobW9iaWxlKSB7XG4gICAgICBtYXJnaW46IDAuNzVlbSAtMS42cmVtO1xuICAgICAgcGFkZGluZzogMC4yNWVtIDEuNnJlbTtcbiAgICB9XG4gIH1cblxuICAvLyBSZW1vdmUgb3V0bGluZSBvbiB0YWIgaW5kZXhcbiAgLk1hdGhKYXhfQ0hUTUwge1xuICAgIG91dGxpbmU6IDA7XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvZXh0ZW5zaW9ucy9weW1kb3duL19hcml0aG1hdGV4LnNjc3MiLCIvLy8vXG4vLy8gQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuLy8vXG4vLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksXG4vLy8gdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvblxuLy8vIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLFxuLy8vIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZVxuLy8vIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vLy9cbi8vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy8vXG4vLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTFxuLy8vIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbi8vLyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSXG4vLy8gREVBTElOR1Ncbi8vLy9cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUnVsZXNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gU2NvcGVkIGluIHR5cGVzZXR0ZWQgY29udGVudCB0byBtYXRjaCBzcGVjaWZpY2l0eSBvZiByZWd1bGFyIGNvbnRlbnRcbi5tZC10eXBlc2V0IHtcblxuICAvLyBEZWxldGlvbnMsIGFkZGl0aW9ucyBhbmQgY29tbWVudHNcbiAgZGVsLmNyaXRpYyxcbiAgaW5zLmNyaXRpYyxcbiAgLmNyaXRpYy5jb21tZW50IHtcbiAgICBtYXJnaW46IDAgMC4yNWVtO1xuICAgIHBhZGRpbmc6IDAuMDYyNWVtIDA7XG4gICAgYm9yZGVyLXJhZGl1czogMC4ycmVtO1xuICAgIGJveC1kZWNvcmF0aW9uLWJyZWFrOiBjbG9uZTtcbiAgfVxuXG4gIC8vIERlbGV0aW9uXG4gIGRlbC5jcml0aWMge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2RlaGlsaXRlLWRpZmYtZGVsZXRlZDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBkZXBlbmRlbnQgb24gb3JkZXIgb2YgaW5jbHVzaW9uXG4gICAgYm94LXNoYWRvdzpcbiAgICAgICswLjI1ZW0gMCAwICRjb2RlaGlsaXRlLWRpZmYtZGVsZXRlZCxcbiAgICAgIC0wLjI1ZW0gMCAwICRjb2RlaGlsaXRlLWRpZmYtZGVsZXRlZDtcbiAgfVxuXG4gIC8vIEFkZGl0aW9uXG4gIGlucy5jcml0aWMge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRjb2RlaGlsaXRlLWRpZmYtaW5zZXJ0ZWQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBkZXBlbmRlbnQgb24gb3JkZXIgb2YgaW5jbHVzaW9uXG4gICAgYm94LXNoYWRvdzpcbiAgICAgICswLjI1ZW0gMCAwICRjb2RlaGlsaXRlLWRpZmYtaW5zZXJ0ZWQsXG4gICAgICAtMC4yNWVtIDAgMCAkY29kZWhpbGl0ZS1kaWZmLWluc2VydGVkO1xuICB9XG5cbiAgLy8gQ29tbWVudFxuICAuY3JpdGljLmNvbW1lbnQge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2RlLWJhY2tncm91bmQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiByZW5hbWUsIGNlbnRyYWxpemUgc29tZWhvd1xuICAgIGNvbG9yOiAkbWQtY29kZS1jb2xvcjtcbiAgICBib3gtc2hhZG93OlxuICAgICAgKzAuMjVlbSAwIDAgJG1kLWNvZGUtYmFja2dyb3VuZCxcbiAgICAgIC0wLjI1ZW0gMCAwICRtZC1jb2RlLWJhY2tncm91bmQ7XG5cbiAgICAvLyBJY29uXG4gICAgJjo6YmVmb3JlIHtcbiAgICAgIEBleHRlbmQgJW1kLWljb247XG5cbiAgICAgIHBhZGRpbmctcmlnaHQ6IDAuMTI1ZW07XG4gICAgICBjb2xvcjogJG1kLWNvbG9yLWJsYWNrLS1saWdodGVyO1xuICAgICAgY29udGVudDogXCJcXEUwQjdcIjsgLy8gY2hhdFxuICAgICAgdmVydGljYWwtYWxpZ246IC0wLjEyNWVtO1xuICAgIH1cbiAgfVxuXG4gIC8vIEJsb2NrXG4gIC5jcml0aWMuYmxvY2sge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIG1hcmdpbjogMWVtIDA7XG4gICAgcGFkZGluZy1yaWdodDogMS42cmVtO1xuICAgIHBhZGRpbmctbGVmdDogMS42cmVtO1xuICAgIGJveC1zaGFkb3c6IG5vbmU7XG5cbiAgICAvLyBEZWNyZWFzZSBzcGFjaW5nIG9uIGZpcnN0IGVsZW1lbnRcbiAgICA6Zmlyc3QtY2hpbGQge1xuICAgICAgbWFyZ2luLXRvcDogMC41ZW07XG4gICAgfVxuXG4gICAgLy8gRGVjcmVhc2Ugc3BhY2luZyBvbiBsYXN0IGVsZW1lbnRcbiAgICA6bGFzdC1jaGlsZCB7XG4gICAgICBtYXJnaW4tYm90dG9tOiAwLjVlbTtcbiAgICB9XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvZXh0ZW5zaW9ucy9weW1kb3duL19jcml0aWMuc2NzcyIsIi8vLy9cbi8vLyBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4vLy9cbi8vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSxcbi8vLyB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uXG4vLy8gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsXG4vLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlXG4vLy8gU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vL1xuLy8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vLy9cbi8vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMXG4vLy8gVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuLy8vIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVJcbi8vLyBERUFMSU5HU1xuLy8vL1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBSdWxlc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBTY29wZWQgaW4gdHlwZXNldHRlZCBjb250ZW50IHRvIG1hdGNoIHNwZWNpZmljaXR5IG9mIHJlZ3VsYXIgY29udGVudFxuLm1kLXR5cGVzZXQge1xuXG4gIC8vIERldGFpbHMgZXh0ZW5zaW9uXG4gIGRldGFpbHMge1xuICAgIEBleHRlbmQgLmFkbW9uaXRpb247XG5cbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBwYWRkaW5nLXRvcDogMDtcblxuICAgIC8vIFJvdGF0ZSB0aXRsZSBpY29uXG4gICAgJltvcGVuXSA+IHN1bW1hcnk6OmFmdGVyIHtcbiAgICAgIHRyYW5zZm9ybTogcm90YXRlKDE4MGRlZyk7XG4gICAgfVxuXG4gICAgLy8gUmVtb3ZlIGJvdHRvbSBzcGFjaW5nXG4gICAgJjpub3QoW29wZW5dKSB7XG4gICAgICBwYWRkaW5nLWJvdHRvbTogMDtcblxuICAgICAgLy8gUmVtb3ZlIGJvdHRvbSBib3JkZXIgaWYgYmxvY2sgaXMgY2xvc2VkXG4gICAgICA+IHN1bW1hcnkge1xuICAgICAgICBib3JkZXItYm90dG9tOiBub25lO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEluY3JlYXNlIHNwYWNpbmcgdG8gdGhlIHJpZ2h0IC0gc2NvcGVkIGhlcmUgZm9yIGhpZ2hlciBzcGVjaWZpY2l0eVxuICAgIHN1bW1hcnkge1xuICAgICAgcGFkZGluZy1yaWdodDogNHJlbTtcblxuICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICBwYWRkaW5nLWxlZnQ6IDRyZW07XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gTWFudWFsbHkgaGlkZSBhbmQgc2hvdywgaWYgYnJvd3NlciBkb2Vzbid0IHN1cHBvcnQgZGV0YWlsc1xuICAgIC5uby1kZXRhaWxzICY6bm90KFtvcGVuXSkge1xuXG4gICAgICAvLyBIaWRlIGFsbCBuZXN0ZWQgdGFncyAuLi5cbiAgICAgID4gKiB7XG4gICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgICB9XG5cbiAgICAgIC8vIC4uLiBidXQgc2hvdyB0aXRsZVxuICAgICAgc3VtbWFyeSB7XG4gICAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFRpdGxlXG4gIHN1bW1hcnkge1xuICAgIEBleHRlbmQgLmFkbW9uaXRpb24tdGl0bGU7XG5cbiAgICAvLyBIYWNrOiBzZXQgdG8gYmxvY2ssIHNvIEZpcmVmb3ggZG9lc24ndCByZW5kZXIgbWFya2VyXG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgb3V0bGluZTogbm9uZTtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG5cbiAgICAvLyBSZW1vdmUgZGVmYXVsdCBkZXRhaWxzIG1hcmtlclxuICAgICY6Oi13ZWJraXQtZGV0YWlscy1tYXJrZXIge1xuICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG5cbiAgICAvLyBJY29uXG4gICAgJjo6YWZ0ZXIge1xuICAgICAgQGV4dGVuZCAlbWQtaWNvbjtcblxuICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgdG9wOiAwLjhyZW07XG4gICAgICByaWdodDogMS4ycmVtO1xuICAgICAgY29sb3I6ICRtZC1jb2xvci1ibGFjay0tbGlnaHRlcjtcbiAgICAgIGZvbnQtc2l6ZTogMnJlbTtcbiAgICAgIGNvbnRlbnQ6IFwiXFxFMzEzXCI7IC8vIGtleWJvYXJkX2Fycm93X2Rvd25cblxuICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICByaWdodDogaW5pdGlhbDtcbiAgICAgICAgbGVmdDogMS4ycmVtO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9leHRlbnNpb25zL3B5bWRvd24vX2RldGFpbHMuc2NzcyIsIi8vLy9cbi8vLyBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4vLy9cbi8vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSxcbi8vLyB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uXG4vLy8gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsXG4vLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlXG4vLy8gU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vL1xuLy8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vLy9cbi8vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMXG4vLy8gVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuLy8vIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVJcbi8vLyBERUFMSU5HU1xuLy8vL1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBSdWxlc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBTY29wZWQgaW4gdHlwZXNldHRlZCBjb250ZW50IHRvIG1hdGNoIHNwZWNpZmljaXR5IG9mIHJlZ3VsYXIgY29udGVudFxuLm1kLXR5cGVzZXQge1xuXG4gIC8vIENvcnJlY3QgYWxpZ25tZW50IG9mIGVtb2ppc1xuICAuZW1vamlvbmUge1xuICAgIHdpZHRoOiAycmVtO1xuICAgIHZlcnRpY2FsLWFsaWduOiB0ZXh0LXRvcDtcbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9leHRlbnNpb25zL3B5bWRvd24vX2Vtb2ppLnNjc3MiLCIvLy8vXG4vLy8gQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuLy8vXG4vLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksXG4vLy8gdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvblxuLy8vIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLFxuLy8vIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZVxuLy8vIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vLy9cbi8vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy8vXG4vLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTFxuLy8vIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbi8vLyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSXG4vLy8gREVBTElOR1Ncbi8vLy9cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUnVsZXNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8gU2NvcGVkIGluIHR5cGVzZXR0ZWQgY29udGVudCB0byBtYXRjaCBzcGVjaWZpY2l0eSBvZiByZWd1bGFyIGNvbnRlbnRcbi5tZC10eXBlc2V0IHtcblxuICAvLyBRdWFsaWZpZWQgY2xhc3Mgc2VsZWN0b3IgdG8gZGlzdGluZ3Vpc2ggaW5saW5lIGNvZGUgZnJvbSBjb2RlIGJsb2Nrc1xuICBjb2RlLmNvZGVoaWxpdGUge1xuICAgICRjb3JyZWN0OiAxIC8gMC44NTtcblxuICAgIG1hcmdpbjogMCAwLjI1ZW0gKiAkY29ycmVjdDtcbiAgICBwYWRkaW5nOiAwLjA2MjVlbSAqICRjb3JyZWN0IDA7XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvZXh0ZW5zaW9ucy9weW1kb3duL19pbmxpbmVoaWxpdGUuc2NzcyIsIi8vLy9cbi8vLyBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4vLy9cbi8vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSxcbi8vLyB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uXG4vLy8gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsXG4vLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlXG4vLy8gU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vL1xuLy8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vLy9cbi8vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMXG4vLy8gVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuLy8vIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVJcbi8vLyBERUFMSU5HU1xuLy8vL1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBSdWxlc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBTY29wZWQgaW4gdHlwZXNldHRlZCBjb250ZW50IHRvIG1hdGNoIHNwZWNpZmljaXR5IG9mIHJlZ3VsYXIgY29udGVudFxuLm1kLXR5cGVzZXQge1xuXG4gIC8vIFRhYmJlZCBjb2RlIGJsb2NrIGNvbnRlbnRcbiAgLnN1cGVyZmVuY2VzLWNvbnRlbnQge1xuICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgb3JkZXI6IDk5O1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGJhY2tncm91bmQtY29sb3I6ICRtZC1jb2xvci13aGl0ZTtcblxuICAgIC8vIEFjdHVhbCBjb250ZW50XG4gICAgPiAqIHtcbiAgICAgIG1hcmdpbjogMDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDBcbiAgICB9XG4gIH1cblxuICAvLyBUYWJiZWQgY29kZSBibG9jayBjb250YWluZXJcbiAgLnN1cGVyZmVuY2VzLXRhYnMge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIGZsZXgtd3JhcDogd3JhcDtcbiAgICBtYXJnaW46IDFlbSAwO1xuICAgIGJvcmRlcjogMC4xcmVtIHNvbGlkICRtZC1jb2xvci1ibGFjay0tbGlnaHRlc3Q7XG4gICAgYm9yZGVyLXJhZGl1czogMC4yZW07XG5cbiAgICAvLyBIaWRlIHJhZGlvIGJ1dHRvbnNcbiAgICA+IGlucHV0IHtcbiAgICAgIGRpc3BsYXk6IG5vbmU7XG5cbiAgICAgIC8vIEFjdGl2ZSB0YWIgbGFiZWxcbiAgICAgICY6Y2hlY2tlZCArIGxhYmVsIHtcbiAgICAgICAgZm9udC13ZWlnaHQ6IDcwMDtcblxuICAgICAgICAvLyBTaG93IGNvZGUgdGFiIGNvbnRlbnRcbiAgICAgICAgJiArIC5zdXBlcmZlbmNlcy1jb250ZW50IHtcbiAgICAgICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRhYiBsYWJlbFxuICAgID4gbGFiZWwge1xuICAgICAgd2lkdGg6IGF1dG87XG4gICAgICBwYWRkaW5nOiAxLjJyZW0gMS4ycmVtO1xuICAgICAgdHJhbnNpdGlvbjogY29sb3IgMC4xMjVzO1xuICAgICAgZm9udC1zaXplOiBtcygtMSk7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7XG5cbiAgICAgIC8vIEhvdmVyZWQgdGFiIGxhYmVsXG4gICAgICBodG1sICY6aG92ZXIge1xuICAgICAgICBjb2xvcjogJG1kLWNvbG9yLWFjY2VudDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBGdWxsLXdpZHRoIGNvbnRhaW5lciBvbiB0b3AtbGV2ZWxcbiAgPiAuc3VwZXJmZW5jZXMtdGFicyB7XG5cbiAgICAvLyBbbW9iaWxlIC1dOiBTdHJldGNoIHRvIHdob2xlIHdpZHRoXG4gICAgQGluY2x1ZGUgYnJlYWstdG8tZGV2aWNlKG1vYmlsZSkge1xuICAgICAgbWFyZ2luOiAxZW0gLTEuNnJlbTtcbiAgICAgIGJvcmRlcjogMDtcbiAgICAgIGJvcmRlci10b3A6IDAuMXJlbSBzb2xpZCAkbWQtY29sb3ItYmxhY2stLWxpZ2h0ZXN0O1xuICAgICAgYm9yZGVyLXJhZGl1czogMDtcblxuICAgICAgLy8gQWN0dWFsIGNvbnRhaW5lciB3aXRoIGNvZGUsIG92ZXJmbG93aW5nXG4gICAgICBwcmUsXG4gICAgICBjb2RlIHtcbiAgICAgICAgcGFkZGluZzogMS4wNXJlbSAxLjZyZW07XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zcmMvYXNzZXRzL3N0eWxlc2hlZXRzL2V4dGVuc2lvbnMvcHltZG93bi9fc3VwZXJmZW5jZXMuc2NzcyIsIi8vLy9cbi8vLyBDb3B5cmlnaHQgKGMpIDIwMTYtMjAxOCBNYXJ0aW4gRG9uYXRoIDxtYXJ0aW4uZG9uYXRoQHNxdWlkZnVuay5jb20+XG4vLy9cbi8vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSxcbi8vLyB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uXG4vLy8gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsXG4vLy8gYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlXG4vLy8gU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vL1xuLy8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vLy9cbi8vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTi1JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMXG4vLy8gVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lOR1xuLy8vIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVJcbi8vLyBERUFMSU5HU1xuLy8vL1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBSdWxlc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vLyBTY29wZWQgaW4gdHlwZXNldHRlZCBjb250ZW50IHRvIG1hdGNoIHNwZWNpZmljaXR5IG9mIHJlZ3VsYXIgY29udGVudFxuLm1kLXR5cGVzZXQge1xuXG4gIC8vIFJlbW92ZSBsaXN0IGljb24gb24gdGFzayBpdGVtc1xuICAudGFzay1saXN0LWl0ZW0ge1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBsaXN0LXN0eWxlLXR5cGU6IG5vbmU7XG5cbiAgICAvLyBNYWtlIGNoZWNrYm94IGl0ZW1zIGFsaWduIHdpdGggbm9ybWFsIGxpc3QgaXRlbXMsIGJ1dCBwb3NpdGlvblxuICAgIC8vIGV2ZXJ5dGhpbmcgaW4gZW1zIGZvciBjb3JyZWN0IGxheW91dCBhdCBzbWFsbGVyIGZvbnQgc2l6ZXNcbiAgICBbdHlwZT1cImNoZWNrYm94XCJdIHtcbiAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgIHRvcDogMC40NWVtO1xuICAgICAgbGVmdDogLTJlbTtcblxuICAgICAgLy8gQWRqdXN0IGZvciBSVEwgbGFuZ3VhZ2VzXG4gICAgICBbZGlyPVwicnRsXCJdICYge1xuICAgICAgICByaWdodDogLTJlbTtcbiAgICAgICAgbGVmdDogaW5pdGlhbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBXcmFwcGVyIGZvciBsaXN0IGNvbnRyb2xzLCBpbiBjYXNlIGN1c3RvbSBjaGVja2JveGVzIGFyZSBlbmFibGVkXG4gIC50YXNrLWxpc3QtY29udHJvbCB7XG5cbiAgICAvLyBDaGVja2JveCBpY29uIGluIHVuY2hlY2tlZCBzdGF0ZVxuICAgIC50YXNrLWxpc3QtaW5kaWNhdG9yOjpiZWZvcmUge1xuICAgICAgQGV4dGVuZCAlbWQtaWNvbjtcblxuICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgdG9wOiAwLjE1ZW07XG4gICAgICBsZWZ0OiAtMS4yNWVtO1xuICAgICAgY29sb3I6ICRtZC1jb2xvci1ibGFjay0tbGlnaHRlcjtcbiAgICAgIGZvbnQtc2l6ZTogMS4yNWVtO1xuICAgICAgY29udGVudDogXCJcXEU4MzVcIjsgLy8gY2hlY2tfYm94X291dGxpbmVfYmxhbmtcbiAgICAgIHZlcnRpY2FsLWFsaWduOiAtMC4yNWVtO1xuXG4gICAgICAvLyBBZGp1c3QgZm9yIFJUTCBsYW5ndWFnZXNcbiAgICAgIFtkaXI9XCJydGxcIl0gJiB7XG4gICAgICAgIHJpZ2h0OiAtMS4yNWVtO1xuICAgICAgICBsZWZ0OiBpbml0aWFsO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENoZWNrYm94IGljb24gaW4gY2hlY2tlZCBzdGF0ZVxuICAgIFt0eXBlPVwiY2hlY2tib3hcIl06Y2hlY2tlZCArIC50YXNrLWxpc3QtaW5kaWNhdG9yOjpiZWZvcmUge1xuICAgICAgY29udGVudDogXCJcXEU4MzRcIjsgLy8gY2hlY2tfYm94XG4gICAgfVxuXG4gICAgLy8gSGlkZSBvcmlnaW5hbCBjaGVja2JveCBiZWhpbmQgaWNvblxuICAgIFt0eXBlPVwiY2hlY2tib3hcIl0ge1xuICAgICAgb3BhY2l0eTogMDtcbiAgICAgIHotaW5kZXg6IC0xO1xuICAgIH1cbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3JjL2Fzc2V0cy9zdHlsZXNoZWV0cy9leHRlbnNpb25zL3B5bWRvd24vX3Rhc2tsaXN0LnNjc3MiLCIvLy8vXG4vLy8gQ29weXJpZ2h0IChjKSAyMDE2LTIwMTggTWFydGluIERvbmF0aCA8bWFydGluLmRvbmF0aEBzcXVpZGZ1bmsuY29tPlxuLy8vXG4vLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksXG4vLy8gdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvblxuLy8vIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLFxuLy8vIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZVxuLy8vIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vLy9cbi8vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy8vXG4vLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTFxuLy8vIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLy8gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkdcbi8vLyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSXG4vLy8gREVBTElOR1Ncbi8vLy9cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVmFyaWFibGVzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vL1xuLy8vIERldmljZS1zcGVjaWZpYyBicmVha3BvaW50c1xuLy8vXG4vLy8gQGV4YW1wbGVcbi8vLyAgICRicmVhay1kZXZpY2VzOiAoXG4vLy8gICAgIG1vYmlsZTogKFxuLy8vICAgICAgIHBvcnRyYWl0OiAgMjIwcHggIDQ3OXB4LFxuLy8vICAgICAgIGxhbmRzY2FwZTogNDgwcHggIDcxOXB4XG4vLy8gICAgICksXG4vLy8gICAgIHRhYmxldDogKFxuLy8vICAgICAgIHBvcnRyYWl0OiAgNzIwcHggIDk1OXB4LFxuLy8vICAgICAgIGxhbmRzY2FwZTogOTYwcHggIDEyMTlweFxuLy8vICAgICApLFxuLy8vICAgICBzY3JlZW46IChcbi8vLyAgICAgICBzbWFsbDogICAgIDEyMjBweCAxNTk5cHgsXG4vLy8gICAgICAgbWVkaXVtOiAgICAxNjAwcHggMTk5OXB4LFxuLy8vICAgICAgIGxhcmdlOiAgICAgMjAwMHB4XG4vLy8gICAgIClcbi8vLyAgICk7XG4vLy9cbi8vLyBAZ3JvdXAgIGhlbHBlcnNcbi8vLyBAYWNjZXNzIHByaXZhdGVcbi8vLyBAdHlwZSAgIE1hcFxuLy8vXG4kYnJlYWstZGV2aWNlczogKCkgIWRlZmF1bHQ7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEhlbHBlcnNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLy8vXG4vLy8gQ2hvb3NlIG1pbmltdW0gYW5kIG1heGltdW0gZGV2aWNlIHdpZHRoc1xuLy8vXG4vLy8gQGdyb3VwICBoZWxwZXJzXG4vLy8gQGFjY2VzcyBwcml2YXRlXG4vLy8gQHBhcmFtICB7TWFwfSAgJGRldmljZXMgTWFwIG9mIGRldmljZXNcbi8vLyBAcmV0dXJuIHtMaXN0fSAgICAgICAgICBNaW5pbXVtIGFuZCBtYXhpbXVtIHdpZHRoXG4vLy9cbkBmdW5jdGlvbiBicmVhay1zZWxlY3QtbWluLW1heCgkZGV2aWNlcykge1xuICAkbWluOiAxMDAwMDAwO1xuICAkbWF4OiAwO1xuICBAZWFjaCAka2V5LCAkdmFsdWUgaW4gJGRldmljZXMge1xuICAgIEB3aGlsZSB0eXBlLW9mKCR2YWx1ZSkgPT0gbWFwIHtcbiAgICAgICR2YWx1ZTogYnJlYWstc2VsZWN0LW1pbi1tYXgoJHZhbHVlKTtcbiAgICB9XG4gICAgQGlmIHR5cGUtb2YoJHZhbHVlKSA9PSBsaXN0IHtcbiAgICAgIEBlYWNoICRudW1iZXIgaW4gJHZhbHVlIHtcbiAgICAgICAgQGlmIHR5cGUtb2YoJG51bWJlcikgPT0gbnVtYmVyIHtcbiAgICAgICAgICAkbWluOiBtaW4oJG51bWJlciwgJG1pbik7XG4gICAgICAgICAgQGlmICRtYXggIT0gbnVsbCB7XG4gICAgICAgICAgICAkbWF4OiBtYXgoJG51bWJlciwgJG1heCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICBAZXJyb3IgXCJJbnZhbGlkIG51bWJlcjogI3skbnVtYmVyfVwiO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBAZWxzZWlmIHR5cGUtb2YoJHZhbHVlKSA9PSBudW1iZXIge1xuICAgICAgJG1pbjogbWluKCR2YWx1ZSwgJG1pbik7XG4gICAgICAkbWF4OiBudWxsO1xuICAgIH0gQGVsc2Uge1xuICAgICAgQGVycm9yIFwiSW52YWxpZCB2YWx1ZTogI3skdmFsdWV9XCI7XG4gICAgfVxuICB9XG4gIEByZXR1cm4gJG1pbiwgJG1heDtcbn1cblxuLy8vXG4vLy8gU2VsZWN0IG1pbmltdW0gYW5kIG1heGltdW0gd2lkdGhzIGZvciBhIGRldmljZSBicmVha3BvaW50XG4vLy9cbi8vLyBAZ3JvdXAgIGhlbHBlcnNcbi8vLyBAYWNjZXNzIHByaXZhdGVcbi8vLyBAcGFyYW0gIHtTdHJpbmd9ICRkZXZpY2UgRGV2aWNlXG4vLy8gQHJldHVybiB7TGlzdH0gICAgICAgICAgIE1pbmltdW0gYW5kIG1heGltdW0gd2lkdGhcbi8vL1xuQGZ1bmN0aW9uIGJyZWFrLXNlbGVjdC1kZXZpY2UoJGRldmljZSkge1xuICAkY3VycmVudDogJGJyZWFrLWRldmljZXM7XG4gIEBmb3IgJG4gZnJvbSAxIHRocm91Z2ggbGVuZ3RoKCRkZXZpY2UpIHtcbiAgICBAaWYgdHlwZS1vZigkY3VycmVudCkgPT0gbWFwIHtcbiAgICAgICRjdXJyZW50OiBtYXAtZ2V0KCRjdXJyZW50LCBudGgoJGRldmljZSwgJG4pKTtcbiAgICB9IEBlbHNlIHtcbiAgICAgIEBlcnJvciBcIkludmFsaWQgZGV2aWNlIG1hcDogI3skZGV2aWNlc31cIjtcbiAgICB9XG4gIH1cbiAgQGlmIHR5cGUtb2YoJGN1cnJlbnQpID09IGxpc3Qgb3IgdHlwZS1vZigkY3VycmVudCkgPT0gbnVtYmVyIHtcbiAgICAkY3VycmVudDogKGRlZmF1bHQ6ICRjdXJyZW50KTtcbiAgfVxuICBAcmV0dXJuIGJyZWFrLXNlbGVjdC1taW4tbWF4KCRjdXJyZW50KTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gTWl4aW5zXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8vL1xuLy8vIEEgbWluaW11bS1tYXhpbXVtIG1lZGlhIHF1ZXJ5IGJyZWFrcG9pbnRcbi8vL1xuLy8vIEBncm91cCAgaGVscGVyc1xuLy8vIEBhY2Nlc3MgcHVibGljXG4vLy8gQHBhcmFtICB7TnVtYmVyfExpc3R9ICRicmVha3BvaW50IE51bWJlciBvciBudW1iZXIgcGFpclxuLy8vXG5AbWl4aW4gYnJlYWstYXQoJGJyZWFrcG9pbnQpIHtcbiAgQGlmIHR5cGUtb2YoJGJyZWFrcG9pbnQpID09IG51bWJlciB7XG4gICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAkYnJlYWtwb2ludCkge1xuICAgICAgQGNvbnRlbnQ7XG4gICAgfVxuICB9IEBlbHNlaWYgdHlwZS1vZigkYnJlYWtwb2ludCkgPT0gbGlzdCB7XG4gICAgJG1pbjogbnRoKCRicmVha3BvaW50LCAxKTtcbiAgICAkbWF4OiBudGgoJGJyZWFrcG9pbnQsIDIpO1xuICAgIEBpZiB0eXBlLW9mKCRtaW4pID09IG51bWJlciBhbmQgdHlwZS1vZigkbWF4KSA9PSBudW1iZXIge1xuICAgICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWluLXdpZHRoOiAkbWluKSBhbmQgKG1heC13aWR0aDogJG1heCkge1xuICAgICAgICBAY29udGVudDtcbiAgICAgIH1cbiAgICB9IEBlbHNlIHtcbiAgICAgIEBlcnJvciBcIkludmFsaWQgYnJlYWtwb2ludDogI3skYnJlYWtwb2ludH1cIjtcbiAgICB9XG4gIH0gQGVsc2Uge1xuICAgIEBlcnJvciBcIkludmFsaWQgYnJlYWtwb2ludDogI3skYnJlYWtwb2ludH1cIjtcbiAgfVxufVxuXG4vLy9cbi8vLyBBbiBvcmllbnRhdGlvbiBtZWRpYSBxdWVyeSBicmVha3BvaW50XG4vLy9cbi8vLyBAZ3JvdXAgIGhlbHBlcnNcbi8vLyBAYWNjZXNzIHB1YmxpY1xuLy8vIEBwYXJhbSAge1N0cmluZ30gJGJyZWFrcG9pbnQgT3JpZW50YXRpb25cbi8vL1xuQG1peGluIGJyZWFrLWF0LW9yaWVudGF0aW9uKCRicmVha3BvaW50KSB7XG4gIEBpZiB0eXBlLW9mKCRicmVha3BvaW50KSA9PSBzdHJpbmcge1xuICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG9yaWVudGF0aW9uOiAkYnJlYWtwb2ludCkge1xuICAgICAgQGNvbnRlbnQ7XG4gICAgfVxuICB9IEBlbHNlIHtcbiAgICBAZXJyb3IgXCJJbnZhbGlkIGJyZWFrcG9pbnQ6ICN7JGJyZWFrcG9pbnR9XCI7XG4gIH1cbn1cblxuLy8vXG4vLy8gQSBtYXhpbXVtLWFzcGVjdC1yYXRpbyBtZWRpYSBxdWVyeSBicmVha3BvaW50XG4vLy9cbi8vLyBAZ3JvdXAgIGhlbHBlcnNcbi8vLyBAYWNjZXNzIHB1YmxpY1xuLy8vIEBwYXJhbSAge051bWJlcn0gJGJyZWFrcG9pbnQgUmF0aW9cbi8vL1xuQG1peGluIGJyZWFrLWF0LXJhdGlvKCRicmVha3BvaW50KSB7XG4gIEBpZiB0eXBlLW9mKCRicmVha3BvaW50KSA9PSBudW1iZXIge1xuICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1heC1hc3BlY3QtcmF0aW86ICRicmVha3BvaW50KSB7XG4gICAgICBAY29udGVudDtcbiAgICB9XG4gIH0gQGVsc2Uge1xuICAgIEBlcnJvciBcIkludmFsaWQgYnJlYWtwb2ludDogI3skYnJlYWtwb2ludH1cIjtcbiAgfVxufVxuXG4vLy9cbi8vLyBBIG1pbmltdW0tbWF4aW11bSBtZWRpYSBxdWVyeSBkZXZpY2UgYnJlYWtwb2ludFxuLy8vXG4vLy8gQGdyb3VwICBoZWxwZXJzXG4vLy8gQGFjY2VzcyBwdWJsaWNcbi8vLyBAcGFyYW0gIHtTdHJpbmd8TGlzdH0gJGJyZWFrcG9pbnQgRGV2aWNlXG4vLy9cbkBtaXhpbiBicmVhay1hdC1kZXZpY2UoJGRldmljZSkge1xuICBAaWYgdHlwZS1vZigkZGV2aWNlKSA9PSBzdHJpbmcge1xuICAgICRkZXZpY2U6ICRkZXZpY2UsO1xuICB9XG4gIEBpZiB0eXBlLW9mKCRkZXZpY2UpID09IGxpc3Qge1xuICAgICRicmVha3BvaW50OiBicmVhay1zZWxlY3QtZGV2aWNlKCRkZXZpY2UpO1xuICAgIEBpZiBudGgoJGJyZWFrcG9pbnQsIDIpICE9IG51bGwge1xuICAgICAgJG1pbjogbnRoKCRicmVha3BvaW50LCAxKTtcbiAgICAgICRtYXg6IG50aCgkYnJlYWtwb2ludCwgMik7XG4gICAgICBAbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4td2lkdGg6ICRtaW4pIGFuZCAobWF4LXdpZHRoOiAkbWF4KSB7XG4gICAgICAgIEBjb250ZW50O1xuICAgICAgfVxuICAgIH0gQGVsc2Uge1xuICAgICAgQGVycm9yIFwiSW52YWxpZCBkZXZpY2U6ICN7JGRldmljZX1cIjtcbiAgICB9XG4gIH0gQGVsc2Uge1xuICAgIEBlcnJvciBcIkludmFsaWQgZGV2aWNlOiAjeyRkZXZpY2V9XCI7XG4gIH1cbn1cblxuLy8vXG4vLy8gQSBtaW5pbXVtIG1lZGlhIHF1ZXJ5IGRldmljZSBicmVha3BvaW50XG4vLy9cbi8vLyBAZ3JvdXAgIGhlbHBlcnNcbi8vLyBAYWNjZXNzIHB1YmxpY1xuLy8vIEBwYXJhbSAge1N0cmluZ3xMaXN0fSAkYnJlYWtwb2ludCBEZXZpY2Vcbi8vL1xuQG1peGluIGJyZWFrLWZyb20tZGV2aWNlKCRkZXZpY2UpIHtcbiAgQGlmIHR5cGUtb2YoJGRldmljZSkgPT0gc3RyaW5nIHtcbiAgICAkZGV2aWNlOiAkZGV2aWNlLDtcbiAgfVxuICBAaWYgdHlwZS1vZigkZGV2aWNlKSA9PSBsaXN0IHtcbiAgICAkYnJlYWtwb2ludDogYnJlYWstc2VsZWN0LWRldmljZSgkZGV2aWNlKTtcbiAgICAkbWluOiBudGgoJGJyZWFrcG9pbnQsIDEpO1xuICAgIEBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogJG1pbikge1xuICAgICAgQGNvbnRlbnQ7XG4gICAgfVxuICB9IEBlbHNlIHtcbiAgICBAZXJyb3IgXCJJbnZhbGlkIGRldmljZTogI3skZGV2aWNlfVwiO1xuICB9XG59XG5cbi8vL1xuLy8vIEEgbWF4aW11bSBtZWRpYSBxdWVyeSBkZXZpY2UgYnJlYWtwb2ludFxuLy8vXG4vLy8gQGdyb3VwICBoZWxwZXJzXG4vLy8gQGFjY2VzcyBwdWJsaWNcbi8vLyBAcGFyYW0gIHtTdHJpbmd8TGlzdH0gJGJyZWFrcG9pbnQgRGV2aWNlXG4vLy9cbkBtaXhpbiBicmVhay10by1kZXZpY2UoJGRldmljZSkge1xuICBAaWYgdHlwZS1vZigkZGV2aWNlKSA9PSBzdHJpbmcge1xuICAgICRkZXZpY2U6ICRkZXZpY2UsO1xuICB9XG4gIEBpZiB0eXBlLW9mKCRkZXZpY2UpID09IGxpc3Qge1xuICAgICRicmVha3BvaW50OiBicmVhay1zZWxlY3QtZGV2aWNlKCRkZXZpY2UpO1xuICAgICRtYXg6IG50aCgkYnJlYWtwb2ludCwgMik7XG4gICAgQG1lZGlhIG9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiAkbWF4KSB7XG4gICAgICBAY29udGVudDtcbiAgICB9XG4gIH0gQGVsc2Uge1xuICAgIEBlcnJvciBcIkludmFsaWQgZGV2aWNlOiAjeyRkZXZpY2V9XCI7XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NyYy9hc3NldHMvc3R5bGVzaGVldHMvaGVscGVycy9fYnJlYWsuc2NzcyJdLCJzb3VyY2VSb290IjoiIn0=*/"
  },
  {
    "path": "SecurityPaper-themes/base.html",
    "content": "{% import \"partials/language.html\" as lang with context %}\n{% set feature = config.theme.feature %}\n{% set palette = config.theme.palette %}\n{% set font = config.theme.font %}\n<!DOCTYPE html>\n<html lang=\"{{ lang.t('language') }}\" class=\"no-js\">\n  <head>\n    {% block site_meta %}\n      <meta charset=\"utf-8\">\n      <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n      <meta http-equiv=\"x-ua-compatible\" content=\"ie=edge\">\n      {% if page and page.meta and page.meta.description %}\n        <meta name=\"description\" content=\"{{ page.meta.description }}\">\n      {% elif config.site_description %}\n        <meta name=\"description\" content=\"{{ config.site_description }}\">\n      {% endif %}\n      {% if page.canonical_url %}\n        <link rel=\"canonical\" href=\"{{ page.canonical_url }}\">\n      {% endif %}\n      {% if page and page.meta and page.meta.author %}\n        <meta name=\"author\" content=\"{{ page.meta.author | first }}\">\n      {% elif config.site_author %}\n        <meta name=\"author\" content=\"{{ config.site_author }}\">\n      {% endif %}\n      {% for key in [\n        \"clipboard.copy\",\n        \"clipboard.copied\",\n        \"search.language\",\n        \"search.pipeline.stopwords\",\n        \"search.pipeline.trimmer\",\n        \"search.result.none\",\n        \"search.result.one\",\n        \"search.result.other\",\n        \"search.tokenizer\"\n      ] %}\n        <meta name=\"lang:{{ key }}\" content=\"{{ lang.t(key) }}\">\n      {% endfor %}\n      <link rel=\"shortcut icon\" href=\"{{ config.theme.favicon }}\">\n      <meta name=\"generator\" content=\"mkdocs-{{ mkdocs_version }}, mkdocs-material-3.1.0\">\n    {% endblock %}\n    {% block htmltitle %}\n      {% if page and page.meta and page.meta.title %}\n        <title>{{ page.meta.title }}</title>\n      {% elif page and page.title and not page.is_homepage %}\n        <title>{{ page.title }} - {{ config.site_name }}</title>\n      {% else %}\n        <title>{{ config.site_name }}</title>\n      {% endif %}\n    {% endblock %}\n    {% block styles %}\n      <link rel=\"stylesheet\" href=\"{{ '/assets/stylesheets/application.css' }}\">\n      {% if palette.primary or palette.accent %}\n        <link rel=\"stylesheet\" href=\"{{ '/assets/stylesheets/application-palette.css' }}\">\n      {% endif %}\n      {% if palette.primary %}\n        {% import \"partials/palette.html\" as map %}\n        {% set primary = map.primary(\n          palette.primary | replace(\" \", \"-\") | lower\n        ) %}\n        <meta name=\"theme-color\" content=\"{{ primary }}\">\n      {% endif %}\n    {% endblock %}\n    {% block libs %}\n      <script src=\"{{ '/assets/javascripts/modernizr.js' }}\"></script>\n    {% endblock %}\n    {% block fonts %}\n      {% if font != false %}\n        <link href=\"https://fonts.gstatic.com\" rel=\"preconnect\" crossorigin>\n        <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family={{\n              font.text | replace(' ', '+')  + ':300,400,400i,700|' +\n              font.code | replace(' ', '+')\n            }}\">\n        <style>body,input{font-family:\"{{ font.text }}\",\"Helvetica Neue\",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:\"{{ font.code }}\",\"Courier New\",Courier,monospace}</style>\n      {% endif %}\n    {% endblock %}\n    <link rel=\"stylesheet\" href=\"{{ '/assets/fonts/material-icons.css' }}\">\n    {% if config.extra.manifest %}\n      <link rel=\"manifest\" href=\"{{ config.extra.manifest }}\">\n    {% endif %}\n    {% for path in config[\"extra_css\"] %}\n      <link rel=\"stylesheet\" href=\"{{ path }}\">\n    {% endfor %}\n    {% block extrahead %}{% endblock %}\n  </head>\n  {% if palette.primary or palette.accent %}\n    {% set primary = palette.primary | replace(\" \", \"-\") | lower %}\n    {% set accent  = palette.accent  | replace(\" \", \"-\") | lower %}\n    <body dir=\"{{ lang.t('direction') }}\" data-md-color-primary=\"{{ primary }}\" data-md-color-accent=\"{{ accent }}\">\n  {% else %}\n    <body dir=\"{{ lang.t('direction') }}\">\n  {% endif %}\n    <svg class=\"md-svg\">\n      <defs>\n        {% set platform = config.extra.repo_icon or config.repo_url %}\n        {% if \"github\" in platform %}\n          {% include \"/assets/images/icons/github.svg\" %}\n        {% elif \"gitlab\" in platform %}\n          {% include \"/assets/images/icons/gitlab.svg\" %}\n        {% elif \"bitbucket\" in platform %}\n          {% include \"/assets/images/icons/bitbucket.svg\" %}\n        {% endif %}\n      </defs>\n    </svg>\n    <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n    <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n    <label class=\"md-overlay\" data-md-component=\"overlay\" for=\"__drawer\"></label>\n    {% if page.toc | first is defined %}\n      <a href=\"{{ (page.toc | first).url }}\" tabindex=\"1\" class=\"md-skip\">\n        {{ lang.t('skip.link.title') }}\n      </a>\n    {% endif %}\n    {% block header %}\n      {% include \"partials/header.html\" %}\n    {% endblock %}\n    <div class=\"md-container\">\n      {% block hero %}\n        {% if page and page.meta and page.meta.hero %}\n          {% include \"partials/hero.html\" with context %}\n        {% endif %}\n      {% endblock %}\n      {% if feature.tabs %}\n        {% include \"partials/tabs.html\" %}\n      {% endif %}\n      <main class=\"md-main\">\n        <div class=\"md-main__inner md-grid\" data-md-component=\"container\">\n          {% block site_nav %}\n            {% if nav %}\n              <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"navigation\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    {% include \"partials/nav.html\" %}\n                  </div>\n                </div>\n              </div>\n            {% endif %}\n            {% if page.toc %}\n              <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"toc\">\n                <div class=\"md-sidebar__scrollwrap\">\n                  <div class=\"md-sidebar__inner\">\n                    {% include \"partials/toc.html\" %}\n                  </div>\n                </div>\n              </div>\n            {% endif %}\n          {% endblock %}\n          <div class=\"md-content\">\n            <article class=\"md-content__inner md-typeset\">\n              {% block content %}\n                {% if page.edit_url %}\n                  <a href=\"{{ page.edit_url }}\" title=\"{{ lang.t('edit.link.title') }}\" class=\"md-icon md-content__icon\">&#xE3C9;</a>\n                {% endif %}\n                {% if not \"\\x3ch1\" in page.content %}\n                  <h1>{{ page.title | default(config.site_name, true)}}</h1>\n                {% endif %}\n                {{ page.content }}\n                {% block source %}\n                  {% if page and page.meta and page.meta.source %}\n                    <h2 id=\"__source\">{{ lang.t(\"meta.source\") }}</h2>\n                    {% set repo = config.repo_url %}\n                    {% if repo | last == \"/\" %}\n                      {% set repo = repo[:-1] %}\n                    {% endif %}\n                    {% set path = page.meta.path | default([\"\"]) %}\n                    {% set file = page.meta.source %}\n                    <a href=\"{{ [repo, path, file] | join('/') }}\" title=\"{{ file }}\" class=\"md-source-file\">\n                      {{ file }}\n                    </a>\n                  {% endif %}\n                {% endblock %}\n              {% endblock %}\n              {% block disqus %}\n                {% include \"partials/integrations/disqus.html\" %}\n              {% endblock %}\n            </article>\n          </div>\n        </div>\n      </main>\n      {% block footer %}\n        {% include \"partials/footer.html\" %}\n      {% endblock %}\n    </div>\n    {% block scripts %}\n      <script src=\"{{ '/assets/javascripts/application.js' }}\"></script>\n      {% if lang.t(\"search.language\") != \"en\" %}\n        {% set languages = lang.t(\"search.language\").split(\",\") %}\n        {% if languages | length and languages[0] != \"\" %}\n          {% set path = \"/assets/javascripts/lunr/\" %}\n          <script src=\"{{ (path ~ 'lunr.stemmer.support.js') }}\"></script>\n          {% for language in languages | map(\"trim\") %}\n            {% if language != \"en\" %}\n              {% if language == \"jp\" %}\n                <script src=\"{{ (path ~ 'tinyseg.js') }}\"></script>\n              {% endif %}\n              {% if language in (\"da\", \"de\", \"du\", \"es\", \"fi\", \"fr\", \"hu\", \"it\", \"jp\", \"no\", \"pt\", \"ro\", \"ru\", \"sv\", \"tr\") %}\n                <script src=\"{{ (path ~ 'lunr.' ~ language ~ '.js') }}\"></script>\n              {% endif %}\n            {% endif %}\n          {% endfor %}\n          {% if languages | length > 1 %}\n            <script src=\"{{ (path ~ 'lunr.multi.js') }}\"></script>\n          {% endif %}\n        {% endif %}\n      {% endif %}\n      <script>app.initialize({version:\"{{ mkdocs_version }}\",url:{base:\"{{ base_url }}\"}})</script>\n      {% for path in config[\"extra_javascript\"] %}\n        <script src=\"{{ path }}\"></script>\n      {% endfor %}\n    {% endblock %}\n    {% block analytics %}\n      {% if config.google_analytics %}\n        {% include \"partials/integrations/analytics.html\" %}\n      {% endif %}\n    {% endblock %}\n    <script async src=\"//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "SecurityPaper-themes/main.html",
    "content": "{% extends \"base.html\" %}\n"
  },
  {
    "path": "SecurityPaper-themes/mkdocs_theme.yml",
    "content": "# Copyright (c) 2016-2018 Martin Donath <martin.donath@squidfunk.com>\n\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to\n# deal in the Software without restriction, including without limitation the\n# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n# sell copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n# IN THE SOFTWARE.\n\n# Language for theme localization\nlanguage: en\n\n# Text direction (can be ltr or rtl), default: ltr\ndirection:\n\n# Feature flags for functionality that alters behavior significantly, and thus\n# may be a matter of taste\nfeature:\n\n  # Another layer on top of the main navigation for larger screens in the form\n  # of tabs, especially useful for larger documentation projects\n  tabs: false\n\n# Sets the primary and accent color palettes as defined in the Material Design\n# documentation - possible values can be looked up in the getting started guide\npalette:\n\n  # Primary color used for header, sidebar and links, default: indigo\n  primary:\n\n  # Accent color for highlighting user interaction, default: indigo\n  accent:\n\n# Fonts used by Material, automatically loaded from Google Fonts - see the site\n# for a list of available fonts\nfont:\n\n  # Default font for text\n  text: Roboto\n\n  # Fixed-width font for code listings\n  code: Roboto Mono\n\n# Favicon to be rendered\nfavicon: assets/images/favicon.png\n\n# The logo of the documentation shown in the header and navigation can either\n# be a Material Icon ligature (see https://material.io/icons/) or an image URL\nlogo:\n  icon: \"\\uE80C\"\n\n# Material includes the search in the header as a partial, not as a separate\n# template, so it's correct that search.html is missing\ninclude_search_page: false\n\n# Material doesn't use MkDocs search functionality but provides its own. For\n# this reason, only the search index needs to be built\nsearch_index_only: true\n\n# Static pages to build\nstatic_templates:\n  - 404.html\n"
  },
  {
    "path": "SecurityPaper-themes/partials/footer.html",
    "content": "{% import \"partials/language.html\" as lang with context %}\n<footer class=\"md-footer\">\n  {% if page.previous_page or page.next_page %}\n    <div class=\"md-footer-nav\">\n      <nav class=\"md-footer-nav__inner md-grid\">\n        {% if page.previous_page %}\n          <a href=\"{{ page.previous_page.url }}\" title=\"{{ page.previous_page.title }}\" class=\"md-flex md-footer-nav__link md-footer-nav__link--prev\" rel=\"prev\">\n            <div class=\"md-flex__cell md-flex__cell--shrink\">\n              <i class=\"md-icon md-icon--arrow-back md-footer-nav__button\"></i>\n            </div>\n            <div class=\"md-flex__cell md-flex__cell--stretch md-footer-nav__title\">\n              <span class=\"md-flex__ellipsis\">\n                <span class=\"md-footer-nav__direction\">\n                  {{ lang.t(\"footer.previous\") }}\n                </span>\n                {{ page.previous_page.title }}\n              </span>\n            </div>\n          </a>\n        {% endif %}\n        {% if page.next_page %}\n          <a href=\"{{ page.next_page.url }}\" title=\"{{ page.next_page.title }}\" class=\"md-flex md-footer-nav__link md-footer-nav__link--next\" rel=\"next\">\n            <div class=\"md-flex__cell md-flex__cell--stretch md-footer-nav__title\">\n              <span class=\"md-flex__ellipsis\">\n                <span class=\"md-footer-nav__direction\">\n                  {{ lang.t(\"footer.next\") }}\n                </span>\n                {{ page.next_page.title }}\n              </span>\n            </div>\n            <div class=\"md-flex__cell md-flex__cell--shrink\">\n              <i class=\"md-icon md-icon--arrow-forward md-footer-nav__button\"></i>\n            </div>\n          </a>\n        {% endif %}\n      </nav>\n    </div>\n  {% endif %}\n  <div class=\"md-footer-meta md-typeset\">\n    <div class=\"md-footer-meta__inner md-grid\">\n      <div class=\"md-footer-copyright\">\n        {% if config.copyright %}\n          <div class=\"md-footer-copyright__highlight\">\n            {{ config.copyright }}\n            <br>\n            <span id=\"busuanzi_container_site_pv\">为安全同学服务<span id=\"busuanzi_value_site_pv\"></span>次</span>\n          </div>\n        {% endif %}\n      </div>\n      {% block social %}\n        {% include \"partials/social.html\" %}\n      {% endblock %}\n    </div>\n  </div>\n</footer>\n"
  },
  {
    "path": "SecurityPaper-themes/partials/header.html",
    "content": "<header class=\"md-header\" data-md-component=\"header\">\n  <nav class=\"md-header-nav md-grid\">\n    <div class=\"md-flex\">\n\n      <div class=\"md-flex__cell md-flex__cell--shrink\">\n        <label class=\"md-icon md-icon--menu md-header-nav__button\" for=\"__drawer\"></label>\n      </div>\n      <div class=\"md-flex__cell md-flex__cell--stretch\">\n        <div class=\"md-flex__ellipsis md-header-nav__title\" data-md-component=\"title\">\n          {% block site_name %}\n            {% if config.site_name == page.title %}\n            <img src=\"{{ config.theme.logo }}\" height=\"57\">\n            {% else %}\n              <span class=\"md-header-nav__topic\" style=\"margin-top: 5px;\">\n                <img src=\"{{ config.theme.logo }}\"  height=\"47\"  style=\"padding-top: 2px; padding-bottom: 2px\">\n              </span>\n              <span class=\"md-header-nav__topic\" >\n                {{ page.title }}\n              </span>\n            {% endif %}\n          {% endblock %}\n        </div>\n      </div>\n      <div class=\"md-flex__cell md-flex__cell--shrink\">\n        {% block search_box %}\n          {% if \"search\" in config[\"plugins\"] %}\n            <label class=\"md-icon md-icon--search md-header-nav__button\" for=\"__search\"></label>\n            {% include \"partials/search.html\" %}\n          {% endif %}\n        {% endblock %}\n      </div>\n      {% if config.repo_url %}\n        <div class=\"md-flex__cell md-flex__cell--shrink\">\n          <div class=\"md-header-nav__source\">\n            {% include \"partials/source.html\" %}\n          </div>\n        </div>\n      {% endif %}\n    </div>\n  </nav>\n</header>\n"
  },
  {
    "path": "SecurityPaper-themes/partials/hero.html",
    "content": "{% set feature = config.theme.feature %}\n{% set class = \"md-hero\" %}\n{% if not feature.tabs %}\n  {% set class = \"md-hero md-hero--expand\" %}\n{% endif %}\n<div class=\"{{ class }}\" data-md-component=\"hero\">\n  <div class=\"md-hero__inner md-grid\">\n    {{ page.meta.hero }}\n  </div>\n</div>\n"
  },
  {
    "path": "SecurityPaper-themes/partials/integrations/analytics.html",
    "content": "<script>!function(e,a,t,n,o,c,i){e.GoogleAnalyticsObject=o,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,c=a.createElement(t),i=a.getElementsByTagName(t)[0],c.async=1,c.src=\"https://www.google-analytics.com/analytics.js\",i.parentNode.insertBefore(c,i)}(window,document,\"script\",0,\"ga\"),ga(\"create\",\"{{ config.google_analytics[0] }}\",\"{{ config.google_analytics[1] }}\"),ga(\"set\",\"anonymizeIp\",!0),ga(\"send\",\"pageview\");var links=document.getElementsByTagName(\"a\");if(Array.prototype.map.call(links,function(a){a.host!=document.location.host&&a.addEventListener(\"click\",function(){var e=a.getAttribute(\"data-md-action\")||\"follow\";ga(\"send\",\"event\",\"outbound\",e,a.href)})}),document.forms.search){var query=document.forms.search.query;query.addEventListener(\"blur\",function(){if(this.value){var e=document.location.pathname;ga(\"send\",\"pageview\",e+\"?q=\"+this.value)}})}</script>\n"
  },
  {
    "path": "SecurityPaper-themes/partials/integrations/disqus.html",
    "content": "{% set disqus = config.extra.disqus %}\n{% if page and page.meta and page.meta.disqus is string %}\n  {% set disqus = page.meta.disqus %}\n{% endif %}\n{% if not page.is_homepage and disqus %}\n  <h2 id=\"__comments\">{{ lang.t(\"meta.comments\") }}</h2>\n  <div id=\"disqus_thread\"></div>\n  <script>\n    var disqus_config = function () {\n      this.page.url = \"{{ page.canonical_url }}\";\n      this.page.identifier =\n        \"{{ page.canonical_url | replace(config.site_url, \"\") }}\";\n    };\n    (function() {\n      var d = document, s = d.createElement(\"script\");\n      s.src = \"//{{ disqus }}.disqus.com/embed.js\";\n      s.setAttribute(\"data-timestamp\", +new Date());\n      (d.head || d.body).appendChild(s);\n    })();\n  </script>\n{% endif %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/ar.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"ar\",\n  \"direction\": \"rtl\",\n  \"clipboard.copy\": \"نسخ إلى الحافظة\",\n  \"clipboard.copied\": \"تم النسخ الى الحافظة\",\n  \"edit.link.title\": \"عدل الصفحة\",\n  \"footer.previous\": \"السابقة\",\n  \"footer.next\": \"التالية\",\n  \"meta.comments\": \"التعليقات\",\n  \"meta.source\": \"المصدر\",\n  \"search.language\": \"\",\n  \"search.pipeline.stopwords\": false,\n  \"search.pipeline.trimmer\": false,\n  \"search.placeholder\": \"بحث\",\n  \"search.result.placeholder\": \"اكتب لبدء البحث\",\n  \"search.result.none\": \"لا توجد نتائج\",\n  \"search.result.one\": \"نتائج البحث مستند واحد\",\n  \"search.result.other\": \"نتائج البحث # مستندات\",\n  \"skip.link.title\": \"انتقل إلى المحتوى\",\n  \"source.link.title\": \"اذهب إلى المصدر\",\n  \"toc.title\": \"جدول المحتويات\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/ca.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"ca\",\n  \"clipboard.copy\": \"Còpia al porta-retalls\",\n  \"clipboard.copied\": \"Copiat al porta-retalls\",\n  \"edit.link.title\": \"Edita aquesta pàgina\",\n  \"footer.previous\": \"Anterior\",\n  \"footer.next\": \"Següent\",\n  \"meta.comments\": \"Comentaris\",\n  \"meta.source\": \"Codi font\",\n  \"search.language\": \"\",\n  \"search.placeholder\": \"Cerca\",\n  \"search.result.placeholder\": \"Escriu per a començar a cercar\",\n  \"search.result.none\": \"Cap document coincideix\",\n  \"search.result.one\": \"1 document coincident\",\n  \"search.result.other\": \"# documents coincidents\",\n  \"skip.link.title\": \"Salta el contingut\",\n  \"source.link.title\": \"Ves al repositori\",\n  \"toc.title\": \"Taula de continguts\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/cs.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"cs\",\n  \"clipboard.copy\": \"Kopírovat do schránky\",\n  \"clipboard.copied\": \"Zkopírováno do schránky\",\n  \"edit.link.title\": \"Upravit tuto stránku\",\n  \"footer.previous\": \"Předchozí\",\n  \"footer.next\": \"Další\",\n  \"meta.comments\": \"Komentáře\",\n  \"meta.source\": \"Zdroj\",\n  \"search.language\": \"ro\",\n  \"search.placeholder\": \"Hledat\",\n  \"search.result.placeholder\": \"Pište co se má vyhledat\",\n  \"search.result.none\": \"Nenalezeny žádné dokumenty\",\n  \"search.result.one\": \"Nalezený dokument: 1\",\n  \"search.result.other\": \"Nalezené dokumenty: #\",\n  \"skip.link.title\": \"Přeskočit obsah\",\n  \"source.link.title\": \"Přejít do repozitáře\",\n  \"toc.title\": \"Obsah\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/da.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"da\",\n  \"clipboard.copy\": \"Kopiér til udklipsholderen\",\n  \"clipboard.copied\": \"Kopieret til udklipsholderen\",\n  \"edit.link.title\": \"Redigér denne side\",\n  \"footer.previous\": \"Forrige\",\n  \"footer.next\": \"Næste\",\n  \"meta.comments\": \"Kommentarer\",\n  \"meta.source\": \"Kilde\",\n  \"search.language\": \"da\",\n  \"search.placeholder\": \"Søg\",\n  \"search.result.placeholder\": \"Indtask søgeord\",\n  \"search.result.none\": \"Ingen resultater fundet\",\n  \"search.result.one\": \"1 resultat\",\n  \"search.result.other\": \"# resultater\",\n  \"skip.link.title\": \"Gå til indholdet\",\n  \"source.link.title\": \"Åbn arkiv\",\n  \"toc.title\": \"Indholdsfortegnelse\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/de.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"de\",\n  \"clipboard.copy\": \"In Zwischenablage kopieren\",\n  \"clipboard.copied\": \"In Zwischenablage kopiert\",\n  \"edit.link.title\": \"Seite editieren\",\n  \"footer.previous\": \"Zurück\",\n  \"footer.next\": \"Weiter\",\n  \"meta.comments\": \"Kommentare\",\n  \"meta.source\": \"Quellcode\",\n  \"search.language\": \"de\",\n  \"search.placeholder\": \"Suche\",\n  \"search.result.placeholder\": \"Suchbegriff eingeben\",\n  \"search.result.none\": \"Keine Suchergebnisse\",\n  \"search.result.one\": \"1 Suchergebnis\",\n  \"search.result.other\": \"# Suchergebnisse\",\n  \"skip.link.title\": \"Zum Inhalt\",\n  \"source.link.title\": \"Quellcode\",\n  \"toc.title\": \"Inhaltsverzeichnis\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/en.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"en\",\n  \"direction\": \"ltr\",\n  \"clipboard.copy\": \"Copy to clipboard\",\n  \"clipboard.copied\": \"Copied to clipboard\",\n  \"edit.link.title\": \"Edit this page\",\n  \"footer.previous\": \"Previous\",\n  \"footer.next\": \"Next\",\n  \"meta.comments\": \"Comments\",\n  \"meta.source\": \"Source\",\n  \"search.language\": \"en\",\n  \"search.pipeline.stopwords\": true,\n  \"search.pipeline.trimmer\": true,\n  \"search.placeholder\": \"Search\",\n  \"search.result.placeholder\": \"Type to start searching\",\n  \"search.result.none\": \"No matching documents\",\n  \"search.result.one\": \"1 matching document\",\n  \"search.result.other\": \"# matching documents\",\n  \"search.tokenizer\": \"[\\s\\-]+\",\n  \"skip.link.title\": \"Skip to content\",\n  \"source.link.title\": \"Go to repository\",\n  \"toc.title\": \"Table of contents\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/es.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"es\",\n  \"clipboard.copy\": \"Copiar al portapapeles\",\n  \"clipboard.copied\": \"Copiado al portapapeles\",\n  \"edit.link.title\": \"Editar esta página\",\n  \"footer.previous\": \"Anterior\",\n  \"footer.next\": \"Siguiente\",\n  \"meta.comments\": \"Comentarios\",\n  \"meta.source\": \"Fuente\",\n  \"search.language\": \"es\",\n  \"search.placeholder\": \"Búsqueda\",\n  \"search.result.placeholder\": \"Teclee para comenzar búsqueda\",\n  \"search.result.none\": \"No se encontraron documentos\",\n  \"search.result.one\": \"1 documento encontrado\",\n  \"search.result.other\": \"# documentos encontrados\",\n  \"skip.link.title\": \"Saltar a contenido\",\n  \"source.link.title\": \"Ir al repositorio\",\n  \"toc.title\": \"Tabla de contenidos\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/fa.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"fa\",\n  \"direction\": \"rtl\",\n  \"clipboard.copy\": \"کپی کردن\",\n  \"clipboard.copied\": \"کپی شد\",\n  \"edit.link.title\": \"این صفحه را ویرایش کنید\",\n  \"footer.previous\": \"قبلی\",\n  \"footer.next\": \"بعدی\",\n  \"meta.comments\": \"نظرات\",\n  \"meta.source\": \"منبع\",\n  \"search.language\": \"\",\n  \"search.pipeline.stopwords\": false,\n  \"search.pipeline.trimmer\": false,\n  \"search.placeholder\": \"جستجو\",\n  \"search.result.placeholder\": \"برای شروع جستجو تایپ کنید\",\n  \"search.result.none\": \"سندی یافت نشد\",\n  \"search.result.one\": \"1 سند یافت شد\",\n  \"search.result.other\": \"# سند یافت شد\",\n  \"skip.link.title\": \"پرش به محتویات\",\n  \"source.link.title\": \"رفتن به مخزن\",\n  \"toc.title\": \"فهرست موضوعات\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/fi.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"fi\",\n  \"clipboard.copy\": \"Kopioi leikepöydälle\",\n  \"clipboard.copied\": \"Kopioitu leikepöydälle\",\n  \"edit.link.title\": \"Muokkaa tätä sivua\",\n  \"footer.previous\": \"Edellinen\",\n  \"footer.next\": \"Seuraava\",\n  \"meta.comments\": \"Kommentit\",\n  \"meta.source\": \"Lähdekodi\",\n  \"search.language\": \"fi\",\n  \"search.placeholder\": \"Hae\",\n  \"search.result.placeholder\": \"Kirjoita aloittaaksesi haun\",\n  \"search.result.none\": \"Ei täsmääviä dokumentteja\",\n  \"search.result.one\": \"1 täsmäävä dokumentti\",\n  \"search.result.other\": \"# täsmäävää dokumenttia\",\n  \"skip.link.title\": \"Hyppää sisältöön\",\n  \"source.link.title\": \"Mene repositoryyn\",\n  \"toc.title\": \"Sisällysluettelo\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/fr.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"fr\",\n  \"clipboard.copy\": \"Copier dans le presse-papier\",\n  \"clipboard.copied\": \"Copié dans le presse-papier\",\n  \"edit.link.title\": \"Editer cette page\",\n  \"footer.previous\": \"Précédent\",\n  \"footer.next\": \"Suivant\",\n  \"meta.comments\": \"Commentaires\",\n  \"meta.source\": \"Source\",\n  \"search.language\": \"fr\",\n  \"search.placeholder\": \"Rechercher\",\n  \"search.result.placeholder\": \"Taper pour démarrer la recherche\",\n  \"search.result.none\": \"Aucun document trouvé\",\n  \"search.result.one\": \"1 document trouvé\",\n  \"search.result.other\": \"# documents trouvés\",\n  \"source.link.title\": \"Aller au dépôt\",\n  \"toc.title\": \"Table des matières\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/gl.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"gl\",\n  \"clipboard.copy\": \"Copiar no cortapapeis\",\n  \"clipboard.copied\": \"Copiado no cortapapeis\",\n  \"edit.link.title\": \"Editar esta páxina\",\n  \"footer.previous\": \"Anterior\",\n  \"footer.next\": \"Seguinte\",\n  \"meta.comments\": \"Comentarios\",\n  \"meta.source\": \"Fonte\",\n  \"search.language\": \"es\",\n  \"search.placeholder\": \"Busca\",\n  \"search.result.placeholder\": \"Insira un termo\",\n  \"search.result.none\": \"Sen resultados\",\n  \"search.result.one\": \"1 resultado atopado\",\n  \"search.result.other\": \"# resultados atopados\",\n  \"skip.link.title\": \"Ir ao contido\",\n  \"source.link.title\": \"Ir ao repositorio\",\n  \"toc.title\": \"Táboa de contidos\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/he.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"he\",\n  \"direction\": \"rtl\",\n  \"clipboard.copy\": \"העתק ללוח\",\n  \"clipboard.copied\": \"הועתק ללוח\",\n  \"edit.link.title\": \"ערוך דף זה\",\n  \"footer.previous\": \"קודם\",\n  \"footer.next\": \"הַבָּא\",\n  \"meta.comments\": \"הערות\",\n  \"meta.source\": \"מָקוֹר\",\n  \"search.language\": \"\",\n  \"search.pipeline.stopwords\": false,\n  \"search.pipeline.trimmer\": false,\n  \"search.placeholder\": \"לחפש\",\n  \"search.result.placeholder\": \"הקלד כדי להתחיל לחפש\",\n  \"search.result.none\": \"אין מסמכים תואמים\",\n  \"search.result.one\": \"1 מסמך תואם\",\n  \"search.result.other\": \"# מסמך תואם\",\n  \"skip.link.title\": \"דלג לתוכן\",\n  \"source.link.title\": \"עבור אל מאגר\",\n  \"toc.title\": \"תוכן העניינים\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/hi.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"hi\",\n  \"clipboard.copy\": \"क्लिपबोर्ड पर कॉपी करें\",\n  \"clipboard.copied\": \"क्लिपबोर्ड पर कॉपी कर दिया गया\",\n  \"edit.link.title\": \"इस पृष्ठ को संपादित करें\",\n  \"footer.previous\": \"पिछला\",\n  \"footer.next\": \"आगामी\",\n  \"meta.comments\": \"टिप्पणियाँ\",\n  \"meta.source\": \"स्रोत\",\n  \"search.language\": \"\",\n  \"search.pipeline.stopwords\": false,\n  \"search.pipeline.trimmer\": false,\n  \"search.placeholder\": \"खोज\",\n  \"search.result.placeholder\": \"खोज शुरू करने के लिए टाइप करें\",\n  \"search.result.none\": \"कोई मिलान डॉक्यूमेंट नहीं\",\n  \"search.result.one\": \"1 मिलान डॉक्यूमेंट\",\n  \"search.result.other\": \"# मिलान डाक्यूमेंट्स\",\n  \"skip.link.title\": \"विषय पर बढ़ें\",\n  \"source.link.title\": \"रिपॉजिटरी पर जाएं\",\n  \"toc.title\": \"विषय - सूची\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/hr.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"hr\",\n  \"clipboard.copy\": \"Kopirajte u međuspremnik\",\n  \"clipboard.copied\": \"Kopirano u međuspremnik\",\n  \"edit.link.title\": \"Uredi stranicu\",\n  \"footer.previous\": \"Prethodno\",\n  \"footer.next\": \"Sljedeće\",\n  \"meta.comments\": \"Komentari\",\n  \"meta.source\": \"Izvor\",\n  \"search.language\": \"\",\n  \"search.pipeline.stopwords\": false,\n  \"search.pipeline.trimmer\": false,\n  \"search.placeholder\": \"Pretraživanje\",\n  \"search.result.placeholder\": \"Unesite pojam pretraživanja\",\n  \"search.result.none\": \"Ništa nije pronađeno\",\n  \"search.result.one\": \"1 rezultat pretraživanja\",\n  \"search.result.other\": \"# rezultata pretraživanja\",\n  \"skip.link.title\": \"Preskočite na sadržaj\",\n  \"source.link.title\": \"Idite u repozitorij\",\n  \"toc.title\": \"Sadržaj\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/hu.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"hu\",\n  \"clipboard.copy\": \"Másolás vágólapra\",\n  \"clipboard.copied\": \"Vágólapra másolva\",\n  \"edit.link.title\": \"Oldal szerkesztése\",\n  \"footer.previous\": \"Előző\",\n  \"footer.next\": \"Következő\",\n  \"meta.comments\": \"Hozzászólások\",\n  \"meta.source\": \"Forrás\",\n  \"search.language\": \"hu\",\n  \"search.placeholder\": \"Keresés\",\n  \"search.result.placeholder\": \"Kereséshez írj ide valamit\",\n  \"search.result.none\": \"Nincs találat\",\n  \"search.result.one\": \"1 egyező dokumentum\",\n  \"search.result.other\": \"# egyező dokumentum\",\n  \"skip.link.title\": \"Kihagyás\",\n  \"source.link.title\": \"Főoldalra ugrás\",\n  \"toc.title\": \"Tartalomjegyzék\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/id.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"id\",\n  \"clipboard.copy\": \"Salin ke memori\",\n  \"clipboard.copied\": \"Tersalin ke memori\",\n  \"edit.link.title\": \"Ubah halaman ini\",\n  \"footer.previous\": \"Sebelumnya\",\n  \"footer.next\": \"Selanjutnya\",\n  \"meta.comments\": \"Komentar\",\n  \"meta.source\": \"Sumber\",\n  \"search.language\": \"\",\n  \"search.pipeline.stopwords\": false,\n  \"search.pipeline.trimmer\": false,\n  \"search.placeholder\": \"Cari\",\n  \"search.result.placeholder\": \"Ketik untuk mulai pencarian\",\n  \"search.result.none\": \"Tidak ada dokumen yang sesuai\",\n  \"search.result.one\": \"1 dokumen ditemukan\",\n  \"search.result.other\": \"# dokumen ditemukan\",\n  \"skip.link.title\": \"Lewati ke isi\",\n  \"source.link.title\": \"Menuju repositori\",\n  \"toc.title\": \"Daftar isi\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/it.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"it\",\n  \"clipboard.copy\": \"Copia\",\n  \"clipboard.copied\": \"Copiato\",\n  \"edit.link.title\": \"Modifica\",\n  \"footer.previous\": \"Precedente\",\n  \"footer.next\": \"Prossimo\",\n  \"meta.comments\": \"Commenti\",\n  \"meta.source\": \"Sorgente\",\n  \"search.language\": \"it\",\n  \"search.placeholder\": \"Cerca\",\n  \"search.result.placeholder\": \"Scrivi per iniziare a cercare\",\n  \"search.result.none\": \"Nessun documento trovato\",\n  \"search.result.one\": \"1 documento trovato\",\n  \"search.result.other\": \"# documenti trovati\",\n  \"skip.link.title\": \"Vai al contenuto\",\n  \"source.link.title\": \"Apri repository\",\n  \"toc.title\": \"Indice\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/ja.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"ja\",\n  \"clipboard.copy\": \"クリップボードへコピー\",\n  \"clipboard.copied\": \"コピーしました\",\n  \"edit.link.title\": \"編集\",\n  \"footer.previous\": \"前\",\n  \"footer.next\": \"次\",\n  \"meta.comments\": \"コメント\",\n  \"meta.source\": \"ソース\",\n  \"search.language\": \"jp\",\n  \"search.placeholder\": \"検索\",\n  \"search.result.placeholder\": \"検索キーワードを入力してください\",\n  \"search.result.none\": \"何も見つかりませんでした\",\n  \"search.result.one\": \"1件見つかりました\",\n  \"search.result.other\": \"#件見つかりました\",\n  \"search.tokenizer\": \"[\\s\\-　、。，．]+\",\n  \"source.link.title\": \"リポジトリへ\",\n  \"toc.title\": \"目次\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/kr.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"kr\",\n  \"clipboard.copy\": \"클립보드로 복사\",\n  \"clipboard.copied\": \"클립보드에 복사됨\",\n  \"edit.link.title\": \"이 페이지를 편집\",\n  \"footer.previous\": \"이전\",\n  \"footer.next\": \"다음\",\n  \"meta.comments\": \"댓글\",\n  \"meta.source\": \"출처\",\n  \"search.language\": \"jp\",\n  \"search.placeholder\": \"검색\",\n  \"search.result.placeholder\": \"검색어를 입력하세요\",\n  \"search.result.none\": \"검색어와 일치하는 문서가 없습니다\",\n  \"search.result.one\": \"1개의 일치하는 문서\",\n  \"search.result.other\": \"#개의 일치하는 문서\",\n  \"source.link.title\": \"저장소로 이동\",\n  \"toc.title\": \"목차\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/nl.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"nl\",\n  \"clipboard.copy\": \"Kopiëren naar klembord\",\n  \"clipboard.copied\": \"Gekopieerd naar klembord\",\n  \"edit.link.title\": \"Wijzig deze pagina\",\n  \"footer.previous\": \"Vorige\",\n  \"footer.next\": \"Volgende\",\n  \"meta.comments\": \"Reacties\",\n  \"meta.source\": \"Bron\",\n  \"search.language\": \"du\",\n  \"search.placeholder\": \"Zoeken\",\n  \"search.result.placeholder\": \"Typ om te beginnen met zoeken\",\n  \"search.result.none\": \"Geen overeenkomende documenten\",\n  \"search.result.one\": \"1 overeenkomende document\",\n  \"search.result.other\": \"# overeenkomende documenten\",\n  \"skip.link.title\": \"Ga naar inhoud\",\n  \"source.link.title\": \"Ga naar repository\",\n  \"toc.title\": \"Inhoudsopgave\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/no.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"no\",\n  \"clipboard.copy\": \"Kopier til utklippstavlen\",\n  \"clipboard.copied\": \"Kopiert til utklippstavlen\",\n  \"edit.link.title\": \"Rediger denne siden\",\n  \"footer.previous\": \"Forrige\",\n  \"footer.next\": \"Neste\",\n  \"meta.comments\": \"Kommentarer\",\n  \"meta.source\": \"Kilde\",\n  \"search.language\": \"no\",\n  \"search.placeholder\": \"Søk\",\n  \"search.result.placeholder\": \"Skriv søkeord\",\n  \"search.result.none\": \"Ingen treff\",\n  \"search.result.one\": \"1 treff\",\n  \"search.result.other\": \"# treff\",\n  \"skip.link.title\": \"Gå til innhold\",\n  \"source.link.title\": \"Gå til kilde\",\n  \"toc.title\": \"Innholdsfortegnelse\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/pl.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"pl\",\n  \"clipboard.copy\": \"Kopiuj do schowka\",\n  \"clipboard.copied\": \"Skopiowane\",\n  \"edit.link.title\": \"Edytuj tę stronę\",\n  \"footer.previous\": \"Poprzednia strona\",\n  \"footer.next\": \"Następna strona\",\n  \"meta.comments\": \"Komentarze\",\n  \"meta.source\": \"Kod źródłowy\",\n  \"search.language\": \"\",\n  \"search.pipeline.stopwords\": false,\n  \"search.pipeline.trimmer\": false,\n  \"search.placeholder\": \"Szukaj\",\n  \"search.result.placeholder\": \"Zacznij pisać, aby szukać\",\n  \"search.result.none\": \"Brak wyników wyszukiwania\",\n  \"search.result.one\": \"Wyniki wyszukiwania: 1\",\n  \"search.result.other\": \"Wyniki wyszukiwania: #\",\n  \"skip.link.title\": \"Przejdź do treści\",\n  \"source.link.title\": \"Idź do repozytorium\",\n  \"toc.title\": \"Spis treści\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/pt.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"pt\",\n  \"clipboard.copy\": \"Copiar para área de transferência\",\n  \"clipboard.copied\": \"Copiado para área de transferência\",\n  \"edit.link.title\": \"Editar esta página\",\n  \"footer.previous\": \"Anterior\",\n  \"footer.next\": \"Próximo\",\n  \"meta.comments\": \"Comentários\",\n  \"meta.source\": \"Fonte\",\n  \"search.language\": \"pt\",\n  \"search.placeholder\": \"Buscar\",\n  \"search.result.placeholder\": \"Digite para iniciar a busca\",\n  \"search.result.none\": \"Nenhum resultado encontrado\",\n  \"search.result.one\": \"1 resultado encontrado\",\n  \"search.result.other\": \"# resultados encontrados\",\n  \"skip.link.title\": \"Ir para o conteúdo\",\n  \"source.link.title\": \"Ir ao repositório\",\n  \"toc.title\": \"Índice\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/ru.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"ru\",\n  \"clipboard.copy\": \"Копировать в буфер\",\n  \"clipboard.copied\": \"Скопировано в буфер\",\n  \"edit.link.title\": \"Редактировать страницу\",\n  \"footer.previous\": \"Назад\",\n  \"footer.next\": \"Вперед\",\n  \"meta.comments\": \"Комментарии\",\n  \"meta.source\": \"Исходный код\",\n  \"search.language\": \"ru\",\n  \"search.placeholder\": \"Поиск\",\n  \"search.result.placeholder\": \"Начните печатать для поиска\",\n  \"search.result.none\": \"Совпадений не найдено\",\n  \"search.result.one\": \"Найдено 1 совпадение\",\n  \"search.result.other\": \"Найдено # совпадений\",\n  \"skip.link.title\": \"Перейти к содержанию\",\n  \"source.link.title\": \"Перейти к репозиторию\",\n  \"toc.title\": \"Содержание\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/sh.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"sh\",\n  \"clipboard.copy\": \"Kopiraj u klipbord\",\n  \"clipboard.copied\": \"Iskopirano u klipbord\",\n  \"edit.link.title\": \"Uredi stranicu\",\n  \"footer.previous\": \"Prethodno\",\n  \"footer.next\": \"Sledeće\",\n  \"meta.comments\": \"Komentari\",\n  \"meta.source\": \"Izvor\",\n  \"search.language\": \"ro\",\n  \"search.placeholder\": \"Pretraga\",\n  \"search.result.placeholder\": \"Unesite pojam pretrage\",\n  \"search.result.none\": \"Ništa nije pronađeno\",\n  \"search.result.one\": \"1 rezultat pretrage\",\n  \"search.result.other\": \"# rezultata pretrage\",\n  \"skip.link.title\": \"Idi na tekst\",\n  \"source.link.title\": \"Idi u repozitorijum\",\n  \"toc.title\": \"Sadržaj\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/sk.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"sk\",\n  \"clipboard.copy\": \"Kopírovať do schránky\",\n  \"clipboard.copied\": \"Skopírované do schránky\",\n  \"edit.link.title\": \"Upraviť túto stránku\",\n  \"footer.previous\": \"Späť\",\n  \"footer.next\": \"Ďalej\",\n  \"meta.comments\": \"Komentáre\",\n  \"meta.source\": \"Zdroj\",\n  \"search.language\": \"sk\",\n  \"search.placeholder\": \"Hľadať\",\n  \"search.result.placeholder\": \"Pre vyhľadávanie začni písať\",\n  \"search.result.none\": \"Žiadne vyhovujúce dokumenty\",\n  \"search.result.one\": \"Vyhovujúci dokument: 1\",\n  \"search.result.other\": \"Vyhovujúce dokumenty: #\",\n  \"skip.link.title\": \"Preskočiť na obsah\",\n  \"source.link.title\": \"Zobraziť repozitár\",\n  \"toc.title\": \"Obsah\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/sr.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"sr\",\n  \"clipboard.copy\": \"Копирај у клипборд\",\n  \"clipboard.copied\": \"Ископирано у клипборд\",\n  \"edit.link.title\": \"Уреди страницу\",\n  \"footer.previous\": \"Претходно\",\n  \"footer.next\": \"Следеће\",\n  \"meta.comments\": \"Коментари\",\n  \"meta.source\": \"Извор\",\n  \"search.language\": \"\",\n  \"search.pipeline.stopwords\": false,\n  \"search.pipeline.trimmer\": false,\n  \"search.placeholder\": \"Претрага\",\n  \"search.result.placeholder\": \"Унесите појам претраге\",\n  \"search.result.none\": \"Нису пронађени документи\",\n  \"search.result.one\": \"1 резултат претраге\",\n  \"search.result.other\": \"# резултата претраге\",\n  \"skip.link.title\": \"Иди на текст\",\n  \"source.link.title\": \"Иди у репозиторијум\",\n  \"toc.title\": \"Садржај\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/sv.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"sv\",\n  \"clipboard.copy\": \"Kopiera till urklipp\",\n  \"clipboard.copied\": \"Kopierat till urklipp\",\n  \"edit.link.title\": \"Redigera sidan\",\n  \"footer.previous\": \"Föregående\",\n  \"footer.next\": \"Nästa\",\n  \"meta.comments\": \"Kommentarer\",\n  \"meta.source\": \"Källa\",\n  \"search.language\": \"sv\",\n  \"search.placeholder\": \"Sök\",\n  \"search.result.placeholder\": \"Skriv sökord\",\n  \"search.result.none\": \"Inga sökresultat\",\n  \"search.result.one\": \"1 sökresultat\",\n  \"search.result.other\": \"# sökresultat\",\n  \"skip.link.title\": \"Gå till innehållet\",\n  \"source.link.title\": \"Gå till datakatalog\",\n  \"toc.title\": \"Innehållsförteckning\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/tr.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"tr\",\n  \"clipboard.copy\": \"Kopyala\",\n  \"clipboard.copied\": \"Kopyalandı\",\n  \"edit.link.title\": \"Düzenle\",\n  \"footer.previous\": \"Önceki\",\n  \"footer.next\": \"Sonraki\",\n  \"meta.comments\": \"Yorumlar\",\n  \"meta.source\": \"Kaynak\",\n  \"search.language\": \"tr\",\n  \"search.placeholder\": \"Ara\",\n  \"search.result.placeholder\": \"Aramaya başlamak için yazın\",\n  \"search.result.none\": \"Eşleşen doküman bulunamadı\",\n  \"search.result.one\": \"1 doküman bulundu\",\n  \"search.result.other\": \"# doküman bulundu\",\n  \"source.link.title\": \"Depoya git\",\n  \"toc.title\": \"İçindekiler\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/uk.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"uk\",\n  \"clipboard.copy\": \"Скопіювати в буфер\",\n  \"clipboard.copied\": \"Скопійовано в буфер\",\n  \"edit.link.title\": \"Редагувати сторінку\",\n  \"footer.previous\": \"Назад\",\n  \"footer.next\": \"Вперед\",\n  \"meta.comments\": \"Коментарі\",\n  \"meta.source\": \"Вихідний код\",\n  \"search.language\": \"ru\",\n  \"search.placeholder\": \"Пошук\",\n  \"search.result.placeholder\": \"Розпочніть писати для пошуку\",\n  \"search.result.none\": \"Збігів не знайдено\",\n  \"search.result.one\": \"Знайдено 1 збіг\",\n  \"search.result.other\": \"Знайдено # збігів\",\n  \"skip.link.title\": \"Перейти до змісту\",\n  \"source.link.title\": \"Перейти до репозиторію\",\n  \"toc.title\": \"Зміст\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/vi.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"vi\",\n  \"clipboard.copy\": \"Sao chép vào bộ nhớ\",\n  \"clipboard.copied\": \"Sao chép xong\",\n  \"edit.link.title\": \"Chỉnh sửa\",\n  \"footer.previous\": \"Trước\",\n  \"footer.next\": \"Sau\",\n  \"meta.comments\": \"Bình luận\",\n  \"meta.source\": \"Mã nguồn\",\n  \"search.placeholder\": \"Tìm kiếm\",\n  \"search.result.placeholder\": \"Nhập để bắt đầu tìm kiếm\",\n  \"search.result.none\": \"Không tìm thấy tài liệu liên quan\",\n  \"search.result.one\": \"1 tài liệu liên quan\",\n  \"search.result.other\": \"# tài liệu liên quan\",\n  \"skip.link.title\": \"Vào thẳng nội dung\",\n  \"source.link.title\": \"Đến kho lưu trữ mã nguồn\",\n  \"toc.title\": \"Mục lục\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/zh-Hant.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"zh-Hant\",\n  \"clipboard.copy\": \"拷貝\",\n  \"clipboard.copied\": \"已拷貝\",\n  \"edit.link.title\": \"編輯此頁\",\n  \"footer.previous\": \"上一頁\",\n  \"footer.next\": \"下一頁\",\n  \"meta.comments\": \"評論\",\n  \"meta.source\": \"來源\",\n  \"search.language\": \"jp\",\n  \"search.placeholder\": \"搜尋\",\n  \"search.result.placeholder\": \"鍵入以開始檢索\",\n  \"search.result.none\": \"沒有找到符合條件的結果\",\n  \"search.result.one\": \"找到 1 个符合條件的結果\",\n  \"search.result.other\": \"# 個符合條件的結果\",\n  \"search.tokenizer\": \"[\\，\\。]+\",\n  \"skip.link.title\": \"跳轉至\",\n  \"source.link.title\": \"前往 Github 倉庫\",\n  \"toc.title\": \"目錄\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/zh-TW.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"zh-Hant\",\n  \"clipboard.copy\": \"複製\",\n  \"clipboard.copied\": \"已複製\",\n  \"edit.link.title\": \"編輯此頁\",\n  \"footer.previous\": \"上一頁\",\n  \"footer.next\": \"下一頁\",\n  \"meta.comments\": \"留言\",\n  \"meta.source\": \"來源\",\n  \"search.language\": \"jp\",\n  \"search.placeholder\": \"搜尋\",\n  \"search.result.placeholder\": \"打字進行搜尋\",\n  \"search.result.none\": \"沒有符合的項目\",\n  \"search.result.one\": \"找到 1 個符合的項目\",\n  \"search.result.other\": \"找到 # 個符合的項目\",\n  \"search.tokenizer\": \"[\\，\\。]+\",\n  \"skip.link.title\": \"跳轉到\",\n  \"source.link.title\": \"前往倉庫\",\n  \"toc.title\": \"本頁目錄\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language/zh.html",
    "content": "{% macro t(key) %}{{ {\n  \"language\": \"zh\",\n  \"clipboard.copy\": \"复制\",\n  \"clipboard.copied\": \"已复制\",\n  \"edit.link.title\": \"编辑此页\",\n  \"footer.previous\": \"后退\",\n  \"footer.next\": \"前进\",\n  \"meta.comments\": \"评论\",\n  \"meta.source\": \"来源\",\n  \"search.language\": \"jp\",\n  \"search.placeholder\": \"搜索\",\n  \"search.result.placeholder\": \"键入以开始搜索\",\n  \"search.result.none\": \"没有找到符合条件的结果\",\n  \"search.result.one\": \"找到 1 个符合条件的结果\",\n  \"search.result.other\": \"# 个符合条件的结果\",\n  \"search.tokenizer\": \"[\\，\\。]+\",\n  \"skip.link.title\": \"跳转至\",\n  \"source.link.title\": \"前往 Github 仓库\",\n  \"toc.title\": \"目录\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/language.html",
    "content": "{% import \"partials/language/\" + config.theme.language + \".html\" as lang %}\n{% import \"partials/language/en.html\" as fallback %}\n{% macro t(key) %}{{ {\n  \"direction\": config.theme.direction,\n  \"search.language\": (\n    config.extra.search | default({})\n  ).language,\n  \"search.tokenizer\": (\n    config.extra.search | default({})\n  ).tokenizer | default(\"\", true),\n}[key] or lang.t(key) or fallback.t(key) }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/nav-item.html",
    "content": "{% set class = \"md-nav__item\" %}\n{% if nav_item.active %}\n  {% set class = \"md-nav__item md-nav__item--active\" %}\n{% endif %}\n{% if nav_item.children %}\n  <li class=\"{{ class }} md-nav__item--nested\">\n    {% if nav_item.active %}\n      <input class=\"md-toggle md-nav__toggle\" data-md-toggle=\"{{ path }}\" type=\"checkbox\" id=\"{{ path }}\" checked>\n    {% else %}\n      <input class=\"md-toggle md-nav__toggle\" data-md-toggle=\"{{ path }}\" type=\"checkbox\" id=\"{{ path }}\">\n    {% endif %}\n    <label class=\"md-nav__link\" for=\"{{ path }}\">\n      {{ nav_item.title }}\n    </label>\n    <nav class=\"md-nav\" data-md-component=\"collapsible\" data-md-level=\"{{ level }}\">\n      <label class=\"md-nav__title\" for=\"{{ path }}\">\n        {{ nav_item.title }}\n      </label>\n      <ul class=\"md-nav__list\" data-md-scrollfix>\n        {% set base = path %}\n        {% for nav_item in nav_item.children %}\n          {% set path = base + \"-\" + loop.index | string %}\n          {% set level = level + 1 %}\n          {% include \"partials/nav-item.html\"  %}\n        {% endfor %}\n      </ul>\n    </nav>\n  </li>\n{% elif nav_item == page %}\n  <li class=\"{{ class }}\">\n    {% set toc_ = page.toc %}\n    <input class=\"md-toggle md-nav__toggle\" data-md-toggle=\"toc\" type=\"checkbox\" id=\"__toc\">\n    {% if toc_ | first is defined and \"\\x3ch1 id=\" in page.content %}\n      {% set toc_ = (toc_ | first).children %}\n    {% endif %}\n    {% if toc_ | first is defined %}\n      <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n        {{ nav_item.title }}\n      </label>\n    {% endif %}\n    <a href=\"{{ nav_item.url }}\" title=\"{{ nav_item.title }}\" class=\"md-nav__link md-nav__link--active\">\n      {{ nav_item.title }}\n    </a>\n    {% if toc_ | first is defined %}\n      {% include \"partials/toc.html\" %}\n    {% endif %}\n  </li>\n{% else %}\n  <li class=\"{{ class }}\">\n    <a href=\"{{ nav_item.url }}\" title=\"{{ nav_item.title }}\" class=\"md-nav__link\">\n      {{ nav_item.title }}\n    </a>\n  </li>\n{% endif %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/nav.html",
    "content": "<nav class=\"md-nav md-nav--primary\" data-md-level=\"0\">\n\n  {% if config.repo_url %}\n    <div class=\"md-nav__source\">\n      {% include \"partials/source.html\" %}\n    </div>\n  {% endif %}\n  <ul class=\"md-nav__list\" data-md-scrollfix>\n    {% for nav_item in nav %}\n      {% set path = \"nav-\" + loop.index | string %}\n      {% set level = 1 %}\n      {% include \"partials/nav-item.html\" %}\n    {% endfor %}\n  </ul>\n</nav>\n"
  },
  {
    "path": "SecurityPaper-themes/partials/palette.html",
    "content": "{% macro primary(key) %}{{ {\n  \"red\":         \"#ef5350\",\n  \"pink\":        \"#e91e63\",\n  \"purple\":      \"#ab47bc\",\n  \"deep-purple\": \"#7e57c2\",\n  \"indigo\":      \"#3f51b5\",\n  \"blue\":        \"#2196f3\",\n  \"light-blue\":  \"#03a9f4\",\n  \"cyan\":        \"#00bcd4\",\n  \"teal\":        \"#009688\",\n  \"green\":       \"#4caf50\",\n  \"light-green\": \"#7cb342\",\n  \"lime\":        \"#c0ca33\",\n  \"yellow\":      \"#f9a825\",\n  \"amber\":       \"#ffa000\",\n  \"orange\":      \"#fb8c00\",\n  \"deep-orange\": \"#ff7043\",\n  \"brown\":       \"#795548\",\n  \"grey\":        \"#757575\",\n  \"blue-grey\":   \"#546e7a\"\n}[key] }}{% endmacro %}\n{% macro accent(key) %}{{ {\n  \"red\":         \"#ff1744\",\n  \"pink\":        \"#f50057\",\n  \"purple\":      \"#e040fb\",\n  \"deep-purple\": \"#7c4dff\",\n  \"indigo\":      \"#536dfe\",\n  \"blue\":        \"#448aff\",\n  \"light-blue\":  \"#0091ea\",\n  \"cyan\":        \"#00b8d4\",\n  \"teal\":        \"#00bfa5\",\n  \"green\":       \"#00c853\",\n  \"light-green\": \"#64dd17\",\n  \"lime\":        \"#aeea00\",\n  \"yellow\":      \"#ffd600\",\n  \"amber\":       \"#ffab00\",\n  \"orange\":      \"#ff9100\",\n  \"deep-orange\": \"#ff6e40\"\n}[key] }}{% endmacro %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/search.html",
    "content": "{% import \"partials/language.html\" as lang with context %}\n<div class=\"md-search\" data-md-component=\"search\" role=\"dialog\">\n  <label class=\"md-search__overlay\" for=\"__search\"></label>\n  <div class=\"md-search__inner\" role=\"search\">\n    <form class=\"md-search__form\" name=\"search\">\n      <input type=\"text\" class=\"md-search__input\" name=\"query\" placeholder=\"{{ lang.t('search.placeholder') }}\" autocapitalize=\"off\" autocorrect=\"off\" autocomplete=\"off\" spellcheck=\"false\" data-md-component=\"query\" data-md-state=\"active\">\n      <label class=\"md-icon md-search__icon\" for=\"__search\"></label>\n      <button type=\"reset\" class=\"md-icon md-search__icon\" data-md-component=\"reset\" tabindex=\"-1\">\n        &#xE5CD;\n      </button>\n    </form>\n    <div class=\"md-search__output\">\n      <div class=\"md-search__scrollwrap\" data-md-scrollfix>\n        <div class=\"md-search-result\" data-md-component=\"result\">\n          <div class=\"md-search-result__meta\">\n            {{ lang.t(\"search.result.placeholder\") }}\n          </div>\n          <ol class=\"md-search-result__list\"></ol>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "SecurityPaper-themes/partials/social.html",
    "content": "{% if config.extra.social %}\n  <div class=\"md-footer-social\">\n    <link rel=\"stylesheet\" href=\"{{ '/assets/fonts/font-awesome.css' }}\">\n    {% for social in config.extra.social %}\n      <a href=\"{{ social.link }}\" class=\"md-footer-social__link fa fa-{{ social.type }}\"></a>\n    {% endfor %}\n  </div>\n{% endif %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/source.html",
    "content": "{% import \"partials/language.html\" as lang with context %}\n{% set platform = config.extra.repo_icon or config.repo_url %}\n{% if \"github\" in platform %}\n  {% set repo_type = \"github\" %}\n{% elif \"gitlab\" in platform %}\n  {% set repo_type = \"gitlab\" %}\n{% elif \"bitbucket\" in platform %}\n  {% set repo_type = \"bitbucket\" %}\n{% else %}\n  {% set repo_type = \"\" %}\n{% endif %}\n{% block repo %}\n  <a href=\"{{ config.repo_url }}\" title=\"{{ lang.t('source.link.title') }}\" class=\"md-source\" data-md-source=\"{{ repo_type }}\">\n    {% if repo_type %}\n      <div class=\"md-source__icon\">\n        <svg viewBox=\"0 0 24 24\" width=\"24\" height=\"24\">\n          <use xlink:href=\"#__{{ repo_type }}\" width=\"24\" height=\"24\"></use>\n        </svg>\n      </div>\n    {% endif %}\n    <div class=\"md-source__repository\">\n      {{ config.repo_name }}\n    </div>\n  </a>\n{% endblock %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/tabs-item.html",
    "content": "{% if nav_item.is_homepage %}\n  <li class=\"md-tabs__item\">\n    {% if not page.ancestors | length and nav | selectattr(\"url\", page.url) %}\n      <a href=\"{{ nav_item.url }}\" title=\"{{ nav_item.title }}\" class=\"md-tabs__link md-tabs__link--active\">\n        {{ nav_item.title }}\n      </a>\n    {% else %}\n      <a href=\"{{ nav_item.url }}\" title=\"{{ nav_item.title }}\" class=\"md-tabs__link\">\n        {{ nav_item.title }}\n      </a>\n    {% endif %}\n  </li>\n{% elif nav_item.children and nav_item.children | length > 0 %}\n  {% set title = title | default(nav_item.title) %}\n  {% if (nav_item.children | first).children %}\n    {% set nav_item = nav_item.children | first %}\n    {% include \"partials/tabs-item.html\" %}\n  {% else %}\n    <li class=\"md-tabs__item\">\n      {% if nav_item.active %}\n        <a href=\"{{ (nav_item.children | first).url }}\" title=\"{{ title }}\" class=\"md-tabs__link md-tabs__link--active\">\n          {{ title }}\n        </a>\n      {% else %}\n        <a href=\"{{ (nav_item.children | first).url }}\" title=\"{{ title }}\" class=\"md-tabs__link\">\n          {{ title }}\n        </a>\n      {% endif %}\n    </li>\n  {% endif %}\n{% endif %}\n"
  },
  {
    "path": "SecurityPaper-themes/partials/tabs.html",
    "content": "{% set class = \"md-tabs\" %}\n{% if page.ancestors | length > 0 %}\n  {% set class = \"md-tabs md-tabs--active\" %}\n{% endif %}\n<nav class=\"{{ class }}\" data-md-component=\"tabs\">\n  <div class=\"md-tabs__inner md-grid\">\n    <ul class=\"md-tabs__list\">\n      {% for nav_item in nav %}\n        {% include \"partials/tabs-item.html\" %}\n      {% endfor %}\n    </ul>\n  </div>\n</nav>\n"
  },
  {
    "path": "SecurityPaper-themes/partials/toc-item.html",
    "content": "<li class=\"md-nav__item\">\n  <a href=\"{{ toc_item.url }}\" title=\"{{ toc_item.title }}\" class=\"md-nav__link\">\n    {{ toc_item.title }}\n  </a>\n  {% if toc_item.children %}\n    <nav class=\"md-nav\">\n      <ul class=\"md-nav__list\">\n        {% for toc_item in toc_item.children %}\n          {% include \"partials/toc-item.html\" %}\n        {% endfor %}\n      </ul>\n    </nav>\n  {% endif %}\n</li>\n"
  },
  {
    "path": "SecurityPaper-themes/partials/toc.html",
    "content": "{% import \"partials/language.html\" as lang with context %}\n<nav class=\"md-nav md-nav--secondary\">\n  {% set toc_ = page.toc %}\n  {% if toc_ | first is defined and \"\\x3ch1 id=\" in page.content %}\n    {% set toc_ = (toc_ | first).children %}\n  {% endif %}\n  {% if toc_ | first is defined %}\n    <label class=\"md-nav__title\" for=\"__toc\">{{ lang.t(\"toc.title\") }}</label>\n    <ul class=\"md-nav__list\" data-md-scrollfix>\n      {% for toc_item in toc_ %}\n        {% include \"partials/toc-item.html\" %}\n      {% endfor %}\n      {% if page.meta.source and page.meta.source | length > 0 %}\n        <li class=\"md-nav__item\">\n          <a href=\"#__source\" title=\"{{ lang.t('meta.source') }}\" class=\"md-nav__link md-nav__link--active\">\n            {{ lang.t(\"meta.source\") }}\n          </a>\n        </li>\n      {% endif %}\n      {% set disqus = config.extra.disqus %}\n      {% if page and page.meta and page.meta.disqus is string %}\n        {% set disqus = page.meta.disqus %}\n      {% endif %}\n      {% if not page.is_homepage and disqus %}\n        <li class=\"md-nav__item\">\n          <a href=\"#__comments\" title=\"{{ lang.t('meta.comments') }}\" class=\"md-nav__link md-nav__link--active\">\n            {{ lang.t(\"meta.comments\") }}\n          </a>\n        </li>\n      {% endif %}\n    </ul>\n  {% endif %}\n</nav>\n"
  },
  {
    "path": "docs/1.SDL介绍/1-什么是SDL.md",
    "content": "\n# 01.什么是SDL\n\n作者：Lost Maniac\n\n------\n\nSDL是微软提出的一种软件开发安全生命周期管理的一种最佳安全实践，全称为Security Development Lifecycle。\n\nSDL是微软软件开发安全保障流程，结合了软件开发整个生命周期，将安全工程师嵌入到整个开发流程，和研发一起来协同工作保障整个软件生命周期内的安全。\n\nSDL分为7个步骤和16种最佳安全实践的方式来保证整体安全流程周期内的可控性。\n"
  },
  {
    "path": "docs/1.SDL介绍/2-企业为什么需求SDL.md",
    "content": "\n# 02.企业为什么需求SDL\n\n\n作者：Murviet\n\n-----\n\n在SDL方法中，目的是为了从安全漏洞产生的根源上解决应用安全问题，通过对软件开发流程的控制，保证产品的安全性。\n\n当一个企业对安全相对重视的情况下，在每年进行安全轮询时还总能找到各种各样的安全问题。每年的漏洞数量并没有明显的下降。这个时候就应该\n 考虑从根源解决问题。\n\n由于企业的开发人员的技术参差不齐，部分相关开发者心中没有安全的相关概念、项目的上线及迭代更新没有相应的规范等等，这些问题都将会是导致出现安全问题的根本原因。\n\n而SDL规范流程正是从根本原因解决这些问题。SDL对软件开发过程中所有参与该项目的相关工种，都将引入相关的安全概念，形成一个闭环，从而解决出现安全的根本问题。"
  },
  {
    "path": "docs/1.SDL介绍/3-哪些企业需要SDL.md",
    "content": "\n# 03.哪些企业需要SDL\n\n作者：Murviet\n\n----\n\n哪些企业需要SDL\n\n随着社会的发展，现在基本上所有的企业都在利用计算机网络进行办公，几乎所有的商业信息都存储在了网络之上。如果对信息安全不够重视，一旦商业机密被他人窃取，受到的经济损失将是无法估计的，有可能影响着企业的生死存亡。\n\n理论上来讲对于信息安全，无论企业规模大小，无论企业信息的重要程度如何，注重信息安全是非常有必要的。但部分企业无法承担网络安全所带来的花销以及人力成本问题，所以企业要衡量一下网络安全在公司所占有的资源以及地位是否能够承受。对于互联网企业、软件开发商以及注重商业机密或大量用户信息依赖在网络环境中的相关企业都应重视网络安全问题。\n\n对于拥有庞大的开发团队的企业，由于大量的开发人员以及产品的频繁迭代，推动SDL规范流程是目前最好的减少企业相关网络应用产品的安全问题。\n\n推动SDL需企业具备以下条件：\n\n1. 重视信息安全\n2. 拥有成熟的开发和管理团队\n3. 规范的产品研发和迭代流程\n"
  },
  {
    "path": "docs/1.SDL介绍/4-SDL所带来的优缺点.md",
    "content": "\n# 04.SDL所带来的优缺点\n\n作者：\n\n----\n\n未完成\n"
  },
  {
    "path": "docs/2.SDL规范文档/1-安全设计Checklist.md",
    "content": "\n# 01.安全设计Checklist\n\n作者：WeiHo@破晓团队（整理）\n\n协作：Lost Maniac、1024、pa55w0rd、doubiduo\n\n-------\n\n## 输入验证\n\n- 校验跨信任边界传递的不可信数据(策略检查数据合法性，含白名单机制等)格式化字符串时，依然要检验用户输入的合法性，避免可造成系统信息泄露或者拒绝服务\n\n- 禁止向Java Runtime.exec()方法传递不可信、未净化的数据(当参数中包含空格，双引号，以-或者/符号开头表示一个参数开关时，可能会导致参数注入漏洞)，建议如果可以禁止JVM执行外部命令，未知漏洞的危害性会大大降低，可以大大提高JVM的安全性。\n\n- 验证路径之前应该先将其标准化为实际路径（特殊的文件名，比如“..”，symbolic links、hard links、shortcuts）\n\n- 从ZipInputStream提取文件，如果不在程序预期计划的目录之内时，应拒绝将其提取出来，或者将其提取到一个安全的位置\n\n- 从ZipInputStream提取文件，若解压之后的文件大小超过一定的限制时，必须拒绝将其解压\n\n- 在处理以前，验证所有来自客户端的数据，包括：所有参数、URL、HTTP头信息（比如：cookie名字和数据值），确定包括了来自 JavaScript、Flash 或其他嵌入代码的post 返回信息\n\n- 如果任何潜在的危险字符必须被作为输入，请确保您执行了额外的安全控制，比如：输入转义、输出编码、特定的安全 API等。部分常见的危险字符，包含但不限于： < > \" ' % ( ) & + \\ \\' \\\"  \n\n- 如果您使用的标准验证规则无法验证下面的输入，那么它们需要被单独验证，比如验证空字节 (%00)； 验证换行符 (%0d, %0a, \\r, \\n)； 验证路径替代字符“点-点-斜杠”（../或 ..\\）；如果支持 UTF-8 扩展字符集编码，验证替代字符： %c0%ae%c0%ae/ (使用规范化验证双编码或其他类型的编码)\n\n- 严格验证来自重定向输入的数据（一个攻击者可能向重定向的目标直接提交恶意代码，从而避开应用程序逻辑以及在重定向前执行的任何验证）\n\n- 验证数据类型\n\n- 验证数据范围\n\n- 验证数据长度\n\n---\n\n## 输出编码\n- 为每一种输出编码方法采用一个标准的、已通过测试的规则\n\n- 通过语义输出编码方式，对所有从服务端返回到客户端的数据进行编码。比如HTML编码、URL编码等，编码形式需根据具体的应用场景选择 \n\n- 除非对目标编译器是安全的，否则请对所有字符进行编码 \n\n- 针对 SQL、XML 和 LDAP 查询，语义净化所有不可信数据的输出 \n\n- 对于操作系统命令，净化所有不可信数据输出\n\n---\n\n## 异常处理\n- 禁止在异常中泄露敏感信息（敏感数据的范围应该基于应用场景以及产品威胁分析的结果来确定。典型的敏感数据包括口令、银行账号、个人信息、通讯记录、密钥等）\n\n- 禁止在异常中泄露应用服务器的指纹信息（如版本，路径，架构）\n\n- 方法发生异常时要恢复到之前的对象状态（业务操作失败时，进行回滚业务；或者避免去修改对象状态，维持对象状态一致性）\n\n- I/O操作- 临时文件使用完毕应及时删除\n\n- 不要将Buffer对象封装的数据暴露给不可信代码\n\n- 在多用户系统中创建文件时指定合适的访问许可，以防止未授权的文件访问\n\n- 当一个外部进程通过其输出流对外输出信息或错误时，必须及时清空其输出流，以防止输出流中的缓冲区被耗尽而导致外部进程被阻塞。\n\n- 白名单控制共享目录操作文件权限，比如读/写/可执行权限\n\n\n---\n\n## 运行环境\n- 不要使用危险的许可与目标组合（比如不要将AllPermission许可赋予给不信任的代码，不要将ReflectPermission许可和suppressAccessChecks目标组合使用，不要将java.lang.RuntimePermission许可与createClassLoader目标组合）\n\n- 不要禁用JVM字节码验证，如果使用的字节码，如class文件被恶意篡改过，将会存在安全风险\n\n- 建议监控平台不要对互联网开放，仅限于内网环境访问；如果监控平台存在远程执行漏洞，将会给所监控的应用带来安全风险\n\n- 建议将所有安全敏感代码(例如进行权限控制或者用户名密码校验的代码)都放在一个jar包中\n\n- 生产代码不能包含任何调试代码或接口\n\n---\n\n## 身份验证\n\n- 除了那些特定设为“公开”的内容以外，对所有的网页和资源都要求进行身份验证，并正确设计身份验证功能\n\n- 所有的身份验证过程必须在服务器后端上执行  \n\n- 在任何可能的情况下，建立并使用标准的、已通过安全测试的身份验证服务(比如 C4A) \n\n- 所有的身份验证控制应当安全的处理未成功的身份验证，比如给出错误模糊提示，隐藏敏感信息\n\n- 登录入口应具有防止暴力猜解及撞库猜解（利用已泄漏的密码字典进行批量登录尝试）的措施，超过设定失败次数需要启用锁定或图片随机码进行访问限制\n\n- 采用https post请求方式传输身份验证的凭据信息\n\n- 身份验证的失败提示信息采用模糊处理，比如可以使用“用户名或密码错误”，而不要使用“用户名错误”或者“密码错误”明确提示。\n\n- 涉及敏感信息或功能的外部系统连接应配置身份验证功能，并进行有效身份验证控制\n\n- 在执行关键操作（如个人信息密码修改操作）时，应对用户身份进行再次验证\n\n- 为高度敏感或重要的交易账户使用多因子身份验证机制，如支付密码、短信验证码等\n\n---\n\n## 短信验证码\n- 一次一用\n\n- 发送频率控制（建议60s获取一次）\n\n- 验证码有效期（建议60s内有效，发短信时进行友好提示）\n\n- 复杂度（短信验证码建议6位数字）\n\n- 安全提示：是否是个人自己操作等风险提示信息\n\n- 在前端校验（客户端的校验只能作为辅助手段，很容易被绕过），必须使用服务端代码对输入数据进行最终校验\n\n- 短信验证码需要限制频率使用，例如：每天一个手机号码只允许发送5次，防止被黑客恶意消耗短信\n\n- 不同场景的短信验证码不可通用\n\n- 单个短信验证码限制有效验证次数\n\n- 验证码需要对应手机号不可通用\n\n- 限制对短信接口的调用（1.推荐添加验证码保证需要人类交互才可以发送短信2.根据自己的业务特点限制每个IP每天的最大发送量）\n\n---\n\n## 图形验证码\n- 一次一用\n\n- 验证码有效期(10分钟内有效，可根据场景兼容安全和体验灵活设置)\n\n- 复杂度（4位及以上数字、字母交替），根据需要也可采用当下流行的拖拽验证码或计算值的验证方式\n\n- 服务器端进行认证\n\n- 从用户体验和安全角度出发，可设计为当用户输3次错误密码后自动弹出验证码输入框进行验证操作\n\n---\n\n## 密码管理\n- 禁止使用私有或者弱加密算法（比如禁止使用DES，SHA1等，推荐使用AES: 128位，RSA: 2048位，DSA: 2048位） \n\n- 采用基于哈希算法和加入盐值（salt）方式安全存储口令信息\n\n- 数据库连接配置中的用户密码要以加密的形式存储（建议所有涉及密码存储的功能点进行加密存储）\n\n- 保证密码传输过程需要加密（建议使用https）\n\n- 密码输入框，可设计为显示密码和隐藏密码切换功能\n\n- 密码重设和更改操作，需要进行二次合法身份验证\n\n- 密码重设时，应对注册手机号和邮箱进行有效验证，链接只能发送到预先注册的邮件地址或预先绑定的手机号\n\n- 临时密码和链接应设计一个短暂的有效期（比如5分钟），防止暴力破解\n\n- 当密码重新设置时，应短信通知用户是否是本人在操作，告知安全风险\n\n- 密码复杂度设置：建议8个字符以上，包含字母、数字及特殊字符等\n\n- 密码设置场景中应具有密码复杂度检查功能（建议在后台验证密码复杂度）\n\n- 密码不能输出到日志和控制台\n\n- 建议设计密码定期修改提醒机制\n\n\n---\n\n## 会话安全\n- 用户登出后应立即清理会话及其相关登录信息 \n\n- 注销功能应当完全终止相关的会话或连接\n\n- 增加Cookie 安全性，添加“HttpOnly”和“secure”属性（当“secure”属性设置为true时表示创建的 Cookie 会被以安全的形式向服务器传输，也就是只能在HTTPS 连接中被浏览器传递到服务器端进行会话验证，在 HTTP 连接中不会传递该信息，也就不会存在Cookie被窃取的问题；设置了\"HttpOnly\"属性，通过程序(JS脚本、Applet等)将无法读取到Cookie信息，这样也能减少XSS跨站脚本攻击风险）\n\n- 会话cookie应设计有效期，超时后立即失效\n\n- 当设计允许用户在多渠道终端同时登录时，建议应进行常用设备登录限制\n\n- 为包含已验证的会话标识符的 cookie 设置域和路径，为站点设置一个恰当的限制值。默认cookie的域是当前域名，默认cookie的路径是当前页面的目录路径。如果想要跨域或者在其他的路径下访问cookie就必须要重新设置这两个属性，domain和path。\n\n- 注销功能应当可用于所有受身份验证保护的网页\n\n- 在平衡风险和业务功能需求的基础上，设置一个尽量短的会话超时时间。通常情况下，应当不超过几个小时。\n\n- 不要在URL、错误信息或日志中暴露会话标识符，会话标识符应当只出现在http头信息中，不要将会话标识符以 GET 参数进行传递\n\n- 定期生成一个新的会话标识符并周期性地使上一个会话标识符失效（这可以缓解那些原标识符被获得的特定会话劫持情况） \n\n- 在身份验证的时候，如果连接从 HTTP 变为 HTTPS，则会生成一个新的会话标识符。在应用程序中，推荐持续使用 HTTPS，不应在 HTTP 和 HTTPS 之间来回转换，有效避免切换过程会话被劫持篡改。\n\n- 为服务器端的操作执行标准的安全会话管理，为每个会话执行合法的身份验证和权限控制，防止存在CSRF跨站点请求伪造漏洞\n\n\n---\n\n## 访问控制\n- 将具有特权的逻辑从其他应用程序代码中隔离开\n\n- 限制只有授权的用户才能访问文件资源\n\n- 限制只有授权的用户才能访问受保护的URL\n\n- 限制只有授权的用户才能访问受保护的功能或服务\n\n- 建议只有授权的用户才能访问直接对象引用\n\n- 限制只有授权的用户才能访问受保护的应用程序数据\n\n- 限制只有授权的用户才能访问与安全相关的配置信息\n\n- 限制只有授权的外部应用程序或接口才能访问受保护的本地程序或资源\n\n- 服务器端执行的访问控制规则和前端实施的访问控制规则必须匹配\n\n- 服务器中创建文件时需指定合理的访问权限（读/写/可执行）\n\n- 当权限重新设置发生变更时，应记录好日志，并短信通知用户是否是本人在操作，告知可能存在的安全风险\n\n---\n\n## 日志规范\n\n- 不要在日志中保存敏感信息，包括系统指纹信息、会话标识符、账号密码、证件、ID等\n\n- 确保日志记录包含了重要的日志事件数据\n\n- 记录所有失败和成功的输入验证 \n\n- 记录所有失败和成功的身份验证记录\n\n- 记录所有失败和成功的访问和操作记录 \n\n- 记录明显的修改事件，包括对于状态数据的修改\n\n- 记录连接无效或者已过期的会话令牌尝试\n\n- 记录所有的管理功能操作行为，包含但不限于安全配置设置的变更\n\n- 记录所有失败和成功的后端连接\n\n- 记录加密模块的错误信息\n\n- 禁止将日志直接保存在可被浏览器访问到的WEB目录中\n\n\n---\n\n## 敏感信息\n\n- 临时产生的敏感数据（写入内存或文件），应具有及时清除和释放机制\n\n- 不要在 HTTP GET 请求参数中包含敏感信息，如用户名、密码、卡号、ID等\n\n- 禁止表单中的自动填充功能，因为表单中可能包含敏感信息，包括身份验证信息\n\n- 不要在客户端上以明文形式保存密码或其他敏感信息\n\n- 为所有敏感信息采用SSL加密传输\n\n- 禁止将敏感信息（包含加密秘钥等）硬编码在程序中\n\n- 禁止明文存储用户的密码、身份证号、银行卡号、持卡人姓名等敏感信息\n\n- 不要在日志中保存敏感信息，包含但不限于系统详细信息、会话标识符、密码等\n\n- 禁止在异常中泄露应用服务器的指纹信息，如版本，路径，组件版本等\n\n- 禁止将源码或sql上传到开源平台或社区，如github、开源中国等\n\n- 请求中含有敏感参数（如订单号、ID等），应进行混淆方式处理，防止产生参数遍历获取信息风险\n\n- 敏感信息需要展示在web页面上时，应在后台进行敏感字段脱敏处理\n\n- 请求返回数据不应包含请求之外的业务数据，特别是敏感信息数据\n\n---\n\n## 密码找回安全\n\n- 服务器端要做认证，避免绕过前端控制\n\n- 增加二次认证因子，如验证码\n\n- 涉及登录验证token之类的，不要直接将验证内容直接返回给用户\n\n- 认证凭证加密，推荐强算法（推荐使用AES: 128位，RSA: 2048位，DSA: 2048位）\n\n- 认证凭证中的参数应进行混淆处理\n\n- 在多个验证操作中，要对各验证机制进行排序，以防出现跳过前面验证机制直接到最后一步认证的安全风险\n\n- 手机短信码验证，需同时校验手机号和短信是否对应\n\n- 输入框中，应校验输入数据合法性，防止产生XSS跨站脚本攻击\n\n- 密码找回链接限制有效访问时间和复用次数（不可重复使用）\n\n---\n\n## SQL注入\n\n- 永远不要信任用户的输入，要对用户的所有输入进行校验，包含SQL语句的过滤和转义\n\n- 永远不要使用动态拼装SQL，可以使用参数化的SQL或者使用存储过程进行数据查询存取\n\n- 永远不要使用管理员权限进行数据库连接，为每个应用使用单独的非特权权限，且配置有限的数据库连接数\n\n- 不要把敏感信息明文存放，采用加密或者哈希、混淆等方式对敏感信息进行脱敏存储\n\n- 应用的异常信息应不带有敏感信息，给出尽可能少的提示；建议使用自定义的错误信息对原始错误信息进行包装，可把异常信息存放在独立的数据库表中\n\n- XML注入- 不要使用字符串/StringBuffer/StringBuilder/StringFormat组装XML\n\n- 建议对XML元素属性或者内容进行转义\n\n---\n\n## XSS跨站脚本攻击\n\n- 对输入的数据进行过滤和转义，包含但不限于< >\" ' % ( ) & + \\ \\' \\\"等危险特殊字符\n\n- 数据添加到html元素属性或者内容中时，对数据进行HTML转义\n\n- 数据添加到script脚本中时，对数据进行script转义\n\n- 数据添加到style中时，对数据进行css转义\n\n---\n\n## CSRF跨站请求伪造\n\n- 建议在每个关键表单中引入了CSRF Token验证(会话中生成的随机串，提交后校验)\n\n- 在关键表单提交时要求用户进行二次身份验证（录入密码、插KEY、输入图片验证码、短信验证码）\n\n- 对请求referer做验证（比如跨域、系统内部应用）\n\n---\n\n## 文件上传安全\n\n- 上传操作应设计身份验证机制，并进行合法身份校验\n\n- 只允许上传满足业务需要的相关文档类型\n\n- 通过检查文件头信息，比如JPEG (jpg)文件头信息（十六进制）：FFD8FF，验证上传文档是否是所期待的类型\n\n- 不要把文件保存在与应用程序相同的 Web 环境中，建议将文件保存在专用的文档服务器中，单独给文档服务器配置域名访问更好\n\n- 限制上传任意可能被 Web 服务器解析的文件 ，比如jsp、php等 \n\n- 上传文件以二进制形式下载，建议不提供直接访问（防止木马文件直接执行）\n\n- 禁止授予上传文件存储目录的可执行权限 \n\n- 禁止客户端自定义文件上传/下载路径（如：使用../../../../进行跳转）\n\n- 文件上传后重命名（需根据业务实际需求制定命名规则）\n\n\n---\n\n## 组件安全\n- 在使用随机数函数时，推荐使用强随机数函数（例如java.security.SecureRandom类）\n\n- 精简组件中不需要的功能、方法，以免带来未知的安全风险\n\n- 不可将系统内部使用的锁对象暴露给不可信代码\n\n- 建议使用SSL Socket代替Socket来进行安全数据交互\n\n- 封装本地方法调用（所有的本地方法都应该被定义为私有的，然后仅通过一个封装方法来调用）\n\n- 使用安全管理器（比如java.security或第三方安全组件）来保护敏感操作\n\n- 编写自定义类加载器必须覆盖getPermissions()函数时，在为代码源分配任意权限前，应调用超类super.getPermissions（）函数，实现除了自定义策略外，系统全局的默认安全策略也被应用。\n\n- 避免完全依赖URLClassLoader和java.util.jar提供的默认自动签名认证机制，应从加载类的代码源（Code-Source）中获取证书链，然后检查证书是否属于本地密钥库（KeyStore）中的受信任签名者\n\n---\n\n## 接口安全\n- 调用方来源IP控制，比如可通过防火墙、主机host deny、Nginx deny等技术措施进行实施\n\n- 调用方身份认证，比如key、secret、证书等技术措施进行实施\n\n- 调用参数认证，需设计参数容错机制，避免出现参数可遍历敏感数据安全问题\n\n- 采用数字签名保障接口身份来源可信，数据防篡改\n\n- 调用方权限控制设置\n\n- 调用频率、有效期进行控制\n\n- 调用行为实时检测，对异常阻拦\n\n- 幂等性校验，保持数据一致性\n\n- 采用应用接入安全网关，实现APPID/KEY身份认证，加密传输，摘要签名安全保障\n\n---\n\n## Dubbo调用安全\n- 采用token验证访问控制，防止消费者绕过注册中心访问提供者；在注册中心控制权限以决定要不要下发令牌给消费者\n\n- 采用filter IP白名单访问控制，同时也可预防生产系统和测试系统之间Dubbo混乱调用问题\n\n- 在必要情况下（如敏感信息操作），连接注册中心Dubbo时要进行用户名和密码校验\n\n---\n\n## Redis调用安全\n- 应启用客户端IP访问控制验证功能\n\n- 应启用客户端身份验证功能\n\n- 敏感信息不要明文存储于Redis"
  },
  {
    "path": "docs/2.SDL规范文档/10-SDL上线规定文档.md",
    "content": "\n# 11. SDL上线规定文档\n\n\n作者：Lost Maniac\n\n协作：\n\n---\n\n## 1. 概述\n### 1.1. 编制目的\n\n为了提升公司各业务线产品的安全质量，降低安全风险，进一步提升公司整体安全水平，结合公司现有产品设计、开发、测试及上线流程，特制定此《XX产品安全开发流程》。\n\n### 1.2. 适用范围\n此流程适用于 **XX** 所有业务线产品的安全设计、开发、测试及上线。\n\n## 2. 什么是安全开发流程（SDL）？\n\nSDL 的全称是 **Security Development Lifecycle**，即：安全开发生命周期。它是由微软最早提出的，是一种帮助解决软件安全问题的方法。SDL 中的方法，试图从安全漏洞产生的根源上解决问题。SDL 是一个安全保证的过程，通过对软件工程的控制，从而保证产品的安全性。它能够帮助企业以最小的成本提高产品的安全性，对企业安全的发展来说，可以起到事半功倍的效果。\n\n## 3. 实施 SDL 的目的\n实施 SDL 的核心目的只有一个，那就是通过在开发过程中加入安全控制的方法，提升各业务线项目、系统的安全性。避免因项目上线后存在安全漏洞被攻击者恶意利用而造成不必要的安全风险和损失。\n\n## 4. 实施 SDL 的好处\n\n* 提前主动发现安全漏洞，降低安全风险和漏洞修复成本\n* 在项目开发前期就引入安全控制的方法，构建标准化安全开发流程，从根源上减少安全漏洞和降低安全风险\n* 保证所有项目在上线前都通知到安全团队\n\n\n## 5. 如何实施安全开发流程\n\n### 5.1. XX SDL 整体流程\n\n\n![整体流程](/images/2018/10/01.jpeg)\n\n\n\n### 5.2. 项目立项\n    要求：需要保证所有项目在立项时都通知到安全团队。\n    通知方式：邮件+企业微信、立项会议\n\n### 5.3. 需求分析\n\n要求：所有需求必须通过安全评审，由安全团队来评估需求是否存在安全风险或是否需要设计安全功能；如果安全评审未通过，不允许进入下一步研发流程\n\n\n> 安全评审流程：\n\n\n![安全评审流程](/images/2018/10/02.jpeg)\n\n\n安全评审成果：安全评审报告\n安全评审沟通方式：邮件+企业微信、jira安全评审提交\n\n### 5.4. 设计\n\n在设计阶段，由产品和研发团队自查，确认是否有违反《XX开发安全红线准则》的行为。\n\n### 5.5. 编码实现\n在编码实现阶段，研发工程师应遵循 **《XX安全开发手册》**。\n\n### 5.6. 测试验证\n在开发工作完成后，应与功能测试同步进行安全测试，安全测试过程中发现的安全漏洞通过“jira XX安全团队漏洞提交”管理。\n\n安全测试需求提交方式：邮件+企业微信、项目安全提测系统\n\n### 5.7. 业务验收\n在业务验收时，应同步进行安全验收，完成后由安全团队发布《XX项目安全验收报告》，如\n果在安全验收过程中发现存在未修复的高危及严重级别安全漏洞，不允许进入上线发布环节。\n\n### 5.8. 上线与维护\n\n* 如果未收到“通过安全验收”的报告，不允许私自上线发布项目。\n* 在项目上线前，由安全团队添加相应必要的安全监控、定期漏洞扫描。"
  },
  {
    "path": "docs/2.SDL规范文档/11-web应用安全业务自查checklist.md",
    "content": "\n# 11. Web应用安全业务自查checklist\n\n\n作者：realjac\n\n协作：Melody\n\n---\n\n## 1. 概述\n### 1.1. 编制目的\n\n* 此checklist用于业务线测试或开发人员在上线前进行安全自查\n* 安全前置落地实施，是将安全需求嵌入开发流程的急先锋\n\n### 1.2. 编写原则\n- 便于业务理解常见安全风险\n- 方便业务检查项目中存在的最显而易见的风险点\n- 不求覆盖最全，保证能在业务落地使用\n- 基于公司常见场景出发的经验归纳\n\n## 2. checklist内容\n\n| 业务功能   | 自查安全项                                                                                     | 风险等级 | 满足/不满足/不适用 | 备注 |\n|:-------|:------------------------------------------------------------------------------------------|:-----|:-----------|:---|\n| 登录     | 1.系统应接入账号安全组统一登录平台                                                                        | 中    |            |    |\n|        | 2.自建登录功能应使用验证码等二次验证机制，且验证码应在每次登录成功或失败后失效刷新；                                               | 中    |            |    |\n|        | 3.如密码等敏感信息应加密传输；                                                                          | 中    |            |    |\n|        | 4.外网系统应使用https传输登录信息；                                                                     | 高    |            |    |\n|        | 5.用户登录失败的提示信息应为“用户名或密码错误”/“登录失败”等模糊提示；                                                    | 低    |            |    |\n| 注册     | 1.应有二次审核机制，如手机/邮箱等方式验证                                                                    | 高    |            |    |\n|        | 2.短信发送接口应限制针对同一手机号的请求频率；                                                                  | 低    |            |    |\n| 密码找回   | 1.应有二次审核机制，如手机/邮箱等方式验证，不可修改需要验证的手机号/邮箱等；                                                  | 高    |            |    |\n|        | 2.短信发送接口应限制针对同一手机号的请求频率；                                                                  | 低    |            |    |\n|        | 3.在每一步环节应判断上一步的合法性；                                                                       | 中    |            |    |\n| 退出登录   | 1.session认证会话应配置过期时间，一般建议60min；                                                           | 低    |            |    |\n|        | 2.点击退出后应销毁服务端认证session，使用户端cookie在退出登录后失效；                                                | 中    |            |    |\n| 上传     | 1.上传功能文件后缀应使用白名单限制为业务需要的文件类型；                                                             | 高    |            |    |\n|        | 2.应限制上传目录的权限，不允许赋予上传目录和上传的文件执行权限；                                                         | 中    |            |    |\n|        | 3.建议使用公司统一的文件存储系统，如…                                                                      | 中    |            |    |\n| 下载     | 1.下载目录应被限定在固定目录内，不允许被../../等路径操作跨目录访问其他文件；                                                | 高    |            |    |\n|        | 2.敏感资源应设置访问控制权限，只允许拥有授权的角色下载；                                                             | 高    |            |    |\n| 跨域需求接口 | 使用CORS跨域时，CORS安全配置：                                                                       |      |            |    |\n|        | 1.应设置Access-Control-Allow-Origin及Origin白名单域名为可信域（xx.test.com)；                              | 中    |            |    |\n|        | 2.只有需要携带Cookie时，才允许设置Access-Control-Allow-Credentials头，且Origin白名单必须精细化设置，不允许如*.test.com的配置。 | 高    |            |    |\n|        | JSONP接口：                                                                                  |      |            |    |\n|        | 1.必须使用白名单严格限制请求来源referer；                                                                 | 高    |            |    |\n| 网络资源调用 | 1.应使用白名单限定允许调用的URL，特别针对内网的请求应严格限定；                                                        | 高    |            |    |\n| 调用系统命令 | 1.应使用白名单限定允许调用的系统命令；                                                                      | 高    |            |    |\n| 敏感操作接口 | 1.应使用白名单限制请求来源referer或增加token等机制验证请求发起者身份；                                                | 高    |            |    |\n|        | 2.应记录应用操作日志；                                                                              | 中    |            |    |\n|        | 3.敏感操作接口如订单支付等，应使用悲观锁或乐观锁保证事务的ACID特性，解决并发竞争问题；                                            | 高    |            |    |\n|        | 4.对敏感资源进行操作时，应在服务端校验资源标识归属人是否与当前登录人一致；                                                    | 高    |            |    |\n|        |                                                                                           |      |            |    |\n| 漏洞扫描   | 1.上线前应使用自动化漏洞扫描工具扫描测试，确定无漏洞和安全风险；                                                         | 必须   |            |    |\n| 源代码审计  | 1.上线前应使用代码扫描工具进行扫描，确定无漏洞和安全风险；                                                            | 必须   |            |    |\n| 数据安全   | 数据处理：（参考公司数据分级标准）                                                                         |      |            |    |\n|        | 1.对用户可控输入且最终会回显输出到页面的数据，应使用公司安全防护组件进行转义安全编码后再输出；                                          | 中    |            |    |\n|        | 2.应将SQL语句预编译处理，未能预编译处理的语句如order by子句应使用白名单控制用户允许的输入；                                      | 高    |            |    |\n|        | 3.应在前端对敏感字段（如手机号、身份证、银行卡号）脱敏展示；                                                           | 中    |            |    |\n|        | 数据传输：                                                                                     |      |            |    |\n|        | 1.外网系统应使用https传输数据；                                                                       | 中    |            |    |\n|        | 2.敏感字段应脱敏/加密处理；                                                                           | 中    |            |    |\n|        | 数据存储：                                                                                     |      |            |    |\n|        | 1.日志中不应包含明文或未脱敏敏感数据；                                                                      | 低    |            |    |\n|        | 2.敏感数据应加密存储；                                                                              | 中    |            |    |\n\n"
  },
  {
    "path": "docs/2.SDL规范文档/2-php安全编码规范.md",
    "content": "\n# 02.php安全编码规范\n\n作者：tinker\n\n协作：\n\n注解：请根据业务安全等级需要自行协调以下建议。\n\n---\n\n## 1.配置\nphp.ini基本安全配置\n\n---\n\n### 1.1应启用“cgi.force_redirect”\ncgi.force_redirect在php.ini中修改，默认是开启的，它可以防止当PHP运行的CGI脚本未经验证的访问。在IIS，OmniHTTPD和Xitami上是禁用的，但在所有其他情况下它应该打开。\n```php\n; php.ini\ncgi.force_redirect=1 ; \n```\n\n---\n\n### 1.2应禁用“enable_dl”\n该指令仅对Apache模块版本的PHP有效。你可以针对每个虚拟机或每个目录开启或关闭dl()动态加载PHP模块。关闭动态加载的主要原因是为了安全。通过动态加载，有可能忽略所有open_basedir限制。默认允许动态加载，除了使用安全模式。在安全模式，总是无法使用dl()。\n```php\n; php.ini\nenable_dl=0 ; \n```\n\n---\n\n### 1.3应禁用“file_uploads”\nfile_uploads默认是开启的，允许将文件上传到您的站点。因为来自陌生人的文件本质上是不可信甚至危险的，除非您的网站绝对需要，否则应禁用此功能。如果开启请进行相应的限制，参考upload_max_filesize, upload_tmp_dir,和post_max_size。 \n```php\n; php.ini\nfile_uploads = 0 ; \n```\n\n---\n\n### 1.4通过“open_basedir”限制文件访问权限\nopen_basedir默认是打开所有文件，它将 PHP 所能打开的文件限制在指定的目录树，包括文件本身。本指令不受安全模式打开或者关闭的影响。当一个脚本试图用例如 fopen() ,include或者 gzopen() 打开一个文件时，该文件的位置将被检查。当文件在指定的目录树之外时 PHP 将拒绝打开它。所有的符号连接都会被解析，所以不可能通过符号连接来避开此限制。\n\nopen_basedir应该配置一个目录，然后可以递归访问。但是，应该避免使用. （当前目录）作为open_basedir值，因为它在脚本执行期间动态解析特殊值 . 指明脚本的工作目录将被作为基准目录，但这有些危险，因为脚本的工作目录可以轻易被 chdir() 而改变。\n\n在 httpd.conf 文件中，open_basedir 可以像其它任何配置选项一样用“php_admin_value open_basedir none”的方法关闭（例如某些虚拟主机中）。在 Windows 中，用分号分隔目录。在任何其它系统中用冒号分隔目录。作为 Apache 模块时，父目录中的 open_basedir 路径自动被继承。\n\n用 open_basedir 指定的限制实际上是前缀，不是目录名。也就是说“open_basedir = /dir/incl”也会允许访问“/dir/include”和“/dir/incls”，如果它们存在的话。如果要将访问限制在仅为指定的目录，用斜线结束路径名。例如：“open_basedir = /dir/incl/”。 \n```php\n; php.ini\nopen_basedir=\"${USER}/scripts/data\" ; \n```\n\n---\n\n### 1.5应禁用“session.use_trans_sid”\n默认为 0（禁用）。当禁用cookie时，如果它开启，PHP会自动将用户的会话ID附加到URL。基于 URL 的会话管理比基于 cookie 的会话管理有更多安全风险，从表面上看，这似乎是让那些禁用cookie的用户正常使用您的网站的好方法。实际上，它使那些用户容易被任何人劫持他们的会话。例如用户有可能通过 email 将一个包含有效的会话 ID 的 URL 发给他的朋友，或者用户总是有可能在收藏夹中存有一个包含会话 ID 的 URL 来以同样的会话 ID 去访问站点。也可以从浏览器历史记录和服务器日志中检索URL获取会话ID。\n```php\n; php.ini\nsession.use_trans_sid = 0 ; \n```\n\n---\n\n### 1.6会话管理cookie不能是持久的\n没有固定生命周期或到期日期的Cookie被称为非持久性或“会话”cookie，这意味着它们只会持续与浏览器会话一样长，并且在浏览器关闭时会消失。具有到期日期的Cookie叫做“持久性”Cookie，他们将被存储/保留到这些生存日期。\n\n管理网站上的登录会话应用非持久性cookie。要使cookie非持久化，只需省略该 expires属性即可。也可以使用session.cookie_lifetime实现。\n\n---\n\n### 1.7应禁用\"allow_url_fopen\"和\"allow_url_include\"\nallow_url_fopen和allow_url_include默认是开启的，他们允许代码从URL中读入脚本。从站点外部吸入可执行代码的能力，加上不完美的输入清理可能会使站点裸露给攻击者。即使该站点的输入过滤在今天是完美的，但不能保证以后也是。\n```php\n; php.ini\nallow_url_fopen = 0\nallow_url_include = 0\n```\n\n## 2.编码\nphp安全编码建议\n\n---\n\n### 2.1慎用sleep()函数\nsleep()有时用于通过限制响应率来防止拒绝服务（DoS）攻击。但是因为它占用了一个线程，每个请求需要更长的时间来服务，这会使应用程序更容易受到DoS攻击，而不是减少风险。\n```php\nif (is_bad_ip($requester)) {\n  sleep(5);  // 不合规的用法\n}\n```\n\n---\n\n### 2.2禁止代码动态注入和执行\neval()函数是一种在运行时运行任意代码的方法。\n函数eval()语言结构是非常危险的，因为它允许执行任意 PHP 代码。因此不鼓励使用它。如果您仔细的确认过，除了使用此结构以外别无方法,请多加注意，不要允许传入任何由用户提供的、未经完整验证过的数据。 \n```php\neval($code_to_be_dynamically_executed)  // 不合规的用法\n```\n\n---\n\n### 2.3禁止凭据硬编码\n因为从编译的应用程序中提取字符串很容易，所以永远不应对凭证进行硬编码。对于分发的应用程序尤其如此。\n凭据应存储在受强保护的加密配置文件或数据库中的代码之外。\n```php\n// 合规的用法\n$uname = getEncryptedUser();\n$password = getEncryptedPass();\nconnect($uname, $password); \n```\n```php\n// 不合规的用法\n$uname = \"steve\";\n$password = \"blue\";\nconnect($uname, $password);\n```\n  \n### 2.4禁止危险函数\n\n   有时候，我们不希望执行包括system()等在那的能够执行命令的php函数，或者能够查看phpinfo信息的\n   \n　　phpinfo()等函数，那么我们就可以禁止它们：\n  \n　　disable_functions = system,passthru,exec,shell_exec,popen,phpinfo\n  \n　　如果你要禁止任何文件和目录的操作，那么可以关闭很多文件操作\n  \n　　disable_functions = chdir,chroot,dir,getcwd,opendir,readdir,scandir,fopen,unlink,delete,copy,mkdir, 　　rmdir,rename,file,file_get_contents,fputs,fwrite,chgrp,chmod,chown\n  \n　　以上只是部分常用的文件处理函数，你也可以把上面执行命令函数和这个函数结合，应该就能够抵制大部分的phpshell了。\n\n"
  },
  {
    "path": "docs/2.SDL规范文档/3-java安全编码规范.md",
    "content": "\n# 03.java安全编码规范\n\n\n作者：108haili\n\n协作：Lost Maniac\n\n-------\n\n## 1输入验证和数据合法性校验\n程序接受数据可能来源于未经验证的用户，网络连接和其他不受信任的来源，如果未对程序接受数据进行校验，则可能会引发安全问题。\n\n### 1.1避免SQL注入\n使用PreparedStatement预编译SQL,解决SQL注入问题，传递给PreparedStatement对象的参数可以被强制进行类型转换，确保在插入或查询数据时与底层的数据库格式匹配。 \n\n```java\nString sqlString = \"select * from db_user where username=? and password=?\";\nPreparedStatement stmt = connection.prepareStatement(sqlString);\nstmt.setString(1, username);\nstmt.setString(2, pwd);\nResultSet rs = stmt.executeQuery();\n```\n\n---\n\n### 1.2避免XML注入\n\n通过StringBulider 或 StringBuffer 拼接XML文件时，需对输入数据进行合法性校验。\n对数量quantity 进行合法性校验，控制只能传入0-9的数字：\n\n```java\nif (!Pattern.matches(\"[0-9]+\", quantity)) {\n    // Format violation\n  }\n  String xmlString = \"<item>\\n<description>Widget</description>\\n\" +\n                     \"<price>500</price>\\n\" +\n                     \"<quantity>\" + quantity + \"</quantity></item>\";\n  outStream.write(xmlString.getBytes());\n  outStream.flush();\n```\n\n---\n\n### 1.3避免跨站点脚本（XSS）\n\n对产生跨站的参数进行严格过滤，禁止传入`<SCRIPT>`标签\n\n//定义需过滤的字段串`<script>`\n\n`String s = \"\\uFE64\" + \"script\" + \"\\uFE65\";`\n\n// 过滤字符串标准化\n\n`s = Normalizer.normalize(s, Form.NFKC);`\n\n// 使用正则表达式匹配inputStr是否存在`<script>`\n\n```java\nPattern pattern = Pattern.compile(inputStr);\nMatcher matcher = pattern.matcher(s);\nif (matcher.find()) {\n  // Found black listed tag\n  throw new IllegalStateException();\n} else {\n  // ...\n}\n```\n\n---\n\n## 2声明和初始化\n\n### 2.1避免类初始化的相互依赖\n\n例：\n\n错误的写法：\n\n```java\npublic class Cycle {\n  private final int balance;\n  private static final Cycle c = new Cycle();\n  private static final int deposit = (int) (Math.random() * 100); // Random deposit\n  public Cycle() {\n    balance = deposit - 10; // Subtract processing fee\n  }\n  public static void main(String[] args) {\n    System.out.println(\"The account balance is: \" + c.balance);\n  }\n}\n```\n\n类加载时初始化指向Cycle类的静态变量c，而类Cycle的无参构造方法又依赖静态变量deposit，导致无法预期的结果。\n正确的写法：\n\n```java\npublic class Cycle {\n  private final int balance;\n  private static final int deposit = (int) (Math.random() * 100); // Random deposit\n  private static final Cycle c = new Cycle();  // Inserted after initialization of required fields\n  public Cycle() {\n    balance = deposit - 10; // Subtract processing fee\n  }\n \n  public static void main(String[] args) {\n    System.out.println(\"The account balance is: \" + c.balance);\n  }\n}\n```\n\n---\n\n## 3表达式\n\n### 3.1不可忽略方法的返回值\n\n忽略方法的放回值可能会导致无法预料的结果。\n\n错误的写法：\n\n```java\npublic void deleteFile(){\n  File someFile = new File(\"someFileName.txt\");\n   someFile.delete();\n}\n```\n\n正确的写法：\n\n```java\npublic void deleteFile(){\n  File someFile = new File(\"someFileName.txt\");\n   if (!someFile.delete()) {\n    // handle failure to delete the file\n  }\n}\n```\n\n### 3.2不要引用空指针\n\n当一个变量指向一个NULL值，使用这个变量的时候又没有检查，这时会导致。NullPointerException。\n\n在使用变量前一定要做是否为NULL值的校验。\n\n### 3.3使用Arrays.equals()来比较数组的内容\n\n数组没有覆盖的`Object. equals()`方法，调用`Object. equals()`方法实际上是比较数组的引用，而不是他们的内容。程序必须使用两个参数`Arrays.equals()`方法来比较两个数组的内容\n\n```java\npublic void arrayEqualsExample() {\n  int[] arr1 = new int[20]; // initialized to 0\n  int[] arr2 = new int[20]; // initialized to 0\n  Arrays.equals(arr1, arr2); // true\n}\n```\n\n---\n\n## 4数字类型和操作\n\n### 4.1防止整数溢出\n\n使用java.lang.Number. BigInteger类进行整数运算，防止整数溢出。\n\n```java\npublic class BigIntegerUtil {\n\n    private static final BigInteger bigMaxInt = BigInteger.valueOf(Integer.MAX_VALUE);\n    private static final BigInteger bigMinInt = BigInteger.valueOf(Integer.MIN_VALUE);\n\n    public static BigInteger intRangeCheck(BigInteger val) throws ArithmeticException {\n        if (val.compareTo(bigMaxInt) == 1 || val.compareTo(bigMinInt) == -1) {\n            throw new ArithmeticException(\"Integer overflow\");\n        }\n        return val;\n    }\n\n    public static int addInt(int v1, int v2) throws ArithmeticException {\n        BigInteger b1 = BigInteger.valueOf(v1);\n        BigInteger b2 = BigInteger.valueOf(v2);\n        BigInteger res = intRangeCheck(b1.add(b2));\n        return res.intValue(); \n    }\n    \n    public static int subInt(int v1, int v2) throws ArithmeticException {\n        BigInteger b1 = BigInteger.valueOf(v1);\n        BigInteger b2 = BigInteger.valueOf(v2);\n        BigInteger res = intRangeCheck(b1.subtract(b2));\n        return res.intValue(); \n    }\n    \n    public static int multiplyInt(int v1, int v2) throws ArithmeticException {\n        BigInteger b1 = BigInteger.valueOf(v1);\n        BigInteger b2 = BigInteger.valueOf(v2);\n        BigInteger res = intRangeCheck(b1.multiply(b2));\n        return res.intValue(); \n    }\n    \n    public static int divideInt(int v1, int v2) throws ArithmeticException {\n        BigInteger b1 = BigInteger.valueOf(v1);\n        BigInteger b2 = BigInteger.valueOf(v2);\n        BigInteger res = intRangeCheck(b1.divide(b2));\n        return res.intValue(); \n    }\n}\n```\n\n### 4.2避免除法和取模运算分母为零\n\n要避免因为分母为零而导致除法和取模运算出现异常。\n\n```java\nif (num2 == 0) {\n  // handle error\n} else {\n result1= num1 /num2;\n  result2= num1 % num2;\n}\n```\n\n## 5类和方法操作\n\n### 5.1数据成员声明为私有，提供可访问的包装方法\n\n攻击者可以用意想不到的方式操纵public或protected的数据成员，所以需要将数据成员为private，对外提供可控的包装方法访问数据成员。\n\n### 5.2敏感类不允许复制\n\n包含私人的，机密或其他敏感数据的类是不允许被复制的，解决的方法有两种：\n\n1、类声明为final\n\n```java\nfinal class SensitiveClass {\n  // ...\n}\n```\n\n2、Clone 方法抛出CloneNotSupportedException异常\n\n```java\nclass SensitiveClass {\n  // ...\n  public final SensitiveClass clone() throws CloneNotSupportedException {\n    throw new CloneNotSupportedException();\n  }\n}\n```\n\n### 5.3比较类的正确做法\n\n如果由同一个类装载器装载，它们具有相同的完全限定名称，则它们是两个相同的类。\n不正确写法：\n\n```java\n// Determine whether object auth has required/expected class object\n if (auth.getClass().getName().equals(\n      \"com.application.auth.DefaultAuthenticationHandler\")) {\n   // ...\n}\n正确写法：\n// Determine whether object auth has required/expected class name\n if (auth.getClass() == com.application.auth.DefaultAuthenticationHandler.class) {\n   // ...\n}\n```\n\n### 5.4不要硬编码敏感信息\n\n硬编码的敏感信息，如密码，服务器IP地址和加密密钥，可能会泄露给攻击者。\n\n敏感信息均必须存在在配置文件或数据库中。\n\n### 5.5验证方法参数\n\n验证方法的参数，可确保操作方法的参数产生有效的结果。不验证方法的参数可能会导致不正确的计算，运行时异常，违反类的不变量，对象的状态不一致。\n对于跨信任边界接收参数的方法，必须进行参数合法性校验\n\n```java\nprivate Object myState = null;\n//对于修改myState 方法的入参，进行非空和合法性校验\nvoid setState(Object state) {\n  if (state == null) {\n    // Handle null state\n  }\n  if (isInvalidState(state)) {\n    // Handle invalid state\n  }\n  myState = state;\n}\n```\n\n### 5.6不要使用过时、陈旧或低效的方法\n\n在程序代码中使用过时的、陈旧的或低效的类或方法可能会导致错误的行为。\n\n### 5.7数组引用问题\n\n某个方法返回一个对敏感对象的内部数组的引用，假定该方法的调用程序不改变这些对象。即使数组对象本身是不可改变的，也可以在数组对象以外操作数组的内容，这种操作将反映在返回该数组的对象中。如果该方法返回可改变的对象，外部实体可以改变在那个类中声明的 public 变量，这种改变将反映在实际对象中。\n\n不正确的写法：\n\n```java\npublic class XXX {\n\tprivate String[] xxxx;\n\tpublic String[] getXXX() {\n\t\t\treturn xxxx;\n\t}\n}\n```\n\n正确的写法：\n\n```java\npublic class XXX {\n\tprivate String[] xxxx;\n\tpublic String[] getXXX() {\n\t\t\tString temp[] = Arrays.copyof(…);  // 或其他数组复制方法\n\t\t\treturn temp;\n\t}\n}\n```\n\n### 5.8不要产生内存泄露\n\n垃圾收集器只收集不可达的对象，因此，存在未使用的可到达的对象，仍然表示内存管理不善。过度的内存泄漏可能会导致内存耗尽，拒绝服务（DoS）。\n\n---\n\n## 6异常处理\n\n### 6.1不要忽略捕获的异常\n\n对于捕获的异常要进行相应的处理，不能忽略已捕获的异常\n\n不正确写法：\n\n```java\nclass Foo implements Runnable {\n  public void run() {\n    try {\n      Thread.sleep(1000);\n    } catch (InterruptedException e) {\n      // 此处InterruptedException被忽略\n    }\n  }\n}\n```\n\n正确写法：\n\n```java\nclass Foo implements Runnable {\n  public void run() {\n    try {\n      Thread.sleep(1000);\n    } catch (InterruptedException e) {\n      Thread.currentThread().interrupt(); // Reset interrupted status\n    }\n  }\n}\n```\n\n### 6.2不允许暴露异常的敏感信息\n\n没有过滤敏感信息的异常堆栈往往会导致信息泄漏，\n\n不正确的写法：\n\n```java\ntry {\n  FileInputStream fis =\n      new FileInputStream(System.getenv(\"APPDATA\") + args[0]);\n} catch (FileNotFoundException e) {\n  // Log the exception\n  throw new IOException(\"Unable to retrieve file\", e);\n}\n```\n\n正确的写法：\n\n```java\nclass ExceptionExample {\n  public static void main(String[] args) {\n    File file = null;\n    try {\n      file = new File(System.getenv(\"APPDATA\") +\n             args[0]).getCanonicalFile();\n      if (!file.getPath().startsWith(\"c:\\\\homepath\")) {\n        log.error(\"Invalid file\");\n        return;\n      }\n    } catch (IOException x) {\n     log.error(\"Invalid file\");\n      return;\n    }\n    try {\n      FileInputStream fis = new FileInputStream(file);\n    } catch (FileNotFoundException x) {\n      log.error(\"Invalid file\");\n      return;\n    }\n  }\n}\n```\n\n### 6.3不允许抛出RuntimeException, Exception,Throwable\n\n不正确的写法：\n\n```java\nboolean isCapitalized(String s) {\n  if (s == null) {\n    throw new RuntimeException(\"Null String\");\n  }\n}\n\nprivate void doSomething() throws Exception {\n  //...\n}\n```\n\n正确写法：\n\n```java\nboolean isCapitalized(String s) {\n  if (s == null) {\n    throw new NullPointerException();\n  }\n}\n\nprivate void doSomething() throws IOException {\n  //...\n}\n```\n\n### 6.4不要捕获NullPointerException或其他父类异常\n\n不正确的写法：\n\n```java\nboolean isName(String s) {\n  try {\n    String names[] = s.split(\" \");\n    if (names.length != 2) {\n      return false;\n    }\n    return (isCapitalized(names[0]) && isCapitalized(names[1]));\n  } catch (NullPointerException e) {\n    return false;\n  }\n}\n```\n\n正确的写法：\n\n```java\nboolean isName(String s) /* throws NullPointerException */ {\n  String names[] = s.split(\" \");\n  if (names.length != 2) {\n    return false;\n  }\n  return (isCapitalized(names[0]) && isCapitalized(names[1]));\n}\n```\n\n## 7多线程编程\n\n### 7.1确保共享变量的可见性\n\n对于共享变量，要确保一个线程对它的改动对其他线程是可见的。\n线程可能会看到一个陈旧的共享变量的值。为了共享变量是最新的，可以将变量声明为`volatile`或同步读取和写入操作。\n将共享变量声明为`volatile`：\n\n```java\nfinal class ControlledStop implements Runnable {\n  private volatile boolean done = false;\n  @Override public void run() {\n    while (!done) {\n      try {\n        // ...\n        Thread.currentThread().sleep(1000); // Do something\n      } catch(InterruptedException ie) { \n        Thread.currentThread().interrupt(); // Reset interrupted status\n      } \n    }    \n  }\n  public void shutdown() {\n    done = true;\n  }\n}\n```\n\n同步读取和写入操作：\n\n```java\nfinal class ControlledStop implements Runnable {\n  private boolean done = false;\n  @Override public void run() {\n    while (!isDone()) {\n      try {\n        // ...\n        Thread.currentThread().sleep(1000); // Do something\n      } catch(InterruptedException ie) { \n        Thread.currentThread().interrupt(); // Reset interrupted status\n      } \n    }    \n  }\n  public synchronized boolean isDone() {\n    return done;\n  }\n  public synchronized void shutdown() {\n    done = true;\n  }\n}\n```\n\n### 7.2确保共享变量的操作是原子的\n\n除了要确保共享变量的更新对其他线程可见的，还需要确保对共享变量的操作是原子的，这时将共享变量声明为volatile往往是不够的。需要使用同步机制或Lock\n同步读取和写入操作：\n\n```java\nfinal class Flag {\n  private volatile boolean flag = true;\n  public synchronized void toggle() {\n    flag ^= true; // Same as flag = !flag;\n  }\n  public boolean getFlag() {\n    return flag;\n  }\n}\n```\n\n//使用读取锁确保读取和写入操作的原子性\n\n```java\nfinal class Flag {\n  private boolean flag = true;\n  private final ReadWriteLock lock = new ReentrantReadWriteLock();\n  private final Lock readLock = lock.readLock();\n  private final Lock writeLock = lock.writeLock();\n  public void toggle() {\n    writeLock.lock();\n    try {\n      flag ^= true; // Same as flag = !flag;\n    } finally {\n      writeLock.unlock();\n    }\n  }\n  public boolean getFlag() {\n    readLock.lock();\n    try {\n      return flag;\n    } finally {\n      readLock.unlock();\n    }\n  }\n}\n```\n\n### 7.3不要调用Thread.run()，不要使用Thread.stop()以终止线程\n\n### 7.4确保执行阻塞操作的线程可以终止\n\n```java\n  public final class SocketReader implements Runnable {\n  private final SocketChannel sc;\n  private final Object lock = new Object();\n  public SocketReader(String host, int port) throws IOException {\n    sc = SocketChannel.open(new InetSocketAddress(host, port));\n  }\n  @Override public void run() {\n    ByteBuffer buf = ByteBuffer.allocate(1024);\n    try {\n      synchronized (lock) {\n        while (!Thread.interrupted()) {\n          sc.read(buf);\n          // ...\n        }\n      }\n    } catch (IOException ie) {\n      // Forward to handler\n    }\n  }\n  public static void main(String[] args) \n                          throws IOException, InterruptedException {\n    SocketReader reader = new SocketReader(\"somehost\", 25);\n    Thread thread = new Thread(reader);\n    thread.start();\n    Thread.sleep(1000);\n    thread.interrupt();\n  }\n}\n```\n\n### 7.5相互依存的任务不要在一个有限的线程池执行\n\n有限线程池指定可以同时执行在线程池中的线程数量的上限。程序不得使用有限线程池线程执行相互依赖的任务。可能会导致线程饥饿死锁，所有的线程池执行的任务正在等待一个可用的线程中执行一个内部队列阻塞\n\n---\n\n## 8输入输出\n\n### 8.1程序终止前删除临时文件\n\n### 8.2检测和处理文件相关的错误\n\nJava的文件操作方法往往有一个返回值，而不是抛出一个异常，表示失败。因此，忽略返回值文件操作的程序，往往无法检测到这些操作是否失败。Java程序必须检查执行文件I / O方法的返回值。\n\n不正确的写法：\n\n```java\nFile file = new File(args[0]);\nfile.delete();\n正确的写法：\nFile file = new File(\"file\");\nif (!file.delete()) {\n  log.error(\"Deletion failed\");\n}\n```\n\n### 8.3及时释放资源\n\n垃圾收集器无法释放非内存资源，如打开的文件描述符与数据库的连接。因此，不释放资源，可能导致资源耗尽攻击。\n\n```java\ntry {\n  final FileInputStream stream = new FileInputStream(fileName);\n  try {\n    final BufferedReader bufRead =\n        new BufferedReader(new InputStreamReader(stream));\n \n    String line;\n    while ((line = bufRead.readLine()) != null) {\n      sendLine(line);\n    }\n  } finally {\n    if (stream != null) {\n      try {\n        stream.close();\n      } catch (IOException e) {\n        // forward to handler\n      }\n    }\n  }\n} catch (IOException e) {\n  // forward to handler\n}\n```\n\n## 9序列化\n\n### 9.1不要序列化未加密的敏感数据\n\n序列化允许一个对象的状态被保存为一个字节序列，然后重新在稍后的时间恢复，它没有提供任何机制来保护序列化的数据。敏感的数据不应该被序列化的例子包括加密密钥，数字证书。 \n解决方法：\n\n1. 对于数据成员可以使用transient ，声明该数据成员是瞬态的。\n2. 重写序列化相关方法writeObject、readObject、readObjectNoData，防止被子类恶意重写\n\n```java\nclass SensitiveClass extends Number {\n  // ...\n  protected final Object writeObject(java.io.ObjectOutputStream out) throws NotSerializableException {\n    throw new NotSerializableException();\n  }\n  protected final Object readObject(java.io.ObjectInputStream in) throws NotSerializableException {\n    throw new NotSerializableException();\n  }\n  protected final Object readObjectNoData(java.io.ObjectInputStream in) throws NotSerializableException {\n    throw new NotSerializableException();\n  }\n}\n```\n\n### 9.2在序列化过程中避免内存和资源泄漏\n\n不正确的写法：\n\n```java\nclass SensorData implements Serializable {\n  // 1 MB of data per instance!\n   public static SensorData readSensorData() {...}\n  public static boolean isAvailable() {...}\n}\nclass SerializeSensorData {\n  public static void main(String[] args) throws IOException {\n    ObjectOutputStream out = null;\n    try {\n      out = new ObjectOutputStream(\n          new BufferedOutputStream(new FileOutputStream(\"ser.dat\")));\n      while (SensorData.isAvailable()) {\n        // note that each SensorData object is 1 MB in size\n        SensorData sd = SensorData.readSensorData();\n        out.writeObject(sd);\n      }\n    } finally {\n      if (out != null) {\n        out.close();\n      }\n    }\n  }\n}\n```\n\n正确写法：\n\n```java\nclass SerializeSensorData {\n  public static void main(String[] args) throws IOException {\n    ObjectOutputStream out = null;\n    try {\n      out = new ObjectOutputStream(\n          new BufferedOutputStream(new FileOutputStream(\"ser.dat\")));\n      while (SensorData.isAvailable()) {\n        // note that each SensorData object is 1 MB in size\n        SensorData sd = SensorData.readSensorData();\n        out.writeObject(sd);\n        out.reset(); // reset the stream\n      }\n    } finally {\n      if (out != null) {\n        out.close();\n      }\n    }\n  }\n}\n```\n\n### 9.3反序列化要在程序最小权限的安全环境中\n\n\n(完成)"
  },
  {
    "path": "docs/2.SDL规范文档/4-python安全编码规范.md",
    "content": "\n# 04.python安全编码规范\n\n\n作者：I\n\n协作：\n\n-------\n\n## python语言安全\n\n本身要注意的有，一些危险函数,危险模块的调用，主要是系统调用。这个如果调用一定要对输入输出做好过滤，以下是代码中各种导致进行系统调用的方式。尽量避免。\n\n- 避免各种情况导致系统调用\n  \n- 谨慎使用Eval\n  \n- 数据序列化\n\n## Web编程\n\n对应Web编程中安全概念在python web框架中的实现。url跳转，目录遍历，任意文件读取也需要考虑在内。针对不同的框架也需要。\n\n### Flask 安全\n\n- 使用Flask-Security\n- 直接生成 HTML 而不通过使用Jinja2\n- 不要在用户提交的数据上调用Markup\n- 使用 Content-Disposition: attachment 标头去避免上传html文件\n- 防止CSRF，flask本身没有实现该功能\n\n### Django 安全\n\n可参考[phithon](https://www.leavesongs.com)的博客，有较多相关资料。\n\n- 关闭DEBUG模式\n- 关闭swagger调试\n- 妥善保存SECRET_KEY\n- 使用SecurityMiddleware\n- 设置SECURE_HSTS_SECONDS开启HSTS头，强制HTTPS访问\n- 设置SECURE_CONTENT_TYPE_NOSNIFF输出nosniff头，防止类型混淆类漏洞\n- 设置SECURE_BROWSER_XSS_FILTER输出x-xss-protection头，让浏览器强制开启XSS过滤\n- 设置SECURE_SSL_REDIRECT让HTTP的请求强制跳转到HTTPS\n- 设置SESSION_COOKIE_SECURE使Cookie为Secure，不允许在HTTP中传输\n- 设置CSRF_COOKIE_SECURE使CSRF Token Cookie设置为Secure，不允许在HTTP中传输\n- 设置CSRF_COOKIE_HTTPONLY为HTTP ONLY\n- 设置X_FRAME_OPTIONS返回X-FRAME-OPTIONS: DENY头，以防止被其他页面作为框架加载导致ClickJacking\n- 部署前运行安全性检测 django-admin.py checksecure --settings=production_settings\n\n## 审计工具\n安装使用方式较为简单，所以不做介绍。\n- [AST-based static Analyzer: Bandit](https://github.com/openstack/bandit)\n- [Static Analyzer: PYT](https://github.com/python-security/pyt)\n\n## 引用\n\n* [从Pwnhub诞生聊Django安全编码](https://www.leavesongs.com/PYTHON/django-coding-experience-from-pwnhub.html)\n* [Python安全编码与代码审计](http://xxlegend.com/2015/07/30/Python%E5%AE%89%E5%85%A8%E7%BC%96%E7%A0%81%E5%92%8C%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1/)\n* [Django Secure](https://django-secure.readthedocs.io/en/latest/settings.html)\n* [Flask安全注意事项](http://docs.jinkan.org/docs/flask/security.html)\n* [Python安全和代码审计相关资料](https://github.com/bit4woo/python_sec)\n* [Flask debu pin 安全问题](https://xz.aliyun.com/t/2553)\n* [Python沙箱逃逸的n种姿势](https://xz.aliyun.com/t/52)\n* [Escaping python sanbox](https://zolmeister.com/2013/05/escaping-python-sandbox.html)\n* [Pickle Security](http://v0ids3curity.blogspot.com/2012/10/exploit-exercise-python-pickles.html)\n* [Security Guide for developers](https://github.com/FallibleInc/security-guide-for-developers)"
  },
  {
    "path": "docs/2.SDL规范文档/5-nodejs安全编码规范.md",
    "content": "# 05.nodejs安全编码规范\n\n\n作者：\n\n协作：\n\n-------\n\n未完成"
  },
  {
    "path": "docs/2.SDL规范文档/6-移动安全规范.md",
    "content": "\n# 06.移动安全规范\n\n\n文档贡献者：johnathan \n\n\n-------\n\n## 1 移动安全入门\n\n移动安全带来了许多Web安全的挑战 - 广泛的受众，快速开发和持续的网络连接 - 加上更多传统胖客户端应用程序（例如缓冲区管理，本地加密和恶意软件）的常见风险。 移动环境的一个独特功能是来自未知开发人员的已安装应用程序的流行，这些应用程序应被视为“不受信任的”。\n\n### 1.1 移动应用的被攻击面\n\n如下所示，移动攻击可以涉及设备层，网络层，数据中心或这些的组合。 固有平台漏洞和社会工程继续为网络盗贼提供重要机会，从而为那些寻求保护用户数据的人带来重大挑战。 \n\n\n\n#### 攻击方向\n\n在移动技术链中有三个点，恶意方可能利用漏洞来发起恶意攻击：\n\n * 设备\n * 网络\n * 数据\n\n### 1.2 设备\n\n移动设备对敏感的公司信息（SCI）构成重大风险; 主要风险包括数据丢失和安全性受损。 无论是iPhone，Android或其他智能手机，针对设备本身的攻击者可以使用各种入口点：\n\n * 浏览器, 邮件, 或其他预加载数据的应用\n * 电话/短信\n * 第三方应用 (apps)\n * 操作系统\n * 射频（例如基带）, 蓝牙或其他通信通道\n\n\n#### 基于浏览器的攻击\n\n基于浏览器的攻击点可以包括：\n\n**网络钓鱼** – 涉及通过电子邮件欺骗来伪装为受信任实体来获取个人信息，例如用户名，密码和信用卡详细信息。 研究表明，移动用户比网络用户提交个人信息的可能性是钓鱼网站的三倍。 这在一定程度上可能是由于移动浏览器运行的缩小的环境，由于有限的屏幕不动产，有限的警告对话，缩小的安全锁图标，并且放弃了许多用户界面指示器，所述环境只显示URL的一小部分 例如大的STOP图标，突出显示的地址栏和其他可视指示器。\n\n**框架** - 构架涉及在iFrame中传送Web / WAP站点，这可以使“包装器”站点执行点击劫持攻击。\n\n**点击劫持** – 也称为UI修复，点击劫持涉及欺骗用户揭露机密信息或当用户点击看起来无害的链接或按钮时控制他们的设备。 此攻击采用嵌入式代码或脚本的形式，无需用户知识。 点击劫持已被利用在包括Facebook的网站窃取信息或直接用户攻击网站。\n\n**下载驱动攻击** – Android尤其容易受到这种攻击，其中网站访问导致发生没有用户知识的下载，或通过诱骗用户具有欺骗性的提示。 下载可以是恶意应用，并且用户然后可以由设备自动提示以安装应用。 当Android设备设置为允许来自“未知来源”的应用时，允许安装。\n\n**Man-in-the-Mobile (MitMo)** – 允许恶意用户利用放置在移动设备上的恶意软件绕过通过短信向用户的手机发送代码以进行身份确认的密码验证系统。\n\n\n#### 基于电话或短信的攻击\n\n电话/短信攻击点可以包括：\n\n**基带攻击** – 利用在手机的GSM / 3GPP基带处理器中发现的漏洞的攻击，GSM / 3GPP基带处理器是向小区基站发送和接收无线电信号的硬件。\n\n**短信钓鱼** – 类似于钓鱼，但使用手机短信代替电子邮件，以提示用户访问非法网站并输入敏感信息，如用户名，密码和信用卡号。\n\n**射频攻击** – 蓝牙，NFC攻击和其他RF攻击在各种外围通信信道上发现通常在附近的设备到设备通信中使用的漏洞。\n\n\n#### 基于应用程序的攻击\n\n基于应用的攻击点可以包括：\n\n**敏感数据存储** – 2011年viaForensics研究发现83％的流行应用程序采样存储数据不安全。\n\n**无加密或弱加密** – 允许传输未加密或弱加密数据的应用程序容易受到攻击。\n\n**SSL验证不正确** – 应用程序的安全套接字层（SSL）验证过程中的错误可能会允许数据安全漏洞。\n\n**配置操作** – 包括未经授权访问管理界面，配置存储和检索明文配置数据。\n\n**动态运行时注入** – 允许攻击者操纵和滥用应用程序的运行时，绕过安全锁，绕过逻辑检查，访问应用程序的特权部分，甚至窃取存储在内存中的数据。\n\n**非必要权限** – 错误配置的应用有时可能会通过授予非必要的权限来打开攻击者的大门。\n\n**提升的权限** – 利用一个错误，设计缺陷或配置监督，以获得通常受应用程序或用户保护的资源。\n\n\n#### 基于操作系统的攻击\n\n基于操作系统的攻击点可以包括：\n\n**没有密码** – 许多用户选择不设置密码，或使用弱PIN，密码或模式锁定。\n\n**iOS 越狱** – “越狱”是用于消除制造商和运营商提出的防止未经授权的代码在设备上运行的安全机制的术语。 一旦这些限制被删除，设备可以成为恶意软件和其他攻击的网关。\n\n**Android rooting** – 类似于越狱，rooting允许Android用户更改或替换系统应用程序和设置，运行需要管理员级权限的专门应用程序。 像越狱，它可能导致敏感数据的暴露。\n\n**密码和数据的可访问性** – 诸如Apple的iOS设备系列的设备在其用于存储加密密码和数据的加密机制中已经存在漏洞。 具有这些漏洞知识的攻击者可以解密设备的钥匙串，暴露用户密码，加密密钥和其他私人数据。\n\n**运营商预安装软件** – 预安装在设备上的软件可能包含安全漏洞。 最近，在Android手机上的一些预加载应用程序被发现包含安全漏洞，可用于擦除手机，窃取数据，甚至窃听电话。\n\n**零日漏洞** – 攻击经常发生在漏洞被首次利用的时间和软件开发人员能够发布解决问题的版本之间的窗口期间。\n\n\n### 1.3 网络\n\n基于网络的攻击点可以包括：\n\n**Wi-Fi (弱加密/无加密)** – 当在Wi-Fi网络上使用无法实施加密的应用程序时，存在恶意攻击者窃听无线连接而窃取数据的风险。 许多应用程序使用SSL / TLS，这提供了一定程度的保护; 然而一些针对SSL / TLS的攻击也被证明可以将关键用户数据暴露给攻击者。\n\n**恶意接入点** – 涉及物理安装授权各方访问安全网络的未授权无线接入点。\n\n**数据包嗅探** – 允许恶意入侵者捕获和分析网络流量，这通常包括以明文传输的用户名和密码信息。\n\n**中间人攻击 (MITM)** – 涉及窃听现有网络连接，侵入该连接，拦截消息和修改选择数据。\n\n**SSLStrip** – 一种中间人攻击的形式，利用了网站上的SSL / TLS实现的弱点，这可以依赖于用户验证HTTPS连接是否存在。 攻击将连接降级到HTTP，无需加密，用户很难在移动浏览器中检测到。\n\n**会话劫持** – 涉及会话密钥的利用以获得对用户和网络信息的未授权访问。\n\n**DNS 劫持** – 利用网络DNS可以将网站的用户引导到攻击者选择的另一个网站。 在某些情况下，攻击还可以通过应用程序注入内容。\n\n**假SSL证书** – 另一个中间人攻击涉及发出假SSL证书，允许恶意用户拦截假定安全的HTTPS连接上的流量。\n\n\n### 1.4 数据\n\n针对数据中心的攻击者使用两个主要入口点：\n\n * Web server\n * 数据库\n\n\n#### 基于web server的攻击\n\n基于Web服务器的攻击和漏洞包括：\n\n**平台漏洞** – 操作系统，服务器软件或Web服务器上运行的应用程序模块的漏洞可能被攻击者利用。 有时可以通过监视移动设备和web服务器之间的通信来发现脆弱性，以发现协议或访问控制中的弱点。\n\n**服务器错误配置** – 配置不良的Web服务器可能允许对通常受保护的资源的未授权访问。\n\n**跨站点脚本 (XSS)** – 跨站点脚本是一种涉及将恶意JavaScript代码注入网站的攻击。 容易受到此类攻击的页面会将用户输入返回浏览器，而不会正确地对其进行整理。 此攻击通常用于在用户访问页面时自动运行代码，从而控制用户的浏览器。 在已经建立对浏览器的控制之后，攻击者可以将该控制用于各种攻击，诸如内容注入或恶意软件传播。\n\n**跨站点请求伪造 (CSRF)** – 跨站点请求伪造涉及攻击者根据特定Web应用程序的功能知识创建HTTP（Web）请求，并诱骗用户或浏览器提交这些请求。 如果Web应用程序易受攻击，攻击可以执行似乎来自用户的事务或提交。 CSRF通常在攻击者已经通过XSS，社交工程或其他方法获得对用户会话的控制之后使用。\n\n**弱输入验证** – 许多Web服务过度信任来自移动应用程序的输入，依靠应用程序来验证最终用户提供的数据。 但是，攻击者可以伪造自己与Web服务器的通信，或完全绕过应用程序的逻辑检查，允许他们利用服务器上缺少的验证逻辑来执行未经授权的操作。\n\n**暴力攻击** – 暴力攻击只是试图猜测对字段的有效输入，通常使用高速率的尝试和可能值的字典。 暴力攻击的最常见用法是身份验证，但也可用于在Web应用程序中发现其他有效值。\n\n#### 基于数据库的攻击\n\n数据库攻击和漏洞包括：\n\n**SQL 注入** – 没有正确验证用户输入的接口可能导致SQL被注入到其他无害的应用程序查询中，导致数据库暴露或以其他方式操纵通常应该限制用户或应用程序的数据。\n\n**执行操作系统级命令** – 与SQL注入类似，某些数据库系统提供了执行操作系统级命令的方法。 攻击者可以将这些命令插入到查询中，使数据库在服务器上执行这些命令，从而为攻击者提供额外的权限，直至并包括根级别系统访问。\n\n**权限提升** – 当攻击利用一些漏洞获得更大的访问时，会发生这种情况。 在数据库上，这可能导致敏感数据被盗。\n数据转储 - 攻击者导致数据库转储数据库中的一些或所有数据，暴露敏感记录。\n\n\n### 1.5 移动应用的类型\n\n移动应用通常分为三个操作类别：\n\n**Web** – 通过通用网络浏览器操作的应用。 有时被称为WAP或移动网站，这些是移动等同于在过去十年中激增的功能性网络应用程序，提供许多功能，如网上银行和购物。 虽然常规网站可用于移动网络浏览器，但许多公司现在创建单独的移动网络应用以优化移动属性，例如更小的屏幕尺寸，基于触摸的导航和GPS位置的可用性。\n\n**Native** – 安装的应用程序，其操作本机移动设备操作系统，为特定的移动平台编译并利用其API。 这些通常（但不总是）通过应用程序市场下载和安装。\n\n**Wrapper** – 通过在专用本机应用程序包装器（有时也称为“shell应用程序”或“混合应用程序”）中利用网页操作的应用程序。虽然对最终用户显示为本机应用程序，但基于Web的功能可能导致不同的漏洞 比在完全本地编码的应用程序中发现。\n\n## 2. 编码实践\n### 2.1 增加代码复杂性和使用混淆\n\n###### 详细描述\n\n反向工程应用程序可以提供有价值的洞察您的应用程序的工作原理。 使您的应用程序在内部更复杂，攻击者更难以看到应用程序如何操作，这可以减少攻击面的数量。\n\n#### 建议\n\n反向工程一个Android应用程序（.apk文件）是很容易实现的，然后可以检查应用程序的内部工作。 混淆代码，以使恶意用户更难以检查应用程序的内部工作，如下面链接到Android开发人员#### 参考文章中所述。\n\n此外，由于iOS应用程序的设计方式，它们容易受到逆向工程攻击。 应用程序的类和协议存储在对象文件中，允许攻击者完全映射应用程序的设计。 Objective-C本身是一种反射语言，能够感知和修改自己的状态; 具有正确工具的攻击者可以以与运行时管理应用程序相同的方式感知和修改应用程序的状态。 Objective-C包含一个简单的消息框架，它非常容易跟踪，并且可以被操纵来拦截甚至篡改应用程序的运行时。 可以使用相对简单的攻击来操纵Objective-C运行时绕过身份验证和策略检查，内部应用程序健全检查或警告应用程序策略的那种逻辑检查。\n\n如果应用程序处理高度敏感的数据，请考虑实施反调试技术。 存在可以增加逆向工程代码的复杂性的各种技术。 一种技术是使用C / C ++来限制攻击者轻松地运行操作。 有丰富的C和C ++库，它们非常成熟，并且易于与Objective-C集成，并且Android提供了JNI（Java Native Interface）。 在iOS上，考虑在低级C中编写代码的关键部分，以避免Objective-C运行时或Objective-C逆向工程工具（如class-dump，class-dump-z，Cycript或Frida）的暴露和操作。\n\n**限制调试器 –** 应用程序可以使用特定的系统调用来指定，以防止操作系统允许调试器附加到进程。 通过防止调试器attach到进程，攻击者干扰低级运行时的能力受到限制。 攻击者必须首先规避调试限制，以便在低级别上攻击应用程序。 这增加了攻击的进一步复杂性。 Android应用程序应该在应用程序清单中设置“android：debuggable =”false“”，以防止攻击者或恶意软件轻松运行运行时操作。 在iOS上，您可以使用`PT_DENY_ATTACH`。\n\n**跟踪检查 –** 应用程序可以确定其当前是否由调试器或其他调试工具跟踪。 如果正在被跟踪，则应用可以执行任何数量的响应动作，例如，丢弃加密密钥以保护用户数据，通知服务器管理员或其他这样的响应以试图保护自身。 可以通过检查进程状态标志或使用其他技术（例如比较“ptrace attach”的返回值，检查父进程，将进程列表中的调试器列入黑名单或比较程序不同部分的时间戳）来检测调试器跟踪。\n\n**优化 -** 为了隐藏高级数学计算和其他类型的复杂逻辑，利用编译器优化可以帮助混淆目标代码，使其不容易被攻击者反汇编。 这使得攻击者更难以获得对特定代码的理解。 在Android中，通过使用本机编译库和本机开发工具包（NDK）可以更容易地实现。 此外，使用LLVM Obfuscator或任何保护程序SDK将提供更好的机器代码混淆。\n\n**Stripping binaries –** 清除原生二进制文件是增加攻击者所需的时间和技能以便查看应用程序低级功能的有效方法。 通过剥离二进制，二进制的符号表被剥离，以便攻击者不能轻易地调试或反向工程应用程序。 剥离二进制文件不会丢弃iOS上的Objective-C类或对象映射数据。 在Android上，您可以重用在gNU / Linux系统上使用的技术，例如`sstrip`或使用UPX。\n\n分布在App Store中的iOS应用程序中的二进制文件被加密，增加了另一层的复杂性。 虽然存在从这些二进制文件中剥离FairPlay数字版权管理（DRM）加密的工具，但这一层DRM增加了攻击二进制所需的时间和熟练程度。 然而，App Store应用程序中使用的加密可能会被熟练的攻击者剥离。 攻击者通过转储在运行时从设备的内存中直接加载应用程序的内存来实现这一点。\n\n#### 参考\n\n### Android\n * [ProGuard](http://proguard.sourceforge.net/) and <http://developer.android.com/tools/help/proguard.html>\n * [DexGuard](http://www.saikoa.com/dexguard)\n * [DashO](https://www.preemptive.com/products/dasho/overview)\n\n### iOS\n * [PreEmptive Protection for iOS - Rename](https://github.com/preemptive/PPiOS-Rename)\n * [ObjC-Obfuscator](https://github.com/FutureWorkshops/Objc-Obfuscator)\n * [FairPlay DRM overview](https://www.theiphonewiki.com/wiki/Copy_Protection_Overview)\n * [Bugging Debuggers](https://www.theiphonewiki.com/wiki/Bugging_Debuggers)\n * [PreEmptive Protection for iOS - ControlFlow](https://www.preemptive.com/products/ppios)\n\n### Other / Multi\n * [LLVM-Obfuscator](https://github.com/obfuscator-llvm/obfuscator/wiki) (iOS, Android, others)\n * [Dotfuscator Community Edition](https://www.preemptive.com/products/dotfuscator/compare-editions) (.NET Obfuscator with Xamarin support)\n\n#### CWE/OWASP\n\n * [OWASP Mobile Application Security Verification Standard, Resiliency Against Reverse Engineering Requirements](https://github.com/OWASP/owasp-masvs/blob/master/Document/0x15-V9-Resiliency_Against_Reverse_Engineering_Requirements.md)\n * [M8 - Security Decisions via Untrusted Inputs](https://www.owasp.org/index.php/Mobile_Top_10_2014-M8); [M10 - Lack of Binary Protections](https://www.owasp.org/index.php/Mobile_Top_10_2014-M10)\n * [CWE-656: Reliance on Security Through Obscurity](http://cwe.mitre.org/data/definitions/656.html)\n\n### 2.2 避免简单逻辑\n\n#### 详细描述 \n\n代码中的简单逻辑测试更容易受到攻击。 例如：\n\n```\nif sessionIsTrusted == 1\n```\n\n这是一个简单的逻辑测试，如果攻击者可以改变这个值，他们可以绕过安全控制。 苹果iOS被攻击使用这种类型的弱点和Android应用程序已经他们的Dalvik二进制补丁绕过各种保护机制。 这些逻辑测试很容易在许多级别上回避。 在组装级别上，攻击者可以仅使用调试器来攻击iOS应用程序，以找到正确的CBZ（零比较和分支）或CBNZ（比较和非零分支）指令并将其反转。 这可以在运行时执行，只需遍历对象的内存地址，并在应用程序运行时更改其实例变量。 在Android上，应用程序可以反编译为SMALI，并在重新编译之前修补分支条件。\n\n#### 建议\n\n考虑一个更好的编程范例，当会话不受信任时，由服务器强制执行权限，或者通过防止某些数据被解密或以其他方式可用，直到应用程序可以使用质询/响应，OTP或其他 形式的认证。 此外，#### 建议将所有健全检查功能声明为静态内联。 使用这种方法，它们被内联编译，使得更难以修补（即攻击者不能简单地重写一个函数或修补一个函数）。 这种技术将需要攻击者从应用程序中寻找并修补检查的每个实例，增加了攻击所需的复杂性。 对于高度敏感的应用程序，建立在安全编码原则中的更复杂的方法可能值得进一步调查。 集成技术（如加密，定时回调和基于流的编程）可能增加攻击者的复杂性。\n\n同样，存储在对象中的简单逻辑变量可以容易地被攻击者操纵。 例如：\n\n```\nsession.trusted = TRUE\n```\n\n这样的值可以由应用程序当前使用的类的实例内的攻击者读取和写入。 在iOS上，通过操作Objective-C运行时，可以操纵这些变量，以便下次应用程序引用这些变量时，将读取任何操作的值。\n\n#### CWE/OWASP \n\n * [M8 - Security Decisions via Untrusted Inputs](https://www.owasp.org/index.php/Mobile_Top_10_2014-M8); [M10 - Lack of Binary Protections](https://www.owasp.org/index.php/Mobile_Top_10_2014-M10)\n * [CWE 200](http://cwe.mitre.org/data/definitions/200.html)\n\n\n### 2.3\t 测试第三方库\n\n#### 详细描述 \n\n开发人员非常依赖第三方库。 在测试代码时，彻底探查和测试这一点很重要。 第三方库可以包含漏洞和弱点。 许多开发人员认为第三方库已经完善并经过测试，然而，问题可能而且确实存在于他们的代码中。\n\n#### 建议\n\n安全审计必须彻底测试第三方库和功能。 这应该包括核心的iOS和Android代码/库。 升级到新版本的第三方库（或操作系统版本）应视为您的应用程序的一部分。 更新的第三方库（或新操作系统版本）可能包含新的漏洞或暴露您的代码中的问题。 应该测试它们，就像为应用程序测试新代码一样。 在iOS上，静态编译第三方库以避免LD_PRELOAD攻击; 在这种攻击中，一个库及其功能可以被替换为具有被恶意代码替换的攻击者库。\n\n#### CWE/OWASP \n\n * [M8 - Security Decisions via Untrusted Inputs](https://www.owasp.org/index.php/Mobile_Top_10_2014-M8)\n * [CWE 829](http://cwe.mitre.org/data/definitions/829.html)\n\n\n### 2.4 实施防篡改技术\n\n#### 详细描述 \n\n攻击者可以在应用上篡改或安装后门，重新签名并将恶意版本发布到第三方应用市场。 这种攻击通常针对流行的应用程序和金融应用程序。\n\n#### 建议\n\n采用防篡改和篡改检测技术来防止非法应用程序执行。\n\n使用校验和，数字签名和其他验证机制来帮助检测文件篡改。 当攻击者试图操纵应用程序时，不会保留正确的校验和，并且这可以检测和防止非法执行。 注意，这样的技术不是万无一失的，并且可以被充分动机的攻击者绕过。 校验和，数字签名和其他验证技术增加了攻击者必须花费的时间和精力才能成功地破坏应用程序。 应用程序可以在检测到篡改的情况下以静默方式擦除其用户数据，密钥或其他重要数据，以进一步挑战攻击者。 检测到篡改的应用程序还可以通知管理员。\n\n在Android上，用于签名应用程序的公钥可以从应用程序的证书中读取，并用于验证应用程序是否已使用开发人员的私钥签名。 使用PackageManager类，可以检索应用程序的签名，然后将它们与正确的值进行比较。 如果有人篡改或重新签名了应用程序，比较将失败，导致检测到篡改应用程序。\n\n#### 参考 \n\n * Android - [https://gist.github.com/scottyab/b849701972d57cf9562e](https://gist.github.com/scottyab/b849701972d57cf9562e)\n \n#### CWE/OWASP\n\n * [M10 - Lack of Binary Protections](https://www.owasp.org/index.php/Mobile_Top_10_2014-M10)\n * [CWE-354: Improper Validation of Integrity Check Value](http://cwe.mitre.org/data/definitions/354.html)\n### 2.5 在内存中安全的存储敏感数据\n\n通常，iOS开发人员会将应用程序设置存储在plist文件中，在某些情况下这可能会受到影响。\n\n#### 详细描述 \n\n当应用程序正在使用时，用户或应用程序特定的数据可以存储在RAM中，并且在用户注销或会话超时时不会正确清除。 因为Android将应用程序存储在内存中（即使在使用后），直到内存被回收，加密密钥可能会保留在内存中。 发现或窃取设备的攻击者可以附加调试器并从应用程序转储内存，或者加载内核模块以转储内存中的全部内容。\n\n当管理密码和其他敏感信息时，应用程序会将该信息保存在内存中，即使缓冲区释放了一段时间。 如果应用程序容易出现缓冲区溢出，格式化字符串，数据泄露和其他漏洞，这可能是一个安全问题，这可能允许攻击者转储进程的内存以恢复敏感信息。\n\n#### 建议\n\n不要将内存中保存敏感数据（例如加密密钥）长于所需的时间。 清除使用后保存密钥的任何变量。 避免对敏感的密钥或密码使用不可变对象，如在Android`java.lang.String`中，而是使用char数组。 即使对不可变对象的引用被删除或清空，它们可能保留在内存中，直到垃圾回收发生（这不能被应用程序强制）。\n\n这只能通过低级语言完成，因为如果优化例程检测到缓冲区在覆盖后不再使用，编译器和即时虚拟机将会因性能原因而忽略这些操作。\n\n有一些工具可以来绕过编译器优化以清除这些缓冲区，但他们都依赖工具链，特定的语言和平台。\n\n#### CWE/OWASP\n\n * [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4)\n * [CWE-316: Cleartext Storage of Sensitive Information in Memory](http://cwe.mitre.org/data/definitions/316.html)\n * [CWE-200: Information Exposure](http://cwe.mitre.org/data/definitions/200.html)\n * [CVE-2014-0160 Heartbleed](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0160)\n\n\n### 2.6 安全的删除数据\n\n#### 详细描述 \n\n在Android上，调用file.delete（）将不会安全地擦除目标文件，并且只要它没有被覆盖，它可以从设备的物理图像刻出。 由于对NAND闪存的积极管理，擦除文件的传统方法通常不在移动设备上工作。\n\n#### 建议\n\n在假设任何写入设备的数据都可以恢复的情况下操作。 在某些情况下，加密可能会增加额外的保护层。\n\n对于大多数应用程序不推荐使用以下方法，但可能删除文件并用大文件覆盖所有可用空间（这将迫使NAND闪存擦除所有未分配的空间）。 这种技术的缺点包括耗尽NAND闪存，导致应用和整个设备响应缓慢，并显着的功耗。\n\n尽可能避免在设备上存储敏感数据。 \n\n加密存储在文件中的敏感数据，在删除之前重写文件的内容和同步可以帮助，但是如上所述，它们不是完全可靠的解决方案。\n\n#### 参考 \n\n - [General Purpose Cypto](https://developer.apple.com/library/mac/documentation/security/conceptual/cryptoservices/GeneralPurposeCrypto/GeneralPurposeCrypto.html)\n \n#### CWE/OWASP\n\n - [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4)\n - [CWE-312: Cleartext Storage of Sensitive Information](http://cwe.mitre.org/data/definitions/312.html)\n - [CWE-313: Cleartext Storage in a File or on Disk](http://cwe.mitre.org/data/definitions/313.html)\n\n### 2.7 避免敏感数据的查询字符串\n\n#### 详细描述\n\n一个主要的突破口是执行一个简单的经过修改过的查询字符串。查询字符串参数是可见的，并且可能经常意外地缓存（从网络历史记录，Web服务器或代理日志等）。应该避免使用未加密的有意义的数据作为查询字符串。 如果用户凭证作为查询字符串参数传输，而不是在POST请求的正文中传输，那么这些凭证可能会被记录在各种地方 - 例如，在用户的浏览器历史记录中，在Web服务器日志中，以及在日志中或者在基础设施服务商采用的任何反向代理。 如果攻击者成功地获得这些资源中的任何一个，则他可以通过捕获存储在那里的用户凭证来提升权限。\n\n#### 建议 \n\n使用安全的具有XSRF令牌保护的POST方法来发送用户数据。 在可以找到查询字符串数据的区域中，默认情况下不会记录POST数据。 无论是POST还是GET，都应使用临时会话Cookie。 使用非零初始化向量和临时会话密钥加密数据也可以帮助防止重放攻击。 如果需要，可以使用在主机之间使用安全算法（例如Diffie-Hellman）协商的临时会话密钥来加密查询字符串数据。\n\n#### 参考\n\nPinto, Marcus (2007). The Web Application Hacker’s Handbook: Discovering and Exploiting Security Flaws (Kindle Locations 2813-2816). Wiley. Kindle Edition.\n\n#### CWE/OWASP \n\n * [M2 - Insecure Data Storage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M2), [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4)\n * [CWE 598](http://cwe.mitre.org/data/definitions/316.html)\n\n## 3\t敏感数据处理\n### 3.1 实现安全数据存储\n\n#### 详细信息 \n\n在移动设备上安全地存储数据需要适当的技术。 只要有可能***“简单地不要存储或缓存数据”*** 是避免数据在设备上被获取最直接的方式。\n\n#### 建议\n\n尽量不要存储敏感数据。 减少用户信息存储的方法包括：\n\n* 仅仅传输和显示，但不持久化存储中。 这还需要特别注意防止敏感数据的屏幕截图被写入磁盘。\n* 仅存储在内存中（在应用程序关闭时清除）。\n\n#### 附加分层加密\n如果在设备上存储敏感数据是应用程序需求，则应向数据添加额外的经过验证的第三方加密（例如，[SQLCipher](https://www.zetetic.net/sqlcipher/)）。\n\n通过添加另一层加密，您可以更好地控制实施和攻击，主要集中在主要的操作系统加密类。 例如，对iOS数据保护类（现在已被入侵）的攻击将无法直接危害您的应用程序。 这种方法具有更复杂的缺点，并且如果实施得不好，实际上会减少安全系数。 如果您不确定是否包括经过验证的第三方加密库，Apple和Android的通用加密库提供了许多标准加密功能，如果使用得当，可以提供相当安全的加密实现。\n\n下面是一些方法：\n\n * 使用SQLCipher在SQLite数据库中加密敏感值，使用[PRAGMA key](https://www.zetetic.net/sqlcipher/sqlcipher-api/#key)加密整个数据库\n * PRAGMA key可以在用户初次安装应用程序或第一次启动时在运行时生成\n * 为每个用户和设备生成唯一的PRAGMA密钥\n * 密钥生成的源应当具有足够的熵（即，避免从诸如用户名的易于预测的数据生成密钥材料）\n\n每当您加密用户数据时，旨在使用随机生成的主密钥对其进行加密，该主密钥在用户访问数据时也使用用户提供的密码加密。 这将防止数据被容易地恢复，如果攻击者从设备中提取主密钥。 由于Apple的数据保护API和钥匙串中的漏洞数量以及大多数Android手机上缺少设备加密，因此不#### 建议将主密钥或密码存储在设备上。\n\n#### Android\n在Android中，记住外部存储设备（如SD卡）没有细粒度的权限，任何应用程序默认情况下具有对存储的读访问权限，可以读取所有文件。 从Android 4.4开始应用程序可以在某些情况下以受保护的方式在SD卡上存储数据 (#### 参考 [http://source.android.com/devices/tech/storage/](http://source.android.com/devices/tech/storage/)).\n\nAndroid和iOS实现标准加密库，例如AES，可用于保护数据。 请注意被此方法加密的数据安全依赖于用于导出密钥和密钥管理的密码安全。 需要考虑密码策略，长度和复杂性与用户方便性以及加密密钥如何存储在内存中。 而且root权限可以转储正在运行的进程的内存，并搜索它的加密密钥。\n\n还要注意，使用标准加密提供程序“AES”通常将默认为较不安全的AES-ECB。 最佳做法是使用256位密钥和SecureRandom生成的随机IV指定AES-CBC或AES-GCM。 您还应该使用经过良好测试的PBKDF2（基于密码的密钥导出函数）来从密码导出密钥。\n\n#### iOS\n\niOS中内置的数据保护API与复杂的密码短语相结合，可以提供额外的数据保护层，但不像实施其他第三方验证的加密技术那么安全。 为了利用这一点，文件必须被专门标记。(#### 参考最佳实践 6.1 [谨慎使用keychain](/iOS/use-the-keychain-carefully)). 任何没有专门使用apple 的文件保护api加密的数据都是未加密存储的\n\n#### 参考\n\n * [Android/iOS Full Database Encryption](http://sqlcipher.net/) - http://sqlcipher.net/\n * [Android Storage Options](http://developer.android.com/guide/topics/data/data-storage.html) - http://developer.android.com/guide/topics/data/data-storage.html\n\n#### CWE/OWASP \n\n * OWASP Mobile Top 10: [M2 - Insecure Data Storage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M2)\n * CWE: [CWE-312 - Cleartext Storage of Sensitive Information](http://cwe.mitre.org/data/definitions/312.html), [CWE-313 - Cleartext Storage in a File or on Disk](http://cwe.mitre.org/data/definitions/313.html), [CWE-522 - Insufficiently Protected Credentials](http://cwe.mitre.org/data/definitions/522.html), [CWE-215 - Information Exposure Through Debug Information](http://cwe.mitre.org/data/definitions/215.html)\n\n### 3.2 使用Cookie的安全设置\n\n#### 详细描述 \n\n如果Cookie未标记为“Secure”，则无论与主机的会话是否安全，都可能通过不安全的连接进行传输。 换句话说，它可以通过HTTP连接来传输。\n\n此外，由于Cookie无法通过客户端访问（例如，无法使用JavaScript代码段访问），因此在Cookie上设置“HTTPOnly”标志可防止跨站点脚本（XSS）等攻击。\n\n#### 建议\n\nSet-Cookie头应该使用“Secure”和“HTTPOnly”设置。 这些设置应适用于本机和/或网络应用程序的所有Cookie。\n\n#### CWE/OWASP \n\n * OWASP Mobile Top 10: [M9 - Improper Session Handling](https://www.owasp.org/index.php/Mobile_Top_10_2014-M9)\n * CWE [CWE-614 - Sensitive Cookie in HTTPS Session Without 'Secure' Attribute](http://cwe.mitre.org/data/definitions/79.html)\n \n\n\n### 3.3 完全验证SSL / TLS\n\n许多应用程序没有正确验证SSL / TLS证书，使他们容易受到中间人（MITM）攻击。 如果应用程序无法正确验证其与服务器的连接，则该应用程序容易受到特权网络攻击者的MITM攻击。 这种类型的攻击使罪犯能够捕获，查看和修改在应用程序和服务器之间发送和接收的流量。\n\n#### 详细描述\n\n未正确验证其与服务器的连接的应用程序容易受到拥有网络管理权限的攻击者的中间人攻击。 这意味着攻击者将能够捕获，查看和修改在应用程序和服务器之间发送和接收的流量。\n\n#### 常见错误：接受自签名证书\n\n开发人员可能会因为各种原因而停用应用中的证书验证。 一个例子是开发人员需要在生产服务器上测试代码，但没有测试环境的域证书。 在这种情况下，开发人员可以向网络库添加代码以接受所有有效的证书。 然而，接受所有证书为有效的，允许攻击者通过简单地使用自签名证书对应用程序执行MITM攻击。 这种开发应用程序的方法使SSL / TLS的效果无效，并且相对于未加密的纯文本连接（除了需要主动MITM攻击来查看和修改流量，而纯文本连接可以被动监控之外）没有实质上的安全提升。\n\n以下是接受所有SSL / TLS证书的有效Android代码示例：\n\n```java\n\tTrustManager[] trustAllCerts = new TrustManager[] {\n\t   new X509TrustManager() {\n\t\t  public java.security.cert.X509Certificate[] getAcceptedIssuers() {\n\t\t\treturn null;\n\t\t  }\n\t\t  public void checkClientTrusted(X509Certificate[] certs, String authType) {  }\n\n\t\t  public void checkServerTrusted(X509Certificate[] certs, String authType) {  }\n\n\t   }\n\t};\n\n\t//Globally set the broken TrustManager\n\tSSLContext sc = SSLContext.getInstance(\"SSL\");\n\tsc.init(null, trustAllCerts, new java.security.SecureRandom());\n\tHttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());\n\n\t//Make the connection to the server\n\tURL url = new URL(\"https://paypal.com\");\n\tHttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();\n\tInputStream ins = urlConnection.getInputStream();\n\tInputStreamReader isr = new InputStreamReader(ins);\n\tBufferedReader in = new BufferedReader(isr);\n\n\tString inputLine;\n\tin.close();\n```\n\n#### 常见错误：设置允许的主机名验证器\n\n在实施SSL / TLS时，另一个常见的开发人员错误是设置一个允许所有主机名的主机名验证器（hostname verifier）。 在这种情况下，应用程序将不接受自签名证书，证书仍然需要被验证。 但是如果应用程序“允许所有主机名”，任何有效的证书颁发机构（CA）为任何域名颁发的证书都可以被用来进行中间人攻击（MITM）和签名网络数据。\n\n下面是一个易受攻击的Android代码示例，它设置了一个允许所有主机名的主机名验证器：\n\n```java\n\tURL url = new URL(\"https://paypal.com\");\n\tHttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();\n\turlConnection.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);\n\tInputStream ins = urlConnection.getInputStream();\n\tInputStreamReader isr = new InputStreamReader(ins);\n\tBufferedReader in = new BufferedReader(isr);\n\n\tString inputLine;\n\tin.close();\n```\n\n#### 建议\n\n#### 一般建议\n\n对于处理高度敏感数据的任何应用程序，请使用证书锁定以防止MITM攻击。 大多数应用程序都定义了它们连接的位置（它们的后端服务器），并固有地信任它们连接的基础设施，因此使用“私有”公钥基础结构（与公共证书分开）是可以接受的（通常更安全） 当局。 使用这种方法，攻击者需要来自服务器端的私钥对他们没有物理访问的设备执行MITM攻击。\n\n如果无法对处理高度敏感数据的任何应用程序功能实施证书锁定，请实施正确的证书验证，该证书验证由两部分组成：\n\n1. **Certificate validation:** 呈现给应用程序的证书必须由应用程序完全验证，并由受信任的根CA进行签名。 \n2. **Hostname validation:** 应用程序必须检查并验证从证书提取的主机名（公用名或CN）与应用程序要与之通信的主机的主机名相匹配。\n\n#### Android建议\n\n将证书固定到Android随附的默认Apache HTTP客户端包括获取所需主机的证书，转换.bks格式的证书，然后将证书固定到DefaultHttpClient实例。 BKS密钥库通常包含在应用程序的APK文件的assets / raw目录中。\n\n以下示例代码演示了如何加载BKS密钥库：\n\n```java\n\tInputStream in = resources.openRawResource(certificateRawResource);\n\n\tkeyStore = KeyStore.getInstance(\"BKS\");\n\tkeyStore.load(resourceStream, password);\n```\n\nhttpClient实例可以被配置为仅允许接受存在于应用程序内存储的证书签名的证书。\n\n以下示例代码说明了此方法：\n\n```    \n\tHttpParams httpParams = new BasicHttpParams();\n\n\tSchemeRegistry schemeRegistry = new SchemeRegistry();\n\tschemeRegistry.register(new Scheme(\"https\", new SSLSocketFactory(keyStore), 443));\n\n\tThreadSafeClientConnManager clientMan = new ThreadSafeClientConnManager(httpParams, schemeRegistry);\n\n\thttpClient = new DefaultHttpClient(clientMan, httpParams);\n\t\n```\n\n有关在Android中实现证书锁定的更多信息，请参阅OWASP [Certificate and Public Key Pinning guide](https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#Android) \n\n此外，[CWAC-NetSecurity](https://github.com/commonsguy/cwac-netsecurity) 是一个将Android 7.0网络安全配置子系统返回到API级别17（Android 4.2）的库。它使得将应用程序绑定到特定的证书颁发机构或证书更容易。支持自签名证书，以及处理其他高级SSL证书方案。\n\n#### For iOS\n一个方案是使用`NSURLSession`或`AFNetworking`类在iOS中实现证书锁定。 此实现的其他详细信息可以在apple developer网站上[HTTPS Server Trust Evaluation](https://developer.apple.com/library/ios/technotes/tn2232/_index.html)中找到。 \n\n此外，一个开源框架的[TrustKit](https://github.com/datatheorem/TrustKit)可以帮助开发人员更容易地在iOS中部署公钥锁定。\n\n#### 参考\n\n* [Your app shouldn’t suffer SSL’s problems](https://moxie.org/blog/authenticity-is-broken-in-ssl-but-your-app-ha/) - https://moxie.org/blog/authenticity-is-broken-in-ssl-but-your-app-ha/ \n\n#### CWE/OWASP\n\n * OWASP Mobile Top 10: [M3- Insufficient Transport Layer Protection](https://www.owasp.org/index.php/Mobile_Top_10_2014-M3)\n * CWE: [CWE-319 - Cleartext Transmission of Sensitive Information](http://cwe.mitre.org/data/definitions/319.html)\n\n### 3.4 防止SSL降级攻击\n\n#### 详细描述\n\n使用这种形式的中间人攻击，攻击者可以通过透明地劫持网络上的HTTP流量，监控HTTPS请求，然后消除SSL / TLS来绕过SSL / TLS，从而在客户端和服务器之间创建不安全的连接。 这种攻击在移动网络应用上尤其难以预防（移动网络应用本质上是一个看起来像应用的网页）。\n\n#### 建议\n\n通过TLS提供所有流量，甚至非敏感流量。 这防止了任何可能的降级/剥离攻击，因为攻击者需要初始明文“入口点”来完成所述攻击。\n\n验证SSL / TLS是否处于活动状态。 在完全本机应用程序中验证SSL / TLS是相对简单的。 移动网络应用可以通过JavaScript验证SSL / TLS，以便如果未检测到HTTPS连接，则客户端将重定向到HTTPS。 要求SSL / TLS的更可靠的手段是HTTP严格传输安全（HSTS）头。 HSTS标头强制与该域的所有后续连接使用TLS和原始证书。 浏览器只是开始实现HSTS头而移动浏览器总是滞后。\n\n在应用程序中使用图标或语言，以确保用户在所述连接不依赖于经过验证的HTTPS会话时知道并进行安全连接。 教育用户是降低SSL / TLS降级攻击风险的重要组成部分。 在应用程式内使用弹出提示和文字提示，强化使用者使用HTTPS保护网路流量的重要性。\n\n最近在Android和iOS中实施的另一种缓解措施是将非TLS /纯文本流量视为开发人员错误。Android最近添加 `android:usesCleartextTraffic` ([Android M and the War on Cleartext Traffic](https://koz.io/android-m-and-the-war-on-cleartext-traffic/)，而iOS 9及更高版本要求您手动添加明文流量的例外。 替换Web协议HTTP / 2是另一个未来的解决方案，因为它仅使用TLS（并且包括其他功能）.\n\n#### 参考\n\n* [Moxie Marlinspike’s sslstrip exploitation tool](https://moxie.org/software/sslstrip/) - https://moxie.org/software/sslstrip/\n\n#### CWE/OWASP\n\n * OWASP Mobile Top 10: [M3- Insufficient Transport Layer Protection](https://www.owasp.org/index.php/Mobile_Top_10_2014-M3)\n * CWE: [CWE-757: Selection of Less-Secure Algorithm During Negotiation ('Algorithm Downgrade')](http://cwe.mitre.org/data/definitions/757.html)\n### 3.5 限制使用UUID\n#### 详细描述 \n\n大多数移动设备具有在制造时为了识别目的而分配的唯一ID（也称为通用唯一标识符（UUID））。 例如，iOS设备分配了所谓的唯一设备标识符（UDID）。 唯一标识设备的能力对于获取，管理和保护数据通常很重要。 开发人员迅速采用UUID和UDID进行设备识别，从而使其成为许多系统的安全基础。\n\n不幸的是，这种方法带来了几个隐私和安全问题。 首先，许多在线系统已将设备的UUID连接到单个用户，以便即使在用户未登录到应用时也能够跨应用进行跟踪。 这种跟踪用户的高级功能已经成为主要的隐私问题。\n\n除此之外，通过UUID识别人员的应用程序有风险暴露设备的以前的所有者的数据到新的所有者。 在一个实例中，在重新设置iPhone之后，即使所有用户数据已被擦除，我们也可以访问先前用户的在线音乐服务的帐户。 这不仅是一个隐私问题，它的安全威胁，因为攻击者可以伪造一个UUID。\n\n苹果已经认识到iOS的UDID的隐私和安全风险，并删除了开发者对它的访问。 在UDID不可用的情况下，一些开发人员应用涉及无线网络接口或OpenUDID的MAC地址的其他设备识别方法。 这些方法现在已在系统/ API级别被禁止，并且作为AppStore审查过程的一部分被标记和拒绝。\n\n#### 建议\n\n我们#### 建议开发人员避免使用任何设备提供的标识符来标识设备，特别是如果它是实施设备身份验证的一部分。 相反，我们#### 建议在注册，安装或首次执行时创建应用程序唯一的“设备因子”。 然后可能需要将此应用程序唯一的设备因子与用户身份验证结合，以创建会话。 设备因子也可以用作加密例程中的附加因子。\n\n由于它不依赖于可预测的，设备提供的数据，因此开发变得更加困难。 通过利用挑战 - 响应方法，服务器和设备可以在用户认证之前彼此认证。 要获得系统访问，攻击者必须利用这两个因素。 开发人员还可以实现在客户端或服务器端重置设备因素的功能，从而强制对用户和设备进行更严格的重新身份验证。\n\n为了在保留广告功能的同时保护用户隐私，Apple#### 建议使用advertisingIdentifier - 在系统中所有应用程序之间共享的唯一标识符。用户可以随时在设置 - >隐私 - >广告菜单中重置其设备上的advertisingIdentifier。\n\n#### 参考\n\n * [Unique Identifiers in iOS](https://possiblemobile.com/2013/04/unique-identifiers/)\n \n#### CWE/OWASP\n\n * [M5 - Poor Authorization and Authentication](https://www.owasp.org/index.php/Mobile_Top_10_2014-M5)\n * [CWE-200: Information Exposure](http://cwe.mitre.org/data/definitions/200.html)\n\n\n### 3.6\t 谨慎处理地理位置数据\n\n#### 详细描述\n\nAndroid和iOS可以使用GPS准确地确定位置。 处理此GPS数据是一个隐私问题，如果攻击者知道其当前或过去的位置，可能会使用户容易受到其他攻击。 本地蓝牙、NFC 、RFID标签的信息也可能泄漏地理位置信息。\n\n此外，访问图库图片的应用程序也可以是用户的隐私问题，它可以通过检查时间戳并且假设图片是用户自己拍摄的图片来抓取存储在其中的GPS位置（如果有的话）。\n\n#### 建议\n\n考虑使用和避免存储GPS数据的影响。 为了更好的隐私，尽量使用最粗粒度的位置服务。 除非必要，不要记录或存储GPS信息。 虽然在某些应用中使用GPS可能很有用，但很少需要记录和存储数据。 避免这种情况防止了许多隐私和安全问题。 GPS定位信息通常在iOS上的locationd缓存和Android上的各种缓存之间缓存一段时间。 一些应用程序自动使用GPS。 一个例子是通常对图像进行地理标记的相机。 如果这是一个问题，请确保从图像中剥离EXIF数据。\n\n在需要安全的地点工作时，请记住，GPS数据可能会报告给Apple和Google服务器，以提高准确性。 Android和iOS设备都能捕获范围内附近接入点的信息，无论设备是否连接到它们。 不要在将在安全位置或其附近运行的应用程序中激活GPS，其坐标或无线网络拓扑不应报告给供应商。 除此之外，攻击者可以使用单个接入点的硬件地址的知识来模拟安全无线环境并从苹果或Google返回环境的GPS坐标。\n\n#### 参考\n\n * [http://www.sans.org/reading-room/whitepapers/forensics/forensic-analysis-ios-devices-34092](http://www.sans.org/reading-room/whitepapers/forensics/forensic-analysis-ios-devices-34092)\n\n#### CWE/OWASP \n\n * [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4)\n * [CWE 200](http://cwe.mitre.org/data/definitions/200.html)\n\n### 3.7 本地会话超时机制\n\n#### 详细描述 \n\n移动设备经常丢失或被盗，攻击者可以利用活动的会话来访问敏感数据，执行事务或在设备所有者的帐户上执行侦察。 此外，如果没有适当的会话超时，应用可能容易受到中间人攻击的数据拦截。\n\n#### 建议\n\n任何时间应用程序不使用超过5分钟，终止活动会话，将用户重定向到登录屏幕，确保没有应用程序数据可见，并要求用户重新输入登录凭据以访问 应用程序。\n\n超时后，还要丢弃和清除与用户数据相关联的所有内存，包括用于解密数据的任何主密钥\n\n此外，确保客户端和服务器端都发生会话超时，以减轻攻击者修改本地超时机制。\n\n#### CWE/OWASP \n\n * OWASP Mobile Top 10: [M9 - Improper Session Handling](https://www.owasp.org/index.php/Mobile_Top_10_2014-M9)\n * CWE: [CWE-613 - Insufficient Session Expiration](http://cwe.mitre.org/data/definitions/613.html)\n\n\n### 3.8 使用增强/双因素身份验证\n\n#### 详细描述 \n\n弱或不存在的身份验证可以授予攻击者对应用程序的未经授权的访问权限。\n\n#### 建议\n\n密码不应该是简单的。 最好要求（如果不是至少支持）复杂密码，包括至少六个字母数字字符的长度（更多字符总是更强）。 作为登录过程的一部分，要求选择一个秘密词或图标（不是用户自己创建的）可以帮助保护用户的帐户，以防他们重复使用密码，并防止密码被从其他数据猜出。\n\n在某些情况下，用户名和密码不能为移动应用程序提供足够的安全性。 当涉及敏感数据或事务时，实施双因素身份验证。 在用户每次登录时都进行二次身份验证可能不大合适，但可以按时间间隔或在访问所选功能时使用。 可以考虑逐步认证方法以提供对非事务性区域的正常访问，但需要针对敏感功能进行第二层认证。\n\n增强认证的选项包括：\n\n* 附加秘密词/图标\n* 通过短信或电子邮件提供的附加代码 - 但请注意，攻击者可能会在被盗设备上访问这两者\n* 密码加上其他用户已知的值，例如用户选择的个人因素\n* 安全问题和答案，由用户预先选择（例如在注册期间）\n\n对于最高级别的安全性，使用一次性密码，要求用户不仅拥有正确的凭据，而且还要包括一次性密码的物理令牌。\n\n#### CWE/OWASP \n\n * OWASP Mobile Top 10: [M5 - Poor Authorization and Authentication](https://www.owasp.org/index.php/Mobile_Top_10_2014-M5)\n * CWE: [CWE-308: Use of Single-factor Authentication](http://cwe.mitre.org/data/definitions/308.html)\n\n\n### 3.9 保护应用程序设置\n\n#### 详细描述 \n\niOS开发人员经常将应用程序设置存储在plist文件中，在某些情况下可能会受到损害。 类似地，Android开发人员通常将设置存储在共享首选项XML文件或SQLite数据库中，这些数据库在默认情况下未加密，可以使用root权限读取或甚至修改，或使用备份。\n\n#### 建议\n\n尽可能将设置编译为代码。 通过plist文件在iOS上配置应用程序没有什么好处，因为更改必须绑定并部署为新的应用程序。 相反，如果将配置包含在应用程序代码中，攻击者需要更多的时间和技能才能修改。 除非先加密不要在字典或其他文件中存储任何关键设置。 理想情况下，使用由用户提供的密码加密的主密钥或用户登录系统时远程提供的密钥加密所有配置文件。\n\n#### CWE/OWASP\n\n * [M2 - Insecure Data Storage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M2), [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4)\n * [CWE 312](http://cwe.mitre.org/data/definitions/312.html), [313](http://cwe.mitre.org/data/definitions/313.html)\n\n\n### 3.10 隐藏帐号并使用令牌\n\n#### 详细信息 \n\n许多app在各种UI显示中存储完整的帐号。\n\n#### 建议\n\n鉴于移动应用在公共场所的广泛使用，显示部分号码（例如***9881）可以帮助确保此信息的最大隐私。 除非需要在设备上存储完整的数字，否则存储部分隐藏的数字。 通常，帐号用于查询服务器端帐户数据; 该数据可以容易地从存储器中被盗取，或者在某些情况下被操纵以处理用户不应该具有访问权限的帐户。 #### 建议将令牌(token)分配给每个帐户，并提供给客户端，而不是帐号。 这些令牌（不应由用户推断）具有到实际帐户的服务器端映射。 如果应用程序数据被盗，用户的帐号不会被暴露，攻击者必须首先确定映射回帐户的令牌，而不能直接查询帐号。\n\n在iOS中，如果你意识到\n\n```\n> - (BOOL)textField:(UITextField *)textField \n\n> shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string\n```\n\n作为文本字段的委托的一部分，您可以更改输入文本的可见性。\n\n \n\n### 3.11 使用安全的网络传输方法传输敏感数据\n\n#### 详细描述 \n\n与网络浏览器不同，移动设备通常不会公开应用程序是否使用SSL / TLS来保护数据传输，因此应用程序用户只能相信应用程序的开发人员已实施网络加密。\n\n多年来，SSL（后继者是TLS）一直是Web通信加密的标准，包括为移动应用程序提供支持的Web服务。 然而，违反认证机构如DigiNotar和Comodo暴露了许多用户伪造证书。 苹果 “[goto fail](https://avandeursen.com/2014/02/22/gotofail-security/)” 错误进一步暴露了SSL / TLS的可靠性依赖于应用程序开发人员。\n\n今天，最佳实践要求应用提供商有效地使用SSL / TLS来保护通过网络传输密码，登录ID和其他敏感数据，甚至进一步利用应用层加密来保护用户数据。\n\n#### 建议\n\n使用SSL / TLS与标准信任验证，或为了增加安全性，实施证书锁定(#### 参考  OWASP “[Pinning Cheat Sheet](https://www.owasp.org/index.php/Pinning_Cheat_Sheet)”).\n\n为了防止通过受损的SSL / TLS连接拦截高度敏感的值（例如登录ID，密码，PIN，帐号等），请在传输过程中增加额外的加密。 使用密钥大小256为AES（也称为Rijndael）加密高度敏感的值。而对于hash，请使用诸如SHA-256或更高版本的算法。\n\n在服务器端，请考虑仅接受强TLS密码和密钥，并禁用较低级别的加密，例如导出级40位加密\n\n#### CWE/OWASP \n\n * OWASP Mobile Top 10: [M3- Insufficient Transport Layer Protection](https://www.owasp.org/index.php/Mobile_Top_10_2014-M3)\n * CWE: [CWE-311 - Missing Encryption of Sensitive Data](http://cwe.mitre.org/data/definitions/311.html), [CWE-319 - Cleartext Transmission of Sensitive Information](http://cwe.mitre.org/data/definitions/319.html)\n\n### 3.12 验证来自客户端的输入\n\n#### 详细描述 \n\n即使数据是从您的应用程序生成的，这些数据也可能被拦截和操纵。 这可能包括导致应用程序崩溃（生成关键崩溃日志），缓冲区溢出，SQL注入和其他攻击的攻击。 通过实现UITextFieldDelegate中的方法并利用上面的#### 建议，这可以很容易地在iOS中执行。\n \n#### 建议\n\n与正确的Web应用程序安全性一样，客户端的所有输入都必须被视为不受信任。 服务必须彻底过滤和验证应用程序和用户的输入。 适当的清理包括在发送之前和接收期间的所有用户输入。\n\n#### References \n\n - iOS\n\t[https://developer.apple.com/library/ios/documentation/uikit/reference/UITextFieldDelegate_Protocol/UITextFieldDelegate/UITextFieldDelegate.html](https://developer.apple.com/library/ios/documentation/uikit/reference/UITextFieldDelegate_Protocol/UITextFieldDelegate/UITextFieldDelegate.html)\t\n - Android - Content Provider Injection Case of Study - \n\t[https://viaforensics.com/mobile-security/ebay-android-content-provider-injection-vulnerability.html](https://viaforensics.com/mobile-security/ebay-android-content-provider-injection-vulnerability.html)\n\t\n#### CWE/OWASP\n\n - [M8 - Security Decisions via Untrusted Inputs](https://www.owasp.org/index.php/Mobile_Top_10_2014-M8)\n - [CWE 79](http://cwe.mitre.org/data/definitions/79.html), [89](http://cwe.mitre.org/data/definitions/89.html), [120](http://cwe.mitre.org/data/definitions/120.html)\n\n### 3.13 避免将应用程序数据存储在备份中\n\n#### 详细描述 \n\n在Android或iOS设备上执行数据备份还可以备份存储在应用程序的私人目录中的敏感信息。\n\n#### 建议\n\n#### Android\n\n默认情况下，Android应用程序的Manifest文件中的`allowBackup`的值为`true`。 这将产生一个Android备份文件（backup.ab），包括设备文件系统上的应用程序私有目录中包含的所有子目录和文件。 因此，显式声明`allowBackup`标志为`false`。\n\n#### iOS\n\n在对安装了特定应用程序的设备执行iTunes备份时，备份将包括设备文件系统上包含在该应用程序的私人目录中的所有子目录（“Caches”子目录除外）和文件。 因此，请避免将任何敏感数据以明文存储在应用程序的私有目录或子目录中的任何文件或文件夹中。\n\n#### CWE/OWASP \n\n - OWASP Mobile Top 10: [M2 - Insecure Data Storage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M2), [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4)\n - CWE: [CWE-538 - File and Directory Information Exposure](http://cwe.mitre.org/data/definitions/538.html)\n\n## 4 缓存与日志\n### 4.1 避免缓存应用程序数据\n\n#### 详细描述 \n\n数据可以在很多地方被捕获，尽管许多是无意的。 开发人员经常忽略一些可以存储数据的方式，包括日志/调试文件，cookie，网络历史记录，网页缓存，属性列表，文件和SQLite数据库。 在移动设备上安全地存储数据需要适当的技术。 只要有可能***“简单地不要存储或缓存数据”*** 是避免数据在设备上被获取最直接的方式。\n\n#### 建议\n\n阻止HTTP高速缓存。 开发人员可以将iOS和Android配置为不缓存网络数据，特别是HTTPS流量。 在iOS中，查看实现NSURLConnection委托并禁用newCachedResponse。 此外，我们#### 建议采取步骤，以避免缓存任何Web进程（如注册）的URL历史记录和页面数据。 HTTP缓存头在此重要，并在Web服务器上配置。 HTTP协议在响应标头中支持“no-store”指令，指示浏览器它不得存储响应或引发它的请求的任何部分。 对于Web应用程序，HTML表单输入可以使用autocomplete = off设置指示浏览器不缓存值。 应用程序启动后，可以通过对设备数据进行读取检查来验证是否已经缓存了数据。\n\n#### 参考\n\n * [http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html)\n\n\n#### CWE/OWASP\n\n * [M2 - Insecure Data Storage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M2), [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4)\n * [CWE 312](http://cwe.mitre.org/data/definitions/312.html), [313](http://cwe.mitre.org/data/definitions/313.html), [522](http://cwe.mitre.org/data/definitions/522.html), [200](http://cwe.mitre.org/data/definitions/200.html)\n\n### 4.2 避免崩溃日志\n\n#### 详细描述 \n\n有很多用于跟踪用户使用情况并收集iOS和Android的崩溃日志的framework，这些framework都是开发的有用工具，但重要的是要在开发人员的足够调试信息和攻击者的信息减少之间找到平衡。\n\n如果应用程序崩溃，生成的日志可以为攻击者提供有价值的信息。\n\n#### 建议\n\n确保已发布的应用程序构建时没有任何警告，并经过彻底测试，以避免崩溃。 这肯定总是目标，值得一提的是由于崩溃日志的价值。 考虑禁用iOS的NSAssert。 如果断言失败，此设置将导致应用程序立即崩溃。 它更加优雅地处理失败的断言比崩溃和生成崩溃日志。 此外，避免通过网络以纯文本发送崩溃日志。\n\n使用安全的开发工具，如clang-analyzer，coverity，ASAN和其他linting实用程序，以确定所有可能的操作，可以使应用程序崩溃或错误功能。\n\n此外，如果应用程序被混淆和剥离，开发人员将需要保留一个地址到符号数据库，以便在崩溃日志中恢复有意义的回溯，使攻击者的生活更加困难，因为在函数中缺乏可理解的名称。\n\n#### CWE/OWASP \n\n * [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4)\n * [CWE 215](http://cwe.mitre.org/data/definitions/215.html)\n\n### 4.3\t限制缓存用户名\n\n#### 详细描述 \n\n在iOS上，当用户启用“保存此用户ID”功能时，用户名将缓存在CredentialsManager对象中。 在运行时，用户名在任何类型的身份验证之前加载到内存中，从而允许恶意进程拦截用户名。\n\n#### 建议\n\n很难同时向用户提供保存的用户名的便利，以及避免通过不安全的存储或在运行时的潜在拦截来泄露用户名。 虽然不像密码那么敏感，但是用户名是应该保护的私人数据。 提供具有更高安全性的高速缓存用户名选项的一种潜在方法是存储掩蔽的用户名而不是实际的用户名，并且在认证中将用户名值替换为哈希值。 可以创建哈希值，包括在注册时存储的唯一设备令牌。 使用散列和设备令牌的进程的好处是，实际用户名不存储在本地或不加保护地加载到内存中，并且复制到另一个设备或在网络上使用的值将不够。 恶意用户必须发现更多信息才能成功窃取认证用户名。\n \n#### 参考\n\n * [http://resources.infosecinstitute.com/ios-application-security-part-20-local-data-storage-nsuserdefaults-coredata-sqlite-plist-files/](http://resources.infosecinstitute.com/ios-application-security-part-20-local-data-storage-nsuserdefaults-coredata-sqlite-plist-files/)\n\n#### CWE/OWASP \n\n * [M2 - Insecure Data Storage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M2); [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4)\n * [CWE 312](http://cwe.mitre.org/data/definitions/312.html), [313](http://cwe.mitre.org/data/definitions/313.html), [522](http://cwe.mitre.org/data/definitions/522.html)\n### 4.4 谨慎管理调试日志\n\n#### 详细描述 \n\n调试日志通常设计为用于检测和纠正应用程序中的缺陷。 这些日志可能泄漏敏感信息，这可能有助于攻击者创建更强大的攻击。\n\n#### 建议\n\n开发人员应考虑调试日志在生产环境中可能出现的风险。 一般来说，我们#### 建议他们在生产中禁用。\n\n通常由应用程序用于输出调试消息的Android系统日志是存储在存储器中的几千字节的循环缓冲器。 在内核崩溃的情况下，还可以从文件系统恢复调试日志。 在设备重新启动时，它被清除，但在此之前，具有READ_LOGS权限的任何Android应用程序都可以查询日志。 在最新版本的Android中，日志文件已被更仔细地隔离，并且不需要请求系统级权限。\n\n在Android中，还可以利用ProGuard或DexGuard完全删除发布版本中Log类的方法调用，从而取消对Log.d，Log.i，Log.v，Log.e方法的所有调用。\n\n在 *proguard.cfg* 中，添加以下代码段：\n\n```\n> -assumenosideeffects class android.util.Log { \n\t\t> public static *** d(...);\n\t\t> public static *** v(...);\n\t\t> public static *** i(...);\n\t\t> public static *** e(...);\n> }\n```\n\n在iOS上禁用NSLog语句将删除可能被拦截的潜在敏感信息，因为额外的好处可能会稍微提高应用程序的性能。 例如，一种方法是在生产构建中定义NSLog：\n\n```\n> #define NSLog(s,...)\n\nThis macro effectively removes all NSLog statements and replaces it with empty text at compilation time.\n\n> NSLog(@”Breakpoint here with data %@”,data.description);\n\nbecomes effectively a no-op.\n\n>\t;\n```\n\n#### CWE/OWASP \n\n - [M10 - Lack of Binary Protections](https://www.owasp.org/index.php/Mobile_Top_10_2014-M10); [M8 - Security Decisions via Untrusted Inputs](https://www.owasp.org/index.php/Mobile_Top_10_2014-M8)\n - [CWE 215](http://cwe.mitre.org/data/definitions/215.html)\n\n### 4.5 注意键盘缓存\n\n#### 详细描述 \n\niOS记录用户键入的内容，以便提供自定义自动更正和表单完成等功能，但敏感数据也可以存储。 几乎每个非数字字按照键入的顺序缓存在键盘缓存中; 缓存的内容超出了应用程序的管理权限，因此应用程序无法从缓存中删除数据。\n\n#### 建议\n\n对任何敏感信息（而不仅仅是密码字段）禁用自动更正功能。 由于键盘缓存敏感信息，它可以恢复。 对于UITextField，查看将autocorrectionType属性设置为UITextAutocorrectionTypeNo以禁用缓存。 随着SDK更新，这些设置可能会随时间而变化，以确保其得到充分研究。 添加企业策略以定期清除键盘字典。 这可以由最终用户通过简单地去设置应用程序，通用>重置>重置键盘字典。\n\nAndroid包含用户字典，用户输入的字词可以保存以供将来自动更正。 此用户字典可用于没有特殊权限的任何应用程序。 为了提高安全性，请考虑实施自定义键盘（以及可能的PIN输入），这可以禁用缓存，并提供针对恶意软件的额外保护。\n\n#### CWE/OWASP \n\n * [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4)\n * [CWE 200](http://cwe.mitre.org/data/definitions/200.html)\n \n\n### 4.6 注意复制和粘贴\n\n#### 详细描述 \n\niOS和Android都支持复制/粘贴。 敏感数据可以以明文形式存储，恢复或者可以从剪贴板修改，而不管数据的源是否最初被加密。 如果在用户复制它时它是纯文本，当其他应用程序访问剪贴板时，它将是明文。\n\n例如，它遵循严格的规则，这意味着应用程序不能读取或写入剪贴板，并且使用它的唯一方式是通过用户交互，做长按来弹出剪贴板菜单。\n\n#### 建议\n\n在适当情况下，禁用用于处理敏感数据的区域的复制/粘贴。 取消复制选项有助于避免数据暴露。 在Android上，剪贴板可以由任何应用程序访问，因此#### 建议使用经过适当配置的内容提供程序来传输复杂的敏感数据。 在iOS上，考虑用户是否需要在应用程序或系统范围内复制/粘贴数据，并选择适当类型的粘贴板。\n\n此外，值得注意的是在取得内容后清除剪贴板，以避免其他应用程序读取它们并泄漏用户正在做什么。\n\n#### CWE/OWASP \n\n * [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4)\n * [CWE 200](http://cwe.mitre.org/data/definitions/200.html)\n \n## 5 webviews\n### 5.1 防止frame劫持和点击劫持\n\n#### 详细描述 \n\nFrame劫持涉及在iFrame中传送Web / WAP站点。 这种攻击可以使“包装”站点执行点击劫持攻击。 点击劫持是一个非常真实的威胁，已被利用高信息服务（例如Facebook）窃取信息或重定向用户到攻击者控制的网站。\n\nFrame劫持的主要目的是诱骗用户点击不同的东西，他们的意图。 目标是通过链接漏洞（如跨站脚本）收集机密信息或控制受影响的计算机。 这种攻击通常采用嵌入在源代码中的脚本的形式，该脚本在用户不知道的情况下执行。 当用户单击看起来执行其他功能的按钮时，可以触发。\n\n#### 建议\n\n在iOS中防止这种做法的最好方法是不使用WebViews。 非常非常小心的使用\n\n``` \n- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script\n```\n\n[(click here for more info on the NSString Class Reference)](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/doc/c_ref/NSString).\n\n防止Frame劫持的一种机制利用客户端JavaScript。 大多数网站已经不能离开JavaScript，因此在JavaScript中实现安全措施（和禁用没有它的网站）是一个方案。 虽然客户端不是不能被篡改，但是这方案确实提高了攻击者的标准。 下面是一个JavaScript代码示例，它强制网站到“顶部”框架，从而“破坏”已加载网站的框架。\n\n攻击者可以添加一些额外的代码来防止Frame劫持被破坏，例如在Frame unload时提醒用户不要退出。 更复杂的JavaScript可能能够对抗这样的技术。 但是包含Frame劫持破坏代码使得简单的Frame劫持变得困难。\n\n**X-FRAME-OPTIONS HEADER**– 最近在一些浏览器中基于响应中的HTTP头实现了一种新的更好的反frame 劫持方案。 通过在Webserver级别配置此HTTP头，指示浏览器不在Frame或iFrame中显示响应内容。在代码示例中提供了Apache配置文件中的示例实现。\n\n专门为WebView设计的API可能被滥用来危害WebView中指定的Web内容的安全性。 保护应用程序及其用户免受这个众所周知的漏洞的最佳方法是：\n\n * 防止X-Frame-Option HTTP响应头加载请求其他域名托管的内容的框架。 但是，这种方案不适用于处理受影响的主机。\n \n * 利用内部防御机制，确保所有UI元素在顶层框架中加载; 这样就避免了在较低的层次，通过不信任的Frame展示内容。\n \n#### 参考 \n\n * [https://developer.mozilla.org/en/The_X-FRAME-OPTIONS_response_header](https://developer.mozilla.org/en/The_X-FRAME-OPTIONS_response_header)\n\n基本Frame破解javascript：\n\n```javascript\nif( self != top ) { \n  top.location = self.location ;\n}\n```\n\n服务器端Apache配置文件的反iframe方案：\n\n```\nHeader add X-FRAME-OPTIONS \"DENY\"\n```\n另一个选项是将此值设置为“SAMEORIGIN”，它将只允许来自相同域的Frame。 此标题已在各种浏览器上测试，包括iOS 4上的Safari，并确认可防止在iFrame中显示页面。 如果在iFrame中没有传送要求，#### 建议使用DENY。\n\n#### CWE/OWASP\n\n * [M1 - Weak Server Side Controls](https://www.owasp.org/index.php/Mobile_Top_10_2014-M1)\n * [CWE 20](http://cwe.mitre.org/data/definitions/20.html)\n### 5.2 使用表单令牌保护CSRF\n\n#### 详细描述 \n\nCSRF (Cross-site Request Forgery) 依赖于已知或可预测的表单值和登录的浏览器会话。\n\n#### 建议\n\n每个表单提交应包含一个令牌，该令牌在表单中或在用户会话的开头载入。 在接收POST请求时，在服务器上检查此令牌，以确保是用户启动它。 此功能已经被主流Web平台提供，仅需要少量定制表单开发。\n\n#### 参考 \n\n * [http://op-co.de/blog/posts/android_ssl_downgrade/](http://op-co.de/blog/posts/android_ssl_downgrade/)\n\n#### CWE/OWASP\n\n * [M1 - Weak Server Side Controls](https://www.owasp.org/index.php/Mobile_Top_10_2014-M1)\n * [CWE 325](http://cwe.mitre.org/data/definitions/325.html)\n\n\n## 6 IOS\n### 6.1 谨慎使用keychain\n\n#### 详细描述 \n\niOS提供了安全数据存储的钥匙串。 然而，在几种情况下，钥匙串可能被泄密并随后被解密。\n\n在iOS的所有版本，包括iOS 7，如果攻击者可以访问加密的iTunes备份，钥匙串可能部分破解。 由于iOS在创建iTunes备份时重新加密钥匙串条目的机制，所以当iTunes备份可用且备份加密的密码已知时，钥匙串可以被部分解密。 但是，未加密的iTunes备份不允许解密钥匙串项。\n\n如果越狱已应用于设备，则钥匙串访问控制将无效。 在越狱的情况下，在设备上运行的任何应用程序都可能读取每个其他应用程序的钥匙串项目。\n\n最后，对于存在BootROM漏洞的旧设备（例如，iPhone 4），该钥匙串可能被具有对该设备的物理访问的攻击者获取。\n#### 建议\n\n当在钥匙串中存储数据时，使用最严格的保护类（由`kSecAttrAccessible`属性定义）仍然允许您的应用程序正常工作。 例如，如果您的应用程序不是设计为在后台运行，请使用`kSecAttrAccessibleWhenUnlocked`或`kSecAttrAccessibleWhenUnlockedThisDeviceOnly`。\n\n要防止通过iTunes备份暴露钥匙串项目，请在实用的情况下使用ThisDeviceOnly 选项。\n\n最后，对于高度敏感的数据，考虑使用应用程序级加密来增强钥匙串提供的保护。 例如，依靠用户输入密码在应用程序内进行认证，然后使用该密码在将数据存储到密钥链之前对数据进行加密。\n\n#### 参考\n \n * [Keychain Services Programming Guide][1]\n\t\n#### CWE/OWASP\n\n * [M2 - Insecure Data Storage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M2); [M5 - Poor Authorization and Authentication](https://www.owasp.org/index.php/Mobile_Top_10_2014-M5)\n * [CWE-312: Cleartext Storage of Sensitive Information](http://cwe.mitre.org/data/definitions/312.html)\n * [CWE-522: Insufficiently Protected Credentials](http://cwe.mitre.org/data/definitions/522.html)\n\n<!-- Links -->\n[1]: https://developer.apple.com/library/ios/documentation/security/Conceptual/keychainServConcepts/01introduction/introduction.html#//apple_ref/doc/uid/TP30000897_\n\n### 6.2 避免缓存应用程序快照\n\n#### 详细描述 \n\n为了提供界面中的视觉过渡，iOS会将屏幕截图作为图像存储在设备NAND闪存的文件系统部分中。 当应用程序暂停（而不是终止）时，当按下Home按钮或电话呼叫或其他事件暂时挂起应用程序时，会发生这种情况。 这些图像通常可以包含用户和应用程序数据。 在一个已发布的案例中，它们包含用户的全名，DOB，地址，雇主和信用评分。\n\n#### 建议\n\n要保护敏感数据，请使用API配置或代码阻止应用程序快照的缓存。\n\n当applicationDidEnterBackground：方法运行结束时，iOS将采用应用程序用户界面的快照，并且它用于转换动画并存储在文件系统中。 应该重载此方法，并且在返回之前应删除用户界面中的所有敏感信息。 这样快照就不会包含它们。\n\n#### 参考\n\n * [Managing Your Applications Flow][1]\n \n#### CWE/OWASP \n\n * [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4); [M2 - Insecure Data Storage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M2)\n * [CWE 200](http://cwe.mitre.org/data/definitions/200.html)\n \n<!-- Links -->\n[1]: https://developer.apple.com/library/iOS/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW47\n\n### 6.3 保护针对缓冲区溢出的攻击\n\n#### 详细描述 \n\n这个最佳实践涵盖了三个iOS代码实现，帮助开发人员减轻缓冲区溢出攻击他们的应用程序的风险：自动引用计数（ARC），地址空间布局随机化（ASLR）和堆栈崩溃保护。\n\n#### 自动引用计数（ARC）\n\n自动引用计数（ARC）是一种内存管理系统，在编译时自动处理对象的引用计数，而不是将此任务留给开发人员。 此功能是与iOS 5一起引入的，但它可以反向运行到以前的版本，因为操作是在编译时执行的。\n\n* 编译器将自动插入释放和保留调用，使开发人员的生活更轻松，并降低引入与对象的内存生命周期相关的漏洞的风险。\n* 因为该过程在编译时发生，所以它不引入任何运行时开销，例如与垃圾收集器不同。 因此，切换到ARC没有明显的缺点。\n\n\n#### 地址空间布局随机化（ASLR）\n\nASLR（地址空间布局随机化）是iOS 4.3中引入的一种安全功能，它随机化应用在内存中的加载和维护。 ASLR对应用程序中使用的地址空间进行随机化，使得在没有首先导致应用程序崩溃的情况下执行恶意代码变得很困难。 它还使转储分配的应用程序的内存的过程变得复杂。 此测试检查应用程序二进制文件是否使用-PIE（位置无关可执行文件）标志进行编译。\n\n#### 堆栈崩溃保护\n\n当应用程序使用堆栈崩溃保护编译时，已知的值或“canary”被放置在堆栈上直接在局部变量之前，以保护保存的基指针，保存的指令指针和函数参数。 在函数返回时检查\"canary\"的值，以查看它是否已被覆盖。 编译器使用启发式方法来智能地将堆栈崩溃保护应用于函数（通常是使用字符数组的函数）。\n\n#### 建议\n\n**启用 ARC** - 在Xcode项目中启用ARC，或者使用Xcode中的重构工具将现有项目迁移到ARC。\n\n**ASLR** - 编译支持PIE的应用程序。 当通过命令行使用选项`-PIE`（在iOS 4.3或更高版本）上编译时，可以启用PIE。\n\n**堆栈崩溃保护** - 使用`-fstack-protector-all`编译器标志编译应用程序，以保护应用程序免受缓冲区溢出攻击。\n\n#### 参考\n\n  * [Transitioning to ARC Release Notes](https://developer.apple.com/library/content/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html) - https://developer.apple.com/library/content/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html\n\n  * [Address Space Layout Randomization](https://developer.apple.com/library/prerelease/content/documentation/Security/Conceptual/SecureCodingGuide/Articles/BufferOverflows.html#//apple_ref/doc/uid/TP40002577-SW22) - https://developer.apple.com/library/prerelease/content/documentation/Security/Conceptual/SecureCodingGuide/Articles/BufferOverflows.html#//apple_ref/doc/uid/TP40002577-SW22\n\n  * [Other Compiler Flags That Affect Security](https://developer.apple.com/library/content/documentation/Security/Conceptual/SecureCodingGuide/Articles/BufferOverflows.html#//apple_ref/doc/uid/TP40002577-SW26) - https://developer.apple.com/library/content/documentation/Security/Conceptual/SecureCodingGuide/Articles/BufferOverflows.html#//apple_ref/doc/uid/TP40002577-SW26 \n\n#### CWE/OWASP\n\n  * OWASP Mobile Top 10: [M10 - Lack of Binary Protections](https://www.owasp.org/index.php/Mobile_Top_10_2014-M10)\n  * CWE: [CWE-121 - Stack-based Buffer Overflow](https://cwe.mitre.org/data/definitions/121.html), [CWE-200 - Information Exposure](http://cwe.mitre.org/data/definitions/200.html)\n\n### 6.4 避免缓存HTTP（S）请求/响应\n\n#### 详细描述 \n\n默认情况下，iOS的`NSURLRequest`将响应缓存在Cache.db文件中。 为了防止这种不安全的行为，开发人员必须明确禁用缓存。\n\n#### 建议\n\n开发人员可以设置`NSURLRequest`的`cachePolicy`属性来禁用HTTP（S）请求和响应的缓存。 禁用缓存的许多方法之一如下面的代码片段所示 (从Stack Overflow转载 [NSURLConnection Delegate Returns Null](http://stackoverflow.com/questions/30667340/nsurlconnection-delegate-returns-null) :\n\n```   \n (NSCachedURLResponse)connection:(NSURLConnection)connection\n\t\t\twillCacheResponse:(NSCachedURLResponse *)cachedResponse {\n\t\treturn nil;\n\t\t}\n```\n\n开发人员还可以在下面引用的Apple Developer文章“Understanding cache access”中找到禁用缓存HTTP（S）请求和响应的其他方法。\n\n#### 参考\n\n * [Understanding cache access](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/URLLoadingSystem/Concepts/CachePolicies.html) - https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/URLLoadingSystem/Concepts/CachePolicies.html\n \n#### CWE/OWASP \n\n * OWASP Mobile Top 10: [M2 - Insecure Data Storage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M2), [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4)\n * CWE: [CWE-312 - Cleartext Storage of Sensitive Information](http://cwe.mitre.org/data/definitions/312.html), [CWE-313 - Cleartext Storage in a File or on Disk](http://cwe.mitre.org/data/definitions/313.html), [CWE-522 - Insufficiently Protected Credentials](http://cwe.mitre.org/data/definitions/522.html)\n\n### 6.5 应用ATS(App Transport Security)\n\n#### 详细描述 \n\niOS 9中的新功能，ATS(App Transport Security)有助于确保应用程序和任何后端服务器之间的安全连接。 默认情况下，当应用程序与iOS 9.0 SDK或更高版本链接时，它会启用。 启用ATS后，HTTP连接将强制使用HTTPS（TLS v1.2），并且使用不安全HTTP连接的任何尝试都将失败。\n\n应用ATS包括几个方案：\n\n* 开发人员可以 *启用* 全局ATS（通过链接到iOS 9.0或更高版本的SDK），然后选择使用例外减少特定服务器上的ATS限制\n* 开发人员可以 *禁用* 全局ATS（通过将NSAllowsArbitraryLoads键设置为YES），然后使用例外来增加特定服务器上的ATS限制\n\n#### 建议\n\n对于在iOS 9.0或更高版本上运行的应用程序，最佳做法是通过链接到iOS 9.0或更高版本的SDK来启用ATS，并且*不要*将`NSAllowsArbitraryLoads`键设置为“Yes”或“True”。 苹果目前允许开发人员为任何不能实施TLS的域设置为例外。 可以使用`NSExceptionAllowsInsecureHTTPLoads`或`NSThirdPartyExceptionAllowsInsecureHTTPLoads`键来设置例外。 重要的是要注意，从2017年1月开始，苹果将要求开发人员对应用程序中声明的任何异常（在App Store审核期间）提供合理的理由。 否则，所有通信必须使用ATS。\n#### 参考\n\n * [App Transport Security REQUIRED January 2017](https://forums.developer.apple.com/thread/48979)\n * [Getting Ready for ATS Enforcement in 2017](https://nabla-c0d3.github.io/blog/2016/08/14/ats-enforced-2017/)\n * [Android buckles down and iOS opens up? Trends in platform security affecting developers](https://www.nowsecure.com/blog/2016/08/24/android-buckles-ios-opens-trends-platform-security-affecting-developers/)\n * [iOS 10 Security Changes Slide Deck](https://nabla-c0d3.github.io/blog/2016/09/19/ios10-slide-deck/)\n * [As of December, 2016, only 20 percent of apps enable ATS](https://www.nowsecure.com/blog/2016/12/29/enable-ios-app-transport-security-ats/)\n \n#### CWE/OWASP \n\n * OWASP Mobile Top 10: [M3 - Insufficient Transport Layer Protection](https://www.owasp.org/index.php/Mobile_Top_10_2014-M3)\n * CWE: [CWE-319 - Cleartext Transmission of Sensitive Information](http://cwe.mitre.org/data/definitions/319.html)\n\n### 6.6 正确应用Touch ID\n\n#### 详细描述 \n\nTouch ID通常被用来允许用户在不输入密码的情况下对其设备进行认证和解锁。 一些开发人员还使用Touch ID，允许用户使用存储的设备指纹对其应用进行身份验证。\n\n当开发人员在其应用中应用Touch ID时，通常会采用以下两种方式之一：\n\n1. 仅使用本地认证框架来认证用户\n  1. 这种方法使认证机制很容易被绕过\n  2. 攻击者可以在运行时修改本地检查，或者通过修补二进制。 这可以通过覆盖`LAContextevaluatePolicy：localizedReason：reply`方法来实现\n2. 使用钥匙串访问控制列表（ACL）\n\n#### 建议\n\n当使用Touch ID进行身份验证时，将应用程序的密钥存储在钥匙串中，并将ACL分配给该项目。 使用此方法，iOS将在读取和将Keychain项目返回到应用程序之前执行用户存在检查。 开发人员可以在Apple网站上找到示例代码： [https://developer.apple.com/library/ios/samplecode/KeychainTouchID/Listings/KeychainTouchID_AAPLKeychainTestsViewController_m.html](https://developer.apple.com/library/ios/samplecode/KeychainTouchID/Listings/KeychainTouchID_AAPLKeychainTestsViewController_m.html).\n\n#### 参考\n\n * [KeychainTouchID: Using Touch ID with Keychain and LocalAuthentication](https://developer.apple.com/library/content/samplecode/KeychainTouchID/Introduction/Intro.html) - https://developer.apple.com/library/content/samplecode/KeychainTouchID/Introduction/Intro.html\n \n#### CWE/OWASP \n\n * OWASP Mobile Top 10: [M5 - Poor Authorization and Authentication](https://www.owasp.org/index.php/Mobile_Top_10_2014-M5)\n * CWE: [CWE-288 - Authentication Bypass Using an Alternate Path or Channel](http://cwe.mitre.org/data/definitions/288.html)\n\n## 7 Android\n### 7.1 谨慎配置 File Permissions\n\n#### 详细描述\n\n所有人可读的文件可以作为程序的一个向量，泄漏敏感信息。 所有人可写文件可能会暴露您的应用程序，让攻击者通过覆盖您的应用从存储读取的数据影响其行为。 示例包括设置文件和存储的登录信息。\n\n#### 建议\n\n不要创建具有MODE_WORLD_READABLE或MODE_WORLD_WRITABLE权限的文件，除非它是必需的，因为任何应用程序都能读取或写入该文件，即使它可能存储在应用程序的私人数据目录中。\n\n_注意: 这些常量在Android API级别17中已弃用。#### 参考: [http://developer.android.com/reference/android/content/Context.html](http://developer.android.com/reference/android/content/Context.html)_\n\n不要使用chmod二进制或系统调用接受文件模式（chmod，fchmod，creat等）的模式，例如0666,0777和0664，\n\n#### CWE/OWASP\n\n * [M2 - Insecure Data Storage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M2)\n * [CWE 280](http://cwe.mitre.org/data/definitions/280.html)\n### 7.2 谨慎实现 Intents\n\n#### 详细描述 \n\nIntents用于组件间信令，而且可以被用来做以下事情：\n\n * *启动Activity，通常为应用程序打开用户界面*\n * *作为广播以通知系统和应用程序的变化*\n * *开始，停止和与后台服务进行通信*\n * *通过ContentProvider访问数据*\n * *作为回调处理事件*\n\n不正确的实现可能导致数据泄露，受限功能被调用和程序流被操纵。\n\n#### 建议\n\n * 通过Intents访问的组件可以是公共的或私有的。 默认值取决于Intents过滤器，很容易错误地允许组件被公开。 可以在应用程序的Manifest中将组件设置为`android：exported = false`，以防止出现这种情况。\n \n * 默认情况下，在清单中声明的公共组件是开放的，所以任何应用程序都可以访问它们。 如果组件不需要被所有其他应用程序访问，请考虑设置对清单中声明的组件的权限。\n\n * 公共组件接收的数据不可信任，必须仔细检查。\n\n#### CWE/OWASP\n\n * [M8 - Security Decisions via Untrusted Inputs](https://www.owasp.org/index.php/Mobile_Top_10_2014-M8); [M10 - Lack of Binary Protections](https://www.owasp.org/index.php/Mobile_Top_10_2014-M10)\n * [CWE 927](http://cwe.mitre.org/data/definitions/316.html)\n\n### 7.3 检查 Activities\n\n通常在Android应用程序中，Activity是应用程序中的“屏幕”。\n\n#### 详细描述\n\n任何应用程序都可以调用[`exported` 和 `enabled`](http://developer.android.com/guide/topics/manifest/activity-element.html)的Activity . 这可能允许攻击者以开发者可能不想要的方式加载UI元素，例如跳过密码锁定屏幕访问数据或功能。 默认情况下，不会导出Activity，但是，如果为Activity定义了Intent过滤器，系统将导出Activity。\n\n#### 建议\n\nActivities 可以通过检查内部应用程序状态来验证它们是否可以加载来确保正确的行为。 例如，首先看看应用程序是否处于“未锁定”状态，如果没有，则跳回到锁定屏幕。 无论定义什么Intent过滤器，`exported` /`enabled`都可以直接使用未定义的数据调用Activity，因此当对不受信任的源提供的数据进行操作时，#### 建议使用输入验证。\n\n传递Intent额外ID的示例代码，而不是整个对象。\n\n```java\n//bad passing the whole paracable object\npublic static Intent getStartingIntent(Context context,\n\t\tUser user) {\n\tIntent i = new Intent(context, UserDetailsActivity.class);\n\ti.putExtra(EXTRA_USER, user);\n\treturn i;\n}\n\n//better to pass just the ID to lookup the user details\npublic static Intent getStartingIntent(Context context,\n\t\tString userId) {\n\tIntent i = new Intent(context, UserDetailsActivity.class);\n\ti.putExtra(EXTRA_USER_ID, userId);\n  return i;\n}\n```\n\nAvoid intent filters on Activities if they are private, instead use explicit intent.\n避免对私有的Activities添加intent过滤器，而是使用显式intent。\n\n```xml\n<activity\n\tandroid:name=\"com.app.YourActivity\"\n\tandroid:label=\"@string/app_name\"\n\tandroid:excludeFromRecents=\"true\"\n\tandroid:exported=\"false\" >\n</activity>\n```\n\n#### 参考\n\n * [http://commonsware.com/blog/2013/09/11/beware-accidental-apis-avoid-intents-extras.html](http://commonsware.com/blog/2013/09/11/beware-accidental-apis-avoid-intents-extras.html)\n * [http://commonsware.com/blog/2014/04/30/if-your-activity-has-intent-filter-export-it.html](http://commonsware.com/blog/2014/04/30/if-your-activity-has-intent-filter-export-it.html)\n\n#### CWE/OWASP\n\n * [M8 - Security Decisions via Untrusted Inputs](https://www.owasp.org/index.php/Mobile_Top_10_2014-M8); [M10 - Lack of Binary Protections](https://www.owasp.org/index.php/Mobile_Top_10_2014-M10)\n * [CWE-927: Use of Implicit Intent for Sensitive Communication](http://cwe.mitre.org/data/definitions/927.html)\n\n### 7.4 谨慎使用 Broadcasts\n\n#### 详细描述 \n\n如果在发送广播Intent时未设置权限，则任何非特权应用程序都可以接收Intent，除非它有明确的目标。\n\n攻击者可以通过以下方式利用没有任何设置权限的Intent：\n\n- 创建包含与合法组件具有相同名称的组件的恶意应用程序\n- 只要该名称（或命名空间）尚未使用，恶意应用程序将安装在目标设备上\n- 从发送到该组件名称的广播Intent提取敏感数据\n\n#### 建议\n\n使用权限来保护应用程序中的Intents。 请记住，当通过广播Intent向第三方组件发送信息时，该组件可能已被恶意安装替换。\n\n#### 参考 \n\n * [https://developer.android.com/training/articles/security-tips.html#Permissions](https://developer.android.com/training/articles/security-tips.html#Permissions)\n * [http://shop.oreilly.com/product/0636920022596.do](http://shop.oreilly.com/product/0636920022596.do)\n\n#### CWE/OWASP\n\n * [M8 - Security Decisions via Untrusted Inputs](https://www.owasp.org/index.php/Mobile_Top_10_2014-M8); [M10 - Lack of Binary Protections](https://www.owasp.org/index.php/Mobile_Top_10_2014-M10)\n * [CWE-925: Improper Verification of Intent by Broadcast Receiver](http://cwe.mitre.org/data/definitions/925.html)\n### 7.5 谨慎实现 PendingIntents\n\nPendingIntent允许应用程序将Intent传递给第二个应用程序，然后可以执行该Intent，就像它是原始应用程序一样（即具有相同的权限）。\n\n#### 详细描述 \n\n使用PendingIntent，应用程序可以将Intent传递给第二个应用程序，然后可以执行该Intent，就像它是原始应用程序一样（即具有相同的权限）。 这允许其他应用程序回调到原始应用程序的私有组件。 外部应用程序，如果是恶意的，可能会尝试影响目标 和/或 数据/完整性。\n\n#### 建议\n\n使用PendingIntents作为对私有BroadcastReceivers或broadcast activities的延迟回调，并在基本Intent中显式指定组件名称。\n\n#### 参考 \n\n * 示例代码 [https://gist.github.com/scottyab/d5ab6a284622ebc46d5a](https://gist.github.com/scottyab/d5ab6a284622ebc46d5a)\n\n#### CWE/OWASP\n\n * [M8 - Security Decisions via Untrusted Inputs](https://www.owasp.org/index.php/Mobile_Top_10_2014-M8); [M10 - Lack of Binary Protections](https://www.owasp.org/index.php/Mobile_Top_10_2014-M10)\n * [CWE-927: Use of Implicit Intent for Sensitive Communication](http://cwe.mitre.org/data/definitions/927.html)\n\n### 7.6 保护应用程序服务\n\n#### 详细描述 \n\n服务通常用于后台处理。 与BroadcastReceivers和应用程序 activities 一样，应用程序服务可以由外部应用程序调用，因此应该由权限和导出标志保护。\n\n#### 建议\n\n服务可以具有可以从外部调用者调用的多于一个方法。 可以为每个方法定义任意权限，并通过使用`checkPermission（）`检查调用包是否具有相应的权限。 或者，可以通过使用AndroidManifest中定义的权限来定义单独的服务和访问权限。\n\n当调用具有敏感数据的服务时，验证正在调用正确的服务，而不是恶意服务。 如果您知道要连接的组件的确切名称，请在用于连接的意图中指定该名称。 另一种方法是再次使用`checkPermission()`来验证调用包是否具有接收所需Intent所需的权限。 用户在安装期间向应用程序授予权限。\n\n下面是一个例子，声明并需要在访问`com.example.MyService.`时使用自定义权限\n\n```xml\n<permission android:name=\"com.example.mypermission\" \nandroid:label=\"my_permission\" android:protectionLevel=\"dangerous\"></permission>`\n```\n```xml\n<service\n\n\tandroid:name=\"com.example.MyService\"\n\t\n\tandroid:permission=\"com.example.mypermission\">\n\t\n\t<intent-filter>\n\t\n\t\t<action android:name=\"com.example.MY_ACTION\" />\n\t\t\n\t</intent-filter>\n\t\t\n</service>\n```\n\n#### CWE/OWASP\n\n * [M8 - Security Decisions via Untrusted Inputs](https://www.owasp.org/index.php/Mobile_Top_10_2014-M8); [M10 - Lack of Binary Protections](https://www.owasp.org/index.php/Mobile_Top_10_2014-M10)\n * [CWE-280: Improper Handling of Insufficient Permissions or Privileges](http://cwe.mitre.org/data/definitions/280.html)\n\n### 7.7 避免 Intent 嗅探\n\n当activity由另一个使用广播Intent的应用程序启动时，Intent中传递的数据可以由恶意应用程序读取。\n\n#### 详细描述 \n\n当另一个应用程序通过发送广播Intent启动activity时，恶意应用程序可以读取Intent中包含的数据。 恶意应用程序还可以读取应用程序的最近Intent列表。 例如，如果应用程序调用并传递URL到Android Web浏览器，攻击者可以嗅探该URL。\n\n#### 建议\n\n不要在使用广播Intent的应用之间传递敏感数据。 而使用显式Intent。\n\n#### CWE/OWASP\n\n * [M8 - Security Decisions via Untrusted Inputs](https://www.owasp.org/index.php/Mobile_Top_10_2014-M8); [M10 - Lack of Binary Protections](https://www.owasp.org/index.php/Mobile_Top_10_2014-M10)\n * [CWE 285: Improper Authorization](http://cwe.mitre.org/data/definitions/285.html)\n\n### 7.8 谨慎使用content providers\n\n#### 详细描述 \n\nContent providers 允许应用程序使用URI寻址方案和关系数据库模型共享数据。 它们也可以用于通过URI方案访问文件。\n\n#### 建议\n\nContent providers 可以声明权限和单独的读写访问。 除非绝对必要，否则不要给内容提供者写访问权限。 除非必需，请确保设置权限，以便非特权应用程序无法读取`ContentProvider`实例。\n\n将访问限制为操作所需的最低限度。 例如，要与向某个联系人发送该邮件的其他应用程序共享即时消息，只共享该单个邮件，而不是所有即时消息。 内容提供商中的记录级委派功能允许共享特定记录或文件，而不共享整个数据库。 一旦外部应用程序返回到原始应用程序，代表结束。\n\n将传递给内容提供者的参数视为不受信任的输入，并且不在没有防护的情况下直接在SQL查询中使用它们。 没有防护的SQL代码可以通过内容提供者请求发送。 如果SQL代码包含在查询中，它可以返回数据或向攻击者提供控制权。\n\n基于文件名传递给提供者的文件的内容提供者应该确保路径遍历被过滤掉。 例如，如果攻击者在请求中包含`../../../ file'，它可能导致程序读取并返回攻击者在其他情况下不能访问的文件中的数据。 应用程序。 此外，请注意，攻击者创建的以下符号链接可能具有类似的结果。\n\n#### CWE/OWASP\n\n * [M7 - Client Side Injection](https://www.owasp.org/index.php/Mobile_Top_10_2014-M7)\n * [CWE 926: Improper Export of Android Application Components](http://cwe.mitre.org/data/definitions/926.html)\n\n### 7.9 遵循WebView最佳实践\n\n#### 详细描述 \n\nWebView可以引入一些安全问题，应该小心地使用。 目前已经发现了使用addJavscriptInterface API所产生的许多可利用的漏洞。\n\n#### 建议\n\n如果不需要JavaScript和Plugin支持，请禁用。 虽然默认情况下都禁用它们，但最佳做法需要明确将其设置为禁用。 禁用本地文件访问。 这限制了对应用程序的资源和资产目录的访问，并减轻了来自网页的攻击，该网页试图获得对其他本地可访问文件的访问。\n\n禁止从第三方主机加载内容。 这可能很难在应用程序内实现。 但是，开发人员可以覆盖shouldOverrideUrlLoading和shouldInterceptRequest来拦截，检查和验证从WebView中发起的大多数请求。 开发者还可以考虑通过使用URI类来检查URI的组件以确保其匹配已批准资源的列表中的条目来实现白名单方案。\n\n示例代码 [https://gist.github.com/scottyab/6f51bbd82a0ffb08ac7a](https://gist.github.com/scottyab/6f51bbd82a0ffb08ac7a)\n\n#### 参考 \n\n * [http://labs.mwrinfosecurity.com/blog/2012/04/23/adventures-with-android-webviews/](http://labs.mwrinfosecurity.com/blog/2012/04/23/adventures-with-android-webviews/)\n * [https://developer.android.com/training/articles/security-tips.html#WebView](https://developer.android.com/training/articles/security-tips.html#WebView)\n \n#### CWE/OWASP\n\n * [M10 - Lack of Binary Protections](https://www.owasp.org/index.php/Mobile_Top_10_2014-M10)\n * [CWE-79: Improper Neutralization of Input During Web Page Generation (Cross-site Scripting)](http://cwe.mitre.org/data/definitions/79.html)\n\n\n### 7.10 避免存储缓存的摄像机图像\n\n远程支票存款应用程序允许一个人用手机的相机拍摄支票的图片，然后将图像发送到他们的金融机构存入他们的帐户。\n\n#### 详细描述 \n\n使用远程支票存款应用程序，一个人可以用手机的相机拍照支票，然后将图像发送到他们的金融机构存入他们的帐户。 许多这些应用程序将保留检查图像（或其一部分）在移动设备的NAND内存中，即使它被删除。\n\n#### 建议\n\n不要在设备上使用非易失性存储器传输支票图像，支票图像可能会残留。 一个可能的替代方案是：\n\n1. 创建一个SurfaceView，显示相机预览或实时预览相机传感器所看到的内容\n2. 插入并编程一个按钮，当按下时，将相机预览作为像素阵列返回\n3. 最后，将像素阵列转换为位图，将其压缩为.jpg，将其编码为Base64，并将其提交到远程位置\n\n此方法将只维护易失性内存中的图像，并防止支票图像在非易失性存储器中的缓存。\n\n特别是使用Android Camera类，可以使用方法takePicture指定当使用`Camera.PictureCallback`接口生成.jpg时的回调。 特别是，我们对方法“public void onPictureTaken（byte [] bytes，Camera camera）感兴趣。\n\n使用这种技术，可以使用“bytes”数组内容，其中包含RAM中的照片。\n \n#### CWE/OWASP\n\n * [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4)\n * [CWE 200: Information Exposure](http://cwe.mitre.org/data/definitions/200.html)\n\n### 7.11 避免GUI对象缓存\n\n远程支票存款应用程序允许人们使用他们的设备拍摄支票的照片，并将其发送到其金融机构以存入帐户。\n\n#### 详细描述 \n\nAndroid将应用程序屏幕保留在内存中，并且多任务可以导致将整个应用程序保留在内存中（即使用户注销其帐户）。 这允许发现或窃取设备的攻击者直接导航到保留的屏幕，其可以包括作为GUI的一部分的敏感用户数据。 例如，如果用户退出银行应用，但不退出或关闭应用，则可以保留显示交易活动的屏幕，并且攻击者可以看到该屏幕。\n\n#### 建议\n\n为了解决这个问题，开发人员有三个常见的选择：\n\n1. 当用户注销时，完全退出应用程序。 虽然违反Android设计原则退出您自己的应用程序，它是更安全，因为退出应用程序将销毁任何保留的GUI屏幕。\n\n2. 任何时间启动活动或访问屏幕时，请执行检查以确定用户是否处于已登录状态。 如果用户未登录，则显示登录屏幕。\n\n3. 在离开屏幕或注销之前，在GUI屏幕上清除数据。\n\n#### CWE/OWASP\n\n * [M4 - Unintended Data Leakage](https://www.owasp.org/index.php/Mobile_Top_10_2014-M4)\n * [CWE 200: Information Exposure](http://cwe.mitre.org/data/definitions/200.html)\n\n\n### 7.12 签名 Android APKs\n\n#### 详细描述 \n\nAPK应使用未过期的证书正确签名。\n\n#### 建议\n\n- 使用生产证书（而不是调试证书）签署生产应用程序\n- 确保证书包含足够的有效期（即，不会在应用的预期有效期内过期）\n- Google#### 建议您的证书至少使用2048位加密\n- 确保包含签名密钥的密钥库被正确保护\n- 此外，将密钥库的访问权限限制为只有那些绝对需要它的人\n\n下面是一个生成私钥的Keytool命令的示例：\n\n```\n$ keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000\n```\n\n#### 参考\n\n * [https://developer.android.com/tools/publishing/app-signing.html#cert](https://developer.android.com/tools/publishing/app-signing.html#cert)\n\n#### CWE/OWASP\n\n * [M6 - Broken Cryptography](https://www.owasp.org/index.php/Mobile_Top_10_2014-M6)\n * [CWE-310: Cryptographic Issues](http://cwe.mitre.org/data/definitions/310.html)\n * [CWE-326: Inadequate Encryption Strength](http://cwe.mitre.org/data/definitions/326.html)\n \n \n\n## 8 Servers\n### 8.1 实施正确的Web服务器配置\n\n#### 详细描述 \n\nWeb服务器上的某些设置可以提高安全性。 Web服务器上通常被忽视的漏洞是信息泄露。 信息泄露可能导致严重的问题，因为每一个信息攻击者都可以从服务器获得使攻击更容易。\n\n#### 建议\n\n减少信息泄露的一种简单方法是禁用详细错误。 详细错误在开发环境中很有用，但在生产环境中可能会泄露关键信息，例如Web框架信息和版本。 攻击者可以使用此信息来定位旨在利用实施特定缺陷的攻击。\n\n减少信息泄露的另一个简单方法是返回服务器响应中的最少量的信息。 默认情况下，Apache将返回其版本号，运行它的操作系统和插件运行。 通过更改配置文件中的单个行，可以减少到只公开服务器正在运行Apache而不影响功能。\n\n可以大大提高安全性的服务器中的一个配置更改是更改任何默认目录。 攻击者经常在Internet上搜索具有“low-hanging fruit”的网站，例如默认登录，容易猜到的管理界面，以及简单的“隐藏”目录命名方案。 这是一个好的策略，模糊处理需要网络访问的服务器上的任何敏感网页的位置。\n\n管理或其他限制区域不应公开网络访问，除非绝对必要，并且必须抵抗暴力攻击。 HTTP认证或没有锁定保护的表单认证可以（并且将）被暴力攻击。\n \n#### CWE/OWASP\n\n * [M1 - Weak Server Side Controls](https://www.owasp.org/index.php/Mobile_Top_10_2014-M1)\n * [CWE 203](http://cwe.mitre.org/data/definitions/203.html)\n\n\n### 8.2正确配置服务器端SSL\n\n#### 详细描述 \n\n许多Web服务器允许较低的加密设置，例如非常弱的导出级40位加密。 实施强密码套件以保护用于创建共享密钥，在客户端和服务器之间加密消息，以及生成消息哈希和签名以确保这些消息的完整性的信息。 还要确保禁用弱协议。\n\n#### 建议\n\n确保正确安装和配置SSL证书以实现最高的加密。 如果可能，仅启用强密码（128位及以上）。\n\nTLSv1已超过10年，并且在2009年被发现很容易受到“重新协商攻击”。\n\n* 大多数使用TLSv1的服务器已修补以关闭此漏洞，但您应针对相关服务器验证此漏洞。\n* TLSv1协议已更新，当前更多的TLSv1.2提供了最新的技术和最强的加密密码。 更新到较新版本的TLS应该更加坚固和面向未来的应用程序。\n\n避免使用弱cipher，例如：\n\n* NULL cipher suite\n* 匿名Diffie-Hellman\n* DES 和 RC4 (因为它们容易受到加密分析攻击)\n\n避免弱协议，例如：\n\n* SSLv2\n* SSLv3 (因为容易受到POODLE攻击 - [CVE-2014-3566](https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2014-3566))\n* TLS 1.0及以下（因为协议容易受到CRIME和BEAST攻击 - [CVE-2012-4929](http://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2012-4929) 和 [CVE-2011-3389](https://cve.mitre.org/cgi-bin/cvename.cgi?name=cve-2011-3389))\n\n如需获取有关如何安全地设计和配置应用程序的传输层安全性的更多信息。#### 参考 OWASP [Transport Layer Protection Cheat Sheet](https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet) for more information about how to securely design and configure transport layer security for an app.\n\n#### 参考 \n\n* [Why Android SSL was downgraded from AES256-SHA to RC4-MD5 in late 2010](http://op-co.de/blog/posts/android_ssl_downgrade/) - http://op-co.de/blog/posts/android_ssl_downgrade/\n\n#### CWE/OWASP\n\n * OWASP Mobile Top 10: [M1 - Weak Server Side Controls](https://www.owasp.org/index.php/Mobile_Top_10_2014-M1)\n * CWE: [CWE-326 - Inadequate Encryption Strength](http://cwe.mitre.org/data/definitions/326.html)\n\n\n### 8.3 使用合适的会话管理\n\n#### 详细描述 \n\n大多数应用程序都通过可能容易受到攻击的Cookie来维护用户的会话。\n\n#### Remediation\n\nWeb语言（例如Java，.NET）提供会话管理，这是经过良好开发和安全测试的。 使服务器软件保持最新的安全补丁。 开发您自己的会话管理更有风险，只有在适当的专业知识。 确保会话cookie的大小足够。 短的或可预测的会话cookie使攻击者可能预测，高压或对会话执行其他攻击。 在会话配置中使用高安全性设置。\n\n#### CWE/OWASP\n\n * [M9 - Improper Session Handling](https://www.owasp.org/index.php/Mobile_Top_10_2014-M9)\n * [CWE 613](http://cwe.mitre.org/data/definitions/613.html)\n\n### 8.4\t 保护和执行Web服务的渗透测试\n\n#### 详细描述 \n\n已经被攻破的服务器有可能拦截用户凭据并对应用用户发起其他攻击。\n\n#### 建议\n\n一般来说，生产Web服务器必须经过彻底测试和防御恶意攻击。 生产服务器软件应更新到最新版本，并加固以防止有关服务器软件和接口的信息泄露。\n\n身份验证表单不应反映用户名是否存在。 如果攻击者有一个方法来确定有效的用户名，他们有一个起点的暴力攻击和网络钓鱼攻击。 通过向客户端提供“无效的用户/密码组合”和“没有找到此类用户名”事件的相同响应，阻止用户名收集。 所有的交换敏感数据的登录表单和表单/页面都应该实现并需要HTTPS。 Web服务器不应允许没有SSL的客户端连接用于此类资源。 关闭详细错误，删除任何遗留的不必要的站点或页面，并持续强化Web资源以防潜在的攻击。\n\n#### 参考 \n\n\n#### CWE/OWASP\n\n * [M1 - Weak Server Side Controls](https://www.owasp.org/index.php/Mobile_Top_10_2014-M1)\n * [CWE 307](http://cwe.mitre.org/data/definitions/307.html), [200](http://cwe.mitre.org/data/definitions/200.html), etc. (could be multiple)\n### 8.5\t 保护内部资源\n\n#### 详细描述 \n\n用于内部使用的资源（例如管理员登录表单）经常使用可能被暴力破解的身份验证。 例如无锁定的HTTP或表单认证。 管理或其他内部资源的泄露可能导致广泛的数据丢失和其他损害。\n\n#### 建议\n\n这种资源应该被阻止外部访问。 任何不需要公共互联网访问的资源都应该使用防火墙规则和网络分段进行限制。 如果登录页面，管理区域或其他资源是外部可访问的，它就会被恶意用户发现和暴力攻击。\n\n#### CWE/OWASP\n\n * [M1 - Weak Server Side Controls](https://www.owasp.org/index.php/Mobile_Top_10_2014-M1)\n * [CWE 200 - Multiple CWE's](http://cwe.mitre.org/data/definitions/200.html)\n\n\n参考文档：https://github.com/nowsecure/secure-mobile-development/\n"
  },
  {
    "path": "docs/2.SDL规范文档/7-产品设计开发最佳实践.md",
    "content": "\n# 08.产品设计开发最佳实践\n\n\n作者：\n\n协作：\n\n-------\n\n未完成"
  },
  {
    "path": "docs/2.SDL规范文档/8-常见协议安全开发实践.md",
    "content": "\n# 09. 常见协议安全\n\n\n作者：I\n\n协作：\n\n-------\n\n本文档通过介绍常见开发过程中因协议配置错误或代码漏洞而导致安全的问题去避免类似现象的发生。\n常见开发过程中的协议:\n\n* HTTPS\n* WebSocket\n* JWT\n* OAuth\n* Json\n* XML\n\n### WebSocket 安全\n\n- 输入未做校验\n- 帧数大小未做限制\n- 最大连接数未做限制，既可以耗尽客户端也可以耗尽服务端\n- 持久链接过多未自动关闭\n- Origin头部未做验证\n- 未采用HTTPS\n- 访问策略未做限制，存在越权现象(授权需由服务端限制)\n\n## OAuth 安全\n\n- 回调域名需要白名单限制访问\n- OAuth Token泄露\n- Refer消息头泄露Authorization Code\n\n## JWT安全\n\n## Json, XML安全\n\n\n\n\n## 引用\n\n* [WebSocket应用安全问题分析](https://security.tencent.com/index.php/blog/msg/119)"
  },
  {
    "path": "docs/2.SDL规范文档/9-MySQL安全配置.md",
    "content": "\n# 10. MySQL安全配置\n\n作者：Jun6l3\n\n协作：\n\n---\n\n数据库作为数据管理的平台，它的安全性首先由系统的内部安全和网络安全两部分来决定。对于系统管理员来说，首先要保证系统本身的安全，在安装MySQL数据库时，需要对基础环境进行较好的配置。\n\n## 修改root用户口令，删除空口令\n\n缺省安装的MySQL的root用户是空密码的，为了安全起见，必须修改为强密码，所谓的强密码，至少8位，由字母、数字和符号组成的不规律密码。使用MySQL自带的命令mysaladmin修改root密码，同时也可以登陆数据库，修改数据库mysql下的user表的字段内容，修改方法如下所示：\n\n```shell\n# /usr/local/mysql/bin/mysqladmin -u root password “upassword” //使用mysqladmin\n#mysql> use mysql;\n#mysql> update user set password=password('upassword') where user='root';\n#mysql> flush privileges; //强制刷新内存授权表，否则用的还是在内存缓冲的口令\n```\n\n## 删除默认数据库和数据库用户\n\n一般情况下，MySQL数据库安装在本地，并且也只需要本地的php脚本对mysql进行读取，所以很多用户不需要，尤其是默认安装的用户。MySQL初始化后会自动生成空用户和test库，进行安装的测试，这会对数据库的安全构成威胁，有必要全部删除，最后的状态只保留单个root即可，当然以后根据需要增加用户和数据库。\n\n```shell\n#mysql> show databases;\n#mysql> drop database test; //删除数据库test\n#use mysql;\n#delete from db; //删除存放数据库的表信息，因为还没有数据库信息。\n#mysql> delete from user where not (user='root') ; // 删除初始非root的用户\n#mysql> delete from user where user='root' and password=''; //删除空密码的root，尽量重复操作\nQuery OK, 2 rows affected (0.00 sec)\n#mysql> flush privileges; //强制刷新内存授权表。\n```\n\n## 改变默认mysql管理员帐号\n\n系统mysql的管理员名称是root，而一般情况下，数据库管理员都没进行修改，这一定程度上对系统用户穷举的恶意行为提供了便利，此时修改为复杂的用户名，请不要在设定为admin或者administraror的形式，因为它们也在易猜的用户字典中。\n\n```shell\nmysql> update user set user=\"newroot\" where user=\"root\"; //改成不易被猜测的用户名mysql> flush privileges;\n```\n\n## 关于密码的管理\n\n密码是数据库安全管理的一个很重要因素，不要将纯文本密码保存到数据库中。如果你的计算机有安全危险，入侵者可以获得所有的密码并使用它们。相反，应使用MD5()、SHA1()或单向哈希函数。也不要从词典中选择密码，有专门的程序可以破解它们，请选用至少八位，由字母、数字和符号组成的强密码。在存取密码时，使用mysql的内置函数password（）的sql语句，对密码进行加密后存储。例如以下方式在users表中加入新用户。\n```shell\n#mysql> insert into users values (1,password(1234),'test');\n```\n\n### 使用独立用户运行msyql\n\n绝对不要作为使用root用户运行MySQL服务器。这样做非常危险，因为任何具有FILE权限的用户能够用root创建文件(例如，~root/.bashrc)。mysqld拒绝使用root运行，除非使用–user=root选项明显指定。应该用普通非特权用户运行mysqld。正如前面的安装过程一样，为数据库建立独立的linux中的mysql账户，该账户用来只用于管理和运行MySQL。\n\n要想用其它Unix用户启动mysqld，增加user选项指定`/etc/my.cnf`选项文件或服务器数据目录的`my.cnf`选项文件中的`[mysqld]`组的用户名。\n\n```shell\n#vim /etc/my.cnf\n[mysqld]\nuser=mysql\n```\n\n该命令使服务器用指定的用户来启动，无论你手动启动或通过`mysqld_safe`或`mysql.server`启动，都能确保使用mysql的身份。也可以在启动数据库是，加上user参数。\n```shell\n# /usr/local/mysql/bin/mysqld_safe --user=mysql &\n```\n\n作为其它linux用户而不用root运行mysqld，你不需要更改user表中的root用户名，因为MySQL账户的用户名与linux账户的用户名无关。确保mysqld运行时，只使用对数据库目录具有读或写权限的linux用户来运行。\n\n## 禁止远程连接数据库\n\n在命令行netstat -ant下看到，默认的3306端口是打开的，此时打开了mysqld的网络监听，允许用户远程通过帐号密码连接数本地据库，默认情况是允许远程连接数据的。为了禁止该功能，启动skip-networking，不监听sql的任何TCP/IP的连接，切断远程访问的权利，保证安全性。假如需要远程管理数据库，可通过安装PhpMyadmin来实现。假如确实需要远程连接数据库，至少修改默认的监听端口，同时添加防火墙规则，只允许可信任的网络的mysql监听端口的数据通过。\n\n```shell\n# vim /etc/my.cf\n将#skip-networking注释去掉。\n# /usr/local/mysql/bin/mysqladmin -u root -p shutdown //停止数据库\n#/usr/local/mysql/bin/mysqld_safe --user=mysql & //后台用mysql用户启动mysql\n```\n\n## 限制连接用户的数量\n\n数据库的某用户多次远程连接，会导致性能的下降和影响其他用户的操作，有必要对其进行限制。可以通过限制单个账户允许的连接数量来实现，设置`my.cnf`文件的mysqld中的`max_user_connections`变量来完成。GRANT语句也可以支持 资源控制选项来限制服务器对一个账户允许的使用范围。\n\n```shell\n#vim /etc/my.cnf\n[mysqld]\nmax_user_connections 2\n```\n\n## 用户目录权限限制\n\n默认的mysql是安装在/usr/local/mysql，而对应的数据库文件在/usr/local/mysql/var目录下，因此，必须保证该目录不能让未经授权的用户访问后把数据库打包拷贝走了，所以要限制对该目录的访问。确保mysqld运行时，只使用对数据库目录具有读或写权限的linux用户来运行。\n\n```shell\n# chown -R root  /usr/local/mysql/  //mysql主目录给root\n# chown -R mysql.mysql /usr/local/mysql/var //确保数据库目录权限所属mysql用户\n```\n\n## 命令历史记录保护\n\n数据库相关的shell操作命令都会分别记录在.bash_history，如果这些文件不慎被读取，会导致数据库密码和数据库结构等信息泄露，而登陆数据库后的操作将记录在.mysql_history文件中，如果使用update表信息来修改数据库用户密码的话，也会被读取密码，因此需要删除这两个文件，同时在进行登陆或备份数据库等与密码相关操作时，应该使用-p参数加入提示输入密码后，隐式输入密码，建议将以上文件置空。\n\n```shell\n# rm .bash_history .mysql_history  //删除历史记录\n# ln -s /dev/null .bash_history   //将shell记录文件置空\n# ln -s /dev/null .mysql_history  //将mysql记录文件置空\n```\n\n## 禁止MySQL对本地文件存取\n\n在mysql中，提供对本地文件的读取，使用的是load data local infile命令，默认在5.0版本中，该选项是默认打开的，该操作令会利用MySQL把本地文件读到数据库中，然后用户就可以非法获取敏感信息了，假如你不需要读取本地文件，请务必关闭。\n\n测试：首先在测试数据库下建立sqlfile.txt文件，用逗号隔开各个字段\n\n```shell\n# vi sqlfile.txt\n1,sszng,111\n2,sman,222\n#mysql> load data local infile 'sqlfile.txt' into table users fields terminated by ','; //读入数据\n#mysql> select * from users;\n\n+--------+------------+----------+\n| userid  | username   | password |\n+--------+------------+----------+\n|      1 | sszng       | 111      |\n|      2 | sman        | 222      |\n+--------+------------+----------+\n```\n\n成功的将本地数据插入数据中，此时应该禁止MySQL中用`“LOAD DATA LOCAL INFILE”`命令。网络上流传的一些攻击方法中就有用它`LOAD DATA LOCAL INFILE`的，同时它也是很多新发现的`SQL Injection`攻击利用的手段！黑客还能通过使用`LOAD DATALOCAL INFILE`装载`“/etc/passwd”`进一个数据库表，然后能用SELECT显示它，这个操作对服务器的安全来说，是致命的。可以在my.cnf中添加`local-infile=0`，或者加参数`local-infile=0`启动mysql。\n\n```shell\n#/usr/local/mysql/bin/mysqld_safe --user=mysql --local-infile=0 &\n#mysql> load data local infile 'sqlfile.txt' into table users fields terminated by ',';\n#ERROR 1148 (42000): The used command is not allowed with this MySQL version\n```\n\n--local-infile=0选项启动mysqld从服务器端禁用所有LOAD DATA LOCAL命令，假如需要获取本地文件，需要打开，但是建议关闭。\n\n## \nMySQL服务器权限控制\nMySQL权限系统的主要功能是证实连接到一台给定主机的用户，并且赋予该用户在数据库上的SELECT、INSERT、UPDATE和DELETE等权限（详见user超级用户表）。它的附加的功能包括有匿名的用户并对于MySQL特定的功能例如LOAD DATA INFILE进行授权及管理操作的能力。\n\n管理员可以对user，db，host等表进行配置，来控制用户的访问权限，而user表权限是超级用户权限。只把user表的权限授予超级用户如服务器或数据库主管是明智的。对其他用户，你应该把在user表中的权限设成’N’并且仅在特定数据库的基础上授权。你可以为特定的数据库、表或列授权，FILE权限给予你用LOAD DATA INFILE和SELECT … INTO OUTFILE语句读和写服务器上的文件，任何被授予FILE权限的用户都能读或写MySQL服务器能读或写的任何文件。(说明用户可以读任何数据库目录下的文件，因为服务器可以访问这些文件）。 FILE权限允许用户在MySQL服务器具有写权限的目录下创建新文件，但不能覆盖已有文件在user表的File_priv设置Y或N。，所以当你不需要对服务器文件读取时，请关闭该权限。\n\n```shell\n#mysql> load data infile 'sqlfile.txt' into table loadfile.users fields terminated by ',';\nQuery OK, 4 rows affected (0.00 sec) //读取本地信息sqlfile.txt'\nRecords: 4  Deleted: 0  Skipped: 0  Warnings: 0\n#mysql> update user set File_priv='N' where user='root'; //禁止读取权限\nQuery OK, 1 row affected (0.00 sec)\nRows matched: 1  Changed: 1  Warnings: 0\nmysql> flush privileges; //刷新授权表\nQuery OK, 0 rows affected (0.00 sec)\n#mysql> load data infile 'sqlfile.txt' into table users fields terminated by ','; //重登陆读取文件\n#ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) //失败\n# mysql> select * from loadfile.users into outfile 'test.txt' fields terminated by ',';\nERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)\n```\n\n为了安全起见，随时使用SHOW GRANTS语句检查查看谁已经访问了什么。然后使用REVOKE语句删除不再需要的权限。\n\n## 使用chroot方式来控制MySQL的运行目录\n\nChroot是linux中的一种系统高级保护手段，它的建立会将其与主系统几乎完全隔离，也就是说，一旦遭到什么问题，也不会危及到正在运行的主系统。这是一个非常有效的办法，特别是在配置网络服务程序的时候。\n\n## 关闭对Web访问的支持\n\n如果不打算让Web访问使用MySQL数据库，没有提供诸如PHP这样的Web语言的时候，重新设置或编译你的PHP，取消它们对MySQL的默认支持。假如服务器中使用php等web程序，试试用Web形式非法的请求，如果得到任何形式的MySQL错误，立即分析原因，及时修改Web程序，堵住漏洞，防止MySQL暴露在web面前。\n\n对于Web的安全检查，在MySQL官方文档中这么建议，对于web应用，至少检查以下清单：\n\n* 试试用Web形式输入单引号和双引号(‘’’和‘”’)。如果得到任何形式的MySQL错误，立即分析原因。\n\n* 试试修改动态URL，可以在其中添加%22(‘”’)、%23(‘#’)和%27(‘’’)。\n\n* 试试在动态URL中修改数据类型，使用前面示例中的字符，包括数字和字符类型。你的应用程序应足够安全，可以防范此类修改和类似攻击。 \n\n* 试试输入字符、空格和特殊符号，不要输入数值字段的数字。你的应用程序应在将它们传递到MySQL之前将它们删除或生成错误。将未经过检查的值传递给MySQL是很危险的！\n\n* 将数据传给MySQL之前先检查其大小。\n\n* 用管理账户之外的用户名将应用程序连接到数据库。不要给应用程序任何不需要的访问权限。\n\n## 数据库备份策略\n一般可采用本地备份和网络备份的形式，可采用MySQL本身自带的mysqldump的方式和直接复制备份形式，\n直接拷贝数据文件最为直接、快速、方便，但缺点是基本上不能实现增量备份。为了保证数据的一致性，需要在备份文件前，执行以下 SQL 语句：FLUSH TABLES WITH READ LOCK；也就是把内存中的数据都刷新到磁盘中，同时锁定数据表，以保证拷贝过程中不会有新的数据写入。这种方法备份出来的数据恢复也很简单，直接拷贝回原来的数据库目录下即可。\n\n使用mysqldump可以把整个数据库装载到一个单独的文本文件中。这个文件包含有所有重建您的数据库所需要的SQL命令。这个命令取得所有的模式（Schema，后面有解释）并且将其转换成DDL语法（CREATE语句，即数据库定义语句），取得所有的数据，并且从这些数据中创建INSERT语句。这个工具将您的数据库中所有的设计倒转。因为所有的东西都被包含到了一个文本文件中。这个文本文件可以用一个简单的批处理和一个合适SQL语句导回到MySQL中。\n\n使用 mysqldump进行备份非常简单，如果要备份数据库” nagios_db_backup ”，使用命令，同时使用管道gzip命令对备份文件进行压缩，建议使用异地备份的形式，可以采用Rsync等方式，将备份服务器的目录挂载到数据库服务器，将数据库文件备份打包在，通过crontab定时备份数据：\n\n```shell\n#!/bin/sh\ntime=`date +\"(\"%F\")\"%R`\n$/usr/local/mysql/bin/mysqldump -u nagios -pnagios nagios | gzip >/home/sszheng/nfs58/nagiosbackup/nagios_backup.$time.gz\n# crontab -l\n# m h  dom mon dow   command\n00 00 * * * /home/sszheng/shnagios/backup.sh\n\n恢复数据使用命令：\ngzip -d nagios_backup.\\(2008-01-24\\)00\\:00.gz\nnagios_backup.(2008-01-24)00:00\n#mysql –u root -p nagios  <  /home/sszheng/nfs58/nagiosbackup/nagios_backup.\\(2008-01-24\\)12\\:00\n```\n\n## 启用SSL连接\nmysql默认未启用SSL连接，使用wireshakr抓包可以查看执行的SQL语句和执行结果，在站库分离、主从复制、主从同步等复杂网络下，导致数据库执行过程可能会被嗅探。\n### 安装时启动SSL\n在MySQL5.7安装初始化阶段，比之前版本多了一步操作，而这个操作就是安装SSL的。\n```\nshell> bin/mysqld --initialize --user=mysql    # MySQL 5.7.6 and up\nshell> bin/mysql_ssl_rsa_setup                 # MySQL 5.7.6 and up\n```\n当运行完这个命令后，默认会在data_dir目录下生成以下pem文件，这些文件就是用于启用SSL功能的：\n```\n[root mysql_data]# ll *.pem\n-rw------- 1 mysql mysql 1675 Jun 12 17:22 ca-key.pem         #CA私钥\n-rw-r--r-- 1 mysql mysql 1074 Jun 12 17:22 ca.pem             #自签的CA证书，客户端连接也需要提供\n-rw-r--r-- 1 mysql mysql 1078 Jun 12 17:22 client-cert.pem    #客户端连接服务器端需要提供的证书文件\n-rw------- 1 mysql mysql 1675 Jun 12 17:22 client-key.pem     #客户端连接服务器端需要提供的私钥文件\n-rw------- 1 mysql mysql 1675 Jun 12 17:22 private_key.pem    #私钥/公钥对的私有成员\n-rw-r--r-- 1 mysql mysql 451 Jun 12 17:22  public_key.pem     #私钥/公钥对的共有成员\n-rw-r--r-- 1 mysql mysql 1078 Jun 12 17:22 server-cert.pem    #服务器端证书文件\n-rw------- 1 mysql mysql 1675 Jun 12 17:22 server-key.pem     #服务器端私钥文件\n```\n本地进入MySQL命令行，可以看到如下变量值：\n```\nroot> mysql -h 10.126.xxx.xxx -udba -p\n```\n查看SSL开启情况\n```\ndba:(none)> show global variables like '%ssl%';\n+---------------+-----------------+\n| Variable_name | Value           |\n+---------------+-----------------+\n| have_openssl  | YES             |\n| have_ssl      | YES             |    #已经开启了SSL\n| ssl_ca        | ca.pem          |\n| ssl_capath    |                 |\n| ssl_cert      | server-cert.pem |\n| ssl_cipher    |                 |\n| ssl_crl       |                 |\n| ssl_crlpath   |                 |\n| ssl_key       | server-key.pem  |\n+---------------+-----------------+\n```\n查看dba连接的方式\n```\ndba:(none)> \\s\n--------------\n/usr/local/mysql/bin/mysql  Ver 14.14 Distrib 5.7.18, for linux-glibc2.5 (x86_64) using  EditLine wrapper\nConnection id:          2973\nCurrent database:\nCurrent user:           dba@10.126.xxx.xxx\nSSL:                    Cipher in use is DHE-RSA-AES256-SHA #表示该dba用户是采用SSL连接到mysql服务器上的，如果不是ssl，那么会显示“Not in use“\nCurrent pager:          more\nUsing outfile:          ''\nUsing delimiter:        ;\nServer version:         5.7.18-log MySQL Community Server (GPL)\nProtocol version:       10\nConnection:             10.126.126.160 via TCP/IP\nServer characterset:    utf8\nDb     characterset:    utf8\nClient characterset:    utf8\nConn.  characterset:    utf8\nTCP port:               3306\nUptime:                 2 hours 35 min 48 sec\n```\n* 如果用户是采用本地localhost或者sock连接数据库，那么不会使用SSL方式了。\n\n### 安装后启动SSL\n* 关闭MySQL服务\n* 运行mysql_ssl_rsa_setup 命令\n* 到data_dir目录下修改.pem文件的所属权限用户为mysql\n```\n    chown -R mysql.mysql *.pem\n```\n* 启动MySQL服务\n\n### 强制某用户必须使用SSL连接数据库\n修改已存在用户 \n```\nALTER USER 'dba'@'%' REQUIRE SSL;\n```\n#新建必须使用SSL用户\n```\ngrant select on *.* to 'dba'@'%' identified by 'xxx' REQUIRE SSL;\n```\n对于上面强制使用ssl连接的用户，如果不是使用ssl连接的就会报错，像下面这样：\n```\n[root]# /usr/local/mysql/bin/mysql -udba -p -h10.126.xxx.xxx --ssl=0\nEnter password: \nERROR 1045 (28000): Access denied for user 'dba'@'10.126.xxx.xxx' (using password: YES)\n```\n\n## Mysqld安全相关启动选项\n\n下列mysqld选项影响安全：\n\n* --allow-suspicious-udfs\n\n* * 该选项控制是否可以载入主函数只有xxx符的用户定义函数。默认情况下，该选项被关闭，并且只能载入至少有辅助符的UDF。这样可以防止从未包含合法UDF的共享对象文件载入函数。\n\n* `--local-infile[={0|1}]`\n\n* * 如果用–local-infile=0启动服务器，则客户端不能使用LOCAL in LOAD DATA语句。\n\n* --old-passwords\n\n* * 强制服务器为新密码生成短(pre-4.1)密码哈希。当服务器必须支持旧版本客户端程序时，为了保证兼容性这很有用。\n\n*  (OBSOLETE) --safe-show-database\n\n* * 在以前版本的MySQL中，该选项使SHOW DATABASES语句只显示用户具有部分权限的数据库名。在MySQL 5.1中，该选项不再作为现在的 默认行为使用，有一个SHOW DATABASES权限可以用来控制每个账户对数据库名的访问。\n\n* --safe-user-create\n\n* * 如果启用，用户不能用GRANT语句创建新用户，除非用户有mysql.user表的INSERT权限。如果你想让用户具有授权权限来创建新用户，你应给用户授予下面的权限：\n\n* * mysql> GRANT INSERT(user) ON mysql.user TO ‘user_name’@’host_name’;\n\n* * 这样确保用户不能直接更改权限列，必须使用GRANT语句给其它用户授予该权限。\n\n* --secure-auth\n\n* * 不允许鉴定有旧(pre-4.1)密码的账户。\n\n* --skip-grant-tables\n\n* * 这个选项导致服务器根本不使用权限系统。这给每个人以完全访问所有的数据库的权力！（通过执行mysqladmin flush-privileges或mysqladmin eload命令，或执行FLUSH PRIVILEGES语句，你能告诉一个正在运行的服务器再次开始使用授权表。）\n* --skip-name-resolve\n\n* * 主机名不被解析。所有在授权表的Host的列值必须是IP号或localhost。\n\n* --skip-networking\n\n* * 在网络上不允许TCP/IP连接。所有到mysqld的连接必须经由Unix套接字进行。\n* --skip-show-database\n\n* * 使用该选项，只允许有SHOW DATABASES权限的用户执行SHOW DATABASES语句，该语句显示所有数据库名。不使用该选项，允许所有用户执行SHOW DATABASES，但只显示用户有SHOW DATABASES权限或部分数据库权限的数据库名。请注意全局权限指数据库的权限。\n"
  },
  {
    "path": "docs/3.SDL落地方案/1-安全培训.md",
    "content": "\n# 01.安全培训\n\n作者：Lost Maniac\n\n协作：李浩、袁文宇、I、Gòd、玄道k4n5ha0、johnathan、一条鱼、dubbo、夏韬、jsp-shell、108haili、1024、小乐天、fireeye、backlion、Minggle、Pa55w0rd\n\n----\n\n\n## 安全意识培训(全员)\n\n* 邮件安全\n  * 钓鱼邮件\n  * 邮件伪造\n  * 第三方转存\n  * 检查发件人\n  * 开启二次验证\n  * 邮件转发\n  * 第三方代收\n  * 邮件附件敏感信息加密\n\n* 病毒防范\n  * 什么是木马病毒\n  * 我安装哪些杀毒软件？\n  * 定期更新病毒库\n\n* 浏览器安全\n  * 不浏览恶意网站\n  * 不从恶意网站下载软件\n  * 下载软件从官网下载\n\n* 信息泄露\n  * 敏感数据上传到云笔记、GitHub\n  * 共享账号\n  * 使用公司邮箱注册外部账号或者私人账号\n  * 社交网络发布公司技术解决方案&保密产品信息\n  * 公司账号和私人账号要隔离\n  * 打印后及时取走\n  * 定期删除浏览记录和搜索记录\n\n* 个人电脑安全\n  * 锁屏幕\n  * 不轻易插入陌生U盘\n  * 及时的系统更新\n  * 不从外部下载破解软件(有需要请找IT同学)\n  * 不将公司数据带离工作场所\n  * 电脑要加开机密码，防止电脑丢失后造成数据泄露\n  * 企业微信、微信、QQ、QQ群文件发送文件要打包加密\n  * 工作文档加密盘（利用如TrueCrypt的之类的加密软件）\n\n* 密码泄露\n  * 根据调查显示目前全世界泄露账号密码以及个人隐私有800亿条\n  * 密码使用超过12位以上使用特殊字符、大小写字母和数字\n  * 密码不要与公司内部密码有关联\n  * 密码三个月要更换一次\n  * 不在浏览器上使用保存密码功能\n\n* WiFi安全\n  * 不连接不可信WiFi\n  * 连接不可信WiFi后需要连接VPN\n  * 不要在工作区私自桥接，共享办公网WIFI\n  * 不要使用WIFI万能钥匙等共享密码的APP\n\n* VPN以及OA安全\n  * VPN账号和OA账号仅自己持有\n  * 任何人不会和你以任何理由要VPN以及OA账号\n  * VPN的动态验证短信不转发给其他人\n\n* 客服注意事项\n  * 我在和谁聊天\n  * 确定对方身份的流程\n  * 我可以提供哪些信息\n  * 敏感操作回拨验证人员身份\n  \n* 物理安全\n  * 门禁\n  * 碎纸机（防止泄露商业信息）\n  * 视频监控\n  * 禁止人员尾随进入工作区\n\n## WEB安全开发\n\n* XSS跨站漏洞\n* SQL注入\n* 跨站请求伪造漏洞\n* 支付逻辑漏洞\n* 越权漏洞\n* 平行权限\n* 验证码逻辑漏洞\n* API未限速漏洞\n* GitHub敏感信息泄露\n* 法律风险意识\n\n## APP安全开发\n\n* 数据安全\n  * 存储\n  * 传输\n  * 使用\n  * 验证\n* 代码安全\n  * 逆向\n  * 调试\n  * 重新打包\n* 环境特性\n  * 系统\n  * 组件\n  * 权限\n  * 端口\n* 业务安全\n  * 逻辑漏洞\n  * 策略\n  * 合规\n\n## 安全运维\n\n* 服务器安全\n  * MFA登录\n  * 使用key登录\n  * 禁止弱密码登录\n  * 禁用无用账号\n  * 账号锁定策略（防止暴力破解，ssh:fail2ban）\n  * 检查特殊账号（空口令）\n  * 禁止root远程登录\n  * 关闭非必须服务器服务\n  * 安装IDS/IPS系统\n  * 进行日志收集\n  \n* 更新\n  * 系统版本要尽量贴近官方版本\n  * 软件版本（例如：php）要及时升级\n\n* 日志\n  * 收集全面\n  * 实时传输\n  * 重点日志例如 ssh 内核日志 业务日志\n  * 业务日志要脱敏\n\n* 软件安装\n  * 只允许可信软件源\n  * 需要新软件需要经过安全评估\n  * 业务代码尽量不使用root权限运行\n\n* 网络安全\n  * ACL限制不需要互相访问的业务通讯\n  * 安全组不要附加\n  * snmp修改团体名称\n\n* 数据安全\n  * 杜绝弱口令\n  * 禁止匿名用户\n  * 数据库加密（按照最小化权限原则）\n  * **Redis必须加密**\n  * 大数据服务必须有鉴权\n  * MongoDB必须加密码\n\n* 流程安全控制\n  * 运维准入\n  * 域名开通流程\n  * VPN申请流程\n  * 跳板机申请流程\n\n\n* 物理安全\n  * 机房服务器不允许使用USB接口\n  * VGA显示器应该处于退出状态\n\n\n## 产品经理安全培训\n\n* 敏感信息泄露\n* 调试开关\n* 防重签名\n* http-dns\n* 数据包劫持\n* 登录机制安全性\n* 防暴力破解\n* 时间窗口合理性\n* 不要成为短信轰炸机\n* 任意用户密码重置\n\n\n## 引用\n"
  },
  {
    "path": "docs/3.SDL落地方案/2-需求评估.md",
    "content": "\n# 02.需求评估\n\n作者：I\n\n协作：\n\n----\n\n记录一次安全设计评审的过程，当然这也是我第一次进行安全评审。因此做一个总结。安全设计评审应该是SDL落地安全人员参与过程中首当其冲的地方。仅指安全人员自身的功用。如果按照`SDL`流程来讲，最前期应该是进行安全培训。我们可以看两个微软SDL官方给出的流程图。\n![image](https://user-images.githubusercontent.com/12653147/45536074-ee425400-b832-11e8-9ca7-442923291a3f.png)\n\n![image](https://user-images.githubusercontent.com/12653147/45536096-01edba80-b833-11e8-8c10-7d9f2387ee44.png)\n\n\n那么在安全设计评审这一阶段，应该怎么去做。我们可以先看下唯品会的SDL中在落地安全设计这一块怎么做的。\n\n![image](https://user-images.githubusercontent.com/12653147/45603582-d4398900-ba5f-11e8-97c3-41704aa37024.png)\n\n\n就我自身而言。是按照以下这个流程进行的。\n\n<img src=\"https://user-images.githubusercontent.com/12653147/45536539-66f5e000-b834-11e8-929b-6b5fcc5cdb98.png\" height=\"400\">\n\n看着一大堆乱七八糟，自上而下的流程，但是做起来其实很快的。此处默认安全人员熟悉各种基本的开发过程中的安全规范以及一些`Checklist`(必须要了解公司开发语言对应的安全开发规范)，举例： `web`安全开发规范，`Python`安全编码规范，`Flask`安全， `Django`安全,常用的安全配置，面临哪些攻击点等等。\nps: 明确逻辑是非常重要的，可以说最为重要，如果连逻辑都不明白，谈什么设计评审。\n\n一些比较基础的: \n\n* HTTPS Everywhere\n* Bcypt 存储Hash\n* OTP\n* 频率限制\n* 盐不要硬编码\n* secret 和 auth-token 不要硬编码\n* 服务器间调用的api不要在app出现\n* CSP, CSRF, HSTS, X-FRAME-OPTIONS, X-XSS-PROTECTION\n* 过滤输入\n等等等....\n\n下面以`C2C`平台交易部分为例进行说明，可以简单的想一下，在智联买一张火车票，打开了支付宝进行支付。:\n![image](https://user-images.githubusercontent.com/12653147/45537646-67dc4100-b837-11e8-9154-a3f78020d931.png)\n\n然后，你知道数字签名当然是很基础的部分了。那么接下来，你就要细化支付流程过程中出现哪些操作，针对这些操作需要做什么样的防护措施。下图是针对用户商户支付方之间的流程：\n\n![image](https://user-images.githubusercontent.com/12653147/45538041-84c54400-b838-11e8-9426-f8e2074c78ca.png)\n\n针对每个输入点，自身可控的输入输出的地方，进行过滤，校验等操作。\n\n所以那么问题来了，如果只单单是用户和支付方之间的呢?\n![image](https://user-images.githubusercontent.com/12653147/45539501-88f36080-b83c-11e8-8b18-26a204eaf0a9.png)\n\n你也可以思考一下如何进行。\n\n并且在`OWASP`应用安全设计中，详细指出了其他一些问题(中文版 Version 1.0 5):\n\n* 数据流:\n\n 用户输入是否被直接用于引用业务逻辑的类或函数? \n\n 是否有一个数据绑定缺陷?\n\n 是否暴露任何后门参数来调用业务逻辑?\n\n 应用程序的执行流程是否正确?\n\n* 身份验证和访问控制:\n\n 是否对所有文件实现访问控制?\n\n 是否安全地处理会话?\n\n 是否存在单点登录?单点登录是否留下后门?\n\n* 已有或内置的安全控制:\n\n 在现有任意安全控制中的弱点; \n\n 安全控制的部署是否正确?\n\n* 架构:\n\n 对所有的输入是否有验证?\n\n 到外部服务器的连接是安全的吗?\n\n* 配置或代码文件和数据存储:\n\n 配置文件中是否含有敏感数据?\n\n 是否支持任何不安全的数据源?\n\n下图(来自OWASP官方文档)详列上述条目以及其他需要检查的地方。\n![image](https://user-images.githubusercontent.com/12653147/45603390-385b4d80-ba5e-11e8-9135-5b8352202820.png)\n![image](https://user-images.githubusercontent.com/12653147/45603400-47420000-ba5e-11e8-9ac6-07ff0aedcc90.png)\n\n但是其实并不需要按照上述所有清单做自检，或者说是当你和开发团队在讨论的过程中不需要涉及全部的checklist，可能只需要在架构上，设计上进行检验，以及身份验证和数据检验上。当然，都是需要根据自己的业务场景去实现，因地制宜。\n\n# Resources\n\n* [Mircosoft SDL lifecycle: Desing](https://www.microsoft.com/en-us/SDL/process/design.aspx)\n* [API Security Checklist](https://github.com/shieldfy/API-Security-Checklist)\n* [The Security Checklist](https://github.com/FallibleInc/security-guide-for-developers)\n* [Part of FLASK Security](https://gist.github.com/mylamour/702d9d6e24a27699d8759967e6eb9f4f)\n* [Part of Django Security](https://gist.github.com/mylamour/311299cc7fb80ad9f6674b2cf4ca02a4)\n"
  },
  {
    "path": "docs/3.SDL落地方案/3-产品设计.md",
    "content": "\n# 03.产品设计\n\n\n作者：Pa55w0rd\n\n协作：\n\n----\n\n\n## 1.应用系统架构安全设计要求\n\n在应用系统设计阶段，应充分考虑该架构的安全性,包括B/S、C/S等形式的安全，主要体现在应用数据和用户会话的安全，还应当考虑应用系统自身体系架构内部的安全，以及与外系统接口的安全。针对某些特殊应用，还需考虑复、抗攻击等安全机制。\n\n### 1.1.应用系统自身架构安全\n1.\t自身结构中各组件之间通讯过程的安全机制<br>\n\t组件之间的通讯包括命令级的和数据级的，应充分考虑：\n\t- 传输命令和数据所采用的协议的安全性。应根据组件之间通讯内容安全性要求程度的不同选择不同安全性要求的协议；\n\t- 考虑程序的模块之间的安全通讯机制；\n\t- 不应使用标准的服务端口或者常见病毒、蠕虫等使用的服务端口。\n\n2.\t认证与访问控制机制，应考虑：\n\t- 组件之间的信任机制；\n\t- 用户的身份认证机制；\n\t- 对于组件资源的访问控制机制；\n\t- 不通用户对资源的权限控制机制。\n\n3.\t组件内重要文件和数据的安全防护机制：<br>\n\t存在于组件内部的重要数据资源应当考虑其相应的安全防护机制，这些重要的数据资源包括：\n\t- 配置文件；\n\t- 用户数据，包括文件数据及数据库中的数据；\n\t- 临时文件和数据；\n\t- 与外系统或者系统内部其他组件接口用的数据文件。\n\n\t对这些重要数据的存取安全性设计，包括:\n    - 文件和数据存放是否加密及采用的加密方式。\n\n### 1.2.应用系统与外系统接口的安全\n\n应用系统与外系统的接口安全设计，主要应考虑以下几个要素：\n1. 与外系统的之间通讯中的安全机制。应充分考虑：\n- 传输命令和数据所采用的协议的安全性。应根据系统之间通讯内容安全性要求程度的不同选择不同安全性要求的协议；\n- 建议不使用默认的服务端口或者常见病毒、蠕虫等使用的服务端口。\n\n2. 与外系统的认证与访问控制机制，应考虑：\n- 系统之间的信任机制；\n- 对于系统之间资源的访问控制机制。\n\n3. 对外系统安全机制的符合性，应考虑：\n- 如果外系统采用的接口方式经评估认为是安全的，本系统应当沿用其接口规范进行设计开发；\n- 如果外系统采用的接口方式经评估认为存在安全缺陷，应商定采用更加安全的接口方式；\n- 在考虑接口安全性的同时，也应当注意接口方式对双方系统性能、磁盘、连接数等各种性能指标和资源的影响。\n\n### 1.3.应用系统其他的安全机制\n除了上述基本的安全架构设计内容外，针对不同的应用，以及应用系统的重要程度，可以补充考虑以下几种安全机制：\n1. 针对Web应用的页面保护与恢复机制。<br>\n利用专用的安全产品，或者系统自身设计时就考虑到了对于Web页面进行静态保护和监控问题，当监控到网页被篡改时能够实时恢复页面。\n2. 针对特殊数据的完整性检查和监控机制。<br>\n应用系统自身的审计机制。这一点也可算作是应用系统的安全功能设计的一部分，参见相关章节的要求。\n3. 应用系统安全性分析。<br>\n任何系统都会存在一定的安全缺陷，关键在于风险和缺陷是否可以被容忍，因此，在应用系统设计完成后，应当就其安全性问题进行自我分析和评价。\n\n## 2.应用系统软件功能安全设计要求\n除了在架构上考虑的安全机制外，这些安全机制及相关的安全功能也应当分配在应用系统软件的各部件中。应用系统在开发中应该考虑如下五个方面的安全功能：\n- \t安全审计；\n- \t通讯安全（此部分内容在架构中进行了设计）；\n- \t数据保护；\n- \t认证与授权；\n- \t资源保障。\n\n### 2.1.认证与授权功能的设计\n1. 应用软件应包含用户身份认证体系的强度设计,重要系统应使用双因素认证措施，加强系统安全性：\n- \t用户名、口令认证；\n- \t一次性口令、动态口令认证；\n- \t证书认证；（可选）\n- \t生物特征的认证（签名、声音、指纹、虹膜、视网膜等）。（可选）\n2. 应用软件应包含认证失败后的处理方式设计\n- \t连续失败3次，将锁定登录账号一个小时。账号锁定后可以由系统管理员解锁，也可以在一段时间后自动解锁；\n- \t通知用户认证失败，防止黑客暴力猜测；\n- \t验证码的功能；\n- \t账号复杂度提醒功能。\n3. 应用软件应包含用户权限分配和管理功能设计。\n- \t系统编码中要实现读、写、执行三个权限的分离设计；\n- \t系统查看、配置、修改、删除、登录、运行等权限设计；\n- \t数据访问范围的权限设计；\n- \t应用功能模块使用权限的设计。\n4. 应用软件应包含接口设计，应明确系统的内部结构和外部接口，对于每一个对外接口应详细说明：\n- \t需要通信的对方系统的安全状况和可信程度；\n- \t需传送的数据的保密性和完整性要求；\n- \t对传送数据的合法性检验规则；\n- \t对通信可靠性的要求；\n- \t与外部系统的互相认证方面的需求。\n\n### 2.2.数据安全功能\n1. 应用系统的数据安全功能，应当根据安全需求进行功能设计，内容涉及：数据库的安全、数据采集、数据传输、数据处理、数据存储、数据备份和恢复的安全。对重要的敏感数据应进行加密和完整性保护。\n2. 应用软件应包含输入的安全性设计，主要指对错误输入、恶意输入进行处理。\n3. 应用软件应包含输出的安全性设计。\n\n### 2.3.安全审计功能\n1. 应用系统具备如下安全审计功能：\n- 审计功能的启动和关闭；\n- 变更审计功能的配置信息；\n- 至少应进行审计的事件：进入和退出的时间(登录、退出系统)、异常的系统使用行为(失败登录)、系统维护行为、敏感行为和其它安全功能要求的审计内容；\n- 每个审计记录中至少记录如下信息：事件的日期和时间、事件的类型、主题标识、事件的结果(成功、失败)和事件相关信息。\n2. 应用系统应支持数据查阅审计功能：按照主题、事件查阅；应用系统应明确用户能够查阅审计数据用户。\n3. 在意外情况出现时，应有措施保证审计数据的可用性，当审计记录溢出时采取保护行动。\n\n### 2.4.容错功能设计\n1. 应用软件应包含各模块的出错处理设计。\n2. 应用软件应包含可能出现的各种异常情况的安全处理设计。\n3. 应用软件应包含抗网络攻击的能力的设计及系统脆弱性分析。4、对于应用软件本身的资源及服务的优先保障设计。\n\n## 3.应用系统存储安全设计要求\n在应用系统存储安全设计时，应对系统的存储容量、存储介质、存储备份内容、存储备份方式、存储设备功能要求及相关的存储技术统筹进行考虑。\n\n### 3.1.应用系统的存储容量设计\n应依据对于应用数据的测算，估算应用系统的存储容量，建议在存储容量估算时应考虑以下要求：\n- 在实际估算值上预留20%的存储余量，并考虑未来的应用存储量的增长需求。\n- 考虑到应用系统自身的审计数据的容量、保存期限以配置相应的存储设备。\n- 对于应用系统中的临时数据和过渡数据，应当设计其保存的时间，并以此考虑这部分的存储容量要求。\n\n### 3.2.应用系统的存储介质选择\n应用系统的存储介质主要包括但不限于：磁带、纸带、闪存、软盘、光\n盘、磁盘和磁盘阵列。具体存储介质的选择应依据应用系统的业务种类及存储周期的要求，采用不同的介质。\n1. 对于应用系统的交易数据，应采用高性能、高可靠的存储介质，如磁盘、磁盘阵列等进行存储；\n2. 对于应用系统的历史数据，应采用可靠、稳定的存储介质，如磁带、光盘等进行存储。\n\n### 3.3.应用系统存储备份对象\n应用系统对于其储存备份的对象设计，应包括如下内容：\n1.\t系统数据的备份：应包括Web服务器的网站内容、Mail服务器的邮件实时备份、数据库、文件服务器中的文件以及其他数据；\n2.\t系统的完全备份：应包括关键的、需要快速恢复的设备，通过磁带机的完全备份，应实现快速的灾难恢复；\n3.\t系统的冗余主机备份：对于关键并且不能停止的服务设备（如计费服务、Web、Mail服务器），应考虑使用多台主机进行冗余备份，以保证当任何一台主机发生故障时，服务器仍可提供服务；\n4.\t系统配置的备份：应包括关键路由器的配置、防火墙的配置、各类服务器操作系统的安全配置以及各类服务器（如Web、Mail、文件服务器等）中服务器软件（如Apache、Sendmail）的配置。\n\n### 3.4.应用系统存储备份方式\n应用系统应当根据不同的阶段，系统数据不同的重要程度，对数据采取不同的备份方式：\n1. 完全备份<br>\n使用备份介质对整个系统进行完全备份，包括系统和数据。这种备份方\n式的优点是直观，容易被人理解，而且当数据丢失时，可以快速恢复丢失的数据。它也有不足之处，即：\n- 定期对系统进行完全备份，因此在备份数据中有大量的重复信息，占用了大量的存贮空间，增加了备份成本；\n- 需要备份的数据量大，因此备份所需要的时间较长。<br>\n建议在关键性应用系统的实施前、实施后、变更以及升级等重要操作时，\n对操作系统进行完全备份。针对信息较小的不断变化的，且变化的内容大于\n50％的，定期进行完全备份。\n2. 增量备份<br>\n每次备份的数据只是相当于上一次备份后增加和修改过的数据。没有重\n复的备份数据，节省备份介质的空间，缩短了备份时间。这种备份的优点很明显，同时也存在某些不足之处，即当发生灾难时，恢复数据比较麻烦。\n建议在关键性应用系统正常运行维护阶段，针对变化的、不断增加的信息，定期进行增量备份。\n3. 差异备份<br>\n每次备份的数据只是相当于上一次完全备份后新增加和修改过的数据，\n即采用完全备份和差异备份相结合备份策略。如每周日进行一次完全备份，\n而周一至周六进行差异备份。其优点为：没有重复的备份数据，即节省备份介质的空间，缩短了备份时间；缺点为：当发生灾难时，恢复数据比较麻烦。\n建议应用系统的正常运行维护阶段，针对不断变化的（变化的内容小于\n50％）系统，定期进行差异备份。\n4. 按需备份<br>\n按需备份是指在正常的备份安排之外，额外进行的备份操作，这种备份\n方式可以弥补冗余管理以及长期转存的日常备份的不足。因此它是一种非常\n灵活、重要的备份方式，在应用系统的各个阶段，如果备份的内容较少，可以采用按需备份。<br>\n建议应用系统在下列情况下采取按需备份：\n- 只需要备份很少的几个文件、目录、数据库或数据库中的表；\n- 备份服务器上必要的配置文件。\n5. 排除备份<br>\n排除备份是指排除不需要的文件后再进行备份。从本质上讲，排除备份不是一种备份方法，只是减少备份冗余的一种方法。<br>\n建议应用系统在下列情况下考虑排除备份：\n- 有些文件非常大，但并不重要；\n- 某些文件总是导致备份异常或出错。\n\n### 3.5.应用系统的存储设备功能要求\n应用系统存储设备的功能要求应包括如下内容：\n1. 存储设备应保证数据的高可用性和完整性要求；\n2. 存储设备应具有在多主机环境下工作的能力；\n3. 存储设备应能方便地做到快速备份和恢复，重要系统应做到双机备份、支持热插拔；\n4. 存储设备应有简便的、功能强大的管理工具，做到对整个存储系统的监视与控制。\n\n## 4.应用系统通讯安全设计要求\n1. 应采用安全通信协议对重要数据进行安全传输（尤其是账号、口令信息），如使用SSL/TLS、HTTPS、SFTP和IPSec等安全协议进行通信：\n- 终端与服务器端之间的WWW服务，建议使用HTTPS安全通信协议；\n- 终端与服务器端之间的FTP服务，建议使SFTP安全通信协议；\n- 终端与服务器端之间的Telnet服务，建议使SSH安全通信协议。\n2. 终端应用程序采用加密传输机制对重要信息进行传输。\n3. 终端应用程序采用完整性检查对业务的重要数据或敏感数据进行检查。\n4. 终端应用程序应采用抗抵赖攻击技术对重要的交互信息进行保护。\n5. 终端应用程序使用固定的通信端口。\n\n## 5.应用系统数据库安全设计要求\n1. 应从以下方面进行数据库的选型：\n- 数据库、应用系统的运行环境；\n- 数据库的稳定性、安全性（多级安全）；\n- 数据库的容量（最多支持的库的数目、表的数目、记录数目）；\n- 数据库的存取速度；\n- 是否支持多种备份方式；\n- 是否支持数据库的导入和导出。\n2. 应明确数据库相关的用户管理、资源管理、特权管理和角色管理，明确各种用户的资源权限，并建立规范的权限文档。\n3. 数据库原则上应及时更新重要补丁。在安装补丁前应先在测试环境进行，提前进行数据备份，充分准备回退方案和应急预案。\n4. 数据库的配置应符合相应的基线配置要求。\n5. 应及时修改数据库的默认密码或将默认账号锁定、删除。\n6. 数据库的账号应根据业务和维护需要进行合理分配，避免账号共用。\n\n## 6.应用系统数据安全设计要求\n\n### 6.1.数据采集安全\n应根据数据采集的内容、采集的频率、数据精确度要求、时间特性等来进行数据采集的安全要求设计，数据采集服务器和采集主机应考虑30%的系统开销及冗余。\n\n### 6.2.数据传输安全\n1. 应按照数据的类型、数据的重要程度、网络的安全状况等综合因素，对\n数据的传输采取不同的安全保护，包括但不限于防火墙、IDS、VPN、病毒防护等安全措施。\n2. 应了解数据传输存在安全隐患的网络或设备，对存在安全隐患的网络采取必要的安全技术，包括但不限于安全通信协议、加密算法、完整性检查算法以及抗抵赖攻击方法等。\n3. 应制定数据传输安全的检查方式，包括但不限于数据传输安全抗主动攻击能力检查、被动抗攻击的能力检查。\n4. 应保障“数据传输安全”有关的重要配置参数安全，包括但不限于口令、加/解密算法、加/解密密钥等。\n5. 应采用安全通信协议对数据进行安全传输，如使用SSL/TLS、HTTPS、\nSFTP和IPSec等安全协议进行通信。\n6. 对传输的信息进行不同等级的加密保护，即根据网络或设备的风险、传输内容安全要求的不同，选择不同安全强度的加密算法对信息进行加密传输。建议使用RSA等高强度的密码算法对非常重要的信息（如口令、加密密钥）进行加密传输；对于普通数据的传输，可以采用DES、3DES\n等加密算法进行加密传输。\n7. 应防止对所传输数据进行未经授权的任何形式的修改，即对业务的重要数据或敏感数据，建议使用MD5、SHA等算法对数据完整性进行保护。\n8. 对重要的交互信息，建议采取抗抵赖技术，包括但不限于数字签名技术。\n9. 为了配合网络其它安全设备，建议采用基于用户名/口令的认证技术、\nVLAN技术、MPLS技术等安全技术手段。\n\n### 6.3.数据处理安全\n1. 应根据数据的类型、数据的处理方式、数据的安全性要求、与其它接口\n有关的敏感等级、数据相关业务应用的重要性程度来进行数据处理过程的安全性设计。\n2. 应对原始数据进行检错和校验操作，保证原始数据的正确性和完整性。\n3. 数据在转换过程中，应采用通用的标准格式，应考虑相关的不同系统和不同应用的格式需求。\n4. 数据处理过程应提供处理数据的状态信息和数据处理过程的动态信息。\n5. 数据处理过程应具备异常处理功能，在任一环节发现问题，均应能及时回退，必要时可以人工处理。\n6. 数据处理的中间过程和中间结果不能暴露给第三方。\n\n"
  },
  {
    "path": "docs/3.SDL落地方案/4-代码编写.md",
    "content": "\n# 04.代码编写\n\n\n作者：tinker\n\n协作：\n\n----\n\n## 1.编写《企业安全编码规范》\n根据公司所使用技术栈的不同，进行编码规范设计。\n\n## 2.制度流程建设\n建立完善的代码测试、反馈、上线流程。对开发人员代码质量问题、代码安全问题进行考核。\n\n参考：代码提交-代码审计-反馈问题-修复问题-测试环境部署\n\n建立漏洞处理流程，对开发人员漏洞修复效率进行考核。\n\n参考：安全人员提交漏洞-开发人员知悉漏洞-开发人员开始修复漏洞-开发人员修复完成漏洞-安全人员复测漏洞-安全人员复测完成或者复测不通过漏洞。\n\n## 3.白盒审计工具推荐\n使用工具将《企业安全编码规范》进行落地。\n\n### 1.sonar（开源）\n基于可定制规则进行静态代码扫描，从而帮助开发人员能够编写更清晰，更安全的代码。\n\n优点：\n\n    1.开源~开源~开源~\n    2.可定制规则（需要一定技术实力进行开发）\n    3.支持CI/CD过程集成\n    4.支持Code Review阶段反馈\n    5.目前官方给出了超过25种语言的支持\n\n缺点：\n\n    1.不支持代码动态分析\n\n相关链接：\n\n    https://www.sonarqube.org/\n    https://github.com/SonarSource/sonarqube\n\n\n"
  },
  {
    "path": "docs/3.SDL落地方案/5-渗透测试.md",
    "content": "\n# 05.渗透测试\n\n作者：枫子\n\n协作：Lost Maniac\n\n----\n\n## 一、总则\n\n* 第一条  为了对信息系统的安全性作深入了解，及时发现信息系统中存在的安全薄弱环节，让技术人员了解当前信息系统的脆弱性和可能造成的影响，以采取必要的防范措施，特制定《渗透测试管理办法》。\n\n* 第二条  本办法适用于公司所有信息系统。\n\n* 第三条本办法阅读对象为公司业务主办发及所有技术人员。\n\n## 二、公司安全工作组职责分工\n\n* 第四条公司安全工作组公司安全工作组（以下简称“安全组”）下设渗透测试小组负责协调组织公司信息系统渗透测试具体实施、结果分析、报告提交、整改跟进和结果复测工作；\n\n* 第五条渗透测试工作涉及本单位的业务主办方、系统运维方、网络运维方、应用运维方和安全管理方。\n* 第六条业务主办方：负责提出新系统上线前业务系统的渗透测试需求，并对渗透结果需要整改的业务影响范围进行评估和确认，跟进整改进度，一般由业务部门人员担。\n\n* 第七条系统运维方：负责业务应用部署、操作系统和中间件的安装升级（含补丁升级）、安全基线配置、漏洞整改的具体实施，一般由系统运维职能人员担任。\n\n* 第八条网络运维方：负责业务相关的网络及安全设备的部署、安全基线配置、补丁升级和漏洞整改及漏洞扫描策略配置和调优，一般由网络运维职能人员担任。\n\n* 第九条应用运维方：负责应用的开发和维护，对应用程序配置和逻辑上的漏洞进行修复，一般由应用开发职能人员担任。\n\n* 第十条安全管理方：负责信息系统的安全管理，组织实施安全检查、漏洞扫描、渗透测试和落实整改，一般由安全管理职能人员担任。\n\n## 三、渗透测试对象\n\n* 第十一条主机系统安全   针对Windows、Linux、AIX等操作系统进行渗透测试。\n* 第十二条数据库系统安全   针对MySQL、Oracle、MSSQL、Sybase、DB2等数据库应用进行渗透测试。。\n* 第十三条应用系统安全   针对如ASP、JSP、PHP、CGI等组成的Web应用，包括但不限于Web应用系统安全、APP软件安全进行渗透测试。\n\n## 四、渗透测试原则和流程\n\n* 第十四条渗透测试工作以业务系统为单位进行，所有信息系统每季度至少进行一次完整的渗透测试。为减轻渗透测试对信息系统的影响，渗透测试时间须避开业务高峰时段，单次渗透测试持续时间须控制在1天到2天，最长不得超过3天。\n\n* 第十五条为防止渗透测试造成信息系统的业务中断，在渗透测试中不得使用含有影响业务正常运行的测试手段。\n\n* 第十六条对于不能接受任何可能风险的信息系统，需搭建与生产环境完全一致的测试环境，包括硬件平台和软件平台（包括但不限于操作系统版本、中间件版本、数据库版本、应用程序版本），再对所搭建的环境进行渗透测试。\n\n* 第十七条新系统上线前和应用变更上线前必须进行渗透测试（包括黑盒测试及白盒测试），对存在高中危漏洞的系统，须整改完成后方可上线。\n\n* 第十八条渗透测试工作完成后由安全管理方出具包含漏洞名称、漏洞描述、安全级别、利用方式、修复建议等内容的渗透测试报告。\n\n## 五、渗透测试工作的准备、监控和应急\n\n* 第十九条渗透测试前期准备安全管理方依据信息系统资产台帐信息，制定包含实施办法、实施时间、实施人员、实施范围等要素的详细测试方案，经安全组评审通过后方可开展。\n\n* 第二十条渗透测试的执行需严格按照通过评审的渗透测试方案定制渗透测试任务，并在既定的时间点开始执行。在渗透测试任务的执行过程中，渗透测试对象所属的安全人员应对渗透测试任务密切监控。\n\n* 第二十一条渗透测试的风险防范为防止在渗透测试过程中出现的异常情况，所有被测试系统须在被渗透操作之前进行一次完整的系统备份，在渗透测试任务执行过程中，业务主办方、系统运维方和安全管理方对被测试对象进行应急保障。当渗透测试过程中出现与影响性评估不符合的情况时，应根据渗透测试方案立即启动应急措施，消减对被测试对象的影响。\n\n## 六、渗透测试后的整改\n\n* 第二十二条渗透测试结束后安全人员需对渗透测试结果进行分析，并制定整改方案和计划，1个工作日内提供包含漏洞类型、风险级别、修复方法等关键表项的渗透测试报告。\n\n* 第二十三条报告提交后1个工作日内安全管理方协调业务主办方、系统运维方、应用运维方、网络运维方组织整改交流，并将需整改的漏洞落实到具体责任人，根据整改交流会上确定的整改周期（评估为高危级别以上的漏洞整改时限为1天，中危级别的漏洞整改时限为2天）完成漏洞整改工作，无法整改的漏洞须备注说明，并提供未整改期间防护手段（在漏洞整改完成前需立即提供临时防范手段）。\n\n* 第二十四条渗透测试结果需由人工对检查出的漏洞进行复核确认，评估漏洞影响性，最终确定系统的风险系数和漏洞的安全级别。\n\n## 七、附则\n\n* 第二十五条本管理办法由技术部负责解释。\n\n* 第二十六条本办法自颁布之日起实行，有新的修改版本颁布后，本办法自行废止。\n\n# 八、附件"
  },
  {
    "path": "docs/3.SDL落地方案/6-上线发布.md",
    "content": "\n# 06.上线发布\n\n作者：Torjan\n\n协作：\n\n----\n\n\n\n# 1.    概述\n\n为进一步规范某公司应用系统上下线管理，实现系统建设、运行维护各阶段的平稳过渡和有序衔接，确保系统安全稳定可靠运行，特制定本办法。规范仅供参考。\n\n\n\n\n\n# 2.    使用范围\n\n本规范中仅供于某公司信息技术部，应用开发部门，运维部门，业务部门参考，系统上线指应用系统在生产环境部署并提供给用户实际使用，包括上线试运行和上线正式运行两个阶段。应用系统的开发阶段、上线试运行阶段、上线正式运行阶段以及系统下线构成其全部生命周期。其中上线试运行阶段又包括上线试运行申请、上线试运行测试、上线试运行和上线试运行验收等环节。\n\n# 3.    上线试运行申请\n\n应用系统开发部门负责向信息技术部申请系统的上线试运行。系统申请上线试运行必须满足以下条件： \n\n1.应用系统开发部门按照系统需求说明书、系统目标任务书或合同中的规定已完成系统的开发和实施，系统经用户试用并修改完善，已相对稳定，具备有关功能和安全保障措施，经业务部门确认能够满足当前业务需求并在一定程度上适应业务的发展。\n\n2.应用系统开发部门对系统进行严格的测试，包括系统的功能实现、安全性、性能、可用性、兼容性、集成性等方面，并形成测试报告。测试结果经信息技术部、业务部门、运维部门和相关人员的认可。\n\n3.应用系统开发部门完成各个层次重点用户的培训工作， 包括系统最终用户和运维部门和相关人员有关人员的培训工作。 \n\n4.应用系统开发部门配合运维部门和相关人员制定详细的上线试运行实施计划、系统备份方案、系统监控方案、安全策略配置方案、应急预案和移交计划等。\n\n5.应用系统开发部门、 运维部门和相关人员共同检查系统的安装环境，确认满足安装所需的服务器、网络、电源等环境保障条件。 \n\n6.运维部门和相关人员基于安全可靠稳定运行和硬件资源整合利用的原则评估确定系统的安装部署模式。\n\n# 4.    上线试运行测试\n\n## 4.1.  上线试运行的安装\n\n运维部门和相关人员负责操作系统和支撑软件系统的安装，包括主机漏洞扫描、安全加固等工作，应用系统开发部门负责上线应用系统软件的安装和整体调试。\n\n应用系统安装调试完成后，运维部门和相关人员即可组织应用系统开发部门开展系统上线试运行测试，测试应在一个月内完成。在上线试运行测试完成前，不对外提供服务。\n\n## 4.2.  上线试运行测试\n\n测试环境测试主要通过性能测试工具对系统进行压力测试和安全评估，重点考察系统的集成性、健壮性、稳定性、负荷响应能力和安全性等指标，并开展系统应急预案演练，形成相关记录和报告，测试环境应该与生产环境类似。\n\n生产环境测试主要考察系统在上线正式运行环境中各功能模块的连通性、响应能力、安全性以及对整个应用系统的影响等指标，形成相关记录和报告。生产环境测试，应避免对在线系统产生不利影响，并应制定有关应急预案，采取数据备份措施。 \n\n测试中存在不符合项时，应用系统开发部门提出整改方案，报信息技术部及业务部门审查通过后，按要求限期整改，并再次申请复测。\n\n## 4.3.  上线前安全测试\n\n应该至少对需要上线的应用进行系统安全和应用安全进行安全测试，包括但不仅限于漏洞扫描，渗透测试，代码审计，基线评估；\n\n对于要对外部开放的应用系统至少应该完成：\n\n系统漏洞扫描，应用漏洞扫描，渗透测试，基线评估等安全评估；\n\n对于内部使用的应用系统至少应该完成：\n\n系统漏洞扫描，应用漏洞扫描（不仅限于以上内容）的安全评估\n\n所有应用在测试后应进行至少一次复测，保证测试和修复结果的可靠，保障应用稳定，安全，可靠上线。\n\n# 5.    上线试运行\n\n信息技术部和业务部门共同确定系统上线试运行开始时间和上线试运行的期限，原则上上线试运行期为三个月，具体可根据系统的复杂程度不同，按照能够全面检验系统运行质量的原则确定合理的试运行时间。\n\n系统进入上线试运行后，按照上线正式运行的要求管理，严格执行某公司关于应用系统运行维护及安全管理的有关规定，做好数据的备份，保证系统及用户数据的安全。业务部门负责提出最终用户的权限分配方案。运维部门负责执行和登记。\n\n上线试运行的初期安排一定时间的观察期。观察期内由应用系统开发部门和运维部门和相关人员共同安排人员进行运行监视、调试、备份和记录，并提交观察期的系统运行报告。在观察期内对系统进行变更时，按照某公司应用系统运行管理规定执行。\n\n观察期原则上不短于上线试运行期的三分之一，一般为一个月。若观察期内系统连续运行未出现故障，未进行重大变更，满足信息技术部和业务部门相关考核要求，可认为观察期结束；否则重新开始观察期。\n\n相关业务部门会同系统运维部门和相关人员审核观察期的系统运行报告，确认系统在观察期内运行稳定，报信息技术部审批后，办理上线试运行期间系统运行管理权限的移交手续。移交内容包括应用系统的管理权限分配情况以及有关技术服务支持的联络机制及联络人等。\n\n系统运行管理权限移交后，系统由运维部门和相关人员负责日常运行管理、监控和系统应用统计，并负责系统和软件产品维护权限的分配和登记。应用系统开发部门负责系统应用程序级的运维技术支持，并配合运维部门和相关人员解决系统运行中出现的有关问题。\n\n系统上线试运行期间，未发生影响用户使用的故障、未发生因软件缺陷而导致系统停运的重大故障、未进行较大变更等，可认为该系统上线试运行期间稳定运行；否则需待系统整改完善后重新开始上线试运行。\n\n系统上线试运行期间发生变更的，需对变更部分及相关功能重新按上线试运行申请流程组织上线试运行测试后再安排上线试运行，对涉及系统重大变更的，需对整个系统重新按上线试运行申请流程组织上线试运行测试后，满足要求的重新开始上线试运行。\n\n系统上线试运行期间稳定运行后，应用系统开发部门需删除临时工作所需的帐号及其它临时措施，组织完成工作报告、技术报告和用户使用报告，并负责办理上线试运行结束和上线试运行验收的申请手续。运维部门和相关人员负责提供系统上线试运行报告，应用系统开发部门配合。\n\n下级单位的等级保护二级及以上应用系统上线试运行需一个月内报上级信息技术部备案。\n\n# 6.    上线试运行验收\n\n系统上线试运行在具备以下条件后，由应用系统开发部门负责向信息技术部申请系统上线试运行验收。\n\n系统上线试运行期间连续稳定运行。\n\n信息技术部、业务部门及运维部门和相关人员应确定系统服务级别，建立保证应用系统正常运行的运行维护管理办法和考核制度，明确系统各级维护管理和应用人员的职责，确保信息的及时、准确、全面和安全。\n\n应用系统开发部门完成用户应用培训、运行维护培训，配合运维部门和相关人员制定系统备份方案、系统监控方案、安全策略配置方案、应急预案等运行技术文档。\n\n应用系统开发部门完成系统的全面移交，移交内容包括系统日常维护手册、系统管理员手册、系统培训手册、系统核心参数及端口配置表、系统用户及口令配置表（需含口令修改关联关系）、技术支持服务联系人及联系方式等。\n\n信息技术部牵头组织验收，成立验收工作组（或验收委员会），成员应由业务部门、系统开发、运行维护的专业人员组成，验收工作组包括技术审查组、生产准备组、文档审查组等专业小组。\n\n验收工作组按要求对项目相关文档进行全面检查，对系统功能实现、性能、安全性、数据备份与恢复、应急与快速恢复方案等进行测试和核实，并作出验收结论。\n\n上线试运行验收要严格按照信息化项目管理有关规定，有效规避投运后的各种风险，认真做好项目开发过程中形成的应用软件源代码（包括二次开发源代码）、各类技术文档的移交、保管、存档工作。运维部门和相关人员负责运行文档的接受和系统生命周期内运行文档的管理。\n\n验收时发现影响系统上线正式运行的重大问题，应责成相关单位立即整改，并延长上线试运行时间，系统完成整改并连续稳定运行一个月后，方可再次申请验收。\n\n通过应用系统的上线试运行验收是应用系统完成上线试运行转入上线正式运行维护的标志。\n\n# 7.    上线正式运行\n\n通过上线试运行验收后，系统完成建转运工作，该应用系统即为正式在运应用系统，需严格按照某公司应用系统运行维护和安全管理相关规定纳入日常管理。\n\n运维部门和相关人员负责系统的日常运行维护，除保证系统所需网络和软硬件环境正常外，还应对系统应用情况进行实时监控，做好应用统计，保证系统安全、可靠和稳定运行。\n\n应用系统开发部门需按合同规定指定专人负责配合运维部门和相关人员开展系统的售后服务和技术支持工作，并具体负责系统的程序代码维护。\n\n系统的修改、调整、更新、升级等维护操作，须严格执行某公司有关应用系统运行维护的管理规定，履行相关流程和审批制度。相关维护操作应先在测试环境上开展，测试通过后部署到生产环境，不得擅自进行在线调试和修改。\n\n为保障系统安全，在根据需要安排应用系统开发部门人员进行维护操作时，运维部门和相关人员应安排专人进行监护。维护操作完成后，运维部门和相关人员应及时收回临时分配出的所有权限。"
  },
  {
    "path": "docs/3.SDL落地方案/7-应急响应.md",
    "content": "\n# 07.应急响应\n\n作者：pa55w0rd\n\n协作\n\n----\n\n## 什么是应急响应和应急响应体系\n\n---\n\n### 基本概念\n\n**安全事件（Security Accident）** 是指影响一个系统正常工作的情况。这里的系统包括主机范畴内的问题，也包括网络范畴内的问题，例如黑客入侵、信息窃取、拒绝服务攻击、网络流量异常等。\n\n**应急响应（Emergency Response）** 是指组织为了应对突发/重大信息安全事件的发生所做的准备以及在事件发生后所采取的措施。\n应急响应是信息安全防护的最后一道防线！\n\n\n**应急响应体系（Emergency Response System）** 是指在突发/重大信息安全事件后对包括计算机运行在内的业务运行进行维持或恢复的各种技术和管理策略和规程。\n\n信息安全应急响应体系的制定是一个周而复始、持续改进的过程，包含以下几个阶段：\n\n- 应急响应需求分析和应急响应策略的确定；\n- 编制应急响应计划文档和技术管理规范；\n- 应急响应计划的测试、培训、演练和维护。\n\n---\n\n### 应急响应目的\n\n应急响应服务的目的是尽可能地减小和控制住网络安全事件的损失，提供有效的响应和恢复指导，并努力防止安全事件的发生。\n\n### 政策要求\n\n- 《关于加强信息安全保障工作的意见》（**中办发『2003』27号文**）指出：“信息安全保障工作的要点在于，实行信息安全等级保护制度，建设基于密码技术的网络信任体系，建设信息安全监控体系，**重视信息安全应急处理工作**，推动信息安全技术研发与产业发展，建设信息安全法制与标准”\n\n- 国家信息安全战略的近期目标：通过五年的努力，基本建成国家信息安全保障体系。\n\n- 为了落实27号文精神国家网络与信息安全协调小组办公室于2003年10月发布了《网络与信息安全信息通报暂行办法》、2004年9月发布了\n- 《关于做好重要信息系统灾难备份工作的通知》，2004年8月发布了《关于建立健全基础信息网络和重要信息系统应急协调机制的意见》等文件。这些文件对推动灾难备份和应急响应的发展起到了重要作用。\n\n### 相关标准 \n\n- GB/T 24364-2009 《信息安全技术 信息安全应急响应计划规范》\n- GB/T 20988-2007 《信息安全技术 信息系统应急响应规范》\n- GB/Z 20985-2007 《信息技术 安全技术 信息安全事件管理指南》 \n- GB/Z 20986-2007 《信息安全技术 信息安全事件分类分级指南》 \n\n--------\n\n## 应急响应六阶段\n\n### 第一阶段：准备——让我们严阵以待\n- 预防为主\n- 微观（一般观点）：\n\n    - 帮助服务对象建立安全政策\n    - 帮助服务对象按照安全政策配置安全设备和软件\n扫描，风险分析，打补丁\n如有条件且得到许可，建立监控设施\n\n- 宏观：\n\n    - 建立协作体系和应急制度\n    - 建立信息沟通渠道和通报机制\n        - 电话、即时通讯、email\n    - 如有条件，建立数据汇总分析的体系和能力\n有关法律法规的制定\n\n- 制定应急响应计划\n- 资源准备\n    - 应急经费筹集\n    - 人力资源\n        - 指挥调度人员\n        - 协作人员\n        - 技术人员\n        - 专家\n        - 设备、系统和服务提供商\n    - 硬件设备准备\n        - 数据保护设备（磁盘、SAN）\n        - 冗余设备 （网络链路、网络设备、关键计算机设备\n    - 软件工具准备\n        - 备份软件\n        - 日志处理软件\n        - 系统软件\n        - 应急启动盘\n        - 病毒、恶意软件查杀软件\n        - 等等\n    - 现场备份\n    - 业务连续性保障\n        - 系统容灾\n        - 搭建临时业务系统\n\n\n### 第二阶段：确认——对情况综合判断\n\n- 确定事件性质和处理人\n- 微观（负责具体网络的CERT）：\n    - 确定事件的责任人：指定一个责任人全权处理，事件，给予必要的资源\n    - 确定事件的性质：\n误会？玩笑？还是恶意的攻击/入侵？\n影响的严重程度，\n预计采用什么样的专用资源来修复？\n- 宏观（负责总体网络的CERT）：\n    - 通过汇总，确定是否发生了全网的大规模事件\n    - 确定应急等级，以决定启动哪一级应急方案\n\n- 事故的标志（征兆和预兆）\n    - Web服务器崩溃\n    - 用户抱怨主机连接网络速度过慢\n    - 子邮件管理员可以看到大批的反弹电子邮件与可疑内容\n    - 网络管理员通告了一个不寻常的偏离典型的网络流量流向\n\n- 来源\n    - 网络和主机IDS  、防病毒软件、文件完整性检查软件\n    - 系统、网络、蜜罐日志\n    - 公开可利用的信息\n    - 第三方监视服务\n\n- 确认事故\n    - 确认网络和系统轮廓：\n分析事故的最好技术方法之一\n    - 理解正常的行为：\n基于处理事故的良好准备\n    - 使用集中的日志管理并创建日志保留策略\n    - 执行事件关联\n    - 保持所有主机时钟同步\n    - 维护和使用信息知识库：\n分析事故时的快速参考\n    - 使用互联网搜索引擎进行研究\n    - 运行包嗅探器以搜集更多的数据\n    - 过滤数据\n    - 经验是不可替代的\n    - 建立诊断矩阵\n    - 寻求帮助\n\n#### 诊断矩阵实例\n\n 征兆 | 拒绝服务 | 恶意代码 | 非授权访问 | 不正确使用\n -- |   --  | -- | -- | --\n 文件，关键，访问尝试 | 低 | 中 | 高 | 低\n 文件，不适当的内容 | 低 | 中 | 低| 高\n 主机崩溃 | 中 | 中 | 中 | 低\n 端口扫码，输入的，<br>不正常的 | 高 | 低 | 中 | 低\n 端口扫码，输出的，<br>不正常的 | 低 | 高 | 中 | 低\n 利用带宽高 | 高 | 中 | 低 | 中\n 利用电子邮件 | 中| 高 | 中 | 中\n\n- 事故优先级- 服务水平协议\n    - 服务水平协议（SLA ）：\n\n定义服务目标及双方的预期及责任\n    - 服务水平协议指标\n        - **远程应急响应服务**\n在确认客户的应急响应请求后? 小时内，交与相关应急响应人员进行处理。无论是否解决，进行处理的当天必须返回响应情况的简报，直到此次响应服务结束。\n        - **本地应急响应服务**\n对本地范围内的客户，？小时内到达现场；对异地的客户，？小时加路途时间内到达现场。\n\n#### 应急响应 SLA矩阵\n\n事故当前或将来可<br>能的影响 | 高（例如：互联网<br>连接，公共Web服<br>务器，防火墙，客<br>户数据）| 中（例如：系统管<br>理员工作站，文件和<br>打印服务器，XYZ <br>应用数据） | 低（例如：用户工<br>作站）\n-- | -- | -- | --\nROOT级访问 | 15min | 30min | 1h\n非授权的数据修改 | 15min | 30min | 2h\n对敏感信息的非<br>授权访问 | 15min | 1h | 1h\n非授权的用户级访问 | 30min | 2h | 4h\n服务不可用 | 30min | 2h | 4h\n骚扰 | 30min | 不限 | 不限\n\n\n### 第三阶段：遏制——制止事态的扩大\n\n- 即时采取的行动\n- 微观：\n    - 防止进一步的损失，确定后果\n    - 初步分析，重点是确定适当的封锁方法\n    - 咨询安全政策\n    - 确定进一步操作的风险\n    - 损失最小化（最快最简单的方式恢复系统的基本功能，例如备机启动）\n    - 可列出若干选项，讲明各自的风险，由服务对象选择\n- 宏观：\n    - 确保封锁方法对各网业务影响最小\n    - 通过协调争取各网一致行动，实施隔离\n    - 汇总数据，估算损失和隔离效果\n\n- 建议组织机构为几类主要的事故建立单独的遏制策略，其标准包括：\n    - 潜在的破坏和资源的窃取\n    - **证据保留的需要**\n    - 服务可用性（例如：网络连接，提供给外部当事方的服务）\n    - 实施战略需要的时间和资源\n    - 战略的有效性（例如：部分遏制事故，完全遏制事故）\n    - **解决方案的期限**（例如：紧急事故工作区需在4 小时内清除，临时工作区需在两周内清除，永久的解决方案）。\n\n### 第四阶段：根除——彻底的补救措施\n\n- 长期的补救措施\n- 微观：\n    - 详细分析，确定原因，定义征兆\n    - 分析漏洞\n    - 加强防范\n    - 消除原因\n    - 修改安全政策\n- 宏观：\n    - 加强宣传，公布危害性和解决办法，呼吁用户解决终端的问题；\n    - 加强检测工作，发现和清理行业与重点部门的问题\n\n### 第五阶段：恢复——系统恢复常态\n\n- 微观：\n    - 被攻击的系统恢复正常的工作状态\n    - 作一个新的备份\n    - 把所有安全上的变更作备份\n    - 服务重新上线\n    - 持续监控\n- 宏观：\n    - 持续汇总分析，了解各网的运行情况\n    - 根据各网的运行情况判断隔离措施的有效性\n    - 通过汇总分析的结果判断仍然受影响的终端的规模\n    - 发现重要用户及时通报解决\n    - 适当的时候解除封锁措施\n\n### 第六阶段：跟踪——还会有第二次吗\n\n- 关注系统恢复以后的安全状况，特别是曾经出问题的地方\n- 建立跟踪文档，规范记录跟踪结果\n- 对响应效果给出评估\n- 对进入司法程序的事件，进行进一步的调查，打击违法犯罪活动\n- 事件的归档与统计\n    - 处理人\n    - 时间和时段\n    - 地点\n    - 工作量\n    - 事件的类型\n    - 对事件的处置情况\n    - 代价\n    - 细节\n\n----------------\n\n## 应急预案的编制和管理\n\n---\n\n### 应急响应预案的制定\n\n- 制定应急响应预案的原则\n    - 首先，必须集中管理应急响应预案的版本和发布。 \n    - 其次，为了建立有效的版本控制体系，必须建立规范的应急响应预案的问题提交、解决、更新、跟踪、发布的渠道和流程。 \n    - 第三，建立相关的保密管理规定，保证应急响应预案中涉及的秘密信息得到保护。 \n    - 第四，应急响应预案在内容管理方面应注意内容的分布和粒度，可根据版本和内容的更新频度将应急响应的内容进行适当的分布。 \n    - 第五，建立合理的应急响应预案的保管制度，强调存放的安全性和易取得性。 \n\n\n- 成功预案的特点\n    - 清楚、简洁\n    - 高级管理层支持/组织承诺\n    - 不断改进和更新的恢复策略\n    - 及时的更新维护\n    - 组织职责分工明确\n    - 保留、备份和异地存储计划\n    - 完整记录并定期演练\n    - 风险得到管理\n    - 弱点得到优先重视\n    - 灵活、可适应\n\n  ---\n\n### 应急响应预案的教育、培训和演练\n\n- 在灾难来临前使相关人员了解熟悉恢复流程\n- 使应急响应预案得到理解并可以使用\n- 促进应急响应预案活动、更新、实用\n- 展示恢复的能力\n- 达到法律和内部审计要求\n\n---\n\n### 演练与演习的类型\n\n- 演练和演习的主要方式有：\n    - 桌面演练；\n    - 模拟演练；\n    - 实战演练等\n- 根据演练和演习的深度，可分为：\n    - 系统级演练；\n    - 应用级演练；\n    - 业务级演练等\n- 根据演练和演习的准备情况，可分为：\n    - 计划内的演练和演习；\n    - 计划外的演练和演习等\n\n---\n\n### 预案维护管理\n\n- 核对预案的功能性\n- 验证预案文档的精确性和完整性\n- 分发更新的文档\n    - 文档计划分发和发布流程\n    - 确保相关的团队收到更新的文档\n- 依靠维护来改变管理流程\n- 提供培训作为持续维护预案的一部分\n    - 为与应急响应的相关人员开展定期培训，如：复习进修课程或灾难备份研讨会\n    - 指派培训责任，如：部门经理要确保员工被送去参加培训\n- 完成时报告预案维护情况\n- 毁掉旧应急响应预案的复印件或电子版本\n\n---\n\n### 预案变更管理\n\n- 业务操作的增长或变化\n    - 如：新的分支、产品和业务功能的增加\n- 公司所有权的变化\n- 关键人员的变化\n- 硬件配置的变化\n- 使用新操作系统\n- 预案审核和演练后\n- 软件/应用软件的变化\n- 新的法律或审计要求\n- 定期审核和更新——如：每年两次\n- 《应急预案管理制度》\n- 应急预案变更记录\n\n-------\n\n## 应急响应体系建立流程\n\n![应急响应计划编制](/images/2018/08/04.png)\n\n### 信息安全应急响应计划编制方法\n\n#### 总则\n\n- 编制目的\n- 编制依据\n- 适应范围\n- 工作原则\n\n#### 角色及职责\n\n- 应急响应领导小组\n- 应急响应技术保障小组\n- 应急响应专家小组\n- 应急响应实施小组\n- 应急响应日常运行小组\n\n#### 预防和预警机制\n\n检测、 预测、 预警，做到 早发现、早报告、早处置\n\n#### 应急响应流程\n\n![应急响应流程](/images/2018/08/05.png)\n\n- 事件通告\n1. 信息通报\n\n<br>\n**信息通报分为组织内信息通报和组织外信息通报两部分**。组织内信息通报的目的是在信息安全事件发生后迅速通知应急响应日常运行小组，并根据评估结果迅速通知所有相关人员，从而快速有序的实施应急响应计划。组织外信息通报目的是将相关信息及时通报给受到负面影响的外部机构、互联的单位系统以及重要用户，同时根据应急响应的需要，应将相关信息准确通报给相关设备设施及服务提供商（包括电信、电力等）等外部组织，以获得适当的应急响应支持。值得注意的是对外信息通报应符合组织的对外信息发布策略。\n\n2. 信息上报\n\n<br>\n信息安全事件发生后，应按照相关规定和要求，及时将情况上报相关主管或监管单位/部门。\n\n3. 信息披露\n\n<br>\n信息发布的目的是避免信息安全事件影响被误传，同时规范组织内人员信息披露，保证信息的一致性。因此，信息安全事件发生后，应根据信息安全事件的严重程度，指定特定的小组及时向新闻媒体发布相关信息，并且指定的小组应严格按照组织相关规定和要求对外发布信息，同时组织内其它部门或者个人不得随意接受新闻媒体采访或对外发表自己的看法。\n\n- 应急响应流程-呼叫树\n\n![应急响应流程-呼叫树](/images/2018/08/06.png)\n\n----\n\n<table style=\"width:100%;\" cellspacing=\"0\" cellpadding=\"2\" align=\"center\" border=\"2\"> \n  <tr> \n    <td rowspan=\"2\"> 小组名称</td> \n    <td rowspan=\"2\"> 姓名</td> \n    <td rowspan=\"2\"> 在小组中职位</td> \n    <td colspan=\"5\" align=\"center\"> 联络信息</td> \n  </tr> \n  <tr> \n    <td>工作电话</td> \n    <td>家庭电话</td> \n    <td>手机</td> \n    <td>电子邮件</td> \n    <td>家庭住址</td> \n  </tr> \n  <tr> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n  </tr> \n  <tr> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n  </tr> \n  <tr> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n  </tr> \n  <tr> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n  </tr> \n  <tr> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n    <td> <br /> </td> \n  </tr>\n  </table>\n\n----\n\n- 信息上报\n\n----\n\n  <table style=\"width:100%;\" cellspacing=\"0\" cellpadding=\"2\" align=\"center\" border=\"2\"> \n   <tbody>\n    <tr> \n     <th colspan=\"2\" align=\"center\"> 重大信息安全事件报告表</th> \n    </tr> \n    <tr> \n     <td colspan=\"2\"> 报告时间： x 年x 月x 日x 时x 分</td> \n    </tr> \n    <tr> \n     <td>单位名称：</td> \n     <td>报告人：</td> \n    </tr> \n    <tr> \n     <td>联系电话：</td> \n     <td>通讯地址：</td> \n    </tr> \n    <tr> \n     <td>传真：</td> \n     <td>电子邮件：</td> \n    </tr> \n    <tr> \n     <td colspan=\"2\"> 发生重大信息安全事件的信息系统名称及用途： </td> \n    </tr> \n    <tr> \n     <td>负责部门：</td> \n     <td>负责人：</td> \n    </tr> \n    <tr> \n     <td colspan=\"2\"> 重大信息安全事件的简要描述（如以前出现过类似情况也应加以说明）： </td> \n    </tr>\n    <tr> \n     <td colspan=\"2\"> 初步判定的事故原因： </td> \n    </tr>\n    <tr> \n     <td colspan=\"2\"> 当前采取的措施： </td> \n    </tr>\n    <tr> \n     <td colspan=\"2\"> 本次重大信息安全事件的初步影响状况： </td> \n    </tr>\n    <tr> \n     <td>影响范围：</td> \n     <td>严重程度：</td> \n    </tr>\n    <tr> \n     <td>值班电话：</td> \n     <td>传真：</td> \n    </tr> \n   </tbody>\n  </table>\n\n----\n\n- 事件分类与定级\n\n要确定信息安全事件后如何实施应急响应计划，对系统损害性质和程度的评估是非常重要的。这个损害评估应该在能够确保人员安全这个最优先任务的前提下尽快完成。所以，如果可能，应急响应日常运行小组是第一个得到事件通知的小组。损害评估规程对于不同的系统是不同的，但是应该涉及到以下领域：\n1. 造成紧急情况或中断的原因；\n1. 潜在的附加中断或损失；\n1. 受到紧急情况影响的区域；\n1. 物理构架（如计算机室结构的完整性、电源、电信以及制热、通风和空调的情况）的状况；\n1. 系统设备的总量和功能状态（如具备完整功能、具备部分功能或丧失功能）；\n1. 系统设备及其存货的损失类型（如水害、水灾或热能、物理以及电涌影响）；\n1. 被更换的项目（如硬件、软件、固件或支持材料）；\n1. 估计恢复正常服务所需的时间。\n\n- 我国信息安全事件分类方法\n\nGB/Z 20986-2007《信息安全事件分级分类指南》\n- 有害程序事件MI\n- 网络攻击事件NAI\n- 信息破坏事件IDI\n- 信息内容安全事件ICSI\n- 设备设施故障FF\n- 灾害性事件DI\n- 其他信息安全事件OI\n- 分级要素\n    - 系统损失\n    - 信息系统重要程度\n    - 社会影响\n\n**特别重大事件(I级）**\n\n特别重大事件是指能够导致特别严重影响或破坏的信息安全事件，包括以下情况： \n- 会使特别重要信息系统遭受特别严重的系统损失  \n- 产生特别重大的社会影响 \n\n**重大事件(II级）**\n\n重大事件是指能够导致严重影响或破坏的信息安全事件，包括以下情况： \n- 会使特别重要信息系统遭受严重的系统损失、或使重要信息系统遭受特别严重- 的系统损失\n- 产生重大的社会影响\n\n**较大事件(III级）**\n\n较大事件是指能够导致严重影响或破坏的信息安全事件，包括以下情况：\n- 会使特别重要信息系统遭受较大的系统损失、或使重要信息系统遭受严重的系统损失，一般信息系统遭受特别严重的系统损失\n- 产生较大的社会影响\n\n**一般事件(IV级）**\n\n一般事件是指不满足以上条件的信息安全事件，包括以下情况： \n- 会使特别重要信息系统遭受较小的系统损失、或使重要信息系统遭受较大的系统损失，一般信息系统遭受严重或严重以下级别的系统损失\n- 产生一般的社会影响\n\n#### 应急启动\n\n- 启动原则——快速、有序；\n- 启动依据——一般而言，对于导致业务中断、系统宕机、网络瘫痪等突发/重大信息安全事件应立即启动应急。但由于组织规模、构成、性质等的不同，不同组织对突发/重大信息安全事件的定义可能不一样，因此，各组织的应急启动条件可能各不相同。启动条件可以基于以下方面考虑：人员的安全和/或设施损失的程度；系统损失的程度（如物理的、运作的或成本的）；系统对于组织使命的影响程度（如保护资产的关键基础设施）；预期的中断持续时间等。只有当损害评估的结果显示一个或多个系统启动条件被满足时，应急响应计划才应被启动。\n- 启动方法——由应急响应领导小组发布应急响应启动令。\n\n#### 应急处置\n\n- 恢复顺序<br>\n当恢复复杂系统时，恢复进程应该反映出BIA中确定的系统优先顺序。恢复的顺序应该反映出系统允许的中断时间，以避免对相关系统及其应用的重大影响。\n- 恢复规程<br>\n为了进行恢复操作，应急响应计划应提供恢复业务能力的详细规程。规程应被设定给适当的恢复小组并且通常涉及到以下行动： \n    1. 获得访问受损设施和／或地理区域的授权； \n    1. 通知相关系统的内部和外部业务伙伴； \n    1. 获得所需的办公用品和工作空间； \n    1. 获得安装所需的硬件部件； \n    1. 获得装载备份介质； \n    1. 恢复关键操作系统和应用软件； \n    1. 恢复系统数据； \n    1. 成功运行备用设备。 \n\n#### 后期处置\n\n- 信息系统重建<br>\n在应急处置工作结束后，要迅速采取措施，抓紧组织抢修受损的基础设施，减少损失，尽快恢复正常工作。\n通过统计各种数据，查明原因，对信息安全事件造成的损失和影响以及恢复重建能力进行分析评估，认真制定恢复重建计划，迅速组织实施信息系统重建。\n- 应急响应总结<br>\n应急响应总结是应急处置之后应进行的工作，具体工作包括：\n    1. 分析和总结事件发生原因；\n    1. 分析和总结事件现象；\n    1. 评估系统的损害程度；\n    1. 评估事件导致的损失；\n    1. 分析和总结应急处置记录；\n    1. 评审应急响应措施的效果和效率，并提出改进建议；\n    1. 评审应急响应计划的效果和效率，并提出改进建议。\n\n\n#### 信息安全事件应急响应总结模板\n\n\n  <table style=\"width:100%;\" cellspacing=\"0\" cellpadding=\"2\" align=\"center\" border=\"2\"> \n   <tbody>\n    <tr> \n     <th colspan=\"2\" align=\"center\"> 信息安全事件应急响应结果报告表 </th> \n    </tr> \n    <tr> \n     <td colspan=\"2\"> 原事件报告时间： x 年x 月x 日x 时x 分</td> \n    </tr> \n    <tr> \n     <td colspan=\"2\"> 备案编号： x 年x 月x 日x 第 x 号</td> \n    </tr> \n    <tr> \n     <td>单位名称：</td> \n     <td>报告人：</td> \n    </tr> \n    <tr> \n     <td>联系电话：</td> \n     <td>通讯地址：</td> \n    </tr> \n    <tr> \n     <td colspan=\"2\"> 信息系统名称及用途： </td> \n    </tr>\n    <tr> \n     <td colspan=\"2\"> 已采用的安全措施： </td> \n    </tr>\n    <tr> \n     <td colspan=\"2\"> 信息安全事件的补充描述及最后判定的事故原因： </td> \n    </tr>\n    <tr> \n     <td colspan=\"2\"> 本次信息安全事件的初步影响状况： </td> \n    </tr> \n    <tr> \n     <td>事后结果：</td> \n     <td>影响范围：</td> \n    </tr> \n    <tr> \n     <td colspan=\"2\"> 严重程度： </td> \n    </tr>\n    <tr> \n     <td colspan=\"2\"> 本次信息安全事件的主要处理过程及结果： </td> \n    </tr>\n    <tr> \n     <td colspan=\"2\"> 针对此类信息安全事件应采取的保障信息系统安全的措施和建议： </td> \n    </tr>\n    <tr> \n     <td colspan=\"2\" align=\"center\"> 报告人签名： </td> \n    </tr>\n   </tbody>\n  </table>\n\n---\n\n### 应急响应保障措施\n\n- 人力保障\n    - 管理人力\n    - 技术人力\n\n- 物质保障\n    - 财力\n    - 交通运输\n    - 通信\n\n- 技术保障\n    - 应急响应技术支持\n    - 事件监控与预警\n    - 应急技术储备\n\n### 附件\n\n- 具体的组织体系结构及人员职责\n- 应急响应计划各小组成员的联络信息\n- 供应商联络信息，包括离站存储和备用站点的外部联系点\n- 系统恢复或处理的标准操作规程和检查列表\n- 支持系统运行所需的硬件、软件、固件和其它资源的设备和系统需求清单\n- 供应商服务水平协议（SLA）、与其它机构的互惠协议和其它关键记录\n- 备用站点的描述和说明\n- 在计划制定前进行的BIA，包含关于系统各部分相互关系、风险、优先级别等\n- 应急响应计划文档的保存和分发方法\n\n## 应急响应工作机构图\n\n![应急响应工作机构图](/images/2018/08/07.png)\n\n### 职责示例\n\n**应急响应领导小组：**<b1. 应急响应领导小组是信息安全应急响应工作的组织领导机构，组长应由组织最高管理层成员担任。领导小组的职责是领导和决策信息安全应急响应的重大事宜，主要如下： \n1. 对应急响应工作的承诺和支持，包括发布正式文件、提供必要资源（人财物）等；\n1. 审核并批准应急响应策略；\n1. 审核并批准应急响应计划；\n1. 批准和监督应急响应计划的执行；\n（1. 启动定期评审、修订应急响应计划；\n1. 负责组织的外部协作工作。\n\n**应急响应组（IRT ）**\n\n- 什么是应急响应组（IRT ）\n    - 应急响应组就是机构可以借助的网络安全专业组织。\n- 为什么需要成立应急响应组\n    - 容易协调响应工作\n    - 提高专业知识\n    - 提高效率\n    - 提高先期主动防御能力\n    - 更加适合于满足机构的需要\n    - 提高联络功能\n    - 提高处理制度障碍方面的能力\n\n\n## 从应急组织到应急体系：信息安全保障的必要条件\n\n- 现实表明，单一的应急组织已经不能应对当今的网络安全威胁，我国的应急体系正是在实际工作的经验总结中逐渐形成的：平台从点到环到面；应急体系从点到树到网\n- “现实世界中发生的任何事情，在网络世界中都可以找到与之对\n应的事件”\n- SARS 事件反映出社会防疫应急体系的重要\n- 红色代码、尼姆达、SQL 杀手、口令蠕虫等具有和现实世界中的疫病相同的特点\n- 处理方式也具有同样的特点：隔离--- 分析--- 治疗\n- 不同之处：“病人”不自知；隔离缺乏法律依据或技术手段；应\n- 急缺乏成熟体系和工作制度…. .\n\n## 国际信息安全应急响应组织\n\n- 美国计算机紧急事件响应小组协调中心           （Computer Emergency Response Team/Coordination Center, CERT/CC）\n- 事件响应与安全组织论坛（Forum of Incident Response and Security Teams, FIRST）  \n- 亚太地区计算机应急响应组（Asia Pacific Computer Emergency Response Team, APCERT） \n- 欧洲计算机网络研究教育协会（Trans-European Research and Education Networking Association, TERENA) \n- 国家计算机网络应急技术处理协调中心        （National Computer network Emergency Response technical Team/Coordination Center of China, CNCERT/CC）\n- 中国教育和科研计算机网紧急响应组(China Education and Research Network Computer Emergency Response Team, CCERT)   \n- 国家计算机病毒应急处理中心 \n- 国家计算机网络入侵防范中心\n- 国家863计划反计算机入侵和防病毒研究中心\n\n## 信息系统应急计划一般过程\n\n- 美国SP800-34 信息技术系统应急计划/预案指南：七步走\n    - 第一步：制定应急计划/预案策略条款\n    - 第二步：进行业务影响分析\n    - 第三步：确定防御性控制\n    - 第四步：制定恢复策略\n    - 第五步：IT应急计划/预案的制定\n    - 第六步：计划/预案的测试、培训和演习\n    - 第七步：计划/预案的维护\n\n\n![七步走](/images/2018/08/08.jpg)"
  },
  {
    "path": "docs/4.构建企业安全/1-内功修炼第一步-挖漏洞.md",
    "content": "\n# 01.内功修炼第一步：挖漏洞\n\n作者：Lost Maniac\n\n协作：\n\n-----\n\n未完成"
  },
  {
    "path": "docs/4.构建企业安全/2-内功修炼第二步-引起重视.md",
    "content": "\n# 02.内功修炼第二步：引起重视\n\n作者：Lost Maniac\n\n协作：\n\n\n-----\n\n未完成"
  },
  {
    "path": "docs/4.构建企业安全/3-互联网安全运营的思考.md",
    "content": "\n# 03.互联网企业安全运营的思考\n\n作者：Johnathan\n协作：\n---- \n\n## 1.信息安全运营的概念\n\n信息安全运营，简单理解就是让信息安全在企业（互联网企业，下文同）中跑起来。具体来讲就是依据信息安全管理和技术，围绕企业核心保护对象，采取科学的管理措施，将人员、技术、流程按照可以量化考核的指标有机结合，让安全在组织内部透明、顺畅的流转，同时增强企业在外部的安全影响力。\n\n## 2.信息安全运营的价值\n\n在企业中，信息安全初期安全工作主要是建立安全组织，构建技术抓手，包括不限于采购安全设备，开发平台等。但是从网络层、主机层、应用层、数据层都部署了一系列安全设备或者安全软件保证业务稳定运行，但是安全情况还是没有得到改善，安全问题和安全事件依然频繁发生，安全部门和业务部门不能形成良好的协作，其根本的原因就是没有进行有效的安全运营。\n没有安全运营就没有办法建立安全部门在公司内部的影响力，对外不能构建安全形象和安全品牌，安全部门逐渐沦为成本部门，只能依靠合规驱动安全工作开展。\n\n## 3.安全运营工作的要点\n\n列举我能想到一些安全运营的思路，抛砖引玉，主要有以下几个点：\n\n### 3.1.夯实内功\n\n提到夯实内功，主要是要在安全部门内部建立内部自恰和闭环的安全运行机制。建章立制略过，重点说一下偏技术方面的内容。\n\n* 1.风险发现\n\n* * 风险发现包括风险评估、外部安全通告、安全设备发现、新型安全攻击手段；\n\n---\n\n* 2.风险预警\n\n* * 安全事件预警；\n* * 安全漏洞预警；\n* * 安全监控预警；\n\n---\n\n* 3.风险处置\n\n* * 应急流程。\n* * 安全策略变更。\n* * 升级安全补丁。\n\n---\n\n* 4.配置变更\n\n* * 安全域内设备的增、删、改变更。\n* * 对外开发端口管理。\n* * 安全补丁的管理。\n\n---\n\n* 5.持续改进（一页纸）\n\n* * 改进发现手段，确保没有死角。\n* * 改进预警机制，人员、事件、配合的事件维度。\n* * 改进风险应急流程，风险处置协作。\n* * 持续优化、梳理安全域策略、区域间端口、安全补丁升级流程。\n\n\t通过风险发现、风险预警、风险处置、配置变更直到持续改进，一定要借助平台（类似opensoc)能力实现，比如工单流、审批流、统计、分析、指标、告警等等。\n\t安全运营工作的量化，可以考核、可以对比分析是做好运营的基础。\n\n### 3.2.建立渠道\n\n* 1.沟通渠道\n\n* * 对外沟通渠道SRC的运营\n* * 对内建立安全接口人组织的运营\n\n---\n\n* 2.展示渠道\n\n* * 对外组织活动、会议的发布渠道\n* * 对内组织活动、会议的沟通渠道\n\n---\n\n* 3.汇报渠道\n\n* * 事件分级汇报渠道\n* * 审批事件沟通渠道\n\n---\n\n### 3.3.充分融入\n\n客观讲，业务部门永远是一个公司生存发展的根本，安全应该是主动了解业务，融入业务，给业务赋能，才能实现业务与安全的双赢。\n让业务了解，明白信息安全的重要性。让安全知道业务的痛点，信息安全保障业务调用安全，实现安全时候一定是透明化、便捷化和无感知的。\n安全一定要在业务便利性和安全性中间找到一个平衡点。\n## 4.后记\n本网站致力于推广SDL的落地，但是在工作实践中，如果没有一个项目管理团队配合，实践起来成本会大大增加。因此，在本文后续的迭代更新中，会尽量从一个更宽阔的视角来阐述SDLC如何通过安全运营在运营、产品、技术等等环节的落地，包括如何提升安全在公司的影响力和对外安全品牌形象。\n\n"
  },
  {
    "path": "docs/4.构建企业安全/4-如何利用Flink实现超大规模用户行为分析.md",
    "content": "# 4.如何利用Flink实现超大规模用户行为分析\n\n作者：瀚思科技\n\n## 网络安全中的用户行为分析\n\n用户行为分析到底是什么？简而言之，其通过分析用户数据（例如交易数据，用户登录数据），找出异常行为以检测外部及内部人士的攻击活动。举例来说，外部攻击通常是由外部黑客通过破解 VPN 密码并夺取员工帐户的方式实现。而内部攻击则往往表现为心存不满的或者即将离职的员工对敏感信息的窃取。我们需要分析的源文件通常表现为多种数据类型，例如服务器数据、网络数据、数据库数据、应用程序数据、安全数据等。传统的用户行为分析系统通常以离线批处理模式根据既定规则对这些数据进行分析。而如今的最新趋势则倾向于添加某种形式的机器学习方案，从而利用在线 / 流式处理，对实时数据进行分析以区分威胁行为与正常行为。\n\n## 实时超大规模用户行为分析的技术挑战\n\n实际应用中，由于部分技术挑战的存在，目前机器学习模型在这一领域中尚未能带来可观的助益。此类挑战具体包括：\n\n1. 输入信息规模过大（往往包含来自十余个领域的上万名独立用户）;\n2. 实际需求往往需要以实时方式检测攻击活动（例如在反欺诈场景中，需要实时监控用户的交易数据）;\n3. 检测逻辑需要将黑名单、业务逻辑规则以及机器学习算法加以结合 ;\n4. 检测逻辑需要以近实时方式进行定制化调整。\n\n那么，我们该如何解决上述挑战？又为何选择 Flink？\n\n首先我们需要一个吞吐量大且资源消耗低效率高的流处理引擎。这一点 Flink 作为新一代的流处理引擎完全符合我们的需求。其次，面对不同的用户数据格式，我们必须支持多种数据源，这一点上 Flink 内置的对多种数据源的支持（CSV，Kafka，Hbase，Text，Socket 数据等）也为用户数据的接入提供了便利。第三，Flink 内置的 RocksDB 数据存储格式使其数据处速度快且资源消耗少。第四，Flink 强大的窗口机制（包括翻转窗口，滑动窗口，两者的组合，全窗口以及用户自定义窗口）可以满足复杂的业务逻辑，使得用户可以编写复杂的业务规则。同时 Flink 对算子（operator）的高可控性，使得用户可以灵活添加删除或更改算子。\n\n下面来看我们这套解决方案的具体架构。\n\n![Flink架构](/images/4.构建企业安全/4-如何利用Flink实现大规模用户行为分析/01.jpg)\n\n如大家所见，我们在左侧列出了作为输入信息的多种不同的数据类型。中部位置为核心引擎，而 Flink 则处于底部。上方为三种 ETL 类型：统计指标、实体关系与序列。我们可以将这些 ETL 类型转换为由 Drools 引擎运行并配合部分机器学习算法的 Scenario 规则。同时在生产环境当中需要为用户提供良好的 Web 界面。因此，我们设计出这样一套界面以帮助用户进行规则配置、响应安全事件并对数据进行可视化展示。\n\n## Drools 规则引擎在 CEP 中的应用\n\n规则引擎方面我们有两个选择：Flink 原生 CEP 和 Drools。那么两者各有什么优势和劣势呢？\n\nFlink CEP 是一套极具通用性、易于使用的实时流式事件处理方案。作为 Flink 的原生组件，省去了第三方库与 Flink 配合使用时可能会导致的各种问题。但其功能现阶段看来还比较基础，不能表达复杂的业务场景，同时它不能够做到动态更新。而 Drools 作为一个完备的规则引擎，在功能全面性上更胜一筹，同时其动态更新的设计方针，能够保证我们在无需对系统进行重新编译及重启的前提下将其部署在运行中的系统当中。\n好的，接下来我们将深入探讨如何利用 Drools 来实现用户行为分析系统。\n\n### Drools 究竟是什么？\n\nDrools 是一套业务规则管理系统（简称 BRMS），且可基于规则引擎实现向前与向后推理。这是一套基于 JVM 的系统，其语义与 Java 非常相似。\n\n```java\npackage com.example;\nimport com.example.Person\n\nrule \"example rule\"\nwhen\n    p: Person(name == \"Michael\")\nthen\n    p.name = \"other\";\n    System.out.println(p.name);\nend\n\ndeclare EventA\n    @role( event )\nend\n\nrule \"Timeout EventA\"\nwhen\n    $a1 : EventA()\n    $a2 : EventA(this after[5s,10s] $a1)\nthen\n    retract($a1);\nend\n```\n\nDrools 的最大优势在于，它语法规则简单，类似 Java，因此编写门槛不高、能够无缝化与 Java 集成，且用户可以对 Drools 规则进行动态配置。但这套方案也存在着自己的不足，例如其内置聚合功能速度缓慢，不适合我们自身或者客户使用场景下的大量聚合操作任务。另外，其内置事件序列处理机制也需要消耗大量内存资源。\n\n作为常用的业务场景，我们需要将三种 ETL 类型翻译成对应的 Drools 规则。具体来讲，事件 / 数据中的每一行都需要由三种 ETL 类型进行处理：统计指标、实体关系与序列，并借此将内容转换为实际行为。\n\n    统计指标：特定翻转窗口内的聚合值，例如一小时内的登录次数。\n\n    实体关系：两个实体之间的关联，例如用户使用哪台设备。\n\n    序列：事件经过过滤并按时间戳排序后，被转换为有序状态。\n\n以上三种 ETL 皆在场景规则当中进行定义，以 drools 规则文件的形式被部属到系统中。如何做到这一点呢，Flink 的 CoFlatMapFunction 提供了完美的解决方案，我们可以利用该功能同时处理两种数据流：事件流与规则流。\n\n听起来不错，很多朋友可能认为 Flink 与 Drools 的配合可能完美无瑕。但事实并非如此——大家在实际使用中可能遇到以下问题：\n\n1. 需要在特定时段之内维持原有窗口状态（作为 Drools 规则引擎的中间结果）。\n2. Flink 内置的窗口机制会在窗口结束时发送输出结果并清除窗口状态。\n3. Flink 内置的 RocksDB 后端会在窗口清除时删除所有记录。\n4. 来自 Flink 的结果会被不断的注入 Drools 规则引擎进行规则匹配，事件一多就会快速耗尽内存资源。\n\n当然，我们可以对 Flink 进行修改以克服上述问题。举例来说，我们可以为 RocksDB 添加“TTL“属性，保证其不再直接删除各条目。另外，我们还可以为内存内能够容纳的条目数量设定阈值，同时及时清除未使用的条目，从而优化 Drools 的内存管理。\n\n### Flink 原生 CEP 组件\n\n以上是使用 Drools 的方案，那么我们是否只能选择 Drools？还有没有其它更好的解决方案？\n\n就目前来看，我们也可以使用 Flink 1.4 中提供的 Flink CEP 新特性。\n\nFlink 近期推出了一系列新功能，我们可以利用其解决“无法热部署“的难题。\n\n1. 触发保存点、取消作业，更新规则，恢复作业。\n2. 保存点内惟一标识运算符状态。\n3. [FLINK-6927] 在 CEP Flink 1.4 中支持模式组。\n4. [FLINK-7129] 动态变更模式开放发布。\n利用上述新特性，我们可以设计出一套新的 Flink CEP 系统，其工作流程如下：\n\n![Flink架构-CEP 组件](/images/4.构建企业安全/4-如何利用Flink实现大规模用户行为分析/02.jpg)\n\n用户利用我们定义的语言编写场景规则，此后我们将这些规则翻译为 Java 代码。接下来，我们对代码进行编译并打包为 jar 文件。最后，我们触发保存点并撤销当前正在运行的作业，部署新规则 jar 而后恢复该作业。\n\n为了将这一思路付诸行动，我们进行了具体实验并发现了一些有趣的现象。如果我们为每种规则创建一条独立的规则流，那么规则数量一旦过多（上千）即会导致初始化缓慢以及内存不足的问题。\n\n那么如何将多条规则纳入同一流？\n\n1. CEP API 仅允许单规则 = 单流\n2. Flink CEP 1.4 提供 GroupPattern 将多种规则合而为一\n3. 目前尚无法对多模式进行优化\n\n因此总结来讲，这套解决方案拥有以下优势与弊端：\n\n优势:\n\n1. 易于实现，代码量仅为 Drools 版本的五分之一。\n2. 可扩展性与并发性更出色，不存在单一大负载的算子。\n3. 易于获取各模式中的运行时指标 。\n\n弊端:\n\n1. 保存点与恢复部署流程会造成数秒延迟。"
  },
  {
    "path": "docs/4.构建企业安全/5-APT 攻击基础科普.md",
    "content": "# 5-APT攻击基础科普\n\n作者：backlion\n\n## APT 的历史起源背景\n\nAPT 这个词汇最早起源于:2005 年英国和美国的 CERT 组织发布了关于有 针对性的社交工程电子邮件，放弃特洛伊木马以泄露敏感信息的第一个警告，尽管没有使用“APT”这个名字。但 “先进的持续威胁”一词被广泛引用，2006 年的美国空军 Greg Rattray 上校经常被引用为创造该术语的个人。后来，在 Stuxnet 震网事件就是专门针对伊朗的核计划的黑客攻击就是一个 APT 攻击例 子。在计算机安全领域以及越来越多的媒体中，APT 这个术语几乎总是用来指 向针对政府，公司和政治活动家的黑客攻击的高级持续模式，而且也延伸到涉及 到群体这些攻击背后。作为一个术语，高级持续威胁(APT)可以被转移焦点到 攻击出现次数。一个常见的误解是 APT 只针对西方国家。西方国家可能会更多地宣传针对西方国家的技术性 APT，但许多国家的行为者都将网络空间安全作 为收集有关个人和群体的情报的手段。在美国，网络司令部的任务是协调美国军 方，应对高级持续网络威胁，也就是 APT 攻击。\n"
  },
  {
    "path": "docs/5.附录/01.相关术语.md",
    "content": "\n# 01.相关术语\n\n作者：mour\n\n协作：Lost Maniac\n\n---\n\n## SDL\n\nSDL是在软件开发过程中帮助开发人员构建更安全的软件并解决安全问题，同时降低开发成本的一套流程方法。\n\n> The Security Development Lifecycle (SDL) is a software development process that helps developers build more secure software and address security compliance requirements while reducing development cost\n\n## ROI\n\n投资回报率（ROI）是指一些资源投资产生的净利润和投资成本之间的比率。高投资回报率意味着投资收益与其成本相比有利。作为绩效衡量指标，ROI用于评估投资效率或比较几种不同投资的效率。从纯粹的经济角度来看，它是将利润与资本投资联系起来的一种方式。投资回报是企业用来确定投资效率或不同投资数量的绩效指标。\n\n## ATT&CK\n\nATT&CK是Adversarial Tactics, Techniques & Common Knowledge的缩写，由MITRE提供的关于对抗战术，技术以及常识性攻防知识\n\n> MITRE’s Adversarial Tactics, Techniques, and Common Knowledge (ATT&CK™) is a curated knowledge base and model for cyber adversary behavior, reflecting the various phases of an adversary’s lifecycle and the platforms they are known to target. ATT&CK is useful for understanding security risk against known adversary behavior, for planning security improvements, and verifying defenses work as expected\n\n## STRIDE\nSTRIDE是由微软的提出的典型的威胁建模方法\n* S: Spoofing(欺骗)\n* T: Tampering(篡改)\n* R: Repudiation(否认)\n* I: Information Disclosure(信息泄露)\n* D: Denial of Service(拒绝服务)\n* E: Elevation of Privilege(提权)\n\n## STIX\n\nSTIX是A structured language for cyber threat intelligence的缩写，目前最新为2.0标准，主要用于交换分享网络威胁情报。\n\n> Structured Threat Information Expression (STIX™) is a language and serialization format used to exchange cyber threat intelligence (CTI).\n\n## 引用\n\n* [应用安全与微软SDL-IT流程](https://blogs.technet.microsoft.com/gcrsec/2008/09/22/sdl-it/)\n* [SDL](https://www.microsoft.com/en-us/sdl)\n* [Adversarial Tactics, Techniques & Common Knowledge](https://attack.mitre.org/wiki/Main_Page)\n* [OWASP](https://www.owasp.org/)\n* [STIX](https://oasis-open.github.io/)\n* [MISP](http://www.misp-project.org/)"
  },
  {
    "path": "docs/5.附录/02.文档变更规范.md",
    "content": "\n# 02.文档变更规范\n\n作者：Lost Maniac\n\n协作：\n\n-----\n\n为了确保大家不会误操作导致问题，特此规范如下\n\n\n### 如何增加大纲内容\n\n\n需要创建问卷调查，详细描述大纲内容需要增加到哪里，详细阐述原因，选项为：同意或不同意  ，投票不得低于20人，得票多的方可增加大纲内容。\n\n---\n\n### 目录规范\n\n目录应该严格按照大纲内容进行命名\n\n目前有\n\n1. SDL介绍\n\n2. SDL规范文档\n\n3. SDL落地方案\n\n4. 快速构建企业安全\n\n5. 附录\n\n\n五个文件夹\n\n另外一个临时文件夹名称用来存放临时文件，经过评审后方可移动到对应目录。\n\n---\n\n### 文件名规范\n\n文件命名每个目录都有对应编号，文件名称应该由编号和题目两个内容组成，中间用半角字符“.”进行分割。例如 “12.安全管理规范”，编号由需要创建文章的文件夹内最大数字加一\n\n---\n\n### 如何添加文章（创建）\n\n---\n首先fork分支到自己本地目录。修改后提交到自己fork的项目。\n\n---\n\n### 如何修改文章\n\n首先fork分支到自己本地目录。修改后提交到自己fork的项目。\n\n\n---\n\n### 获得投票权利\n加入SDL China群内即可获得投票权利\n\n---\n\n### 获得修改权利\n\n加入群聊后，需要提出至少五条文档建议，增加或修改。错别字不在此范围内。\n\n---\n\n### 权限回收\n\n一个月内未对文档作出改进、创建、编辑等操作，会被回收文档编辑权限，重新获得只需要提交一条建议。权限被回收后原则上邮箱不会被收回，作为以前为文档作出贡献的激励。原则上勋章墙不会被撤销。\n\n---\n\n### 不遵循规范处罚办法\n\n第一次不遵循规范，取消文档编辑权限\n\n第二次不遵循规范，取消投票权利\n"
  },
  {
    "path": "docs/5.附录/03.GitHub工作流.md",
    "content": "\n# 03.Github工作流\n\n作者：Pa55w0rd\n\n\n\n\nfork项目到自己账户，修改后提交给主分支，审核后即可展示。\n提交可以多种方式，如web、命令、客户端，这里演示web提交方式\n提交SDL落地方案-产品设计\n1. 选择相应的文件,所有文档都在**_post**目录下\n```\nsdlchina-web/_posts/3.SDL落地方案/2018-08-17-SDL-3-产品设计.md\n```\n\n选择**edit**或者**create new file**，文件名必须要符合: ```YEAR-MONTH-DAY-title.md```\n\n![图片1](/images/2018/10/github/1.png)\n\n2. 编辑文档\n所有博客文章顶部必须有一段YAML头信息(YAML front- matter),文章可以使用markdown格式编写\n```\n---\ndate: 2018-08-17\n# 03.产品设计\ncategories:\n  - 3.SDL落地方案\ndescription: 和研发同学进行产品设计定框架部分应该怎么去执行\ntype: Document\n---\n```\n\n编辑完成之后点击**commit changes**(同命令```git add . && git commit -m \"添加产品设计\" && git pusht origin master```)\n\n![图片2](/images/2018/10/github/2.png)\n\n3. 提交pull请求\n点击**New pull request**\n\n![图片3](/images/2018/10/github/3.png)\n\n检查没有问题，点击**Create pull request**\n\n![图片4](/images/2018/10/github/4.png)\n\n提交成功，等待管理员**Merge**之后就成功了\n\n![图片5](/images/2018/10/github/5.png)\n"
  },
  {
    "path": "docs/5.附录/04.NAXSI安装测试与简介.md",
    "content": "\n# 04.NAXSI安装测试与简介\n\n\n# NAXSI安装测试与简介\n\n## 一、安装和测试\n安装环境Ubuntu Server 16.04。\n\n### 1、安装ElasticSearch和Kibana作为日志存储和展示工具。\nubuntu环境首先安装jdk：\n```\napt install openjdk-8-jre-headless\n```\n\nElasticSearch和Kibana官方当前最新版本为6.4.2，但是nxapi工具目前只能支持到5.x系列，所以从官网https://www.elastic.co/downloads/past-releases ，分别找到Kibana和ElasticSearch的5.6.12版本的下载链接。然后下载、安装如下：\n\n```\nwget https://artifacts.elastic.co/downloads/kibana/kibana-5.6.12-linux-x86_64.tar.gz\nwget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.6.12.tar.gz\ntar zxf elasticsearch-5.6.12.tar.gz\ntar zxf kibana-5.6.12-linux-x86_64.tar.gz\n```\n\n#### 配置和启动ElasticSearch\nElasticSearch默认需要使用非root用户运行，所以：\n```\nchown -R linux:linux kibana-5.6.12-linux-x86_64/ elasticsearch-5.6.12/\nsu linux\n```\n修改ElasticSearch配置参数：\n```\ncd elasticsearch-5.6.12 && vi config/elasticsearch.yml\n将参数修改为：\nnetwork.host: 0.0.0.0\nhttp.port: 9200\n```\n\n增大max_map_count内核参数，然后启动服务：\n```\nsudo sysctl -w vm.max_map_count=262144\n./bin/elasticsearch &\n```\n\n验证节点是否启动正常：\n```\ncurl 127.0.0.1:9200/_cat/nodes?pretty\n172.18.42.126 2 96 9 0.67 0.53 0.28 mdi * dYtak9q\n```\n\n#### 配置和启动Kibana\n```\ncd ../kibana-5.6.12-linux-x86_64/\nvi config/kibana.yml\n```\n将参数修改为：\n```\nserver.port: 5601\nserver.host: \"0.0.0.0\"\nelasticsearch.url: \"http://localhost:9200\"\n```\n启动服务：\n```\n./bin/kibana &\n```\n通过浏览器访问 http://172.18.42.126:5601 来验证服务是否启动正常。\n\n\n### 2、安装 Nginx和NAXSI\n从http://nginx.org/en/download.html 下载nginx源码包：\n```\nwget http://nginx.org/download/nginx-1.14.0.tar.gz\n```\n\n从https://github.com/nbs-system/naxsi/releases 下载naxsi：\n```\nwget https://github.com/nbs-system/naxsi/archive/0.56.tar.gz\n```\n\n#### 编译安装\n\n```\ntar zxf nginx-1.14.0.tar.gz\nmv 0.56.tar.gz naxsi-0.56.tar.gz && tar zxf naxsi-0.56.tar.gz ; \ncd nginx-1.14.0\n./configure --prefix=/opt/naxsi/ --add-module=../naxsi-0.56/naxsi_src/ --with-http_ssl_module \\\n --without-mail_pop3_module --without-mail_smtp_module \\\n --without-mail_imap_module --without-http_uwsgi_module \\\n --without-http_scgi_module\nmake && make intall\n```\n通过上面这种方式，直接将NAXSI编译进nginx中；也可以通过—add-dynamic-module添加NAXSI模块，将NAXSI编译为so库，然后在nginx配置文件中通过load_module /path/to/module.so;加载NAXSI功能；\n\n\n#### 配置\n将NAXSI的默认配置拷贝到nginx配置目录\n```\ncp ../naxsi-0.56/naxsi_config/naxsi_core.rules  /opt/naxsi/conf/naxsi_core.rules\n```\n\n创建存储naxsi告警日志的文件\n```\ncd /opt/naxsi\ntouch logs/naxsi.log \n```\n\n新建配置文件\n```\nvi conf/naxsi.conf\n```\n添加如下内容：\n```\nSecRulesEnabled;\nLearningMode;\nDeniedUrl \"50x.html\";\nCheckRule \"$SQL >= 8\" BLOCK;\nCheckRule \"$XSS >= 8\" BLOCK;\nerror_log /opt/naxsi/logs/naxsi.log;\n```\n\n编辑nginx默认配置文件：\n```\nvi conf/nginx.conf\n```\n首先更改监听端口为8011，然后在http部分添加：\n```\ninclude       /opt/naxsi/conf/naxsi_core.rules;\n```\n在server的location部分添加：\n```\ninclude naxsi.conf;\n```\n\n启动服务：\n```\n./sbin/nginx\n```\n\n验证nginx服务是否启动正常：\n```\ncurl 172.18.42.126:8011/\n```\n\n### 3、测试NAXSI的检测功能\n在一个终端中执行 tail -f /opt/naxsi/logs/naxsi.log 以实时查看NAXSI的日志。\n\n在其他终端发起正常请求 curl 172.18.42.126:8011/ 在日志终端中没有任何输出。\n\n在其他终端发起一个XSS测试请求：\n```\ncurl ‘172.18.42.126:8011/?a=<'\n```\n\n可以看到在日志终端中，实时显示出了NAXSI的一条告警日志：\n```\n2018/10/09 02:49:54 [error] 17938#0: *4 NAXSI_FMT: ip=172.18.42.77&server=172.18.42.126&uri=/&learning=1&vers=0.56&total_processed=4&total_blocked=1&block=1&cscore0=$XSS&score0=8&zone0=ARGS&id0=1302&var_name0=a, client: 172.18.42.77, server: localhost, request: \"GET /?a=< HTTP/1.1\", host: \"172.18.42.126:8011\"\n```\n\n多次发起XSS测试请求，以便制造更多的告警日志：\n```\ncurl ‘172.18.42.126:8011/test1?a=<111111111111'\ncurl ‘172.18.42.126:8011/tset1?a=<222222222222’\ncurl ‘172.18.42.126:8011/test3?a=<333333333333’\ncurl ‘172.18.42.126:8011/test3?a=<444444444444’\ncurl ‘172.18.42.126:8011/test3?a=<555555555555'\n```\n\n### 4、将告警日志输出到ElasticSearch并在Kibana显示\n上面已经将告警日志直接存储在 /opt/naxsi/logs/naxsi.log 文件中；\n进入NAXSI的源代码目录中：\n```\ncd naxsi-0.56/nxapi\n```\n安装nxtool.py依赖的elasticsearch接口驱动：\n```\npip install elasticsearch\n```\n\n#### 编辑配置文件\n源代码目录中 nxapi.json 文件是 nxtool.py 执行时的配置文件，复制一份并编辑：\n```\ncp nxapi.json mytest.json\nvi mytest.json\n```\n修改elasticsearch的版本配置为5：\n```\n\"version\" : \"5\"\n```\n删除其中syslogd相关的部分；\n修改naxsi的配置为：\n```\n\"naxsi\" : {\n \"rules_path\" : \"/opt/naxsi/conf/naxsi_core.rules\"\n},\n```\n\n#### 导入数据\n```\n删除旧索引:\ncurl -XDELETE 127.0.0.1:9200/nxapi\n \n建立新索引:\ncurl -XPUT 127.0.0.1:9200/nxapi\n\n将naxsi的告警日志存储进ElasticSearch:\npython nxtool.py -c mytest.json  —files=/opt/naxsi/logs/naxsi.log\n\n检查ElasticSearch中数据状态，并做汇总分析输出:\npython nxtool.py -c mytest.json -x\n\n验证是否存在nxapi索引:\ncurl 127.0.0.1:9200/_cat/indices/?pretty\n\n查看索引中的内容:\ncurl 127.0.0.1:9200/nxapi/_search?pretty\n```\n\n从浏览器访问Kibana，配置Index pattern为nxapi，即可在Discover中看到数据。\n\n\n\n## 二、NAXSI和nxapi/nxtool\n\n\n### NAXSI\n\nNaxsi是一个第三方Nginx模块，提供WAF功能，NAXSI是“Nginx Anti XSS & SQL Injection”的缩写。\n\nNaxsi灵活强大，社区内对于流行的Web应用程序（如WordPress）有现成的规则， 同时也可以使用Naxsi的学习模式创建自己的规则并微调它们。\n\nNAXSI的核心规则文件是naxsi_core.rules，此文件包含了用于检测恶意攻击的通用签名。通常在nginx配置文件的http部分include这个文件；\n\n另外我们还需要制定我们在自己的策略文件：如上述安装过程的naxsi.conf文件，这个文件包含了具体的防护策略，其中的一些内容如下：\n```\nLearningMode;\nSecRulesEnabled;\nDeniedUrl \"/50x.html\";\n\nCheckRule \"$SQL >= 8\" BLOCK; #策略，当一个请求中SQL注入的分值大于等于8的时候则阻断请求，下面的类似\nCheckRule \"$RFI >= 8\" BLOCK;\nCheckRule \"$TRAVERSAL >= 4\" BLOCK;\nCheckRule \"$EVADE >= 4\" BLOCK;\nCheckRule \"$XSS >= 8\" BLOCK;\n```\n这里是上面的配置指令含义：\n\nLearningMode -启动Naxsi学习模式，只记录，不拦截；只会在Nginx错误日志中出现安全异常日志，而不会阻断请求；这样的非阻塞初始行为是有用的，因为默认规则非常积极可能会产生很多误报；之后，根据这些例外情况（误报），我们将为合法流量创建白名单\nSecRulesEnabled -为server块或位置启用Naxsi\nSecRulesDisabled -为server块或位置禁用Naxsi \nDeniedUrl -被拒绝的请求将被内部转发到这里配置的位置。类似50x文件。\nCheckRule -设置阈值计数器，一旦达到该阈值（例如，SQL计数器为8分），请求将被阻塞\n\n可以在任意location中引用上述策略配置，需要注意，NAXSI的配置需要在location配置的第一行；\ninclude /path/to/naxsi.rules;\n\n规则定义了匹配什么，匹配后如何打分；\n策略定义了是否开启拦截，以及对特定攻击的拦截阀值；\n\n#### Naxsi规则\n \nNaxsi配置的最重要的部分是它的规则。 有两种类型的规则 —— 主规则和基本规则：\n主规则（MainRule）将用于server全局，包含用于检测恶意活动的通用签名\n基本规则（BasicRule）是主要用于白名单误报特征码和其他规则，应用于某个location\n\n下面是一个MainRule的例子：\n```\nMainRule \"str:--\" \"msg:mysql comment (--)\" \"mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie\" \"s:$SQL:4\" id:1007;\n```\nMainRule 是每一个规则的起始指令，类似地，每个规则以id号结束\nstr:在规则的第二部分中，str:意味着该签名是纯字符串；正则表达式可以用指令rx:\nmsg:给出了一些说明信息\nmz:表示match zone，即请求的哪一部分将被检查，这可以是正文，URL，参数等\ns:确定匹配后给某个变量分配的得分。得分被添加到不同的变量，如SQL（SQL攻击），RFI（远程文件包含攻击）等\n\n上述规则（id 1007）与注释\"mysql comments\"意味着如果字符串\"--\"在一个请求（体，参数等）的任何部分被发现，SQL变量加4分；\n\n请求URI（ http://Your_IP/index.html?asd=---- 触发SQL注入告警），你会发现，触发规则1007\n我们需要4个破折号（ -- ）这是因为对于每一对，我们得到4分，SQL链需要8分来阻止请求。因此，只有一对破折号不会有问题，在大多数情况下，合法流量不会受到影响。\n\n上述签名规则的意思是：如果在请求中出现连续的两个中横线，则SQL计数增加4分；\n\n一个特殊规则指令是negative 。 如果签名不匹配，则增加某变量的分数。\n\n看另外一个例子：\n```\nMainRule negative \"rx:multipart/form-data|application/x-www-form-urlencoded\" \"msg:Content is neither mulipart/x-www-form..\" \"mz:$HEADERS_VAR:Content-type\" \"s:$EVADE:4\" id:1402;\n```\n上述规则意思是：如果Content-type请求头既不是multipart/form-data ，也不是application/x-www-form-urlencoded，则匹配（因为有negative），则将EVADE变量加4分。\n\n#### 白名单规则\n白名单是用第二种类型的规则，Naxsi的BasicRule创建的；使用基本规则，可以将已有的另外一个规则的全部或其中一部分列入白名单。\n\n为了演示基本规则的工作原理，让我们回到SQL注入规则（id 1007）\n试想一下，某个文件名有两个破折号，如文件some--file.html，使用规则1007，此文件将增加4分到SQL计数器，这个文件名和结果分数不足以阻止请求，但它仍然是一个误报，可能会导致问题。 例如，如果我们还有一个带有两个破折号的参数，那么请求将触发规则1007。\n\n请求 http://Your_IP/some--file.html?asd=--\n\n您应该在错误日志的输出中看到类似于下面的信息：\n```\n2015/11/14 14:43:36 [error] 5182#0: *10 NAXSI_FMT: ip=X.X.X.X&server=Y.Y.Y.Y&uri=/some--file.html&learning=1&total_processed=10&total_blocked=6&zone0=URL&id0=1007&var_name0=&zone1=ARGS&id1=1007&var_name1=asd, client: X.X.X.X, server: localhost, request: \"GET /some--file.html?asd=-- HTTP/1.1\", host: \"Y.Y.Y.Y\"\n```\n\n为了解决这个误报，我们需要一个白名单，看起来像这样：\n\nBasicRule wl:1007 \"mz:URL\";\n重要的关键词是wl白名单，其次是规则ID，还指定了匹配区域为URL部分；\n这句话的意思是：匹配规则1007的请求，如果匹配到的区域是URL部分，则放过这个请求，即认为这个请求是合法的，不做计数器分值处理。\n\n要应用此白名单，请先为白名单创建新文件：\nvi /etc/nginx/naxsi_whitelist.rules\n然后，将规则粘贴到文件中：\nBasicRule wl:1007 \"mz:URL\";\n如果还有其他白名单，可以一起放在这个文件内，每个一行;\n\n将定义白名单的文件包含到配置中：\nvi /etc/nginx/sites-enabled/default\n```\n        location / {\n                # First attempt to serve request as file, then\n                # as directory, then fall back to displaying a 404.\n                try_files $uri $uri/ =404;\n                # Uncomment to enable naxsi on this location\n                include /etc/nginx/naxsi.rules;\n                include /etc/nginx/naxsi_whitelist.rules;\n        }\n```\n重新加载Nginx：\nsudo service nginx reload\n\n现在，如果你再试一次相同的请求Your_IP/some--file.html?asd=--\n只有asd参数相当于两个破折号会引发4分的SQL计数，但文件名不会;因此，不会在错误日志中看到异常请求\n\n确定错误日志中没有合法请求后，可以禁用Naxsi的学习模式：\n注释掉LearningMode，在指令前加入#即可：\n```\n#LearningMode;\nSecRulesEnabled;\n#SecRulesDisabled;\n```\n最后重新加载Nginx使更改生效：\nservice nginx reload\n现在，Naxsi将阻止任何可疑的请求.\n\n在nginx的每个server段加入 set $naxsi_extensive_log 1; 开启naxsi的扩展日志记录功能，可以记录下具体触发naxsi拦截规则的请求内容，方便后续分析拦截的是攻击请求还是误拦了正常的业务请求。\n\n\n\n### nxapi/nxtool\nnxapi/nxtool的主要功能：\n将NAXSI Events导入到elasticsearch中；\n生成白名单；\nEvent管理；\n对数据库中的信息生产报告；\n\n配置文件\nnxtool的配置信息存储在一个json文件中，源代码目录中包含了一个默认的配置文件nxapi.json。\n\n如果要将NAXSI的Event导入Elasticsearch，需要提前配置好Elasticsearch。\n常用命令：\n./nxtool.py -c nxapi.json —files=/PATH/TO/LOGFILE.LOG #将log文件中的Event导入到ElasticSearch中。\n./nxtool.py -c nxapi.json -x #nxtool从ElasticSearch中读出信息并做汇总统计分析，然后输出\nnxtool同时也支持从FIFO管道文件读入信息转存到ElasticSearch，只需要把naxsi/nginx日志指向对应的管道文件即可。\n\n"
  },
  {
    "path": "docs/6.Project/1-内部钓鱼系统.md",
    "content": "\n# 01.内部钓鱼系统\n\n作者：Lost Maniac\n\n协作：\n\n-----\n\n## 简介\n---\n\n本项目是基于thinkphp写的一个内部钓鱼网站系统。用来测试甲方公司内部钓鱼，请勿用于非法用途。\n\n## 项目源码\n\n本项目托管在GitHub，地址为：https://github.com/SecurityPaper/mail_fishing\n\n## 部署方法\n---\n\n支持**windows**、**linux**、**MAC**。\n\n克隆项目到本地\n```bash\ngit clone https://github.com/MSG-maniac/mail_fishing.git\n```\n部署目录为项目根目录的public目录\n\n具体参考thinkphp部署方法 \n```url\nhttps://www.kancloud.cn/manual/thinkphp5/336757\n```\n\n### 举个栗子\n---\n如果当前终端在/usr/share/nginx目录下\n\n执行命令\n```bash\ngit clone https://github.com/MSG-maniac/mail_fishing.git\n```\n\nnginx配置文件如下\n```nginx\nserver {\n    #默认http请求自动跳转到https\n    listen       80;\n    server_name oa.xxx.com;\n    rewrite ^(.*)$  https://$host$1 permanent;\n}\n\nserver {\n    listen      443 ssl;\n    server_name oa.xxx.com;\n\n    #需要配置证书\n    ssl on;\n    ssl_certificate     /opt/ssl/oa.crt;\n    ssl_certificate_key /opt/ssl/oa.key;\n\n    location / {\n        root   /usr/share/nginx/mail_fishing/public;\n        index index.php  index.html index.htm;\n        if (!-e $request_filename) {\n                rewrite  ^(.*)$  /index.php?s=/$1  last;\n                break;\n        }\n    }\n\n\n    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000\n    #\n    location ~ \\.php$ {\n        root           /usr/share/nginx/mail_fishing/public;\n        fastcgi_pass   127.0.0.1:9000;\n        fastcgi_index  index.php;\n        fastcgi_param  SCRIPT_FILENAME   $document_root$fastcgi_script_name;\n        include        fastcgi_params;\n    }\n}\n```\n\n## 模板文件替换\n\n文件路径\n```file\napplication\\index\\view\\index.html\n```\n模板内需要包含一个html的form表单\n\n默认是一个极简内容页，新模板一定要包含：\n```html\n<form action=\"/index/index/input\" method=\"post\">\n```\n\n仿制页面时候请把静态文件放入到目录,或者自定义目录：\n```\npublic\\static\n```\n\n## 配置数据库\n\n数据库文件在根目录，导入即可：\n```\nmail.sql\n```\n\n配置数据库连接：\n```\n文件路径:\nconfig/database.php\n\n默认如下\n    // 数据库类型\n    'type'            => 'mysql',\n    // 服务器地址\n    'hostname'        => '127.0.0.1',\n    // 数据库名\n    'database'        => 'mail',\n    // 用户名\n    'username'        => 'root',\n    // 密码\n    'password'        => '',\n```\n\n## 部署完成\n\n到此部署完成，可以找邮箱开始给公司同事发邮件了。\n\n## 中招查看\n\n```\nhttp://oa.xxx.com/superhack/index/search?key=fcvxz657o54ewn123cvb432lg\n```\n自己替换域名"
  },
  {
    "path": "docs/6.Project/2-工作流自动化代码审计.md",
    "content": "\n# 02.工作流自动化代码审计\n\n作者：Lost Maniac\n\n协作：\n\n-----\n\n## 简介\n---\n\nsonar\n\n## 项目源码\n\n本项目托管在GitHub，地址为：https://github.com/sdlchina/php_code_audit\n\n## 部署方法\n---\n\n安装文档基于centos 7.x\n\n### 安装PGsql\n\n打开官网安装文档 `https://www.postgresql.org/download/linux/redhat/`\n\n选择要安装的版本为10版本\n\n安装repo源\n\n`yum install https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-centos10-10-2.noarch.rpm`\n\n安装客户端\n\n`yum install postgresql10`\n\n安装服务端\n\n`yum install postgresql10-server`\n\n新建数据库存储目录\n\n`mkdir -p /www/pgsql/data`  //递归方式创建pgsql/data目录\n\n授权目录权限\n\nchown -R postgres:postgres  /www/pgsql/\n\n修改开机启动配置文件\n\n`vim /usr/lib/systemd/system/postgresql-10.service`\n\n-----\n\n```conf\n[Unit]\nDescription=PostgreSQL 10 database server\nDocumentation=https://www.postgresql.org/docs/10/static/\nAfter=syslog.target\nAfter=network.target\n\n[Service]\nType=notify\n\nUser=postgres\nGroup=postgres\n\n# Note: avoid inserting whitespace in these Environment= lines, or you may\n# break postgresql-setup.\n\n# Location of database directory\nEnvironment=PGDATA=/www/pgsql/data/\n\n# Where to send early-startup messages from the server (before the logging\n# options of postgresql.conf take effect)\n# This is normally controlled by the global default set by systemd\n# StandardOutput=syslog\n\n# Disable OOM kill on the postmaster\nOOMScoreAdjust=-1000\nEnvironment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj\nEnvironment=PG_OOM_ADJUST_VALUE=0\n\nExecStartPre=/usr/pgsql-10/bin/postgresql-10-check-db-dir ${PGDATA}\nExecStart=/usr/pgsql-10/bin/postmaster -D ${PGDATA}\nExecReload=/bin/kill -HUP $MAINPID\nKillMode=mixed\nKillSignal=SIGINT\n\n\n# Do not set any timeout value, so that systemd will not kill postmaster\n# during crash recovery.\nTimeoutSec=0\n\n[Install]\nWantedBy=multi-user.target\n```\n\n修改初始化脚本\n\n`vim /usr/pgsql-10/bin/postgresql-10-setup`\n\n-----\n\n```conf\n# Log file for initdb\nPGLOG=/www/pgsql/log/initdb.log\n\n```\n\n-----\n\n对PGsql进行初始化\n\n`/usr/pgsql-10/bin/postgresql-10-setup initdb`\n\n检查目录`/www/pgsql/data`目录下有文件表示初始化成功\n\n开启pgsql服务\n\n`systemctl start postgresql-10.service`\n\n检查pgsql服务\n\n`systemctl status postgresql-10.service`\n\n显示\n\n```linux\n● postgresql-10.service - PostgreSQL 10 database server\n   Loaded: loaded (/usr/lib/systemd/system/postgresql-10.service; disabled; vendor preset: disabled)\n   Active: active (running) since Mon 2018-09-10 11:35:21 CST; 1h 5min ago\n     Docs: https://www.postgresql.org/docs/10/static/\n  Process: 17986 ExecStartPre=/usr/pgsql-10/bin/postgresql-10-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)\n Main PID: 17993 (postmaster)\n   CGroup: /system.slice/postgresql-10.service\n           ├─17993 /usr/pgsql-10/bin/postmaster -D /www/pgsql/data/\n           ├─17994 postgres: logger process\n           ├─17996 postgres: checkpointer process\n           ├─17997 postgres: writer process\n           ├─17998 postgres: wal writer process\n           ├─17999 postgres: autovacuum launcher process\n           ├─18000 postgres: stats collector process\n           └─18001 postgres: bgworker: logical replication launcher\n```\n\n表示服务启动成功\n\n由于pgsql默认既是监听127.0.0.1，所以不加密码也OK\n\n切换到postgres用户\n\n`su - postgres`\n\n连接到数据库\n\n`psql`\n\n创建数据库\n\n`postgres=#  CREATE DATABASE sonar;`\n\n创建用户\n\n`CREATE USER sonar WITH PASSWORD 'xxxxx';`\n\n创建授权\n\n`GRANT ALL PRIVILEGES ON DATABASE sonar to sonar;`\n\n修改配置文件\n\n`vim /www/pgsql/data/pg_hba.conf`\n\n```conf\n# TYPE  DATABASE        USER            ADDRESS                 METHOD\n\n# \"local\" is for Unix domain socket connections only\nlocal   all             all                                     trust\n# IPv4 local connections:\nhost    all             all             127.0.0.1/32            trust\n# IPv6 local connections:\nhost    all             all             ::1/128                 trust\n# Allow replication connections from localhost, by a user with the\n# replication privilege.\n#local   replication     all                                     peer\n#host    replication     all             127.0.0.1/32            ident\n#host    replication     all             ::1/128                 ident\nhost    all             all             0.0.0.0/0       md5\n```\n\n重新载入配置文件\n\n`systemctl reload postgresql-10.service`\n\n\n\n### 安装sonar\n\n官方下载地址：`https://www.sonarqube.org/downloads/`\n\n本次选择最新版本7.3版本\n\n新建安装目录\n\n`mkdir /www/sonar`\n\n由于sonar不能使用root启动，所以我们需要新建用户\n\n新建用户\n`useradd sonar`\n\n切换到安装目录\n\n`cd /www/sonar`\n\n下载sonar\n\n`wget https://sonarsource.bintray.com/Distribution/sonarqube/sonarqube-7.3.zip`\n\n解压sonar\n\n`unzip sonarqube-7.3.zip`\n\n> 如果提示没有unzip命令请执行`yum install unzip`安装命令后，再次执行解压\n\n切换到sonar解压后目录\n\n`cd sonarqube-7.3`\n\n移动所有文件到上级目录&返回上级目录\n\n`mv * .. && cd ..`\n\n删除无用文件\n\n`rm -rf sonarqube-7.3.zip sonarqube-7.3/`\n\n修改目录所属权限\n\n`chown -R sonar:sonar /www/sonar/`\n\n切换用户\n\n`su - sonar`\n\n切换目录\n\n`cd /www/sonar/`\n\n配置文件\n\n`vim /www/sonar/conf/sonar.properties`\n\n```conf\nsonar.jdbc.username=sonar\nsonar.jdbc.password=xxxxx\nsonar.jdbc.url=jdbc:postgresql://localhost/sonar\nsonar.web.javaOpts=-Xmx8120m -Xms128m -XX:+HeapDumpOnOutOfMemoryError\nsonar.web.host=127.0.0.1\nsonar.web.port=9000\nsonar.search.javaOpts=-Xms512m -Xmx4096m -XX:+HeapDumpOnOutOfMemoryError\nsonar.telemetry.enable=false\n```\n\n启动服务\n\n`/www/sonar/bin/linux-x86-64/sonar.sh start`\n\n测试是否能访问\n\n```curl http://127.0.0.1:9000\n\n### 安装NGINX\n\nyum install nginx\n\n增加配置文件\n\n`/etc/nginx/conf.d/sonar.conf`\n\n```nginx\nserver {\n        server_name sonar.xxx.com;\n        listen 80;\n        location / {\n                proxy_pass http://127.0.0.1:9000;\n        }\n}\n```\n\n编辑文件`/etc/nginx/nginx.conf`\n\n```nginx\nuser nginx;\nworker_processes 4;\nerror_log /var/log/nginx/error.log;\npid /run/nginx.pid;\n\n# Load dynamic modules. See /usr/share/nginx/README.dynamic.\ninclude /usr/share/nginx/modules/*.conf;\n\nevents {\n    worker_connections 1024;\n}\n\nhttp {\n    log_format  main  '$remote_addr - $remote_user [$time_local] \"$request\" '\n                      '$status $body_bytes_sent \"$http_referer\" '\n                      '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n\n    access_log  /var/log/nginx/access.log  main;\n\n    sendfile            on;\n    tcp_nopush          on;\n    tcp_nodelay         on;\n    keepalive_timeout   65;\n    types_hash_max_size 2048;\n    client_max_body_size 100m;\n\n    include             /etc/nginx/mime.types;\n    default_type        application/octet-stream;\n\n    # Load modular configuration files from the /etc/nginx/conf.d directory.\n    # See http://nginx.org/en/docs/ngx_core_module.html#include\n    # for more information.\n    include /etc/nginx/conf.d/*.conf;\n\n    server {\n        listen       80 default_server;\n        server_name  _;\n        return 444;\n    }\n}\n```\n\n`systemctl reload nginx.service`\n\n### 安装Jenkins\n\n执行命令\n\n`sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo`\n\n`sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key`\n\n安装jenkins\n\n`yum install jenkins`\n\n启动jenkins\n\nsystemctl start jenkins.service\n\n\n配置jenkins的NGINX规则\n\n新建配置文件\n\n`/etc/nginx/conf.d/jenkins.conf`\n\n```nginx\nupstream jenkins {\n  keepalive 32; # keepalive connections\n  server 127.0.0.1:8080; # jenkins ip and port\n}\n \nserver {\n  listen          80;       # Listen on port 80 for IPv4 requests\n\n  server_name     jenkins.example.com;\n\n  #this is the jenkins web root directory (mentioned in the /etc/default/jenkins file)\n  root            /var/run/jenkins/war/;\n\n  access_log      /var/log/nginx/jenkins/access.log;\n  error_log       /var/log/nginx/jenkins/error.log;\n  ignore_invalid_headers off; #pass through headers from Jenkins which are considered invalid by Nginx server.\n\n  location ~ \"^/static/[0-9a-fA-F]{8}\\/(.*)$\" {\n    #rewrite all static files into requests to the root\n    #E.g /static/12345678/css/something.css will become /css/something.css\n    rewrite \"^/static/[0-9a-fA-F]{8}\\/(.*)\" /$1 last;\n  }\n\n  location /userContent {\n    #have nginx handle all the static requests to the userContent folder files\n    #note : This is the $JENKINS_HOME dir\n\troot /var/lib/jenkins/;\n    if (!-f $request_filename){\n      #this file does not exist, might be a directory or a /**view** url\n      rewrite (.*) /$1 last;\n\t  break;\n    }\n\tsendfile on;\n  }\n\n  location @jenkins {\n      sendfile off;\n      proxy_pass         http://jenkins;\n      proxy_redirect     default;\n      proxy_http_version 1.1;\n\n      proxy_set_header   Host              $host;\n      proxy_set_header   X-Real-IP         $remote_addr;\n      proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;\n      proxy_set_header   X-Forwarded-Proto $scheme;\n      proxy_max_temp_file_size 0;\n\n      #this is the maximum upload size\n      client_max_body_size       10m;\n      client_body_buffer_size    128k;\n\n      proxy_connect_timeout      90;\n      proxy_send_timeout         90;\n      proxy_read_timeout         90;\n      proxy_buffering            off;\n      proxy_request_buffering    off; # Required for HTTP CLI commands in Jenkins > 2.54\n      proxy_set_header Connection \"\"; # Clear for keepalive\n  }\n\n  location / {\n    # Optional configuration to detect and redirect iPhones\n    if ($http_user_agent ~* '(iPhone|iPod)') {\n      rewrite ^/$ /view/iphone/ redirect;\n    }\n\n    try_files $uri @jenkins;\n  }\n}\n```\n\n重新载入NGINX配置文件\n\n`systemctl reload nginx.service`\n\n\n### 配置联动\n\n访问jenkins域名\n\n点击`系统管理-》插件管理`\n\n勾选如下插件\n\n```shell\nSonarQube Scanner\nGitLab\n```\n\n安装完插件后，等待重启\n\n#### 配置SonarQube\n\n重启后选择 `系统管理` -> `系统设置`\n\nSonarQube servers\n\n勾选Enable injection of SonarQube server configuration as build environment variables\n\n点击`Add SonarQube`\n\nname:sonar\n\nserver Url : 填写自己sonar服务器url\n\nServer authentication token： 在sonar后台，`管理用户` 类目新建即可\n\n注意：token只会出现一次。\n\n点击保存\n\n#### 全局工具配置\n\n找到全局工具配置\n\n选择`新增 SonarQube Scanner`\n\nName:sonar\n\n点击`保存`\n\n#### 凭据\n\n在jenkins右侧选择`凭据`\n\n添加自己的gitlab账号\n\n#### 配置任务\n\n\n点击新建任务\n\n填写名称，选择`构建一个自由风格的软件项目`\n\n源码管理\n\n选择git\n\n填写git地址，\n\n选择刚刚填写的凭据\n\n构建这里选择增加`Execute SonarQube Scanner`\n\nAnalysis properties\n\n填写如下信息\n\n```conf\n# 配置唯一ID\nsonar.projectKey=oa\n# 配置显示名称\nsonar.projectName=oa\n# 配置项目初始目录\nsonar.sources=$WORKSPACE\n#配置项目语言\nsonar.language=php\n#配置文件编码\nsonar.sourceEncoding=UTF-8\n#配置排除文件或者文件夹\nsonar.exclusions=public/*\nsonar.exclusions=*.js\nsonar.exclusions=*.css\nsonar.exclusions=*.html\nsonar.exclusions=*.jpg\nsonar.exclusions=*.jpge\nsonar.exclusions=*.png\nsonar.exclusions=*.gif\nsonar.exclusions=*.pdf\nsonar.exclusions=*.htm\nsonar.exclusions=vendor/**\nsonar.exclusions=Vendor/**\n```\n\n点击保存后\n\n点击右侧立刻构建\n\n\n本文档完成"
  },
  {
    "path": "docs/6.Project/3-泰式感知.md",
    "content": "\n# 03.泰式感知\n\n\n作者：Lost Maniac\n\n协作：\n\n-----\n\n## 简介\n\n泰式感知，命名是由玄道发起，经过十几个名字的激烈讨论和投票，最终获胜。\n\n## 功能\n\n泰式感知系统收集互联网大量安全舆情，通过订阅关键字，精准推送到订阅用户手中。让用户第一时间知晓安全舆情。\n\n## 使用方法\n\n内测中，测试完成开放。"
  },
  {
    "path": "docs/7.安全前瞻/1-BeyondCorp-以全新方式保障企业安全.md",
    "content": "# BeyondCorp -以全新方式保障企业安全\n\n翻译：lmowen\n\n## 作者\n\n**Rory Ward**是一名谷歌爱尔兰的站点可靠性工程经理。他曾经就职于Valista@爱尔兰，AOL@硅谷，Netscape，KIVA，General Magic，以及Retix@洛杉矶。他持有爱尔兰都柏林城市大学的计算机应用理学士学位。roryward@google.com \n\n**Betsy Beyer**是一位纽约技术作家，专长于谷歌SRE软件的虚拟化方向。她曾负责为谷歌数据中心以及硬件操作团队提供文章。在搬到纽约之前，Betsy曾是斯坦福大学的技术写作讲师。她持有斯坦福大学和杜兰大学的学位。bbeyer@google.com\n\n## 简介\n\n目前，事实上每个公司都通过使用防火墙来实现边界安全管控。然而，这种安全模型是有问题的，因为当该边界被攻入后，攻击者会拥有对公司私有内部网络相对容易的访问权限。而随着公司采用移动和云技术，边界区域变得越来越难以实施。谷歌正在采取一种不同的方法来实现网络安全。我们正在移除私有内部网络的需求，并公司应用转向互联网。\n\n企业从IT基础设施的早期就已经使用边界安全来保护和管控内部资源的访问。边界安全模型经常被比作一座中世纪城堡：一堵有厚墙的堡垒，四周有护城河，有严密的守卫，设有唯一的单点进出口。任何位于城墙之外的东西都被认为是危险的，而认为墙内任何东西都是可信的。任何人都经过了吊桥便具备使用城堡内所有资源的权利。\n\n当所有的员工都在公司大楼里工作时，边界安全模型是很适用的。然而，随着移动办公的出现，和激增各种移动办公设备，以及越来越多地使用基于云的服务，新型攻击向量已经出现，将传统的范式扩展到再非单点。边界安全模型的关键假设不再成立：边界不再只代表企业的物理位置，而且边界内也不能继续被认为是个人计算机和企业应用存在的绝对安全场所。\n\n当大多数企业认为内部网络是一个安全的环境时，谷歌的经验证明这种观念是错误的。相反，我们应该假设内部网络和公众一样充满危险，并基于这个假设构建所有企业应用。\n\nGoogle的BeyondCorp方案目标正在转向一种新的模式，不再使用私有企业网络。相反，访问仅依赖于设备和用户证书，而不管用户的网络位置——无论是企业办公地、家庭网络还是酒店，或者咖啡店。对企业资源的所有访问都经过完全认证、完全授权，以及基于设备状态和用户证书进行完全加密。我们可以加强细粒度的访问控制，用以访问不同等级的企业资源。因此，所有谷歌员工都可以成功地在任何网络环境下工作，而不需要传统的VPN连接到所谓的私有网络中。企业本地访问与远程访问之间，除了可能的网络延迟不同之外，用户体验几乎一致。\n\n\n## BeyondCorp的主要构成\n\nBeyondCorp由许多协作的组件构成，用以确保仅恰当授权过的设备和用户才允许访问所需的企业应用。下面描述每个组件（见图1）。\n\n![图1 BeyondCorp组件与访问流](/images/7.安全前瞻/1-BeyondCorp-以全新方式保障企业安全/1.png \"BeyondCorp组件与访问流\")\n\n## 安全地设备识别\n\n### 设备资产数据库\n\nBeyondCorp使用“受控设备”这样一个概念，指的是企业采购和主动管理的设备。只有受控设备才能访问公司应用程序。一套围绕着设备跟踪和采购的流程是该模型运转起设备库资产数据库是的基石。一个设备的整个生命周期中，谷歌持续跟踪对它进行的任何变更。该信息被监控、分析，并可用于BeyondCorp的其他部分。因为谷歌有多个资产数据库，元-资产数据库用于合并和规范来自这些多个源的设备信息，并使这些信息可用于BeyondCorp的下游组件。由于这个元-资产的存在，我们有能力知道所有那些需要访问我们的企业设备。\n\n### 设备识别\n\n所有受控设备都需要以唯一的方式识别并对应到设备资产数据库中的记录。一种实现此唯一标识的办法是每个设备都需要配备唯一标识的设备证书。要想得到证书，一个设备必须存在于设备资产数据库中，并且状态正常。证书存储于硬件或可信平台模块（TPM）软件上，或者其他合格的证书仓库。设备鉴权流程验证证书仓库的有效性，并且只有被认为足够安全的设备可以被归类为受控设备。这些检查也与证书更新一同定期更新而强制执行。一旦安装，证书用于企业服务的所有通信。证书用于唯一标识设备，但它不仅是单方面地授予访问权限；相反，它被用作关联设备的一组信息的密钥。\n\n## 安全地用户识别\n\n### 用户与组数据库\n\nBeyondCorp还跟踪和管理用户与用户组数据库中的所有用户。这个数据库系统与Google的人力资源流程紧密的关联着，而Google的人力资源流程正是负责管理所有用户的工作分类、用户名和组成员资格。当员工加入公司，改变角色或责任，或离开公司，这个数据库被更新。该系统告知BeyondCorp关于需要接入我们企业用户的所有恰当/相关信息。\n\n### 单点登录系统\n\n一个外部化的单点登录（SSO）系统是集中式的用户身份验证门户，该门户为请求访问我们企业资源的用户验证主要和次要因素凭证。通过对用户和群组数据库进行验证后，SSO系统生成临时令牌，该令牌可以作为特定授权过程的一部分。\n\n## 移除信任网络\n\n### 部署无私有网络\n\n为使本地和远程访问相同，BeyondCorp定义和部署一个无私有网络，非常类似外部网络但使用私有地址空间。无私有网络仅连接到因特网、有限的基础设施服务（例如，DNS、DHCP和NTP），以及\n配置管理系统，如Puppet。所有设备都被被分配给这个网络中，即使其物理位置位于谷歌大厦内。在这个网络和谷歌的其他部分之间存在着一个严格管理的ACL（访问控制列表）。\n\n### 有线/无线网络802.1x接入认证\n\n对于有线和无线接入，Google都基于802.1x认证使用RADIUS服务器将设备分配至向适当的网络。我们使用动态的而非静态的VLAN分配。这种方法意味着，对于已验证的设备我们使用RADIUS服务器通知交换机适当的VLAN分配，而不是依赖于交换机/端口静态配置。受控设备提供证书作为802.1x握手协议的一部分，并被分配到无私有网络，而企业网络中未识别和非受控的设备的设备则被分配到后补网络或者访客网络中。\n\n## 外部化应用程序和工作流\n\n### 面向Internet的访问代理\n\n谷歌的所有企业应用程序都同时面向外部和内部客户端，通过面向Internet的访问代理，强制执行客户端和应用程序之间的加密。访问代理为每个应用程序配置并提供公共的功能，比如全局可达性、负载均衡、访问控制检查、应用程序健康检查和拒绝服务保护。该代理在完成访问控制检查后（下方详述），将适当的请求代理发给后端应用程序。\n\n### 公共DNS入口\n\n谷歌所有的企业应用程序都对外可达，注册在公共DNS中，并伴有一个CNAME通过面向因特网的接入搭理指向该应用程序。\n\n## 实施基于资产的访问控制\n\n### 基于设备和用户的信任推理\n\n对单个用户或者单个设备的访问级别可以随着时间的推移而改变。通过询问多个数据源，我们能够动态地推断配给设备或用户的信任级别。接下来访问控制引擎（下方详述）可以使用该信任级别作为其决策过程的一部分。例如，没有升级到最新操作系统补丁包的设备可能被降级信任级别。一类特定的设备，如特定型号的手机或平板电脑，可能被分配特定的信任级别。用户若从新的地理位置访问应用程序可能会被分配一个不同的信任级别。我们同时使用静态规则和启发式规则来确定这些信任级别。\n\n### 访问控制引擎\n\n访问代理中的访问控制引擎基于每个访问请求为企业级应用程序提供服务级别授权。授权决策对于用户、用户所属的组、设备证书，以及来自设备资产数据库中的记录做出断言。如果需要，访问控制引擎也可以执行基于位置的访问控制。对用户和设备推断的信任水平也包含在授权决策中。例如，谷歌的bug跟踪系统可以仅限于全职工程师使用工程设备才能访问。对财务应用的访问，可以限制仅金融操作组中的全职和兼职雇员使用受控的非工程设备访问。访问控制引擎也可以以不同的方式限制应用程序的各个功能部分。例如，在我们的bug跟踪系统中，与更新或搜索相同的bug跟踪系统比较，查看一个条目需要不那么严格的访问控制。\n\n### 管道输入访问控制引擎\n\n访问控制引擎不间断的从一个管道中获取信息，这个管道正是用来动态地提取用于做出访问决策的有用信息。该信息包括证书白名单、设备和用户的信任级别，以及关于设备和用户的资产细节以及其他各种因素。\n\n## 端到端的例子\n\n### 应用\n\n对于这个例子，让我们假设一个应用程序将被BeyondCorp采用。工程师们使用的该应用程序进行审查源代码，注释代码，更新代码，以及经审稿人批准，提交代码。应用程序codereview.corp.google.com, 只限于全职和兼职的工程师使用任何受控设备可访问\n\n### 配置面向Internet的访问代理\n\ncodereview.corp.google.com的应用负责人配置访问代理。配置指定后台的位置，以及后台能够接受的最大流量。codereview.corp.google.com在公共DNS中注册，并拥有CNAME指向该访问代理。举例：\n\n```shell\n$ dig @8.8.8.8 codereview.corp.google.com\n; <<>> DiG 9.8.1-P1 <<>> @8.8.8.8 codereview.corp.google.com\n; (1 server found)\n;; global options: +cmd\n;; Got answer:\n;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12976\n;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0,\nADDITIONAL: 0\n;; QUESTION SECTION:\n;codereview.corp.google.com. IN A\n;; ANSWER SECTION:\ncodereview.corp.google.com. 21599 IN CNAME\naccessproxy.l.google.com.\naccessproxy.l.google.com. 299 IN A 74.125.136.129\n;; Query time: 10 msec\n;; SERVER: 8.8.8.8#53(8.8.8.8)\n;; WHEN: Wed Aug 20 19:30:06 2014\n;; MSG SIZE rcvd: 86\n```\n\n### 配置访问控制引擎\n\n访问控制引擎提供了一条默认规则，该规则定义了全职员工使用受控设备访问的限制。codereview.corp.google.com的应用负责人提出了一个更加具体的规则，包括两种方式：对具有最高信任级别的受控设备，以及对具有最高信任级别的全职和兼职工程师。\n\n### 工程师访问网络\n\n**如果网络处于企业办公地外的物理区域：**工程师使用谷歌提供的笔记本电脑访问任何WiFi网络。例如，这个网络可能是机场的有限门户的WiFi网络，或者是咖啡店的WiFi。不需要设置VPN就能连接到企业网络。\n\n**如果网络位于企业办公地内的物理区域：**一名工程师访问使用谷歌提供的笔记本或台式机访问企业网络。笔记本在802.1x握手协议中提供其设备证书给RADIUS服务器。由于提供了有效的证书，笔记本被在无私有网络中分配到一个地址。如果设备不是公司提供的笔记本，或者它的证书过期了，设备将被在补充网络中分配一个地址，仅具有非常有限的访问权限。\n\n### 任意网络访问应用程序\n\n一名工程师使用公司授予的笔记本电脑访问应用codereview.corp.google.com。其过程你可以参考图1中的流程。\n\n1. 请求被指向访问代理。笔记本提供其设备证书。\n2. 访问代理不能识别用户并重定向到SSO系统。\n3. 工程师提供他/她的双因素身份认证凭据，由SSO系统认证和颁发令牌，并被重定向回访问代理。\n4. 访问代理现在具有设备证书（标识设备）和SSO令牌（标识用户）。\n5. 访问控制引擎执行指定授权检查，该检查由应用codereview.corp.google.com所配置。\n\n这个授权检查是在每一个请求上进行的：\n\n    a. 用户被确认属于工程组内成员\n    b. 用户被确认拥有足够的信任级别\n    c. 该设备被确认是状态正常的受控设备\n    d. 该设备被证实具有足够的信任级别。\n    e. 如果所有这些检查通过，则请求被传递到适当的后台完成服务。\n    f. 如果上述检查中的任何一项失败，则拒绝该请求。\n\n通过这种方法，我们在基于每个请求基础上执行丰富的服务等级认证和授权检查\n\n\n## 迁移至BeyondCorp\n\n像世界上几乎所有其他企业一样，谷歌维护着一个客户端和应用程序之前的私有网络。这一范式对公司日常工作至关重要的基础设施来说，产生了显著的意义。而公司的所有组成部分都将迁移至BeyondCorp，一次性将所有网络用户和所有应用程序都迁移到BeyondCorp环境将会对业务连续性带来较大的风险。因为这个原因，谷歌投入了大量的成本来进行分阶段迁移，并且成功地实现了零生产力的影响将大部分网络用户组织转移到BeyondCorp。以下部分，如图2所示，详细说明我们所做的一些工作。\n\n![图 2 迁移至BeyondCorp](/images/7.安全前瞻/1-BeyondCorp-以全新方式保障企业安全/2.png \"图 2 迁移至BeyondCorp\")\n\n### 工作流验证\n\n谷歌使用的所有应用程序都需要通过访问代理。BeyondCorp发起审查和检验这些应用程序，完成的任务范围覆盖从简单的（例如，支持HTTPS流量）到更困难的（例如，SSO集成）。每个应用程序都需要一套访问代理配置，并且在许多情况下，配置特定的访问控制引擎。每个应用程序都经过了以下阶段：\n\n1. 从私有网络直接访问和通过VPN外部访问。\n2. 从私有网络直接访问，以及外部和非私有网络访问代理通过访问代理访问。在这种情况下，我们使用分开的DNS。内网DNS直接指向应用程序和外部DNS指向访问代理。\n3. 所有外部、私有网络或非私有网络都通过访问代理访问\n\n### 工作职能分析\n\n通过梳理整个公司的工作职能，并参照工作流验证，我们能够排定用户群体进行迁移的优先级。那个时候我们能够基于对用户工作流和BeyondCorp能力的透彻理解而从财务、销售、法务或工程师团队中选择用户。\n\n### 浅谈VPN的使用\n\n随着越来越多的应用程序可以通过访问代理访问，我们开始主动限制用户使用VPN，具体采用以下策略：\n\n1. 我们限制了只有被证明实在有必要的用户才可使用VPN的访问。\n2. 我们监控了VPN的使用，并删除了未在定义的周期内使用VPN用户的访问权限。\n3. 我们监控VPN活跃用户的使用情况。如果他们所有的工作流程均可通过访问代理完成，我们强烈建议用户放弃他们的VPN访问权限。\n\n### 流量分析管道\n\n我们把用户转移到非私有网络时，仅当我们确定（或非常接近确定）他们所有的工作流程都可以从这个网络上获得时，这点很重要。为了建立相对的确定度，我们建立了流量分析管道。作为这个管道的输入，我们从公司的每个交换机捕获了采样的NetFlow数据。然后这部分数据被用于和对在非私有网络和公司网络的其余部分之间网络的标准ACL进行比对分析。这个分析使我们能够识别出通过ACL的总交通量，以及一个没能通过ACL的有序列表。然后，未通过流量可以附加到特定的工作流和/或特定的用户和/或特定的设备。我们接着逐步解决未通过的清单，使之在BeyondCorp环境中发挥作用。\n\n### 非私有网络模拟\n\n为了增加流量分析管道，该管道使用采样交换机的数据，我们也模拟了非私有网络行为监控器在公司的流量，通过安装在所有连接到谷歌网络的用户设备上的流量监视器。这个流量监视器基于每个设备针对非私有网络和公司的网络检查所有传入和传出流量，并记录了没有通过的流量。监控器有两种模式：\n\n1. 记录模式：捕获不合格的流量，但仍然允许说设备访问。\n2. 强制模式：捕获并丢弃不合格的流量\n\n### 迁移策略\n\n有了流量分析管道和非私有网络模拟，我们定义了已经分阶段执行了迁移策略，包括以下内容：\n\n1. 通过工作职能，工作流或位置信息识别潜在候选集\n2. 在记录模式下操作模拟器，识别出连续30天达到99.9%个合格流量设备的那些用户\n3. 为连续30天达到99.9%个合格流量设备的那些用户开启强制模式。如有必要，用户可以将模拟器恢复到记录模式。\n4. 在将模拟器在强制模式下成功运行30天后，将该情况记录进设备资产库中。\n5. 除了在候选集合中包含之外，在模拟器的强制模式下30天的成功操作提供了一个非常强烈的信号，当下一个802.1x认证请求由RADIUS服务器服务时，设备应该被分配给非私用网络。\n\n### 例外处置\n\n除了自动化将用户和设备进行网络迁移之外，我们也尽可能地为用户提供了一个简单暂时免除此迁移的例外申请流程。我们维护了一张在BeyondCorp环境中尚未合格的工作流程的列表。用户可以搜索这些列表，并以合理的审批后，标明自己和自己的设备作为某个工作流的合法存在。当该工作流最终合格时，其用户被通知进行迁移。\n\n### 完成BeyondCorp\n\n谷歌企业向BeyondCorp的迁移正在进行中，它所需要的大部分工作已经完成。我们的迁移工具和策略允许我们主动地将用户、设备和工作流移到BeyondCorp，而且并不影响到日常生产力。\n\n我们预期到工作流长尾效应该还需要一些时间来完全实现向BeyondCorp的迁移。例如，使用专有协议来与服务器通讯的胖客户端应用程序就将是一个挑战。"
  },
  {
    "path": "docs/_headers",
    "content": "/*\n  Cache-Control : public, max-age=604800 , must-revalidate"
  },
  {
    "path": "docs/index.md",
    "content": "# 关于我们\n\n** 所有文档均由中国互联网一线安全工程师编写整理 **\n\n\n<span id=\"busuanzi_container_site_pv\">为安全同学服务<span id=\"busuanzi_value_site_pv\"></span>次</span>\n\n## 关注我们\n\n---\n\n![aaa](/images/weixin.jpg)\n\n## 加入我们\n\n---\n\n贡献文档&修改文档&完善文档皆可加入about页面、且可以申请xxx@sdlchina.edu.ky邮箱\n\n---\n\n## 文档署名\n\n---\n\n文档作者分为两种“作者”，“协作者”\n\n创建新文档即可添加“作者”，并且作者不可变更。\n\n修改文档&完善文档即可添加自己ID到协作者。协作者ID可以添加多个，按照提交先后顺序进行添加，上不封顶。\n\n---\n\n## 贡献文档方法\n\n---\n\n### GitHub工作流\n\n如果有熟悉GitHub工作流方式贡献文档的同学，可以使用GitHub工作流。\n\n需要掌握知识：GitHub工作流、jekyll\n\n也可由参考我们提供的教程：（暂时为空）\n\n### 邮件贡献\n\n如果有地方需要修改，或者增加文档，可以发送邮件到\n\n1. lost_maniac@sdlchina.edu.ky\n2. mour@sdlchina.org.cn\n\n---\n\n## 成员（按照名称拼音首字母排序）\n\n-----\n\n<section class=\"about\">\n    <ul class=\"about-list\">\n    \n    <center>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/1024.jpg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>1024</dt>\n                <dd>Two Steps From Hell - Never Back Down</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/108haili.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>108haili</dt>\n                <dd>生活不应只有诗和远方?还得有一台去远方的车!</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/backlion.jpg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>backlion</dt>\n                <dd>像风一样的人行走在黑夜.</dd>\n            </dl>\n        </li>\n        <li>\n            <img class=\"picture\" src=\"/images/head/chuanguosuiyuebulao.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>穿过岁月不老</dt>\n                <dd>人生就像蜡烛 ，站不正 必然泪多命短！</dd>\n            </dl>\n        </li>\n        <li>\n            <img class=\"picture\" src=\"/images/head/cloudwafs.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>Cloudwafs</dt>\n                <dd>Always Be Ready!</dd>\n            </dl>\n        </li>\n        \n        <li>\n            <img class=\"picture\" src=\"/images/head/doubiduo.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>doubiduo</dt>\n                <dd>半夜不睡觉，白天爱迟到。</dd>\n            </dl>\n        </li>\n\n        <li>\n        <img class=\"picture\" src=\"/images/head/dubbo.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>dubbo</dt>\n                <dd>这个锅，我背了</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/fengzi1.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>枫子</dt>\n                <dd>这个人很懒，什么都没留下。</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/fengzi.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>fengzi</dt>\n                <dd> 安全小菜鸡。。</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/fireeye.jpg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>fireeye</dt>\n                <dd> 我要异常的的低调，fireeye</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/God.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>Gòd</dt>\n                <dd>我没什么爱好</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/hzkey.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>hzkey</dt>\n                <dd> 先行其言而后从之</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/I.png\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>I</dt>\n                <dd>慎独</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/johnathan.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>johnathan</dt>\n                <dd> 用心做一个互联网行业信息安全的践行者。</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/jsp-shell.jpg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>jsp-shell</dt>\n                <dd> t66y、tumblr什么的,我一个也没听过!</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/Jun6l3.jpg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>Jun6l3</dt>\n                <dd>不知道写什么好呢，就这个吧，哈哈</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/k4n5ha0.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>k4n5ha0</dt>\n                <dd> 找不到工作的安全爱好者</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/lmowen.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>lmowen</dt>\n                <dd> Take it easy! Don't panic!</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/lost_maniac.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>Lost Maniac</dt>\n                <dd>SecurityPaper发起人，美图安全经理</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/Minggle.jpg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>Minggle</dt>\n                <dd>这家伙真的真的真的非常懒，相信我，真的！</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/Murviet.png\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>Murviet</dt>\n                <dd>看啥啊</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/pa55w0rd.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>pa55w0rd </dt>\n                <dd>闲散人一个</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/realjac.jpg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>realjac </dt>\n                <dd>不随缘的随心，能改变的随性</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/tinker.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>tinker </dt>\n                <dd>I don't work like that. It's not professional.</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/yiming.png\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>Torjan </dt>\n                <dd>Torjan</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/Weiho.png\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>Weiho</dt>\n                <dd> Life is short,try everything</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/xiaoletian.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>小乐天</dt>\n                <dd> 没有不可能</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/xiatao.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>夏韬</dt>\n                <dd> 信息安全爱好者</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/xuandao.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>玄道</dt>\n                <dd>鲜衣怒马为中华，我以我血荐轩辕</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/yitiaoyu.jpeg\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>一条鱼</dt>\n                <dd>为人民服务</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/zhanzhexizao.png\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>站着洗澡</dt>\n                <dd>大智若愚</dd>\n            </dl>\n        </li>\n        </center>\n\n    </ul>\n</section>\n\n## 公司成员 （先后顺序）\n\n<section class=\"about\">\n    <ul class=\"about-list\">\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/corporation/hansight.png\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>瀚思科技</dt>\n                <dd>全场景大数据安全平台</dd>\n            </dl>\n        </li>\n\n        <li>\n            <img class=\"picture\" src=\"/images/head/corporation/yidonganquan.png\" alt=\"\">\n            <dl class=\"desc\">\n                <dt>移动安全联盟</dt>\n                <dd>由国内外移动安全相关的企事业单位、高等院校、科研院所等自愿结成的跨行业、开放性的合作与促进平台</dd>\n            </dl>\n        </li>\n\n    </ul>\n</section>\n"
  },
  {
    "path": "docs/update.md",
    "content": "# 更新日志\n\n## 2019年8月26日\n\n更新内容：\n\n1. 增加“SDL落地方案-代码编写”部分\n\n## 2019年4月25日\n\n更新内容：\n\n1. 增加应用安全业务自查checklist\n2. 增加成员realjac\n3. 更新copyright时间\n\n## 2019年4月8日\n\n更新内容：\n\n1. 增加996.ICU license\n\n\n## 2019年3月1日\n\n更新内容：\n\n1. 增加成员移动安全联盟\n\n\n## 2019年2月23日\n\n更新内容：\n\n1. 增加成员Cloudwafs\n2. 增加php安全规范\n\n## 2019年2月21日\n\n更新内容：\n\n1. 增加成员穿过岁月不老\n2. 增加SDL落地方案-上线发布部分\n3. 增加成员Torjan\n\n\n## 2018年12月17日\n\n更新内容：\n\n1. 增加公司贡献成员瀚思科技\n2. 增加新文档，瀚思科技贡献《利用Flink实现超大规模用户行为分析》\n3. 增加新文档，成员backlion贡献《APT 攻击基础科普》\n\n## 2018年12月10日\n\n更新内容：\n\n1. 增加新成员lmowen\n2. 增加新文档，《BeyondCorp -以全新方式保障企业安全》\n\n\n## 2018年12月02日\n\n更新内容：\n\n1. 整合安卓和IOS安全规范为移动安全规范。\n\n## 2018年11月20日\n\n更新内容：\n\n1. 完善了php安全规范\n\n## 2018年11月8日\n\n更新内容：\n\n1. 增加新成员tinker\n\n## 2018年11月7日\n\n更新内容：\n\n1. 添加防止短信接口被滥用的措施\n\n## 2018年10月17日\n\n更新内容：\n\n1. 增加SDL落地流程文档\n2. 修复bootcss挂掉问题\n\n---\n\n## 2018年10月16日\n\n更新内容：\n\n1. 去掉单个文章计数统计\n2. 增加首页不蒜子连接\n\n---\n\n## 2018年10月15日\n\n更新内容：\n\n1. 增加“泰式感知”说明页面\n2. 增加GitHub工作流。\n\n---\n\n## 2018年9月26日\n\n更新内容：\n\n1. 删除福利相关，隐藏但是可以用：）\n2. 增加安全意识培训浏览器安全。\n3. 更新大量安全培训相关知识\n4. 增加mysql安全配置\n5. 增加大量贡献文档修改建议的小伙伴\n\n---\n\n## 2018年9月25日\n\n更新内容：\n\n1. 增加about页面加入方法，贡献文档等等说明\n2. 修改首页slogan\n\n## 2018年9月23日\n\n更新内容：\n\n1. 修改样式，代码框下部增加20px\n2. 更新java编码规范\n\n---\n\n## 2018年9月11日\n\n更新内容：\n\n1. 工作流自动化代码审计\n\n---\n\n## 2018年9月02日\n\n更新内容：\n\n1. 增加文档 IOS安全规范文档\n\n---\n\n## 2018年8月31日\n\n更新内容：\n\n1. 增加文档 Android安全规范文档\n2. 增加应急响应文档\n\n---\n\n## 2018年8月30日\n\n更新内容：\n\n1. 增加文档 哪些企业需要SDL\n2. 新增python代码安全规范\n\n---\n\n## 2018年8月26日\n\n更新内容：\n\n1. 增加内部钓鱼系统部署文档\n2. 增加php代码审计工具的文档\n3. 增加导航栏类目，Project\n4. 增加企业为什么需要SDL\n5. 增加成员Murviet\n\n---\n\n## 2018年8月26日\n\n更新内容：\n\n1. 新增文档《互联网企业安全运营的思考》\n2. 修复文档《内功修炼第二步-引起重视》中的错误日期\n\n---\n\n## 2018年8月23日\n\n新增内容：\n\n1. 增加团队成员枫子\n2. 增加渗透测试章节\n3. 安全设计--密码找回增加一条\n4. 安全培训--增加一些条目\n\n网站优化：\n\n1. 优化css加载\b方式\n2. 优化jq的js文件加载方式\n3. 优化谷歌字体加载方式\n\n---\n\n## 2018年8月22日\n\n1. 增加安全培训--APP安全开发培训\n2. 增加安全培训--web安全开发培训\n3. 增加安全培训--产品经理安全培训\n\n---\n\n## 2018年08月21日\n\n新增内容：\n\n1. 安全培训-运维安全培训\n2. 相关术语增加 SDL 、ROI、ATT&CK 、STRIDE内容\n\n---\n\n## 2018年08月20日\n\n修改内容：\n\n1. 增加安全设计checklist内容\n\n网站优化：\n\n1. 增加网站About页面成员css样式\n2. 增加网站About页面成员\n\n---\n\n## 2018年08月19日\n\n新增文章内容：\n\n1. 什么是SDL\n2. 落地方案--安全培训（安全意识培训）\n\n---\n\n## 2018年08月18日\n\n新增文章内容：\n\n1. 安全设计Chechklist\n\n---\n\n## 2018年08月17日\n\n更新主体大纲内容\n\n---\n\n## 2018年08月16日\n\nSDL China成立\n\n-----\n"
  },
  {
    "path": "mkdocs.yml",
    "content": "site_name: Security Paper\nsite_description: 所有文档均由中国互联网一线安全工程师编写整理\nsite_author: Security Paper\nsite_url: https://www.securitypaper.org\n\n# Repository\nrepo_name: SecurityPaper/SecurityPaper-web\nrepo_url: https://github.com/SecurityPaper/SecurityPaper-web\nedit_uri: \"https://github.com/SecurityPaper/SecurityPaper-web\"\n\n# Copyright\ncopyright: 'Copyright &copy; 2016 - 2019 SecurityPaper'\n\n# Configuration\ntheme:\n  name: null\n  custom_dir: SecurityPaper-themes\n\n  logo: \"/images/logo.svg\"\n  # feature:\n  #   tabs: true\n\n  # 404 page\n  static_templates:\n    - 404.html\n\n  # Don't include MkDocs' JavaScript\n  include_search_page: false\n  search_index_only: true\n\n  # Default values, taken from mkdocs_theme.yml\n  language: zh\n  feature:\n    tabs: true\n  palette:\n    primary: light blue\n    accent: light blue\n  font:\n    text: Roboto\n    code: Roboto Mono\n  favicon: assets/images/favicon.png\n  highlightjs: true\n\n\n# Customization\n# extra:\n#   social:\n#     - type: globe\n#       link: https://www.securitypaper.org/\n#     - type: github-alt\n#       link: https://github.com/SecurityPaper/SecurityPaper-web/\n\n\n# Extensions\n# markdown_extensions:\n#   - markdown.extensions.admonition\n#   - markdown.extensions.codehilite:\n#       guess_lang: false\n#   - markdown.extensions.def_list\n#   - markdown.extensions.footnotes\n#   - markdown.extensions.meta\n#   - markdown.extensions.toc:\n#       permalink: true\n#   - pymdownx.arithmatex\n#   - pymdownx.betterem:\n#       smart_enable: all\n#   - pymdownx.caret\n#   - pymdownx.critic\n#   - pymdownx.details\n#   # - pymdownx.emoji:\n#   #     emoji_generator: !!python/name:pymdownx.emoji.to_svg\n#   - pymdownx.inlinehilite\n#   - pymdownx.keys\n#   - pymdownx.magiclink\n#   - pymdownx.mark\n#   - pymdownx.smartsymbols\n#   - pymdownx.superfences\n#   - pymdownx.tasklist:\n#       custom_checkbox: true\n#   - pymdownx.tilde\n\n# markdown_extensions:\n#   - admonition\n#   - codehilite:\n#       guess_lang: false\n#   - toc:\n#       permalink: true\n\n# Page tree\n# nav:\n#   - 首页: index.md\n#   - Extensions:\n#     - Admonition: SDL_introduction/1.什么是SDL.md\n#     - CodeHilite: SDL_introduction/2.企业为什么需求SDL.md\n#     - Footnotes: SDL_introduction/footnotes.md\n#     - Metadata: SDL_introduction/metadata.md\n#     - Permalinks: SDL_introduction/permalinks.md\n#     - PyMdown: SDL_introduction/pymdown.md\n#   - Specimen: specimen.md\n#   - Customization: customization.md\n#   - Compliance with GDPR: compliance.md\n#   - Release notes: release-notes.md\n#   - Author's notes: authors-notes.md\n#   - Contributing: contributing.md\n#   - License: license.md\n\n# Google Analytics\ngoogle_analytics:\n  - !!python/object/apply:os.getenv [\"GOOGLE_ANALYTICS_KEY\"]\n  - auto\n"
  },
  {
    "path": "requirements.txt",
    "content": "mkdocs"
  }
]