"use strict" ; import * as path from "path" ; import * as vscode from "vscode" ; import { Limit } from "./throttle" ; import Utilities from "./utilities" ; import { settings } from "./settings" ; /**
 * shows AREPL output (variables, errors, timing, and stdout/stderr)
 * https://code.visualstudio.com/docs/extensions/webview
 */ export default class PythonPanelPreview { static readonly scheme = "pythonPanelPreview" ; static readonly PREVIEW_URI = PythonPanelPreview . scheme + "://authority/preview" ; public throttledUpdate : ( ) => void ; private _onDidChange : vscode . EventEmitter < vscode . Uri > ; private lastTime : number = 999999999 ; private html ; private readonly landingPage = `
    <br>
    <p style="font-size:14px">Start typing or make a change and your code will be evaluated.</p>
    
    <p style="font-size:14px">⚠ <b style="color:red">WARNING:</b> code is evaluated WHILE YOU TYPE - don't try deleting files/folders! ⚠</p>
    <p>evaluation while you type can be turned off or adjusted in the settings</p>
    <br>
    <h3>AREPL v2.0.3 🐛 - Flamingo</h3>
    <ul>
    <li>🐛 Fixed python path from python extension no longer being automatically used by AREPL</li>
    <li>Help me make arepl better by filling out this short survey: <a href="https://forms.gle/m7xirfRnSRoPAe9e9">https://forms.gle/m7xirfRnSRoPAe9e9</a></li>
    </ul>
    <br>
    
    <h3>Examples</h3>
    
<h4>Simple List</h4>
<code style="white-space:pre-wrap">
x = [1,2,3]
y = [num*2 for num in x]
print(y)
</code>

<h4>Dumping</h4>
<code style="white-space:pre-wrap">
from arepl_dump import dump 

def milesToKilometers(miles):
    kilometers = miles*1.60934
    dump() # dumps all the vars in your function

    # or dump when function is called for a second time
    dump(None,1) 

milesToKilometers(2*2)
milesToKilometers(3*3)

for char in ['a','b','c']:
    dump(char,2) # dump a var at a specific iteration

a=1
dump(a) # dump specific vars at any point in your program
a=2
</code>

<h4>Turtle</h4>
<code style="white-space:pre-wrap">
import turtle

# window in right hand side of screen
turtle.setup(500,500,-1,0)

# you can comment this out to keep state inbetween runs
turtle.reset()

turtle.forward(100)
turtle.left(90)
</code>

<h4>Web call</h4>
<code style="white-space:pre-wrap">
import requests
import datetime as dt

r = requests.get("https://api.github.com")

#$save
# #$save saves state so request is not re-executed when modifying below

now = dt.datetime.now()
if r.status_code == 200:
    print("API up at " + str(now))

</code>` ; private readonly footer = `<br><br>
        <div id="footer">
        <p style="margin:0px;">
            report an <a href="https://github.com/almenon/arepl-vscode/issues">issue</a>  |
            ⭐ <a href="https://marketplace.visualstudio.com/items?itemName=almenon.arepl#review-details">rate me</a> ⭐ |
            talk on <a href="https://gitter.im/arepl/lobby">gitter</a> |
                <a href="https://twitter.com/intent/tweet?button_hashtag=arepl" id="twitterButton">
                    <i id="twitterIcon"></i>Tweet #arepl</a>
        </p>
        </div>` ; private css : string ; private jsonRendererScript : string ; private errorContainer = "" ; private jsonRendererCode = `<script></script>` ; private emptyPrint = `<br><h3>Print Output:</h3><div id="print"></div>` ; private printContainer = this . emptyPrint ; private timeContainer = "" ; private panel : vscode . WebviewPanel ; private customCSS = "" ; constructor ( private context , htmlUpdateFrequency = 50 ) { this . _onDidChange = new vscode . EventEmitter < vscode . Uri > ( ) ; if ( htmlUpdateFrequency != 0 ) { const l = new Limit ( ) ; this . throttledUpdate = l . throttledUpdate ( this . updateContent , htmlUpdateFrequency ) ; } else this . throttledUpdate = this . updateContent ; } start ( linkedFileName ) { this . panel = vscode . window . createWebviewPanel ( "arepl" , "AREPL - " + linkedFileName , vscode . ViewColumn . Two , { enableScripts : true } ) ; this . css = `<link rel="stylesheet" type="text/css" href="${ this . getMediaPath ( "pythonPanelPreview.css" , this . panel . webview ) }">` ; this . jsonRendererScript = `<script src="${ this . getMediaPath ( "jsonRenderer.js" , this . panel . webview ) }"></script>` ; this . panel . webview . html = this . landingPage ; return this . panel ; } public updateVars ( vars ) { let userVarsCode = `userVars = ${ JSON . stringify ( vars ) };` ; userVarsCode = userVarsCode . replace ( /<\/script>/g , "<\\/script>" ) ; this . jsonRendererCode = `<script>
            window.onload = function(){
                ${ userVarsCode }
                let jsonRenderer = renderjson.set_icons('+', '-') // default icons look a bit wierd, overriding
                    .set_show_to_level(${ settings ( ) . get ( "show_to_level" ) }) 
                    .set_max_string_length(${ settings ( ) . get ( "max_string_length" ) });
                document.getElementById("results").appendChild(jsonRenderer(userVars));
            }
            </script>` ; } public updateTime ( time ) { let color ; time = Math . floor ( time ) ; if ( time > this . lastTime ) color = "red" ; else color = "green" ; this . lastTime = time ; this . timeContainer = `<p style="position:fixed;left:90%;top:90%;color:${ color };">${ time } ms</p>` ; } param refresh public updateError ( err , refresh = false ) { err = Utilities . escapeHtml ( err ) ; err = this . makeErrorGoogleable ( err ) ; this . errorContainer = `<div id="error">${ err }</div>` ; if ( refresh ) this . throttledUpdate ( ) ; } public injectCustomCSS ( css , refresh = false ) { this . customCSS = css ; if ( refresh ) this . throttledUpdate ( ) ; } public handlePrint ( printResults ) { printResults = Utilities . escapeHtml ( printResults ) ; this . printContainer = `<br><h3>Print Output:</h3><div class="print">${ printResults }</div>` ; this . throttledUpdate ( ) ; } clearPrint ( ) { this . printContainer = this . emptyPrint ; } public displayProcessError ( err ) { let errMsg = `Error in the AREPL extension!\n${ err }` ; if ( err . includes ( "ENOENT" ) || err . includes ( "9009" ) ) { errMsg = errMsg + `\n\nAre you sure you have installed python 3 and it is in your PATH?
            You can download python here: https://www.python.org/downloads/` ; } this . updateError ( errMsg , true ) ; } private makeErrorGoogleable ( err ) { if ( err && err . trim ( ) . length > 0 ) { let errLines = err . split ( "\n" ) ; for ( let i = errLines . length - 1 ; i >= 0 ; i -- ) { const errRegex = /(^[\w\.]+): / ; if ( errLines [ i ] . match ( errRegex ) ) { const googleLink = "https://www.google.com/search?q=python " ; errLines [ i ] = errLines [ i ] . link ( googleLink + errLines [ i ] ) ; } } return errLines . join ( "\n" ) ; } else return err ; } get onDidChange ( ) : vscode . Event < vscode . Uri > { return this . _onDidChange . event ; } private getMediaPath ( mediaFile , webview ) { const onDiskPath = vscode . Uri . file ( path . join ( this . context . extensionPath , "media" , mediaFile ) ) ; return webview . asWebviewUri ( onDiskPath ) ; } private updateContent ( ) { const printPlacement = settings ( ) . get < string > ( "printResultPlacement" ) ; const showFooter = settings ( ) . get < boolean > ( "showFooter" ) ; const variables = '<h3>Variables:</h3><div id="results"></div>' ; this . html = `<!doctype html>
        <html lang="en">
        <head>
            <title>AREPL</title>
            ${ this . css }
            <style>${ this . customCSS }</style>
            ${ this . jsonRendererScript }
            ${ this . jsonRendererCode }
        </head>
        <body>
            ${ this . errorContainer }
            ${ printPlacement == "bottom" ? variables + this . printContainer : this . printContainer + variables }
            ${ this . timeContainer }
            ${ showFooter ? this . footer : "" }
            <div id="${ Math . random ( ) }" style="display:none"></div>
        </body>
        </html>` ; try { this . panel . webview . html = this . html ; } catch ( error ) { if ( error instanceof Error && error . message . includes ( "disposed" ) ) { console . warn ( error ) ; } else throw error ; } this . _onDidChange . fire ( vscode . Uri . parse ( PythonPanelPreview . PREVIEW_URI ) ) ; } }