diff --git a/pyscriptjs/public/bokeh_interactive.html b/pyscriptjs/public/bokeh_interactive.html
new file mode 100644
index 0000000..822eaea
--- /dev/null
+++ b/pyscriptjs/public/bokeh_interactive.html
@@ -0,0 +1,96 @@
+
+ Bokeh Example
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+- bokeh
+- numpy
+
+ Bokeh Example
+
+
+
+import asyncio
+import json
+import pyodide
+
+from js import Bokeh, console, JSON
+
+from bokeh import __version__
+from bokeh.document import Document
+from bokeh.embed.util import OutputDocumentFor, standalone_docs_json
+from bokeh.models import Slider, Div
+from bokeh.layouts import Row
+from bokeh.protocol.messages.patch_doc import process_document_events
+
+# create a new plot with default tools, using figure
+p = Slider(start=0.1, end=10, value=1, step=.1, title="Amplitude")
+div = Div(text=f'Amplitude is: {p.value}')
+
+def callback(attr, old, new):
+ div.text = f'Amplitude is: {new}'
+
+p.on_change('value', callback)
+
+row = Row(children=[p, div])
+
+print("about to embed")
+
+def doc_json(model, target):
+ with OutputDocumentFor([model]) as doc:
+ doc.title = ""
+ docs_json = standalone_docs_json([model])
+
+ doc_json = list(docs_json.values())[0]
+ root_id = doc_json['roots']['root_ids'][0]
+
+ return doc, json.dumps(dict(
+ target_id = target,
+ root_id = root_id,
+ doc = doc_json,
+ version = __version__,
+ ))
+
+def link_docs(pydoc, jsdoc):
+ def jssync(event):
+ if (event.setter_id is not None):
+ return
+ events = [event]
+ json_patch = jsdoc.create_json_patch_string(pyodide.to_js(events))
+ pydoc.apply_json_patch(json.loads(json_patch))
+
+ jsdoc.on_change(pyodide.create_proxy(jssync), pyodide.to_js(False))
+
+ def pysync(event):
+ json_patch = process_document_events([event], use_buffers=False)[0]
+
+ jsdoc.apply_json_patch(JSON.parse(json_patch), {}, setter_id='js')
+
+ pydoc.on_change(pysync)
+
+async def show(plot, target):
+ pydoc, model_json = doc_json(plot, target)
+ views = await Bokeh.embed.embed_item(JSON.parse(model_json))
+ print("Done embedding...")
+ jsdoc = views[0].model.document
+ link_docs(pydoc, jsdoc)
+
+await show(row, 'myplot')
+
+
+
+
diff --git a/pyscriptjs/public/panel.html b/pyscriptjs/public/panel.html
new file mode 100644
index 0000000..25cc314
--- /dev/null
+++ b/pyscriptjs/public/panel.html
@@ -0,0 +1,97 @@
+
+ Bokeh Example
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+- bokeh
+- numpy
+
+ Bokeh Example
+
+
+
+import json
+import pyodide
+import asyncio
+import micropip
+
+from js import Bokeh, console, JSON
+
+import bokeh
+
+from bokeh.document import Document
+from bokeh.embed.util import OutputDocumentFor, standalone_docs_json
+from bokeh.protocol.messages.patch_doc import process_document_events
+
+await micropip.install(['panel==0.13.0rc5'])
+
+import panel as pn
+
+def callback(new):
+ return f'Amplitude is: {new}'
+
+slider = pn.widgets.FloatSlider(start=0, end=10, name='Amplitude')
+
+row = pn.Row(slider, pn.bind(callback, slider))
+
+print("about to embed")
+
+def doc_json(model, target):
+ doc = model.server_doc()
+ model = doc.roots[0]
+ docs_json = standalone_docs_json([model])
+
+ doc_json = list(docs_json.values())[0]
+ root_id = doc_json['roots']['root_ids'][0]
+
+ return doc, json.dumps(dict(
+ target_id = target,
+ root_id = root_id,
+ doc = doc_json,
+ version = bokeh.__version__,
+ ))
+
+def link_docs(pydoc, jsdoc):
+ def jssync(event):
+ if (event.setter_id is not None):
+ return
+ events = [event]
+ json_patch = jsdoc.create_json_patch_string(pyodide.to_js(events))
+ pydoc.apply_json_patch(json.loads(json_patch))
+
+ jsdoc.on_change(pyodide.create_proxy(jssync), pyodide.to_js(False))
+
+ def pysync(event):
+ json_patch = process_document_events([event], use_buffers=False)[0]
+
+ jsdoc.apply_json_patch(JSON.parse(json_patch), {}, setter_id='js')
+
+ pydoc.on_change(pysync)
+
+async def show(plot, target):
+ pydoc, model_json = doc_json(plot, target)
+ views = await Bokeh.embed.embed_item(JSON.parse(model_json))
+ print("Done embedding...")
+ jsdoc = views[0].model.document
+ link_docs(pydoc, jsdoc)
+
+await show(row, 'myplot')
+
+
+
+