1 Learning Objectives

Today, time permitting, we’ll aim to:

By the end of today’s class, students are anticipated to:

1.1 Working on GitHub

  • Let’s start with a survey of github. Let’s use the MDS public repo as an example. Notice…
    • Directory: You can see a directory of files, along with a README (in other folders, too).
      • Can’t make folders on gh… need to make locally.
    • File Rendering: GitHub renders certain file types nicely.
    • Editing: Use the “pen” icon. Then “commit”. Not so good for big changes (can’t save) – we’ll see how to make changes locally later.
    • Commits: List that shows the entire “history” of the project since you initiated git. See at the repo’s “home” directory.
    • diffs: Click on a commit to see what was changed!
    • File History and Blame: History shows the commit history of the file; blame shows who did what.
    • Issues: A way for open dialogue to happen amongst your team.
  • Exercise 1:
    • Create a new public github repo.
    • Initiate with a README file.
    • Edit the README file by adding some new text.
  • Exercise 2: Navigate to the github repo that makes the stat545.com website. Investigate the file cm001_course-intro-sw-install-account-signup.md in the main repo.
    • When was the last change made? By whom?
    • What was added on line 10 in the most recent change?
    • Who was the last person to change line 17?
    • When was the first commit made? By whom? What did the file look like after that change?
  • Exercise 3: Collaboration
    • Add your neighbour as a collaborator to your github repo. Go to Settings -> Collaborators, and type in their github username.
    • Modify your neighbour’s README by adding some text, like “ was here.”
    • Add an issue titled something like “README should be reviewed” and tag the repo owner by preceding their username with @.
    • Repo owners: check your email. You should have a notification. Close the issue (or comment+close).
      • NOTE: Click “Watch” to be notified of issues even if your aren’t tagged!
  • Exercise 4: forking.
    • Fork your other neighbour’s repo by navigating to their repo and clicking “fork”.
      • You’ll have your own copy of their repo on your account.
    • Add a new file called testing.md, and add some text to it.
    • Make a pull request by clicking pull request. Be sure to leave a comment.
    • Owners of the repo: Accept the pull request.
  • What happened in Exercise 4? A separate copy of the repo was modified, and merged to the main repo.

1.2 Working Locally

GitHub can’t offer the suite of editing capabilities that you have on your local machine. So we set up a local version of the repo and communicate with the remote repo.

  • Exercise 5: (Do together) Connect RStudio to git and GitHub
    • Did you config git? Enter the commands (with your credentials) specified at the top of this page.
    • Psst… what is this “terminal” or “shell”? A “control center” for your computer (and remote servers!)
    • Clone your github repo to your local machine in RStudio. instructions
      • Don’t have the “Version Control” option after clicking File -> New Project? Follow these instructions.
    • Open your README file, and add a line. Could be I added this line locally.
      • YES RStudio can be used as a regular text editor!
    • Go over to the git tab. Stage, commit, pull, and push your change.
    • Navigate to your remote repo. Do you see the change? You should!
  • Exercise 6: (Do yourself) Toy line
    • Make a new R script in your local repo.
    • Go here and copy-and-paste the “toy line” script (chunks 3,4,5 in that section).
    • Click “compile notebook” on it!
    • Commit these changes, and push to your repo (after pulling!)
    • Do you see the change on your remote repo?
  • Advanced stuff.
    • FYI: Alternatives to GitHub: bare repo on your own server.
    • Merge conflicts. Branch. Revert.
      • Do via source tree, or bash.

1.3 Git and GitHub take-home Lessons

  • GitHub is not git! It holds your repo remotely.
    • There are alternatives to GitHub, like Bitbucket or a bare repo on your own server.
    • Useful for collaboration! How many times do you want to send a file to your supervisor/advisor? email is clunky…
  • Working with git:
    • local repository: a self-contained project on your computer
    • remote repository: that project on some “cloud”, like GitHub, BitBucket, your own server, …
    • git client: program on your computer that helps you use git (commit, push, pull, …)
  • Adopt git in your workflow! This means:
    • Dedicate a self-contained directory to your project.
    • Set up an R project for the directory.
    • Set up git for that directory.
    • Save perpetually, commit often, pull/push (to github) periodically!
  • git can be painful.
    • Problems? Often best to just burn it down and start fresh…
    • Documentation difficult to read. Check out this parody of github documentation.
    • Use a git client to make it easier to work with git. RStudio, Source Tree, GitHub desktop, …

1.4 Markdown and R Markdown

Regular markdown:

  • Markdown syntax.
    • Some functionality in Slack.
    • Can also include raw HTML.
  • In RStudio, render this to HTML by clicking “preview”.
    • Files: md -> html. Could do pdf or even Word, too.

RMarkdown:

  • Differences between markdown and R markdown.
    • Includes LaTeX (super useful for theses – check out LyX if you’re new).
    • code chunks!
    • YAML header. Can make some pretty html files with YAML.
  • How to render: rmarkdown::render or click “knit”.
    • Files: Rmd -> md -> html or pdf or word (and other permutations… keep_md: yes to keep the intermediate md file. Or output: github_document). Useful slide
LS0tCnRpdGxlOiAiU1RBVCA1NDUgQ2xhc3MgTWVldGluZyAwMyIKb3V0cHV0OgogICAgaHRtbF9ub3RlYm9vazoKICAgICAgICB0b2M6IHRydWUKICAgICAgICB0aGVtZTogY2VydWxlYW4KICAgICAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgojIExlYXJuaW5nIE9iamVjdGl2ZXMKClRvZGF5LCB0aW1lIHBlcm1pdHRpbmcsIHdlJ2xsIGFpbSB0bzoKCi0gaGF2ZSBhIGdpdGh1YiByZXBvIHNldCB1cCAKLSBoYXZlIHRoYXQgcmVwbyBjbG9uZWQgbG9jYWxseQotIGlmIHRoZXJlJ3MgdGltZTogUk1hcmtkb3duCgpCeSB0aGUgZW5kIG9mIHRvZGF5J3MgY2xhc3MsIHN0dWRlbnRzIGFyZSBhbnRpY2lwYXRlZCB0bzoKCi0gRGVtb25zdHJhdGUgdXNhZ2Ugb2YgUlN0dWRpbydzIGdpdCBjbGllbnQKCiMjIFdvcmtpbmcgb24gR2l0SHViCgotIExldCdzIHN0YXJ0IHdpdGggYSBzdXJ2ZXkgb2YgZ2l0aHViLiBMZXQncyB1c2UgdGhlIFtNRFMgcHVibGljIHJlcG9dKGh0dHBzOi8vZ2l0aHViLmNvbS9VQkMtTURTL3B1YmxpYykgYXMgYW4gZXhhbXBsZS4gTm90aWNlLi4uCiAgICAtIF9fRGlyZWN0b3J5X186IFlvdSBjYW4gc2VlIGEgZGlyZWN0b3J5IG9mIGZpbGVzLCBhbG9uZyB3aXRoIGEgX1JFQURNRV8gKGluIG90aGVyIGZvbGRlcnMsIHRvbykuCiAgICAgICAgLSBDYW4ndCBtYWtlIGZvbGRlcnMgb24gZ2guLi4gbmVlZCB0byBtYWtlIGxvY2FsbHkuIAogICAgLSBfX0ZpbGUgUmVuZGVyaW5nX186IEdpdEh1YiByZW5kZXJzIGNlcnRhaW4gZmlsZSB0eXBlcyBuaWNlbHkuCiAgICAgICAgLSBNYXJrZG93biEgY3N2L3RzdiEgcGRmIQogICAgICAgIC0gTm90IGh0bWwgOigKICAgICAgICAtIEJhc2ljYWxseSBnZXQgYSBmcmVlIHdlYnNpdGUuIFtNYWtlIGl0IGJyb3dzYWJsZSFdKGh0dHA6Ly9oYXBweWdpdHdpdGhyLmNvbS9yZXBvLWJyb3dzYWJpbGl0eS5odG1sKS4KICAgIC0gX19FZGl0aW5nX186IFVzZSB0aGUgInBlbiIgaWNvbi4gVGhlbiAiY29tbWl0Ii4gTm90IHNvIGdvb2QgZm9yIGJpZyBjaGFuZ2VzIChjYW4ndCBzYXZlKSAtLSB3ZSdsbCBzZWUgaG93IHRvIG1ha2UgY2hhbmdlcyBsb2NhbGx5IGxhdGVyLiAKICAgIC0gX19Db21taXRzX186IExpc3QgdGhhdCBzaG93cyB0aGUgZW50aXJlICJoaXN0b3J5IiBvZiB0aGUgcHJvamVjdCBzaW5jZSB5b3UgaW5pdGlhdGVkIGdpdC4gU2VlIGF0IHRoZSByZXBvJ3MgImhvbWUiIGRpcmVjdG9yeS4gCiAgICAtIF9fZGlmZnNfXzogQ2xpY2sgb24gYSBjb21taXQgdG8gc2VlIHdoYXQgd2FzIGNoYW5nZWQhCiAgICAtIEZpbGUgX19IaXN0b3J5X18gYW5kIF9fQmxhbWVfXzogSGlzdG9yeSBzaG93cyB0aGUgY29tbWl0IGhpc3Rvcnkgb2YgdGhlIGZpbGU7IGJsYW1lIHNob3dzIHdobyBkaWQgd2hhdC4gCiAgICAtIF9fSXNzdWVzX186IEEgd2F5IGZvciBvcGVuIGRpYWxvZ3VlIHRvIGhhcHBlbiBhbW9uZ3N0IHlvdXIgdGVhbS4KLSBFeGVyY2lzZSAxOgogICAgLSBDcmVhdGUgYSBuZXcgcHVibGljIGdpdGh1YiByZXBvLgogICAgLSBJbml0aWF0ZSB3aXRoIGEgUkVBRE1FIGZpbGUuIAogICAgLSBFZGl0IHRoZSBSRUFETUUgZmlsZSBieSBhZGRpbmcgc29tZSBuZXcgdGV4dC4KLSBFeGVyY2lzZSAyOiBOYXZpZ2F0ZSB0byB0aGUgW2dpdGh1YiByZXBvIHRoYXQgbWFrZXMgdGhlIHN0YXQ1NDUuY29tIHdlYnNpdGVdKGh0dHBzOi8vZ2l0aHViLmNvbS9TVEFUNTQ1LVVCQy9TVEFUNTQ1LVVCQy5naXRodWIuaW8pLiBJbnZlc3RpZ2F0ZSB0aGUgZmlsZSBgY20wMDFfY291cnNlLWludHJvLXN3LWluc3RhbGwtYWNjb3VudC1zaWdudXAubWRgIGluIHRoZSBtYWluIHJlcG8uCiAgICAtIFdoZW4gd2FzIHRoZSBsYXN0IGNoYW5nZSBtYWRlPyBCeSB3aG9tPwogICAgLSBXaGF0IHdhcyBhZGRlZCBvbiBsaW5lIDEwIGluIHRoZSBtb3N0IHJlY2VudCBjaGFuZ2U/CiAgICAtIFdobyB3YXMgdGhlIGxhc3QgcGVyc29uIHRvIGNoYW5nZSBsaW5lIDE3PwogICAgLSBXaGVuIHdhcyB0aGUgZmlyc3QgY29tbWl0IG1hZGU/IEJ5IHdob20/IFdoYXQgZGlkIHRoZSBmaWxlIGxvb2sgbGlrZSBhZnRlciB0aGF0IGNoYW5nZT8KLSBFeGVyY2lzZSAzOiBDb2xsYWJvcmF0aW9uCiAgICAtIEFkZCB5b3VyIG5laWdoYm91ciBhcyBhIGNvbGxhYm9yYXRvciB0byB5b3VyIGdpdGh1YiByZXBvLiBHbyB0byBTZXR0aW5ncyAtPiBDb2xsYWJvcmF0b3JzLCBhbmQgdHlwZSBpbiB0aGVpciBnaXRodWIgdXNlcm5hbWUuCiAgICAtIE1vZGlmeSBfeW91ciBuZWlnaGJvdXInc18gUkVBRE1FIGJ5IGFkZGluZyBzb21lIHRleHQsIGxpa2UgIjxteSBuYW1lPiB3YXMgaGVyZS4iCiAgICAtIEFkZCBhbiBpc3N1ZSB0aXRsZWQgc29tZXRoaW5nIGxpa2UgIlJFQURNRSBzaG91bGQgYmUgcmV2aWV3ZWQiIGFuZCB0YWcgdGhlIHJlcG8gb3duZXIgYnkgcHJlY2VkaW5nIHRoZWlyIHVzZXJuYW1lIHdpdGggYEBgLgogICAgLSBSZXBvIG93bmVyczogY2hlY2sgeW91ciBlbWFpbC4gWW91IHNob3VsZCBoYXZlIGEgbm90aWZpY2F0aW9uLiBDbG9zZSB0aGUgaXNzdWUgKG9yIGNvbW1lbnQrY2xvc2UpLgogICAgICAgIC0gTk9URTogQ2xpY2sgIldhdGNoIiB0byBiZSBub3RpZmllZCBvZiBpc3N1ZXMgZXZlbiBpZiB5b3VyIGFyZW4ndCB0YWdnZWQhCi0gRXhlcmNpc2UgNDogZm9ya2luZy4KICAgIC0gX0ZvcmtfIHlvdXIgX290aGVyXyBuZWlnaGJvdXIncyByZXBvIGJ5IG5hdmlnYXRpbmcgdG8gdGhlaXIgcmVwbyBhbmQgY2xpY2tpbmcgImZvcmsiLgogICAgICAgIC0gWW91J2xsIGhhdmUgeW91ciBvd24gY29weSBvZiB0aGVpciByZXBvIG9uIHlvdXIgYWNjb3VudC4KICAgIC0gQWRkIGEgbmV3IGZpbGUgY2FsbGVkIGB0ZXN0aW5nLm1kYCwgYW5kIGFkZCBzb21lIHRleHQgdG8gaXQuCiAgICAtIE1ha2UgYSBwdWxsIHJlcXVlc3QgYnkgY2xpY2tpbmcgYHB1bGwgcmVxdWVzdGAuIEJlIHN1cmUgdG8gbGVhdmUgYSBjb21tZW50LiAKICAgIC0gT3duZXJzIG9mIHRoZSByZXBvOiBBY2NlcHQgdGhlIHB1bGwgcmVxdWVzdC4KLSBXaGF0IGhhcHBlbmVkIGluIEV4ZXJjaXNlIDQ/IEEgX3NlcGFyYXRlIGNvcHlfIG9mIHRoZSByZXBvIHdhcyBtb2RpZmllZCwgYW5kIF9tZXJnZWRfIHRvIHRoZSBtYWluIHJlcG8uIAoKCiMjIFdvcmtpbmcgTG9jYWxseQoKR2l0SHViIGNhbid0IG9mZmVyIHRoZSBzdWl0ZSBvZiBlZGl0aW5nIGNhcGFiaWxpdGllcyB0aGF0IHlvdSBoYXZlIG9uIHlvdXIgbG9jYWwgbWFjaGluZS4gU28gd2Ugc2V0IHVwIGEgX2xvY2FsXyB2ZXJzaW9uIG9mIHRoZSByZXBvIGFuZCBjb21tdW5pY2F0ZSB3aXRoIHRoZSBfcmVtb3RlXyByZXBvLiAKCi0gRXhlcmNpc2UgNTogKERvIHRvZ2V0aGVyKSBDb25uZWN0IFJTdHVkaW8gdG8gZ2l0IGFuZCBHaXRIdWIKICAgIC0gRGlkIHlvdSBgY29uZmlnYCBnaXQ/IEVudGVyIHRoZSBjb21tYW5kcyAod2l0aCB5b3VyIGNyZWRlbnRpYWxzKSBzcGVjaWZpZWQgYXQgdGhlIHRvcCBvZiBbdGhpc10oaHR0cDovL2hhcHB5Z2l0d2l0aHIuY29tL2hlbGxvLWdpdC5odG1sI2hlbGxvLWdpdCkgcGFnZS4KICAgIC0gUHNzdC4uLiB3aGF0IGlzIHRoaXMgInRlcm1pbmFsIiBvciAic2hlbGwiPyBBICJjb250cm9sIGNlbnRlciIgZm9yIHlvdXIgY29tcHV0ZXIgKGFuZCByZW1vdGUgc2VydmVycyEpCiAgICAtIF9DbG9uZV8geW91ciBnaXRodWIgcmVwbyB0byB5b3VyIGxvY2FsIG1hY2hpbmUgaW4gUlN0dWRpby4gW2luc3RydWN0aW9uc10oaHR0cDovL2hhcHB5Z2l0d2l0aHIuY29tL3JzdHVkaW8tZ2l0LWdpdGh1Yi5odG1sI2Nsb25lLXRoZS1uZXctZ2l0aHViLXJlcG9zaXRvcnktdG8teW91ci1jb21wdXRlci12aWEtcnN0dWRpbykKICAgICAgICAtIERvbid0IGhhdmUgdGhlICJWZXJzaW9uIENvbnRyb2wiIG9wdGlvbiBhZnRlciBjbGlja2luZyBGaWxlIC0+IE5ldyBQcm9qZWN0PyBGb2xsb3cgW3RoZXNlXShodHRwOi8vaGFwcHlnaXR3aXRoci5jb20vcnN0dWRpby1zZWUtZ2l0Lmh0bWwpIGluc3RydWN0aW9ucy4KICAgIC0gT3BlbiB5b3VyIFJFQURNRSBmaWxlLCBhbmQgYWRkIGEgbGluZS4gQ291bGQgYmUgYEkgYWRkZWQgdGhpcyBsaW5lIGxvY2FsbHkuYAogICAgICAgIC0gWUVTIFJTdHVkaW8gY2FuIGJlIHVzZWQgYXMgYSByZWd1bGFyIHRleHQgZWRpdG9yIQogICAgLSBHbyBvdmVyIHRvIHRoZSBgZ2l0YCB0YWIuIFN0YWdlLCBjb21taXQsIHB1bGwsIGFuZCBwdXNoIHlvdXIgY2hhbmdlLgogICAgLSBOYXZpZ2F0ZSB0byB5b3VyIHJlbW90ZSByZXBvLiBEbyB5b3Ugc2VlIHRoZSBjaGFuZ2U/IFlvdSBzaG91bGQhCiAgICAKLSBFeGVyY2lzZSA2OiAoRG8geW91cnNlbGYpIFRveSBsaW5lCiAgICAtIE1ha2UgYSBuZXcgUiBzY3JpcHQgaW4geW91ciBsb2NhbCByZXBvLgogICAgLSBHbyBbaGVyZV0oaHR0cDovL3N0YXQ1NDUuY29tL2Jsb2NrMDAyX2hlbGxvLXItd29ya3NwYWNlLXdkLXByb2plY3QuaHRtbCNyc3R1ZGlvLXByb2plY3RzKSBhbmQgY29weS1hbmQtcGFzdGUgdGhlICJ0b3kgbGluZSIgc2NyaXB0IChjaHVua3MgMyw0LDUgaW4gdGhhdCBzZWN0aW9uKS4KICAgIC0gQ2xpY2sgImNvbXBpbGUgbm90ZWJvb2siIG9uIGl0IQogICAgLSBDb21taXQgdGhlc2UgY2hhbmdlcywgYW5kIHB1c2ggdG8geW91ciByZXBvIChhZnRlciBgcHVsbGBpbmchKQogICAgLSBEbyB5b3Ugc2VlIHRoZSBjaGFuZ2Ugb24geW91ciByZW1vdGUgcmVwbz8KLSBBZHZhbmNlZCBzdHVmZi4KICAgIC0gRllJOiBBbHRlcm5hdGl2ZXMgdG8gR2l0SHViOiBiYXJlIHJlcG8gb24geW91ciBvd24gc2VydmVyLgogICAgLSBNZXJnZSBjb25mbGljdHMuIEJyYW5jaC4gUmV2ZXJ0LgogICAgICAgIC0gRG8gdmlhIHNvdXJjZSB0cmVlLCBvciBiYXNoLiAKCiMjIEdpdCBhbmQgR2l0SHViIHRha2UtaG9tZSBMZXNzb25zCgotIEdpdEh1YiBpcyBub3QgZ2l0ISBJdCBob2xkcyB5b3VyIHJlcG8gcmVtb3RlbHkuCiAgICAtIFRoZXJlIGFyZSBhbHRlcm5hdGl2ZXMgdG8gR2l0SHViLCBsaWtlIEJpdGJ1Y2tldCBvciBhIGJhcmUgcmVwbyBvbiB5b3VyIG93biBzZXJ2ZXIuIAogICAgLSBVc2VmdWwgZm9yIGNvbGxhYm9yYXRpb24hIEhvdyBtYW55IHRpbWVzIGRvIHlvdSB3YW50IHRvIHNlbmQgYSBmaWxlIHRvIHlvdXIgc3VwZXJ2aXNvci9hZHZpc29yPyBlbWFpbCBpcyBjbHVua3kuLi4gCi0gV29ya2luZyB3aXRoIGdpdDoKICAgIC0gbG9jYWwgcmVwb3NpdG9yeTogYSBzZWxmLWNvbnRhaW5lZCBwcm9qZWN0IG9uIHlvdXIgY29tcHV0ZXIKICAgIC0gcmVtb3RlIHJlcG9zaXRvcnk6IHRoYXQgcHJvamVjdCBvbiBzb21lICJjbG91ZCIsIGxpa2UgR2l0SHViLCBCaXRCdWNrZXQsIHlvdXIgb3duIHNlcnZlciwgLi4uCiAgICAtIGdpdCBjbGllbnQ6IHByb2dyYW0gb24geW91ciBjb21wdXRlciB0aGF0IGhlbHBzIHlvdSB1c2UgZ2l0IChjb21taXQsIHB1c2gsIHB1bGwsIC4uLikKLSBBZG9wdCBnaXQgaW4geW91ciB3b3JrZmxvdyEgVGhpcyBtZWFuczoKICAgIC0gRGVkaWNhdGUgYSBzZWxmLWNvbnRhaW5lZCBkaXJlY3RvcnkgdG8geW91ciBwcm9qZWN0LgogICAgLSBTZXQgdXAgYW4gUiBwcm9qZWN0IGZvciB0aGUgZGlyZWN0b3J5LgogICAgLSBTZXQgdXAgZ2l0IGZvciB0aGF0IGRpcmVjdG9yeS4gCiAgICAtIF9fU2F2ZV9fIHBlcnBldHVhbGx5LCBfX2NvbW1pdF9fIG9mdGVuLCBfX3B1bGwvcHVzaF9fICh0byBnaXRodWIpIHBlcmlvZGljYWxseSEKLSBnaXQgY2FuIGJlIHBhaW5mdWwuCiAgICAtIFByb2JsZW1zPyBPZnRlbiBiZXN0IHRvIGp1c3QgYnVybiBpdCBkb3duIGFuZCBzdGFydCBmcmVzaC4uLgogICAgLSBEb2N1bWVudGF0aW9uIGRpZmZpY3VsdCB0byByZWFkLiBDaGVjayBvdXQgW3RoaXMgcGFyb2R5XShodHRwczovL2dpdC1tYW4tcGFnZS1nZW5lcmF0b3IubG9rYWx0b2cubmV0Lykgb2YgZ2l0aHViIGRvY3VtZW50YXRpb24uIAogICAgLSBVc2UgYSBnaXQgY2xpZW50IHRvIG1ha2UgaXQgZWFzaWVyIHRvIHdvcmsgd2l0aCBnaXQuIFJTdHVkaW8sIFNvdXJjZSBUcmVlLCBHaXRIdWIgZGVza3RvcCwgLi4uCgoKIyMgTWFya2Rvd24gYW5kIFIgTWFya2Rvd24KClJlZ3VsYXIgbWFya2Rvd246CgotIFtNYXJrZG93biBzeW50YXhdKGh0dHBzOi8vZGFyaW5nZmlyZWJhbGwubmV0L3Byb2plY3RzL21hcmtkb3duL3N5bnRheCkuCiAgICAtIFNvbWUgZnVuY3Rpb25hbGl0eSBpbiBTbGFjay4KICAgIC0gQ2FuIGFsc28gaW5jbHVkZSByYXcgSFRNTC4KLSBJbiBSU3R1ZGlvLCByZW5kZXIgdGhpcyB0byBIVE1MIGJ5IGNsaWNraW5nICJwcmV2aWV3Ii4KICAgIC0gRmlsZXM6IGBtZGAgLT4gYGh0bWxgLiBDb3VsZCBkbyBgcGRmYCBvciBldmVuIFdvcmQsIHRvby4KClJNYXJrZG93bjoKCi0gRGlmZmVyZW5jZXMgYmV0d2VlbiBtYXJrZG93biBhbmQgUiBtYXJrZG93bi4KICAgIC0gSW5jbHVkZXMgTGFUZVggKHN1cGVyIHVzZWZ1bCBmb3IgdGhlc2VzIC0tIGNoZWNrIG91dCBMeVggaWYgeW91J3JlIG5ldykuCiAgICAtIGNvZGUgY2h1bmtzIQogICAgLSBZQU1MIGhlYWRlci4gQ2FuIG1ha2Ugc29tZSBbcHJldHR5IGh0bWwgZmlsZXNdKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20vaHRtbF9kb2N1bWVudF9mb3JtYXQuaHRtbCkgd2l0aCBZQU1MLgotIEhvdyB0byByZW5kZXI6IGBybWFya2Rvd246OnJlbmRlcmAgb3IgY2xpY2sgImtuaXQiLiAKICAgIC0gRmlsZXM6IGBSbWRgIC0+IGBtZGAgLT4gYGh0bWxgIG9yIGBwZGZgIG9yIHdvcmQgKGFuZCBvdGhlciBwZXJtdXRhdGlvbnMuLi4gYGtlZXBfbWQ6IHllc2AgdG8ga2VlcCB0aGUgaW50ZXJtZWRpYXRlIGBtZGAgZmlsZS4gT3IgYG91dHB1dDogZ2l0aHViX2RvY3VtZW50YCkuIFtVc2VmdWwgc2xpZGVdKGh0dHBzOi8vc3BlYWtlcmRlY2suY29tL2plbm55YmMvaGFwcHktZ2l0LWFuZC1naXRodWItZm9yLXRoZS11c2VyP3NsaWRlPTU2KQ==