├── .gitattributes
├── .gitignore
├── .isort.cfg
├── .pylintrc
├── .vscode
└── settings.json
├── DEVELOPER_GUIDE.md
├── LICENSE
├── MANIFEST.in
├── README.md
├── VERSION
├── assets
└── images
│ ├── examples
│ └── SketchApp.gif
│ ├── panel-logo.png
│ ├── panel-sketch-basic-example.png
│ ├── panel-sketch-binder.gif
│ └── panel-sketch-logo.png
├── binder
├── jupyter-examples-server
│ ├── __init__.py
│ ├── examples-icon.svg
│ ├── jupyter_examples_server.py
│ └── setup.py
└── requirements.txt
├── docker
└── Dockerfile.pip
├── examples
├── Sketch.ipynb
└── pyp5js
│ ├── __init__.py
│ └── gallery
│ ├── gallery.py
│ ├── sketch_000.py
│ ├── sketch_001.py
│ ├── sketch_002.py
│ ├── sketch_004.py
│ ├── sketch_005.py
│ ├── sketch_006.py
│ ├── sketch_007.py
│ ├── sketch_008.py
│ └── sketch_010.py
├── mypy.ini
├── panel_sketch
├── .bokeh
├── __init__.py
├── bokeh.ext.json
├── config.py
├── dist
│ ├── panel_sketch.js
│ ├── panel_sketch.js.map
│ ├── panel_sketch.json
│ └── panel_sketch.min.js
├── index.ts
├── models
│ ├── __init__.py
│ ├── index.ts
│ ├── sketch.py
│ └── sketch.ts
├── package-lock.json
├── package.json
├── sketch.py
├── sketch_base.py
├── sketch_compiler
│ ├── __init__.py
│ ├── assets
│ │ └── js
│ │ │ └── transcrypt
│ │ │ ├── org.transcrypt.__runtime__.js
│ │ │ ├── org.transcrypt.__runtime__.map
│ │ │ ├── org.transcrypt.__runtime__.py
│ │ │ ├── pyp5js.js
│ │ │ ├── pyp5js.map
│ │ │ ├── pyp5js.py
│ │ │ ├── pyp5js.python_functions.js
│ │ │ ├── pyp5js.python_functions.map
│ │ │ └── pyp5js.python_functions.py
│ ├── template_pyodide_basic.js
│ ├── template_pyodide_pyp5js.js
│ ├── template_transcrypt_basic.py
│ └── template_transcrypt_pyp5js.py
├── sketch_editor.py
├── sketch_viewer.py
└── tsconfig.json
├── pyproject.toml
├── pytest.ini
├── setup.py
├── tasks
├── __init__.py
└── test.py
└── tests
├── __init__.py
├── models
├── __init__.py
└── test_sketch.py
├── test_pyodide_compiler.py
├── test_sketch.py
├── test_sketch_base.py
├── test_sketch_compiler.py
├── test_sketch_editor.py
├── test_sketch_viewer.py
└── test_transcrypt_compiler.py
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Line Endings configuration file for Git
2 | # See https://docs.github.com/en/free-pro-team@latest/github/using-git/configuring-git-to-handle-line-endings
3 | # Set the default behavior, in case people don't have or can't have core.autocrlf set.
4 | * text=auto
5 |
6 | # Explicitly declare text files you want to always be normalized and converted
7 | # to native line endings on checkout.
8 | *.py text
9 | *.js text
10 | *.html text
11 | *.css text
12 | *.yml text
13 | *.md text
14 |
15 | # Denote all files that are truly binary and should not be modified.
16 | *.png binary
17 | *.jpg binary
18 | *.gif binary
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
131 | # Custom ignore
132 | panel_sketch/node_modules
133 | test_results
134 | !panel_sketch/dist
--------------------------------------------------------------------------------
/.isort.cfg:
--------------------------------------------------------------------------------
1 | [settings]
2 |
--------------------------------------------------------------------------------
/.pylintrc:
--------------------------------------------------------------------------------
1 | [MASTER]
2 | load-plugins=pylint.extensions.mccabe
3 | extension-pkg-whitelist: cx_Oracle
4 |
5 | [FORMAT]
6 | max-line-length=100
7 |
8 | [MESSAGES CONTROL]
9 | # bad-continuation: Pylint cannot handle valid indendation created by Black
10 | # duplicate-code: The _current_event and _past_event have some similar code. But it's ok.
11 | disable=bad-continuation,duplicate-code
12 |
13 |
14 | [DESIGN]
15 | max-attributes=12
16 | max-parents=13
17 |
18 | [TYPECHECK]
19 | generated-members=REQUEST,acl_users,aq_parent,"[a-zA-Z]+_set{1,2}",save,delete
20 | ignored-modules=winreg
21 |
22 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "python.pythonPath": ".venv\\Scripts\\python.exe"
3 | }
--------------------------------------------------------------------------------
/DEVELOPER_GUIDE.md:
--------------------------------------------------------------------------------
1 | # For Contributers
2 |
3 | ## Prerequisites
4 |
5 | - Python
6 | - Node >= 14
7 |
8 | ## Installation
9 |
10 | ```bash
11 | git clone https://github.com/marcskovmadsen/panel-sketch
12 | cd panel-sketch
13 | ```
14 |
15 | Create your virtual environment.
16 |
17 | ```bash
18 | python -m venv .venv
19 | ```
20 |
21 | Activate your virtual environment. On Windows with Git Bash it can be done via
22 |
23 | ```bash
24 | source .venv/Scripts/activate
25 | ```
26 |
27 | Install the `panel-sketch` package for editing
28 |
29 | ```bash
30 | pip install -e .[all]
31 | ```
32 |
33 | ## Bokeh Models build
34 |
35 | ```bash
36 | panel build panel_sketch
37 | ```
38 |
39 | ## Tests
40 |
41 | ```bash
42 | invoke test.all
43 | ```
44 |
45 | will run `isort`, `autoflake`, `black`, `pylint`, `mypy` and `pytest`. It should look like
46 |
47 | ```bash
48 | $ invoke test.all
49 |
50 | Running isort the Python code import sorter
51 | ===========================================
52 |
53 | isort .
54 | Skipped 7 files
55 |
56 | Running autoflake to remove unused imports on all .py files recursively
57 | =======================================================================
58 |
59 | autoflake --imports=pytest,pandas,numpy,plotly,dash,urllib3 --in-place --recur
60 | sive .
61 |
62 | Running Black the Python code formatter
63 | =======================================
64 |
65 | black .
66 | All done! \u2728 \U0001f370 \u2728
67 | 16 files left unchanged.
68 |
69 | Running pylint.
70 | Pylint looks for programming errors, helps enforcing a coding standard,
71 | sniffs for code smells and offers simple refactoring suggestions.
72 | =======================================================================
73 |
74 | pylint setup.py tasks panel_sketch tests
75 |
76 | --------------------------------------------------------------------
77 | Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)
78 |
79 |
80 | Running mypy for identifying python type errors
81 | ===============================================
82 |
83 | mypy setup.py tasks panel_sketch tests
84 | Success: no issues found in 16 source files
85 |
86 | Running pytest the test framework
87 | =================================
88 |
89 | pytest tests --doctest-modules --cov=panel_sketch -m "not functionaltest a
90 | nd not integrationtest" --cov-report html:test_results/cov_html
91 | ============================= test session starts =============================
92 | platform win32 -- Python 3.8.4, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
93 | rootdir: C:\repos\private\panel-sketch, configfile: pytest.ini, testpaths: tests
94 | plugins: anyio-2.2.0, cov-2.11.1
95 | collected 6 items
96 |
97 | tests\test_config.py . [ 16%]
98 | tests\test_highchart.py ... [ 66%]
99 | tests\models\test_highchart.py .. [100%]
100 |
101 | ----------- coverage: platform win32, python 3.8.4-final-0 -----------
102 | Coverage HTML written to dir test_results/cov_html
103 |
104 |
105 | ============================== 6 passed in 2.07s ==============================
106 |
107 | All Tests Passed Successfully
108 | =============================
109 | ```
110 |
111 | ## Package build
112 |
113 | In the `VERSION` file update the `version` number and then run
114 |
115 | ```bash
116 | python setup.py sdist bdist_wheel
117 | ```
118 |
119 | ## Package Deploy
120 |
121 | to production
122 |
123 | ```bash
124 | python -m twine upload dist/*20210411.1*
125 | ```
126 |
127 | or to test
128 |
129 | ```bash
130 | python -m twine upload --repository testpypi dist/*20210403.1.4*
131 | ```
132 |
133 | Have binder build the new image: [binder](https://mybinder.org/v2/gh/MarcSkovMadsen/panel-sketch/HEAD?filepath=examples)
134 |
135 | ## Build and Run Binder Image Locally
136 |
137 | In order to test the Binder Image you can install repo2docker
138 |
139 | ```python
140 | python -m pip install jupyter-repo2docker
141 | ```
142 |
143 | You can then run
144 |
145 | ```python
146 | jupyter-repo2docker https://github.com/MarcSkovMadsen/panel-sketch
147 | ```
148 |
149 | Note: Does not work on Windows.
150 |
151 | ## Open Binder
152 |
153 | Open Binder to rebuild the package
154 |
155 | [Open Binder](https://mybinder.org/v2/gh/MarcSkovMadsen/panel-sketch/HEAD?filepath=examples)
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Marc Skov Madsen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | graft panel_sketch/dist
2 | include panel_sketch/*.json
3 | include panel_sketch/models/*.ts
4 | include panel_sketch/index.ts
5 | include README.md
6 | global-exclude *.ipynb_checkpoints/*
7 | global-exclude *.py[co]
8 | global-exclude *~
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # ✏ ️ Panel Sketch
4 |
5 | THIS IS APLHA SOFTWARE AND YOU MAY EXPERIENCE API CHANGES AND ROUGH EDGES.
6 |
7 | The purpose of the `panel-sketch` package is to make it easy for Pythonistas to quickly sketch interactive visualizations and other applications running in
8 |
9 | - The browser - also without a Python backend
10 | - The Jupyter Notebook.
11 | - Your favorite editor or IDE.
12 |
13 | It is heavily inspired by [p5js](https://p5js.org/get-started/), [p5js sketches](https://editor.p5js.org/p5/sketches) and [pyp5js](https://github.com/berinhard/pyp5js) ❤️ It is not limited to the p5js universe though.
14 |
15 | You can also think of it as a [Code Sandbox](https://codesandbox.io/) or [JS Fiddle](https://jsfiddle.net/) but for #Python, #PyData and #PyViz 🐍.
16 |
17 | [](https://mybinder.org/v2/gh/marcskovmadsen/panel-sketch/HEAD?urlpath=lab/tree/examples/Sketch.ipynb)
18 |
19 | It leverages the powerful `Python` to `Javascript` frameworks [Pyodide](https://github.com/pyodide/pyodide) and [Transcrypt](https://www.transcrypt.org/) 💪. Potentially [Brython](https://brython.info/) and other could be added in the future.
20 |
21 | Check out the `panel-sketch` examples on **Binder**
22 |
23 | | Jupyter Notebook | Jupyter Labs | Panel Apps |
24 | | - | - | - |
25 | | [](https://mybinder.org/v2/gh/marcskovmadsen/panel-sketch/HEAD?filepath=examples) | [](https://mybinder.org/v2/gh/marcskovmadsen/panel-sketch/HEAD?urlpath=lab/tree/examples) | [](https://mybinder.org/v2/gh/marcskovmadsen/panel-sketch/HEAD?urlpath=panel) |
26 |
27 | ## License
28 |
29 | The `panel-sketch` python package and repository is open source and free to use (MIT License).
30 |
31 | ## Installation
32 |
33 | With `pip`
34 |
35 | ```bash
36 | pip install panel-sketch
37 | ```
38 |
39 | ## Usage
40 |
41 | ```python
42 | from panel_sketch import Sketch
43 |
44 | import panel as pn
45 | pn.config.sizing_mode="stretch_width"
46 |
47 | args={"r": 10, "g": 200, "b": 40} # This will give us the color for our sketch
48 |
49 | sketch_python = """
50 | # https://p5js.org/examples/interaction-wavemaker.html
51 |
52 |
53 | from pyp5js import *
54 |
55 | t = 0
56 |
57 |
58 | def setup():
59 | createCanvas(600, 600)
60 | stroke(250)
61 | strokeWeight(3)
62 | fill(window.args.r, window.args.g, window.args.b)
63 |
64 |
65 | def draw():
66 | global t
67 | background(10, 10)
68 | fill(window.args.r, window.args.g, window.args.b)
69 |
70 | xAngle = map(mouseX, 0, width, -4 * PI, 4 * PI, True)
71 | yAngle = map(mouseY, 0, height, -4 * PI, 4 * PI, True)
72 | for x in range(0, width, 30):
73 | for y in range(0, height, 30):
74 |
75 | angle = xAngle * (x / width) + yAngle * (y / height)
76 |
77 | myX = x + 20 * cos(2 * PI * t + angle)
78 | myY = y + 20 * sin(2 * TWO_PI * t + angle)
79 |
80 | ellipse(myX, myY, 10)
81 |
82 | t = t + 0.01
83 | """
84 |
85 | sketch = Sketch(object=sketch_python, template="pyp5js", compiler="pyodide", args=args)
86 | sketch.viewer.view.servable()
87 | ```
88 |
89 | 
90 |
91 | ## Reference Guides
92 |
93 | ### [Sketch Reference Example](https://github.com/MarcSkovMadsen/panel-sketch/blob/main/examples/Sketch.ipynb)
94 |
95 | [](https://mybinder.org/v2/gh/marcskovmadsen/panel-sketch/HEAD?urlpath=lab/tree/examples/Sketch.ipynb)
96 |
97 | ## Examples
98 |
99 | ### [Gallery App](https://github.com/MarcSkovMadsen/panel-sketch/blob/main/examples/pyp5js/gallery/gallery.py)
100 |
101 | [](https://mybinder.org/v2/gh/marcskovmadsen/panel-sketch/HEAD?urlpath=lab/tree/examples/pyp5js/gallery/gallery.py)
102 |
103 | ## Additional Resources
104 |
105 | You can find more inspiration via the links below.
106 |
107 | - [p5js](https://p5js.org/get-started/) and [p5js sketches](https://editor.p5js.org/p5/sketches)
108 | - [pyp5js](https://github.com/berinhard/pyp5js)
109 | - [Pyodide](https://github.com/pyodide/pyodide)
110 | - [Transcrypt](https://www.transcrypt.org/)
111 | - [Brython](https://brython.info/)
112 | - [Panel](https://panel.holoviz.org)
113 | - [Awesome Panel](https://awesome-panel.org)
114 |
115 | ## Roadmap
116 |
117 | When I get the time I would like to
118 |
119 | - add example using basic template to Sketch Reference Example
120 | - Add `basic` template examples.
121 | - Enable using the content of notebook cells instead of a string to instantite `Sketch`.
122 | - Add more notebook examples
123 | - Enable easy import and export of sketches
124 | - Find out how I can serve the target js modules in notebook (Enable Transcrypt in Notebook).
125 | - Support [alternatives](https://www.slant.co/options/147/alternatives/~p5-js-alternatives) to p5js like [three.js](https://threejs.org/)
126 | - change `window.args` to `args` reference.
127 | - change `Sketch.viewer.view` to `Sketch.viewer`. Similarly for `Sketch.editor`.
128 | - (re-)align with pyp5js
129 | - Add example app to [Awesome Panel](https://awesome-panel.org).
130 | - Support extensions to p5js like [m5.js](https://ml5js.org/)
131 | - Create youtube tutorial video
132 | - Add badges for 100% test coverage etc.
133 | - Distribute as conda package
134 |
135 | ## Change Log
136 |
137 | - 20210410: First Release to PyPi.
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 20210411.2
--------------------------------------------------------------------------------
/assets/images/examples/SketchApp.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarcSkovMadsen/panel-sketch/518cb177e2e8d1899b58f3a3f4d80d26c82ec760/assets/images/examples/SketchApp.gif
--------------------------------------------------------------------------------
/assets/images/panel-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarcSkovMadsen/panel-sketch/518cb177e2e8d1899b58f3a3f4d80d26c82ec760/assets/images/panel-logo.png
--------------------------------------------------------------------------------
/assets/images/panel-sketch-basic-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarcSkovMadsen/panel-sketch/518cb177e2e8d1899b58f3a3f4d80d26c82ec760/assets/images/panel-sketch-basic-example.png
--------------------------------------------------------------------------------
/assets/images/panel-sketch-binder.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarcSkovMadsen/panel-sketch/518cb177e2e8d1899b58f3a3f4d80d26c82ec760/assets/images/panel-sketch-binder.gif
--------------------------------------------------------------------------------
/assets/images/panel-sketch-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarcSkovMadsen/panel-sketch/518cb177e2e8d1899b58f3a3f4d80d26c82ec760/assets/images/panel-sketch-logo.png
--------------------------------------------------------------------------------
/binder/jupyter-examples-server/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarcSkovMadsen/panel-sketch/518cb177e2e8d1899b58f3a3f4d80d26c82ec760/binder/jupyter-examples-server/__init__.py
--------------------------------------------------------------------------------
/binder/jupyter-examples-server/examples-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/binder/jupyter-examples-server/jupyter_examples_server.py:
--------------------------------------------------------------------------------
1 | """
2 | Function to configure serving the panel example apps via jupyter-server-proxy.
3 | """
4 | import pathlib
5 | from glob import glob
6 |
7 | ICON_PATH = str((pathlib.Path(__file__).parent / "examples-icon.svg").absolute())
8 |
9 |
10 | def panel_serve_examples():
11 | """Returns the jupyter-server-proxy configuration for serving the example notebooks as Panel
12 | apps.
13 |
14 | Returns:
15 | Dict: The configuration dictionary
16 | """
17 | # See:
18 | # https://jupyter-server-proxy.readthedocs.io/en/latest/server-process.html
19 | # https://github.com/holoviz/jupyter-panel-proxy/blob/master/panel_server/__init__.py
20 | return {
21 | "command": [
22 | "panel",
23 | "serve",
24 | *glob("examples/*.ipynb"),
25 | "examples/pyp5js/gallery/gallery.py",
26 | "--allow-websocket-origin=*",
27 | "--port",
28 | "{port}",
29 | "--prefix",
30 | "{base_url}panel",
31 | "--static-dirs",
32 | "transcrypt=panel_sketch/sketch_compiler/assets/js/transcrypt/",
33 | ],
34 | "absolute_url": True,
35 | "timeout": 360,
36 | "launcher_entry": {
37 | "enabled": True,
38 | "title": "Panel Sketch Apps",
39 | "icon_path": ICON_PATH,
40 | },
41 | }
42 |
--------------------------------------------------------------------------------
/binder/jupyter-examples-server/setup.py:
--------------------------------------------------------------------------------
1 | """This setup.py will install a package that configures the jupyter-server-proxy to
2 | panel serve the example notebooks."""
3 | import setuptools
4 |
5 | setuptools.setup(
6 | name="jupyter-panel-examples-server",
7 | py_modules=["jupyter_examples_server"],
8 | entry_points={
9 | "jupyter_serverproxy_servers": [
10 | "panel = jupyter_examples_server:panel_serve_examples",
11 | ]
12 | },
13 | install_requires=["jupyter-server-proxy", "panel"],
14 | )
15 |
--------------------------------------------------------------------------------
/binder/requirements.txt:
--------------------------------------------------------------------------------
1 | -e .
2 | -e binder/jupyter-examples-server/.
3 | jupyter-server-proxy
4 | transcrypt==3.7.16
--------------------------------------------------------------------------------
/docker/Dockerfile.pip:
--------------------------------------------------------------------------------
1 | FROM python:3.8.9-slim-buster
2 |
3 | RUN pip install pip --upgrade
4 | RUN pip install panel-sketch
5 |
6 | ENTRYPOINT ["bash"]
--------------------------------------------------------------------------------
/examples/Sketch.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "adb7a7ff-8f09-4536-999a-7cacf69bce58",
6 | "metadata": {},
7 | "source": [
8 | ""
9 | ]
10 | },
11 | {
12 | "cell_type": "markdown",
13 | "id": "preliminary-frontier",
14 | "metadata": {},
15 | "source": [
16 | "# ✏️ Panel Sketch Pane\n",
17 | "\n",
18 | "**This is PRE-ALPHA and you may experience api changes and rough edges!**\n",
19 | "\n",
20 | "The purpose of the `panel-sketch` package is to make it easy for Pythonistas to quickly sketch interactive visualizations and other analytics apps **running in The browser without a Python backend**.\n",
21 | "\n",
22 | "You can use it from your Jupyter Notebook or your favorite editor or IDE.\n",
23 | "\n",
24 | "It is heavily inspired by [p5js](https://p5js.org/get-started/), [p5js sketches](https://editor.p5js.org/p5/sketches) and [pyp5js](https://github.com/berinhard/pyp5js) ❤️ It is not limited to the p5js universe though.\n",
25 | "\n",
26 | "You can also think of it as a [Code Sandbox](https://codesandbox.io/) or [JS Fiddle](https://jsfiddle.net/) but for #Python, #PyData and #PyViz 🐍.\n",
27 | "\n",
28 | "It leverages the powerful `Python` to `Javascript` frameworks [Pyodide](https://github.com/pyodide/pyodide) and [Transcrypt](https://www.transcrypt.org/) 💪."
29 | ]
30 | },
31 | {
32 | "cell_type": "markdown",
33 | "id": "9c77feaa-7485-4444-94b4-4618288b4f00",
34 | "metadata": {},
35 | "source": [
36 | "## Parameters:\n",
37 | "\n",
38 | "For layout and styling related parameters see the [Panel Customization Guide](https://panel.holoviz.org/user_guide/Customization.html).\n",
39 | "\n",
40 | "* **``object``** (string): A Python script. It is transpiled to javascript ([Transcrypt](https://www.transcrypt.org/)) or run directly in javascript ([Pyodide](https://github.com/pyodide/pyodide)).\n",
41 | "* **``html``** (string) A HTML string to mark up the Sketch. Default is `
`. \n",
42 | "* **``css``** (string): A CSS String to style the Sketch. You can style the HTML div via the `#sketch-element` reference.\n",
43 | "* **``javascript``** (string): The result of the compilation of the python script.\n",
44 | "\n",
45 | "* **``args``** (dict): A Dictionary of keys and values that can be reference via (currently) `window.args` in the python script.\n",
46 | "\n",
47 | "* **``template``** (string): The template to use for compilation. One of 'basic' or 'pyp5js'. Default is (currently) 'pyp5js'.\n",
48 | "* **``compiler``** (string): The compiler to use for compilation. One of 'transcrypt' or 'pyodide'. Default is 'pyodide'.\n",
49 | "\n",
50 | "* **``loading``** (bool): Whether or not the Sketch is loading. For example during compilation.\n",
51 | "\n",
52 | "## Properties\n",
53 | "\n",
54 | "* **``viewer``** (SketchViewer): A Viewer that makes viewing the Sketch a joy. Use it (currently) via `Sketch.viewer.view`.\n",
55 | "* **``editor``** (SketchEditor): An Editor that makes editing the Sketch a joy. Use it (currently) via `Sketch.editor.view`.\n",
56 | "\n",
57 | "## The sketch-element and sketchElement\n",
58 | "\n",
59 | "- The `sketch-element` id is a reserved keyword and replaced in Python, HTML and CSS when viewed in the `Sketch.viewer`.\n",
60 | " - You can reference the `div` element via `sketchElement` in Python.\n",
61 | " - You can style the HTML div via the `#sketch-element` reference.\n",
62 | "___\n",
63 | "\n",
64 | "# Usage\n",
65 | "\n",
66 | "## Imports"
67 | ]
68 | },
69 | {
70 | "cell_type": "code",
71 | "execution_count": null,
72 | "id": "005268b9-4cfc-42a3-b3e3-add9a274a801",
73 | "metadata": {},
74 | "outputs": [],
75 | "source": [
76 | "from panel_sketch import Sketch\n",
77 | "\n",
78 | "import panel as pn\n",
79 | "pn.config.sizing_mode=\"stretch_width\"\n",
80 | "pn.extension()"
81 | ]
82 | },
83 | {
84 | "cell_type": "markdown",
85 | "id": "95176896-a6ec-48a5-b6ff-164d7dea4242",
86 | "metadata": {},
87 | "source": [
88 | "# Example using pyp5js template and pyodide compiler\n",
89 | "\n",
90 | "Simple but beautiful Sketch based on the awesome [pyp5js](https://github.com/berinhard/pyp5js) template and compiled using just the just as awesome [Pyodide](https://github.com/pyodide/pyodide) compiler.\n",
91 | "\n",
92 | "You can find a gallery of pyp5js examples [here](https://berinhard.github.io/pyp5js/examples/)."
93 | ]
94 | },
95 | {
96 | "cell_type": "code",
97 | "execution_count": null,
98 | "id": "30cca610-b007-4daf-b0c9-8f7ae1d72fc2",
99 | "metadata": {},
100 | "outputs": [],
101 | "source": [
102 | "args={\"r\": 10, \"g\": 200, \"b\": 40} # This will give us the color for our sketch"
103 | ]
104 | },
105 | {
106 | "cell_type": "code",
107 | "execution_count": null,
108 | "id": "599689b4-420f-4afe-bdd1-04c2011e62a2",
109 | "metadata": {},
110 | "outputs": [],
111 | "source": [
112 | "sketch_python = \"\"\"\n",
113 | "# https://p5js.org/examples/interaction-wavemaker.html\n",
114 | "\n",
115 | "\n",
116 | "from pyp5js import *\n",
117 | "\n",
118 | "t = 0\n",
119 | "\n",
120 | "\n",
121 | "def setup():\n",
122 | " createCanvas(600, 600)\n",
123 | " stroke(250)\n",
124 | " strokeWeight(3)\n",
125 | " fill(window.args.r, window.args.g, window.args.b)\n",
126 | "\n",
127 | "\n",
128 | "def draw():\n",
129 | " global t\n",
130 | " background(10, 10)\n",
131 | " fill(window.args.r, window.args.g, window.args.b)\n",
132 | "\n",
133 | " xAngle = map(mouseX, 0, width, -4 * PI, 4 * PI, True)\n",
134 | " yAngle = map(mouseY, 0, height, -4 * PI, 4 * PI, True)\n",
135 | " for x in range(0, width, 30):\n",
136 | " for y in range(0, height, 30):\n",
137 | "\n",
138 | " angle = xAngle * (x / width) + yAngle * (y / height)\n",
139 | "\n",
140 | " myX = x + 20 * cos(2 * PI * t + angle)\n",
141 | " myY = y + 20 * sin(2 * TWO_PI * t + angle)\n",
142 | "\n",
143 | " ellipse(myX, myY, 10)\n",
144 | "\n",
145 | " t = t + 0.01\n",
146 | "\"\"\""
147 | ]
148 | },
149 | {
150 | "cell_type": "code",
151 | "execution_count": null,
152 | "id": "8c252f91-c842-4e35-a978-01bd4e93c63a",
153 | "metadata": {},
154 | "outputs": [],
155 | "source": [
156 | "sketch = Sketch(object=sketch_python, template=\"pyp5js\", compiler=\"pyodide\", args=args)\n",
157 | "sketch.viewer.view"
158 | ]
159 | },
160 | {
161 | "cell_type": "code",
162 | "execution_count": null,
163 | "id": "240da151-8a5f-4044-862b-3505caf4e90e",
164 | "metadata": {},
165 | "outputs": [],
166 | "source": [
167 | "slider = pn.widgets.IntSlider(name=\"Green\", value=200, start=0, end=255, step=1)\n",
168 | "@pn.depends(value=slider, watch=True)\n",
169 | "def _update_value(value):\n",
170 | " sketch.args = {\"r\": 10, \"g\": value, \"b\": 40}\n",
171 | "slider"
172 | ]
173 | },
174 | {
175 | "cell_type": "markdown",
176 | "id": "careful-bottle",
177 | "metadata": {},
178 | "source": [
179 | "# App\n",
180 | "\n",
181 | "Let's wrap it up as an app in a nice template."
182 | ]
183 | },
184 | {
185 | "cell_type": "code",
186 | "execution_count": null,
187 | "id": "recovered-marsh",
188 | "metadata": {},
189 | "outputs": [],
190 | "source": [
191 | "app = pn.template.FastListTemplate(\n",
192 | " site=\"Panel Sketch\", \n",
193 | " title=\"Reference Example\", \n",
194 | " main=[\n",
195 | " pn.pane.Markdown(\"Thanks **p5js** and **pyp5js** ❤️\"),\n",
196 | " sketch.viewer.view,\n",
197 | " ], \n",
198 | " sidebar=[slider]\n",
199 | ").servable()"
200 | ]
201 | },
202 | {
203 | "cell_type": "markdown",
204 | "id": "forty-reaction",
205 | "metadata": {},
206 | "source": [
207 | "Serve the app with `panel serve Sketch.ipynb` and add something like `--static-dirs transcrypt=panel_sketch/sketch_compiler/assets/js/transcrypt/` (hack for now) and explore it at http://localhost:5006/Sketch.\n",
208 | "\n",
209 | ""
210 | ]
211 | },
212 | {
213 | "cell_type": "markdown",
214 | "id": "bb9a0878-df08-4f26-b7c2-2d6569266295",
215 | "metadata": {},
216 | "source": [
217 | "**That's all. Happy coding 👍**"
218 | ]
219 | }
220 | ],
221 | "metadata": {
222 | "kernelspec": {
223 | "display_name": "Python 3",
224 | "language": "python",
225 | "name": "python3"
226 | },
227 | "language_info": {
228 | "codemirror_mode": {
229 | "name": "ipython",
230 | "version": 3
231 | },
232 | "file_extension": ".py",
233 | "mimetype": "text/x-python",
234 | "name": "python",
235 | "nbconvert_exporter": "python",
236 | "pygments_lexer": "ipython3",
237 | "version": "3.8.4"
238 | }
239 | },
240 | "nbformat": 4,
241 | "nbformat_minor": 5
242 | }
243 |
--------------------------------------------------------------------------------
/examples/pyp5js/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarcSkovMadsen/panel-sketch/518cb177e2e8d1899b58f3a3f4d80d26c82ec760/examples/pyp5js/__init__.py
--------------------------------------------------------------------------------
/examples/pyp5js/gallery/gallery.py:
--------------------------------------------------------------------------------
1 | import pathlib
2 |
3 | import panel as pn
4 | import param
5 |
6 | from panel_sketch import Sketch
7 |
8 | pn.config.sizing_mode = "stretch_width"
9 | pn.extension("ace")
10 |
11 | ROOT = pathlib.Path(__file__).parent
12 | EXAMPLES = {
13 | "PyP5JS - Basic": "sketch_000.py",
14 | "PyP5JS - Angles and mouse coordinates": "sketch_001.py",
15 | "PyP5JS - Move Eye": "sketch_002.py",
16 | # "PyP5JS - Boids": "sketch_004.py", Does not work with pyodide
17 | "PyP5JS - Globals variables (HSB and CENTER)": "sketch_005.py",
18 | # "PyP5JS - Registering event functions such as keyPressed": "sketch_006.py",
19 | "PyP5JS - p5.Vector static methods": "sketch_007.py",
20 | "PyP5JS - p5.dom.js usage": "sketch_008.py",
21 | # "PyP5JS - Working with images": "sketch_008.py", # Need to serve assets
22 | "PyP5JS - Complex Shapes": "sketch_010.py",
23 | }
24 | EXAMPLE = list(EXAMPLES.keys())[0]
25 |
26 |
27 | class Gallery(param.Parameterized):
28 | example = param.ObjectSelector(EXAMPLE, objects=list(EXAMPLES.keys()))
29 | sketch = param.ClassSelector(class_=Sketch)
30 |
31 | def __init__(self, **params):
32 | super().__init__(**params)
33 |
34 | self.sketch = Sketch()
35 | self._update_sketch_object()
36 |
37 | @param.depends("example", watch=True)
38 | def _update_sketch_object(self):
39 | self.sketch.html = self.sketch.param.html.default
40 | self.sketch.css = self.sketch.param.css.default
41 | self.sketch.object = (ROOT / EXAMPLES[self.example]).read_text()
42 |
43 |
44 | pn.config.sizing_mode = "stretch_width"
45 | gallery = Gallery()
46 |
47 | template = pn.template.FastListTemplate(
48 | site="Panel Sketch", title="Examples", main_max_width="1200px"
49 | )
50 | template.sidebar[:] = [
51 | gallery.sketch.param.template,
52 | gallery.param.example,
53 | gallery.sketch.param.compiler,
54 | ]
55 | template.main[:] = [
56 | pn.Column(
57 | pn.pane.Markdown("# ✏️ Sketch"),
58 | pn.layout.Divider(sizing_mode="stretch_width"),
59 | gallery.sketch.viewer.view,
60 | ),
61 | gallery.sketch.editor.view,
62 | ]
63 |
64 | template.servable()
65 |
--------------------------------------------------------------------------------
/examples/pyp5js/gallery/sketch_000.py:
--------------------------------------------------------------------------------
1 | def setup():
2 |
3 | createCanvas(200, 200)
4 |
5 | background(160)
6 |
7 |
8 | def draw():
9 |
10 | fill("blue")
11 |
12 | background(200)
13 |
14 | radius = sin(frameCount / 60) * 50 + 50
15 |
16 | ellipse(100, 100, radius, radius)
17 |
--------------------------------------------------------------------------------
/examples/pyp5js/gallery/sketch_001.py:
--------------------------------------------------------------------------------
1 | # https://p5js.org/examples/interaction-wavemaker.html
2 |
3 |
4 | from pyp5js import *
5 |
6 | t = 0
7 |
8 |
9 | def setup():
10 | createCanvas(600, 600)
11 | stroke(250)
12 | strokeWeight(3)
13 | fill(40, 200, 40)
14 |
15 |
16 | def draw():
17 | global t
18 | background(10, 10)
19 |
20 | xAngle = map(mouseX, 0, width, -4 * PI, 4 * PI, True)
21 | yAngle = map(mouseY, 0, height, -4 * PI, 4 * PI, True)
22 | for x in range(0, width, 30):
23 | for y in range(0, height, 30):
24 |
25 | angle = xAngle * (x / width) + yAngle * (y / height)
26 |
27 | myX = x + 20 * cos(2 * PI * t + angle)
28 | myY = y + 20 * sin(2 * TWO_PI * t + angle)
29 |
30 | ellipse(myX, myY, 10)
31 |
32 | t = t + 0.01
33 |
--------------------------------------------------------------------------------
/examples/pyp5js/gallery/sketch_002.py:
--------------------------------------------------------------------------------
1 | """
2 | * Move Eye.
3 | * by Simon Greenwold.
4 | *
5 | * The camera lifts up (controlled by mouseY) while looking at the same point.
6 | """
7 | from pyp5js import *
8 |
9 |
10 | def setup():
11 | createCanvas(640, 360, _P5_INSTANCE.WEBGL)
12 | fill(204)
13 |
14 |
15 | def draw():
16 | ambientLight(50)
17 | directionalLight(255, 0, 0, 0.25, 0.25, 0)
18 | background(0)
19 |
20 | # Change height of the camera with mouseY
21 | camera(
22 | 30.0,
23 | mouseY,
24 | 220.0, # eyeX, eyeY, eyeZ
25 | 0.0,
26 | 0.0,
27 | 0.0, # centerX, centerY, centerZ
28 | 0.0,
29 | 1.0,
30 | 0.0,
31 | ) # upX, upY, upZ
32 |
33 | noStroke()
34 | box(90)
35 | stroke(255)
36 | line(-100, 0, 0, 100, 0, 0)
37 | line(0, -100, 0, 0, 100, 0)
38 | line(0, 0, -100, 0, 0, 100)
39 |
--------------------------------------------------------------------------------
/examples/pyp5js/gallery/sketch_004.py:
--------------------------------------------------------------------------------
1 | # From Prof. Claudio Esperança examples for BrythonIDE
2 | # https://github.com/esperanc/brythonide/blob/master/demoSketches/boids.py
3 |
4 | from pyp5js import *
5 |
6 | boids = []
7 |
8 |
9 | def setup():
10 | createCanvas(720, 400)
11 |
12 | # Add an initial set of boids into the system
13 | for i in range(40):
14 | boids.append(Boid(random(720), random(400)))
15 |
16 |
17 | def draw():
18 | background(51)
19 | # Run all the boids
20 | for boid in boids:
21 | boid.run(boids)
22 |
23 |
24 | # Boid class
25 | # Methods for Separation, Cohesion, Alignment added
26 | class Boid(object):
27 | def __init__(self, x, y):
28 | self.acceleration = createVector(0, 0)
29 | self.velocity = p5.Vector.random2D()
30 | self.position = createVector(x, y)
31 | self.r = 3.0
32 | self.maxspeed = 3 # Maximum speed
33 | self.maxforce = 0.05 # Maximum steering force
34 |
35 | def run(self, boids):
36 | self.flock(boids)
37 | self.update()
38 | self.borders()
39 | self.render()
40 |
41 | # Forces go into acceleration
42 | def applyForce(self, force):
43 | self.acceleration.add(force)
44 |
45 | # We accumulate a new acceleration each time based on three rules
46 | def flock(self, boids):
47 | sep = self.separate(boids) # Separation
48 | ali = self.align(boids) # Alignment
49 | coh = self.cohesion(boids) # Cohesion
50 | # Arbitrarily weight these forces
51 | sep.mult(2.5)
52 | ali.mult(1.0)
53 | coh.mult(1.0)
54 | # Add the force vectors to acceleration
55 | self.applyForce(sep)
56 | self.applyForce(ali)
57 | self.applyForce(coh)
58 |
59 | # Method to update location
60 | def update(self):
61 | # Update velocity
62 | self.velocity.add(self.acceleration)
63 | # Limit speed
64 | self.velocity.limit(self.maxspeed)
65 | self.position.add(self.velocity)
66 | # Reset acceleration to 0 each cycle
67 | self.acceleration.mult(0)
68 |
69 | # A method that calculates and applies a steering force towards a target
70 | # STEER = DESIRED MINUS VELOCITY
71 | def seek(self, target):
72 | desired = p5.Vector.sub(
73 | target, self.position
74 | ) # A vector pointing from the location to the target
75 | # Normalize desired and scale to maximum speed
76 | desired.normalize()
77 | desired.mult(self.maxspeed)
78 | # Steering = Desired minus Velocity
79 | steer = p5.Vector.sub(desired, self.velocity)
80 | steer.limit(self.maxforce) # Limit to maximum steering force
81 | return steer
82 |
83 | # Draw boid as a circle
84 | def render(self):
85 | fill(127, 127)
86 | stroke(200)
87 | ellipse(self.position.x, self.position.y, 16, 16)
88 |
89 | # Wraparound
90 | def borders(self):
91 | if self.position.x < -self.r:
92 | self.position.x = width + self.r
93 | if self.position.y < -self.r:
94 | self.position.y = height + self.r
95 | if self.position.x > width + self.r:
96 | self.position.x = -self.r
97 | if self.position.y > height + self.r:
98 | self.position.y = -self.r
99 |
100 | # Separation
101 | # Method checks for nearby boids and steers away
102 | def separate(self, boids):
103 | desiredseparation = 25.0
104 | steer = createVector(0, 0)
105 | count = 0
106 | # For every boid in the system, check if it's too close
107 | for i in range(len(boids)):
108 | d = p5.Vector.dist(self.position, boids[i].position)
109 | # If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself)
110 | if (d > 0) and (d < desiredseparation):
111 | # Calculate vector pointing away from neighbor
112 | diff = p5.Vector.sub(self.position, boids[i].position)
113 | diff.normalize()
114 | diff.div(d) # Weight by distance
115 | steer.add(diff)
116 | count += 1 # Keep track of how many
117 | # Average -- divide by how many
118 | if count > 0:
119 | steer.div(count)
120 |
121 | # As long as the vector is greater than 0
122 | if steer.mag() > 0:
123 | # Implement Reynolds: Steering = Desired - Velocity
124 | steer.normalize()
125 | steer.mult(self.maxspeed)
126 | steer.sub(self.velocity)
127 | steer.limit(self.maxforce)
128 |
129 | return steer
130 |
131 | # Alignment
132 | # For every nearby boid in the system, calculate the average velocity
133 | def align(self, boids):
134 | neighbordist = 50
135 | sum = createVector(0, 0)
136 | count = 0
137 | for i in range(len(boids)):
138 | d = p5.Vector.dist(self.position, boids[i].position)
139 | if (d > 0) and (d < neighbordist):
140 | sum.add(boids[i].velocity)
141 | count += 1
142 |
143 | if count > 0:
144 | sum.div(count)
145 | sum.normalize()
146 | sum.mult(self.maxspeed)
147 | steer = p5.Vector.sub(sum, self.velocity)
148 | steer.limit(self.maxforce)
149 | return steer
150 | else:
151 | return createVector(0, 0)
152 |
153 | # Cohesion
154 | # For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location
155 | def cohesion(self, boids):
156 | neighbordist = 50
157 | sum = createVector(0, 0) # Start with empty vector to accumulate all locations
158 | count = 0
159 | for i in range(len(boids)):
160 | d = p5.Vector.dist(self.position, boids[i].position)
161 | if (d > 0) and (d < neighbordist):
162 | sum.add(boids[i].position) # Add location
163 | count += 1
164 |
165 | if count > 0:
166 | sum.div(count)
167 | return self.seek(sum) # Steer towards the location
168 | else:
169 | return createVector(0, 0)
170 |
--------------------------------------------------------------------------------
/examples/pyp5js/gallery/sketch_005.py:
--------------------------------------------------------------------------------
1 | from pyp5js import *
2 |
3 |
4 | def setup():
5 | createCanvas(600, 600)
6 | noStroke()
7 | rectMode(CENTER)
8 |
9 |
10 | def draw():
11 | colorMode(HSB, 100)
12 | h = map(mouseY, 0, 600, 0, 100)
13 | background(h, 100, 100)
14 | fill(100 - h, 100, 100)
15 | rect(300, 300, mouseX + 1, mouseX + 1)
16 |
--------------------------------------------------------------------------------
/examples/pyp5js/gallery/sketch_006.py:
--------------------------------------------------------------------------------
1 | from pyp5js import *
2 |
3 | r = None
4 |
5 |
6 | def setup():
7 | global r
8 |
9 | createCanvas(900, 900)
10 | r = random(100, 700)
11 | noFill()
12 |
13 |
14 | def draw():
15 | x, y = 100, 100
16 | rect(x, y, r, r)
17 |
18 |
19 | def keyPressed():
20 | console.log("Key pressed event")
21 |
22 | if key == "n":
23 | global r
24 | r = random(100, 700)
25 | redraw()
26 |
27 |
28 | def mouseDragged():
29 | global r
30 | r = random(100, 700)
31 | redraw()
32 |
--------------------------------------------------------------------------------
/examples/pyp5js/gallery/sketch_007.py:
--------------------------------------------------------------------------------
1 | from pyp5js import *
2 |
3 |
4 | def setup():
5 | createCanvas(900, 900)
6 | stroke(27, 27, 27, 10)
7 | strokeWeight(2)
8 |
9 |
10 | def draw():
11 | push()
12 |
13 | translate(width / 2, height / 2)
14 | v = p5.Vector.random2D()
15 | v.normalize()
16 | v.mult(random(100, 400))
17 | line(0, 0, v.x, v.y)
18 |
19 | pop()
20 |
--------------------------------------------------------------------------------
/examples/pyp5js/gallery/sketch_008.py:
--------------------------------------------------------------------------------
1 | from pyp5js import *
2 |
3 | rect_base_size = 30
4 | positions = []
5 | rect_size = None
6 |
7 |
8 | def setup():
9 | global rect_size
10 |
11 | createP("Hi! This is an example of how to use p5.dom.js with pyp5js")
12 |
13 | # creates a container div
14 | slider_div = createDiv()
15 | slider_div.style("display", "block")
16 |
17 | # creates the slider
18 | rect_size = createSlider(0, 600, 100)
19 | rect_size.style("width", "50%")
20 |
21 | # adds the slider to the container div
22 | slider_div.child(rect_size)
23 |
24 | createCanvas(600, 600)
25 |
26 | for x in range(-rect_base_size, width + rect_base_size, rect_base_size):
27 | for y in range(-rect_base_size, height + rect_base_size, rect_base_size):
28 | positions.append((x, y))
29 |
30 | noFill()
31 | strokeWeight(2)
32 | rectMode(CENTER)
33 |
34 |
35 | def draw():
36 | background(255)
37 | size = rect_size.value()
38 | for x, y in positions:
39 | rect(x, y, size, size)
40 |
--------------------------------------------------------------------------------
/examples/pyp5js/gallery/sketch_010.py:
--------------------------------------------------------------------------------
1 | from pyp5js import *
2 |
3 | add_library("p5.dom.js")
4 |
5 |
6 | MY_POINTS = [
7 | (100, 50),
8 | (300, 100),
9 | (200, 300),
10 | (100, 300),
11 | ]
12 | FRAME_IDX = 0
13 | POINT_SIZE = 10
14 | CNV = None
15 |
16 |
17 | def setup():
18 | global CNV
19 | CNV = createCanvas(400, 400)
20 |
21 | BUTTON_PREV = createButton("Previous frame")
22 | BUTTON_PREV.position(CNV.position().x, CNV.height + CNV.position().y)
23 | BUTTON_PREV.mousePressed(prev_frame)
24 |
25 | BUTTON_NEXT = createButton("Next frame")
26 | BUTTON_NEXT.position(CNV.position().x + BUTTON_PREV.size().width, BUTTON_PREV.position().y)
27 | BUTTON_NEXT.mousePressed(next_frame)
28 |
29 | background(190)
30 | draw_labels(MY_POINTS)
31 |
32 |
33 | def draw():
34 | background(190)
35 | draw_closed_curve_vertex(MY_POINTS, FRAME_IDX)
36 | draw_labels(MY_POINTS)
37 |
38 |
39 | def mouseClicked():
40 | global FRAME_IDX
41 | global MY_POINTS
42 | if is_point_in_canvas(mouseX, mouseY):
43 | i = get_point_index(mouseX, mouseY)
44 | if i != None:
45 | MY_POINTS.pop(i)
46 | if FRAME_IDX >= len(MY_POINTS):
47 | # cap i if it exceeds maximum length now.
48 | FRAME_IDX = len(MY_POINTS) - 1
49 | else:
50 | MY_POINTS.append((mouseX, mouseY))
51 |
52 |
53 | def get_point_index(x, y):
54 | for idx, (p_x, p_y) in enumerate(MY_POINTS):
55 | if (p_x - POINT_SIZE < x and x < p_x + POINT_SIZE) and (
56 | p_y - POINT_SIZE < y and y < p_y + POINT_SIZE
57 | ):
58 | return idx
59 |
60 |
61 | def is_point_in_canvas(x, y):
62 | if (x < 0 or x > CNV.width) or (y < 0 or y > CNV.height):
63 | return False
64 | return True
65 |
66 |
67 | def next_frame():
68 | global FRAME_IDX
69 | if FRAME_IDX < len(MY_POINTS) - 1:
70 | FRAME_IDX += 1
71 |
72 |
73 | def prev_frame():
74 | global FRAME_IDX
75 | if FRAME_IDX > 0:
76 | FRAME_IDX -= 1
77 |
78 |
79 | def draw_closed_curve_vertex(points, max_idx):
80 | if len(points) < 2:
81 | return
82 | used_points = []
83 | beginShape()
84 |
85 | # start by using the last point as the initial control point
86 | idx = len(points) - 1
87 | curveVertex(*points[idx])
88 | used_points.append(idx)
89 |
90 | # add each point to the curve
91 | for idx, p in enumerate(points):
92 | if idx > max_idx:
93 | break
94 | curveVertex(*p)
95 | used_points.append(idx)
96 |
97 | # to close the curve, we need to create the last curve.
98 | # for that, we must go to the first point
99 | idx = 0
100 | curveVertex(*points[idx])
101 | used_points.append(idx)
102 |
103 | # and use the next point as a control point.
104 | idx = 1
105 | curveVertex(*points[idx])
106 | used_points.append(idx)
107 | endShape()
108 |
109 | textSize(10)
110 | noStroke()
111 | text(
112 | "Points used to draw this curve (first and last are control points only)",
113 | 5,
114 | CNV.height - 30,
115 | )
116 |
117 | textSize(20)
118 | text(", ".join(used_points), 10, CNV.height - 10)
119 | stroke(0)
120 |
121 | for i in range(len(used_points) - 1):
122 | draw_dotted_line(points[used_points[i]], points[used_points[i + 1]])
123 |
124 |
125 | def draw_labels(points):
126 | strokeWeight(POINT_SIZE)
127 | for idx, p in enumerate(points):
128 | ts = 32
129 | textSize(ts)
130 | textY = p[1] - ts / 2
131 |
132 | if p[1] > CNV.height / 2:
133 | textY = p[1] + ts
134 |
135 | noStroke()
136 | text(idx, p[0], textY)
137 | stroke(0)
138 | point(*p)
139 |
140 | strokeWeight(1)
141 |
142 |
143 | def draw_dotted_line(p1, p2):
144 | stroke(100)
145 | strokeWeight(3)
146 | for i in range(11):
147 | x = lerp(p1[0], p2[0], i / 10)
148 | y = lerp(p1[1], p2[1], i / 10)
149 | point(x, y)
150 |
151 | stroke(0)
152 | strokeWeight(1)
153 |
--------------------------------------------------------------------------------
/mypy.ini:
--------------------------------------------------------------------------------
1 | [mypy]
2 | [mypy-sqlalchemy.orm]
3 | ignore_missing_imports=True
4 | [mypy-isodate]
5 | ignore_missing_imports=True
6 | [mypy-sqlalchemy]
7 | ignore_missing_imports=True
8 | [mypy-blpapi]
9 | ignore_missing_imports=True
10 | [mypy-setuptools.*]
11 | ignore_missing_imports=True
12 | [mypy-invoke.*]
13 | ignore_missing_imports=True
14 | [mypy-cx_Oracle.*]
15 | ignore_missing_imports = True
16 | [mypy-factory]
17 | ignore_missing_imports = True
18 | [mypy-freezegun]
19 | ignore_missing_imports = True
20 | [mypy-numpy]
21 | ignore_missing_imports = True
22 | [mypy-pandas.*]
23 | ignore_missing_imports = True
24 | [mypy-pytest]
25 | ignore_missing_imports = True
26 | [mypy-rest_framework.*]
27 | ignore_missing_imports = True
28 | [mypy-rest_pandas.*]
29 | ignore_missing_imports = True
30 | [mypy-django_filters.*]
31 | ignore_missing_imports = True
32 | [mypy-jsonfield.*]
33 | ignore_missing_imports = True
34 | [mypy-pyomo.*]
35 | ignore_missing_imports = True
36 | [mypy-pyutilib.*]
37 | ignore_missing_imports = True
38 | [mypy-networkx.*]
39 | ignore_missing_imports = True
40 | [mypy-matplotlib.*]
41 | ignore_missing_imports = True
42 | [mypy-sklearn.*]
43 | ignore_missing_imports = True
44 | [mypy-plotly.graph_objs.*]
45 | ignore_missing_imports = True
46 | [mypy-plotly.*]
47 | ignore_missing_imports = True
48 | [mypy-bokeh.*]
49 | ignore_missing_imports = True
50 | [mypy-sqlalchemy.*]
51 | ignore_missing_imports = True
52 | [mypy-winreg.*]
53 | ignore_missing_imports = True
54 | [mypy-selenium.*]
55 | ignore_missing_imports = True
56 | [mypy-holoviews.*]
57 | ignore_missing_imports = True
58 | [mypy-hvplot.*]
59 | ignore_missing_imports = True
60 | [mypy-panel.*]
61 | ignore_missing_imports = True
62 | [mypy-param.*]
63 | ignore_missing_imports = True
64 | [mypy-trading_analytics.utils.services.pandas_io.*]
65 | ignore_missing_imports = True
66 | [mypy-pyodbc.*]
67 | ignore_missing_imports = True
68 | [mypy-odlenv.*]
69 | ignore_missing_imports = True
70 | [mypy-odltransform.*]
71 | ignore_missing_imports = True
72 | [mypy-tqdm.*]
73 | ignore_missing_imports = True
74 | [mypy-awesome_panel_extensions.*]
75 | ignore_missing_imports = True
76 | [mypy-kubernetes.*]
77 | ignore_missing_imports = True
78 | [mypy-paramiko.*]
79 | ignore_missing_imports = True
80 | [mypy-dash.*]
81 | ignore_missing_imports = True
82 | [mypy-dash_bootstrap_components.*]
83 | ignore_missing_imports = True
84 | [mypy-dash_core_components.*]
85 | ignore_missing_imports = True
86 | [mypy-dash_table.*]
87 | ignore_missing_imports = True
88 | [mypy-dash_html_components.*]
89 | ignore_missing_imports = True
90 | [mypy-pypsa.*]
91 | ignore_missing_imports = True
92 | [mypy-entsoe.*]
93 | ignore_missing_imports = True
94 | [mypy-pyviz_comms.*]
95 | ignore_missing_imports = True
--------------------------------------------------------------------------------
/panel_sketch/.bokeh:
--------------------------------------------------------------------------------
1 | {"bokeh_version":"2.3.1","signatures":{"package.json":"feff06f34b7bac4390b35764271b0fed0f9c7d772ee10846a055a2c6e2feec88","package-lock.json":"06a7684b967bd03d95bc5dffeb939ab89b481b59644740afb0bfa03887e306cc","tsconfig.json":"87a823f0ef7885d0f8a99f845fc9b04922e05517668df9ba4dec17527eadeb41"}}
--------------------------------------------------------------------------------
/panel_sketch/__init__.py:
--------------------------------------------------------------------------------
1 | """Use
2 |
3 | - panel_sketch.config.js_files to define which Highcharts js files to include
4 | - the HighChart pane to use the Highcharts Chart in Panel.
5 | """
6 | from . import config
7 | from .sketch import Sketch
8 |
--------------------------------------------------------------------------------
/panel_sketch/bokeh.ext.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/panel_sketch/config.py:
--------------------------------------------------------------------------------
1 | """Configures Panel.extension"""
2 | from panel import extension
3 |
4 | # Enables using pn.extension("sketch", ...)
5 | # pylint: disable=protected-access
6 | extension._imports["sketch"] = "panel_sketch.models.sketch"
7 | # pylint: enable=protected-access
8 |
--------------------------------------------------------------------------------
/panel_sketch/dist/panel_sketch.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Copyright (c) 2012 - 2021, Anaconda, Inc., and Bokeh Contributors
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification,
6 | * are permitted provided that the following conditions are met:
7 | *
8 | * Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | *
11 | * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * Neither the name of Anaconda nor the names of any contributors
16 | * may be used to endorse or promote products derived from this software
17 | * without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29 | * THE POSSIBILITY OF SUCH DAMAGE.
30 | */
31 | (function(root, factory) {
32 | factory(root["Bokeh"], undefined);
33 | })(this, function(Bokeh, version) {
34 | var define;
35 | return (function(modules, entry, aliases, externals) {
36 | const bokeh = typeof Bokeh !== "undefined" && (version != null ? Bokeh[version] : Bokeh);
37 | if (bokeh != null) {
38 | return bokeh.register_plugin(modules, entry, aliases);
39 | } else {
40 | throw new Error("Cannot find Bokeh " + version + ". You have to load it prior to loading plugins.");
41 | }
42 | })
43 | ({
44 | "a6a4fae5e8": /* index.js */ function _(require, module, exports, __esModule, __esExport) {
45 | __esModule();
46 | const tslib_1 = require("tslib");
47 | const SketchExtensions = tslib_1.__importStar(require("8fbb31f6e4") /* ./models/ */);
48 | exports.SketchExtensions = SketchExtensions;
49 | const base_1 = require("@bokehjs/base");
50 | base_1.register_models(SketchExtensions);
51 | },
52 | "8fbb31f6e4": /* models\index.js */ function _(require, module, exports, __esModule, __esExport) {
53 | __esModule();
54 | var sketch_1 = require("b09786f089") /* ./sketch */;
55 | __esExport("Sketch", sketch_1.Sketch);
56 | },
57 | "b09786f089": /* models\sketch.js */ function _(require, module, exports, __esModule, __esExport) {
58 | __esModule();
59 | // See https://docs.bokeh.org/en/latest/docs/reference/models/layouts.html
60 | const html_box_1 = require("@bokehjs/models/layouts/html_box");
61 | // The view of the Bokeh extension/ HTML element
62 | // Here you can define how to render the model as well as react to model changes or View events.
63 | class SketchView extends html_box_1.HTMLBoxView {
64 | connect_signals() {
65 | super.connect_signals();
66 | this.connect(this.model.properties.value.change, () => {
67 | this.render();
68 | });
69 | }
70 | render() {
71 | console.log("render");
72 | console.log(this.model);
73 | super.render();
74 | this.el.innerHTML = this.model.value;
75 | this.valueElement = this.el.firstElementChild;
76 | this.valueElement.addEventListener("click", () => { this.model.clicks += 1; }, false);
77 | }
78 | }
79 | exports.SketchView = SketchView;
80 | SketchView.__name__ = "SketchView";
81 | // The Bokeh .ts model corresponding to the Bokeh .py model
82 | class Sketch extends html_box_1.HTMLBox {
83 | constructor(attrs) {
84 | super(attrs);
85 | }
86 | static init_Sketch() {
87 | this.prototype.default_view = SketchView;
88 | this.define(({ String, Int }) => ({
89 | value: [String, ""],
90 | clicks: [Int, 0],
91 | }));
92 | }
93 | }
94 | exports.Sketch = Sketch;
95 | Sketch.__name__ = "Sketch";
96 | Sketch.__module__ = "panel_sketch.models.sketch";
97 | Sketch.init_Sketch();
98 | },
99 | }, "a6a4fae5e8", {"index":"a6a4fae5e8","models/index":"8fbb31f6e4","models/sketch":"b09786f089"}, {});});
100 | //# sourceMappingURL=panel_sketch.js.map
101 |
--------------------------------------------------------------------------------
/panel_sketch/dist/panel_sketch.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["@@\\panel_sketch\\dist\\lib\\index.js","@@\\panel_sketch\\dist\\lib\\models\\index.js","@@\\panel_sketch\\dist\\lib\\models\\sketch.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,ACRA;AACA;AACA;AACA;AACA;AACA,ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"generated.js","sourceRoot":"","sourcesContent":["/* index.js */ function _(require, module, exports, __esModule, __esExport) {\r\n __esModule();\r\n const tslib_1 = require(\"tslib\");\r\n const SketchExtensions = tslib_1.__importStar(require(\"8fbb31f6e4\") /* ./models/ */);\r\n exports.SketchExtensions = SketchExtensions;\r\n const base_1 = require(\"@bokehjs/base\");\r\n base_1.register_models(SketchExtensions);\r\n}\r\n","/* models\\index.js */ function _(require, module, exports, __esModule, __esExport) {\r\n __esModule();\r\n var sketch_1 = require(\"b09786f089\") /* ./sketch */;\r\n __esExport(\"Sketch\", sketch_1.Sketch);\r\n}\r\n","/* models\\sketch.js */ function _(require, module, exports, __esModule, __esExport) {\r\n __esModule();\r\n // See https://docs.bokeh.org/en/latest/docs/reference/models/layouts.html\r\n const html_box_1 = require(\"@bokehjs/models/layouts/html_box\");\r\n // The view of the Bokeh extension/ HTML element\r\n // Here you can define how to render the model as well as react to model changes or View events.\r\n class SketchView extends html_box_1.HTMLBoxView {\r\n connect_signals() {\r\n super.connect_signals();\r\n this.connect(this.model.properties.value.change, () => {\r\n this.render();\r\n });\r\n }\r\n render() {\r\n console.log(\"render\");\r\n console.log(this.model);\r\n super.render();\r\n this.el.innerHTML = this.model.value;\r\n this.valueElement = this.el.firstElementChild;\r\n this.valueElement.addEventListener(\"click\", () => { this.model.clicks += 1; }, false);\r\n }\r\n }\r\n exports.SketchView = SketchView;\r\n SketchView.__name__ = \"SketchView\";\r\n // The Bokeh .ts model corresponding to the Bokeh .py model\r\n class Sketch extends html_box_1.HTMLBox {\r\n constructor(attrs) {\r\n super(attrs);\r\n }\r\n static init_Sketch() {\r\n this.prototype.default_view = SketchView;\r\n this.define(({ String, Int }) => ({\r\n value: [String, \"\"],\r\n clicks: [Int, 0],\r\n }));\r\n }\r\n }\r\n exports.Sketch = Sketch;\r\n Sketch.__name__ = \"Sketch\";\r\n Sketch.__module__ = \"panel_sketch.models.sketch\";\r\n Sketch.init_Sketch();\r\n}\r\n"]}
--------------------------------------------------------------------------------
/panel_sketch/dist/panel_sketch.json:
--------------------------------------------------------------------------------
1 | {"version":4,"artifacts":[{"module":{"file":"C:\\repos\\private\\panel-sketch\\panel_sketch\\dist\\lib\\index.js","base":"C:\\repos\\private\\panel-sketch\\panel_sketch\\dist\\lib","base_path":"index.js","canonical":"index","resolution":"ESM","id":"a6a4fae5e8","hash":"a6a4fae5e8621dbe0faff153de10809af162bc8ce2f58d15ef68d93238557bfb","source":"\"use strict\";\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nexports.SketchExtensions = void 0;\r\nconst tslib_1 = require(\"tslib\");\r\nconst SketchExtensions = tslib_1.__importStar(require(\"./models/\"));\r\nexports.SketchExtensions = SketchExtensions;\r\nconst base_1 = require(\"@bokehjs/base\");\r\nbase_1.register_models(SketchExtensions);\r\n//# sourceMappingURL=index.js.map\r\n","type":"js","dependency_paths":[["./models/","C:\\repos\\private\\panel-sketch\\panel_sketch\\dist\\lib\\models\\index.js"]],"dependency_map":[],"exported":[],"externals":[],"shims":[]},"code":{"source":"/* index.js */ function _(require, module, exports, __esModule, __esExport) {\r\n __esModule();\r\n const tslib_1 = require(\"tslib\");\r\n const SketchExtensions = tslib_1.__importStar(require(\"8fbb31f6e4\") /* ./models/ */);\r\n exports.SketchExtensions = SketchExtensions;\r\n const base_1 = require(\"@bokehjs/base\");\r\n base_1.register_models(SketchExtensions);\r\n}\r\n","min_source":"function _(e,s,t,o,b){o();const i=e(\"tslib\").__importStar(e(\"8fbb31f6e4\"));t.SketchExtensions=i;e(\"@bokehjs/base\").register_models(i)}\n//# sourceMappingURL=index.min.js.map","min_map":"{\"version\":3,\"sources\":[\"0\"],\"names\":[\"_\",\"require\",\"module\",\"exports\",\"__esModule\",\"__esExport\",\"SketchExtensions\",\"__importStar\",\"register_models\"],\"mappings\":\"AAAe,SAASA,EAAEC,EAASC,EAAQC,EAASC,EAAYC,GAC5DD,IACA,MACME,EADUL,EAAQ,SACSM,aAAaN,EAAQ,eACtDE,EAAQG,iBAAmBA,EACZL,EAAQ,iBAChBO,gBAAgBF\",\"file\":\"index.min.js\"}"}},{"module":{"file":"C:\\repos\\private\\panel-sketch\\panel_sketch\\dist\\lib\\models\\index.js","base":"C:\\repos\\private\\panel-sketch\\panel_sketch\\dist\\lib","base_path":"models\\index.js","canonical":"models/index","resolution":"ESM","id":"8fbb31f6e4","hash":"8fbb31f6e442028bf00b351a45ad9b19d3417bca2668596cad1a956f9e9e2339","source":"\"use strict\";\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nexports.Sketch = void 0;\r\nvar sketch_1 = require(\"./sketch\");\r\nObject.defineProperty(exports, \"Sketch\", { enumerable: true, get: function () { return sketch_1.Sketch; } });\r\n//# sourceMappingURL=index.js.map\r\n","type":"js","dependency_paths":[["./sketch","C:\\repos\\private\\panel-sketch\\panel_sketch\\dist\\lib\\models\\sketch.js"]],"dependency_map":[],"exported":[{"type":"bindings","bindings":[[null,"Sketch"]],"module":"./sketch"}],"externals":[],"shims":[]},"code":{"source":"/* models\\index.js */ function _(require, module, exports, __esModule, __esExport) {\r\n __esModule();\r\n var sketch_1 = require(\"b09786f089\") /* ./sketch */;\r\n __esExport(\"Sketch\", sketch_1.Sketch);\r\n}\r\n","min_source":"function _(c,t,e,f,h){f(),h(\"Sketch\",c(\"b09786f089\").Sketch)}\n//# sourceMappingURL=index.min.js.map","min_map":"{\"version\":3,\"sources\":[\"0\"],\"names\":[\"_\",\"require\",\"module\",\"exports\",\"__esModule\",\"__esExport\",\"Sketch\"],\"mappings\":\"AAAsB,SAASA,EAAEC,EAASC,EAAQC,EAASC,EAAYC,GACnED,IAEAC,EAAW,SADIJ,EAAQ,cACOK\",\"file\":\"index.min.js\"}"}},{"module":{"file":"C:\\repos\\private\\panel-sketch\\panel_sketch\\dist\\lib\\models\\sketch.js","base":"C:\\repos\\private\\panel-sketch\\panel_sketch\\dist\\lib","base_path":"models\\sketch.js","canonical":"models/sketch","resolution":"ESM","id":"b09786f089","hash":"b09786f0896bc50755f36069bab84014cab67a8d00dc90ec1e4b3a1e08f15d98","source":"\"use strict\";\r\nObject.defineProperty(exports, \"__esModule\", { value: true });\r\nexports.Sketch = exports.SketchView = void 0;\r\n// See https://docs.bokeh.org/en/latest/docs/reference/models/layouts.html\r\nconst html_box_1 = require(\"@bokehjs/models/layouts/html_box\");\r\n// The view of the Bokeh extension/ HTML element\r\n// Here you can define how to render the model as well as react to model changes or View events.\r\nclass SketchView extends html_box_1.HTMLBoxView {\r\n connect_signals() {\r\n super.connect_signals();\r\n this.connect(this.model.properties.value.change, () => {\r\n this.render();\r\n });\r\n }\r\n render() {\r\n console.log(\"render\");\r\n console.log(this.model);\r\n super.render();\r\n this.el.innerHTML = this.model.value;\r\n this.valueElement = this.el.firstElementChild;\r\n this.valueElement.addEventListener(\"click\", () => { this.model.clicks += 1; }, false);\r\n }\r\n}\r\nexports.SketchView = SketchView;\r\nSketchView.__name__ = \"SketchView\";\r\n// The Bokeh .ts model corresponding to the Bokeh .py model\r\nclass Sketch extends html_box_1.HTMLBox {\r\n constructor(attrs) {\r\n super(attrs);\r\n }\r\n static init_Sketch() {\r\n this.prototype.default_view = SketchView;\r\n this.define(({ String, Int }) => ({\r\n value: [String, \"\"],\r\n clicks: [Int, 0],\r\n }));\r\n }\r\n}\r\nexports.Sketch = Sketch;\r\nSketch.__name__ = \"Sketch\";\r\nSketch.__module__ = \"panel_sketch.models.sketch\";\r\nSketch.init_Sketch();\r\n//# sourceMappingURL=sketch.js.map\r\n","type":"js","dependency_paths":[],"dependency_map":[],"exported":[{"type":"named","name":"SketchView"},{"type":"named","name":"Sketch"}],"externals":[],"shims":[]},"code":{"source":"/* models\\sketch.js */ function _(require, module, exports, __esModule, __esExport) {\r\n __esModule();\r\n // See https://docs.bokeh.org/en/latest/docs/reference/models/layouts.html\r\n const html_box_1 = require(\"@bokehjs/models/layouts/html_box\");\r\n // The view of the Bokeh extension/ HTML element\r\n // Here you can define how to render the model as well as react to model changes or View events.\r\n class SketchView extends html_box_1.HTMLBoxView {\r\n connect_signals() {\r\n super.connect_signals();\r\n this.connect(this.model.properties.value.change, () => {\r\n this.render();\r\n });\r\n }\r\n render() {\r\n console.log(\"render\");\r\n console.log(this.model);\r\n super.render();\r\n this.el.innerHTML = this.model.value;\r\n this.valueElement = this.el.firstElementChild;\r\n this.valueElement.addEventListener(\"click\", () => { this.model.clicks += 1; }, false);\r\n }\r\n }\r\n exports.SketchView = SketchView;\r\n SketchView.__name__ = \"SketchView\";\r\n // The Bokeh .ts model corresponding to the Bokeh .py model\r\n class Sketch extends html_box_1.HTMLBox {\r\n constructor(attrs) {\r\n super(attrs);\r\n }\r\n static init_Sketch() {\r\n this.prototype.default_view = SketchView;\r\n this.define(({ String, Int }) => ({\r\n value: [String, \"\"],\r\n clicks: [Int, 0],\r\n }));\r\n }\r\n }\r\n exports.Sketch = Sketch;\r\n Sketch.__name__ = \"Sketch\";\r\n Sketch.__module__ = \"panel_sketch.models.sketch\";\r\n Sketch.init_Sketch();\r\n}\r\n","min_source":"function _(e,t,s,n,i){n();const l=e(\"@bokehjs/models/layouts/html_box\");class c extends l.HTMLBoxView{connect_signals(){super.connect_signals(),this.connect(this.model.properties.value.change,(()=>{this.render()}))}render(){console.log(\"render\"),console.log(this.model),super.render(),this.el.innerHTML=this.model.value,this.valueElement=this.el.firstElementChild,this.valueElement.addEventListener(\"click\",(()=>{this.model.clicks+=1}),!1)}}s.SketchView=c,c.__name__=\"SketchView\";class o extends l.HTMLBox{constructor(e){super(e)}static init_Sketch(){this.prototype.default_view=c,this.define((({String:e,Int:t})=>({value:[e,\"\"],clicks:[t,0]})))}}s.Sketch=o,o.__name__=\"Sketch\",o.__module__=\"panel_sketch.models.sketch\",o.init_Sketch()}\n//# sourceMappingURL=sketch.min.js.map","min_map":"{\"version\":3,\"sources\":[\"0\"],\"names\":[\"_\",\"require\",\"module\",\"exports\",\"__esModule\",\"__esExport\",\"html_box_1\",\"SketchView\",\"HTMLBoxView\",\"[object Object]\",\"super\",\"connect_signals\",\"this\",\"connect\",\"model\",\"properties\",\"value\",\"change\",\"render\",\"console\",\"log\",\"el\",\"innerHTML\",\"valueElement\",\"firstElementChild\",\"addEventListener\",\"clicks\",\"__name__\",\"Sketch\",\"HTMLBox\",\"attrs\",\"prototype\",\"default_view\",\"define\",\"String\",\"Int\",\"__module__\",\"init_Sketch\"],\"mappings\":\"AAAuB,SAASA,EAAEC,EAASC,EAAQC,EAASC,EAAYC,GACpED,IAEA,MAAME,EAAaL,EAAQ,oCAG3B,MAAMM,UAAmBD,EAAWE,YAChCC,kBACIC,MAAMC,kBACNC,KAAKC,QAAQD,KAAKE,MAAMC,WAAWC,MAAMC,QAAQ,KAC7CL,KAAKM,YAGbT,SACIU,QAAQC,IAAI,UACZD,QAAQC,IAAIR,KAAKE,OACjBJ,MAAMQ,SACNN,KAAKS,GAAGC,UAAYV,KAAKE,MAAME,MAC/BJ,KAAKW,aAAeX,KAAKS,GAAGG,kBAC5BZ,KAAKW,aAAaE,iBAAiB,SAAS,KAAQb,KAAKE,MAAMY,QAAU,KAAM,IAGvFvB,EAAQI,WAAaA,EACrBA,EAAWoB,SAAW,aAEtB,MAAMC,UAAetB,EAAWuB,QAC5BpB,YAAYqB,GACRpB,MAAMoB,GAEVrB,qBACIG,KAAKmB,UAAUC,aAAezB,EAC9BK,KAAKqB,QAAO,EAAGC,OAAAA,EAAQC,IAAAA,MAAU,CAC7BnB,MAAO,CAACkB,EAAQ,gDAChBR,OAAQ,CAACS,EAAK,QAI1BhC,EAAQyB,OAASA,EACjBA,EAAOD,SAAW,SAClBC,EAAOQ,WAAa,6BACpBR,EAAOS\",\"file\":\"sketch.min.js\"}"}}]}
--------------------------------------------------------------------------------
/panel_sketch/dist/panel_sketch.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Copyright (c) 2012 - 2021, Anaconda, Inc., and Bokeh Contributors
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification,
6 | * are permitted provided that the following conditions are met:
7 | *
8 | * Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | *
11 | * Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * Neither the name of Anaconda nor the names of any contributors
16 | * may be used to endorse or promote products derived from this software
17 | * without specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29 | * THE POSSIBILITY OF SUCH DAMAGE.
30 | */
31 | (function(root, factory) {
32 | factory(root["Bokeh"], undefined);
33 | })(this, function(Bokeh, version) {
34 | var define;
35 | return (function(modules, entry, aliases, externals) {
36 | const bokeh = typeof Bokeh !== "undefined" && (version != null ? Bokeh[version] : Bokeh);
37 | if (bokeh != null) {
38 | return bokeh.register_plugin(modules, entry, aliases);
39 | } else {
40 | throw new Error("Cannot find Bokeh " + version + ". You have to load it prior to loading plugins.");
41 | }
42 | })
43 | ({
44 | "a6a4fae5e8": function _(e,s,t,o,b){o();const i=e("tslib").__importStar(e("8fbb31f6e4"));t.SketchExtensions=i;e("@bokehjs/base").register_models(i)},
45 | "8fbb31f6e4": function _(c,t,e,f,h){f(),h("Sketch",c("b09786f089").Sketch)},
46 | "b09786f089": function _(e,t,s,n,i){n();const l=e("@bokehjs/models/layouts/html_box");class c extends l.HTMLBoxView{connect_signals(){super.connect_signals(),this.connect(this.model.properties.value.change,(()=>{this.render()}))}render(){console.log("render"),console.log(this.model),super.render(),this.el.innerHTML=this.model.value,this.valueElement=this.el.firstElementChild,this.valueElement.addEventListener("click",(()=>{this.model.clicks+=1}),!1)}}s.SketchView=c,c.__name__="SketchView";class o extends l.HTMLBox{constructor(e){super(e)}static init_Sketch(){this.prototype.default_view=c,this.define((({String:e,Int:t})=>({value:[e,""],clicks:[t,0]})))}}s.Sketch=o,o.__name__="Sketch",o.__module__="panel_sketch.models.sketch",o.init_Sketch()},
47 | }, "a6a4fae5e8", {"index":"a6a4fae5e8","models/index":"8fbb31f6e4","models/sketch":"b09786f089"}, {});});
48 |
--------------------------------------------------------------------------------
/panel_sketch/index.ts:
--------------------------------------------------------------------------------
1 | import * as SketchExtensions from "./models/"
2 | export {SketchExtensions}
3 |
4 | import {register_models} from "@bokehjs/base"
5 | register_models(SketchExtensions as any)
--------------------------------------------------------------------------------
/panel_sketch/models/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarcSkovMadsen/panel-sketch/518cb177e2e8d1899b58f3a3f4d80d26c82ec760/panel_sketch/models/__init__.py
--------------------------------------------------------------------------------
/panel_sketch/models/index.ts:
--------------------------------------------------------------------------------
1 | export {Sketch} from "./sketch"
--------------------------------------------------------------------------------
/panel_sketch/models/sketch.py:
--------------------------------------------------------------------------------
1 | """Sketch Bokeh Model"""
2 | from bokeh.core.properties import Int, String
3 | from bokeh.models import HTMLBox
4 |
5 | DEFAULT_OBJECT = ""
6 |
7 |
8 | class Sketch(HTMLBox):
9 | """Example implementation of a Custom Bokeh Model"""
10 |
11 | value = String(default=DEFAULT_OBJECT)
12 | clicks = Int(default=0)
13 |
--------------------------------------------------------------------------------
/panel_sketch/models/sketch.ts:
--------------------------------------------------------------------------------
1 | // See https://docs.bokeh.org/en/latest/docs/reference/models/layouts.html
2 | import { HTMLBox, HTMLBoxView } from "@bokehjs/models/layouts/html_box"
3 |
4 | // See https://docs.bokeh.org/en/latest/docs/reference/core/properties.html
5 | import * as p from "@bokehjs/core/properties"
6 |
7 | // The view of the Bokeh extension/ HTML element
8 | // Here you can define how to render the model as well as react to model changes or View events.
9 | export class SketchView extends HTMLBoxView {
10 | model: Sketch
11 | valueElement: any // Element
12 |
13 | connect_signals(): void {
14 | super.connect_signals()
15 |
16 | this.connect(this.model.properties.value.change, () => {
17 | this.render();
18 | })
19 | }
20 |
21 | render(): void {
22 | console.log("render")
23 | console.log(this.model)
24 | super.render()
25 | this.el.innerHTML = this.model.value
26 | this.valueElement = this.el.firstElementChild
27 |
28 | this.valueElement.addEventListener("click", () => {this.model.clicks+=1;}, false)
29 | }
30 | }
31 |
32 | export namespace Sketch {
33 | export type Attrs = p.AttrsOf
34 | export type Props = HTMLBox.Props & {
35 | value: p.Property,
36 | clicks: p.Property,
37 | }
38 | }
39 |
40 | export interface Sketch extends Sketch.Attrs { }
41 |
42 | // The Bokeh .ts model corresponding to the Bokeh .py model
43 | export class Sketch extends HTMLBox {
44 | properties: Sketch.Props
45 |
46 | constructor(attrs?: Partial) {
47 | super(attrs)
48 | }
49 |
50 | static __module__ = "panel_sketch.models.sketch"
51 |
52 | static init_Sketch(): void {
53 | this.prototype.default_view = SketchView;
54 |
55 | this.define(({String, Int}) => ({
56 | value: [String, ""],
57 | clicks: [Int, 0],
58 | }))
59 | }
60 | }
--------------------------------------------------------------------------------
/panel_sketch/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "panel_sketch",
3 | "version": "0.0.1",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "version": "0.0.1",
9 | "license": "BSD-3-Clause",
10 | "dependencies": {
11 | "@bokeh/bokehjs": "^2.3.0"
12 | },
13 | "devDependencies": {}
14 | },
15 | "node_modules/@bokeh/bokehjs": {
16 | "version": "2.3.0",
17 | "resolved": "https://registry.npmjs.org/@bokeh/bokehjs/-/bokehjs-2.3.0.tgz",
18 | "integrity": "sha512-geKBhYUVJ5IaY0UNk9k2P0yiYLCj+DOeNjdDneuTJ8K5R9fs0Rpp4iiaQKUGr1yUyQHGHLU8sk4CFZ+Bd5ZILg==",
19 | "dependencies": {
20 | "@bokeh/numbro": "^1.6.2",
21 | "@bokeh/slickgrid": "~2.4.2701",
22 | "choices.js": "^9.0.1",
23 | "es5-ext": "^0.10.53",
24 | "es6-map": "^0.1.5",
25 | "es6-promise": "4.2.8",
26 | "es6-set": "^0.1.5",
27 | "es6-symbol": "^3.1.3",
28 | "es6-weak-map": "^2.0.2",
29 | "flatbush": "^3.2.1",
30 | "flatpickr": "^4.6.6",
31 | "hammerjs": "^2.0.4",
32 | "nouislider": "^14.6.3",
33 | "proj4": "^2.6.3",
34 | "sprintf-js": "^1.1.2",
35 | "timezone": "^1.0.23",
36 | "tslib": "^2.0.3",
37 | "underscore.template": "^0.1.7"
38 | },
39 | "engines": {
40 | "node": ">=14",
41 | "npm": ">=7.4"
42 | }
43 | },
44 | "node_modules/@bokeh/numbro": {
45 | "version": "1.6.2",
46 | "resolved": "https://registry.npmjs.org/@bokeh/numbro/-/numbro-1.6.2.tgz",
47 | "integrity": "sha512-owIECPc3T3QXHCb2v5Ez+/uE9SIxI7N4nd9iFlWnfBrOelr0/omvFn09VisRn37AAFAY39sJiCVgECwryHWUPA==",
48 | "engines": {
49 | "node": "*"
50 | }
51 | },
52 | "node_modules/@bokeh/slickgrid": {
53 | "version": "2.4.2702",
54 | "resolved": "https://registry.npmjs.org/@bokeh/slickgrid/-/slickgrid-2.4.2702.tgz",
55 | "integrity": "sha512-W9tm8Qdw5BrylbZbaVWaQMgLfW/klesnj6J3FnyWpo18hCCOFApccUD8iOnRv7bF6PHlgWk84mW3JT5RSzYKjA==",
56 | "dependencies": {
57 | "@types/slickgrid": "^2.1.30",
58 | "jquery": ">=3.4.0",
59 | "jquery-ui": ">=1.8.0",
60 | "tslib": "^1.10.0"
61 | }
62 | },
63 | "node_modules/@bokeh/slickgrid/node_modules/tslib": {
64 | "version": "1.14.1",
65 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
66 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
67 | },
68 | "node_modules/@types/jquery": {
69 | "version": "3.5.5",
70 | "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.5.tgz",
71 | "integrity": "sha512-6RXU9Xzpc6vxNrS6FPPapN1SxSHgQ336WC6Jj/N8q30OiaBZ00l1GBgeP7usjVZPivSkGUfL1z/WW6TX989M+w==",
72 | "dependencies": {
73 | "@types/sizzle": "*"
74 | }
75 | },
76 | "node_modules/@types/sizzle": {
77 | "version": "2.3.2",
78 | "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz",
79 | "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg=="
80 | },
81 | "node_modules/@types/slickgrid": {
82 | "version": "2.1.30",
83 | "resolved": "https://registry.npmjs.org/@types/slickgrid/-/slickgrid-2.1.30.tgz",
84 | "integrity": "sha512-9nTqNWD3BtEVK0CP+G+mBtvSrKTfQy3Dg5/al+GdTSVMHFm37UxsHJ1eURwPg7rYu6vc7xU95fGTCKMZbxsD5w==",
85 | "dependencies": {
86 | "@types/jquery": "*"
87 | }
88 | },
89 | "node_modules/choices.js": {
90 | "version": "9.0.1",
91 | "resolved": "https://registry.npmjs.org/choices.js/-/choices.js-9.0.1.tgz",
92 | "integrity": "sha512-JgpeDY0Tmg7tqY6jaW/druSklJSt7W68tXFJIw0GSGWmO37SDAL8o60eICNGbzIODjj02VNNtf5h6TgoHDtCsA==",
93 | "dependencies": {
94 | "deepmerge": "^4.2.0",
95 | "fuse.js": "^3.4.5",
96 | "redux": "^4.0.4"
97 | }
98 | },
99 | "node_modules/d": {
100 | "version": "1.0.1",
101 | "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
102 | "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
103 | "dependencies": {
104 | "es5-ext": "^0.10.50",
105 | "type": "^1.0.1"
106 | }
107 | },
108 | "node_modules/deepmerge": {
109 | "version": "4.2.2",
110 | "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
111 | "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
112 | "engines": {
113 | "node": ">=0.10.0"
114 | }
115 | },
116 | "node_modules/es5-ext": {
117 | "version": "0.10.53",
118 | "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
119 | "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
120 | "dependencies": {
121 | "es6-iterator": "~2.0.3",
122 | "es6-symbol": "~3.1.3",
123 | "next-tick": "~1.0.0"
124 | }
125 | },
126 | "node_modules/es6-iterator": {
127 | "version": "2.0.3",
128 | "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
129 | "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
130 | "dependencies": {
131 | "d": "1",
132 | "es5-ext": "^0.10.35",
133 | "es6-symbol": "^3.1.1"
134 | }
135 | },
136 | "node_modules/es6-map": {
137 | "version": "0.1.5",
138 | "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
139 | "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
140 | "dependencies": {
141 | "d": "1",
142 | "es5-ext": "~0.10.14",
143 | "es6-iterator": "~2.0.1",
144 | "es6-set": "~0.1.5",
145 | "es6-symbol": "~3.1.1",
146 | "event-emitter": "~0.3.5"
147 | }
148 | },
149 | "node_modules/es6-promise": {
150 | "version": "4.2.8",
151 | "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
152 | "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
153 | },
154 | "node_modules/es6-set": {
155 | "version": "0.1.5",
156 | "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
157 | "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
158 | "dependencies": {
159 | "d": "1",
160 | "es5-ext": "~0.10.14",
161 | "es6-iterator": "~2.0.1",
162 | "es6-symbol": "3.1.1",
163 | "event-emitter": "~0.3.5"
164 | }
165 | },
166 | "node_modules/es6-set/node_modules/es6-symbol": {
167 | "version": "3.1.1",
168 | "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
169 | "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
170 | "dependencies": {
171 | "d": "1",
172 | "es5-ext": "~0.10.14"
173 | }
174 | },
175 | "node_modules/es6-symbol": {
176 | "version": "3.1.3",
177 | "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
178 | "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
179 | "dependencies": {
180 | "d": "^1.0.1",
181 | "ext": "^1.1.2"
182 | }
183 | },
184 | "node_modules/es6-weak-map": {
185 | "version": "2.0.3",
186 | "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
187 | "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
188 | "dependencies": {
189 | "d": "1",
190 | "es5-ext": "^0.10.46",
191 | "es6-iterator": "^2.0.3",
192 | "es6-symbol": "^3.1.1"
193 | }
194 | },
195 | "node_modules/event-emitter": {
196 | "version": "0.3.5",
197 | "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
198 | "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
199 | "dependencies": {
200 | "d": "1",
201 | "es5-ext": "~0.10.14"
202 | }
203 | },
204 | "node_modules/ext": {
205 | "version": "1.4.0",
206 | "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
207 | "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
208 | "dependencies": {
209 | "type": "^2.0.0"
210 | }
211 | },
212 | "node_modules/ext/node_modules/type": {
213 | "version": "2.5.0",
214 | "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz",
215 | "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw=="
216 | },
217 | "node_modules/flatbush": {
218 | "version": "3.3.0",
219 | "resolved": "https://registry.npmjs.org/flatbush/-/flatbush-3.3.0.tgz",
220 | "integrity": "sha512-F3EzQvKpdmXUbFwWxLKBpytOFEGYQMCTBLuqZ4GEajFOEAvnOIBiyxW3OFSZXIOtpCS8teN6bFEpNZtnVXuDQA==",
221 | "dependencies": {
222 | "flatqueue": "^1.2.0"
223 | }
224 | },
225 | "node_modules/flatpickr": {
226 | "version": "4.6.9",
227 | "resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.9.tgz",
228 | "integrity": "sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw=="
229 | },
230 | "node_modules/flatqueue": {
231 | "version": "1.2.1",
232 | "resolved": "https://registry.npmjs.org/flatqueue/-/flatqueue-1.2.1.tgz",
233 | "integrity": "sha512-X86TpWS1rGuY7m382HuA9vngLeDuWA9lJvhEG+GfgKMV5onSvx5a71cl7GMbXzhWtlN9dGfqOBrpfqeOtUfGYQ=="
234 | },
235 | "node_modules/fuse.js": {
236 | "version": "3.6.1",
237 | "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-3.6.1.tgz",
238 | "integrity": "sha512-hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw==",
239 | "engines": {
240 | "node": ">=6"
241 | }
242 | },
243 | "node_modules/hammerjs": {
244 | "version": "2.0.8",
245 | "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
246 | "integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE=",
247 | "engines": {
248 | "node": ">=0.8.0"
249 | }
250 | },
251 | "node_modules/jquery": {
252 | "version": "3.6.0",
253 | "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
254 | "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
255 | },
256 | "node_modules/jquery-ui": {
257 | "version": "1.12.1",
258 | "resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.12.1.tgz",
259 | "integrity": "sha1-vLQEXI3QU5wTS8FIjN0+dop6nlE="
260 | },
261 | "node_modules/js-tokens": {
262 | "version": "4.0.0",
263 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
264 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
265 | },
266 | "node_modules/loose-envify": {
267 | "version": "1.4.0",
268 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
269 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
270 | "dependencies": {
271 | "js-tokens": "^3.0.0 || ^4.0.0"
272 | },
273 | "bin": {
274 | "loose-envify": "cli.js"
275 | }
276 | },
277 | "node_modules/mgrs": {
278 | "version": "1.0.0",
279 | "resolved": "https://registry.npmjs.org/mgrs/-/mgrs-1.0.0.tgz",
280 | "integrity": "sha1-+5FYjnjJACVnI5XLQLJffNatGCk="
281 | },
282 | "node_modules/next-tick": {
283 | "version": "1.0.0",
284 | "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
285 | "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
286 | },
287 | "node_modules/nouislider": {
288 | "version": "14.6.4",
289 | "resolved": "https://registry.npmjs.org/nouislider/-/nouislider-14.6.4.tgz",
290 | "integrity": "sha512-PVCGYl+aC7/nVEbW61ypJWfuW3UCpvctz/luxpt4byxxli1FFyjBX9NIiy4Yak9AaO6a5BkPGfFYMCW4eg3eeQ=="
291 | },
292 | "node_modules/proj4": {
293 | "version": "2.7.2",
294 | "resolved": "https://registry.npmjs.org/proj4/-/proj4-2.7.2.tgz",
295 | "integrity": "sha512-x/EboBmIq48a9FED0Z9zWCXkd8VIpXHLsyEXljGtsnzeztC41bFjPjJ0S//wBbNLDnDYRe0e6c3FSSiqMCebDA==",
296 | "dependencies": {
297 | "mgrs": "1.0.0",
298 | "wkt-parser": "^1.2.4"
299 | }
300 | },
301 | "node_modules/redux": {
302 | "version": "4.0.5",
303 | "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz",
304 | "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==",
305 | "dependencies": {
306 | "loose-envify": "^1.4.0",
307 | "symbol-observable": "^1.2.0"
308 | }
309 | },
310 | "node_modules/sprintf-js": {
311 | "version": "1.1.2",
312 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
313 | "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
314 | },
315 | "node_modules/symbol-observable": {
316 | "version": "1.2.0",
317 | "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
318 | "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==",
319 | "engines": {
320 | "node": ">=0.10.0"
321 | }
322 | },
323 | "node_modules/timezone": {
324 | "version": "1.0.23",
325 | "resolved": "https://registry.npmjs.org/timezone/-/timezone-1.0.23.tgz",
326 | "integrity": "sha512-yhQgk6qmSLB+TF8HGmApZAVI5bfzR1CoKUGr+WMZWmx75ED1uDewAZA8QMGCQ70TEv4GmM8pDB9jrHuxdaQ1PA=="
327 | },
328 | "node_modules/tslib": {
329 | "version": "2.1.0",
330 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
331 | "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A=="
332 | },
333 | "node_modules/type": {
334 | "version": "1.2.0",
335 | "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
336 | "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
337 | },
338 | "node_modules/underscore.template": {
339 | "version": "0.1.7",
340 | "resolved": "https://registry.npmjs.org/underscore.template/-/underscore.template-0.1.7.tgz",
341 | "integrity": "sha1-MBPg6hgXVjBvFgnpWcr7xyKts+k="
342 | },
343 | "node_modules/wkt-parser": {
344 | "version": "1.2.4",
345 | "resolved": "https://registry.npmjs.org/wkt-parser/-/wkt-parser-1.2.4.tgz",
346 | "integrity": "sha512-ZzKnc7ml/91fOPh5bANBL4vUlWPIYYv11waCtWTkl2TRN+LEmBg60Q1MA8gqV4hEp4MGfSj9JiHz91zw/gTDXg=="
347 | }
348 | },
349 | "dependencies": {
350 | "@bokeh/bokehjs": {
351 | "version": "2.3.0",
352 | "resolved": "https://registry.npmjs.org/@bokeh/bokehjs/-/bokehjs-2.3.0.tgz",
353 | "integrity": "sha512-geKBhYUVJ5IaY0UNk9k2P0yiYLCj+DOeNjdDneuTJ8K5R9fs0Rpp4iiaQKUGr1yUyQHGHLU8sk4CFZ+Bd5ZILg==",
354 | "requires": {
355 | "@bokeh/numbro": "^1.6.2",
356 | "@bokeh/slickgrid": "~2.4.2701",
357 | "choices.js": "^9.0.1",
358 | "es5-ext": "^0.10.53",
359 | "es6-map": "^0.1.5",
360 | "es6-promise": "4.2.8",
361 | "es6-set": "^0.1.5",
362 | "es6-symbol": "^3.1.3",
363 | "es6-weak-map": "^2.0.2",
364 | "flatbush": "^3.2.1",
365 | "flatpickr": "^4.6.6",
366 | "hammerjs": "^2.0.4",
367 | "nouislider": "^14.6.3",
368 | "proj4": "^2.6.3",
369 | "sprintf-js": "^1.1.2",
370 | "timezone": "^1.0.23",
371 | "tslib": "^2.0.3",
372 | "underscore.template": "^0.1.7"
373 | }
374 | },
375 | "@bokeh/numbro": {
376 | "version": "1.6.2",
377 | "resolved": "https://registry.npmjs.org/@bokeh/numbro/-/numbro-1.6.2.tgz",
378 | "integrity": "sha512-owIECPc3T3QXHCb2v5Ez+/uE9SIxI7N4nd9iFlWnfBrOelr0/omvFn09VisRn37AAFAY39sJiCVgECwryHWUPA=="
379 | },
380 | "@bokeh/slickgrid": {
381 | "version": "2.4.2702",
382 | "resolved": "https://registry.npmjs.org/@bokeh/slickgrid/-/slickgrid-2.4.2702.tgz",
383 | "integrity": "sha512-W9tm8Qdw5BrylbZbaVWaQMgLfW/klesnj6J3FnyWpo18hCCOFApccUD8iOnRv7bF6PHlgWk84mW3JT5RSzYKjA==",
384 | "requires": {
385 | "@types/slickgrid": "^2.1.30",
386 | "jquery": ">=3.4.0",
387 | "jquery-ui": ">=1.8.0",
388 | "tslib": "^1.10.0"
389 | },
390 | "dependencies": {
391 | "tslib": {
392 | "version": "1.14.1",
393 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
394 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
395 | }
396 | }
397 | },
398 | "@types/jquery": {
399 | "version": "3.5.5",
400 | "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.5.tgz",
401 | "integrity": "sha512-6RXU9Xzpc6vxNrS6FPPapN1SxSHgQ336WC6Jj/N8q30OiaBZ00l1GBgeP7usjVZPivSkGUfL1z/WW6TX989M+w==",
402 | "requires": {
403 | "@types/sizzle": "*"
404 | }
405 | },
406 | "@types/sizzle": {
407 | "version": "2.3.2",
408 | "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz",
409 | "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg=="
410 | },
411 | "@types/slickgrid": {
412 | "version": "2.1.30",
413 | "resolved": "https://registry.npmjs.org/@types/slickgrid/-/slickgrid-2.1.30.tgz",
414 | "integrity": "sha512-9nTqNWD3BtEVK0CP+G+mBtvSrKTfQy3Dg5/al+GdTSVMHFm37UxsHJ1eURwPg7rYu6vc7xU95fGTCKMZbxsD5w==",
415 | "requires": {
416 | "@types/jquery": "*"
417 | }
418 | },
419 | "choices.js": {
420 | "version": "9.0.1",
421 | "resolved": "https://registry.npmjs.org/choices.js/-/choices.js-9.0.1.tgz",
422 | "integrity": "sha512-JgpeDY0Tmg7tqY6jaW/druSklJSt7W68tXFJIw0GSGWmO37SDAL8o60eICNGbzIODjj02VNNtf5h6TgoHDtCsA==",
423 | "requires": {
424 | "deepmerge": "^4.2.0",
425 | "fuse.js": "^3.4.5",
426 | "redux": "^4.0.4"
427 | }
428 | },
429 | "d": {
430 | "version": "1.0.1",
431 | "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
432 | "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
433 | "requires": {
434 | "es5-ext": "^0.10.50",
435 | "type": "^1.0.1"
436 | }
437 | },
438 | "deepmerge": {
439 | "version": "4.2.2",
440 | "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
441 | "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
442 | },
443 | "es5-ext": {
444 | "version": "0.10.53",
445 | "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
446 | "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
447 | "requires": {
448 | "es6-iterator": "~2.0.3",
449 | "es6-symbol": "~3.1.3",
450 | "next-tick": "~1.0.0"
451 | }
452 | },
453 | "es6-iterator": {
454 | "version": "2.0.3",
455 | "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
456 | "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
457 | "requires": {
458 | "d": "1",
459 | "es5-ext": "^0.10.35",
460 | "es6-symbol": "^3.1.1"
461 | }
462 | },
463 | "es6-map": {
464 | "version": "0.1.5",
465 | "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
466 | "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
467 | "requires": {
468 | "d": "1",
469 | "es5-ext": "~0.10.14",
470 | "es6-iterator": "~2.0.1",
471 | "es6-set": "~0.1.5",
472 | "es6-symbol": "~3.1.1",
473 | "event-emitter": "~0.3.5"
474 | }
475 | },
476 | "es6-promise": {
477 | "version": "4.2.8",
478 | "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
479 | "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
480 | },
481 | "es6-set": {
482 | "version": "0.1.5",
483 | "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
484 | "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
485 | "requires": {
486 | "d": "1",
487 | "es5-ext": "~0.10.14",
488 | "es6-iterator": "~2.0.1",
489 | "es6-symbol": "3.1.1",
490 | "event-emitter": "~0.3.5"
491 | },
492 | "dependencies": {
493 | "es6-symbol": {
494 | "version": "3.1.1",
495 | "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
496 | "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
497 | "requires": {
498 | "d": "1",
499 | "es5-ext": "~0.10.14"
500 | }
501 | }
502 | }
503 | },
504 | "es6-symbol": {
505 | "version": "3.1.3",
506 | "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
507 | "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
508 | "requires": {
509 | "d": "^1.0.1",
510 | "ext": "^1.1.2"
511 | }
512 | },
513 | "es6-weak-map": {
514 | "version": "2.0.3",
515 | "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
516 | "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
517 | "requires": {
518 | "d": "1",
519 | "es5-ext": "^0.10.46",
520 | "es6-iterator": "^2.0.3",
521 | "es6-symbol": "^3.1.1"
522 | }
523 | },
524 | "event-emitter": {
525 | "version": "0.3.5",
526 | "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
527 | "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
528 | "requires": {
529 | "d": "1",
530 | "es5-ext": "~0.10.14"
531 | }
532 | },
533 | "ext": {
534 | "version": "1.4.0",
535 | "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
536 | "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
537 | "requires": {
538 | "type": "^2.0.0"
539 | },
540 | "dependencies": {
541 | "type": {
542 | "version": "2.5.0",
543 | "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz",
544 | "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw=="
545 | }
546 | }
547 | },
548 | "flatbush": {
549 | "version": "3.3.0",
550 | "resolved": "https://registry.npmjs.org/flatbush/-/flatbush-3.3.0.tgz",
551 | "integrity": "sha512-F3EzQvKpdmXUbFwWxLKBpytOFEGYQMCTBLuqZ4GEajFOEAvnOIBiyxW3OFSZXIOtpCS8teN6bFEpNZtnVXuDQA==",
552 | "requires": {
553 | "flatqueue": "^1.2.0"
554 | }
555 | },
556 | "flatpickr": {
557 | "version": "4.6.9",
558 | "resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.9.tgz",
559 | "integrity": "sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw=="
560 | },
561 | "flatqueue": {
562 | "version": "1.2.1",
563 | "resolved": "https://registry.npmjs.org/flatqueue/-/flatqueue-1.2.1.tgz",
564 | "integrity": "sha512-X86TpWS1rGuY7m382HuA9vngLeDuWA9lJvhEG+GfgKMV5onSvx5a71cl7GMbXzhWtlN9dGfqOBrpfqeOtUfGYQ=="
565 | },
566 | "fuse.js": {
567 | "version": "3.6.1",
568 | "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-3.6.1.tgz",
569 | "integrity": "sha512-hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw=="
570 | },
571 | "hammerjs": {
572 | "version": "2.0.8",
573 | "resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
574 | "integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE="
575 | },
576 | "jquery": {
577 | "version": "3.6.0",
578 | "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
579 | "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw=="
580 | },
581 | "jquery-ui": {
582 | "version": "1.12.1",
583 | "resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.12.1.tgz",
584 | "integrity": "sha1-vLQEXI3QU5wTS8FIjN0+dop6nlE="
585 | },
586 | "js-tokens": {
587 | "version": "4.0.0",
588 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
589 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
590 | },
591 | "loose-envify": {
592 | "version": "1.4.0",
593 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
594 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
595 | "requires": {
596 | "js-tokens": "^3.0.0 || ^4.0.0"
597 | }
598 | },
599 | "mgrs": {
600 | "version": "1.0.0",
601 | "resolved": "https://registry.npmjs.org/mgrs/-/mgrs-1.0.0.tgz",
602 | "integrity": "sha1-+5FYjnjJACVnI5XLQLJffNatGCk="
603 | },
604 | "next-tick": {
605 | "version": "1.0.0",
606 | "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
607 | "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
608 | },
609 | "nouislider": {
610 | "version": "14.6.4",
611 | "resolved": "https://registry.npmjs.org/nouislider/-/nouislider-14.6.4.tgz",
612 | "integrity": "sha512-PVCGYl+aC7/nVEbW61ypJWfuW3UCpvctz/luxpt4byxxli1FFyjBX9NIiy4Yak9AaO6a5BkPGfFYMCW4eg3eeQ=="
613 | },
614 | "proj4": {
615 | "version": "2.7.2",
616 | "resolved": "https://registry.npmjs.org/proj4/-/proj4-2.7.2.tgz",
617 | "integrity": "sha512-x/EboBmIq48a9FED0Z9zWCXkd8VIpXHLsyEXljGtsnzeztC41bFjPjJ0S//wBbNLDnDYRe0e6c3FSSiqMCebDA==",
618 | "requires": {
619 | "mgrs": "1.0.0",
620 | "wkt-parser": "^1.2.4"
621 | }
622 | },
623 | "redux": {
624 | "version": "4.0.5",
625 | "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz",
626 | "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==",
627 | "requires": {
628 | "loose-envify": "^1.4.0",
629 | "symbol-observable": "^1.2.0"
630 | }
631 | },
632 | "sprintf-js": {
633 | "version": "1.1.2",
634 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
635 | "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
636 | },
637 | "symbol-observable": {
638 | "version": "1.2.0",
639 | "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
640 | "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
641 | },
642 | "timezone": {
643 | "version": "1.0.23",
644 | "resolved": "https://registry.npmjs.org/timezone/-/timezone-1.0.23.tgz",
645 | "integrity": "sha512-yhQgk6qmSLB+TF8HGmApZAVI5bfzR1CoKUGr+WMZWmx75ED1uDewAZA8QMGCQ70TEv4GmM8pDB9jrHuxdaQ1PA=="
646 | },
647 | "tslib": {
648 | "version": "2.1.0",
649 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
650 | "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A=="
651 | },
652 | "type": {
653 | "version": "1.2.0",
654 | "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
655 | "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
656 | },
657 | "underscore.template": {
658 | "version": "0.1.7",
659 | "resolved": "https://registry.npmjs.org/underscore.template/-/underscore.template-0.1.7.tgz",
660 | "integrity": "sha1-MBPg6hgXVjBvFgnpWcr7xyKts+k="
661 | },
662 | "wkt-parser": {
663 | "version": "1.2.4",
664 | "resolved": "https://registry.npmjs.org/wkt-parser/-/wkt-parser-1.2.4.tgz",
665 | "integrity": "sha512-ZzKnc7ml/91fOPh5bANBL4vUlWPIYYv11waCtWTkl2TRN+LEmBg60Q1MA8gqV4hEp4MGfSj9JiHz91zw/gTDXg=="
666 | }
667 | }
668 | }
669 |
--------------------------------------------------------------------------------
/panel_sketch/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "panel_sketch",
3 | "version": "0.0.1",
4 | "description": "HighCharts extensions for Panel",
5 | "license": "BSD-3-Clause",
6 | "keywords": [],
7 | "repository": {},
8 | "dependencies": {
9 | "@bokeh/bokehjs": "^2.3.0"
10 | },
11 | "devDependencies": {}
12 | }
13 |
--------------------------------------------------------------------------------
/panel_sketch/sketch.py:
--------------------------------------------------------------------------------
1 | """Sketch makes it easy for Pythonistas to quickly sketch interactive visualizations and other
2 | applications running in.
3 |
4 | - the browser. Potentially without a Python backend
5 | - the Jupyter Notebook.
6 | - your favorite editor or IDE.
7 |
8 | It is heavily inspired by [p5js](https://p5js.org/get-started/),
9 | [p5js sketches](https://editor.p5js.org/p5/sketches) and
10 | [pyp5js](https://github.com/berinhard/pyp5js) but not limited to the p5js universe. You can also
11 | think of it as a [Code Sandbox](https://codesandbox.io/) or
12 | [JS Fiddle](https://jsfiddle.net/) but for #Python 🐍 and data science.
13 | """
14 |
15 | import panel as pn
16 | import param
17 |
18 | from .sketch_base import SketchBase
19 | from .sketch_compiler import COMPILERS
20 | from .sketch_editor import SketchEditor
21 | from .sketch_viewer import SketchViewer
22 |
23 | pn.config.js_files["p5"] = "https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.js"
24 | pn.config.js_files["pyodide"] = "https://pyodide-cdn2.iodide.io/v0.15.0/full/pyodide.js"
25 |
26 |
27 | class Sketch(SketchBase): # pylint: disable=too-many-instance-attributes
28 | """Sketch makes it easy for Pythonistas to quickly sketch interactive visualizations and other
29 | applications running in.
30 |
31 | - the browser. Potentially without a Python backend
32 | - the Jupyter Notebook.
33 | - your favorite editor or IDE.
34 |
35 | It is heavily inspired by [p5js](https://p5js.org/get-started/),
36 | [p5js sketches](https://editor.p5js.org/p5/sketches) and
37 | [pyp5js](https://github.com/berinhard/pyp5js) but not limited to the p5js universe. You can also
38 | think of it as a [Code Sandbox](https://codesandbox.io/) or
39 | [JS Fiddle](https://jsfiddle.net/) but for #Python 🐍 and data science."""
40 |
41 | def __init__(self, **params):
42 | params["args"] = params.get("args", {})
43 |
44 | super().__init__(**params)
45 |
46 | self._viewer = None
47 | self._editor = None
48 | self._compilers = {}
49 |
50 | self._compile_object()
51 |
52 | @property
53 | def viewer(self):
54 | """A Viewer that makes viewing the Sketch a joy"""
55 | if not self._viewer:
56 | self._viewer = SketchViewer(sketch=self)
57 | return self._viewer
58 |
59 | @property
60 | def editor(self):
61 | """An Editor that makes editing the Sketch a joy"""
62 | if not self._editor:
63 | self._editor = SketchEditor(sketch=self)
64 | return self._editor
65 |
66 | @property
67 | def _compiler(self):
68 | """A Compiler that makes compiling the Sketch a joy"""
69 | if self.compiler not in self._compilers:
70 | self._compilers[self.compiler] = COMPILERS[self.compiler](sketch=self)
71 | return self._compilers[self.compiler]
72 |
73 | @param.depends("object", watch=True)
74 | def _compile_object(self):
75 | self._compiler.run()
76 |
--------------------------------------------------------------------------------
/panel_sketch/sketch_base.py:
--------------------------------------------------------------------------------
1 | """SketchBase is the basic Data Model of a Sketch"""
2 | import param
3 |
4 | DEFAULT_SKETCH = """
5 | def setup():
6 |
7 | createCanvas(200, 200)
8 |
9 | background(160)
10 |
11 | def draw():
12 |
13 | fill("blue")
14 |
15 | background(200)
16 |
17 | radius = sin(frameCount / 60) * 50 + 50
18 |
19 | ellipse(100, 100, radius, radius)
20 | """
21 |
22 | TEMPLATES = ["basic", "pyp5js"]
23 | DEFAULT_TEMPLATE = "pyp5js"
24 |
25 | COMPILERS = ["pyodide", "transcrypt"]
26 | DEFAULT_COMPILER = "pyodide"
27 |
28 |
29 | class SketchBase(param.Parameterized):
30 | """SketchBase is the basic Data Model of a Sketch"""
31 |
32 | object = param.String(
33 | default=DEFAULT_SKETCH,
34 | doc="""A Python script. It is transpiled to javascript (Transcript) or run directly in javascript (Pyodide). You can reference the `div` element via `sketchElement` in Python""",
35 | )
36 | html = param.String(
37 | default="""""",
38 | doc="""A HTML String to mark up the Sketch.""",
39 | )
40 | css = param.String(
41 | default="",
42 | doc="""A CSS String to style the Sketch. You can style the HTML div via the `#sketch-element` reference.""",
43 | )
44 | javascript = param.String(
45 | default="", doc="""The result of the compilation of the python object."""
46 | )
47 |
48 | args = param.Dict(
49 | doc="""A Dictionary of keys and values that can be reference via `window.args` in the python script."""
50 | )
51 |
52 | template = param.ObjectSelector(
53 | DEFAULT_TEMPLATE,
54 | objects=TEMPLATES,
55 | doc="""The template to use for compilation. One of 'basic', 'pyp5js'. Default is (currently) 'pyp5js'.""",
56 | )
57 | compiler = param.ObjectSelector(DEFAULT_COMPILER, objects=COMPILERS)
58 |
59 | loading = param.Boolean(
60 | doc="""Whether or not the Sketch is loading. For example during compilation."""
61 | )
62 |
63 | def __init__(self, **params):
64 | if "args" not in params:
65 | params["args"] = {}
66 |
67 | super().__init__(**params)
68 |
--------------------------------------------------------------------------------
/panel_sketch/sketch_compiler/__init__.py:
--------------------------------------------------------------------------------
1 | """The Sketch Compilers makes it easy to compiles a Sketch"""
2 | import pathlib
3 | import subprocess
4 | import tempfile
5 | from textwrap import dedent
6 | from typing import Dict, List
7 |
8 | import param
9 |
10 | from ..sketch_base import SketchBase
11 |
12 | ROOT = pathlib.Path(__file__).parent
13 |
14 | PYODIDE_TEMPLATE_STRINGS = {
15 | "basic": (ROOT / "template_pyodide_basic.js").read_text(),
16 | "pyp5js": (ROOT / "template_pyodide_pyp5js.js").read_text(),
17 | }
18 |
19 | TRANSCRYPT_TEMPLATE_STRINGS = {
20 | "basic": (ROOT / "template_transcrypt_basic.py").read_text(),
21 | "pyp5js": (ROOT / "template_transcrypt_pyp5js.py").read_text(),
22 | }
23 |
24 | OBJECT_PREFIX = "sketchElement = document.getElementById('sketch-element')\n"
25 |
26 | TRANSCRYPT_DIR = str(ROOT / "assets" / "js" / "transcrypt").replace("\\", "/") + "/"
27 |
28 | print(f"""
29 | Warning: Remember to add --static-dirs transcrypt={TRANSCRYPT_DIR} when running panel serve"""
30 | )
31 |
32 |
33 | class SketchCompilerBase(param.Parameterized):
34 | """The SketchCompilerBase should be inherited by child classes"""
35 |
36 | run = param.Action(constant=True)
37 |
38 | sketch = param.ClassSelector(class_=SketchBase, precedence=-1, constant=True)
39 |
40 | _TEMPLATE_STRINGS: Dict[str, str] = {}
41 |
42 | def __init__(self, **params):
43 | super().__init__(**params)
44 |
45 | with param.edit_constant(self):
46 | self.run = self._run_compiler
47 |
48 | def _run_compiler(self):
49 | # pylint: disable=no-member
50 | self.sketch.loading=True
51 |
52 | python = OBJECT_PREFIX + self.sketch.object
53 | self.sketch.javascript = self._compile(python, self._template_string)
54 |
55 | self.sketch.loading=False
56 |
57 | @classmethod
58 | def _compile(cls, sketch_object, template_string):
59 | raise NotImplementedError("Implement this is child classes")
60 |
61 | @property
62 | def _template_string(self):
63 | # pylint: disable=no-member
64 | return self._TEMPLATE_STRINGS[self.sketch.template]
65 |
66 |
67 | class TranscryptCompiler(SketchCompilerBase):
68 | """The TranscryptCompiler uses the Transcrypt Python library"""
69 |
70 | arguments = param.List(
71 | default=["transcrypt", "-b", "-n", "-m"],
72 | constant=True,
73 | doc="""The arguments to transpile from sketch.py to sketch.js""",
74 | )
75 |
76 | _TEMPLATE_STRINGS: Dict[str, str] = TRANSCRYPT_TEMPLATE_STRINGS
77 |
78 | @classmethod
79 | def _compile(cls, sketch_object, template_string):
80 | if "from pyp5js import *" in template_string:
81 | template_name = "pyp5js"
82 | else:
83 | template_name = "basic"
84 | with tempfile.TemporaryDirectory(prefix="panel_sketch_transcrypt") as tmpdir:
85 | root = pathlib.Path(tmpdir)
86 | sketch_py = root / "sketch.py"
87 | sketch_py.write_text(template_string.replace("{{sketch_object}}", sketch_object))
88 |
89 | if template_name == "pyp5js":
90 | arguments = [
91 | "transcrypt",
92 | "-xp",
93 | "c:\\repos\\private\\panel-sketch\\.venv\\lib\\site-packages\\pyp5js",
94 | "-k",
95 | "-ks",
96 | "-b",
97 | "-m",
98 | "-n",
99 | str(sketch_py),
100 | ]
101 | else:
102 | arguments = ["transcrypt", "-b", "-n", "-m"] + [str(sketch_py)]
103 | print(" ".join(arguments))
104 | subprocess.run(
105 | arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=True
106 | )
107 |
108 | # We should find a way to serve the transcrypt and p5 assets locally
109 | sketch_js = (root / "__target__/sketch.js").read_text().replace("from './", "from '../transcrypt/")
110 | # results.append(sketch_js)
111 | return sketch_js
112 |
113 |
114 | class PyodideCompiler(SketchCompilerBase):
115 | """The PyodideCompiler uses the Pyodide JS library"""
116 |
117 | run = param.Action(constant=True)
118 |
119 | sketch = param.ClassSelector(class_=SketchBase, precedence=-1, constant=True)
120 |
121 | _TEMPLATE_STRINGS: Dict[str, str] = PYODIDE_TEMPLATE_STRINGS
122 |
123 | @classmethod
124 | def _compile(cls, sketch_object, template_string):
125 | sketch_object = cls._clean_object(sketch_object)
126 | return template_string.replace("{{sketch_object}}", sketch_object)
127 |
128 | @staticmethod
129 | def _clean_object(value: str) -> str:
130 | clean = dedent(value)
131 | clean = clean.replace("from pyp5js import *\n", "")
132 | return clean
133 |
134 |
135 | COMPILERS = {"pyodide": PyodideCompiler, "transcrypt": TranscryptCompiler}
136 |
--------------------------------------------------------------------------------
/panel_sketch/sketch_compiler/assets/js/transcrypt/org.transcrypt.__runtime__.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "file": "org.transcrypt.__runtime__.js",
4 | "sources": [
5 | "org.transcrypt.__runtime__.py"
6 | ],
7 | "mappings": "AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA;AAAA;AAAA;AAGA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AAEA;AAAA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAEA;AAAA;AACA;AACA;AAAA;AAAA;AAEA;AAAA;AACA;AACA;AAAA;AAAA;AAEA;AAAA;AACA;AACA;AAAA;AAAA;AAEA;AAAA;AACA;AACA;AAAA;AAAA;AAEA;AAAA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAEA;AAAA;AACA;AACA;AAAA;AAAA;AAEA;AAAA;AACA;AACA;AAAA;AAAA;AAEA;AAAA;AACA;AACA;AAAA;AAAA;AAEA;AAAA;AACA;AACA;AAAA;AAAA;AAMA;AAAA;AAAA;AAKA;AAAA;AAAA;AAGA;AAAA;AAAA;AAGA;AAAA;AAAA;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAEA;AACA;AAAA;AAIA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AACA;AACA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AACA;AAAA;AA0GA;AAAA;AAUA;AACA;AAEA;AACA;AAAA;AAAA;AAEA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAAA;AAEA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAEA;AAEA;AACA;AAAA"
8 | }
--------------------------------------------------------------------------------
/panel_sketch/sketch_compiler/assets/js/transcrypt/org.transcrypt.__runtime__.py:
--------------------------------------------------------------------------------
1 | # Transcrypt runtime module
2 |
3 | # __pragma__ ('js', 'export var __envir__ = {{}};\n{}', __include__ ('org/transcrypt/__envir__.js'))
4 | # __pragma__ ('js', '{}', __include__ ('org/transcrypt/__core__.js'))
5 | # __pragma__ ('js', '{}', __include__ ('org/transcrypt/__builtin__.js'))
6 |
7 | # __pragma__ ('skip')
8 | copy = Math = __typeof__ = __repr__ = document = console = window = 0
9 | # __pragma__ ('noskip')
10 |
11 | # __pragma__ ('notconv') # !!! tconv gives a problem with __terminal__, needs investigation
12 | # __pragma__ ('nokwargs')
13 | # __pragma__ ('noalias', 'sort')
14 |
15 |
16 | class BaseException:
17 | pass
18 |
19 |
20 | class Exception(BaseException):
21 | # __pragma__ ('kwargs')
22 | def __init__(self, *args, **kwargs):
23 | self.__args__ = args
24 | try:
25 | self.stack = kwargs.error.stack # Integrate with JavaScript Error object
26 | except:
27 | self.stack = "No stack trace available"
28 |
29 | # __pragma__ ('nokwargs')
30 |
31 | def __repr__(self):
32 | if len(self.__args__) > 1:
33 | return "{}{}".format(self.__class__.__name__, repr(tuple(self.__args__)))
34 | elif len(self.__args__):
35 | return "{}({})".format(self.__class__.__name__, repr(self.__args__[0]))
36 | else:
37 | return "{}()".format(self.__class__.__name__)
38 |
39 | def __str__(self):
40 | if len(self.__args__) > 1:
41 | return str(tuple(self.__args__))
42 | elif len(self.__args__):
43 | return str(self.__args__[0])
44 | else:
45 | return ""
46 |
47 |
48 | class IterableError(Exception):
49 | def __init__(self, error):
50 | Exception.__init__(self, "Can't iterate over non-iterable", error=error)
51 |
52 |
53 | class StopIteration(Exception):
54 | def __init__(self, error):
55 | Exception.__init__(self, "Iterator exhausted", error=error)
56 |
57 |
58 | class ValueError(Exception):
59 | def __init__(self, message, error):
60 | Exception.__init__(self, message, error=error)
61 |
62 |
63 | class KeyError(Exception):
64 | def __init__(self, message, error):
65 | Exception.__init__(self, message, error=error)
66 |
67 |
68 | class AssertionError(Exception):
69 | def __init__(self, message, error):
70 | if message:
71 | Exception.__init__(self, message, error=error)
72 | else:
73 | Exception.__init__(self, error=error)
74 |
75 |
76 | class NotImplementedError(Exception):
77 | def __init__(self, message, error):
78 | Exception.__init__(self, message, error=error)
79 |
80 |
81 | class IndexError(Exception):
82 | def __init__(self, message, error):
83 | Exception.__init__(self, message, error=error)
84 |
85 |
86 | class AttributeError(Exception):
87 | def __init__(self, message, error):
88 | Exception.__init__(self, message, error=error)
89 |
90 |
91 | class TypeError(Exception):
92 | def __init__(self, message, error):
93 | Exception.__init__(self, message, error=error)
94 |
95 |
96 | # Warnings Exceptions
97 | # N.B. This is a limited subset of the warnings defined in
98 | # the cpython implementation to keep things small for now.
99 |
100 |
101 | class Warning(Exception):
102 | """Warning Base Class"""
103 |
104 |
105 | class UserWarning(Warning):
106 | pass
107 |
108 |
109 | class DeprecationWarning(Warning):
110 | pass
111 |
112 |
113 | class RuntimeWarning(Warning):
114 | pass
115 |
116 |
117 | # __pragma__ ('kwargs')
118 |
119 |
120 | def __sort__(iterable, key=None, reverse=False): # Used by py_sort, can deal with kwargs
121 | if key:
122 | iterable.sort(
123 | lambda a, b: 1 if key(a) > key(b) else -1
124 | ) # JavaScript sort, case '==' is irrelevant for sorting
125 | else:
126 | iterable.sort() # JavaScript sort
127 |
128 | if reverse:
129 | iterable.reverse()
130 |
131 |
132 | def sorted(iterable, key=None, reverse=False):
133 | if type(iterable) == dict:
134 | result = copy(iterable.keys())
135 | else:
136 | result = copy(iterable)
137 |
138 | __sort__(result, key, reverse)
139 | return result
140 |
141 |
142 | # __pragma__ ('nokwargs')
143 |
144 |
145 | def map(func, iterable):
146 | return [func(item) for item in iterable]
147 |
148 |
149 | def filter(func, iterable):
150 | if func == None:
151 | func = bool
152 | return [item for item in iterable if func(item)]
153 |
154 |
155 | def divmod(n, d):
156 | return n // d, n % d
157 |
158 |
159 | # __pragma__ ('ifdef', '__complex__')
160 |
161 |
162 | class complex:
163 | def __init__(self, real, imag=None):
164 | if imag == None:
165 | if type(real) == complex:
166 | self.real = real.real
167 | self.imag = real.imag
168 | else:
169 | self.real = real
170 | self.imag = 0
171 | else:
172 | self.real = real
173 | self.imag = imag
174 |
175 | def __neg__(self):
176 | return complex(-self.real, -self.imag)
177 |
178 | def __exp__(self):
179 | modulus = Math.exp(self.real)
180 | return complex(modulus * Math.cos(self.imag), modulus * Math.sin(self.imag))
181 |
182 | def __log__(self):
183 | return complex(
184 | Math.log(Math.sqrt(self.real * self.real + self.imag * self.imag)),
185 | Math.atan2(self.imag, self.real),
186 | )
187 |
188 | def __pow__(self, other): # a ** b = exp (b log a)
189 | return (self.__log__().__mul__(other)).__exp__()
190 |
191 | def __rpow__(self, real): # real ** comp -> comp.__rpow__ (real)
192 | return self.__mul__(Math.log(real)).__exp__()
193 |
194 | def __mul__(self, other):
195 | if __typeof__(other) is "number":
196 | return complex(self.real * other, self.imag * other)
197 | else:
198 | return complex(
199 | self.real * other.real - self.imag * other.imag,
200 | self.real * other.imag + self.imag * other.real,
201 | )
202 |
203 | def __rmul__(self, real): # real + comp -> comp.__rmul__ (real)
204 | return complex(self.real * real, self.imag * real)
205 |
206 | def __div__(self, other):
207 | if __typeof__(other) is "number":
208 | return complex(self.real / other, self.imag / other)
209 | else:
210 | denom = other.real * other.real + other.imag * other.imag
211 | return complex(
212 | (self.real * other.real + self.imag * other.imag) / denom,
213 | (self.imag * other.real - self.real * other.imag) / denom,
214 | )
215 |
216 | def __rdiv__(self, real): # real / comp -> comp.__rdiv__ (real)
217 | denom = self.real * self.real
218 | return complex((real * self.real) / denom, (real * self.imag) / denom)
219 |
220 | def __add__(self, other):
221 | if __typeof__(other) is "number":
222 | return complex(self.real + other, self.imag)
223 | else: # Assume other is complex
224 | return complex(self.real + other.real, self.imag + other.imag)
225 |
226 | def __radd__(self, real): # real + comp -> comp.__radd__ (real)
227 | return complex(self.real + real, self.imag)
228 |
229 | def __sub__(self, other):
230 | if __typeof__(other) is "number":
231 | return complex(self.real - other, self.imag)
232 | else:
233 | return complex(self.real - other.real, self.imag - other.imag)
234 |
235 | def __rsub__(self, real): # real - comp -> comp.__rsub__ (real)
236 | return complex(real - self.real, -self.imag)
237 |
238 | def __repr__(self):
239 | return "({}{}{}j)".format(self.real, "+" if self.imag >= 0 else "", self.imag)
240 |
241 | def __str__(self):
242 | return __repr__(self)[1:-1]
243 |
244 | def __eq__(self, other):
245 | if __typeof__(other) is "number":
246 | return self.real == other
247 | else:
248 | return self.real == other.real and self.imag == other.imag
249 |
250 | def __ne__(self, other):
251 | if __typeof__(other) is "number":
252 | return self.real != other
253 | else:
254 | return self.real != other.real or self.imag != other.imag
255 |
256 | def conjugate(self):
257 | return complex(self.real, -self.imag)
258 |
259 |
260 | def __conj__(aNumber):
261 | if isinstance(aNumber, complex):
262 | return complex(aNumber.real, -aNumber.imag)
263 | else:
264 | return complex(aNumber, 0)
265 |
266 |
267 | # __pragma__ ('endif')
268 |
269 |
270 | class __Terminal__:
271 | """
272 | Printing to either the console or to html happens async, but is blocked by calling window.prompt.
273 | So while all input and print statements are encountered in normal order, the print's exit immediately without yet having actually printed
274 | This means the next input takes control, blocking actual printing and so on indefinitely
275 | The effect is that everything's only printed after all inputs are done
276 | To prevent that, what's needed is to only execute the next window.prompt after actual printing has been done
277 | Since we've no way to find out when that is, a timeout is used.
278 | """
279 |
280 | def __init__(self):
281 | self.buffer = ""
282 |
283 | try:
284 | self.element = document.getElementById("__terminal__")
285 | except:
286 | self.element = None
287 |
288 | if self.element:
289 | self.element.style.overflowX = "auto"
290 | self.element.style.boxSizing = "border-box"
291 | self.element.style.padding = "5px"
292 | self.element.innerHTML = "_"
293 |
294 | # __pragma__ ('kwargs')
295 |
296 | def print(self, *args, sep=" ", end="\n"):
297 | self.buffer = "{}{}{}".format(self.buffer, sep.join([str(arg) for arg in args]), end)[
298 | -4096:
299 | ]
300 |
301 | if self.element:
302 | self.element.innerHTML = self.buffer.replace("\n", "
").replace(" ", " ")
303 | self.element.scrollTop = self.element.scrollHeight
304 | else:
305 | console.log(sep.join([str(arg) for arg in args]))
306 |
307 | def input(self, question):
308 | self.print("{}".format(question), end="")
309 | answer = window.prompt("\n".join(self.buffer.split("\n")[-8:]))
310 | self.print(answer)
311 | return answer
312 |
313 | # __pragma__ ('nokwargs')
314 |
315 |
316 | __terminal__ = __Terminal__()
317 |
318 | print = __terminal__.print
319 | input = __terminal__.input
320 |
--------------------------------------------------------------------------------
/panel_sketch/sketch_compiler/assets/js/transcrypt/pyp5js.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "file": "pyp5js.js",
4 | "sources": [
5 | "pyp5js.py"
6 | ],
7 | "mappings": "AAAA;AAAA;AAAA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAEA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAEA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAEA;AAAA;AAEA;AACA;AACA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAEA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAGA;AACA;AAEA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAEA;AAAA;AAIA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AACA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAGA;AAGA;AAQA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA;AAAA;AAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA;AAEA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AArsCA"
8 | }
--------------------------------------------------------------------------------
/panel_sketch/sketch_compiler/assets/js/transcrypt/pyp5js.python_functions.js:
--------------------------------------------------------------------------------
1 | // Transcrypt'ed from Python, 2021-04-11 14:24:48
2 | import {AssertionError, AttributeError, BaseException, DeprecationWarning, Exception, IndexError, IterableError, KeyError, NotImplementedError, RuntimeWarning, StopIteration, UserWarning, ValueError, Warning, __JsIterator__, __PyIterator__, __Terminal__, __add__, __and__, __call__, __class__, __envir__, __eq__, __floordiv__, __ge__, __get__, __getcm__, __getitem__, __getslice__, __getsm__, __gt__, __i__, __iadd__, __iand__, __idiv__, __ijsmod__, __ilshift__, __imatmul__, __imod__, __imul__, __in__, __init__, __ior__, __ipow__, __irshift__, __isub__, __ixor__, __jsUsePyNext__, __jsmod__, __k__, __kwargtrans__, __le__, __lshift__, __lt__, __matmul__, __mergefields__, __mergekwargtrans__, __mod__, __mul__, __ne__, __neg__, __nest__, __or__, __pow__, __pragma__, __proxy__, __pyUseJsNext__, __rshift__, __setitem__, __setproperty__, __setslice__, __sort__, __specialattrib__, __sub__, __super__, __t__, __terminal__, __truediv__, __withblock__, __xor__, abs, all, any, assert, bool, bytearray, bytes, callable, chr, copy, deepcopy, delattr, dict, dir, divmod, enumerate, filter, float, getattr, hasattr, input, int, isinstance, issubclass, len, list, map, max, min, object, ord, pow, print, property, py_TypeError, py_iter, py_metatype, py_next, py_reversed, py_typeof, range, repr, round, set, setattr, sorted, str, sum, tuple, zip} from './org.transcrypt.__runtime__.js';
3 | var __name__ = 'pyp5js.python_functions';
4 | export var PythonFunctions = __class__ ('PythonFunctions', [object], {
5 | __module__: __name__,
6 | });
7 | setattr (PythonFunctions, 'map', map);
8 | setattr (PythonFunctions, 'filter', filter);
9 | setattr (PythonFunctions, 'set', set);
10 |
11 | //# sourceMappingURL=pyp5js.python_functions.map
--------------------------------------------------------------------------------
/panel_sketch/sketch_compiler/assets/js/transcrypt/pyp5js.python_functions.map:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "file": "pyp5js.python_functions.js",
4 | "sources": [
5 | "pyp5js.python_functions.py"
6 | ],
7 | "mappings": "AAAA;AAIA;AAJA;AAAA;AAAA;AAAA;AAEA;AACA;AACA;AAAA"
8 | }
--------------------------------------------------------------------------------
/panel_sketch/sketch_compiler/assets/js/transcrypt/pyp5js.python_functions.py:
--------------------------------------------------------------------------------
1 | class PythonFunctions:
2 | pass
3 |
4 |
5 | setattr(PythonFunctions, "map", map)
6 | setattr(PythonFunctions, "filter", filter)
7 | setattr(PythonFunctions, "set", set)
8 |
--------------------------------------------------------------------------------
/panel_sketch/sketch_compiler/template_pyodide_basic.js:
--------------------------------------------------------------------------------
1 | console.log("pyodide basic")
2 | let userCode = `
3 | {{sketch_object}}
4 | `;
5 |
6 | function runCode() {
7 | let code = userCode
8 |
9 | if (window.instance) {
10 | window.instance.canvas.remove();
11 | }
12 |
13 | console.log("Python execution output:");
14 | pyodide.runPython(code);
15 | }
16 |
17 | languagePluginLoader.then(() => {
18 | pyodide.runPython(`
19 | import io, code, sys
20 | from js import pyodide, window, document
21 | print(sys.version)
22 | `)
23 |
24 | window.runSketchCode = (code) => {
25 | userCode = code;
26 | runCode();
27 | }
28 |
29 | runCode();
30 | });
--------------------------------------------------------------------------------
/panel_sketch/sketch_compiler/template_pyodide_pyp5js.js:
--------------------------------------------------------------------------------
1 | console.log("pyodide pyp5js")
2 | let wrapper_content = `
3 | class PythonFunctions: pass
4 |
5 | setattr(PythonFunctions, 'map', map)
6 | setattr(PythonFunctions, 'filter', filter)
7 | setattr(PythonFunctions, 'set', set)
8 |
9 |
10 | _P5_INSTANCE = None
11 |
12 | _CTX_MIDDLE = None
13 | _DEFAULT_FILL = None
14 | _DEFAULT_LEADMULT = None
15 | _DEFAULT_STROKE = None
16 | _DEFAULT_TEXT_FILL = None
17 |
18 | ADD = None
19 | ALT = None
20 | ARROW = None
21 | AUDIO = None
22 | AUTO = None
23 | AXES = None
24 | BACKSPACE = None
25 | BASELINE = None
26 | BEVEL = None
27 | BEZIER = None
28 | BLEND = None
29 | BLUR = None
30 | BOLD = None
31 | BOLDITALIC = None
32 | BOTTOM = None
33 | BURN = None
34 | CENTER = None
35 | CHORD = None
36 | CLAMP = None
37 | CLOSE = None
38 | CONTROL = None
39 | CORNER = None
40 | CORNERS = None
41 | CROSS = None
42 | CURVE = None
43 | DARKEST = None
44 | DEG_TO_RAD = None
45 | DEGREES = None
46 | DELETE = None
47 | DIFFERENCE = None
48 | DILATE = None
49 | DODGE = None
50 | DOWN_ARROW = None
51 | ENTER = None
52 | ERODE = None
53 | ESCAPE = None
54 | EXCLUSION = None
55 | FILL = None
56 | GRAY = None
57 | GRID = None
58 | HALF_PI = None
59 | HAND = None
60 | HARD_LIGHT = None
61 | HSB = None
62 | HSL = None
63 | IMAGE = None
64 | IMMEDIATE = None
65 | INVERT = None
66 | ITALIC = None
67 | LANDSCAPE = None
68 | LEFT = None
69 | LEFT_ARROW = None
70 | LIGHTEST = None
71 | LINE_LOOP = None
72 | LINE_STRIP = None
73 | LINEAR = None
74 | LINES = None
75 | MIRROR = None
76 | MITER = None
77 | MOVE = None
78 | MULTIPLY = None
79 | NEAREST = None
80 | NORMAL = None
81 | OPAQUE = None
82 | OPEN = None
83 | OPTION = None
84 | OVERLAY = None
85 | PI = None
86 | PIE = None
87 | POINTS = None
88 | PORTRAIT = None
89 | POSTERIZE = None
90 | PROJECT = None
91 | QUAD_STRIP = None
92 | QUADRATIC = None
93 | QUADS = None
94 | QUARTER_PI = None
95 | RAD_TO_DEG = None
96 | RADIANS = None
97 | RADIUS = None
98 | REPEAT = None
99 | REPLACE = None
100 | RETURN = None
101 | RGB = None
102 | RIGHT = None
103 | RIGHT_ARROW = None
104 | ROUND = None
105 | SCREEN = None
106 | SHIFT = None
107 | SOFT_LIGHT = None
108 | SQUARE = None
109 | STROKE = None
110 | SUBTRACT = None
111 | TAB = None
112 | TAU = None
113 | TEXT = None
114 | TEXTURE = None
115 | THRESHOLD = None
116 | TOP = None
117 | TRIANGLE_FAN = None
118 | TRIANGLE_STRIP = None
119 | TRIANGLES = None
120 | TWO_PI = None
121 | UP_ARROW = None
122 | VIDEO = None
123 | WAIT = None
124 | WEBGL = None
125 | P2D = None
126 | PI = None
127 |
128 | frameCount = None
129 | focused = None
130 | displayWidth = None
131 | displayHeight = None
132 | windowWidth = None
133 | windowHeight = None
134 | width = None
135 | height = None
136 | deviceOrientation = None
137 | accelerationX = None
138 | accelerationY = None
139 | accelerationZ = None
140 | pAccelerationX = None
141 | pAccelerationY = None
142 | pAccelerationZ = None
143 | rotationX = None
144 | rotationY = None
145 | rotationZ = None
146 | pRotationX = None
147 | pRotationY = None
148 | pRotationZ = None
149 | turnAxis = None
150 | keyIsPressed = None
151 | key = None
152 | keyCode = None
153 | mouseX = None
154 | mouseY = None
155 | pmouseX = None
156 | pmouseY = None
157 | winMouseX = None
158 | winMouseY = None
159 | pwinMouseX = None
160 | pwinMouseY = None
161 | mouseButton = None
162 | mouseIsPressed = None
163 | touches = None
164 | pixels = None
165 |
166 |
167 | def alpha(*args):
168 | return _P5_INSTANCE.alpha(*args)
169 |
170 | def blue(*args):
171 | return _P5_INSTANCE.blue(*args)
172 |
173 | def brightness(*args):
174 | return _P5_INSTANCE.brightness(*args)
175 |
176 | def color(*args):
177 | return _P5_INSTANCE.color(*args)
178 |
179 | def green(*args):
180 | return _P5_INSTANCE.green(*args)
181 |
182 | def hue(*args):
183 | return _P5_INSTANCE.hue(*args)
184 |
185 | def lerpColor(*args):
186 | return _P5_INSTANCE.lerpColor(*args)
187 |
188 | def lightness(*args):
189 | return _P5_INSTANCE.lightness(*args)
190 |
191 | def red(*args):
192 | return _P5_INSTANCE.red(*args)
193 |
194 | def saturation(*args):
195 | return _P5_INSTANCE.saturation(*args)
196 |
197 | def background(*args):
198 | return _P5_INSTANCE.background(*args)
199 |
200 | def clear(*args):
201 | p5_clear = _P5_INSTANCE.clear(*args)
202 | return p5_clear
203 |
204 | def erase(*args):
205 | return _P5_INSTANCE.erase(*args)
206 |
207 | def noErase(*args):
208 | return _P5_INSTANCE.noErase(*args)
209 |
210 | def colorMode(*args):
211 | return _P5_INSTANCE.colorMode(*args)
212 |
213 | def fill(*args):
214 | return _P5_INSTANCE.fill(*args)
215 |
216 | def noFill(*args):
217 | return _P5_INSTANCE.noFill(*args)
218 |
219 | def noStroke(*args):
220 | return _P5_INSTANCE.noStroke(*args)
221 |
222 | def stroke(*args):
223 | return _P5_INSTANCE.stroke(*args)
224 |
225 | def arc(*args):
226 | return _P5_INSTANCE.arc(*args)
227 |
228 | def ellipse(*args):
229 | return _P5_INSTANCE.ellipse(*args)
230 |
231 | def circle(*args):
232 | return _P5_INSTANCE.circle(*args)
233 |
234 | def line(*args):
235 | return _P5_INSTANCE.line(*args)
236 |
237 | def point(*args):
238 | return _P5_INSTANCE.point(*args)
239 |
240 | def quad(*args):
241 | return _P5_INSTANCE.quad(*args)
242 |
243 | def rect(*args):
244 | return _P5_INSTANCE.rect(*args)
245 |
246 | def square(*args):
247 | return _P5_INSTANCE.square(*args)
248 |
249 | def triangle(*args):
250 | return _P5_INSTANCE.triangle(*args)
251 |
252 | def plane(*args):
253 | return _P5_INSTANCE.plane(*args)
254 |
255 | def box(*args):
256 | return _P5_INSTANCE.box(*args)
257 |
258 | def sphere(*args):
259 | return _P5_INSTANCE.sphere(*args)
260 |
261 | def cylinder(*args):
262 | return _P5_INSTANCE.cylinder(*args)
263 |
264 | def cone(*args):
265 | return _P5_INSTANCE.cone(*args)
266 |
267 | def ellipsoid(*args):
268 | return _P5_INSTANCE.ellipsoid(*args)
269 |
270 | def torus(*args):
271 | return _P5_INSTANCE.torus(*args)
272 |
273 | def loadModel(*args):
274 | return _P5_INSTANCE.loadModel(*args)
275 |
276 | def model(*args):
277 | return _P5_INSTANCE.model(*args)
278 |
279 | def ellipseMode(*args):
280 | return _P5_INSTANCE.ellipseMode(*args)
281 |
282 | def noSmooth(*args):
283 | return _P5_INSTANCE.noSmooth(*args)
284 |
285 | def rectMode(*args):
286 | return _P5_INSTANCE.rectMode(*args)
287 |
288 | def smooth(*args):
289 | return _P5_INSTANCE.smooth(*args)
290 |
291 | def strokeCap(*args):
292 | return _P5_INSTANCE.strokeCap(*args)
293 |
294 | def strokeJoin(*args):
295 | return _P5_INSTANCE.strokeJoin(*args)
296 |
297 | def strokeWeight(*args):
298 | return _P5_INSTANCE.strokeWeight(*args)
299 |
300 | def bezier(*args):
301 | return _P5_INSTANCE.bezier(*args)
302 |
303 | def bezierDetail(*args):
304 | return _P5_INSTANCE.bezierDetail(*args)
305 |
306 | def bezierPoint(*args):
307 | return _P5_INSTANCE.bezierPoint(*args)
308 |
309 | def bezierTangent(*args):
310 | return _P5_INSTANCE.bezierTangent(*args)
311 |
312 | def curve(*args):
313 | return _P5_INSTANCE.curve(*args)
314 |
315 | def curveDetail(*args):
316 | return _P5_INSTANCE.curveDetail(*args)
317 |
318 | def curveTightness(*args):
319 | return _P5_INSTANCE.curveTightness(*args)
320 |
321 | def curvePoint(*args):
322 | return _P5_INSTANCE.curvePoint(*args)
323 |
324 | def curveTangent(*args):
325 | return _P5_INSTANCE.curveTangent(*args)
326 |
327 | def beginContour(*args):
328 | return _P5_INSTANCE.beginContour(*args)
329 |
330 | def beginShape(*args):
331 | return _P5_INSTANCE.beginShape(*args)
332 |
333 | def bezierVertex(*args):
334 | return _P5_INSTANCE.bezierVertex(*args)
335 |
336 | def curveVertex(*args):
337 | return _P5_INSTANCE.curveVertex(*args)
338 |
339 | def endContour(*args):
340 | return _P5_INSTANCE.endContour(*args)
341 |
342 | def endShape(*args):
343 | return _P5_INSTANCE.endShape(*args)
344 |
345 | def quadraticVertex(*args):
346 | return _P5_INSTANCE.quadraticVertex(*args)
347 |
348 | def vertex(*args):
349 | return _P5_INSTANCE.vertex(*args)
350 |
351 | def cursor(*args):
352 | return _P5_INSTANCE.cursor(*args)
353 |
354 | def frameRate(*args):
355 | return _P5_INSTANCE.frameRate(*args)
356 |
357 | def noCursor(*args):
358 | return _P5_INSTANCE.noCursor(*args)
359 |
360 | def fullscreen(*args):
361 | return _P5_INSTANCE.fullscreen(*args)
362 |
363 | def pixelDensity(*args):
364 | return _P5_INSTANCE.pixelDensity(*args)
365 |
366 | def displayDensity(*args):
367 | return _P5_INSTANCE.displayDensity(*args)
368 |
369 | def getURL(*args):
370 | return _P5_INSTANCE.getURL(*args)
371 |
372 | def getURLPath(*args):
373 | return _P5_INSTANCE.getURLPath(*args)
374 |
375 | def getURLParams(*args):
376 | return _P5_INSTANCE.getURLParams(*args)
377 |
378 | def preload(*args):
379 | return _P5_INSTANCE.preload(*args)
380 |
381 | def remove(*args):
382 | return _P5_INSTANCE.remove(*args)
383 |
384 | def noLoop(*args):
385 | return _P5_INSTANCE.noLoop(*args)
386 |
387 | def loop(*args):
388 | return _P5_INSTANCE.loop(*args)
389 |
390 | def push(*args):
391 | return _P5_INSTANCE.push(*args)
392 |
393 | def redraw(*args):
394 | return _P5_INSTANCE.redraw(*args)
395 |
396 | def resizeCanvas(*args):
397 | return _P5_INSTANCE.resizeCanvas(*args)
398 |
399 | def noCanvas(*args):
400 | return _P5_INSTANCE.noCanvas(*args)
401 |
402 | def createGraphics(*args):
403 | return _P5_INSTANCE.createGraphics(*args)
404 |
405 | def blendMode(*args):
406 | return _P5_INSTANCE.blendMode(*args)
407 |
408 | def setAttributes(*args):
409 | return _P5_INSTANCE.setAttributes(*args)
410 |
411 | def applyMatrix(*args):
412 | return _P5_INSTANCE.applyMatrix(*args)
413 |
414 | def resetMatrix(*args):
415 | return _P5_INSTANCE.resetMatrix(*args)
416 |
417 | def rotate(*args):
418 | return _P5_INSTANCE.rotate(*args)
419 |
420 | def rotateX(*args):
421 | return _P5_INSTANCE.rotateX(*args)
422 |
423 | def rotateY(*args):
424 | return _P5_INSTANCE.rotateY(*args)
425 |
426 | def rotateZ(*args):
427 | return _P5_INSTANCE.rotateZ(*args)
428 |
429 | def scale(*args):
430 | return _P5_INSTANCE.scale(*args)
431 |
432 | def shearX(*args):
433 | return _P5_INSTANCE.shearX(*args)
434 |
435 | def shearY(*args):
436 | return _P5_INSTANCE.shearY(*args)
437 |
438 | def translate(*args):
439 | return _P5_INSTANCE.translate(*args)
440 |
441 | def createStringDict(*args):
442 | return _P5_INSTANCE.createStringDict(*args)
443 |
444 | def createNumberDict(*args):
445 | return _P5_INSTANCE.createNumberDict(*args)
446 |
447 | def append(*args):
448 | return _P5_INSTANCE.append(*args)
449 |
450 | def arrayCopy(*args):
451 | return _P5_INSTANCE.arrayCopy(*args)
452 |
453 | def concat(*args):
454 | return _P5_INSTANCE.concat(*args)
455 |
456 | def reverse(*args):
457 | return _P5_INSTANCE.reverse(*args)
458 |
459 | def shorten(*args):
460 | return _P5_INSTANCE.shorten(*args)
461 |
462 | def shuffle(*args):
463 | return _P5_INSTANCE.shuffle(*args)
464 |
465 | def sort(*args):
466 | return _P5_INSTANCE.sort(*args)
467 |
468 | def splice(*args):
469 | return _P5_INSTANCE.splice(*args)
470 |
471 | def subset(*args):
472 | return _P5_INSTANCE.subset(*args)
473 |
474 | def float(*args):
475 | return _P5_INSTANCE.float(*args)
476 |
477 | def int(*args):
478 | return _P5_INSTANCE.int(*args)
479 |
480 | def str(*args):
481 | return _P5_INSTANCE.str(*args)
482 |
483 | def boolean(*args):
484 | return _P5_INSTANCE.boolean(*args)
485 |
486 | def byte(*args):
487 | return _P5_INSTANCE.byte(*args)
488 |
489 | def char(*args):
490 | return _P5_INSTANCE.char(*args)
491 |
492 | def unchar(*args):
493 | return _P5_INSTANCE.unchar(*args)
494 |
495 | def hex(*args):
496 | return _P5_INSTANCE.hex(*args)
497 |
498 | def unhex(*args):
499 | return _P5_INSTANCE.unhex(*args)
500 |
501 | def join(*args):
502 | return _P5_INSTANCE.join(*args)
503 |
504 | def match(*args):
505 | return _P5_INSTANCE.match(*args)
506 |
507 | def matchAll(*args):
508 | return _P5_INSTANCE.matchAll(*args)
509 |
510 | def nf(*args):
511 | return _P5_INSTANCE.nf(*args)
512 |
513 | def nfc(*args):
514 | return _P5_INSTANCE.nfc(*args)
515 |
516 | def nfp(*args):
517 | return _P5_INSTANCE.nfp(*args)
518 |
519 | def nfs(*args):
520 | return _P5_INSTANCE.nfs(*args)
521 |
522 | def split(*args):
523 | return _P5_INSTANCE.split(*args)
524 |
525 | def splitTokens(*args):
526 | return _P5_INSTANCE.splitTokens(*args)
527 |
528 | def trim(*args):
529 | return _P5_INSTANCE.trim(*args)
530 |
531 | def setMoveThreshold(*args):
532 | return _P5_INSTANCE.setMoveThreshold(*args)
533 |
534 | def setShakeThreshold(*args):
535 | return _P5_INSTANCE.setShakeThreshold(*args)
536 |
537 | def keyIsDown(*args):
538 | return _P5_INSTANCE.keyIsDown(*args)
539 |
540 | def createImage(*args):
541 | return _P5_INSTANCE.createImage(*args)
542 |
543 | def saveCanvas(*args):
544 | return _P5_INSTANCE.saveCanvas(*args)
545 |
546 | def saveFrames(*args):
547 | return _P5_INSTANCE.saveFrames(*args)
548 |
549 | def loadImage(*args):
550 | return _P5_INSTANCE.loadImage(*args)
551 |
552 | def image(*args):
553 | return _P5_INSTANCE.image(*args)
554 |
555 | def tint(*args):
556 | return _P5_INSTANCE.tint(*args)
557 |
558 | def noTint(*args):
559 | return _P5_INSTANCE.noTint(*args)
560 |
561 | def imageMode(*args):
562 | return _P5_INSTANCE.imageMode(*args)
563 |
564 | def blend(*args):
565 | return _P5_INSTANCE.blend(*args)
566 |
567 | def copy(*args):
568 | return _P5_INSTANCE.copy(*args)
569 |
570 | def filter(*args):
571 | if len(args) > 1 and (args[0] is None or callable(args[0])):
572 | return PythonFunctions.filter(*args)
573 | else:
574 | return _P5_INSTANCE.filter(*args)
575 |
576 | def get(*args):
577 | return _P5_INSTANCE.get(*args)
578 |
579 | def loadPixels(*args):
580 | return _P5_INSTANCE.loadPixels(*args)
581 |
582 | def set(*args):
583 | if len(args) <= 1:
584 | return PythonFunctions.set(*args)
585 | else:
586 | return _P5_INSTANCE.set(*args)
587 |
588 | def updatePixels(*args):
589 | return _P5_INSTANCE.updatePixels(*args)
590 |
591 | def loadJSON(*args):
592 | return _P5_INSTANCE.loadJSON(*args)
593 |
594 | def loadStrings(*args):
595 | return _P5_INSTANCE.loadStrings(*args)
596 |
597 | def loadTable(*args):
598 | return _P5_INSTANCE.loadTable(*args)
599 |
600 | def loadXML(*args):
601 | return _P5_INSTANCE.loadXML(*args)
602 |
603 | def loadBytes(*args):
604 | return _P5_INSTANCE.loadBytes(*args)
605 |
606 | def httpGet(*args):
607 | return _P5_INSTANCE.httpGet(*args)
608 |
609 | def httpPost(*args):
610 | return _P5_INSTANCE.httpPost(*args)
611 |
612 | def httpDo(*args):
613 | return _P5_INSTANCE.httpDo(*args)
614 |
615 | def createWriter(*args):
616 | return _P5_INSTANCE.createWriter(*args)
617 |
618 | def save(*args):
619 | return _P5_INSTANCE.save(*args)
620 |
621 | def saveJSON(*args):
622 | return _P5_INSTANCE.saveJSON(*args)
623 |
624 | def saveStrings(*args):
625 | return _P5_INSTANCE.saveStrings(*args)
626 |
627 | def saveTable(*args):
628 | return _P5_INSTANCE.saveTable(*args)
629 |
630 | def day(*args):
631 | return _P5_INSTANCE.day(*args)
632 |
633 | def hour(*args):
634 | return _P5_INSTANCE.hour(*args)
635 |
636 | def minute(*args):
637 | return _P5_INSTANCE.minute(*args)
638 |
639 | def millis(*args):
640 | return _P5_INSTANCE.millis(*args)
641 |
642 | def month(*args):
643 | return _P5_INSTANCE.month(*args)
644 |
645 | def second(*args):
646 | return _P5_INSTANCE.second(*args)
647 |
648 | def year(*args):
649 | return _P5_INSTANCE.year(*args)
650 |
651 | def createVector(*args):
652 | return _P5_INSTANCE.createVector(*args)
653 |
654 | def abs(*args):
655 | return _P5_INSTANCE.abs(*args)
656 |
657 | def ceil(*args):
658 | return _P5_INSTANCE.ceil(*args)
659 |
660 | def constrain(*args):
661 | return _P5_INSTANCE.constrain(*args)
662 |
663 | def dist(*args):
664 | return _P5_INSTANCE.dist(*args)
665 |
666 | def exp(*args):
667 | return _P5_INSTANCE.exp(*args)
668 |
669 | def floor(*args):
670 | return _P5_INSTANCE.floor(*args)
671 |
672 | def lerp(*args):
673 | return _P5_INSTANCE.lerp(*args)
674 |
675 | def log(*args):
676 | return _P5_INSTANCE.log(*args)
677 |
678 | def mag(*args):
679 | return _P5_INSTANCE.mag(*args)
680 |
681 | def map(*args):
682 | if len(args) > 1 and callable(args[0]):
683 | return PythonFunctions.map(*args)
684 | else:
685 | return _P5_INSTANCE.map(*args)
686 |
687 | def max(*args):
688 | return _P5_INSTANCE.max(*args)
689 |
690 | def min(*args):
691 | return _P5_INSTANCE.min(*args)
692 |
693 | def norm(*args):
694 | return _P5_INSTANCE.norm(*args)
695 |
696 | def pow(*args):
697 | return _P5_INSTANCE.pow(*args)
698 |
699 | def round(*args):
700 | return _P5_INSTANCE.round(*args)
701 |
702 | def sq(*args):
703 | return _P5_INSTANCE.sq(*args)
704 |
705 | def sqrt(*args):
706 | return _P5_INSTANCE.sqrt(*args)
707 |
708 | def noise(*args):
709 | return _P5_INSTANCE.noise(*args)
710 |
711 | def noiseDetail(*args):
712 | return _P5_INSTANCE.noiseDetail(*args)
713 |
714 | def noiseSeed(*args):
715 | return _P5_INSTANCE.noiseSeed(*args)
716 |
717 | def randomSeed(*args):
718 | return _P5_INSTANCE.randomSeed(*args)
719 |
720 | def random(*args):
721 | return _P5_INSTANCE.random(*args)
722 |
723 | def randomGaussian(*args):
724 | return _P5_INSTANCE.randomGaussian(*args)
725 |
726 | def acos(*args):
727 | return _P5_INSTANCE.acos(*args)
728 |
729 | def asin(*args):
730 | return _P5_INSTANCE.asin(*args)
731 |
732 | def atan(*args):
733 | return _P5_INSTANCE.atan(*args)
734 |
735 | def atan2(*args):
736 | return _P5_INSTANCE.atan2(*args)
737 |
738 | def cos(*args):
739 | return _P5_INSTANCE.cos(*args)
740 |
741 | def sin(*args):
742 | return _P5_INSTANCE.sin(*args)
743 |
744 | def tan(*args):
745 | return _P5_INSTANCE.tan(*args)
746 |
747 | def degrees(*args):
748 | return _P5_INSTANCE.degrees(*args)
749 |
750 | def radians(*args):
751 | return _P5_INSTANCE.radians(*args)
752 |
753 | def angleMode(*args):
754 | return _P5_INSTANCE.angleMode(*args)
755 |
756 | def textAlign(*args):
757 | return _P5_INSTANCE.textAlign(*args)
758 |
759 | def textLeading(*args):
760 | return _P5_INSTANCE.textLeading(*args)
761 |
762 | def textSize(*args):
763 | return _P5_INSTANCE.textSize(*args)
764 |
765 | def textStyle(*args):
766 | return _P5_INSTANCE.textStyle(*args)
767 |
768 | def textWidth(*args):
769 | return _P5_INSTANCE.textWidth(*args)
770 |
771 | def textAscent(*args):
772 | return _P5_INSTANCE.textAscent(*args)
773 |
774 | def textDescent(*args):
775 | return _P5_INSTANCE.textDescent(*args)
776 |
777 | def loadFont(*args):
778 | return _P5_INSTANCE.loadFont(*args)
779 |
780 | def text(*args):
781 | return _P5_INSTANCE.text(*args)
782 |
783 | def textFont(*args):
784 | return _P5_INSTANCE.textFont(*args)
785 |
786 | def orbitControl(*args):
787 | return _P5_INSTANCE.orbitControl(*args)
788 |
789 | def debugMode(*args):
790 | return _P5_INSTANCE.debugMode(*args)
791 |
792 | def noDebugMode(*args):
793 | return _P5_INSTANCE.noDebugMode(*args)
794 |
795 | def ambientLight(*args):
796 | return _P5_INSTANCE.ambientLight(*args)
797 |
798 | def directionalLight(*args):
799 | return _P5_INSTANCE.directionalLight(*args)
800 |
801 | def pointLight(*args):
802 | return _P5_INSTANCE.pointLight(*args)
803 |
804 | def lights(*args):
805 | return _P5_INSTANCE.lights(*args)
806 |
807 | def loadShader(*args):
808 | return _P5_INSTANCE.loadShader(*args)
809 |
810 | def createShader(*args):
811 | return _P5_INSTANCE.createShader(*args)
812 |
813 | def shader(*args):
814 | return _P5_INSTANCE.shader(*args)
815 |
816 | def resetShader(*args):
817 | return _P5_INSTANCE.resetShader(*args)
818 |
819 | def normalMaterial(*args):
820 | return _P5_INSTANCE.normalMaterial(*args)
821 |
822 | def texture(*args):
823 | return _P5_INSTANCE.texture(*args)
824 |
825 | def textureMode(*args):
826 | return _P5_INSTANCE.textureMode(*args)
827 |
828 | def textureWrap(*args):
829 | return _P5_INSTANCE.textureWrap(*args)
830 |
831 | def ambientMaterial(*args):
832 | return _P5_INSTANCE.ambientMaterial(*args)
833 |
834 | def specularMaterial(*args):
835 | return _P5_INSTANCE.specularMaterial(*args)
836 |
837 | def shininess(*args):
838 | return _P5_INSTANCE.shininess(*args)
839 |
840 | def camera(*args):
841 | return _P5_INSTANCE.camera(*args)
842 |
843 | def perspective(*args):
844 | return _P5_INSTANCE.perspective(*args)
845 |
846 | def ortho(*args):
847 | return _P5_INSTANCE.ortho(*args)
848 |
849 | def createCamera(*args):
850 | return _P5_INSTANCE.createCamera(*args)
851 |
852 | def setCamera(*args):
853 | return _P5_INSTANCE.setCamera(*args)
854 |
855 | def select(*args):
856 | return _P5_INSTANCE.select(*args)
857 |
858 | def selectAll(*args):
859 | return _P5_INSTANCE.selectAll(*args)
860 |
861 | def removeElements(*args):
862 | return _P5_INSTANCE.removeElements(*args)
863 |
864 | def changed(*args):
865 | return _P5_INSTANCE.changed(*args)
866 |
867 | def input(*args):
868 | return _P5_INSTANCE.input(*args)
869 |
870 | def createDiv(*args):
871 | return _P5_INSTANCE.createDiv(*args)
872 |
873 | def createP(*args):
874 | return _P5_INSTANCE.createP(*args)
875 |
876 | def createSpan(*args):
877 | return _P5_INSTANCE.createSpan(*args)
878 |
879 | def createImg(*args):
880 | return _P5_INSTANCE.createImg(*args)
881 |
882 | def createA(*args):
883 | return _P5_INSTANCE.createA(*args)
884 |
885 | def createSlider(*args):
886 | return _P5_INSTANCE.createSlider(*args)
887 |
888 | def createButton(*args):
889 | return _P5_INSTANCE.createButton(*args)
890 |
891 | def createCheckbox(*args):
892 | return _P5_INSTANCE.createCheckbox(*args)
893 |
894 | def createSelect(*args):
895 | return _P5_INSTANCE.createSelect(*args)
896 |
897 | def createRadio(*args):
898 | return _P5_INSTANCE.createRadio(*args)
899 |
900 | def createColorPicker(*args):
901 | return _P5_INSTANCE.createColorPicker(*args)
902 |
903 | def createInput(*args):
904 | return _P5_INSTANCE.createInput(*args)
905 |
906 | def createFileInput(*args):
907 | return _P5_INSTANCE.createFileInput(*args)
908 |
909 | def createVideo(*args):
910 | return _P5_INSTANCE.createVideo(*args)
911 |
912 | def createAudio(*args):
913 | return _P5_INSTANCE.createAudio(*args)
914 |
915 | def createCapture(*args):
916 | return _P5_INSTANCE.createCapture(*args)
917 |
918 | def createElement(*args):
919 | return _P5_INSTANCE.createElement(*args)
920 |
921 | def createCanvas(*args):
922 | canvas = _P5_INSTANCE.createCanvas(*args)
923 |
924 | global width, height
925 | width = _P5_INSTANCE.width
926 | height = _P5_INSTANCE.height
927 |
928 | return canvas
929 |
930 |
931 | def pop(*args):
932 | p5_pop = _P5_INSTANCE.pop(*args)
933 | return p5_pop
934 |
935 |
936 | # Processing Python or Java mode compatibility aliases
937 | size = createCanvas
938 | popMatrix = pop
939 | popStyle = pop
940 | pushMatrix = push
941 | pushStyle = push
942 |
943 | def pre_draw(p5_instance, draw_func):
944 | """
945 | We need to run this before the actual draw to insert and update p5 env variables
946 | """
947 | global _CTX_MIDDLE, _DEFAULT_FILL, _DEFAULT_LEADMULT, _DEFAULT_STROKE, _DEFAULT_TEXT_FILL
948 |
949 | global ADD, ALT, ARROW, AUTO, AUDIO, AXES, BACKSPACE, BASELINE, BEVEL, BEZIER, BLEND, BLUR, BOLD, BOLDITALIC
950 | global BOTTOM, BURN, CENTER, CHORD, CLAMP, CLOSE, CONTROL, CORNER, CORNERS, CROSS, CURVE, DARKEST
951 | global DEG_TO_RAD, DEGREES, DELETE, DIFFERENCE, DILATE, DODGE, DOWN_ARROW, ENTER, ERODE, ESCAPE, EXCLUSION
952 | global FILL, GRAY, GRID, HALF_PI, HAND, HARD_LIGHT, HSB, HSL, IMAGE, IMMEDIATE, INVERT, ITALIC, LANDSCAPE
953 | global LEFT, LEFT_ARROW, LIGHTEST, LINE_LOOP, LINE_STRIP, LINEAR, LINES, MIRROR, MITER, MOVE, MULTIPLY, NEAREST
954 | global NORMAL, OPAQUE, OPEN, OPTION, OVERLAY, P2D, PI, PIE, POINTS, PORTRAIT, POSTERIZE, PROJECT, QUAD_STRIP, QUADRATIC
955 | global QUADS, QUARTER_PI, RAD_TO_DEG, RADIANS, RADIUS, REPEAT, REPLACE, RETURN, RGB, RIGHT, RIGHT_ARROW
956 | global ROUND, SCREEN, SHIFT, SOFT_LIGHT, SQUARE, STROKE, SUBTRACT, TAB, TAU, TEXT, TEXTURE, THRESHOLD, TOP
957 | global TRIANGLE_FAN, TRIANGLE_STRIP, TRIANGLES, TWO_PI, UP_ARROW, VIDEO, WAIT, WEBGL
958 |
959 | global frameCount, focused, displayWidth, displayHeight, windowWidth, windowHeight, width, height
960 | global deviceOrientation, accelerationX, accelerationY, accelerationZ
961 | global pAccelerationX, pAccelerationY, pAccelerationZ, rotationX, rotationY, rotationZ
962 | global pRotationX, pRotationY, pRotationZ, turnAxis, keyIsPressed, key, keyCode, mouseX, mouseY, pmouseX, pmouseY
963 | global winMouseX, winMouseY, pwinMouseX, pwinMouseY, mouseButton, mouseIsPressed, touches, pixels
964 |
965 | _CTX_MIDDLE = p5_instance._CTX_MIDDLE
966 | _DEFAULT_FILL = p5_instance._DEFAULT_FILL
967 | _DEFAULT_LEADMULT = p5_instance._DEFAULT_LEADMULT
968 | _DEFAULT_STROKE = p5_instance._DEFAULT_STROKE
969 | _DEFAULT_TEXT_FILL = p5_instance._DEFAULT_TEXT_FILL
970 |
971 | ADD = p5_instance.ADD
972 | ALT = p5_instance.ALT
973 | ARROW = p5_instance.ARROW
974 | AUDIO = p5_instance.AUDIO
975 | AUTO = p5_instance.AUTO
976 | AXES = p5_instance.AXES
977 | BACKSPACE = p5_instance.BACKSPACE
978 | BASELINE = p5_instance.BASELINE
979 | BEVEL = p5_instance.BEVEL
980 | BEZIER = p5_instance.BEZIER
981 | BLEND = p5_instance.BLEND
982 | BLUR = p5_instance.BLUR
983 | BOLD = p5_instance.BOLD
984 | BOLDITALIC = p5_instance.BOLDITALIC
985 | BOTTOM = p5_instance.BOTTOM
986 | BURN = p5_instance.BURN
987 | CENTER = p5_instance.CENTER
988 | CHORD = p5_instance.CHORD
989 | CLAMP = p5_instance.CLAMP
990 | CLOSE = p5_instance.CLOSE
991 | CONTROL = p5_instance.CONTROL
992 | CORNER = p5_instance.CORNER
993 | CORNERS = p5_instance.CORNERS
994 | CROSS = p5_instance.CROSS
995 | CURVE = p5_instance.CURVE
996 | DARKEST = p5_instance.DARKEST
997 | DEG_TO_RAD = p5_instance.DEG_TO_RAD
998 | DEGREES = p5_instance.DEGREES
999 | DELETE = p5_instance.DELETE
1000 | DIFFERENCE = p5_instance.DIFFERENCE
1001 | DILATE = p5_instance.DILATE
1002 | DODGE = p5_instance.DODGE
1003 | DOWN_ARROW = p5_instance.DOWN_ARROW
1004 | ENTER = p5_instance.ENTER
1005 | ERODE = p5_instance.ERODE
1006 | ESCAPE = p5_instance.ESCAPE
1007 | EXCLUSION = p5_instance.EXCLUSION
1008 | FILL = p5_instance.FILL
1009 | GRAY = p5_instance.GRAY
1010 | GRID = p5_instance.GRID
1011 | HALF_PI = p5_instance.HALF_PI
1012 | HAND = p5_instance.HAND
1013 | HARD_LIGHT = p5_instance.HARD_LIGHT
1014 | HSB = p5_instance.HSB
1015 | HSL = p5_instance.HSL
1016 | IMAGE = p5_instance.IMAGE
1017 | IMMEDIATE = p5_instance.IMMEDIATE
1018 | INVERT = p5_instance.INVERT
1019 | ITALIC = p5_instance.ITALIC
1020 | LANDSCAPE = p5_instance.LANDSCAPE
1021 | LEFT = p5_instance.LEFT
1022 | LEFT_ARROW = p5_instance.LEFT_ARROW
1023 | LIGHTEST = p5_instance.LIGHTEST
1024 | LINE_LOOP = p5_instance.LINE_LOOP
1025 | LINE_STRIP = p5_instance.LINE_STRIP
1026 | LINEAR = p5_instance.LINEAR
1027 | LINES = p5_instance.LINES
1028 | MIRROR = p5_instance.MIRROR
1029 | MITER = p5_instance.MITER
1030 | MOVE = p5_instance.MOVE
1031 | MULTIPLY = p5_instance.MULTIPLY
1032 | NEAREST = p5_instance.NEAREST
1033 | NORMAL = p5_instance.NORMAL
1034 | OPAQUE = p5_instance.OPAQUE
1035 | OPEN = p5_instance.OPEN
1036 | OPTION = p5_instance.OPTION
1037 | OVERLAY = p5_instance.OVERLAY
1038 | P2D = p5_instance.P2D
1039 | P3D = p5_instance.WEBGL
1040 | PI = p5_instance.PI
1041 | PIE = p5_instance.PIE
1042 | POINTS = p5_instance.POINTS
1043 | PORTRAIT = p5_instance.PORTRAIT
1044 | POSTERIZE = p5_instance.POSTERIZE
1045 | PROJECT = p5_instance.PROJECT
1046 | QUAD_STRIP = p5_instance.QUAD_STRIP
1047 | QUADRATIC = p5_instance.QUADRATIC
1048 | QUADS = p5_instance.QUADS
1049 | QUARTER_PI = p5_instance.QUARTER_PI
1050 | RAD_TO_DEG = p5_instance.RAD_TO_DEG
1051 | RADIANS = p5_instance.RADIANS
1052 | RADIUS = p5_instance.RADIUS
1053 | REPEAT = p5_instance.REPEAT
1054 | REPLACE = p5_instance.REPLACE
1055 | RETURN = p5_instance.RETURN
1056 | RGB = p5_instance.RGB
1057 | RIGHT = p5_instance.RIGHT
1058 | RIGHT_ARROW = p5_instance.RIGHT_ARROW
1059 | ROUND = p5_instance.ROUND
1060 | SCREEN = p5_instance.SCREEN
1061 | SHIFT = p5_instance.SHIFT
1062 | SOFT_LIGHT = p5_instance.SOFT_LIGHT
1063 | SQUARE = p5_instance.SQUARE
1064 | STROKE = p5_instance.STROKE
1065 | SUBTRACT = p5_instance.SUBTRACT
1066 | TAB = p5_instance.TAB
1067 | TAU = p5_instance.TAU
1068 | TEXT = p5_instance.TEXT
1069 | TEXTURE = p5_instance.TEXTURE
1070 | THRESHOLD = p5_instance.THRESHOLD
1071 | TOP = p5_instance.TOP
1072 | TRIANGLE_FAN = p5_instance.TRIANGLE_FAN
1073 | TRIANGLE_STRIP = p5_instance.TRIANGLE_STRIP
1074 | TRIANGLES = p5_instance.TRIANGLES
1075 | TWO_PI = p5_instance.TWO_PI
1076 | UP_ARROW = p5_instance.UP_ARROW
1077 | VIDEO = p5_instance.VIDEO
1078 | WAIT = p5_instance.WAIT
1079 | WEBGL = p5_instance.WEBGL
1080 |
1081 | frameCount = p5_instance.frameCount
1082 | focused = p5_instance.focused
1083 | displayWidth = p5_instance.displayWidth
1084 | displayHeight = p5_instance.displayHeight
1085 | windowWidth = p5_instance.windowWidth
1086 | windowHeight = p5_instance.windowHeight
1087 | width = p5_instance.width
1088 | height = p5_instance.height
1089 | deviceOrientation = p5_instance.deviceOrientation
1090 | accelerationX = p5_instance.accelerationX
1091 | accelerationY = p5_instance.accelerationY
1092 | accelerationZ = p5_instance.accelerationZ
1093 | pAccelerationX = p5_instance.pAccelerationX
1094 | pAccelerationY = p5_instance.pAccelerationY
1095 | pAccelerationZ = p5_instance.pAccelerationZ
1096 | rotationX = p5_instance.rotationX
1097 | rotationY = p5_instance.rotationY
1098 | rotationZ = p5_instance.rotationZ
1099 | pRotationX = p5_instance.pRotationX
1100 | pRotationY = p5_instance.pRotationY
1101 | pRotationZ = p5_instance.pRotationZ
1102 | turnAxis = p5_instance.turnAxis
1103 | keyIsPressed = p5_instance.keyIsPressed
1104 | key = p5_instance.key
1105 | keyCode = p5_instance.keyCode
1106 | mouseX = p5_instance.mouseX
1107 | mouseY = p5_instance.mouseY
1108 | pmouseX = p5_instance.pmouseX
1109 | pmouseY = p5_instance.pmouseY
1110 | winMouseX = p5_instance.winMouseX
1111 | winMouseY = p5_instance.winMouseY
1112 | pwinMouseX = p5_instance.pwinMouseX
1113 | pwinMouseY = p5_instance.pwinMouseY
1114 | mouseButton = p5_instance.mouseButton
1115 | mouseIsPressed = p5_instance.mouseIsPressed
1116 | touches = p5_instance.touches
1117 | pixels = p5_instance.pixels
1118 |
1119 | return draw_func()
1120 |
1121 |
1122 | def global_p5_injection(p5_sketch):
1123 | """
1124 | Injects the p5js's skecth instance as a global variable to setup and draw functions
1125 | """
1126 |
1127 | def decorator(f):
1128 | def wrapper():
1129 | global _P5_INSTANCE
1130 | _P5_INSTANCE = p5_sketch
1131 | return pre_draw(_P5_INSTANCE, f)
1132 |
1133 |
1134 | return wrapper
1135 |
1136 |
1137 | return decorator
1138 |
1139 |
1140 | def start_p5(setup_func, draw_func, event_functions):
1141 | """
1142 | This is the entrypoint function. It accepts 2 parameters:
1143 |
1144 | - setup_func: a Python setup callable
1145 | - draw_func: a Python draw callable
1146 | - event_functions: a config dict for the event functions in the format:
1147 | {"eventFunctionName": python_event_function}
1148 |
1149 | This method gets the p5js's sketch instance and injects them
1150 | """
1151 |
1152 | def sketch_setup(p5_sketch):
1153 | """
1154 | Callback function called to configure new p5 instance
1155 | """
1156 | p5_sketch.setup = global_p5_injection(p5_sketch)(setup_func)
1157 | p5_sketch.draw = global_p5_injection(p5_sketch)(draw_func)
1158 |
1159 |
1160 | window.instance = p5.new(sketch_setup, 'sketch-element')
1161 |
1162 | # inject event functions into p5
1163 | event_function_names = (
1164 | "deviceMoved", "deviceTurned", "deviceShaken", "windowResized",
1165 | "keyPressed", "keyReleased", "keyTyped",
1166 | "mousePressed", "mouseReleased", "mouseClicked", "doubleClicked",
1167 | "mouseMoved", "mouseDragged", "mouseWheel",
1168 | "touchStarted", "touchMoved", "touchEnded"
1169 | )
1170 |
1171 | for f_name in [f for f in event_function_names if event_functions.get(f, None)]:
1172 | func = event_functions[f_name]
1173 | event_func = global_p5_injection(instance)(func)
1174 | setattr(instance, f_name, event_func)
1175 | `;
1176 |
1177 | let placeholder = `
1178 | def setup():
1179 | pass
1180 |
1181 | def draw():
1182 | pass
1183 | `;
1184 |
1185 | let userCode = `
1186 | {{sketch_object}}
1187 | `;
1188 |
1189 | function runCode() {
1190 | let code = [
1191 | placeholder,
1192 | userCode,
1193 | wrapper_content,
1194 | 'start_p5(setup, draw, {});',
1195 | ].join('\n');
1196 |
1197 | if (window.instance) {
1198 | window.instance.canvas.remove();
1199 | }
1200 |
1201 | console.log("Python execution output:");
1202 | pyodide.runPython(code);
1203 | }
1204 |
1205 | languagePluginLoader.then(() => {
1206 | pyodide.runPython(`
1207 | import io, code, sys
1208 | from js import pyodide, p5, window, document
1209 | print(sys.version)
1210 | `)
1211 |
1212 | window.runSketchCode = (code) => {
1213 | userCode = code;
1214 | runCode();
1215 | }
1216 |
1217 | runCode();
1218 | });
--------------------------------------------------------------------------------
/panel_sketch/sketch_compiler/template_transcrypt_basic.py:
--------------------------------------------------------------------------------
1 | {{sketch_object}}
--------------------------------------------------------------------------------
/panel_sketch/sketch_compiler/template_transcrypt_pyp5js.py:
--------------------------------------------------------------------------------
1 | from pyp5js import *
2 |
3 | {{sketch_object}}
4 |
5 | event_functions = {}
6 | try:
7 | event_functions["deviceMoved"]= deviceMoved
8 | except:
9 | pass
10 | try:
11 | event_functions["deviceTurned"]= deviceTurned
12 | except:
13 | pass
14 | try:
15 | event_functions["deviceShaken"]= deviceShaken
16 | except:
17 | pass
18 | try:
19 | event_functions["keyPressed"]= keyPressed
20 | except:
21 | pass
22 | try:
23 | event_functions["keyReleased"]= keyReleased
24 | except:
25 | pass
26 | try:
27 | event_functions["keyTyped"]= keyTyped
28 | except:
29 | pass
30 | try:
31 | event_functions["mouseMoved"]= mouseMoved
32 | except:
33 | pass
34 | try:
35 | event_functions["mouseDragged"]= mouseDragged
36 | except:
37 | pass
38 | try:
39 | event_functions["mousePressed"]= mousePressed
40 | except:
41 | pass
42 | try:
43 | event_functions["mouseReleased"]= mouseReleased
44 | except:
45 | pass
46 | try:
47 | event_functions["mouseClicked"]= mouseClicked
48 | except:
49 | pass
50 | try:
51 | event_functions["doubleClicked"]= doubleClicked
52 | except:
53 | pass
54 | try:
55 | event_functions["mouseWheel"]= mouseWheel
56 | except:
57 | pass
58 | try:
59 | event_functions["touchStarted"]= touchStarted
60 | except:
61 | pass
62 | try:
63 | event_functions["touchMoved"]= touchMoved
64 | except:
65 | pass
66 | try:
67 | event_functions["touchEnded"]= touchEnded
68 | except:
69 | pass
70 | try:
71 | event_functions["windowResized"]= windowResized
72 | except:
73 | pass
74 |
75 |
76 | def start_p5(setup_func, draw_func, event_functions):
77 | """
78 | This is the entrypoint function. It accepts 2 parameters:
79 | - setup_func: a Python setup callable
80 | - draw_func: a Python draw callable
81 | - event_functions: a config dict for the event functions in the format:
82 | {"eventFunctionName": python_event_function}
83 | This method gets the p5js's sketch instance and injects them
84 | """
85 | # Hack: For some reason it is needed
86 | sketchElement.innerText=""
87 |
88 | def sketch_setup(p5_sketch):
89 | p5_sketch.setup = global_p5_injection(p5_sketch)(setup_func)
90 | p5_sketch.draw = global_p5_injection(p5_sketch)(draw_func)
91 |
92 |
93 | instance = __new__(p5(sketch_setup, 'sketch-element'))
94 |
95 | # inject event functions into p5
96 | event_function_names = (
97 | "deviceMoved", "deviceTurned", "deviceShaken", "windowResized",
98 | "keyPressed", "keyReleased", "keyTyped",
99 | "mousePressed", "mouseReleased", "mouseClicked", "doubleClicked",
100 | "mouseMoved", "mouseDragged", "mouseWheel",
101 | "touchStarted", "touchMoved", "touchEnded"
102 | )
103 |
104 | for f_name in [f for f in event_function_names if event_functions.get(f, None)]:
105 | func = event_functions[f_name]
106 | event_func = global_p5_injection(instance)(func)
107 | setattr(instance, f_name, event_func)
108 |
109 | start_p5(setup, draw, event_functions)
--------------------------------------------------------------------------------
/panel_sketch/sketch_editor.py:
--------------------------------------------------------------------------------
1 | """The SketchEditor enables editing the SketchBase and derived classes"""
2 | import datetime
3 |
4 | import panel as pn
5 | import param
6 |
7 | from .sketch_base import SketchBase
8 |
9 | EDITOR_HEIGHT = 600
10 | EDITOR_MARGIN = (20, 5, 10, 5)
11 | MAX_LOG_LINES = 50
12 |
13 |
14 | class SketchEditor(param.Parameterized):
15 | """The SketchEditor enables editing the SketchBase and derived classes"""
16 |
17 | compile = param.Action()
18 |
19 | view = param.Parameter()
20 |
21 | sketch = param.ClassSelector(class_=SketchBase, constant=True, precedence=-1)
22 |
23 | def __init__(self, **params):
24 | super().__init__(**params)
25 |
26 | self.compile = self._compile_sketch
27 | self._create_view()
28 |
29 | def _create_view(self):
30 | sketch: SketchBase = self.sketch
31 | build_button = pn.widgets.Button(
32 | name="▶", button_type="primary", margin=(10, 0, 10, 5), width=50, sizing_mode="fixed"
33 | )
34 |
35 | self._python_editor = pn.widgets.Ace(
36 | name="🐍 PYTHON",
37 | language="python",
38 | height=EDITOR_HEIGHT,
39 | value=sketch.object,
40 | margin=EDITOR_MARGIN,
41 | )
42 |
43 | # # pylint: disable=no-value-for-parameter,no-member
44 | @param.depends(code=sketch.param.object, watch=True)
45 | def _update_python_editor(code):
46 | self._python_editor.value = code
47 |
48 | self._html_editor = pn.widgets.Ace(
49 | name="🗎 HTML",
50 | language="html",
51 | height=EDITOR_HEIGHT,
52 | value=sketch.html,
53 | margin=EDITOR_MARGIN,
54 | )
55 |
56 | @param.depends(code=sketch.param.html, watch=True)
57 | def _update_html_editor(code):
58 | self._html_editor.value = code
59 |
60 | self._css_editor = pn.widgets.Ace(
61 | name="🎨 CSS",
62 | language="css",
63 | height=EDITOR_HEIGHT,
64 | value=sketch.css,
65 | margin=EDITOR_MARGIN,
66 | )
67 |
68 | @param.depends(code=sketch.param.css, watch=True)
69 | def _update_css_editor(code):
70 | self._css_editor.value = code
71 |
72 | self._javascript_editor = pn.widgets.Ace(
73 | name="☕ JS",
74 | language="javascript",
75 | readonly=True,
76 | height=EDITOR_HEIGHT,
77 | value=sketch.javascript,
78 | margin=EDITOR_MARGIN,
79 | )
80 |
81 | @param.depends(code=sketch.param.javascript, watch=True)
82 | def _update_javascript_editor(code):
83 | self._javascript_editor.value = code
84 |
85 | self._log = pn.widgets.TextAreaInput(
86 | name="⚠️ Log", height=EDITOR_HEIGHT, margin=EDITOR_MARGIN, disabled=True
87 | )
88 |
89 | build_button.on_click(self.compile)
90 |
91 | self.view = pn.Column(
92 | pn.Row(build_button),
93 | pn.Tabs(
94 | self._python_editor,
95 | self._html_editor,
96 | self._css_editor,
97 | self._javascript_editor,
98 | self._log,
99 | ),
100 | )
101 |
102 | def _compile_sketch(self, _=None):
103 | sketch = self.sketch
104 | sketch.html = self._html_editor.value
105 | sketch.css = self._css_editor.value
106 | if sketch.object == self._python_editor.value:
107 | # Hack to force update
108 | sketch.object = self._python_editor.value + "\n"
109 | else:
110 | sketch.object = self._python_editor.value
111 |
112 | log_value = "\n".join(self._log.value.split("\n")[:MAX_LOG_LINES])
113 | self._log.value = (
114 | datetime.datetime.now().strftime("%H:%M:%S: ") + "Build" + "\n" + log_value
115 | )
116 |
--------------------------------------------------------------------------------
/panel_sketch/sketch_viewer.py:
--------------------------------------------------------------------------------
1 | """The SketchViewer makes it easy to View a Sketch"""
2 | import uuid
3 | from textwrap import dedent
4 |
5 | import panel as pn
6 | import param
7 |
8 | from .sketch_base import SketchBase
9 |
10 | LAYOUT_NONE = (None, None, None)
11 |
12 |
13 | class SketchViewer(param.Parameterized):
14 | """The SketchViewer makes it easy to View a Sketch"""
15 |
16 | sketch = param.ClassSelector(class_=SketchBase, constant=True, precedence=-1)
17 |
18 | view = param.Parameter(constant=True)
19 |
20 | def __init__(self, **params):
21 | super().__init__(**params)
22 |
23 | self._uuid = uuid.uuid4()
24 | self._create_view()
25 |
26 | self._update_html_pane()
27 | self._update_css_pane()
28 | self._update_js_args_pane()
29 | self._update_js_pane()
30 |
31 | def _create_view(self):
32 | self._html_pane = pn.pane.HTML(height=200, width=200)
33 | self._css_pane = pn.pane.HTML(width=0, height=0, margin=0, sizing_mode="fixed")
34 | self._js_args_pane = pn.pane.HTML(width=0, height=0, margin=0, sizing_mode="fixed")
35 | self._js_pane = pn.pane.HTML(width=0, height=0, margin=0, sizing_mode="fixed")
36 | with param.edit_constant(self):
37 | self.view = pn.Column(
38 | self._css_pane, self._html_pane, self._js_args_pane, self._js_pane
39 | )
40 |
41 | def _to_unique(self, value):
42 | return value.replace("sketch-element", f"sketch-{self._uuid}")
43 |
44 | # pylint: disable=no-member
45 | @param.depends("sketch.html", watch=True)
46 | def _update_html_pane(self):
47 | html_unique = self._to_unique(self.sketch.html)
48 | self._html_pane.object = html_unique
49 |
50 | @param.depends("sketch.css", watch=True)
51 | def _update_css_pane(self):
52 | css_unique = self._to_unique(self.sketch.css)
53 | self._css_pane.object = ""
54 |
55 | @param.depends("sketch.args", watch=True)
56 | def _update_js_args_pane(self):
57 | javascript_args_unique = self._to_unique(f"""var args = {str(self.sketch.args)}""")
58 | self._js_args_pane.object = (
59 | f''
60 | )
61 |
62 | @param.depends("sketch.loading", watch=True)
63 | def _signal_loading(self):
64 | print("signal_loading", self.sketch.loading)
65 | self.view.loading=self.sketch.loading
66 |
67 | @param.depends("sketch.javascript", watch=True)
68 | def _update_js_pane(self):
69 | self._update_layout()
70 | javascript_unique = self._to_unique(self.sketch.javascript)
71 | self._js_pane.object = f""""""
72 |
73 | def _update_layout(self):
74 | width, height, sizing_mode = self._get_layout(self.sketch.object)
75 | if height:
76 | self._html_pane.height = height
77 | if width:
78 | self._html_pane.width = width
79 | if sizing_mode:
80 | self._html_pane.sizing_mode = sizing_mode
81 |
82 | @staticmethod
83 | def _get_layout(value: str):
84 | clean = dedent(value)
85 | index = clean.find("createCanvas(") # '...createCanvas(200, 200)\n\n background(160)'
86 | if index == -1:
87 | return LAYOUT_NONE
88 |
89 | clean = clean[index:-1].replace("createCanvas(", "") # '200, 200)\n\n background(160)'
90 | index = clean.find(")")
91 | clean = clean[0:index] # '200, 200
92 | args = clean.split(",")
93 | width = int(args[0])
94 | height = int(args[1])
95 | sizing_mode = "fixed"
96 | return width, height, sizing_mode
97 |
--------------------------------------------------------------------------------
/panel_sketch/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "noImplicitAny": true,
4 | "noImplicitThis": true,
5 | "noImplicitReturns": true,
6 | "noUnusedLocals": true,
7 | "noUnusedParameters": true,
8 | "strictNullChecks": true,
9 | "strictBindCallApply": false,
10 | "strictFunctionTypes": false,
11 | "strictPropertyInitialization": false,
12 | "alwaysStrict": true,
13 | "noErrorTruncation": true,
14 | "noEmitOnError": false,
15 | "declaration": true,
16 | "sourceMap": true,
17 | "importHelpers": false,
18 | "experimentalDecorators": true,
19 | "module": "esnext",
20 | "moduleResolution": "node",
21 | "esModuleInterop": true,
22 | "resolveJsonModule": true,
23 | "skipLibCheck": true,
24 | "target": "ES2017",
25 | "lib": ["es2017", "dom", "dom.iterable"],
26 | "baseUrl": ".",
27 | "outDir": "./dist/lib",
28 | "paths": {
29 | "@bokehjs/*": [
30 | "./node_modules/@bokeh/bokehjs/build/js/lib/*",
31 | "./node_modules/@bokeh/bokehjs/build/js/types/*"
32 | ]
33 | }
34 | },
35 | "include": ["./**/*.ts"]
36 | }
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.black]
2 | line-length = 100
--------------------------------------------------------------------------------
/pytest.ini:
--------------------------------------------------------------------------------
1 | [pytest]
2 | testpaths = tests
3 | junit_family=legacy
4 | python_files = tests.py test_*.py *_tests.py
5 | markers =
6 | unittest: Small, isolated test
7 | integration_test: A test towards some external system or service. For example a database
8 | functionaltest: Large potentially non-isolated test requiring access to external services
9 | slow: A slow test. Skip normally. But run this when you have the time.
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | """Setup file for the Awesome Panel Extensions"""
2 | import pathlib
3 | from typing import List
4 |
5 | import setuptools
6 |
7 | # I only want to include a short README with a focus on the package
8 | with open("README.md", "r") as fh:
9 | long_description = fh.read()
10 |
11 | ROOT = pathlib.Path.cwd()
12 | VERSION = (ROOT / "VERSION").read_text().strip()
13 |
14 | install_requires = [
15 | "panel>=0.11.1",
16 | "bokeh>=2.3",
17 | ]
18 |
19 | _recommended: List[str] = []
20 |
21 | _tests = [
22 | "autoflake",
23 | "invoke",
24 | "isort",
25 | "jupyter-repo2docker",
26 | "mypy",
27 | "pylint>=2.6.0",
28 | "pytest",
29 | "pytest-cov",
30 | "rope",
31 | "twine",
32 | "wheel",
33 | ]
34 |
35 | _examples = [
36 | "notebook",
37 | "jupyterlab",
38 | "transcrypt",
39 | ]
40 |
41 | _doc: List[str] = []
42 |
43 | extras_require = {
44 | "examples": _recommended + _examples,
45 | "tests": _tests,
46 | "recommended": _recommended,
47 | "doc": _recommended + _doc,
48 | }
49 |
50 | extras_require["all"] = sorted(set(sum(extras_require.values(), [])))
51 |
52 | setuptools.setup(
53 | name="panel-sketch",
54 | version=VERSION,
55 | description="""To sketch high performing, interactive visualizations running in the browser
56 | and drawing inspiration from p5js""",
57 | long_description=long_description,
58 | long_description_content_type="text/markdown",
59 | author="Marc Skov Madsen",
60 | author_email="marc.skov.madsen@gmail.com",
61 | platforms=["Windows", "Mac OS X", "Linux"],
62 | license="MIT",
63 | url="https://github.com/MarcSkovMadsen/panel-sketch",
64 | # My Project contains more folders/ packages but they should not be included
65 | packages=setuptools.find_packages(include=["panel_sketch", "panel_sketch.*"]),
66 | include_package_data=True,
67 | classifiers=[
68 | # I would like to indicate that this package is a package for the Panel framework
69 | "License :: OSI Approved :: MIT License",
70 | "Development Status :: 3 - Alpha",
71 | "Programming Language :: Python :: 3",
72 | "Programming Language :: Python :: 3.7",
73 | "Programming Language :: Python :: 3.8",
74 | "Programming Language :: Python :: 3.9",
75 | "Operating System :: OS Independent",
76 | "Intended Audience :: Developers",
77 | "Intended Audience :: Science/Research",
78 | "Intended Audience :: Financial and Insurance Industry",
79 | "Intended Audience :: Healthcare Industry",
80 | "Intended Audience :: Information Technology",
81 | "Intended Audience :: Legal Industry",
82 | "Intended Audience :: Other Audience",
83 | "Intended Audience :: Science/Research",
84 | "Natural Language :: English",
85 | "Topic :: Scientific/Engineering",
86 | "Topic :: Scientific/Engineering :: Visualization",
87 | "Topic :: Scientific/Engineering :: Information Analysis",
88 | "Topic :: Office/Business",
89 | "Topic :: Office/Business :: Financial",
90 | "Topic :: Software Development :: Libraries",
91 | ],
92 | python_requires=">=3.7",
93 | install_requires=install_requires,
94 | extras_require=extras_require,
95 | tests_require=extras_require["tests"],
96 | )
97 |
--------------------------------------------------------------------------------
/tasks/__init__.py:
--------------------------------------------------------------------------------
1 | """Here we import the different task submodules/ collections"""
2 | from invoke import Collection
3 |
4 | from . import test
5 |
6 | # pylint: disable=invalid-name
7 | # as invoke only recognizes lower case
8 | namespace = Collection()
9 | namespace.add_collection(test)
10 |
--------------------------------------------------------------------------------
/tasks/test.py:
--------------------------------------------------------------------------------
1 | """Module of Invoke tasks regarding CODE QUALITY to be invoked from the command line. Try
2 |
3 | invoke --list
4 |
5 | from the command line for a list of all available commands.
6 | """
7 |
8 | from invoke import task
9 |
10 | PACKAGE_FOLDER = "panel_sketch"
11 |
12 |
13 | @task
14 | def bandit(command):
15 | """Runs Bandit the security linter from PyCQA."""
16 | print(
17 | """
18 | Running Bandit the Python Security Linter
19 | to identify common security issues in Python code
20 | =================================================
21 | """
22 | )
23 | command.run("bandit -r ./", echo=True)
24 |
25 |
26 | @task
27 | def black(command):
28 | """Runs black (autoformatter) on all .py files recursively"""
29 | print(
30 | """
31 | Running Black the Python code formatter
32 | =======================================
33 | """
34 | )
35 | command.run("black .", echo=True)
36 |
37 |
38 | @task
39 | def isort(command):
40 | """Runs isort (import sorter) on all .py files recursively"""
41 | print(
42 | """
43 | Running isort the Python code import sorter
44 | ===========================================
45 | """
46 | )
47 | command.run("isort .", echo=True)
48 |
49 |
50 | @task
51 | def pytest(
52 | command,
53 | test_files="tests",
54 | integrationtest=False,
55 | test_results="test_results",
56 | open_results=True,
57 | ):
58 | """Runs pytest to identify failing tests
59 |
60 | Arguments:
61 | command {[type]} -- Invoke command object
62 |
63 | Keyword Arguments:
64 | root_dir {str} -- The directory from which to run the tests
65 | test_files {str} -- A space separated list of folders and files to test. (default: {'tests})
66 | integrationtest {bool} -- If True tests marked integrationtest or functionaltest will be
67 | run. Otherwise not. (default: {False})
68 | test_results {string} -- If not None test reports will be generated in the test_results
69 | folder
70 | open_results {bool} -- If True test reports in the 'test_results' folder will be opened in
71 | a browser
72 |
73 | # Print running pytest
74 | """
75 | print(
76 | """
77 | Running pytest the test framework
78 | =================================
79 | """
80 | )
81 | # Build the command_string
82 | command_string = f"pytest {test_files} --doctest-modules --cov={PACKAGE_FOLDER}"
83 | if not integrationtest:
84 | command_string += ' -m "not functionaltest and not integrationtest"'
85 | if test_results:
86 | # command_string += f" --junitxml={test_results}/test-results-api.xml"
87 | command_string += f" --cov-report html:{test_results}/cov_html"
88 |
89 | # Run the command_string
90 | command.run(command_string, echo=True)
91 |
92 | # Open the test coverage report in a browser
93 | if test_results and open_results:
94 | command.run("start test_results/cov_html/index.html")
95 |
96 |
97 | @task()
98 | def pylint(command, files=f"setup.py tasks {PACKAGE_FOLDER} tests"):
99 | """Runs pylint (linter) on all .py files recursively to identify coding errors
100 |
101 | Arguments:
102 | command {[type]} -- [description]
103 | files {string} -- A space separated list of files and folders to lint
104 | """
105 | # https://stackoverflow.com/questions/22241435/pylint-discard-cached-file-state
106 | # from astroid import MANAGER
107 | # MANAGER.astroid_cache.clear()
108 | print(
109 | """
110 | Running pylint.
111 | Pylint looks for programming errors, helps enforcing a coding standard,
112 | sniffs for code smells and offers simple refactoring suggestions.
113 | =======================================================================
114 | """
115 | )
116 | command_string = f"pylint {files}"
117 | command.run(command_string, echo=True)
118 |
119 |
120 | @task
121 | def mypy(command, files=f"setup.py tasks {PACKAGE_FOLDER} tests"):
122 | """Runs mypy (static type checker) on all .py files recursively
123 |
124 | Arguments:
125 | command {[type]} -- [description]
126 | files {string} -- A space separated list of files and folders to lint
127 | """
128 | print(
129 | """
130 | Running mypy for identifying python type errors
131 | ===============================================
132 | """
133 | )
134 | command_string = f"mypy {files}"
135 | command.run(command_string, echo=True)
136 |
137 |
138 | @task
139 | def autoflake(command):
140 | """Runs autoflake to remove unused imports on all .py files recursively
141 |
142 | Arguments:
143 | command {[type]} -- [description]
144 | """
145 | print(
146 | """
147 | Running autoflake to remove unused imports on all .py files recursively
148 | =======================================================================
149 | """
150 | )
151 | # command.run("RUN rm -rf .mypy_cache/; exit 0")
152 | command.run(
153 | "autoflake --imports=pytest,pandas,numpy,plotly,dash,urllib3 --in-place --recursive .",
154 | echo=True,
155 | )
156 |
157 |
158 | @task(
159 | pre=[isort, autoflake, black, pylint, mypy, pytest],
160 | aliases=["pre_commit", "test"],
161 | name="all",
162 | )
163 | def _all(command): # pylint: disable=unused-argument
164 | """Runs isort, autoflake, black, pylint, mypy and pytest
165 |
166 | Arguments:
167 | command {[type]} -- [description]
168 | """
169 | # If we get to this point all tests listed in 'pre' have passed
170 | # unless we have run the task with the --warn flag
171 | if not command.config.run.warn:
172 | print(
173 | """
174 | All Tests Passed Successfully
175 | =============================
176 | """
177 | )
178 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarcSkovMadsen/panel-sketch/518cb177e2e8d1899b58f3a3f4d80d26c82ec760/tests/__init__.py
--------------------------------------------------------------------------------
/tests/models/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarcSkovMadsen/panel-sketch/518cb177e2e8d1899b58f3a3f4d80d26c82ec760/tests/models/__init__.py
--------------------------------------------------------------------------------
/tests/models/test_sketch.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=redefined-outer-name,protected-access
2 | # pylint: disable=missing-function-docstring,missing-module-docstring,missing-class-docstring
3 |
4 | from panel_sketch.models.sketch import Sketch
5 |
6 |
7 | def test_constructor():
8 | Sketch()
9 |
--------------------------------------------------------------------------------
/tests/test_pyodide_compiler.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=redefined-outer-name,protected-access
2 | # pylint: disable=missing-function-docstring,missing-module-docstring,missing-class-docstring
3 | from panel_sketch.sketch_compiler import PyodideCompiler
4 |
5 | INDENTED = """
6 | def setup():
7 | pass
8 |
9 | def draw():
10 | pass
11 | """
12 |
13 | UNINDENTED = """
14 | def setup():
15 | pass
16 |
17 | def draw():
18 | pass
19 | """
20 |
21 |
22 | def test_clean_unindents():
23 | assert PyodideCompiler._clean_object(INDENTED) == UNINDENTED
24 |
25 |
26 | def test_clean_removes_pyp5js_import():
27 | sketch = """
28 | # https://p5js.org/examples/interaction-wavemaker.html
29 |
30 |
31 | from pyp5js import *
32 |
33 | t = 0
34 | """
35 | assert (
36 | PyodideCompiler._clean_object(sketch)
37 | == """
38 | # https://p5js.org/examples/interaction-wavemaker.html
39 |
40 |
41 |
42 | t = 0
43 | """
44 | )
45 |
--------------------------------------------------------------------------------
/tests/test_sketch.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=redefined-outer-name,protected-access
2 | # pylint: disable=missing-function-docstring,missing-module-docstring,missing-class-docstring
3 | import panel as pn
4 |
5 | from panel_sketch import Sketch
6 |
7 |
8 | def test_constructor():
9 | Sketch()
10 |
11 |
12 | def test_app():
13 | sketch = Sketch(
14 | # Test that it also works indented
15 | object="""
16 | def setup():
17 |
18 | createCanvas(200, 200)
19 |
20 | background(160)
21 |
22 | def draw():
23 |
24 | fill("blue")
25 |
26 | background(200)
27 |
28 | radius = sin(frameCount / 60) * window.args.value + 50
29 |
30 | ellipse(100, 100, radius, radius)
31 | """,
32 | )
33 |
34 | slider = pn.widgets.FloatSlider(value=50, start=10, end=100, step=1)
35 |
36 | @pn.depends(value=slider, watch=True)
37 | def _update_value(value):
38 | sketch.args = dict(value=value)
39 |
40 | _update_value(slider.value)
41 |
42 | return pn.Column(sketch.viewer.view, slider)
43 |
44 |
45 | if __name__.startswith("bokeh"):
46 | test_app().servable()
47 |
--------------------------------------------------------------------------------
/tests/test_sketch_base.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=redefined-outer-name,protected-access
2 | # pylint: disable=missing-function-docstring,missing-module-docstring,missing-class-docstring
3 | from panel_sketch.sketch_base import SketchBase
4 |
5 |
6 | def test_can_construct():
7 | sketch = SketchBase()
8 |
9 | assert sketch.args == {}
10 |
--------------------------------------------------------------------------------
/tests/test_sketch_compiler.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=redefined-outer-name,protected-access
2 | # pylint: disable=missing-function-docstring,missing-module-docstring,missing-class-docstring
3 | from panel_sketch.sketch_compiler import PyodideCompiler, SketchBase
4 |
5 | SKETCH_PYTHON = """
6 | print('Hello Compiler World')
7 | """
8 |
9 |
10 | def test_can_construct():
11 | # Given
12 | script = "print('Hello Compiler World')"
13 | sketch = SketchBase(object=script, template="pyp5js")
14 | compiler = PyodideCompiler(sketch=sketch)
15 |
16 | assert sketch.javascript == ""
17 |
18 | # When
19 | compiler.run()
20 |
21 | # Then
22 | assert script in sketch.javascript
23 |
24 |
25 | def test_can_compile_basic_template():
26 | # Given
27 | script = "print('Hello Compiler World')"
28 | sketch = SketchBase(object=script, template="basic")
29 | compiler = PyodideCompiler(sketch=sketch)
30 |
31 | # When
32 | compiler.run()
33 |
34 | # Then
35 | assert "_P5_INSTANCE" not in sketch.javascript
36 |
--------------------------------------------------------------------------------
/tests/test_sketch_editor.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=redefined-outer-name,protected-access
2 | # pylint: disable=missing-function-docstring,missing-module-docstring,missing-class-docstring
3 | from panel_sketch.sketch_editor import SketchBase, SketchEditor
4 |
5 |
6 | def test_can_construct():
7 | sketch = SketchBase()
8 | editor = SketchEditor(sketch=sketch)
9 |
10 | assert editor.sketch is sketch
11 | assert editor.view
12 |
13 |
14 | def test_can_update_sketch():
15 | sketch = SketchBase()
16 | editor = SketchEditor(sketch=sketch)
17 |
18 | sketch.object = "a"
19 | assert editor._python_editor.value == sketch.object
20 |
21 | sketch.html = "b"
22 | assert editor._html_editor.value == sketch.html
23 |
24 | sketch.css = "c"
25 | assert editor._css_editor.value == sketch.css
26 |
27 | sketch.javascript = "d"
28 | assert editor._javascript_editor.value == sketch.javascript
29 |
30 |
31 | def test_can_compile():
32 | # Given
33 | sketch = SketchBase()
34 | editor = SketchEditor(sketch=sketch)
35 |
36 | assert editor._log.value == ""
37 | # When
38 | editor._python_editor.value = "print('a')"
39 | editor._html_editor.value = "HI"
40 | editor._css_editor.value = """
41 | #sketch-element {
42 | color: blue;
43 | }
44 | """
45 |
46 | editor.compile()
47 |
48 | # Then
49 | assert sketch.object == editor._python_editor.value
50 | assert sketch.html == editor._html_editor.value
51 | assert sketch.css == editor._css_editor.value
52 |
--------------------------------------------------------------------------------
/tests/test_sketch_viewer.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=redefined-outer-name,protected-access
2 | # pylint: disable=missing-function-docstring,missing-module-docstring,missing-class-docstring
3 | from panel_sketch.sketch_viewer import SketchBase, SketchViewer
4 |
5 |
6 | def test_can_constructor():
7 | sketch = SketchBase(javascript="console.log('sketch-element')")
8 | viewer = SketchViewer(sketch=sketch)
9 |
10 | assert viewer.sketch == sketch
11 | assert viewer.view
12 |
13 | assert "sketch-" in viewer._html_pane.object
14 | assert "sketch-" in viewer._js_pane.object
15 |
16 | assert "sketch-element" not in viewer._html_pane.object
17 | assert "sketch-element" not in viewer._js_pane.object
18 |
19 |
20 | def test_get_layout_fixed():
21 | sketch = """
22 | def setup():
23 |
24 | createCanvas(200, 200)
25 |
26 | background(160)
27 | """
28 | assert SketchViewer._get_layout(sketch) == (200, 200, "fixed")
29 |
30 |
31 | def test_get_layout_none():
32 | sketch = """
33 | def setup():
34 |
35 | background(160)
36 | """
37 | assert SketchViewer._get_layout(sketch) == (None, None, None)
38 |
39 |
40 | def test_get_layout_more_args():
41 | sketch = """
42 | def setup():
43 | createCanvas(640, 360, _P5_INSTANCE.WEBGL)
44 | fill(204)
45 | """
46 | assert SketchViewer._get_layout(sketch) == (640, 360, "fixed")
47 |
--------------------------------------------------------------------------------
/tests/test_transcrypt_compiler.py:
--------------------------------------------------------------------------------
1 | # pylint: disable=redefined-outer-name,protected-access
2 | # pylint: disable=missing-function-docstring,missing-module-docstring,missing-class-docstring
3 | from panel_sketch.sketch_compiler import SketchBase, TranscryptCompiler
4 |
5 | SKETCH_PYTHON = """
6 | print('Hello Compiler World')
7 | """
8 |
9 |
10 | def duplicate_count(value):
11 | return len([x for x in set(value) if value.count(x) > 1])
12 |
13 |
14 | def test_can_construct():
15 | sketch = SketchBase(object=SKETCH_PYTHON, template="basic")
16 | compiler = TranscryptCompiler(sketch=sketch)
17 |
18 | compiler.run()
19 |
20 | # When concatenating transcrypt generated modules we need to make sure they only appear once
21 | assert sketch.javascript.count("var __name__") == 1
22 | assert (
23 | sketch.javascript.count("var sketchElement = document.getElementById('sketch-element')\n")
24 | == 1
25 | )
26 |
27 |
28 | def test_can_construct():
29 | sketch = SketchBase(object=SKETCH_PYTHON, template="pyp5js")
30 | compiler = TranscryptCompiler(sketch=sketch)
31 |
32 | compiler.run()
33 |
34 | # When concatenating transcrypt generated modules we need to make sure they only appear once
35 | assert sketch.javascript.count("var __name__") == 1
36 | assert (
37 | sketch.javascript.count("var sketchElement = document.getElementById ('sketch-element')")
38 | == 1
39 | )
40 |
--------------------------------------------------------------------------------