Python and R Studio

RStudio is an Integrated Development Environment (IDE) designed primarily for the R programming language. It was created by a company originally called RStudio, Inc. Key features include:

  • A script editor with syntax highlighting and code completion
  • An interactive R console
  • An environment/variable explorer
  • Built-in tools for plotting, package management, and version control (Git)
  • Support for R Markdown (combining code, output, and narrative text)

Late 2022, RStudio, Inc. rebranded to Posit, PBC reflecting a strategic shift in mission:

RStudio (old) Posit (new)
Focus R-centric Language-agnostic (R and Python)
Mission Open-source tools for R Open-source data science for all
IDE name RStudio Still called RStudio (the IDE kept its name)
New products Positron (a new IDE), Quarto, etc.

So Posit is the company, and RStudio is still the name of the classic IDE it produces. Posit also develops newer tools like Positron, a next-generation IDE built on VS Code that natively supports both R and Python. This lesson focuses on programming in Python within R Studio.

RStudio supports Python through the reticulate R package. Here’s what you need to do in order to use Python within R Studio and to add Python code blocks to R Notebooks:

  1. Install Python on your machine (generally via python.org or Anaconda/Miniconda — the latter is recommended for environment management)

  2. Install the reticulate** package in R by either using R Studio or running:

    install.packages("reticulate")
  3. Configure your Python environment (recommended and often required):

    library(reticulate)
    use_python("/path/to/python")      # point to a specific interpreter
    # or
    use_virtualenv("myenv")            # use a virtual environment
    # or
    use_condaenv("myenv")              # use a conda environment

    If Python cannot be found or you get an error from py_config(), then set reticulate* to where your Python interpreter (typically python3) is installed and point the reticulate** package to that executable with `use_python_.

  4. You can then run Python in a few ways:

    • In R Markdown / Quarto documents using {python} code chunks
    • Interactively via repl_python() in the R console
    • Calling Python functions directly from R code
    • Writing full Python (.py) programs

Limitation: RStudio’s Python support is functional but secondary — it lacks features like a native Python debugger or a dedicated Python console. For those features, a dedicated Python IDE, such as PyCharm, Colab, or VS Code, is recommended.

Positron is Posit’s next-gen IDE (currently in active development/beta as of early 2026) and is the better choice for true Python work. It is built on VS Code and natively supports both R and Python as first-class languages, has a dedicated Python interpreter selector and fully supports Python virtual environments, Jupyter-style notebooks, and standard Python debugging.

Python Virtual Environment

The tutorial below explains how to configure a Python virtual environment in which to install all Python packages and run Python code. It is an alternative to using use_python().

Programming in Python

This lesson is not a tutorial on the Python programming language, but instead a tutorial on how to program in Python within R Studio. To that end, we present code below that shows how to include both R and Python code blocks within an R Notebook, execute each, and pass data between R and Python so that the best language, packages, and code structures can be used in a data analytics project.

The code in this R Notebook python-sandbox.Rmd and it has the following features which demonstrate various aspects of Python programming in R Studio and R Notebooks:

  1. py_config() – shows which Python interpreter RStudio is actually using, so you can confirm it’s the right one
  2. Basic print + sys info – confirms Python chunks execute and that f-strings work (Python 3.6+)
  3. Arithmetic & data types – exercises numbers, strings, and lists
  4. Standard library imports – confirms import works without needing any third-party packages
  5. R to Python – uses reticulate’s r object to pass R variables into a Python chunk
  6. Python to R – uses reticulate’s py object to pass Python variables back into an R chunk

Complete R Notebook for downloading and experimenting: python-sandbox.Rmd


Files & Resources

All Files for Lesson 7.100

Acknowledgements

Given the pervasive inclusion of Generative AI in development and writing environments, we acknowledge that AI may have been used in the preparation of this lesson. All code, material, and content has been validated, verified for accuracy, and edited. We thank Ohida Binte Amin for recording tutorials and testing Python code.

Errata

Let us know.

LS0tCnRpdGxlOiAiUHJvZ3JhbW1pbmcgd2l0aCBQeXRob24gaW4gUiBTdHVkaW8gKFBvc2l0KSIKcGFyYW1zOgogIGNhdGVnb3J5OiA3CiAgbnVtYmVyOiAxMDAKICB0aW1lOiAzMAogIGxldmVsOiBiZWdpbm5lcgogIHRhZ3M6ICJQeXRob24sU1FMLHNxbGRmLGRhdGFiYXNlLHNxbGl0ZSIKICBkZXNjcmlwdGlvbjogIkRlbW9uc3RyYXRlcyBob3cgdG8gcHJvZ3JhbSBpbiBQeXRob24gdXNpbmcgUiBTdHVkaW8KICAgICAgICAgICAgICAgIChQb3NpdCkgYXMgYSBkZXZlbG9wbWVudCBlbnZpcm9ubWVudC4gU2hvd3MgaG93IHRvCiAgICAgICAgICAgICAgICBtaXggUHl0aG9uIGluIFIgd2l0aGluIFIgTm90ZWJvb2tzLiIKZGF0ZTogIjxzbWFsbD5gciBTeXMuRGF0ZSgpYDwvc21hbGw+IgphdXRob3I6ICI8c21hbGw+TWFydGluIFNjaGVkbGJhdWVyPC9zbWFsbD4iCmVtYWlsOiAibS5zY2hlZGxiYXVlckBuZXUuZWR1IgphZmZpbGl0YXRpb246ICJOb3J0aGVhc3Rlcm4gVW5pdmVyc2l0eSIKb3V0cHV0OiAKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgY29sbGFwc2VkOiBmYWxzZQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdGhlbWU6IHNwYWNlbGFiCiAgICBoaWdobGlnaHQ6IHRhbmdvCi0tLQoKLS0tCnRpdGxlOiAiPHNtYWxsPmByIHBhcmFtcyRjYXRlZ29yeWAuYHIgcGFyYW1zJG51bWJlcmA8L3NtYWxsPjxici8+PHNwYW4gc3R5bGU9J2NvbG9yOiAjMkU0MDUzOyBmb250LXNpemU6IDAuOWVtJz5gciBybWFya2Rvd246Om1ldGFkYXRhJHRpdGxlYDwvc3Bhbj4iCi0tLQoKYGBge3IgY29kZT14ZnVuOjpyZWFkX3V0ZjgocGFzdGUwKGhlcmU6OmhlcmUoKSwnL1IvX2luc2VydDJEQi5SJykpLCBpbmNsdWRlID0gRkFMU0V9CmBgYAoKIyMgUHl0aG9uIGFuZCBSIFN0dWRpbwoKKipSU3R1ZGlvKiogaXMgYW4gKipJbnRlZ3JhdGVkIERldmVsb3BtZW50IEVudmlyb25tZW50IChJREUpKiogZGVzaWduZWQgcHJpbWFyaWx5IGZvciB0aGUgKipSIHByb2dyYW1taW5nIGxhbmd1YWdlKiouIEl0IHdhcyBjcmVhdGVkIGJ5IGEgY29tcGFueSBvcmlnaW5hbGx5IGNhbGxlZCBSU3R1ZGlvLCBJbmMuIEtleSBmZWF0dXJlcyBpbmNsdWRlOgoKLSAgIEEgc2NyaXB0IGVkaXRvciB3aXRoIHN5bnRheCBoaWdobGlnaHRpbmcgYW5kIGNvZGUgY29tcGxldGlvbgotICAgQW4gaW50ZXJhY3RpdmUgUiBjb25zb2xlCi0gICBBbiBlbnZpcm9ubWVudC92YXJpYWJsZSBleHBsb3JlcgotICAgQnVpbHQtaW4gdG9vbHMgZm9yIHBsb3R0aW5nLCBwYWNrYWdlIG1hbmFnZW1lbnQsIGFuZCB2ZXJzaW9uIGNvbnRyb2wgKEdpdCkKLSAgIFN1cHBvcnQgZm9yIFIgTWFya2Rvd24gKGNvbWJpbmluZyBjb2RlLCBvdXRwdXQsIGFuZCBuYXJyYXRpdmUgdGV4dCkKCkxhdGUgMjAyMiwgUlN0dWRpbywgSW5jLiAqKnJlYnJhbmRlZCB0byBQb3NpdCwgUEJDKiogcmVmbGVjdGluZyBhIHN0cmF0ZWdpYyBzaGlmdCBpbiBtaXNzaW9uOgoKfCAgIHwgUlN0dWRpbyAob2xkKSB8IFBvc2l0IChuZXcpIHwKfC0tLS18LS0tLXwtLS0tfAp8ICoqRm9jdXMqKiB8IFItY2VudHJpYyB8IExhbmd1YWdlLWFnbm9zdGljIChSICphbmQqIFB5dGhvbikgfAp8ICoqTWlzc2lvbioqIHwgT3Blbi1zb3VyY2UgdG9vbHMgZm9yIFIgfCBPcGVuLXNvdXJjZSBkYXRhIHNjaWVuY2UgZm9yIGFsbCB8CnwgKipJREUgbmFtZSoqIHwgUlN0dWRpbyB8IFN0aWxsIGNhbGxlZCAqKlJTdHVkaW8qKiAodGhlIElERSBrZXB0IGl0cyBuYW1lKSB8CnwgKipOZXcgcHJvZHVjdHMqKiB8IOKAlCB8IFBvc2l0cm9uIChhIG5ldyBJREUpLCBRdWFydG8sIGV0Yy4gfAoKU28gKipQb3NpdCBpcyB0aGUgY29tcGFueSoqLCBhbmQgKipSU3R1ZGlvIGlzIHN0aWxsIHRoZSBuYW1lIG9mIHRoZSBjbGFzc2ljIElERSoqIGl0IHByb2R1Y2VzLiBQb3NpdCBhbHNvIGRldmVsb3BzIG5ld2VyIHRvb2xzIGxpa2UgKipQb3NpdHJvbioqLCBhIG5leHQtZ2VuZXJhdGlvbiBJREUgYnVpbHQgb24gVlMgQ29kZSB0aGF0IG5hdGl2ZWx5IHN1cHBvcnRzIGJvdGggUiBhbmQgUHl0aG9uLiBUaGlzIGxlc3NvbiBmb2N1c2VzIG9uIHByb2dyYW1taW5nIGluIFB5dGhvbiB3aXRoaW4gUiBTdHVkaW8uCgpSU3R1ZGlvIHN1cHBvcnRzIFB5dGhvbiB0aHJvdWdoIHRoZSAqKnJldGljdWxhdGUqKiBSIHBhY2thZ2UuIEhlcmUncyB3aGF0IHlvdSBuZWVkIHRvIGRvIGluIG9yZGVyIHRvIHVzZSBQeXRob24gd2l0aGluIFIgU3R1ZGlvIGFuZCB0byBhZGQgUHl0aG9uIGNvZGUgYmxvY2tzIHRvIFIgTm90ZWJvb2tzOgoKMS4gICoqSW5zdGFsbCBQeXRob24qKiBvbiB5b3VyIG1hY2hpbmUgKGdlbmVyYWxseSB2aWEgW3B5dGhvbi5vcmddKGh0dHA6Ly9weXRob24ub3JnKSBvciBBbmFjb25kYS9NaW5pY29uZGEg4oCUIHRoZSBsYXR0ZXIgaXMgcmVjb21tZW5kZWQgZm9yIGVudmlyb25tZW50IG1hbmFnZW1lbnQpCgoyLiAgKipJbnN0YWxsIHRoZSoqIHJldGljdWxhdGVcKlwqIHBhY2thZ2UgaW4gUiBieSBlaXRoZXIgdXNpbmcgUiBTdHVkaW8gb3IgcnVubmluZzoKCiAgICBgYGAgcgogICAgaW5zdGFsbC5wYWNrYWdlcygicmV0aWN1bGF0ZSIpCiAgICBgYGAKCjMuICAqKkNvbmZpZ3VyZSB5b3VyIFB5dGhvbiBlbnZpcm9ubWVudCoqIChyZWNvbW1lbmRlZCBhbmQgb2Z0ZW4gcmVxdWlyZWQpOgoKICAgIGBgYCByCiAgICBsaWJyYXJ5KHJldGljdWxhdGUpCiAgICB1c2VfcHl0aG9uKCIvcGF0aC90by9weXRob24iKSAgICAgICMgcG9pbnQgdG8gYSBzcGVjaWZpYyBpbnRlcnByZXRlcgogICAgIyBvcgogICAgdXNlX3ZpcnR1YWxlbnYoIm15ZW52IikgICAgICAgICAgICAjIHVzZSBhIHZpcnR1YWwgZW52aXJvbm1lbnQKICAgICMgb3IKICAgIHVzZV9jb25kYWVudigibXllbnYiKSAgICAgICAgICAgICAgIyB1c2UgYSBjb25kYSBlbnZpcm9ubWVudAogICAgYGBgCgogICAgSWYgUHl0aG9uIGNhbm5vdCBiZSBmb3VuZCBvciB5b3UgZ2V0IGFuIGVycm9yIGZyb20gYHB5X2NvbmZpZygpYCwgdGhlbiBzZXQgKipyZXRpY3VsYXRlXCogdG8gd2hlcmUgeW91ciBQeXRob24gaW50ZXJwcmV0ZXIgKHR5cGljYWxseSAqcHl0aG9uMyopIGlzIGluc3RhbGxlZCBhbmQgcG9pbnQgdGhlKiogcmV0aWN1bGF0ZVwqXCogcGFja2FnZSB0byB0aGF0IGV4ZWN1dGFibGUgd2l0aCBcYHVzZV9weXRob25cXy4KCjQuICBZb3UgY2FuIHRoZW4gcnVuIFB5dGhvbiBpbiBhIGZldyB3YXlzOgoKICAgIC0gICBJbiAqKlIgTWFya2Rvd24gLyBRdWFydG8qKiBkb2N1bWVudHMgdXNpbmcgYHtweXRob259YCBjb2RlIGNodW5rcwogICAgLSAgIEludGVyYWN0aXZlbHkgdmlhIGByZXBsX3B5dGhvbigpYCBpbiB0aGUgUiBjb25zb2xlCiAgICAtICAgQ2FsbGluZyBQeXRob24gZnVuY3Rpb25zIGRpcmVjdGx5IGZyb20gUiBjb2RlCiAgICAtICAgV3JpdGluZyBmdWxsIFB5dGhvbiAoKi5weSopIHByb2dyYW1zCgo+ICoqTGltaXRhdGlvbjoqKiBSU3R1ZGlvJ3MgUHl0aG9uIHN1cHBvcnQgaXMgZnVuY3Rpb25hbCBidXQgc2Vjb25kYXJ5IOKAlCBpdCBsYWNrcyBmZWF0dXJlcyBsaWtlIGEgbmF0aXZlIFB5dGhvbiBkZWJ1Z2dlciBvciBhIGRlZGljYXRlZCBQeXRob24gY29uc29sZS4gRm9yIHRob3NlIGZlYXR1cmVzLCBhIGRlZGljYXRlZCBQeXRob24gSURFLCBzdWNoIGFzIFB5Q2hhcm0sIENvbGFiLCBvciBWUyBDb2RlLCBpcyByZWNvbW1lbmRlZC4KCioqUG9zaXRyb24qKiBpcyBQb3NpdCdzIG5leHQtZ2VuIElERSAoY3VycmVudGx5IGluIGFjdGl2ZSBkZXZlbG9wbWVudC9iZXRhIGFzIG9mIGVhcmx5IDIwMjYpIGFuZCBpcyB0aGUgYmV0dGVyIGNob2ljZSBmb3IgdHJ1ZSBQeXRob24gd29yay4gSXQgaXMgYnVpbHQgb24gVlMgQ29kZSBhbmQgbmF0aXZlbHkgc3VwcG9ydHMgKipib3RoIFIgYW5kIFB5dGhvbioqIGFzIGZpcnN0LWNsYXNzIGxhbmd1YWdlcywgaGFzIGEgZGVkaWNhdGVkIFB5dGhvbiBpbnRlcnByZXRlciBzZWxlY3RvciBhbmQgZnVsbHkgc3VwcG9ydHMgUHl0aG9uIHZpcnR1YWwgZW52aXJvbm1lbnRzLCBKdXB5dGVyLXN0eWxlIG5vdGVib29rcywgYW5kIHN0YW5kYXJkIFB5dGhvbiBkZWJ1Z2dpbmcuCgpgYGB7ciBlY2hvPUZBTFNFfQpsaXN0Lm9mLnBhY2thZ2VzIDwtIGMoInJldGljdWxhdGUiKQoKbmV3LnBhY2thZ2VzIDwtIGxpc3Qub2YucGFja2FnZXNbIShsaXN0Lm9mLnBhY2thZ2VzICVpbiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbGxlZC5wYWNrYWdlcygpWywiUGFja2FnZSJdKV0KCmlmKGxlbmd0aChuZXcucGFja2FnZXMpKSAKICBpbnN0YWxsLnBhY2thZ2VzKG5ldy5wYWNrYWdlcywgcmVwb3MgPSAiaHR0cHM6Ly9jbG91ZC5yLXByb2plY3Qub3JnIikKYGBgCgpgYGB7ciBlY2hvPUZBTFNFfQpsaWJyYXJ5KHJldGljdWxhdGUpCmBgYAoKIyMgUHl0aG9uIFZpcnR1YWwgRW52aXJvbm1lbnQKClRoZSB0dXRvcmlhbCBiZWxvdyBleHBsYWlucyBob3cgdG8gY29uZmlndXJlIGEgUHl0aG9uIHZpcnR1YWwgZW52aXJvbm1lbnQgaW4gd2hpY2ggdG8gaW5zdGFsbCBhbGwgUHl0aG9uIHBhY2thZ2VzIGFuZCBydW4gUHl0aG9uIGNvZGUuIEl0IGlzIGFuIGFsdGVybmF0aXZlIHRvIHVzaW5nIGB1c2VfcHl0aG9uKClgLgoKPGlmcmFtZSBzcmM9Imh0dHBzOi8vbm9ydGhlYXN0ZXJuLmhvc3RlZC5wYW5vcHRvLmNvbS9QYW5vcHRvL1BhZ2VzL0VtYmVkLmFzcHg/aWQ9YWNlYjYwYWQtZDhkOC00YjAwLThhYjQtYjNmZDAxMDZlMmJiJmFtcDthdXRvcGxheT1mYWxzZSZhbXA7b2ZmZXJ2aWV3ZXI9dHJ1ZSZhbXA7c2hvd3RpdGxlPWZhbHNlJmFtcDtzaG93YnJhbmQ9ZmFsc2UmYW1wO2NhcHRpb25zPWZhbHNlJmFtcDtpbnRlcmFjdGl2aXR5PWFsbCIgc3R5bGU9ImJvcmRlcjogMXB4IHNvbGlkICM0NjQ2NDY7IHdpZHRoOiA3MjBweDsgaGVpZ2h0OiA0MDVweDsiIGFsbG93ZnVsbHNjcmVlbiBhbGxvdz0iYXV0b3BsYXkiIGFyaWEtbGFiZWw9IlBhbm9wdG8gRW1iZWRkZWQgVmlkZW8gUGxheWVyIiBhcmlhLWRlc2NyaXB0aW9uPSJDb25maWd1cmluZyBQeXRob24gaW4gUiBTdHVkaW8iIGRhdGEtZXh0ZXJuYWw9IjEiPgoKPC9pZnJhbWU+CgojIyBQcm9ncmFtbWluZyBpbiBQeXRob24KClRoaXMgbGVzc29uIGlzIG5vdCBhIHR1dG9yaWFsIG9uIHRoZSBQeXRob24gcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UsIGJ1dCBpbnN0ZWFkIGEgdHV0b3JpYWwgb24gaG93IHRvIHByb2dyYW0gaW4gUHl0aG9uIHdpdGhpbiBSIFN0dWRpby4gVG8gdGhhdCBlbmQsIHdlIHByZXNlbnQgY29kZSBiZWxvdyB0aGF0IHNob3dzIGhvdyB0byBpbmNsdWRlIGJvdGggUiBhbmQgUHl0aG9uIGNvZGUgYmxvY2tzIHdpdGhpbiBhbiBSIE5vdGVib29rLCBleGVjdXRlIGVhY2gsIGFuZCBwYXNzIGRhdGEgYmV0d2VlbiBSIGFuZCBQeXRob24gc28gdGhhdCB0aGUgYmVzdCBsYW5ndWFnZSwgcGFja2FnZXMsIGFuZCBjb2RlIHN0cnVjdHVyZXMgY2FuIGJlIHVzZWQgaW4gYSBkYXRhIGFuYWx5dGljcyBwcm9qZWN0LgoKVGhlIGNvZGUgaW4gdGhpcyBSIE5vdGVib29rIFtweXRob24tc2FuZGJveC5SbWRdKHB5dGhvbi1zYW5kYm94LlJtZCkgYW5kIGl0IGhhcyB0aGUgZm9sbG93aW5nIGZlYXR1cmVzIHdoaWNoIGRlbW9uc3RyYXRlIHZhcmlvdXMgYXNwZWN0cyBvZiBQeXRob24gcHJvZ3JhbW1pbmcgaW4gUiBTdHVkaW8gYW5kIFIgTm90ZWJvb2tzOgoKMS4gICoqYHB5X2NvbmZpZygpYCoqIC0tIHNob3dzIHdoaWNoIFB5dGhvbiBpbnRlcnByZXRlciBSU3R1ZGlvIGlzIGFjdHVhbGx5IHVzaW5nLCBzbyB5b3UgY2FuIGNvbmZpcm0gaXQncyB0aGUgcmlnaHQgb25lCjIuICAqKkJhc2ljIHByaW50ICsgc3lzIGluZm8qKiAtLSBjb25maXJtcyBQeXRob24gY2h1bmtzIGV4ZWN1dGUgYW5kIHRoYXQgZi1zdHJpbmdzIHdvcmsgKFB5dGhvbiAzLjYrKQozLiAgKipBcml0aG1ldGljICYgZGF0YSB0eXBlcyoqIC0tIGV4ZXJjaXNlcyBudW1iZXJzLCBzdHJpbmdzLCBhbmQgbGlzdHMKNC4gICoqU3RhbmRhcmQgbGlicmFyeSBpbXBvcnRzKiogLS0gY29uZmlybXMgYGltcG9ydGAgd29ya3Mgd2l0aG91dCBuZWVkaW5nIGFueSB0aGlyZC1wYXJ0eSBwYWNrYWdlcwo1LiAgKipSIHRvIFB5dGhvbioqIC0tIHVzZXMgYHJldGljdWxhdGVgJ3MgYHJgIG9iamVjdCB0byBwYXNzIFIgdmFyaWFibGVzIGludG8gYSBQeXRob24gY2h1bmsKNi4gICoqUHl0aG9uIHRvIFIqKiAtLSB1c2VzIGByZXRpY3VsYXRlYCdzIGBweWAgb2JqZWN0IHRvIHBhc3MgUHl0aG9uIHZhcmlhYmxlcyBiYWNrIGludG8gYW4gUiBjaHVuawoKKipDb21wbGV0ZSBSIE5vdGVib29rIGZvciBkb3dubG9hZGluZyBhbmQgZXhwZXJpbWVudGluZyoqOiBbcHl0aG9uLXNhbmRib3guUm1kXShweXRob24tc2FuZGJveC5SbWQpCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIEZpbGVzICYgUmVzb3VyY2VzCgpgYGB7ciB6aXBGaWxlcywgZWNobz1GQUxTRX0KemlwTmFtZSA9IHNwcmludGYoIkxlc3NvbkZpbGVzLSVzLSVzLnppcCIsIAogICAgICAgICAgICAgICAgIHBhcmFtcyRjYXRlZ29yeSwKICAgICAgICAgICAgICAgICBwYXJhbXMkbnVtYmVyKQoKdGV4dEFMaW5rID0gcGFzdGUwKCJBbGwgRmlsZXMgZm9yIExlc3NvbiAiLCAKICAgICAgICAgICAgICAgcGFyYW1zJGNhdGVnb3J5LCIuIixwYXJhbXMkbnVtYmVyKQoKIyBkb3dubG9hZEZpbGVzTGluaygpIGlzIGluY2x1ZGVkIGZyb20gX2luc2VydDJEQi5SCmtuaXRyOjpyYXdfaHRtbChkb3dubG9hZEZpbGVzTGluaygiLiIsIHppcE5hbWUsIHRleHRBTGluaykpCmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBBY2tub3dsZWRnZW1lbnRzCgpHaXZlbiB0aGUgcGVydmFzaXZlIGluY2x1c2lvbiBvZiBHZW5lcmF0aXZlIEFJIGluIGRldmVsb3BtZW50IGFuZCB3cml0aW5nIGVudmlyb25tZW50cywgd2UgYWNrbm93bGVkZ2UgdGhhdCBBSSBtYXkgaGF2ZSBiZWVuIHVzZWQgaW4gdGhlIHByZXBhcmF0aW9uIG9mIHRoaXMgbGVzc29uLiBBbGwgY29kZSwgbWF0ZXJpYWwsIGFuZCBjb250ZW50IGhhcyBiZWVuIHZhbGlkYXRlZCwgdmVyaWZpZWQgZm9yIGFjY3VyYWN5LCBhbmQgZWRpdGVkLiBXZSB0aGFuayBPaGlkYSBCaW50ZSBBbWluIGZvciByZWNvcmRpbmcgdHV0b3JpYWxzIGFuZCB0ZXN0aW5nIFB5dGhvbiBjb2RlLgoKIyMgRXJyYXRhCgpbTGV0IHVzIGtub3ddKGh0dHBzOi8vZm9ybS5qb3Rmb3JtLmNvbS8yMTIxODcwNzI3ODQxNTcpe3RhcmdldD0iX2JsYW5rIn0uCg==