diff --git a/poc/example.html b/poc/example.html
new file mode 100644
index 00000000..0dbe7ac4
--- /dev/null
+++ b/poc/example.html
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+sum([1, 2, 3, 4, 5])
+
+
+
diff --git a/poc/pyscript.js b/poc/pyscript.js
new file mode 100644
index 00000000..d7322850
--- /dev/null
+++ b/poc/pyscript.js
@@ -0,0 +1,117 @@
+class PyScript extends HTMLElement {
+ constructor() {
+ super();
+
+ // attach shadow so we can preserve the element original innerHtml content
+ this.shadow = this.attachShadow({ mode: 'open'});
+
+ this.wrapper = document.createElement('slot');
+
+ // add an extra div where we can attach the codemirror editor
+ this.editor = document.createElement('div');
+
+ this.shadow.appendChild(this.wrapper);
+ this.shadow.appendChild(this.editor);
+ this.code = this.wrapper.innerHTML;
+ }
+ connectedCallback() {
+
+ }
+
+ render(){
+ // debugger;
+ }
+ }
+
+ customElements.define('py-script', PyScript);
+
+
+ function create_menu (){
+
+ var div = document.createElement("div");
+
+ div.innerHTML = `
+
+ `;
+ document.body.appendChild(div);
+
+ document.querySelectorAll('py-script').forEach((elem, i) => {
+ var code = elem.innerHTML;
+ elem.innerHTML = "";
+ elem.code = code;
+ elem.cm = CodeMirror(elem, {
+ lineNumbers: true,
+ tabSize: 2,
+ value: code,
+ mode: 'python'
+ });
+
+ elem.btnRun = document.createElement('button');
+ elem.btnRun.innerHTML = "run";
+ elem.btnRun.classList.add("run");
+
+ elem.appendChild(elem.btnRun);
+
+ elem.btnEdit = document.createElement('button');
+ elem.btnEdit.innerHTML = "edit";
+ elem.btnEdit.classList.add("edit");
+ elem.appendChild(elem.btnEdit);
+
+ var eDiv = document.createElement('div');
+
+ elem.editorOut = document.createElement('textarea');
+ elem.editorOut.classList.add("output");
+ elem.editorOut.disabled = true;
+ eDiv.appendChild(elem.editorOut);
+ elem.appendChild(eDiv);
+
+ function addToOutput(s) {
+ elem.editorOut.value += ">>>" + s + "\n";
+ }
+ elem.btnRun.onclick = evaluatePython;
+
+ async function evaluatePython() {
+ var code = elem.cm.getValue();
+ let pyodide = await pyodideReadyPromise;
+ try {
+ let output = pyodide.runPython(code);
+ addToOutput(output);
+ } catch (err) {
+ addToOutput(err);
+ }
+ }
+
+
+ });
+ }
+
+ window.onload= create_menu;
+
+ async function main() {
+ let pyodide = await loadPyodide({
+ indexURL: "https://cdn.jsdelivr.net/pyodide/v0.19.0/full/",
+ });
+
+ return pyodide;
+ }
+ let pyodideReadyPromise = main();
+
+ async function evaluatePython() {
+ let pyodide = await pyodideReadyPromise;
+ try {
+ let output = pyodide.runPython(code.value);
+ addToOutput(output);
+ } catch (err) {
+ addToOutput(err);
+ }
+ }
+
diff --git a/poc/pyscript1.css b/poc/pyscript1.css
new file mode 100644
index 00000000..62b603c9
--- /dev/null
+++ b/poc/pyscript1.css
@@ -0,0 +1,140 @@
+body {
+ background-color: #f5f5f5;
+ padding-left: 80px;
+}
+
+button {
+ overflow: visible;
+ position: relative;
+ float: right;
+ border: 0;
+ padding: 0;
+ cursor: pointer;
+ height: 40px;
+ width: 110px;
+ font: 13px/40px 'lucida sans', 'trebuchet MS', 'Tahoma';
+ color: #fff;
+ margin-top: -20px;
+ text-transform: uppercase;
+ border-radius: 40px;
+ text-shadow: 0 -1px 0 rgba(0, 0 ,0, .3);
+}
+
+button.edit {
+ background-color: rgba(83, 83, 83, 0.8);
+}
+
+button.run{
+ background: #198cff;
+}
+
+textarea.output {
+ width: 100%;
+ height: 50px;
+ background: rgba(235, 235, 235, 0.8);
+}
+
+.float{
+ position:fixed;
+ width:60px;
+ height:60px;
+ top:40px;
+ left:20px;
+ /* background-color:#0C9; */
+ color:#FFF;
+ border-radius:50px;
+ text-align:center;
+ box-shadow: 2px 2px 3px #999;
+}
+
+
+.adminActions {
+ position: fixed;
+
+ top:20px;
+ left:15px;
+}
+
+ .adminButton {
+ height: 60px;
+ width: 60px;
+ background-color: rgba(67, 83, 143, .8);
+ border-radius: 50%;
+ display: block;
+ color: #fff;
+ text-align: center;
+ position: relative;
+ z-index: 1;
+ }
+
+ .adminButton i {
+ font-size: 22px;
+ }
+
+ .adminButtons {
+ position: absolute;
+ width: 100%;
+ /* bottom: 120%; */
+ bottom: -380%;
+ text-align: center;
+ }
+
+ .adminButtons a {
+ display: block;
+ width: 45px;
+ height: 45px;
+ border-radius: 50%;
+ text-decoration: none;
+ margin: 10px auto 0;
+ line-height: 1.15;
+ color: #fff;
+ opacity: 0;
+ visibility: hidden;
+ position: relative;
+ box-shadow: 0 0 5px 1px rgba(51, 51, 51, .3);
+ }
+
+ .adminButtons a:hover {
+ transform: scale(1.05);
+ }
+
+ .adminButtons a:nth-child(1) {background-color: #ff5722; transition: opacity .2s ease-in-out .03s, transform .15s ease-in-out;}
+ .adminButtons a:nth-child(2) {background-color: #03a9f4; transition: opacity .2s ease-in-out .025s, transform .15s ease-in-out;}
+ .adminButtons a:nth-child(3) {background-color: #f44336; transition: opacity .2s ease-in-out .02s, transform .15s ease-in-out;}
+ .adminButtons a:nth-child(4) {background-color: #4CAF50; transition: opacity .2s ease-in-out .05s, transform .15s ease-in-out;}
+
+ .adminActions a i {
+ position: absolute;
+ top: 50%; left: 50%;
+ transform: translate(-50%, -50%);
+ }
+
+ .adminToggle {
+ -webkit-appearance: none;
+ position: absolute;
+ border-radius: 50%;
+ top: 0; left: 0;
+ margin: 0;
+ width: 100%;
+ height: 100%;
+ cursor: pointer;
+ background-color: transparent;
+ border: none;
+ outline: none;
+ z-index: 2;
+ transition: box-shadow .2s ease-in-out;
+ box-shadow: 0 3px 5px 1px rgba(51, 51, 51, .3);
+ }
+
+ .adminToggle:hover {
+ box-shadow: 0 3px 6px 2px rgba(51, 51, 51, .3);
+ }
+
+ .adminToggle:checked ~ .adminButtons a {
+ opacity: 1;
+ visibility: visible;
+ }
+
+
+
+
\ No newline at end of file