diff --git a/.deepsource.toml b/.deepsource.toml
index b8aa7aa..6e6717e 100644
--- a/.deepsource.toml
+++ b/.deepsource.toml
@@ -1,6 +1,6 @@
version = 1
-exclude_patterns = ["**/antlrgen/*","**/BitVector.py"]
+exclude_patterns = ["lfr/antlrgen/**.*","**/BitVector.py"]
[[analyzers]]
name = "python"
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index d9be9cb..ce5d0c6 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1,44 +1,29 @@
-# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.166.1/containers/ubuntu/.devcontainer/base.Dockerfile
+# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.194.3/containers/ubuntu/.devcontainer/base.Dockerfile
-# [Choice] Ubuntu version: bionic, focal
+# [Choice] Ubuntu version: hirsute, bionic, focal
ARG VARIANT="focal"
FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT}
-# FROM ubuntu:20.04
ENV PYTHONFAULTHANDLER=1 \
PYTHONUNBUFFERED=1 \
PYTHONHASHSEED=random \
PIP_NO_CACHE_DIR=off \
- # PIP_DISABLE_PIP_VERSION_CHECK=on \
+ PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100 \
- POETRY_VERSION=1.0.0
+ POETRY_VERSION=1.2.0
# [Optional] Uncomment this section to install additional OS packages.
-RUN export DEBIAN_FRONTEND=noninteractive \
- && sudo apt-get update \
- && apt-get -y install --no-install-recommends build-essential curl software-properties-common \
- python3-pip git make build-essential python-dev libssl-dev zlib1g-dev \
- libbz2-dev libreadline-dev libsqlite3-dev curl libffi-dev \
- graphviz libgraphviz-dev \
- libcairo2-dev pkg-config python3-dev
+RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
+ && apt-get -y install --no-install-recommends curl build-essential \
+ software-properties-common python3-pip make build-essential \
+ python-dev libssl-dev zlib1g-dev libbz2-dev libreadline-dev \
+ libsqlite3-dev curl libffi-dev redis-server openjdk-8-jre-headless \
+ graphviz libgraphviz-dev libcairo2-dev pkg-config python3-dev python3.8-venv \
+ python3-setuptools liblzma-dev \
+ python3-pygraphviz apt-utils
+
+# RUN poetry config virtualenvs.create false
+RUN pip install --upgrade pip
+RUN pip install setuptools pygraphviz
-# Things that didn't install - make python3-dev
-
-# Install and setup pyenv
-RUN git clone git://github.com/yyuu/pyenv.git .pyenv
-RUN git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv
-
-ENV HOME /
-ENV PYENV_ROOT $HOME/.pyenv
-ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH
-
-RUN pyenv install 3.8.0
-RUN pyenv global 3.8.0
-
-RUN pip install pygraphviz
-
-RUN pip install "poetry==$POETRY_VERSION"
-
-RUN poetry config virtualenvs.create false
-ENV PYTHONPATH=${PYTHONPATH}:${PWD}
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index f7f93da..8a8756b 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -5,23 +5,35 @@
"build": {
"dockerfile": "Dockerfile",
// Update 'VARIANT' to pick an Ubuntu version: focal, bionic
- "args": { "VARIANT": "focal" }
+ "args": {
+ "VARIANT": "focal"
+ }
},
-
// Set *default* container specific settings.json values on container create.
- "settings": {
- "terminal.integrated.shell.linux": "/bin/bash"
- },
-
// Add the IDs of extensions you want installed when the container is created.
- "extensions": ["ms-python.vscode-pylance", "ms-python.python","njpwerner.autodocstring","bungcip.better-toml", "rkrishnasanka.lfr", "rkrishnasanka.uf"]
-
+ "customizations": {
+ "vscode": {
+ "extensions": [
+ "ms-python.vscode-pylance",
+ "ms-python.python",
+ "njpwerner.autodocstring",
+ "bungcip.better-toml",
+ "rkrishnasanka.lfr",
+ "rkrishnasanka.uf",
+ "LittleFoxTeam.vscode-python-test-adapter"
+ ]
+ }
+ },
+ "features": {
+ "ghcr.io/devcontainers-contrib/features/black:2": {},
+ "ghcr.io/devcontainers-contrib/features/isort:2": {},
+ "ghcr.io/devcontainers-contrib/features/poetry:2": {},
+ "ghcr.io/devcontainers-contrib/features/pylint:2": {}
+ },
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
-
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "uname -a",
-
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
- // "remoteUser": "vscode"
-}
+ "remoteUser": "root"
+}
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..4bb443c
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.pdf binary
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 3ddcae8..334f4fb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -130,10 +130,11 @@ dmypy.json
# Output
out/
+output/
.idea/
.antlr/
Verilog2001.g4
*.old
-pre_processor_dump.lfr
\ No newline at end of file
+pre_processor_dump.lfr
diff --git a/.gitmodules b/.gitmodules
index abdfddb..6908d52 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,12 @@
-[submodule "test"]
- path = test
- url = https://github.com/CIDARLAB/LFR-TestCases.git
+[submodule "pymint"]
+ path = pymint
+ url = https://github.com/cidarlab/pymint
+ branch = master
+[submodule "pyparchmint"]
+ path = pyparchmint
+ url = https://github.com/cidarlab/pyparchmint
+ branch = master
+[submodule "dafd"]
+ path = dafd
+ url = https://github.com/rkrishnasanka/dafd
+ branch = master
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 555dc1a..a215e90 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -74,6 +74,8 @@
"args": [
"--outpath",
"./out/",
+ "--technology",
+ "dropx",
"${file}"
],
"console": "integratedTerminal"
@@ -91,6 +93,21 @@
],
"console": "integratedTerminal"
},
+ {
+ "name": "Debug - Customfile, NO GEN (with distribute library)",
+ "type": "python",
+ "request": "launch",
+ "program": "${workspaceFolder}/lfr/cmdline.py",
+ "args": [
+ "--no-gen",
+ "--outpath",
+ "./out/",
+ "--pre-load",
+ "../LFR-Testcases/distribute-library",
+ "${file}"
+ ],
+ "console": "integratedTerminal"
+ },
{
"name": "Debug - CLI TEST",
"type": "python",
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 2fd9fa5..da38bed 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,12 +1,20 @@
{
- "python.linting.flake8Enabled": true,
+ "python.linting.flake8Enabled": false,
"python.linting.enabled": true,
- "python.linting.flake8Args": ["--max-line-length=88", "--ignore=E203"],
+ "python.linting.flake8Args": [
+ "--max-line-length=88",
+ "--ignore=E203"
+ ],
"python.formatting.provider": "black",
"editor.formatOnSave": true,
- "python.linting.pylintEnabled": false,
+ "python.linting.pylintEnabled": true,
"python.formatting.blackArgs": [
"--line-length=88",
"--experimental-string-processing"
- ]
-}
+ ],
+ "python.testing.pytestArgs": [
+ "tests"
+ ],
+ "python.testing.unittestEnabled": false,
+ "python.testing.pytestEnabled": true,
+}
\ No newline at end of file
diff --git a/LFR-Logo-01.png b/LFR-Logo-01.png
new file mode 100644
index 0000000..3254a80
Binary files /dev/null and b/LFR-Logo-01.png differ
diff --git a/README.md b/README.md
index f48f598..0a21a4d 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# LFR
+# LFR
## Dependencies
@@ -8,8 +8,16 @@ LFR requires the user to install graphviz onto the system for the pygraphviz dep
We need ANTLR for generating the listener. Install ANTLR4 from the [website](https://www.antlr.org/index.html)
+### LFR Grammar
+
+```
+antlr4 -o ./lfr/antlrgen/lfr -listener -visitor -Dlanguage=Python3 -lib . ./lfrX.g4
+```
+
+### Reggie(Graph Match) Grammar
+
```
-antlr4 -o ./lfr/antlrgen -listener -visitor -Dlanguage=Python3 -lib . ./lfrX.g4
+antlr4 -o ./lfr/antlrgen/reggie -listener -visitor -Dlanguage=Python3 -lib . ./reggie.g4
```
### Graphviz
diff --git a/dafd b/dafd
new file mode 160000
index 0000000..3c60c93
--- /dev/null
+++ b/dafd
@@ -0,0 +1 @@
+Subproject commit 3c60c9313cec92c37b7e5fc8b23e1f5fb9bf0c4b
diff --git a/lfr/netlistgenerator/v2/__init__.py b/lfr/antlrgen/lfr/__init__.py
similarity index 100%
rename from lfr/netlistgenerator/v2/__init__.py
rename to lfr/antlrgen/lfr/__init__.py
diff --git a/lfr/antlrgen/lfr/lfrX.interp b/lfr/antlrgen/lfr/lfrX.interp
new file mode 100755
index 0000000..0aa2eaa
--- /dev/null
+++ b/lfr/antlrgen/lfr/lfrX.interp
@@ -0,0 +1,226 @@
+token literal names:
+null
+'endmodule'
+'module'
+'('
+')'
+';'
+','
+'finput'
+'foutput'
+'control'
+'distribute@'
+'begin'
+'end'
+'if'
+'else'
+'endcase'
+'case'
+':'
+'default'
+'<='
+'.'
+'signal'
+'flow'
+'storage'
+'pump'
+'number'
+'assign'
+'='
+'['
+']'
+'{'
+'}'
+'#MAP'
+'"'
+'#MATERIAL'
+'#CONSTRAIN'
+'AND'
+'OR'
+'>'
+'<'
+'>='
+'+'
+'-'
+'!'
+'~'
+'&'
+'~&'
+'|'
+'~|'
+'^'
+'~^'
+'^~'
+'*'
+'/'
+'%'
+'=='
+'!='
+'==='
+'!=='
+'&&'
+'||'
+'**'
+'>>'
+'<<'
+'>>>'
+'<<<'
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+ID
+WS
+One_line_comment
+Block_comment
+Import_line
+Real_number
+Decimal_number
+Binary_number
+Octal_number
+Hex_number
+
+rule names:
+skeleton
+module
+moduledefinition
+body
+ioblock
+vectorvar
+explicitIOBlock
+declvar
+distributionBlock
+distributionBody
+distributeBodyStat
+ifElseBlock
+ifBlock
+elseBlock
+elseIfBlock
+distributeCondition
+statementBlock
+caseBlock
+caseBlockHeader
+casestat
+defaultCaseStat
+distvalue
+distributionassignstat
+sensitivitylist
+signal
+statements
+statement
+moduleinstantiationstat
+instanceioblock
+orderedioblock
+unorderedioblock
+explicitinstanceiomapping
+instancename
+moduletype
+tempvariablesstat
+signalvarstat
+fluiddeclstat
+storagestat
+pumpvarstat
+numvarstat
+assignstat
+literalassignstat
+bracketexpression
+expression
+expressionterm
+logiccondition_operand
+logiccondition
+logic_value
+vector
+variables
+concatenation
+lhs
+ioassignstat
+technologydirectives
+technologymappingdirective
+materialmappingdirective
+mappingoperator
+performancedirective
+constraint
+unit
+unary_operator
+binary_operator
+unary_module_path_operator
+binary_module_path_operator
+number
+
+
+atn:
+[4, 1, 75, 593, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 1, 0, 4, 0, 132, 8, 0, 11, 0, 12, 0, 133, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 146, 8, 2, 1, 2, 1, 2, 1, 3, 1, 3, 4, 3, 152, 8, 3, 11, 3, 12, 3, 153, 1, 4, 1, 4, 1, 4, 5, 4, 159, 8, 4, 10, 4, 12, 4, 162, 9, 4, 1, 4, 1, 4, 1, 4, 5, 4, 167, 8, 4, 10, 4, 12, 4, 170, 9, 4, 3, 4, 172, 8, 4, 1, 5, 1, 5, 3, 5, 176, 8, 5, 1, 6, 1, 6, 1, 6, 1, 6, 5, 6, 182, 8, 6, 10, 6, 12, 6, 185, 9, 6, 1, 6, 1, 6, 1, 6, 1, 6, 5, 6, 191, 8, 6, 10, 6, 12, 6, 194, 9, 6, 1, 6, 1, 6, 1, 6, 1, 6, 5, 6, 200, 8, 6, 10, 6, 12, 6, 203, 9, 6, 3, 6, 205, 8, 6, 1, 7, 3, 7, 208, 8, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 4, 9, 221, 8, 9, 11, 9, 12, 9, 222, 1, 10, 1, 10, 1, 10, 3, 10, 228, 8, 10, 1, 11, 1, 11, 5, 11, 232, 8, 11, 10, 11, 12, 11, 235, 9, 11, 1, 11, 3, 11, 238, 8, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 4, 16, 262, 8, 16, 11, 16, 12, 16, 263, 1, 16, 1, 16, 1, 16, 3, 16, 269, 8, 16, 1, 17, 1, 17, 4, 17, 273, 8, 17, 11, 17, 12, 17, 274, 1, 17, 3, 17, 278, 8, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 3, 22, 302, 8, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 5, 23, 309, 8, 23, 10, 23, 12, 23, 312, 9, 23, 1, 24, 1, 24, 3, 24, 316, 8, 24, 1, 25, 1, 25, 1, 25, 1, 25, 3, 25, 322, 8, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 3, 26, 329, 8, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 3, 28, 339, 8, 28, 1, 29, 1, 29, 1, 29, 5, 29, 344, 8, 29, 10, 29, 12, 29, 347, 9, 29, 1, 30, 1, 30, 1, 30, 5, 30, 352, 8, 30, 10, 30, 12, 30, 355, 9, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 3, 34, 372, 8, 34, 1, 35, 1, 35, 1, 35, 1, 35, 5, 35, 378, 8, 35, 10, 35, 12, 35, 381, 9, 35, 1, 36, 1, 36, 1, 36, 1, 36, 5, 36, 387, 8, 36, 10, 36, 12, 36, 390, 9, 36, 1, 37, 1, 37, 1, 37, 1, 37, 5, 37, 396, 8, 37, 10, 37, 12, 37, 399, 9, 37, 1, 38, 1, 38, 1, 38, 1, 38, 5, 38, 405, 8, 38, 10, 38, 12, 38, 408, 9, 38, 1, 39, 1, 39, 1, 39, 1, 39, 5, 39, 414, 8, 39, 10, 39, 12, 39, 417, 9, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 3, 40, 424, 8, 40, 1, 41, 1, 41, 1, 41, 1, 41, 3, 41, 430, 8, 41, 1, 42, 3, 42, 433, 8, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 3, 43, 441, 8, 43, 1, 43, 1, 43, 1, 43, 3, 43, 446, 8, 43, 5, 43, 448, 8, 43, 10, 43, 12, 43, 451, 9, 43, 1, 44, 3, 44, 454, 8, 44, 1, 44, 1, 44, 3, 44, 458, 8, 44, 1, 45, 1, 45, 3, 45, 462, 8, 45, 1, 45, 1, 45, 1, 45, 3, 45, 467, 8, 45, 5, 45, 469, 8, 45, 10, 45, 12, 45, 472, 9, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 3, 48, 484, 8, 48, 1, 48, 1, 48, 1, 49, 1, 49, 3, 49, 490, 8, 49, 1, 50, 1, 50, 1, 50, 1, 50, 5, 50, 496, 8, 50, 10, 50, 12, 50, 499, 9, 50, 1, 50, 1, 50, 3, 50, 503, 8, 50, 1, 51, 1, 51, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 3, 53, 512, 8, 53, 1, 54, 1, 54, 1, 54, 4, 54, 517, 8, 54, 11, 54, 12, 54, 518, 1, 54, 1, 54, 1, 54, 1, 54, 3, 54, 525, 8, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 3, 56, 535, 8, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 5, 57, 544, 8, 57, 10, 57, 12, 57, 547, 9, 57, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 553, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 559, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 565, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 571, 8, 58, 1, 58, 1, 58, 1, 58, 1, 58, 3, 58, 577, 8, 58, 3, 58, 579, 8, 58, 1, 59, 1, 59, 1, 60, 1, 60, 1, 61, 1, 61, 1, 62, 1, 62, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 0, 0, 65, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 0, 7, 2, 0, 23, 24, 26, 26, 1, 0, 36, 37, 1, 0, 41, 51, 5, 0, 19, 19, 38, 42, 45, 45, 47, 47, 49, 65, 1, 0, 43, 51, 5, 0, 45, 45, 47, 47, 49, 51, 55, 56, 59, 60, 1, 0, 71, 75, 601, 0, 131, 1, 0, 0, 0, 2, 135, 1, 0, 0, 0, 4, 139, 1, 0, 0, 0, 6, 151, 1, 0, 0, 0, 8, 171, 1, 0, 0, 0, 10, 173, 1, 0, 0, 0, 12, 204, 1, 0, 0, 0, 14, 207, 1, 0, 0, 0, 16, 211, 1, 0, 0, 0, 18, 220, 1, 0, 0, 0, 20, 227, 1, 0, 0, 0, 22, 229, 1, 0, 0, 0, 24, 239, 1, 0, 0, 0, 26, 245, 1, 0, 0, 0, 28, 248, 1, 0, 0, 0, 30, 255, 1, 0, 0, 0, 32, 268, 1, 0, 0, 0, 34, 270, 1, 0, 0, 0, 36, 281, 1, 0, 0, 0, 38, 286, 1, 0, 0, 0, 40, 290, 1, 0, 0, 0, 42, 294, 1, 0, 0, 0, 44, 296, 1, 0, 0, 0, 46, 305, 1, 0, 0, 0, 48, 313, 1, 0, 0, 0, 50, 321, 1, 0, 0, 0, 52, 328, 1, 0, 0, 0, 54, 330, 1, 0, 0, 0, 56, 338, 1, 0, 0, 0, 58, 340, 1, 0, 0, 0, 60, 348, 1, 0, 0, 0, 62, 356, 1, 0, 0, 0, 64, 362, 1, 0, 0, 0, 66, 364, 1, 0, 0, 0, 68, 371, 1, 0, 0, 0, 70, 373, 1, 0, 0, 0, 72, 382, 1, 0, 0, 0, 74, 391, 1, 0, 0, 0, 76, 400, 1, 0, 0, 0, 78, 409, 1, 0, 0, 0, 80, 418, 1, 0, 0, 0, 82, 425, 1, 0, 0, 0, 84, 432, 1, 0, 0, 0, 86, 440, 1, 0, 0, 0, 88, 457, 1, 0, 0, 0, 90, 461, 1, 0, 0, 0, 92, 473, 1, 0, 0, 0, 94, 477, 1, 0, 0, 0, 96, 479, 1, 0, 0, 0, 98, 489, 1, 0, 0, 0, 100, 491, 1, 0, 0, 0, 102, 504, 1, 0, 0, 0, 104, 506, 1, 0, 0, 0, 106, 511, 1, 0, 0, 0, 108, 513, 1, 0, 0, 0, 110, 528, 1, 0, 0, 0, 112, 534, 1, 0, 0, 0, 114, 536, 1, 0, 0, 0, 116, 578, 1, 0, 0, 0, 118, 580, 1, 0, 0, 0, 120, 582, 1, 0, 0, 0, 122, 584, 1, 0, 0, 0, 124, 586, 1, 0, 0, 0, 126, 588, 1, 0, 0, 0, 128, 590, 1, 0, 0, 0, 130, 132, 3, 2, 1, 0, 131, 130, 1, 0, 0, 0, 132, 133, 1, 0, 0, 0, 133, 131, 1, 0, 0, 0, 133, 134, 1, 0, 0, 0, 134, 1, 1, 0, 0, 0, 135, 136, 3, 4, 2, 0, 136, 137, 3, 6, 3, 0, 137, 138, 5, 1, 0, 0, 138, 3, 1, 0, 0, 0, 139, 140, 5, 2, 0, 0, 140, 145, 5, 66, 0, 0, 141, 142, 5, 3, 0, 0, 142, 143, 3, 8, 4, 0, 143, 144, 5, 4, 0, 0, 144, 146, 1, 0, 0, 0, 145, 141, 1, 0, 0, 0, 145, 146, 1, 0, 0, 0, 146, 147, 1, 0, 0, 0, 147, 148, 5, 5, 0, 0, 148, 5, 1, 0, 0, 0, 149, 152, 3, 50, 25, 0, 150, 152, 3, 16, 8, 0, 151, 149, 1, 0, 0, 0, 151, 150, 1, 0, 0, 0, 152, 153, 1, 0, 0, 0, 153, 151, 1, 0, 0, 0, 153, 154, 1, 0, 0, 0, 154, 7, 1, 0, 0, 0, 155, 160, 3, 10, 5, 0, 156, 157, 5, 6, 0, 0, 157, 159, 3, 10, 5, 0, 158, 156, 1, 0, 0, 0, 159, 162, 1, 0, 0, 0, 160, 158, 1, 0, 0, 0, 160, 161, 1, 0, 0, 0, 161, 172, 1, 0, 0, 0, 162, 160, 1, 0, 0, 0, 163, 168, 3, 12, 6, 0, 164, 165, 5, 6, 0, 0, 165, 167, 3, 12, 6, 0, 166, 164, 1, 0, 0, 0, 167, 170, 1, 0, 0, 0, 168, 166, 1, 0, 0, 0, 168, 169, 1, 0, 0, 0, 169, 172, 1, 0, 0, 0, 170, 168, 1, 0, 0, 0, 171, 155, 1, 0, 0, 0, 171, 163, 1, 0, 0, 0, 172, 9, 1, 0, 0, 0, 173, 175, 5, 66, 0, 0, 174, 176, 3, 96, 48, 0, 175, 174, 1, 0, 0, 0, 175, 176, 1, 0, 0, 0, 176, 11, 1, 0, 0, 0, 177, 178, 5, 7, 0, 0, 178, 183, 3, 14, 7, 0, 179, 180, 5, 6, 0, 0, 180, 182, 3, 14, 7, 0, 181, 179, 1, 0, 0, 0, 182, 185, 1, 0, 0, 0, 183, 181, 1, 0, 0, 0, 183, 184, 1, 0, 0, 0, 184, 205, 1, 0, 0, 0, 185, 183, 1, 0, 0, 0, 186, 187, 5, 8, 0, 0, 187, 192, 3, 14, 7, 0, 188, 189, 5, 6, 0, 0, 189, 191, 3, 14, 7, 0, 190, 188, 1, 0, 0, 0, 191, 194, 1, 0, 0, 0, 192, 190, 1, 0, 0, 0, 192, 193, 1, 0, 0, 0, 193, 205, 1, 0, 0, 0, 194, 192, 1, 0, 0, 0, 195, 196, 5, 9, 0, 0, 196, 201, 3, 14, 7, 0, 197, 198, 5, 6, 0, 0, 198, 200, 3, 14, 7, 0, 199, 197, 1, 0, 0, 0, 200, 203, 1, 0, 0, 0, 201, 199, 1, 0, 0, 0, 201, 202, 1, 0, 0, 0, 202, 205, 1, 0, 0, 0, 203, 201, 1, 0, 0, 0, 204, 177, 1, 0, 0, 0, 204, 186, 1, 0, 0, 0, 204, 195, 1, 0, 0, 0, 205, 13, 1, 0, 0, 0, 206, 208, 3, 96, 48, 0, 207, 206, 1, 0, 0, 0, 207, 208, 1, 0, 0, 0, 208, 209, 1, 0, 0, 0, 209, 210, 5, 66, 0, 0, 210, 15, 1, 0, 0, 0, 211, 212, 5, 10, 0, 0, 212, 213, 5, 3, 0, 0, 213, 214, 3, 46, 23, 0, 214, 215, 5, 4, 0, 0, 215, 216, 5, 11, 0, 0, 216, 217, 3, 18, 9, 0, 217, 218, 5, 12, 0, 0, 218, 17, 1, 0, 0, 0, 219, 221, 3, 20, 10, 0, 220, 219, 1, 0, 0, 0, 221, 222, 1, 0, 0, 0, 222, 220, 1, 0, 0, 0, 222, 223, 1, 0, 0, 0, 223, 19, 1, 0, 0, 0, 224, 228, 3, 44, 22, 0, 225, 228, 3, 34, 17, 0, 226, 228, 3, 22, 11, 0, 227, 224, 1, 0, 0, 0, 227, 225, 1, 0, 0, 0, 227, 226, 1, 0, 0, 0, 228, 21, 1, 0, 0, 0, 229, 233, 3, 24, 12, 0, 230, 232, 3, 28, 14, 0, 231, 230, 1, 0, 0, 0, 232, 235, 1, 0, 0, 0, 233, 231, 1, 0, 0, 0, 233, 234, 1, 0, 0, 0, 234, 237, 1, 0, 0, 0, 235, 233, 1, 0, 0, 0, 236, 238, 3, 26, 13, 0, 237, 236, 1, 0, 0, 0, 237, 238, 1, 0, 0, 0, 238, 23, 1, 0, 0, 0, 239, 240, 5, 13, 0, 0, 240, 241, 5, 3, 0, 0, 241, 242, 3, 30, 15, 0, 242, 243, 5, 4, 0, 0, 243, 244, 3, 32, 16, 0, 244, 25, 1, 0, 0, 0, 245, 246, 5, 14, 0, 0, 246, 247, 3, 32, 16, 0, 247, 27, 1, 0, 0, 0, 248, 249, 5, 14, 0, 0, 249, 250, 5, 13, 0, 0, 250, 251, 5, 3, 0, 0, 251, 252, 3, 30, 15, 0, 252, 253, 5, 4, 0, 0, 253, 254, 3, 32, 16, 0, 254, 29, 1, 0, 0, 0, 255, 256, 3, 102, 51, 0, 256, 257, 3, 126, 63, 0, 257, 258, 3, 42, 21, 0, 258, 31, 1, 0, 0, 0, 259, 261, 5, 11, 0, 0, 260, 262, 3, 44, 22, 0, 261, 260, 1, 0, 0, 0, 262, 263, 1, 0, 0, 0, 263, 261, 1, 0, 0, 0, 263, 264, 1, 0, 0, 0, 264, 265, 1, 0, 0, 0, 265, 266, 5, 12, 0, 0, 266, 269, 1, 0, 0, 0, 267, 269, 3, 44, 22, 0, 268, 259, 1, 0, 0, 0, 268, 267, 1, 0, 0, 0, 269, 33, 1, 0, 0, 0, 270, 272, 3, 36, 18, 0, 271, 273, 3, 38, 19, 0, 272, 271, 1, 0, 0, 0, 273, 274, 1, 0, 0, 0, 274, 272, 1, 0, 0, 0, 274, 275, 1, 0, 0, 0, 275, 277, 1, 0, 0, 0, 276, 278, 3, 40, 20, 0, 277, 276, 1, 0, 0, 0, 277, 278, 1, 0, 0, 0, 278, 279, 1, 0, 0, 0, 279, 280, 5, 15, 0, 0, 280, 35, 1, 0, 0, 0, 281, 282, 5, 16, 0, 0, 282, 283, 5, 3, 0, 0, 283, 284, 3, 102, 51, 0, 284, 285, 5, 4, 0, 0, 285, 37, 1, 0, 0, 0, 286, 287, 3, 42, 21, 0, 287, 288, 5, 17, 0, 0, 288, 289, 3, 32, 16, 0, 289, 39, 1, 0, 0, 0, 290, 291, 5, 18, 0, 0, 291, 292, 5, 17, 0, 0, 292, 293, 3, 32, 16, 0, 293, 41, 1, 0, 0, 0, 294, 295, 3, 128, 64, 0, 295, 43, 1, 0, 0, 0, 296, 297, 3, 102, 51, 0, 297, 301, 5, 19, 0, 0, 298, 302, 3, 128, 64, 0, 299, 302, 3, 98, 49, 0, 300, 302, 3, 86, 43, 0, 301, 298, 1, 0, 0, 0, 301, 299, 1, 0, 0, 0, 301, 300, 1, 0, 0, 0, 302, 303, 1, 0, 0, 0, 303, 304, 5, 5, 0, 0, 304, 45, 1, 0, 0, 0, 305, 310, 3, 48, 24, 0, 306, 307, 5, 6, 0, 0, 307, 309, 3, 48, 24, 0, 308, 306, 1, 0, 0, 0, 309, 312, 1, 0, 0, 0, 310, 308, 1, 0, 0, 0, 310, 311, 1, 0, 0, 0, 311, 47, 1, 0, 0, 0, 312, 310, 1, 0, 0, 0, 313, 315, 5, 66, 0, 0, 314, 316, 3, 96, 48, 0, 315, 314, 1, 0, 0, 0, 315, 316, 1, 0, 0, 0, 316, 49, 1, 0, 0, 0, 317, 318, 3, 52, 26, 0, 318, 319, 5, 5, 0, 0, 319, 322, 1, 0, 0, 0, 320, 322, 3, 106, 53, 0, 321, 317, 1, 0, 0, 0, 321, 320, 1, 0, 0, 0, 322, 51, 1, 0, 0, 0, 323, 329, 3, 104, 52, 0, 324, 329, 3, 80, 40, 0, 325, 329, 3, 68, 34, 0, 326, 329, 3, 82, 41, 0, 327, 329, 3, 54, 27, 0, 328, 323, 1, 0, 0, 0, 328, 324, 1, 0, 0, 0, 328, 325, 1, 0, 0, 0, 328, 326, 1, 0, 0, 0, 328, 327, 1, 0, 0, 0, 329, 53, 1, 0, 0, 0, 330, 331, 3, 66, 33, 0, 331, 332, 3, 64, 32, 0, 332, 333, 5, 3, 0, 0, 333, 334, 3, 56, 28, 0, 334, 335, 5, 4, 0, 0, 335, 55, 1, 0, 0, 0, 336, 339, 3, 58, 29, 0, 337, 339, 3, 60, 30, 0, 338, 336, 1, 0, 0, 0, 338, 337, 1, 0, 0, 0, 339, 57, 1, 0, 0, 0, 340, 345, 3, 10, 5, 0, 341, 342, 5, 6, 0, 0, 342, 344, 3, 10, 5, 0, 343, 341, 1, 0, 0, 0, 344, 347, 1, 0, 0, 0, 345, 343, 1, 0, 0, 0, 345, 346, 1, 0, 0, 0, 346, 59, 1, 0, 0, 0, 347, 345, 1, 0, 0, 0, 348, 353, 3, 62, 31, 0, 349, 350, 5, 6, 0, 0, 350, 352, 3, 62, 31, 0, 351, 349, 1, 0, 0, 0, 352, 355, 1, 0, 0, 0, 353, 351, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 354, 61, 1, 0, 0, 0, 355, 353, 1, 0, 0, 0, 356, 357, 5, 20, 0, 0, 357, 358, 5, 66, 0, 0, 358, 359, 5, 3, 0, 0, 359, 360, 3, 98, 49, 0, 360, 361, 5, 4, 0, 0, 361, 63, 1, 0, 0, 0, 362, 363, 5, 66, 0, 0, 363, 65, 1, 0, 0, 0, 364, 365, 5, 66, 0, 0, 365, 67, 1, 0, 0, 0, 366, 372, 3, 72, 36, 0, 367, 372, 3, 74, 37, 0, 368, 372, 3, 78, 39, 0, 369, 372, 3, 70, 35, 0, 370, 372, 3, 76, 38, 0, 371, 366, 1, 0, 0, 0, 371, 367, 1, 0, 0, 0, 371, 368, 1, 0, 0, 0, 371, 369, 1, 0, 0, 0, 371, 370, 1, 0, 0, 0, 372, 69, 1, 0, 0, 0, 373, 374, 5, 21, 0, 0, 374, 379, 3, 14, 7, 0, 375, 376, 5, 6, 0, 0, 376, 378, 3, 14, 7, 0, 377, 375, 1, 0, 0, 0, 378, 381, 1, 0, 0, 0, 379, 377, 1, 0, 0, 0, 379, 380, 1, 0, 0, 0, 380, 71, 1, 0, 0, 0, 381, 379, 1, 0, 0, 0, 382, 383, 5, 22, 0, 0, 383, 388, 3, 14, 7, 0, 384, 385, 5, 6, 0, 0, 385, 387, 3, 14, 7, 0, 386, 384, 1, 0, 0, 0, 387, 390, 1, 0, 0, 0, 388, 386, 1, 0, 0, 0, 388, 389, 1, 0, 0, 0, 389, 73, 1, 0, 0, 0, 390, 388, 1, 0, 0, 0, 391, 392, 5, 23, 0, 0, 392, 397, 3, 14, 7, 0, 393, 394, 5, 6, 0, 0, 394, 396, 3, 14, 7, 0, 395, 393, 1, 0, 0, 0, 396, 399, 1, 0, 0, 0, 397, 395, 1, 0, 0, 0, 397, 398, 1, 0, 0, 0, 398, 75, 1, 0, 0, 0, 399, 397, 1, 0, 0, 0, 400, 401, 5, 24, 0, 0, 401, 406, 3, 14, 7, 0, 402, 403, 5, 6, 0, 0, 403, 405, 3, 14, 7, 0, 404, 402, 1, 0, 0, 0, 405, 408, 1, 0, 0, 0, 406, 404, 1, 0, 0, 0, 406, 407, 1, 0, 0, 0, 407, 77, 1, 0, 0, 0, 408, 406, 1, 0, 0, 0, 409, 410, 5, 25, 0, 0, 410, 415, 3, 82, 41, 0, 411, 412, 5, 6, 0, 0, 412, 414, 3, 82, 41, 0, 413, 411, 1, 0, 0, 0, 414, 417, 1, 0, 0, 0, 415, 413, 1, 0, 0, 0, 415, 416, 1, 0, 0, 0, 416, 79, 1, 0, 0, 0, 417, 415, 1, 0, 0, 0, 418, 419, 5, 26, 0, 0, 419, 420, 3, 102, 51, 0, 420, 423, 5, 27, 0, 0, 421, 424, 3, 84, 42, 0, 422, 424, 3, 86, 43, 0, 423, 421, 1, 0, 0, 0, 423, 422, 1, 0, 0, 0, 424, 81, 1, 0, 0, 0, 425, 426, 5, 66, 0, 0, 426, 429, 5, 27, 0, 0, 427, 430, 3, 84, 42, 0, 428, 430, 3, 86, 43, 0, 429, 427, 1, 0, 0, 0, 429, 428, 1, 0, 0, 0, 430, 83, 1, 0, 0, 0, 431, 433, 3, 120, 60, 0, 432, 431, 1, 0, 0, 0, 432, 433, 1, 0, 0, 0, 433, 434, 1, 0, 0, 0, 434, 435, 5, 3, 0, 0, 435, 436, 3, 86, 43, 0, 436, 437, 5, 4, 0, 0, 437, 85, 1, 0, 0, 0, 438, 441, 3, 84, 42, 0, 439, 441, 3, 88, 44, 0, 440, 438, 1, 0, 0, 0, 440, 439, 1, 0, 0, 0, 441, 449, 1, 0, 0, 0, 442, 445, 3, 122, 61, 0, 443, 446, 3, 84, 42, 0, 444, 446, 3, 88, 44, 0, 445, 443, 1, 0, 0, 0, 445, 444, 1, 0, 0, 0, 446, 448, 1, 0, 0, 0, 447, 442, 1, 0, 0, 0, 448, 451, 1, 0, 0, 0, 449, 447, 1, 0, 0, 0, 449, 450, 1, 0, 0, 0, 450, 87, 1, 0, 0, 0, 451, 449, 1, 0, 0, 0, 452, 454, 3, 120, 60, 0, 453, 452, 1, 0, 0, 0, 453, 454, 1, 0, 0, 0, 454, 455, 1, 0, 0, 0, 455, 458, 3, 98, 49, 0, 456, 458, 3, 128, 64, 0, 457, 453, 1, 0, 0, 0, 457, 456, 1, 0, 0, 0, 458, 89, 1, 0, 0, 0, 459, 462, 3, 84, 42, 0, 460, 462, 3, 88, 44, 0, 461, 459, 1, 0, 0, 0, 461, 460, 1, 0, 0, 0, 462, 470, 1, 0, 0, 0, 463, 466, 3, 122, 61, 0, 464, 467, 3, 84, 42, 0, 465, 467, 3, 88, 44, 0, 466, 464, 1, 0, 0, 0, 466, 465, 1, 0, 0, 0, 467, 469, 1, 0, 0, 0, 468, 463, 1, 0, 0, 0, 469, 472, 1, 0, 0, 0, 470, 468, 1, 0, 0, 0, 470, 471, 1, 0, 0, 0, 471, 91, 1, 0, 0, 0, 472, 470, 1, 0, 0, 0, 473, 474, 3, 90, 45, 0, 474, 475, 3, 126, 63, 0, 475, 476, 3, 94, 47, 0, 476, 93, 1, 0, 0, 0, 477, 478, 3, 128, 64, 0, 478, 95, 1, 0, 0, 0, 479, 480, 5, 28, 0, 0, 480, 483, 5, 72, 0, 0, 481, 482, 5, 17, 0, 0, 482, 484, 5, 72, 0, 0, 483, 481, 1, 0, 0, 0, 483, 484, 1, 0, 0, 0, 484, 485, 1, 0, 0, 0, 485, 486, 5, 29, 0, 0, 486, 97, 1, 0, 0, 0, 487, 490, 3, 10, 5, 0, 488, 490, 3, 100, 50, 0, 489, 487, 1, 0, 0, 0, 489, 488, 1, 0, 0, 0, 490, 99, 1, 0, 0, 0, 491, 492, 5, 30, 0, 0, 492, 497, 3, 10, 5, 0, 493, 494, 5, 6, 0, 0, 494, 496, 3, 10, 5, 0, 495, 493, 1, 0, 0, 0, 496, 499, 1, 0, 0, 0, 497, 495, 1, 0, 0, 0, 497, 498, 1, 0, 0, 0, 498, 500, 1, 0, 0, 0, 499, 497, 1, 0, 0, 0, 500, 502, 5, 31, 0, 0, 501, 503, 3, 96, 48, 0, 502, 501, 1, 0, 0, 0, 502, 503, 1, 0, 0, 0, 503, 101, 1, 0, 0, 0, 504, 505, 3, 98, 49, 0, 505, 103, 1, 0, 0, 0, 506, 507, 3, 12, 6, 0, 507, 105, 1, 0, 0, 0, 508, 512, 3, 114, 57, 0, 509, 512, 3, 108, 54, 0, 510, 512, 3, 110, 55, 0, 511, 508, 1, 0, 0, 0, 511, 509, 1, 0, 0, 0, 511, 510, 1, 0, 0, 0, 512, 107, 1, 0, 0, 0, 513, 514, 5, 32, 0, 0, 514, 516, 5, 33, 0, 0, 515, 517, 5, 66, 0, 0, 516, 515, 1, 0, 0, 0, 517, 518, 1, 0, 0, 0, 518, 516, 1, 0, 0, 0, 518, 519, 1, 0, 0, 0, 519, 520, 1, 0, 0, 0, 520, 521, 5, 33, 0, 0, 521, 524, 5, 33, 0, 0, 522, 525, 3, 112, 56, 0, 523, 525, 7, 0, 0, 0, 524, 522, 1, 0, 0, 0, 524, 523, 1, 0, 0, 0, 525, 526, 1, 0, 0, 0, 526, 527, 5, 33, 0, 0, 527, 109, 1, 0, 0, 0, 528, 529, 5, 34, 0, 0, 529, 530, 5, 66, 0, 0, 530, 531, 5, 66, 0, 0, 531, 111, 1, 0, 0, 0, 532, 535, 3, 122, 61, 0, 533, 535, 3, 120, 60, 0, 534, 532, 1, 0, 0, 0, 534, 533, 1, 0, 0, 0, 535, 113, 1, 0, 0, 0, 536, 537, 5, 35, 0, 0, 537, 538, 5, 33, 0, 0, 538, 539, 3, 112, 56, 0, 539, 540, 5, 33, 0, 0, 540, 545, 3, 116, 58, 0, 541, 542, 7, 1, 0, 0, 542, 544, 3, 116, 58, 0, 543, 541, 1, 0, 0, 0, 544, 547, 1, 0, 0, 0, 545, 543, 1, 0, 0, 0, 545, 546, 1, 0, 0, 0, 546, 115, 1, 0, 0, 0, 547, 545, 1, 0, 0, 0, 548, 549, 5, 66, 0, 0, 549, 550, 5, 27, 0, 0, 550, 552, 3, 128, 64, 0, 551, 553, 3, 118, 59, 0, 552, 551, 1, 0, 0, 0, 552, 553, 1, 0, 0, 0, 553, 579, 1, 0, 0, 0, 554, 555, 5, 66, 0, 0, 555, 556, 5, 38, 0, 0, 556, 558, 3, 128, 64, 0, 557, 559, 3, 118, 59, 0, 558, 557, 1, 0, 0, 0, 558, 559, 1, 0, 0, 0, 559, 579, 1, 0, 0, 0, 560, 561, 5, 66, 0, 0, 561, 562, 5, 39, 0, 0, 562, 564, 3, 128, 64, 0, 563, 565, 3, 118, 59, 0, 564, 563, 1, 0, 0, 0, 564, 565, 1, 0, 0, 0, 565, 579, 1, 0, 0, 0, 566, 567, 5, 66, 0, 0, 567, 568, 5, 40, 0, 0, 568, 570, 3, 128, 64, 0, 569, 571, 3, 118, 59, 0, 570, 569, 1, 0, 0, 0, 570, 571, 1, 0, 0, 0, 571, 579, 1, 0, 0, 0, 572, 573, 5, 66, 0, 0, 573, 574, 5, 19, 0, 0, 574, 576, 3, 128, 64, 0, 575, 577, 3, 118, 59, 0, 576, 575, 1, 0, 0, 0, 576, 577, 1, 0, 0, 0, 577, 579, 1, 0, 0, 0, 578, 548, 1, 0, 0, 0, 578, 554, 1, 0, 0, 0, 578, 560, 1, 0, 0, 0, 578, 566, 1, 0, 0, 0, 578, 572, 1, 0, 0, 0, 579, 117, 1, 0, 0, 0, 580, 581, 5, 66, 0, 0, 581, 119, 1, 0, 0, 0, 582, 583, 7, 2, 0, 0, 583, 121, 1, 0, 0, 0, 584, 585, 7, 3, 0, 0, 585, 123, 1, 0, 0, 0, 586, 587, 7, 4, 0, 0, 587, 125, 1, 0, 0, 0, 588, 589, 7, 5, 0, 0, 589, 127, 1, 0, 0, 0, 590, 591, 7, 6, 0, 0, 591, 129, 1, 0, 0, 0, 61, 133, 145, 151, 153, 160, 168, 171, 175, 183, 192, 201, 204, 207, 222, 227, 233, 237, 263, 268, 274, 277, 301, 310, 315, 321, 328, 338, 345, 353, 371, 379, 388, 397, 406, 415, 423, 429, 432, 440, 445, 449, 453, 457, 461, 466, 470, 483, 489, 497, 502, 511, 518, 524, 534, 545, 552, 558, 564, 570, 576, 578]
\ No newline at end of file
diff --git a/lfr/antlrgen/lfrX.tokens b/lfr/antlrgen/lfr/lfrX.tokens
similarity index 100%
rename from lfr/antlrgen/lfrX.tokens
rename to lfr/antlrgen/lfr/lfrX.tokens
diff --git a/lfr/antlrgen/lfr/lfrXLexer.interp b/lfr/antlrgen/lfr/lfrXLexer.interp
new file mode 100755
index 0000000..f408e7a
--- /dev/null
+++ b/lfr/antlrgen/lfr/lfrXLexer.interp
@@ -0,0 +1,260 @@
+token literal names:
+null
+'endmodule'
+'module'
+'('
+')'
+';'
+','
+'finput'
+'foutput'
+'control'
+'distribute@'
+'begin'
+'end'
+'if'
+'else'
+'endcase'
+'case'
+':'
+'default'
+'<='
+'.'
+'signal'
+'flow'
+'storage'
+'pump'
+'number'
+'assign'
+'='
+'['
+']'
+'{'
+'}'
+'#MAP'
+'"'
+'#MATERIAL'
+'#CONSTRAIN'
+'AND'
+'OR'
+'>'
+'<'
+'>='
+'+'
+'-'
+'!'
+'~'
+'&'
+'~&'
+'|'
+'~|'
+'^'
+'~^'
+'^~'
+'*'
+'/'
+'%'
+'=='
+'!='
+'==='
+'!=='
+'&&'
+'||'
+'**'
+'>>'
+'<<'
+'>>>'
+'<<<'
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+ID
+WS
+One_line_comment
+Block_comment
+Import_line
+Real_number
+Decimal_number
+Binary_number
+Octal_number
+Hex_number
+
+rule names:
+T__0
+T__1
+T__2
+T__3
+T__4
+T__5
+T__6
+T__7
+T__8
+T__9
+T__10
+T__11
+T__12
+T__13
+T__14
+T__15
+T__16
+T__17
+T__18
+T__19
+T__20
+T__21
+T__22
+T__23
+T__24
+T__25
+T__26
+T__27
+T__28
+T__29
+T__30
+T__31
+T__32
+T__33
+T__34
+T__35
+T__36
+T__37
+T__38
+T__39
+T__40
+T__41
+T__42
+T__43
+T__44
+T__45
+T__46
+T__47
+T__48
+T__49
+T__50
+T__51
+T__52
+T__53
+T__54
+T__55
+T__56
+T__57
+T__58
+T__59
+T__60
+T__61
+T__62
+T__63
+T__64
+ID
+WS
+One_line_comment
+Block_comment
+Import_line
+Real_number
+Decimal_number
+Binary_number
+Octal_number
+Hex_number
+Sign
+Size
+Non_zero_unsigned_number
+Unsigned_number
+Binary_value
+Octal_value
+Hex_value
+Decimal_base
+Binary_base
+Octal_base
+Hex_base
+Non_zero_decimal_digit
+Decimal_digit
+Binary_digit
+Octal_digit
+Hex_digit
+X_digit
+Z_digit
+
+channel names:
+DEFAULT_TOKEN_CHANNEL
+HIDDEN
+
+mode names:
+DEFAULT_MODE
+
+atn:
+[4, 0, 75, 668, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 42, 1, 42, 1, 43, 1, 43, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 52, 1, 52, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 5, 65, 456, 8, 65, 10, 65, 12, 65, 459, 9, 65, 1, 66, 4, 66, 462, 8, 66, 11, 66, 12, 66, 463, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 67, 5, 67, 472, 8, 67, 10, 67, 12, 67, 475, 9, 67, 1, 67, 3, 67, 478, 8, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, 1, 68, 5, 68, 488, 8, 68, 10, 68, 12, 68, 491, 9, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 69, 1, 69, 5, 69, 500, 8, 69, 10, 69, 12, 69, 503, 9, 69, 1, 69, 3, 69, 506, 8, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 3, 70, 519, 8, 70, 1, 70, 1, 70, 3, 70, 523, 8, 70, 1, 70, 1, 70, 3, 70, 527, 8, 70, 1, 71, 1, 71, 3, 71, 531, 8, 71, 1, 71, 1, 71, 1, 71, 1, 71, 3, 71, 537, 8, 71, 1, 71, 1, 71, 1, 71, 5, 71, 542, 8, 71, 10, 71, 12, 71, 545, 9, 71, 1, 71, 3, 71, 548, 8, 71, 1, 71, 1, 71, 1, 71, 5, 71, 553, 8, 71, 10, 71, 12, 71, 556, 9, 71, 3, 71, 558, 8, 71, 1, 72, 3, 72, 561, 8, 72, 1, 72, 1, 72, 1, 72, 1, 73, 3, 73, 567, 8, 73, 1, 73, 1, 73, 1, 73, 1, 74, 3, 74, 573, 8, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 76, 1, 76, 1, 77, 1, 77, 1, 77, 5, 77, 585, 8, 77, 10, 77, 12, 77, 588, 9, 77, 1, 78, 1, 78, 1, 78, 5, 78, 593, 8, 78, 10, 78, 12, 78, 596, 9, 78, 1, 79, 1, 79, 1, 79, 5, 79, 601, 8, 79, 10, 79, 12, 79, 604, 9, 79, 1, 80, 1, 80, 1, 80, 5, 80, 609, 8, 80, 10, 80, 12, 80, 612, 9, 80, 1, 81, 1, 81, 1, 81, 5, 81, 617, 8, 81, 10, 81, 12, 81, 620, 9, 81, 1, 82, 1, 82, 3, 82, 624, 8, 82, 1, 82, 1, 82, 1, 83, 1, 83, 3, 83, 630, 8, 83, 1, 83, 1, 83, 1, 84, 1, 84, 3, 84, 636, 8, 84, 1, 84, 1, 84, 1, 85, 1, 85, 3, 85, 642, 8, 85, 1, 85, 1, 85, 1, 86, 1, 86, 1, 87, 1, 87, 1, 88, 1, 88, 1, 88, 3, 88, 653, 8, 88, 1, 89, 1, 89, 1, 89, 3, 89, 658, 8, 89, 1, 90, 1, 90, 1, 90, 3, 90, 663, 8, 90, 1, 91, 1, 91, 1, 92, 1, 92, 3, 473, 489, 501, 0, 93, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44, 89, 45, 91, 46, 93, 47, 95, 48, 97, 49, 99, 50, 101, 51, 103, 52, 105, 53, 107, 54, 109, 55, 111, 56, 113, 57, 115, 58, 117, 59, 119, 60, 121, 61, 123, 62, 125, 63, 127, 64, 129, 65, 131, 66, 133, 67, 135, 68, 137, 69, 139, 70, 141, 71, 143, 72, 145, 73, 147, 74, 149, 75, 151, 0, 153, 0, 155, 0, 157, 0, 159, 0, 161, 0, 163, 0, 165, 0, 167, 0, 169, 0, 171, 0, 173, 0, 175, 0, 177, 0, 179, 0, 181, 0, 183, 0, 185, 0, 1, 0, 17, 3, 0, 65, 90, 95, 95, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 3, 0, 9, 10, 13, 13, 32, 32, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 2, 0, 83, 83, 115, 115, 2, 0, 68, 68, 100, 100, 2, 0, 66, 66, 98, 98, 2, 0, 79, 79, 111, 111, 2, 0, 72, 72, 104, 104, 1, 0, 49, 57, 1, 0, 48, 57, 1, 0, 48, 49, 1, 0, 48, 55, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 88, 88, 120, 120, 3, 0, 63, 63, 90, 90, 122, 122, 690, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, 0, 111, 1, 0, 0, 0, 0, 113, 1, 0, 0, 0, 0, 115, 1, 0, 0, 0, 0, 117, 1, 0, 0, 0, 0, 119, 1, 0, 0, 0, 0, 121, 1, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 125, 1, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 129, 1, 0, 0, 0, 0, 131, 1, 0, 0, 0, 0, 133, 1, 0, 0, 0, 0, 135, 1, 0, 0, 0, 0, 137, 1, 0, 0, 0, 0, 139, 1, 0, 0, 0, 0, 141, 1, 0, 0, 0, 0, 143, 1, 0, 0, 0, 0, 145, 1, 0, 0, 0, 0, 147, 1, 0, 0, 0, 0, 149, 1, 0, 0, 0, 1, 187, 1, 0, 0, 0, 3, 197, 1, 0, 0, 0, 5, 204, 1, 0, 0, 0, 7, 206, 1, 0, 0, 0, 9, 208, 1, 0, 0, 0, 11, 210, 1, 0, 0, 0, 13, 212, 1, 0, 0, 0, 15, 219, 1, 0, 0, 0, 17, 227, 1, 0, 0, 0, 19, 235, 1, 0, 0, 0, 21, 247, 1, 0, 0, 0, 23, 253, 1, 0, 0, 0, 25, 257, 1, 0, 0, 0, 27, 260, 1, 0, 0, 0, 29, 265, 1, 0, 0, 0, 31, 273, 1, 0, 0, 0, 33, 278, 1, 0, 0, 0, 35, 280, 1, 0, 0, 0, 37, 288, 1, 0, 0, 0, 39, 291, 1, 0, 0, 0, 41, 293, 1, 0, 0, 0, 43, 300, 1, 0, 0, 0, 45, 305, 1, 0, 0, 0, 47, 313, 1, 0, 0, 0, 49, 318, 1, 0, 0, 0, 51, 325, 1, 0, 0, 0, 53, 332, 1, 0, 0, 0, 55, 334, 1, 0, 0, 0, 57, 336, 1, 0, 0, 0, 59, 338, 1, 0, 0, 0, 61, 340, 1, 0, 0, 0, 63, 342, 1, 0, 0, 0, 65, 347, 1, 0, 0, 0, 67, 349, 1, 0, 0, 0, 69, 359, 1, 0, 0, 0, 71, 370, 1, 0, 0, 0, 73, 374, 1, 0, 0, 0, 75, 377, 1, 0, 0, 0, 77, 379, 1, 0, 0, 0, 79, 381, 1, 0, 0, 0, 81, 384, 1, 0, 0, 0, 83, 386, 1, 0, 0, 0, 85, 388, 1, 0, 0, 0, 87, 390, 1, 0, 0, 0, 89, 392, 1, 0, 0, 0, 91, 394, 1, 0, 0, 0, 93, 397, 1, 0, 0, 0, 95, 399, 1, 0, 0, 0, 97, 402, 1, 0, 0, 0, 99, 404, 1, 0, 0, 0, 101, 407, 1, 0, 0, 0, 103, 410, 1, 0, 0, 0, 105, 412, 1, 0, 0, 0, 107, 414, 1, 0, 0, 0, 109, 416, 1, 0, 0, 0, 111, 419, 1, 0, 0, 0, 113, 422, 1, 0, 0, 0, 115, 426, 1, 0, 0, 0, 117, 430, 1, 0, 0, 0, 119, 433, 1, 0, 0, 0, 121, 436, 1, 0, 0, 0, 123, 439, 1, 0, 0, 0, 125, 442, 1, 0, 0, 0, 127, 445, 1, 0, 0, 0, 129, 449, 1, 0, 0, 0, 131, 453, 1, 0, 0, 0, 133, 461, 1, 0, 0, 0, 135, 467, 1, 0, 0, 0, 137, 483, 1, 0, 0, 0, 139, 497, 1, 0, 0, 0, 141, 526, 1, 0, 0, 0, 143, 557, 1, 0, 0, 0, 145, 560, 1, 0, 0, 0, 147, 566, 1, 0, 0, 0, 149, 572, 1, 0, 0, 0, 151, 577, 1, 0, 0, 0, 153, 579, 1, 0, 0, 0, 155, 581, 1, 0, 0, 0, 157, 589, 1, 0, 0, 0, 159, 597, 1, 0, 0, 0, 161, 605, 1, 0, 0, 0, 163, 613, 1, 0, 0, 0, 165, 621, 1, 0, 0, 0, 167, 627, 1, 0, 0, 0, 169, 633, 1, 0, 0, 0, 171, 639, 1, 0, 0, 0, 173, 645, 1, 0, 0, 0, 175, 647, 1, 0, 0, 0, 177, 652, 1, 0, 0, 0, 179, 657, 1, 0, 0, 0, 181, 662, 1, 0, 0, 0, 183, 664, 1, 0, 0, 0, 185, 666, 1, 0, 0, 0, 187, 188, 5, 101, 0, 0, 188, 189, 5, 110, 0, 0, 189, 190, 5, 100, 0, 0, 190, 191, 5, 109, 0, 0, 191, 192, 5, 111, 0, 0, 192, 193, 5, 100, 0, 0, 193, 194, 5, 117, 0, 0, 194, 195, 5, 108, 0, 0, 195, 196, 5, 101, 0, 0, 196, 2, 1, 0, 0, 0, 197, 198, 5, 109, 0, 0, 198, 199, 5, 111, 0, 0, 199, 200, 5, 100, 0, 0, 200, 201, 5, 117, 0, 0, 201, 202, 5, 108, 0, 0, 202, 203, 5, 101, 0, 0, 203, 4, 1, 0, 0, 0, 204, 205, 5, 40, 0, 0, 205, 6, 1, 0, 0, 0, 206, 207, 5, 41, 0, 0, 207, 8, 1, 0, 0, 0, 208, 209, 5, 59, 0, 0, 209, 10, 1, 0, 0, 0, 210, 211, 5, 44, 0, 0, 211, 12, 1, 0, 0, 0, 212, 213, 5, 102, 0, 0, 213, 214, 5, 105, 0, 0, 214, 215, 5, 110, 0, 0, 215, 216, 5, 112, 0, 0, 216, 217, 5, 117, 0, 0, 217, 218, 5, 116, 0, 0, 218, 14, 1, 0, 0, 0, 219, 220, 5, 102, 0, 0, 220, 221, 5, 111, 0, 0, 221, 222, 5, 117, 0, 0, 222, 223, 5, 116, 0, 0, 223, 224, 5, 112, 0, 0, 224, 225, 5, 117, 0, 0, 225, 226, 5, 116, 0, 0, 226, 16, 1, 0, 0, 0, 227, 228, 5, 99, 0, 0, 228, 229, 5, 111, 0, 0, 229, 230, 5, 110, 0, 0, 230, 231, 5, 116, 0, 0, 231, 232, 5, 114, 0, 0, 232, 233, 5, 111, 0, 0, 233, 234, 5, 108, 0, 0, 234, 18, 1, 0, 0, 0, 235, 236, 5, 100, 0, 0, 236, 237, 5, 105, 0, 0, 237, 238, 5, 115, 0, 0, 238, 239, 5, 116, 0, 0, 239, 240, 5, 114, 0, 0, 240, 241, 5, 105, 0, 0, 241, 242, 5, 98, 0, 0, 242, 243, 5, 117, 0, 0, 243, 244, 5, 116, 0, 0, 244, 245, 5, 101, 0, 0, 245, 246, 5, 64, 0, 0, 246, 20, 1, 0, 0, 0, 247, 248, 5, 98, 0, 0, 248, 249, 5, 101, 0, 0, 249, 250, 5, 103, 0, 0, 250, 251, 5, 105, 0, 0, 251, 252, 5, 110, 0, 0, 252, 22, 1, 0, 0, 0, 253, 254, 5, 101, 0, 0, 254, 255, 5, 110, 0, 0, 255, 256, 5, 100, 0, 0, 256, 24, 1, 0, 0, 0, 257, 258, 5, 105, 0, 0, 258, 259, 5, 102, 0, 0, 259, 26, 1, 0, 0, 0, 260, 261, 5, 101, 0, 0, 261, 262, 5, 108, 0, 0, 262, 263, 5, 115, 0, 0, 263, 264, 5, 101, 0, 0, 264, 28, 1, 0, 0, 0, 265, 266, 5, 101, 0, 0, 266, 267, 5, 110, 0, 0, 267, 268, 5, 100, 0, 0, 268, 269, 5, 99, 0, 0, 269, 270, 5, 97, 0, 0, 270, 271, 5, 115, 0, 0, 271, 272, 5, 101, 0, 0, 272, 30, 1, 0, 0, 0, 273, 274, 5, 99, 0, 0, 274, 275, 5, 97, 0, 0, 275, 276, 5, 115, 0, 0, 276, 277, 5, 101, 0, 0, 277, 32, 1, 0, 0, 0, 278, 279, 5, 58, 0, 0, 279, 34, 1, 0, 0, 0, 280, 281, 5, 100, 0, 0, 281, 282, 5, 101, 0, 0, 282, 283, 5, 102, 0, 0, 283, 284, 5, 97, 0, 0, 284, 285, 5, 117, 0, 0, 285, 286, 5, 108, 0, 0, 286, 287, 5, 116, 0, 0, 287, 36, 1, 0, 0, 0, 288, 289, 5, 60, 0, 0, 289, 290, 5, 61, 0, 0, 290, 38, 1, 0, 0, 0, 291, 292, 5, 46, 0, 0, 292, 40, 1, 0, 0, 0, 293, 294, 5, 115, 0, 0, 294, 295, 5, 105, 0, 0, 295, 296, 5, 103, 0, 0, 296, 297, 5, 110, 0, 0, 297, 298, 5, 97, 0, 0, 298, 299, 5, 108, 0, 0, 299, 42, 1, 0, 0, 0, 300, 301, 5, 102, 0, 0, 301, 302, 5, 108, 0, 0, 302, 303, 5, 111, 0, 0, 303, 304, 5, 119, 0, 0, 304, 44, 1, 0, 0, 0, 305, 306, 5, 115, 0, 0, 306, 307, 5, 116, 0, 0, 307, 308, 5, 111, 0, 0, 308, 309, 5, 114, 0, 0, 309, 310, 5, 97, 0, 0, 310, 311, 5, 103, 0, 0, 311, 312, 5, 101, 0, 0, 312, 46, 1, 0, 0, 0, 313, 314, 5, 112, 0, 0, 314, 315, 5, 117, 0, 0, 315, 316, 5, 109, 0, 0, 316, 317, 5, 112, 0, 0, 317, 48, 1, 0, 0, 0, 318, 319, 5, 110, 0, 0, 319, 320, 5, 117, 0, 0, 320, 321, 5, 109, 0, 0, 321, 322, 5, 98, 0, 0, 322, 323, 5, 101, 0, 0, 323, 324, 5, 114, 0, 0, 324, 50, 1, 0, 0, 0, 325, 326, 5, 97, 0, 0, 326, 327, 5, 115, 0, 0, 327, 328, 5, 115, 0, 0, 328, 329, 5, 105, 0, 0, 329, 330, 5, 103, 0, 0, 330, 331, 5, 110, 0, 0, 331, 52, 1, 0, 0, 0, 332, 333, 5, 61, 0, 0, 333, 54, 1, 0, 0, 0, 334, 335, 5, 91, 0, 0, 335, 56, 1, 0, 0, 0, 336, 337, 5, 93, 0, 0, 337, 58, 1, 0, 0, 0, 338, 339, 5, 123, 0, 0, 339, 60, 1, 0, 0, 0, 340, 341, 5, 125, 0, 0, 341, 62, 1, 0, 0, 0, 342, 343, 5, 35, 0, 0, 343, 344, 5, 77, 0, 0, 344, 345, 5, 65, 0, 0, 345, 346, 5, 80, 0, 0, 346, 64, 1, 0, 0, 0, 347, 348, 5, 34, 0, 0, 348, 66, 1, 0, 0, 0, 349, 350, 5, 35, 0, 0, 350, 351, 5, 77, 0, 0, 351, 352, 5, 65, 0, 0, 352, 353, 5, 84, 0, 0, 353, 354, 5, 69, 0, 0, 354, 355, 5, 82, 0, 0, 355, 356, 5, 73, 0, 0, 356, 357, 5, 65, 0, 0, 357, 358, 5, 76, 0, 0, 358, 68, 1, 0, 0, 0, 359, 360, 5, 35, 0, 0, 360, 361, 5, 67, 0, 0, 361, 362, 5, 79, 0, 0, 362, 363, 5, 78, 0, 0, 363, 364, 5, 83, 0, 0, 364, 365, 5, 84, 0, 0, 365, 366, 5, 82, 0, 0, 366, 367, 5, 65, 0, 0, 367, 368, 5, 73, 0, 0, 368, 369, 5, 78, 0, 0, 369, 70, 1, 0, 0, 0, 370, 371, 5, 65, 0, 0, 371, 372, 5, 78, 0, 0, 372, 373, 5, 68, 0, 0, 373, 72, 1, 0, 0, 0, 374, 375, 5, 79, 0, 0, 375, 376, 5, 82, 0, 0, 376, 74, 1, 0, 0, 0, 377, 378, 5, 62, 0, 0, 378, 76, 1, 0, 0, 0, 379, 380, 5, 60, 0, 0, 380, 78, 1, 0, 0, 0, 381, 382, 5, 62, 0, 0, 382, 383, 5, 61, 0, 0, 383, 80, 1, 0, 0, 0, 384, 385, 5, 43, 0, 0, 385, 82, 1, 0, 0, 0, 386, 387, 5, 45, 0, 0, 387, 84, 1, 0, 0, 0, 388, 389, 5, 33, 0, 0, 389, 86, 1, 0, 0, 0, 390, 391, 5, 126, 0, 0, 391, 88, 1, 0, 0, 0, 392, 393, 5, 38, 0, 0, 393, 90, 1, 0, 0, 0, 394, 395, 5, 126, 0, 0, 395, 396, 5, 38, 0, 0, 396, 92, 1, 0, 0, 0, 397, 398, 5, 124, 0, 0, 398, 94, 1, 0, 0, 0, 399, 400, 5, 126, 0, 0, 400, 401, 5, 124, 0, 0, 401, 96, 1, 0, 0, 0, 402, 403, 5, 94, 0, 0, 403, 98, 1, 0, 0, 0, 404, 405, 5, 126, 0, 0, 405, 406, 5, 94, 0, 0, 406, 100, 1, 0, 0, 0, 407, 408, 5, 94, 0, 0, 408, 409, 5, 126, 0, 0, 409, 102, 1, 0, 0, 0, 410, 411, 5, 42, 0, 0, 411, 104, 1, 0, 0, 0, 412, 413, 5, 47, 0, 0, 413, 106, 1, 0, 0, 0, 414, 415, 5, 37, 0, 0, 415, 108, 1, 0, 0, 0, 416, 417, 5, 61, 0, 0, 417, 418, 5, 61, 0, 0, 418, 110, 1, 0, 0, 0, 419, 420, 5, 33, 0, 0, 420, 421, 5, 61, 0, 0, 421, 112, 1, 0, 0, 0, 422, 423, 5, 61, 0, 0, 423, 424, 5, 61, 0, 0, 424, 425, 5, 61, 0, 0, 425, 114, 1, 0, 0, 0, 426, 427, 5, 33, 0, 0, 427, 428, 5, 61, 0, 0, 428, 429, 5, 61, 0, 0, 429, 116, 1, 0, 0, 0, 430, 431, 5, 38, 0, 0, 431, 432, 5, 38, 0, 0, 432, 118, 1, 0, 0, 0, 433, 434, 5, 124, 0, 0, 434, 435, 5, 124, 0, 0, 435, 120, 1, 0, 0, 0, 436, 437, 5, 42, 0, 0, 437, 438, 5, 42, 0, 0, 438, 122, 1, 0, 0, 0, 439, 440, 5, 62, 0, 0, 440, 441, 5, 62, 0, 0, 441, 124, 1, 0, 0, 0, 442, 443, 5, 60, 0, 0, 443, 444, 5, 60, 0, 0, 444, 126, 1, 0, 0, 0, 445, 446, 5, 62, 0, 0, 446, 447, 5, 62, 0, 0, 447, 448, 5, 62, 0, 0, 448, 128, 1, 0, 0, 0, 449, 450, 5, 60, 0, 0, 450, 451, 5, 60, 0, 0, 451, 452, 5, 60, 0, 0, 452, 130, 1, 0, 0, 0, 453, 457, 7, 0, 0, 0, 454, 456, 7, 1, 0, 0, 455, 454, 1, 0, 0, 0, 456, 459, 1, 0, 0, 0, 457, 455, 1, 0, 0, 0, 457, 458, 1, 0, 0, 0, 458, 132, 1, 0, 0, 0, 459, 457, 1, 0, 0, 0, 460, 462, 7, 2, 0, 0, 461, 460, 1, 0, 0, 0, 462, 463, 1, 0, 0, 0, 463, 461, 1, 0, 0, 0, 463, 464, 1, 0, 0, 0, 464, 465, 1, 0, 0, 0, 465, 466, 6, 66, 0, 0, 466, 134, 1, 0, 0, 0, 467, 468, 5, 47, 0, 0, 468, 469, 5, 47, 0, 0, 469, 473, 1, 0, 0, 0, 470, 472, 9, 0, 0, 0, 471, 470, 1, 0, 0, 0, 472, 475, 1, 0, 0, 0, 473, 474, 1, 0, 0, 0, 473, 471, 1, 0, 0, 0, 474, 477, 1, 0, 0, 0, 475, 473, 1, 0, 0, 0, 476, 478, 5, 13, 0, 0, 477, 476, 1, 0, 0, 0, 477, 478, 1, 0, 0, 0, 478, 479, 1, 0, 0, 0, 479, 480, 5, 10, 0, 0, 480, 481, 1, 0, 0, 0, 481, 482, 6, 67, 1, 0, 482, 136, 1, 0, 0, 0, 483, 484, 5, 47, 0, 0, 484, 485, 5, 42, 0, 0, 485, 489, 1, 0, 0, 0, 486, 488, 9, 0, 0, 0, 487, 486, 1, 0, 0, 0, 488, 491, 1, 0, 0, 0, 489, 490, 1, 0, 0, 0, 489, 487, 1, 0, 0, 0, 490, 492, 1, 0, 0, 0, 491, 489, 1, 0, 0, 0, 492, 493, 5, 42, 0, 0, 493, 494, 5, 47, 0, 0, 494, 495, 1, 0, 0, 0, 495, 496, 6, 68, 1, 0, 496, 138, 1, 0, 0, 0, 497, 501, 5, 96, 0, 0, 498, 500, 9, 0, 0, 0, 499, 498, 1, 0, 0, 0, 500, 503, 1, 0, 0, 0, 501, 502, 1, 0, 0, 0, 501, 499, 1, 0, 0, 0, 502, 505, 1, 0, 0, 0, 503, 501, 1, 0, 0, 0, 504, 506, 5, 13, 0, 0, 505, 504, 1, 0, 0, 0, 505, 506, 1, 0, 0, 0, 506, 507, 1, 0, 0, 0, 507, 508, 5, 10, 0, 0, 508, 509, 1, 0, 0, 0, 509, 510, 6, 69, 1, 0, 510, 140, 1, 0, 0, 0, 511, 512, 3, 157, 78, 0, 512, 513, 5, 46, 0, 0, 513, 514, 3, 157, 78, 0, 514, 527, 1, 0, 0, 0, 515, 518, 3, 157, 78, 0, 516, 517, 5, 46, 0, 0, 517, 519, 3, 157, 78, 0, 518, 516, 1, 0, 0, 0, 518, 519, 1, 0, 0, 0, 519, 520, 1, 0, 0, 0, 520, 522, 7, 3, 0, 0, 521, 523, 7, 4, 0, 0, 522, 521, 1, 0, 0, 0, 522, 523, 1, 0, 0, 0, 523, 524, 1, 0, 0, 0, 524, 525, 3, 157, 78, 0, 525, 527, 1, 0, 0, 0, 526, 511, 1, 0, 0, 0, 526, 515, 1, 0, 0, 0, 527, 142, 1, 0, 0, 0, 528, 558, 3, 157, 78, 0, 529, 531, 3, 153, 76, 0, 530, 529, 1, 0, 0, 0, 530, 531, 1, 0, 0, 0, 531, 532, 1, 0, 0, 0, 532, 533, 3, 165, 82, 0, 533, 534, 3, 157, 78, 0, 534, 558, 1, 0, 0, 0, 535, 537, 3, 153, 76, 0, 536, 535, 1, 0, 0, 0, 536, 537, 1, 0, 0, 0, 537, 538, 1, 0, 0, 0, 538, 539, 3, 165, 82, 0, 539, 543, 3, 183, 91, 0, 540, 542, 5, 95, 0, 0, 541, 540, 1, 0, 0, 0, 542, 545, 1, 0, 0, 0, 543, 541, 1, 0, 0, 0, 543, 544, 1, 0, 0, 0, 544, 558, 1, 0, 0, 0, 545, 543, 1, 0, 0, 0, 546, 548, 3, 153, 76, 0, 547, 546, 1, 0, 0, 0, 547, 548, 1, 0, 0, 0, 548, 549, 1, 0, 0, 0, 549, 550, 3, 165, 82, 0, 550, 554, 3, 185, 92, 0, 551, 553, 5, 95, 0, 0, 552, 551, 1, 0, 0, 0, 553, 556, 1, 0, 0, 0, 554, 552, 1, 0, 0, 0, 554, 555, 1, 0, 0, 0, 555, 558, 1, 0, 0, 0, 556, 554, 1, 0, 0, 0, 557, 528, 1, 0, 0, 0, 557, 530, 1, 0, 0, 0, 557, 536, 1, 0, 0, 0, 557, 547, 1, 0, 0, 0, 558, 144, 1, 0, 0, 0, 559, 561, 3, 153, 76, 0, 560, 559, 1, 0, 0, 0, 560, 561, 1, 0, 0, 0, 561, 562, 1, 0, 0, 0, 562, 563, 3, 167, 83, 0, 563, 564, 3, 159, 79, 0, 564, 146, 1, 0, 0, 0, 565, 567, 3, 153, 76, 0, 566, 565, 1, 0, 0, 0, 566, 567, 1, 0, 0, 0, 567, 568, 1, 0, 0, 0, 568, 569, 3, 169, 84, 0, 569, 570, 3, 161, 80, 0, 570, 148, 1, 0, 0, 0, 571, 573, 3, 153, 76, 0, 572, 571, 1, 0, 0, 0, 572, 573, 1, 0, 0, 0, 573, 574, 1, 0, 0, 0, 574, 575, 3, 171, 85, 0, 575, 576, 3, 163, 81, 0, 576, 150, 1, 0, 0, 0, 577, 578, 7, 4, 0, 0, 578, 152, 1, 0, 0, 0, 579, 580, 3, 155, 77, 0, 580, 154, 1, 0, 0, 0, 581, 586, 3, 173, 86, 0, 582, 585, 5, 95, 0, 0, 583, 585, 3, 175, 87, 0, 584, 582, 1, 0, 0, 0, 584, 583, 1, 0, 0, 0, 585, 588, 1, 0, 0, 0, 586, 584, 1, 0, 0, 0, 586, 587, 1, 0, 0, 0, 587, 156, 1, 0, 0, 0, 588, 586, 1, 0, 0, 0, 589, 594, 3, 175, 87, 0, 590, 593, 5, 95, 0, 0, 591, 593, 3, 175, 87, 0, 592, 590, 1, 0, 0, 0, 592, 591, 1, 0, 0, 0, 593, 596, 1, 0, 0, 0, 594, 592, 1, 0, 0, 0, 594, 595, 1, 0, 0, 0, 595, 158, 1, 0, 0, 0, 596, 594, 1, 0, 0, 0, 597, 602, 3, 177, 88, 0, 598, 601, 5, 95, 0, 0, 599, 601, 3, 177, 88, 0, 600, 598, 1, 0, 0, 0, 600, 599, 1, 0, 0, 0, 601, 604, 1, 0, 0, 0, 602, 600, 1, 0, 0, 0, 602, 603, 1, 0, 0, 0, 603, 160, 1, 0, 0, 0, 604, 602, 1, 0, 0, 0, 605, 610, 3, 179, 89, 0, 606, 609, 5, 95, 0, 0, 607, 609, 3, 179, 89, 0, 608, 606, 1, 0, 0, 0, 608, 607, 1, 0, 0, 0, 609, 612, 1, 0, 0, 0, 610, 608, 1, 0, 0, 0, 610, 611, 1, 0, 0, 0, 611, 162, 1, 0, 0, 0, 612, 610, 1, 0, 0, 0, 613, 618, 3, 181, 90, 0, 614, 617, 5, 95, 0, 0, 615, 617, 3, 181, 90, 0, 616, 614, 1, 0, 0, 0, 616, 615, 1, 0, 0, 0, 617, 620, 1, 0, 0, 0, 618, 616, 1, 0, 0, 0, 618, 619, 1, 0, 0, 0, 619, 164, 1, 0, 0, 0, 620, 618, 1, 0, 0, 0, 621, 623, 5, 39, 0, 0, 622, 624, 7, 5, 0, 0, 623, 622, 1, 0, 0, 0, 623, 624, 1, 0, 0, 0, 624, 625, 1, 0, 0, 0, 625, 626, 7, 6, 0, 0, 626, 166, 1, 0, 0, 0, 627, 629, 5, 39, 0, 0, 628, 630, 7, 5, 0, 0, 629, 628, 1, 0, 0, 0, 629, 630, 1, 0, 0, 0, 630, 631, 1, 0, 0, 0, 631, 632, 7, 7, 0, 0, 632, 168, 1, 0, 0, 0, 633, 635, 5, 39, 0, 0, 634, 636, 7, 5, 0, 0, 635, 634, 1, 0, 0, 0, 635, 636, 1, 0, 0, 0, 636, 637, 1, 0, 0, 0, 637, 638, 7, 8, 0, 0, 638, 170, 1, 0, 0, 0, 639, 641, 5, 39, 0, 0, 640, 642, 7, 5, 0, 0, 641, 640, 1, 0, 0, 0, 641, 642, 1, 0, 0, 0, 642, 643, 1, 0, 0, 0, 643, 644, 7, 9, 0, 0, 644, 172, 1, 0, 0, 0, 645, 646, 7, 10, 0, 0, 646, 174, 1, 0, 0, 0, 647, 648, 7, 11, 0, 0, 648, 176, 1, 0, 0, 0, 649, 653, 3, 183, 91, 0, 650, 653, 3, 185, 92, 0, 651, 653, 7, 12, 0, 0, 652, 649, 1, 0, 0, 0, 652, 650, 1, 0, 0, 0, 652, 651, 1, 0, 0, 0, 653, 178, 1, 0, 0, 0, 654, 658, 3, 183, 91, 0, 655, 658, 3, 185, 92, 0, 656, 658, 7, 13, 0, 0, 657, 654, 1, 0, 0, 0, 657, 655, 1, 0, 0, 0, 657, 656, 1, 0, 0, 0, 658, 180, 1, 0, 0, 0, 659, 663, 3, 183, 91, 0, 660, 663, 3, 185, 92, 0, 661, 663, 7, 14, 0, 0, 662, 659, 1, 0, 0, 0, 662, 660, 1, 0, 0, 0, 662, 661, 1, 0, 0, 0, 663, 182, 1, 0, 0, 0, 664, 665, 7, 15, 0, 0, 665, 184, 1, 0, 0, 0, 666, 667, 7, 16, 0, 0, 667, 186, 1, 0, 0, 0, 37, 0, 457, 463, 473, 477, 489, 501, 505, 518, 522, 526, 530, 536, 543, 547, 554, 557, 560, 566, 572, 584, 586, 592, 594, 600, 602, 608, 610, 616, 618, 623, 629, 635, 641, 652, 657, 662, 2, 6, 0, 0, 0, 1, 0]
\ No newline at end of file
diff --git a/lfr/antlrgen/lfr/lfrXLexer.py b/lfr/antlrgen/lfr/lfrXLexer.py
new file mode 100755
index 0000000..394e348
--- /dev/null
+++ b/lfr/antlrgen/lfr/lfrXLexer.py
@@ -0,0 +1,6161 @@
+# Generated from ./lfrX.g4 by ANTLR 4.10.1
+import sys
+from io import StringIO
+
+from antlr4 import *
+
+if sys.version_info[1] > 5:
+ from typing import TextIO
+else:
+ from typing.io import TextIO
+
+
+def serializedATN():
+ return [
+ 4,
+ 0,
+ 75,
+ 668,
+ 6,
+ -1,
+ 2,
+ 0,
+ 7,
+ 0,
+ 2,
+ 1,
+ 7,
+ 1,
+ 2,
+ 2,
+ 7,
+ 2,
+ 2,
+ 3,
+ 7,
+ 3,
+ 2,
+ 4,
+ 7,
+ 4,
+ 2,
+ 5,
+ 7,
+ 5,
+ 2,
+ 6,
+ 7,
+ 6,
+ 2,
+ 7,
+ 7,
+ 7,
+ 2,
+ 8,
+ 7,
+ 8,
+ 2,
+ 9,
+ 7,
+ 9,
+ 2,
+ 10,
+ 7,
+ 10,
+ 2,
+ 11,
+ 7,
+ 11,
+ 2,
+ 12,
+ 7,
+ 12,
+ 2,
+ 13,
+ 7,
+ 13,
+ 2,
+ 14,
+ 7,
+ 14,
+ 2,
+ 15,
+ 7,
+ 15,
+ 2,
+ 16,
+ 7,
+ 16,
+ 2,
+ 17,
+ 7,
+ 17,
+ 2,
+ 18,
+ 7,
+ 18,
+ 2,
+ 19,
+ 7,
+ 19,
+ 2,
+ 20,
+ 7,
+ 20,
+ 2,
+ 21,
+ 7,
+ 21,
+ 2,
+ 22,
+ 7,
+ 22,
+ 2,
+ 23,
+ 7,
+ 23,
+ 2,
+ 24,
+ 7,
+ 24,
+ 2,
+ 25,
+ 7,
+ 25,
+ 2,
+ 26,
+ 7,
+ 26,
+ 2,
+ 27,
+ 7,
+ 27,
+ 2,
+ 28,
+ 7,
+ 28,
+ 2,
+ 29,
+ 7,
+ 29,
+ 2,
+ 30,
+ 7,
+ 30,
+ 2,
+ 31,
+ 7,
+ 31,
+ 2,
+ 32,
+ 7,
+ 32,
+ 2,
+ 33,
+ 7,
+ 33,
+ 2,
+ 34,
+ 7,
+ 34,
+ 2,
+ 35,
+ 7,
+ 35,
+ 2,
+ 36,
+ 7,
+ 36,
+ 2,
+ 37,
+ 7,
+ 37,
+ 2,
+ 38,
+ 7,
+ 38,
+ 2,
+ 39,
+ 7,
+ 39,
+ 2,
+ 40,
+ 7,
+ 40,
+ 2,
+ 41,
+ 7,
+ 41,
+ 2,
+ 42,
+ 7,
+ 42,
+ 2,
+ 43,
+ 7,
+ 43,
+ 2,
+ 44,
+ 7,
+ 44,
+ 2,
+ 45,
+ 7,
+ 45,
+ 2,
+ 46,
+ 7,
+ 46,
+ 2,
+ 47,
+ 7,
+ 47,
+ 2,
+ 48,
+ 7,
+ 48,
+ 2,
+ 49,
+ 7,
+ 49,
+ 2,
+ 50,
+ 7,
+ 50,
+ 2,
+ 51,
+ 7,
+ 51,
+ 2,
+ 52,
+ 7,
+ 52,
+ 2,
+ 53,
+ 7,
+ 53,
+ 2,
+ 54,
+ 7,
+ 54,
+ 2,
+ 55,
+ 7,
+ 55,
+ 2,
+ 56,
+ 7,
+ 56,
+ 2,
+ 57,
+ 7,
+ 57,
+ 2,
+ 58,
+ 7,
+ 58,
+ 2,
+ 59,
+ 7,
+ 59,
+ 2,
+ 60,
+ 7,
+ 60,
+ 2,
+ 61,
+ 7,
+ 61,
+ 2,
+ 62,
+ 7,
+ 62,
+ 2,
+ 63,
+ 7,
+ 63,
+ 2,
+ 64,
+ 7,
+ 64,
+ 2,
+ 65,
+ 7,
+ 65,
+ 2,
+ 66,
+ 7,
+ 66,
+ 2,
+ 67,
+ 7,
+ 67,
+ 2,
+ 68,
+ 7,
+ 68,
+ 2,
+ 69,
+ 7,
+ 69,
+ 2,
+ 70,
+ 7,
+ 70,
+ 2,
+ 71,
+ 7,
+ 71,
+ 2,
+ 72,
+ 7,
+ 72,
+ 2,
+ 73,
+ 7,
+ 73,
+ 2,
+ 74,
+ 7,
+ 74,
+ 2,
+ 75,
+ 7,
+ 75,
+ 2,
+ 76,
+ 7,
+ 76,
+ 2,
+ 77,
+ 7,
+ 77,
+ 2,
+ 78,
+ 7,
+ 78,
+ 2,
+ 79,
+ 7,
+ 79,
+ 2,
+ 80,
+ 7,
+ 80,
+ 2,
+ 81,
+ 7,
+ 81,
+ 2,
+ 82,
+ 7,
+ 82,
+ 2,
+ 83,
+ 7,
+ 83,
+ 2,
+ 84,
+ 7,
+ 84,
+ 2,
+ 85,
+ 7,
+ 85,
+ 2,
+ 86,
+ 7,
+ 86,
+ 2,
+ 87,
+ 7,
+ 87,
+ 2,
+ 88,
+ 7,
+ 88,
+ 2,
+ 89,
+ 7,
+ 89,
+ 2,
+ 90,
+ 7,
+ 90,
+ 2,
+ 91,
+ 7,
+ 91,
+ 2,
+ 92,
+ 7,
+ 92,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 5,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 7,
+ 1,
+ 7,
+ 1,
+ 7,
+ 1,
+ 7,
+ 1,
+ 7,
+ 1,
+ 7,
+ 1,
+ 7,
+ 1,
+ 7,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 9,
+ 1,
+ 9,
+ 1,
+ 9,
+ 1,
+ 9,
+ 1,
+ 9,
+ 1,
+ 9,
+ 1,
+ 9,
+ 1,
+ 9,
+ 1,
+ 9,
+ 1,
+ 9,
+ 1,
+ 9,
+ 1,
+ 9,
+ 1,
+ 10,
+ 1,
+ 10,
+ 1,
+ 10,
+ 1,
+ 10,
+ 1,
+ 10,
+ 1,
+ 10,
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 12,
+ 1,
+ 12,
+ 1,
+ 12,
+ 1,
+ 13,
+ 1,
+ 13,
+ 1,
+ 13,
+ 1,
+ 13,
+ 1,
+ 13,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 15,
+ 1,
+ 15,
+ 1,
+ 15,
+ 1,
+ 15,
+ 1,
+ 15,
+ 1,
+ 16,
+ 1,
+ 16,
+ 1,
+ 17,
+ 1,
+ 17,
+ 1,
+ 17,
+ 1,
+ 17,
+ 1,
+ 17,
+ 1,
+ 17,
+ 1,
+ 17,
+ 1,
+ 17,
+ 1,
+ 18,
+ 1,
+ 18,
+ 1,
+ 18,
+ 1,
+ 19,
+ 1,
+ 19,
+ 1,
+ 20,
+ 1,
+ 20,
+ 1,
+ 20,
+ 1,
+ 20,
+ 1,
+ 20,
+ 1,
+ 20,
+ 1,
+ 20,
+ 1,
+ 21,
+ 1,
+ 21,
+ 1,
+ 21,
+ 1,
+ 21,
+ 1,
+ 21,
+ 1,
+ 22,
+ 1,
+ 22,
+ 1,
+ 22,
+ 1,
+ 22,
+ 1,
+ 22,
+ 1,
+ 22,
+ 1,
+ 22,
+ 1,
+ 22,
+ 1,
+ 23,
+ 1,
+ 23,
+ 1,
+ 23,
+ 1,
+ 23,
+ 1,
+ 23,
+ 1,
+ 24,
+ 1,
+ 24,
+ 1,
+ 24,
+ 1,
+ 24,
+ 1,
+ 24,
+ 1,
+ 24,
+ 1,
+ 24,
+ 1,
+ 25,
+ 1,
+ 25,
+ 1,
+ 25,
+ 1,
+ 25,
+ 1,
+ 25,
+ 1,
+ 25,
+ 1,
+ 25,
+ 1,
+ 26,
+ 1,
+ 26,
+ 1,
+ 27,
+ 1,
+ 27,
+ 1,
+ 28,
+ 1,
+ 28,
+ 1,
+ 29,
+ 1,
+ 29,
+ 1,
+ 30,
+ 1,
+ 30,
+ 1,
+ 31,
+ 1,
+ 31,
+ 1,
+ 31,
+ 1,
+ 31,
+ 1,
+ 31,
+ 1,
+ 32,
+ 1,
+ 32,
+ 1,
+ 33,
+ 1,
+ 33,
+ 1,
+ 33,
+ 1,
+ 33,
+ 1,
+ 33,
+ 1,
+ 33,
+ 1,
+ 33,
+ 1,
+ 33,
+ 1,
+ 33,
+ 1,
+ 33,
+ 1,
+ 34,
+ 1,
+ 34,
+ 1,
+ 34,
+ 1,
+ 34,
+ 1,
+ 34,
+ 1,
+ 34,
+ 1,
+ 34,
+ 1,
+ 34,
+ 1,
+ 34,
+ 1,
+ 34,
+ 1,
+ 34,
+ 1,
+ 35,
+ 1,
+ 35,
+ 1,
+ 35,
+ 1,
+ 35,
+ 1,
+ 36,
+ 1,
+ 36,
+ 1,
+ 36,
+ 1,
+ 37,
+ 1,
+ 37,
+ 1,
+ 38,
+ 1,
+ 38,
+ 1,
+ 39,
+ 1,
+ 39,
+ 1,
+ 39,
+ 1,
+ 40,
+ 1,
+ 40,
+ 1,
+ 41,
+ 1,
+ 41,
+ 1,
+ 42,
+ 1,
+ 42,
+ 1,
+ 43,
+ 1,
+ 43,
+ 1,
+ 44,
+ 1,
+ 44,
+ 1,
+ 45,
+ 1,
+ 45,
+ 1,
+ 45,
+ 1,
+ 46,
+ 1,
+ 46,
+ 1,
+ 47,
+ 1,
+ 47,
+ 1,
+ 47,
+ 1,
+ 48,
+ 1,
+ 48,
+ 1,
+ 49,
+ 1,
+ 49,
+ 1,
+ 49,
+ 1,
+ 50,
+ 1,
+ 50,
+ 1,
+ 50,
+ 1,
+ 51,
+ 1,
+ 51,
+ 1,
+ 52,
+ 1,
+ 52,
+ 1,
+ 53,
+ 1,
+ 53,
+ 1,
+ 54,
+ 1,
+ 54,
+ 1,
+ 54,
+ 1,
+ 55,
+ 1,
+ 55,
+ 1,
+ 55,
+ 1,
+ 56,
+ 1,
+ 56,
+ 1,
+ 56,
+ 1,
+ 56,
+ 1,
+ 57,
+ 1,
+ 57,
+ 1,
+ 57,
+ 1,
+ 57,
+ 1,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 1,
+ 59,
+ 1,
+ 59,
+ 1,
+ 59,
+ 1,
+ 60,
+ 1,
+ 60,
+ 1,
+ 60,
+ 1,
+ 61,
+ 1,
+ 61,
+ 1,
+ 61,
+ 1,
+ 62,
+ 1,
+ 62,
+ 1,
+ 62,
+ 1,
+ 63,
+ 1,
+ 63,
+ 1,
+ 63,
+ 1,
+ 63,
+ 1,
+ 64,
+ 1,
+ 64,
+ 1,
+ 64,
+ 1,
+ 64,
+ 1,
+ 65,
+ 1,
+ 65,
+ 5,
+ 65,
+ 456,
+ 8,
+ 65,
+ 10,
+ 65,
+ 12,
+ 65,
+ 459,
+ 9,
+ 65,
+ 1,
+ 66,
+ 4,
+ 66,
+ 462,
+ 8,
+ 66,
+ 11,
+ 66,
+ 12,
+ 66,
+ 463,
+ 1,
+ 66,
+ 1,
+ 66,
+ 1,
+ 67,
+ 1,
+ 67,
+ 1,
+ 67,
+ 1,
+ 67,
+ 5,
+ 67,
+ 472,
+ 8,
+ 67,
+ 10,
+ 67,
+ 12,
+ 67,
+ 475,
+ 9,
+ 67,
+ 1,
+ 67,
+ 3,
+ 67,
+ 478,
+ 8,
+ 67,
+ 1,
+ 67,
+ 1,
+ 67,
+ 1,
+ 67,
+ 1,
+ 67,
+ 1,
+ 68,
+ 1,
+ 68,
+ 1,
+ 68,
+ 1,
+ 68,
+ 5,
+ 68,
+ 488,
+ 8,
+ 68,
+ 10,
+ 68,
+ 12,
+ 68,
+ 491,
+ 9,
+ 68,
+ 1,
+ 68,
+ 1,
+ 68,
+ 1,
+ 68,
+ 1,
+ 68,
+ 1,
+ 68,
+ 1,
+ 69,
+ 1,
+ 69,
+ 5,
+ 69,
+ 500,
+ 8,
+ 69,
+ 10,
+ 69,
+ 12,
+ 69,
+ 503,
+ 9,
+ 69,
+ 1,
+ 69,
+ 3,
+ 69,
+ 506,
+ 8,
+ 69,
+ 1,
+ 69,
+ 1,
+ 69,
+ 1,
+ 69,
+ 1,
+ 69,
+ 1,
+ 70,
+ 1,
+ 70,
+ 1,
+ 70,
+ 1,
+ 70,
+ 1,
+ 70,
+ 1,
+ 70,
+ 1,
+ 70,
+ 3,
+ 70,
+ 519,
+ 8,
+ 70,
+ 1,
+ 70,
+ 1,
+ 70,
+ 3,
+ 70,
+ 523,
+ 8,
+ 70,
+ 1,
+ 70,
+ 1,
+ 70,
+ 3,
+ 70,
+ 527,
+ 8,
+ 70,
+ 1,
+ 71,
+ 1,
+ 71,
+ 3,
+ 71,
+ 531,
+ 8,
+ 71,
+ 1,
+ 71,
+ 1,
+ 71,
+ 1,
+ 71,
+ 1,
+ 71,
+ 3,
+ 71,
+ 537,
+ 8,
+ 71,
+ 1,
+ 71,
+ 1,
+ 71,
+ 1,
+ 71,
+ 5,
+ 71,
+ 542,
+ 8,
+ 71,
+ 10,
+ 71,
+ 12,
+ 71,
+ 545,
+ 9,
+ 71,
+ 1,
+ 71,
+ 3,
+ 71,
+ 548,
+ 8,
+ 71,
+ 1,
+ 71,
+ 1,
+ 71,
+ 1,
+ 71,
+ 5,
+ 71,
+ 553,
+ 8,
+ 71,
+ 10,
+ 71,
+ 12,
+ 71,
+ 556,
+ 9,
+ 71,
+ 3,
+ 71,
+ 558,
+ 8,
+ 71,
+ 1,
+ 72,
+ 3,
+ 72,
+ 561,
+ 8,
+ 72,
+ 1,
+ 72,
+ 1,
+ 72,
+ 1,
+ 72,
+ 1,
+ 73,
+ 3,
+ 73,
+ 567,
+ 8,
+ 73,
+ 1,
+ 73,
+ 1,
+ 73,
+ 1,
+ 73,
+ 1,
+ 74,
+ 3,
+ 74,
+ 573,
+ 8,
+ 74,
+ 1,
+ 74,
+ 1,
+ 74,
+ 1,
+ 74,
+ 1,
+ 75,
+ 1,
+ 75,
+ 1,
+ 76,
+ 1,
+ 76,
+ 1,
+ 77,
+ 1,
+ 77,
+ 1,
+ 77,
+ 5,
+ 77,
+ 585,
+ 8,
+ 77,
+ 10,
+ 77,
+ 12,
+ 77,
+ 588,
+ 9,
+ 77,
+ 1,
+ 78,
+ 1,
+ 78,
+ 1,
+ 78,
+ 5,
+ 78,
+ 593,
+ 8,
+ 78,
+ 10,
+ 78,
+ 12,
+ 78,
+ 596,
+ 9,
+ 78,
+ 1,
+ 79,
+ 1,
+ 79,
+ 1,
+ 79,
+ 5,
+ 79,
+ 601,
+ 8,
+ 79,
+ 10,
+ 79,
+ 12,
+ 79,
+ 604,
+ 9,
+ 79,
+ 1,
+ 80,
+ 1,
+ 80,
+ 1,
+ 80,
+ 5,
+ 80,
+ 609,
+ 8,
+ 80,
+ 10,
+ 80,
+ 12,
+ 80,
+ 612,
+ 9,
+ 80,
+ 1,
+ 81,
+ 1,
+ 81,
+ 1,
+ 81,
+ 5,
+ 81,
+ 617,
+ 8,
+ 81,
+ 10,
+ 81,
+ 12,
+ 81,
+ 620,
+ 9,
+ 81,
+ 1,
+ 82,
+ 1,
+ 82,
+ 3,
+ 82,
+ 624,
+ 8,
+ 82,
+ 1,
+ 82,
+ 1,
+ 82,
+ 1,
+ 83,
+ 1,
+ 83,
+ 3,
+ 83,
+ 630,
+ 8,
+ 83,
+ 1,
+ 83,
+ 1,
+ 83,
+ 1,
+ 84,
+ 1,
+ 84,
+ 3,
+ 84,
+ 636,
+ 8,
+ 84,
+ 1,
+ 84,
+ 1,
+ 84,
+ 1,
+ 85,
+ 1,
+ 85,
+ 3,
+ 85,
+ 642,
+ 8,
+ 85,
+ 1,
+ 85,
+ 1,
+ 85,
+ 1,
+ 86,
+ 1,
+ 86,
+ 1,
+ 87,
+ 1,
+ 87,
+ 1,
+ 88,
+ 1,
+ 88,
+ 1,
+ 88,
+ 3,
+ 88,
+ 653,
+ 8,
+ 88,
+ 1,
+ 89,
+ 1,
+ 89,
+ 1,
+ 89,
+ 3,
+ 89,
+ 658,
+ 8,
+ 89,
+ 1,
+ 90,
+ 1,
+ 90,
+ 1,
+ 90,
+ 3,
+ 90,
+ 663,
+ 8,
+ 90,
+ 1,
+ 91,
+ 1,
+ 91,
+ 1,
+ 92,
+ 1,
+ 92,
+ 3,
+ 473,
+ 489,
+ 501,
+ 0,
+ 93,
+ 1,
+ 1,
+ 3,
+ 2,
+ 5,
+ 3,
+ 7,
+ 4,
+ 9,
+ 5,
+ 11,
+ 6,
+ 13,
+ 7,
+ 15,
+ 8,
+ 17,
+ 9,
+ 19,
+ 10,
+ 21,
+ 11,
+ 23,
+ 12,
+ 25,
+ 13,
+ 27,
+ 14,
+ 29,
+ 15,
+ 31,
+ 16,
+ 33,
+ 17,
+ 35,
+ 18,
+ 37,
+ 19,
+ 39,
+ 20,
+ 41,
+ 21,
+ 43,
+ 22,
+ 45,
+ 23,
+ 47,
+ 24,
+ 49,
+ 25,
+ 51,
+ 26,
+ 53,
+ 27,
+ 55,
+ 28,
+ 57,
+ 29,
+ 59,
+ 30,
+ 61,
+ 31,
+ 63,
+ 32,
+ 65,
+ 33,
+ 67,
+ 34,
+ 69,
+ 35,
+ 71,
+ 36,
+ 73,
+ 37,
+ 75,
+ 38,
+ 77,
+ 39,
+ 79,
+ 40,
+ 81,
+ 41,
+ 83,
+ 42,
+ 85,
+ 43,
+ 87,
+ 44,
+ 89,
+ 45,
+ 91,
+ 46,
+ 93,
+ 47,
+ 95,
+ 48,
+ 97,
+ 49,
+ 99,
+ 50,
+ 101,
+ 51,
+ 103,
+ 52,
+ 105,
+ 53,
+ 107,
+ 54,
+ 109,
+ 55,
+ 111,
+ 56,
+ 113,
+ 57,
+ 115,
+ 58,
+ 117,
+ 59,
+ 119,
+ 60,
+ 121,
+ 61,
+ 123,
+ 62,
+ 125,
+ 63,
+ 127,
+ 64,
+ 129,
+ 65,
+ 131,
+ 66,
+ 133,
+ 67,
+ 135,
+ 68,
+ 137,
+ 69,
+ 139,
+ 70,
+ 141,
+ 71,
+ 143,
+ 72,
+ 145,
+ 73,
+ 147,
+ 74,
+ 149,
+ 75,
+ 151,
+ 0,
+ 153,
+ 0,
+ 155,
+ 0,
+ 157,
+ 0,
+ 159,
+ 0,
+ 161,
+ 0,
+ 163,
+ 0,
+ 165,
+ 0,
+ 167,
+ 0,
+ 169,
+ 0,
+ 171,
+ 0,
+ 173,
+ 0,
+ 175,
+ 0,
+ 177,
+ 0,
+ 179,
+ 0,
+ 181,
+ 0,
+ 183,
+ 0,
+ 185,
+ 0,
+ 1,
+ 0,
+ 17,
+ 3,
+ 0,
+ 65,
+ 90,
+ 95,
+ 95,
+ 97,
+ 122,
+ 4,
+ 0,
+ 48,
+ 57,
+ 65,
+ 90,
+ 95,
+ 95,
+ 97,
+ 122,
+ 3,
+ 0,
+ 9,
+ 10,
+ 13,
+ 13,
+ 32,
+ 32,
+ 2,
+ 0,
+ 69,
+ 69,
+ 101,
+ 101,
+ 2,
+ 0,
+ 43,
+ 43,
+ 45,
+ 45,
+ 2,
+ 0,
+ 83,
+ 83,
+ 115,
+ 115,
+ 2,
+ 0,
+ 68,
+ 68,
+ 100,
+ 100,
+ 2,
+ 0,
+ 66,
+ 66,
+ 98,
+ 98,
+ 2,
+ 0,
+ 79,
+ 79,
+ 111,
+ 111,
+ 2,
+ 0,
+ 72,
+ 72,
+ 104,
+ 104,
+ 1,
+ 0,
+ 49,
+ 57,
+ 1,
+ 0,
+ 48,
+ 57,
+ 1,
+ 0,
+ 48,
+ 49,
+ 1,
+ 0,
+ 48,
+ 55,
+ 3,
+ 0,
+ 48,
+ 57,
+ 65,
+ 70,
+ 97,
+ 102,
+ 2,
+ 0,
+ 88,
+ 88,
+ 120,
+ 120,
+ 3,
+ 0,
+ 63,
+ 63,
+ 90,
+ 90,
+ 122,
+ 122,
+ 690,
+ 0,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 5,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 7,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 9,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 11,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 13,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 15,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 17,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 19,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 21,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 23,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 25,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 27,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 29,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 31,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 33,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 35,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 37,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 39,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 41,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 43,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 45,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 47,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 49,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 51,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 53,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 55,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 57,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 59,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 61,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 63,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 65,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 67,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 69,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 71,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 73,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 75,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 77,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 79,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 81,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 83,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 85,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 87,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 89,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 91,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 93,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 95,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 97,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 99,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 101,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 103,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 105,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 107,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 109,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 111,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 113,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 115,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 117,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 119,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 121,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 123,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 125,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 127,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 129,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 131,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 133,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 135,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 137,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 139,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 141,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 143,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 145,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 147,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 149,
+ 1,
+ 0,
+ 0,
+ 0,
+ 1,
+ 187,
+ 1,
+ 0,
+ 0,
+ 0,
+ 3,
+ 197,
+ 1,
+ 0,
+ 0,
+ 0,
+ 5,
+ 204,
+ 1,
+ 0,
+ 0,
+ 0,
+ 7,
+ 206,
+ 1,
+ 0,
+ 0,
+ 0,
+ 9,
+ 208,
+ 1,
+ 0,
+ 0,
+ 0,
+ 11,
+ 210,
+ 1,
+ 0,
+ 0,
+ 0,
+ 13,
+ 212,
+ 1,
+ 0,
+ 0,
+ 0,
+ 15,
+ 219,
+ 1,
+ 0,
+ 0,
+ 0,
+ 17,
+ 227,
+ 1,
+ 0,
+ 0,
+ 0,
+ 19,
+ 235,
+ 1,
+ 0,
+ 0,
+ 0,
+ 21,
+ 247,
+ 1,
+ 0,
+ 0,
+ 0,
+ 23,
+ 253,
+ 1,
+ 0,
+ 0,
+ 0,
+ 25,
+ 257,
+ 1,
+ 0,
+ 0,
+ 0,
+ 27,
+ 260,
+ 1,
+ 0,
+ 0,
+ 0,
+ 29,
+ 265,
+ 1,
+ 0,
+ 0,
+ 0,
+ 31,
+ 273,
+ 1,
+ 0,
+ 0,
+ 0,
+ 33,
+ 278,
+ 1,
+ 0,
+ 0,
+ 0,
+ 35,
+ 280,
+ 1,
+ 0,
+ 0,
+ 0,
+ 37,
+ 288,
+ 1,
+ 0,
+ 0,
+ 0,
+ 39,
+ 291,
+ 1,
+ 0,
+ 0,
+ 0,
+ 41,
+ 293,
+ 1,
+ 0,
+ 0,
+ 0,
+ 43,
+ 300,
+ 1,
+ 0,
+ 0,
+ 0,
+ 45,
+ 305,
+ 1,
+ 0,
+ 0,
+ 0,
+ 47,
+ 313,
+ 1,
+ 0,
+ 0,
+ 0,
+ 49,
+ 318,
+ 1,
+ 0,
+ 0,
+ 0,
+ 51,
+ 325,
+ 1,
+ 0,
+ 0,
+ 0,
+ 53,
+ 332,
+ 1,
+ 0,
+ 0,
+ 0,
+ 55,
+ 334,
+ 1,
+ 0,
+ 0,
+ 0,
+ 57,
+ 336,
+ 1,
+ 0,
+ 0,
+ 0,
+ 59,
+ 338,
+ 1,
+ 0,
+ 0,
+ 0,
+ 61,
+ 340,
+ 1,
+ 0,
+ 0,
+ 0,
+ 63,
+ 342,
+ 1,
+ 0,
+ 0,
+ 0,
+ 65,
+ 347,
+ 1,
+ 0,
+ 0,
+ 0,
+ 67,
+ 349,
+ 1,
+ 0,
+ 0,
+ 0,
+ 69,
+ 359,
+ 1,
+ 0,
+ 0,
+ 0,
+ 71,
+ 370,
+ 1,
+ 0,
+ 0,
+ 0,
+ 73,
+ 374,
+ 1,
+ 0,
+ 0,
+ 0,
+ 75,
+ 377,
+ 1,
+ 0,
+ 0,
+ 0,
+ 77,
+ 379,
+ 1,
+ 0,
+ 0,
+ 0,
+ 79,
+ 381,
+ 1,
+ 0,
+ 0,
+ 0,
+ 81,
+ 384,
+ 1,
+ 0,
+ 0,
+ 0,
+ 83,
+ 386,
+ 1,
+ 0,
+ 0,
+ 0,
+ 85,
+ 388,
+ 1,
+ 0,
+ 0,
+ 0,
+ 87,
+ 390,
+ 1,
+ 0,
+ 0,
+ 0,
+ 89,
+ 392,
+ 1,
+ 0,
+ 0,
+ 0,
+ 91,
+ 394,
+ 1,
+ 0,
+ 0,
+ 0,
+ 93,
+ 397,
+ 1,
+ 0,
+ 0,
+ 0,
+ 95,
+ 399,
+ 1,
+ 0,
+ 0,
+ 0,
+ 97,
+ 402,
+ 1,
+ 0,
+ 0,
+ 0,
+ 99,
+ 404,
+ 1,
+ 0,
+ 0,
+ 0,
+ 101,
+ 407,
+ 1,
+ 0,
+ 0,
+ 0,
+ 103,
+ 410,
+ 1,
+ 0,
+ 0,
+ 0,
+ 105,
+ 412,
+ 1,
+ 0,
+ 0,
+ 0,
+ 107,
+ 414,
+ 1,
+ 0,
+ 0,
+ 0,
+ 109,
+ 416,
+ 1,
+ 0,
+ 0,
+ 0,
+ 111,
+ 419,
+ 1,
+ 0,
+ 0,
+ 0,
+ 113,
+ 422,
+ 1,
+ 0,
+ 0,
+ 0,
+ 115,
+ 426,
+ 1,
+ 0,
+ 0,
+ 0,
+ 117,
+ 430,
+ 1,
+ 0,
+ 0,
+ 0,
+ 119,
+ 433,
+ 1,
+ 0,
+ 0,
+ 0,
+ 121,
+ 436,
+ 1,
+ 0,
+ 0,
+ 0,
+ 123,
+ 439,
+ 1,
+ 0,
+ 0,
+ 0,
+ 125,
+ 442,
+ 1,
+ 0,
+ 0,
+ 0,
+ 127,
+ 445,
+ 1,
+ 0,
+ 0,
+ 0,
+ 129,
+ 449,
+ 1,
+ 0,
+ 0,
+ 0,
+ 131,
+ 453,
+ 1,
+ 0,
+ 0,
+ 0,
+ 133,
+ 461,
+ 1,
+ 0,
+ 0,
+ 0,
+ 135,
+ 467,
+ 1,
+ 0,
+ 0,
+ 0,
+ 137,
+ 483,
+ 1,
+ 0,
+ 0,
+ 0,
+ 139,
+ 497,
+ 1,
+ 0,
+ 0,
+ 0,
+ 141,
+ 526,
+ 1,
+ 0,
+ 0,
+ 0,
+ 143,
+ 557,
+ 1,
+ 0,
+ 0,
+ 0,
+ 145,
+ 560,
+ 1,
+ 0,
+ 0,
+ 0,
+ 147,
+ 566,
+ 1,
+ 0,
+ 0,
+ 0,
+ 149,
+ 572,
+ 1,
+ 0,
+ 0,
+ 0,
+ 151,
+ 577,
+ 1,
+ 0,
+ 0,
+ 0,
+ 153,
+ 579,
+ 1,
+ 0,
+ 0,
+ 0,
+ 155,
+ 581,
+ 1,
+ 0,
+ 0,
+ 0,
+ 157,
+ 589,
+ 1,
+ 0,
+ 0,
+ 0,
+ 159,
+ 597,
+ 1,
+ 0,
+ 0,
+ 0,
+ 161,
+ 605,
+ 1,
+ 0,
+ 0,
+ 0,
+ 163,
+ 613,
+ 1,
+ 0,
+ 0,
+ 0,
+ 165,
+ 621,
+ 1,
+ 0,
+ 0,
+ 0,
+ 167,
+ 627,
+ 1,
+ 0,
+ 0,
+ 0,
+ 169,
+ 633,
+ 1,
+ 0,
+ 0,
+ 0,
+ 171,
+ 639,
+ 1,
+ 0,
+ 0,
+ 0,
+ 173,
+ 645,
+ 1,
+ 0,
+ 0,
+ 0,
+ 175,
+ 647,
+ 1,
+ 0,
+ 0,
+ 0,
+ 177,
+ 652,
+ 1,
+ 0,
+ 0,
+ 0,
+ 179,
+ 657,
+ 1,
+ 0,
+ 0,
+ 0,
+ 181,
+ 662,
+ 1,
+ 0,
+ 0,
+ 0,
+ 183,
+ 664,
+ 1,
+ 0,
+ 0,
+ 0,
+ 185,
+ 666,
+ 1,
+ 0,
+ 0,
+ 0,
+ 187,
+ 188,
+ 5,
+ 101,
+ 0,
+ 0,
+ 188,
+ 189,
+ 5,
+ 110,
+ 0,
+ 0,
+ 189,
+ 190,
+ 5,
+ 100,
+ 0,
+ 0,
+ 190,
+ 191,
+ 5,
+ 109,
+ 0,
+ 0,
+ 191,
+ 192,
+ 5,
+ 111,
+ 0,
+ 0,
+ 192,
+ 193,
+ 5,
+ 100,
+ 0,
+ 0,
+ 193,
+ 194,
+ 5,
+ 117,
+ 0,
+ 0,
+ 194,
+ 195,
+ 5,
+ 108,
+ 0,
+ 0,
+ 195,
+ 196,
+ 5,
+ 101,
+ 0,
+ 0,
+ 196,
+ 2,
+ 1,
+ 0,
+ 0,
+ 0,
+ 197,
+ 198,
+ 5,
+ 109,
+ 0,
+ 0,
+ 198,
+ 199,
+ 5,
+ 111,
+ 0,
+ 0,
+ 199,
+ 200,
+ 5,
+ 100,
+ 0,
+ 0,
+ 200,
+ 201,
+ 5,
+ 117,
+ 0,
+ 0,
+ 201,
+ 202,
+ 5,
+ 108,
+ 0,
+ 0,
+ 202,
+ 203,
+ 5,
+ 101,
+ 0,
+ 0,
+ 203,
+ 4,
+ 1,
+ 0,
+ 0,
+ 0,
+ 204,
+ 205,
+ 5,
+ 40,
+ 0,
+ 0,
+ 205,
+ 6,
+ 1,
+ 0,
+ 0,
+ 0,
+ 206,
+ 207,
+ 5,
+ 41,
+ 0,
+ 0,
+ 207,
+ 8,
+ 1,
+ 0,
+ 0,
+ 0,
+ 208,
+ 209,
+ 5,
+ 59,
+ 0,
+ 0,
+ 209,
+ 10,
+ 1,
+ 0,
+ 0,
+ 0,
+ 210,
+ 211,
+ 5,
+ 44,
+ 0,
+ 0,
+ 211,
+ 12,
+ 1,
+ 0,
+ 0,
+ 0,
+ 212,
+ 213,
+ 5,
+ 102,
+ 0,
+ 0,
+ 213,
+ 214,
+ 5,
+ 105,
+ 0,
+ 0,
+ 214,
+ 215,
+ 5,
+ 110,
+ 0,
+ 0,
+ 215,
+ 216,
+ 5,
+ 112,
+ 0,
+ 0,
+ 216,
+ 217,
+ 5,
+ 117,
+ 0,
+ 0,
+ 217,
+ 218,
+ 5,
+ 116,
+ 0,
+ 0,
+ 218,
+ 14,
+ 1,
+ 0,
+ 0,
+ 0,
+ 219,
+ 220,
+ 5,
+ 102,
+ 0,
+ 0,
+ 220,
+ 221,
+ 5,
+ 111,
+ 0,
+ 0,
+ 221,
+ 222,
+ 5,
+ 117,
+ 0,
+ 0,
+ 222,
+ 223,
+ 5,
+ 116,
+ 0,
+ 0,
+ 223,
+ 224,
+ 5,
+ 112,
+ 0,
+ 0,
+ 224,
+ 225,
+ 5,
+ 117,
+ 0,
+ 0,
+ 225,
+ 226,
+ 5,
+ 116,
+ 0,
+ 0,
+ 226,
+ 16,
+ 1,
+ 0,
+ 0,
+ 0,
+ 227,
+ 228,
+ 5,
+ 99,
+ 0,
+ 0,
+ 228,
+ 229,
+ 5,
+ 111,
+ 0,
+ 0,
+ 229,
+ 230,
+ 5,
+ 110,
+ 0,
+ 0,
+ 230,
+ 231,
+ 5,
+ 116,
+ 0,
+ 0,
+ 231,
+ 232,
+ 5,
+ 114,
+ 0,
+ 0,
+ 232,
+ 233,
+ 5,
+ 111,
+ 0,
+ 0,
+ 233,
+ 234,
+ 5,
+ 108,
+ 0,
+ 0,
+ 234,
+ 18,
+ 1,
+ 0,
+ 0,
+ 0,
+ 235,
+ 236,
+ 5,
+ 100,
+ 0,
+ 0,
+ 236,
+ 237,
+ 5,
+ 105,
+ 0,
+ 0,
+ 237,
+ 238,
+ 5,
+ 115,
+ 0,
+ 0,
+ 238,
+ 239,
+ 5,
+ 116,
+ 0,
+ 0,
+ 239,
+ 240,
+ 5,
+ 114,
+ 0,
+ 0,
+ 240,
+ 241,
+ 5,
+ 105,
+ 0,
+ 0,
+ 241,
+ 242,
+ 5,
+ 98,
+ 0,
+ 0,
+ 242,
+ 243,
+ 5,
+ 117,
+ 0,
+ 0,
+ 243,
+ 244,
+ 5,
+ 116,
+ 0,
+ 0,
+ 244,
+ 245,
+ 5,
+ 101,
+ 0,
+ 0,
+ 245,
+ 246,
+ 5,
+ 64,
+ 0,
+ 0,
+ 246,
+ 20,
+ 1,
+ 0,
+ 0,
+ 0,
+ 247,
+ 248,
+ 5,
+ 98,
+ 0,
+ 0,
+ 248,
+ 249,
+ 5,
+ 101,
+ 0,
+ 0,
+ 249,
+ 250,
+ 5,
+ 103,
+ 0,
+ 0,
+ 250,
+ 251,
+ 5,
+ 105,
+ 0,
+ 0,
+ 251,
+ 252,
+ 5,
+ 110,
+ 0,
+ 0,
+ 252,
+ 22,
+ 1,
+ 0,
+ 0,
+ 0,
+ 253,
+ 254,
+ 5,
+ 101,
+ 0,
+ 0,
+ 254,
+ 255,
+ 5,
+ 110,
+ 0,
+ 0,
+ 255,
+ 256,
+ 5,
+ 100,
+ 0,
+ 0,
+ 256,
+ 24,
+ 1,
+ 0,
+ 0,
+ 0,
+ 257,
+ 258,
+ 5,
+ 105,
+ 0,
+ 0,
+ 258,
+ 259,
+ 5,
+ 102,
+ 0,
+ 0,
+ 259,
+ 26,
+ 1,
+ 0,
+ 0,
+ 0,
+ 260,
+ 261,
+ 5,
+ 101,
+ 0,
+ 0,
+ 261,
+ 262,
+ 5,
+ 108,
+ 0,
+ 0,
+ 262,
+ 263,
+ 5,
+ 115,
+ 0,
+ 0,
+ 263,
+ 264,
+ 5,
+ 101,
+ 0,
+ 0,
+ 264,
+ 28,
+ 1,
+ 0,
+ 0,
+ 0,
+ 265,
+ 266,
+ 5,
+ 101,
+ 0,
+ 0,
+ 266,
+ 267,
+ 5,
+ 110,
+ 0,
+ 0,
+ 267,
+ 268,
+ 5,
+ 100,
+ 0,
+ 0,
+ 268,
+ 269,
+ 5,
+ 99,
+ 0,
+ 0,
+ 269,
+ 270,
+ 5,
+ 97,
+ 0,
+ 0,
+ 270,
+ 271,
+ 5,
+ 115,
+ 0,
+ 0,
+ 271,
+ 272,
+ 5,
+ 101,
+ 0,
+ 0,
+ 272,
+ 30,
+ 1,
+ 0,
+ 0,
+ 0,
+ 273,
+ 274,
+ 5,
+ 99,
+ 0,
+ 0,
+ 274,
+ 275,
+ 5,
+ 97,
+ 0,
+ 0,
+ 275,
+ 276,
+ 5,
+ 115,
+ 0,
+ 0,
+ 276,
+ 277,
+ 5,
+ 101,
+ 0,
+ 0,
+ 277,
+ 32,
+ 1,
+ 0,
+ 0,
+ 0,
+ 278,
+ 279,
+ 5,
+ 58,
+ 0,
+ 0,
+ 279,
+ 34,
+ 1,
+ 0,
+ 0,
+ 0,
+ 280,
+ 281,
+ 5,
+ 100,
+ 0,
+ 0,
+ 281,
+ 282,
+ 5,
+ 101,
+ 0,
+ 0,
+ 282,
+ 283,
+ 5,
+ 102,
+ 0,
+ 0,
+ 283,
+ 284,
+ 5,
+ 97,
+ 0,
+ 0,
+ 284,
+ 285,
+ 5,
+ 117,
+ 0,
+ 0,
+ 285,
+ 286,
+ 5,
+ 108,
+ 0,
+ 0,
+ 286,
+ 287,
+ 5,
+ 116,
+ 0,
+ 0,
+ 287,
+ 36,
+ 1,
+ 0,
+ 0,
+ 0,
+ 288,
+ 289,
+ 5,
+ 60,
+ 0,
+ 0,
+ 289,
+ 290,
+ 5,
+ 61,
+ 0,
+ 0,
+ 290,
+ 38,
+ 1,
+ 0,
+ 0,
+ 0,
+ 291,
+ 292,
+ 5,
+ 46,
+ 0,
+ 0,
+ 292,
+ 40,
+ 1,
+ 0,
+ 0,
+ 0,
+ 293,
+ 294,
+ 5,
+ 115,
+ 0,
+ 0,
+ 294,
+ 295,
+ 5,
+ 105,
+ 0,
+ 0,
+ 295,
+ 296,
+ 5,
+ 103,
+ 0,
+ 0,
+ 296,
+ 297,
+ 5,
+ 110,
+ 0,
+ 0,
+ 297,
+ 298,
+ 5,
+ 97,
+ 0,
+ 0,
+ 298,
+ 299,
+ 5,
+ 108,
+ 0,
+ 0,
+ 299,
+ 42,
+ 1,
+ 0,
+ 0,
+ 0,
+ 300,
+ 301,
+ 5,
+ 102,
+ 0,
+ 0,
+ 301,
+ 302,
+ 5,
+ 108,
+ 0,
+ 0,
+ 302,
+ 303,
+ 5,
+ 111,
+ 0,
+ 0,
+ 303,
+ 304,
+ 5,
+ 119,
+ 0,
+ 0,
+ 304,
+ 44,
+ 1,
+ 0,
+ 0,
+ 0,
+ 305,
+ 306,
+ 5,
+ 115,
+ 0,
+ 0,
+ 306,
+ 307,
+ 5,
+ 116,
+ 0,
+ 0,
+ 307,
+ 308,
+ 5,
+ 111,
+ 0,
+ 0,
+ 308,
+ 309,
+ 5,
+ 114,
+ 0,
+ 0,
+ 309,
+ 310,
+ 5,
+ 97,
+ 0,
+ 0,
+ 310,
+ 311,
+ 5,
+ 103,
+ 0,
+ 0,
+ 311,
+ 312,
+ 5,
+ 101,
+ 0,
+ 0,
+ 312,
+ 46,
+ 1,
+ 0,
+ 0,
+ 0,
+ 313,
+ 314,
+ 5,
+ 112,
+ 0,
+ 0,
+ 314,
+ 315,
+ 5,
+ 117,
+ 0,
+ 0,
+ 315,
+ 316,
+ 5,
+ 109,
+ 0,
+ 0,
+ 316,
+ 317,
+ 5,
+ 112,
+ 0,
+ 0,
+ 317,
+ 48,
+ 1,
+ 0,
+ 0,
+ 0,
+ 318,
+ 319,
+ 5,
+ 110,
+ 0,
+ 0,
+ 319,
+ 320,
+ 5,
+ 117,
+ 0,
+ 0,
+ 320,
+ 321,
+ 5,
+ 109,
+ 0,
+ 0,
+ 321,
+ 322,
+ 5,
+ 98,
+ 0,
+ 0,
+ 322,
+ 323,
+ 5,
+ 101,
+ 0,
+ 0,
+ 323,
+ 324,
+ 5,
+ 114,
+ 0,
+ 0,
+ 324,
+ 50,
+ 1,
+ 0,
+ 0,
+ 0,
+ 325,
+ 326,
+ 5,
+ 97,
+ 0,
+ 0,
+ 326,
+ 327,
+ 5,
+ 115,
+ 0,
+ 0,
+ 327,
+ 328,
+ 5,
+ 115,
+ 0,
+ 0,
+ 328,
+ 329,
+ 5,
+ 105,
+ 0,
+ 0,
+ 329,
+ 330,
+ 5,
+ 103,
+ 0,
+ 0,
+ 330,
+ 331,
+ 5,
+ 110,
+ 0,
+ 0,
+ 331,
+ 52,
+ 1,
+ 0,
+ 0,
+ 0,
+ 332,
+ 333,
+ 5,
+ 61,
+ 0,
+ 0,
+ 333,
+ 54,
+ 1,
+ 0,
+ 0,
+ 0,
+ 334,
+ 335,
+ 5,
+ 91,
+ 0,
+ 0,
+ 335,
+ 56,
+ 1,
+ 0,
+ 0,
+ 0,
+ 336,
+ 337,
+ 5,
+ 93,
+ 0,
+ 0,
+ 337,
+ 58,
+ 1,
+ 0,
+ 0,
+ 0,
+ 338,
+ 339,
+ 5,
+ 123,
+ 0,
+ 0,
+ 339,
+ 60,
+ 1,
+ 0,
+ 0,
+ 0,
+ 340,
+ 341,
+ 5,
+ 125,
+ 0,
+ 0,
+ 341,
+ 62,
+ 1,
+ 0,
+ 0,
+ 0,
+ 342,
+ 343,
+ 5,
+ 35,
+ 0,
+ 0,
+ 343,
+ 344,
+ 5,
+ 77,
+ 0,
+ 0,
+ 344,
+ 345,
+ 5,
+ 65,
+ 0,
+ 0,
+ 345,
+ 346,
+ 5,
+ 80,
+ 0,
+ 0,
+ 346,
+ 64,
+ 1,
+ 0,
+ 0,
+ 0,
+ 347,
+ 348,
+ 5,
+ 34,
+ 0,
+ 0,
+ 348,
+ 66,
+ 1,
+ 0,
+ 0,
+ 0,
+ 349,
+ 350,
+ 5,
+ 35,
+ 0,
+ 0,
+ 350,
+ 351,
+ 5,
+ 77,
+ 0,
+ 0,
+ 351,
+ 352,
+ 5,
+ 65,
+ 0,
+ 0,
+ 352,
+ 353,
+ 5,
+ 84,
+ 0,
+ 0,
+ 353,
+ 354,
+ 5,
+ 69,
+ 0,
+ 0,
+ 354,
+ 355,
+ 5,
+ 82,
+ 0,
+ 0,
+ 355,
+ 356,
+ 5,
+ 73,
+ 0,
+ 0,
+ 356,
+ 357,
+ 5,
+ 65,
+ 0,
+ 0,
+ 357,
+ 358,
+ 5,
+ 76,
+ 0,
+ 0,
+ 358,
+ 68,
+ 1,
+ 0,
+ 0,
+ 0,
+ 359,
+ 360,
+ 5,
+ 35,
+ 0,
+ 0,
+ 360,
+ 361,
+ 5,
+ 67,
+ 0,
+ 0,
+ 361,
+ 362,
+ 5,
+ 79,
+ 0,
+ 0,
+ 362,
+ 363,
+ 5,
+ 78,
+ 0,
+ 0,
+ 363,
+ 364,
+ 5,
+ 83,
+ 0,
+ 0,
+ 364,
+ 365,
+ 5,
+ 84,
+ 0,
+ 0,
+ 365,
+ 366,
+ 5,
+ 82,
+ 0,
+ 0,
+ 366,
+ 367,
+ 5,
+ 65,
+ 0,
+ 0,
+ 367,
+ 368,
+ 5,
+ 73,
+ 0,
+ 0,
+ 368,
+ 369,
+ 5,
+ 78,
+ 0,
+ 0,
+ 369,
+ 70,
+ 1,
+ 0,
+ 0,
+ 0,
+ 370,
+ 371,
+ 5,
+ 65,
+ 0,
+ 0,
+ 371,
+ 372,
+ 5,
+ 78,
+ 0,
+ 0,
+ 372,
+ 373,
+ 5,
+ 68,
+ 0,
+ 0,
+ 373,
+ 72,
+ 1,
+ 0,
+ 0,
+ 0,
+ 374,
+ 375,
+ 5,
+ 79,
+ 0,
+ 0,
+ 375,
+ 376,
+ 5,
+ 82,
+ 0,
+ 0,
+ 376,
+ 74,
+ 1,
+ 0,
+ 0,
+ 0,
+ 377,
+ 378,
+ 5,
+ 62,
+ 0,
+ 0,
+ 378,
+ 76,
+ 1,
+ 0,
+ 0,
+ 0,
+ 379,
+ 380,
+ 5,
+ 60,
+ 0,
+ 0,
+ 380,
+ 78,
+ 1,
+ 0,
+ 0,
+ 0,
+ 381,
+ 382,
+ 5,
+ 62,
+ 0,
+ 0,
+ 382,
+ 383,
+ 5,
+ 61,
+ 0,
+ 0,
+ 383,
+ 80,
+ 1,
+ 0,
+ 0,
+ 0,
+ 384,
+ 385,
+ 5,
+ 43,
+ 0,
+ 0,
+ 385,
+ 82,
+ 1,
+ 0,
+ 0,
+ 0,
+ 386,
+ 387,
+ 5,
+ 45,
+ 0,
+ 0,
+ 387,
+ 84,
+ 1,
+ 0,
+ 0,
+ 0,
+ 388,
+ 389,
+ 5,
+ 33,
+ 0,
+ 0,
+ 389,
+ 86,
+ 1,
+ 0,
+ 0,
+ 0,
+ 390,
+ 391,
+ 5,
+ 126,
+ 0,
+ 0,
+ 391,
+ 88,
+ 1,
+ 0,
+ 0,
+ 0,
+ 392,
+ 393,
+ 5,
+ 38,
+ 0,
+ 0,
+ 393,
+ 90,
+ 1,
+ 0,
+ 0,
+ 0,
+ 394,
+ 395,
+ 5,
+ 126,
+ 0,
+ 0,
+ 395,
+ 396,
+ 5,
+ 38,
+ 0,
+ 0,
+ 396,
+ 92,
+ 1,
+ 0,
+ 0,
+ 0,
+ 397,
+ 398,
+ 5,
+ 124,
+ 0,
+ 0,
+ 398,
+ 94,
+ 1,
+ 0,
+ 0,
+ 0,
+ 399,
+ 400,
+ 5,
+ 126,
+ 0,
+ 0,
+ 400,
+ 401,
+ 5,
+ 124,
+ 0,
+ 0,
+ 401,
+ 96,
+ 1,
+ 0,
+ 0,
+ 0,
+ 402,
+ 403,
+ 5,
+ 94,
+ 0,
+ 0,
+ 403,
+ 98,
+ 1,
+ 0,
+ 0,
+ 0,
+ 404,
+ 405,
+ 5,
+ 126,
+ 0,
+ 0,
+ 405,
+ 406,
+ 5,
+ 94,
+ 0,
+ 0,
+ 406,
+ 100,
+ 1,
+ 0,
+ 0,
+ 0,
+ 407,
+ 408,
+ 5,
+ 94,
+ 0,
+ 0,
+ 408,
+ 409,
+ 5,
+ 126,
+ 0,
+ 0,
+ 409,
+ 102,
+ 1,
+ 0,
+ 0,
+ 0,
+ 410,
+ 411,
+ 5,
+ 42,
+ 0,
+ 0,
+ 411,
+ 104,
+ 1,
+ 0,
+ 0,
+ 0,
+ 412,
+ 413,
+ 5,
+ 47,
+ 0,
+ 0,
+ 413,
+ 106,
+ 1,
+ 0,
+ 0,
+ 0,
+ 414,
+ 415,
+ 5,
+ 37,
+ 0,
+ 0,
+ 415,
+ 108,
+ 1,
+ 0,
+ 0,
+ 0,
+ 416,
+ 417,
+ 5,
+ 61,
+ 0,
+ 0,
+ 417,
+ 418,
+ 5,
+ 61,
+ 0,
+ 0,
+ 418,
+ 110,
+ 1,
+ 0,
+ 0,
+ 0,
+ 419,
+ 420,
+ 5,
+ 33,
+ 0,
+ 0,
+ 420,
+ 421,
+ 5,
+ 61,
+ 0,
+ 0,
+ 421,
+ 112,
+ 1,
+ 0,
+ 0,
+ 0,
+ 422,
+ 423,
+ 5,
+ 61,
+ 0,
+ 0,
+ 423,
+ 424,
+ 5,
+ 61,
+ 0,
+ 0,
+ 424,
+ 425,
+ 5,
+ 61,
+ 0,
+ 0,
+ 425,
+ 114,
+ 1,
+ 0,
+ 0,
+ 0,
+ 426,
+ 427,
+ 5,
+ 33,
+ 0,
+ 0,
+ 427,
+ 428,
+ 5,
+ 61,
+ 0,
+ 0,
+ 428,
+ 429,
+ 5,
+ 61,
+ 0,
+ 0,
+ 429,
+ 116,
+ 1,
+ 0,
+ 0,
+ 0,
+ 430,
+ 431,
+ 5,
+ 38,
+ 0,
+ 0,
+ 431,
+ 432,
+ 5,
+ 38,
+ 0,
+ 0,
+ 432,
+ 118,
+ 1,
+ 0,
+ 0,
+ 0,
+ 433,
+ 434,
+ 5,
+ 124,
+ 0,
+ 0,
+ 434,
+ 435,
+ 5,
+ 124,
+ 0,
+ 0,
+ 435,
+ 120,
+ 1,
+ 0,
+ 0,
+ 0,
+ 436,
+ 437,
+ 5,
+ 42,
+ 0,
+ 0,
+ 437,
+ 438,
+ 5,
+ 42,
+ 0,
+ 0,
+ 438,
+ 122,
+ 1,
+ 0,
+ 0,
+ 0,
+ 439,
+ 440,
+ 5,
+ 62,
+ 0,
+ 0,
+ 440,
+ 441,
+ 5,
+ 62,
+ 0,
+ 0,
+ 441,
+ 124,
+ 1,
+ 0,
+ 0,
+ 0,
+ 442,
+ 443,
+ 5,
+ 60,
+ 0,
+ 0,
+ 443,
+ 444,
+ 5,
+ 60,
+ 0,
+ 0,
+ 444,
+ 126,
+ 1,
+ 0,
+ 0,
+ 0,
+ 445,
+ 446,
+ 5,
+ 62,
+ 0,
+ 0,
+ 446,
+ 447,
+ 5,
+ 62,
+ 0,
+ 0,
+ 447,
+ 448,
+ 5,
+ 62,
+ 0,
+ 0,
+ 448,
+ 128,
+ 1,
+ 0,
+ 0,
+ 0,
+ 449,
+ 450,
+ 5,
+ 60,
+ 0,
+ 0,
+ 450,
+ 451,
+ 5,
+ 60,
+ 0,
+ 0,
+ 451,
+ 452,
+ 5,
+ 60,
+ 0,
+ 0,
+ 452,
+ 130,
+ 1,
+ 0,
+ 0,
+ 0,
+ 453,
+ 457,
+ 7,
+ 0,
+ 0,
+ 0,
+ 454,
+ 456,
+ 7,
+ 1,
+ 0,
+ 0,
+ 455,
+ 454,
+ 1,
+ 0,
+ 0,
+ 0,
+ 456,
+ 459,
+ 1,
+ 0,
+ 0,
+ 0,
+ 457,
+ 455,
+ 1,
+ 0,
+ 0,
+ 0,
+ 457,
+ 458,
+ 1,
+ 0,
+ 0,
+ 0,
+ 458,
+ 132,
+ 1,
+ 0,
+ 0,
+ 0,
+ 459,
+ 457,
+ 1,
+ 0,
+ 0,
+ 0,
+ 460,
+ 462,
+ 7,
+ 2,
+ 0,
+ 0,
+ 461,
+ 460,
+ 1,
+ 0,
+ 0,
+ 0,
+ 462,
+ 463,
+ 1,
+ 0,
+ 0,
+ 0,
+ 463,
+ 461,
+ 1,
+ 0,
+ 0,
+ 0,
+ 463,
+ 464,
+ 1,
+ 0,
+ 0,
+ 0,
+ 464,
+ 465,
+ 1,
+ 0,
+ 0,
+ 0,
+ 465,
+ 466,
+ 6,
+ 66,
+ 0,
+ 0,
+ 466,
+ 134,
+ 1,
+ 0,
+ 0,
+ 0,
+ 467,
+ 468,
+ 5,
+ 47,
+ 0,
+ 0,
+ 468,
+ 469,
+ 5,
+ 47,
+ 0,
+ 0,
+ 469,
+ 473,
+ 1,
+ 0,
+ 0,
+ 0,
+ 470,
+ 472,
+ 9,
+ 0,
+ 0,
+ 0,
+ 471,
+ 470,
+ 1,
+ 0,
+ 0,
+ 0,
+ 472,
+ 475,
+ 1,
+ 0,
+ 0,
+ 0,
+ 473,
+ 474,
+ 1,
+ 0,
+ 0,
+ 0,
+ 473,
+ 471,
+ 1,
+ 0,
+ 0,
+ 0,
+ 474,
+ 477,
+ 1,
+ 0,
+ 0,
+ 0,
+ 475,
+ 473,
+ 1,
+ 0,
+ 0,
+ 0,
+ 476,
+ 478,
+ 5,
+ 13,
+ 0,
+ 0,
+ 477,
+ 476,
+ 1,
+ 0,
+ 0,
+ 0,
+ 477,
+ 478,
+ 1,
+ 0,
+ 0,
+ 0,
+ 478,
+ 479,
+ 1,
+ 0,
+ 0,
+ 0,
+ 479,
+ 480,
+ 5,
+ 10,
+ 0,
+ 0,
+ 480,
+ 481,
+ 1,
+ 0,
+ 0,
+ 0,
+ 481,
+ 482,
+ 6,
+ 67,
+ 1,
+ 0,
+ 482,
+ 136,
+ 1,
+ 0,
+ 0,
+ 0,
+ 483,
+ 484,
+ 5,
+ 47,
+ 0,
+ 0,
+ 484,
+ 485,
+ 5,
+ 42,
+ 0,
+ 0,
+ 485,
+ 489,
+ 1,
+ 0,
+ 0,
+ 0,
+ 486,
+ 488,
+ 9,
+ 0,
+ 0,
+ 0,
+ 487,
+ 486,
+ 1,
+ 0,
+ 0,
+ 0,
+ 488,
+ 491,
+ 1,
+ 0,
+ 0,
+ 0,
+ 489,
+ 490,
+ 1,
+ 0,
+ 0,
+ 0,
+ 489,
+ 487,
+ 1,
+ 0,
+ 0,
+ 0,
+ 490,
+ 492,
+ 1,
+ 0,
+ 0,
+ 0,
+ 491,
+ 489,
+ 1,
+ 0,
+ 0,
+ 0,
+ 492,
+ 493,
+ 5,
+ 42,
+ 0,
+ 0,
+ 493,
+ 494,
+ 5,
+ 47,
+ 0,
+ 0,
+ 494,
+ 495,
+ 1,
+ 0,
+ 0,
+ 0,
+ 495,
+ 496,
+ 6,
+ 68,
+ 1,
+ 0,
+ 496,
+ 138,
+ 1,
+ 0,
+ 0,
+ 0,
+ 497,
+ 501,
+ 5,
+ 96,
+ 0,
+ 0,
+ 498,
+ 500,
+ 9,
+ 0,
+ 0,
+ 0,
+ 499,
+ 498,
+ 1,
+ 0,
+ 0,
+ 0,
+ 500,
+ 503,
+ 1,
+ 0,
+ 0,
+ 0,
+ 501,
+ 502,
+ 1,
+ 0,
+ 0,
+ 0,
+ 501,
+ 499,
+ 1,
+ 0,
+ 0,
+ 0,
+ 502,
+ 505,
+ 1,
+ 0,
+ 0,
+ 0,
+ 503,
+ 501,
+ 1,
+ 0,
+ 0,
+ 0,
+ 504,
+ 506,
+ 5,
+ 13,
+ 0,
+ 0,
+ 505,
+ 504,
+ 1,
+ 0,
+ 0,
+ 0,
+ 505,
+ 506,
+ 1,
+ 0,
+ 0,
+ 0,
+ 506,
+ 507,
+ 1,
+ 0,
+ 0,
+ 0,
+ 507,
+ 508,
+ 5,
+ 10,
+ 0,
+ 0,
+ 508,
+ 509,
+ 1,
+ 0,
+ 0,
+ 0,
+ 509,
+ 510,
+ 6,
+ 69,
+ 1,
+ 0,
+ 510,
+ 140,
+ 1,
+ 0,
+ 0,
+ 0,
+ 511,
+ 512,
+ 3,
+ 157,
+ 78,
+ 0,
+ 512,
+ 513,
+ 5,
+ 46,
+ 0,
+ 0,
+ 513,
+ 514,
+ 3,
+ 157,
+ 78,
+ 0,
+ 514,
+ 527,
+ 1,
+ 0,
+ 0,
+ 0,
+ 515,
+ 518,
+ 3,
+ 157,
+ 78,
+ 0,
+ 516,
+ 517,
+ 5,
+ 46,
+ 0,
+ 0,
+ 517,
+ 519,
+ 3,
+ 157,
+ 78,
+ 0,
+ 518,
+ 516,
+ 1,
+ 0,
+ 0,
+ 0,
+ 518,
+ 519,
+ 1,
+ 0,
+ 0,
+ 0,
+ 519,
+ 520,
+ 1,
+ 0,
+ 0,
+ 0,
+ 520,
+ 522,
+ 7,
+ 3,
+ 0,
+ 0,
+ 521,
+ 523,
+ 7,
+ 4,
+ 0,
+ 0,
+ 522,
+ 521,
+ 1,
+ 0,
+ 0,
+ 0,
+ 522,
+ 523,
+ 1,
+ 0,
+ 0,
+ 0,
+ 523,
+ 524,
+ 1,
+ 0,
+ 0,
+ 0,
+ 524,
+ 525,
+ 3,
+ 157,
+ 78,
+ 0,
+ 525,
+ 527,
+ 1,
+ 0,
+ 0,
+ 0,
+ 526,
+ 511,
+ 1,
+ 0,
+ 0,
+ 0,
+ 526,
+ 515,
+ 1,
+ 0,
+ 0,
+ 0,
+ 527,
+ 142,
+ 1,
+ 0,
+ 0,
+ 0,
+ 528,
+ 558,
+ 3,
+ 157,
+ 78,
+ 0,
+ 529,
+ 531,
+ 3,
+ 153,
+ 76,
+ 0,
+ 530,
+ 529,
+ 1,
+ 0,
+ 0,
+ 0,
+ 530,
+ 531,
+ 1,
+ 0,
+ 0,
+ 0,
+ 531,
+ 532,
+ 1,
+ 0,
+ 0,
+ 0,
+ 532,
+ 533,
+ 3,
+ 165,
+ 82,
+ 0,
+ 533,
+ 534,
+ 3,
+ 157,
+ 78,
+ 0,
+ 534,
+ 558,
+ 1,
+ 0,
+ 0,
+ 0,
+ 535,
+ 537,
+ 3,
+ 153,
+ 76,
+ 0,
+ 536,
+ 535,
+ 1,
+ 0,
+ 0,
+ 0,
+ 536,
+ 537,
+ 1,
+ 0,
+ 0,
+ 0,
+ 537,
+ 538,
+ 1,
+ 0,
+ 0,
+ 0,
+ 538,
+ 539,
+ 3,
+ 165,
+ 82,
+ 0,
+ 539,
+ 543,
+ 3,
+ 183,
+ 91,
+ 0,
+ 540,
+ 542,
+ 5,
+ 95,
+ 0,
+ 0,
+ 541,
+ 540,
+ 1,
+ 0,
+ 0,
+ 0,
+ 542,
+ 545,
+ 1,
+ 0,
+ 0,
+ 0,
+ 543,
+ 541,
+ 1,
+ 0,
+ 0,
+ 0,
+ 543,
+ 544,
+ 1,
+ 0,
+ 0,
+ 0,
+ 544,
+ 558,
+ 1,
+ 0,
+ 0,
+ 0,
+ 545,
+ 543,
+ 1,
+ 0,
+ 0,
+ 0,
+ 546,
+ 548,
+ 3,
+ 153,
+ 76,
+ 0,
+ 547,
+ 546,
+ 1,
+ 0,
+ 0,
+ 0,
+ 547,
+ 548,
+ 1,
+ 0,
+ 0,
+ 0,
+ 548,
+ 549,
+ 1,
+ 0,
+ 0,
+ 0,
+ 549,
+ 550,
+ 3,
+ 165,
+ 82,
+ 0,
+ 550,
+ 554,
+ 3,
+ 185,
+ 92,
+ 0,
+ 551,
+ 553,
+ 5,
+ 95,
+ 0,
+ 0,
+ 552,
+ 551,
+ 1,
+ 0,
+ 0,
+ 0,
+ 553,
+ 556,
+ 1,
+ 0,
+ 0,
+ 0,
+ 554,
+ 552,
+ 1,
+ 0,
+ 0,
+ 0,
+ 554,
+ 555,
+ 1,
+ 0,
+ 0,
+ 0,
+ 555,
+ 558,
+ 1,
+ 0,
+ 0,
+ 0,
+ 556,
+ 554,
+ 1,
+ 0,
+ 0,
+ 0,
+ 557,
+ 528,
+ 1,
+ 0,
+ 0,
+ 0,
+ 557,
+ 530,
+ 1,
+ 0,
+ 0,
+ 0,
+ 557,
+ 536,
+ 1,
+ 0,
+ 0,
+ 0,
+ 557,
+ 547,
+ 1,
+ 0,
+ 0,
+ 0,
+ 558,
+ 144,
+ 1,
+ 0,
+ 0,
+ 0,
+ 559,
+ 561,
+ 3,
+ 153,
+ 76,
+ 0,
+ 560,
+ 559,
+ 1,
+ 0,
+ 0,
+ 0,
+ 560,
+ 561,
+ 1,
+ 0,
+ 0,
+ 0,
+ 561,
+ 562,
+ 1,
+ 0,
+ 0,
+ 0,
+ 562,
+ 563,
+ 3,
+ 167,
+ 83,
+ 0,
+ 563,
+ 564,
+ 3,
+ 159,
+ 79,
+ 0,
+ 564,
+ 146,
+ 1,
+ 0,
+ 0,
+ 0,
+ 565,
+ 567,
+ 3,
+ 153,
+ 76,
+ 0,
+ 566,
+ 565,
+ 1,
+ 0,
+ 0,
+ 0,
+ 566,
+ 567,
+ 1,
+ 0,
+ 0,
+ 0,
+ 567,
+ 568,
+ 1,
+ 0,
+ 0,
+ 0,
+ 568,
+ 569,
+ 3,
+ 169,
+ 84,
+ 0,
+ 569,
+ 570,
+ 3,
+ 161,
+ 80,
+ 0,
+ 570,
+ 148,
+ 1,
+ 0,
+ 0,
+ 0,
+ 571,
+ 573,
+ 3,
+ 153,
+ 76,
+ 0,
+ 572,
+ 571,
+ 1,
+ 0,
+ 0,
+ 0,
+ 572,
+ 573,
+ 1,
+ 0,
+ 0,
+ 0,
+ 573,
+ 574,
+ 1,
+ 0,
+ 0,
+ 0,
+ 574,
+ 575,
+ 3,
+ 171,
+ 85,
+ 0,
+ 575,
+ 576,
+ 3,
+ 163,
+ 81,
+ 0,
+ 576,
+ 150,
+ 1,
+ 0,
+ 0,
+ 0,
+ 577,
+ 578,
+ 7,
+ 4,
+ 0,
+ 0,
+ 578,
+ 152,
+ 1,
+ 0,
+ 0,
+ 0,
+ 579,
+ 580,
+ 3,
+ 155,
+ 77,
+ 0,
+ 580,
+ 154,
+ 1,
+ 0,
+ 0,
+ 0,
+ 581,
+ 586,
+ 3,
+ 173,
+ 86,
+ 0,
+ 582,
+ 585,
+ 5,
+ 95,
+ 0,
+ 0,
+ 583,
+ 585,
+ 3,
+ 175,
+ 87,
+ 0,
+ 584,
+ 582,
+ 1,
+ 0,
+ 0,
+ 0,
+ 584,
+ 583,
+ 1,
+ 0,
+ 0,
+ 0,
+ 585,
+ 588,
+ 1,
+ 0,
+ 0,
+ 0,
+ 586,
+ 584,
+ 1,
+ 0,
+ 0,
+ 0,
+ 586,
+ 587,
+ 1,
+ 0,
+ 0,
+ 0,
+ 587,
+ 156,
+ 1,
+ 0,
+ 0,
+ 0,
+ 588,
+ 586,
+ 1,
+ 0,
+ 0,
+ 0,
+ 589,
+ 594,
+ 3,
+ 175,
+ 87,
+ 0,
+ 590,
+ 593,
+ 5,
+ 95,
+ 0,
+ 0,
+ 591,
+ 593,
+ 3,
+ 175,
+ 87,
+ 0,
+ 592,
+ 590,
+ 1,
+ 0,
+ 0,
+ 0,
+ 592,
+ 591,
+ 1,
+ 0,
+ 0,
+ 0,
+ 593,
+ 596,
+ 1,
+ 0,
+ 0,
+ 0,
+ 594,
+ 592,
+ 1,
+ 0,
+ 0,
+ 0,
+ 594,
+ 595,
+ 1,
+ 0,
+ 0,
+ 0,
+ 595,
+ 158,
+ 1,
+ 0,
+ 0,
+ 0,
+ 596,
+ 594,
+ 1,
+ 0,
+ 0,
+ 0,
+ 597,
+ 602,
+ 3,
+ 177,
+ 88,
+ 0,
+ 598,
+ 601,
+ 5,
+ 95,
+ 0,
+ 0,
+ 599,
+ 601,
+ 3,
+ 177,
+ 88,
+ 0,
+ 600,
+ 598,
+ 1,
+ 0,
+ 0,
+ 0,
+ 600,
+ 599,
+ 1,
+ 0,
+ 0,
+ 0,
+ 601,
+ 604,
+ 1,
+ 0,
+ 0,
+ 0,
+ 602,
+ 600,
+ 1,
+ 0,
+ 0,
+ 0,
+ 602,
+ 603,
+ 1,
+ 0,
+ 0,
+ 0,
+ 603,
+ 160,
+ 1,
+ 0,
+ 0,
+ 0,
+ 604,
+ 602,
+ 1,
+ 0,
+ 0,
+ 0,
+ 605,
+ 610,
+ 3,
+ 179,
+ 89,
+ 0,
+ 606,
+ 609,
+ 5,
+ 95,
+ 0,
+ 0,
+ 607,
+ 609,
+ 3,
+ 179,
+ 89,
+ 0,
+ 608,
+ 606,
+ 1,
+ 0,
+ 0,
+ 0,
+ 608,
+ 607,
+ 1,
+ 0,
+ 0,
+ 0,
+ 609,
+ 612,
+ 1,
+ 0,
+ 0,
+ 0,
+ 610,
+ 608,
+ 1,
+ 0,
+ 0,
+ 0,
+ 610,
+ 611,
+ 1,
+ 0,
+ 0,
+ 0,
+ 611,
+ 162,
+ 1,
+ 0,
+ 0,
+ 0,
+ 612,
+ 610,
+ 1,
+ 0,
+ 0,
+ 0,
+ 613,
+ 618,
+ 3,
+ 181,
+ 90,
+ 0,
+ 614,
+ 617,
+ 5,
+ 95,
+ 0,
+ 0,
+ 615,
+ 617,
+ 3,
+ 181,
+ 90,
+ 0,
+ 616,
+ 614,
+ 1,
+ 0,
+ 0,
+ 0,
+ 616,
+ 615,
+ 1,
+ 0,
+ 0,
+ 0,
+ 617,
+ 620,
+ 1,
+ 0,
+ 0,
+ 0,
+ 618,
+ 616,
+ 1,
+ 0,
+ 0,
+ 0,
+ 618,
+ 619,
+ 1,
+ 0,
+ 0,
+ 0,
+ 619,
+ 164,
+ 1,
+ 0,
+ 0,
+ 0,
+ 620,
+ 618,
+ 1,
+ 0,
+ 0,
+ 0,
+ 621,
+ 623,
+ 5,
+ 39,
+ 0,
+ 0,
+ 622,
+ 624,
+ 7,
+ 5,
+ 0,
+ 0,
+ 623,
+ 622,
+ 1,
+ 0,
+ 0,
+ 0,
+ 623,
+ 624,
+ 1,
+ 0,
+ 0,
+ 0,
+ 624,
+ 625,
+ 1,
+ 0,
+ 0,
+ 0,
+ 625,
+ 626,
+ 7,
+ 6,
+ 0,
+ 0,
+ 626,
+ 166,
+ 1,
+ 0,
+ 0,
+ 0,
+ 627,
+ 629,
+ 5,
+ 39,
+ 0,
+ 0,
+ 628,
+ 630,
+ 7,
+ 5,
+ 0,
+ 0,
+ 629,
+ 628,
+ 1,
+ 0,
+ 0,
+ 0,
+ 629,
+ 630,
+ 1,
+ 0,
+ 0,
+ 0,
+ 630,
+ 631,
+ 1,
+ 0,
+ 0,
+ 0,
+ 631,
+ 632,
+ 7,
+ 7,
+ 0,
+ 0,
+ 632,
+ 168,
+ 1,
+ 0,
+ 0,
+ 0,
+ 633,
+ 635,
+ 5,
+ 39,
+ 0,
+ 0,
+ 634,
+ 636,
+ 7,
+ 5,
+ 0,
+ 0,
+ 635,
+ 634,
+ 1,
+ 0,
+ 0,
+ 0,
+ 635,
+ 636,
+ 1,
+ 0,
+ 0,
+ 0,
+ 636,
+ 637,
+ 1,
+ 0,
+ 0,
+ 0,
+ 637,
+ 638,
+ 7,
+ 8,
+ 0,
+ 0,
+ 638,
+ 170,
+ 1,
+ 0,
+ 0,
+ 0,
+ 639,
+ 641,
+ 5,
+ 39,
+ 0,
+ 0,
+ 640,
+ 642,
+ 7,
+ 5,
+ 0,
+ 0,
+ 641,
+ 640,
+ 1,
+ 0,
+ 0,
+ 0,
+ 641,
+ 642,
+ 1,
+ 0,
+ 0,
+ 0,
+ 642,
+ 643,
+ 1,
+ 0,
+ 0,
+ 0,
+ 643,
+ 644,
+ 7,
+ 9,
+ 0,
+ 0,
+ 644,
+ 172,
+ 1,
+ 0,
+ 0,
+ 0,
+ 645,
+ 646,
+ 7,
+ 10,
+ 0,
+ 0,
+ 646,
+ 174,
+ 1,
+ 0,
+ 0,
+ 0,
+ 647,
+ 648,
+ 7,
+ 11,
+ 0,
+ 0,
+ 648,
+ 176,
+ 1,
+ 0,
+ 0,
+ 0,
+ 649,
+ 653,
+ 3,
+ 183,
+ 91,
+ 0,
+ 650,
+ 653,
+ 3,
+ 185,
+ 92,
+ 0,
+ 651,
+ 653,
+ 7,
+ 12,
+ 0,
+ 0,
+ 652,
+ 649,
+ 1,
+ 0,
+ 0,
+ 0,
+ 652,
+ 650,
+ 1,
+ 0,
+ 0,
+ 0,
+ 652,
+ 651,
+ 1,
+ 0,
+ 0,
+ 0,
+ 653,
+ 178,
+ 1,
+ 0,
+ 0,
+ 0,
+ 654,
+ 658,
+ 3,
+ 183,
+ 91,
+ 0,
+ 655,
+ 658,
+ 3,
+ 185,
+ 92,
+ 0,
+ 656,
+ 658,
+ 7,
+ 13,
+ 0,
+ 0,
+ 657,
+ 654,
+ 1,
+ 0,
+ 0,
+ 0,
+ 657,
+ 655,
+ 1,
+ 0,
+ 0,
+ 0,
+ 657,
+ 656,
+ 1,
+ 0,
+ 0,
+ 0,
+ 658,
+ 180,
+ 1,
+ 0,
+ 0,
+ 0,
+ 659,
+ 663,
+ 3,
+ 183,
+ 91,
+ 0,
+ 660,
+ 663,
+ 3,
+ 185,
+ 92,
+ 0,
+ 661,
+ 663,
+ 7,
+ 14,
+ 0,
+ 0,
+ 662,
+ 659,
+ 1,
+ 0,
+ 0,
+ 0,
+ 662,
+ 660,
+ 1,
+ 0,
+ 0,
+ 0,
+ 662,
+ 661,
+ 1,
+ 0,
+ 0,
+ 0,
+ 663,
+ 182,
+ 1,
+ 0,
+ 0,
+ 0,
+ 664,
+ 665,
+ 7,
+ 15,
+ 0,
+ 0,
+ 665,
+ 184,
+ 1,
+ 0,
+ 0,
+ 0,
+ 666,
+ 667,
+ 7,
+ 16,
+ 0,
+ 0,
+ 667,
+ 186,
+ 1,
+ 0,
+ 0,
+ 0,
+ 37,
+ 0,
+ 457,
+ 463,
+ 473,
+ 477,
+ 489,
+ 501,
+ 505,
+ 518,
+ 522,
+ 526,
+ 530,
+ 536,
+ 543,
+ 547,
+ 554,
+ 557,
+ 560,
+ 566,
+ 572,
+ 584,
+ 586,
+ 592,
+ 594,
+ 600,
+ 602,
+ 608,
+ 610,
+ 616,
+ 618,
+ 623,
+ 629,
+ 635,
+ 641,
+ 652,
+ 657,
+ 662,
+ 2,
+ 6,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ ]
+
+
+class lfrXLexer(Lexer):
+ atn = ATNDeserializer().deserialize(serializedATN())
+
+ decisionsToDFA = [DFA(ds, i) for i, ds in enumerate(atn.decisionToState)]
+
+ T__0 = 1
+ T__1 = 2
+ T__2 = 3
+ T__3 = 4
+ T__4 = 5
+ T__5 = 6
+ T__6 = 7
+ T__7 = 8
+ T__8 = 9
+ T__9 = 10
+ T__10 = 11
+ T__11 = 12
+ T__12 = 13
+ T__13 = 14
+ T__14 = 15
+ T__15 = 16
+ T__16 = 17
+ T__17 = 18
+ T__18 = 19
+ T__19 = 20
+ T__20 = 21
+ T__21 = 22
+ T__22 = 23
+ T__23 = 24
+ T__24 = 25
+ T__25 = 26
+ T__26 = 27
+ T__27 = 28
+ T__28 = 29
+ T__29 = 30
+ T__30 = 31
+ T__31 = 32
+ T__32 = 33
+ T__33 = 34
+ T__34 = 35
+ T__35 = 36
+ T__36 = 37
+ T__37 = 38
+ T__38 = 39
+ T__39 = 40
+ T__40 = 41
+ T__41 = 42
+ T__42 = 43
+ T__43 = 44
+ T__44 = 45
+ T__45 = 46
+ T__46 = 47
+ T__47 = 48
+ T__48 = 49
+ T__49 = 50
+ T__50 = 51
+ T__51 = 52
+ T__52 = 53
+ T__53 = 54
+ T__54 = 55
+ T__55 = 56
+ T__56 = 57
+ T__57 = 58
+ T__58 = 59
+ T__59 = 60
+ T__60 = 61
+ T__61 = 62
+ T__62 = 63
+ T__63 = 64
+ T__64 = 65
+ ID = 66
+ WS = 67
+ One_line_comment = 68
+ Block_comment = 69
+ Import_line = 70
+ Real_number = 71
+ Decimal_number = 72
+ Binary_number = 73
+ Octal_number = 74
+ Hex_number = 75
+
+ channelNames = ["DEFAULT_TOKEN_CHANNEL", "HIDDEN"]
+
+ modeNames = ["DEFAULT_MODE"]
+
+ literalNames = [
+ "",
+ "'endmodule'",
+ "'module'",
+ "'('",
+ "')'",
+ "';'",
+ "','",
+ "'finput'",
+ "'foutput'",
+ "'control'",
+ "'distribute@'",
+ "'begin'",
+ "'end'",
+ "'if'",
+ "'else'",
+ "'endcase'",
+ "'case'",
+ "':'",
+ "'default'",
+ "'<='",
+ "'.'",
+ "'signal'",
+ "'flow'",
+ "'storage'",
+ "'pump'",
+ "'number'",
+ "'assign'",
+ "'='",
+ "'['",
+ "']'",
+ "'{'",
+ "'}'",
+ "'#MAP'",
+ "'\"'",
+ "'#MATERIAL'",
+ "'#CONSTRAIN'",
+ "'AND'",
+ "'OR'",
+ "'>'",
+ "'<'",
+ "'>='",
+ "'+'",
+ "'-'",
+ "'!'",
+ "'~'",
+ "'&'",
+ "'~&'",
+ "'|'",
+ "'~|'",
+ "'^'",
+ "'~^'",
+ "'^~'",
+ "'*'",
+ "'/'",
+ "'%'",
+ "'=='",
+ "'!='",
+ "'==='",
+ "'!=='",
+ "'&&'",
+ "'||'",
+ "'**'",
+ "'>>'",
+ "'<<'",
+ "'>>>'",
+ "'<<<'",
+ ]
+
+ symbolicNames = [
+ "",
+ "ID",
+ "WS",
+ "One_line_comment",
+ "Block_comment",
+ "Import_line",
+ "Real_number",
+ "Decimal_number",
+ "Binary_number",
+ "Octal_number",
+ "Hex_number",
+ ]
+
+ ruleNames = [
+ "T__0",
+ "T__1",
+ "T__2",
+ "T__3",
+ "T__4",
+ "T__5",
+ "T__6",
+ "T__7",
+ "T__8",
+ "T__9",
+ "T__10",
+ "T__11",
+ "T__12",
+ "T__13",
+ "T__14",
+ "T__15",
+ "T__16",
+ "T__17",
+ "T__18",
+ "T__19",
+ "T__20",
+ "T__21",
+ "T__22",
+ "T__23",
+ "T__24",
+ "T__25",
+ "T__26",
+ "T__27",
+ "T__28",
+ "T__29",
+ "T__30",
+ "T__31",
+ "T__32",
+ "T__33",
+ "T__34",
+ "T__35",
+ "T__36",
+ "T__37",
+ "T__38",
+ "T__39",
+ "T__40",
+ "T__41",
+ "T__42",
+ "T__43",
+ "T__44",
+ "T__45",
+ "T__46",
+ "T__47",
+ "T__48",
+ "T__49",
+ "T__50",
+ "T__51",
+ "T__52",
+ "T__53",
+ "T__54",
+ "T__55",
+ "T__56",
+ "T__57",
+ "T__58",
+ "T__59",
+ "T__60",
+ "T__61",
+ "T__62",
+ "T__63",
+ "T__64",
+ "ID",
+ "WS",
+ "One_line_comment",
+ "Block_comment",
+ "Import_line",
+ "Real_number",
+ "Decimal_number",
+ "Binary_number",
+ "Octal_number",
+ "Hex_number",
+ "Sign",
+ "Size",
+ "Non_zero_unsigned_number",
+ "Unsigned_number",
+ "Binary_value",
+ "Octal_value",
+ "Hex_value",
+ "Decimal_base",
+ "Binary_base",
+ "Octal_base",
+ "Hex_base",
+ "Non_zero_decimal_digit",
+ "Decimal_digit",
+ "Binary_digit",
+ "Octal_digit",
+ "Hex_digit",
+ "X_digit",
+ "Z_digit",
+ ]
+
+ grammarFileName = "lfrX.g4"
+
+ def __init__(self, input=None, output: TextIO = sys.stdout):
+ super().__init__(input, output)
+ self.checkVersion("4.10.1")
+ self._interp = LexerATNSimulator(
+ self, self.atn, self.decisionsToDFA, PredictionContextCache()
+ )
+ self._actions = None
+ self._predicates = None
diff --git a/lfr/antlrgen/lfrXLexer.tokens b/lfr/antlrgen/lfr/lfrXLexer.tokens
similarity index 100%
rename from lfr/antlrgen/lfrXLexer.tokens
rename to lfr/antlrgen/lfr/lfrXLexer.tokens
diff --git a/lfr/antlrgen/lfrXListener.py b/lfr/antlrgen/lfr/lfrXListener.py
similarity index 54%
rename from lfr/antlrgen/lfrXListener.py
rename to lfr/antlrgen/lfr/lfrXListener.py
index 9297a88..f7ea614 100755
--- a/lfr/antlrgen/lfrXListener.py
+++ b/lfr/antlrgen/lfr/lfrXListener.py
@@ -1,597 +1,561 @@
-# Generated from ./lfrX.g4 by ANTLR 4.9.1
+# Generated from ./lfrX.g4 by ANTLR 4.10.1
from antlr4 import *
+
if __name__ is not None and "." in __name__:
from .lfrXParser import lfrXParser
else:
from lfrXParser import lfrXParser
+
# This class defines a complete listener for a parse tree produced by lfrXParser.
class lfrXListener(ParseTreeListener):
-
# Enter a parse tree produced by lfrXParser#skeleton.
- def enterSkeleton(self, ctx:lfrXParser.SkeletonContext):
+ def enterSkeleton(self, ctx: lfrXParser.SkeletonContext):
pass
# Exit a parse tree produced by lfrXParser#skeleton.
- def exitSkeleton(self, ctx:lfrXParser.SkeletonContext):
+ def exitSkeleton(self, ctx: lfrXParser.SkeletonContext):
pass
-
# Enter a parse tree produced by lfrXParser#module.
- def enterModule(self, ctx:lfrXParser.ModuleContext):
+ def enterModule(self, ctx: lfrXParser.ModuleContext):
pass
# Exit a parse tree produced by lfrXParser#module.
- def exitModule(self, ctx:lfrXParser.ModuleContext):
+ def exitModule(self, ctx: lfrXParser.ModuleContext):
pass
-
# Enter a parse tree produced by lfrXParser#moduledefinition.
- def enterModuledefinition(self, ctx:lfrXParser.ModuledefinitionContext):
+ def enterModuledefinition(self, ctx: lfrXParser.ModuledefinitionContext):
pass
# Exit a parse tree produced by lfrXParser#moduledefinition.
- def exitModuledefinition(self, ctx:lfrXParser.ModuledefinitionContext):
+ def exitModuledefinition(self, ctx: lfrXParser.ModuledefinitionContext):
pass
-
# Enter a parse tree produced by lfrXParser#body.
- def enterBody(self, ctx:lfrXParser.BodyContext):
+ def enterBody(self, ctx: lfrXParser.BodyContext):
pass
# Exit a parse tree produced by lfrXParser#body.
- def exitBody(self, ctx:lfrXParser.BodyContext):
+ def exitBody(self, ctx: lfrXParser.BodyContext):
pass
-
# Enter a parse tree produced by lfrXParser#ioblock.
- def enterIoblock(self, ctx:lfrXParser.IoblockContext):
+ def enterIoblock(self, ctx: lfrXParser.IoblockContext):
pass
# Exit a parse tree produced by lfrXParser#ioblock.
- def exitIoblock(self, ctx:lfrXParser.IoblockContext):
+ def exitIoblock(self, ctx: lfrXParser.IoblockContext):
pass
-
# Enter a parse tree produced by lfrXParser#vectorvar.
- def enterVectorvar(self, ctx:lfrXParser.VectorvarContext):
+ def enterVectorvar(self, ctx: lfrXParser.VectorvarContext):
pass
# Exit a parse tree produced by lfrXParser#vectorvar.
- def exitVectorvar(self, ctx:lfrXParser.VectorvarContext):
+ def exitVectorvar(self, ctx: lfrXParser.VectorvarContext):
pass
-
# Enter a parse tree produced by lfrXParser#explicitIOBlock.
- def enterExplicitIOBlock(self, ctx:lfrXParser.ExplicitIOBlockContext):
+ def enterExplicitIOBlock(self, ctx: lfrXParser.ExplicitIOBlockContext):
pass
# Exit a parse tree produced by lfrXParser#explicitIOBlock.
- def exitExplicitIOBlock(self, ctx:lfrXParser.ExplicitIOBlockContext):
+ def exitExplicitIOBlock(self, ctx: lfrXParser.ExplicitIOBlockContext):
pass
-
# Enter a parse tree produced by lfrXParser#declvar.
- def enterDeclvar(self, ctx:lfrXParser.DeclvarContext):
+ def enterDeclvar(self, ctx: lfrXParser.DeclvarContext):
pass
# Exit a parse tree produced by lfrXParser#declvar.
- def exitDeclvar(self, ctx:lfrXParser.DeclvarContext):
+ def exitDeclvar(self, ctx: lfrXParser.DeclvarContext):
pass
-
# Enter a parse tree produced by lfrXParser#distributionBlock.
- def enterDistributionBlock(self, ctx:lfrXParser.DistributionBlockContext):
+ def enterDistributionBlock(self, ctx: lfrXParser.DistributionBlockContext):
pass
# Exit a parse tree produced by lfrXParser#distributionBlock.
- def exitDistributionBlock(self, ctx:lfrXParser.DistributionBlockContext):
+ def exitDistributionBlock(self, ctx: lfrXParser.DistributionBlockContext):
pass
-
# Enter a parse tree produced by lfrXParser#distributionBody.
- def enterDistributionBody(self, ctx:lfrXParser.DistributionBodyContext):
+ def enterDistributionBody(self, ctx: lfrXParser.DistributionBodyContext):
pass
# Exit a parse tree produced by lfrXParser#distributionBody.
- def exitDistributionBody(self, ctx:lfrXParser.DistributionBodyContext):
+ def exitDistributionBody(self, ctx: lfrXParser.DistributionBodyContext):
pass
-
# Enter a parse tree produced by lfrXParser#distributeBodyStat.
- def enterDistributeBodyStat(self, ctx:lfrXParser.DistributeBodyStatContext):
+ def enterDistributeBodyStat(self, ctx: lfrXParser.DistributeBodyStatContext):
pass
# Exit a parse tree produced by lfrXParser#distributeBodyStat.
- def exitDistributeBodyStat(self, ctx:lfrXParser.DistributeBodyStatContext):
+ def exitDistributeBodyStat(self, ctx: lfrXParser.DistributeBodyStatContext):
pass
-
# Enter a parse tree produced by lfrXParser#ifElseBlock.
- def enterIfElseBlock(self, ctx:lfrXParser.IfElseBlockContext):
+ def enterIfElseBlock(self, ctx: lfrXParser.IfElseBlockContext):
pass
# Exit a parse tree produced by lfrXParser#ifElseBlock.
- def exitIfElseBlock(self, ctx:lfrXParser.IfElseBlockContext):
+ def exitIfElseBlock(self, ctx: lfrXParser.IfElseBlockContext):
pass
-
# Enter a parse tree produced by lfrXParser#ifBlock.
- def enterIfBlock(self, ctx:lfrXParser.IfBlockContext):
+ def enterIfBlock(self, ctx: lfrXParser.IfBlockContext):
pass
# Exit a parse tree produced by lfrXParser#ifBlock.
- def exitIfBlock(self, ctx:lfrXParser.IfBlockContext):
+ def exitIfBlock(self, ctx: lfrXParser.IfBlockContext):
pass
-
# Enter a parse tree produced by lfrXParser#elseBlock.
- def enterElseBlock(self, ctx:lfrXParser.ElseBlockContext):
+ def enterElseBlock(self, ctx: lfrXParser.ElseBlockContext):
pass
# Exit a parse tree produced by lfrXParser#elseBlock.
- def exitElseBlock(self, ctx:lfrXParser.ElseBlockContext):
+ def exitElseBlock(self, ctx: lfrXParser.ElseBlockContext):
pass
-
# Enter a parse tree produced by lfrXParser#elseIfBlock.
- def enterElseIfBlock(self, ctx:lfrXParser.ElseIfBlockContext):
+ def enterElseIfBlock(self, ctx: lfrXParser.ElseIfBlockContext):
pass
# Exit a parse tree produced by lfrXParser#elseIfBlock.
- def exitElseIfBlock(self, ctx:lfrXParser.ElseIfBlockContext):
+ def exitElseIfBlock(self, ctx: lfrXParser.ElseIfBlockContext):
pass
-
# Enter a parse tree produced by lfrXParser#distributeCondition.
- def enterDistributeCondition(self, ctx:lfrXParser.DistributeConditionContext):
+ def enterDistributeCondition(self, ctx: lfrXParser.DistributeConditionContext):
pass
# Exit a parse tree produced by lfrXParser#distributeCondition.
- def exitDistributeCondition(self, ctx:lfrXParser.DistributeConditionContext):
+ def exitDistributeCondition(self, ctx: lfrXParser.DistributeConditionContext):
pass
-
# Enter a parse tree produced by lfrXParser#statementBlock.
- def enterStatementBlock(self, ctx:lfrXParser.StatementBlockContext):
+ def enterStatementBlock(self, ctx: lfrXParser.StatementBlockContext):
pass
# Exit a parse tree produced by lfrXParser#statementBlock.
- def exitStatementBlock(self, ctx:lfrXParser.StatementBlockContext):
+ def exitStatementBlock(self, ctx: lfrXParser.StatementBlockContext):
pass
-
# Enter a parse tree produced by lfrXParser#caseBlock.
- def enterCaseBlock(self, ctx:lfrXParser.CaseBlockContext):
+ def enterCaseBlock(self, ctx: lfrXParser.CaseBlockContext):
pass
# Exit a parse tree produced by lfrXParser#caseBlock.
- def exitCaseBlock(self, ctx:lfrXParser.CaseBlockContext):
+ def exitCaseBlock(self, ctx: lfrXParser.CaseBlockContext):
pass
-
# Enter a parse tree produced by lfrXParser#caseBlockHeader.
- def enterCaseBlockHeader(self, ctx:lfrXParser.CaseBlockHeaderContext):
+ def enterCaseBlockHeader(self, ctx: lfrXParser.CaseBlockHeaderContext):
pass
# Exit a parse tree produced by lfrXParser#caseBlockHeader.
- def exitCaseBlockHeader(self, ctx:lfrXParser.CaseBlockHeaderContext):
+ def exitCaseBlockHeader(self, ctx: lfrXParser.CaseBlockHeaderContext):
pass
-
# Enter a parse tree produced by lfrXParser#casestat.
- def enterCasestat(self, ctx:lfrXParser.CasestatContext):
+ def enterCasestat(self, ctx: lfrXParser.CasestatContext):
pass
# Exit a parse tree produced by lfrXParser#casestat.
- def exitCasestat(self, ctx:lfrXParser.CasestatContext):
+ def exitCasestat(self, ctx: lfrXParser.CasestatContext):
pass
-
# Enter a parse tree produced by lfrXParser#defaultCaseStat.
- def enterDefaultCaseStat(self, ctx:lfrXParser.DefaultCaseStatContext):
+ def enterDefaultCaseStat(self, ctx: lfrXParser.DefaultCaseStatContext):
pass
# Exit a parse tree produced by lfrXParser#defaultCaseStat.
- def exitDefaultCaseStat(self, ctx:lfrXParser.DefaultCaseStatContext):
+ def exitDefaultCaseStat(self, ctx: lfrXParser.DefaultCaseStatContext):
pass
-
# Enter a parse tree produced by lfrXParser#distvalue.
- def enterDistvalue(self, ctx:lfrXParser.DistvalueContext):
+ def enterDistvalue(self, ctx: lfrXParser.DistvalueContext):
pass
# Exit a parse tree produced by lfrXParser#distvalue.
- def exitDistvalue(self, ctx:lfrXParser.DistvalueContext):
+ def exitDistvalue(self, ctx: lfrXParser.DistvalueContext):
pass
-
# Enter a parse tree produced by lfrXParser#distributionassignstat.
- def enterDistributionassignstat(self, ctx:lfrXParser.DistributionassignstatContext):
+ def enterDistributionassignstat(
+ self, ctx: lfrXParser.DistributionassignstatContext
+ ):
pass
# Exit a parse tree produced by lfrXParser#distributionassignstat.
- def exitDistributionassignstat(self, ctx:lfrXParser.DistributionassignstatContext):
+ def exitDistributionassignstat(self, ctx: lfrXParser.DistributionassignstatContext):
pass
-
# Enter a parse tree produced by lfrXParser#sensitivitylist.
- def enterSensitivitylist(self, ctx:lfrXParser.SensitivitylistContext):
+ def enterSensitivitylist(self, ctx: lfrXParser.SensitivitylistContext):
pass
# Exit a parse tree produced by lfrXParser#sensitivitylist.
- def exitSensitivitylist(self, ctx:lfrXParser.SensitivitylistContext):
+ def exitSensitivitylist(self, ctx: lfrXParser.SensitivitylistContext):
pass
-
# Enter a parse tree produced by lfrXParser#signal.
- def enterSignal(self, ctx:lfrXParser.SignalContext):
+ def enterSignal(self, ctx: lfrXParser.SignalContext):
pass
# Exit a parse tree produced by lfrXParser#signal.
- def exitSignal(self, ctx:lfrXParser.SignalContext):
+ def exitSignal(self, ctx: lfrXParser.SignalContext):
pass
-
# Enter a parse tree produced by lfrXParser#statements.
- def enterStatements(self, ctx:lfrXParser.StatementsContext):
+ def enterStatements(self, ctx: lfrXParser.StatementsContext):
pass
# Exit a parse tree produced by lfrXParser#statements.
- def exitStatements(self, ctx:lfrXParser.StatementsContext):
+ def exitStatements(self, ctx: lfrXParser.StatementsContext):
pass
-
# Enter a parse tree produced by lfrXParser#statement.
- def enterStatement(self, ctx:lfrXParser.StatementContext):
+ def enterStatement(self, ctx: lfrXParser.StatementContext):
pass
# Exit a parse tree produced by lfrXParser#statement.
- def exitStatement(self, ctx:lfrXParser.StatementContext):
+ def exitStatement(self, ctx: lfrXParser.StatementContext):
pass
-
# Enter a parse tree produced by lfrXParser#moduleinstantiationstat.
- def enterModuleinstantiationstat(self, ctx:lfrXParser.ModuleinstantiationstatContext):
+ def enterModuleinstantiationstat(
+ self, ctx: lfrXParser.ModuleinstantiationstatContext
+ ):
pass
# Exit a parse tree produced by lfrXParser#moduleinstantiationstat.
- def exitModuleinstantiationstat(self, ctx:lfrXParser.ModuleinstantiationstatContext):
+ def exitModuleinstantiationstat(
+ self, ctx: lfrXParser.ModuleinstantiationstatContext
+ ):
pass
-
# Enter a parse tree produced by lfrXParser#instanceioblock.
- def enterInstanceioblock(self, ctx:lfrXParser.InstanceioblockContext):
+ def enterInstanceioblock(self, ctx: lfrXParser.InstanceioblockContext):
pass
# Exit a parse tree produced by lfrXParser#instanceioblock.
- def exitInstanceioblock(self, ctx:lfrXParser.InstanceioblockContext):
+ def exitInstanceioblock(self, ctx: lfrXParser.InstanceioblockContext):
pass
-
# Enter a parse tree produced by lfrXParser#orderedioblock.
- def enterOrderedioblock(self, ctx:lfrXParser.OrderedioblockContext):
+ def enterOrderedioblock(self, ctx: lfrXParser.OrderedioblockContext):
pass
# Exit a parse tree produced by lfrXParser#orderedioblock.
- def exitOrderedioblock(self, ctx:lfrXParser.OrderedioblockContext):
+ def exitOrderedioblock(self, ctx: lfrXParser.OrderedioblockContext):
pass
-
# Enter a parse tree produced by lfrXParser#unorderedioblock.
- def enterUnorderedioblock(self, ctx:lfrXParser.UnorderedioblockContext):
+ def enterUnorderedioblock(self, ctx: lfrXParser.UnorderedioblockContext):
pass
# Exit a parse tree produced by lfrXParser#unorderedioblock.
- def exitUnorderedioblock(self, ctx:lfrXParser.UnorderedioblockContext):
+ def exitUnorderedioblock(self, ctx: lfrXParser.UnorderedioblockContext):
pass
-
# Enter a parse tree produced by lfrXParser#explicitinstanceiomapping.
- def enterExplicitinstanceiomapping(self, ctx:lfrXParser.ExplicitinstanceiomappingContext):
+ def enterExplicitinstanceiomapping(
+ self, ctx: lfrXParser.ExplicitinstanceiomappingContext
+ ):
pass
# Exit a parse tree produced by lfrXParser#explicitinstanceiomapping.
- def exitExplicitinstanceiomapping(self, ctx:lfrXParser.ExplicitinstanceiomappingContext):
+ def exitExplicitinstanceiomapping(
+ self, ctx: lfrXParser.ExplicitinstanceiomappingContext
+ ):
pass
-
# Enter a parse tree produced by lfrXParser#instancename.
- def enterInstancename(self, ctx:lfrXParser.InstancenameContext):
+ def enterInstancename(self, ctx: lfrXParser.InstancenameContext):
pass
# Exit a parse tree produced by lfrXParser#instancename.
- def exitInstancename(self, ctx:lfrXParser.InstancenameContext):
+ def exitInstancename(self, ctx: lfrXParser.InstancenameContext):
pass
-
# Enter a parse tree produced by lfrXParser#moduletype.
- def enterModuletype(self, ctx:lfrXParser.ModuletypeContext):
+ def enterModuletype(self, ctx: lfrXParser.ModuletypeContext):
pass
# Exit a parse tree produced by lfrXParser#moduletype.
- def exitModuletype(self, ctx:lfrXParser.ModuletypeContext):
+ def exitModuletype(self, ctx: lfrXParser.ModuletypeContext):
pass
-
# Enter a parse tree produced by lfrXParser#tempvariablesstat.
- def enterTempvariablesstat(self, ctx:lfrXParser.TempvariablesstatContext):
+ def enterTempvariablesstat(self, ctx: lfrXParser.TempvariablesstatContext):
pass
# Exit a parse tree produced by lfrXParser#tempvariablesstat.
- def exitTempvariablesstat(self, ctx:lfrXParser.TempvariablesstatContext):
+ def exitTempvariablesstat(self, ctx: lfrXParser.TempvariablesstatContext):
pass
-
# Enter a parse tree produced by lfrXParser#signalvarstat.
- def enterSignalvarstat(self, ctx:lfrXParser.SignalvarstatContext):
+ def enterSignalvarstat(self, ctx: lfrXParser.SignalvarstatContext):
pass
# Exit a parse tree produced by lfrXParser#signalvarstat.
- def exitSignalvarstat(self, ctx:lfrXParser.SignalvarstatContext):
+ def exitSignalvarstat(self, ctx: lfrXParser.SignalvarstatContext):
pass
-
# Enter a parse tree produced by lfrXParser#fluiddeclstat.
- def enterFluiddeclstat(self, ctx:lfrXParser.FluiddeclstatContext):
+ def enterFluiddeclstat(self, ctx: lfrXParser.FluiddeclstatContext):
pass
# Exit a parse tree produced by lfrXParser#fluiddeclstat.
- def exitFluiddeclstat(self, ctx:lfrXParser.FluiddeclstatContext):
+ def exitFluiddeclstat(self, ctx: lfrXParser.FluiddeclstatContext):
pass
-
# Enter a parse tree produced by lfrXParser#storagestat.
- def enterStoragestat(self, ctx:lfrXParser.StoragestatContext):
+ def enterStoragestat(self, ctx: lfrXParser.StoragestatContext):
pass
# Exit a parse tree produced by lfrXParser#storagestat.
- def exitStoragestat(self, ctx:lfrXParser.StoragestatContext):
+ def exitStoragestat(self, ctx: lfrXParser.StoragestatContext):
pass
-
# Enter a parse tree produced by lfrXParser#pumpvarstat.
- def enterPumpvarstat(self, ctx:lfrXParser.PumpvarstatContext):
+ def enterPumpvarstat(self, ctx: lfrXParser.PumpvarstatContext):
pass
# Exit a parse tree produced by lfrXParser#pumpvarstat.
- def exitPumpvarstat(self, ctx:lfrXParser.PumpvarstatContext):
+ def exitPumpvarstat(self, ctx: lfrXParser.PumpvarstatContext):
pass
-
# Enter a parse tree produced by lfrXParser#numvarstat.
- def enterNumvarstat(self, ctx:lfrXParser.NumvarstatContext):
+ def enterNumvarstat(self, ctx: lfrXParser.NumvarstatContext):
pass
# Exit a parse tree produced by lfrXParser#numvarstat.
- def exitNumvarstat(self, ctx:lfrXParser.NumvarstatContext):
+ def exitNumvarstat(self, ctx: lfrXParser.NumvarstatContext):
pass
-
# Enter a parse tree produced by lfrXParser#assignstat.
- def enterAssignstat(self, ctx:lfrXParser.AssignstatContext):
+ def enterAssignstat(self, ctx: lfrXParser.AssignstatContext):
pass
# Exit a parse tree produced by lfrXParser#assignstat.
- def exitAssignstat(self, ctx:lfrXParser.AssignstatContext):
+ def exitAssignstat(self, ctx: lfrXParser.AssignstatContext):
pass
-
# Enter a parse tree produced by lfrXParser#literalassignstat.
- def enterLiteralassignstat(self, ctx:lfrXParser.LiteralassignstatContext):
+ def enterLiteralassignstat(self, ctx: lfrXParser.LiteralassignstatContext):
pass
# Exit a parse tree produced by lfrXParser#literalassignstat.
- def exitLiteralassignstat(self, ctx:lfrXParser.LiteralassignstatContext):
+ def exitLiteralassignstat(self, ctx: lfrXParser.LiteralassignstatContext):
pass
-
# Enter a parse tree produced by lfrXParser#bracketexpression.
- def enterBracketexpression(self, ctx:lfrXParser.BracketexpressionContext):
+ def enterBracketexpression(self, ctx: lfrXParser.BracketexpressionContext):
pass
# Exit a parse tree produced by lfrXParser#bracketexpression.
- def exitBracketexpression(self, ctx:lfrXParser.BracketexpressionContext):
+ def exitBracketexpression(self, ctx: lfrXParser.BracketexpressionContext):
pass
-
# Enter a parse tree produced by lfrXParser#expression.
- def enterExpression(self, ctx:lfrXParser.ExpressionContext):
+ def enterExpression(self, ctx: lfrXParser.ExpressionContext):
pass
# Exit a parse tree produced by lfrXParser#expression.
- def exitExpression(self, ctx:lfrXParser.ExpressionContext):
+ def exitExpression(self, ctx: lfrXParser.ExpressionContext):
pass
-
# Enter a parse tree produced by lfrXParser#expressionterm.
- def enterExpressionterm(self, ctx:lfrXParser.ExpressiontermContext):
+ def enterExpressionterm(self, ctx: lfrXParser.ExpressiontermContext):
pass
# Exit a parse tree produced by lfrXParser#expressionterm.
- def exitExpressionterm(self, ctx:lfrXParser.ExpressiontermContext):
+ def exitExpressionterm(self, ctx: lfrXParser.ExpressiontermContext):
pass
-
# Enter a parse tree produced by lfrXParser#logiccondition_operand.
- def enterLogiccondition_operand(self, ctx:lfrXParser.Logiccondition_operandContext):
+ def enterLogiccondition_operand(
+ self, ctx: lfrXParser.Logiccondition_operandContext
+ ):
pass
# Exit a parse tree produced by lfrXParser#logiccondition_operand.
- def exitLogiccondition_operand(self, ctx:lfrXParser.Logiccondition_operandContext):
+ def exitLogiccondition_operand(self, ctx: lfrXParser.Logiccondition_operandContext):
pass
-
# Enter a parse tree produced by lfrXParser#logiccondition.
- def enterLogiccondition(self, ctx:lfrXParser.LogicconditionContext):
+ def enterLogiccondition(self, ctx: lfrXParser.LogicconditionContext):
pass
# Exit a parse tree produced by lfrXParser#logiccondition.
- def exitLogiccondition(self, ctx:lfrXParser.LogicconditionContext):
+ def exitLogiccondition(self, ctx: lfrXParser.LogicconditionContext):
pass
-
# Enter a parse tree produced by lfrXParser#logic_value.
- def enterLogic_value(self, ctx:lfrXParser.Logic_valueContext):
+ def enterLogic_value(self, ctx: lfrXParser.Logic_valueContext):
pass
# Exit a parse tree produced by lfrXParser#logic_value.
- def exitLogic_value(self, ctx:lfrXParser.Logic_valueContext):
+ def exitLogic_value(self, ctx: lfrXParser.Logic_valueContext):
pass
-
# Enter a parse tree produced by lfrXParser#vector.
- def enterVector(self, ctx:lfrXParser.VectorContext):
+ def enterVector(self, ctx: lfrXParser.VectorContext):
pass
# Exit a parse tree produced by lfrXParser#vector.
- def exitVector(self, ctx:lfrXParser.VectorContext):
+ def exitVector(self, ctx: lfrXParser.VectorContext):
pass
-
# Enter a parse tree produced by lfrXParser#variables.
- def enterVariables(self, ctx:lfrXParser.VariablesContext):
+ def enterVariables(self, ctx: lfrXParser.VariablesContext):
pass
# Exit a parse tree produced by lfrXParser#variables.
- def exitVariables(self, ctx:lfrXParser.VariablesContext):
+ def exitVariables(self, ctx: lfrXParser.VariablesContext):
pass
-
# Enter a parse tree produced by lfrXParser#concatenation.
- def enterConcatenation(self, ctx:lfrXParser.ConcatenationContext):
+ def enterConcatenation(self, ctx: lfrXParser.ConcatenationContext):
pass
# Exit a parse tree produced by lfrXParser#concatenation.
- def exitConcatenation(self, ctx:lfrXParser.ConcatenationContext):
+ def exitConcatenation(self, ctx: lfrXParser.ConcatenationContext):
pass
-
# Enter a parse tree produced by lfrXParser#lhs.
- def enterLhs(self, ctx:lfrXParser.LhsContext):
+ def enterLhs(self, ctx: lfrXParser.LhsContext):
pass
# Exit a parse tree produced by lfrXParser#lhs.
- def exitLhs(self, ctx:lfrXParser.LhsContext):
+ def exitLhs(self, ctx: lfrXParser.LhsContext):
pass
-
# Enter a parse tree produced by lfrXParser#ioassignstat.
- def enterIoassignstat(self, ctx:lfrXParser.IoassignstatContext):
+ def enterIoassignstat(self, ctx: lfrXParser.IoassignstatContext):
pass
# Exit a parse tree produced by lfrXParser#ioassignstat.
- def exitIoassignstat(self, ctx:lfrXParser.IoassignstatContext):
+ def exitIoassignstat(self, ctx: lfrXParser.IoassignstatContext):
pass
-
# Enter a parse tree produced by lfrXParser#technologydirectives.
- def enterTechnologydirectives(self, ctx:lfrXParser.TechnologydirectivesContext):
+ def enterTechnologydirectives(self, ctx: lfrXParser.TechnologydirectivesContext):
pass
# Exit a parse tree produced by lfrXParser#technologydirectives.
- def exitTechnologydirectives(self, ctx:lfrXParser.TechnologydirectivesContext):
+ def exitTechnologydirectives(self, ctx: lfrXParser.TechnologydirectivesContext):
pass
-
# Enter a parse tree produced by lfrXParser#technologymappingdirective.
- def enterTechnologymappingdirective(self, ctx:lfrXParser.TechnologymappingdirectiveContext):
+ def enterTechnologymappingdirective(
+ self, ctx: lfrXParser.TechnologymappingdirectiveContext
+ ):
pass
# Exit a parse tree produced by lfrXParser#technologymappingdirective.
- def exitTechnologymappingdirective(self, ctx:lfrXParser.TechnologymappingdirectiveContext):
+ def exitTechnologymappingdirective(
+ self, ctx: lfrXParser.TechnologymappingdirectiveContext
+ ):
pass
-
# Enter a parse tree produced by lfrXParser#materialmappingdirective.
- def enterMaterialmappingdirective(self, ctx:lfrXParser.MaterialmappingdirectiveContext):
+ def enterMaterialmappingdirective(
+ self, ctx: lfrXParser.MaterialmappingdirectiveContext
+ ):
pass
# Exit a parse tree produced by lfrXParser#materialmappingdirective.
- def exitMaterialmappingdirective(self, ctx:lfrXParser.MaterialmappingdirectiveContext):
+ def exitMaterialmappingdirective(
+ self, ctx: lfrXParser.MaterialmappingdirectiveContext
+ ):
pass
-
# Enter a parse tree produced by lfrXParser#mappingoperator.
- def enterMappingoperator(self, ctx:lfrXParser.MappingoperatorContext):
+ def enterMappingoperator(self, ctx: lfrXParser.MappingoperatorContext):
pass
# Exit a parse tree produced by lfrXParser#mappingoperator.
- def exitMappingoperator(self, ctx:lfrXParser.MappingoperatorContext):
+ def exitMappingoperator(self, ctx: lfrXParser.MappingoperatorContext):
pass
-
# Enter a parse tree produced by lfrXParser#performancedirective.
- def enterPerformancedirective(self, ctx:lfrXParser.PerformancedirectiveContext):
+ def enterPerformancedirective(self, ctx: lfrXParser.PerformancedirectiveContext):
pass
# Exit a parse tree produced by lfrXParser#performancedirective.
- def exitPerformancedirective(self, ctx:lfrXParser.PerformancedirectiveContext):
+ def exitPerformancedirective(self, ctx: lfrXParser.PerformancedirectiveContext):
pass
-
# Enter a parse tree produced by lfrXParser#constraint.
- def enterConstraint(self, ctx:lfrXParser.ConstraintContext):
+ def enterConstraint(self, ctx: lfrXParser.ConstraintContext):
pass
# Exit a parse tree produced by lfrXParser#constraint.
- def exitConstraint(self, ctx:lfrXParser.ConstraintContext):
+ def exitConstraint(self, ctx: lfrXParser.ConstraintContext):
pass
-
# Enter a parse tree produced by lfrXParser#unit.
- def enterUnit(self, ctx:lfrXParser.UnitContext):
+ def enterUnit(self, ctx: lfrXParser.UnitContext):
pass
# Exit a parse tree produced by lfrXParser#unit.
- def exitUnit(self, ctx:lfrXParser.UnitContext):
+ def exitUnit(self, ctx: lfrXParser.UnitContext):
pass
-
# Enter a parse tree produced by lfrXParser#unary_operator.
- def enterUnary_operator(self, ctx:lfrXParser.Unary_operatorContext):
+ def enterUnary_operator(self, ctx: lfrXParser.Unary_operatorContext):
pass
# Exit a parse tree produced by lfrXParser#unary_operator.
- def exitUnary_operator(self, ctx:lfrXParser.Unary_operatorContext):
+ def exitUnary_operator(self, ctx: lfrXParser.Unary_operatorContext):
pass
-
# Enter a parse tree produced by lfrXParser#binary_operator.
- def enterBinary_operator(self, ctx:lfrXParser.Binary_operatorContext):
+ def enterBinary_operator(self, ctx: lfrXParser.Binary_operatorContext):
pass
# Exit a parse tree produced by lfrXParser#binary_operator.
- def exitBinary_operator(self, ctx:lfrXParser.Binary_operatorContext):
+ def exitBinary_operator(self, ctx: lfrXParser.Binary_operatorContext):
pass
-
# Enter a parse tree produced by lfrXParser#unary_module_path_operator.
- def enterUnary_module_path_operator(self, ctx:lfrXParser.Unary_module_path_operatorContext):
+ def enterUnary_module_path_operator(
+ self, ctx: lfrXParser.Unary_module_path_operatorContext
+ ):
pass
# Exit a parse tree produced by lfrXParser#unary_module_path_operator.
- def exitUnary_module_path_operator(self, ctx:lfrXParser.Unary_module_path_operatorContext):
+ def exitUnary_module_path_operator(
+ self, ctx: lfrXParser.Unary_module_path_operatorContext
+ ):
pass
-
# Enter a parse tree produced by lfrXParser#binary_module_path_operator.
- def enterBinary_module_path_operator(self, ctx:lfrXParser.Binary_module_path_operatorContext):
+ def enterBinary_module_path_operator(
+ self, ctx: lfrXParser.Binary_module_path_operatorContext
+ ):
pass
# Exit a parse tree produced by lfrXParser#binary_module_path_operator.
- def exitBinary_module_path_operator(self, ctx:lfrXParser.Binary_module_path_operatorContext):
+ def exitBinary_module_path_operator(
+ self, ctx: lfrXParser.Binary_module_path_operatorContext
+ ):
pass
-
# Enter a parse tree produced by lfrXParser#number.
- def enterNumber(self, ctx:lfrXParser.NumberContext):
+ def enterNumber(self, ctx: lfrXParser.NumberContext):
pass
# Exit a parse tree produced by lfrXParser#number.
- def exitNumber(self, ctx:lfrXParser.NumberContext):
+ def exitNumber(self, ctx: lfrXParser.NumberContext):
pass
-
-del lfrXParser
\ No newline at end of file
+del lfrXParser
diff --git a/lfr/antlrgen/lfr/lfrXParser.py b/lfr/antlrgen/lfr/lfrXParser.py
new file mode 100755
index 0000000..9cf5d05
--- /dev/null
+++ b/lfr/antlrgen/lfr/lfrXParser.py
@@ -0,0 +1,9885 @@
+# Generated from ./lfrX.g4 by ANTLR 4.10.1
+# encoding: utf-8
+import sys
+from io import StringIO
+
+from antlr4 import *
+
+if sys.version_info[1] > 5:
+ from typing import TextIO
+else:
+ from typing.io import TextIO
+
+
+def serializedATN():
+ return [
+ 4,
+ 1,
+ 75,
+ 593,
+ 2,
+ 0,
+ 7,
+ 0,
+ 2,
+ 1,
+ 7,
+ 1,
+ 2,
+ 2,
+ 7,
+ 2,
+ 2,
+ 3,
+ 7,
+ 3,
+ 2,
+ 4,
+ 7,
+ 4,
+ 2,
+ 5,
+ 7,
+ 5,
+ 2,
+ 6,
+ 7,
+ 6,
+ 2,
+ 7,
+ 7,
+ 7,
+ 2,
+ 8,
+ 7,
+ 8,
+ 2,
+ 9,
+ 7,
+ 9,
+ 2,
+ 10,
+ 7,
+ 10,
+ 2,
+ 11,
+ 7,
+ 11,
+ 2,
+ 12,
+ 7,
+ 12,
+ 2,
+ 13,
+ 7,
+ 13,
+ 2,
+ 14,
+ 7,
+ 14,
+ 2,
+ 15,
+ 7,
+ 15,
+ 2,
+ 16,
+ 7,
+ 16,
+ 2,
+ 17,
+ 7,
+ 17,
+ 2,
+ 18,
+ 7,
+ 18,
+ 2,
+ 19,
+ 7,
+ 19,
+ 2,
+ 20,
+ 7,
+ 20,
+ 2,
+ 21,
+ 7,
+ 21,
+ 2,
+ 22,
+ 7,
+ 22,
+ 2,
+ 23,
+ 7,
+ 23,
+ 2,
+ 24,
+ 7,
+ 24,
+ 2,
+ 25,
+ 7,
+ 25,
+ 2,
+ 26,
+ 7,
+ 26,
+ 2,
+ 27,
+ 7,
+ 27,
+ 2,
+ 28,
+ 7,
+ 28,
+ 2,
+ 29,
+ 7,
+ 29,
+ 2,
+ 30,
+ 7,
+ 30,
+ 2,
+ 31,
+ 7,
+ 31,
+ 2,
+ 32,
+ 7,
+ 32,
+ 2,
+ 33,
+ 7,
+ 33,
+ 2,
+ 34,
+ 7,
+ 34,
+ 2,
+ 35,
+ 7,
+ 35,
+ 2,
+ 36,
+ 7,
+ 36,
+ 2,
+ 37,
+ 7,
+ 37,
+ 2,
+ 38,
+ 7,
+ 38,
+ 2,
+ 39,
+ 7,
+ 39,
+ 2,
+ 40,
+ 7,
+ 40,
+ 2,
+ 41,
+ 7,
+ 41,
+ 2,
+ 42,
+ 7,
+ 42,
+ 2,
+ 43,
+ 7,
+ 43,
+ 2,
+ 44,
+ 7,
+ 44,
+ 2,
+ 45,
+ 7,
+ 45,
+ 2,
+ 46,
+ 7,
+ 46,
+ 2,
+ 47,
+ 7,
+ 47,
+ 2,
+ 48,
+ 7,
+ 48,
+ 2,
+ 49,
+ 7,
+ 49,
+ 2,
+ 50,
+ 7,
+ 50,
+ 2,
+ 51,
+ 7,
+ 51,
+ 2,
+ 52,
+ 7,
+ 52,
+ 2,
+ 53,
+ 7,
+ 53,
+ 2,
+ 54,
+ 7,
+ 54,
+ 2,
+ 55,
+ 7,
+ 55,
+ 2,
+ 56,
+ 7,
+ 56,
+ 2,
+ 57,
+ 7,
+ 57,
+ 2,
+ 58,
+ 7,
+ 58,
+ 2,
+ 59,
+ 7,
+ 59,
+ 2,
+ 60,
+ 7,
+ 60,
+ 2,
+ 61,
+ 7,
+ 61,
+ 2,
+ 62,
+ 7,
+ 62,
+ 2,
+ 63,
+ 7,
+ 63,
+ 2,
+ 64,
+ 7,
+ 64,
+ 1,
+ 0,
+ 4,
+ 0,
+ 132,
+ 8,
+ 0,
+ 11,
+ 0,
+ 12,
+ 0,
+ 133,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 2,
+ 1,
+ 2,
+ 1,
+ 2,
+ 1,
+ 2,
+ 1,
+ 2,
+ 3,
+ 2,
+ 146,
+ 8,
+ 2,
+ 1,
+ 2,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 3,
+ 4,
+ 3,
+ 152,
+ 8,
+ 3,
+ 11,
+ 3,
+ 12,
+ 3,
+ 153,
+ 1,
+ 4,
+ 1,
+ 4,
+ 1,
+ 4,
+ 5,
+ 4,
+ 159,
+ 8,
+ 4,
+ 10,
+ 4,
+ 12,
+ 4,
+ 162,
+ 9,
+ 4,
+ 1,
+ 4,
+ 1,
+ 4,
+ 1,
+ 4,
+ 5,
+ 4,
+ 167,
+ 8,
+ 4,
+ 10,
+ 4,
+ 12,
+ 4,
+ 170,
+ 9,
+ 4,
+ 3,
+ 4,
+ 172,
+ 8,
+ 4,
+ 1,
+ 5,
+ 1,
+ 5,
+ 3,
+ 5,
+ 176,
+ 8,
+ 5,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 5,
+ 6,
+ 182,
+ 8,
+ 6,
+ 10,
+ 6,
+ 12,
+ 6,
+ 185,
+ 9,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 5,
+ 6,
+ 191,
+ 8,
+ 6,
+ 10,
+ 6,
+ 12,
+ 6,
+ 194,
+ 9,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 5,
+ 6,
+ 200,
+ 8,
+ 6,
+ 10,
+ 6,
+ 12,
+ 6,
+ 203,
+ 9,
+ 6,
+ 3,
+ 6,
+ 205,
+ 8,
+ 6,
+ 1,
+ 7,
+ 3,
+ 7,
+ 208,
+ 8,
+ 7,
+ 1,
+ 7,
+ 1,
+ 7,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 9,
+ 4,
+ 9,
+ 221,
+ 8,
+ 9,
+ 11,
+ 9,
+ 12,
+ 9,
+ 222,
+ 1,
+ 10,
+ 1,
+ 10,
+ 1,
+ 10,
+ 3,
+ 10,
+ 228,
+ 8,
+ 10,
+ 1,
+ 11,
+ 1,
+ 11,
+ 5,
+ 11,
+ 232,
+ 8,
+ 11,
+ 10,
+ 11,
+ 12,
+ 11,
+ 235,
+ 9,
+ 11,
+ 1,
+ 11,
+ 3,
+ 11,
+ 238,
+ 8,
+ 11,
+ 1,
+ 12,
+ 1,
+ 12,
+ 1,
+ 12,
+ 1,
+ 12,
+ 1,
+ 12,
+ 1,
+ 12,
+ 1,
+ 13,
+ 1,
+ 13,
+ 1,
+ 13,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 15,
+ 1,
+ 15,
+ 1,
+ 15,
+ 1,
+ 15,
+ 1,
+ 16,
+ 1,
+ 16,
+ 4,
+ 16,
+ 262,
+ 8,
+ 16,
+ 11,
+ 16,
+ 12,
+ 16,
+ 263,
+ 1,
+ 16,
+ 1,
+ 16,
+ 1,
+ 16,
+ 3,
+ 16,
+ 269,
+ 8,
+ 16,
+ 1,
+ 17,
+ 1,
+ 17,
+ 4,
+ 17,
+ 273,
+ 8,
+ 17,
+ 11,
+ 17,
+ 12,
+ 17,
+ 274,
+ 1,
+ 17,
+ 3,
+ 17,
+ 278,
+ 8,
+ 17,
+ 1,
+ 17,
+ 1,
+ 17,
+ 1,
+ 18,
+ 1,
+ 18,
+ 1,
+ 18,
+ 1,
+ 18,
+ 1,
+ 18,
+ 1,
+ 19,
+ 1,
+ 19,
+ 1,
+ 19,
+ 1,
+ 19,
+ 1,
+ 20,
+ 1,
+ 20,
+ 1,
+ 20,
+ 1,
+ 20,
+ 1,
+ 21,
+ 1,
+ 21,
+ 1,
+ 22,
+ 1,
+ 22,
+ 1,
+ 22,
+ 1,
+ 22,
+ 1,
+ 22,
+ 3,
+ 22,
+ 302,
+ 8,
+ 22,
+ 1,
+ 22,
+ 1,
+ 22,
+ 1,
+ 23,
+ 1,
+ 23,
+ 1,
+ 23,
+ 5,
+ 23,
+ 309,
+ 8,
+ 23,
+ 10,
+ 23,
+ 12,
+ 23,
+ 312,
+ 9,
+ 23,
+ 1,
+ 24,
+ 1,
+ 24,
+ 3,
+ 24,
+ 316,
+ 8,
+ 24,
+ 1,
+ 25,
+ 1,
+ 25,
+ 1,
+ 25,
+ 1,
+ 25,
+ 3,
+ 25,
+ 322,
+ 8,
+ 25,
+ 1,
+ 26,
+ 1,
+ 26,
+ 1,
+ 26,
+ 1,
+ 26,
+ 1,
+ 26,
+ 3,
+ 26,
+ 329,
+ 8,
+ 26,
+ 1,
+ 27,
+ 1,
+ 27,
+ 1,
+ 27,
+ 1,
+ 27,
+ 1,
+ 27,
+ 1,
+ 27,
+ 1,
+ 28,
+ 1,
+ 28,
+ 3,
+ 28,
+ 339,
+ 8,
+ 28,
+ 1,
+ 29,
+ 1,
+ 29,
+ 1,
+ 29,
+ 5,
+ 29,
+ 344,
+ 8,
+ 29,
+ 10,
+ 29,
+ 12,
+ 29,
+ 347,
+ 9,
+ 29,
+ 1,
+ 30,
+ 1,
+ 30,
+ 1,
+ 30,
+ 5,
+ 30,
+ 352,
+ 8,
+ 30,
+ 10,
+ 30,
+ 12,
+ 30,
+ 355,
+ 9,
+ 30,
+ 1,
+ 31,
+ 1,
+ 31,
+ 1,
+ 31,
+ 1,
+ 31,
+ 1,
+ 31,
+ 1,
+ 31,
+ 1,
+ 32,
+ 1,
+ 32,
+ 1,
+ 33,
+ 1,
+ 33,
+ 1,
+ 34,
+ 1,
+ 34,
+ 1,
+ 34,
+ 1,
+ 34,
+ 1,
+ 34,
+ 3,
+ 34,
+ 372,
+ 8,
+ 34,
+ 1,
+ 35,
+ 1,
+ 35,
+ 1,
+ 35,
+ 1,
+ 35,
+ 5,
+ 35,
+ 378,
+ 8,
+ 35,
+ 10,
+ 35,
+ 12,
+ 35,
+ 381,
+ 9,
+ 35,
+ 1,
+ 36,
+ 1,
+ 36,
+ 1,
+ 36,
+ 1,
+ 36,
+ 5,
+ 36,
+ 387,
+ 8,
+ 36,
+ 10,
+ 36,
+ 12,
+ 36,
+ 390,
+ 9,
+ 36,
+ 1,
+ 37,
+ 1,
+ 37,
+ 1,
+ 37,
+ 1,
+ 37,
+ 5,
+ 37,
+ 396,
+ 8,
+ 37,
+ 10,
+ 37,
+ 12,
+ 37,
+ 399,
+ 9,
+ 37,
+ 1,
+ 38,
+ 1,
+ 38,
+ 1,
+ 38,
+ 1,
+ 38,
+ 5,
+ 38,
+ 405,
+ 8,
+ 38,
+ 10,
+ 38,
+ 12,
+ 38,
+ 408,
+ 9,
+ 38,
+ 1,
+ 39,
+ 1,
+ 39,
+ 1,
+ 39,
+ 1,
+ 39,
+ 5,
+ 39,
+ 414,
+ 8,
+ 39,
+ 10,
+ 39,
+ 12,
+ 39,
+ 417,
+ 9,
+ 39,
+ 1,
+ 40,
+ 1,
+ 40,
+ 1,
+ 40,
+ 1,
+ 40,
+ 1,
+ 40,
+ 3,
+ 40,
+ 424,
+ 8,
+ 40,
+ 1,
+ 41,
+ 1,
+ 41,
+ 1,
+ 41,
+ 1,
+ 41,
+ 3,
+ 41,
+ 430,
+ 8,
+ 41,
+ 1,
+ 42,
+ 3,
+ 42,
+ 433,
+ 8,
+ 42,
+ 1,
+ 42,
+ 1,
+ 42,
+ 1,
+ 42,
+ 1,
+ 42,
+ 1,
+ 43,
+ 1,
+ 43,
+ 3,
+ 43,
+ 441,
+ 8,
+ 43,
+ 1,
+ 43,
+ 1,
+ 43,
+ 1,
+ 43,
+ 3,
+ 43,
+ 446,
+ 8,
+ 43,
+ 5,
+ 43,
+ 448,
+ 8,
+ 43,
+ 10,
+ 43,
+ 12,
+ 43,
+ 451,
+ 9,
+ 43,
+ 1,
+ 44,
+ 3,
+ 44,
+ 454,
+ 8,
+ 44,
+ 1,
+ 44,
+ 1,
+ 44,
+ 3,
+ 44,
+ 458,
+ 8,
+ 44,
+ 1,
+ 45,
+ 1,
+ 45,
+ 3,
+ 45,
+ 462,
+ 8,
+ 45,
+ 1,
+ 45,
+ 1,
+ 45,
+ 1,
+ 45,
+ 3,
+ 45,
+ 467,
+ 8,
+ 45,
+ 5,
+ 45,
+ 469,
+ 8,
+ 45,
+ 10,
+ 45,
+ 12,
+ 45,
+ 472,
+ 9,
+ 45,
+ 1,
+ 46,
+ 1,
+ 46,
+ 1,
+ 46,
+ 1,
+ 46,
+ 1,
+ 47,
+ 1,
+ 47,
+ 1,
+ 48,
+ 1,
+ 48,
+ 1,
+ 48,
+ 1,
+ 48,
+ 3,
+ 48,
+ 484,
+ 8,
+ 48,
+ 1,
+ 48,
+ 1,
+ 48,
+ 1,
+ 49,
+ 1,
+ 49,
+ 3,
+ 49,
+ 490,
+ 8,
+ 49,
+ 1,
+ 50,
+ 1,
+ 50,
+ 1,
+ 50,
+ 1,
+ 50,
+ 5,
+ 50,
+ 496,
+ 8,
+ 50,
+ 10,
+ 50,
+ 12,
+ 50,
+ 499,
+ 9,
+ 50,
+ 1,
+ 50,
+ 1,
+ 50,
+ 3,
+ 50,
+ 503,
+ 8,
+ 50,
+ 1,
+ 51,
+ 1,
+ 51,
+ 1,
+ 52,
+ 1,
+ 52,
+ 1,
+ 53,
+ 1,
+ 53,
+ 1,
+ 53,
+ 3,
+ 53,
+ 512,
+ 8,
+ 53,
+ 1,
+ 54,
+ 1,
+ 54,
+ 1,
+ 54,
+ 4,
+ 54,
+ 517,
+ 8,
+ 54,
+ 11,
+ 54,
+ 12,
+ 54,
+ 518,
+ 1,
+ 54,
+ 1,
+ 54,
+ 1,
+ 54,
+ 1,
+ 54,
+ 3,
+ 54,
+ 525,
+ 8,
+ 54,
+ 1,
+ 54,
+ 1,
+ 54,
+ 1,
+ 55,
+ 1,
+ 55,
+ 1,
+ 55,
+ 1,
+ 55,
+ 1,
+ 56,
+ 1,
+ 56,
+ 3,
+ 56,
+ 535,
+ 8,
+ 56,
+ 1,
+ 57,
+ 1,
+ 57,
+ 1,
+ 57,
+ 1,
+ 57,
+ 1,
+ 57,
+ 1,
+ 57,
+ 1,
+ 57,
+ 5,
+ 57,
+ 544,
+ 8,
+ 57,
+ 10,
+ 57,
+ 12,
+ 57,
+ 547,
+ 9,
+ 57,
+ 1,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 3,
+ 58,
+ 553,
+ 8,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 3,
+ 58,
+ 559,
+ 8,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 3,
+ 58,
+ 565,
+ 8,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 3,
+ 58,
+ 571,
+ 8,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 1,
+ 58,
+ 3,
+ 58,
+ 577,
+ 8,
+ 58,
+ 3,
+ 58,
+ 579,
+ 8,
+ 58,
+ 1,
+ 59,
+ 1,
+ 59,
+ 1,
+ 60,
+ 1,
+ 60,
+ 1,
+ 61,
+ 1,
+ 61,
+ 1,
+ 62,
+ 1,
+ 62,
+ 1,
+ 63,
+ 1,
+ 63,
+ 1,
+ 64,
+ 1,
+ 64,
+ 1,
+ 64,
+ 0,
+ 0,
+ 65,
+ 0,
+ 2,
+ 4,
+ 6,
+ 8,
+ 10,
+ 12,
+ 14,
+ 16,
+ 18,
+ 20,
+ 22,
+ 24,
+ 26,
+ 28,
+ 30,
+ 32,
+ 34,
+ 36,
+ 38,
+ 40,
+ 42,
+ 44,
+ 46,
+ 48,
+ 50,
+ 52,
+ 54,
+ 56,
+ 58,
+ 60,
+ 62,
+ 64,
+ 66,
+ 68,
+ 70,
+ 72,
+ 74,
+ 76,
+ 78,
+ 80,
+ 82,
+ 84,
+ 86,
+ 88,
+ 90,
+ 92,
+ 94,
+ 96,
+ 98,
+ 100,
+ 102,
+ 104,
+ 106,
+ 108,
+ 110,
+ 112,
+ 114,
+ 116,
+ 118,
+ 120,
+ 122,
+ 124,
+ 126,
+ 128,
+ 0,
+ 7,
+ 2,
+ 0,
+ 23,
+ 24,
+ 26,
+ 26,
+ 1,
+ 0,
+ 36,
+ 37,
+ 1,
+ 0,
+ 41,
+ 51,
+ 5,
+ 0,
+ 19,
+ 19,
+ 38,
+ 42,
+ 45,
+ 45,
+ 47,
+ 47,
+ 49,
+ 65,
+ 1,
+ 0,
+ 43,
+ 51,
+ 5,
+ 0,
+ 45,
+ 45,
+ 47,
+ 47,
+ 49,
+ 51,
+ 55,
+ 56,
+ 59,
+ 60,
+ 1,
+ 0,
+ 71,
+ 75,
+ 601,
+ 0,
+ 131,
+ 1,
+ 0,
+ 0,
+ 0,
+ 2,
+ 135,
+ 1,
+ 0,
+ 0,
+ 0,
+ 4,
+ 139,
+ 1,
+ 0,
+ 0,
+ 0,
+ 6,
+ 151,
+ 1,
+ 0,
+ 0,
+ 0,
+ 8,
+ 171,
+ 1,
+ 0,
+ 0,
+ 0,
+ 10,
+ 173,
+ 1,
+ 0,
+ 0,
+ 0,
+ 12,
+ 204,
+ 1,
+ 0,
+ 0,
+ 0,
+ 14,
+ 207,
+ 1,
+ 0,
+ 0,
+ 0,
+ 16,
+ 211,
+ 1,
+ 0,
+ 0,
+ 0,
+ 18,
+ 220,
+ 1,
+ 0,
+ 0,
+ 0,
+ 20,
+ 227,
+ 1,
+ 0,
+ 0,
+ 0,
+ 22,
+ 229,
+ 1,
+ 0,
+ 0,
+ 0,
+ 24,
+ 239,
+ 1,
+ 0,
+ 0,
+ 0,
+ 26,
+ 245,
+ 1,
+ 0,
+ 0,
+ 0,
+ 28,
+ 248,
+ 1,
+ 0,
+ 0,
+ 0,
+ 30,
+ 255,
+ 1,
+ 0,
+ 0,
+ 0,
+ 32,
+ 268,
+ 1,
+ 0,
+ 0,
+ 0,
+ 34,
+ 270,
+ 1,
+ 0,
+ 0,
+ 0,
+ 36,
+ 281,
+ 1,
+ 0,
+ 0,
+ 0,
+ 38,
+ 286,
+ 1,
+ 0,
+ 0,
+ 0,
+ 40,
+ 290,
+ 1,
+ 0,
+ 0,
+ 0,
+ 42,
+ 294,
+ 1,
+ 0,
+ 0,
+ 0,
+ 44,
+ 296,
+ 1,
+ 0,
+ 0,
+ 0,
+ 46,
+ 305,
+ 1,
+ 0,
+ 0,
+ 0,
+ 48,
+ 313,
+ 1,
+ 0,
+ 0,
+ 0,
+ 50,
+ 321,
+ 1,
+ 0,
+ 0,
+ 0,
+ 52,
+ 328,
+ 1,
+ 0,
+ 0,
+ 0,
+ 54,
+ 330,
+ 1,
+ 0,
+ 0,
+ 0,
+ 56,
+ 338,
+ 1,
+ 0,
+ 0,
+ 0,
+ 58,
+ 340,
+ 1,
+ 0,
+ 0,
+ 0,
+ 60,
+ 348,
+ 1,
+ 0,
+ 0,
+ 0,
+ 62,
+ 356,
+ 1,
+ 0,
+ 0,
+ 0,
+ 64,
+ 362,
+ 1,
+ 0,
+ 0,
+ 0,
+ 66,
+ 364,
+ 1,
+ 0,
+ 0,
+ 0,
+ 68,
+ 371,
+ 1,
+ 0,
+ 0,
+ 0,
+ 70,
+ 373,
+ 1,
+ 0,
+ 0,
+ 0,
+ 72,
+ 382,
+ 1,
+ 0,
+ 0,
+ 0,
+ 74,
+ 391,
+ 1,
+ 0,
+ 0,
+ 0,
+ 76,
+ 400,
+ 1,
+ 0,
+ 0,
+ 0,
+ 78,
+ 409,
+ 1,
+ 0,
+ 0,
+ 0,
+ 80,
+ 418,
+ 1,
+ 0,
+ 0,
+ 0,
+ 82,
+ 425,
+ 1,
+ 0,
+ 0,
+ 0,
+ 84,
+ 432,
+ 1,
+ 0,
+ 0,
+ 0,
+ 86,
+ 440,
+ 1,
+ 0,
+ 0,
+ 0,
+ 88,
+ 457,
+ 1,
+ 0,
+ 0,
+ 0,
+ 90,
+ 461,
+ 1,
+ 0,
+ 0,
+ 0,
+ 92,
+ 473,
+ 1,
+ 0,
+ 0,
+ 0,
+ 94,
+ 477,
+ 1,
+ 0,
+ 0,
+ 0,
+ 96,
+ 479,
+ 1,
+ 0,
+ 0,
+ 0,
+ 98,
+ 489,
+ 1,
+ 0,
+ 0,
+ 0,
+ 100,
+ 491,
+ 1,
+ 0,
+ 0,
+ 0,
+ 102,
+ 504,
+ 1,
+ 0,
+ 0,
+ 0,
+ 104,
+ 506,
+ 1,
+ 0,
+ 0,
+ 0,
+ 106,
+ 511,
+ 1,
+ 0,
+ 0,
+ 0,
+ 108,
+ 513,
+ 1,
+ 0,
+ 0,
+ 0,
+ 110,
+ 528,
+ 1,
+ 0,
+ 0,
+ 0,
+ 112,
+ 534,
+ 1,
+ 0,
+ 0,
+ 0,
+ 114,
+ 536,
+ 1,
+ 0,
+ 0,
+ 0,
+ 116,
+ 578,
+ 1,
+ 0,
+ 0,
+ 0,
+ 118,
+ 580,
+ 1,
+ 0,
+ 0,
+ 0,
+ 120,
+ 582,
+ 1,
+ 0,
+ 0,
+ 0,
+ 122,
+ 584,
+ 1,
+ 0,
+ 0,
+ 0,
+ 124,
+ 586,
+ 1,
+ 0,
+ 0,
+ 0,
+ 126,
+ 588,
+ 1,
+ 0,
+ 0,
+ 0,
+ 128,
+ 590,
+ 1,
+ 0,
+ 0,
+ 0,
+ 130,
+ 132,
+ 3,
+ 2,
+ 1,
+ 0,
+ 131,
+ 130,
+ 1,
+ 0,
+ 0,
+ 0,
+ 132,
+ 133,
+ 1,
+ 0,
+ 0,
+ 0,
+ 133,
+ 131,
+ 1,
+ 0,
+ 0,
+ 0,
+ 133,
+ 134,
+ 1,
+ 0,
+ 0,
+ 0,
+ 134,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ 135,
+ 136,
+ 3,
+ 4,
+ 2,
+ 0,
+ 136,
+ 137,
+ 3,
+ 6,
+ 3,
+ 0,
+ 137,
+ 138,
+ 5,
+ 1,
+ 0,
+ 0,
+ 138,
+ 3,
+ 1,
+ 0,
+ 0,
+ 0,
+ 139,
+ 140,
+ 5,
+ 2,
+ 0,
+ 0,
+ 140,
+ 145,
+ 5,
+ 66,
+ 0,
+ 0,
+ 141,
+ 142,
+ 5,
+ 3,
+ 0,
+ 0,
+ 142,
+ 143,
+ 3,
+ 8,
+ 4,
+ 0,
+ 143,
+ 144,
+ 5,
+ 4,
+ 0,
+ 0,
+ 144,
+ 146,
+ 1,
+ 0,
+ 0,
+ 0,
+ 145,
+ 141,
+ 1,
+ 0,
+ 0,
+ 0,
+ 145,
+ 146,
+ 1,
+ 0,
+ 0,
+ 0,
+ 146,
+ 147,
+ 1,
+ 0,
+ 0,
+ 0,
+ 147,
+ 148,
+ 5,
+ 5,
+ 0,
+ 0,
+ 148,
+ 5,
+ 1,
+ 0,
+ 0,
+ 0,
+ 149,
+ 152,
+ 3,
+ 50,
+ 25,
+ 0,
+ 150,
+ 152,
+ 3,
+ 16,
+ 8,
+ 0,
+ 151,
+ 149,
+ 1,
+ 0,
+ 0,
+ 0,
+ 151,
+ 150,
+ 1,
+ 0,
+ 0,
+ 0,
+ 152,
+ 153,
+ 1,
+ 0,
+ 0,
+ 0,
+ 153,
+ 151,
+ 1,
+ 0,
+ 0,
+ 0,
+ 153,
+ 154,
+ 1,
+ 0,
+ 0,
+ 0,
+ 154,
+ 7,
+ 1,
+ 0,
+ 0,
+ 0,
+ 155,
+ 160,
+ 3,
+ 10,
+ 5,
+ 0,
+ 156,
+ 157,
+ 5,
+ 6,
+ 0,
+ 0,
+ 157,
+ 159,
+ 3,
+ 10,
+ 5,
+ 0,
+ 158,
+ 156,
+ 1,
+ 0,
+ 0,
+ 0,
+ 159,
+ 162,
+ 1,
+ 0,
+ 0,
+ 0,
+ 160,
+ 158,
+ 1,
+ 0,
+ 0,
+ 0,
+ 160,
+ 161,
+ 1,
+ 0,
+ 0,
+ 0,
+ 161,
+ 172,
+ 1,
+ 0,
+ 0,
+ 0,
+ 162,
+ 160,
+ 1,
+ 0,
+ 0,
+ 0,
+ 163,
+ 168,
+ 3,
+ 12,
+ 6,
+ 0,
+ 164,
+ 165,
+ 5,
+ 6,
+ 0,
+ 0,
+ 165,
+ 167,
+ 3,
+ 12,
+ 6,
+ 0,
+ 166,
+ 164,
+ 1,
+ 0,
+ 0,
+ 0,
+ 167,
+ 170,
+ 1,
+ 0,
+ 0,
+ 0,
+ 168,
+ 166,
+ 1,
+ 0,
+ 0,
+ 0,
+ 168,
+ 169,
+ 1,
+ 0,
+ 0,
+ 0,
+ 169,
+ 172,
+ 1,
+ 0,
+ 0,
+ 0,
+ 170,
+ 168,
+ 1,
+ 0,
+ 0,
+ 0,
+ 171,
+ 155,
+ 1,
+ 0,
+ 0,
+ 0,
+ 171,
+ 163,
+ 1,
+ 0,
+ 0,
+ 0,
+ 172,
+ 9,
+ 1,
+ 0,
+ 0,
+ 0,
+ 173,
+ 175,
+ 5,
+ 66,
+ 0,
+ 0,
+ 174,
+ 176,
+ 3,
+ 96,
+ 48,
+ 0,
+ 175,
+ 174,
+ 1,
+ 0,
+ 0,
+ 0,
+ 175,
+ 176,
+ 1,
+ 0,
+ 0,
+ 0,
+ 176,
+ 11,
+ 1,
+ 0,
+ 0,
+ 0,
+ 177,
+ 178,
+ 5,
+ 7,
+ 0,
+ 0,
+ 178,
+ 183,
+ 3,
+ 14,
+ 7,
+ 0,
+ 179,
+ 180,
+ 5,
+ 6,
+ 0,
+ 0,
+ 180,
+ 182,
+ 3,
+ 14,
+ 7,
+ 0,
+ 181,
+ 179,
+ 1,
+ 0,
+ 0,
+ 0,
+ 182,
+ 185,
+ 1,
+ 0,
+ 0,
+ 0,
+ 183,
+ 181,
+ 1,
+ 0,
+ 0,
+ 0,
+ 183,
+ 184,
+ 1,
+ 0,
+ 0,
+ 0,
+ 184,
+ 205,
+ 1,
+ 0,
+ 0,
+ 0,
+ 185,
+ 183,
+ 1,
+ 0,
+ 0,
+ 0,
+ 186,
+ 187,
+ 5,
+ 8,
+ 0,
+ 0,
+ 187,
+ 192,
+ 3,
+ 14,
+ 7,
+ 0,
+ 188,
+ 189,
+ 5,
+ 6,
+ 0,
+ 0,
+ 189,
+ 191,
+ 3,
+ 14,
+ 7,
+ 0,
+ 190,
+ 188,
+ 1,
+ 0,
+ 0,
+ 0,
+ 191,
+ 194,
+ 1,
+ 0,
+ 0,
+ 0,
+ 192,
+ 190,
+ 1,
+ 0,
+ 0,
+ 0,
+ 192,
+ 193,
+ 1,
+ 0,
+ 0,
+ 0,
+ 193,
+ 205,
+ 1,
+ 0,
+ 0,
+ 0,
+ 194,
+ 192,
+ 1,
+ 0,
+ 0,
+ 0,
+ 195,
+ 196,
+ 5,
+ 9,
+ 0,
+ 0,
+ 196,
+ 201,
+ 3,
+ 14,
+ 7,
+ 0,
+ 197,
+ 198,
+ 5,
+ 6,
+ 0,
+ 0,
+ 198,
+ 200,
+ 3,
+ 14,
+ 7,
+ 0,
+ 199,
+ 197,
+ 1,
+ 0,
+ 0,
+ 0,
+ 200,
+ 203,
+ 1,
+ 0,
+ 0,
+ 0,
+ 201,
+ 199,
+ 1,
+ 0,
+ 0,
+ 0,
+ 201,
+ 202,
+ 1,
+ 0,
+ 0,
+ 0,
+ 202,
+ 205,
+ 1,
+ 0,
+ 0,
+ 0,
+ 203,
+ 201,
+ 1,
+ 0,
+ 0,
+ 0,
+ 204,
+ 177,
+ 1,
+ 0,
+ 0,
+ 0,
+ 204,
+ 186,
+ 1,
+ 0,
+ 0,
+ 0,
+ 204,
+ 195,
+ 1,
+ 0,
+ 0,
+ 0,
+ 205,
+ 13,
+ 1,
+ 0,
+ 0,
+ 0,
+ 206,
+ 208,
+ 3,
+ 96,
+ 48,
+ 0,
+ 207,
+ 206,
+ 1,
+ 0,
+ 0,
+ 0,
+ 207,
+ 208,
+ 1,
+ 0,
+ 0,
+ 0,
+ 208,
+ 209,
+ 1,
+ 0,
+ 0,
+ 0,
+ 209,
+ 210,
+ 5,
+ 66,
+ 0,
+ 0,
+ 210,
+ 15,
+ 1,
+ 0,
+ 0,
+ 0,
+ 211,
+ 212,
+ 5,
+ 10,
+ 0,
+ 0,
+ 212,
+ 213,
+ 5,
+ 3,
+ 0,
+ 0,
+ 213,
+ 214,
+ 3,
+ 46,
+ 23,
+ 0,
+ 214,
+ 215,
+ 5,
+ 4,
+ 0,
+ 0,
+ 215,
+ 216,
+ 5,
+ 11,
+ 0,
+ 0,
+ 216,
+ 217,
+ 3,
+ 18,
+ 9,
+ 0,
+ 217,
+ 218,
+ 5,
+ 12,
+ 0,
+ 0,
+ 218,
+ 17,
+ 1,
+ 0,
+ 0,
+ 0,
+ 219,
+ 221,
+ 3,
+ 20,
+ 10,
+ 0,
+ 220,
+ 219,
+ 1,
+ 0,
+ 0,
+ 0,
+ 221,
+ 222,
+ 1,
+ 0,
+ 0,
+ 0,
+ 222,
+ 220,
+ 1,
+ 0,
+ 0,
+ 0,
+ 222,
+ 223,
+ 1,
+ 0,
+ 0,
+ 0,
+ 223,
+ 19,
+ 1,
+ 0,
+ 0,
+ 0,
+ 224,
+ 228,
+ 3,
+ 44,
+ 22,
+ 0,
+ 225,
+ 228,
+ 3,
+ 34,
+ 17,
+ 0,
+ 226,
+ 228,
+ 3,
+ 22,
+ 11,
+ 0,
+ 227,
+ 224,
+ 1,
+ 0,
+ 0,
+ 0,
+ 227,
+ 225,
+ 1,
+ 0,
+ 0,
+ 0,
+ 227,
+ 226,
+ 1,
+ 0,
+ 0,
+ 0,
+ 228,
+ 21,
+ 1,
+ 0,
+ 0,
+ 0,
+ 229,
+ 233,
+ 3,
+ 24,
+ 12,
+ 0,
+ 230,
+ 232,
+ 3,
+ 28,
+ 14,
+ 0,
+ 231,
+ 230,
+ 1,
+ 0,
+ 0,
+ 0,
+ 232,
+ 235,
+ 1,
+ 0,
+ 0,
+ 0,
+ 233,
+ 231,
+ 1,
+ 0,
+ 0,
+ 0,
+ 233,
+ 234,
+ 1,
+ 0,
+ 0,
+ 0,
+ 234,
+ 237,
+ 1,
+ 0,
+ 0,
+ 0,
+ 235,
+ 233,
+ 1,
+ 0,
+ 0,
+ 0,
+ 236,
+ 238,
+ 3,
+ 26,
+ 13,
+ 0,
+ 237,
+ 236,
+ 1,
+ 0,
+ 0,
+ 0,
+ 237,
+ 238,
+ 1,
+ 0,
+ 0,
+ 0,
+ 238,
+ 23,
+ 1,
+ 0,
+ 0,
+ 0,
+ 239,
+ 240,
+ 5,
+ 13,
+ 0,
+ 0,
+ 240,
+ 241,
+ 5,
+ 3,
+ 0,
+ 0,
+ 241,
+ 242,
+ 3,
+ 30,
+ 15,
+ 0,
+ 242,
+ 243,
+ 5,
+ 4,
+ 0,
+ 0,
+ 243,
+ 244,
+ 3,
+ 32,
+ 16,
+ 0,
+ 244,
+ 25,
+ 1,
+ 0,
+ 0,
+ 0,
+ 245,
+ 246,
+ 5,
+ 14,
+ 0,
+ 0,
+ 246,
+ 247,
+ 3,
+ 32,
+ 16,
+ 0,
+ 247,
+ 27,
+ 1,
+ 0,
+ 0,
+ 0,
+ 248,
+ 249,
+ 5,
+ 14,
+ 0,
+ 0,
+ 249,
+ 250,
+ 5,
+ 13,
+ 0,
+ 0,
+ 250,
+ 251,
+ 5,
+ 3,
+ 0,
+ 0,
+ 251,
+ 252,
+ 3,
+ 30,
+ 15,
+ 0,
+ 252,
+ 253,
+ 5,
+ 4,
+ 0,
+ 0,
+ 253,
+ 254,
+ 3,
+ 32,
+ 16,
+ 0,
+ 254,
+ 29,
+ 1,
+ 0,
+ 0,
+ 0,
+ 255,
+ 256,
+ 3,
+ 102,
+ 51,
+ 0,
+ 256,
+ 257,
+ 3,
+ 126,
+ 63,
+ 0,
+ 257,
+ 258,
+ 3,
+ 42,
+ 21,
+ 0,
+ 258,
+ 31,
+ 1,
+ 0,
+ 0,
+ 0,
+ 259,
+ 261,
+ 5,
+ 11,
+ 0,
+ 0,
+ 260,
+ 262,
+ 3,
+ 44,
+ 22,
+ 0,
+ 261,
+ 260,
+ 1,
+ 0,
+ 0,
+ 0,
+ 262,
+ 263,
+ 1,
+ 0,
+ 0,
+ 0,
+ 263,
+ 261,
+ 1,
+ 0,
+ 0,
+ 0,
+ 263,
+ 264,
+ 1,
+ 0,
+ 0,
+ 0,
+ 264,
+ 265,
+ 1,
+ 0,
+ 0,
+ 0,
+ 265,
+ 266,
+ 5,
+ 12,
+ 0,
+ 0,
+ 266,
+ 269,
+ 1,
+ 0,
+ 0,
+ 0,
+ 267,
+ 269,
+ 3,
+ 44,
+ 22,
+ 0,
+ 268,
+ 259,
+ 1,
+ 0,
+ 0,
+ 0,
+ 268,
+ 267,
+ 1,
+ 0,
+ 0,
+ 0,
+ 269,
+ 33,
+ 1,
+ 0,
+ 0,
+ 0,
+ 270,
+ 272,
+ 3,
+ 36,
+ 18,
+ 0,
+ 271,
+ 273,
+ 3,
+ 38,
+ 19,
+ 0,
+ 272,
+ 271,
+ 1,
+ 0,
+ 0,
+ 0,
+ 273,
+ 274,
+ 1,
+ 0,
+ 0,
+ 0,
+ 274,
+ 272,
+ 1,
+ 0,
+ 0,
+ 0,
+ 274,
+ 275,
+ 1,
+ 0,
+ 0,
+ 0,
+ 275,
+ 277,
+ 1,
+ 0,
+ 0,
+ 0,
+ 276,
+ 278,
+ 3,
+ 40,
+ 20,
+ 0,
+ 277,
+ 276,
+ 1,
+ 0,
+ 0,
+ 0,
+ 277,
+ 278,
+ 1,
+ 0,
+ 0,
+ 0,
+ 278,
+ 279,
+ 1,
+ 0,
+ 0,
+ 0,
+ 279,
+ 280,
+ 5,
+ 15,
+ 0,
+ 0,
+ 280,
+ 35,
+ 1,
+ 0,
+ 0,
+ 0,
+ 281,
+ 282,
+ 5,
+ 16,
+ 0,
+ 0,
+ 282,
+ 283,
+ 5,
+ 3,
+ 0,
+ 0,
+ 283,
+ 284,
+ 3,
+ 102,
+ 51,
+ 0,
+ 284,
+ 285,
+ 5,
+ 4,
+ 0,
+ 0,
+ 285,
+ 37,
+ 1,
+ 0,
+ 0,
+ 0,
+ 286,
+ 287,
+ 3,
+ 42,
+ 21,
+ 0,
+ 287,
+ 288,
+ 5,
+ 17,
+ 0,
+ 0,
+ 288,
+ 289,
+ 3,
+ 32,
+ 16,
+ 0,
+ 289,
+ 39,
+ 1,
+ 0,
+ 0,
+ 0,
+ 290,
+ 291,
+ 5,
+ 18,
+ 0,
+ 0,
+ 291,
+ 292,
+ 5,
+ 17,
+ 0,
+ 0,
+ 292,
+ 293,
+ 3,
+ 32,
+ 16,
+ 0,
+ 293,
+ 41,
+ 1,
+ 0,
+ 0,
+ 0,
+ 294,
+ 295,
+ 3,
+ 128,
+ 64,
+ 0,
+ 295,
+ 43,
+ 1,
+ 0,
+ 0,
+ 0,
+ 296,
+ 297,
+ 3,
+ 102,
+ 51,
+ 0,
+ 297,
+ 301,
+ 5,
+ 19,
+ 0,
+ 0,
+ 298,
+ 302,
+ 3,
+ 128,
+ 64,
+ 0,
+ 299,
+ 302,
+ 3,
+ 98,
+ 49,
+ 0,
+ 300,
+ 302,
+ 3,
+ 86,
+ 43,
+ 0,
+ 301,
+ 298,
+ 1,
+ 0,
+ 0,
+ 0,
+ 301,
+ 299,
+ 1,
+ 0,
+ 0,
+ 0,
+ 301,
+ 300,
+ 1,
+ 0,
+ 0,
+ 0,
+ 302,
+ 303,
+ 1,
+ 0,
+ 0,
+ 0,
+ 303,
+ 304,
+ 5,
+ 5,
+ 0,
+ 0,
+ 304,
+ 45,
+ 1,
+ 0,
+ 0,
+ 0,
+ 305,
+ 310,
+ 3,
+ 48,
+ 24,
+ 0,
+ 306,
+ 307,
+ 5,
+ 6,
+ 0,
+ 0,
+ 307,
+ 309,
+ 3,
+ 48,
+ 24,
+ 0,
+ 308,
+ 306,
+ 1,
+ 0,
+ 0,
+ 0,
+ 309,
+ 312,
+ 1,
+ 0,
+ 0,
+ 0,
+ 310,
+ 308,
+ 1,
+ 0,
+ 0,
+ 0,
+ 310,
+ 311,
+ 1,
+ 0,
+ 0,
+ 0,
+ 311,
+ 47,
+ 1,
+ 0,
+ 0,
+ 0,
+ 312,
+ 310,
+ 1,
+ 0,
+ 0,
+ 0,
+ 313,
+ 315,
+ 5,
+ 66,
+ 0,
+ 0,
+ 314,
+ 316,
+ 3,
+ 96,
+ 48,
+ 0,
+ 315,
+ 314,
+ 1,
+ 0,
+ 0,
+ 0,
+ 315,
+ 316,
+ 1,
+ 0,
+ 0,
+ 0,
+ 316,
+ 49,
+ 1,
+ 0,
+ 0,
+ 0,
+ 317,
+ 318,
+ 3,
+ 52,
+ 26,
+ 0,
+ 318,
+ 319,
+ 5,
+ 5,
+ 0,
+ 0,
+ 319,
+ 322,
+ 1,
+ 0,
+ 0,
+ 0,
+ 320,
+ 322,
+ 3,
+ 106,
+ 53,
+ 0,
+ 321,
+ 317,
+ 1,
+ 0,
+ 0,
+ 0,
+ 321,
+ 320,
+ 1,
+ 0,
+ 0,
+ 0,
+ 322,
+ 51,
+ 1,
+ 0,
+ 0,
+ 0,
+ 323,
+ 329,
+ 3,
+ 104,
+ 52,
+ 0,
+ 324,
+ 329,
+ 3,
+ 80,
+ 40,
+ 0,
+ 325,
+ 329,
+ 3,
+ 68,
+ 34,
+ 0,
+ 326,
+ 329,
+ 3,
+ 82,
+ 41,
+ 0,
+ 327,
+ 329,
+ 3,
+ 54,
+ 27,
+ 0,
+ 328,
+ 323,
+ 1,
+ 0,
+ 0,
+ 0,
+ 328,
+ 324,
+ 1,
+ 0,
+ 0,
+ 0,
+ 328,
+ 325,
+ 1,
+ 0,
+ 0,
+ 0,
+ 328,
+ 326,
+ 1,
+ 0,
+ 0,
+ 0,
+ 328,
+ 327,
+ 1,
+ 0,
+ 0,
+ 0,
+ 329,
+ 53,
+ 1,
+ 0,
+ 0,
+ 0,
+ 330,
+ 331,
+ 3,
+ 66,
+ 33,
+ 0,
+ 331,
+ 332,
+ 3,
+ 64,
+ 32,
+ 0,
+ 332,
+ 333,
+ 5,
+ 3,
+ 0,
+ 0,
+ 333,
+ 334,
+ 3,
+ 56,
+ 28,
+ 0,
+ 334,
+ 335,
+ 5,
+ 4,
+ 0,
+ 0,
+ 335,
+ 55,
+ 1,
+ 0,
+ 0,
+ 0,
+ 336,
+ 339,
+ 3,
+ 58,
+ 29,
+ 0,
+ 337,
+ 339,
+ 3,
+ 60,
+ 30,
+ 0,
+ 338,
+ 336,
+ 1,
+ 0,
+ 0,
+ 0,
+ 338,
+ 337,
+ 1,
+ 0,
+ 0,
+ 0,
+ 339,
+ 57,
+ 1,
+ 0,
+ 0,
+ 0,
+ 340,
+ 345,
+ 3,
+ 10,
+ 5,
+ 0,
+ 341,
+ 342,
+ 5,
+ 6,
+ 0,
+ 0,
+ 342,
+ 344,
+ 3,
+ 10,
+ 5,
+ 0,
+ 343,
+ 341,
+ 1,
+ 0,
+ 0,
+ 0,
+ 344,
+ 347,
+ 1,
+ 0,
+ 0,
+ 0,
+ 345,
+ 343,
+ 1,
+ 0,
+ 0,
+ 0,
+ 345,
+ 346,
+ 1,
+ 0,
+ 0,
+ 0,
+ 346,
+ 59,
+ 1,
+ 0,
+ 0,
+ 0,
+ 347,
+ 345,
+ 1,
+ 0,
+ 0,
+ 0,
+ 348,
+ 353,
+ 3,
+ 62,
+ 31,
+ 0,
+ 349,
+ 350,
+ 5,
+ 6,
+ 0,
+ 0,
+ 350,
+ 352,
+ 3,
+ 62,
+ 31,
+ 0,
+ 351,
+ 349,
+ 1,
+ 0,
+ 0,
+ 0,
+ 352,
+ 355,
+ 1,
+ 0,
+ 0,
+ 0,
+ 353,
+ 351,
+ 1,
+ 0,
+ 0,
+ 0,
+ 353,
+ 354,
+ 1,
+ 0,
+ 0,
+ 0,
+ 354,
+ 61,
+ 1,
+ 0,
+ 0,
+ 0,
+ 355,
+ 353,
+ 1,
+ 0,
+ 0,
+ 0,
+ 356,
+ 357,
+ 5,
+ 20,
+ 0,
+ 0,
+ 357,
+ 358,
+ 5,
+ 66,
+ 0,
+ 0,
+ 358,
+ 359,
+ 5,
+ 3,
+ 0,
+ 0,
+ 359,
+ 360,
+ 3,
+ 98,
+ 49,
+ 0,
+ 360,
+ 361,
+ 5,
+ 4,
+ 0,
+ 0,
+ 361,
+ 63,
+ 1,
+ 0,
+ 0,
+ 0,
+ 362,
+ 363,
+ 5,
+ 66,
+ 0,
+ 0,
+ 363,
+ 65,
+ 1,
+ 0,
+ 0,
+ 0,
+ 364,
+ 365,
+ 5,
+ 66,
+ 0,
+ 0,
+ 365,
+ 67,
+ 1,
+ 0,
+ 0,
+ 0,
+ 366,
+ 372,
+ 3,
+ 72,
+ 36,
+ 0,
+ 367,
+ 372,
+ 3,
+ 74,
+ 37,
+ 0,
+ 368,
+ 372,
+ 3,
+ 78,
+ 39,
+ 0,
+ 369,
+ 372,
+ 3,
+ 70,
+ 35,
+ 0,
+ 370,
+ 372,
+ 3,
+ 76,
+ 38,
+ 0,
+ 371,
+ 366,
+ 1,
+ 0,
+ 0,
+ 0,
+ 371,
+ 367,
+ 1,
+ 0,
+ 0,
+ 0,
+ 371,
+ 368,
+ 1,
+ 0,
+ 0,
+ 0,
+ 371,
+ 369,
+ 1,
+ 0,
+ 0,
+ 0,
+ 371,
+ 370,
+ 1,
+ 0,
+ 0,
+ 0,
+ 372,
+ 69,
+ 1,
+ 0,
+ 0,
+ 0,
+ 373,
+ 374,
+ 5,
+ 21,
+ 0,
+ 0,
+ 374,
+ 379,
+ 3,
+ 14,
+ 7,
+ 0,
+ 375,
+ 376,
+ 5,
+ 6,
+ 0,
+ 0,
+ 376,
+ 378,
+ 3,
+ 14,
+ 7,
+ 0,
+ 377,
+ 375,
+ 1,
+ 0,
+ 0,
+ 0,
+ 378,
+ 381,
+ 1,
+ 0,
+ 0,
+ 0,
+ 379,
+ 377,
+ 1,
+ 0,
+ 0,
+ 0,
+ 379,
+ 380,
+ 1,
+ 0,
+ 0,
+ 0,
+ 380,
+ 71,
+ 1,
+ 0,
+ 0,
+ 0,
+ 381,
+ 379,
+ 1,
+ 0,
+ 0,
+ 0,
+ 382,
+ 383,
+ 5,
+ 22,
+ 0,
+ 0,
+ 383,
+ 388,
+ 3,
+ 14,
+ 7,
+ 0,
+ 384,
+ 385,
+ 5,
+ 6,
+ 0,
+ 0,
+ 385,
+ 387,
+ 3,
+ 14,
+ 7,
+ 0,
+ 386,
+ 384,
+ 1,
+ 0,
+ 0,
+ 0,
+ 387,
+ 390,
+ 1,
+ 0,
+ 0,
+ 0,
+ 388,
+ 386,
+ 1,
+ 0,
+ 0,
+ 0,
+ 388,
+ 389,
+ 1,
+ 0,
+ 0,
+ 0,
+ 389,
+ 73,
+ 1,
+ 0,
+ 0,
+ 0,
+ 390,
+ 388,
+ 1,
+ 0,
+ 0,
+ 0,
+ 391,
+ 392,
+ 5,
+ 23,
+ 0,
+ 0,
+ 392,
+ 397,
+ 3,
+ 14,
+ 7,
+ 0,
+ 393,
+ 394,
+ 5,
+ 6,
+ 0,
+ 0,
+ 394,
+ 396,
+ 3,
+ 14,
+ 7,
+ 0,
+ 395,
+ 393,
+ 1,
+ 0,
+ 0,
+ 0,
+ 396,
+ 399,
+ 1,
+ 0,
+ 0,
+ 0,
+ 397,
+ 395,
+ 1,
+ 0,
+ 0,
+ 0,
+ 397,
+ 398,
+ 1,
+ 0,
+ 0,
+ 0,
+ 398,
+ 75,
+ 1,
+ 0,
+ 0,
+ 0,
+ 399,
+ 397,
+ 1,
+ 0,
+ 0,
+ 0,
+ 400,
+ 401,
+ 5,
+ 24,
+ 0,
+ 0,
+ 401,
+ 406,
+ 3,
+ 14,
+ 7,
+ 0,
+ 402,
+ 403,
+ 5,
+ 6,
+ 0,
+ 0,
+ 403,
+ 405,
+ 3,
+ 14,
+ 7,
+ 0,
+ 404,
+ 402,
+ 1,
+ 0,
+ 0,
+ 0,
+ 405,
+ 408,
+ 1,
+ 0,
+ 0,
+ 0,
+ 406,
+ 404,
+ 1,
+ 0,
+ 0,
+ 0,
+ 406,
+ 407,
+ 1,
+ 0,
+ 0,
+ 0,
+ 407,
+ 77,
+ 1,
+ 0,
+ 0,
+ 0,
+ 408,
+ 406,
+ 1,
+ 0,
+ 0,
+ 0,
+ 409,
+ 410,
+ 5,
+ 25,
+ 0,
+ 0,
+ 410,
+ 415,
+ 3,
+ 82,
+ 41,
+ 0,
+ 411,
+ 412,
+ 5,
+ 6,
+ 0,
+ 0,
+ 412,
+ 414,
+ 3,
+ 82,
+ 41,
+ 0,
+ 413,
+ 411,
+ 1,
+ 0,
+ 0,
+ 0,
+ 414,
+ 417,
+ 1,
+ 0,
+ 0,
+ 0,
+ 415,
+ 413,
+ 1,
+ 0,
+ 0,
+ 0,
+ 415,
+ 416,
+ 1,
+ 0,
+ 0,
+ 0,
+ 416,
+ 79,
+ 1,
+ 0,
+ 0,
+ 0,
+ 417,
+ 415,
+ 1,
+ 0,
+ 0,
+ 0,
+ 418,
+ 419,
+ 5,
+ 26,
+ 0,
+ 0,
+ 419,
+ 420,
+ 3,
+ 102,
+ 51,
+ 0,
+ 420,
+ 423,
+ 5,
+ 27,
+ 0,
+ 0,
+ 421,
+ 424,
+ 3,
+ 84,
+ 42,
+ 0,
+ 422,
+ 424,
+ 3,
+ 86,
+ 43,
+ 0,
+ 423,
+ 421,
+ 1,
+ 0,
+ 0,
+ 0,
+ 423,
+ 422,
+ 1,
+ 0,
+ 0,
+ 0,
+ 424,
+ 81,
+ 1,
+ 0,
+ 0,
+ 0,
+ 425,
+ 426,
+ 5,
+ 66,
+ 0,
+ 0,
+ 426,
+ 429,
+ 5,
+ 27,
+ 0,
+ 0,
+ 427,
+ 430,
+ 3,
+ 84,
+ 42,
+ 0,
+ 428,
+ 430,
+ 3,
+ 86,
+ 43,
+ 0,
+ 429,
+ 427,
+ 1,
+ 0,
+ 0,
+ 0,
+ 429,
+ 428,
+ 1,
+ 0,
+ 0,
+ 0,
+ 430,
+ 83,
+ 1,
+ 0,
+ 0,
+ 0,
+ 431,
+ 433,
+ 3,
+ 120,
+ 60,
+ 0,
+ 432,
+ 431,
+ 1,
+ 0,
+ 0,
+ 0,
+ 432,
+ 433,
+ 1,
+ 0,
+ 0,
+ 0,
+ 433,
+ 434,
+ 1,
+ 0,
+ 0,
+ 0,
+ 434,
+ 435,
+ 5,
+ 3,
+ 0,
+ 0,
+ 435,
+ 436,
+ 3,
+ 86,
+ 43,
+ 0,
+ 436,
+ 437,
+ 5,
+ 4,
+ 0,
+ 0,
+ 437,
+ 85,
+ 1,
+ 0,
+ 0,
+ 0,
+ 438,
+ 441,
+ 3,
+ 84,
+ 42,
+ 0,
+ 439,
+ 441,
+ 3,
+ 88,
+ 44,
+ 0,
+ 440,
+ 438,
+ 1,
+ 0,
+ 0,
+ 0,
+ 440,
+ 439,
+ 1,
+ 0,
+ 0,
+ 0,
+ 441,
+ 449,
+ 1,
+ 0,
+ 0,
+ 0,
+ 442,
+ 445,
+ 3,
+ 122,
+ 61,
+ 0,
+ 443,
+ 446,
+ 3,
+ 84,
+ 42,
+ 0,
+ 444,
+ 446,
+ 3,
+ 88,
+ 44,
+ 0,
+ 445,
+ 443,
+ 1,
+ 0,
+ 0,
+ 0,
+ 445,
+ 444,
+ 1,
+ 0,
+ 0,
+ 0,
+ 446,
+ 448,
+ 1,
+ 0,
+ 0,
+ 0,
+ 447,
+ 442,
+ 1,
+ 0,
+ 0,
+ 0,
+ 448,
+ 451,
+ 1,
+ 0,
+ 0,
+ 0,
+ 449,
+ 447,
+ 1,
+ 0,
+ 0,
+ 0,
+ 449,
+ 450,
+ 1,
+ 0,
+ 0,
+ 0,
+ 450,
+ 87,
+ 1,
+ 0,
+ 0,
+ 0,
+ 451,
+ 449,
+ 1,
+ 0,
+ 0,
+ 0,
+ 452,
+ 454,
+ 3,
+ 120,
+ 60,
+ 0,
+ 453,
+ 452,
+ 1,
+ 0,
+ 0,
+ 0,
+ 453,
+ 454,
+ 1,
+ 0,
+ 0,
+ 0,
+ 454,
+ 455,
+ 1,
+ 0,
+ 0,
+ 0,
+ 455,
+ 458,
+ 3,
+ 98,
+ 49,
+ 0,
+ 456,
+ 458,
+ 3,
+ 128,
+ 64,
+ 0,
+ 457,
+ 453,
+ 1,
+ 0,
+ 0,
+ 0,
+ 457,
+ 456,
+ 1,
+ 0,
+ 0,
+ 0,
+ 458,
+ 89,
+ 1,
+ 0,
+ 0,
+ 0,
+ 459,
+ 462,
+ 3,
+ 84,
+ 42,
+ 0,
+ 460,
+ 462,
+ 3,
+ 88,
+ 44,
+ 0,
+ 461,
+ 459,
+ 1,
+ 0,
+ 0,
+ 0,
+ 461,
+ 460,
+ 1,
+ 0,
+ 0,
+ 0,
+ 462,
+ 470,
+ 1,
+ 0,
+ 0,
+ 0,
+ 463,
+ 466,
+ 3,
+ 122,
+ 61,
+ 0,
+ 464,
+ 467,
+ 3,
+ 84,
+ 42,
+ 0,
+ 465,
+ 467,
+ 3,
+ 88,
+ 44,
+ 0,
+ 466,
+ 464,
+ 1,
+ 0,
+ 0,
+ 0,
+ 466,
+ 465,
+ 1,
+ 0,
+ 0,
+ 0,
+ 467,
+ 469,
+ 1,
+ 0,
+ 0,
+ 0,
+ 468,
+ 463,
+ 1,
+ 0,
+ 0,
+ 0,
+ 469,
+ 472,
+ 1,
+ 0,
+ 0,
+ 0,
+ 470,
+ 468,
+ 1,
+ 0,
+ 0,
+ 0,
+ 470,
+ 471,
+ 1,
+ 0,
+ 0,
+ 0,
+ 471,
+ 91,
+ 1,
+ 0,
+ 0,
+ 0,
+ 472,
+ 470,
+ 1,
+ 0,
+ 0,
+ 0,
+ 473,
+ 474,
+ 3,
+ 90,
+ 45,
+ 0,
+ 474,
+ 475,
+ 3,
+ 126,
+ 63,
+ 0,
+ 475,
+ 476,
+ 3,
+ 94,
+ 47,
+ 0,
+ 476,
+ 93,
+ 1,
+ 0,
+ 0,
+ 0,
+ 477,
+ 478,
+ 3,
+ 128,
+ 64,
+ 0,
+ 478,
+ 95,
+ 1,
+ 0,
+ 0,
+ 0,
+ 479,
+ 480,
+ 5,
+ 28,
+ 0,
+ 0,
+ 480,
+ 483,
+ 5,
+ 72,
+ 0,
+ 0,
+ 481,
+ 482,
+ 5,
+ 17,
+ 0,
+ 0,
+ 482,
+ 484,
+ 5,
+ 72,
+ 0,
+ 0,
+ 483,
+ 481,
+ 1,
+ 0,
+ 0,
+ 0,
+ 483,
+ 484,
+ 1,
+ 0,
+ 0,
+ 0,
+ 484,
+ 485,
+ 1,
+ 0,
+ 0,
+ 0,
+ 485,
+ 486,
+ 5,
+ 29,
+ 0,
+ 0,
+ 486,
+ 97,
+ 1,
+ 0,
+ 0,
+ 0,
+ 487,
+ 490,
+ 3,
+ 10,
+ 5,
+ 0,
+ 488,
+ 490,
+ 3,
+ 100,
+ 50,
+ 0,
+ 489,
+ 487,
+ 1,
+ 0,
+ 0,
+ 0,
+ 489,
+ 488,
+ 1,
+ 0,
+ 0,
+ 0,
+ 490,
+ 99,
+ 1,
+ 0,
+ 0,
+ 0,
+ 491,
+ 492,
+ 5,
+ 30,
+ 0,
+ 0,
+ 492,
+ 497,
+ 3,
+ 10,
+ 5,
+ 0,
+ 493,
+ 494,
+ 5,
+ 6,
+ 0,
+ 0,
+ 494,
+ 496,
+ 3,
+ 10,
+ 5,
+ 0,
+ 495,
+ 493,
+ 1,
+ 0,
+ 0,
+ 0,
+ 496,
+ 499,
+ 1,
+ 0,
+ 0,
+ 0,
+ 497,
+ 495,
+ 1,
+ 0,
+ 0,
+ 0,
+ 497,
+ 498,
+ 1,
+ 0,
+ 0,
+ 0,
+ 498,
+ 500,
+ 1,
+ 0,
+ 0,
+ 0,
+ 499,
+ 497,
+ 1,
+ 0,
+ 0,
+ 0,
+ 500,
+ 502,
+ 5,
+ 31,
+ 0,
+ 0,
+ 501,
+ 503,
+ 3,
+ 96,
+ 48,
+ 0,
+ 502,
+ 501,
+ 1,
+ 0,
+ 0,
+ 0,
+ 502,
+ 503,
+ 1,
+ 0,
+ 0,
+ 0,
+ 503,
+ 101,
+ 1,
+ 0,
+ 0,
+ 0,
+ 504,
+ 505,
+ 3,
+ 98,
+ 49,
+ 0,
+ 505,
+ 103,
+ 1,
+ 0,
+ 0,
+ 0,
+ 506,
+ 507,
+ 3,
+ 12,
+ 6,
+ 0,
+ 507,
+ 105,
+ 1,
+ 0,
+ 0,
+ 0,
+ 508,
+ 512,
+ 3,
+ 114,
+ 57,
+ 0,
+ 509,
+ 512,
+ 3,
+ 108,
+ 54,
+ 0,
+ 510,
+ 512,
+ 3,
+ 110,
+ 55,
+ 0,
+ 511,
+ 508,
+ 1,
+ 0,
+ 0,
+ 0,
+ 511,
+ 509,
+ 1,
+ 0,
+ 0,
+ 0,
+ 511,
+ 510,
+ 1,
+ 0,
+ 0,
+ 0,
+ 512,
+ 107,
+ 1,
+ 0,
+ 0,
+ 0,
+ 513,
+ 514,
+ 5,
+ 32,
+ 0,
+ 0,
+ 514,
+ 516,
+ 5,
+ 33,
+ 0,
+ 0,
+ 515,
+ 517,
+ 5,
+ 66,
+ 0,
+ 0,
+ 516,
+ 515,
+ 1,
+ 0,
+ 0,
+ 0,
+ 517,
+ 518,
+ 1,
+ 0,
+ 0,
+ 0,
+ 518,
+ 516,
+ 1,
+ 0,
+ 0,
+ 0,
+ 518,
+ 519,
+ 1,
+ 0,
+ 0,
+ 0,
+ 519,
+ 520,
+ 1,
+ 0,
+ 0,
+ 0,
+ 520,
+ 521,
+ 5,
+ 33,
+ 0,
+ 0,
+ 521,
+ 524,
+ 5,
+ 33,
+ 0,
+ 0,
+ 522,
+ 525,
+ 3,
+ 112,
+ 56,
+ 0,
+ 523,
+ 525,
+ 7,
+ 0,
+ 0,
+ 0,
+ 524,
+ 522,
+ 1,
+ 0,
+ 0,
+ 0,
+ 524,
+ 523,
+ 1,
+ 0,
+ 0,
+ 0,
+ 525,
+ 526,
+ 1,
+ 0,
+ 0,
+ 0,
+ 526,
+ 527,
+ 5,
+ 33,
+ 0,
+ 0,
+ 527,
+ 109,
+ 1,
+ 0,
+ 0,
+ 0,
+ 528,
+ 529,
+ 5,
+ 34,
+ 0,
+ 0,
+ 529,
+ 530,
+ 5,
+ 66,
+ 0,
+ 0,
+ 530,
+ 531,
+ 5,
+ 66,
+ 0,
+ 0,
+ 531,
+ 111,
+ 1,
+ 0,
+ 0,
+ 0,
+ 532,
+ 535,
+ 3,
+ 122,
+ 61,
+ 0,
+ 533,
+ 535,
+ 3,
+ 120,
+ 60,
+ 0,
+ 534,
+ 532,
+ 1,
+ 0,
+ 0,
+ 0,
+ 534,
+ 533,
+ 1,
+ 0,
+ 0,
+ 0,
+ 535,
+ 113,
+ 1,
+ 0,
+ 0,
+ 0,
+ 536,
+ 537,
+ 5,
+ 35,
+ 0,
+ 0,
+ 537,
+ 538,
+ 5,
+ 33,
+ 0,
+ 0,
+ 538,
+ 539,
+ 3,
+ 112,
+ 56,
+ 0,
+ 539,
+ 540,
+ 5,
+ 33,
+ 0,
+ 0,
+ 540,
+ 545,
+ 3,
+ 116,
+ 58,
+ 0,
+ 541,
+ 542,
+ 7,
+ 1,
+ 0,
+ 0,
+ 542,
+ 544,
+ 3,
+ 116,
+ 58,
+ 0,
+ 543,
+ 541,
+ 1,
+ 0,
+ 0,
+ 0,
+ 544,
+ 547,
+ 1,
+ 0,
+ 0,
+ 0,
+ 545,
+ 543,
+ 1,
+ 0,
+ 0,
+ 0,
+ 545,
+ 546,
+ 1,
+ 0,
+ 0,
+ 0,
+ 546,
+ 115,
+ 1,
+ 0,
+ 0,
+ 0,
+ 547,
+ 545,
+ 1,
+ 0,
+ 0,
+ 0,
+ 548,
+ 549,
+ 5,
+ 66,
+ 0,
+ 0,
+ 549,
+ 550,
+ 5,
+ 27,
+ 0,
+ 0,
+ 550,
+ 552,
+ 3,
+ 128,
+ 64,
+ 0,
+ 551,
+ 553,
+ 3,
+ 118,
+ 59,
+ 0,
+ 552,
+ 551,
+ 1,
+ 0,
+ 0,
+ 0,
+ 552,
+ 553,
+ 1,
+ 0,
+ 0,
+ 0,
+ 553,
+ 579,
+ 1,
+ 0,
+ 0,
+ 0,
+ 554,
+ 555,
+ 5,
+ 66,
+ 0,
+ 0,
+ 555,
+ 556,
+ 5,
+ 38,
+ 0,
+ 0,
+ 556,
+ 558,
+ 3,
+ 128,
+ 64,
+ 0,
+ 557,
+ 559,
+ 3,
+ 118,
+ 59,
+ 0,
+ 558,
+ 557,
+ 1,
+ 0,
+ 0,
+ 0,
+ 558,
+ 559,
+ 1,
+ 0,
+ 0,
+ 0,
+ 559,
+ 579,
+ 1,
+ 0,
+ 0,
+ 0,
+ 560,
+ 561,
+ 5,
+ 66,
+ 0,
+ 0,
+ 561,
+ 562,
+ 5,
+ 39,
+ 0,
+ 0,
+ 562,
+ 564,
+ 3,
+ 128,
+ 64,
+ 0,
+ 563,
+ 565,
+ 3,
+ 118,
+ 59,
+ 0,
+ 564,
+ 563,
+ 1,
+ 0,
+ 0,
+ 0,
+ 564,
+ 565,
+ 1,
+ 0,
+ 0,
+ 0,
+ 565,
+ 579,
+ 1,
+ 0,
+ 0,
+ 0,
+ 566,
+ 567,
+ 5,
+ 66,
+ 0,
+ 0,
+ 567,
+ 568,
+ 5,
+ 40,
+ 0,
+ 0,
+ 568,
+ 570,
+ 3,
+ 128,
+ 64,
+ 0,
+ 569,
+ 571,
+ 3,
+ 118,
+ 59,
+ 0,
+ 570,
+ 569,
+ 1,
+ 0,
+ 0,
+ 0,
+ 570,
+ 571,
+ 1,
+ 0,
+ 0,
+ 0,
+ 571,
+ 579,
+ 1,
+ 0,
+ 0,
+ 0,
+ 572,
+ 573,
+ 5,
+ 66,
+ 0,
+ 0,
+ 573,
+ 574,
+ 5,
+ 19,
+ 0,
+ 0,
+ 574,
+ 576,
+ 3,
+ 128,
+ 64,
+ 0,
+ 575,
+ 577,
+ 3,
+ 118,
+ 59,
+ 0,
+ 576,
+ 575,
+ 1,
+ 0,
+ 0,
+ 0,
+ 576,
+ 577,
+ 1,
+ 0,
+ 0,
+ 0,
+ 577,
+ 579,
+ 1,
+ 0,
+ 0,
+ 0,
+ 578,
+ 548,
+ 1,
+ 0,
+ 0,
+ 0,
+ 578,
+ 554,
+ 1,
+ 0,
+ 0,
+ 0,
+ 578,
+ 560,
+ 1,
+ 0,
+ 0,
+ 0,
+ 578,
+ 566,
+ 1,
+ 0,
+ 0,
+ 0,
+ 578,
+ 572,
+ 1,
+ 0,
+ 0,
+ 0,
+ 579,
+ 117,
+ 1,
+ 0,
+ 0,
+ 0,
+ 580,
+ 581,
+ 5,
+ 66,
+ 0,
+ 0,
+ 581,
+ 119,
+ 1,
+ 0,
+ 0,
+ 0,
+ 582,
+ 583,
+ 7,
+ 2,
+ 0,
+ 0,
+ 583,
+ 121,
+ 1,
+ 0,
+ 0,
+ 0,
+ 584,
+ 585,
+ 7,
+ 3,
+ 0,
+ 0,
+ 585,
+ 123,
+ 1,
+ 0,
+ 0,
+ 0,
+ 586,
+ 587,
+ 7,
+ 4,
+ 0,
+ 0,
+ 587,
+ 125,
+ 1,
+ 0,
+ 0,
+ 0,
+ 588,
+ 589,
+ 7,
+ 5,
+ 0,
+ 0,
+ 589,
+ 127,
+ 1,
+ 0,
+ 0,
+ 0,
+ 590,
+ 591,
+ 7,
+ 6,
+ 0,
+ 0,
+ 591,
+ 129,
+ 1,
+ 0,
+ 0,
+ 0,
+ 61,
+ 133,
+ 145,
+ 151,
+ 153,
+ 160,
+ 168,
+ 171,
+ 175,
+ 183,
+ 192,
+ 201,
+ 204,
+ 207,
+ 222,
+ 227,
+ 233,
+ 237,
+ 263,
+ 268,
+ 274,
+ 277,
+ 301,
+ 310,
+ 315,
+ 321,
+ 328,
+ 338,
+ 345,
+ 353,
+ 371,
+ 379,
+ 388,
+ 397,
+ 406,
+ 415,
+ 423,
+ 429,
+ 432,
+ 440,
+ 445,
+ 449,
+ 453,
+ 457,
+ 461,
+ 466,
+ 470,
+ 483,
+ 489,
+ 497,
+ 502,
+ 511,
+ 518,
+ 524,
+ 534,
+ 545,
+ 552,
+ 558,
+ 564,
+ 570,
+ 576,
+ 578,
+ ]
+
+
+class lfrXParser(Parser):
+ grammarFileName = "lfrX.g4"
+
+ atn = ATNDeserializer().deserialize(serializedATN())
+
+ decisionsToDFA = [DFA(ds, i) for i, ds in enumerate(atn.decisionToState)]
+
+ sharedContextCache = PredictionContextCache()
+
+ literalNames = [
+ "",
+ "'endmodule'",
+ "'module'",
+ "'('",
+ "')'",
+ "';'",
+ "','",
+ "'finput'",
+ "'foutput'",
+ "'control'",
+ "'distribute@'",
+ "'begin'",
+ "'end'",
+ "'if'",
+ "'else'",
+ "'endcase'",
+ "'case'",
+ "':'",
+ "'default'",
+ "'<='",
+ "'.'",
+ "'signal'",
+ "'flow'",
+ "'storage'",
+ "'pump'",
+ "'number'",
+ "'assign'",
+ "'='",
+ "'['",
+ "']'",
+ "'{'",
+ "'}'",
+ "'#MAP'",
+ "'\"'",
+ "'#MATERIAL'",
+ "'#CONSTRAIN'",
+ "'AND'",
+ "'OR'",
+ "'>'",
+ "'<'",
+ "'>='",
+ "'+'",
+ "'-'",
+ "'!'",
+ "'~'",
+ "'&'",
+ "'~&'",
+ "'|'",
+ "'~|'",
+ "'^'",
+ "'~^'",
+ "'^~'",
+ "'*'",
+ "'/'",
+ "'%'",
+ "'=='",
+ "'!='",
+ "'==='",
+ "'!=='",
+ "'&&'",
+ "'||'",
+ "'**'",
+ "'>>'",
+ "'<<'",
+ "'>>>'",
+ "'<<<'",
+ ]
+
+ symbolicNames = [
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "ID",
+ "WS",
+ "One_line_comment",
+ "Block_comment",
+ "Import_line",
+ "Real_number",
+ "Decimal_number",
+ "Binary_number",
+ "Octal_number",
+ "Hex_number",
+ ]
+
+ RULE_skeleton = 0
+ RULE_module = 1
+ RULE_moduledefinition = 2
+ RULE_body = 3
+ RULE_ioblock = 4
+ RULE_vectorvar = 5
+ RULE_explicitIOBlock = 6
+ RULE_declvar = 7
+ RULE_distributionBlock = 8
+ RULE_distributionBody = 9
+ RULE_distributeBodyStat = 10
+ RULE_ifElseBlock = 11
+ RULE_ifBlock = 12
+ RULE_elseBlock = 13
+ RULE_elseIfBlock = 14
+ RULE_distributeCondition = 15
+ RULE_statementBlock = 16
+ RULE_caseBlock = 17
+ RULE_caseBlockHeader = 18
+ RULE_casestat = 19
+ RULE_defaultCaseStat = 20
+ RULE_distvalue = 21
+ RULE_distributionassignstat = 22
+ RULE_sensitivitylist = 23
+ RULE_signal = 24
+ RULE_statements = 25
+ RULE_statement = 26
+ RULE_moduleinstantiationstat = 27
+ RULE_instanceioblock = 28
+ RULE_orderedioblock = 29
+ RULE_unorderedioblock = 30
+ RULE_explicitinstanceiomapping = 31
+ RULE_instancename = 32
+ RULE_moduletype = 33
+ RULE_tempvariablesstat = 34
+ RULE_signalvarstat = 35
+ RULE_fluiddeclstat = 36
+ RULE_storagestat = 37
+ RULE_pumpvarstat = 38
+ RULE_numvarstat = 39
+ RULE_assignstat = 40
+ RULE_literalassignstat = 41
+ RULE_bracketexpression = 42
+ RULE_expression = 43
+ RULE_expressionterm = 44
+ RULE_logiccondition_operand = 45
+ RULE_logiccondition = 46
+ RULE_logic_value = 47
+ RULE_vector = 48
+ RULE_variables = 49
+ RULE_concatenation = 50
+ RULE_lhs = 51
+ RULE_ioassignstat = 52
+ RULE_technologydirectives = 53
+ RULE_technologymappingdirective = 54
+ RULE_materialmappingdirective = 55
+ RULE_mappingoperator = 56
+ RULE_performancedirective = 57
+ RULE_constraint = 58
+ RULE_unit = 59
+ RULE_unary_operator = 60
+ RULE_binary_operator = 61
+ RULE_unary_module_path_operator = 62
+ RULE_binary_module_path_operator = 63
+ RULE_number = 64
+
+ ruleNames = [
+ "skeleton",
+ "module",
+ "moduledefinition",
+ "body",
+ "ioblock",
+ "vectorvar",
+ "explicitIOBlock",
+ "declvar",
+ "distributionBlock",
+ "distributionBody",
+ "distributeBodyStat",
+ "ifElseBlock",
+ "ifBlock",
+ "elseBlock",
+ "elseIfBlock",
+ "distributeCondition",
+ "statementBlock",
+ "caseBlock",
+ "caseBlockHeader",
+ "casestat",
+ "defaultCaseStat",
+ "distvalue",
+ "distributionassignstat",
+ "sensitivitylist",
+ "signal",
+ "statements",
+ "statement",
+ "moduleinstantiationstat",
+ "instanceioblock",
+ "orderedioblock",
+ "unorderedioblock",
+ "explicitinstanceiomapping",
+ "instancename",
+ "moduletype",
+ "tempvariablesstat",
+ "signalvarstat",
+ "fluiddeclstat",
+ "storagestat",
+ "pumpvarstat",
+ "numvarstat",
+ "assignstat",
+ "literalassignstat",
+ "bracketexpression",
+ "expression",
+ "expressionterm",
+ "logiccondition_operand",
+ "logiccondition",
+ "logic_value",
+ "vector",
+ "variables",
+ "concatenation",
+ "lhs",
+ "ioassignstat",
+ "technologydirectives",
+ "technologymappingdirective",
+ "materialmappingdirective",
+ "mappingoperator",
+ "performancedirective",
+ "constraint",
+ "unit",
+ "unary_operator",
+ "binary_operator",
+ "unary_module_path_operator",
+ "binary_module_path_operator",
+ "number",
+ ]
+
+ EOF = Token.EOF
+ T__0 = 1
+ T__1 = 2
+ T__2 = 3
+ T__3 = 4
+ T__4 = 5
+ T__5 = 6
+ T__6 = 7
+ T__7 = 8
+ T__8 = 9
+ T__9 = 10
+ T__10 = 11
+ T__11 = 12
+ T__12 = 13
+ T__13 = 14
+ T__14 = 15
+ T__15 = 16
+ T__16 = 17
+ T__17 = 18
+ T__18 = 19
+ T__19 = 20
+ T__20 = 21
+ T__21 = 22
+ T__22 = 23
+ T__23 = 24
+ T__24 = 25
+ T__25 = 26
+ T__26 = 27
+ T__27 = 28
+ T__28 = 29
+ T__29 = 30
+ T__30 = 31
+ T__31 = 32
+ T__32 = 33
+ T__33 = 34
+ T__34 = 35
+ T__35 = 36
+ T__36 = 37
+ T__37 = 38
+ T__38 = 39
+ T__39 = 40
+ T__40 = 41
+ T__41 = 42
+ T__42 = 43
+ T__43 = 44
+ T__44 = 45
+ T__45 = 46
+ T__46 = 47
+ T__47 = 48
+ T__48 = 49
+ T__49 = 50
+ T__50 = 51
+ T__51 = 52
+ T__52 = 53
+ T__53 = 54
+ T__54 = 55
+ T__55 = 56
+ T__56 = 57
+ T__57 = 58
+ T__58 = 59
+ T__59 = 60
+ T__60 = 61
+ T__61 = 62
+ T__62 = 63
+ T__63 = 64
+ T__64 = 65
+ ID = 66
+ WS = 67
+ One_line_comment = 68
+ Block_comment = 69
+ Import_line = 70
+ Real_number = 71
+ Decimal_number = 72
+ Binary_number = 73
+ Octal_number = 74
+ Hex_number = 75
+
+ def __init__(self, input: TokenStream, output: TextIO = sys.stdout):
+ super().__init__(input, output)
+ self.checkVersion("4.10.1")
+ self._interp = ParserATNSimulator(
+ self, self.atn, self.decisionsToDFA, self.sharedContextCache
+ )
+ self._predicates = None
+
+ class SkeletonContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def module(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.ModuleContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.ModuleContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_skeleton
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterSkeleton"):
+ listener.enterSkeleton(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitSkeleton"):
+ listener.exitSkeleton(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitSkeleton"):
+ return visitor.visitSkeleton(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def skeleton(self):
+ localctx = lfrXParser.SkeletonContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 0, self.RULE_skeleton)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 131
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while True:
+ self.state = 130
+ self.module()
+ self.state = 133
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if not (_la == lfrXParser.T__1):
+ break
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ModuleContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def moduledefinition(self):
+ return self.getTypedRuleContext(lfrXParser.ModuledefinitionContext, 0)
+
+ def body(self):
+ return self.getTypedRuleContext(lfrXParser.BodyContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_module
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterModule"):
+ listener.enterModule(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitModule"):
+ listener.exitModule(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitModule"):
+ return visitor.visitModule(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def module(self):
+ localctx = lfrXParser.ModuleContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 2, self.RULE_module)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 135
+ self.moduledefinition()
+ self.state = 136
+ self.body()
+ self.state = 137
+ self.match(lfrXParser.T__0)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ModuledefinitionContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def ID(self):
+ return self.getToken(lfrXParser.ID, 0)
+
+ def ioblock(self):
+ return self.getTypedRuleContext(lfrXParser.IoblockContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_moduledefinition
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterModuledefinition"):
+ listener.enterModuledefinition(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitModuledefinition"):
+ listener.exitModuledefinition(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitModuledefinition"):
+ return visitor.visitModuledefinition(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def moduledefinition(self):
+ localctx = lfrXParser.ModuledefinitionContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 4, self.RULE_moduledefinition)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 139
+ self.match(lfrXParser.T__1)
+ self.state = 140
+ self.match(lfrXParser.ID)
+ self.state = 145
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la == lfrXParser.T__2:
+ self.state = 141
+ self.match(lfrXParser.T__2)
+ self.state = 142
+ self.ioblock()
+ self.state = 143
+ self.match(lfrXParser.T__3)
+
+ self.state = 147
+ self.match(lfrXParser.T__4)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class BodyContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def statements(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.StatementsContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.StatementsContext, i)
+
+ def distributionBlock(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.DistributionBlockContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.DistributionBlockContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_body
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterBody"):
+ listener.enterBody(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitBody"):
+ listener.exitBody(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitBody"):
+ return visitor.visitBody(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def body(self):
+ localctx = lfrXParser.BodyContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 6, self.RULE_body)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 151
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while True:
+ self.state = 151
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [
+ lfrXParser.T__6,
+ lfrXParser.T__7,
+ lfrXParser.T__8,
+ lfrXParser.T__20,
+ lfrXParser.T__21,
+ lfrXParser.T__22,
+ lfrXParser.T__23,
+ lfrXParser.T__24,
+ lfrXParser.T__25,
+ lfrXParser.T__31,
+ lfrXParser.T__33,
+ lfrXParser.T__34,
+ lfrXParser.ID,
+ ]:
+ self.state = 149
+ self.statements()
+ pass
+ elif token in [lfrXParser.T__9]:
+ self.state = 150
+ self.distributionBlock()
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ self.state = 153
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if not (
+ (
+ (((_la - 7)) & ~0x3F) == 0
+ and (
+ (1 << (_la - 7))
+ & (
+ (1 << (lfrXParser.T__6 - 7))
+ | (1 << (lfrXParser.T__7 - 7))
+ | (1 << (lfrXParser.T__8 - 7))
+ | (1 << (lfrXParser.T__9 - 7))
+ | (1 << (lfrXParser.T__20 - 7))
+ | (1 << (lfrXParser.T__21 - 7))
+ | (1 << (lfrXParser.T__22 - 7))
+ | (1 << (lfrXParser.T__23 - 7))
+ | (1 << (lfrXParser.T__24 - 7))
+ | (1 << (lfrXParser.T__25 - 7))
+ | (1 << (lfrXParser.T__31 - 7))
+ | (1 << (lfrXParser.T__33 - 7))
+ | (1 << (lfrXParser.T__34 - 7))
+ | (1 << (lfrXParser.ID - 7))
+ )
+ )
+ != 0
+ )
+ ):
+ break
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class IoblockContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def vectorvar(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.VectorvarContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.VectorvarContext, i)
+
+ def explicitIOBlock(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.ExplicitIOBlockContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.ExplicitIOBlockContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_ioblock
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterIoblock"):
+ listener.enterIoblock(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitIoblock"):
+ listener.exitIoblock(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitIoblock"):
+ return visitor.visitIoblock(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def ioblock(self):
+ localctx = lfrXParser.IoblockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 8, self.RULE_ioblock)
+ self._la = 0 # Token type
+ try:
+ self.state = 171
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [lfrXParser.ID]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 155
+ self.vectorvar()
+ self.state = 160
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == lfrXParser.T__5:
+ self.state = 156
+ self.match(lfrXParser.T__5)
+ self.state = 157
+ self.vectorvar()
+ self.state = 162
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ pass
+ elif token in [lfrXParser.T__6, lfrXParser.T__7, lfrXParser.T__8]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 163
+ self.explicitIOBlock()
+ self.state = 168
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == lfrXParser.T__5:
+ self.state = 164
+ self.match(lfrXParser.T__5)
+ self.state = 165
+ self.explicitIOBlock()
+ self.state = 170
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class VectorvarContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def ID(self):
+ return self.getToken(lfrXParser.ID, 0)
+
+ def vector(self):
+ return self.getTypedRuleContext(lfrXParser.VectorContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_vectorvar
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterVectorvar"):
+ listener.enterVectorvar(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitVectorvar"):
+ listener.exitVectorvar(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitVectorvar"):
+ return visitor.visitVectorvar(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def vectorvar(self):
+ localctx = lfrXParser.VectorvarContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 10, self.RULE_vectorvar)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 173
+ self.match(lfrXParser.ID)
+ self.state = 175
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la == lfrXParser.T__27:
+ self.state = 174
+ self.vector()
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ExplicitIOBlockContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def declvar(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.DeclvarContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.DeclvarContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_explicitIOBlock
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterExplicitIOBlock"):
+ listener.enterExplicitIOBlock(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitExplicitIOBlock"):
+ listener.exitExplicitIOBlock(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitExplicitIOBlock"):
+ return visitor.visitExplicitIOBlock(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def explicitIOBlock(self):
+ localctx = lfrXParser.ExplicitIOBlockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 12, self.RULE_explicitIOBlock)
+ try:
+ self.state = 204
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [lfrXParser.T__6]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 177
+ self.match(lfrXParser.T__6)
+ self.state = 178
+ self.declvar()
+ self.state = 183
+ self._errHandler.sync(self)
+ _alt = self._interp.adaptivePredict(self._input, 8, self._ctx)
+ while _alt != 2 and _alt != ATN.INVALID_ALT_NUMBER:
+ if _alt == 1:
+ self.state = 179
+ self.match(lfrXParser.T__5)
+ self.state = 180
+ self.declvar()
+ self.state = 185
+ self._errHandler.sync(self)
+ _alt = self._interp.adaptivePredict(self._input, 8, self._ctx)
+
+ pass
+ elif token in [lfrXParser.T__7]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 186
+ self.match(lfrXParser.T__7)
+ self.state = 187
+ self.declvar()
+ self.state = 192
+ self._errHandler.sync(self)
+ _alt = self._interp.adaptivePredict(self._input, 9, self._ctx)
+ while _alt != 2 and _alt != ATN.INVALID_ALT_NUMBER:
+ if _alt == 1:
+ self.state = 188
+ self.match(lfrXParser.T__5)
+ self.state = 189
+ self.declvar()
+ self.state = 194
+ self._errHandler.sync(self)
+ _alt = self._interp.adaptivePredict(self._input, 9, self._ctx)
+
+ pass
+ elif token in [lfrXParser.T__8]:
+ self.enterOuterAlt(localctx, 3)
+ self.state = 195
+ self.match(lfrXParser.T__8)
+ self.state = 196
+ self.declvar()
+ self.state = 201
+ self._errHandler.sync(self)
+ _alt = self._interp.adaptivePredict(self._input, 10, self._ctx)
+ while _alt != 2 and _alt != ATN.INVALID_ALT_NUMBER:
+ if _alt == 1:
+ self.state = 197
+ self.match(lfrXParser.T__5)
+ self.state = 198
+ self.declvar()
+ self.state = 203
+ self._errHandler.sync(self)
+ _alt = self._interp.adaptivePredict(self._input, 10, self._ctx)
+
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class DeclvarContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def ID(self):
+ return self.getToken(lfrXParser.ID, 0)
+
+ def vector(self):
+ return self.getTypedRuleContext(lfrXParser.VectorContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_declvar
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterDeclvar"):
+ listener.enterDeclvar(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitDeclvar"):
+ listener.exitDeclvar(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitDeclvar"):
+ return visitor.visitDeclvar(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def declvar(self):
+ localctx = lfrXParser.DeclvarContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 14, self.RULE_declvar)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 207
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la == lfrXParser.T__27:
+ self.state = 206
+ self.vector()
+
+ self.state = 209
+ self.match(lfrXParser.ID)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class DistributionBlockContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def sensitivitylist(self):
+ return self.getTypedRuleContext(lfrXParser.SensitivitylistContext, 0)
+
+ def distributionBody(self):
+ return self.getTypedRuleContext(lfrXParser.DistributionBodyContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_distributionBlock
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterDistributionBlock"):
+ listener.enterDistributionBlock(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitDistributionBlock"):
+ listener.exitDistributionBlock(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitDistributionBlock"):
+ return visitor.visitDistributionBlock(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def distributionBlock(self):
+ localctx = lfrXParser.DistributionBlockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 16, self.RULE_distributionBlock)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 211
+ self.match(lfrXParser.T__9)
+ self.state = 212
+ self.match(lfrXParser.T__2)
+ self.state = 213
+ self.sensitivitylist()
+ self.state = 214
+ self.match(lfrXParser.T__3)
+ self.state = 215
+ self.match(lfrXParser.T__10)
+ self.state = 216
+ self.distributionBody()
+ self.state = 217
+ self.match(lfrXParser.T__11)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class DistributionBodyContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def distributeBodyStat(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.DistributeBodyStatContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.DistributeBodyStatContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_distributionBody
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterDistributionBody"):
+ listener.enterDistributionBody(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitDistributionBody"):
+ listener.exitDistributionBody(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitDistributionBody"):
+ return visitor.visitDistributionBody(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def distributionBody(self):
+ localctx = lfrXParser.DistributionBodyContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 18, self.RULE_distributionBody)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 220
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while True:
+ self.state = 219
+ self.distributeBodyStat()
+ self.state = 222
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if not (
+ (
+ (((_la - 13)) & ~0x3F) == 0
+ and (
+ (1 << (_la - 13))
+ & (
+ (1 << (lfrXParser.T__12 - 13))
+ | (1 << (lfrXParser.T__15 - 13))
+ | (1 << (lfrXParser.T__29 - 13))
+ | (1 << (lfrXParser.ID - 13))
+ )
+ )
+ != 0
+ )
+ ):
+ break
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class DistributeBodyStatContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def distributionassignstat(self):
+ return self.getTypedRuleContext(lfrXParser.DistributionassignstatContext, 0)
+
+ def caseBlock(self):
+ return self.getTypedRuleContext(lfrXParser.CaseBlockContext, 0)
+
+ def ifElseBlock(self):
+ return self.getTypedRuleContext(lfrXParser.IfElseBlockContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_distributeBodyStat
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterDistributeBodyStat"):
+ listener.enterDistributeBodyStat(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitDistributeBodyStat"):
+ listener.exitDistributeBodyStat(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitDistributeBodyStat"):
+ return visitor.visitDistributeBodyStat(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def distributeBodyStat(self):
+ localctx = lfrXParser.DistributeBodyStatContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 20, self.RULE_distributeBodyStat)
+ try:
+ self.state = 227
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [lfrXParser.T__29, lfrXParser.ID]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 224
+ self.distributionassignstat()
+ pass
+ elif token in [lfrXParser.T__15]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 225
+ self.caseBlock()
+ pass
+ elif token in [lfrXParser.T__12]:
+ self.enterOuterAlt(localctx, 3)
+ self.state = 226
+ self.ifElseBlock()
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class IfElseBlockContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def ifBlock(self):
+ return self.getTypedRuleContext(lfrXParser.IfBlockContext, 0)
+
+ def elseIfBlock(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.ElseIfBlockContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.ElseIfBlockContext, i)
+
+ def elseBlock(self):
+ return self.getTypedRuleContext(lfrXParser.ElseBlockContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_ifElseBlock
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterIfElseBlock"):
+ listener.enterIfElseBlock(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitIfElseBlock"):
+ listener.exitIfElseBlock(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitIfElseBlock"):
+ return visitor.visitIfElseBlock(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def ifElseBlock(self):
+ localctx = lfrXParser.IfElseBlockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 22, self.RULE_ifElseBlock)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 229
+ self.ifBlock()
+ self.state = 233
+ self._errHandler.sync(self)
+ _alt = self._interp.adaptivePredict(self._input, 15, self._ctx)
+ while _alt != 2 and _alt != ATN.INVALID_ALT_NUMBER:
+ if _alt == 1:
+ self.state = 230
+ self.elseIfBlock()
+ self.state = 235
+ self._errHandler.sync(self)
+ _alt = self._interp.adaptivePredict(self._input, 15, self._ctx)
+
+ self.state = 237
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la == lfrXParser.T__13:
+ self.state = 236
+ self.elseBlock()
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class IfBlockContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def distributeCondition(self):
+ return self.getTypedRuleContext(lfrXParser.DistributeConditionContext, 0)
+
+ def statementBlock(self):
+ return self.getTypedRuleContext(lfrXParser.StatementBlockContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_ifBlock
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterIfBlock"):
+ listener.enterIfBlock(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitIfBlock"):
+ listener.exitIfBlock(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitIfBlock"):
+ return visitor.visitIfBlock(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def ifBlock(self):
+ localctx = lfrXParser.IfBlockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 24, self.RULE_ifBlock)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 239
+ self.match(lfrXParser.T__12)
+ self.state = 240
+ self.match(lfrXParser.T__2)
+ self.state = 241
+ self.distributeCondition()
+ self.state = 242
+ self.match(lfrXParser.T__3)
+ self.state = 243
+ self.statementBlock()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ElseBlockContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def statementBlock(self):
+ return self.getTypedRuleContext(lfrXParser.StatementBlockContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_elseBlock
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterElseBlock"):
+ listener.enterElseBlock(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitElseBlock"):
+ listener.exitElseBlock(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitElseBlock"):
+ return visitor.visitElseBlock(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def elseBlock(self):
+ localctx = lfrXParser.ElseBlockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 26, self.RULE_elseBlock)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 245
+ self.match(lfrXParser.T__13)
+ self.state = 246
+ self.statementBlock()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ElseIfBlockContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def distributeCondition(self):
+ return self.getTypedRuleContext(lfrXParser.DistributeConditionContext, 0)
+
+ def statementBlock(self):
+ return self.getTypedRuleContext(lfrXParser.StatementBlockContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_elseIfBlock
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterElseIfBlock"):
+ listener.enterElseIfBlock(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitElseIfBlock"):
+ listener.exitElseIfBlock(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitElseIfBlock"):
+ return visitor.visitElseIfBlock(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def elseIfBlock(self):
+ localctx = lfrXParser.ElseIfBlockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 28, self.RULE_elseIfBlock)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 248
+ self.match(lfrXParser.T__13)
+ self.state = 249
+ self.match(lfrXParser.T__12)
+ self.state = 250
+ self.match(lfrXParser.T__2)
+ self.state = 251
+ self.distributeCondition()
+ self.state = 252
+ self.match(lfrXParser.T__3)
+ self.state = 253
+ self.statementBlock()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class DistributeConditionContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def lhs(self):
+ return self.getTypedRuleContext(lfrXParser.LhsContext, 0)
+
+ def binary_module_path_operator(self):
+ return self.getTypedRuleContext(
+ lfrXParser.Binary_module_path_operatorContext, 0
+ )
+
+ def distvalue(self):
+ return self.getTypedRuleContext(lfrXParser.DistvalueContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_distributeCondition
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterDistributeCondition"):
+ listener.enterDistributeCondition(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitDistributeCondition"):
+ listener.exitDistributeCondition(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitDistributeCondition"):
+ return visitor.visitDistributeCondition(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def distributeCondition(self):
+ localctx = lfrXParser.DistributeConditionContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 30, self.RULE_distributeCondition)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 255
+ self.lhs()
+ self.state = 256
+ self.binary_module_path_operator()
+ self.state = 257
+ self.distvalue()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class StatementBlockContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def distributionassignstat(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(
+ lfrXParser.DistributionassignstatContext
+ )
+ else:
+ return self.getTypedRuleContext(
+ lfrXParser.DistributionassignstatContext, i
+ )
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_statementBlock
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterStatementBlock"):
+ listener.enterStatementBlock(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitStatementBlock"):
+ listener.exitStatementBlock(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitStatementBlock"):
+ return visitor.visitStatementBlock(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def statementBlock(self):
+ localctx = lfrXParser.StatementBlockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 32, self.RULE_statementBlock)
+ self._la = 0 # Token type
+ try:
+ self.state = 268
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [lfrXParser.T__10]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 259
+ self.match(lfrXParser.T__10)
+ self.state = 261
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while True:
+ self.state = 260
+ self.distributionassignstat()
+ self.state = 263
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if not (_la == lfrXParser.T__29 or _la == lfrXParser.ID):
+ break
+
+ self.state = 265
+ self.match(lfrXParser.T__11)
+ pass
+ elif token in [lfrXParser.T__29, lfrXParser.ID]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 267
+ self.distributionassignstat()
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class CaseBlockContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def caseBlockHeader(self):
+ return self.getTypedRuleContext(lfrXParser.CaseBlockHeaderContext, 0)
+
+ def casestat(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.CasestatContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.CasestatContext, i)
+
+ def defaultCaseStat(self):
+ return self.getTypedRuleContext(lfrXParser.DefaultCaseStatContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_caseBlock
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterCaseBlock"):
+ listener.enterCaseBlock(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitCaseBlock"):
+ listener.exitCaseBlock(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitCaseBlock"):
+ return visitor.visitCaseBlock(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def caseBlock(self):
+ localctx = lfrXParser.CaseBlockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 34, self.RULE_caseBlock)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 270
+ self.caseBlockHeader()
+ self.state = 272
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while True:
+ self.state = 271
+ self.casestat()
+ self.state = 274
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if not (
+ (
+ (((_la - 71)) & ~0x3F) == 0
+ and (
+ (1 << (_la - 71))
+ & (
+ (1 << (lfrXParser.Real_number - 71))
+ | (1 << (lfrXParser.Decimal_number - 71))
+ | (1 << (lfrXParser.Binary_number - 71))
+ | (1 << (lfrXParser.Octal_number - 71))
+ | (1 << (lfrXParser.Hex_number - 71))
+ )
+ )
+ != 0
+ )
+ ):
+ break
+
+ self.state = 277
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la == lfrXParser.T__17:
+ self.state = 276
+ self.defaultCaseStat()
+
+ self.state = 279
+ self.match(lfrXParser.T__14)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class CaseBlockHeaderContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def lhs(self):
+ return self.getTypedRuleContext(lfrXParser.LhsContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_caseBlockHeader
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterCaseBlockHeader"):
+ listener.enterCaseBlockHeader(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitCaseBlockHeader"):
+ listener.exitCaseBlockHeader(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitCaseBlockHeader"):
+ return visitor.visitCaseBlockHeader(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def caseBlockHeader(self):
+ localctx = lfrXParser.CaseBlockHeaderContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 36, self.RULE_caseBlockHeader)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 281
+ self.match(lfrXParser.T__15)
+ self.state = 282
+ self.match(lfrXParser.T__2)
+ self.state = 283
+ self.lhs()
+ self.state = 284
+ self.match(lfrXParser.T__3)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class CasestatContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def distvalue(self):
+ return self.getTypedRuleContext(lfrXParser.DistvalueContext, 0)
+
+ def statementBlock(self):
+ return self.getTypedRuleContext(lfrXParser.StatementBlockContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_casestat
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterCasestat"):
+ listener.enterCasestat(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitCasestat"):
+ listener.exitCasestat(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitCasestat"):
+ return visitor.visitCasestat(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def casestat(self):
+ localctx = lfrXParser.CasestatContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 38, self.RULE_casestat)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 286
+ self.distvalue()
+ self.state = 287
+ self.match(lfrXParser.T__16)
+ self.state = 288
+ self.statementBlock()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class DefaultCaseStatContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def statementBlock(self):
+ return self.getTypedRuleContext(lfrXParser.StatementBlockContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_defaultCaseStat
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterDefaultCaseStat"):
+ listener.enterDefaultCaseStat(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitDefaultCaseStat"):
+ listener.exitDefaultCaseStat(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitDefaultCaseStat"):
+ return visitor.visitDefaultCaseStat(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def defaultCaseStat(self):
+ localctx = lfrXParser.DefaultCaseStatContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 40, self.RULE_defaultCaseStat)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 290
+ self.match(lfrXParser.T__17)
+ self.state = 291
+ self.match(lfrXParser.T__16)
+ self.state = 292
+ self.statementBlock()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class DistvalueContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def number(self):
+ return self.getTypedRuleContext(lfrXParser.NumberContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_distvalue
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterDistvalue"):
+ listener.enterDistvalue(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitDistvalue"):
+ listener.exitDistvalue(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitDistvalue"):
+ return visitor.visitDistvalue(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def distvalue(self):
+ localctx = lfrXParser.DistvalueContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 42, self.RULE_distvalue)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 294
+ self.number()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class DistributionassignstatContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def lhs(self):
+ return self.getTypedRuleContext(lfrXParser.LhsContext, 0)
+
+ def number(self):
+ return self.getTypedRuleContext(lfrXParser.NumberContext, 0)
+
+ def variables(self):
+ return self.getTypedRuleContext(lfrXParser.VariablesContext, 0)
+
+ def expression(self):
+ return self.getTypedRuleContext(lfrXParser.ExpressionContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_distributionassignstat
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterDistributionassignstat"):
+ listener.enterDistributionassignstat(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitDistributionassignstat"):
+ listener.exitDistributionassignstat(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitDistributionassignstat"):
+ return visitor.visitDistributionassignstat(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def distributionassignstat(self):
+ localctx = lfrXParser.DistributionassignstatContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 44, self.RULE_distributionassignstat)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 296
+ self.lhs()
+ self.state = 297
+ self.match(lfrXParser.T__18)
+ self.state = 301
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 21, self._ctx)
+ if la_ == 1:
+ self.state = 298
+ self.number()
+ pass
+
+ elif la_ == 2:
+ self.state = 299
+ self.variables()
+ pass
+
+ elif la_ == 3:
+ self.state = 300
+ self.expression()
+ pass
+
+ self.state = 303
+ self.match(lfrXParser.T__4)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class SensitivitylistContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def signal(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.SignalContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.SignalContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_sensitivitylist
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterSensitivitylist"):
+ listener.enterSensitivitylist(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitSensitivitylist"):
+ listener.exitSensitivitylist(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitSensitivitylist"):
+ return visitor.visitSensitivitylist(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def sensitivitylist(self):
+ localctx = lfrXParser.SensitivitylistContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 46, self.RULE_sensitivitylist)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 305
+ self.signal()
+ self.state = 310
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == lfrXParser.T__5:
+ self.state = 306
+ self.match(lfrXParser.T__5)
+ self.state = 307
+ self.signal()
+ self.state = 312
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class SignalContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def ID(self):
+ return self.getToken(lfrXParser.ID, 0)
+
+ def vector(self):
+ return self.getTypedRuleContext(lfrXParser.VectorContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_signal
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterSignal"):
+ listener.enterSignal(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitSignal"):
+ listener.exitSignal(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitSignal"):
+ return visitor.visitSignal(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def signal(self):
+ localctx = lfrXParser.SignalContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 48, self.RULE_signal)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 313
+ self.match(lfrXParser.ID)
+ self.state = 315
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la == lfrXParser.T__27:
+ self.state = 314
+ self.vector()
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class StatementsContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def statement(self):
+ return self.getTypedRuleContext(lfrXParser.StatementContext, 0)
+
+ def technologydirectives(self):
+ return self.getTypedRuleContext(lfrXParser.TechnologydirectivesContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_statements
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterStatements"):
+ listener.enterStatements(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitStatements"):
+ listener.exitStatements(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitStatements"):
+ return visitor.visitStatements(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def statements(self):
+ localctx = lfrXParser.StatementsContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 50, self.RULE_statements)
+ try:
+ self.state = 321
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [
+ lfrXParser.T__6,
+ lfrXParser.T__7,
+ lfrXParser.T__8,
+ lfrXParser.T__20,
+ lfrXParser.T__21,
+ lfrXParser.T__22,
+ lfrXParser.T__23,
+ lfrXParser.T__24,
+ lfrXParser.T__25,
+ lfrXParser.ID,
+ ]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 317
+ self.statement()
+ self.state = 318
+ self.match(lfrXParser.T__4)
+ pass
+ elif token in [lfrXParser.T__31, lfrXParser.T__33, lfrXParser.T__34]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 320
+ self.technologydirectives()
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class StatementContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def ioassignstat(self):
+ return self.getTypedRuleContext(lfrXParser.IoassignstatContext, 0)
+
+ def assignstat(self):
+ return self.getTypedRuleContext(lfrXParser.AssignstatContext, 0)
+
+ def tempvariablesstat(self):
+ return self.getTypedRuleContext(lfrXParser.TempvariablesstatContext, 0)
+
+ def literalassignstat(self):
+ return self.getTypedRuleContext(lfrXParser.LiteralassignstatContext, 0)
+
+ def moduleinstantiationstat(self):
+ return self.getTypedRuleContext(
+ lfrXParser.ModuleinstantiationstatContext, 0
+ )
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_statement
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterStatement"):
+ listener.enterStatement(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitStatement"):
+ listener.exitStatement(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitStatement"):
+ return visitor.visitStatement(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def statement(self):
+ localctx = lfrXParser.StatementContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 52, self.RULE_statement)
+ try:
+ self.state = 328
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 25, self._ctx)
+ if la_ == 1:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 323
+ self.ioassignstat()
+ pass
+
+ elif la_ == 2:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 324
+ self.assignstat()
+ pass
+
+ elif la_ == 3:
+ self.enterOuterAlt(localctx, 3)
+ self.state = 325
+ self.tempvariablesstat()
+ pass
+
+ elif la_ == 4:
+ self.enterOuterAlt(localctx, 4)
+ self.state = 326
+ self.literalassignstat()
+ pass
+
+ elif la_ == 5:
+ self.enterOuterAlt(localctx, 5)
+ self.state = 327
+ self.moduleinstantiationstat()
+ pass
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ModuleinstantiationstatContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def moduletype(self):
+ return self.getTypedRuleContext(lfrXParser.ModuletypeContext, 0)
+
+ def instancename(self):
+ return self.getTypedRuleContext(lfrXParser.InstancenameContext, 0)
+
+ def instanceioblock(self):
+ return self.getTypedRuleContext(lfrXParser.InstanceioblockContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_moduleinstantiationstat
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterModuleinstantiationstat"):
+ listener.enterModuleinstantiationstat(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitModuleinstantiationstat"):
+ listener.exitModuleinstantiationstat(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitModuleinstantiationstat"):
+ return visitor.visitModuleinstantiationstat(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def moduleinstantiationstat(self):
+ localctx = lfrXParser.ModuleinstantiationstatContext(
+ self, self._ctx, self.state
+ )
+ self.enterRule(localctx, 54, self.RULE_moduleinstantiationstat)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 330
+ self.moduletype()
+ self.state = 331
+ self.instancename()
+ self.state = 332
+ self.match(lfrXParser.T__2)
+ self.state = 333
+ self.instanceioblock()
+ self.state = 334
+ self.match(lfrXParser.T__3)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class InstanceioblockContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def orderedioblock(self):
+ return self.getTypedRuleContext(lfrXParser.OrderedioblockContext, 0)
+
+ def unorderedioblock(self):
+ return self.getTypedRuleContext(lfrXParser.UnorderedioblockContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_instanceioblock
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterInstanceioblock"):
+ listener.enterInstanceioblock(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitInstanceioblock"):
+ listener.exitInstanceioblock(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitInstanceioblock"):
+ return visitor.visitInstanceioblock(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def instanceioblock(self):
+ localctx = lfrXParser.InstanceioblockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 56, self.RULE_instanceioblock)
+ try:
+ self.state = 338
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [lfrXParser.ID]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 336
+ self.orderedioblock()
+ pass
+ elif token in [lfrXParser.T__19]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 337
+ self.unorderedioblock()
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class OrderedioblockContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def vectorvar(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.VectorvarContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.VectorvarContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_orderedioblock
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterOrderedioblock"):
+ listener.enterOrderedioblock(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitOrderedioblock"):
+ listener.exitOrderedioblock(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitOrderedioblock"):
+ return visitor.visitOrderedioblock(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def orderedioblock(self):
+ localctx = lfrXParser.OrderedioblockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 58, self.RULE_orderedioblock)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 340
+ self.vectorvar()
+ self.state = 345
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == lfrXParser.T__5:
+ self.state = 341
+ self.match(lfrXParser.T__5)
+ self.state = 342
+ self.vectorvar()
+ self.state = 347
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class UnorderedioblockContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def explicitinstanceiomapping(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(
+ lfrXParser.ExplicitinstanceiomappingContext
+ )
+ else:
+ return self.getTypedRuleContext(
+ lfrXParser.ExplicitinstanceiomappingContext, i
+ )
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_unorderedioblock
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterUnorderedioblock"):
+ listener.enterUnorderedioblock(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitUnorderedioblock"):
+ listener.exitUnorderedioblock(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitUnorderedioblock"):
+ return visitor.visitUnorderedioblock(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def unorderedioblock(self):
+ localctx = lfrXParser.UnorderedioblockContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 60, self.RULE_unorderedioblock)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 348
+ self.explicitinstanceiomapping()
+ self.state = 353
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == lfrXParser.T__5:
+ self.state = 349
+ self.match(lfrXParser.T__5)
+ self.state = 350
+ self.explicitinstanceiomapping()
+ self.state = 355
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ExplicitinstanceiomappingContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def ID(self):
+ return self.getToken(lfrXParser.ID, 0)
+
+ def variables(self):
+ return self.getTypedRuleContext(lfrXParser.VariablesContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_explicitinstanceiomapping
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterExplicitinstanceiomapping"):
+ listener.enterExplicitinstanceiomapping(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitExplicitinstanceiomapping"):
+ listener.exitExplicitinstanceiomapping(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitExplicitinstanceiomapping"):
+ return visitor.visitExplicitinstanceiomapping(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def explicitinstanceiomapping(self):
+ localctx = lfrXParser.ExplicitinstanceiomappingContext(
+ self, self._ctx, self.state
+ )
+ self.enterRule(localctx, 62, self.RULE_explicitinstanceiomapping)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 356
+ self.match(lfrXParser.T__19)
+ self.state = 357
+ self.match(lfrXParser.ID)
+ self.state = 358
+ self.match(lfrXParser.T__2)
+ self.state = 359
+ self.variables()
+ self.state = 360
+ self.match(lfrXParser.T__3)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class InstancenameContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def ID(self):
+ return self.getToken(lfrXParser.ID, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_instancename
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterInstancename"):
+ listener.enterInstancename(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitInstancename"):
+ listener.exitInstancename(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitInstancename"):
+ return visitor.visitInstancename(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def instancename(self):
+ localctx = lfrXParser.InstancenameContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 64, self.RULE_instancename)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 362
+ self.match(lfrXParser.ID)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ModuletypeContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def ID(self):
+ return self.getToken(lfrXParser.ID, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_moduletype
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterModuletype"):
+ listener.enterModuletype(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitModuletype"):
+ listener.exitModuletype(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitModuletype"):
+ return visitor.visitModuletype(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def moduletype(self):
+ localctx = lfrXParser.ModuletypeContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 66, self.RULE_moduletype)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 364
+ self.match(lfrXParser.ID)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class TempvariablesstatContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def fluiddeclstat(self):
+ return self.getTypedRuleContext(lfrXParser.FluiddeclstatContext, 0)
+
+ def storagestat(self):
+ return self.getTypedRuleContext(lfrXParser.StoragestatContext, 0)
+
+ def numvarstat(self):
+ return self.getTypedRuleContext(lfrXParser.NumvarstatContext, 0)
+
+ def signalvarstat(self):
+ return self.getTypedRuleContext(lfrXParser.SignalvarstatContext, 0)
+
+ def pumpvarstat(self):
+ return self.getTypedRuleContext(lfrXParser.PumpvarstatContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_tempvariablesstat
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterTempvariablesstat"):
+ listener.enterTempvariablesstat(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitTempvariablesstat"):
+ listener.exitTempvariablesstat(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitTempvariablesstat"):
+ return visitor.visitTempvariablesstat(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def tempvariablesstat(self):
+ localctx = lfrXParser.TempvariablesstatContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 68, self.RULE_tempvariablesstat)
+ try:
+ self.state = 371
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [lfrXParser.T__21]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 366
+ self.fluiddeclstat()
+ pass
+ elif token in [lfrXParser.T__22]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 367
+ self.storagestat()
+ pass
+ elif token in [lfrXParser.T__24]:
+ self.enterOuterAlt(localctx, 3)
+ self.state = 368
+ self.numvarstat()
+ pass
+ elif token in [lfrXParser.T__20]:
+ self.enterOuterAlt(localctx, 4)
+ self.state = 369
+ self.signalvarstat()
+ pass
+ elif token in [lfrXParser.T__23]:
+ self.enterOuterAlt(localctx, 5)
+ self.state = 370
+ self.pumpvarstat()
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class SignalvarstatContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def declvar(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.DeclvarContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.DeclvarContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_signalvarstat
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterSignalvarstat"):
+ listener.enterSignalvarstat(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitSignalvarstat"):
+ listener.exitSignalvarstat(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitSignalvarstat"):
+ return visitor.visitSignalvarstat(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def signalvarstat(self):
+ localctx = lfrXParser.SignalvarstatContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 70, self.RULE_signalvarstat)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 373
+ self.match(lfrXParser.T__20)
+ self.state = 374
+ self.declvar()
+ self.state = 379
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == lfrXParser.T__5:
+ self.state = 375
+ self.match(lfrXParser.T__5)
+ self.state = 376
+ self.declvar()
+ self.state = 381
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class FluiddeclstatContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def declvar(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.DeclvarContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.DeclvarContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_fluiddeclstat
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterFluiddeclstat"):
+ listener.enterFluiddeclstat(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitFluiddeclstat"):
+ listener.exitFluiddeclstat(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitFluiddeclstat"):
+ return visitor.visitFluiddeclstat(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def fluiddeclstat(self):
+ localctx = lfrXParser.FluiddeclstatContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 72, self.RULE_fluiddeclstat)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 382
+ self.match(lfrXParser.T__21)
+ self.state = 383
+ self.declvar()
+ self.state = 388
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == lfrXParser.T__5:
+ self.state = 384
+ self.match(lfrXParser.T__5)
+ self.state = 385
+ self.declvar()
+ self.state = 390
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class StoragestatContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def declvar(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.DeclvarContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.DeclvarContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_storagestat
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterStoragestat"):
+ listener.enterStoragestat(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitStoragestat"):
+ listener.exitStoragestat(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitStoragestat"):
+ return visitor.visitStoragestat(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def storagestat(self):
+ localctx = lfrXParser.StoragestatContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 74, self.RULE_storagestat)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 391
+ self.match(lfrXParser.T__22)
+ self.state = 392
+ self.declvar()
+ self.state = 397
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == lfrXParser.T__5:
+ self.state = 393
+ self.match(lfrXParser.T__5)
+ self.state = 394
+ self.declvar()
+ self.state = 399
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class PumpvarstatContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def declvar(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.DeclvarContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.DeclvarContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_pumpvarstat
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterPumpvarstat"):
+ listener.enterPumpvarstat(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitPumpvarstat"):
+ listener.exitPumpvarstat(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitPumpvarstat"):
+ return visitor.visitPumpvarstat(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def pumpvarstat(self):
+ localctx = lfrXParser.PumpvarstatContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 76, self.RULE_pumpvarstat)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 400
+ self.match(lfrXParser.T__23)
+ self.state = 401
+ self.declvar()
+ self.state = 406
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == lfrXParser.T__5:
+ self.state = 402
+ self.match(lfrXParser.T__5)
+ self.state = 403
+ self.declvar()
+ self.state = 408
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class NumvarstatContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def literalassignstat(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.LiteralassignstatContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.LiteralassignstatContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_numvarstat
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterNumvarstat"):
+ listener.enterNumvarstat(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitNumvarstat"):
+ listener.exitNumvarstat(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitNumvarstat"):
+ return visitor.visitNumvarstat(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def numvarstat(self):
+ localctx = lfrXParser.NumvarstatContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 78, self.RULE_numvarstat)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 409
+ self.match(lfrXParser.T__24)
+ self.state = 410
+ self.literalassignstat()
+ self.state = 415
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == lfrXParser.T__5:
+ self.state = 411
+ self.match(lfrXParser.T__5)
+ self.state = 412
+ self.literalassignstat()
+ self.state = 417
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class AssignstatContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def lhs(self):
+ return self.getTypedRuleContext(lfrXParser.LhsContext, 0)
+
+ def bracketexpression(self):
+ return self.getTypedRuleContext(lfrXParser.BracketexpressionContext, 0)
+
+ def expression(self):
+ return self.getTypedRuleContext(lfrXParser.ExpressionContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_assignstat
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterAssignstat"):
+ listener.enterAssignstat(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitAssignstat"):
+ listener.exitAssignstat(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitAssignstat"):
+ return visitor.visitAssignstat(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def assignstat(self):
+ localctx = lfrXParser.AssignstatContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 80, self.RULE_assignstat)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 418
+ self.match(lfrXParser.T__25)
+ self.state = 419
+ self.lhs()
+ self.state = 420
+ self.match(lfrXParser.T__26)
+ self.state = 423
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 35, self._ctx)
+ if la_ == 1:
+ self.state = 421
+ self.bracketexpression()
+ pass
+
+ elif la_ == 2:
+ self.state = 422
+ self.expression()
+ pass
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class LiteralassignstatContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def ID(self):
+ return self.getToken(lfrXParser.ID, 0)
+
+ def bracketexpression(self):
+ return self.getTypedRuleContext(lfrXParser.BracketexpressionContext, 0)
+
+ def expression(self):
+ return self.getTypedRuleContext(lfrXParser.ExpressionContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_literalassignstat
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterLiteralassignstat"):
+ listener.enterLiteralassignstat(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitLiteralassignstat"):
+ listener.exitLiteralassignstat(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitLiteralassignstat"):
+ return visitor.visitLiteralassignstat(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def literalassignstat(self):
+ localctx = lfrXParser.LiteralassignstatContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 82, self.RULE_literalassignstat)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 425
+ self.match(lfrXParser.ID)
+ self.state = 426
+ self.match(lfrXParser.T__26)
+ self.state = 429
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 36, self._ctx)
+ if la_ == 1:
+ self.state = 427
+ self.bracketexpression()
+ pass
+
+ elif la_ == 2:
+ self.state = 428
+ self.expression()
+ pass
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class BracketexpressionContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def expression(self):
+ return self.getTypedRuleContext(lfrXParser.ExpressionContext, 0)
+
+ def unary_operator(self):
+ return self.getTypedRuleContext(lfrXParser.Unary_operatorContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_bracketexpression
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterBracketexpression"):
+ listener.enterBracketexpression(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitBracketexpression"):
+ listener.exitBracketexpression(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitBracketexpression"):
+ return visitor.visitBracketexpression(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def bracketexpression(self):
+ localctx = lfrXParser.BracketexpressionContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 84, self.RULE_bracketexpression)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 432
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if ((_la) & ~0x3F) == 0 and (
+ (1 << _la)
+ & (
+ (1 << lfrXParser.T__40)
+ | (1 << lfrXParser.T__41)
+ | (1 << lfrXParser.T__42)
+ | (1 << lfrXParser.T__43)
+ | (1 << lfrXParser.T__44)
+ | (1 << lfrXParser.T__45)
+ | (1 << lfrXParser.T__46)
+ | (1 << lfrXParser.T__47)
+ | (1 << lfrXParser.T__48)
+ | (1 << lfrXParser.T__49)
+ | (1 << lfrXParser.T__50)
+ )
+ ) != 0:
+ self.state = 431
+ self.unary_operator()
+
+ self.state = 434
+ self.match(lfrXParser.T__2)
+ self.state = 435
+ self.expression()
+ self.state = 436
+ self.match(lfrXParser.T__3)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ExpressionContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def bracketexpression(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.BracketexpressionContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.BracketexpressionContext, i)
+
+ def expressionterm(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.ExpressiontermContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.ExpressiontermContext, i)
+
+ def binary_operator(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.Binary_operatorContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.Binary_operatorContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_expression
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterExpression"):
+ listener.enterExpression(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitExpression"):
+ listener.exitExpression(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitExpression"):
+ return visitor.visitExpression(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def expression(self):
+ localctx = lfrXParser.ExpressionContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 86, self.RULE_expression)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 440
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 38, self._ctx)
+ if la_ == 1:
+ self.state = 438
+ self.bracketexpression()
+ pass
+
+ elif la_ == 2:
+ self.state = 439
+ self.expressionterm()
+ pass
+
+ self.state = 449
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while (((_la - 19)) & ~0x3F) == 0 and (
+ (1 << (_la - 19))
+ & (
+ (1 << (lfrXParser.T__18 - 19))
+ | (1 << (lfrXParser.T__37 - 19))
+ | (1 << (lfrXParser.T__38 - 19))
+ | (1 << (lfrXParser.T__39 - 19))
+ | (1 << (lfrXParser.T__40 - 19))
+ | (1 << (lfrXParser.T__41 - 19))
+ | (1 << (lfrXParser.T__44 - 19))
+ | (1 << (lfrXParser.T__46 - 19))
+ | (1 << (lfrXParser.T__48 - 19))
+ | (1 << (lfrXParser.T__49 - 19))
+ | (1 << (lfrXParser.T__50 - 19))
+ | (1 << (lfrXParser.T__51 - 19))
+ | (1 << (lfrXParser.T__52 - 19))
+ | (1 << (lfrXParser.T__53 - 19))
+ | (1 << (lfrXParser.T__54 - 19))
+ | (1 << (lfrXParser.T__55 - 19))
+ | (1 << (lfrXParser.T__56 - 19))
+ | (1 << (lfrXParser.T__57 - 19))
+ | (1 << (lfrXParser.T__58 - 19))
+ | (1 << (lfrXParser.T__59 - 19))
+ | (1 << (lfrXParser.T__60 - 19))
+ | (1 << (lfrXParser.T__61 - 19))
+ | (1 << (lfrXParser.T__62 - 19))
+ | (1 << (lfrXParser.T__63 - 19))
+ | (1 << (lfrXParser.T__64 - 19))
+ )
+ ) != 0:
+ self.state = 442
+ self.binary_operator()
+ self.state = 445
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 39, self._ctx)
+ if la_ == 1:
+ self.state = 443
+ self.bracketexpression()
+ pass
+
+ elif la_ == 2:
+ self.state = 444
+ self.expressionterm()
+ pass
+
+ self.state = 451
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ExpressiontermContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def variables(self):
+ return self.getTypedRuleContext(lfrXParser.VariablesContext, 0)
+
+ def unary_operator(self):
+ return self.getTypedRuleContext(lfrXParser.Unary_operatorContext, 0)
+
+ def number(self):
+ return self.getTypedRuleContext(lfrXParser.NumberContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_expressionterm
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterExpressionterm"):
+ listener.enterExpressionterm(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitExpressionterm"):
+ listener.exitExpressionterm(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitExpressionterm"):
+ return visitor.visitExpressionterm(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def expressionterm(self):
+ localctx = lfrXParser.ExpressiontermContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 88, self.RULE_expressionterm)
+ self._la = 0 # Token type
+ try:
+ self.state = 457
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [
+ lfrXParser.T__29,
+ lfrXParser.T__40,
+ lfrXParser.T__41,
+ lfrXParser.T__42,
+ lfrXParser.T__43,
+ lfrXParser.T__44,
+ lfrXParser.T__45,
+ lfrXParser.T__46,
+ lfrXParser.T__47,
+ lfrXParser.T__48,
+ lfrXParser.T__49,
+ lfrXParser.T__50,
+ lfrXParser.ID,
+ ]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 453
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if ((_la) & ~0x3F) == 0 and (
+ (1 << _la)
+ & (
+ (1 << lfrXParser.T__40)
+ | (1 << lfrXParser.T__41)
+ | (1 << lfrXParser.T__42)
+ | (1 << lfrXParser.T__43)
+ | (1 << lfrXParser.T__44)
+ | (1 << lfrXParser.T__45)
+ | (1 << lfrXParser.T__46)
+ | (1 << lfrXParser.T__47)
+ | (1 << lfrXParser.T__48)
+ | (1 << lfrXParser.T__49)
+ | (1 << lfrXParser.T__50)
+ )
+ ) != 0:
+ self.state = 452
+ self.unary_operator()
+
+ self.state = 455
+ self.variables()
+ pass
+ elif token in [
+ lfrXParser.Real_number,
+ lfrXParser.Decimal_number,
+ lfrXParser.Binary_number,
+ lfrXParser.Octal_number,
+ lfrXParser.Hex_number,
+ ]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 456
+ self.number()
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class Logiccondition_operandContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def bracketexpression(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.BracketexpressionContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.BracketexpressionContext, i)
+
+ def expressionterm(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.ExpressiontermContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.ExpressiontermContext, i)
+
+ def binary_operator(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.Binary_operatorContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.Binary_operatorContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_logiccondition_operand
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterLogiccondition_operand"):
+ listener.enterLogiccondition_operand(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitLogiccondition_operand"):
+ listener.exitLogiccondition_operand(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitLogiccondition_operand"):
+ return visitor.visitLogiccondition_operand(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def logiccondition_operand(self):
+ localctx = lfrXParser.Logiccondition_operandContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 90, self.RULE_logiccondition_operand)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 461
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 43, self._ctx)
+ if la_ == 1:
+ self.state = 459
+ self.bracketexpression()
+ pass
+
+ elif la_ == 2:
+ self.state = 460
+ self.expressionterm()
+ pass
+
+ self.state = 470
+ self._errHandler.sync(self)
+ _alt = self._interp.adaptivePredict(self._input, 45, self._ctx)
+ while _alt != 2 and _alt != ATN.INVALID_ALT_NUMBER:
+ if _alt == 1:
+ self.state = 463
+ self.binary_operator()
+ self.state = 466
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 44, self._ctx)
+ if la_ == 1:
+ self.state = 464
+ self.bracketexpression()
+ pass
+
+ elif la_ == 2:
+ self.state = 465
+ self.expressionterm()
+ pass
+
+ self.state = 472
+ self._errHandler.sync(self)
+ _alt = self._interp.adaptivePredict(self._input, 45, self._ctx)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class LogicconditionContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def logiccondition_operand(self):
+ return self.getTypedRuleContext(lfrXParser.Logiccondition_operandContext, 0)
+
+ def binary_module_path_operator(self):
+ return self.getTypedRuleContext(
+ lfrXParser.Binary_module_path_operatorContext, 0
+ )
+
+ def logic_value(self):
+ return self.getTypedRuleContext(lfrXParser.Logic_valueContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_logiccondition
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterLogiccondition"):
+ listener.enterLogiccondition(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitLogiccondition"):
+ listener.exitLogiccondition(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitLogiccondition"):
+ return visitor.visitLogiccondition(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def logiccondition(self):
+ localctx = lfrXParser.LogicconditionContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 92, self.RULE_logiccondition)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 473
+ self.logiccondition_operand()
+ self.state = 474
+ self.binary_module_path_operator()
+ self.state = 475
+ self.logic_value()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class Logic_valueContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def number(self):
+ return self.getTypedRuleContext(lfrXParser.NumberContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_logic_value
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterLogic_value"):
+ listener.enterLogic_value(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitLogic_value"):
+ listener.exitLogic_value(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitLogic_value"):
+ return visitor.visitLogic_value(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def logic_value(self):
+ localctx = lfrXParser.Logic_valueContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 94, self.RULE_logic_value)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 477
+ self.number()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class VectorContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.start = None # Token
+ self.end = None # Token
+
+ def Decimal_number(self, i: int = None):
+ if i is None:
+ return self.getTokens(lfrXParser.Decimal_number)
+ else:
+ return self.getToken(lfrXParser.Decimal_number, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_vector
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterVector"):
+ listener.enterVector(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitVector"):
+ listener.exitVector(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitVector"):
+ return visitor.visitVector(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def vector(self):
+ localctx = lfrXParser.VectorContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 96, self.RULE_vector)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 479
+ self.match(lfrXParser.T__27)
+ self.state = 480
+ localctx.start = self.match(lfrXParser.Decimal_number)
+ self.state = 483
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la == lfrXParser.T__16:
+ self.state = 481
+ self.match(lfrXParser.T__16)
+ self.state = 482
+ localctx.end = self.match(lfrXParser.Decimal_number)
+
+ self.state = 485
+ self.match(lfrXParser.T__28)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class VariablesContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def vectorvar(self):
+ return self.getTypedRuleContext(lfrXParser.VectorvarContext, 0)
+
+ def concatenation(self):
+ return self.getTypedRuleContext(lfrXParser.ConcatenationContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_variables
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterVariables"):
+ listener.enterVariables(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitVariables"):
+ listener.exitVariables(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitVariables"):
+ return visitor.visitVariables(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def variables(self):
+ localctx = lfrXParser.VariablesContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 98, self.RULE_variables)
+ try:
+ self.state = 489
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [lfrXParser.ID]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 487
+ self.vectorvar()
+ pass
+ elif token in [lfrXParser.T__29]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 488
+ self.concatenation()
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ConcatenationContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def vectorvar(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.VectorvarContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.VectorvarContext, i)
+
+ def vector(self):
+ return self.getTypedRuleContext(lfrXParser.VectorContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_concatenation
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterConcatenation"):
+ listener.enterConcatenation(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitConcatenation"):
+ listener.exitConcatenation(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitConcatenation"):
+ return visitor.visitConcatenation(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def concatenation(self):
+ localctx = lfrXParser.ConcatenationContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 100, self.RULE_concatenation)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 491
+ self.match(lfrXParser.T__29)
+ self.state = 492
+ self.vectorvar()
+ self.state = 497
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == lfrXParser.T__5:
+ self.state = 493
+ self.match(lfrXParser.T__5)
+ self.state = 494
+ self.vectorvar()
+ self.state = 499
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ self.state = 500
+ self.match(lfrXParser.T__30)
+ self.state = 502
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la == lfrXParser.T__27:
+ self.state = 501
+ self.vector()
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class LhsContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def variables(self):
+ return self.getTypedRuleContext(lfrXParser.VariablesContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_lhs
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterLhs"):
+ listener.enterLhs(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitLhs"):
+ listener.exitLhs(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitLhs"):
+ return visitor.visitLhs(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def lhs(self):
+ localctx = lfrXParser.LhsContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 102, self.RULE_lhs)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 504
+ self.variables()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class IoassignstatContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def explicitIOBlock(self):
+ return self.getTypedRuleContext(lfrXParser.ExplicitIOBlockContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_ioassignstat
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterIoassignstat"):
+ listener.enterIoassignstat(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitIoassignstat"):
+ listener.exitIoassignstat(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitIoassignstat"):
+ return visitor.visitIoassignstat(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def ioassignstat(self):
+ localctx = lfrXParser.IoassignstatContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 104, self.RULE_ioassignstat)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 506
+ self.explicitIOBlock()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class TechnologydirectivesContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def performancedirective(self):
+ return self.getTypedRuleContext(lfrXParser.PerformancedirectiveContext, 0)
+
+ def technologymappingdirective(self):
+ return self.getTypedRuleContext(
+ lfrXParser.TechnologymappingdirectiveContext, 0
+ )
+
+ def materialmappingdirective(self):
+ return self.getTypedRuleContext(
+ lfrXParser.MaterialmappingdirectiveContext, 0
+ )
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_technologydirectives
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterTechnologydirectives"):
+ listener.enterTechnologydirectives(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitTechnologydirectives"):
+ listener.exitTechnologydirectives(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitTechnologydirectives"):
+ return visitor.visitTechnologydirectives(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def technologydirectives(self):
+ localctx = lfrXParser.TechnologydirectivesContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 106, self.RULE_technologydirectives)
+ try:
+ self.state = 511
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [lfrXParser.T__34]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 508
+ self.performancedirective()
+ pass
+ elif token in [lfrXParser.T__31]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 509
+ self.technologymappingdirective()
+ pass
+ elif token in [lfrXParser.T__33]:
+ self.enterOuterAlt(localctx, 3)
+ self.state = 510
+ self.materialmappingdirective()
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class TechnologymappingdirectiveContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.assignmode = None # Token
+
+ def mappingoperator(self):
+ return self.getTypedRuleContext(lfrXParser.MappingoperatorContext, 0)
+
+ def ID(self, i: int = None):
+ if i is None:
+ return self.getTokens(lfrXParser.ID)
+ else:
+ return self.getToken(lfrXParser.ID, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_technologymappingdirective
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterTechnologymappingdirective"):
+ listener.enterTechnologymappingdirective(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitTechnologymappingdirective"):
+ listener.exitTechnologymappingdirective(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitTechnologymappingdirective"):
+ return visitor.visitTechnologymappingdirective(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def technologymappingdirective(self):
+ localctx = lfrXParser.TechnologymappingdirectiveContext(
+ self, self._ctx, self.state
+ )
+ self.enterRule(localctx, 108, self.RULE_technologymappingdirective)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 513
+ self.match(lfrXParser.T__31)
+ self.state = 514
+ self.match(lfrXParser.T__32)
+ self.state = 516
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while True:
+ self.state = 515
+ self.match(lfrXParser.ID)
+ self.state = 518
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if not (_la == lfrXParser.ID):
+ break
+
+ self.state = 520
+ self.match(lfrXParser.T__32)
+ self.state = 521
+ self.match(lfrXParser.T__32)
+ self.state = 524
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [
+ lfrXParser.T__18,
+ lfrXParser.T__37,
+ lfrXParser.T__38,
+ lfrXParser.T__39,
+ lfrXParser.T__40,
+ lfrXParser.T__41,
+ lfrXParser.T__42,
+ lfrXParser.T__43,
+ lfrXParser.T__44,
+ lfrXParser.T__45,
+ lfrXParser.T__46,
+ lfrXParser.T__47,
+ lfrXParser.T__48,
+ lfrXParser.T__49,
+ lfrXParser.T__50,
+ lfrXParser.T__51,
+ lfrXParser.T__52,
+ lfrXParser.T__53,
+ lfrXParser.T__54,
+ lfrXParser.T__55,
+ lfrXParser.T__56,
+ lfrXParser.T__57,
+ lfrXParser.T__58,
+ lfrXParser.T__59,
+ lfrXParser.T__60,
+ lfrXParser.T__61,
+ lfrXParser.T__62,
+ lfrXParser.T__63,
+ lfrXParser.T__64,
+ ]:
+ self.state = 522
+ self.mappingoperator()
+ pass
+ elif token in [lfrXParser.T__22, lfrXParser.T__23, lfrXParser.T__25]:
+ self.state = 523
+ localctx.assignmode = self._input.LT(1)
+ _la = self._input.LA(1)
+ if not (
+ (
+ ((_la) & ~0x3F) == 0
+ and (
+ (1 << _la)
+ & (
+ (1 << lfrXParser.T__22)
+ | (1 << lfrXParser.T__23)
+ | (1 << lfrXParser.T__25)
+ )
+ )
+ != 0
+ )
+ ):
+ localctx.assignmode = self._errHandler.recoverInline(self)
+ else:
+ self._errHandler.reportMatch(self)
+ self.consume()
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ self.state = 526
+ self.match(lfrXParser.T__32)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class MaterialmappingdirectiveContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.materialtype = None # Token
+
+ def ID(self, i: int = None):
+ if i is None:
+ return self.getTokens(lfrXParser.ID)
+ else:
+ return self.getToken(lfrXParser.ID, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_materialmappingdirective
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterMaterialmappingdirective"):
+ listener.enterMaterialmappingdirective(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitMaterialmappingdirective"):
+ listener.exitMaterialmappingdirective(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitMaterialmappingdirective"):
+ return visitor.visitMaterialmappingdirective(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def materialmappingdirective(self):
+ localctx = lfrXParser.MaterialmappingdirectiveContext(
+ self, self._ctx, self.state
+ )
+ self.enterRule(localctx, 110, self.RULE_materialmappingdirective)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 528
+ self.match(lfrXParser.T__33)
+ self.state = 529
+ self.match(lfrXParser.ID)
+ self.state = 530
+ localctx.materialtype = self.match(lfrXParser.ID)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class MappingoperatorContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def binary_operator(self):
+ return self.getTypedRuleContext(lfrXParser.Binary_operatorContext, 0)
+
+ def unary_operator(self):
+ return self.getTypedRuleContext(lfrXParser.Unary_operatorContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_mappingoperator
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterMappingoperator"):
+ listener.enterMappingoperator(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitMappingoperator"):
+ listener.exitMappingoperator(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitMappingoperator"):
+ return visitor.visitMappingoperator(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def mappingoperator(self):
+ localctx = lfrXParser.MappingoperatorContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 112, self.RULE_mappingoperator)
+ try:
+ self.state = 534
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 53, self._ctx)
+ if la_ == 1:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 532
+ self.binary_operator()
+ pass
+
+ elif la_ == 2:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 533
+ self.unary_operator()
+ pass
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class PerformancedirectiveContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def mappingoperator(self):
+ return self.getTypedRuleContext(lfrXParser.MappingoperatorContext, 0)
+
+ def constraint(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(lfrXParser.ConstraintContext)
+ else:
+ return self.getTypedRuleContext(lfrXParser.ConstraintContext, i)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_performancedirective
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterPerformancedirective"):
+ listener.enterPerformancedirective(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitPerformancedirective"):
+ listener.exitPerformancedirective(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitPerformancedirective"):
+ return visitor.visitPerformancedirective(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def performancedirective(self):
+ localctx = lfrXParser.PerformancedirectiveContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 114, self.RULE_performancedirective)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 536
+ self.match(lfrXParser.T__34)
+ self.state = 537
+ self.match(lfrXParser.T__32)
+ self.state = 538
+ self.mappingoperator()
+ self.state = 539
+ self.match(lfrXParser.T__32)
+ self.state = 540
+ self.constraint()
+ self.state = 545
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == lfrXParser.T__35 or _la == lfrXParser.T__36:
+ self.state = 541
+ _la = self._input.LA(1)
+ if not (_la == lfrXParser.T__35 or _la == lfrXParser.T__36):
+ self._errHandler.recoverInline(self)
+ else:
+ self._errHandler.reportMatch(self)
+ self.consume()
+ self.state = 542
+ self.constraint()
+ self.state = 547
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ConstraintContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.operator = None # Token
+
+ def ID(self):
+ return self.getToken(lfrXParser.ID, 0)
+
+ def number(self):
+ return self.getTypedRuleContext(lfrXParser.NumberContext, 0)
+
+ def unit(self):
+ return self.getTypedRuleContext(lfrXParser.UnitContext, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_constraint
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterConstraint"):
+ listener.enterConstraint(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitConstraint"):
+ listener.exitConstraint(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitConstraint"):
+ return visitor.visitConstraint(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def constraint(self):
+ localctx = lfrXParser.ConstraintContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 116, self.RULE_constraint)
+ try:
+ self.state = 578
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 60, self._ctx)
+ if la_ == 1:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 548
+ self.match(lfrXParser.ID)
+ self.state = 549
+ localctx.operator = self.match(lfrXParser.T__26)
+ self.state = 550
+ self.number()
+ self.state = 552
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 55, self._ctx)
+ if la_ == 1:
+ self.state = 551
+ self.unit()
+
+ pass
+
+ elif la_ == 2:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 554
+ self.match(lfrXParser.ID)
+ self.state = 555
+ localctx.operator = self.match(lfrXParser.T__37)
+ self.state = 556
+ self.number()
+ self.state = 558
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 56, self._ctx)
+ if la_ == 1:
+ self.state = 557
+ self.unit()
+
+ pass
+
+ elif la_ == 3:
+ self.enterOuterAlt(localctx, 3)
+ self.state = 560
+ self.match(lfrXParser.ID)
+ self.state = 561
+ localctx.operator = self.match(lfrXParser.T__38)
+ self.state = 562
+ self.number()
+ self.state = 564
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 57, self._ctx)
+ if la_ == 1:
+ self.state = 563
+ self.unit()
+
+ pass
+
+ elif la_ == 4:
+ self.enterOuterAlt(localctx, 4)
+ self.state = 566
+ self.match(lfrXParser.ID)
+ self.state = 567
+ localctx.operator = self.match(lfrXParser.T__39)
+ self.state = 568
+ self.number()
+ self.state = 570
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 58, self._ctx)
+ if la_ == 1:
+ self.state = 569
+ self.unit()
+
+ pass
+
+ elif la_ == 5:
+ self.enterOuterAlt(localctx, 5)
+ self.state = 572
+ self.match(lfrXParser.ID)
+ self.state = 573
+ localctx.operator = self.match(lfrXParser.T__18)
+ self.state = 574
+ self.number()
+ self.state = 576
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 59, self._ctx)
+ if la_ == 1:
+ self.state = 575
+ self.unit()
+
+ pass
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class UnitContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def ID(self):
+ return self.getToken(lfrXParser.ID, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_unit
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterUnit"):
+ listener.enterUnit(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitUnit"):
+ listener.exitUnit(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitUnit"):
+ return visitor.visitUnit(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def unit(self):
+ localctx = lfrXParser.UnitContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 118, self.RULE_unit)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 580
+ self.match(lfrXParser.ID)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class Unary_operatorContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_unary_operator
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterUnary_operator"):
+ listener.enterUnary_operator(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitUnary_operator"):
+ listener.exitUnary_operator(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitUnary_operator"):
+ return visitor.visitUnary_operator(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def unary_operator(self):
+ localctx = lfrXParser.Unary_operatorContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 120, self.RULE_unary_operator)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 582
+ _la = self._input.LA(1)
+ if not (
+ (
+ ((_la) & ~0x3F) == 0
+ and (
+ (1 << _la)
+ & (
+ (1 << lfrXParser.T__40)
+ | (1 << lfrXParser.T__41)
+ | (1 << lfrXParser.T__42)
+ | (1 << lfrXParser.T__43)
+ | (1 << lfrXParser.T__44)
+ | (1 << lfrXParser.T__45)
+ | (1 << lfrXParser.T__46)
+ | (1 << lfrXParser.T__47)
+ | (1 << lfrXParser.T__48)
+ | (1 << lfrXParser.T__49)
+ | (1 << lfrXParser.T__50)
+ )
+ )
+ != 0
+ )
+ ):
+ self._errHandler.recoverInline(self)
+ else:
+ self._errHandler.reportMatch(self)
+ self.consume()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class Binary_operatorContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_binary_operator
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterBinary_operator"):
+ listener.enterBinary_operator(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitBinary_operator"):
+ listener.exitBinary_operator(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitBinary_operator"):
+ return visitor.visitBinary_operator(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def binary_operator(self):
+ localctx = lfrXParser.Binary_operatorContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 122, self.RULE_binary_operator)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 584
+ _la = self._input.LA(1)
+ if not (
+ (
+ (((_la - 19)) & ~0x3F) == 0
+ and (
+ (1 << (_la - 19))
+ & (
+ (1 << (lfrXParser.T__18 - 19))
+ | (1 << (lfrXParser.T__37 - 19))
+ | (1 << (lfrXParser.T__38 - 19))
+ | (1 << (lfrXParser.T__39 - 19))
+ | (1 << (lfrXParser.T__40 - 19))
+ | (1 << (lfrXParser.T__41 - 19))
+ | (1 << (lfrXParser.T__44 - 19))
+ | (1 << (lfrXParser.T__46 - 19))
+ | (1 << (lfrXParser.T__48 - 19))
+ | (1 << (lfrXParser.T__49 - 19))
+ | (1 << (lfrXParser.T__50 - 19))
+ | (1 << (lfrXParser.T__51 - 19))
+ | (1 << (lfrXParser.T__52 - 19))
+ | (1 << (lfrXParser.T__53 - 19))
+ | (1 << (lfrXParser.T__54 - 19))
+ | (1 << (lfrXParser.T__55 - 19))
+ | (1 << (lfrXParser.T__56 - 19))
+ | (1 << (lfrXParser.T__57 - 19))
+ | (1 << (lfrXParser.T__58 - 19))
+ | (1 << (lfrXParser.T__59 - 19))
+ | (1 << (lfrXParser.T__60 - 19))
+ | (1 << (lfrXParser.T__61 - 19))
+ | (1 << (lfrXParser.T__62 - 19))
+ | (1 << (lfrXParser.T__63 - 19))
+ | (1 << (lfrXParser.T__64 - 19))
+ )
+ )
+ != 0
+ )
+ ):
+ self._errHandler.recoverInline(self)
+ else:
+ self._errHandler.reportMatch(self)
+ self.consume()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class Unary_module_path_operatorContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_unary_module_path_operator
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterUnary_module_path_operator"):
+ listener.enterUnary_module_path_operator(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitUnary_module_path_operator"):
+ listener.exitUnary_module_path_operator(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitUnary_module_path_operator"):
+ return visitor.visitUnary_module_path_operator(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def unary_module_path_operator(self):
+ localctx = lfrXParser.Unary_module_path_operatorContext(
+ self, self._ctx, self.state
+ )
+ self.enterRule(localctx, 124, self.RULE_unary_module_path_operator)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 586
+ _la = self._input.LA(1)
+ if not (
+ (
+ ((_la) & ~0x3F) == 0
+ and (
+ (1 << _la)
+ & (
+ (1 << lfrXParser.T__42)
+ | (1 << lfrXParser.T__43)
+ | (1 << lfrXParser.T__44)
+ | (1 << lfrXParser.T__45)
+ | (1 << lfrXParser.T__46)
+ | (1 << lfrXParser.T__47)
+ | (1 << lfrXParser.T__48)
+ | (1 << lfrXParser.T__49)
+ | (1 << lfrXParser.T__50)
+ )
+ )
+ != 0
+ )
+ ):
+ self._errHandler.recoverInline(self)
+ else:
+ self._errHandler.reportMatch(self)
+ self.consume()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class Binary_module_path_operatorContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_binary_module_path_operator
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterBinary_module_path_operator"):
+ listener.enterBinary_module_path_operator(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitBinary_module_path_operator"):
+ listener.exitBinary_module_path_operator(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitBinary_module_path_operator"):
+ return visitor.visitBinary_module_path_operator(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def binary_module_path_operator(self):
+ localctx = lfrXParser.Binary_module_path_operatorContext(
+ self, self._ctx, self.state
+ )
+ self.enterRule(localctx, 126, self.RULE_binary_module_path_operator)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 588
+ _la = self._input.LA(1)
+ if not (
+ (
+ ((_la) & ~0x3F) == 0
+ and (
+ (1 << _la)
+ & (
+ (1 << lfrXParser.T__44)
+ | (1 << lfrXParser.T__46)
+ | (1 << lfrXParser.T__48)
+ | (1 << lfrXParser.T__49)
+ | (1 << lfrXParser.T__50)
+ | (1 << lfrXParser.T__54)
+ | (1 << lfrXParser.T__55)
+ | (1 << lfrXParser.T__58)
+ | (1 << lfrXParser.T__59)
+ )
+ )
+ != 0
+ )
+ ):
+ self._errHandler.recoverInline(self)
+ else:
+ self._errHandler.reportMatch(self)
+ self.consume()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class NumberContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def Decimal_number(self):
+ return self.getToken(lfrXParser.Decimal_number, 0)
+
+ def Octal_number(self):
+ return self.getToken(lfrXParser.Octal_number, 0)
+
+ def Binary_number(self):
+ return self.getToken(lfrXParser.Binary_number, 0)
+
+ def Hex_number(self):
+ return self.getToken(lfrXParser.Hex_number, 0)
+
+ def Real_number(self):
+ return self.getToken(lfrXParser.Real_number, 0)
+
+ def getRuleIndex(self):
+ return lfrXParser.RULE_number
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterNumber"):
+ listener.enterNumber(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitNumber"):
+ listener.exitNumber(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitNumber"):
+ return visitor.visitNumber(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def number(self):
+ localctx = lfrXParser.NumberContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 128, self.RULE_number)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 590
+ _la = self._input.LA(1)
+ if not (
+ (
+ (((_la - 71)) & ~0x3F) == 0
+ and (
+ (1 << (_la - 71))
+ & (
+ (1 << (lfrXParser.Real_number - 71))
+ | (1 << (lfrXParser.Decimal_number - 71))
+ | (1 << (lfrXParser.Binary_number - 71))
+ | (1 << (lfrXParser.Octal_number - 71))
+ | (1 << (lfrXParser.Hex_number - 71))
+ )
+ )
+ != 0
+ )
+ ):
+ self._errHandler.recoverInline(self)
+ else:
+ self._errHandler.reportMatch(self)
+ self.consume()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
diff --git a/lfr/antlrgen/lfrXVisitor.py b/lfr/antlrgen/lfr/lfrXVisitor.py
similarity index 58%
rename from lfr/antlrgen/lfrXVisitor.py
rename to lfr/antlrgen/lfr/lfrXVisitor.py
index 6297a96..0a9b03d 100755
--- a/lfr/antlrgen/lfrXVisitor.py
+++ b/lfr/antlrgen/lfr/lfrXVisitor.py
@@ -1,5 +1,6 @@
-# Generated from ./lfrX.g4 by ANTLR 4.9.1
+# Generated from ./lfrX.g4 by ANTLR 4.10.1
from antlr4 import *
+
if __name__ is not None and "." in __name__:
from .lfrXParser import lfrXParser
else:
@@ -7,332 +8,283 @@
# This class defines a complete generic visitor for a parse tree produced by lfrXParser.
-class lfrXVisitor(ParseTreeVisitor):
+class lfrXVisitor(ParseTreeVisitor):
# Visit a parse tree produced by lfrXParser#skeleton.
- def visitSkeleton(self, ctx:lfrXParser.SkeletonContext):
+ def visitSkeleton(self, ctx: lfrXParser.SkeletonContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#module.
- def visitModule(self, ctx:lfrXParser.ModuleContext):
+ def visitModule(self, ctx: lfrXParser.ModuleContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#moduledefinition.
- def visitModuledefinition(self, ctx:lfrXParser.ModuledefinitionContext):
+ def visitModuledefinition(self, ctx: lfrXParser.ModuledefinitionContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#body.
- def visitBody(self, ctx:lfrXParser.BodyContext):
+ def visitBody(self, ctx: lfrXParser.BodyContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#ioblock.
- def visitIoblock(self, ctx:lfrXParser.IoblockContext):
+ def visitIoblock(self, ctx: lfrXParser.IoblockContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#vectorvar.
- def visitVectorvar(self, ctx:lfrXParser.VectorvarContext):
+ def visitVectorvar(self, ctx: lfrXParser.VectorvarContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#explicitIOBlock.
- def visitExplicitIOBlock(self, ctx:lfrXParser.ExplicitIOBlockContext):
+ def visitExplicitIOBlock(self, ctx: lfrXParser.ExplicitIOBlockContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#declvar.
- def visitDeclvar(self, ctx:lfrXParser.DeclvarContext):
+ def visitDeclvar(self, ctx: lfrXParser.DeclvarContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#distributionBlock.
- def visitDistributionBlock(self, ctx:lfrXParser.DistributionBlockContext):
+ def visitDistributionBlock(self, ctx: lfrXParser.DistributionBlockContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#distributionBody.
- def visitDistributionBody(self, ctx:lfrXParser.DistributionBodyContext):
+ def visitDistributionBody(self, ctx: lfrXParser.DistributionBodyContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#distributeBodyStat.
- def visitDistributeBodyStat(self, ctx:lfrXParser.DistributeBodyStatContext):
+ def visitDistributeBodyStat(self, ctx: lfrXParser.DistributeBodyStatContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#ifElseBlock.
- def visitIfElseBlock(self, ctx:lfrXParser.IfElseBlockContext):
+ def visitIfElseBlock(self, ctx: lfrXParser.IfElseBlockContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#ifBlock.
- def visitIfBlock(self, ctx:lfrXParser.IfBlockContext):
+ def visitIfBlock(self, ctx: lfrXParser.IfBlockContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#elseBlock.
- def visitElseBlock(self, ctx:lfrXParser.ElseBlockContext):
+ def visitElseBlock(self, ctx: lfrXParser.ElseBlockContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#elseIfBlock.
- def visitElseIfBlock(self, ctx:lfrXParser.ElseIfBlockContext):
+ def visitElseIfBlock(self, ctx: lfrXParser.ElseIfBlockContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#distributeCondition.
- def visitDistributeCondition(self, ctx:lfrXParser.DistributeConditionContext):
+ def visitDistributeCondition(self, ctx: lfrXParser.DistributeConditionContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#statementBlock.
- def visitStatementBlock(self, ctx:lfrXParser.StatementBlockContext):
+ def visitStatementBlock(self, ctx: lfrXParser.StatementBlockContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#caseBlock.
- def visitCaseBlock(self, ctx:lfrXParser.CaseBlockContext):
+ def visitCaseBlock(self, ctx: lfrXParser.CaseBlockContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#caseBlockHeader.
- def visitCaseBlockHeader(self, ctx:lfrXParser.CaseBlockHeaderContext):
+ def visitCaseBlockHeader(self, ctx: lfrXParser.CaseBlockHeaderContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#casestat.
- def visitCasestat(self, ctx:lfrXParser.CasestatContext):
+ def visitCasestat(self, ctx: lfrXParser.CasestatContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#defaultCaseStat.
- def visitDefaultCaseStat(self, ctx:lfrXParser.DefaultCaseStatContext):
+ def visitDefaultCaseStat(self, ctx: lfrXParser.DefaultCaseStatContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#distvalue.
- def visitDistvalue(self, ctx:lfrXParser.DistvalueContext):
+ def visitDistvalue(self, ctx: lfrXParser.DistvalueContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#distributionassignstat.
- def visitDistributionassignstat(self, ctx:lfrXParser.DistributionassignstatContext):
+ def visitDistributionassignstat(
+ self, ctx: lfrXParser.DistributionassignstatContext
+ ):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#sensitivitylist.
- def visitSensitivitylist(self, ctx:lfrXParser.SensitivitylistContext):
+ def visitSensitivitylist(self, ctx: lfrXParser.SensitivitylistContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#signal.
- def visitSignal(self, ctx:lfrXParser.SignalContext):
+ def visitSignal(self, ctx: lfrXParser.SignalContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#statements.
- def visitStatements(self, ctx:lfrXParser.StatementsContext):
+ def visitStatements(self, ctx: lfrXParser.StatementsContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#statement.
- def visitStatement(self, ctx:lfrXParser.StatementContext):
+ def visitStatement(self, ctx: lfrXParser.StatementContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#moduleinstantiationstat.
- def visitModuleinstantiationstat(self, ctx:lfrXParser.ModuleinstantiationstatContext):
+ def visitModuleinstantiationstat(
+ self, ctx: lfrXParser.ModuleinstantiationstatContext
+ ):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#instanceioblock.
- def visitInstanceioblock(self, ctx:lfrXParser.InstanceioblockContext):
+ def visitInstanceioblock(self, ctx: lfrXParser.InstanceioblockContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#orderedioblock.
- def visitOrderedioblock(self, ctx:lfrXParser.OrderedioblockContext):
+ def visitOrderedioblock(self, ctx: lfrXParser.OrderedioblockContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#unorderedioblock.
- def visitUnorderedioblock(self, ctx:lfrXParser.UnorderedioblockContext):
+ def visitUnorderedioblock(self, ctx: lfrXParser.UnorderedioblockContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#explicitinstanceiomapping.
- def visitExplicitinstanceiomapping(self, ctx:lfrXParser.ExplicitinstanceiomappingContext):
+ def visitExplicitinstanceiomapping(
+ self, ctx: lfrXParser.ExplicitinstanceiomappingContext
+ ):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#instancename.
- def visitInstancename(self, ctx:lfrXParser.InstancenameContext):
+ def visitInstancename(self, ctx: lfrXParser.InstancenameContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#moduletype.
- def visitModuletype(self, ctx:lfrXParser.ModuletypeContext):
+ def visitModuletype(self, ctx: lfrXParser.ModuletypeContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#tempvariablesstat.
- def visitTempvariablesstat(self, ctx:lfrXParser.TempvariablesstatContext):
+ def visitTempvariablesstat(self, ctx: lfrXParser.TempvariablesstatContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#signalvarstat.
- def visitSignalvarstat(self, ctx:lfrXParser.SignalvarstatContext):
+ def visitSignalvarstat(self, ctx: lfrXParser.SignalvarstatContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#fluiddeclstat.
- def visitFluiddeclstat(self, ctx:lfrXParser.FluiddeclstatContext):
+ def visitFluiddeclstat(self, ctx: lfrXParser.FluiddeclstatContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#storagestat.
- def visitStoragestat(self, ctx:lfrXParser.StoragestatContext):
+ def visitStoragestat(self, ctx: lfrXParser.StoragestatContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#pumpvarstat.
- def visitPumpvarstat(self, ctx:lfrXParser.PumpvarstatContext):
+ def visitPumpvarstat(self, ctx: lfrXParser.PumpvarstatContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#numvarstat.
- def visitNumvarstat(self, ctx:lfrXParser.NumvarstatContext):
+ def visitNumvarstat(self, ctx: lfrXParser.NumvarstatContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#assignstat.
- def visitAssignstat(self, ctx:lfrXParser.AssignstatContext):
+ def visitAssignstat(self, ctx: lfrXParser.AssignstatContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#literalassignstat.
- def visitLiteralassignstat(self, ctx:lfrXParser.LiteralassignstatContext):
+ def visitLiteralassignstat(self, ctx: lfrXParser.LiteralassignstatContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#bracketexpression.
- def visitBracketexpression(self, ctx:lfrXParser.BracketexpressionContext):
+ def visitBracketexpression(self, ctx: lfrXParser.BracketexpressionContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#expression.
- def visitExpression(self, ctx:lfrXParser.ExpressionContext):
+ def visitExpression(self, ctx: lfrXParser.ExpressionContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#expressionterm.
- def visitExpressionterm(self, ctx:lfrXParser.ExpressiontermContext):
+ def visitExpressionterm(self, ctx: lfrXParser.ExpressiontermContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#logiccondition_operand.
- def visitLogiccondition_operand(self, ctx:lfrXParser.Logiccondition_operandContext):
+ def visitLogiccondition_operand(
+ self, ctx: lfrXParser.Logiccondition_operandContext
+ ):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#logiccondition.
- def visitLogiccondition(self, ctx:lfrXParser.LogicconditionContext):
+ def visitLogiccondition(self, ctx: lfrXParser.LogicconditionContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#logic_value.
- def visitLogic_value(self, ctx:lfrXParser.Logic_valueContext):
+ def visitLogic_value(self, ctx: lfrXParser.Logic_valueContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#vector.
- def visitVector(self, ctx:lfrXParser.VectorContext):
+ def visitVector(self, ctx: lfrXParser.VectorContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#variables.
- def visitVariables(self, ctx:lfrXParser.VariablesContext):
+ def visitVariables(self, ctx: lfrXParser.VariablesContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#concatenation.
- def visitConcatenation(self, ctx:lfrXParser.ConcatenationContext):
+ def visitConcatenation(self, ctx: lfrXParser.ConcatenationContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#lhs.
- def visitLhs(self, ctx:lfrXParser.LhsContext):
+ def visitLhs(self, ctx: lfrXParser.LhsContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#ioassignstat.
- def visitIoassignstat(self, ctx:lfrXParser.IoassignstatContext):
+ def visitIoassignstat(self, ctx: lfrXParser.IoassignstatContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#technologydirectives.
- def visitTechnologydirectives(self, ctx:lfrXParser.TechnologydirectivesContext):
+ def visitTechnologydirectives(self, ctx: lfrXParser.TechnologydirectivesContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#technologymappingdirective.
- def visitTechnologymappingdirective(self, ctx:lfrXParser.TechnologymappingdirectiveContext):
+ def visitTechnologymappingdirective(
+ self, ctx: lfrXParser.TechnologymappingdirectiveContext
+ ):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#materialmappingdirective.
- def visitMaterialmappingdirective(self, ctx:lfrXParser.MaterialmappingdirectiveContext):
+ def visitMaterialmappingdirective(
+ self, ctx: lfrXParser.MaterialmappingdirectiveContext
+ ):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#mappingoperator.
- def visitMappingoperator(self, ctx:lfrXParser.MappingoperatorContext):
+ def visitMappingoperator(self, ctx: lfrXParser.MappingoperatorContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#performancedirective.
- def visitPerformancedirective(self, ctx:lfrXParser.PerformancedirectiveContext):
+ def visitPerformancedirective(self, ctx: lfrXParser.PerformancedirectiveContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#constraint.
- def visitConstraint(self, ctx:lfrXParser.ConstraintContext):
+ def visitConstraint(self, ctx: lfrXParser.ConstraintContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#unit.
- def visitUnit(self, ctx:lfrXParser.UnitContext):
+ def visitUnit(self, ctx: lfrXParser.UnitContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#unary_operator.
- def visitUnary_operator(self, ctx:lfrXParser.Unary_operatorContext):
+ def visitUnary_operator(self, ctx: lfrXParser.Unary_operatorContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#binary_operator.
- def visitBinary_operator(self, ctx:lfrXParser.Binary_operatorContext):
+ def visitBinary_operator(self, ctx: lfrXParser.Binary_operatorContext):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#unary_module_path_operator.
- def visitUnary_module_path_operator(self, ctx:lfrXParser.Unary_module_path_operatorContext):
+ def visitUnary_module_path_operator(
+ self, ctx: lfrXParser.Unary_module_path_operatorContext
+ ):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#binary_module_path_operator.
- def visitBinary_module_path_operator(self, ctx:lfrXParser.Binary_module_path_operatorContext):
+ def visitBinary_module_path_operator(
+ self, ctx: lfrXParser.Binary_module_path_operatorContext
+ ):
return self.visitChildren(ctx)
-
# Visit a parse tree produced by lfrXParser#number.
- def visitNumber(self, ctx:lfrXParser.NumberContext):
+ def visitNumber(self, ctx: lfrXParser.NumberContext):
return self.visitChildren(ctx)
-
-del lfrXParser
\ No newline at end of file
+del lfrXParser
diff --git a/lfr/antlrgen/lfrX.interp b/lfr/antlrgen/lfrX.interp
deleted file mode 100755
index 9cdae8d..0000000
--- a/lfr/antlrgen/lfrX.interp
+++ /dev/null
@@ -1,226 +0,0 @@
-token literal names:
-null
-'endmodule'
-'module'
-'('
-')'
-';'
-','
-'finput'
-'foutput'
-'control'
-'distribute@'
-'begin'
-'end'
-'if'
-'else'
-'endcase'
-'case'
-':'
-'default'
-'<='
-'.'
-'signal'
-'flow'
-'storage'
-'pump'
-'number'
-'assign'
-'='
-'['
-']'
-'{'
-'}'
-'#MAP'
-'"'
-'#MATERIAL'
-'#CONSTRAIN'
-'AND'
-'OR'
-'>'
-'<'
-'>='
-'+'
-'-'
-'!'
-'~'
-'&'
-'~&'
-'|'
-'~|'
-'^'
-'~^'
-'^~'
-'*'
-'/'
-'%'
-'=='
-'!='
-'==='
-'!=='
-'&&'
-'||'
-'**'
-'>>'
-'<<'
-'>>>'
-'<<<'
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-
-token symbolic names:
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-ID
-WS
-One_line_comment
-Block_comment
-Import_line
-Real_number
-Decimal_number
-Binary_number
-Octal_number
-Hex_number
-
-rule names:
-skeleton
-module
-moduledefinition
-body
-ioblock
-vectorvar
-explicitIOBlock
-declvar
-distributionBlock
-distributionBody
-distributeBodyStat
-ifElseBlock
-ifBlock
-elseBlock
-elseIfBlock
-distributeCondition
-statementBlock
-caseBlock
-caseBlockHeader
-casestat
-defaultCaseStat
-distvalue
-distributionassignstat
-sensitivitylist
-signal
-statements
-statement
-moduleinstantiationstat
-instanceioblock
-orderedioblock
-unorderedioblock
-explicitinstanceiomapping
-instancename
-moduletype
-tempvariablesstat
-signalvarstat
-fluiddeclstat
-storagestat
-pumpvarstat
-numvarstat
-assignstat
-literalassignstat
-bracketexpression
-expression
-expressionterm
-logiccondition_operand
-logiccondition
-logic_value
-vector
-variables
-concatenation
-lhs
-ioassignstat
-technologydirectives
-technologymappingdirective
-materialmappingdirective
-mappingoperator
-performancedirective
-constraint
-unit
-unary_operator
-binary_operator
-unary_module_path_operator
-binary_module_path_operator
-number
-
-
-atn:
-[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 77, 595, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 3, 2, 6, 2, 134, 10, 2, 13, 2, 14, 2, 135, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 148, 10, 4, 3, 4, 3, 4, 3, 5, 3, 5, 6, 5, 154, 10, 5, 13, 5, 14, 5, 155, 3, 6, 3, 6, 3, 6, 7, 6, 161, 10, 6, 12, 6, 14, 6, 164, 11, 6, 3, 6, 3, 6, 3, 6, 7, 6, 169, 10, 6, 12, 6, 14, 6, 172, 11, 6, 5, 6, 174, 10, 6, 3, 7, 3, 7, 5, 7, 178, 10, 7, 3, 8, 3, 8, 3, 8, 3, 8, 7, 8, 184, 10, 8, 12, 8, 14, 8, 187, 11, 8, 3, 8, 3, 8, 3, 8, 3, 8, 7, 8, 193, 10, 8, 12, 8, 14, 8, 196, 11, 8, 3, 8, 3, 8, 3, 8, 3, 8, 7, 8, 202, 10, 8, 12, 8, 14, 8, 205, 11, 8, 5, 8, 207, 10, 8, 3, 9, 5, 9, 210, 10, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 6, 11, 223, 10, 11, 13, 11, 14, 11, 224, 3, 12, 3, 12, 3, 12, 5, 12, 230, 10, 12, 3, 13, 3, 13, 7, 13, 234, 10, 13, 12, 13, 14, 13, 237, 11, 13, 3, 13, 5, 13, 240, 10, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 6, 18, 264, 10, 18, 13, 18, 14, 18, 265, 3, 18, 3, 18, 3, 18, 5, 18, 271, 10, 18, 3, 19, 3, 19, 6, 19, 275, 10, 19, 13, 19, 14, 19, 276, 3, 19, 5, 19, 280, 10, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 5, 24, 304, 10, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 7, 25, 311, 10, 25, 12, 25, 14, 25, 314, 11, 25, 3, 26, 3, 26, 5, 26, 318, 10, 26, 3, 27, 3, 27, 3, 27, 3, 27, 5, 27, 324, 10, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 5, 28, 331, 10, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 5, 30, 341, 10, 30, 3, 31, 3, 31, 3, 31, 7, 31, 346, 10, 31, 12, 31, 14, 31, 349, 11, 31, 3, 32, 3, 32, 3, 32, 7, 32, 354, 10, 32, 12, 32, 14, 32, 357, 11, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 5, 36, 374, 10, 36, 3, 37, 3, 37, 3, 37, 3, 37, 7, 37, 380, 10, 37, 12, 37, 14, 37, 383, 11, 37, 3, 38, 3, 38, 3, 38, 3, 38, 7, 38, 389, 10, 38, 12, 38, 14, 38, 392, 11, 38, 3, 39, 3, 39, 3, 39, 3, 39, 7, 39, 398, 10, 39, 12, 39, 14, 39, 401, 11, 39, 3, 40, 3, 40, 3, 40, 3, 40, 7, 40, 407, 10, 40, 12, 40, 14, 40, 410, 11, 40, 3, 41, 3, 41, 3, 41, 3, 41, 7, 41, 416, 10, 41, 12, 41, 14, 41, 419, 11, 41, 3, 42, 3, 42, 3, 42, 3, 42, 3, 42, 5, 42, 426, 10, 42, 3, 43, 3, 43, 3, 43, 3, 43, 5, 43, 432, 10, 43, 3, 44, 5, 44, 435, 10, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 5, 45, 443, 10, 45, 3, 45, 3, 45, 3, 45, 5, 45, 448, 10, 45, 7, 45, 450, 10, 45, 12, 45, 14, 45, 453, 11, 45, 3, 46, 5, 46, 456, 10, 46, 3, 46, 3, 46, 5, 46, 460, 10, 46, 3, 47, 3, 47, 5, 47, 464, 10, 47, 3, 47, 3, 47, 3, 47, 5, 47, 469, 10, 47, 7, 47, 471, 10, 47, 12, 47, 14, 47, 474, 11, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 5, 50, 486, 10, 50, 3, 50, 3, 50, 3, 51, 3, 51, 5, 51, 492, 10, 51, 3, 52, 3, 52, 3, 52, 3, 52, 7, 52, 498, 10, 52, 12, 52, 14, 52, 501, 11, 52, 3, 52, 3, 52, 5, 52, 505, 10, 52, 3, 53, 3, 53, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 5, 55, 514, 10, 55, 3, 56, 3, 56, 3, 56, 6, 56, 519, 10, 56, 13, 56, 14, 56, 520, 3, 56, 3, 56, 3, 56, 3, 56, 5, 56, 527, 10, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 5, 58, 537, 10, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 7, 59, 546, 10, 59, 12, 59, 14, 59, 549, 11, 59, 3, 60, 3, 60, 3, 60, 3, 60, 5, 60, 555, 10, 60, 3, 60, 3, 60, 3, 60, 3, 60, 5, 60, 561, 10, 60, 3, 60, 3, 60, 3, 60, 3, 60, 5, 60, 567, 10, 60, 3, 60, 3, 60, 3, 60, 3, 60, 5, 60, 573, 10, 60, 3, 60, 3, 60, 3, 60, 3, 60, 5, 60, 579, 10, 60, 5, 60, 581, 10, 60, 3, 61, 3, 61, 3, 62, 3, 62, 3, 63, 3, 63, 3, 64, 3, 64, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 2, 2, 67, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 2, 9, 4, 2, 25, 26, 28, 28, 3, 2, 38, 39, 3, 2, 43, 53, 7, 2, 21, 21, 40, 44, 47, 47, 49, 49, 51, 67, 3, 2, 45, 53, 7, 2, 47, 47, 49, 49, 51, 53, 57, 58, 61, 62, 3, 2, 73, 77, 2, 603, 2, 133, 3, 2, 2, 2, 4, 137, 3, 2, 2, 2, 6, 141, 3, 2, 2, 2, 8, 153, 3, 2, 2, 2, 10, 173, 3, 2, 2, 2, 12, 175, 3, 2, 2, 2, 14, 206, 3, 2, 2, 2, 16, 209, 3, 2, 2, 2, 18, 213, 3, 2, 2, 2, 20, 222, 3, 2, 2, 2, 22, 229, 3, 2, 2, 2, 24, 231, 3, 2, 2, 2, 26, 241, 3, 2, 2, 2, 28, 247, 3, 2, 2, 2, 30, 250, 3, 2, 2, 2, 32, 257, 3, 2, 2, 2, 34, 270, 3, 2, 2, 2, 36, 272, 3, 2, 2, 2, 38, 283, 3, 2, 2, 2, 40, 288, 3, 2, 2, 2, 42, 292, 3, 2, 2, 2, 44, 296, 3, 2, 2, 2, 46, 298, 3, 2, 2, 2, 48, 307, 3, 2, 2, 2, 50, 315, 3, 2, 2, 2, 52, 323, 3, 2, 2, 2, 54, 330, 3, 2, 2, 2, 56, 332, 3, 2, 2, 2, 58, 340, 3, 2, 2, 2, 60, 342, 3, 2, 2, 2, 62, 350, 3, 2, 2, 2, 64, 358, 3, 2, 2, 2, 66, 364, 3, 2, 2, 2, 68, 366, 3, 2, 2, 2, 70, 373, 3, 2, 2, 2, 72, 375, 3, 2, 2, 2, 74, 384, 3, 2, 2, 2, 76, 393, 3, 2, 2, 2, 78, 402, 3, 2, 2, 2, 80, 411, 3, 2, 2, 2, 82, 420, 3, 2, 2, 2, 84, 427, 3, 2, 2, 2, 86, 434, 3, 2, 2, 2, 88, 442, 3, 2, 2, 2, 90, 459, 3, 2, 2, 2, 92, 463, 3, 2, 2, 2, 94, 475, 3, 2, 2, 2, 96, 479, 3, 2, 2, 2, 98, 481, 3, 2, 2, 2, 100, 491, 3, 2, 2, 2, 102, 493, 3, 2, 2, 2, 104, 506, 3, 2, 2, 2, 106, 508, 3, 2, 2, 2, 108, 513, 3, 2, 2, 2, 110, 515, 3, 2, 2, 2, 112, 530, 3, 2, 2, 2, 114, 536, 3, 2, 2, 2, 116, 538, 3, 2, 2, 2, 118, 580, 3, 2, 2, 2, 120, 582, 3, 2, 2, 2, 122, 584, 3, 2, 2, 2, 124, 586, 3, 2, 2, 2, 126, 588, 3, 2, 2, 2, 128, 590, 3, 2, 2, 2, 130, 592, 3, 2, 2, 2, 132, 134, 5, 4, 3, 2, 133, 132, 3, 2, 2, 2, 134, 135, 3, 2, 2, 2, 135, 133, 3, 2, 2, 2, 135, 136, 3, 2, 2, 2, 136, 3, 3, 2, 2, 2, 137, 138, 5, 6, 4, 2, 138, 139, 5, 8, 5, 2, 139, 140, 7, 3, 2, 2, 140, 5, 3, 2, 2, 2, 141, 142, 7, 4, 2, 2, 142, 147, 7, 68, 2, 2, 143, 144, 7, 5, 2, 2, 144, 145, 5, 10, 6, 2, 145, 146, 7, 6, 2, 2, 146, 148, 3, 2, 2, 2, 147, 143, 3, 2, 2, 2, 147, 148, 3, 2, 2, 2, 148, 149, 3, 2, 2, 2, 149, 150, 7, 7, 2, 2, 150, 7, 3, 2, 2, 2, 151, 154, 5, 52, 27, 2, 152, 154, 5, 18, 10, 2, 153, 151, 3, 2, 2, 2, 153, 152, 3, 2, 2, 2, 154, 155, 3, 2, 2, 2, 155, 153, 3, 2, 2, 2, 155, 156, 3, 2, 2, 2, 156, 9, 3, 2, 2, 2, 157, 162, 5, 12, 7, 2, 158, 159, 7, 8, 2, 2, 159, 161, 5, 12, 7, 2, 160, 158, 3, 2, 2, 2, 161, 164, 3, 2, 2, 2, 162, 160, 3, 2, 2, 2, 162, 163, 3, 2, 2, 2, 163, 174, 3, 2, 2, 2, 164, 162, 3, 2, 2, 2, 165, 170, 5, 14, 8, 2, 166, 167, 7, 8, 2, 2, 167, 169, 5, 14, 8, 2, 168, 166, 3, 2, 2, 2, 169, 172, 3, 2, 2, 2, 170, 168, 3, 2, 2, 2, 170, 171, 3, 2, 2, 2, 171, 174, 3, 2, 2, 2, 172, 170, 3, 2, 2, 2, 173, 157, 3, 2, 2, 2, 173, 165, 3, 2, 2, 2, 174, 11, 3, 2, 2, 2, 175, 177, 7, 68, 2, 2, 176, 178, 5, 98, 50, 2, 177, 176, 3, 2, 2, 2, 177, 178, 3, 2, 2, 2, 178, 13, 3, 2, 2, 2, 179, 180, 7, 9, 2, 2, 180, 185, 5, 16, 9, 2, 181, 182, 7, 8, 2, 2, 182, 184, 5, 16, 9, 2, 183, 181, 3, 2, 2, 2, 184, 187, 3, 2, 2, 2, 185, 183, 3, 2, 2, 2, 185, 186, 3, 2, 2, 2, 186, 207, 3, 2, 2, 2, 187, 185, 3, 2, 2, 2, 188, 189, 7, 10, 2, 2, 189, 194, 5, 16, 9, 2, 190, 191, 7, 8, 2, 2, 191, 193, 5, 16, 9, 2, 192, 190, 3, 2, 2, 2, 193, 196, 3, 2, 2, 2, 194, 192, 3, 2, 2, 2, 194, 195, 3, 2, 2, 2, 195, 207, 3, 2, 2, 2, 196, 194, 3, 2, 2, 2, 197, 198, 7, 11, 2, 2, 198, 203, 5, 16, 9, 2, 199, 200, 7, 8, 2, 2, 200, 202, 5, 16, 9, 2, 201, 199, 3, 2, 2, 2, 202, 205, 3, 2, 2, 2, 203, 201, 3, 2, 2, 2, 203, 204, 3, 2, 2, 2, 204, 207, 3, 2, 2, 2, 205, 203, 3, 2, 2, 2, 206, 179, 3, 2, 2, 2, 206, 188, 3, 2, 2, 2, 206, 197, 3, 2, 2, 2, 207, 15, 3, 2, 2, 2, 208, 210, 5, 98, 50, 2, 209, 208, 3, 2, 2, 2, 209, 210, 3, 2, 2, 2, 210, 211, 3, 2, 2, 2, 211, 212, 7, 68, 2, 2, 212, 17, 3, 2, 2, 2, 213, 214, 7, 12, 2, 2, 214, 215, 7, 5, 2, 2, 215, 216, 5, 48, 25, 2, 216, 217, 7, 6, 2, 2, 217, 218, 7, 13, 2, 2, 218, 219, 5, 20, 11, 2, 219, 220, 7, 14, 2, 2, 220, 19, 3, 2, 2, 2, 221, 223, 5, 22, 12, 2, 222, 221, 3, 2, 2, 2, 223, 224, 3, 2, 2, 2, 224, 222, 3, 2, 2, 2, 224, 225, 3, 2, 2, 2, 225, 21, 3, 2, 2, 2, 226, 230, 5, 46, 24, 2, 227, 230, 5, 36, 19, 2, 228, 230, 5, 24, 13, 2, 229, 226, 3, 2, 2, 2, 229, 227, 3, 2, 2, 2, 229, 228, 3, 2, 2, 2, 230, 23, 3, 2, 2, 2, 231, 235, 5, 26, 14, 2, 232, 234, 5, 30, 16, 2, 233, 232, 3, 2, 2, 2, 234, 237, 3, 2, 2, 2, 235, 233, 3, 2, 2, 2, 235, 236, 3, 2, 2, 2, 236, 239, 3, 2, 2, 2, 237, 235, 3, 2, 2, 2, 238, 240, 5, 28, 15, 2, 239, 238, 3, 2, 2, 2, 239, 240, 3, 2, 2, 2, 240, 25, 3, 2, 2, 2, 241, 242, 7, 15, 2, 2, 242, 243, 7, 5, 2, 2, 243, 244, 5, 32, 17, 2, 244, 245, 7, 6, 2, 2, 245, 246, 5, 34, 18, 2, 246, 27, 3, 2, 2, 2, 247, 248, 7, 16, 2, 2, 248, 249, 5, 34, 18, 2, 249, 29, 3, 2, 2, 2, 250, 251, 7, 16, 2, 2, 251, 252, 7, 15, 2, 2, 252, 253, 7, 5, 2, 2, 253, 254, 5, 32, 17, 2, 254, 255, 7, 6, 2, 2, 255, 256, 5, 34, 18, 2, 256, 31, 3, 2, 2, 2, 257, 258, 5, 104, 53, 2, 258, 259, 5, 128, 65, 2, 259, 260, 5, 44, 23, 2, 260, 33, 3, 2, 2, 2, 261, 263, 7, 13, 2, 2, 262, 264, 5, 46, 24, 2, 263, 262, 3, 2, 2, 2, 264, 265, 3, 2, 2, 2, 265, 263, 3, 2, 2, 2, 265, 266, 3, 2, 2, 2, 266, 267, 3, 2, 2, 2, 267, 268, 7, 14, 2, 2, 268, 271, 3, 2, 2, 2, 269, 271, 5, 46, 24, 2, 270, 261, 3, 2, 2, 2, 270, 269, 3, 2, 2, 2, 271, 35, 3, 2, 2, 2, 272, 274, 5, 38, 20, 2, 273, 275, 5, 40, 21, 2, 274, 273, 3, 2, 2, 2, 275, 276, 3, 2, 2, 2, 276, 274, 3, 2, 2, 2, 276, 277, 3, 2, 2, 2, 277, 279, 3, 2, 2, 2, 278, 280, 5, 42, 22, 2, 279, 278, 3, 2, 2, 2, 279, 280, 3, 2, 2, 2, 280, 281, 3, 2, 2, 2, 281, 282, 7, 17, 2, 2, 282, 37, 3, 2, 2, 2, 283, 284, 7, 18, 2, 2, 284, 285, 7, 5, 2, 2, 285, 286, 5, 104, 53, 2, 286, 287, 7, 6, 2, 2, 287, 39, 3, 2, 2, 2, 288, 289, 5, 44, 23, 2, 289, 290, 7, 19, 2, 2, 290, 291, 5, 34, 18, 2, 291, 41, 3, 2, 2, 2, 292, 293, 7, 20, 2, 2, 293, 294, 7, 19, 2, 2, 294, 295, 5, 34, 18, 2, 295, 43, 3, 2, 2, 2, 296, 297, 5, 130, 66, 2, 297, 45, 3, 2, 2, 2, 298, 299, 5, 104, 53, 2, 299, 303, 7, 21, 2, 2, 300, 304, 5, 130, 66, 2, 301, 304, 5, 100, 51, 2, 302, 304, 5, 88, 45, 2, 303, 300, 3, 2, 2, 2, 303, 301, 3, 2, 2, 2, 303, 302, 3, 2, 2, 2, 304, 305, 3, 2, 2, 2, 305, 306, 7, 7, 2, 2, 306, 47, 3, 2, 2, 2, 307, 312, 5, 50, 26, 2, 308, 309, 7, 8, 2, 2, 309, 311, 5, 50, 26, 2, 310, 308, 3, 2, 2, 2, 311, 314, 3, 2, 2, 2, 312, 310, 3, 2, 2, 2, 312, 313, 3, 2, 2, 2, 313, 49, 3, 2, 2, 2, 314, 312, 3, 2, 2, 2, 315, 317, 7, 68, 2, 2, 316, 318, 5, 98, 50, 2, 317, 316, 3, 2, 2, 2, 317, 318, 3, 2, 2, 2, 318, 51, 3, 2, 2, 2, 319, 320, 5, 54, 28, 2, 320, 321, 7, 7, 2, 2, 321, 324, 3, 2, 2, 2, 322, 324, 5, 108, 55, 2, 323, 319, 3, 2, 2, 2, 323, 322, 3, 2, 2, 2, 324, 53, 3, 2, 2, 2, 325, 331, 5, 106, 54, 2, 326, 331, 5, 82, 42, 2, 327, 331, 5, 70, 36, 2, 328, 331, 5, 84, 43, 2, 329, 331, 5, 56, 29, 2, 330, 325, 3, 2, 2, 2, 330, 326, 3, 2, 2, 2, 330, 327, 3, 2, 2, 2, 330, 328, 3, 2, 2, 2, 330, 329, 3, 2, 2, 2, 331, 55, 3, 2, 2, 2, 332, 333, 5, 68, 35, 2, 333, 334, 5, 66, 34, 2, 334, 335, 7, 5, 2, 2, 335, 336, 5, 58, 30, 2, 336, 337, 7, 6, 2, 2, 337, 57, 3, 2, 2, 2, 338, 341, 5, 60, 31, 2, 339, 341, 5, 62, 32, 2, 340, 338, 3, 2, 2, 2, 340, 339, 3, 2, 2, 2, 341, 59, 3, 2, 2, 2, 342, 347, 5, 12, 7, 2, 343, 344, 7, 8, 2, 2, 344, 346, 5, 12, 7, 2, 345, 343, 3, 2, 2, 2, 346, 349, 3, 2, 2, 2, 347, 345, 3, 2, 2, 2, 347, 348, 3, 2, 2, 2, 348, 61, 3, 2, 2, 2, 349, 347, 3, 2, 2, 2, 350, 355, 5, 64, 33, 2, 351, 352, 7, 8, 2, 2, 352, 354, 5, 64, 33, 2, 353, 351, 3, 2, 2, 2, 354, 357, 3, 2, 2, 2, 355, 353, 3, 2, 2, 2, 355, 356, 3, 2, 2, 2, 356, 63, 3, 2, 2, 2, 357, 355, 3, 2, 2, 2, 358, 359, 7, 22, 2, 2, 359, 360, 7, 68, 2, 2, 360, 361, 7, 5, 2, 2, 361, 362, 5, 100, 51, 2, 362, 363, 7, 6, 2, 2, 363, 65, 3, 2, 2, 2, 364, 365, 7, 68, 2, 2, 365, 67, 3, 2, 2, 2, 366, 367, 7, 68, 2, 2, 367, 69, 3, 2, 2, 2, 368, 374, 5, 74, 38, 2, 369, 374, 5, 76, 39, 2, 370, 374, 5, 80, 41, 2, 371, 374, 5, 72, 37, 2, 372, 374, 5, 78, 40, 2, 373, 368, 3, 2, 2, 2, 373, 369, 3, 2, 2, 2, 373, 370, 3, 2, 2, 2, 373, 371, 3, 2, 2, 2, 373, 372, 3, 2, 2, 2, 374, 71, 3, 2, 2, 2, 375, 376, 7, 23, 2, 2, 376, 381, 5, 16, 9, 2, 377, 378, 7, 8, 2, 2, 378, 380, 5, 16, 9, 2, 379, 377, 3, 2, 2, 2, 380, 383, 3, 2, 2, 2, 381, 379, 3, 2, 2, 2, 381, 382, 3, 2, 2, 2, 382, 73, 3, 2, 2, 2, 383, 381, 3, 2, 2, 2, 384, 385, 7, 24, 2, 2, 385, 390, 5, 16, 9, 2, 386, 387, 7, 8, 2, 2, 387, 389, 5, 16, 9, 2, 388, 386, 3, 2, 2, 2, 389, 392, 3, 2, 2, 2, 390, 388, 3, 2, 2, 2, 390, 391, 3, 2, 2, 2, 391, 75, 3, 2, 2, 2, 392, 390, 3, 2, 2, 2, 393, 394, 7, 25, 2, 2, 394, 399, 5, 16, 9, 2, 395, 396, 7, 8, 2, 2, 396, 398, 5, 16, 9, 2, 397, 395, 3, 2, 2, 2, 398, 401, 3, 2, 2, 2, 399, 397, 3, 2, 2, 2, 399, 400, 3, 2, 2, 2, 400, 77, 3, 2, 2, 2, 401, 399, 3, 2, 2, 2, 402, 403, 7, 26, 2, 2, 403, 408, 5, 16, 9, 2, 404, 405, 7, 8, 2, 2, 405, 407, 5, 16, 9, 2, 406, 404, 3, 2, 2, 2, 407, 410, 3, 2, 2, 2, 408, 406, 3, 2, 2, 2, 408, 409, 3, 2, 2, 2, 409, 79, 3, 2, 2, 2, 410, 408, 3, 2, 2, 2, 411, 412, 7, 27, 2, 2, 412, 417, 5, 84, 43, 2, 413, 414, 7, 8, 2, 2, 414, 416, 5, 84, 43, 2, 415, 413, 3, 2, 2, 2, 416, 419, 3, 2, 2, 2, 417, 415, 3, 2, 2, 2, 417, 418, 3, 2, 2, 2, 418, 81, 3, 2, 2, 2, 419, 417, 3, 2, 2, 2, 420, 421, 7, 28, 2, 2, 421, 422, 5, 104, 53, 2, 422, 425, 7, 29, 2, 2, 423, 426, 5, 86, 44, 2, 424, 426, 5, 88, 45, 2, 425, 423, 3, 2, 2, 2, 425, 424, 3, 2, 2, 2, 426, 83, 3, 2, 2, 2, 427, 428, 7, 68, 2, 2, 428, 431, 7, 29, 2, 2, 429, 432, 5, 86, 44, 2, 430, 432, 5, 88, 45, 2, 431, 429, 3, 2, 2, 2, 431, 430, 3, 2, 2, 2, 432, 85, 3, 2, 2, 2, 433, 435, 5, 122, 62, 2, 434, 433, 3, 2, 2, 2, 434, 435, 3, 2, 2, 2, 435, 436, 3, 2, 2, 2, 436, 437, 7, 5, 2, 2, 437, 438, 5, 88, 45, 2, 438, 439, 7, 6, 2, 2, 439, 87, 3, 2, 2, 2, 440, 443, 5, 86, 44, 2, 441, 443, 5, 90, 46, 2, 442, 440, 3, 2, 2, 2, 442, 441, 3, 2, 2, 2, 443, 451, 3, 2, 2, 2, 444, 447, 5, 124, 63, 2, 445, 448, 5, 86, 44, 2, 446, 448, 5, 90, 46, 2, 447, 445, 3, 2, 2, 2, 447, 446, 3, 2, 2, 2, 448, 450, 3, 2, 2, 2, 449, 444, 3, 2, 2, 2, 450, 453, 3, 2, 2, 2, 451, 449, 3, 2, 2, 2, 451, 452, 3, 2, 2, 2, 452, 89, 3, 2, 2, 2, 453, 451, 3, 2, 2, 2, 454, 456, 5, 122, 62, 2, 455, 454, 3, 2, 2, 2, 455, 456, 3, 2, 2, 2, 456, 457, 3, 2, 2, 2, 457, 460, 5, 100, 51, 2, 458, 460, 5, 130, 66, 2, 459, 455, 3, 2, 2, 2, 459, 458, 3, 2, 2, 2, 460, 91, 3, 2, 2, 2, 461, 464, 5, 86, 44, 2, 462, 464, 5, 90, 46, 2, 463, 461, 3, 2, 2, 2, 463, 462, 3, 2, 2, 2, 464, 472, 3, 2, 2, 2, 465, 468, 5, 124, 63, 2, 466, 469, 5, 86, 44, 2, 467, 469, 5, 90, 46, 2, 468, 466, 3, 2, 2, 2, 468, 467, 3, 2, 2, 2, 469, 471, 3, 2, 2, 2, 470, 465, 3, 2, 2, 2, 471, 474, 3, 2, 2, 2, 472, 470, 3, 2, 2, 2, 472, 473, 3, 2, 2, 2, 473, 93, 3, 2, 2, 2, 474, 472, 3, 2, 2, 2, 475, 476, 5, 92, 47, 2, 476, 477, 5, 128, 65, 2, 477, 478, 5, 96, 49, 2, 478, 95, 3, 2, 2, 2, 479, 480, 5, 130, 66, 2, 480, 97, 3, 2, 2, 2, 481, 482, 7, 30, 2, 2, 482, 485, 7, 74, 2, 2, 483, 484, 7, 19, 2, 2, 484, 486, 7, 74, 2, 2, 485, 483, 3, 2, 2, 2, 485, 486, 3, 2, 2, 2, 486, 487, 3, 2, 2, 2, 487, 488, 7, 31, 2, 2, 488, 99, 3, 2, 2, 2, 489, 492, 5, 12, 7, 2, 490, 492, 5, 102, 52, 2, 491, 489, 3, 2, 2, 2, 491, 490, 3, 2, 2, 2, 492, 101, 3, 2, 2, 2, 493, 494, 7, 32, 2, 2, 494, 499, 5, 12, 7, 2, 495, 496, 7, 8, 2, 2, 496, 498, 5, 12, 7, 2, 497, 495, 3, 2, 2, 2, 498, 501, 3, 2, 2, 2, 499, 497, 3, 2, 2, 2, 499, 500, 3, 2, 2, 2, 500, 502, 3, 2, 2, 2, 501, 499, 3, 2, 2, 2, 502, 504, 7, 33, 2, 2, 503, 505, 5, 98, 50, 2, 504, 503, 3, 2, 2, 2, 504, 505, 3, 2, 2, 2, 505, 103, 3, 2, 2, 2, 506, 507, 5, 100, 51, 2, 507, 105, 3, 2, 2, 2, 508, 509, 5, 14, 8, 2, 509, 107, 3, 2, 2, 2, 510, 514, 5, 116, 59, 2, 511, 514, 5, 110, 56, 2, 512, 514, 5, 112, 57, 2, 513, 510, 3, 2, 2, 2, 513, 511, 3, 2, 2, 2, 513, 512, 3, 2, 2, 2, 514, 109, 3, 2, 2, 2, 515, 516, 7, 34, 2, 2, 516, 518, 7, 35, 2, 2, 517, 519, 7, 68, 2, 2, 518, 517, 3, 2, 2, 2, 519, 520, 3, 2, 2, 2, 520, 518, 3, 2, 2, 2, 520, 521, 3, 2, 2, 2, 521, 522, 3, 2, 2, 2, 522, 523, 7, 35, 2, 2, 523, 526, 7, 35, 2, 2, 524, 527, 5, 114, 58, 2, 525, 527, 9, 2, 2, 2, 526, 524, 3, 2, 2, 2, 526, 525, 3, 2, 2, 2, 527, 528, 3, 2, 2, 2, 528, 529, 7, 35, 2, 2, 529, 111, 3, 2, 2, 2, 530, 531, 7, 36, 2, 2, 531, 532, 7, 68, 2, 2, 532, 533, 7, 68, 2, 2, 533, 113, 3, 2, 2, 2, 534, 537, 5, 124, 63, 2, 535, 537, 5, 122, 62, 2, 536, 534, 3, 2, 2, 2, 536, 535, 3, 2, 2, 2, 537, 115, 3, 2, 2, 2, 538, 539, 7, 37, 2, 2, 539, 540, 7, 35, 2, 2, 540, 541, 5, 114, 58, 2, 541, 542, 7, 35, 2, 2, 542, 547, 5, 118, 60, 2, 543, 544, 9, 3, 2, 2, 544, 546, 5, 118, 60, 2, 545, 543, 3, 2, 2, 2, 546, 549, 3, 2, 2, 2, 547, 545, 3, 2, 2, 2, 547, 548, 3, 2, 2, 2, 548, 117, 3, 2, 2, 2, 549, 547, 3, 2, 2, 2, 550, 551, 7, 68, 2, 2, 551, 552, 7, 29, 2, 2, 552, 554, 5, 130, 66, 2, 553, 555, 5, 120, 61, 2, 554, 553, 3, 2, 2, 2, 554, 555, 3, 2, 2, 2, 555, 581, 3, 2, 2, 2, 556, 557, 7, 68, 2, 2, 557, 558, 7, 40, 2, 2, 558, 560, 5, 130, 66, 2, 559, 561, 5, 120, 61, 2, 560, 559, 3, 2, 2, 2, 560, 561, 3, 2, 2, 2, 561, 581, 3, 2, 2, 2, 562, 563, 7, 68, 2, 2, 563, 564, 7, 41, 2, 2, 564, 566, 5, 130, 66, 2, 565, 567, 5, 120, 61, 2, 566, 565, 3, 2, 2, 2, 566, 567, 3, 2, 2, 2, 567, 581, 3, 2, 2, 2, 568, 569, 7, 68, 2, 2, 569, 570, 7, 42, 2, 2, 570, 572, 5, 130, 66, 2, 571, 573, 5, 120, 61, 2, 572, 571, 3, 2, 2, 2, 572, 573, 3, 2, 2, 2, 573, 581, 3, 2, 2, 2, 574, 575, 7, 68, 2, 2, 575, 576, 7, 21, 2, 2, 576, 578, 5, 130, 66, 2, 577, 579, 5, 120, 61, 2, 578, 577, 3, 2, 2, 2, 578, 579, 3, 2, 2, 2, 579, 581, 3, 2, 2, 2, 580, 550, 3, 2, 2, 2, 580, 556, 3, 2, 2, 2, 580, 562, 3, 2, 2, 2, 580, 568, 3, 2, 2, 2, 580, 574, 3, 2, 2, 2, 581, 119, 3, 2, 2, 2, 582, 583, 7, 68, 2, 2, 583, 121, 3, 2, 2, 2, 584, 585, 9, 4, 2, 2, 585, 123, 3, 2, 2, 2, 586, 587, 9, 5, 2, 2, 587, 125, 3, 2, 2, 2, 588, 589, 9, 6, 2, 2, 589, 127, 3, 2, 2, 2, 590, 591, 9, 7, 2, 2, 591, 129, 3, 2, 2, 2, 592, 593, 9, 8, 2, 2, 593, 131, 3, 2, 2, 2, 63, 135, 147, 153, 155, 162, 170, 173, 177, 185, 194, 203, 206, 209, 224, 229, 235, 239, 265, 270, 276, 279, 303, 312, 317, 323, 330, 340, 347, 355, 373, 381, 390, 399, 408, 417, 425, 431, 434, 442, 447, 451, 455, 459, 463, 468, 472, 485, 491, 499, 504, 513, 520, 526, 536, 547, 554, 560, 566, 572, 578, 580]
\ No newline at end of file
diff --git a/lfr/antlrgen/lfrXLexer.interp b/lfr/antlrgen/lfrXLexer.interp
deleted file mode 100755
index 8635d76..0000000
--- a/lfr/antlrgen/lfrXLexer.interp
+++ /dev/null
@@ -1,260 +0,0 @@
-token literal names:
-null
-'endmodule'
-'module'
-'('
-')'
-';'
-','
-'finput'
-'foutput'
-'control'
-'distribute@'
-'begin'
-'end'
-'if'
-'else'
-'endcase'
-'case'
-':'
-'default'
-'<='
-'.'
-'signal'
-'flow'
-'storage'
-'pump'
-'number'
-'assign'
-'='
-'['
-']'
-'{'
-'}'
-'#MAP'
-'"'
-'#MATERIAL'
-'#CONSTRAIN'
-'AND'
-'OR'
-'>'
-'<'
-'>='
-'+'
-'-'
-'!'
-'~'
-'&'
-'~&'
-'|'
-'~|'
-'^'
-'~^'
-'^~'
-'*'
-'/'
-'%'
-'=='
-'!='
-'==='
-'!=='
-'&&'
-'||'
-'**'
-'>>'
-'<<'
-'>>>'
-'<<<'
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-
-token symbolic names:
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-null
-ID
-WS
-One_line_comment
-Block_comment
-Import_line
-Real_number
-Decimal_number
-Binary_number
-Octal_number
-Hex_number
-
-rule names:
-T__0
-T__1
-T__2
-T__3
-T__4
-T__5
-T__6
-T__7
-T__8
-T__9
-T__10
-T__11
-T__12
-T__13
-T__14
-T__15
-T__16
-T__17
-T__18
-T__19
-T__20
-T__21
-T__22
-T__23
-T__24
-T__25
-T__26
-T__27
-T__28
-T__29
-T__30
-T__31
-T__32
-T__33
-T__34
-T__35
-T__36
-T__37
-T__38
-T__39
-T__40
-T__41
-T__42
-T__43
-T__44
-T__45
-T__46
-T__47
-T__48
-T__49
-T__50
-T__51
-T__52
-T__53
-T__54
-T__55
-T__56
-T__57
-T__58
-T__59
-T__60
-T__61
-T__62
-T__63
-T__64
-ID
-WS
-One_line_comment
-Block_comment
-Import_line
-Real_number
-Decimal_number
-Binary_number
-Octal_number
-Hex_number
-Sign
-Size
-Non_zero_unsigned_number
-Unsigned_number
-Binary_value
-Octal_value
-Hex_value
-Decimal_base
-Binary_base
-Octal_base
-Hex_base
-Non_zero_decimal_digit
-Decimal_digit
-Binary_digit
-Octal_digit
-Hex_digit
-X_digit
-Z_digit
-
-channel names:
-DEFAULT_TOKEN_CHANNEL
-HIDDEN
-
-mode names:
-DEFAULT_MODE
-
-atn:
-[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 77, 670, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 43, 3, 43, 3, 44, 3, 44, 3, 45, 3, 45, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 54, 3, 54, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 3, 66, 3, 67, 3, 67, 7, 67, 458, 10, 67, 12, 67, 14, 67, 461, 11, 67, 3, 68, 6, 68, 464, 10, 68, 13, 68, 14, 68, 465, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 7, 69, 474, 10, 69, 12, 69, 14, 69, 477, 11, 69, 3, 69, 5, 69, 480, 10, 69, 3, 69, 3, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 7, 70, 490, 10, 70, 12, 70, 14, 70, 493, 11, 70, 3, 70, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 7, 71, 502, 10, 71, 12, 71, 14, 71, 505, 11, 71, 3, 71, 5, 71, 508, 10, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 5, 72, 521, 10, 72, 3, 72, 3, 72, 5, 72, 525, 10, 72, 3, 72, 3, 72, 5, 72, 529, 10, 72, 3, 73, 3, 73, 5, 73, 533, 10, 73, 3, 73, 3, 73, 3, 73, 3, 73, 5, 73, 539, 10, 73, 3, 73, 3, 73, 3, 73, 7, 73, 544, 10, 73, 12, 73, 14, 73, 547, 11, 73, 3, 73, 5, 73, 550, 10, 73, 3, 73, 3, 73, 3, 73, 7, 73, 555, 10, 73, 12, 73, 14, 73, 558, 11, 73, 5, 73, 560, 10, 73, 3, 74, 5, 74, 563, 10, 74, 3, 74, 3, 74, 3, 74, 3, 75, 5, 75, 569, 10, 75, 3, 75, 3, 75, 3, 75, 3, 76, 5, 76, 575, 10, 76, 3, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 7, 79, 587, 10, 79, 12, 79, 14, 79, 590, 11, 79, 3, 80, 3, 80, 3, 80, 7, 80, 595, 10, 80, 12, 80, 14, 80, 598, 11, 80, 3, 81, 3, 81, 3, 81, 7, 81, 603, 10, 81, 12, 81, 14, 81, 606, 11, 81, 3, 82, 3, 82, 3, 82, 7, 82, 611, 10, 82, 12, 82, 14, 82, 614, 11, 82, 3, 83, 3, 83, 3, 83, 7, 83, 619, 10, 83, 12, 83, 14, 83, 622, 11, 83, 3, 84, 3, 84, 5, 84, 626, 10, 84, 3, 84, 3, 84, 3, 85, 3, 85, 5, 85, 632, 10, 85, 3, 85, 3, 85, 3, 86, 3, 86, 5, 86, 638, 10, 86, 3, 86, 3, 86, 3, 87, 3, 87, 5, 87, 644, 10, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 89, 3, 89, 3, 90, 3, 90, 3, 90, 5, 90, 655, 10, 90, 3, 91, 3, 91, 3, 91, 5, 91, 660, 10, 91, 3, 92, 3, 92, 3, 92, 5, 92, 665, 10, 92, 3, 93, 3, 93, 3, 94, 3, 94, 5, 475, 491, 503, 2, 95, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, 67, 35, 69, 36, 71, 37, 73, 38, 75, 39, 77, 40, 79, 41, 81, 42, 83, 43, 85, 44, 87, 45, 89, 46, 91, 47, 93, 48, 95, 49, 97, 50, 99, 51, 101, 52, 103, 53, 105, 54, 107, 55, 109, 56, 111, 57, 113, 58, 115, 59, 117, 60, 119, 61, 121, 62, 123, 63, 125, 64, 127, 65, 129, 66, 131, 67, 133, 68, 135, 69, 137, 70, 139, 71, 141, 72, 143, 73, 145, 74, 147, 75, 149, 76, 151, 77, 153, 2, 155, 2, 157, 2, 159, 2, 161, 2, 163, 2, 165, 2, 167, 2, 169, 2, 171, 2, 173, 2, 175, 2, 177, 2, 179, 2, 181, 2, 183, 2, 185, 2, 187, 2, 3, 2, 19, 5, 2, 67, 92, 97, 97, 99, 124, 6, 2, 50, 59, 67, 92, 97, 97, 99, 124, 5, 2, 11, 12, 15, 15, 34, 34, 4, 2, 71, 71, 103, 103, 4, 2, 45, 45, 47, 47, 4, 2, 85, 85, 117, 117, 4, 2, 70, 70, 102, 102, 4, 2, 68, 68, 100, 100, 4, 2, 81, 81, 113, 113, 4, 2, 74, 74, 106, 106, 3, 2, 51, 59, 3, 2, 50, 59, 3, 2, 50, 51, 3, 2, 50, 57, 5, 2, 50, 59, 67, 72, 99, 104, 4, 2, 90, 90, 122, 122, 5, 2, 65, 65, 92, 92, 124, 124, 2, 692, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2, 2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3, 2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 2, 87, 3, 2, 2, 2, 2, 89, 3, 2, 2, 2, 2, 91, 3, 2, 2, 2, 2, 93, 3, 2, 2, 2, 2, 95, 3, 2, 2, 2, 2, 97, 3, 2, 2, 2, 2, 99, 3, 2, 2, 2, 2, 101, 3, 2, 2, 2, 2, 103, 3, 2, 2, 2, 2, 105, 3, 2, 2, 2, 2, 107, 3, 2, 2, 2, 2, 109, 3, 2, 2, 2, 2, 111, 3, 2, 2, 2, 2, 113, 3, 2, 2, 2, 2, 115, 3, 2, 2, 2, 2, 117, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2, 2, 2, 2, 123, 3, 2, 2, 2, 2, 125, 3, 2, 2, 2, 2, 127, 3, 2, 2, 2, 2, 129, 3, 2, 2, 2, 2, 131, 3, 2, 2, 2, 2, 133, 3, 2, 2, 2, 2, 135, 3, 2, 2, 2, 2, 137, 3, 2, 2, 2, 2, 139, 3, 2, 2, 2, 2, 141, 3, 2, 2, 2, 2, 143, 3, 2, 2, 2, 2, 145, 3, 2, 2, 2, 2, 147, 3, 2, 2, 2, 2, 149, 3, 2, 2, 2, 2, 151, 3, 2, 2, 2, 3, 189, 3, 2, 2, 2, 5, 199, 3, 2, 2, 2, 7, 206, 3, 2, 2, 2, 9, 208, 3, 2, 2, 2, 11, 210, 3, 2, 2, 2, 13, 212, 3, 2, 2, 2, 15, 214, 3, 2, 2, 2, 17, 221, 3, 2, 2, 2, 19, 229, 3, 2, 2, 2, 21, 237, 3, 2, 2, 2, 23, 249, 3, 2, 2, 2, 25, 255, 3, 2, 2, 2, 27, 259, 3, 2, 2, 2, 29, 262, 3, 2, 2, 2, 31, 267, 3, 2, 2, 2, 33, 275, 3, 2, 2, 2, 35, 280, 3, 2, 2, 2, 37, 282, 3, 2, 2, 2, 39, 290, 3, 2, 2, 2, 41, 293, 3, 2, 2, 2, 43, 295, 3, 2, 2, 2, 45, 302, 3, 2, 2, 2, 47, 307, 3, 2, 2, 2, 49, 315, 3, 2, 2, 2, 51, 320, 3, 2, 2, 2, 53, 327, 3, 2, 2, 2, 55, 334, 3, 2, 2, 2, 57, 336, 3, 2, 2, 2, 59, 338, 3, 2, 2, 2, 61, 340, 3, 2, 2, 2, 63, 342, 3, 2, 2, 2, 65, 344, 3, 2, 2, 2, 67, 349, 3, 2, 2, 2, 69, 351, 3, 2, 2, 2, 71, 361, 3, 2, 2, 2, 73, 372, 3, 2, 2, 2, 75, 376, 3, 2, 2, 2, 77, 379, 3, 2, 2, 2, 79, 381, 3, 2, 2, 2, 81, 383, 3, 2, 2, 2, 83, 386, 3, 2, 2, 2, 85, 388, 3, 2, 2, 2, 87, 390, 3, 2, 2, 2, 89, 392, 3, 2, 2, 2, 91, 394, 3, 2, 2, 2, 93, 396, 3, 2, 2, 2, 95, 399, 3, 2, 2, 2, 97, 401, 3, 2, 2, 2, 99, 404, 3, 2, 2, 2, 101, 406, 3, 2, 2, 2, 103, 409, 3, 2, 2, 2, 105, 412, 3, 2, 2, 2, 107, 414, 3, 2, 2, 2, 109, 416, 3, 2, 2, 2, 111, 418, 3, 2, 2, 2, 113, 421, 3, 2, 2, 2, 115, 424, 3, 2, 2, 2, 117, 428, 3, 2, 2, 2, 119, 432, 3, 2, 2, 2, 121, 435, 3, 2, 2, 2, 123, 438, 3, 2, 2, 2, 125, 441, 3, 2, 2, 2, 127, 444, 3, 2, 2, 2, 129, 447, 3, 2, 2, 2, 131, 451, 3, 2, 2, 2, 133, 455, 3, 2, 2, 2, 135, 463, 3, 2, 2, 2, 137, 469, 3, 2, 2, 2, 139, 485, 3, 2, 2, 2, 141, 499, 3, 2, 2, 2, 143, 528, 3, 2, 2, 2, 145, 559, 3, 2, 2, 2, 147, 562, 3, 2, 2, 2, 149, 568, 3, 2, 2, 2, 151, 574, 3, 2, 2, 2, 153, 579, 3, 2, 2, 2, 155, 581, 3, 2, 2, 2, 157, 583, 3, 2, 2, 2, 159, 591, 3, 2, 2, 2, 161, 599, 3, 2, 2, 2, 163, 607, 3, 2, 2, 2, 165, 615, 3, 2, 2, 2, 167, 623, 3, 2, 2, 2, 169, 629, 3, 2, 2, 2, 171, 635, 3, 2, 2, 2, 173, 641, 3, 2, 2, 2, 175, 647, 3, 2, 2, 2, 177, 649, 3, 2, 2, 2, 179, 654, 3, 2, 2, 2, 181, 659, 3, 2, 2, 2, 183, 664, 3, 2, 2, 2, 185, 666, 3, 2, 2, 2, 187, 668, 3, 2, 2, 2, 189, 190, 7, 103, 2, 2, 190, 191, 7, 112, 2, 2, 191, 192, 7, 102, 2, 2, 192, 193, 7, 111, 2, 2, 193, 194, 7, 113, 2, 2, 194, 195, 7, 102, 2, 2, 195, 196, 7, 119, 2, 2, 196, 197, 7, 110, 2, 2, 197, 198, 7, 103, 2, 2, 198, 4, 3, 2, 2, 2, 199, 200, 7, 111, 2, 2, 200, 201, 7, 113, 2, 2, 201, 202, 7, 102, 2, 2, 202, 203, 7, 119, 2, 2, 203, 204, 7, 110, 2, 2, 204, 205, 7, 103, 2, 2, 205, 6, 3, 2, 2, 2, 206, 207, 7, 42, 2, 2, 207, 8, 3, 2, 2, 2, 208, 209, 7, 43, 2, 2, 209, 10, 3, 2, 2, 2, 210, 211, 7, 61, 2, 2, 211, 12, 3, 2, 2, 2, 212, 213, 7, 46, 2, 2, 213, 14, 3, 2, 2, 2, 214, 215, 7, 104, 2, 2, 215, 216, 7, 107, 2, 2, 216, 217, 7, 112, 2, 2, 217, 218, 7, 114, 2, 2, 218, 219, 7, 119, 2, 2, 219, 220, 7, 118, 2, 2, 220, 16, 3, 2, 2, 2, 221, 222, 7, 104, 2, 2, 222, 223, 7, 113, 2, 2, 223, 224, 7, 119, 2, 2, 224, 225, 7, 118, 2, 2, 225, 226, 7, 114, 2, 2, 226, 227, 7, 119, 2, 2, 227, 228, 7, 118, 2, 2, 228, 18, 3, 2, 2, 2, 229, 230, 7, 101, 2, 2, 230, 231, 7, 113, 2, 2, 231, 232, 7, 112, 2, 2, 232, 233, 7, 118, 2, 2, 233, 234, 7, 116, 2, 2, 234, 235, 7, 113, 2, 2, 235, 236, 7, 110, 2, 2, 236, 20, 3, 2, 2, 2, 237, 238, 7, 102, 2, 2, 238, 239, 7, 107, 2, 2, 239, 240, 7, 117, 2, 2, 240, 241, 7, 118, 2, 2, 241, 242, 7, 116, 2, 2, 242, 243, 7, 107, 2, 2, 243, 244, 7, 100, 2, 2, 244, 245, 7, 119, 2, 2, 245, 246, 7, 118, 2, 2, 246, 247, 7, 103, 2, 2, 247, 248, 7, 66, 2, 2, 248, 22, 3, 2, 2, 2, 249, 250, 7, 100, 2, 2, 250, 251, 7, 103, 2, 2, 251, 252, 7, 105, 2, 2, 252, 253, 7, 107, 2, 2, 253, 254, 7, 112, 2, 2, 254, 24, 3, 2, 2, 2, 255, 256, 7, 103, 2, 2, 256, 257, 7, 112, 2, 2, 257, 258, 7, 102, 2, 2, 258, 26, 3, 2, 2, 2, 259, 260, 7, 107, 2, 2, 260, 261, 7, 104, 2, 2, 261, 28, 3, 2, 2, 2, 262, 263, 7, 103, 2, 2, 263, 264, 7, 110, 2, 2, 264, 265, 7, 117, 2, 2, 265, 266, 7, 103, 2, 2, 266, 30, 3, 2, 2, 2, 267, 268, 7, 103, 2, 2, 268, 269, 7, 112, 2, 2, 269, 270, 7, 102, 2, 2, 270, 271, 7, 101, 2, 2, 271, 272, 7, 99, 2, 2, 272, 273, 7, 117, 2, 2, 273, 274, 7, 103, 2, 2, 274, 32, 3, 2, 2, 2, 275, 276, 7, 101, 2, 2, 276, 277, 7, 99, 2, 2, 277, 278, 7, 117, 2, 2, 278, 279, 7, 103, 2, 2, 279, 34, 3, 2, 2, 2, 280, 281, 7, 60, 2, 2, 281, 36, 3, 2, 2, 2, 282, 283, 7, 102, 2, 2, 283, 284, 7, 103, 2, 2, 284, 285, 7, 104, 2, 2, 285, 286, 7, 99, 2, 2, 286, 287, 7, 119, 2, 2, 287, 288, 7, 110, 2, 2, 288, 289, 7, 118, 2, 2, 289, 38, 3, 2, 2, 2, 290, 291, 7, 62, 2, 2, 291, 292, 7, 63, 2, 2, 292, 40, 3, 2, 2, 2, 293, 294, 7, 48, 2, 2, 294, 42, 3, 2, 2, 2, 295, 296, 7, 117, 2, 2, 296, 297, 7, 107, 2, 2, 297, 298, 7, 105, 2, 2, 298, 299, 7, 112, 2, 2, 299, 300, 7, 99, 2, 2, 300, 301, 7, 110, 2, 2, 301, 44, 3, 2, 2, 2, 302, 303, 7, 104, 2, 2, 303, 304, 7, 110, 2, 2, 304, 305, 7, 113, 2, 2, 305, 306, 7, 121, 2, 2, 306, 46, 3, 2, 2, 2, 307, 308, 7, 117, 2, 2, 308, 309, 7, 118, 2, 2, 309, 310, 7, 113, 2, 2, 310, 311, 7, 116, 2, 2, 311, 312, 7, 99, 2, 2, 312, 313, 7, 105, 2, 2, 313, 314, 7, 103, 2, 2, 314, 48, 3, 2, 2, 2, 315, 316, 7, 114, 2, 2, 316, 317, 7, 119, 2, 2, 317, 318, 7, 111, 2, 2, 318, 319, 7, 114, 2, 2, 319, 50, 3, 2, 2, 2, 320, 321, 7, 112, 2, 2, 321, 322, 7, 119, 2, 2, 322, 323, 7, 111, 2, 2, 323, 324, 7, 100, 2, 2, 324, 325, 7, 103, 2, 2, 325, 326, 7, 116, 2, 2, 326, 52, 3, 2, 2, 2, 327, 328, 7, 99, 2, 2, 328, 329, 7, 117, 2, 2, 329, 330, 7, 117, 2, 2, 330, 331, 7, 107, 2, 2, 331, 332, 7, 105, 2, 2, 332, 333, 7, 112, 2, 2, 333, 54, 3, 2, 2, 2, 334, 335, 7, 63, 2, 2, 335, 56, 3, 2, 2, 2, 336, 337, 7, 93, 2, 2, 337, 58, 3, 2, 2, 2, 338, 339, 7, 95, 2, 2, 339, 60, 3, 2, 2, 2, 340, 341, 7, 125, 2, 2, 341, 62, 3, 2, 2, 2, 342, 343, 7, 127, 2, 2, 343, 64, 3, 2, 2, 2, 344, 345, 7, 37, 2, 2, 345, 346, 7, 79, 2, 2, 346, 347, 7, 67, 2, 2, 347, 348, 7, 82, 2, 2, 348, 66, 3, 2, 2, 2, 349, 350, 7, 36, 2, 2, 350, 68, 3, 2, 2, 2, 351, 352, 7, 37, 2, 2, 352, 353, 7, 79, 2, 2, 353, 354, 7, 67, 2, 2, 354, 355, 7, 86, 2, 2, 355, 356, 7, 71, 2, 2, 356, 357, 7, 84, 2, 2, 357, 358, 7, 75, 2, 2, 358, 359, 7, 67, 2, 2, 359, 360, 7, 78, 2, 2, 360, 70, 3, 2, 2, 2, 361, 362, 7, 37, 2, 2, 362, 363, 7, 69, 2, 2, 363, 364, 7, 81, 2, 2, 364, 365, 7, 80, 2, 2, 365, 366, 7, 85, 2, 2, 366, 367, 7, 86, 2, 2, 367, 368, 7, 84, 2, 2, 368, 369, 7, 67, 2, 2, 369, 370, 7, 75, 2, 2, 370, 371, 7, 80, 2, 2, 371, 72, 3, 2, 2, 2, 372, 373, 7, 67, 2, 2, 373, 374, 7, 80, 2, 2, 374, 375, 7, 70, 2, 2, 375, 74, 3, 2, 2, 2, 376, 377, 7, 81, 2, 2, 377, 378, 7, 84, 2, 2, 378, 76, 3, 2, 2, 2, 379, 380, 7, 64, 2, 2, 380, 78, 3, 2, 2, 2, 381, 382, 7, 62, 2, 2, 382, 80, 3, 2, 2, 2, 383, 384, 7, 64, 2, 2, 384, 385, 7, 63, 2, 2, 385, 82, 3, 2, 2, 2, 386, 387, 7, 45, 2, 2, 387, 84, 3, 2, 2, 2, 388, 389, 7, 47, 2, 2, 389, 86, 3, 2, 2, 2, 390, 391, 7, 35, 2, 2, 391, 88, 3, 2, 2, 2, 392, 393, 7, 128, 2, 2, 393, 90, 3, 2, 2, 2, 394, 395, 7, 40, 2, 2, 395, 92, 3, 2, 2, 2, 396, 397, 7, 128, 2, 2, 397, 398, 7, 40, 2, 2, 398, 94, 3, 2, 2, 2, 399, 400, 7, 126, 2, 2, 400, 96, 3, 2, 2, 2, 401, 402, 7, 128, 2, 2, 402, 403, 7, 126, 2, 2, 403, 98, 3, 2, 2, 2, 404, 405, 7, 96, 2, 2, 405, 100, 3, 2, 2, 2, 406, 407, 7, 128, 2, 2, 407, 408, 7, 96, 2, 2, 408, 102, 3, 2, 2, 2, 409, 410, 7, 96, 2, 2, 410, 411, 7, 128, 2, 2, 411, 104, 3, 2, 2, 2, 412, 413, 7, 44, 2, 2, 413, 106, 3, 2, 2, 2, 414, 415, 7, 49, 2, 2, 415, 108, 3, 2, 2, 2, 416, 417, 7, 39, 2, 2, 417, 110, 3, 2, 2, 2, 418, 419, 7, 63, 2, 2, 419, 420, 7, 63, 2, 2, 420, 112, 3, 2, 2, 2, 421, 422, 7, 35, 2, 2, 422, 423, 7, 63, 2, 2, 423, 114, 3, 2, 2, 2, 424, 425, 7, 63, 2, 2, 425, 426, 7, 63, 2, 2, 426, 427, 7, 63, 2, 2, 427, 116, 3, 2, 2, 2, 428, 429, 7, 35, 2, 2, 429, 430, 7, 63, 2, 2, 430, 431, 7, 63, 2, 2, 431, 118, 3, 2, 2, 2, 432, 433, 7, 40, 2, 2, 433, 434, 7, 40, 2, 2, 434, 120, 3, 2, 2, 2, 435, 436, 7, 126, 2, 2, 436, 437, 7, 126, 2, 2, 437, 122, 3, 2, 2, 2, 438, 439, 7, 44, 2, 2, 439, 440, 7, 44, 2, 2, 440, 124, 3, 2, 2, 2, 441, 442, 7, 64, 2, 2, 442, 443, 7, 64, 2, 2, 443, 126, 3, 2, 2, 2, 444, 445, 7, 62, 2, 2, 445, 446, 7, 62, 2, 2, 446, 128, 3, 2, 2, 2, 447, 448, 7, 64, 2, 2, 448, 449, 7, 64, 2, 2, 449, 450, 7, 64, 2, 2, 450, 130, 3, 2, 2, 2, 451, 452, 7, 62, 2, 2, 452, 453, 7, 62, 2, 2, 453, 454, 7, 62, 2, 2, 454, 132, 3, 2, 2, 2, 455, 459, 9, 2, 2, 2, 456, 458, 9, 3, 2, 2, 457, 456, 3, 2, 2, 2, 458, 461, 3, 2, 2, 2, 459, 457, 3, 2, 2, 2, 459, 460, 3, 2, 2, 2, 460, 134, 3, 2, 2, 2, 461, 459, 3, 2, 2, 2, 462, 464, 9, 4, 2, 2, 463, 462, 3, 2, 2, 2, 464, 465, 3, 2, 2, 2, 465, 463, 3, 2, 2, 2, 465, 466, 3, 2, 2, 2, 466, 467, 3, 2, 2, 2, 467, 468, 8, 68, 2, 2, 468, 136, 3, 2, 2, 2, 469, 470, 7, 49, 2, 2, 470, 471, 7, 49, 2, 2, 471, 475, 3, 2, 2, 2, 472, 474, 11, 2, 2, 2, 473, 472, 3, 2, 2, 2, 474, 477, 3, 2, 2, 2, 475, 476, 3, 2, 2, 2, 475, 473, 3, 2, 2, 2, 476, 479, 3, 2, 2, 2, 477, 475, 3, 2, 2, 2, 478, 480, 7, 15, 2, 2, 479, 478, 3, 2, 2, 2, 479, 480, 3, 2, 2, 2, 480, 481, 3, 2, 2, 2, 481, 482, 7, 12, 2, 2, 482, 483, 3, 2, 2, 2, 483, 484, 8, 69, 3, 2, 484, 138, 3, 2, 2, 2, 485, 486, 7, 49, 2, 2, 486, 487, 7, 44, 2, 2, 487, 491, 3, 2, 2, 2, 488, 490, 11, 2, 2, 2, 489, 488, 3, 2, 2, 2, 490, 493, 3, 2, 2, 2, 491, 492, 3, 2, 2, 2, 491, 489, 3, 2, 2, 2, 492, 494, 3, 2, 2, 2, 493, 491, 3, 2, 2, 2, 494, 495, 7, 44, 2, 2, 495, 496, 7, 49, 2, 2, 496, 497, 3, 2, 2, 2, 497, 498, 8, 70, 3, 2, 498, 140, 3, 2, 2, 2, 499, 503, 7, 98, 2, 2, 500, 502, 11, 2, 2, 2, 501, 500, 3, 2, 2, 2, 502, 505, 3, 2, 2, 2, 503, 504, 3, 2, 2, 2, 503, 501, 3, 2, 2, 2, 504, 507, 3, 2, 2, 2, 505, 503, 3, 2, 2, 2, 506, 508, 7, 15, 2, 2, 507, 506, 3, 2, 2, 2, 507, 508, 3, 2, 2, 2, 508, 509, 3, 2, 2, 2, 509, 510, 7, 12, 2, 2, 510, 511, 3, 2, 2, 2, 511, 512, 8, 71, 3, 2, 512, 142, 3, 2, 2, 2, 513, 514, 5, 159, 80, 2, 514, 515, 7, 48, 2, 2, 515, 516, 5, 159, 80, 2, 516, 529, 3, 2, 2, 2, 517, 520, 5, 159, 80, 2, 518, 519, 7, 48, 2, 2, 519, 521, 5, 159, 80, 2, 520, 518, 3, 2, 2, 2, 520, 521, 3, 2, 2, 2, 521, 522, 3, 2, 2, 2, 522, 524, 9, 5, 2, 2, 523, 525, 9, 6, 2, 2, 524, 523, 3, 2, 2, 2, 524, 525, 3, 2, 2, 2, 525, 526, 3, 2, 2, 2, 526, 527, 5, 159, 80, 2, 527, 529, 3, 2, 2, 2, 528, 513, 3, 2, 2, 2, 528, 517, 3, 2, 2, 2, 529, 144, 3, 2, 2, 2, 530, 560, 5, 159, 80, 2, 531, 533, 5, 155, 78, 2, 532, 531, 3, 2, 2, 2, 532, 533, 3, 2, 2, 2, 533, 534, 3, 2, 2, 2, 534, 535, 5, 167, 84, 2, 535, 536, 5, 159, 80, 2, 536, 560, 3, 2, 2, 2, 537, 539, 5, 155, 78, 2, 538, 537, 3, 2, 2, 2, 538, 539, 3, 2, 2, 2, 539, 540, 3, 2, 2, 2, 540, 541, 5, 167, 84, 2, 541, 545, 5, 185, 93, 2, 542, 544, 7, 97, 2, 2, 543, 542, 3, 2, 2, 2, 544, 547, 3, 2, 2, 2, 545, 543, 3, 2, 2, 2, 545, 546, 3, 2, 2, 2, 546, 560, 3, 2, 2, 2, 547, 545, 3, 2, 2, 2, 548, 550, 5, 155, 78, 2, 549, 548, 3, 2, 2, 2, 549, 550, 3, 2, 2, 2, 550, 551, 3, 2, 2, 2, 551, 552, 5, 167, 84, 2, 552, 556, 5, 187, 94, 2, 553, 555, 7, 97, 2, 2, 554, 553, 3, 2, 2, 2, 555, 558, 3, 2, 2, 2, 556, 554, 3, 2, 2, 2, 556, 557, 3, 2, 2, 2, 557, 560, 3, 2, 2, 2, 558, 556, 3, 2, 2, 2, 559, 530, 3, 2, 2, 2, 559, 532, 3, 2, 2, 2, 559, 538, 3, 2, 2, 2, 559, 549, 3, 2, 2, 2, 560, 146, 3, 2, 2, 2, 561, 563, 5, 155, 78, 2, 562, 561, 3, 2, 2, 2, 562, 563, 3, 2, 2, 2, 563, 564, 3, 2, 2, 2, 564, 565, 5, 169, 85, 2, 565, 566, 5, 161, 81, 2, 566, 148, 3, 2, 2, 2, 567, 569, 5, 155, 78, 2, 568, 567, 3, 2, 2, 2, 568, 569, 3, 2, 2, 2, 569, 570, 3, 2, 2, 2, 570, 571, 5, 171, 86, 2, 571, 572, 5, 163, 82, 2, 572, 150, 3, 2, 2, 2, 573, 575, 5, 155, 78, 2, 574, 573, 3, 2, 2, 2, 574, 575, 3, 2, 2, 2, 575, 576, 3, 2, 2, 2, 576, 577, 5, 173, 87, 2, 577, 578, 5, 165, 83, 2, 578, 152, 3, 2, 2, 2, 579, 580, 9, 6, 2, 2, 580, 154, 3, 2, 2, 2, 581, 582, 5, 157, 79, 2, 582, 156, 3, 2, 2, 2, 583, 588, 5, 175, 88, 2, 584, 587, 7, 97, 2, 2, 585, 587, 5, 177, 89, 2, 586, 584, 3, 2, 2, 2, 586, 585, 3, 2, 2, 2, 587, 590, 3, 2, 2, 2, 588, 586, 3, 2, 2, 2, 588, 589, 3, 2, 2, 2, 589, 158, 3, 2, 2, 2, 590, 588, 3, 2, 2, 2, 591, 596, 5, 177, 89, 2, 592, 595, 7, 97, 2, 2, 593, 595, 5, 177, 89, 2, 594, 592, 3, 2, 2, 2, 594, 593, 3, 2, 2, 2, 595, 598, 3, 2, 2, 2, 596, 594, 3, 2, 2, 2, 596, 597, 3, 2, 2, 2, 597, 160, 3, 2, 2, 2, 598, 596, 3, 2, 2, 2, 599, 604, 5, 179, 90, 2, 600, 603, 7, 97, 2, 2, 601, 603, 5, 179, 90, 2, 602, 600, 3, 2, 2, 2, 602, 601, 3, 2, 2, 2, 603, 606, 3, 2, 2, 2, 604, 602, 3, 2, 2, 2, 604, 605, 3, 2, 2, 2, 605, 162, 3, 2, 2, 2, 606, 604, 3, 2, 2, 2, 607, 612, 5, 181, 91, 2, 608, 611, 7, 97, 2, 2, 609, 611, 5, 181, 91, 2, 610, 608, 3, 2, 2, 2, 610, 609, 3, 2, 2, 2, 611, 614, 3, 2, 2, 2, 612, 610, 3, 2, 2, 2, 612, 613, 3, 2, 2, 2, 613, 164, 3, 2, 2, 2, 614, 612, 3, 2, 2, 2, 615, 620, 5, 183, 92, 2, 616, 619, 7, 97, 2, 2, 617, 619, 5, 183, 92, 2, 618, 616, 3, 2, 2, 2, 618, 617, 3, 2, 2, 2, 619, 622, 3, 2, 2, 2, 620, 618, 3, 2, 2, 2, 620, 621, 3, 2, 2, 2, 621, 166, 3, 2, 2, 2, 622, 620, 3, 2, 2, 2, 623, 625, 7, 41, 2, 2, 624, 626, 9, 7, 2, 2, 625, 624, 3, 2, 2, 2, 625, 626, 3, 2, 2, 2, 626, 627, 3, 2, 2, 2, 627, 628, 9, 8, 2, 2, 628, 168, 3, 2, 2, 2, 629, 631, 7, 41, 2, 2, 630, 632, 9, 7, 2, 2, 631, 630, 3, 2, 2, 2, 631, 632, 3, 2, 2, 2, 632, 633, 3, 2, 2, 2, 633, 634, 9, 9, 2, 2, 634, 170, 3, 2, 2, 2, 635, 637, 7, 41, 2, 2, 636, 638, 9, 7, 2, 2, 637, 636, 3, 2, 2, 2, 637, 638, 3, 2, 2, 2, 638, 639, 3, 2, 2, 2, 639, 640, 9, 10, 2, 2, 640, 172, 3, 2, 2, 2, 641, 643, 7, 41, 2, 2, 642, 644, 9, 7, 2, 2, 643, 642, 3, 2, 2, 2, 643, 644, 3, 2, 2, 2, 644, 645, 3, 2, 2, 2, 645, 646, 9, 11, 2, 2, 646, 174, 3, 2, 2, 2, 647, 648, 9, 12, 2, 2, 648, 176, 3, 2, 2, 2, 649, 650, 9, 13, 2, 2, 650, 178, 3, 2, 2, 2, 651, 655, 5, 185, 93, 2, 652, 655, 5, 187, 94, 2, 653, 655, 9, 14, 2, 2, 654, 651, 3, 2, 2, 2, 654, 652, 3, 2, 2, 2, 654, 653, 3, 2, 2, 2, 655, 180, 3, 2, 2, 2, 656, 660, 5, 185, 93, 2, 657, 660, 5, 187, 94, 2, 658, 660, 9, 15, 2, 2, 659, 656, 3, 2, 2, 2, 659, 657, 3, 2, 2, 2, 659, 658, 3, 2, 2, 2, 660, 182, 3, 2, 2, 2, 661, 665, 5, 185, 93, 2, 662, 665, 5, 187, 94, 2, 663, 665, 9, 16, 2, 2, 664, 661, 3, 2, 2, 2, 664, 662, 3, 2, 2, 2, 664, 663, 3, 2, 2, 2, 665, 184, 3, 2, 2, 2, 666, 667, 9, 17, 2, 2, 667, 186, 3, 2, 2, 2, 668, 669, 9, 18, 2, 2, 669, 188, 3, 2, 2, 2, 39, 2, 459, 465, 475, 479, 491, 503, 507, 520, 524, 528, 532, 538, 545, 549, 556, 559, 562, 568, 574, 586, 588, 594, 596, 602, 604, 610, 612, 618, 620, 625, 631, 637, 643, 654, 659, 664, 4, 8, 2, 2, 2, 3, 2]
\ No newline at end of file
diff --git a/lfr/antlrgen/lfrXLexer.py b/lfr/antlrgen/lfrXLexer.py
deleted file mode 100755
index e64bdbf..0000000
--- a/lfr/antlrgen/lfrXLexer.py
+++ /dev/null
@@ -1,444 +0,0 @@
-# Generated from ./lfrX.g4 by ANTLR 4.9.1
-from antlr4 import *
-from io import StringIO
-from typing.io import TextIO
-import sys
-
-
-
-def serializedATN():
- with StringIO() as buf:
- buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2M")
- buf.write("\u029e\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7")
- buf.write("\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r")
- buf.write("\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23")
- buf.write("\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30")
- buf.write("\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36")
- buf.write("\t\36\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%")
- buf.write("\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4,\t,\4-\t-\4.")
- buf.write("\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64")
- buf.write("\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:")
- buf.write("\4;\t;\4<\t<\4=\t=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\t")
- buf.write("C\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I\tI\4J\tJ\4K\tK\4L\t")
- buf.write("L\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT\4U\t")
- buf.write("U\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4")
- buf.write("^\t^\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3")
- buf.write("\3\3\3\3\3\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b")
- buf.write("\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\t\3")
- buf.write("\t\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13")
- buf.write("\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3")
- buf.write("\f\3\f\3\f\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\17\3\17\3")
- buf.write("\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20")
- buf.write("\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\23\3\23\3\23\3\23")
- buf.write("\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\25\3\25\3\26\3\26")
- buf.write("\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\30")
- buf.write("\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31")
- buf.write("\3\31\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33")
- buf.write("\3\33\3\33\3\33\3\33\3\34\3\34\3\35\3\35\3\36\3\36\3\37")
- buf.write("\3\37\3 \3 \3!\3!\3!\3!\3!\3\"\3\"\3#\3#\3#\3#\3#\3#\3")
- buf.write("#\3#\3#\3#\3$\3$\3$\3$\3$\3$\3$\3$\3$\3$\3$\3%\3%\3%\3")
- buf.write("%\3&\3&\3&\3\'\3\'\3(\3(\3)\3)\3)\3*\3*\3+\3+\3,\3,\3")
- buf.write("-\3-\3.\3.\3/\3/\3/\3\60\3\60\3\61\3\61\3\61\3\62\3\62")
- buf.write("\3\63\3\63\3\63\3\64\3\64\3\64\3\65\3\65\3\66\3\66\3\67")
- buf.write("\3\67\38\38\38\39\39\39\3:\3:\3:\3:\3;\3;\3;\3;\3<\3<")
- buf.write("\3<\3=\3=\3=\3>\3>\3>\3?\3?\3?\3@\3@\3@\3A\3A\3A\3A\3")
- buf.write("B\3B\3B\3B\3C\3C\7C\u01ca\nC\fC\16C\u01cd\13C\3D\6D\u01d0")
- buf.write("\nD\rD\16D\u01d1\3D\3D\3E\3E\3E\3E\7E\u01da\nE\fE\16E")
- buf.write("\u01dd\13E\3E\5E\u01e0\nE\3E\3E\3E\3E\3F\3F\3F\3F\7F\u01ea")
- buf.write("\nF\fF\16F\u01ed\13F\3F\3F\3F\3F\3F\3G\3G\7G\u01f6\nG")
- buf.write("\fG\16G\u01f9\13G\3G\5G\u01fc\nG\3G\3G\3G\3G\3H\3H\3H")
- buf.write("\3H\3H\3H\3H\5H\u0209\nH\3H\3H\5H\u020d\nH\3H\3H\5H\u0211")
- buf.write("\nH\3I\3I\5I\u0215\nI\3I\3I\3I\3I\5I\u021b\nI\3I\3I\3")
- buf.write("I\7I\u0220\nI\fI\16I\u0223\13I\3I\5I\u0226\nI\3I\3I\3")
- buf.write("I\7I\u022b\nI\fI\16I\u022e\13I\5I\u0230\nI\3J\5J\u0233")
- buf.write("\nJ\3J\3J\3J\3K\5K\u0239\nK\3K\3K\3K\3L\5L\u023f\nL\3")
- buf.write("L\3L\3L\3M\3M\3N\3N\3O\3O\3O\7O\u024b\nO\fO\16O\u024e")
- buf.write("\13O\3P\3P\3P\7P\u0253\nP\fP\16P\u0256\13P\3Q\3Q\3Q\7")
- buf.write("Q\u025b\nQ\fQ\16Q\u025e\13Q\3R\3R\3R\7R\u0263\nR\fR\16")
- buf.write("R\u0266\13R\3S\3S\3S\7S\u026b\nS\fS\16S\u026e\13S\3T\3")
- buf.write("T\5T\u0272\nT\3T\3T\3U\3U\5U\u0278\nU\3U\3U\3V\3V\5V\u027e")
- buf.write("\nV\3V\3V\3W\3W\5W\u0284\nW\3W\3W\3X\3X\3Y\3Y\3Z\3Z\3")
- buf.write("Z\5Z\u028f\nZ\3[\3[\3[\5[\u0294\n[\3\\\3\\\3\\\5\\\u0299")
- buf.write("\n\\\3]\3]\3^\3^\5\u01db\u01eb\u01f7\2_\3\3\5\4\7\5\t")
- buf.write("\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20")
- buf.write("\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65")
- buf.write("\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60")
- buf.write("_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u{?}@\177A\u0081")
- buf.write("B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091")
- buf.write("J\u0093K\u0095L\u0097M\u0099\2\u009b\2\u009d\2\u009f\2")
- buf.write("\u00a1\2\u00a3\2\u00a5\2\u00a7\2\u00a9\2\u00ab\2\u00ad")
- buf.write("\2\u00af\2\u00b1\2\u00b3\2\u00b5\2\u00b7\2\u00b9\2\u00bb")
- buf.write("\2\3\2\23\5\2C\\aac|\6\2\62;C\\aac|\5\2\13\f\17\17\"\"")
- buf.write("\4\2GGgg\4\2--//\4\2UUuu\4\2FFff\4\2DDdd\4\2QQqq\4\2J")
- buf.write("Jjj\3\2\63;\3\2\62;\3\2\62\63\3\2\629\5\2\62;CHch\4\2")
- buf.write("ZZzz\5\2AA\\\\||\2\u02b4\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3")
- buf.write("\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2")
- buf.write("\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2")
- buf.write("\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2")
- buf.write("!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2")
- buf.write("\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3")
- buf.write("\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2")
- buf.write("\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2")
- buf.write("\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2")
- buf.write("\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3")
- buf.write("\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c")
- buf.write("\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2")
- buf.write("m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2")
- buf.write("\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2")
- buf.write("\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2")
- buf.write("\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d")
- buf.write("\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2")
- buf.write("\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\3\u00bd\3\2\2\2\5\u00c7")
- buf.write("\3\2\2\2\7\u00ce\3\2\2\2\t\u00d0\3\2\2\2\13\u00d2\3\2")
- buf.write("\2\2\r\u00d4\3\2\2\2\17\u00d6\3\2\2\2\21\u00dd\3\2\2\2")
- buf.write("\23\u00e5\3\2\2\2\25\u00ed\3\2\2\2\27\u00f9\3\2\2\2\31")
- buf.write("\u00ff\3\2\2\2\33\u0103\3\2\2\2\35\u0106\3\2\2\2\37\u010b")
- buf.write("\3\2\2\2!\u0113\3\2\2\2#\u0118\3\2\2\2%\u011a\3\2\2\2")
- buf.write("\'\u0122\3\2\2\2)\u0125\3\2\2\2+\u0127\3\2\2\2-\u012e")
- buf.write("\3\2\2\2/\u0133\3\2\2\2\61\u013b\3\2\2\2\63\u0140\3\2")
- buf.write("\2\2\65\u0147\3\2\2\2\67\u014e\3\2\2\29\u0150\3\2\2\2")
- buf.write(";\u0152\3\2\2\2=\u0154\3\2\2\2?\u0156\3\2\2\2A\u0158\3")
- buf.write("\2\2\2C\u015d\3\2\2\2E\u015f\3\2\2\2G\u0169\3\2\2\2I\u0174")
- buf.write("\3\2\2\2K\u0178\3\2\2\2M\u017b\3\2\2\2O\u017d\3\2\2\2")
- buf.write("Q\u017f\3\2\2\2S\u0182\3\2\2\2U\u0184\3\2\2\2W\u0186\3")
- buf.write("\2\2\2Y\u0188\3\2\2\2[\u018a\3\2\2\2]\u018c\3\2\2\2_\u018f")
- buf.write("\3\2\2\2a\u0191\3\2\2\2c\u0194\3\2\2\2e\u0196\3\2\2\2")
- buf.write("g\u0199\3\2\2\2i\u019c\3\2\2\2k\u019e\3\2\2\2m\u01a0\3")
- buf.write("\2\2\2o\u01a2\3\2\2\2q\u01a5\3\2\2\2s\u01a8\3\2\2\2u\u01ac")
- buf.write("\3\2\2\2w\u01b0\3\2\2\2y\u01b3\3\2\2\2{\u01b6\3\2\2\2")
- buf.write("}\u01b9\3\2\2\2\177\u01bc\3\2\2\2\u0081\u01bf\3\2\2\2")
- buf.write("\u0083\u01c3\3\2\2\2\u0085\u01c7\3\2\2\2\u0087\u01cf\3")
- buf.write("\2\2\2\u0089\u01d5\3\2\2\2\u008b\u01e5\3\2\2\2\u008d\u01f3")
- buf.write("\3\2\2\2\u008f\u0210\3\2\2\2\u0091\u022f\3\2\2\2\u0093")
- buf.write("\u0232\3\2\2\2\u0095\u0238\3\2\2\2\u0097\u023e\3\2\2\2")
- buf.write("\u0099\u0243\3\2\2\2\u009b\u0245\3\2\2\2\u009d\u0247\3")
- buf.write("\2\2\2\u009f\u024f\3\2\2\2\u00a1\u0257\3\2\2\2\u00a3\u025f")
- buf.write("\3\2\2\2\u00a5\u0267\3\2\2\2\u00a7\u026f\3\2\2\2\u00a9")
- buf.write("\u0275\3\2\2\2\u00ab\u027b\3\2\2\2\u00ad\u0281\3\2\2\2")
- buf.write("\u00af\u0287\3\2\2\2\u00b1\u0289\3\2\2\2\u00b3\u028e\3")
- buf.write("\2\2\2\u00b5\u0293\3\2\2\2\u00b7\u0298\3\2\2\2\u00b9\u029a")
- buf.write("\3\2\2\2\u00bb\u029c\3\2\2\2\u00bd\u00be\7g\2\2\u00be")
- buf.write("\u00bf\7p\2\2\u00bf\u00c0\7f\2\2\u00c0\u00c1\7o\2\2\u00c1")
- buf.write("\u00c2\7q\2\2\u00c2\u00c3\7f\2\2\u00c3\u00c4\7w\2\2\u00c4")
- buf.write("\u00c5\7n\2\2\u00c5\u00c6\7g\2\2\u00c6\4\3\2\2\2\u00c7")
- buf.write("\u00c8\7o\2\2\u00c8\u00c9\7q\2\2\u00c9\u00ca\7f\2\2\u00ca")
- buf.write("\u00cb\7w\2\2\u00cb\u00cc\7n\2\2\u00cc\u00cd\7g\2\2\u00cd")
- buf.write("\6\3\2\2\2\u00ce\u00cf\7*\2\2\u00cf\b\3\2\2\2\u00d0\u00d1")
- buf.write("\7+\2\2\u00d1\n\3\2\2\2\u00d2\u00d3\7=\2\2\u00d3\f\3\2")
- buf.write("\2\2\u00d4\u00d5\7.\2\2\u00d5\16\3\2\2\2\u00d6\u00d7\7")
- buf.write("h\2\2\u00d7\u00d8\7k\2\2\u00d8\u00d9\7p\2\2\u00d9\u00da")
- buf.write("\7r\2\2\u00da\u00db\7w\2\2\u00db\u00dc\7v\2\2\u00dc\20")
- buf.write("\3\2\2\2\u00dd\u00de\7h\2\2\u00de\u00df\7q\2\2\u00df\u00e0")
- buf.write("\7w\2\2\u00e0\u00e1\7v\2\2\u00e1\u00e2\7r\2\2\u00e2\u00e3")
- buf.write("\7w\2\2\u00e3\u00e4\7v\2\2\u00e4\22\3\2\2\2\u00e5\u00e6")
- buf.write("\7e\2\2\u00e6\u00e7\7q\2\2\u00e7\u00e8\7p\2\2\u00e8\u00e9")
- buf.write("\7v\2\2\u00e9\u00ea\7t\2\2\u00ea\u00eb\7q\2\2\u00eb\u00ec")
- buf.write("\7n\2\2\u00ec\24\3\2\2\2\u00ed\u00ee\7f\2\2\u00ee\u00ef")
- buf.write("\7k\2\2\u00ef\u00f0\7u\2\2\u00f0\u00f1\7v\2\2\u00f1\u00f2")
- buf.write("\7t\2\2\u00f2\u00f3\7k\2\2\u00f3\u00f4\7d\2\2\u00f4\u00f5")
- buf.write("\7w\2\2\u00f5\u00f6\7v\2\2\u00f6\u00f7\7g\2\2\u00f7\u00f8")
- buf.write("\7B\2\2\u00f8\26\3\2\2\2\u00f9\u00fa\7d\2\2\u00fa\u00fb")
- buf.write("\7g\2\2\u00fb\u00fc\7i\2\2\u00fc\u00fd\7k\2\2\u00fd\u00fe")
- buf.write("\7p\2\2\u00fe\30\3\2\2\2\u00ff\u0100\7g\2\2\u0100\u0101")
- buf.write("\7p\2\2\u0101\u0102\7f\2\2\u0102\32\3\2\2\2\u0103\u0104")
- buf.write("\7k\2\2\u0104\u0105\7h\2\2\u0105\34\3\2\2\2\u0106\u0107")
- buf.write("\7g\2\2\u0107\u0108\7n\2\2\u0108\u0109\7u\2\2\u0109\u010a")
- buf.write("\7g\2\2\u010a\36\3\2\2\2\u010b\u010c\7g\2\2\u010c\u010d")
- buf.write("\7p\2\2\u010d\u010e\7f\2\2\u010e\u010f\7e\2\2\u010f\u0110")
- buf.write("\7c\2\2\u0110\u0111\7u\2\2\u0111\u0112\7g\2\2\u0112 \3")
- buf.write("\2\2\2\u0113\u0114\7e\2\2\u0114\u0115\7c\2\2\u0115\u0116")
- buf.write("\7u\2\2\u0116\u0117\7g\2\2\u0117\"\3\2\2\2\u0118\u0119")
- buf.write("\7<\2\2\u0119$\3\2\2\2\u011a\u011b\7f\2\2\u011b\u011c")
- buf.write("\7g\2\2\u011c\u011d\7h\2\2\u011d\u011e\7c\2\2\u011e\u011f")
- buf.write("\7w\2\2\u011f\u0120\7n\2\2\u0120\u0121\7v\2\2\u0121&\3")
- buf.write("\2\2\2\u0122\u0123\7>\2\2\u0123\u0124\7?\2\2\u0124(\3")
- buf.write("\2\2\2\u0125\u0126\7\60\2\2\u0126*\3\2\2\2\u0127\u0128")
- buf.write("\7u\2\2\u0128\u0129\7k\2\2\u0129\u012a\7i\2\2\u012a\u012b")
- buf.write("\7p\2\2\u012b\u012c\7c\2\2\u012c\u012d\7n\2\2\u012d,\3")
- buf.write("\2\2\2\u012e\u012f\7h\2\2\u012f\u0130\7n\2\2\u0130\u0131")
- buf.write("\7q\2\2\u0131\u0132\7y\2\2\u0132.\3\2\2\2\u0133\u0134")
- buf.write("\7u\2\2\u0134\u0135\7v\2\2\u0135\u0136\7q\2\2\u0136\u0137")
- buf.write("\7t\2\2\u0137\u0138\7c\2\2\u0138\u0139\7i\2\2\u0139\u013a")
- buf.write("\7g\2\2\u013a\60\3\2\2\2\u013b\u013c\7r\2\2\u013c\u013d")
- buf.write("\7w\2\2\u013d\u013e\7o\2\2\u013e\u013f\7r\2\2\u013f\62")
- buf.write("\3\2\2\2\u0140\u0141\7p\2\2\u0141\u0142\7w\2\2\u0142\u0143")
- buf.write("\7o\2\2\u0143\u0144\7d\2\2\u0144\u0145\7g\2\2\u0145\u0146")
- buf.write("\7t\2\2\u0146\64\3\2\2\2\u0147\u0148\7c\2\2\u0148\u0149")
- buf.write("\7u\2\2\u0149\u014a\7u\2\2\u014a\u014b\7k\2\2\u014b\u014c")
- buf.write("\7i\2\2\u014c\u014d\7p\2\2\u014d\66\3\2\2\2\u014e\u014f")
- buf.write("\7?\2\2\u014f8\3\2\2\2\u0150\u0151\7]\2\2\u0151:\3\2\2")
- buf.write("\2\u0152\u0153\7_\2\2\u0153<\3\2\2\2\u0154\u0155\7}\2")
- buf.write("\2\u0155>\3\2\2\2\u0156\u0157\7\177\2\2\u0157@\3\2\2\2")
- buf.write("\u0158\u0159\7%\2\2\u0159\u015a\7O\2\2\u015a\u015b\7C")
- buf.write("\2\2\u015b\u015c\7R\2\2\u015cB\3\2\2\2\u015d\u015e\7$")
- buf.write("\2\2\u015eD\3\2\2\2\u015f\u0160\7%\2\2\u0160\u0161\7O")
- buf.write("\2\2\u0161\u0162\7C\2\2\u0162\u0163\7V\2\2\u0163\u0164")
- buf.write("\7G\2\2\u0164\u0165\7T\2\2\u0165\u0166\7K\2\2\u0166\u0167")
- buf.write("\7C\2\2\u0167\u0168\7N\2\2\u0168F\3\2\2\2\u0169\u016a")
- buf.write("\7%\2\2\u016a\u016b\7E\2\2\u016b\u016c\7Q\2\2\u016c\u016d")
- buf.write("\7P\2\2\u016d\u016e\7U\2\2\u016e\u016f\7V\2\2\u016f\u0170")
- buf.write("\7T\2\2\u0170\u0171\7C\2\2\u0171\u0172\7K\2\2\u0172\u0173")
- buf.write("\7P\2\2\u0173H\3\2\2\2\u0174\u0175\7C\2\2\u0175\u0176")
- buf.write("\7P\2\2\u0176\u0177\7F\2\2\u0177J\3\2\2\2\u0178\u0179")
- buf.write("\7Q\2\2\u0179\u017a\7T\2\2\u017aL\3\2\2\2\u017b\u017c")
- buf.write("\7@\2\2\u017cN\3\2\2\2\u017d\u017e\7>\2\2\u017eP\3\2\2")
- buf.write("\2\u017f\u0180\7@\2\2\u0180\u0181\7?\2\2\u0181R\3\2\2")
- buf.write("\2\u0182\u0183\7-\2\2\u0183T\3\2\2\2\u0184\u0185\7/\2")
- buf.write("\2\u0185V\3\2\2\2\u0186\u0187\7#\2\2\u0187X\3\2\2\2\u0188")
- buf.write("\u0189\7\u0080\2\2\u0189Z\3\2\2\2\u018a\u018b\7(\2\2\u018b")
- buf.write("\\\3\2\2\2\u018c\u018d\7\u0080\2\2\u018d\u018e\7(\2\2")
- buf.write("\u018e^\3\2\2\2\u018f\u0190\7~\2\2\u0190`\3\2\2\2\u0191")
- buf.write("\u0192\7\u0080\2\2\u0192\u0193\7~\2\2\u0193b\3\2\2\2\u0194")
- buf.write("\u0195\7`\2\2\u0195d\3\2\2\2\u0196\u0197\7\u0080\2\2\u0197")
- buf.write("\u0198\7`\2\2\u0198f\3\2\2\2\u0199\u019a\7`\2\2\u019a")
- buf.write("\u019b\7\u0080\2\2\u019bh\3\2\2\2\u019c\u019d\7,\2\2\u019d")
- buf.write("j\3\2\2\2\u019e\u019f\7\61\2\2\u019fl\3\2\2\2\u01a0\u01a1")
- buf.write("\7\'\2\2\u01a1n\3\2\2\2\u01a2\u01a3\7?\2\2\u01a3\u01a4")
- buf.write("\7?\2\2\u01a4p\3\2\2\2\u01a5\u01a6\7#\2\2\u01a6\u01a7")
- buf.write("\7?\2\2\u01a7r\3\2\2\2\u01a8\u01a9\7?\2\2\u01a9\u01aa")
- buf.write("\7?\2\2\u01aa\u01ab\7?\2\2\u01abt\3\2\2\2\u01ac\u01ad")
- buf.write("\7#\2\2\u01ad\u01ae\7?\2\2\u01ae\u01af\7?\2\2\u01afv\3")
- buf.write("\2\2\2\u01b0\u01b1\7(\2\2\u01b1\u01b2\7(\2\2\u01b2x\3")
- buf.write("\2\2\2\u01b3\u01b4\7~\2\2\u01b4\u01b5\7~\2\2\u01b5z\3")
- buf.write("\2\2\2\u01b6\u01b7\7,\2\2\u01b7\u01b8\7,\2\2\u01b8|\3")
- buf.write("\2\2\2\u01b9\u01ba\7@\2\2\u01ba\u01bb\7@\2\2\u01bb~\3")
- buf.write("\2\2\2\u01bc\u01bd\7>\2\2\u01bd\u01be\7>\2\2\u01be\u0080")
- buf.write("\3\2\2\2\u01bf\u01c0\7@\2\2\u01c0\u01c1\7@\2\2\u01c1\u01c2")
- buf.write("\7@\2\2\u01c2\u0082\3\2\2\2\u01c3\u01c4\7>\2\2\u01c4\u01c5")
- buf.write("\7>\2\2\u01c5\u01c6\7>\2\2\u01c6\u0084\3\2\2\2\u01c7\u01cb")
- buf.write("\t\2\2\2\u01c8\u01ca\t\3\2\2\u01c9\u01c8\3\2\2\2\u01ca")
- buf.write("\u01cd\3\2\2\2\u01cb\u01c9\3\2\2\2\u01cb\u01cc\3\2\2\2")
- buf.write("\u01cc\u0086\3\2\2\2\u01cd\u01cb\3\2\2\2\u01ce\u01d0\t")
- buf.write("\4\2\2\u01cf\u01ce\3\2\2\2\u01d0\u01d1\3\2\2\2\u01d1\u01cf")
- buf.write("\3\2\2\2\u01d1\u01d2\3\2\2\2\u01d2\u01d3\3\2\2\2\u01d3")
- buf.write("\u01d4\bD\2\2\u01d4\u0088\3\2\2\2\u01d5\u01d6\7\61\2\2")
- buf.write("\u01d6\u01d7\7\61\2\2\u01d7\u01db\3\2\2\2\u01d8\u01da")
- buf.write("\13\2\2\2\u01d9\u01d8\3\2\2\2\u01da\u01dd\3\2\2\2\u01db")
- buf.write("\u01dc\3\2\2\2\u01db\u01d9\3\2\2\2\u01dc\u01df\3\2\2\2")
- buf.write("\u01dd\u01db\3\2\2\2\u01de\u01e0\7\17\2\2\u01df\u01de")
- buf.write("\3\2\2\2\u01df\u01e0\3\2\2\2\u01e0\u01e1\3\2\2\2\u01e1")
- buf.write("\u01e2\7\f\2\2\u01e2\u01e3\3\2\2\2\u01e3\u01e4\bE\3\2")
- buf.write("\u01e4\u008a\3\2\2\2\u01e5\u01e6\7\61\2\2\u01e6\u01e7")
- buf.write("\7,\2\2\u01e7\u01eb\3\2\2\2\u01e8\u01ea\13\2\2\2\u01e9")
- buf.write("\u01e8\3\2\2\2\u01ea\u01ed\3\2\2\2\u01eb\u01ec\3\2\2\2")
- buf.write("\u01eb\u01e9\3\2\2\2\u01ec\u01ee\3\2\2\2\u01ed\u01eb\3")
- buf.write("\2\2\2\u01ee\u01ef\7,\2\2\u01ef\u01f0\7\61\2\2\u01f0\u01f1")
- buf.write("\3\2\2\2\u01f1\u01f2\bF\3\2\u01f2\u008c\3\2\2\2\u01f3")
- buf.write("\u01f7\7b\2\2\u01f4\u01f6\13\2\2\2\u01f5\u01f4\3\2\2\2")
- buf.write("\u01f6\u01f9\3\2\2\2\u01f7\u01f8\3\2\2\2\u01f7\u01f5\3")
- buf.write("\2\2\2\u01f8\u01fb\3\2\2\2\u01f9\u01f7\3\2\2\2\u01fa\u01fc")
- buf.write("\7\17\2\2\u01fb\u01fa\3\2\2\2\u01fb\u01fc\3\2\2\2\u01fc")
- buf.write("\u01fd\3\2\2\2\u01fd\u01fe\7\f\2\2\u01fe\u01ff\3\2\2\2")
- buf.write("\u01ff\u0200\bG\3\2\u0200\u008e\3\2\2\2\u0201\u0202\5")
- buf.write("\u009fP\2\u0202\u0203\7\60\2\2\u0203\u0204\5\u009fP\2")
- buf.write("\u0204\u0211\3\2\2\2\u0205\u0208\5\u009fP\2\u0206\u0207")
- buf.write("\7\60\2\2\u0207\u0209\5\u009fP\2\u0208\u0206\3\2\2\2\u0208")
- buf.write("\u0209\3\2\2\2\u0209\u020a\3\2\2\2\u020a\u020c\t\5\2\2")
- buf.write("\u020b\u020d\t\6\2\2\u020c\u020b\3\2\2\2\u020c\u020d\3")
- buf.write("\2\2\2\u020d\u020e\3\2\2\2\u020e\u020f\5\u009fP\2\u020f")
- buf.write("\u0211\3\2\2\2\u0210\u0201\3\2\2\2\u0210\u0205\3\2\2\2")
- buf.write("\u0211\u0090\3\2\2\2\u0212\u0230\5\u009fP\2\u0213\u0215")
- buf.write("\5\u009bN\2\u0214\u0213\3\2\2\2\u0214\u0215\3\2\2\2\u0215")
- buf.write("\u0216\3\2\2\2\u0216\u0217\5\u00a7T\2\u0217\u0218\5\u009f")
- buf.write("P\2\u0218\u0230\3\2\2\2\u0219\u021b\5\u009bN\2\u021a\u0219")
- buf.write("\3\2\2\2\u021a\u021b\3\2\2\2\u021b\u021c\3\2\2\2\u021c")
- buf.write("\u021d\5\u00a7T\2\u021d\u0221\5\u00b9]\2\u021e\u0220\7")
- buf.write("a\2\2\u021f\u021e\3\2\2\2\u0220\u0223\3\2\2\2\u0221\u021f")
- buf.write("\3\2\2\2\u0221\u0222\3\2\2\2\u0222\u0230\3\2\2\2\u0223")
- buf.write("\u0221\3\2\2\2\u0224\u0226\5\u009bN\2\u0225\u0224\3\2")
- buf.write("\2\2\u0225\u0226\3\2\2\2\u0226\u0227\3\2\2\2\u0227\u0228")
- buf.write("\5\u00a7T\2\u0228\u022c\5\u00bb^\2\u0229\u022b\7a\2\2")
- buf.write("\u022a\u0229\3\2\2\2\u022b\u022e\3\2\2\2\u022c\u022a\3")
- buf.write("\2\2\2\u022c\u022d\3\2\2\2\u022d\u0230\3\2\2\2\u022e\u022c")
- buf.write("\3\2\2\2\u022f\u0212\3\2\2\2\u022f\u0214\3\2\2\2\u022f")
- buf.write("\u021a\3\2\2\2\u022f\u0225\3\2\2\2\u0230\u0092\3\2\2\2")
- buf.write("\u0231\u0233\5\u009bN\2\u0232\u0231\3\2\2\2\u0232\u0233")
- buf.write("\3\2\2\2\u0233\u0234\3\2\2\2\u0234\u0235\5\u00a9U\2\u0235")
- buf.write("\u0236\5\u00a1Q\2\u0236\u0094\3\2\2\2\u0237\u0239\5\u009b")
- buf.write("N\2\u0238\u0237\3\2\2\2\u0238\u0239\3\2\2\2\u0239\u023a")
- buf.write("\3\2\2\2\u023a\u023b\5\u00abV\2\u023b\u023c\5\u00a3R\2")
- buf.write("\u023c\u0096\3\2\2\2\u023d\u023f\5\u009bN\2\u023e\u023d")
- buf.write("\3\2\2\2\u023e\u023f\3\2\2\2\u023f\u0240\3\2\2\2\u0240")
- buf.write("\u0241\5\u00adW\2\u0241\u0242\5\u00a5S\2\u0242\u0098\3")
- buf.write("\2\2\2\u0243\u0244\t\6\2\2\u0244\u009a\3\2\2\2\u0245\u0246")
- buf.write("\5\u009dO\2\u0246\u009c\3\2\2\2\u0247\u024c\5\u00afX\2")
- buf.write("\u0248\u024b\7a\2\2\u0249\u024b\5\u00b1Y\2\u024a\u0248")
- buf.write("\3\2\2\2\u024a\u0249\3\2\2\2\u024b\u024e\3\2\2\2\u024c")
- buf.write("\u024a\3\2\2\2\u024c\u024d\3\2\2\2\u024d\u009e\3\2\2\2")
- buf.write("\u024e\u024c\3\2\2\2\u024f\u0254\5\u00b1Y\2\u0250\u0253")
- buf.write("\7a\2\2\u0251\u0253\5\u00b1Y\2\u0252\u0250\3\2\2\2\u0252")
- buf.write("\u0251\3\2\2\2\u0253\u0256\3\2\2\2\u0254\u0252\3\2\2\2")
- buf.write("\u0254\u0255\3\2\2\2\u0255\u00a0\3\2\2\2\u0256\u0254\3")
- buf.write("\2\2\2\u0257\u025c\5\u00b3Z\2\u0258\u025b\7a\2\2\u0259")
- buf.write("\u025b\5\u00b3Z\2\u025a\u0258\3\2\2\2\u025a\u0259\3\2")
- buf.write("\2\2\u025b\u025e\3\2\2\2\u025c\u025a\3\2\2\2\u025c\u025d")
- buf.write("\3\2\2\2\u025d\u00a2\3\2\2\2\u025e\u025c\3\2\2\2\u025f")
- buf.write("\u0264\5\u00b5[\2\u0260\u0263\7a\2\2\u0261\u0263\5\u00b5")
- buf.write("[\2\u0262\u0260\3\2\2\2\u0262\u0261\3\2\2\2\u0263\u0266")
- buf.write("\3\2\2\2\u0264\u0262\3\2\2\2\u0264\u0265\3\2\2\2\u0265")
- buf.write("\u00a4\3\2\2\2\u0266\u0264\3\2\2\2\u0267\u026c\5\u00b7")
- buf.write("\\\2\u0268\u026b\7a\2\2\u0269\u026b\5\u00b7\\\2\u026a")
- buf.write("\u0268\3\2\2\2\u026a\u0269\3\2\2\2\u026b\u026e\3\2\2\2")
- buf.write("\u026c\u026a\3\2\2\2\u026c\u026d\3\2\2\2\u026d\u00a6\3")
- buf.write("\2\2\2\u026e\u026c\3\2\2\2\u026f\u0271\7)\2\2\u0270\u0272")
- buf.write("\t\7\2\2\u0271\u0270\3\2\2\2\u0271\u0272\3\2\2\2\u0272")
- buf.write("\u0273\3\2\2\2\u0273\u0274\t\b\2\2\u0274\u00a8\3\2\2\2")
- buf.write("\u0275\u0277\7)\2\2\u0276\u0278\t\7\2\2\u0277\u0276\3")
- buf.write("\2\2\2\u0277\u0278\3\2\2\2\u0278\u0279\3\2\2\2\u0279\u027a")
- buf.write("\t\t\2\2\u027a\u00aa\3\2\2\2\u027b\u027d\7)\2\2\u027c")
- buf.write("\u027e\t\7\2\2\u027d\u027c\3\2\2\2\u027d\u027e\3\2\2\2")
- buf.write("\u027e\u027f\3\2\2\2\u027f\u0280\t\n\2\2\u0280\u00ac\3")
- buf.write("\2\2\2\u0281\u0283\7)\2\2\u0282\u0284\t\7\2\2\u0283\u0282")
- buf.write("\3\2\2\2\u0283\u0284\3\2\2\2\u0284\u0285\3\2\2\2\u0285")
- buf.write("\u0286\t\13\2\2\u0286\u00ae\3\2\2\2\u0287\u0288\t\f\2")
- buf.write("\2\u0288\u00b0\3\2\2\2\u0289\u028a\t\r\2\2\u028a\u00b2")
- buf.write("\3\2\2\2\u028b\u028f\5\u00b9]\2\u028c\u028f\5\u00bb^\2")
- buf.write("\u028d\u028f\t\16\2\2\u028e\u028b\3\2\2\2\u028e\u028c")
- buf.write("\3\2\2\2\u028e\u028d\3\2\2\2\u028f\u00b4\3\2\2\2\u0290")
- buf.write("\u0294\5\u00b9]\2\u0291\u0294\5\u00bb^\2\u0292\u0294\t")
- buf.write("\17\2\2\u0293\u0290\3\2\2\2\u0293\u0291\3\2\2\2\u0293")
- buf.write("\u0292\3\2\2\2\u0294\u00b6\3\2\2\2\u0295\u0299\5\u00b9")
- buf.write("]\2\u0296\u0299\5\u00bb^\2\u0297\u0299\t\20\2\2\u0298")
- buf.write("\u0295\3\2\2\2\u0298\u0296\3\2\2\2\u0298\u0297\3\2\2\2")
- buf.write("\u0299\u00b8\3\2\2\2\u029a\u029b\t\21\2\2\u029b\u00ba")
- buf.write("\3\2\2\2\u029c\u029d\t\22\2\2\u029d\u00bc\3\2\2\2\'\2")
- buf.write("\u01cb\u01d1\u01db\u01df\u01eb\u01f7\u01fb\u0208\u020c")
- buf.write("\u0210\u0214\u021a\u0221\u0225\u022c\u022f\u0232\u0238")
- buf.write("\u023e\u024a\u024c\u0252\u0254\u025a\u025c\u0262\u0264")
- buf.write("\u026a\u026c\u0271\u0277\u027d\u0283\u028e\u0293\u0298")
- buf.write("\4\b\2\2\2\3\2")
- return buf.getvalue()
-
-
-class lfrXLexer(Lexer):
-
- atn = ATNDeserializer().deserialize(serializedATN())
-
- decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
-
- T__0 = 1
- T__1 = 2
- T__2 = 3
- T__3 = 4
- T__4 = 5
- T__5 = 6
- T__6 = 7
- T__7 = 8
- T__8 = 9
- T__9 = 10
- T__10 = 11
- T__11 = 12
- T__12 = 13
- T__13 = 14
- T__14 = 15
- T__15 = 16
- T__16 = 17
- T__17 = 18
- T__18 = 19
- T__19 = 20
- T__20 = 21
- T__21 = 22
- T__22 = 23
- T__23 = 24
- T__24 = 25
- T__25 = 26
- T__26 = 27
- T__27 = 28
- T__28 = 29
- T__29 = 30
- T__30 = 31
- T__31 = 32
- T__32 = 33
- T__33 = 34
- T__34 = 35
- T__35 = 36
- T__36 = 37
- T__37 = 38
- T__38 = 39
- T__39 = 40
- T__40 = 41
- T__41 = 42
- T__42 = 43
- T__43 = 44
- T__44 = 45
- T__45 = 46
- T__46 = 47
- T__47 = 48
- T__48 = 49
- T__49 = 50
- T__50 = 51
- T__51 = 52
- T__52 = 53
- T__53 = 54
- T__54 = 55
- T__55 = 56
- T__56 = 57
- T__57 = 58
- T__58 = 59
- T__59 = 60
- T__60 = 61
- T__61 = 62
- T__62 = 63
- T__63 = 64
- T__64 = 65
- ID = 66
- WS = 67
- One_line_comment = 68
- Block_comment = 69
- Import_line = 70
- Real_number = 71
- Decimal_number = 72
- Binary_number = 73
- Octal_number = 74
- Hex_number = 75
-
- channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ]
-
- modeNames = [ "DEFAULT_MODE" ]
-
- literalNames = [ "",
- "'endmodule'", "'module'", "'('", "')'", "';'", "','", "'finput'",
- "'foutput'", "'control'", "'distribute@'", "'begin'", "'end'",
- "'if'", "'else'", "'endcase'", "'case'", "':'", "'default'",
- "'<='", "'.'", "'signal'", "'flow'", "'storage'", "'pump'",
- "'number'", "'assign'", "'='", "'['", "']'", "'{'", "'}'", "'#MAP'",
- "'\"'", "'#MATERIAL'", "'#CONSTRAIN'", "'AND'", "'OR'", "'>'",
- "'<'", "'>='", "'+'", "'-'", "'!'", "'~'", "'&'", "'~&'", "'|'",
- "'~|'", "'^'", "'~^'", "'^~'", "'*'", "'/'", "'%'", "'=='",
- "'!='", "'==='", "'!=='", "'&&'", "'||'", "'**'", "'>>'", "'<<'",
- "'>>>'", "'<<<'" ]
-
- symbolicNames = [ "",
- "ID", "WS", "One_line_comment", "Block_comment", "Import_line",
- "Real_number", "Decimal_number", "Binary_number", "Octal_number",
- "Hex_number" ]
-
- ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6",
- "T__7", "T__8", "T__9", "T__10", "T__11", "T__12", "T__13",
- "T__14", "T__15", "T__16", "T__17", "T__18", "T__19",
- "T__20", "T__21", "T__22", "T__23", "T__24", "T__25",
- "T__26", "T__27", "T__28", "T__29", "T__30", "T__31",
- "T__32", "T__33", "T__34", "T__35", "T__36", "T__37",
- "T__38", "T__39", "T__40", "T__41", "T__42", "T__43",
- "T__44", "T__45", "T__46", "T__47", "T__48", "T__49",
- "T__50", "T__51", "T__52", "T__53", "T__54", "T__55",
- "T__56", "T__57", "T__58", "T__59", "T__60", "T__61",
- "T__62", "T__63", "T__64", "ID", "WS", "One_line_comment",
- "Block_comment", "Import_line", "Real_number", "Decimal_number",
- "Binary_number", "Octal_number", "Hex_number", "Sign",
- "Size", "Non_zero_unsigned_number", "Unsigned_number",
- "Binary_value", "Octal_value", "Hex_value", "Decimal_base",
- "Binary_base", "Octal_base", "Hex_base", "Non_zero_decimal_digit",
- "Decimal_digit", "Binary_digit", "Octal_digit", "Hex_digit",
- "X_digit", "Z_digit" ]
-
- grammarFileName = "lfrX.g4"
-
- def __init__(self, input=None, output:TextIO = sys.stdout):
- super().__init__(input, output)
- self.checkVersion("4.9.1")
- self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache())
- self._actions = None
- self._predicates = None
-
-
diff --git a/lfr/antlrgen/lfrXParser.py b/lfr/antlrgen/lfrXParser.py
deleted file mode 100755
index 386bc6e..0000000
--- a/lfr/antlrgen/lfrXParser.py
+++ /dev/null
@@ -1,4931 +0,0 @@
-# Generated from ./lfrX.g4 by ANTLR 4.9.1
-# encoding: utf-8
-from antlr4 import *
-from io import StringIO
-import sys
-if sys.version_info[1] > 5:
- from typing import TextIO
-else:
- from typing.io import TextIO
-
-
-def serializedATN():
- with StringIO() as buf:
- buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3M")
- buf.write("\u0253\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7")
- buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16")
- buf.write("\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23")
- buf.write("\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31")
- buf.write("\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36")
- buf.write("\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t")
- buf.write("&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4,\t,\4-\t-\4.\t.\4")
- buf.write("/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t\64")
- buf.write("\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t")
- buf.write(";\4<\t<\4=\t=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\3\2\6\2\u0086")
- buf.write("\n\2\r\2\16\2\u0087\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3")
- buf.write("\4\3\4\5\4\u0094\n\4\3\4\3\4\3\5\3\5\6\5\u009a\n\5\r\5")
- buf.write("\16\5\u009b\3\6\3\6\3\6\7\6\u00a1\n\6\f\6\16\6\u00a4\13")
- buf.write("\6\3\6\3\6\3\6\7\6\u00a9\n\6\f\6\16\6\u00ac\13\6\5\6\u00ae")
- buf.write("\n\6\3\7\3\7\5\7\u00b2\n\7\3\b\3\b\3\b\3\b\7\b\u00b8\n")
- buf.write("\b\f\b\16\b\u00bb\13\b\3\b\3\b\3\b\3\b\7\b\u00c1\n\b\f")
- buf.write("\b\16\b\u00c4\13\b\3\b\3\b\3\b\3\b\7\b\u00ca\n\b\f\b\16")
- buf.write("\b\u00cd\13\b\5\b\u00cf\n\b\3\t\5\t\u00d2\n\t\3\t\3\t")
- buf.write("\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\n\3\13\6\13\u00df\n\13")
- buf.write("\r\13\16\13\u00e0\3\f\3\f\3\f\5\f\u00e6\n\f\3\r\3\r\7")
- buf.write("\r\u00ea\n\r\f\r\16\r\u00ed\13\r\3\r\5\r\u00f0\n\r\3\16")
- buf.write("\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\20\3\20\3\20")
- buf.write("\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\22\3\22\6\22")
- buf.write("\u0108\n\22\r\22\16\22\u0109\3\22\3\22\3\22\5\22\u010f")
- buf.write("\n\22\3\23\3\23\6\23\u0113\n\23\r\23\16\23\u0114\3\23")
- buf.write("\5\23\u0118\n\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3")
- buf.write("\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\27\3\27\3\30")
- buf.write("\3\30\3\30\3\30\3\30\5\30\u0130\n\30\3\30\3\30\3\31\3")
- buf.write("\31\3\31\7\31\u0137\n\31\f\31\16\31\u013a\13\31\3\32\3")
- buf.write("\32\5\32\u013e\n\32\3\33\3\33\3\33\3\33\5\33\u0144\n\33")
- buf.write("\3\34\3\34\3\34\3\34\3\34\5\34\u014b\n\34\3\35\3\35\3")
- buf.write("\35\3\35\3\35\3\35\3\36\3\36\5\36\u0155\n\36\3\37\3\37")
- buf.write("\3\37\7\37\u015a\n\37\f\37\16\37\u015d\13\37\3 \3 \3 ")
- buf.write("\7 \u0162\n \f \16 \u0165\13 \3!\3!\3!\3!\3!\3!\3\"\3")
- buf.write("\"\3#\3#\3$\3$\3$\3$\3$\5$\u0176\n$\3%\3%\3%\3%\7%\u017c")
- buf.write("\n%\f%\16%\u017f\13%\3&\3&\3&\3&\7&\u0185\n&\f&\16&\u0188")
- buf.write("\13&\3\'\3\'\3\'\3\'\7\'\u018e\n\'\f\'\16\'\u0191\13\'")
- buf.write("\3(\3(\3(\3(\7(\u0197\n(\f(\16(\u019a\13(\3)\3)\3)\3)")
- buf.write("\7)\u01a0\n)\f)\16)\u01a3\13)\3*\3*\3*\3*\3*\5*\u01aa")
- buf.write("\n*\3+\3+\3+\3+\5+\u01b0\n+\3,\5,\u01b3\n,\3,\3,\3,\3")
- buf.write(",\3-\3-\5-\u01bb\n-\3-\3-\3-\5-\u01c0\n-\7-\u01c2\n-\f")
- buf.write("-\16-\u01c5\13-\3.\5.\u01c8\n.\3.\3.\5.\u01cc\n.\3/\3")
- buf.write("/\5/\u01d0\n/\3/\3/\3/\5/\u01d5\n/\7/\u01d7\n/\f/\16/")
- buf.write("\u01da\13/\3\60\3\60\3\60\3\60\3\61\3\61\3\62\3\62\3\62")
- buf.write("\3\62\5\62\u01e6\n\62\3\62\3\62\3\63\3\63\5\63\u01ec\n")
- buf.write("\63\3\64\3\64\3\64\3\64\7\64\u01f2\n\64\f\64\16\64\u01f5")
- buf.write("\13\64\3\64\3\64\5\64\u01f9\n\64\3\65\3\65\3\66\3\66\3")
- buf.write("\67\3\67\3\67\5\67\u0202\n\67\38\38\38\68\u0207\n8\r8")
- buf.write("\168\u0208\38\38\38\38\58\u020f\n8\38\38\39\39\39\39\3")
- buf.write(":\3:\5:\u0219\n:\3;\3;\3;\3;\3;\3;\3;\7;\u0222\n;\f;\16")
- buf.write(";\u0225\13;\3<\3<\3<\3<\5<\u022b\n<\3<\3<\3<\3<\5<\u0231")
- buf.write("\n<\3<\3<\3<\3<\5<\u0237\n<\3<\3<\3<\3<\5<\u023d\n<\3")
- buf.write("<\3<\3<\3<\5<\u0243\n<\5<\u0245\n<\3=\3=\3>\3>\3?\3?\3")
- buf.write("@\3@\3A\3A\3B\3B\3B\2\2C\2\4\6\b\n\f\16\20\22\24\26\30")
- buf.write("\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNPRTVXZ\\^`b")
- buf.write("dfhjlnprtvxz|~\u0080\u0082\2\t\4\2\31\32\34\34\3\2&\'")
- buf.write("\3\2+\65\7\2\25\25(,//\61\61\63C\3\2-\65\7\2//\61\61\63")
- buf.write("\659:=>\3\2IM\2\u025b\2\u0085\3\2\2\2\4\u0089\3\2\2\2")
- buf.write("\6\u008d\3\2\2\2\b\u0099\3\2\2\2\n\u00ad\3\2\2\2\f\u00af")
- buf.write("\3\2\2\2\16\u00ce\3\2\2\2\20\u00d1\3\2\2\2\22\u00d5\3")
- buf.write("\2\2\2\24\u00de\3\2\2\2\26\u00e5\3\2\2\2\30\u00e7\3\2")
- buf.write("\2\2\32\u00f1\3\2\2\2\34\u00f7\3\2\2\2\36\u00fa\3\2\2")
- buf.write("\2 \u0101\3\2\2\2\"\u010e\3\2\2\2$\u0110\3\2\2\2&\u011b")
- buf.write("\3\2\2\2(\u0120\3\2\2\2*\u0124\3\2\2\2,\u0128\3\2\2\2")
- buf.write(".\u012a\3\2\2\2\60\u0133\3\2\2\2\62\u013b\3\2\2\2\64\u0143")
- buf.write("\3\2\2\2\66\u014a\3\2\2\28\u014c\3\2\2\2:\u0154\3\2\2")
- buf.write("\2<\u0156\3\2\2\2>\u015e\3\2\2\2@\u0166\3\2\2\2B\u016c")
- buf.write("\3\2\2\2D\u016e\3\2\2\2F\u0175\3\2\2\2H\u0177\3\2\2\2")
- buf.write("J\u0180\3\2\2\2L\u0189\3\2\2\2N\u0192\3\2\2\2P\u019b\3")
- buf.write("\2\2\2R\u01a4\3\2\2\2T\u01ab\3\2\2\2V\u01b2\3\2\2\2X\u01ba")
- buf.write("\3\2\2\2Z\u01cb\3\2\2\2\\\u01cf\3\2\2\2^\u01db\3\2\2\2")
- buf.write("`\u01df\3\2\2\2b\u01e1\3\2\2\2d\u01eb\3\2\2\2f\u01ed\3")
- buf.write("\2\2\2h\u01fa\3\2\2\2j\u01fc\3\2\2\2l\u0201\3\2\2\2n\u0203")
- buf.write("\3\2\2\2p\u0212\3\2\2\2r\u0218\3\2\2\2t\u021a\3\2\2\2")
- buf.write("v\u0244\3\2\2\2x\u0246\3\2\2\2z\u0248\3\2\2\2|\u024a\3")
- buf.write("\2\2\2~\u024c\3\2\2\2\u0080\u024e\3\2\2\2\u0082\u0250")
- buf.write("\3\2\2\2\u0084\u0086\5\4\3\2\u0085\u0084\3\2\2\2\u0086")
- buf.write("\u0087\3\2\2\2\u0087\u0085\3\2\2\2\u0087\u0088\3\2\2\2")
- buf.write("\u0088\3\3\2\2\2\u0089\u008a\5\6\4\2\u008a\u008b\5\b\5")
- buf.write("\2\u008b\u008c\7\3\2\2\u008c\5\3\2\2\2\u008d\u008e\7\4")
- buf.write("\2\2\u008e\u0093\7D\2\2\u008f\u0090\7\5\2\2\u0090\u0091")
- buf.write("\5\n\6\2\u0091\u0092\7\6\2\2\u0092\u0094\3\2\2\2\u0093")
- buf.write("\u008f\3\2\2\2\u0093\u0094\3\2\2\2\u0094\u0095\3\2\2\2")
- buf.write("\u0095\u0096\7\7\2\2\u0096\7\3\2\2\2\u0097\u009a\5\64")
- buf.write("\33\2\u0098\u009a\5\22\n\2\u0099\u0097\3\2\2\2\u0099\u0098")
- buf.write("\3\2\2\2\u009a\u009b\3\2\2\2\u009b\u0099\3\2\2\2\u009b")
- buf.write("\u009c\3\2\2\2\u009c\t\3\2\2\2\u009d\u00a2\5\f\7\2\u009e")
- buf.write("\u009f\7\b\2\2\u009f\u00a1\5\f\7\2\u00a0\u009e\3\2\2\2")
- buf.write("\u00a1\u00a4\3\2\2\2\u00a2\u00a0\3\2\2\2\u00a2\u00a3\3")
- buf.write("\2\2\2\u00a3\u00ae\3\2\2\2\u00a4\u00a2\3\2\2\2\u00a5\u00aa")
- buf.write("\5\16\b\2\u00a6\u00a7\7\b\2\2\u00a7\u00a9\5\16\b\2\u00a8")
- buf.write("\u00a6\3\2\2\2\u00a9\u00ac\3\2\2\2\u00aa\u00a8\3\2\2\2")
- buf.write("\u00aa\u00ab\3\2\2\2\u00ab\u00ae\3\2\2\2\u00ac\u00aa\3")
- buf.write("\2\2\2\u00ad\u009d\3\2\2\2\u00ad\u00a5\3\2\2\2\u00ae\13")
- buf.write("\3\2\2\2\u00af\u00b1\7D\2\2\u00b0\u00b2\5b\62\2\u00b1")
- buf.write("\u00b0\3\2\2\2\u00b1\u00b2\3\2\2\2\u00b2\r\3\2\2\2\u00b3")
- buf.write("\u00b4\7\t\2\2\u00b4\u00b9\5\20\t\2\u00b5\u00b6\7\b\2")
- buf.write("\2\u00b6\u00b8\5\20\t\2\u00b7\u00b5\3\2\2\2\u00b8\u00bb")
- buf.write("\3\2\2\2\u00b9\u00b7\3\2\2\2\u00b9\u00ba\3\2\2\2\u00ba")
- buf.write("\u00cf\3\2\2\2\u00bb\u00b9\3\2\2\2\u00bc\u00bd\7\n\2\2")
- buf.write("\u00bd\u00c2\5\20\t\2\u00be\u00bf\7\b\2\2\u00bf\u00c1")
- buf.write("\5\20\t\2\u00c0\u00be\3\2\2\2\u00c1\u00c4\3\2\2\2\u00c2")
- buf.write("\u00c0\3\2\2\2\u00c2\u00c3\3\2\2\2\u00c3\u00cf\3\2\2\2")
- buf.write("\u00c4\u00c2\3\2\2\2\u00c5\u00c6\7\13\2\2\u00c6\u00cb")
- buf.write("\5\20\t\2\u00c7\u00c8\7\b\2\2\u00c8\u00ca\5\20\t\2\u00c9")
- buf.write("\u00c7\3\2\2\2\u00ca\u00cd\3\2\2\2\u00cb\u00c9\3\2\2\2")
- buf.write("\u00cb\u00cc\3\2\2\2\u00cc\u00cf\3\2\2\2\u00cd\u00cb\3")
- buf.write("\2\2\2\u00ce\u00b3\3\2\2\2\u00ce\u00bc\3\2\2\2\u00ce\u00c5")
- buf.write("\3\2\2\2\u00cf\17\3\2\2\2\u00d0\u00d2\5b\62\2\u00d1\u00d0")
- buf.write("\3\2\2\2\u00d1\u00d2\3\2\2\2\u00d2\u00d3\3\2\2\2\u00d3")
- buf.write("\u00d4\7D\2\2\u00d4\21\3\2\2\2\u00d5\u00d6\7\f\2\2\u00d6")
- buf.write("\u00d7\7\5\2\2\u00d7\u00d8\5\60\31\2\u00d8\u00d9\7\6\2")
- buf.write("\2\u00d9\u00da\7\r\2\2\u00da\u00db\5\24\13\2\u00db\u00dc")
- buf.write("\7\16\2\2\u00dc\23\3\2\2\2\u00dd\u00df\5\26\f\2\u00de")
- buf.write("\u00dd\3\2\2\2\u00df\u00e0\3\2\2\2\u00e0\u00de\3\2\2\2")
- buf.write("\u00e0\u00e1\3\2\2\2\u00e1\25\3\2\2\2\u00e2\u00e6\5.\30")
- buf.write("\2\u00e3\u00e6\5$\23\2\u00e4\u00e6\5\30\r\2\u00e5\u00e2")
- buf.write("\3\2\2\2\u00e5\u00e3\3\2\2\2\u00e5\u00e4\3\2\2\2\u00e6")
- buf.write("\27\3\2\2\2\u00e7\u00eb\5\32\16\2\u00e8\u00ea\5\36\20")
- buf.write("\2\u00e9\u00e8\3\2\2\2\u00ea\u00ed\3\2\2\2\u00eb\u00e9")
- buf.write("\3\2\2\2\u00eb\u00ec\3\2\2\2\u00ec\u00ef\3\2\2\2\u00ed")
- buf.write("\u00eb\3\2\2\2\u00ee\u00f0\5\34\17\2\u00ef\u00ee\3\2\2")
- buf.write("\2\u00ef\u00f0\3\2\2\2\u00f0\31\3\2\2\2\u00f1\u00f2\7")
- buf.write("\17\2\2\u00f2\u00f3\7\5\2\2\u00f3\u00f4\5 \21\2\u00f4")
- buf.write("\u00f5\7\6\2\2\u00f5\u00f6\5\"\22\2\u00f6\33\3\2\2\2\u00f7")
- buf.write("\u00f8\7\20\2\2\u00f8\u00f9\5\"\22\2\u00f9\35\3\2\2\2")
- buf.write("\u00fa\u00fb\7\20\2\2\u00fb\u00fc\7\17\2\2\u00fc\u00fd")
- buf.write("\7\5\2\2\u00fd\u00fe\5 \21\2\u00fe\u00ff\7\6\2\2\u00ff")
- buf.write("\u0100\5\"\22\2\u0100\37\3\2\2\2\u0101\u0102\5h\65\2\u0102")
- buf.write("\u0103\5\u0080A\2\u0103\u0104\5,\27\2\u0104!\3\2\2\2\u0105")
- buf.write("\u0107\7\r\2\2\u0106\u0108\5.\30\2\u0107\u0106\3\2\2\2")
- buf.write("\u0108\u0109\3\2\2\2\u0109\u0107\3\2\2\2\u0109\u010a\3")
- buf.write("\2\2\2\u010a\u010b\3\2\2\2\u010b\u010c\7\16\2\2\u010c")
- buf.write("\u010f\3\2\2\2\u010d\u010f\5.\30\2\u010e\u0105\3\2\2\2")
- buf.write("\u010e\u010d\3\2\2\2\u010f#\3\2\2\2\u0110\u0112\5&\24")
- buf.write("\2\u0111\u0113\5(\25\2\u0112\u0111\3\2\2\2\u0113\u0114")
- buf.write("\3\2\2\2\u0114\u0112\3\2\2\2\u0114\u0115\3\2\2\2\u0115")
- buf.write("\u0117\3\2\2\2\u0116\u0118\5*\26\2\u0117\u0116\3\2\2\2")
- buf.write("\u0117\u0118\3\2\2\2\u0118\u0119\3\2\2\2\u0119\u011a\7")
- buf.write("\21\2\2\u011a%\3\2\2\2\u011b\u011c\7\22\2\2\u011c\u011d")
- buf.write("\7\5\2\2\u011d\u011e\5h\65\2\u011e\u011f\7\6\2\2\u011f")
- buf.write("\'\3\2\2\2\u0120\u0121\5,\27\2\u0121\u0122\7\23\2\2\u0122")
- buf.write("\u0123\5\"\22\2\u0123)\3\2\2\2\u0124\u0125\7\24\2\2\u0125")
- buf.write("\u0126\7\23\2\2\u0126\u0127\5\"\22\2\u0127+\3\2\2\2\u0128")
- buf.write("\u0129\5\u0082B\2\u0129-\3\2\2\2\u012a\u012b\5h\65\2\u012b")
- buf.write("\u012f\7\25\2\2\u012c\u0130\5\u0082B\2\u012d\u0130\5d")
- buf.write("\63\2\u012e\u0130\5X-\2\u012f\u012c\3\2\2\2\u012f\u012d")
- buf.write("\3\2\2\2\u012f\u012e\3\2\2\2\u0130\u0131\3\2\2\2\u0131")
- buf.write("\u0132\7\7\2\2\u0132/\3\2\2\2\u0133\u0138\5\62\32\2\u0134")
- buf.write("\u0135\7\b\2\2\u0135\u0137\5\62\32\2\u0136\u0134\3\2\2")
- buf.write("\2\u0137\u013a\3\2\2\2\u0138\u0136\3\2\2\2\u0138\u0139")
- buf.write("\3\2\2\2\u0139\61\3\2\2\2\u013a\u0138\3\2\2\2\u013b\u013d")
- buf.write("\7D\2\2\u013c\u013e\5b\62\2\u013d\u013c\3\2\2\2\u013d")
- buf.write("\u013e\3\2\2\2\u013e\63\3\2\2\2\u013f\u0140\5\66\34\2")
- buf.write("\u0140\u0141\7\7\2\2\u0141\u0144\3\2\2\2\u0142\u0144\5")
- buf.write("l\67\2\u0143\u013f\3\2\2\2\u0143\u0142\3\2\2\2\u0144\65")
- buf.write("\3\2\2\2\u0145\u014b\5j\66\2\u0146\u014b\5R*\2\u0147\u014b")
- buf.write("\5F$\2\u0148\u014b\5T+\2\u0149\u014b\58\35\2\u014a\u0145")
- buf.write("\3\2\2\2\u014a\u0146\3\2\2\2\u014a\u0147\3\2\2\2\u014a")
- buf.write("\u0148\3\2\2\2\u014a\u0149\3\2\2\2\u014b\67\3\2\2\2\u014c")
- buf.write("\u014d\5D#\2\u014d\u014e\5B\"\2\u014e\u014f\7\5\2\2\u014f")
- buf.write("\u0150\5:\36\2\u0150\u0151\7\6\2\2\u01519\3\2\2\2\u0152")
- buf.write("\u0155\5<\37\2\u0153\u0155\5> \2\u0154\u0152\3\2\2\2\u0154")
- buf.write("\u0153\3\2\2\2\u0155;\3\2\2\2\u0156\u015b\5\f\7\2\u0157")
- buf.write("\u0158\7\b\2\2\u0158\u015a\5\f\7\2\u0159\u0157\3\2\2\2")
- buf.write("\u015a\u015d\3\2\2\2\u015b\u0159\3\2\2\2\u015b\u015c\3")
- buf.write("\2\2\2\u015c=\3\2\2\2\u015d\u015b\3\2\2\2\u015e\u0163")
- buf.write("\5@!\2\u015f\u0160\7\b\2\2\u0160\u0162\5@!\2\u0161\u015f")
- buf.write("\3\2\2\2\u0162\u0165\3\2\2\2\u0163\u0161\3\2\2\2\u0163")
- buf.write("\u0164\3\2\2\2\u0164?\3\2\2\2\u0165\u0163\3\2\2\2\u0166")
- buf.write("\u0167\7\26\2\2\u0167\u0168\7D\2\2\u0168\u0169\7\5\2\2")
- buf.write("\u0169\u016a\5d\63\2\u016a\u016b\7\6\2\2\u016bA\3\2\2")
- buf.write("\2\u016c\u016d\7D\2\2\u016dC\3\2\2\2\u016e\u016f\7D\2")
- buf.write("\2\u016fE\3\2\2\2\u0170\u0176\5J&\2\u0171\u0176\5L\'\2")
- buf.write("\u0172\u0176\5P)\2\u0173\u0176\5H%\2\u0174\u0176\5N(\2")
- buf.write("\u0175\u0170\3\2\2\2\u0175\u0171\3\2\2\2\u0175\u0172\3")
- buf.write("\2\2\2\u0175\u0173\3\2\2\2\u0175\u0174\3\2\2\2\u0176G")
- buf.write("\3\2\2\2\u0177\u0178\7\27\2\2\u0178\u017d\5\20\t\2\u0179")
- buf.write("\u017a\7\b\2\2\u017a\u017c\5\20\t\2\u017b\u0179\3\2\2")
- buf.write("\2\u017c\u017f\3\2\2\2\u017d\u017b\3\2\2\2\u017d\u017e")
- buf.write("\3\2\2\2\u017eI\3\2\2\2\u017f\u017d\3\2\2\2\u0180\u0181")
- buf.write("\7\30\2\2\u0181\u0186\5\20\t\2\u0182\u0183\7\b\2\2\u0183")
- buf.write("\u0185\5\20\t\2\u0184\u0182\3\2\2\2\u0185\u0188\3\2\2")
- buf.write("\2\u0186\u0184\3\2\2\2\u0186\u0187\3\2\2\2\u0187K\3\2")
- buf.write("\2\2\u0188\u0186\3\2\2\2\u0189\u018a\7\31\2\2\u018a\u018f")
- buf.write("\5\20\t\2\u018b\u018c\7\b\2\2\u018c\u018e\5\20\t\2\u018d")
- buf.write("\u018b\3\2\2\2\u018e\u0191\3\2\2\2\u018f\u018d\3\2\2\2")
- buf.write("\u018f\u0190\3\2\2\2\u0190M\3\2\2\2\u0191\u018f\3\2\2")
- buf.write("\2\u0192\u0193\7\32\2\2\u0193\u0198\5\20\t\2\u0194\u0195")
- buf.write("\7\b\2\2\u0195\u0197\5\20\t\2\u0196\u0194\3\2\2\2\u0197")
- buf.write("\u019a\3\2\2\2\u0198\u0196\3\2\2\2\u0198\u0199\3\2\2\2")
- buf.write("\u0199O\3\2\2\2\u019a\u0198\3\2\2\2\u019b\u019c\7\33\2")
- buf.write("\2\u019c\u01a1\5T+\2\u019d\u019e\7\b\2\2\u019e\u01a0\5")
- buf.write("T+\2\u019f\u019d\3\2\2\2\u01a0\u01a3\3\2\2\2\u01a1\u019f")
- buf.write("\3\2\2\2\u01a1\u01a2\3\2\2\2\u01a2Q\3\2\2\2\u01a3\u01a1")
- buf.write("\3\2\2\2\u01a4\u01a5\7\34\2\2\u01a5\u01a6\5h\65\2\u01a6")
- buf.write("\u01a9\7\35\2\2\u01a7\u01aa\5V,\2\u01a8\u01aa\5X-\2\u01a9")
- buf.write("\u01a7\3\2\2\2\u01a9\u01a8\3\2\2\2\u01aaS\3\2\2\2\u01ab")
- buf.write("\u01ac\7D\2\2\u01ac\u01af\7\35\2\2\u01ad\u01b0\5V,\2\u01ae")
- buf.write("\u01b0\5X-\2\u01af\u01ad\3\2\2\2\u01af\u01ae\3\2\2\2\u01b0")
- buf.write("U\3\2\2\2\u01b1\u01b3\5z>\2\u01b2\u01b1\3\2\2\2\u01b2")
- buf.write("\u01b3\3\2\2\2\u01b3\u01b4\3\2\2\2\u01b4\u01b5\7\5\2\2")
- buf.write("\u01b5\u01b6\5X-\2\u01b6\u01b7\7\6\2\2\u01b7W\3\2\2\2")
- buf.write("\u01b8\u01bb\5V,\2\u01b9\u01bb\5Z.\2\u01ba\u01b8\3\2\2")
- buf.write("\2\u01ba\u01b9\3\2\2\2\u01bb\u01c3\3\2\2\2\u01bc\u01bf")
- buf.write("\5|?\2\u01bd\u01c0\5V,\2\u01be\u01c0\5Z.\2\u01bf\u01bd")
- buf.write("\3\2\2\2\u01bf\u01be\3\2\2\2\u01c0\u01c2\3\2\2\2\u01c1")
- buf.write("\u01bc\3\2\2\2\u01c2\u01c5\3\2\2\2\u01c3\u01c1\3\2\2\2")
- buf.write("\u01c3\u01c4\3\2\2\2\u01c4Y\3\2\2\2\u01c5\u01c3\3\2\2")
- buf.write("\2\u01c6\u01c8\5z>\2\u01c7\u01c6\3\2\2\2\u01c7\u01c8\3")
- buf.write("\2\2\2\u01c8\u01c9\3\2\2\2\u01c9\u01cc\5d\63\2\u01ca\u01cc")
- buf.write("\5\u0082B\2\u01cb\u01c7\3\2\2\2\u01cb\u01ca\3\2\2\2\u01cc")
- buf.write("[\3\2\2\2\u01cd\u01d0\5V,\2\u01ce\u01d0\5Z.\2\u01cf\u01cd")
- buf.write("\3\2\2\2\u01cf\u01ce\3\2\2\2\u01d0\u01d8\3\2\2\2\u01d1")
- buf.write("\u01d4\5|?\2\u01d2\u01d5\5V,\2\u01d3\u01d5\5Z.\2\u01d4")
- buf.write("\u01d2\3\2\2\2\u01d4\u01d3\3\2\2\2\u01d5\u01d7\3\2\2\2")
- buf.write("\u01d6\u01d1\3\2\2\2\u01d7\u01da\3\2\2\2\u01d8\u01d6\3")
- buf.write("\2\2\2\u01d8\u01d9\3\2\2\2\u01d9]\3\2\2\2\u01da\u01d8")
- buf.write("\3\2\2\2\u01db\u01dc\5\\/\2\u01dc\u01dd\5\u0080A\2\u01dd")
- buf.write("\u01de\5`\61\2\u01de_\3\2\2\2\u01df\u01e0\5\u0082B\2\u01e0")
- buf.write("a\3\2\2\2\u01e1\u01e2\7\36\2\2\u01e2\u01e5\7J\2\2\u01e3")
- buf.write("\u01e4\7\23\2\2\u01e4\u01e6\7J\2\2\u01e5\u01e3\3\2\2\2")
- buf.write("\u01e5\u01e6\3\2\2\2\u01e6\u01e7\3\2\2\2\u01e7\u01e8\7")
- buf.write("\37\2\2\u01e8c\3\2\2\2\u01e9\u01ec\5\f\7\2\u01ea\u01ec")
- buf.write("\5f\64\2\u01eb\u01e9\3\2\2\2\u01eb\u01ea\3\2\2\2\u01ec")
- buf.write("e\3\2\2\2\u01ed\u01ee\7 \2\2\u01ee\u01f3\5\f\7\2\u01ef")
- buf.write("\u01f0\7\b\2\2\u01f0\u01f2\5\f\7\2\u01f1\u01ef\3\2\2\2")
- buf.write("\u01f2\u01f5\3\2\2\2\u01f3\u01f1\3\2\2\2\u01f3\u01f4\3")
- buf.write("\2\2\2\u01f4\u01f6\3\2\2\2\u01f5\u01f3\3\2\2\2\u01f6\u01f8")
- buf.write("\7!\2\2\u01f7\u01f9\5b\62\2\u01f8\u01f7\3\2\2\2\u01f8")
- buf.write("\u01f9\3\2\2\2\u01f9g\3\2\2\2\u01fa\u01fb\5d\63\2\u01fb")
- buf.write("i\3\2\2\2\u01fc\u01fd\5\16\b\2\u01fdk\3\2\2\2\u01fe\u0202")
- buf.write("\5t;\2\u01ff\u0202\5n8\2\u0200\u0202\5p9\2\u0201\u01fe")
- buf.write("\3\2\2\2\u0201\u01ff\3\2\2\2\u0201\u0200\3\2\2\2\u0202")
- buf.write("m\3\2\2\2\u0203\u0204\7\"\2\2\u0204\u0206\7#\2\2\u0205")
- buf.write("\u0207\7D\2\2\u0206\u0205\3\2\2\2\u0207\u0208\3\2\2\2")
- buf.write("\u0208\u0206\3\2\2\2\u0208\u0209\3\2\2\2\u0209\u020a\3")
- buf.write("\2\2\2\u020a\u020b\7#\2\2\u020b\u020e\7#\2\2\u020c\u020f")
- buf.write("\5r:\2\u020d\u020f\t\2\2\2\u020e\u020c\3\2\2\2\u020e\u020d")
- buf.write("\3\2\2\2\u020f\u0210\3\2\2\2\u0210\u0211\7#\2\2\u0211")
- buf.write("o\3\2\2\2\u0212\u0213\7$\2\2\u0213\u0214\7D\2\2\u0214")
- buf.write("\u0215\7D\2\2\u0215q\3\2\2\2\u0216\u0219\5|?\2\u0217\u0219")
- buf.write("\5z>\2\u0218\u0216\3\2\2\2\u0218\u0217\3\2\2\2\u0219s")
- buf.write("\3\2\2\2\u021a\u021b\7%\2\2\u021b\u021c\7#\2\2\u021c\u021d")
- buf.write("\5r:\2\u021d\u021e\7#\2\2\u021e\u0223\5v<\2\u021f\u0220")
- buf.write("\t\3\2\2\u0220\u0222\5v<\2\u0221\u021f\3\2\2\2\u0222\u0225")
- buf.write("\3\2\2\2\u0223\u0221\3\2\2\2\u0223\u0224\3\2\2\2\u0224")
- buf.write("u\3\2\2\2\u0225\u0223\3\2\2\2\u0226\u0227\7D\2\2\u0227")
- buf.write("\u0228\7\35\2\2\u0228\u022a\5\u0082B\2\u0229\u022b\5x")
- buf.write("=\2\u022a\u0229\3\2\2\2\u022a\u022b\3\2\2\2\u022b\u0245")
- buf.write("\3\2\2\2\u022c\u022d\7D\2\2\u022d\u022e\7(\2\2\u022e\u0230")
- buf.write("\5\u0082B\2\u022f\u0231\5x=\2\u0230\u022f\3\2\2\2\u0230")
- buf.write("\u0231\3\2\2\2\u0231\u0245\3\2\2\2\u0232\u0233\7D\2\2")
- buf.write("\u0233\u0234\7)\2\2\u0234\u0236\5\u0082B\2\u0235\u0237")
- buf.write("\5x=\2\u0236\u0235\3\2\2\2\u0236\u0237\3\2\2\2\u0237\u0245")
- buf.write("\3\2\2\2\u0238\u0239\7D\2\2\u0239\u023a\7*\2\2\u023a\u023c")
- buf.write("\5\u0082B\2\u023b\u023d\5x=\2\u023c\u023b\3\2\2\2\u023c")
- buf.write("\u023d\3\2\2\2\u023d\u0245\3\2\2\2\u023e\u023f\7D\2\2")
- buf.write("\u023f\u0240\7\25\2\2\u0240\u0242\5\u0082B\2\u0241\u0243")
- buf.write("\5x=\2\u0242\u0241\3\2\2\2\u0242\u0243\3\2\2\2\u0243\u0245")
- buf.write("\3\2\2\2\u0244\u0226\3\2\2\2\u0244\u022c\3\2\2\2\u0244")
- buf.write("\u0232\3\2\2\2\u0244\u0238\3\2\2\2\u0244\u023e\3\2\2\2")
- buf.write("\u0245w\3\2\2\2\u0246\u0247\7D\2\2\u0247y\3\2\2\2\u0248")
- buf.write("\u0249\t\4\2\2\u0249{\3\2\2\2\u024a\u024b\t\5\2\2\u024b")
- buf.write("}\3\2\2\2\u024c\u024d\t\6\2\2\u024d\177\3\2\2\2\u024e")
- buf.write("\u024f\t\7\2\2\u024f\u0081\3\2\2\2\u0250\u0251\t\b\2\2")
- buf.write("\u0251\u0083\3\2\2\2?\u0087\u0093\u0099\u009b\u00a2\u00aa")
- buf.write("\u00ad\u00b1\u00b9\u00c2\u00cb\u00ce\u00d1\u00e0\u00e5")
- buf.write("\u00eb\u00ef\u0109\u010e\u0114\u0117\u012f\u0138\u013d")
- buf.write("\u0143\u014a\u0154\u015b\u0163\u0175\u017d\u0186\u018f")
- buf.write("\u0198\u01a1\u01a9\u01af\u01b2\u01ba\u01bf\u01c3\u01c7")
- buf.write("\u01cb\u01cf\u01d4\u01d8\u01e5\u01eb\u01f3\u01f8\u0201")
- buf.write("\u0208\u020e\u0218\u0223\u022a\u0230\u0236\u023c\u0242")
- buf.write("\u0244")
- return buf.getvalue()
-
-
-class lfrXParser ( Parser ):
-
- grammarFileName = "lfrX.g4"
-
- atn = ATNDeserializer().deserialize(serializedATN())
-
- decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ]
-
- sharedContextCache = PredictionContextCache()
-
- literalNames = [ "", "'endmodule'", "'module'", "'('", "')'",
- "';'", "','", "'finput'", "'foutput'", "'control'",
- "'distribute@'", "'begin'", "'end'", "'if'", "'else'",
- "'endcase'", "'case'", "':'", "'default'", "'<='",
- "'.'", "'signal'", "'flow'", "'storage'", "'pump'",
- "'number'", "'assign'", "'='", "'['", "']'", "'{'",
- "'}'", "'#MAP'", "'\"'", "'#MATERIAL'", "'#CONSTRAIN'",
- "'AND'", "'OR'", "'>'", "'<'", "'>='", "'+'", "'-'",
- "'!'", "'~'", "'&'", "'~&'", "'|'", "'~|'", "'^'",
- "'~^'", "'^~'", "'*'", "'/'", "'%'", "'=='", "'!='",
- "'==='", "'!=='", "'&&'", "'||'", "'**'", "'>>'", "'<<'",
- "'>>>'", "'<<<'" ]
-
- symbolicNames = [ "", "", "", "",
- "", "", "", "",
- "", "", "", "",
- "", "", "", "",
- "", "", "", "",
- "", "", "", "",
- "", "", "", "",
- "", "", "", "",
- "", "", "", "",
- "", "", "", "",
- "", "", "", "",
- "", "", "", "",
- "", "", "", "",
- "", "", "", "",
- "", "", "", "",
- "", "", "", "",
- "", "", "ID", "WS", "One_line_comment",
- "Block_comment", "Import_line", "Real_number", "Decimal_number",
- "Binary_number", "Octal_number", "Hex_number" ]
-
- RULE_skeleton = 0
- RULE_module = 1
- RULE_moduledefinition = 2
- RULE_body = 3
- RULE_ioblock = 4
- RULE_vectorvar = 5
- RULE_explicitIOBlock = 6
- RULE_declvar = 7
- RULE_distributionBlock = 8
- RULE_distributionBody = 9
- RULE_distributeBodyStat = 10
- RULE_ifElseBlock = 11
- RULE_ifBlock = 12
- RULE_elseBlock = 13
- RULE_elseIfBlock = 14
- RULE_distributeCondition = 15
- RULE_statementBlock = 16
- RULE_caseBlock = 17
- RULE_caseBlockHeader = 18
- RULE_casestat = 19
- RULE_defaultCaseStat = 20
- RULE_distvalue = 21
- RULE_distributionassignstat = 22
- RULE_sensitivitylist = 23
- RULE_signal = 24
- RULE_statements = 25
- RULE_statement = 26
- RULE_moduleinstantiationstat = 27
- RULE_instanceioblock = 28
- RULE_orderedioblock = 29
- RULE_unorderedioblock = 30
- RULE_explicitinstanceiomapping = 31
- RULE_instancename = 32
- RULE_moduletype = 33
- RULE_tempvariablesstat = 34
- RULE_signalvarstat = 35
- RULE_fluiddeclstat = 36
- RULE_storagestat = 37
- RULE_pumpvarstat = 38
- RULE_numvarstat = 39
- RULE_assignstat = 40
- RULE_literalassignstat = 41
- RULE_bracketexpression = 42
- RULE_expression = 43
- RULE_expressionterm = 44
- RULE_logiccondition_operand = 45
- RULE_logiccondition = 46
- RULE_logic_value = 47
- RULE_vector = 48
- RULE_variables = 49
- RULE_concatenation = 50
- RULE_lhs = 51
- RULE_ioassignstat = 52
- RULE_technologydirectives = 53
- RULE_technologymappingdirective = 54
- RULE_materialmappingdirective = 55
- RULE_mappingoperator = 56
- RULE_performancedirective = 57
- RULE_constraint = 58
- RULE_unit = 59
- RULE_unary_operator = 60
- RULE_binary_operator = 61
- RULE_unary_module_path_operator = 62
- RULE_binary_module_path_operator = 63
- RULE_number = 64
-
- ruleNames = [ "skeleton", "module", "moduledefinition", "body", "ioblock",
- "vectorvar", "explicitIOBlock", "declvar", "distributionBlock",
- "distributionBody", "distributeBodyStat", "ifElseBlock",
- "ifBlock", "elseBlock", "elseIfBlock", "distributeCondition",
- "statementBlock", "caseBlock", "caseBlockHeader", "casestat",
- "defaultCaseStat", "distvalue", "distributionassignstat",
- "sensitivitylist", "signal", "statements", "statement",
- "moduleinstantiationstat", "instanceioblock", "orderedioblock",
- "unorderedioblock", "explicitinstanceiomapping", "instancename",
- "moduletype", "tempvariablesstat", "signalvarstat", "fluiddeclstat",
- "storagestat", "pumpvarstat", "numvarstat", "assignstat",
- "literalassignstat", "bracketexpression", "expression",
- "expressionterm", "logiccondition_operand", "logiccondition",
- "logic_value", "vector", "variables", "concatenation",
- "lhs", "ioassignstat", "technologydirectives", "technologymappingdirective",
- "materialmappingdirective", "mappingoperator", "performancedirective",
- "constraint", "unit", "unary_operator", "binary_operator",
- "unary_module_path_operator", "binary_module_path_operator",
- "number" ]
-
- EOF = Token.EOF
- T__0=1
- T__1=2
- T__2=3
- T__3=4
- T__4=5
- T__5=6
- T__6=7
- T__7=8
- T__8=9
- T__9=10
- T__10=11
- T__11=12
- T__12=13
- T__13=14
- T__14=15
- T__15=16
- T__16=17
- T__17=18
- T__18=19
- T__19=20
- T__20=21
- T__21=22
- T__22=23
- T__23=24
- T__24=25
- T__25=26
- T__26=27
- T__27=28
- T__28=29
- T__29=30
- T__30=31
- T__31=32
- T__32=33
- T__33=34
- T__34=35
- T__35=36
- T__36=37
- T__37=38
- T__38=39
- T__39=40
- T__40=41
- T__41=42
- T__42=43
- T__43=44
- T__44=45
- T__45=46
- T__46=47
- T__47=48
- T__48=49
- T__49=50
- T__50=51
- T__51=52
- T__52=53
- T__53=54
- T__54=55
- T__55=56
- T__56=57
- T__57=58
- T__58=59
- T__59=60
- T__60=61
- T__61=62
- T__62=63
- T__63=64
- T__64=65
- ID=66
- WS=67
- One_line_comment=68
- Block_comment=69
- Import_line=70
- Real_number=71
- Decimal_number=72
- Binary_number=73
- Octal_number=74
- Hex_number=75
-
- def __init__(self, input:TokenStream, output:TextIO = sys.stdout):
- super().__init__(input, output)
- self.checkVersion("4.9.1")
- self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache)
- self._predicates = None
-
-
-
-
- class SkeletonContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def module(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.ModuleContext)
- else:
- return self.getTypedRuleContext(lfrXParser.ModuleContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_skeleton
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterSkeleton" ):
- listener.enterSkeleton(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitSkeleton" ):
- listener.exitSkeleton(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitSkeleton" ):
- return visitor.visitSkeleton(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def skeleton(self):
-
- localctx = lfrXParser.SkeletonContext(self, self._ctx, self.state)
- self.enterRule(localctx, 0, self.RULE_skeleton)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 131
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while True:
- self.state = 130
- self.module()
- self.state = 133
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if not (_la==lfrXParser.T__1):
- break
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class ModuleContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def moduledefinition(self):
- return self.getTypedRuleContext(lfrXParser.ModuledefinitionContext,0)
-
-
- def body(self):
- return self.getTypedRuleContext(lfrXParser.BodyContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_module
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterModule" ):
- listener.enterModule(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitModule" ):
- listener.exitModule(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitModule" ):
- return visitor.visitModule(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def module(self):
-
- localctx = lfrXParser.ModuleContext(self, self._ctx, self.state)
- self.enterRule(localctx, 2, self.RULE_module)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 135
- self.moduledefinition()
- self.state = 136
- self.body()
- self.state = 137
- self.match(lfrXParser.T__0)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class ModuledefinitionContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def ID(self):
- return self.getToken(lfrXParser.ID, 0)
-
- def ioblock(self):
- return self.getTypedRuleContext(lfrXParser.IoblockContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_moduledefinition
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterModuledefinition" ):
- listener.enterModuledefinition(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitModuledefinition" ):
- listener.exitModuledefinition(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitModuledefinition" ):
- return visitor.visitModuledefinition(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def moduledefinition(self):
-
- localctx = lfrXParser.ModuledefinitionContext(self, self._ctx, self.state)
- self.enterRule(localctx, 4, self.RULE_moduledefinition)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 139
- self.match(lfrXParser.T__1)
- self.state = 140
- self.match(lfrXParser.ID)
- self.state = 145
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if _la==lfrXParser.T__2:
- self.state = 141
- self.match(lfrXParser.T__2)
- self.state = 142
- self.ioblock()
- self.state = 143
- self.match(lfrXParser.T__3)
-
-
- self.state = 147
- self.match(lfrXParser.T__4)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class BodyContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def statements(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.StatementsContext)
- else:
- return self.getTypedRuleContext(lfrXParser.StatementsContext,i)
-
-
- def distributionBlock(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.DistributionBlockContext)
- else:
- return self.getTypedRuleContext(lfrXParser.DistributionBlockContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_body
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterBody" ):
- listener.enterBody(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitBody" ):
- listener.exitBody(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitBody" ):
- return visitor.visitBody(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def body(self):
-
- localctx = lfrXParser.BodyContext(self, self._ctx, self.state)
- self.enterRule(localctx, 6, self.RULE_body)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 151
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while True:
- self.state = 151
- self._errHandler.sync(self)
- token = self._input.LA(1)
- if token in [lfrXParser.T__6, lfrXParser.T__7, lfrXParser.T__8, lfrXParser.T__20, lfrXParser.T__21, lfrXParser.T__22, lfrXParser.T__23, lfrXParser.T__24, lfrXParser.T__25, lfrXParser.T__31, lfrXParser.T__33, lfrXParser.T__34, lfrXParser.ID]:
- self.state = 149
- self.statements()
- pass
- elif token in [lfrXParser.T__9]:
- self.state = 150
- self.distributionBlock()
- pass
- else:
- raise NoViableAltException(self)
-
- self.state = 153
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if not (((((_la - 7)) & ~0x3f) == 0 and ((1 << (_la - 7)) & ((1 << (lfrXParser.T__6 - 7)) | (1 << (lfrXParser.T__7 - 7)) | (1 << (lfrXParser.T__8 - 7)) | (1 << (lfrXParser.T__9 - 7)) | (1 << (lfrXParser.T__20 - 7)) | (1 << (lfrXParser.T__21 - 7)) | (1 << (lfrXParser.T__22 - 7)) | (1 << (lfrXParser.T__23 - 7)) | (1 << (lfrXParser.T__24 - 7)) | (1 << (lfrXParser.T__25 - 7)) | (1 << (lfrXParser.T__31 - 7)) | (1 << (lfrXParser.T__33 - 7)) | (1 << (lfrXParser.T__34 - 7)) | (1 << (lfrXParser.ID - 7)))) != 0)):
- break
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class IoblockContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def vectorvar(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.VectorvarContext)
- else:
- return self.getTypedRuleContext(lfrXParser.VectorvarContext,i)
-
-
- def explicitIOBlock(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.ExplicitIOBlockContext)
- else:
- return self.getTypedRuleContext(lfrXParser.ExplicitIOBlockContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_ioblock
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterIoblock" ):
- listener.enterIoblock(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitIoblock" ):
- listener.exitIoblock(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitIoblock" ):
- return visitor.visitIoblock(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def ioblock(self):
-
- localctx = lfrXParser.IoblockContext(self, self._ctx, self.state)
- self.enterRule(localctx, 8, self.RULE_ioblock)
- self._la = 0 # Token type
- try:
- self.state = 171
- self._errHandler.sync(self)
- token = self._input.LA(1)
- if token in [lfrXParser.ID]:
- self.enterOuterAlt(localctx, 1)
- self.state = 155
- self.vectorvar()
- self.state = 160
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while _la==lfrXParser.T__5:
- self.state = 156
- self.match(lfrXParser.T__5)
- self.state = 157
- self.vectorvar()
- self.state = 162
- self._errHandler.sync(self)
- _la = self._input.LA(1)
-
- pass
- elif token in [lfrXParser.T__6, lfrXParser.T__7, lfrXParser.T__8]:
- self.enterOuterAlt(localctx, 2)
- self.state = 163
- self.explicitIOBlock()
- self.state = 168
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while _la==lfrXParser.T__5:
- self.state = 164
- self.match(lfrXParser.T__5)
- self.state = 165
- self.explicitIOBlock()
- self.state = 170
- self._errHandler.sync(self)
- _la = self._input.LA(1)
-
- pass
- else:
- raise NoViableAltException(self)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class VectorvarContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def ID(self):
- return self.getToken(lfrXParser.ID, 0)
-
- def vector(self):
- return self.getTypedRuleContext(lfrXParser.VectorContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_vectorvar
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterVectorvar" ):
- listener.enterVectorvar(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitVectorvar" ):
- listener.exitVectorvar(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitVectorvar" ):
- return visitor.visitVectorvar(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def vectorvar(self):
-
- localctx = lfrXParser.VectorvarContext(self, self._ctx, self.state)
- self.enterRule(localctx, 10, self.RULE_vectorvar)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 173
- self.match(lfrXParser.ID)
- self.state = 175
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if _la==lfrXParser.T__27:
- self.state = 174
- self.vector()
-
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class ExplicitIOBlockContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def declvar(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.DeclvarContext)
- else:
- return self.getTypedRuleContext(lfrXParser.DeclvarContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_explicitIOBlock
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterExplicitIOBlock" ):
- listener.enterExplicitIOBlock(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitExplicitIOBlock" ):
- listener.exitExplicitIOBlock(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitExplicitIOBlock" ):
- return visitor.visitExplicitIOBlock(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def explicitIOBlock(self):
-
- localctx = lfrXParser.ExplicitIOBlockContext(self, self._ctx, self.state)
- self.enterRule(localctx, 12, self.RULE_explicitIOBlock)
- try:
- self.state = 204
- self._errHandler.sync(self)
- token = self._input.LA(1)
- if token in [lfrXParser.T__6]:
- self.enterOuterAlt(localctx, 1)
- self.state = 177
- self.match(lfrXParser.T__6)
- self.state = 178
- self.declvar()
- self.state = 183
- self._errHandler.sync(self)
- _alt = self._interp.adaptivePredict(self._input,8,self._ctx)
- while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
- if _alt==1:
- self.state = 179
- self.match(lfrXParser.T__5)
- self.state = 180
- self.declvar()
- self.state = 185
- self._errHandler.sync(self)
- _alt = self._interp.adaptivePredict(self._input,8,self._ctx)
-
- pass
- elif token in [lfrXParser.T__7]:
- self.enterOuterAlt(localctx, 2)
- self.state = 186
- self.match(lfrXParser.T__7)
- self.state = 187
- self.declvar()
- self.state = 192
- self._errHandler.sync(self)
- _alt = self._interp.adaptivePredict(self._input,9,self._ctx)
- while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
- if _alt==1:
- self.state = 188
- self.match(lfrXParser.T__5)
- self.state = 189
- self.declvar()
- self.state = 194
- self._errHandler.sync(self)
- _alt = self._interp.adaptivePredict(self._input,9,self._ctx)
-
- pass
- elif token in [lfrXParser.T__8]:
- self.enterOuterAlt(localctx, 3)
- self.state = 195
- self.match(lfrXParser.T__8)
- self.state = 196
- self.declvar()
- self.state = 201
- self._errHandler.sync(self)
- _alt = self._interp.adaptivePredict(self._input,10,self._ctx)
- while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
- if _alt==1:
- self.state = 197
- self.match(lfrXParser.T__5)
- self.state = 198
- self.declvar()
- self.state = 203
- self._errHandler.sync(self)
- _alt = self._interp.adaptivePredict(self._input,10,self._ctx)
-
- pass
- else:
- raise NoViableAltException(self)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class DeclvarContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def ID(self):
- return self.getToken(lfrXParser.ID, 0)
-
- def vector(self):
- return self.getTypedRuleContext(lfrXParser.VectorContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_declvar
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterDeclvar" ):
- listener.enterDeclvar(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitDeclvar" ):
- listener.exitDeclvar(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitDeclvar" ):
- return visitor.visitDeclvar(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def declvar(self):
-
- localctx = lfrXParser.DeclvarContext(self, self._ctx, self.state)
- self.enterRule(localctx, 14, self.RULE_declvar)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 207
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if _la==lfrXParser.T__27:
- self.state = 206
- self.vector()
-
-
- self.state = 209
- self.match(lfrXParser.ID)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class DistributionBlockContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def sensitivitylist(self):
- return self.getTypedRuleContext(lfrXParser.SensitivitylistContext,0)
-
-
- def distributionBody(self):
- return self.getTypedRuleContext(lfrXParser.DistributionBodyContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_distributionBlock
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterDistributionBlock" ):
- listener.enterDistributionBlock(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitDistributionBlock" ):
- listener.exitDistributionBlock(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitDistributionBlock" ):
- return visitor.visitDistributionBlock(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def distributionBlock(self):
-
- localctx = lfrXParser.DistributionBlockContext(self, self._ctx, self.state)
- self.enterRule(localctx, 16, self.RULE_distributionBlock)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 211
- self.match(lfrXParser.T__9)
- self.state = 212
- self.match(lfrXParser.T__2)
- self.state = 213
- self.sensitivitylist()
- self.state = 214
- self.match(lfrXParser.T__3)
- self.state = 215
- self.match(lfrXParser.T__10)
- self.state = 216
- self.distributionBody()
- self.state = 217
- self.match(lfrXParser.T__11)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class DistributionBodyContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def distributeBodyStat(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.DistributeBodyStatContext)
- else:
- return self.getTypedRuleContext(lfrXParser.DistributeBodyStatContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_distributionBody
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterDistributionBody" ):
- listener.enterDistributionBody(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitDistributionBody" ):
- listener.exitDistributionBody(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitDistributionBody" ):
- return visitor.visitDistributionBody(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def distributionBody(self):
-
- localctx = lfrXParser.DistributionBodyContext(self, self._ctx, self.state)
- self.enterRule(localctx, 18, self.RULE_distributionBody)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 220
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while True:
- self.state = 219
- self.distributeBodyStat()
- self.state = 222
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if not (((((_la - 13)) & ~0x3f) == 0 and ((1 << (_la - 13)) & ((1 << (lfrXParser.T__12 - 13)) | (1 << (lfrXParser.T__15 - 13)) | (1 << (lfrXParser.T__29 - 13)) | (1 << (lfrXParser.ID - 13)))) != 0)):
- break
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class DistributeBodyStatContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def distributionassignstat(self):
- return self.getTypedRuleContext(lfrXParser.DistributionassignstatContext,0)
-
-
- def caseBlock(self):
- return self.getTypedRuleContext(lfrXParser.CaseBlockContext,0)
-
-
- def ifElseBlock(self):
- return self.getTypedRuleContext(lfrXParser.IfElseBlockContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_distributeBodyStat
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterDistributeBodyStat" ):
- listener.enterDistributeBodyStat(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitDistributeBodyStat" ):
- listener.exitDistributeBodyStat(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitDistributeBodyStat" ):
- return visitor.visitDistributeBodyStat(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def distributeBodyStat(self):
-
- localctx = lfrXParser.DistributeBodyStatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 20, self.RULE_distributeBodyStat)
- try:
- self.state = 227
- self._errHandler.sync(self)
- token = self._input.LA(1)
- if token in [lfrXParser.T__29, lfrXParser.ID]:
- self.enterOuterAlt(localctx, 1)
- self.state = 224
- self.distributionassignstat()
- pass
- elif token in [lfrXParser.T__15]:
- self.enterOuterAlt(localctx, 2)
- self.state = 225
- self.caseBlock()
- pass
- elif token in [lfrXParser.T__12]:
- self.enterOuterAlt(localctx, 3)
- self.state = 226
- self.ifElseBlock()
- pass
- else:
- raise NoViableAltException(self)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class IfElseBlockContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def ifBlock(self):
- return self.getTypedRuleContext(lfrXParser.IfBlockContext,0)
-
-
- def elseIfBlock(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.ElseIfBlockContext)
- else:
- return self.getTypedRuleContext(lfrXParser.ElseIfBlockContext,i)
-
-
- def elseBlock(self):
- return self.getTypedRuleContext(lfrXParser.ElseBlockContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_ifElseBlock
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterIfElseBlock" ):
- listener.enterIfElseBlock(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitIfElseBlock" ):
- listener.exitIfElseBlock(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitIfElseBlock" ):
- return visitor.visitIfElseBlock(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def ifElseBlock(self):
-
- localctx = lfrXParser.IfElseBlockContext(self, self._ctx, self.state)
- self.enterRule(localctx, 22, self.RULE_ifElseBlock)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 229
- self.ifBlock()
- self.state = 233
- self._errHandler.sync(self)
- _alt = self._interp.adaptivePredict(self._input,15,self._ctx)
- while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
- if _alt==1:
- self.state = 230
- self.elseIfBlock()
- self.state = 235
- self._errHandler.sync(self)
- _alt = self._interp.adaptivePredict(self._input,15,self._ctx)
-
- self.state = 237
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if _la==lfrXParser.T__13:
- self.state = 236
- self.elseBlock()
-
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class IfBlockContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def distributeCondition(self):
- return self.getTypedRuleContext(lfrXParser.DistributeConditionContext,0)
-
-
- def statementBlock(self):
- return self.getTypedRuleContext(lfrXParser.StatementBlockContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_ifBlock
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterIfBlock" ):
- listener.enterIfBlock(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitIfBlock" ):
- listener.exitIfBlock(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitIfBlock" ):
- return visitor.visitIfBlock(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def ifBlock(self):
-
- localctx = lfrXParser.IfBlockContext(self, self._ctx, self.state)
- self.enterRule(localctx, 24, self.RULE_ifBlock)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 239
- self.match(lfrXParser.T__12)
- self.state = 240
- self.match(lfrXParser.T__2)
- self.state = 241
- self.distributeCondition()
- self.state = 242
- self.match(lfrXParser.T__3)
- self.state = 243
- self.statementBlock()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class ElseBlockContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def statementBlock(self):
- return self.getTypedRuleContext(lfrXParser.StatementBlockContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_elseBlock
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterElseBlock" ):
- listener.enterElseBlock(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitElseBlock" ):
- listener.exitElseBlock(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitElseBlock" ):
- return visitor.visitElseBlock(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def elseBlock(self):
-
- localctx = lfrXParser.ElseBlockContext(self, self._ctx, self.state)
- self.enterRule(localctx, 26, self.RULE_elseBlock)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 245
- self.match(lfrXParser.T__13)
- self.state = 246
- self.statementBlock()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class ElseIfBlockContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def distributeCondition(self):
- return self.getTypedRuleContext(lfrXParser.DistributeConditionContext,0)
-
-
- def statementBlock(self):
- return self.getTypedRuleContext(lfrXParser.StatementBlockContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_elseIfBlock
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterElseIfBlock" ):
- listener.enterElseIfBlock(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitElseIfBlock" ):
- listener.exitElseIfBlock(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitElseIfBlock" ):
- return visitor.visitElseIfBlock(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def elseIfBlock(self):
-
- localctx = lfrXParser.ElseIfBlockContext(self, self._ctx, self.state)
- self.enterRule(localctx, 28, self.RULE_elseIfBlock)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 248
- self.match(lfrXParser.T__13)
- self.state = 249
- self.match(lfrXParser.T__12)
- self.state = 250
- self.match(lfrXParser.T__2)
- self.state = 251
- self.distributeCondition()
- self.state = 252
- self.match(lfrXParser.T__3)
- self.state = 253
- self.statementBlock()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class DistributeConditionContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def lhs(self):
- return self.getTypedRuleContext(lfrXParser.LhsContext,0)
-
-
- def binary_module_path_operator(self):
- return self.getTypedRuleContext(lfrXParser.Binary_module_path_operatorContext,0)
-
-
- def distvalue(self):
- return self.getTypedRuleContext(lfrXParser.DistvalueContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_distributeCondition
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterDistributeCondition" ):
- listener.enterDistributeCondition(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitDistributeCondition" ):
- listener.exitDistributeCondition(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitDistributeCondition" ):
- return visitor.visitDistributeCondition(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def distributeCondition(self):
-
- localctx = lfrXParser.DistributeConditionContext(self, self._ctx, self.state)
- self.enterRule(localctx, 30, self.RULE_distributeCondition)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 255
- self.lhs()
- self.state = 256
- self.binary_module_path_operator()
- self.state = 257
- self.distvalue()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class StatementBlockContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def distributionassignstat(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.DistributionassignstatContext)
- else:
- return self.getTypedRuleContext(lfrXParser.DistributionassignstatContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_statementBlock
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterStatementBlock" ):
- listener.enterStatementBlock(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitStatementBlock" ):
- listener.exitStatementBlock(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitStatementBlock" ):
- return visitor.visitStatementBlock(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def statementBlock(self):
-
- localctx = lfrXParser.StatementBlockContext(self, self._ctx, self.state)
- self.enterRule(localctx, 32, self.RULE_statementBlock)
- self._la = 0 # Token type
- try:
- self.state = 268
- self._errHandler.sync(self)
- token = self._input.LA(1)
- if token in [lfrXParser.T__10]:
- self.enterOuterAlt(localctx, 1)
- self.state = 259
- self.match(lfrXParser.T__10)
- self.state = 261
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while True:
- self.state = 260
- self.distributionassignstat()
- self.state = 263
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if not (_la==lfrXParser.T__29 or _la==lfrXParser.ID):
- break
-
- self.state = 265
- self.match(lfrXParser.T__11)
- pass
- elif token in [lfrXParser.T__29, lfrXParser.ID]:
- self.enterOuterAlt(localctx, 2)
- self.state = 267
- self.distributionassignstat()
- pass
- else:
- raise NoViableAltException(self)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class CaseBlockContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def caseBlockHeader(self):
- return self.getTypedRuleContext(lfrXParser.CaseBlockHeaderContext,0)
-
-
- def casestat(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.CasestatContext)
- else:
- return self.getTypedRuleContext(lfrXParser.CasestatContext,i)
-
-
- def defaultCaseStat(self):
- return self.getTypedRuleContext(lfrXParser.DefaultCaseStatContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_caseBlock
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterCaseBlock" ):
- listener.enterCaseBlock(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitCaseBlock" ):
- listener.exitCaseBlock(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitCaseBlock" ):
- return visitor.visitCaseBlock(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def caseBlock(self):
-
- localctx = lfrXParser.CaseBlockContext(self, self._ctx, self.state)
- self.enterRule(localctx, 34, self.RULE_caseBlock)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 270
- self.caseBlockHeader()
- self.state = 272
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while True:
- self.state = 271
- self.casestat()
- self.state = 274
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if not (((((_la - 71)) & ~0x3f) == 0 and ((1 << (_la - 71)) & ((1 << (lfrXParser.Real_number - 71)) | (1 << (lfrXParser.Decimal_number - 71)) | (1 << (lfrXParser.Binary_number - 71)) | (1 << (lfrXParser.Octal_number - 71)) | (1 << (lfrXParser.Hex_number - 71)))) != 0)):
- break
-
- self.state = 277
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if _la==lfrXParser.T__17:
- self.state = 276
- self.defaultCaseStat()
-
-
- self.state = 279
- self.match(lfrXParser.T__14)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class CaseBlockHeaderContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def lhs(self):
- return self.getTypedRuleContext(lfrXParser.LhsContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_caseBlockHeader
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterCaseBlockHeader" ):
- listener.enterCaseBlockHeader(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitCaseBlockHeader" ):
- listener.exitCaseBlockHeader(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitCaseBlockHeader" ):
- return visitor.visitCaseBlockHeader(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def caseBlockHeader(self):
-
- localctx = lfrXParser.CaseBlockHeaderContext(self, self._ctx, self.state)
- self.enterRule(localctx, 36, self.RULE_caseBlockHeader)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 281
- self.match(lfrXParser.T__15)
- self.state = 282
- self.match(lfrXParser.T__2)
- self.state = 283
- self.lhs()
- self.state = 284
- self.match(lfrXParser.T__3)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class CasestatContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def distvalue(self):
- return self.getTypedRuleContext(lfrXParser.DistvalueContext,0)
-
-
- def statementBlock(self):
- return self.getTypedRuleContext(lfrXParser.StatementBlockContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_casestat
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterCasestat" ):
- listener.enterCasestat(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitCasestat" ):
- listener.exitCasestat(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitCasestat" ):
- return visitor.visitCasestat(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def casestat(self):
-
- localctx = lfrXParser.CasestatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 38, self.RULE_casestat)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 286
- self.distvalue()
- self.state = 287
- self.match(lfrXParser.T__16)
- self.state = 288
- self.statementBlock()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class DefaultCaseStatContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def statementBlock(self):
- return self.getTypedRuleContext(lfrXParser.StatementBlockContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_defaultCaseStat
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterDefaultCaseStat" ):
- listener.enterDefaultCaseStat(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitDefaultCaseStat" ):
- listener.exitDefaultCaseStat(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitDefaultCaseStat" ):
- return visitor.visitDefaultCaseStat(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def defaultCaseStat(self):
-
- localctx = lfrXParser.DefaultCaseStatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 40, self.RULE_defaultCaseStat)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 290
- self.match(lfrXParser.T__17)
- self.state = 291
- self.match(lfrXParser.T__16)
- self.state = 292
- self.statementBlock()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class DistvalueContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def number(self):
- return self.getTypedRuleContext(lfrXParser.NumberContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_distvalue
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterDistvalue" ):
- listener.enterDistvalue(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitDistvalue" ):
- listener.exitDistvalue(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitDistvalue" ):
- return visitor.visitDistvalue(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def distvalue(self):
-
- localctx = lfrXParser.DistvalueContext(self, self._ctx, self.state)
- self.enterRule(localctx, 42, self.RULE_distvalue)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 294
- self.number()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class DistributionassignstatContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def lhs(self):
- return self.getTypedRuleContext(lfrXParser.LhsContext,0)
-
-
- def number(self):
- return self.getTypedRuleContext(lfrXParser.NumberContext,0)
-
-
- def variables(self):
- return self.getTypedRuleContext(lfrXParser.VariablesContext,0)
-
-
- def expression(self):
- return self.getTypedRuleContext(lfrXParser.ExpressionContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_distributionassignstat
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterDistributionassignstat" ):
- listener.enterDistributionassignstat(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitDistributionassignstat" ):
- listener.exitDistributionassignstat(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitDistributionassignstat" ):
- return visitor.visitDistributionassignstat(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def distributionassignstat(self):
-
- localctx = lfrXParser.DistributionassignstatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 44, self.RULE_distributionassignstat)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 296
- self.lhs()
- self.state = 297
- self.match(lfrXParser.T__18)
- self.state = 301
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,21,self._ctx)
- if la_ == 1:
- self.state = 298
- self.number()
- pass
-
- elif la_ == 2:
- self.state = 299
- self.variables()
- pass
-
- elif la_ == 3:
- self.state = 300
- self.expression()
- pass
-
-
- self.state = 303
- self.match(lfrXParser.T__4)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class SensitivitylistContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def signal(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.SignalContext)
- else:
- return self.getTypedRuleContext(lfrXParser.SignalContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_sensitivitylist
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterSensitivitylist" ):
- listener.enterSensitivitylist(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitSensitivitylist" ):
- listener.exitSensitivitylist(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitSensitivitylist" ):
- return visitor.visitSensitivitylist(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def sensitivitylist(self):
-
- localctx = lfrXParser.SensitivitylistContext(self, self._ctx, self.state)
- self.enterRule(localctx, 46, self.RULE_sensitivitylist)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 305
- self.signal()
- self.state = 310
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while _la==lfrXParser.T__5:
- self.state = 306
- self.match(lfrXParser.T__5)
- self.state = 307
- self.signal()
- self.state = 312
- self._errHandler.sync(self)
- _la = self._input.LA(1)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class SignalContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def ID(self):
- return self.getToken(lfrXParser.ID, 0)
-
- def vector(self):
- return self.getTypedRuleContext(lfrXParser.VectorContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_signal
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterSignal" ):
- listener.enterSignal(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitSignal" ):
- listener.exitSignal(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitSignal" ):
- return visitor.visitSignal(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def signal(self):
-
- localctx = lfrXParser.SignalContext(self, self._ctx, self.state)
- self.enterRule(localctx, 48, self.RULE_signal)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 313
- self.match(lfrXParser.ID)
- self.state = 315
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if _la==lfrXParser.T__27:
- self.state = 314
- self.vector()
-
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class StatementsContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def statement(self):
- return self.getTypedRuleContext(lfrXParser.StatementContext,0)
-
-
- def technologydirectives(self):
- return self.getTypedRuleContext(lfrXParser.TechnologydirectivesContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_statements
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterStatements" ):
- listener.enterStatements(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitStatements" ):
- listener.exitStatements(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitStatements" ):
- return visitor.visitStatements(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def statements(self):
-
- localctx = lfrXParser.StatementsContext(self, self._ctx, self.state)
- self.enterRule(localctx, 50, self.RULE_statements)
- try:
- self.state = 321
- self._errHandler.sync(self)
- token = self._input.LA(1)
- if token in [lfrXParser.T__6, lfrXParser.T__7, lfrXParser.T__8, lfrXParser.T__20, lfrXParser.T__21, lfrXParser.T__22, lfrXParser.T__23, lfrXParser.T__24, lfrXParser.T__25, lfrXParser.ID]:
- self.enterOuterAlt(localctx, 1)
- self.state = 317
- self.statement()
- self.state = 318
- self.match(lfrXParser.T__4)
- pass
- elif token in [lfrXParser.T__31, lfrXParser.T__33, lfrXParser.T__34]:
- self.enterOuterAlt(localctx, 2)
- self.state = 320
- self.technologydirectives()
- pass
- else:
- raise NoViableAltException(self)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class StatementContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def ioassignstat(self):
- return self.getTypedRuleContext(lfrXParser.IoassignstatContext,0)
-
-
- def assignstat(self):
- return self.getTypedRuleContext(lfrXParser.AssignstatContext,0)
-
-
- def tempvariablesstat(self):
- return self.getTypedRuleContext(lfrXParser.TempvariablesstatContext,0)
-
-
- def literalassignstat(self):
- return self.getTypedRuleContext(lfrXParser.LiteralassignstatContext,0)
-
-
- def moduleinstantiationstat(self):
- return self.getTypedRuleContext(lfrXParser.ModuleinstantiationstatContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_statement
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterStatement" ):
- listener.enterStatement(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitStatement" ):
- listener.exitStatement(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitStatement" ):
- return visitor.visitStatement(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def statement(self):
-
- localctx = lfrXParser.StatementContext(self, self._ctx, self.state)
- self.enterRule(localctx, 52, self.RULE_statement)
- try:
- self.state = 328
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,25,self._ctx)
- if la_ == 1:
- self.enterOuterAlt(localctx, 1)
- self.state = 323
- self.ioassignstat()
- pass
-
- elif la_ == 2:
- self.enterOuterAlt(localctx, 2)
- self.state = 324
- self.assignstat()
- pass
-
- elif la_ == 3:
- self.enterOuterAlt(localctx, 3)
- self.state = 325
- self.tempvariablesstat()
- pass
-
- elif la_ == 4:
- self.enterOuterAlt(localctx, 4)
- self.state = 326
- self.literalassignstat()
- pass
-
- elif la_ == 5:
- self.enterOuterAlt(localctx, 5)
- self.state = 327
- self.moduleinstantiationstat()
- pass
-
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class ModuleinstantiationstatContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def moduletype(self):
- return self.getTypedRuleContext(lfrXParser.ModuletypeContext,0)
-
-
- def instancename(self):
- return self.getTypedRuleContext(lfrXParser.InstancenameContext,0)
-
-
- def instanceioblock(self):
- return self.getTypedRuleContext(lfrXParser.InstanceioblockContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_moduleinstantiationstat
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterModuleinstantiationstat" ):
- listener.enterModuleinstantiationstat(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitModuleinstantiationstat" ):
- listener.exitModuleinstantiationstat(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitModuleinstantiationstat" ):
- return visitor.visitModuleinstantiationstat(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def moduleinstantiationstat(self):
-
- localctx = lfrXParser.ModuleinstantiationstatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 54, self.RULE_moduleinstantiationstat)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 330
- self.moduletype()
- self.state = 331
- self.instancename()
- self.state = 332
- self.match(lfrXParser.T__2)
- self.state = 333
- self.instanceioblock()
- self.state = 334
- self.match(lfrXParser.T__3)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class InstanceioblockContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def orderedioblock(self):
- return self.getTypedRuleContext(lfrXParser.OrderedioblockContext,0)
-
-
- def unorderedioblock(self):
- return self.getTypedRuleContext(lfrXParser.UnorderedioblockContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_instanceioblock
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterInstanceioblock" ):
- listener.enterInstanceioblock(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitInstanceioblock" ):
- listener.exitInstanceioblock(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitInstanceioblock" ):
- return visitor.visitInstanceioblock(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def instanceioblock(self):
-
- localctx = lfrXParser.InstanceioblockContext(self, self._ctx, self.state)
- self.enterRule(localctx, 56, self.RULE_instanceioblock)
- try:
- self.state = 338
- self._errHandler.sync(self)
- token = self._input.LA(1)
- if token in [lfrXParser.ID]:
- self.enterOuterAlt(localctx, 1)
- self.state = 336
- self.orderedioblock()
- pass
- elif token in [lfrXParser.T__19]:
- self.enterOuterAlt(localctx, 2)
- self.state = 337
- self.unorderedioblock()
- pass
- else:
- raise NoViableAltException(self)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class OrderedioblockContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def vectorvar(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.VectorvarContext)
- else:
- return self.getTypedRuleContext(lfrXParser.VectorvarContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_orderedioblock
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterOrderedioblock" ):
- listener.enterOrderedioblock(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitOrderedioblock" ):
- listener.exitOrderedioblock(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitOrderedioblock" ):
- return visitor.visitOrderedioblock(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def orderedioblock(self):
-
- localctx = lfrXParser.OrderedioblockContext(self, self._ctx, self.state)
- self.enterRule(localctx, 58, self.RULE_orderedioblock)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 340
- self.vectorvar()
- self.state = 345
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while _la==lfrXParser.T__5:
- self.state = 341
- self.match(lfrXParser.T__5)
- self.state = 342
- self.vectorvar()
- self.state = 347
- self._errHandler.sync(self)
- _la = self._input.LA(1)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class UnorderedioblockContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def explicitinstanceiomapping(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.ExplicitinstanceiomappingContext)
- else:
- return self.getTypedRuleContext(lfrXParser.ExplicitinstanceiomappingContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_unorderedioblock
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterUnorderedioblock" ):
- listener.enterUnorderedioblock(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitUnorderedioblock" ):
- listener.exitUnorderedioblock(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitUnorderedioblock" ):
- return visitor.visitUnorderedioblock(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def unorderedioblock(self):
-
- localctx = lfrXParser.UnorderedioblockContext(self, self._ctx, self.state)
- self.enterRule(localctx, 60, self.RULE_unorderedioblock)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 348
- self.explicitinstanceiomapping()
- self.state = 353
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while _la==lfrXParser.T__5:
- self.state = 349
- self.match(lfrXParser.T__5)
- self.state = 350
- self.explicitinstanceiomapping()
- self.state = 355
- self._errHandler.sync(self)
- _la = self._input.LA(1)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class ExplicitinstanceiomappingContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def ID(self):
- return self.getToken(lfrXParser.ID, 0)
-
- def variables(self):
- return self.getTypedRuleContext(lfrXParser.VariablesContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_explicitinstanceiomapping
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterExplicitinstanceiomapping" ):
- listener.enterExplicitinstanceiomapping(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitExplicitinstanceiomapping" ):
- listener.exitExplicitinstanceiomapping(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitExplicitinstanceiomapping" ):
- return visitor.visitExplicitinstanceiomapping(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def explicitinstanceiomapping(self):
-
- localctx = lfrXParser.ExplicitinstanceiomappingContext(self, self._ctx, self.state)
- self.enterRule(localctx, 62, self.RULE_explicitinstanceiomapping)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 356
- self.match(lfrXParser.T__19)
- self.state = 357
- self.match(lfrXParser.ID)
- self.state = 358
- self.match(lfrXParser.T__2)
- self.state = 359
- self.variables()
- self.state = 360
- self.match(lfrXParser.T__3)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class InstancenameContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def ID(self):
- return self.getToken(lfrXParser.ID, 0)
-
- def getRuleIndex(self):
- return lfrXParser.RULE_instancename
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterInstancename" ):
- listener.enterInstancename(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitInstancename" ):
- listener.exitInstancename(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitInstancename" ):
- return visitor.visitInstancename(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def instancename(self):
-
- localctx = lfrXParser.InstancenameContext(self, self._ctx, self.state)
- self.enterRule(localctx, 64, self.RULE_instancename)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 362
- self.match(lfrXParser.ID)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class ModuletypeContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def ID(self):
- return self.getToken(lfrXParser.ID, 0)
-
- def getRuleIndex(self):
- return lfrXParser.RULE_moduletype
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterModuletype" ):
- listener.enterModuletype(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitModuletype" ):
- listener.exitModuletype(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitModuletype" ):
- return visitor.visitModuletype(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def moduletype(self):
-
- localctx = lfrXParser.ModuletypeContext(self, self._ctx, self.state)
- self.enterRule(localctx, 66, self.RULE_moduletype)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 364
- self.match(lfrXParser.ID)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class TempvariablesstatContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def fluiddeclstat(self):
- return self.getTypedRuleContext(lfrXParser.FluiddeclstatContext,0)
-
-
- def storagestat(self):
- return self.getTypedRuleContext(lfrXParser.StoragestatContext,0)
-
-
- def numvarstat(self):
- return self.getTypedRuleContext(lfrXParser.NumvarstatContext,0)
-
-
- def signalvarstat(self):
- return self.getTypedRuleContext(lfrXParser.SignalvarstatContext,0)
-
-
- def pumpvarstat(self):
- return self.getTypedRuleContext(lfrXParser.PumpvarstatContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_tempvariablesstat
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterTempvariablesstat" ):
- listener.enterTempvariablesstat(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitTempvariablesstat" ):
- listener.exitTempvariablesstat(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitTempvariablesstat" ):
- return visitor.visitTempvariablesstat(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def tempvariablesstat(self):
-
- localctx = lfrXParser.TempvariablesstatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 68, self.RULE_tempvariablesstat)
- try:
- self.state = 371
- self._errHandler.sync(self)
- token = self._input.LA(1)
- if token in [lfrXParser.T__21]:
- self.enterOuterAlt(localctx, 1)
- self.state = 366
- self.fluiddeclstat()
- pass
- elif token in [lfrXParser.T__22]:
- self.enterOuterAlt(localctx, 2)
- self.state = 367
- self.storagestat()
- pass
- elif token in [lfrXParser.T__24]:
- self.enterOuterAlt(localctx, 3)
- self.state = 368
- self.numvarstat()
- pass
- elif token in [lfrXParser.T__20]:
- self.enterOuterAlt(localctx, 4)
- self.state = 369
- self.signalvarstat()
- pass
- elif token in [lfrXParser.T__23]:
- self.enterOuterAlt(localctx, 5)
- self.state = 370
- self.pumpvarstat()
- pass
- else:
- raise NoViableAltException(self)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class SignalvarstatContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def declvar(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.DeclvarContext)
- else:
- return self.getTypedRuleContext(lfrXParser.DeclvarContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_signalvarstat
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterSignalvarstat" ):
- listener.enterSignalvarstat(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitSignalvarstat" ):
- listener.exitSignalvarstat(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitSignalvarstat" ):
- return visitor.visitSignalvarstat(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def signalvarstat(self):
-
- localctx = lfrXParser.SignalvarstatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 70, self.RULE_signalvarstat)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 373
- self.match(lfrXParser.T__20)
- self.state = 374
- self.declvar()
- self.state = 379
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while _la==lfrXParser.T__5:
- self.state = 375
- self.match(lfrXParser.T__5)
- self.state = 376
- self.declvar()
- self.state = 381
- self._errHandler.sync(self)
- _la = self._input.LA(1)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class FluiddeclstatContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def declvar(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.DeclvarContext)
- else:
- return self.getTypedRuleContext(lfrXParser.DeclvarContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_fluiddeclstat
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterFluiddeclstat" ):
- listener.enterFluiddeclstat(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitFluiddeclstat" ):
- listener.exitFluiddeclstat(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitFluiddeclstat" ):
- return visitor.visitFluiddeclstat(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def fluiddeclstat(self):
-
- localctx = lfrXParser.FluiddeclstatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 72, self.RULE_fluiddeclstat)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 382
- self.match(lfrXParser.T__21)
- self.state = 383
- self.declvar()
- self.state = 388
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while _la==lfrXParser.T__5:
- self.state = 384
- self.match(lfrXParser.T__5)
- self.state = 385
- self.declvar()
- self.state = 390
- self._errHandler.sync(self)
- _la = self._input.LA(1)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class StoragestatContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def declvar(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.DeclvarContext)
- else:
- return self.getTypedRuleContext(lfrXParser.DeclvarContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_storagestat
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterStoragestat" ):
- listener.enterStoragestat(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitStoragestat" ):
- listener.exitStoragestat(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitStoragestat" ):
- return visitor.visitStoragestat(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def storagestat(self):
-
- localctx = lfrXParser.StoragestatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 74, self.RULE_storagestat)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 391
- self.match(lfrXParser.T__22)
- self.state = 392
- self.declvar()
- self.state = 397
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while _la==lfrXParser.T__5:
- self.state = 393
- self.match(lfrXParser.T__5)
- self.state = 394
- self.declvar()
- self.state = 399
- self._errHandler.sync(self)
- _la = self._input.LA(1)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class PumpvarstatContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def declvar(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.DeclvarContext)
- else:
- return self.getTypedRuleContext(lfrXParser.DeclvarContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_pumpvarstat
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterPumpvarstat" ):
- listener.enterPumpvarstat(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitPumpvarstat" ):
- listener.exitPumpvarstat(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitPumpvarstat" ):
- return visitor.visitPumpvarstat(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def pumpvarstat(self):
-
- localctx = lfrXParser.PumpvarstatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 76, self.RULE_pumpvarstat)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 400
- self.match(lfrXParser.T__23)
- self.state = 401
- self.declvar()
- self.state = 406
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while _la==lfrXParser.T__5:
- self.state = 402
- self.match(lfrXParser.T__5)
- self.state = 403
- self.declvar()
- self.state = 408
- self._errHandler.sync(self)
- _la = self._input.LA(1)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class NumvarstatContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def literalassignstat(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.LiteralassignstatContext)
- else:
- return self.getTypedRuleContext(lfrXParser.LiteralassignstatContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_numvarstat
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterNumvarstat" ):
- listener.enterNumvarstat(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitNumvarstat" ):
- listener.exitNumvarstat(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitNumvarstat" ):
- return visitor.visitNumvarstat(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def numvarstat(self):
-
- localctx = lfrXParser.NumvarstatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 78, self.RULE_numvarstat)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 409
- self.match(lfrXParser.T__24)
- self.state = 410
- self.literalassignstat()
- self.state = 415
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while _la==lfrXParser.T__5:
- self.state = 411
- self.match(lfrXParser.T__5)
- self.state = 412
- self.literalassignstat()
- self.state = 417
- self._errHandler.sync(self)
- _la = self._input.LA(1)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class AssignstatContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def lhs(self):
- return self.getTypedRuleContext(lfrXParser.LhsContext,0)
-
-
- def bracketexpression(self):
- return self.getTypedRuleContext(lfrXParser.BracketexpressionContext,0)
-
-
- def expression(self):
- return self.getTypedRuleContext(lfrXParser.ExpressionContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_assignstat
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterAssignstat" ):
- listener.enterAssignstat(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitAssignstat" ):
- listener.exitAssignstat(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitAssignstat" ):
- return visitor.visitAssignstat(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def assignstat(self):
-
- localctx = lfrXParser.AssignstatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 80, self.RULE_assignstat)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 418
- self.match(lfrXParser.T__25)
- self.state = 419
- self.lhs()
- self.state = 420
- self.match(lfrXParser.T__26)
- self.state = 423
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,35,self._ctx)
- if la_ == 1:
- self.state = 421
- self.bracketexpression()
- pass
-
- elif la_ == 2:
- self.state = 422
- self.expression()
- pass
-
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class LiteralassignstatContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def ID(self):
- return self.getToken(lfrXParser.ID, 0)
-
- def bracketexpression(self):
- return self.getTypedRuleContext(lfrXParser.BracketexpressionContext,0)
-
-
- def expression(self):
- return self.getTypedRuleContext(lfrXParser.ExpressionContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_literalassignstat
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterLiteralassignstat" ):
- listener.enterLiteralassignstat(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitLiteralassignstat" ):
- listener.exitLiteralassignstat(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitLiteralassignstat" ):
- return visitor.visitLiteralassignstat(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def literalassignstat(self):
-
- localctx = lfrXParser.LiteralassignstatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 82, self.RULE_literalassignstat)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 425
- self.match(lfrXParser.ID)
- self.state = 426
- self.match(lfrXParser.T__26)
- self.state = 429
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,36,self._ctx)
- if la_ == 1:
- self.state = 427
- self.bracketexpression()
- pass
-
- elif la_ == 2:
- self.state = 428
- self.expression()
- pass
-
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class BracketexpressionContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def expression(self):
- return self.getTypedRuleContext(lfrXParser.ExpressionContext,0)
-
-
- def unary_operator(self):
- return self.getTypedRuleContext(lfrXParser.Unary_operatorContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_bracketexpression
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterBracketexpression" ):
- listener.enterBracketexpression(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitBracketexpression" ):
- listener.exitBracketexpression(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitBracketexpression" ):
- return visitor.visitBracketexpression(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def bracketexpression(self):
-
- localctx = lfrXParser.BracketexpressionContext(self, self._ctx, self.state)
- self.enterRule(localctx, 84, self.RULE_bracketexpression)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 432
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << lfrXParser.T__40) | (1 << lfrXParser.T__41) | (1 << lfrXParser.T__42) | (1 << lfrXParser.T__43) | (1 << lfrXParser.T__44) | (1 << lfrXParser.T__45) | (1 << lfrXParser.T__46) | (1 << lfrXParser.T__47) | (1 << lfrXParser.T__48) | (1 << lfrXParser.T__49) | (1 << lfrXParser.T__50))) != 0):
- self.state = 431
- self.unary_operator()
-
-
- self.state = 434
- self.match(lfrXParser.T__2)
- self.state = 435
- self.expression()
- self.state = 436
- self.match(lfrXParser.T__3)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class ExpressionContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def bracketexpression(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.BracketexpressionContext)
- else:
- return self.getTypedRuleContext(lfrXParser.BracketexpressionContext,i)
-
-
- def expressionterm(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.ExpressiontermContext)
- else:
- return self.getTypedRuleContext(lfrXParser.ExpressiontermContext,i)
-
-
- def binary_operator(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.Binary_operatorContext)
- else:
- return self.getTypedRuleContext(lfrXParser.Binary_operatorContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_expression
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterExpression" ):
- listener.enterExpression(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitExpression" ):
- listener.exitExpression(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitExpression" ):
- return visitor.visitExpression(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def expression(self):
-
- localctx = lfrXParser.ExpressionContext(self, self._ctx, self.state)
- self.enterRule(localctx, 86, self.RULE_expression)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 440
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,38,self._ctx)
- if la_ == 1:
- self.state = 438
- self.bracketexpression()
- pass
-
- elif la_ == 2:
- self.state = 439
- self.expressionterm()
- pass
-
-
- self.state = 449
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while ((((_la - 19)) & ~0x3f) == 0 and ((1 << (_la - 19)) & ((1 << (lfrXParser.T__18 - 19)) | (1 << (lfrXParser.T__37 - 19)) | (1 << (lfrXParser.T__38 - 19)) | (1 << (lfrXParser.T__39 - 19)) | (1 << (lfrXParser.T__40 - 19)) | (1 << (lfrXParser.T__41 - 19)) | (1 << (lfrXParser.T__44 - 19)) | (1 << (lfrXParser.T__46 - 19)) | (1 << (lfrXParser.T__48 - 19)) | (1 << (lfrXParser.T__49 - 19)) | (1 << (lfrXParser.T__50 - 19)) | (1 << (lfrXParser.T__51 - 19)) | (1 << (lfrXParser.T__52 - 19)) | (1 << (lfrXParser.T__53 - 19)) | (1 << (lfrXParser.T__54 - 19)) | (1 << (lfrXParser.T__55 - 19)) | (1 << (lfrXParser.T__56 - 19)) | (1 << (lfrXParser.T__57 - 19)) | (1 << (lfrXParser.T__58 - 19)) | (1 << (lfrXParser.T__59 - 19)) | (1 << (lfrXParser.T__60 - 19)) | (1 << (lfrXParser.T__61 - 19)) | (1 << (lfrXParser.T__62 - 19)) | (1 << (lfrXParser.T__63 - 19)) | (1 << (lfrXParser.T__64 - 19)))) != 0):
- self.state = 442
- self.binary_operator()
- self.state = 445
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,39,self._ctx)
- if la_ == 1:
- self.state = 443
- self.bracketexpression()
- pass
-
- elif la_ == 2:
- self.state = 444
- self.expressionterm()
- pass
-
-
- self.state = 451
- self._errHandler.sync(self)
- _la = self._input.LA(1)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class ExpressiontermContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def variables(self):
- return self.getTypedRuleContext(lfrXParser.VariablesContext,0)
-
-
- def unary_operator(self):
- return self.getTypedRuleContext(lfrXParser.Unary_operatorContext,0)
-
-
- def number(self):
- return self.getTypedRuleContext(lfrXParser.NumberContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_expressionterm
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterExpressionterm" ):
- listener.enterExpressionterm(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitExpressionterm" ):
- listener.exitExpressionterm(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitExpressionterm" ):
- return visitor.visitExpressionterm(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def expressionterm(self):
-
- localctx = lfrXParser.ExpressiontermContext(self, self._ctx, self.state)
- self.enterRule(localctx, 88, self.RULE_expressionterm)
- self._la = 0 # Token type
- try:
- self.state = 457
- self._errHandler.sync(self)
- token = self._input.LA(1)
- if token in [lfrXParser.T__29, lfrXParser.T__40, lfrXParser.T__41, lfrXParser.T__42, lfrXParser.T__43, lfrXParser.T__44, lfrXParser.T__45, lfrXParser.T__46, lfrXParser.T__47, lfrXParser.T__48, lfrXParser.T__49, lfrXParser.T__50, lfrXParser.ID]:
- self.enterOuterAlt(localctx, 1)
- self.state = 453
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << lfrXParser.T__40) | (1 << lfrXParser.T__41) | (1 << lfrXParser.T__42) | (1 << lfrXParser.T__43) | (1 << lfrXParser.T__44) | (1 << lfrXParser.T__45) | (1 << lfrXParser.T__46) | (1 << lfrXParser.T__47) | (1 << lfrXParser.T__48) | (1 << lfrXParser.T__49) | (1 << lfrXParser.T__50))) != 0):
- self.state = 452
- self.unary_operator()
-
-
- self.state = 455
- self.variables()
- pass
- elif token in [lfrXParser.Real_number, lfrXParser.Decimal_number, lfrXParser.Binary_number, lfrXParser.Octal_number, lfrXParser.Hex_number]:
- self.enterOuterAlt(localctx, 2)
- self.state = 456
- self.number()
- pass
- else:
- raise NoViableAltException(self)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class Logiccondition_operandContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def bracketexpression(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.BracketexpressionContext)
- else:
- return self.getTypedRuleContext(lfrXParser.BracketexpressionContext,i)
-
-
- def expressionterm(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.ExpressiontermContext)
- else:
- return self.getTypedRuleContext(lfrXParser.ExpressiontermContext,i)
-
-
- def binary_operator(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.Binary_operatorContext)
- else:
- return self.getTypedRuleContext(lfrXParser.Binary_operatorContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_logiccondition_operand
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterLogiccondition_operand" ):
- listener.enterLogiccondition_operand(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitLogiccondition_operand" ):
- listener.exitLogiccondition_operand(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitLogiccondition_operand" ):
- return visitor.visitLogiccondition_operand(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def logiccondition_operand(self):
-
- localctx = lfrXParser.Logiccondition_operandContext(self, self._ctx, self.state)
- self.enterRule(localctx, 90, self.RULE_logiccondition_operand)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 461
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,43,self._ctx)
- if la_ == 1:
- self.state = 459
- self.bracketexpression()
- pass
-
- elif la_ == 2:
- self.state = 460
- self.expressionterm()
- pass
-
-
- self.state = 470
- self._errHandler.sync(self)
- _alt = self._interp.adaptivePredict(self._input,45,self._ctx)
- while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER:
- if _alt==1:
- self.state = 463
- self.binary_operator()
- self.state = 466
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,44,self._ctx)
- if la_ == 1:
- self.state = 464
- self.bracketexpression()
- pass
-
- elif la_ == 2:
- self.state = 465
- self.expressionterm()
- pass
-
-
- self.state = 472
- self._errHandler.sync(self)
- _alt = self._interp.adaptivePredict(self._input,45,self._ctx)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class LogicconditionContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def logiccondition_operand(self):
- return self.getTypedRuleContext(lfrXParser.Logiccondition_operandContext,0)
-
-
- def binary_module_path_operator(self):
- return self.getTypedRuleContext(lfrXParser.Binary_module_path_operatorContext,0)
-
-
- def logic_value(self):
- return self.getTypedRuleContext(lfrXParser.Logic_valueContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_logiccondition
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterLogiccondition" ):
- listener.enterLogiccondition(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitLogiccondition" ):
- listener.exitLogiccondition(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitLogiccondition" ):
- return visitor.visitLogiccondition(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def logiccondition(self):
-
- localctx = lfrXParser.LogicconditionContext(self, self._ctx, self.state)
- self.enterRule(localctx, 92, self.RULE_logiccondition)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 473
- self.logiccondition_operand()
- self.state = 474
- self.binary_module_path_operator()
- self.state = 475
- self.logic_value()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class Logic_valueContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def number(self):
- return self.getTypedRuleContext(lfrXParser.NumberContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_logic_value
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterLogic_value" ):
- listener.enterLogic_value(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitLogic_value" ):
- listener.exitLogic_value(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitLogic_value" ):
- return visitor.visitLogic_value(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def logic_value(self):
-
- localctx = lfrXParser.Logic_valueContext(self, self._ctx, self.state)
- self.enterRule(localctx, 94, self.RULE_logic_value)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 477
- self.number()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class VectorContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
- self.start = None # Token
- self.end = None # Token
-
- def Decimal_number(self, i:int=None):
- if i is None:
- return self.getTokens(lfrXParser.Decimal_number)
- else:
- return self.getToken(lfrXParser.Decimal_number, i)
-
- def getRuleIndex(self):
- return lfrXParser.RULE_vector
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterVector" ):
- listener.enterVector(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitVector" ):
- listener.exitVector(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitVector" ):
- return visitor.visitVector(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def vector(self):
-
- localctx = lfrXParser.VectorContext(self, self._ctx, self.state)
- self.enterRule(localctx, 96, self.RULE_vector)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 479
- self.match(lfrXParser.T__27)
- self.state = 480
- localctx.start = self.match(lfrXParser.Decimal_number)
- self.state = 483
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if _la==lfrXParser.T__16:
- self.state = 481
- self.match(lfrXParser.T__16)
- self.state = 482
- localctx.end = self.match(lfrXParser.Decimal_number)
-
-
- self.state = 485
- self.match(lfrXParser.T__28)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class VariablesContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def vectorvar(self):
- return self.getTypedRuleContext(lfrXParser.VectorvarContext,0)
-
-
- def concatenation(self):
- return self.getTypedRuleContext(lfrXParser.ConcatenationContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_variables
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterVariables" ):
- listener.enterVariables(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitVariables" ):
- listener.exitVariables(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitVariables" ):
- return visitor.visitVariables(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def variables(self):
-
- localctx = lfrXParser.VariablesContext(self, self._ctx, self.state)
- self.enterRule(localctx, 98, self.RULE_variables)
- try:
- self.state = 489
- self._errHandler.sync(self)
- token = self._input.LA(1)
- if token in [lfrXParser.ID]:
- self.enterOuterAlt(localctx, 1)
- self.state = 487
- self.vectorvar()
- pass
- elif token in [lfrXParser.T__29]:
- self.enterOuterAlt(localctx, 2)
- self.state = 488
- self.concatenation()
- pass
- else:
- raise NoViableAltException(self)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class ConcatenationContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def vectorvar(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.VectorvarContext)
- else:
- return self.getTypedRuleContext(lfrXParser.VectorvarContext,i)
-
-
- def vector(self):
- return self.getTypedRuleContext(lfrXParser.VectorContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_concatenation
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterConcatenation" ):
- listener.enterConcatenation(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitConcatenation" ):
- listener.exitConcatenation(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitConcatenation" ):
- return visitor.visitConcatenation(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def concatenation(self):
-
- localctx = lfrXParser.ConcatenationContext(self, self._ctx, self.state)
- self.enterRule(localctx, 100, self.RULE_concatenation)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 491
- self.match(lfrXParser.T__29)
- self.state = 492
- self.vectorvar()
- self.state = 497
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while _la==lfrXParser.T__5:
- self.state = 493
- self.match(lfrXParser.T__5)
- self.state = 494
- self.vectorvar()
- self.state = 499
- self._errHandler.sync(self)
- _la = self._input.LA(1)
-
- self.state = 500
- self.match(lfrXParser.T__30)
- self.state = 502
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if _la==lfrXParser.T__27:
- self.state = 501
- self.vector()
-
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class LhsContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def variables(self):
- return self.getTypedRuleContext(lfrXParser.VariablesContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_lhs
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterLhs" ):
- listener.enterLhs(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitLhs" ):
- listener.exitLhs(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitLhs" ):
- return visitor.visitLhs(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def lhs(self):
-
- localctx = lfrXParser.LhsContext(self, self._ctx, self.state)
- self.enterRule(localctx, 102, self.RULE_lhs)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 504
- self.variables()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class IoassignstatContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def explicitIOBlock(self):
- return self.getTypedRuleContext(lfrXParser.ExplicitIOBlockContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_ioassignstat
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterIoassignstat" ):
- listener.enterIoassignstat(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitIoassignstat" ):
- listener.exitIoassignstat(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitIoassignstat" ):
- return visitor.visitIoassignstat(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def ioassignstat(self):
-
- localctx = lfrXParser.IoassignstatContext(self, self._ctx, self.state)
- self.enterRule(localctx, 104, self.RULE_ioassignstat)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 506
- self.explicitIOBlock()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class TechnologydirectivesContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def performancedirective(self):
- return self.getTypedRuleContext(lfrXParser.PerformancedirectiveContext,0)
-
-
- def technologymappingdirective(self):
- return self.getTypedRuleContext(lfrXParser.TechnologymappingdirectiveContext,0)
-
-
- def materialmappingdirective(self):
- return self.getTypedRuleContext(lfrXParser.MaterialmappingdirectiveContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_technologydirectives
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterTechnologydirectives" ):
- listener.enterTechnologydirectives(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitTechnologydirectives" ):
- listener.exitTechnologydirectives(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitTechnologydirectives" ):
- return visitor.visitTechnologydirectives(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def technologydirectives(self):
-
- localctx = lfrXParser.TechnologydirectivesContext(self, self._ctx, self.state)
- self.enterRule(localctx, 106, self.RULE_technologydirectives)
- try:
- self.state = 511
- self._errHandler.sync(self)
- token = self._input.LA(1)
- if token in [lfrXParser.T__34]:
- self.enterOuterAlt(localctx, 1)
- self.state = 508
- self.performancedirective()
- pass
- elif token in [lfrXParser.T__31]:
- self.enterOuterAlt(localctx, 2)
- self.state = 509
- self.technologymappingdirective()
- pass
- elif token in [lfrXParser.T__33]:
- self.enterOuterAlt(localctx, 3)
- self.state = 510
- self.materialmappingdirective()
- pass
- else:
- raise NoViableAltException(self)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class TechnologymappingdirectiveContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
- self.assignmode = None # Token
-
- def mappingoperator(self):
- return self.getTypedRuleContext(lfrXParser.MappingoperatorContext,0)
-
-
- def ID(self, i:int=None):
- if i is None:
- return self.getTokens(lfrXParser.ID)
- else:
- return self.getToken(lfrXParser.ID, i)
-
- def getRuleIndex(self):
- return lfrXParser.RULE_technologymappingdirective
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterTechnologymappingdirective" ):
- listener.enterTechnologymappingdirective(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitTechnologymappingdirective" ):
- listener.exitTechnologymappingdirective(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitTechnologymappingdirective" ):
- return visitor.visitTechnologymappingdirective(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def technologymappingdirective(self):
-
- localctx = lfrXParser.TechnologymappingdirectiveContext(self, self._ctx, self.state)
- self.enterRule(localctx, 108, self.RULE_technologymappingdirective)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 513
- self.match(lfrXParser.T__31)
- self.state = 514
- self.match(lfrXParser.T__32)
- self.state = 516
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while True:
- self.state = 515
- self.match(lfrXParser.ID)
- self.state = 518
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if not (_la==lfrXParser.ID):
- break
-
- self.state = 520
- self.match(lfrXParser.T__32)
- self.state = 521
- self.match(lfrXParser.T__32)
- self.state = 524
- self._errHandler.sync(self)
- token = self._input.LA(1)
- if token in [lfrXParser.T__18, lfrXParser.T__37, lfrXParser.T__38, lfrXParser.T__39, lfrXParser.T__40, lfrXParser.T__41, lfrXParser.T__42, lfrXParser.T__43, lfrXParser.T__44, lfrXParser.T__45, lfrXParser.T__46, lfrXParser.T__47, lfrXParser.T__48, lfrXParser.T__49, lfrXParser.T__50, lfrXParser.T__51, lfrXParser.T__52, lfrXParser.T__53, lfrXParser.T__54, lfrXParser.T__55, lfrXParser.T__56, lfrXParser.T__57, lfrXParser.T__58, lfrXParser.T__59, lfrXParser.T__60, lfrXParser.T__61, lfrXParser.T__62, lfrXParser.T__63, lfrXParser.T__64]:
- self.state = 522
- self.mappingoperator()
- pass
- elif token in [lfrXParser.T__22, lfrXParser.T__23, lfrXParser.T__25]:
- self.state = 523
- localctx.assignmode = self._input.LT(1)
- _la = self._input.LA(1)
- if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << lfrXParser.T__22) | (1 << lfrXParser.T__23) | (1 << lfrXParser.T__25))) != 0)):
- localctx.assignmode = self._errHandler.recoverInline(self)
- else:
- self._errHandler.reportMatch(self)
- self.consume()
- pass
- else:
- raise NoViableAltException(self)
-
- self.state = 526
- self.match(lfrXParser.T__32)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class MaterialmappingdirectiveContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
- self.materialtype = None # Token
-
- def ID(self, i:int=None):
- if i is None:
- return self.getTokens(lfrXParser.ID)
- else:
- return self.getToken(lfrXParser.ID, i)
-
- def getRuleIndex(self):
- return lfrXParser.RULE_materialmappingdirective
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterMaterialmappingdirective" ):
- listener.enterMaterialmappingdirective(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitMaterialmappingdirective" ):
- listener.exitMaterialmappingdirective(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitMaterialmappingdirective" ):
- return visitor.visitMaterialmappingdirective(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def materialmappingdirective(self):
-
- localctx = lfrXParser.MaterialmappingdirectiveContext(self, self._ctx, self.state)
- self.enterRule(localctx, 110, self.RULE_materialmappingdirective)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 528
- self.match(lfrXParser.T__33)
- self.state = 529
- self.match(lfrXParser.ID)
- self.state = 530
- localctx.materialtype = self.match(lfrXParser.ID)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class MappingoperatorContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def binary_operator(self):
- return self.getTypedRuleContext(lfrXParser.Binary_operatorContext,0)
-
-
- def unary_operator(self):
- return self.getTypedRuleContext(lfrXParser.Unary_operatorContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_mappingoperator
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterMappingoperator" ):
- listener.enterMappingoperator(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitMappingoperator" ):
- listener.exitMappingoperator(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitMappingoperator" ):
- return visitor.visitMappingoperator(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def mappingoperator(self):
-
- localctx = lfrXParser.MappingoperatorContext(self, self._ctx, self.state)
- self.enterRule(localctx, 112, self.RULE_mappingoperator)
- try:
- self.state = 534
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,53,self._ctx)
- if la_ == 1:
- self.enterOuterAlt(localctx, 1)
- self.state = 532
- self.binary_operator()
- pass
-
- elif la_ == 2:
- self.enterOuterAlt(localctx, 2)
- self.state = 533
- self.unary_operator()
- pass
-
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class PerformancedirectiveContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def mappingoperator(self):
- return self.getTypedRuleContext(lfrXParser.MappingoperatorContext,0)
-
-
- def constraint(self, i:int=None):
- if i is None:
- return self.getTypedRuleContexts(lfrXParser.ConstraintContext)
- else:
- return self.getTypedRuleContext(lfrXParser.ConstraintContext,i)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_performancedirective
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterPerformancedirective" ):
- listener.enterPerformancedirective(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitPerformancedirective" ):
- listener.exitPerformancedirective(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitPerformancedirective" ):
- return visitor.visitPerformancedirective(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def performancedirective(self):
-
- localctx = lfrXParser.PerformancedirectiveContext(self, self._ctx, self.state)
- self.enterRule(localctx, 114, self.RULE_performancedirective)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 536
- self.match(lfrXParser.T__34)
- self.state = 537
- self.match(lfrXParser.T__32)
- self.state = 538
- self.mappingoperator()
- self.state = 539
- self.match(lfrXParser.T__32)
- self.state = 540
- self.constraint()
- self.state = 545
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- while _la==lfrXParser.T__35 or _la==lfrXParser.T__36:
- self.state = 541
- _la = self._input.LA(1)
- if not(_la==lfrXParser.T__35 or _la==lfrXParser.T__36):
- self._errHandler.recoverInline(self)
- else:
- self._errHandler.reportMatch(self)
- self.consume()
- self.state = 542
- self.constraint()
- self.state = 547
- self._errHandler.sync(self)
- _la = self._input.LA(1)
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class ConstraintContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
- self.operator = None # Token
-
- def ID(self):
- return self.getToken(lfrXParser.ID, 0)
-
- def number(self):
- return self.getTypedRuleContext(lfrXParser.NumberContext,0)
-
-
- def unit(self):
- return self.getTypedRuleContext(lfrXParser.UnitContext,0)
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_constraint
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterConstraint" ):
- listener.enterConstraint(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitConstraint" ):
- listener.exitConstraint(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitConstraint" ):
- return visitor.visitConstraint(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def constraint(self):
-
- localctx = lfrXParser.ConstraintContext(self, self._ctx, self.state)
- self.enterRule(localctx, 116, self.RULE_constraint)
- try:
- self.state = 578
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,60,self._ctx)
- if la_ == 1:
- self.enterOuterAlt(localctx, 1)
- self.state = 548
- self.match(lfrXParser.ID)
- self.state = 549
- localctx.operator = self.match(lfrXParser.T__26)
- self.state = 550
- self.number()
- self.state = 552
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,55,self._ctx)
- if la_ == 1:
- self.state = 551
- self.unit()
-
-
- pass
-
- elif la_ == 2:
- self.enterOuterAlt(localctx, 2)
- self.state = 554
- self.match(lfrXParser.ID)
- self.state = 555
- localctx.operator = self.match(lfrXParser.T__37)
- self.state = 556
- self.number()
- self.state = 558
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,56,self._ctx)
- if la_ == 1:
- self.state = 557
- self.unit()
-
-
- pass
-
- elif la_ == 3:
- self.enterOuterAlt(localctx, 3)
- self.state = 560
- self.match(lfrXParser.ID)
- self.state = 561
- localctx.operator = self.match(lfrXParser.T__38)
- self.state = 562
- self.number()
- self.state = 564
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,57,self._ctx)
- if la_ == 1:
- self.state = 563
- self.unit()
-
-
- pass
-
- elif la_ == 4:
- self.enterOuterAlt(localctx, 4)
- self.state = 566
- self.match(lfrXParser.ID)
- self.state = 567
- localctx.operator = self.match(lfrXParser.T__39)
- self.state = 568
- self.number()
- self.state = 570
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,58,self._ctx)
- if la_ == 1:
- self.state = 569
- self.unit()
-
-
- pass
-
- elif la_ == 5:
- self.enterOuterAlt(localctx, 5)
- self.state = 572
- self.match(lfrXParser.ID)
- self.state = 573
- localctx.operator = self.match(lfrXParser.T__18)
- self.state = 574
- self.number()
- self.state = 576
- self._errHandler.sync(self)
- la_ = self._interp.adaptivePredict(self._input,59,self._ctx)
- if la_ == 1:
- self.state = 575
- self.unit()
-
-
- pass
-
-
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class UnitContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def ID(self):
- return self.getToken(lfrXParser.ID, 0)
-
- def getRuleIndex(self):
- return lfrXParser.RULE_unit
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterUnit" ):
- listener.enterUnit(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitUnit" ):
- listener.exitUnit(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitUnit" ):
- return visitor.visitUnit(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def unit(self):
-
- localctx = lfrXParser.UnitContext(self, self._ctx, self.state)
- self.enterRule(localctx, 118, self.RULE_unit)
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 580
- self.match(lfrXParser.ID)
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class Unary_operatorContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_unary_operator
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterUnary_operator" ):
- listener.enterUnary_operator(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitUnary_operator" ):
- listener.exitUnary_operator(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitUnary_operator" ):
- return visitor.visitUnary_operator(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def unary_operator(self):
-
- localctx = lfrXParser.Unary_operatorContext(self, self._ctx, self.state)
- self.enterRule(localctx, 120, self.RULE_unary_operator)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 582
- _la = self._input.LA(1)
- if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << lfrXParser.T__40) | (1 << lfrXParser.T__41) | (1 << lfrXParser.T__42) | (1 << lfrXParser.T__43) | (1 << lfrXParser.T__44) | (1 << lfrXParser.T__45) | (1 << lfrXParser.T__46) | (1 << lfrXParser.T__47) | (1 << lfrXParser.T__48) | (1 << lfrXParser.T__49) | (1 << lfrXParser.T__50))) != 0)):
- self._errHandler.recoverInline(self)
- else:
- self._errHandler.reportMatch(self)
- self.consume()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class Binary_operatorContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_binary_operator
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterBinary_operator" ):
- listener.enterBinary_operator(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitBinary_operator" ):
- listener.exitBinary_operator(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitBinary_operator" ):
- return visitor.visitBinary_operator(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def binary_operator(self):
-
- localctx = lfrXParser.Binary_operatorContext(self, self._ctx, self.state)
- self.enterRule(localctx, 122, self.RULE_binary_operator)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 584
- _la = self._input.LA(1)
- if not(((((_la - 19)) & ~0x3f) == 0 and ((1 << (_la - 19)) & ((1 << (lfrXParser.T__18 - 19)) | (1 << (lfrXParser.T__37 - 19)) | (1 << (lfrXParser.T__38 - 19)) | (1 << (lfrXParser.T__39 - 19)) | (1 << (lfrXParser.T__40 - 19)) | (1 << (lfrXParser.T__41 - 19)) | (1 << (lfrXParser.T__44 - 19)) | (1 << (lfrXParser.T__46 - 19)) | (1 << (lfrXParser.T__48 - 19)) | (1 << (lfrXParser.T__49 - 19)) | (1 << (lfrXParser.T__50 - 19)) | (1 << (lfrXParser.T__51 - 19)) | (1 << (lfrXParser.T__52 - 19)) | (1 << (lfrXParser.T__53 - 19)) | (1 << (lfrXParser.T__54 - 19)) | (1 << (lfrXParser.T__55 - 19)) | (1 << (lfrXParser.T__56 - 19)) | (1 << (lfrXParser.T__57 - 19)) | (1 << (lfrXParser.T__58 - 19)) | (1 << (lfrXParser.T__59 - 19)) | (1 << (lfrXParser.T__60 - 19)) | (1 << (lfrXParser.T__61 - 19)) | (1 << (lfrXParser.T__62 - 19)) | (1 << (lfrXParser.T__63 - 19)) | (1 << (lfrXParser.T__64 - 19)))) != 0)):
- self._errHandler.recoverInline(self)
- else:
- self._errHandler.reportMatch(self)
- self.consume()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class Unary_module_path_operatorContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_unary_module_path_operator
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterUnary_module_path_operator" ):
- listener.enterUnary_module_path_operator(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitUnary_module_path_operator" ):
- listener.exitUnary_module_path_operator(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitUnary_module_path_operator" ):
- return visitor.visitUnary_module_path_operator(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def unary_module_path_operator(self):
-
- localctx = lfrXParser.Unary_module_path_operatorContext(self, self._ctx, self.state)
- self.enterRule(localctx, 124, self.RULE_unary_module_path_operator)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 586
- _la = self._input.LA(1)
- if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << lfrXParser.T__42) | (1 << lfrXParser.T__43) | (1 << lfrXParser.T__44) | (1 << lfrXParser.T__45) | (1 << lfrXParser.T__46) | (1 << lfrXParser.T__47) | (1 << lfrXParser.T__48) | (1 << lfrXParser.T__49) | (1 << lfrXParser.T__50))) != 0)):
- self._errHandler.recoverInline(self)
- else:
- self._errHandler.reportMatch(self)
- self.consume()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class Binary_module_path_operatorContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
-
- def getRuleIndex(self):
- return lfrXParser.RULE_binary_module_path_operator
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterBinary_module_path_operator" ):
- listener.enterBinary_module_path_operator(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitBinary_module_path_operator" ):
- listener.exitBinary_module_path_operator(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitBinary_module_path_operator" ):
- return visitor.visitBinary_module_path_operator(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def binary_module_path_operator(self):
-
- localctx = lfrXParser.Binary_module_path_operatorContext(self, self._ctx, self.state)
- self.enterRule(localctx, 126, self.RULE_binary_module_path_operator)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 588
- _la = self._input.LA(1)
- if not((((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << lfrXParser.T__44) | (1 << lfrXParser.T__46) | (1 << lfrXParser.T__48) | (1 << lfrXParser.T__49) | (1 << lfrXParser.T__50) | (1 << lfrXParser.T__54) | (1 << lfrXParser.T__55) | (1 << lfrXParser.T__58) | (1 << lfrXParser.T__59))) != 0)):
- self._errHandler.recoverInline(self)
- else:
- self._errHandler.reportMatch(self)
- self.consume()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
- class NumberContext(ParserRuleContext):
- __slots__ = 'parser'
-
- def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
- super().__init__(parent, invokingState)
- self.parser = parser
-
- def Decimal_number(self):
- return self.getToken(lfrXParser.Decimal_number, 0)
-
- def Octal_number(self):
- return self.getToken(lfrXParser.Octal_number, 0)
-
- def Binary_number(self):
- return self.getToken(lfrXParser.Binary_number, 0)
-
- def Hex_number(self):
- return self.getToken(lfrXParser.Hex_number, 0)
-
- def Real_number(self):
- return self.getToken(lfrXParser.Real_number, 0)
-
- def getRuleIndex(self):
- return lfrXParser.RULE_number
-
- def enterRule(self, listener:ParseTreeListener):
- if hasattr( listener, "enterNumber" ):
- listener.enterNumber(self)
-
- def exitRule(self, listener:ParseTreeListener):
- if hasattr( listener, "exitNumber" ):
- listener.exitNumber(self)
-
- def accept(self, visitor:ParseTreeVisitor):
- if hasattr( visitor, "visitNumber" ):
- return visitor.visitNumber(self)
- else:
- return visitor.visitChildren(self)
-
-
-
-
- def number(self):
-
- localctx = lfrXParser.NumberContext(self, self._ctx, self.state)
- self.enterRule(localctx, 128, self.RULE_number)
- self._la = 0 # Token type
- try:
- self.enterOuterAlt(localctx, 1)
- self.state = 590
- _la = self._input.LA(1)
- if not(((((_la - 71)) & ~0x3f) == 0 and ((1 << (_la - 71)) & ((1 << (lfrXParser.Real_number - 71)) | (1 << (lfrXParser.Decimal_number - 71)) | (1 << (lfrXParser.Binary_number - 71)) | (1 << (lfrXParser.Octal_number - 71)) | (1 << (lfrXParser.Hex_number - 71)))) != 0)):
- self._errHandler.recoverInline(self)
- else:
- self._errHandler.reportMatch(self)
- self.consume()
- except RecognitionException as re:
- localctx.exception = re
- self._errHandler.reportError(self, re)
- self._errHandler.recover(self, re)
- finally:
- self.exitRule()
- return localctx
-
-
-
-
-
diff --git a/lfr/antlrgen/reggie/reggie.interp b/lfr/antlrgen/reggie/reggie.interp
new file mode 100644
index 0000000..e0d67b3
--- /dev/null
+++ b/lfr/antlrgen/reggie/reggie.interp
@@ -0,0 +1,65 @@
+token literal names:
+null
+'{'
+','
+'}'
+'('
+')'
+':'
+'['
+']'
+'*'
+'+'
+'|'
+'->'
+'<->'
+null
+'?'
+null
+null
+null
+null
+
+token symbolic names:
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+ID
+QUESTIONMARK_WILDCARD
+WS
+NL
+INT
+STRING
+
+rule names:
+graph
+graphstatement
+statementmodifier
+basestatement
+subgraph
+vertex
+coloringfilter
+structuralvertexpattern
+intmodifier
+starmodifier
+plusmodifier
+structuralid
+labelfilter
+label
+vertex2vertex
+edge
+
+
+atn:
+[4, 1, 19, 150, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 37, 8, 0, 10, 0, 12, 0, 40, 9, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 50, 8, 1, 1, 2, 1, 2, 1, 2, 3, 2, 55, 8, 2, 1, 3, 1, 3, 1, 3, 3, 3, 60, 8, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 5, 4, 69, 8, 4, 10, 4, 12, 4, 72, 9, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 3, 5, 79, 8, 5, 1, 5, 3, 5, 82, 8, 5, 1, 5, 5, 5, 85, 8, 5, 10, 5, 12, 5, 88, 9, 5, 1, 6, 1, 6, 1, 6, 1, 6, 5, 6, 94, 8, 6, 10, 6, 12, 6, 97, 9, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 3, 7, 104, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 5, 12, 119, 8, 12, 10, 12, 12, 12, 122, 9, 12, 1, 12, 1, 12, 1, 12, 1, 12, 5, 12, 128, 8, 12, 10, 12, 12, 12, 131, 9, 12, 1, 12, 1, 12, 3, 12, 135, 8, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 5, 14, 143, 8, 14, 10, 14, 12, 14, 146, 9, 14, 1, 15, 1, 15, 1, 15, 0, 0, 16, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 0, 2, 1, 0, 14, 15, 1, 0, 12, 13, 150, 0, 32, 1, 0, 0, 0, 2, 49, 1, 0, 0, 0, 4, 54, 1, 0, 0, 0, 6, 59, 1, 0, 0, 0, 8, 61, 1, 0, 0, 0, 10, 75, 1, 0, 0, 0, 12, 89, 1, 0, 0, 0, 14, 103, 1, 0, 0, 0, 16, 105, 1, 0, 0, 0, 18, 109, 1, 0, 0, 0, 20, 111, 1, 0, 0, 0, 22, 113, 1, 0, 0, 0, 24, 134, 1, 0, 0, 0, 26, 136, 1, 0, 0, 0, 28, 138, 1, 0, 0, 0, 30, 147, 1, 0, 0, 0, 32, 33, 5, 1, 0, 0, 33, 38, 3, 2, 1, 0, 34, 35, 5, 2, 0, 0, 35, 37, 3, 2, 1, 0, 36, 34, 1, 0, 0, 0, 37, 40, 1, 0, 0, 0, 38, 36, 1, 0, 0, 0, 38, 39, 1, 0, 0, 0, 39, 41, 1, 0, 0, 0, 40, 38, 1, 0, 0, 0, 41, 42, 5, 3, 0, 0, 42, 1, 1, 0, 0, 0, 43, 50, 3, 6, 3, 0, 44, 45, 5, 4, 0, 0, 45, 46, 3, 6, 3, 0, 46, 47, 5, 5, 0, 0, 47, 48, 3, 4, 2, 0, 48, 50, 1, 0, 0, 0, 49, 43, 1, 0, 0, 0, 49, 44, 1, 0, 0, 0, 50, 3, 1, 0, 0, 0, 51, 55, 3, 16, 8, 0, 52, 55, 3, 20, 10, 0, 53, 55, 3, 18, 9, 0, 54, 51, 1, 0, 0, 0, 54, 52, 1, 0, 0, 0, 54, 53, 1, 0, 0, 0, 55, 5, 1, 0, 0, 0, 56, 60, 3, 8, 4, 0, 57, 60, 3, 28, 14, 0, 58, 60, 3, 10, 5, 0, 59, 56, 1, 0, 0, 0, 59, 57, 1, 0, 0, 0, 59, 58, 1, 0, 0, 0, 60, 7, 1, 0, 0, 0, 61, 62, 5, 14, 0, 0, 62, 63, 5, 6, 0, 0, 63, 64, 1, 0, 0, 0, 64, 65, 5, 1, 0, 0, 65, 70, 3, 28, 14, 0, 66, 67, 5, 2, 0, 0, 67, 69, 3, 28, 14, 0, 68, 66, 1, 0, 0, 0, 69, 72, 1, 0, 0, 0, 70, 68, 1, 0, 0, 0, 70, 71, 1, 0, 0, 0, 71, 73, 1, 0, 0, 0, 72, 70, 1, 0, 0, 0, 73, 74, 5, 3, 0, 0, 74, 9, 1, 0, 0, 0, 75, 78, 3, 22, 11, 0, 76, 77, 5, 6, 0, 0, 77, 79, 3, 24, 12, 0, 78, 76, 1, 0, 0, 0, 78, 79, 1, 0, 0, 0, 79, 81, 1, 0, 0, 0, 80, 82, 3, 12, 6, 0, 81, 80, 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82, 86, 1, 0, 0, 0, 83, 85, 3, 14, 7, 0, 84, 83, 1, 0, 0, 0, 85, 88, 1, 0, 0, 0, 86, 84, 1, 0, 0, 0, 86, 87, 1, 0, 0, 0, 87, 11, 1, 0, 0, 0, 88, 86, 1, 0, 0, 0, 89, 90, 5, 1, 0, 0, 90, 95, 5, 19, 0, 0, 91, 92, 5, 2, 0, 0, 92, 94, 5, 19, 0, 0, 93, 91, 1, 0, 0, 0, 94, 97, 1, 0, 0, 0, 95, 93, 1, 0, 0, 0, 95, 96, 1, 0, 0, 0, 96, 98, 1, 0, 0, 0, 97, 95, 1, 0, 0, 0, 98, 99, 5, 3, 0, 0, 99, 13, 1, 0, 0, 0, 100, 104, 3, 16, 8, 0, 101, 104, 3, 18, 9, 0, 102, 104, 3, 20, 10, 0, 103, 100, 1, 0, 0, 0, 103, 101, 1, 0, 0, 0, 103, 102, 1, 0, 0, 0, 104, 15, 1, 0, 0, 0, 105, 106, 5, 7, 0, 0, 106, 107, 5, 18, 0, 0, 107, 108, 5, 8, 0, 0, 108, 17, 1, 0, 0, 0, 109, 110, 5, 9, 0, 0, 110, 19, 1, 0, 0, 0, 111, 112, 5, 10, 0, 0, 112, 21, 1, 0, 0, 0, 113, 114, 7, 0, 0, 0, 114, 23, 1, 0, 0, 0, 115, 120, 3, 26, 13, 0, 116, 117, 5, 11, 0, 0, 117, 119, 3, 26, 13, 0, 118, 116, 1, 0, 0, 0, 119, 122, 1, 0, 0, 0, 120, 118, 1, 0, 0, 0, 120, 121, 1, 0, 0, 0, 121, 135, 1, 0, 0, 0, 122, 120, 1, 0, 0, 0, 123, 124, 5, 4, 0, 0, 124, 129, 3, 26, 13, 0, 125, 126, 5, 11, 0, 0, 126, 128, 3, 26, 13, 0, 127, 125, 1, 0, 0, 0, 128, 131, 1, 0, 0, 0, 129, 127, 1, 0, 0, 0, 129, 130, 1, 0, 0, 0, 130, 132, 1, 0, 0, 0, 131, 129, 1, 0, 0, 0, 132, 133, 5, 5, 0, 0, 133, 135, 1, 0, 0, 0, 134, 115, 1, 0, 0, 0, 134, 123, 1, 0, 0, 0, 135, 25, 1, 0, 0, 0, 136, 137, 5, 14, 0, 0, 137, 27, 1, 0, 0, 0, 138, 144, 3, 10, 5, 0, 139, 140, 3, 30, 15, 0, 140, 141, 3, 10, 5, 0, 141, 143, 1, 0, 0, 0, 142, 139, 1, 0, 0, 0, 143, 146, 1, 0, 0, 0, 144, 142, 1, 0, 0, 0, 144, 145, 1, 0, 0, 0, 145, 29, 1, 0, 0, 0, 146, 144, 1, 0, 0, 0, 147, 148, 7, 1, 0, 0, 148, 31, 1, 0, 0, 0, 14, 38, 49, 54, 59, 70, 78, 81, 86, 95, 103, 120, 129, 134, 144]
\ No newline at end of file
diff --git a/lfr/antlrgen/reggie/reggie.tokens b/lfr/antlrgen/reggie/reggie.tokens
new file mode 100644
index 0000000..dd59d83
--- /dev/null
+++ b/lfr/antlrgen/reggie/reggie.tokens
@@ -0,0 +1,33 @@
+T__0=1
+T__1=2
+T__2=3
+T__3=4
+T__4=5
+T__5=6
+T__6=7
+T__7=8
+T__8=9
+T__9=10
+T__10=11
+T__11=12
+T__12=13
+ID=14
+QUESTIONMARK_WILDCARD=15
+WS=16
+NL=17
+INT=18
+STRING=19
+'{'=1
+','=2
+'}'=3
+'('=4
+')'=5
+':'=6
+'['=7
+']'=8
+'*'=9
+'+'=10
+'|'=11
+'->'=12
+'<->'=13
+'?'=15
diff --git a/lfr/antlrgen/reggie/reggieLexer.interp b/lfr/antlrgen/reggie/reggieLexer.interp
new file mode 100644
index 0000000..4c01e37
--- /dev/null
+++ b/lfr/antlrgen/reggie/reggieLexer.interp
@@ -0,0 +1,78 @@
+token literal names:
+null
+'{'
+','
+'}'
+'('
+')'
+':'
+'['
+']'
+'*'
+'+'
+'|'
+'->'
+'<->'
+null
+'?'
+null
+null
+null
+null
+
+token symbolic names:
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+ID
+QUESTIONMARK_WILDCARD
+WS
+NL
+INT
+STRING
+
+rule names:
+T__0
+T__1
+T__2
+T__3
+T__4
+T__5
+T__6
+T__7
+T__8
+T__9
+T__10
+T__11
+T__12
+ID
+QUESTIONMARK_WILDCARD
+WS
+NL
+INT
+STRING
+HEX
+UNICODE
+ESC
+SAFECODEPOINT
+
+channel names:
+DEFAULT_TOKEN_CHANNEL
+HIDDEN
+
+mode names:
+DEFAULT_MODE
+
+atn:
+[4, 0, 19, 129, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 5, 13, 79, 8, 13, 10, 13, 12, 13, 82, 9, 13, 1, 14, 1, 14, 1, 15, 4, 15, 87, 8, 15, 11, 15, 12, 15, 88, 1, 15, 1, 15, 1, 16, 4, 16, 94, 8, 16, 11, 16, 12, 16, 95, 1, 16, 1, 16, 1, 17, 4, 17, 101, 8, 17, 11, 17, 12, 17, 102, 1, 18, 1, 18, 1, 18, 5, 18, 108, 8, 18, 10, 18, 12, 18, 111, 9, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 3, 21, 126, 8, 21, 1, 22, 1, 22, 0, 0, 23, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 0, 41, 0, 43, 0, 45, 0, 1, 0, 8, 3, 0, 65, 90, 95, 95, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 2, 0, 9, 9, 32, 32, 2, 0, 10, 10, 13, 13, 1, 0, 48, 57, 3, 0, 48, 57, 65, 70, 97, 102, 8, 0, 34, 34, 47, 47, 92, 92, 98, 98, 102, 102, 110, 110, 114, 114, 116, 116, 3, 0, 0, 31, 34, 34, 92, 92, 131, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 1, 47, 1, 0, 0, 0, 3, 49, 1, 0, 0, 0, 5, 51, 1, 0, 0, 0, 7, 53, 1, 0, 0, 0, 9, 55, 1, 0, 0, 0, 11, 57, 1, 0, 0, 0, 13, 59, 1, 0, 0, 0, 15, 61, 1, 0, 0, 0, 17, 63, 1, 0, 0, 0, 19, 65, 1, 0, 0, 0, 21, 67, 1, 0, 0, 0, 23, 69, 1, 0, 0, 0, 25, 72, 1, 0, 0, 0, 27, 76, 1, 0, 0, 0, 29, 83, 1, 0, 0, 0, 31, 86, 1, 0, 0, 0, 33, 93, 1, 0, 0, 0, 35, 100, 1, 0, 0, 0, 37, 104, 1, 0, 0, 0, 39, 114, 1, 0, 0, 0, 41, 116, 1, 0, 0, 0, 43, 122, 1, 0, 0, 0, 45, 127, 1, 0, 0, 0, 47, 48, 5, 123, 0, 0, 48, 2, 1, 0, 0, 0, 49, 50, 5, 44, 0, 0, 50, 4, 1, 0, 0, 0, 51, 52, 5, 125, 0, 0, 52, 6, 1, 0, 0, 0, 53, 54, 5, 40, 0, 0, 54, 8, 1, 0, 0, 0, 55, 56, 5, 41, 0, 0, 56, 10, 1, 0, 0, 0, 57, 58, 5, 58, 0, 0, 58, 12, 1, 0, 0, 0, 59, 60, 5, 91, 0, 0, 60, 14, 1, 0, 0, 0, 61, 62, 5, 93, 0, 0, 62, 16, 1, 0, 0, 0, 63, 64, 5, 42, 0, 0, 64, 18, 1, 0, 0, 0, 65, 66, 5, 43, 0, 0, 66, 20, 1, 0, 0, 0, 67, 68, 5, 124, 0, 0, 68, 22, 1, 0, 0, 0, 69, 70, 5, 45, 0, 0, 70, 71, 5, 62, 0, 0, 71, 24, 1, 0, 0, 0, 72, 73, 5, 60, 0, 0, 73, 74, 5, 45, 0, 0, 74, 75, 5, 62, 0, 0, 75, 26, 1, 0, 0, 0, 76, 80, 7, 0, 0, 0, 77, 79, 7, 1, 0, 0, 78, 77, 1, 0, 0, 0, 79, 82, 1, 0, 0, 0, 80, 78, 1, 0, 0, 0, 80, 81, 1, 0, 0, 0, 81, 28, 1, 0, 0, 0, 82, 80, 1, 0, 0, 0, 83, 84, 5, 63, 0, 0, 84, 30, 1, 0, 0, 0, 85, 87, 7, 2, 0, 0, 86, 85, 1, 0, 0, 0, 87, 88, 1, 0, 0, 0, 88, 86, 1, 0, 0, 0, 88, 89, 1, 0, 0, 0, 89, 90, 1, 0, 0, 0, 90, 91, 6, 15, 0, 0, 91, 32, 1, 0, 0, 0, 92, 94, 7, 3, 0, 0, 93, 92, 1, 0, 0, 0, 94, 95, 1, 0, 0, 0, 95, 93, 1, 0, 0, 0, 95, 96, 1, 0, 0, 0, 96, 97, 1, 0, 0, 0, 97, 98, 6, 16, 0, 0, 98, 34, 1, 0, 0, 0, 99, 101, 7, 4, 0, 0, 100, 99, 1, 0, 0, 0, 101, 102, 1, 0, 0, 0, 102, 100, 1, 0, 0, 0, 102, 103, 1, 0, 0, 0, 103, 36, 1, 0, 0, 0, 104, 109, 5, 34, 0, 0, 105, 108, 3, 43, 21, 0, 106, 108, 3, 45, 22, 0, 107, 105, 1, 0, 0, 0, 107, 106, 1, 0, 0, 0, 108, 111, 1, 0, 0, 0, 109, 107, 1, 0, 0, 0, 109, 110, 1, 0, 0, 0, 110, 112, 1, 0, 0, 0, 111, 109, 1, 0, 0, 0, 112, 113, 5, 34, 0, 0, 113, 38, 1, 0, 0, 0, 114, 115, 7, 5, 0, 0, 115, 40, 1, 0, 0, 0, 116, 117, 5, 117, 0, 0, 117, 118, 3, 39, 19, 0, 118, 119, 3, 39, 19, 0, 119, 120, 3, 39, 19, 0, 120, 121, 3, 39, 19, 0, 121, 42, 1, 0, 0, 0, 122, 125, 5, 92, 0, 0, 123, 126, 7, 6, 0, 0, 124, 126, 3, 41, 20, 0, 125, 123, 1, 0, 0, 0, 125, 124, 1, 0, 0, 0, 126, 44, 1, 0, 0, 0, 127, 128, 8, 7, 0, 0, 128, 46, 1, 0, 0, 0, 8, 0, 80, 88, 95, 102, 107, 109, 125, 1, 6, 0, 0]
\ No newline at end of file
diff --git a/lfr/antlrgen/reggie/reggieLexer.py b/lfr/antlrgen/reggie/reggieLexer.py
new file mode 100644
index 0000000..7f449fc
--- /dev/null
+++ b/lfr/antlrgen/reggie/reggieLexer.py
@@ -0,0 +1,1303 @@
+# Generated from ./reggie.g4 by ANTLR 4.10.1
+import sys
+from io import StringIO
+
+from antlr4 import *
+
+if sys.version_info[1] > 5:
+ from typing import TextIO
+else:
+ from typing.io import TextIO
+
+
+def serializedATN():
+ return [
+ 4,
+ 0,
+ 19,
+ 129,
+ 6,
+ -1,
+ 2,
+ 0,
+ 7,
+ 0,
+ 2,
+ 1,
+ 7,
+ 1,
+ 2,
+ 2,
+ 7,
+ 2,
+ 2,
+ 3,
+ 7,
+ 3,
+ 2,
+ 4,
+ 7,
+ 4,
+ 2,
+ 5,
+ 7,
+ 5,
+ 2,
+ 6,
+ 7,
+ 6,
+ 2,
+ 7,
+ 7,
+ 7,
+ 2,
+ 8,
+ 7,
+ 8,
+ 2,
+ 9,
+ 7,
+ 9,
+ 2,
+ 10,
+ 7,
+ 10,
+ 2,
+ 11,
+ 7,
+ 11,
+ 2,
+ 12,
+ 7,
+ 12,
+ 2,
+ 13,
+ 7,
+ 13,
+ 2,
+ 14,
+ 7,
+ 14,
+ 2,
+ 15,
+ 7,
+ 15,
+ 2,
+ 16,
+ 7,
+ 16,
+ 2,
+ 17,
+ 7,
+ 17,
+ 2,
+ 18,
+ 7,
+ 18,
+ 2,
+ 19,
+ 7,
+ 19,
+ 2,
+ 20,
+ 7,
+ 20,
+ 2,
+ 21,
+ 7,
+ 21,
+ 2,
+ 22,
+ 7,
+ 22,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 2,
+ 1,
+ 3,
+ 1,
+ 3,
+ 1,
+ 4,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 5,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 7,
+ 1,
+ 7,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 9,
+ 1,
+ 9,
+ 1,
+ 10,
+ 1,
+ 10,
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 12,
+ 1,
+ 12,
+ 1,
+ 12,
+ 1,
+ 12,
+ 1,
+ 13,
+ 1,
+ 13,
+ 5,
+ 13,
+ 79,
+ 8,
+ 13,
+ 10,
+ 13,
+ 12,
+ 13,
+ 82,
+ 9,
+ 13,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 15,
+ 4,
+ 15,
+ 87,
+ 8,
+ 15,
+ 11,
+ 15,
+ 12,
+ 15,
+ 88,
+ 1,
+ 15,
+ 1,
+ 15,
+ 1,
+ 16,
+ 4,
+ 16,
+ 94,
+ 8,
+ 16,
+ 11,
+ 16,
+ 12,
+ 16,
+ 95,
+ 1,
+ 16,
+ 1,
+ 16,
+ 1,
+ 17,
+ 4,
+ 17,
+ 101,
+ 8,
+ 17,
+ 11,
+ 17,
+ 12,
+ 17,
+ 102,
+ 1,
+ 18,
+ 1,
+ 18,
+ 1,
+ 18,
+ 5,
+ 18,
+ 108,
+ 8,
+ 18,
+ 10,
+ 18,
+ 12,
+ 18,
+ 111,
+ 9,
+ 18,
+ 1,
+ 18,
+ 1,
+ 18,
+ 1,
+ 19,
+ 1,
+ 19,
+ 1,
+ 20,
+ 1,
+ 20,
+ 1,
+ 20,
+ 1,
+ 20,
+ 1,
+ 20,
+ 1,
+ 20,
+ 1,
+ 21,
+ 1,
+ 21,
+ 1,
+ 21,
+ 3,
+ 21,
+ 126,
+ 8,
+ 21,
+ 1,
+ 22,
+ 1,
+ 22,
+ 0,
+ 0,
+ 23,
+ 1,
+ 1,
+ 3,
+ 2,
+ 5,
+ 3,
+ 7,
+ 4,
+ 9,
+ 5,
+ 11,
+ 6,
+ 13,
+ 7,
+ 15,
+ 8,
+ 17,
+ 9,
+ 19,
+ 10,
+ 21,
+ 11,
+ 23,
+ 12,
+ 25,
+ 13,
+ 27,
+ 14,
+ 29,
+ 15,
+ 31,
+ 16,
+ 33,
+ 17,
+ 35,
+ 18,
+ 37,
+ 19,
+ 39,
+ 0,
+ 41,
+ 0,
+ 43,
+ 0,
+ 45,
+ 0,
+ 1,
+ 0,
+ 8,
+ 3,
+ 0,
+ 65,
+ 90,
+ 95,
+ 95,
+ 97,
+ 122,
+ 4,
+ 0,
+ 48,
+ 57,
+ 65,
+ 90,
+ 95,
+ 95,
+ 97,
+ 122,
+ 2,
+ 0,
+ 9,
+ 9,
+ 32,
+ 32,
+ 2,
+ 0,
+ 10,
+ 10,
+ 13,
+ 13,
+ 1,
+ 0,
+ 48,
+ 57,
+ 3,
+ 0,
+ 48,
+ 57,
+ 65,
+ 70,
+ 97,
+ 102,
+ 8,
+ 0,
+ 34,
+ 34,
+ 47,
+ 47,
+ 92,
+ 92,
+ 98,
+ 98,
+ 102,
+ 102,
+ 110,
+ 110,
+ 114,
+ 114,
+ 116,
+ 116,
+ 3,
+ 0,
+ 0,
+ 31,
+ 34,
+ 34,
+ 92,
+ 92,
+ 131,
+ 0,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 3,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 5,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 7,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 9,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 11,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 13,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 15,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 17,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 19,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 21,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 23,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 25,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 27,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 29,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 31,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 33,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 35,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 37,
+ 1,
+ 0,
+ 0,
+ 0,
+ 1,
+ 47,
+ 1,
+ 0,
+ 0,
+ 0,
+ 3,
+ 49,
+ 1,
+ 0,
+ 0,
+ 0,
+ 5,
+ 51,
+ 1,
+ 0,
+ 0,
+ 0,
+ 7,
+ 53,
+ 1,
+ 0,
+ 0,
+ 0,
+ 9,
+ 55,
+ 1,
+ 0,
+ 0,
+ 0,
+ 11,
+ 57,
+ 1,
+ 0,
+ 0,
+ 0,
+ 13,
+ 59,
+ 1,
+ 0,
+ 0,
+ 0,
+ 15,
+ 61,
+ 1,
+ 0,
+ 0,
+ 0,
+ 17,
+ 63,
+ 1,
+ 0,
+ 0,
+ 0,
+ 19,
+ 65,
+ 1,
+ 0,
+ 0,
+ 0,
+ 21,
+ 67,
+ 1,
+ 0,
+ 0,
+ 0,
+ 23,
+ 69,
+ 1,
+ 0,
+ 0,
+ 0,
+ 25,
+ 72,
+ 1,
+ 0,
+ 0,
+ 0,
+ 27,
+ 76,
+ 1,
+ 0,
+ 0,
+ 0,
+ 29,
+ 83,
+ 1,
+ 0,
+ 0,
+ 0,
+ 31,
+ 86,
+ 1,
+ 0,
+ 0,
+ 0,
+ 33,
+ 93,
+ 1,
+ 0,
+ 0,
+ 0,
+ 35,
+ 100,
+ 1,
+ 0,
+ 0,
+ 0,
+ 37,
+ 104,
+ 1,
+ 0,
+ 0,
+ 0,
+ 39,
+ 114,
+ 1,
+ 0,
+ 0,
+ 0,
+ 41,
+ 116,
+ 1,
+ 0,
+ 0,
+ 0,
+ 43,
+ 122,
+ 1,
+ 0,
+ 0,
+ 0,
+ 45,
+ 127,
+ 1,
+ 0,
+ 0,
+ 0,
+ 47,
+ 48,
+ 5,
+ 123,
+ 0,
+ 0,
+ 48,
+ 2,
+ 1,
+ 0,
+ 0,
+ 0,
+ 49,
+ 50,
+ 5,
+ 44,
+ 0,
+ 0,
+ 50,
+ 4,
+ 1,
+ 0,
+ 0,
+ 0,
+ 51,
+ 52,
+ 5,
+ 125,
+ 0,
+ 0,
+ 52,
+ 6,
+ 1,
+ 0,
+ 0,
+ 0,
+ 53,
+ 54,
+ 5,
+ 40,
+ 0,
+ 0,
+ 54,
+ 8,
+ 1,
+ 0,
+ 0,
+ 0,
+ 55,
+ 56,
+ 5,
+ 41,
+ 0,
+ 0,
+ 56,
+ 10,
+ 1,
+ 0,
+ 0,
+ 0,
+ 57,
+ 58,
+ 5,
+ 58,
+ 0,
+ 0,
+ 58,
+ 12,
+ 1,
+ 0,
+ 0,
+ 0,
+ 59,
+ 60,
+ 5,
+ 91,
+ 0,
+ 0,
+ 60,
+ 14,
+ 1,
+ 0,
+ 0,
+ 0,
+ 61,
+ 62,
+ 5,
+ 93,
+ 0,
+ 0,
+ 62,
+ 16,
+ 1,
+ 0,
+ 0,
+ 0,
+ 63,
+ 64,
+ 5,
+ 42,
+ 0,
+ 0,
+ 64,
+ 18,
+ 1,
+ 0,
+ 0,
+ 0,
+ 65,
+ 66,
+ 5,
+ 43,
+ 0,
+ 0,
+ 66,
+ 20,
+ 1,
+ 0,
+ 0,
+ 0,
+ 67,
+ 68,
+ 5,
+ 124,
+ 0,
+ 0,
+ 68,
+ 22,
+ 1,
+ 0,
+ 0,
+ 0,
+ 69,
+ 70,
+ 5,
+ 45,
+ 0,
+ 0,
+ 70,
+ 71,
+ 5,
+ 62,
+ 0,
+ 0,
+ 71,
+ 24,
+ 1,
+ 0,
+ 0,
+ 0,
+ 72,
+ 73,
+ 5,
+ 60,
+ 0,
+ 0,
+ 73,
+ 74,
+ 5,
+ 45,
+ 0,
+ 0,
+ 74,
+ 75,
+ 5,
+ 62,
+ 0,
+ 0,
+ 75,
+ 26,
+ 1,
+ 0,
+ 0,
+ 0,
+ 76,
+ 80,
+ 7,
+ 0,
+ 0,
+ 0,
+ 77,
+ 79,
+ 7,
+ 1,
+ 0,
+ 0,
+ 78,
+ 77,
+ 1,
+ 0,
+ 0,
+ 0,
+ 79,
+ 82,
+ 1,
+ 0,
+ 0,
+ 0,
+ 80,
+ 78,
+ 1,
+ 0,
+ 0,
+ 0,
+ 80,
+ 81,
+ 1,
+ 0,
+ 0,
+ 0,
+ 81,
+ 28,
+ 1,
+ 0,
+ 0,
+ 0,
+ 82,
+ 80,
+ 1,
+ 0,
+ 0,
+ 0,
+ 83,
+ 84,
+ 5,
+ 63,
+ 0,
+ 0,
+ 84,
+ 30,
+ 1,
+ 0,
+ 0,
+ 0,
+ 85,
+ 87,
+ 7,
+ 2,
+ 0,
+ 0,
+ 86,
+ 85,
+ 1,
+ 0,
+ 0,
+ 0,
+ 87,
+ 88,
+ 1,
+ 0,
+ 0,
+ 0,
+ 88,
+ 86,
+ 1,
+ 0,
+ 0,
+ 0,
+ 88,
+ 89,
+ 1,
+ 0,
+ 0,
+ 0,
+ 89,
+ 90,
+ 1,
+ 0,
+ 0,
+ 0,
+ 90,
+ 91,
+ 6,
+ 15,
+ 0,
+ 0,
+ 91,
+ 32,
+ 1,
+ 0,
+ 0,
+ 0,
+ 92,
+ 94,
+ 7,
+ 3,
+ 0,
+ 0,
+ 93,
+ 92,
+ 1,
+ 0,
+ 0,
+ 0,
+ 94,
+ 95,
+ 1,
+ 0,
+ 0,
+ 0,
+ 95,
+ 93,
+ 1,
+ 0,
+ 0,
+ 0,
+ 95,
+ 96,
+ 1,
+ 0,
+ 0,
+ 0,
+ 96,
+ 97,
+ 1,
+ 0,
+ 0,
+ 0,
+ 97,
+ 98,
+ 6,
+ 16,
+ 0,
+ 0,
+ 98,
+ 34,
+ 1,
+ 0,
+ 0,
+ 0,
+ 99,
+ 101,
+ 7,
+ 4,
+ 0,
+ 0,
+ 100,
+ 99,
+ 1,
+ 0,
+ 0,
+ 0,
+ 101,
+ 102,
+ 1,
+ 0,
+ 0,
+ 0,
+ 102,
+ 100,
+ 1,
+ 0,
+ 0,
+ 0,
+ 102,
+ 103,
+ 1,
+ 0,
+ 0,
+ 0,
+ 103,
+ 36,
+ 1,
+ 0,
+ 0,
+ 0,
+ 104,
+ 109,
+ 5,
+ 34,
+ 0,
+ 0,
+ 105,
+ 108,
+ 3,
+ 43,
+ 21,
+ 0,
+ 106,
+ 108,
+ 3,
+ 45,
+ 22,
+ 0,
+ 107,
+ 105,
+ 1,
+ 0,
+ 0,
+ 0,
+ 107,
+ 106,
+ 1,
+ 0,
+ 0,
+ 0,
+ 108,
+ 111,
+ 1,
+ 0,
+ 0,
+ 0,
+ 109,
+ 107,
+ 1,
+ 0,
+ 0,
+ 0,
+ 109,
+ 110,
+ 1,
+ 0,
+ 0,
+ 0,
+ 110,
+ 112,
+ 1,
+ 0,
+ 0,
+ 0,
+ 111,
+ 109,
+ 1,
+ 0,
+ 0,
+ 0,
+ 112,
+ 113,
+ 5,
+ 34,
+ 0,
+ 0,
+ 113,
+ 38,
+ 1,
+ 0,
+ 0,
+ 0,
+ 114,
+ 115,
+ 7,
+ 5,
+ 0,
+ 0,
+ 115,
+ 40,
+ 1,
+ 0,
+ 0,
+ 0,
+ 116,
+ 117,
+ 5,
+ 117,
+ 0,
+ 0,
+ 117,
+ 118,
+ 3,
+ 39,
+ 19,
+ 0,
+ 118,
+ 119,
+ 3,
+ 39,
+ 19,
+ 0,
+ 119,
+ 120,
+ 3,
+ 39,
+ 19,
+ 0,
+ 120,
+ 121,
+ 3,
+ 39,
+ 19,
+ 0,
+ 121,
+ 42,
+ 1,
+ 0,
+ 0,
+ 0,
+ 122,
+ 125,
+ 5,
+ 92,
+ 0,
+ 0,
+ 123,
+ 126,
+ 7,
+ 6,
+ 0,
+ 0,
+ 124,
+ 126,
+ 3,
+ 41,
+ 20,
+ 0,
+ 125,
+ 123,
+ 1,
+ 0,
+ 0,
+ 0,
+ 125,
+ 124,
+ 1,
+ 0,
+ 0,
+ 0,
+ 126,
+ 44,
+ 1,
+ 0,
+ 0,
+ 0,
+ 127,
+ 128,
+ 8,
+ 7,
+ 0,
+ 0,
+ 128,
+ 46,
+ 1,
+ 0,
+ 0,
+ 0,
+ 8,
+ 0,
+ 80,
+ 88,
+ 95,
+ 102,
+ 107,
+ 109,
+ 125,
+ 1,
+ 6,
+ 0,
+ 0,
+ ]
+
+
+class reggieLexer(Lexer):
+ atn = ATNDeserializer().deserialize(serializedATN())
+
+ decisionsToDFA = [DFA(ds, i) for i, ds in enumerate(atn.decisionToState)]
+
+ T__0 = 1
+ T__1 = 2
+ T__2 = 3
+ T__3 = 4
+ T__4 = 5
+ T__5 = 6
+ T__6 = 7
+ T__7 = 8
+ T__8 = 9
+ T__9 = 10
+ T__10 = 11
+ T__11 = 12
+ T__12 = 13
+ ID = 14
+ QUESTIONMARK_WILDCARD = 15
+ WS = 16
+ NL = 17
+ INT = 18
+ STRING = 19
+
+ channelNames = ["DEFAULT_TOKEN_CHANNEL", "HIDDEN"]
+
+ modeNames = ["DEFAULT_MODE"]
+
+ literalNames = [
+ "",
+ "'{'",
+ "','",
+ "'}'",
+ "'('",
+ "')'",
+ "':'",
+ "'['",
+ "']'",
+ "'*'",
+ "'+'",
+ "'|'",
+ "'->'",
+ "'<->'",
+ "'?'",
+ ]
+
+ symbolicNames = [
+ "",
+ "ID",
+ "QUESTIONMARK_WILDCARD",
+ "WS",
+ "NL",
+ "INT",
+ "STRING",
+ ]
+
+ ruleNames = [
+ "T__0",
+ "T__1",
+ "T__2",
+ "T__3",
+ "T__4",
+ "T__5",
+ "T__6",
+ "T__7",
+ "T__8",
+ "T__9",
+ "T__10",
+ "T__11",
+ "T__12",
+ "ID",
+ "QUESTIONMARK_WILDCARD",
+ "WS",
+ "NL",
+ "INT",
+ "STRING",
+ "HEX",
+ "UNICODE",
+ "ESC",
+ "SAFECODEPOINT",
+ ]
+
+ grammarFileName = "reggie.g4"
+
+ def __init__(self, input=None, output: TextIO = sys.stdout):
+ super().__init__(input, output)
+ self.checkVersion("4.10.1")
+ self._interp = LexerATNSimulator(
+ self, self.atn, self.decisionsToDFA, PredictionContextCache()
+ )
+ self._actions = None
+ self._predicates = None
diff --git a/lfr/antlrgen/reggie/reggieLexer.tokens b/lfr/antlrgen/reggie/reggieLexer.tokens
new file mode 100644
index 0000000..dd59d83
--- /dev/null
+++ b/lfr/antlrgen/reggie/reggieLexer.tokens
@@ -0,0 +1,33 @@
+T__0=1
+T__1=2
+T__2=3
+T__3=4
+T__4=5
+T__5=6
+T__6=7
+T__7=8
+T__8=9
+T__9=10
+T__10=11
+T__11=12
+T__12=13
+ID=14
+QUESTIONMARK_WILDCARD=15
+WS=16
+NL=17
+INT=18
+STRING=19
+'{'=1
+','=2
+'}'=3
+'('=4
+')'=5
+':'=6
+'['=7
+']'=8
+'*'=9
+'+'=10
+'|'=11
+'->'=12
+'<->'=13
+'?'=15
diff --git a/lfr/antlrgen/reggie/reggieListener.py b/lfr/antlrgen/reggie/reggieListener.py
new file mode 100644
index 0000000..e8c4d0c
--- /dev/null
+++ b/lfr/antlrgen/reggie/reggieListener.py
@@ -0,0 +1,145 @@
+# Generated from ./reggie.g4 by ANTLR 4.10.1
+from antlr4 import *
+
+if __name__ is not None and "." in __name__:
+ from .reggieParser import reggieParser
+else:
+ from reggieParser import reggieParser
+
+
+# This class defines a complete listener for a parse tree produced by reggieParser.
+class reggieListener(ParseTreeListener):
+ # Enter a parse tree produced by reggieParser#graph.
+ def enterGraph(self, ctx: reggieParser.GraphContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#graph.
+ def exitGraph(self, ctx: reggieParser.GraphContext):
+ pass
+
+ # Enter a parse tree produced by reggieParser#graphstatement.
+ def enterGraphstatement(self, ctx: reggieParser.GraphstatementContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#graphstatement.
+ def exitGraphstatement(self, ctx: reggieParser.GraphstatementContext):
+ pass
+
+ # Enter a parse tree produced by reggieParser#statementmodifier.
+ def enterStatementmodifier(self, ctx: reggieParser.StatementmodifierContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#statementmodifier.
+ def exitStatementmodifier(self, ctx: reggieParser.StatementmodifierContext):
+ pass
+
+ # Enter a parse tree produced by reggieParser#basestatement.
+ def enterBasestatement(self, ctx: reggieParser.BasestatementContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#basestatement.
+ def exitBasestatement(self, ctx: reggieParser.BasestatementContext):
+ pass
+
+ # Enter a parse tree produced by reggieParser#subgraph.
+ def enterSubgraph(self, ctx: reggieParser.SubgraphContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#subgraph.
+ def exitSubgraph(self, ctx: reggieParser.SubgraphContext):
+ pass
+
+ # Enter a parse tree produced by reggieParser#vertex.
+ def enterVertex(self, ctx: reggieParser.VertexContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#vertex.
+ def exitVertex(self, ctx: reggieParser.VertexContext):
+ pass
+
+ # Enter a parse tree produced by reggieParser#coloringfilter.
+ def enterColoringfilter(self, ctx: reggieParser.ColoringfilterContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#coloringfilter.
+ def exitColoringfilter(self, ctx: reggieParser.ColoringfilterContext):
+ pass
+
+ # Enter a parse tree produced by reggieParser#structuralvertexpattern.
+ def enterStructuralvertexpattern(
+ self, ctx: reggieParser.StructuralvertexpatternContext
+ ):
+ pass
+
+ # Exit a parse tree produced by reggieParser#structuralvertexpattern.
+ def exitStructuralvertexpattern(
+ self, ctx: reggieParser.StructuralvertexpatternContext
+ ):
+ pass
+
+ # Enter a parse tree produced by reggieParser#intmodifier.
+ def enterIntmodifier(self, ctx: reggieParser.IntmodifierContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#intmodifier.
+ def exitIntmodifier(self, ctx: reggieParser.IntmodifierContext):
+ pass
+
+ # Enter a parse tree produced by reggieParser#starmodifier.
+ def enterStarmodifier(self, ctx: reggieParser.StarmodifierContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#starmodifier.
+ def exitStarmodifier(self, ctx: reggieParser.StarmodifierContext):
+ pass
+
+ # Enter a parse tree produced by reggieParser#plusmodifier.
+ def enterPlusmodifier(self, ctx: reggieParser.PlusmodifierContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#plusmodifier.
+ def exitPlusmodifier(self, ctx: reggieParser.PlusmodifierContext):
+ pass
+
+ # Enter a parse tree produced by reggieParser#structuralid.
+ def enterStructuralid(self, ctx: reggieParser.StructuralidContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#structuralid.
+ def exitStructuralid(self, ctx: reggieParser.StructuralidContext):
+ pass
+
+ # Enter a parse tree produced by reggieParser#labelfilter.
+ def enterLabelfilter(self, ctx: reggieParser.LabelfilterContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#labelfilter.
+ def exitLabelfilter(self, ctx: reggieParser.LabelfilterContext):
+ pass
+
+ # Enter a parse tree produced by reggieParser#label.
+ def enterLabel(self, ctx: reggieParser.LabelContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#label.
+ def exitLabel(self, ctx: reggieParser.LabelContext):
+ pass
+
+ # Enter a parse tree produced by reggieParser#vertex2vertex.
+ def enterVertex2vertex(self, ctx: reggieParser.Vertex2vertexContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#vertex2vertex.
+ def exitVertex2vertex(self, ctx: reggieParser.Vertex2vertexContext):
+ pass
+
+ # Enter a parse tree produced by reggieParser#edge.
+ def enterEdge(self, ctx: reggieParser.EdgeContext):
+ pass
+
+ # Exit a parse tree produced by reggieParser#edge.
+ def exitEdge(self, ctx: reggieParser.EdgeContext):
+ pass
+
+
+del reggieParser
diff --git a/lfr/antlrgen/reggie/reggieParser.py b/lfr/antlrgen/reggie/reggieParser.py
new file mode 100644
index 0000000..1e6edf0
--- /dev/null
+++ b/lfr/antlrgen/reggie/reggieParser.py
@@ -0,0 +1,2397 @@
+# Generated from ./reggie.g4 by ANTLR 4.10.1
+# encoding: utf-8
+import sys
+from io import StringIO
+
+from antlr4 import *
+
+if sys.version_info[1] > 5:
+ from typing import TextIO
+else:
+ from typing.io import TextIO
+
+
+def serializedATN():
+ return [
+ 4,
+ 1,
+ 19,
+ 150,
+ 2,
+ 0,
+ 7,
+ 0,
+ 2,
+ 1,
+ 7,
+ 1,
+ 2,
+ 2,
+ 7,
+ 2,
+ 2,
+ 3,
+ 7,
+ 3,
+ 2,
+ 4,
+ 7,
+ 4,
+ 2,
+ 5,
+ 7,
+ 5,
+ 2,
+ 6,
+ 7,
+ 6,
+ 2,
+ 7,
+ 7,
+ 7,
+ 2,
+ 8,
+ 7,
+ 8,
+ 2,
+ 9,
+ 7,
+ 9,
+ 2,
+ 10,
+ 7,
+ 10,
+ 2,
+ 11,
+ 7,
+ 11,
+ 2,
+ 12,
+ 7,
+ 12,
+ 2,
+ 13,
+ 7,
+ 13,
+ 2,
+ 14,
+ 7,
+ 14,
+ 2,
+ 15,
+ 7,
+ 15,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 5,
+ 0,
+ 37,
+ 8,
+ 0,
+ 10,
+ 0,
+ 12,
+ 0,
+ 40,
+ 9,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 3,
+ 1,
+ 50,
+ 8,
+ 1,
+ 1,
+ 2,
+ 1,
+ 2,
+ 1,
+ 2,
+ 3,
+ 2,
+ 55,
+ 8,
+ 2,
+ 1,
+ 3,
+ 1,
+ 3,
+ 1,
+ 3,
+ 3,
+ 3,
+ 60,
+ 8,
+ 3,
+ 1,
+ 4,
+ 1,
+ 4,
+ 1,
+ 4,
+ 1,
+ 4,
+ 1,
+ 4,
+ 1,
+ 4,
+ 1,
+ 4,
+ 5,
+ 4,
+ 69,
+ 8,
+ 4,
+ 10,
+ 4,
+ 12,
+ 4,
+ 72,
+ 9,
+ 4,
+ 1,
+ 4,
+ 1,
+ 4,
+ 1,
+ 5,
+ 1,
+ 5,
+ 1,
+ 5,
+ 3,
+ 5,
+ 79,
+ 8,
+ 5,
+ 1,
+ 5,
+ 3,
+ 5,
+ 82,
+ 8,
+ 5,
+ 1,
+ 5,
+ 5,
+ 5,
+ 85,
+ 8,
+ 5,
+ 10,
+ 5,
+ 12,
+ 5,
+ 88,
+ 9,
+ 5,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 5,
+ 6,
+ 94,
+ 8,
+ 6,
+ 10,
+ 6,
+ 12,
+ 6,
+ 97,
+ 9,
+ 6,
+ 1,
+ 6,
+ 1,
+ 6,
+ 1,
+ 7,
+ 1,
+ 7,
+ 1,
+ 7,
+ 3,
+ 7,
+ 104,
+ 8,
+ 7,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 8,
+ 1,
+ 9,
+ 1,
+ 9,
+ 1,
+ 10,
+ 1,
+ 10,
+ 1,
+ 11,
+ 1,
+ 11,
+ 1,
+ 12,
+ 1,
+ 12,
+ 1,
+ 12,
+ 5,
+ 12,
+ 119,
+ 8,
+ 12,
+ 10,
+ 12,
+ 12,
+ 12,
+ 122,
+ 9,
+ 12,
+ 1,
+ 12,
+ 1,
+ 12,
+ 1,
+ 12,
+ 1,
+ 12,
+ 5,
+ 12,
+ 128,
+ 8,
+ 12,
+ 10,
+ 12,
+ 12,
+ 12,
+ 131,
+ 9,
+ 12,
+ 1,
+ 12,
+ 1,
+ 12,
+ 3,
+ 12,
+ 135,
+ 8,
+ 12,
+ 1,
+ 13,
+ 1,
+ 13,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 14,
+ 1,
+ 14,
+ 5,
+ 14,
+ 143,
+ 8,
+ 14,
+ 10,
+ 14,
+ 12,
+ 14,
+ 146,
+ 9,
+ 14,
+ 1,
+ 15,
+ 1,
+ 15,
+ 1,
+ 15,
+ 0,
+ 0,
+ 16,
+ 0,
+ 2,
+ 4,
+ 6,
+ 8,
+ 10,
+ 12,
+ 14,
+ 16,
+ 18,
+ 20,
+ 22,
+ 24,
+ 26,
+ 28,
+ 30,
+ 0,
+ 2,
+ 1,
+ 0,
+ 14,
+ 15,
+ 1,
+ 0,
+ 12,
+ 13,
+ 150,
+ 0,
+ 32,
+ 1,
+ 0,
+ 0,
+ 0,
+ 2,
+ 49,
+ 1,
+ 0,
+ 0,
+ 0,
+ 4,
+ 54,
+ 1,
+ 0,
+ 0,
+ 0,
+ 6,
+ 59,
+ 1,
+ 0,
+ 0,
+ 0,
+ 8,
+ 61,
+ 1,
+ 0,
+ 0,
+ 0,
+ 10,
+ 75,
+ 1,
+ 0,
+ 0,
+ 0,
+ 12,
+ 89,
+ 1,
+ 0,
+ 0,
+ 0,
+ 14,
+ 103,
+ 1,
+ 0,
+ 0,
+ 0,
+ 16,
+ 105,
+ 1,
+ 0,
+ 0,
+ 0,
+ 18,
+ 109,
+ 1,
+ 0,
+ 0,
+ 0,
+ 20,
+ 111,
+ 1,
+ 0,
+ 0,
+ 0,
+ 22,
+ 113,
+ 1,
+ 0,
+ 0,
+ 0,
+ 24,
+ 134,
+ 1,
+ 0,
+ 0,
+ 0,
+ 26,
+ 136,
+ 1,
+ 0,
+ 0,
+ 0,
+ 28,
+ 138,
+ 1,
+ 0,
+ 0,
+ 0,
+ 30,
+ 147,
+ 1,
+ 0,
+ 0,
+ 0,
+ 32,
+ 33,
+ 5,
+ 1,
+ 0,
+ 0,
+ 33,
+ 38,
+ 3,
+ 2,
+ 1,
+ 0,
+ 34,
+ 35,
+ 5,
+ 2,
+ 0,
+ 0,
+ 35,
+ 37,
+ 3,
+ 2,
+ 1,
+ 0,
+ 36,
+ 34,
+ 1,
+ 0,
+ 0,
+ 0,
+ 37,
+ 40,
+ 1,
+ 0,
+ 0,
+ 0,
+ 38,
+ 36,
+ 1,
+ 0,
+ 0,
+ 0,
+ 38,
+ 39,
+ 1,
+ 0,
+ 0,
+ 0,
+ 39,
+ 41,
+ 1,
+ 0,
+ 0,
+ 0,
+ 40,
+ 38,
+ 1,
+ 0,
+ 0,
+ 0,
+ 41,
+ 42,
+ 5,
+ 3,
+ 0,
+ 0,
+ 42,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ 43,
+ 50,
+ 3,
+ 6,
+ 3,
+ 0,
+ 44,
+ 45,
+ 5,
+ 4,
+ 0,
+ 0,
+ 45,
+ 46,
+ 3,
+ 6,
+ 3,
+ 0,
+ 46,
+ 47,
+ 5,
+ 5,
+ 0,
+ 0,
+ 47,
+ 48,
+ 3,
+ 4,
+ 2,
+ 0,
+ 48,
+ 50,
+ 1,
+ 0,
+ 0,
+ 0,
+ 49,
+ 43,
+ 1,
+ 0,
+ 0,
+ 0,
+ 49,
+ 44,
+ 1,
+ 0,
+ 0,
+ 0,
+ 50,
+ 3,
+ 1,
+ 0,
+ 0,
+ 0,
+ 51,
+ 55,
+ 3,
+ 16,
+ 8,
+ 0,
+ 52,
+ 55,
+ 3,
+ 20,
+ 10,
+ 0,
+ 53,
+ 55,
+ 3,
+ 18,
+ 9,
+ 0,
+ 54,
+ 51,
+ 1,
+ 0,
+ 0,
+ 0,
+ 54,
+ 52,
+ 1,
+ 0,
+ 0,
+ 0,
+ 54,
+ 53,
+ 1,
+ 0,
+ 0,
+ 0,
+ 55,
+ 5,
+ 1,
+ 0,
+ 0,
+ 0,
+ 56,
+ 60,
+ 3,
+ 8,
+ 4,
+ 0,
+ 57,
+ 60,
+ 3,
+ 28,
+ 14,
+ 0,
+ 58,
+ 60,
+ 3,
+ 10,
+ 5,
+ 0,
+ 59,
+ 56,
+ 1,
+ 0,
+ 0,
+ 0,
+ 59,
+ 57,
+ 1,
+ 0,
+ 0,
+ 0,
+ 59,
+ 58,
+ 1,
+ 0,
+ 0,
+ 0,
+ 60,
+ 7,
+ 1,
+ 0,
+ 0,
+ 0,
+ 61,
+ 62,
+ 5,
+ 14,
+ 0,
+ 0,
+ 62,
+ 63,
+ 5,
+ 6,
+ 0,
+ 0,
+ 63,
+ 64,
+ 1,
+ 0,
+ 0,
+ 0,
+ 64,
+ 65,
+ 5,
+ 1,
+ 0,
+ 0,
+ 65,
+ 70,
+ 3,
+ 28,
+ 14,
+ 0,
+ 66,
+ 67,
+ 5,
+ 2,
+ 0,
+ 0,
+ 67,
+ 69,
+ 3,
+ 28,
+ 14,
+ 0,
+ 68,
+ 66,
+ 1,
+ 0,
+ 0,
+ 0,
+ 69,
+ 72,
+ 1,
+ 0,
+ 0,
+ 0,
+ 70,
+ 68,
+ 1,
+ 0,
+ 0,
+ 0,
+ 70,
+ 71,
+ 1,
+ 0,
+ 0,
+ 0,
+ 71,
+ 73,
+ 1,
+ 0,
+ 0,
+ 0,
+ 72,
+ 70,
+ 1,
+ 0,
+ 0,
+ 0,
+ 73,
+ 74,
+ 5,
+ 3,
+ 0,
+ 0,
+ 74,
+ 9,
+ 1,
+ 0,
+ 0,
+ 0,
+ 75,
+ 78,
+ 3,
+ 22,
+ 11,
+ 0,
+ 76,
+ 77,
+ 5,
+ 6,
+ 0,
+ 0,
+ 77,
+ 79,
+ 3,
+ 24,
+ 12,
+ 0,
+ 78,
+ 76,
+ 1,
+ 0,
+ 0,
+ 0,
+ 78,
+ 79,
+ 1,
+ 0,
+ 0,
+ 0,
+ 79,
+ 81,
+ 1,
+ 0,
+ 0,
+ 0,
+ 80,
+ 82,
+ 3,
+ 12,
+ 6,
+ 0,
+ 81,
+ 80,
+ 1,
+ 0,
+ 0,
+ 0,
+ 81,
+ 82,
+ 1,
+ 0,
+ 0,
+ 0,
+ 82,
+ 86,
+ 1,
+ 0,
+ 0,
+ 0,
+ 83,
+ 85,
+ 3,
+ 14,
+ 7,
+ 0,
+ 84,
+ 83,
+ 1,
+ 0,
+ 0,
+ 0,
+ 85,
+ 88,
+ 1,
+ 0,
+ 0,
+ 0,
+ 86,
+ 84,
+ 1,
+ 0,
+ 0,
+ 0,
+ 86,
+ 87,
+ 1,
+ 0,
+ 0,
+ 0,
+ 87,
+ 11,
+ 1,
+ 0,
+ 0,
+ 0,
+ 88,
+ 86,
+ 1,
+ 0,
+ 0,
+ 0,
+ 89,
+ 90,
+ 5,
+ 1,
+ 0,
+ 0,
+ 90,
+ 95,
+ 5,
+ 19,
+ 0,
+ 0,
+ 91,
+ 92,
+ 5,
+ 2,
+ 0,
+ 0,
+ 92,
+ 94,
+ 5,
+ 19,
+ 0,
+ 0,
+ 93,
+ 91,
+ 1,
+ 0,
+ 0,
+ 0,
+ 94,
+ 97,
+ 1,
+ 0,
+ 0,
+ 0,
+ 95,
+ 93,
+ 1,
+ 0,
+ 0,
+ 0,
+ 95,
+ 96,
+ 1,
+ 0,
+ 0,
+ 0,
+ 96,
+ 98,
+ 1,
+ 0,
+ 0,
+ 0,
+ 97,
+ 95,
+ 1,
+ 0,
+ 0,
+ 0,
+ 98,
+ 99,
+ 5,
+ 3,
+ 0,
+ 0,
+ 99,
+ 13,
+ 1,
+ 0,
+ 0,
+ 0,
+ 100,
+ 104,
+ 3,
+ 16,
+ 8,
+ 0,
+ 101,
+ 104,
+ 3,
+ 18,
+ 9,
+ 0,
+ 102,
+ 104,
+ 3,
+ 20,
+ 10,
+ 0,
+ 103,
+ 100,
+ 1,
+ 0,
+ 0,
+ 0,
+ 103,
+ 101,
+ 1,
+ 0,
+ 0,
+ 0,
+ 103,
+ 102,
+ 1,
+ 0,
+ 0,
+ 0,
+ 104,
+ 15,
+ 1,
+ 0,
+ 0,
+ 0,
+ 105,
+ 106,
+ 5,
+ 7,
+ 0,
+ 0,
+ 106,
+ 107,
+ 5,
+ 18,
+ 0,
+ 0,
+ 107,
+ 108,
+ 5,
+ 8,
+ 0,
+ 0,
+ 108,
+ 17,
+ 1,
+ 0,
+ 0,
+ 0,
+ 109,
+ 110,
+ 5,
+ 9,
+ 0,
+ 0,
+ 110,
+ 19,
+ 1,
+ 0,
+ 0,
+ 0,
+ 111,
+ 112,
+ 5,
+ 10,
+ 0,
+ 0,
+ 112,
+ 21,
+ 1,
+ 0,
+ 0,
+ 0,
+ 113,
+ 114,
+ 7,
+ 0,
+ 0,
+ 0,
+ 114,
+ 23,
+ 1,
+ 0,
+ 0,
+ 0,
+ 115,
+ 120,
+ 3,
+ 26,
+ 13,
+ 0,
+ 116,
+ 117,
+ 5,
+ 11,
+ 0,
+ 0,
+ 117,
+ 119,
+ 3,
+ 26,
+ 13,
+ 0,
+ 118,
+ 116,
+ 1,
+ 0,
+ 0,
+ 0,
+ 119,
+ 122,
+ 1,
+ 0,
+ 0,
+ 0,
+ 120,
+ 118,
+ 1,
+ 0,
+ 0,
+ 0,
+ 120,
+ 121,
+ 1,
+ 0,
+ 0,
+ 0,
+ 121,
+ 135,
+ 1,
+ 0,
+ 0,
+ 0,
+ 122,
+ 120,
+ 1,
+ 0,
+ 0,
+ 0,
+ 123,
+ 124,
+ 5,
+ 4,
+ 0,
+ 0,
+ 124,
+ 129,
+ 3,
+ 26,
+ 13,
+ 0,
+ 125,
+ 126,
+ 5,
+ 11,
+ 0,
+ 0,
+ 126,
+ 128,
+ 3,
+ 26,
+ 13,
+ 0,
+ 127,
+ 125,
+ 1,
+ 0,
+ 0,
+ 0,
+ 128,
+ 131,
+ 1,
+ 0,
+ 0,
+ 0,
+ 129,
+ 127,
+ 1,
+ 0,
+ 0,
+ 0,
+ 129,
+ 130,
+ 1,
+ 0,
+ 0,
+ 0,
+ 130,
+ 132,
+ 1,
+ 0,
+ 0,
+ 0,
+ 131,
+ 129,
+ 1,
+ 0,
+ 0,
+ 0,
+ 132,
+ 133,
+ 5,
+ 5,
+ 0,
+ 0,
+ 133,
+ 135,
+ 1,
+ 0,
+ 0,
+ 0,
+ 134,
+ 115,
+ 1,
+ 0,
+ 0,
+ 0,
+ 134,
+ 123,
+ 1,
+ 0,
+ 0,
+ 0,
+ 135,
+ 25,
+ 1,
+ 0,
+ 0,
+ 0,
+ 136,
+ 137,
+ 5,
+ 14,
+ 0,
+ 0,
+ 137,
+ 27,
+ 1,
+ 0,
+ 0,
+ 0,
+ 138,
+ 144,
+ 3,
+ 10,
+ 5,
+ 0,
+ 139,
+ 140,
+ 3,
+ 30,
+ 15,
+ 0,
+ 140,
+ 141,
+ 3,
+ 10,
+ 5,
+ 0,
+ 141,
+ 143,
+ 1,
+ 0,
+ 0,
+ 0,
+ 142,
+ 139,
+ 1,
+ 0,
+ 0,
+ 0,
+ 143,
+ 146,
+ 1,
+ 0,
+ 0,
+ 0,
+ 144,
+ 142,
+ 1,
+ 0,
+ 0,
+ 0,
+ 144,
+ 145,
+ 1,
+ 0,
+ 0,
+ 0,
+ 145,
+ 29,
+ 1,
+ 0,
+ 0,
+ 0,
+ 146,
+ 144,
+ 1,
+ 0,
+ 0,
+ 0,
+ 147,
+ 148,
+ 7,
+ 1,
+ 0,
+ 0,
+ 148,
+ 31,
+ 1,
+ 0,
+ 0,
+ 0,
+ 14,
+ 38,
+ 49,
+ 54,
+ 59,
+ 70,
+ 78,
+ 81,
+ 86,
+ 95,
+ 103,
+ 120,
+ 129,
+ 134,
+ 144,
+ ]
+
+
+class reggieParser(Parser):
+ grammarFileName = "reggie.g4"
+
+ atn = ATNDeserializer().deserialize(serializedATN())
+
+ decisionsToDFA = [DFA(ds, i) for i, ds in enumerate(atn.decisionToState)]
+
+ sharedContextCache = PredictionContextCache()
+
+ literalNames = [
+ "",
+ "'{'",
+ "','",
+ "'}'",
+ "'('",
+ "')'",
+ "':'",
+ "'['",
+ "']'",
+ "'*'",
+ "'+'",
+ "'|'",
+ "'->'",
+ "'<->'",
+ "",
+ "'?'",
+ ]
+
+ symbolicNames = [
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "ID",
+ "QUESTIONMARK_WILDCARD",
+ "WS",
+ "NL",
+ "INT",
+ "STRING",
+ ]
+
+ RULE_graph = 0
+ RULE_graphstatement = 1
+ RULE_statementmodifier = 2
+ RULE_basestatement = 3
+ RULE_subgraph = 4
+ RULE_vertex = 5
+ RULE_coloringfilter = 6
+ RULE_structuralvertexpattern = 7
+ RULE_intmodifier = 8
+ RULE_starmodifier = 9
+ RULE_plusmodifier = 10
+ RULE_structuralid = 11
+ RULE_labelfilter = 12
+ RULE_label = 13
+ RULE_vertex2vertex = 14
+ RULE_edge = 15
+
+ ruleNames = [
+ "graph",
+ "graphstatement",
+ "statementmodifier",
+ "basestatement",
+ "subgraph",
+ "vertex",
+ "coloringfilter",
+ "structuralvertexpattern",
+ "intmodifier",
+ "starmodifier",
+ "plusmodifier",
+ "structuralid",
+ "labelfilter",
+ "label",
+ "vertex2vertex",
+ "edge",
+ ]
+
+ EOF = Token.EOF
+ T__0 = 1
+ T__1 = 2
+ T__2 = 3
+ T__3 = 4
+ T__4 = 5
+ T__5 = 6
+ T__6 = 7
+ T__7 = 8
+ T__8 = 9
+ T__9 = 10
+ T__10 = 11
+ T__11 = 12
+ T__12 = 13
+ ID = 14
+ QUESTIONMARK_WILDCARD = 15
+ WS = 16
+ NL = 17
+ INT = 18
+ STRING = 19
+
+ def __init__(self, input: TokenStream, output: TextIO = sys.stdout):
+ super().__init__(input, output)
+ self.checkVersion("4.10.1")
+ self._interp = ParserATNSimulator(
+ self, self.atn, self.decisionsToDFA, self.sharedContextCache
+ )
+ self._predicates = None
+
+ class GraphContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def graphstatement(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(reggieParser.GraphstatementContext)
+ else:
+ return self.getTypedRuleContext(reggieParser.GraphstatementContext, i)
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_graph
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterGraph"):
+ listener.enterGraph(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitGraph"):
+ listener.exitGraph(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitGraph"):
+ return visitor.visitGraph(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def graph(self):
+ localctx = reggieParser.GraphContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 0, self.RULE_graph)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 32
+ self.match(reggieParser.T__0)
+ self.state = 33
+ self.graphstatement()
+ self.state = 38
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == reggieParser.T__1:
+ self.state = 34
+ self.match(reggieParser.T__1)
+ self.state = 35
+ self.graphstatement()
+ self.state = 40
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ self.state = 41
+ self.match(reggieParser.T__2)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class GraphstatementContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def basestatement(self):
+ return self.getTypedRuleContext(reggieParser.BasestatementContext, 0)
+
+ def statementmodifier(self):
+ return self.getTypedRuleContext(reggieParser.StatementmodifierContext, 0)
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_graphstatement
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterGraphstatement"):
+ listener.enterGraphstatement(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitGraphstatement"):
+ listener.exitGraphstatement(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitGraphstatement"):
+ return visitor.visitGraphstatement(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def graphstatement(self):
+ localctx = reggieParser.GraphstatementContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 2, self.RULE_graphstatement)
+ try:
+ self.state = 49
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [reggieParser.ID, reggieParser.QUESTIONMARK_WILDCARD]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 43
+ self.basestatement()
+ pass
+ elif token in [reggieParser.T__3]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 44
+ self.match(reggieParser.T__3)
+ self.state = 45
+ self.basestatement()
+ self.state = 46
+ self.match(reggieParser.T__4)
+ self.state = 47
+ self.statementmodifier()
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class StatementmodifierContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def intmodifier(self):
+ return self.getTypedRuleContext(reggieParser.IntmodifierContext, 0)
+
+ def plusmodifier(self):
+ return self.getTypedRuleContext(reggieParser.PlusmodifierContext, 0)
+
+ def starmodifier(self):
+ return self.getTypedRuleContext(reggieParser.StarmodifierContext, 0)
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_statementmodifier
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterStatementmodifier"):
+ listener.enterStatementmodifier(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitStatementmodifier"):
+ listener.exitStatementmodifier(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitStatementmodifier"):
+ return visitor.visitStatementmodifier(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def statementmodifier(self):
+ localctx = reggieParser.StatementmodifierContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 4, self.RULE_statementmodifier)
+ try:
+ self.state = 54
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [reggieParser.T__6]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 51
+ self.intmodifier()
+ pass
+ elif token in [reggieParser.T__9]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 52
+ self.plusmodifier()
+ pass
+ elif token in [reggieParser.T__8]:
+ self.enterOuterAlt(localctx, 3)
+ self.state = 53
+ self.starmodifier()
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class BasestatementContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def subgraph(self):
+ return self.getTypedRuleContext(reggieParser.SubgraphContext, 0)
+
+ def vertex2vertex(self):
+ return self.getTypedRuleContext(reggieParser.Vertex2vertexContext, 0)
+
+ def vertex(self):
+ return self.getTypedRuleContext(reggieParser.VertexContext, 0)
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_basestatement
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterBasestatement"):
+ listener.enterBasestatement(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitBasestatement"):
+ listener.exitBasestatement(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitBasestatement"):
+ return visitor.visitBasestatement(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def basestatement(self):
+ localctx = reggieParser.BasestatementContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 6, self.RULE_basestatement)
+ try:
+ self.state = 59
+ self._errHandler.sync(self)
+ la_ = self._interp.adaptivePredict(self._input, 3, self._ctx)
+ if la_ == 1:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 56
+ self.subgraph()
+ pass
+
+ elif la_ == 2:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 57
+ self.vertex2vertex()
+ pass
+
+ elif la_ == 3:
+ self.enterOuterAlt(localctx, 3)
+ self.state = 58
+ self.vertex()
+ pass
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class SubgraphContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def vertex2vertex(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(reggieParser.Vertex2vertexContext)
+ else:
+ return self.getTypedRuleContext(reggieParser.Vertex2vertexContext, i)
+
+ def ID(self):
+ return self.getToken(reggieParser.ID, 0)
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_subgraph
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterSubgraph"):
+ listener.enterSubgraph(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitSubgraph"):
+ listener.exitSubgraph(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitSubgraph"):
+ return visitor.visitSubgraph(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def subgraph(self):
+ localctx = reggieParser.SubgraphContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 8, self.RULE_subgraph)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 61
+ self.match(reggieParser.ID)
+ self.state = 62
+ self.match(reggieParser.T__5)
+ self.state = 64
+ self.match(reggieParser.T__0)
+ self.state = 65
+ self.vertex2vertex()
+ self.state = 70
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == reggieParser.T__1:
+ self.state = 66
+ self.match(reggieParser.T__1)
+ self.state = 67
+ self.vertex2vertex()
+ self.state = 72
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ self.state = 73
+ self.match(reggieParser.T__2)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class VertexContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def structuralid(self):
+ return self.getTypedRuleContext(reggieParser.StructuralidContext, 0)
+
+ def labelfilter(self):
+ return self.getTypedRuleContext(reggieParser.LabelfilterContext, 0)
+
+ def coloringfilter(self):
+ return self.getTypedRuleContext(reggieParser.ColoringfilterContext, 0)
+
+ def structuralvertexpattern(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(
+ reggieParser.StructuralvertexpatternContext
+ )
+ else:
+ return self.getTypedRuleContext(
+ reggieParser.StructuralvertexpatternContext, i
+ )
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_vertex
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterVertex"):
+ listener.enterVertex(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitVertex"):
+ listener.exitVertex(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitVertex"):
+ return visitor.visitVertex(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def vertex(self):
+ localctx = reggieParser.VertexContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 10, self.RULE_vertex)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 75
+ self.structuralid()
+ self.state = 78
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la == reggieParser.T__5:
+ self.state = 76
+ self.match(reggieParser.T__5)
+ self.state = 77
+ self.labelfilter()
+
+ self.state = 81
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la == reggieParser.T__0:
+ self.state = 80
+ self.coloringfilter()
+
+ self.state = 86
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while ((_la) & ~0x3F) == 0 and (
+ (1 << _la)
+ & (
+ (1 << reggieParser.T__6)
+ | (1 << reggieParser.T__8)
+ | (1 << reggieParser.T__9)
+ )
+ ) != 0:
+ self.state = 83
+ self.structuralvertexpattern()
+ self.state = 88
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class ColoringfilterContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def STRING(self, i: int = None):
+ if i is None:
+ return self.getTokens(reggieParser.STRING)
+ else:
+ return self.getToken(reggieParser.STRING, i)
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_coloringfilter
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterColoringfilter"):
+ listener.enterColoringfilter(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitColoringfilter"):
+ listener.exitColoringfilter(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitColoringfilter"):
+ return visitor.visitColoringfilter(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def coloringfilter(self):
+ localctx = reggieParser.ColoringfilterContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 12, self.RULE_coloringfilter)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 89
+ self.match(reggieParser.T__0)
+ self.state = 90
+ self.match(reggieParser.STRING)
+ self.state = 95
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == reggieParser.T__1:
+ self.state = 91
+ self.match(reggieParser.T__1)
+ self.state = 92
+ self.match(reggieParser.STRING)
+ self.state = 97
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ self.state = 98
+ self.match(reggieParser.T__2)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class StructuralvertexpatternContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def intmodifier(self):
+ return self.getTypedRuleContext(reggieParser.IntmodifierContext, 0)
+
+ def starmodifier(self):
+ return self.getTypedRuleContext(reggieParser.StarmodifierContext, 0)
+
+ def plusmodifier(self):
+ return self.getTypedRuleContext(reggieParser.PlusmodifierContext, 0)
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_structuralvertexpattern
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterStructuralvertexpattern"):
+ listener.enterStructuralvertexpattern(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitStructuralvertexpattern"):
+ listener.exitStructuralvertexpattern(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitStructuralvertexpattern"):
+ return visitor.visitStructuralvertexpattern(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def structuralvertexpattern(self):
+ localctx = reggieParser.StructuralvertexpatternContext(
+ self, self._ctx, self.state
+ )
+ self.enterRule(localctx, 14, self.RULE_structuralvertexpattern)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 103
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [reggieParser.T__6]:
+ self.state = 100
+ self.intmodifier()
+ pass
+ elif token in [reggieParser.T__8]:
+ self.state = 101
+ self.starmodifier()
+ pass
+ elif token in [reggieParser.T__9]:
+ self.state = 102
+ self.plusmodifier()
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class IntmodifierContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def INT(self):
+ return self.getToken(reggieParser.INT, 0)
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_intmodifier
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterIntmodifier"):
+ listener.enterIntmodifier(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitIntmodifier"):
+ listener.exitIntmodifier(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitIntmodifier"):
+ return visitor.visitIntmodifier(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def intmodifier(self):
+ localctx = reggieParser.IntmodifierContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 16, self.RULE_intmodifier)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 105
+ self.match(reggieParser.T__6)
+ self.state = 106
+ self.match(reggieParser.INT)
+ self.state = 107
+ self.match(reggieParser.T__7)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class StarmodifierContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_starmodifier
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterStarmodifier"):
+ listener.enterStarmodifier(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitStarmodifier"):
+ listener.exitStarmodifier(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitStarmodifier"):
+ return visitor.visitStarmodifier(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def starmodifier(self):
+ localctx = reggieParser.StarmodifierContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 18, self.RULE_starmodifier)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 109
+ self.match(reggieParser.T__8)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class PlusmodifierContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_plusmodifier
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterPlusmodifier"):
+ listener.enterPlusmodifier(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitPlusmodifier"):
+ listener.exitPlusmodifier(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitPlusmodifier"):
+ return visitor.visitPlusmodifier(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def plusmodifier(self):
+ localctx = reggieParser.PlusmodifierContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 20, self.RULE_plusmodifier)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 111
+ self.match(reggieParser.T__9)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class StructuralidContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def ID(self):
+ return self.getToken(reggieParser.ID, 0)
+
+ def QUESTIONMARK_WILDCARD(self):
+ return self.getToken(reggieParser.QUESTIONMARK_WILDCARD, 0)
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_structuralid
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterStructuralid"):
+ listener.enterStructuralid(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitStructuralid"):
+ listener.exitStructuralid(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitStructuralid"):
+ return visitor.visitStructuralid(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def structuralid(self):
+ localctx = reggieParser.StructuralidContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 22, self.RULE_structuralid)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 113
+ _la = self._input.LA(1)
+ if not (
+ _la == reggieParser.ID or _la == reggieParser.QUESTIONMARK_WILDCARD
+ ):
+ self._errHandler.recoverInline(self)
+ else:
+ self._errHandler.reportMatch(self)
+ self.consume()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class LabelfilterContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def label(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(reggieParser.LabelContext)
+ else:
+ return self.getTypedRuleContext(reggieParser.LabelContext, i)
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_labelfilter
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterLabelfilter"):
+ listener.enterLabelfilter(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitLabelfilter"):
+ listener.exitLabelfilter(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitLabelfilter"):
+ return visitor.visitLabelfilter(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def labelfilter(self):
+ localctx = reggieParser.LabelfilterContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 24, self.RULE_labelfilter)
+ self._la = 0 # Token type
+ try:
+ self.state = 134
+ self._errHandler.sync(self)
+ token = self._input.LA(1)
+ if token in [reggieParser.ID]:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 115
+ self.label()
+ self.state = 120
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == reggieParser.T__10:
+ self.state = 116
+ self.match(reggieParser.T__10)
+ self.state = 117
+ self.label()
+ self.state = 122
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ pass
+ elif token in [reggieParser.T__3]:
+ self.enterOuterAlt(localctx, 2)
+ self.state = 123
+ self.match(reggieParser.T__3)
+ self.state = 124
+ self.label()
+ self.state = 129
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == reggieParser.T__10:
+ self.state = 125
+ self.match(reggieParser.T__10)
+ self.state = 126
+ self.label()
+ self.state = 131
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ self.state = 132
+ self.match(reggieParser.T__4)
+ pass
+ else:
+ raise NoViableAltException(self)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class LabelContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def ID(self):
+ return self.getToken(reggieParser.ID, 0)
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_label
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterLabel"):
+ listener.enterLabel(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitLabel"):
+ listener.exitLabel(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitLabel"):
+ return visitor.visitLabel(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def label(self):
+ localctx = reggieParser.LabelContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 26, self.RULE_label)
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 136
+ self.match(reggieParser.ID)
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class Vertex2vertexContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def vertex(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(reggieParser.VertexContext)
+ else:
+ return self.getTypedRuleContext(reggieParser.VertexContext, i)
+
+ def edge(self, i: int = None):
+ if i is None:
+ return self.getTypedRuleContexts(reggieParser.EdgeContext)
+ else:
+ return self.getTypedRuleContext(reggieParser.EdgeContext, i)
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_vertex2vertex
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterVertex2vertex"):
+ listener.enterVertex2vertex(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitVertex2vertex"):
+ listener.exitVertex2vertex(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitVertex2vertex"):
+ return visitor.visitVertex2vertex(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def vertex2vertex(self):
+ localctx = reggieParser.Vertex2vertexContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 28, self.RULE_vertex2vertex)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 138
+ self.vertex()
+ self.state = 144
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la == reggieParser.T__11 or _la == reggieParser.T__12:
+ self.state = 139
+ self.edge()
+ self.state = 140
+ self.vertex()
+ self.state = 146
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
+ class EdgeContext(ParserRuleContext):
+ __slots__ = "parser"
+
+ def __init__(
+ self, parser, parent: ParserRuleContext = None, invokingState: int = -1
+ ):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+
+ def getRuleIndex(self):
+ return reggieParser.RULE_edge
+
+ def enterRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "enterEdge"):
+ listener.enterEdge(self)
+
+ def exitRule(self, listener: ParseTreeListener):
+ if hasattr(listener, "exitEdge"):
+ listener.exitEdge(self)
+
+ def accept(self, visitor: ParseTreeVisitor):
+ if hasattr(visitor, "visitEdge"):
+ return visitor.visitEdge(self)
+ else:
+ return visitor.visitChildren(self)
+
+ def edge(self):
+ localctx = reggieParser.EdgeContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 30, self.RULE_edge)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 147
+ _la = self._input.LA(1)
+ if not (_la == reggieParser.T__11 or _la == reggieParser.T__12):
+ self._errHandler.recoverInline(self)
+ else:
+ self._errHandler.reportMatch(self)
+ self.consume()
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
diff --git a/lfr/antlrgen/reggie/reggieVisitor.py b/lfr/antlrgen/reggie/reggieVisitor.py
new file mode 100644
index 0000000..69c8219
--- /dev/null
+++ b/lfr/antlrgen/reggie/reggieVisitor.py
@@ -0,0 +1,80 @@
+# Generated from ./reggie.g4 by ANTLR 4.10.1
+from antlr4 import *
+
+if __name__ is not None and "." in __name__:
+ from .reggieParser import reggieParser
+else:
+ from reggieParser import reggieParser
+
+# This class defines a complete generic visitor for a parse tree produced by reggieParser.
+
+
+class reggieVisitor(ParseTreeVisitor):
+ # Visit a parse tree produced by reggieParser#graph.
+ def visitGraph(self, ctx: reggieParser.GraphContext):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#graphstatement.
+ def visitGraphstatement(self, ctx: reggieParser.GraphstatementContext):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#statementmodifier.
+ def visitStatementmodifier(self, ctx: reggieParser.StatementmodifierContext):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#basestatement.
+ def visitBasestatement(self, ctx: reggieParser.BasestatementContext):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#subgraph.
+ def visitSubgraph(self, ctx: reggieParser.SubgraphContext):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#vertex.
+ def visitVertex(self, ctx: reggieParser.VertexContext):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#coloringfilter.
+ def visitColoringfilter(self, ctx: reggieParser.ColoringfilterContext):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#structuralvertexpattern.
+ def visitStructuralvertexpattern(
+ self, ctx: reggieParser.StructuralvertexpatternContext
+ ):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#intmodifier.
+ def visitIntmodifier(self, ctx: reggieParser.IntmodifierContext):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#starmodifier.
+ def visitStarmodifier(self, ctx: reggieParser.StarmodifierContext):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#plusmodifier.
+ def visitPlusmodifier(self, ctx: reggieParser.PlusmodifierContext):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#structuralid.
+ def visitStructuralid(self, ctx: reggieParser.StructuralidContext):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#labelfilter.
+ def visitLabelfilter(self, ctx: reggieParser.LabelfilterContext):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#label.
+ def visitLabel(self, ctx: reggieParser.LabelContext):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#vertex2vertex.
+ def visitVertex2vertex(self, ctx: reggieParser.Vertex2vertexContext):
+ return self.visitChildren(ctx)
+
+ # Visit a parse tree produced by reggieParser#edge.
+ def visitEdge(self, ctx: reggieParser.EdgeContext):
+ return self.visitChildren(ctx)
+
+
+del reggieParser
diff --git a/lfr/api.py b/lfr/api.py
new file mode 100644
index 0000000..61b86e7
--- /dev/null
+++ b/lfr/api.py
@@ -0,0 +1,192 @@
+import os
+from pathlib import Path
+from typing import List, Union
+
+from antlr4 import CommonTokenStream, FileStream, ParseTreeWalker
+
+from lfr import parameters
+from lfr.antlrgen.lfr.lfrXLexer import lfrXLexer
+from lfr.antlrgen.lfr.lfrXParser import lfrXParser
+from lfr.moduleinstanceListener import ModuleInstanceListener
+from lfr.netlistgenerator.generator import generate
+from lfr.netlistgenerator.mappinglibrary_generator import (
+ generate_dropx_library,
+ generate_mars_library,
+ generate_mlsi_library,
+)
+from lfr.parameters import OUTPUT_DIR, PREPROCESSOR_DUMP_FILE_NAME
+from lfr.postProcessListener import PostProcessListener
+from lfr.preprocessor import PreProcessor
+from lfr.utils import print_netlist, printgraph, serialize_netlist
+
+
+def run_preprocessor(
+ input_files: List[str],
+ pre_load: List[str] = [],
+ preprocessor_dump_input_path: Path = Path(PREPROCESSOR_DUMP_FILE_NAME).resolve(),
+) -> bool:
+ """Runs the preprocessor on the input files
+
+ Args:
+ input_files (List[str]): input files to be preprocessed
+ pre_load (List[str], optional): Preload Directory. Defaults to [].
+
+ Returns:
+ bool: True if the preprocessor ran successfully, False otherwise
+ """
+ pre_load_file_list = pre_load
+ print(pre_load_file_list)
+
+ # Utilize the prepreocessor to generate the input file
+ preprocessor = PreProcessor(input_files, pre_load_file_list)
+
+ if preprocessor.check_syntax_errors():
+ print("Stopping compiler because of syntax errors")
+ return False
+
+ preprocessor.process(preprocessor_dump_input_path)
+ return True
+
+
+def synthesize_module(
+ input_path: Path = Path(PREPROCESSOR_DUMP_FILE_NAME).resolve(),
+ no_annotations_flag: bool = False,
+ print_fig: bool = True,
+) -> Union[ModuleInstanceListener, PostProcessListener]:
+ """Generates the module from the preprocessor dump
+
+ This is the method you want to use if you want to get module/fluid interaction graph
+
+ Args:
+ preprocessor_dump_input_path (Path, optional): Location of the preprocessor dump. Defaults to Path(PREPROCESSOR_DUMP_FILE_NAME).resolve().
+ no_annotations_flag (bool, optional): Skips parsing annotations. Defaults to False.
+
+ Returns:
+ Union[ModuleInstanceListener, PostProcessListener]: Returns the object model for the overall device module
+ """
+ # Modifiy this to translate relative path to absolute path in the future
+ finput = FileStream(str(input_path))
+
+ lexer = lfrXLexer(finput)
+
+ stream = CommonTokenStream(lexer)
+
+ parser = lfrXParser(stream)
+
+ tree = parser.skeleton()
+
+ walker = ParseTreeWalker()
+
+ if no_annotations_flag is True:
+ mapping_listener = ModuleInstanceListener()
+ else:
+ mapping_listener = PostProcessListener()
+
+ walker.walk(mapping_listener, tree)
+
+ mapping_listener.print_stack()
+
+ mapping_listener.print_variables()
+
+ if mapping_listener.currentModule is not None:
+ interactiongraph = mapping_listener.currentModule.FIG
+ if print_fig is True:
+ printgraph(interactiongraph, mapping_listener.currentModule.name + ".dot")
+
+ return mapping_listener
+
+
+def compile_lfr(
+ input_files: List[str],
+ outpath: str = "./out/",
+ technology: str = "dropx",
+ library_path: str = "./library",
+ no_mapping_flag: bool = False,
+ no_gen_flag: bool = False,
+ no_annotations_flag: bool = False,
+ pre_load: List[str] = [],
+) -> int:
+ """Standard API to compile a lfr file
+
+ This is the hook that we use for running lfr files from the command line or in
+ programs. Assumes that all the paths for the input files exist. It can create
+ the output directories if they aren't present.
+
+ Args:
+ input_files (List[str]): The paths for the input lfr files
+ outpath (str, optional): The path where all the outputs are saved. Defaults to "out/".
+ technology (str, optional): String for library that we need to use. Defaults to "dropx".
+ library_path (str, optional): path where all the library files are placed. Defaults to "./library".
+ no_mapping_flag (bool, optional): Enables/Disables mapping. Defaults to False.
+ no_gen_flag (bool, optional): Enables/Disables device generation. Defaults to False.
+ no_annotations_flag (bool, optional): Skip Annotation parsing. Defaults to False.
+ pre_load (List[str], optional): Preload Directory. Defaults to [].
+
+ Raises:
+ ValueError: _description_
+ ValueError: _description_
+
+ Returns:
+ int: 0 if the compilation was successful, >0 if theres an error
+ """
+ preprocessor_dump_rel_input_path = PREPROCESSOR_DUMP_FILE_NAME
+ preprocessor_dump_input_path = Path(preprocessor_dump_rel_input_path).resolve()
+
+ preprocessor_success = run_preprocessor(
+ input_files, pre_load, preprocessor_dump_input_path
+ )
+
+ if preprocessor_success is False:
+ return 1
+
+ print("output dir:", outpath)
+ print(input_files)
+
+ abspath = Path(outpath).absolute()
+ parameters.OUTPUT_DIR = abspath
+
+ if os.path.isdir(abspath) is not True:
+ print("Creating the output directory:")
+ path = Path(parameters.OUTPUT_DIR)
+ path.mkdir(parents=True)
+
+ library = None
+ # library = libraries[library_name]
+
+ # Setup and run the compiler's mapping listener
+ mapping_listener = synthesize_module(
+ preprocessor_dump_input_path, no_annotations_flag
+ )
+
+ if no_gen_flag is True:
+ return 0
+
+ # Check if the module compilation was successful
+ if mapping_listener.success:
+ # Now Process the Modules Generated
+ # V2 generator
+ if technology == "dropx":
+ library = generate_dropx_library()
+ elif technology == "mars":
+ library = generate_mars_library()
+ elif technology == "mlsi":
+ library = generate_mlsi_library()
+ else:
+ print("Implement Library for whatever else")
+ raise NotImplementedError(
+ f"No implementation found library for technology: {technology}"
+ )
+
+ if mapping_listener.currentModule is None:
+ raise ValueError()
+ if library is None:
+ raise ValueError()
+ unsized_devices = generate(mapping_listener.currentModule, library)
+
+ for index, unsized_device in enumerate(unsized_devices):
+ output_path = Path(OUTPUT_DIR).joinpath(f"variant_{index}")
+ output_path.mkdir(parents=True, exist_ok=True)
+ print_netlist(output_path, unsized_device)
+ serialize_netlist(output_path, unsized_device)
+
+ return 0
diff --git a/lfr/cmdline.py b/lfr/cmdline.py
index fe90788..43486ad 100644
--- a/lfr/cmdline.py
+++ b/lfr/cmdline.py
@@ -2,24 +2,12 @@
import glob
import json
import os
-import sys
-from pathlib import Path
-from antlr4 import CommonTokenStream, FileStream, ParseTreeWalker
+from art import tprint
import lfr.parameters as parameters
-from lfr.antlrgen.lfrXLexer import lfrXLexer
-from lfr.antlrgen.lfrXParser import lfrXParser
-from lfr.moduleinstanceListener import ModuleInstanceListener
+from lfr.api import compile_lfr
from lfr.netlistgenerator.mappinglibrary import MappingLibrary
-from lfr.netlistgenerator.v2.generator import (
- generate,
- generate_dropx_library,
- generate_mars_library,
-)
-from lfr.utils import print_netlist, printgraph, serialize_netlist
-from lfr.preprocessor import PreProcessor
-from lfr.postProcessListener import PostProcessListener
def load_libraries():
@@ -34,6 +22,8 @@ def load_libraries():
def main():
+ # Print LFR ASCII Banner
+ tprint("---- LFR ----")
parser = argparse.ArgumentParser()
parser.add_argument(
@@ -69,93 +59,37 @@ def main():
" #CONSTRAIN"
),
)
+ parser.add_argument(
+ "--pre-load",
+ type=str,
+ action="append",
+ help=(
+ "This lets the preprocessor look for the different design libraries that"
+ " need to be added to the memory (avoid using this outside bulk testing)"
+ ),
+ )
args = parser.parse_args()
- # Utilize the prepreocessor to generate the input file
- preprocessor = PreProcessor(args.input)
-
- if preprocessor.check_syntax_errors():
- print("Stopping compiler because of syntax errors")
- sys.exit(0)
-
- preprocessor.process()
-
- print("output dir:", args.outpath)
- print(args.input)
-
- rel_input_path = "pre_processor_dump.lfr"
- input_path = Path(rel_input_path).resolve()
-
- abspath = os.path.abspath(args.outpath)
- parameters.OUTPUT_DIR = abspath
-
- if os.path.isdir(abspath) is not True:
- print("Creating the output directory:")
- path = Path(parameters.OUTPUT_DIR)
- path.mkdir(parents=True)
-
- library_name = args.technology
- # libraries = load_libraries()
- # if library_name not in libraries.keys():
- # raise Exception("Could not find mapping library")
-
- library = None
- # library = libraries[library_name]
-
- # Modifiy this to translate relative path to absolute path in the future
- finput = FileStream(str(input_path))
-
- lexer = lfrXLexer(finput)
-
- stream = CommonTokenStream(lexer)
-
- parser = lfrXParser(stream)
-
- tree = parser.skeleton()
-
- walker = ParseTreeWalker()
-
- if args.no_annotations is True:
- mapping_listener = ModuleInstanceListener()
- else:
- mapping_listener = PostProcessListener()
-
- walker.walk(mapping_listener, tree)
-
- mapping_listener.print_stack()
-
- mapping_listener.print_variables()
-
- interactiongraph = mapping_listener.currentModule.FIG
-
- printgraph(interactiongraph, mapping_listener.currentModule.name + ".dot")
-
- if args.no_gen is True:
- sys.exit(0)
-
- # Check if the module compilation was successful
- if mapping_listener.success:
- # Now Process the Modules Generated
- # V2 generator
- if args.technology == "dropx":
- library = generate_dropx_library()
- elif args.technology == "mars":
- library = generate_mars_library()
- elif args.technology == "mlsi":
- print("Implement Library for MLSI")
- pass
- else:
- print("Implement Library for whatever else")
- pass
-
- if mapping_listener.currentModule is None:
- raise ValueError()
- if library is None:
- raise ValueError()
- unsized_device = generate(mapping_listener.currentModule, library)
-
- print_netlist(unsized_device)
- serialize_netlist(unsized_device)
+ # Generate proxy variables for the parsed args
+ input_files = args.input
+ outpath = args.outpath
+ technology = args.technology
+ library_path = args.library
+ no_mapping_flag = args.no_mapping
+ no_gen_flag = args.no_gen
+ no_annotations_flag = args.no_annotations
+ pre_load = args.pre_load
+
+ compile_lfr(
+ input_files=input_files,
+ outpath=outpath,
+ technology=technology,
+ library_path=library_path,
+ no_mapping_flag=no_mapping_flag,
+ no_gen_flag=no_gen_flag,
+ no_annotations_flag=no_annotations_flag,
+ pre_load=pre_load,
+ )
if __name__ == "__main__":
diff --git a/lfr/compiler/distribute/distributeblock.py b/lfr/compiler/distribute/distributeblock.py
index 1054ec4..7fe2577 100644
--- a/lfr/compiler/distribute/distributeblock.py
+++ b/lfr/compiler/distribute/distributeblock.py
@@ -1,4 +1,4 @@
-from typing import List
+from typing import List, Optional
from lfr.compiler.distribute.BitVector import BitVector
from lfr.compiler.distribute.statetable import StateTable
@@ -10,13 +10,19 @@ class DistributeBlock:
def __init__(self) -> None:
self._sensitivity_list: List[VectorRange] = []
# self._state_header: List[str] = None
- self._state_table: StateTable = None
+ self._state_table: Optional[StateTable] = None
def generate_fig(self, fig: FluidInteractionGraph) -> None:
- # TODO - Create the fig based on the given distribute logic shown here
+ # Create the fig based on the given distribute logic shown here
+ if self._state_table is None:
+ raise ValueError("State Table has not being initialized")
print("Implement the fig generation from this")
self._state_table.generate_connectivity_table()
+ # Save a copy of this on the fig
+ # TODO - Check if we need to make a new export item out of this or not
+ fig.add_state_table(self._state_table)
+
print("Connectivity table for the distribution block")
self._state_table.print_connectivity_table()
@@ -24,15 +30,16 @@ def generate_fig(self, fig: FluidInteractionGraph) -> None:
self._state_table.generate_or_annotations(fig)
- # TODO - Mark all the single items with no pairs
+ # Mark all the single items with no pairs
self._state_table.generate_not_annotations(fig)
# TODO - How to map the control mappings for each
# of the annotations to the control signals
- # self._state_table.compute_control_mapping()
+ self._state_table.compute_control_mapping()
@property
def state_table(self) -> StateTable:
+ assert self._state_table is not None
return self._state_table
@property
@@ -53,6 +60,9 @@ def sensitivity_list(self, signal_list: List[VectorRange]) -> None:
def set_connectivity(self, state, source, target) -> None:
# Make the connectivity here based on the state
# This will be called mulitple times per distributeassignstat
+ if self._state_table is None:
+ raise ValueError("State Table has not being initialized")
+
self._state_table.save_connectivity(state, source, target)
@staticmethod
@@ -73,19 +83,23 @@ def generate_state_vector(
self, signal_list: List[VectorRange], value_list: List[bool]
) -> BitVector:
# self._state_table.convert_to_fullstate_vector()
+
+ if self._state_table is None:
+ raise ValueError("State Table has not being initialized")
+
individual_signal_list = []
individual_value_list = []
i = 0
for signal in signal_list:
for j in range(len(signal)):
- individual_signal_list.append(signal[j].id)
+ individual_signal_list.append(signal[j].ID)
value = value_list[i + j]
individual_value_list.append(value)
i += 1
ret = self._state_table.convert_to_fullstate_vector(
- individual_signal_list, individual_value_list
+ signal_list=individual_signal_list, state=individual_value_list
)
return ret
@@ -94,5 +108,5 @@ def __generate_state_header(signal_list: List[VectorRange]) -> List[str]:
state_header = []
for vector_range in signal_list:
for i in range(len(vector_range)):
- state_header.append(vector_range[i].id)
+ state_header.append(vector_range[i].ID)
return state_header
diff --git a/lfr/compiler/distribute/statetable.py b/lfr/compiler/distribute/statetable.py
index 7ce35d7..bffc6eb 100644
--- a/lfr/compiler/distribute/statetable.py
+++ b/lfr/compiler/distribute/statetable.py
@@ -1,5 +1,12 @@
from __future__ import annotations
+from typing import TYPE_CHECKING, Optional, Union
+
+from lfr.fig.fignode import FIGNode
+
+if TYPE_CHECKING:
+ from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+
from typing import Dict, List, Tuple
import networkx as nx
@@ -7,8 +14,13 @@
from tabulate import tabulate
from lfr.compiler.distribute.BitVector import BitVector
-from lfr.fig.fignode import ANDAnnotation, NOTAnnotation, ORAnnotation
-from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+from lfr.fig.annotation import (
+ ANDAnnotation,
+ DistributeAnnotation,
+ NOTAnnotation,
+ ORAnnotation,
+)
+from lfr.utils import convert_list_to_str
class StateTable:
@@ -19,9 +31,10 @@ def __init__(self, signal_list: List[str]) -> None:
# state table into flow annotations using z3
self._connectivity_states: Dict[BitVector, nx.DiGraph] = {}
# self._colored_graph: nx.DiGraph = None
- self._connectivity_matrix = None
- self._connectivity_column_headers = None
- self._connectivity_edges = {}
+ self._connectivity_matrix = np.zeros((1, 1))
+ self._control_matrix = np.zeros((1, 1))
+ self._connectivity_column_headers: List[str] = []
+ self._connectivity_edges: Dict[str, Tuple[str, str]] = {}
self._and_annotations: List[ANDAnnotation] = []
self._or_annotations: List[ORAnnotation] = []
self._not_annotations: List[NOTAnnotation] = []
@@ -40,7 +53,7 @@ def get_connectivity_edge(self, i: int) -> Tuple[str, str]:
return edge
def convert_to_fullstate_vector(
- self, signal_list: List[str], state: BitVector
+ self, signal_list: List[str], state: List[bool]
) -> BitVector:
# Go through the each of the signal and update the specific BitVector value
full_state_bitvector = BitVector(size=len(self._headers))
@@ -62,17 +75,15 @@ def save_connectivity(
# Add source and target if they are not present
if source not in list(digraph.nodes):
print(
- "Could not find source - {} in state table connectivity graph, adding node".format(
- source
- )
+ "Could not find source - {} in state table connectivity graph, adding"
+ " node".format(source)
)
digraph.add_node(source)
if target not in list(digraph.nodes):
print(
- "Could not find target - {} in state table connectivity graph, adding node".format(
- target
- )
+ "Could not find target - {} in state table connectivity graph, adding"
+ " node".format(target)
)
digraph.add_node(target)
@@ -81,8 +92,7 @@ def save_connectivity(
digraph.add_edge(source, target)
def generate_connectivity_table(self) -> None:
-
- connectivy_column_headers = []
+ connectivy_column_headers: List[str] = []
self._connectivity_column_headers = connectivy_column_headers
# First setup the dimensions for the matrix
row_size = len(self._connectivity_states.keys())
@@ -100,20 +110,25 @@ def generate_connectivity_table(self) -> None:
column_size = len(list(full_connectivity_graph.edges))
for edge in list(full_connectivity_graph.edges):
- edge_name = self.__convert_edge_to_name(edge)
+ edge_name = self.convert_edge_to_name(edge)
connectivy_column_headers.append(edge_name)
self._connectivity_edges[edge_name] = edge
self._connectivity_matrix = np.zeros((row_size, column_size), dtype=int)
+ self._control_matrix = np.zeros((row_size, len(self._headers)), dtype=int)
+ # Actually fill out the matrices now
i = 0
for state in self._connectivity_states:
graph = self._connectivity_states[state]
for edge in list(graph.edges):
self.__update_connectivity_matix(edge, i, 1)
+ self.__update_control_matrix(i, state)
i += 1
+ # TODO - Generate the full connectivity table with mapping options
+
def generate_and_annotations(self, fig: FluidInteractionGraph) -> None:
m = self._connectivity_matrix
shape = m.shape
@@ -179,14 +194,22 @@ def generate_and_annotations(self, fig: FluidInteractionGraph) -> None:
)
fig.connect_fignodes(source_node, target_node)
- origin_nodes = [fig.get_fignode(edge[0]) for edge in candidate]
- print("Added AND annotation on FIG: {}".format(str(origin_nodes)))
- assert origin_nodes is not None
- annotation = fig.add_and_annotation(origin_nodes)
+ # origin_nodes = [fig.get_fignode(edge[0]) for edge in candidate]
+ tuple_names = [self.convert_edge_to_name(edge) for edge in candidate]
+ print(
+ "Added AND annotation on FIG: {}".format(
+ convert_list_to_str(tuple_names)
+ )
+ )
+
+ fignode_tuples = [
+ (fig.get_fignode(edge[0]), fig.get_fignode(edge[1]))
+ for edge in candidate
+ ]
+ annotation = fig.add_and_annotation(fignode_tuples)
self._and_annotations.append(annotation)
def generate_or_annotations(self, fig: FluidInteractionGraph) -> None:
-
self.print_connectivity_table()
m = np.copy(self._connectivity_matrix)
# Zerofill SKIPPED COLUMS
@@ -221,7 +244,7 @@ def generate_or_annotations(self, fig: FluidInteractionGraph) -> None:
# TODO - Go through the rows, see if the row-i and row-j
# compute the XOR of the current vector with the accumulate
xord_vector = np.logical_xor(accumulate_vector, row_j)
- distance = self.__hamming_distance(xord_vector, accumulate_vector)
+ distance = self.hamming_distance(xord_vector, accumulate_vector)
count = self.__ones_count(xord_vector)
if distance == 1 and count == ones_count + 1:
@@ -246,7 +269,9 @@ def generate_or_annotations(self, fig: FluidInteractionGraph) -> None:
# else (is not present in AND annotation) pick up the positive's corresponding
# flow node as one of the targets for the or annotation
for candidate in all_candidates:
- args_for_annotation = []
+ args_for_annotation: List[
+ Union[Tuple[FIGNode, FIGNode], DistributeAnnotation]
+ ] = []
for row_index in candidate:
row = m[row_index, :]
for i in range(len(row)):
@@ -268,22 +293,26 @@ def generate_or_annotations(self, fig: FluidInteractionGraph) -> None:
# Add the connection target in inot the annotion targets we want
# this representated for the entire converage
target = edge[1]
- args_for_annotation.append(fig.get_fignode(target))
# Check if the source is in any of the AND annotations
source = edge[0]
found_flag = False
annotation_to_use = None
for annotation in self._and_annotations:
- if source in fig.neighbors(annotation.id):
- found_flag = True
- annotation_to_use = fig.get_fignode(annotation.id)
+ if source in annotation.get_items():
+ annotation_to_use = annotation
break
- if found_flag is True:
+ if annotation_to_use is not None:
if annotation_to_use not in args_for_annotation:
args_for_annotation.append(annotation_to_use)
else:
- if source not in args_for_annotation:
- args_for_annotation.append(fig.get_fignode(source))
+ source_fignode = fig.get_fignode(source)
+ target_fignode = fig.get_fignode(target)
+ if (
+ source_fignode in args_for_annotation
+ and target_fignode in args_for_annotation
+ ) is False:
+ item_to_add = (source_fignode, target_fignode)
+ args_for_annotation.append(item_to_add)
self._or_annotations.append(fig.add_or_annotation(args_for_annotation))
@@ -304,11 +333,15 @@ def generate_not_annotations(self, fig: FluidInteractionGraph) -> None:
)
)
fig.connect_fignodes(source_node, target_node)
- annotation = fig.add_not_annotation([source_node, target_node])
+ annotation = fig.add_not_annotation((source_node, target_node))
self._not_annotations.append(annotation)
+ def compute_control_mapping(self) -> None:
+ print("TODO - Implement method to generate the control mapping")
+ # TODO - Generate the full connectivity table with mapping options
+
@staticmethod
- def __hamming_distance(vec1, vec2) -> int:
+ def hamming_distance(vec1, vec2) -> int:
assert vec1.size == vec2.size
# Start with a distance of zero, and count up
distance = 0
@@ -331,20 +364,33 @@ def __ones_count(vec1) -> int:
return ret
@staticmethod
- def __convert_edge_to_name(edge: Tuple[str, str]) -> str:
+ def convert_edge_to_name(edge: Tuple[str, str]) -> str:
+ """Generate the name of the edge to a string for printing purposes
+
+ Args:
+ edge (Tuple[str, str]): This is the networkx edge that we want to convert
+
+ Returns:
+ str: String representation of edge for printing
+ """
return "{}->{}".format(edge[0], edge[1])
def __update_connectivity_matix(self, edge, row, value):
- edge_name = self.__convert_edge_to_name(edge)
+ edge_name = self.convert_edge_to_name(edge)
m = self._connectivity_matrix
column = self._connectivity_column_headers.index(edge_name)
m[row, column] = value
+ def __update_control_matrix(self, row_index: int, control_state_vector: BitVector):
+ m = self._control_matrix
+ for column_index in range(control_state_vector.length()):
+ m[row_index, column_index] = control_state_vector[column_index]
+
def add_to_column_skip_list(self, edge: Tuple[str, str]):
# TODO - add the column to skip edge list to
# prevent double count during xor finding
edge_index = self._connectivity_column_headers.index(
- self.__convert_edge_to_name(edge)
+ self.convert_edge_to_name(edge)
)
self._or_column_skip_list.append(edge_index)
@@ -352,4 +398,17 @@ def print_connectivity_table(self):
m = self._connectivity_matrix
headers = self._connectivity_column_headers
table = tabulate(m, headers, tablefmt="fancy_grid")
+
+ m2 = self._control_matrix
+ control_headers = self._headers
+ table2 = tabulate(m2, control_headers, tablefmt="fancy_grid")
+
print(table)
+ print(table2)
+
+ m3 = np.concatenate((m, m2), axis=1)
+ headers_full = headers.copy()
+ headers_full.extend(control_headers)
+ table3 = tabulate(m3, headers_full, tablefmt="fancy_grid")
+
+ print(table3)
diff --git a/lfr/compiler/language/concatenation.py b/lfr/compiler/language/concatenation.py
index 175baef..3d9ad8a 100644
--- a/lfr/compiler/language/concatenation.py
+++ b/lfr/compiler/language/concatenation.py
@@ -1,9 +1,22 @@
+from __future__ import annotations
+
+from typing import List, Optional
+
+from lfr.compiler.language.vector import Vector
from lfr.compiler.language.vectorrange import VectorRange
class Concatenation:
- def __init__(self, ranges=None):
- self.ranges = []
+ """
+ A concatenation is the represetnation of mutiple
+ vector ranges stitched togeter.
+
+ TODO - A concatenation of concatenations should be a concatenation,
+ while this needs to be tested more thoroughly, this is future work.
+ """
+
+ def __init__(self, ranges: List[VectorRange]):
+ self.ranges: List[VectorRange] = []
if ranges is not None:
self.ranges = ranges
name = "CONCAT"
@@ -30,12 +43,18 @@ def __len__(self):
size = size + len(vrange)
return size
- def get_range(self, startindex: int = None, endindex: int = None) -> VectorRange:
- start = startindex if startindex is not None else 0
+ def get_range(
+ self, startindex: int = 0, endindex: Optional[int] = None
+ ) -> VectorRange:
+ start = startindex
end = endindex if endindex is not None else len(self) - 1
- # vec = []
- # for r in self.ranges:
- # vec.extend(r)
- ret = VectorRange(self, start, end)
+ concatenated_data = []
+ for data in self.ranges:
+ concatenated_data.extend(data)
+ concatenated_vector = Vector(
+ self.id,
+ )
+ concatenated_vector.vec = concatenated_data
+ ret = VectorRange(concatenated_vector, start, end)
return ret
diff --git a/lfr/compiler/language/fluidexpression.py b/lfr/compiler/language/fluidexpression.py
index d4f7433..33b40e7 100644
--- a/lfr/compiler/language/fluidexpression.py
+++ b/lfr/compiler/language/fluidexpression.py
@@ -21,13 +21,13 @@ def __init__(self, module: Module) -> None:
def process_expression(
self, termlist: List[Union[VectorRange, float]], operatorlist: List[str]
):
-
- # In step1, we go over and complete all the numeric operations in the precedence of
- # numeric operation order. It is possible that there are no numeric operations going
- # on in the expression. In that case we have the option to go to the next step. It
- # is also possible there are purely numeric operations and hence we only delete terms
- # if the numeric operation happens. In the second scenario, logic dictates that every
- # find will require us to delete the operator and the term.
+ # In step1, we go over and complete all the numeric operations in the
+ # precedence of numeric operation order. It is possible that there are no
+ # numeric operations going on in the expression. In that case we have the
+ # option to go to the next step. It is also possible there are purely numeric
+ # operations and hence we only delete terms if the numeric operation happens.
+ # In the second scenario, logic dictates that every find will require us to
+ # delete the operator and the term.
# First go over the numeric operator order
for operatorset in self.numeric_operator_order:
@@ -142,7 +142,7 @@ def process_unary_operation(self, term, operator):
result.append(interaction)
v = Vector.create_from_list_things(operator, result)
- ret = v.get_range()
+ ret = VectorRange.get_range_from_vector(v)
return ret
def __evalute_fluid_fluid_operator(
@@ -182,19 +182,22 @@ def __evalute_fluid_fluid_operator(
"Unsuppored operator on two fluid values: {0}".format(operator)
)
elif operator == "+":
- # TODO: We need to return the operation node here that is generated by operating on the
+ # TODO: We need to return the operation node here that is generated by
+ # operating on the
# two different operators
interactiontype = InteractionType.MIX
elif operator == "-":
- # TODO: In case of substraction, we need to return the operand1 back again,
- # since the subtracted node becomes an output, of whats given to the fluid
+ # TODO: In case of substraction, we need to return the operand1 back
+ # again, since the subtracted node becomes an output, of whats given
+ # to the fluid
interactiontype = InteractionType.SIEVE
else:
raise Exception(
"Unsuppored operator on two fluid values: {0}".format(operator)
)
- # Check if the operation here is between two different fluids or a fluid and an fluidinteraction
+ # Check if the operation here is between two different fluids or a fluid
+ # and an fluidinteraction
if isinstance(operand1_element, Interaction) and isinstance(
operand2_element, Interaction
):
@@ -222,12 +225,11 @@ def __evalute_fluid_fluid_operator(
result.append(result_element)
v = Vector.create_from_list_things(vecname, result)
- return v.get_range()
+ return VectorRange.get_range_from_vector(v)
def __evaluate_fluid_numeric_operator(
self, operand_fluidic: VectorRange, operand_numeric: float, operator: str
) -> VectorRange:
-
fluid = operand_fluidic[0]
interactions = []
for fluid in operand_fluidic:
@@ -271,7 +273,7 @@ def __evaluate_fluid_numeric_operator(
v = Vector.create_from_list_things(
"interaction_" + operand_fluidic.id, interactions
)
- result = v.get_range()
+ result = VectorRange.get_range_from_vector(v)
return result
@staticmethod
diff --git a/lfr/compiler/language/vector.py b/lfr/compiler/language/vector.py
index d32ba48..8acf596 100644
--- a/lfr/compiler/language/vector.py
+++ b/lfr/compiler/language/vector.py
@@ -1,41 +1,45 @@
-from typing import List
+from typing import Generic, List, Optional, Type, TypeVar
-from lfr.compiler.language.vectorrange import VectorRange
+T = TypeVar("T")
-class Vector:
+class Vector(Generic[T]):
+ """
+ Vector of objects T
+ """
+
def __init__(
- self, id: str, vectortype=None, startindex: int = 0, endindex: int = 0
+ self,
+ id: str,
+ vector_type: Optional[Type[T]] = None,
+ startindex: int = 0,
+ endindex: int = -1,
):
self.id = id
self.startindex = startindex
self.endindex = endindex
- self.vec = []
+ self.vec: List[T] = []
- if vectortype is not None:
- # If its a singular item avoid the indexing
+ if vector_type is not None:
+ # If it's a singular item avoid the indexing
if len(self) == 1:
- self.vec.append(vectortype(self.id))
+ self.vec.append(vector_type(self.id))
else:
for i in range(len(self)):
- self.vec.append(vectortype(self.id + "_" + str(i)))
+ self.vec.append(vector_type(self.id + "_" + str(i)))
+
+ self.endindex = len(self.vec) - 1
+
else:
print("Creating a vector of type [None]")
- def __len__(self):
+ def __len__(self) -> int:
return abs(self.startindex - self.endindex) + 1
- def get_items(self) -> list:
+ def get_items(self) -> List[T]:
return self.vec
- def get_range(self, startindex: int = None, endindex: int = None) -> VectorRange:
- start = startindex if startindex is not None else self.startindex
- end = endindex if endindex is not None else self.endindex
- ret = VectorRange(self, start, end)
-
- return ret
-
- def __getitem__(self, key: int):
+ def __getitem__(self, key):
if isinstance(key, slice):
start, stop, step = key.indices(len(self.vec))
return [self.vec[i] for i in range(start, stop, step)]
diff --git a/lfr/compiler/language/vectorrange.py b/lfr/compiler/language/vectorrange.py
index 85fe2a3..cfde0d0 100644
--- a/lfr/compiler/language/vectorrange.py
+++ b/lfr/compiler/language/vectorrange.py
@@ -1,24 +1,35 @@
-from networkx.algorithms.operators.unary import reverse
+from __future__ import annotations
+from typing import TYPE_CHECKING, Generic, Optional, TypeVar
-class VectorRange:
- def __init__(self, vector, startindex: int, endindex: int):
- self.vector = vector
- if startindex is None:
- self.startindex = 0
- else:
- self.startindex = startindex
+if TYPE_CHECKING:
+ from lfr.compiler.language.vector import Vector
+
+T = TypeVar("T")
+
+
+class VectorRange(Generic[T]):
+ """
+ Vector Range is akin to a slice that you can use to navigate a vector
+ """
+
+ def __init__(self, vector: Vector[T], startindex: int = 0, endindex: int = -1):
+ self.vector: Vector[T] = vector
- if endindex is None:
- self.endindex = len(self.vector) - 1
+ self.startindex = startindex
+
+ if endindex < 0:
+ self.endindex = len(self.vector) + endindex
else:
self.endindex = endindex
@property
- def id(self):
+ def id(self) -> str:
return self.vector.id
def __getitem__(self, key):
+ if isinstance(key, slice):
+ raise NotImplementedError("Need to implement the slice")
if self.startindex <= self.endindex:
return self.vector[self.startindex + key]
else:
@@ -28,12 +39,34 @@ def __iter__(self):
if self.startindex <= self.endindex:
return iter(self.vector[self.startindex : self.endindex + 1])
else:
- return iter(reverse(self.vector[self.startindex : self.endindex + 1]))
+ return reversed((self.vector[self.startindex : self.endindex + 1]))
- def __len__(self):
+ def __len__(self) -> int:
return abs(self.startindex - self.endindex) + 1
- def __str__(self):
- return "< VectorRange : {0} [{1} : {2}]>".format(
+ def __str__(self) -> str:
+ return "".format(
self.vector.id, self.startindex, self.endindex
)
+
+ @staticmethod
+ def get_range_from_vector(
+ vector: Vector[T],
+ startindex: Optional[int] = None,
+ endindex: Optional[int] = None,
+ ) -> VectorRange:
+ """Returns a VectorRange from a vector
+
+ Args:
+ vector (Vector[T]): Vector that want to be able to go through
+ startindex (Optional[int], optional): the start index of the range. Defaults to None.
+ endindex (Optional[int], optional): the end index of the range. Defaults to None.
+
+ Returns:
+ VectorRange: Vector range for the given indices
+ """
+ start = startindex if startindex is not None else vector.startindex
+ end = endindex if endindex is not None else vector.endindex
+ ret = VectorRange(vector, start, end)
+
+ return ret
diff --git a/lfr/compiler/lfrerror.py b/lfr/compiler/lfrerror.py
index 5f788e4..e550737 100644
--- a/lfr/compiler/lfrerror.py
+++ b/lfr/compiler/lfrerror.py
@@ -8,6 +8,7 @@ class ErrorType(Enum):
VARIABLE_NOT_RECOGNIZED = 30
SIGNAL_NOT_FOUND = 40
MODULE_NOT_FOUND = 50
+ MODULE_SIGNAL_BINDING_MISMATCH = 60
class LFRError:
diff --git a/lfr/compiler/module.py b/lfr/compiler/module.py
index 87ac4d3..a64b120 100644
--- a/lfr/compiler/module.py
+++ b/lfr/compiler/module.py
@@ -1,7 +1,7 @@
from __future__ import annotations
import copy
-from typing import Dict, List, Optional
+from typing import Dict, List, Optional, Union
from lfr.compiler.moduleio import ModuleIO
from lfr.fig.fignode import FIGNode, Flow, IONode, IOType
@@ -28,7 +28,7 @@ def __init__(self, name):
self.name = name
self._imported_modules: List[Module] = []
self._io: List[ModuleIO] = []
- self.FIG = FluidInteractionGraph()
+ self.FIG: FluidInteractionGraph = FluidInteractionGraph()
self.fluids = {}
self._mappings: List[NodeMappingTemplate] = []
@@ -53,6 +53,12 @@ def get_explicit_mappings(self) -> List[NodeMappingTemplate]:
def add_io(self, io: ModuleIO):
self._io.append(io)
for i in range(len(io.vector_ref)):
+ if isinstance(io.vector_ref[i], IONode) is False:
+ raise TypeError(
+ "Cannot add IO that is not of type, found {}".format(
+ io.vector_ref[i]
+ )
+ )
self.FIG.add_fignode(io.vector_ref[i])
def get_io(self, name: str) -> ModuleIO:
@@ -66,7 +72,7 @@ def get_all_io(self) -> List[ModuleIO]:
return self._io
def add_fluid(self, fluid: Flow):
- self.fluids[fluid.id] = fluid
+ self.fluids[fluid.ID] = fluid
self.FIG.add_fignode(fluid)
def get_fluid(self, name: str) -> Optional[FIGNode]:
@@ -80,6 +86,7 @@ def add_fluid_connection(self, item1id: str, item2id: str) -> None:
def add_fluid_custom_interaction(
self, item: Flow, operator: str, interaction_type: InteractionType
) -> Interaction:
+ # TODO - Figure out why the interaction_type is not being used here
# Check if the item exists
finteraction = FluidProcessInteraction(item, operator)
self.FIG.add_interaction(finteraction)
@@ -93,7 +100,8 @@ def add_finteraction_custom_interaction(
) -> Interaction:
# Check if the item exists
# TODO: create finteraction factory method and FluidInteraction
- # finteraction = FluidInteraction(fluid1=item, interactiontype=interaction_type, custominteraction= operator)
+ # finteraction = FluidInteraction(fluid1=item, interactiontype=interaction_type,
+ # custominteraction= operator)
finteraction = FluidProcessInteraction(item, operator)
self.FIG.add_interaction(finteraction)
return finteraction
@@ -108,7 +116,6 @@ def add_finteraction_custom_interaction(
def add_fluid_fluid_interaction(
self, fluid1: Flow, fluid2: Flow, interaction_type: InteractionType
) -> Interaction:
-
fluid_interaction = FluidFluidInteraction(fluid1, fluid2, interaction_type)
self.FIG.add_interaction(fluid_interaction)
@@ -125,7 +132,6 @@ def add_fluid_finteraction_interaction(
fluid1, finteraction, interaction_type
)
- # self.FIG.add_fluid_finteraction_interaction(fluid1, finteraction, new_fluid_interaction)
self.FIG.add_interaction(new_fluid_interaction)
return new_fluid_interaction
@@ -152,20 +158,48 @@ def add_interaction_output(self, output: Flow, interaction: Interaction):
def add_fluid_numeric_interaction(
self,
fluid1: Flow,
- number: float,
+ number: Union[int, float],
interaction_type: InteractionType,
) -> Interaction:
- # finteraction = FluidInteraction(fluid1=fluid1, interactiontype=interaction)
- finteraction = None
+ """Add a fluid numeric interaction to the module
+
+ Args:
+ fluid1 (Flow): Fluid to interact with
+ number (Union[int, float]): Number to interact with
+ interaction_type (InteractionType): Type of interaction
+
+ Raises:
+ NotImplementedError: Currently not supporting variables and their lookups
+ ValueError: If the interaction type is not supported
+
+ Returns:
+ Interaction: The interaction that was added
+ """
+
+ finteraction: Union[FluidIntegerInteraction, FluidNumberInteraction]
if interaction_type is InteractionType.METER:
finteraction = FluidNumberInteraction(fluid1, number, interaction_type)
elif interaction_type is InteractionType.DILUTE:
- finteraction = FluidNumberInteraction(fluid1, number, interaction_type)
+ if isinstance(number, float):
+ finteraction = FluidNumberInteraction(fluid1, number, interaction_type)
+ elif isinstance(number, int):
+ raise ValueError("Dilute interaction only supports float values")
+ else:
+ # If its a variable get the corresponding value for it
+ # from the variable store
+ raise NotImplementedError()
elif interaction_type is InteractionType.DIVIDE:
- finteraction = FluidIntegerInteraction(fluid1, number, interaction_type)
+ if isinstance(number, int):
+ finteraction = FluidIntegerInteraction(fluid1, number, interaction_type)
+ elif isinstance(number, float):
+ raise ValueError("Divide interaction only supports integer values")
+ else:
+ # If its a variable get the corresponding value for it
+ # from the variable store
+ raise NotImplementedError()
else:
- raise Exception("Unsupported Numeric Operator")
+ raise ValueError(f"Unsupported Numeric Operator: {interaction_type}")
self.FIG.add_interaction(finteraction)
@@ -188,31 +222,44 @@ def instantiate_module(
module_to_import = module_check
# Step 2 - Create a copy of the fig
- fig_copy = copy.deepcopy(module_to_import.FIG)
+ if module_to_import is None:
+ raise ReferenceError("module_to_import is set to none")
+
+ fig_copy: FluidInteractionGraph = copy.deepcopy(module_to_import.FIG)
# Step 3 - Convert all the flow IO nodes where mappings exist
# to flow nodes
for there_node_key in io_mapping.keys():
fignode = fig_copy.get_fignode(there_node_key)
# Skip if its a control type one
- if fignode.type is IOType.CONTROL:
- continue
+ if isinstance(fignode, IONode) is True:
+ if fignode.type is IOType.CONTROL: # type: ignore
+ continue
+ else:
+ raise TypeError("Node not of type IO Node")
+
# Convert this node into a flow node
- # Sanity check to see if its flow input/output
- assert (
- fignode.type is IOType.FLOW_INPUT or fignode.type is IOType.FLOW_OUTPUT
- )
# Replace
- new_fignode = Flow(fignode.id)
+ new_fignode = Flow(fignode.ID)
fig_copy.switch_fignode(fignode, new_fignode)
# Step 4 - Relabel all the nodes with the prefix defined by
# var_name
- rename_map = {}
+ fig_node_rename_map = {}
+ annotation_rename_map = {}
for node in list(fig_copy.nodes):
- rename_map[node] = self.__generate_instance_node_name(node, var_name)
+ fig_node_rename_map[node] = self.__generate_instance_node_name(
+ node, var_name
+ )
+
+ # Step 4.1 - Relabel all the annotations with the prefix defined by var_name
+ for annotation in list(fig_copy.annotations):
+ annotation_rename_map[annotation.id] = self.__generate_instance_node_name(
+ annotation.id, var_name
+ )
- fig_copy.rename_nodes(rename_map)
+ fig_copy.rename_nodes(fig_node_rename_map)
+ fig_copy.rename_annotations(fig_node_rename_map, annotation_rename_map)
# Step 5 - Stitch together tall the io newly formed io nodes into
# current fig
@@ -223,7 +270,7 @@ def instantiate_module(
# target_fig = self.FIG.get_fignode(rename_map[value])
# source_fig = self.FIG.get_fignode(key)
there_check_node = module_to_import.FIG.get_fignode(there_id)
- there_node = self.FIG.get_fignode(rename_map[there_id])
+ there_node = self.FIG.get_fignode(fig_node_rename_map[there_id])
here_node = self.FIG.get_fignode(here_id)
if (
isinstance(there_check_node, IONode)
@@ -258,20 +305,20 @@ def instantiate_module(
(FluidicOperatorMapping, StorageMapping, PumpMapping),
):
# Swap the basic node from original to the instance
- there_node_id = mapping_instance.node.id
- here_node = self.FIG.get_fignode(rename_map[there_node_id])
+ there_node_id = mapping_instance.node.ID
+ here_node = self.FIG.get_fignode(fig_node_rename_map[there_node_id])
mapping_instance.node = here_node
elif isinstance(mapping_instance, NetworkMapping):
# TODO - Swap the nodes in the inputs and the outputs
# Swap the inputs
nodes_to_switch = mapping_instance.input_nodes
mapping_instance.input_nodes = self.__switch_fignodes_list(
- rename_map, nodes_to_switch
+ fig_node_rename_map, nodes_to_switch
)
nodes_to_switch = mapping_instance.output_nodes
mapping_instance.output_nodes = self.__switch_fignodes_list(
- rename_map, nodes_to_switch
+ fig_node_rename_map, nodes_to_switch
)
self.mappings.append(mappingtemplate_copy)
diff --git a/lfr/compiler/moduleio.py b/lfr/compiler/moduleio.py
index d663330..4fcfb15 100644
--- a/lfr/compiler/moduleio.py
+++ b/lfr/compiler/moduleio.py
@@ -1,12 +1,14 @@
+from typing import Optional
+
from lfr.compiler.language.vectorrange import VectorRange
from lfr.fig.fignode import IOType
class ModuleIO:
- def __init__(self, name: str, iotype: IOType = None):
+ def __init__(self, name: str, iotype: IOType):
self.type = iotype
self._id = name
- self._vector_ref = None
+ self._vector_ref: Optional[VectorRange] = None
@property
def id(self) -> str:
@@ -14,6 +16,11 @@ def id(self) -> str:
@property
def vector_ref(self) -> VectorRange:
+ if self._vector_ref is None:
+ raise ValueError(
+ f"Vector Reference is not set for ModuleIO: {self.id}, type:"
+ f" {self.type}"
+ )
return self._vector_ref
@vector_ref.setter
diff --git a/lfr/distBlockListener.py b/lfr/distBlockListener.py
index 6782ebc..679efc1 100644
--- a/lfr/distBlockListener.py
+++ b/lfr/distBlockListener.py
@@ -1,6 +1,6 @@
from typing import List, Optional, Tuple
-from lfr.antlrgen.lfrXParser import lfrXParser
+from lfr.antlrgen.lfr.lfrXParser import lfrXParser
from lfr.compiler.distribute.BitVector import BitVector
from lfr.compiler.distribute.distributeblock import DistributeBlock
from lfr.compiler.language.vectorrange import VectorRange
@@ -13,7 +13,7 @@ def __init__(self) -> None:
super().__init__()
self._current_dist_block: Optional[DistributeBlock] = None
self._current_sensitivity_list = None
- self._current_state: BitVector
+ self._current_state: Optional[BitVector]
self._current_connectivities: List[Tuple[str, str]] = []
# This particular variable is only used for
# figuring out the else statement
@@ -24,6 +24,9 @@ def exitDistributeCondition(self, ctx: lfrXParser.DistributeConditionContext):
rhs = self.stack.pop()
lhs = self.stack.pop()
+ if isinstance(rhs, BitVector):
+ rhs = rhs.intValue()
+
relation_operator = ctx.binary_module_path_operator().getText()
# TODO - Basically we need to know what the conditions are we need to set
@@ -33,15 +36,26 @@ def exitDistributeCondition(self, ctx: lfrXParser.DistributeConditionContext):
# this needs to be extended to work with all kinds of conditions
# not just 1 variable and the values of 0 or 1.
assert len(lhs) == 1
- assert rhs == 0 or rhs == 1
- assert relation_operator == "=="
+ if relation_operator != "==":
+ raise NotImplementedError(
+ 'Did not implement distribute condition beyond "=="'
+ )
+
+ if type(rhs) == float or type(rhs) == int:
+ if (rhs == 0 or rhs == 1) is False:
+ raise NotImplementedError(
+ "Did not implement distribute condition to be beyond simple 1 or 0"
+ " conditions"
+ )
+
+ if self._current_dist_block is None:
+ raise ValueError('"_current_dist_block" is set to None')
state_vector = self._current_dist_block.generate_state_vector([lhs], [rhs == 1])
self._current_state = state_vector
def enterDistributionBlock(self, ctx: lfrXParser.DistributionBlockContext):
print("Entering the Distribution Block")
- # TODO - Instantiate the distribute graph or whatever class that encapsulates this
self._current_dist_block = DistributeBlock()
def exitSensitivitylist(self, ctx: lfrXParser.SensitivitylistContext):
@@ -77,11 +91,19 @@ def exitSensitivitylist(self, ctx: lfrXParser.SensitivitylistContext):
vrange = VectorRange(v, start_index, end_index)
sentivity_list.append(vrange)
+ if self._current_dist_block is None:
+ raise ValueError('"_current_dist_block" is set to None')
+
self._current_dist_block.sensitivity_list = sentivity_list
def exitDistributionBlock(self, ctx: lfrXParser.DistributionBlockContext):
print("Exit the Distribution Block")
# TODO - Generate the fig from the distribute block
+ if self._current_dist_block is None:
+ raise ValueError('"_current_dist_block" is set to None')
+
+ if self.currentModule is None:
+ raise ValueError("Current module set to none")
self._current_dist_block.generate_fig(self.currentModule.FIG)
def enterDistributionassignstat(
@@ -102,18 +124,18 @@ def exitDistributionassignstat(self, ctx: lfrXParser.DistributionassignstatConte
print("LHS, RHS sizes are equal")
for source, target in zip(rhs, lhs):
print(source, target)
- sourceid = source.id
- targetid = target.id
+ sourceid = source.ID
+ targetid = target.ID
self._current_connectivities.append((sourceid, targetid))
elif len(lhs) != len(rhs):
print("LHS not equal to RHS")
for source in rhs:
- sourceid = source.id
+ sourceid = source.ID
for target in lhs:
- targetid = target.id
+ targetid = target.ID
self._current_connectivities.append((sourceid, targetid))
def enterIfElseBlock(self, ctx: lfrXParser.IfElseBlockContext):
@@ -131,7 +153,12 @@ def enterElseIfBlock(self, ctx: lfrXParser.ElseIfBlockContext):
def exitIfBlock(self, ctx: lfrXParser.IfBlockContext):
# We need to go through all the current connectivities
# and put them into the distribute block
+ if self._current_state is None:
+ raise ValueError("No state set for if block")
self._accumulated_states.append(self._current_state)
+ if self._current_dist_block is None:
+ raise ValueError('"_current_dist_block" is set to None')
+
dist_block = self._current_dist_block
for connectivity in self._current_connectivities:
dist_block.set_connectivity(
@@ -141,7 +168,13 @@ def exitIfBlock(self, ctx: lfrXParser.IfBlockContext):
def exitElseIfBlock(self, ctx: lfrXParser.ElseIfBlockContext):
# We need to go through all the current connectivities
# and put them into the distribute block
+ if self._current_state is None:
+ raise ValueError("No state set for if block")
self._accumulated_states.append(self._current_state)
+
+ if self._current_dist_block is None:
+ raise ValueError('"_current_dist_block" is set to None')
+
dist_block = self._current_dist_block
for connectivity in self._current_connectivities:
dist_block.set_connectivity(
@@ -152,6 +185,9 @@ def enterElseBlock(self, ctx: lfrXParser.ElseBlockContext):
self._current_connectivities = []
def exitElseBlock(self, ctx: lfrXParser.ElseBlockContext):
+ if self._current_dist_block is None:
+ raise ValueError('"_current_dist_block" is set to None')
+
remaining_states = self._current_dist_block.get_remaining_states(
self._accumulated_states
)
@@ -176,8 +212,14 @@ def exitCasestat(self, ctx: lfrXParser.CasestatContext):
rhs = self.stack.pop()
assert isinstance(rhs, BitVector)
lhs = self._current_lhs
+
+ if self._current_dist_block is None:
+ raise ValueError('"_current_dist_block" is set to None')
+
dist_block = self._current_dist_block
rhs_list = [rhs[i] == 1 for i in range(len(rhs))]
+ if lhs is None:
+ raise ValueError("LHS set to none in case stat")
state_vector = self._current_dist_block.generate_state_vector([lhs], rhs_list)
self._current_state = state_vector
diff --git a/lfr/fig/annotation.py b/lfr/fig/annotation.py
new file mode 100644
index 0000000..82eec3e
--- /dev/null
+++ b/lfr/fig/annotation.py
@@ -0,0 +1,70 @@
+from __future__ import annotations
+
+from typing import List, Tuple, Union
+
+from lfr.fig.fignode import FIGNode
+
+
+class DistributeAnnotation:
+ def __init__(self, id: str) -> None:
+ self._id = id
+ self._annotated_items: List[
+ Union[Tuple[FIGNode, FIGNode], DistributeAnnotation]
+ ] = []
+
+ @property
+ def id(self) -> str:
+ return self._id
+
+ def rename(self, new_id: str) -> None:
+ self._id = new_id
+
+ def add_annotated_item(
+ self, item: Union[Tuple[FIGNode, FIGNode], DistributeAnnotation]
+ ) -> None:
+ self._annotated_items.append(item)
+
+ def remove_item(
+ self, item: Union[Tuple[FIGNode, FIGNode], DistributeAnnotation]
+ ) -> None:
+ self._annotated_items.remove(item)
+
+ def get_items(self) -> List[Union[Tuple[FIGNode, FIGNode], DistributeAnnotation]]:
+ return self._annotated_items
+
+ def clear_items(self) -> None:
+ self._annotated_items.clear()
+
+ def __hash__(self) -> int:
+ return hash(hex(id(self)))
+
+ @property
+ def match_string(self) -> str:
+ raise NotImplementedError("Not implemented to the base disribution graph")
+
+
+class ANDAnnotation(DistributeAnnotation):
+ def __init__(self, id: str) -> None:
+ super(ANDAnnotation, self).__init__(id)
+
+ @property
+ def match_string(self):
+ return "DISTRIBUTE_AND"
+
+
+class ORAnnotation(DistributeAnnotation):
+ def __init__(self, id: str) -> None:
+ super(ORAnnotation, self).__init__(id)
+
+ @property
+ def match_string(self):
+ return "DISTRIBUTE_OR"
+
+
+class NOTAnnotation(DistributeAnnotation):
+ def __init__(self, id: str) -> None:
+ super(NOTAnnotation, self).__init__(id)
+
+ @property
+ def match_string(self):
+ return "DISTRIBUTE_NOT"
diff --git a/lfr/fig/autocomplete.py b/lfr/fig/autocomplete.py
new file mode 100644
index 0000000..5003a9c
--- /dev/null
+++ b/lfr/fig/autocomplete.py
@@ -0,0 +1,8 @@
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+
+
+def connect_orphan_IO(fig: FluidInteractionGraph) -> None:
+ # Step 1 - Go through all the flow nodes and check to see if any of them have zero outputs.
+ # Step 2 - If they do then generate a new IO node and connect it to the flow node.
+
+ raise NotImplementedError()
diff --git a/lfr/fig/fignode.py b/lfr/fig/fignode.py
index 9044bf3..0ea078d 100644
--- a/lfr/fig/fignode.py
+++ b/lfr/fig/fignode.py
@@ -1,4 +1,5 @@
from enum import Enum
+from typing import Optional
MATCH_STRING_ORDERING = [
"IO",
@@ -18,131 +19,256 @@ class IOType(Enum):
class FIGNode:
+ """The fundamental unit of the fluid interaction graph
+
+ All the fignodes are build on top of this.
+ """
+
def __init__(self, id: str) -> None:
+ """Creates a new instance of FIGNode
+
+ Args:
+ id (str): unique ID of the fignode
+ """
self._id: str = id
@property
- def id(self):
+ def ID(self) -> str:
+ """Returns the ID of the fignode
+
+ Returns:
+ str: ID of the fignode
+ """
return self._id
@property
def match_string(self):
+ """Returns the Match String
+
+ For the fig node the match string is "-"
+
+ Returns:
+ _type_: _description_
+ """
return "-"
def __str__(self) -> str:
- return self.id
+ return self.ID
def __eq__(self, other):
if isinstance(other, FIGNode):
- return self.id == other.id
+ return self.ID == other.ID
else:
- False
+ return False
def rename(self, id: str) -> None:
+ """Renames the ID of the fignode
+
+ Args:
+ id (str): the new ID for the fignode
+ """
self._id = id
+ def __hash__(self) -> int:
+ return hash(hex(id(self)))
+
class ValueNode(FIGNode):
+ """FIGNodes that carries the value that you
+ use to operate on the fluid interaction graph
+ """
+
def __init__(self, id: str, val: float) -> None:
+ """Creates a new instance of ValueNode
+
+ Args:
+ id (str): ID of the value node
+ val (float): value that we need to store on the node
+ """
super(ValueNode, self).__init__(id)
self._value = val
@property
- def value(self):
+ def value(self) -> float:
+ """Returns the value stored on the node
+
+ Returns:
+ float: value stored on the node
+ """
return self._value
@property
- def match_string(self):
+ def match_string(self) -> str:
+ """Returns the match string
+
+ Returns:
+ str: the value fo the match_string
+ """
return "VALUE"
+ def __str__(self) -> str:
+ return "VALUE - {}".format(self._value)
+
class Flow(FIGNode):
- def __init__(self, id) -> None:
+ """
+ Flow node is the node used represent fluids flowing around
+ node that we use
+ """
+
+ def __init__(self, id: str) -> None:
+ """Creates a new instance of Flow
+
+ Args:
+ id (str): id of the flow node
+ """
super(Flow, self).__init__(id)
@property
def match_string(self):
+ """Returns the match string
+
+ Returns:
+ str: the value fo the match_string
+ """
return "FLOW"
def __str__(self) -> str:
- return "FLOW - {}".format(self.id)
+ return "FLOW - {}".format(self.ID)
class IONode(Flow):
- def __init__(self, id: str, iotype=None):
+ """
+ The IONode is used to identify ports (inputs, outputs and control)
+ are represented using this fig node
+ """
+
+ def __init__(self, id: str, iotype: Optional[IOType] = None) -> None:
+ """Creates a new IONode
+
+ Args:
+ id (str): ID of the IONode
+ iotype (Optional[IOType], optional): IOType of the node. Defaults to None.
+ """
super(IONode, self).__init__(id)
- self._type = iotype
+ if iotype is None:
+ self._type = IOType.FLOW_INPUT
+ else:
+ self._type = iotype
@property
def type(self) -> IOType:
+ """Returns the IOType of the node
+
+ Raises:
+ ValueError: If no IOType is not assigned
+
+ Returns:
+ IOType: Type of IO for the node
+ """
+ if self._type is None:
+ raise ValueError("Type not set for IO: {}".format(self.ID))
return self._type
@type.setter
def type(self, iotype: IOType) -> None:
+ """Sets the IOType of the node
+
+ Args:
+ iotype (IOType): IOType we want to set
+ """
self._type = iotype
def __str__(self) -> str:
- return "Name: {0.id}, Type : {0.type}".format(self)
+ return "IO - Name: {0.ID}, Type : {0.type}".format(self)
@property
- def match_string(self):
+ def match_string(self) -> str:
+ """Returns the match string
+
+ Returns:
+ str: the value fo the match_string
+ """
return "IO"
class Storage(Flow):
+ """
+ The Storage Node is the node that we use for represnting storage units
+ where flow stops.
+ """
+
def __init__(self, id: str) -> None:
+ """Creates a new Storage element
+
+ Args:
+ id (str): ID of the fignode
+ """
super(Storage, self).__init__(id)
@property
- def match_string(self):
+ def match_string(self) -> str:
+ """Returns the match string
+
+ Returns:
+ str: the value fo the match_string
+ """
return "STORAGE"
+ def __str__(self) -> str:
+ return "STORAGE - {}".format(self.ID)
+
class Pump(Flow):
+ """The pump element is a node that represents
+ active flow movement within the fluid interaction
+ graph
+ """
+
def __init__(self, id: str) -> None:
+ """Creates a new instance of a Pump elemeent
+
+ Args:
+ id (str): ID of the pump
+ """
super(Pump, self).__init__(id)
@property
def match_string(self) -> str:
- return "PUMP"
-
+ """Returns the match string
-class Signal(FIGNode):
- def __init__(self, id: str) -> None:
- super(Signal, self).__init__(id)
-
- @property
- def match_string(self):
- return "SIGNAL"
+ Returns:
+ str: the value fo the match_string
+ """
+ return "PUMP"
+ def __str__(self) -> str:
+ return "PUMP - {}".format(self.ID)
-class DistributeNode(FIGNode):
- def __init__(self, id: str) -> None:
- super(DistributeNode, self).__init__(id)
+class Signal(FIGNode):
+ """
+ The signal node represents the control signal
+ that flows through the device
+ """
-class ANDAnnotation(DistributeNode):
def __init__(self, id: str) -> None:
- super(ANDAnnotation, self).__init__(id)
-
- @property
- def match_string(self):
- return "DISTRIBUTE-AND"
+ """Creates a new instance of the
+ signal node
-
-class ORAnnotation(DistributeNode):
- def __init__(self, id: str) -> None:
- super(ORAnnotation, self).__init__(id)
+ Args:
+ id (str): ID of the node
+ """
+ super(Signal, self).__init__(id)
@property
def match_string(self):
- return "DISTRIBUTE-OR"
-
+ """Returns the match string
-class NOTAnnotation(DistributeNode):
- def __init__(self, id: str) -> None:
- super(NOTAnnotation, self).__init__(id)
+ Returns:
+ str: the value fo the match_string
+ """
+ return "SIGNAL"
- @property
- def match_string(self):
- return "DISTRIBUTE-NOT"
+ def __str__(self) -> str:
+ return "SIGNAL - {}".format(self.ID)
diff --git a/lfr/fig/fluidinteractiongraph.py b/lfr/fig/fluidinteractiongraph.py
index c5c4364..1f70319 100644
--- a/lfr/fig/fluidinteractiongraph.py
+++ b/lfr/fig/fluidinteractiongraph.py
@@ -1,19 +1,19 @@
from __future__ import annotations
import copy
-from typing import Dict, List
+import uuid
+from typing import Dict, List, Tuple, Union
import networkx as nx
-from lfr.fig.fignode import (
+from lfr.compiler.distribute.statetable import StateTable
+from lfr.fig.annotation import (
ANDAnnotation,
- FIGNode,
- IONode,
- IOType,
+ DistributeAnnotation,
NOTAnnotation,
ORAnnotation,
- ValueNode,
)
+from lfr.fig.fignode import FIGNode, IONode, IOType, ValueNode
from lfr.fig.interaction import (
FluidFluidInteraction,
FluidIntegerInteraction,
@@ -22,41 +22,149 @@
Interaction,
InteractionType,
)
-from lfr.postprocessor.mapping import NodeMappingTemplate
class FluidInteractionGraph(nx.DiGraph):
+ """Fluid Interaction Graph
+
+ This is the main data structure for the Fluid Interaction Graph. It is a directed graph
+ where the nodes are the fluid objects and the interactions between the fluid objects.
+
+ It additionally stores the annotations and the state tables.
+ """
+
def __init__(self, data=None, val=None, **attr) -> None:
+ """Constructor for the FluidInteractionGraph
+
+ Args:
+ data (dict, optional): Networkx data dict. Defaults to None.
+ val (dict, optional): Networkx val dict. Defaults to None.
+ """
super(FluidInteractionGraph, self).__init__()
self._fignodes: Dict[str, FIGNode] = {}
# self._fluid_interactions = dict()
self._gen_id = 0
+ self._annotations_reverse_map: Dict[
+ Union[FIGNode, DistributeAnnotation], List[DistributeAnnotation]
+ ] = dict()
+ self._annotations: List[DistributeAnnotation] = []
+ # Use this to store all the control to flow logic
+ self._state_tables: List[StateTable] = []
+
+ def add_state_table(self, state_table: StateTable) -> None:
+ """Adds a state table to the FluidInteractionGraph
+
+ Args:
+ state_table (StateTable): State table to add
+ """
+ self._state_tables.append(state_table)
+
+ @property
+ def annotations(self) -> List[DistributeAnnotation]:
+ """Returns the list of annotations
+
+ Returns:
+ List[DistributeAnnotation]: List of annotations
+ """
+ return self._annotations
+
+ def get_annotation_by_id(self, id: str) -> DistributeAnnotation:
+ """Returns the annotation with the given ID
+
+ Args:
+ id (str): ID of the annotation
+
+ Raises:
+ KeyError: If the annotation is not found
+
+ Returns:
+ DistributeAnnotation: Annotation with the given ID
+ """
+ for annotation in self._annotations:
+ if annotation.id == id:
+ return annotation
+ raise KeyError(f"Cannot find the annotation with ID: {id}")
def add_fignode(self, node: FIGNode) -> None:
- self._fignodes[node.id] = node
- self.add_node(node.id)
+ """Adds a FIGNode to the FluidInteractionGraph
+
+ Args:
+ node (FIGNode): FIGNode to add
+ """
+ self._fignodes[node.ID] = node
+ self._annotations_reverse_map[node] = []
+ self.add_node(node.ID)
def get_fignode(self, id: str) -> FIGNode:
- if id in self._fignodes.keys():
+ """Returns the FIGNode with the given ID
+
+ Args:
+ id (str): ID of the FIGNode
+
+ Raises:
+ Exception: If the FIGNode is not found
+
+ Returns:
+ FIGNode: FIGNode with the given ID
+ """
+ if id in self._fignodes:
return self._fignodes[id]
else:
- raise Exception(
- "Cannot find the node '{}' in the FluidInteractionGraph".format(
- id
- )
- )
+ raise Exception(f"Cannot find the node '{id}' in the FluidInteractionGraph")
def load_fignodes(self, fig_nodes: List[FIGNode]) -> None:
+ """Loads the FIGNodes into the FluidInteractionGraph
+
+ Args:
+ fig_nodes (List[FIGNode]): List of FIGNodes to load
+ """
for node in fig_nodes:
- self._fignodes[node.id] = node
+ self._fignodes[node.ID] = node
+
+ # Add an entry for the reverse map here to make things simpler
+ self._annotations_reverse_map[node] = []
+
+ def load_annotations(self, annotations: List[DistributeAnnotation]) -> None:
+ """Loads the annotations into the FluidInteractionGraph
+
+ Args:
+ annotations (List[DistributeAnnotation]): List of annotations to load
+ """
+ self._annotations.extend(annotations)
+ for annotation in annotations:
+ for item in annotation.get_items():
+ if isinstance(item, DistributeAnnotation):
+ self.__add_to_reverse_map(item, annotation)
+ else:
+ self.__add_to_reverse_map(item[0], annotation)
+ self.__add_to_reverse_map(item[1], annotation)
def contains_fignode(self, fluid_object: FIGNode) -> bool:
- return fluid_object.id in self._fignodes.keys()
+ """Returns true if the FIGNode is present in the FluidInteractionGraph
+
+ Args:
+ fluid_object (FIGNode): FIGNode to check
+
+ Returns:
+ bool: True if the FIGNode is present in the FluidInteractionGraph
+ """
+ return fluid_object.ID in self._fignodes
def switch_fignode(self, old_fignode: FIGNode, new_fignode: FIGNode) -> None:
- self._fignodes[old_fignode.id] = new_fignode
+ """Switch the old fignode with the new fignode
+
+ Args:
+ old_fignode (FIGNode): the old fignode
+ new_fignode (FIGNode): the new fignode
+ """
+ self._fignodes[old_fignode.ID] = new_fignode
def rename_nodes(self, rename_map: Dict[str, str]) -> None:
+ """Rename the nodes in the FIG
+
+ Args:
+ rename_map (Dict[str, str]): a map from the old node ID to the new node ID
+ """
for node in self.nodes:
fig_node = self._fignodes[node]
fig_node.rename(rename_map[node])
@@ -67,13 +175,76 @@ def rename_nodes(self, rename_map: Dict[str, str]) -> None:
nx.relabel_nodes(self, rename_map, False)
+ def rename_annotations(
+ self, fig_node_rename_map: Dict[str, str], annotation_rename_map: Dict[str, str]
+ ) -> None:
+ """Rename the annotations in the FIG
+
+ Args:
+ fig_node_rename_map (Dict[str, str]): a map from the old fignode ID to the new
+ annotation_rename_map (Dict[str, str]): a map from the old annotation ID to the
+ """
+ for annotation in self._annotations:
+ annotation.rename(annotation_rename_map[annotation.id])
+
+ fig_copy = self
+ # Switch all the items of the annotations to the new fignodes
+ for annotation in list(fig_copy.annotations):
+ new_items_list: List[
+ Union[Tuple[FIGNode, FIGNode], DistributeAnnotation]
+ ] = []
+
+ old_fignode_item_id_list = [
+ (item[0].ID, item[1].ID)
+ for item in annotation.get_items()
+ if isinstance(item, tuple())
+ ]
+
+ # Now switch the items to the new fignodes
+ for (
+ old_fignode_item_id_1,
+ old_fignode_item_id_2,
+ ) in old_fignode_item_id_list:
+ new_fignode_item_id_1 = fig_node_rename_map[old_fignode_item_id_1]
+ new_fignode_item_id_2 = fig_node_rename_map[old_fignode_item_id_2]
+ tuple_to_add: Tuple[FIGNode, FIGNode] = (
+ fig_copy.get_fignode(new_fignode_item_id_1),
+ fig_copy.get_fignode(new_fignode_item_id_2),
+ )
+ new_items_list.append(tuple_to_add)
+
+ old_annotation_item_id_list = [
+ item.id
+ for item in annotation.get_items()
+ if isinstance(item, DistributeAnnotation)
+ ]
+
+ for old_annotation_item_id in old_annotation_item_id_list:
+ new_annotation_item_id = annotation_rename_map[old_annotation_item_id]
+ annotation_to_add: DistributeAnnotation = fig_copy.get_annotation_by_id(
+ new_annotation_item_id
+ )
+ new_items_list.append(annotation_to_add)
+
+ # now replace the annotation items with the new ones
+ annotation.clear_items()
+ for item in new_items_list:
+ annotation.add_annotated_item(item)
+
def add_interaction(self, interaction: Interaction):
- if interaction.id not in self._fignodes.keys():
- self._fignodes[interaction.id] = interaction
+ """Add an interaction to the FIG
+
+ Args:
+ interaction (Interaction): the interaction to add
+
+ Raises:
+ Exception: If the interaction is already present in the FIG
+ Exception: If the interaction is of an invalid type
+ """
+ if interaction.ID not in self._fignodes:
+ self.add_fignode(interaction)
else:
- raise Exception(
- "Interaction already present in the FIG: {0}".format(interaction.id)
- )
+ raise Exception(f"Interaction already present in the FIG: {interaction.ID}")
if isinstance(interaction, FluidFluidInteraction):
self.__add_fluid_fluid_interaction(interaction)
@@ -91,30 +262,46 @@ def add_interaction(self, interaction: Interaction):
raise Exception("Invalid Interaction Type found here")
def connect_fignodes(self, source: FIGNode, target: FIGNode):
- if source.id not in self._fignodes.keys():
+ """Connect two fignodes in the FIG
+
+ Args:
+ source (FIGNode): source fignode
+ target (FIGNode): target fignode
+
+ Raises:
+ Exception: if the source fignode is not present in the FIG
+ """
+ if source.ID not in self._fignodes:
raise Exception(
- "Unable to add interaction because of missing flow: {0}".format(
- source.id
- )
+ f"Unable to add interaction because of missing flow: {source.ID}"
)
- if target.id not in self._fignodes.keys():
+ if target.ID not in self._fignodes:
raise Exception(
- "Unable to add interaction because of missing flow: {0}".format(
- target.id
- )
+ f"Unable to add interaction because of missing flow: {target.ID}"
)
- self.add_edge(source.id, target.id)
+ self.add_edge(source.ID, target.ID)
def get_interactions(self) -> List[Interaction]:
- return [
- self._fignodes[key]
- for key in self._fignodes
- if isinstance(self._fignodes[key], Interaction)
- ]
+ """Get all the interactions in the FIG
+
+ Returns:
+ List[Interaction]: a list of all the interactions in the FIG
+ """
+ ret = []
+ for item in self._fignodes.values():
+ if isinstance(item, Interaction):
+ ret.append(item)
+
+ return ret
@property
- def get_io(self) -> List[IONode]:
+ def io(self) -> List[IONode]:
+ """Get all the IONodes in the FIG
+
+ Returns:
+ List[IONode]: a list of all the IONodes in the FIG
+ """
ret = []
for key in self._fignodes:
node = self._fignodes[key]
@@ -123,54 +310,117 @@ def get_io(self) -> List[IONode]:
return ret
- def add_and_annotation(self, nodes: List[FIGNode]) -> ANDAnnotation:
- print("Need to implement the generation of the AND annotations")
- fig_node_name = "DIST_AND_" + "_".join([node.id for node in nodes])
- annotation_node = ANDAnnotation(fig_node_name)
- self.add_fignode(annotation_node)
- for node in nodes:
- self.add_edge(annotation_node.id, node.id)
- return annotation_node
-
- def add_or_annotation(self, nodes: List[FIGNode]) -> ORAnnotation:
- print("Need to implement the generation of the OR annotation")
- fig_node_name = "DIST_OR_" + "_".join([node.id for node in nodes])
- annotation_node = ORAnnotation(fig_node_name)
- self.add_fignode(annotation_node)
- for node in nodes:
- self.add_edge(annotation_node.id, node.id)
- return annotation_node
-
- def add_not_annotation(self, nodes: List[FIGNode]) -> NOTAnnotation:
- print("Need to implement the generation of the NOT annotation")
- fig_node_name = "DIST_NOT_" + "_".join([node.id for node in nodes])
- annotation_node = NOTAnnotation(fig_node_name)
- self.add_fignode(annotation_node)
- for node in nodes:
- self.add_edge(annotation_node.id, node.id)
- return annotation_node
-
- # def generate_match_string(self) -> str:
- # # Generate match string that we can use against any kind of a string match system
- # ret = ''
- # # Start with the inputs
- # for ionode in self.get_io():
- # ret += ionode.match_string
-
- # return ret
+ def get_fig_annotations(self, fig_node: FIGNode) -> List[DistributeAnnotation]:
+ """Get the annotations for a given FIGNode
+
+ Args:
+ fig_node (FIGNode): the FIGNode to get the annotations for
+
+ Returns:
+ List[DistributeAnnotation]: a list of the annotations for the given FIGNode
+ """
+ return self._annotations_reverse_map[fig_node]
+
+ def add_and_annotation(
+ self, fignode_tuples: List[Tuple[FIGNode, FIGNode]]
+ ) -> ANDAnnotation:
+ annotation_name = "DIST_AND_" + str(uuid.uuid4())
+ print(f"Adding DIST-AND annotation '{annotation_name}' for fig nodes:")
+ for item in fignode_tuples:
+ print(f"{item[0]}->{item[1]}")
+ annotation = ANDAnnotation(annotation_name)
+ self._annotations.append(annotation)
+ self._annotations_reverse_map[annotation] = []
+ for fignode_tuple in fignode_tuples:
+ annotation.add_annotated_item(fignode_tuple)
+ self.__add_to_reverse_map(fignode_tuple[0], annotation)
+ self.__add_to_reverse_map(fignode_tuple[1], annotation)
+ return annotation
+
+ def add_or_annotation(
+ self,
+ constrained_items: List[Union[Tuple[FIGNode, FIGNode], DistributeAnnotation]],
+ ) -> ORAnnotation:
+ """Add a new OR annotation to the FIG
+
+ Args:
+ constrained_items (List[Union[Tuple[FIGNode, FIGNode], DistributeAnnotation]]): a list
+ of tuples of FIGNodes or DistributeAnnotations
+
+ Returns:
+ ORAnnotation: the new ORAnnotation
+ """
+ annotation_name = "DIST_OR_" + str(uuid.uuid4())
+ print(f"Adding DIST-OR annotation '{annotation_name}' for fig nodes:")
+ for item in constrained_items:
+ if isinstance(item, DistributeAnnotation):
+ print(f"{item.id} (Annotation)")
+ else:
+ print(f"{item[0]}->{item[1]}")
+
+ annotation = ORAnnotation(annotation_name)
+ self._annotations.append(annotation)
+ self._annotations_reverse_map[annotation] = []
+ for item in constrained_items:
+ annotation.add_annotated_item(item)
+ if isinstance(item, DistributeAnnotation):
+ pass
+ else:
+ self.__add_to_reverse_map(item[0], annotation)
+ self.__add_to_reverse_map(item[1], annotation)
+
+ return annotation
+
+ def add_not_annotation(
+ self, fignode_tuple: Tuple[FIGNode, FIGNode]
+ ) -> NOTAnnotation:
+ """Add a new NOT annotation to the FIG
+
+ Args:
+ fignode_tuple (Tuple[FIGNode, FIGNode]): a tuple of FIGNodes
+
+ Returns:
+ NOTAnnotation: the new NOTAnnotation
+ """
+ annotation_name = "DIST_NOT_" + str(uuid.uuid4())
+ print(f"Adding DIST-AND annotation '{annotation_name}' for fig nodes:")
+ print(f"{fignode_tuple[0]}->{fignode_tuple[1]}")
+
+ annotation = NOTAnnotation(annotation_name)
+ self._annotations.append(annotation)
+ self._annotations_reverse_map[annotation] = []
+ annotation.add_annotated_item(fignode_tuple)
+ self.__add_to_reverse_map(fignode_tuple[0], annotation)
+ self.__add_to_reverse_map(fignode_tuple[1], annotation)
+ return annotation
def add_fig(self, fig_to_add: FluidInteractionGraph) -> None:
- # Check if any of the incoming fig nodes
+ """Add a FluidInteractionGraph to this FIG
+
+ Args:
+ fig_to_add (FluidInteractionGraph): the FIG to add
+
+ Raises:
+ Exception: if any of the nodes in the FIG to add are already present in this FIG
+ """
+ # Check if any of the incoming fig nodes are already present here
for node_id in fig_to_add.nodes:
- fig_node = fig_to_add.get_fignode(node_id)
- assert fig_node is not None
- # Check if fignode is alreay present in this
- self.add_fignode(fig_node)
+ if node_id in self._fignodes:
+ raise Exception(f"Node '{node_id}' already present in the FIG")
+ self.add_fignode(fig_to_add.get_fignode(node_id))
for edge in fig_to_add.edges:
self.add_edge(edge[0], edge[1])
+ # TODO - Verify if the cloned annotations are correct or not
+ self.load_annotations(fig_to_add.annotations)
+
def get_input_fignodes(self) -> List[IONode]:
+ """Get all the input IONodes in the FIG
+
+ Returns:
+ List[IONode]: a list of all the input IONodes in the FIG
+ """
ret = []
for fignode in self._fignodes.values():
if isinstance(fignode, IONode):
@@ -182,103 +432,209 @@ def get_input_fignodes(self) -> List[IONode]:
def __str__(self):
return self.edges.__str__()
+ def copy(self, as_view):
+ return super().copy(as_view=as_view)
+
def __deepcopy__(self, memo=None):
if memo is None:
memo = {}
+
not_there = []
existing = memo.get(self, not_there)
if existing is not not_there:
print("ALREADY COPIED TO", repr(existing))
return existing
- fignodes_copy = copy.deepcopy(
- [self._fignodes[key] for key in self._fignodes], memo
- )
+
+ fignodes_copy_list = []
+
+ # Map old_fignode <-> new_fignode
+ fignodes_copy_map: Dict[FIGNode, FIGNode] = {}
+
+ for fignode in self._fignodes.values():
+ fignode_copy = copy.copy(fignode)
+ fignodes_copy_list.append(fignode_copy)
+ fignodes_copy_map[fignode] = fignode_copy
+
fig_copy = self.copy(as_view=False)
fig_copy.__class__ = FluidInteractionGraph
- fig_copy.load_fignodes(fignodes_copy)
+ assert isinstance(fig_copy, FluidInteractionGraph)
+ fig_copy.load_fignodes(fignodes_copy_list)
+
+ # Now since all the annotations are loaded up, copy the right cloned
+ # references to fig nodes for the constriants
+ figannotations_copy_list = []
+
+ # Map old_annotatin <-> new_annotation
+ figannotations_copy_map: Dict[DistributeAnnotation, DistributeAnnotation] = {}
+
+ # Copy the annotations into the new fig copy
+ for current_annotation in self._annotations:
+ copy_annotation = copy.deepcopy(current_annotation)
+ copy_annotation.clear_items()
+ figannotations_copy_list.append(copy_annotation)
+ figannotations_copy_map[current_annotation] = copy_annotation
+
+ # TODO - Copy the annotations items
+ for current_annotation in self._annotations:
+ copy_annotation = figannotations_copy_map[current_annotation]
+ for annotation_item in current_annotation.get_items():
+ if isinstance(annotation_item, DistributeAnnotation):
+ annotation_to_add = figannotations_copy_map[annotation_item]
+ copy_annotation.add_annotated_item(annotation_to_add)
+ else:
+ tuple_to_add = (
+ fignodes_copy_map[annotation_item[0]],
+ fignodes_copy_map[annotation_item[1]],
+ )
+ copy_annotation.add_annotated_item(tuple_to_add)
+
+ fig_copy.load_annotations(figannotations_copy_list)
return fig_copy
# ---------- HELPER METHODS -----------
+ def __add_to_reverse_map(
+ self,
+ item: Union[FIGNode, DistributeAnnotation],
+ annotation: DistributeAnnotation,
+ ) -> None:
+ """Adds to reverse map
+
+ Args:
+ item (Union[FIGNode, DistributeAnnotation]): Add to reverse map
+ annotation (DistributeAnnotation): the annotation to add
+
+ Raises:
+ Exception: if the annotation is already present in the reverse map
+ """
+ if self._annotations_reverse_map is None:
+ self._annotations_reverse_map = dict()
+
+ if isinstance(item, DistributeAnnotation):
+ self.__add_to_reverse_map(item, annotation)
+ else:
+ if item in self._annotations_reverse_map:
+ annotation_list = self._annotations_reverse_map[item]
+ if annotation not in annotation_list:
+ annotation_list.append(annotation)
+ else:
+ if annotation in self._annotations_reverse_map[item]:
+ raise Exception("Annotation already present in the reverse map !")
+
+ self._annotations_reverse_map[item] = [annotation]
+
def __get_val_node_id(self) -> str:
+ """Get a unique ID for a value node
+
+ Returns:
+ str: a unique ID for a value node
+ """
self._gen_id += 1
- return "val_{0}".format(self._gen_id)
+ return f"val_{self._gen_id}"
def __add_fluid_fluid_interaction(self, interaction: FluidFluidInteraction) -> None:
+ """Adds a fluid-fluid interaction to the FIG
+
+ Args:
+ interaction (FluidFluidInteraction): the interaction to add
+
+ Raises:
+ Exception: if the interaction is not a fluid-fluid interaction
+ Exception: if the interaction is not a valid interaction
+ """
# Check if flow exists
- if interaction.fluids[0].id not in self._fignodes.keys():
+ if interaction.fluids[0].ID not in self._fignodes:
raise Exception(
- "Unable to add interaction because of missing flow: {0}".format(
- interaction.fluids[0].id
- )
+ "Unable to add interaction because of missing flow:"
+ f" {interaction.fluids[0].ID}"
)
- if interaction.fluids[1].id not in self._fignodes.keys():
+ if interaction.fluids[1].ID not in self._fignodes:
raise Exception(
- "Unable to add interaction because of missing flow: {0}".format(
- interaction.fluids[1].id
- )
+ "Unable to add interaction because of missing flow:"
+ f" {interaction.fluids[1].ID}"
)
- self.add_node(interaction.id)
- self.add_edge(interaction.fluids[0].id, interaction.id)
+ self.add_node(interaction.ID)
+ self.add_edge(interaction.fluids[0].ID, interaction.ID)
# Figure out how we want to connect FIGNodes
if interaction.type is InteractionType.SIEVE:
# In the case of a SIEVE interaction, we need to add the second
# FIGNode as an output
- self.add_edge(interaction.id, interaction.fluids[1].id)
+ self.add_edge(interaction.ID, interaction.fluids[1].ID)
else:
- self.add_edge(interaction.fluids[1].id, interaction.id)
+ self.add_edge(interaction.fluids[1].ID, interaction.ID)
# TODO: Need to add an output node
def __add_single_fluid_interaction(
self, interaction: FluidProcessInteraction
) -> None:
- if interaction.fluid.id not in self._fignodes.keys():
+ """adds a single fluid interaction to the FIG
+
+ Args:
+ interaction (FluidProcessInteraction): the interaction to add
+
+ Raises:
+ Exception: if the interaction is not a fluid-process interaction
+ """
+ if interaction.fluid.ID not in self._fignodes:
raise Exception(
- "Unable to add interaction because of missing flow: {0}".format(
- interaction.fluid.id
- )
+ "Unable to add interaction because of missing flow:"
+ " {interaction.fluid.ID}"
)
- self.add_node(interaction.id)
- self.add_edge(interaction.fluid.id, interaction.id)
+ self.add_node(interaction.ID)
+ self.add_edge(interaction.fluid.ID, interaction.ID)
# TODO: Need to add an output node
def __add_fluid_number_interaction(
self, interaction: FluidNumberInteraction
) -> None:
- if interaction.fluid.id not in self._fignodes.keys():
+ """adds a fluid-number interaction to the FIG
+
+ Args:
+ interaction (FluidNumberInteraction): the interaction to add
+
+ Raises:
+ Exception: if the interaction is not a fluid-number interaction
+ """
+ if interaction.fluid.ID not in self._fignodes:
raise Exception(
- "Unable to add interaction because of missing flow: {0}".format(
- interaction.fluid.id
- )
+ "Unable to add interaction because of missing flow:"
+ f" {interaction.fluid.ID}"
)
# Create new Value node
val_node = ValueNode(self.__get_val_node_id(), interaction.value)
- self._fignodes[val_node.id] = val_node
+ self.add_fignode(val_node)
- self.add_node(interaction.id)
- self.add_edge(interaction.fluid.id, interaction.id)
- self.add_edge(val_node.id, interaction.id)
+ self.add_node(interaction.ID)
+ self.add_edge(interaction.fluid.ID, interaction.ID)
+ self.add_edge(val_node.ID, interaction.ID)
def __add_fluid_integer_interaction(
self, interaction: FluidIntegerInteraction
) -> None:
- if interaction.fluid.id not in self._fignodes.keys():
+ """adds a fluid-integer interaction to the FIG
+
+ Args:
+ interaction (FluidIntegerInteraction): the interaction to add
+
+ Raises:
+ Exception: if the interaction is not a fluid-integer interaction
+ """
+ if interaction.fluid.ID not in self._fignodes:
raise Exception(
- "Unable to add interaction because of missing flow: {0}".format(
- interaction.fluid.id
- )
+ "Unable to add interaction because of missing flow:"
+ f" {interaction.fluid.ID}"
)
# Create new Value node
val_node = ValueNode(self.__get_val_node_id(), interaction.value)
- self._fignodes[val_node.id] = val_node
+ self.add_fignode(val_node)
- self.add_node(interaction.id)
- self.add_edge(interaction.fluid.id, interaction.id)
- self.add_edge(val_node.id, interaction.id)
+ self.add_node(interaction.ID)
+ self.add_edge(interaction.fluid.ID, interaction.ID)
+ self.add_edge(val_node.ID, interaction.ID)
diff --git a/lfr/fig/interaction.py b/lfr/fig/interaction.py
index 26bbb39..6497140 100644
--- a/lfr/fig/interaction.py
+++ b/lfr/fig/interaction.py
@@ -14,7 +14,6 @@ class InteractionType(Enum):
class Interaction(Flow):
-
INTERACTION_ID = 0
def __init__(self, id: str, interaction_type: InteractionType) -> None:
@@ -38,17 +37,41 @@ def type(self) -> InteractionType:
@staticmethod
def get_id(
- fluid1: FIGNode = None, fluid2: FIGNode = None, operator_string: str = ""
+ fluid1: FIGNode, fluid2: Optional[FIGNode] = None, operator_string: str = ""
) -> str:
+ """Generates a unique ID for the interaction
+
+ The user needs to provide atleast one fignode and the operator string to generate the ID.
+
+ Args:
+ fluid1 (FIGNode): First fignode
+ fluid2 (Optional[FIGNode]): Second FIGNode
+ operator_string (str): Operator String
+
+ Raises:
+ ValueError: If there is no fignode provided
+ ValueError: If there is no operator string provided
+
+ Returns:
+ str: unique ID for the interaction
+ """
+
id = None
+ # If no operator string is given then we cannot proceed
+ if operator_string is None or operator_string == "":
+ raise ValueError("Operator string cannot be None")
+
+ if fluid1 is None:
+ raise ValueError("id of fluid1 is found to be None")
+
if fluid2 is not None:
- if fluid1.id < fluid2.id:
- id = fluid1.id + "_" + operator_string + "_" + fluid2.id
+ if fluid1.ID < fluid2.ID:
+ id = fluid1.ID + "_" + operator_string + "_" + fluid2.ID
else:
- id = fluid2.id + "_" + operator_string + "_" + fluid1.id
+ id = fluid2.ID + "_" + operator_string + "_" + fluid1.ID
else:
- id = fluid1.id + "_" + operator_string
+ id = fluid1.ID + "_" + operator_string
id = id + "_" + str(Interaction.INTERACTION_ID)
Interaction.INTERACTION_ID += 1
@@ -92,15 +115,17 @@ def __init__(
fluid1: Flow,
fluid2: Flow,
interaction_type: InteractionType,
- interaction_data: str = None,
+ interaction_data: Optional[str] = None,
) -> None:
"""Creates an interaction between two fluids
Args:
- fluid1 (FIGNode): [description]
- fluid2 (FIGNode): [description]
- interaction_type (InteractionType, optional): [description]. Defaults to None.
- interaction_data (str, optional): [description]. Defaults to None.
+ fluid1 (FIGNode): Fluid1 that needs to be included in the interaction
+ fluid2 (FIGNode): Fluid2 that needs to be included in the interaction
+ interaction_type (InteractionType, optional): Type of Fluid Interaction.
+ Defaults to None.
+ interaction_data (str, optional): Interaction data (typically used for
+ fluid-number interactions). Defaults to None.
"""
id = Interaction.get_id(
fluid1, fluid2, Interaction.get_operator_str(interaction_type)
diff --git a/lfr/fig/simplification.py b/lfr/fig/simplification.py
new file mode 100644
index 0000000..95e1d0b
--- /dev/null
+++ b/lfr/fig/simplification.py
@@ -0,0 +1,135 @@
+from typing import List
+
+import networkx as nx
+
+from lfr.fig.fignode import Flow
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+
+"""FIG Simplification
+
+This class consists of all the methods that can be used to simplify/reduce
+the fluid interaction graph.
+"""
+
+
+def remove_passthrough_nodes(fig: FluidInteractionGraph) -> None:
+ """Remove all the passthrough nodes from the fluid interaction graph.
+
+ Args:
+ fig: The fluid interaction graph to remove the passthrough nodes from.
+ """
+
+ # Step 1. Do a shallow copy of the graph
+ # Step 2. Remove all the fignodes that are not Flow
+ # Step 3. Now get the all the disconnected pieces of the graph
+ # Step 4. Create a Construction node for each of the disconnected pieces
+ # Return all the constructions nodes
+
+ # Step 1. Do a shallow copy of the graph
+ fig_original = fig
+ fig_copy = fig.copy(
+ as_view=False
+ ) # Note this does not copy anything besides the nx.DiGraph at the moment
+
+ # Step 2. Remove all the fignodes that are not Flow
+ remove_list = []
+ for node_id in fig_copy.nodes:
+ node = fig_original.get_fignode(node_id)
+ if node.match_string != "FLOW":
+ remove_list.append(node_id)
+
+ for node_id in remove_list:
+ fig_copy.remove_node(node_id)
+
+ i = 0
+ # Step 3. Now get the all the disconnected pieces of the graph
+ for component in nx.connected_components(fig_copy.to_undirected()):
+ print("Flow candidate:", component)
+ sub = fig_original.subgraph(component)
+ # TODO - Decide what the mapping type should be. for now assume that we just a
+ # single passthrough type scenario where we don't have to do much work
+ is_passthrough = __check_if_passthrough(sub)
+ if is_passthrough:
+ print("Passthrough found:", component)
+ # Do the required remove candidate
+ # Find the input and output nodes
+ input_fignode = find_input_node(sub)
+ output_fignode = find_output_node(sub)
+
+ # Find which nodes are connected to the input and output nodes
+ # Find the incoming neighbors of the input node
+ incoming_neighbors = [
+ edge[0] for edge in list(fig_original.in_edges(input_fignode))
+ ]
+ # Find the outgoing neighbors of the output node
+ outouting_neighbors = [
+ edge[1] for edge in list(fig_original.out_edges(output_fignode))
+ ]
+
+ # Delete all the nodes in the component
+ for fig_node in component:
+ fig_original.remove_node(fig_node)
+
+ # If |incoming_neighbors| == 1 and |outouting_neighbors| == 1 : delete the
+ # whole component and connect the input and the output else create a single
+ # flow node and make the connections
+ if len(incoming_neighbors) == 1 and len(outouting_neighbors) == 1:
+ print("Removing the component:", component)
+ # Connect the input and output nodes
+ fig_original.add_edge(incoming_neighbors[0], outouting_neighbors[0])
+ else:
+ if input_fignode == output_fignode:
+ print(
+ "Since its a single flow node, we are skipping the component:",
+ component,
+ )
+ continue
+ # Create a new FLOW node
+ flow_node = Flow(f"FLOW_component_replacement_{i}")
+ i += 0
+ print("Replacing the component with:", flow_node)
+ # Add the flow node to the graph
+ fig_original.add_fignode(flow_node)
+
+ # Connect the input and output nodes
+ for incoming_neighbor_id in incoming_neighbors:
+ incoming_neighbor = fig_original.get_fignode(incoming_neighbor_id)
+ fig_original.connect_fignodes(incoming_neighbor, flow_node)
+
+ for outouting_neighbor_id in outouting_neighbors:
+ outgoing_neighbor = fig_original.get_fignode(outouting_neighbor_id)
+ fig_original.connect_fignodes(flow_node, outgoing_neighbor)
+
+
+def __check_if_passthrough(sub: nx.DiGraph) -> bool:
+ # Return true if its a single chain of flow channels
+ in_count = 0
+ out_count = 0
+ for node in list(sub.nodes):
+ inedges = list(sub.in_edges(node))
+ outedges = list(sub.out_edges(node))
+ if len(inedges) == 0:
+ in_count += 1
+ if len(outedges) == 0:
+ out_count += 1
+
+ if in_count == 1 and out_count == 1:
+ return True
+ else:
+ return False
+
+
+def find_input_node(sub: nx.DiGraph) -> str:
+ for node in list(sub.nodes):
+ inedges = list(sub.in_edges(node))
+ if len(inedges) == 0:
+ return node
+ raise Exception("No input node found")
+
+
+def find_output_node(sub: nx.DiGraph) -> str:
+ for node in list(sub.nodes):
+ outedges = list(sub.out_edges(node))
+ if len(outedges) == 0:
+ return node
+ raise Exception("No input node found")
diff --git a/lfr/graphmatch/README.md b/lfr/graphmatch/README.md
new file mode 100644
index 0000000..0a9d138
--- /dev/null
+++ b/lfr/graphmatch/README.md
@@ -0,0 +1,886 @@
+
+
+## Queries
+
+Match queries for MINT Componnet library 2021 Spring
+
+### PORT
+
+```
+{
+ v1:IO
+}
+```
+
+### MIXER
+
+```
+{
+ v1:MIX
+}
+```
+
+### DROPLET CAPACITANCE SENSOR
+
+```
+{
+ v1:PROCESS
+}
+```
+
+### LONG CELL TRAP
+
+```
+{
+ v1:STORAGE
+}
+```
+
+### SQUARE CELL TRAP
+
+```
+{
+ v1:STORAGE
+}
+```
+
+### REACTION CHAMBER
+
+```
+{
+ v1:STROAGE
+}
+```
+
+### CHEMOSTAT RING
+
+```
+{
+ v1:STORAGE
+}
+```
+
+### CURVED MIXER
+
+```
+{
+ v1:MIX
+}
+```
+
+### DIAMOND REACTION CHAMBER
+
+```
+{
+ v1:STORAGE
+}
+```
+
+### NOZZLE DROPLET GENERATOR
+
+```
+{
+ v1:METER
+}
+```
+
+### DROPLET GENERATOR FLOW FOCUS
+
+```
+{
+ v1:IO -> v2:METER
+}
+```
+
+### DROPLET GENERATOR T
+
+```
+{
+ v1:METER
+}
+```
+
+### DROPLET MERGER
+
+```
+{
+ v1:MIX
+}
+```
+
+### DROPLET SPLITTER
+```
+{
+ v1:DIVIDE
+}
+```
+
+### FILTER
+
+```
+{
+ v1:PROCESS
+}
+```
+
+### GRADIENT GENERATOR
+
+TODO - Figure out how to show this as the gradient generator
+```
+{
+ ???????
+}
+```
+
+### LL CHAMBER
+TODO - Change the name of this
+
+```
+{
+ v1:MIX -> v2:STORAGE
+}
+```
+
+### LOGIC ARRAY
+
+TODO - Figure out how to control sequences work from an LFR file. Also figure out where the
+
+```
+{
+ v1:STORAGE <-> v2:STORAGE,
+ v1:STORAGE <-> v3:STORAGE,
+ v1:STORAGE <-> v4:STORAGE,
+ v2:STORAGE <-> v3:STORAGE,
+ v3:STORAGE <-> v4:STORAGE
+}
+```
+
+### DROPLET MERGER
+
+```
+{
+ v1:MIX
+}
+```
+
+### MUX
+
+### Output MUX
+
+### 1->2
+
+```
+{
+ v1 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo1 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo2 { "DISTRIBUTE_OR", "or_1" }
+}
+```
+
+### 1->4
+
+```
+{
+ v1 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo1 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo2 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo3 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo4 { "DISTRIBUTE_OR", "or_1" }
+}
+```
+
+### 1->8
+
+```
+{
+ v1 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo1 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo2 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo3 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo4 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo5 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo6 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo7 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo8 { "DISTRIBUTE_OR", "or_1" }
+}
+```
+
+
+### 1->16
+
+```
+{
+ v1 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo1 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo2 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo3 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo4 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo5 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo6 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo7 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo8 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo9 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo10 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo11 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo12 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo13 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo14 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo15 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo16 { "DISTRIBUTE_OR", "or_1" }
+}
+```
+
+
+### 1->32
+
+```
+{
+ v1 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo1 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo2 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo3 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo4 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo5 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo6 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo7 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo8 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo9 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo10 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo11 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo12 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo13 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo14 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo15 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo16 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo17 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo18 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo19 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo20 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo21 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo22 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo23 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo24 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo25 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo26 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo27 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo28 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo29 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo30 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo31 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo32 { "DISTRIBUTE_OR", "or_1" }
+}
+```
+
+### Input MUX
+
+### 2->1
+```
+{
+ v1 { "DISTRIBUTE_OR", "or_1" },
+ vi1 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi2 { "DISTRIBUTE_OR", "or_1" } -> v1
+}
+```
+
+### 4->1
+```
+{
+ v1 { "DISTRIBUTE_OR", "or_1" },
+ vi1 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi2 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi3 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi4 { "DISTRIBUTE_OR", "or_1" } -> v1
+}
+```
+
+### 8->1
+```
+{
+ v1 { "DISTRIBUTE_OR", "or_1" },
+ vi1 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi2 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi3 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi4 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi5 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi6 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi7 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi8 { "DISTRIBUTE_OR", "or_1" } -> v1
+}
+```
+
+### 16->1
+```
+{
+ v1 { "DISTRIBUTE_OR", "or_1" },
+ vi1 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi2 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi3 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi4 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi5 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi6 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi7 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi8 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi9 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi10 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi11 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi12 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi13 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi14 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi15 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi16 { "DISTRIBUTE_OR", "or_1" } -> v1
+}
+```
+
+### 32->1
+```
+{
+ v1 { "DISTRIBUTE_OR", "or_1" },
+ vi1 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi2 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi3 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi4 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi5 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi6 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi7 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi8 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi9 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi10 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi11 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi12 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi13 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi14 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi15 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi16 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi17 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi18 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi19 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi20 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi21 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi22 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi23 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi24 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi25 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi26 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi27 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi28 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi29 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi30 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi31 { "DISTRIBUTE_OR", "or_1" } -> v1,
+ vi32 { "DISTRIBUTE_OR", "or_1" } -> v1
+}
+```
+
+
+### PATTERN BASED
+
+```
+{
+ ? { "or_1" } -> v1,
+ (? { "or_1" } -> v1)+
+}
+```
+
+```
+{
+ v1 -> ? { "or_1" },
+ (v1 -> ? { "or_1" })+
+}
+```
+
+### PICOINJECTOR
+```
+{
+ v1:MIX
+}
+```
+
+### PORT
+
+```
+{
+ v1:IO
+}
+```
+
+### PUMP
+
+```
+{
+ v1:PUMP
+}
+```
+
+### PUMP3D
+
+```
+{
+ v1:PUMP
+}
+```
+
+### ROTARY MIXER
+
+```
+{
+ v1:MIX -> v2:STROAGE
+}
+```
+
+```
+{
+ v1:STORAGE -> v2:MIX
+}
+```
+
+### DROPLET SORTER
+
+```
+{
+ v1:SIEVE
+}
+```
+
+### MIXER3D
+
+```
+{
+ v1:MIX
+}
+```
+
+### TRANSPOSER
+
+```
+{
+
+}
+```
+
+### TREE
+
+### Output
+
+### 1->2
+
+```
+{
+ v1 -> vo1,
+ v1 -> vo2
+}
+```
+
+### 1->4
+
+```
+{
+ v1 -> vo1,
+ v1 -> vo2,
+ v1 -> vo3,
+ v1 -> vo4
+}
+```
+
+### 1->8
+
+```
+{
+ v1 -> vo1,
+ v1 -> vo2,
+ v1 -> vo3,
+ v1 -> vo4,
+ v1 -> vo5,
+ v1 -> vo6,
+ v1 -> vo7,
+ v1 -> vo8
+}
+```
+
+
+### 1->16
+
+```
+{
+ v1 -> vo1,
+ v1 -> vo2,
+ v1 -> vo3,
+ v1 -> vo4,
+ v1 -> vo5,
+ v1 -> vo6,
+ v1 -> vo7,
+ v1 -> vo8,
+ v1 -> vo9,
+ v1 -> vo10,
+ v1 -> vo11,
+ v1 -> vo12,
+ v1 -> vo13,
+ v1 -> vo14,
+ v1 -> vo15,
+ v1 -> vo16
+}
+```
+
+
+### 1->32
+
+```
+{
+ v1 -> vo1 ,
+ v1 -> vo2 ,
+ v1 -> vo3 ,
+ v1 -> vo4 ,
+ v1 -> vo5 ,
+ v1 -> vo6 ,
+ v1 -> vo7 ,
+ v1 -> vo8 ,
+ v1 -> vo9 ,
+ v1 -> vo10 ,
+ v1 -> vo11 ,
+ v1 -> vo12 ,
+ v1 -> vo13 ,
+ v1 -> vo14 ,
+ v1 -> vo15 ,
+ v1 -> vo16 ,
+ v1 -> vo17 ,
+ v1 -> vo18 ,
+ v1 -> vo19 ,
+ v1 -> vo20 ,
+ v1 -> vo21 ,
+ v1 -> vo22 ,
+ v1 -> vo23 ,
+ v1 -> vo24 ,
+ v1 -> vo25 ,
+ v1 -> vo26 ,
+ v1 -> vo27 ,
+ v1 -> vo28 ,
+ v1 -> vo29 ,
+ v1 -> vo30 ,
+ v1 -> vo31 ,
+ v1 -> vo32
+}
+```
+
+### Input
+
+### 2->1
+```
+{
+ vi1 -> v1,
+ vi2 -> v1
+}
+```
+
+### 4->1
+```
+{
+ vi1 -> v1,
+ vi2 -> v1,
+ vi3 -> v1,
+ vi4 -> v1
+}
+```
+
+### 8->1
+```
+{
+ vi1 -> v1,
+ vi2 -> v1,
+ vi3 -> v1,
+ vi4 -> v1,
+ vi5 -> v1,
+ vi6 -> v1,
+ vi7 -> v1,
+ vi8 -> v1
+}
+```
+
+### 16->1
+```
+{
+ vi1 -> v1,
+ vi2 -> v1,
+ vi3 -> v1,
+ vi4 -> v1,
+ vi5 -> v1,
+ vi6 -> v1,
+ vi7 -> v1,
+ vi8 -> v1,
+ vi9 -> v1,
+ vi10 -> v1,
+ vi11 -> v1,
+ vi12 -> v1,
+ vi13 -> v1,
+ vi14 -> v1,
+ vi15 -> v1,
+ vi16 -> v1
+}
+```
+
+### 32->1
+```
+{
+ vi1 -> v1,
+ vi2 -> v1,
+ vi3 -> v1,
+ vi4 -> v1,
+ vi5 -> v1,
+ vi6 -> v1,
+ vi7 -> v1,
+ vi8 -> v1,
+ vi9 -> v1,
+ vi10 -> v1,
+ vi11 -> v1,
+ vi12 -> v1,
+ vi13 -> v1,
+ vi14 -> v1,
+ vi15 -> v1,
+ vi16 -> v1,
+ vi17 -> v1,
+ vi18 -> v1,
+ vi19 -> v1,
+ vi20 -> v1,
+ vi21 -> v1,
+ vi22 -> v1,
+ vi23 -> v1,
+ vi24 -> v1,
+ vi25 -> v1,
+ vi26 -> v1,
+ vi27 -> v1,
+ vi28 -> v1,
+ vi29 -> v1,
+ vi30 -> v1,
+ vi31 -> v1,
+ vi32 -> v1
+}
+```
+
+
+
+
+### Pattern Based
+```
+{
+ v1:FLOW -> ?:FLOW,
+ (v1:FLOW -> ?:FLOW)+
+}
+```
+
+```
+{
+ ?:FLOW -> v1:FLOW,
+ (?: FLOW -> v1:FLOW)+
+}
+```
+
+### YTREE
+
+### Output
+
+### 1->2
+
+```
+{
+ v1 -> vo1,
+ v1 -> vo2
+}
+```
+
+### 1->4
+
+```
+{
+ v1 -> vo1,
+ v1 -> vo2,
+ v1 -> vo3,
+ v1 -> vo4
+}
+```
+
+### 1->8
+
+```
+{
+ v1 -> vo1,
+ v1 -> vo2,
+ v1 -> vo3,
+ v1 -> vo4,
+ v1 -> vo5,
+ v1 -> vo6,
+ v1 -> vo7,
+ v1 -> vo8
+}
+```
+
+
+### 1->16
+
+```
+{
+ v1 -> vo1,
+ v1 -> vo2,
+ v1 -> vo3,
+ v1 -> vo4,
+ v1 -> vo5,
+ v1 -> vo6,
+ v1 -> vo7,
+ v1 -> vo8,
+ v1 -> vo9,
+ v1 -> vo10,
+ v1 -> vo11,
+ v1 -> vo12,
+ v1 -> vo13,
+ v1 -> vo14,
+ v1 -> vo15,
+ v1 -> vo16
+}
+```
+
+
+### 1->32
+
+```
+{
+ v1 -> vo1 ,
+ v1 -> vo2 ,
+ v1 -> vo3 ,
+ v1 -> vo4 ,
+ v1 -> vo5 ,
+ v1 -> vo6 ,
+ v1 -> vo7 ,
+ v1 -> vo8 ,
+ v1 -> vo9 ,
+ v1 -> vo10 ,
+ v1 -> vo11 ,
+ v1 -> vo12 ,
+ v1 -> vo13 ,
+ v1 -> vo14 ,
+ v1 -> vo15 ,
+ v1 -> vo16 ,
+ v1 -> vo17 ,
+ v1 -> vo18 ,
+ v1 -> vo19 ,
+ v1 -> vo20 ,
+ v1 -> vo21 ,
+ v1 -> vo22 ,
+ v1 -> vo23 ,
+ v1 -> vo24 ,
+ v1 -> vo25 ,
+ v1 -> vo26 ,
+ v1 -> vo27 ,
+ v1 -> vo28 ,
+ v1 -> vo29 ,
+ v1 -> vo30 ,
+ v1 -> vo31 ,
+ v1 -> vo32
+}
+```
+
+### Input
+
+### 2->1
+```
+{
+ vi1 -> v1,
+ vi2 -> v1
+}
+```
+
+### 4->1
+```
+{
+ vi1 -> v1,
+ vi2 -> v1,
+ vi3 -> v1,
+ vi4 -> v1
+}
+```
+
+### 8->1
+```
+{
+ vi1 -> v1,
+ vi2 -> v1,
+ vi3 -> v1,
+ vi4 -> v1,
+ vi5 -> v1,
+ vi6 -> v1,
+ vi7 -> v1,
+ vi8 -> v1
+}
+```
+
+### 16->1
+```
+{
+ vi1 -> v1,
+ vi2 -> v1,
+ vi3 -> v1,
+ vi4 -> v1,
+ vi5 -> v1,
+ vi6 -> v1,
+ vi7 -> v1,
+ vi8 -> v1,
+ vi9 -> v1,
+ vi10 -> v1,
+ vi11 -> v1,
+ vi12 -> v1,
+ vi13 -> v1,
+ vi14 -> v1,
+ vi15 -> v1,
+ vi16 -> v1
+}
+```
+
+### 32->1
+```
+{
+ vi1 -> v1,
+ vi2 -> v1,
+ vi3 -> v1,
+ vi4 -> v1,
+ vi5 -> v1,
+ vi6 -> v1,
+ vi7 -> v1,
+ vi8 -> v1,
+ vi9 -> v1,
+ vi10 -> v1,
+ vi11 -> v1,
+ vi12 -> v1,
+ vi13 -> v1,
+ vi14 -> v1,
+ vi15 -> v1,
+ vi16 -> v1,
+ vi17 -> v1,
+ vi18 -> v1,
+ vi19 -> v1,
+ vi20 -> v1,
+ vi21 -> v1,
+ vi22 -> v1,
+ vi23 -> v1,
+ vi24 -> v1,
+ vi25 -> v1,
+ vi26 -> v1,
+ vi27 -> v1,
+ vi28 -> v1,
+ vi29 -> v1,
+ vi30 -> v1,
+ vi31 -> v1,
+ vi32 -> v1
+}
+```
+
+### Pattern based
+
+
+```
+{
+ v1:FLOW -> ?:FLOW,
+ (v1:FLOW -> ?:FLOW)+
+}
+```
+
+```
+{
+ ?:FLOW -> v1:FLOW,
+ (?: FLOW -> v1:FLOW)+
+}
+```
\ No newline at end of file
diff --git a/lfr/graphmatch/__init__.py b/lfr/graphmatch/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/lfr/graphmatch/figmappingmatcher.py b/lfr/graphmatch/figmappingmatcher.py
new file mode 100644
index 0000000..ed4fcee
--- /dev/null
+++ b/lfr/graphmatch/figmappingmatcher.py
@@ -0,0 +1,71 @@
+from typing import Dict
+
+from networkx.algorithms.isomorphism import DiGraphMatcher
+from networkx.classes import digraph
+
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+from lfr.graphmatch.nodefilter import NodeFilter
+
+
+class FIGMappingMatcher(DiGraphMatcher):
+ """Implementation of VF2 algorithm for matching undirected graphs.
+
+ Suitable for Graph and MultiGraph instances.
+ """
+
+ def __init__(
+ self,
+ G1: FluidInteractionGraph,
+ G2: digraph.DiGraph,
+ semantic_information: Dict[str, NodeFilter],
+ ):
+ self._fig = G1
+ self._semantic_information = semantic_information
+ super(FIGMappingMatcher, self).__init__(G1, G2)
+
+ def semantic_feasibility(self, G1_node, G2_node):
+ """Returns True if adding (G1_node, G2_node) is symantically feasible.
+
+ The semantic feasibility function should return True if it is
+ acceptable to add the candidate pair (G1_node, G2_node) to the current
+ partial isomorphism mapping. The logic should focus on semantic
+ information contained in the edge data or a formalized node class.
+
+ By acceptable, we mean that the subsequent mapping can still become a
+ complete isomorphism mapping. Thus, if adding the candidate pair
+ definitely makes it so that the subsequent mapping cannot become a
+ complete isomorphism mapping, then this function must return False.
+
+ The default semantic feasibility function always returns True. The
+ effect is that semantics are not considered in the matching of G1
+ and G2.
+
+ The semantic checks might differ based on the what type of test is
+ being performed. A keyword description of the test is stored in
+ self.test. Here is a quick description of the currently implemented
+ tests::
+
+ test='graph'
+ Indicates that the graph matcher is looking for a graph-graph
+ isomorphism.
+
+ test='subgraph'
+ Indicates that the graph matcher is looking for a subgraph-graph
+ isomorphism such that a subgraph of G1 is isomorphic to G2.
+
+ Any subclass which redefines semantic_feasibility() must maintain
+ the above form to keep the match() method functional. Implementations
+ should consider multigraphs.
+ """
+
+ # Get the semantic information from here and then use it to figure out if
+ # its right type of node or not
+
+ # Figure out if G1 or G2 is the pattern graph
+ g1_fig_info = self._fig.get_fignode(G1_node)
+ g2_semantic_info = self._semantic_information[G2_node]
+
+ if g2_semantic_info.is_valid_node_type(g1_fig_info.match_string):
+ return True
+ else:
+ return False
diff --git a/lfr/graphmatch/interface.py b/lfr/graphmatch/interface.py
new file mode 100644
index 0000000..9e1b616
--- /dev/null
+++ b/lfr/graphmatch/interface.py
@@ -0,0 +1,315 @@
+from typing import Dict, FrozenSet, List, Optional, Tuple
+
+from lfr.fig.annotation import DistributeAnnotation
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+from lfr.graphmatch.figmappingmatcher import FIGMappingMatcher
+from lfr.graphmatch.matchpattern import MatchPattern
+from lfr.graphmatch.nodefilter import NodeFilter
+from lfr.netlistgenerator import LibraryPrimitivesEntry
+from lfr.netlistgenerator.mappinglibrary import MappingLibrary
+
+
+def bijective_match_node_constraints(
+ fig: FluidInteractionGraph,
+ semantic_information: Dict[str, NodeFilter],
+ subgraph: Dict[str, str],
+) -> bool:
+ # Check if the constraints match for the subgraph
+ # STEP 1 - generate new unique names for each node to simplify the matching
+ # algorihtm
+
+ # STEP 2 - Create a dictionary match_node_dict that has keys which are the set of
+ # all the renamed match graph node ID's and values to be the list of all the
+ # relationships for those nodes
+
+ # STEP 3 - Create a dictionary fig_node_dict that has keys which are the set of all
+ # the renamed FIGNode ID's and values to be the list of all the relationships for
+ # those nodes (use DISTRIBUTE ANNOTATION MATCH STRING)
+
+ # STEP 4 - Check if the dictionaries match :
+
+ # RETURN TRUE CONDITIONS
+ # 1 - Exact match in the final dictionary (the mapping between the two dictionary
+ # keys is a bijection)
+ # 2 - TODO - Mapping between the two dictionary keys is a surjection (This will
+ # allow us to have composable functiontions)
+
+ # RETIRN FALSE CONDITIONS:
+ # 1 - Cannot find node in one of the annotations (this will limit the types of
+ # matches) and not allow composable matches for disribution annotations networks
+ # 2 - Final dictionary entries do not match:
+ # 2.1 - Every entry in teh match node dictionary should be present in the
+ # fig_node_dict
+ # 2.2 - Assuming coverage is limited to the exact match subgraph in the fig, we
+ # need to ensure that
+
+ # Step 1 - Generate new unique names for each node to simplify the matching
+ # algorihtm
+ # Loop through each of the nodes in the fig and the mapping
+ new_ids = {}
+ # new_id_counter = 0
+ for key, value in subgraph.items():
+ # new_ids[key] = str(new_id_counter)
+ # new_ids[value] = str(new_id_counter)
+ # new_id_counter += 1
+ # TODO - easier to debug revert back to counter based system
+ new_ids[key] = "{}_{}".format(key, value)
+ new_ids[value] = "{}_{}".format(key, value)
+
+ # Step 2 - Create a dictionary match_node_dict that has keys which are the set of
+ # all the renamed match graph node ID's and values to be the list of all the
+ # relationships for those nodes
+ match_node_dict: Dict[FrozenSet[str], List[str]] = {}
+
+ # Create a dictionary to keep all the match_node relationships
+ # Stores {relationship_id: [matchnode ids]}
+ match_node_relationships: Dict[str, List[str]] = {}
+ # Create a dictionary to keep all the node relationship types
+ # Stores {relationship_id: relationship_type}
+ node_relationship_types: Dict[str, str] = {}
+
+ # Loop through each of the NodeFilters in the semantic information
+ for match_node_id, node_filter in semantic_information.items():
+ # Put the relationship_id and relationship_type into the coresponding dicts
+ # Go through each of the tuples in the node_filter constraints
+ for relationship_type, relationship_id in node_filter.get_constraints():
+ # If the relationship_id is not in the relationship_id dict, add it
+ if relationship_id not in match_node_relationships:
+ match_node_relationships[relationship_id] = []
+ node_relationship_types[relationship_id] = relationship_type
+ # Add the match_node_id to the list of match_node_ids for the
+ # relationship_id (We add the newly generated ids to the match_node_dict).
+ match_node_relationships[relationship_id].append(new_ids[match_node_id])
+
+ # Populate the match_node_dict with the data from the match_node_relationships
+ for (
+ relationship_id,
+ relationship_match_node_ids,
+ ) in match_node_relationships.items():
+ # generate a set of all the match_node_ids for the relationship_id
+ match_node_ids_set = frozenset(relationship_match_node_ids)
+ if match_node_ids_set not in match_node_dict:
+ match_node_dict[match_node_ids_set] = []
+ # Add the relationship type into the list corresponding to the ids set
+ match_node_dict[match_node_ids_set].append(
+ node_relationship_types[relationship_id]
+ )
+
+ # Step 3 - Create a dictionary fig_node_dict that has keys which are the set of all
+ fig_node_dict: Dict[FrozenSet[str], List[str]] = {}
+ # Loop throught the fignodes in the subgraph find the corresponding annotations and
+ # populate the fig_node_dict
+ checked_annotations = []
+ for fig_node_id in subgraph.keys():
+ fig_node = fig.get_fignode(fig_node_id)
+ annotations = fig.get_fig_annotations(fig_node)
+ # Generate the set of all the items in the fig_node annotation
+ for annotation in annotations:
+ # Check if the annotation has already been checked
+ if annotations not in checked_annotations:
+ checked_annotations.append(annotations)
+ else:
+ continue
+
+ annotation_set = set()
+ skip_annotation = False
+ for item in annotation.get_items():
+ if isinstance(item, DistributeAnnotation):
+ raise NotImplementedError(
+ "Need to figure out how to define/process nested relationship"
+ )
+ else:
+ # TODO - Handle scenarios where the Item is not found in the
+ # mapping scope
+ if item[0].ID in new_ids.keys() and item[1].ID in new_ids.keys():
+ annotation_set.add(new_ids[item[0].ID])
+ annotation_set.add(new_ids[item[1].ID])
+ else:
+ print(
+ 'Warning! Rejecting annotation "{}" for consideration in'
+ " DISTRIBUTE RELATIONSHIP Matching since it has items not"
+ " covered by the Primitive".format(annotation)
+ )
+ skip_annotation = True
+ break
+
+ if skip_annotation:
+ # Skip adding the annotation since there were fig items outside of the
+ # current mapping domain
+ continue
+
+ # Add the annotation_set to the fig_node_dict with the corresponding
+ # annotation type
+ if frozenset(annotation_set) not in fig_node_dict:
+ fig_node_dict[frozenset(annotation_set)] = []
+
+ fig_node_dict[frozenset(annotation_set)].append(annotation.match_string)
+
+ # Step 4 - Check if the dictionaries match (is a bijection)
+ # Step 4.1 - Check if the relatships between the fig and the match networks are
+ # surjective
+ # Step 4.1.1 - Check if each of the keys in the match_node_dict is in the
+ # fig_node_dict
+ for ids_set in match_node_dict.keys():
+ if ids_set not in fig_node_dict:
+ return False
+ # Step 4.1.2 - Check if each of the values in the fig_node_dict is in the
+ # match_node_dict
+ fig_rels_list = fig_node_dict[ids_set]
+ fig_rels_list.sort()
+ match_rels_list = match_node_dict[ids_set]
+ match_rels_list.sort()
+ if fig_rels_list != match_rels_list:
+ return False
+ # Step 4.2 - Check if the relationships between the fig and the match networks are
+ # injective
+ # Step 4.2.1 - Check if each of the keys in the fig_node_dict is in the
+ # match_node_dict
+ for ids_set in fig_node_dict.keys():
+ if ids_set not in match_node_dict:
+ return False
+ # Step 4.2.2 - Check if each of the values in the match_node_dict is in the
+ # fig_node_dict
+ fig_rels_list = fig_node_dict[ids_set]
+ fig_rels_list.sort()
+ match_rels_list = match_node_dict[ids_set]
+ match_rels_list.sort()
+ if fig_rels_list != match_rels_list:
+ return False
+
+ # If we get to this point, then the match network is a bijection
+ return True
+
+
+def get_fig_matches(
+ fig: FluidInteractionGraph, library: MappingLibrary
+) -> List[LibraryPrimitivesEntry]:
+ """Get the matches for the given FluidInteractionGraph and MappingLibrary.
+
+
+ Args:
+ fig (FluidInteractionGraph): FIG to match.
+ library (MappingLibrary): Library to match against
+
+ Returns:
+ List[LibraryPrimitivesEntry]: This returns a list of tuples of the
+ matches ordered this way: (primitive_uid, primitive_mint, match_node_dict). The
+ keys in the match_node_dict is from the FIG and the values are from the match
+ pattern.
+ """
+ ret = []
+
+ # TODO - Retrun the networkx subgraph views of the of the FIG
+ # Step 1 - Generate the match candidates by running the subgraph isomerism for all
+ # the items stored in the library
+ for minty_uid, mint, match_pattern_string in library.get_match_patterns():
+ if match_pattern_string == "" or match_pattern_string is None:
+ print("Warning ! - Missing match string for mint- {}".format(minty_uid))
+ continue
+ pattern = MatchPattern(match_pattern_string)
+ structural_template = pattern.get_structural_template()
+ semantic_information = pattern.get_semantic_template()
+ GM = FIGMappingMatcher(fig, structural_template, semantic_information)
+
+ for subgraph in GM.subgraph_isomorphisms_iter():
+ # Work with these subgraphs at the end and then push them through the
+ # constraint checking phase
+
+ # This would be a match, figure out how to get the mapping from GM.mapping
+
+ # Loop through each of the candates
+ # Compare the constraints on all the nodes for this for subgraph to
+ # confirm the match
+
+ distribution_constaints = []
+ distribution_annotations = []
+ for node_filter in semantic_information.values():
+ distribution_constaints.extend(node_filter.get_constraints())
+
+ for fig_id in subgraph.keys():
+ fig_node = fig.get_fignode(fig_id)
+ distribution_annotations.extend(fig.get_fig_annotations(fig_node))
+
+ # Constraint matching Logic - This logic allows for annotated fig_nodes to
+ # be matched against match patterns that dont have any distribtion
+ # constraints. The 4 cases shown here describe the different ways in which
+ # this logic can work.
+
+ # Case 1 - if subgraph has no distribution annotations and match template
+ # has no distribution constraints - SKIP | MATCH
+
+ # Case 2 - if subgraph has no distribution annotations and match template
+ # has distribtion constraints - SKIP | NO-MATCH
+
+ # Case 3 - if subgraph has distribution annotations and match
+ # template has no distribution constraints - SKIP | MATCH
+
+ # Case 4 - if subgraph has distribution annotations and match template
+ # has distribution constraints - NO-SKIP | CHECK-MATCH
+
+ # Case 1 + Case 3 Logic - We only need to check if the distribution
+ # constraints are zero (LOGIC REDUCTION)
+ if len(distribution_constaints) == 0:
+ # No distribution constraints, so we can skip node constraint matching
+ print("Found Match: {}".format(minty_uid))
+ print(subgraph)
+
+ # MATCH
+ ret.append((minty_uid, mint, subgraph))
+ # SKIP
+ continue
+
+ # Case 2 Logic
+ if len(distribution_annotations) == 0 and len(distribution_constaints) > 0:
+ # NO-MATCH, SKIP
+ continue
+
+ # Case 4 Logic
+ if len(distribution_annotations) > 0 and len(distribution_constaints) > 0:
+ # Check if the subgraph annotations matche the distribution constraints
+ # TODO - Also expand this algorithm to allow for surjective matches.
+ # This would allow us to verify the composability of the matches with
+ # the library
+ if bijective_match_node_constraints(
+ fig, semantic_information, subgraph
+ ):
+ # TODO - Extract the specific mapping for the subgraph
+ print("Found Match: {}".format(minty_uid))
+ print(subgraph)
+
+ ret.append((minty_uid, mint, subgraph))
+ else:
+ # NO-MATCH, SKIP
+ continue
+
+ return ret
+
+
+def find_structural_matches(
+ match,
+ privitives: List[LibraryPrimitivesEntry],
+) -> List[LibraryPrimitivesEntry]:
+ """Finds all the primitives with the matching structural template.
+
+ Args:
+ privitives (List[LibraryPrimitivesEntry]): List of primitives to match.
+
+ Returns:
+ List[LibraryPrimitivesEntry]: List of primitives that match
+ """
+
+ # Go through each of the primitives and find the ones that match the structure
+ # template
+ raise NotImplementedError()
+ return privitives
+
+
+def generate_single_match(
+ fig_subgraph, library_entry
+) -> Optional[Tuple[str, Dict[str, str]]]:
+ # TODO - using fig subgraph view test to see if the subgraph is a structural match
+ # to technology entry from the mapping library, pass back the match tuple if it is
+ # if it isn't then figure out how to do this separately. Also don't enable node
+ # filters for this step. Enabling them will cause the match to fail.
+ raise NotImplementedError()
+ return ("test", {"test": "test"})
diff --git a/lfr/graphmatch/matchpattern.py b/lfr/graphmatch/matchpattern.py
new file mode 100644
index 0000000..5516e42
--- /dev/null
+++ b/lfr/graphmatch/matchpattern.py
@@ -0,0 +1,61 @@
+from __future__ import annotations
+
+from typing import Dict
+
+from antlr4 import InputStream
+from antlr4.CommonTokenStream import CommonTokenStream
+from antlr4.tree.Tree import ParseTreeWalker
+from networkx.classes.digraph import DiGraph
+
+from lfr.antlrgen.reggie.reggieLexer import reggieLexer
+from lfr.antlrgen.reggie.reggieParser import reggieParser
+from lfr.graphmatch.matchpatterngenerator import MatchPatternGenerator
+from lfr.graphmatch.nodefilter import NodeFilter
+
+
+class MatchPattern:
+ def __init__(self, pattern_string: str = "") -> None:
+ if pattern_string == "" or pattern_string is None:
+ raise Exception("Empty Pattern found")
+
+ self.__pattern_string = pattern_string
+ self._structural_template = None
+
+ # Dictionary that stores the nodefilter object and the node id
+ self._semantic_template: Dict[str, NodeFilter] = {}
+
+ self.__parse_pattern(pattern_string)
+
+ def get_structural_template(self) -> DiGraph:
+ if self._structural_template is None:
+ raise Exception("No structural template assigned")
+
+ return self._structural_template
+
+ def get_semantic_template(self) -> Dict[str, NodeFilter]:
+ return self._semantic_template
+
+ def __parse_pattern(self, pattern) -> None:
+ # Implement the reggie parser walker, execution of the compiler
+ # Step 1 - Parse the thing
+ # Step 2 - Save the structural Template
+ # Step 3 - Save the semantic template
+ istream = InputStream(pattern)
+ lexer = reggieLexer(istream)
+ stream = CommonTokenStream(lexer)
+ parser = reggieParser(stream)
+
+ syntax_errors = parser.getNumberOfSyntaxErrors()
+ if syntax_errors > 0:
+ raise Exception(
+ "Could not parse the match expression, interrupting parsing flow"
+ )
+
+ tree = parser.graph()
+ walker = ParseTreeWalker()
+ listener = MatchPatternGenerator()
+
+ walker.walk(listener, tree)
+
+ self._structural_template = listener.structural_template
+ self._semantic_template = listener.semantic_template
diff --git a/lfr/graphmatch/matchpatterngenerator.py b/lfr/graphmatch/matchpatterngenerator.py
new file mode 100644
index 0000000..4eb6383
--- /dev/null
+++ b/lfr/graphmatch/matchpatterngenerator.py
@@ -0,0 +1,72 @@
+from typing import Dict, List
+
+import networkx as nx
+
+from lfr.antlrgen.reggie.reggieListener import reggieListener
+from lfr.antlrgen.reggie.reggieParser import reggieParser
+from lfr.graphmatch.nodefilter import NodeFilter
+
+
+class MatchPatternGenerator(reggieListener):
+ def __init__(self) -> None:
+ super(MatchPatternGenerator, self).__init__()
+
+ self.structural_template = nx.DiGraph()
+ self.semantic_template: Dict[str, NodeFilter] = {}
+ self._vertices_stack: List[str] = []
+
+ def enterVertex(self, ctx: reggieParser.VertexContext):
+ vertex_id = ctx.structuralid().getText()
+
+ self._vertices_stack.append(vertex_id)
+
+ # Skip the generation if the vertex is already in the structural template
+ if vertex_id in self.structural_template.nodes:
+ return
+
+ # Get the type filters for the semantic template
+ label_filters = []
+ if ctx.labelfilter() is not None:
+ label_filters = [label.getText() for label in ctx.labelfilter().label()]
+
+ # Get the coloring filter
+ coloring_labels = []
+ if ctx.coloringfilter() is not None:
+ coloring_labels = [
+ MatchPatternGenerator.remove_quotes(s.getText())
+ for s in ctx.coloringfilter().STRING()
+ ]
+ constraints_tuples = []
+ for i in range(0, len(coloring_labels), 2):
+ constraints_tuples.append((coloring_labels[i], coloring_labels[i + 1]))
+
+ # TODO - Put in the filter type information here
+ semanitc_info = NodeFilter()
+
+ if vertex_id == "?":
+ raise NotImplementedError()
+
+ else:
+ self.structural_template.add_node(vertex_id)
+ self.semantic_template[vertex_id] = NodeFilter(
+ node_types_filter=label_filters,
+ node_constraints=constraints_tuples,
+ )
+
+ def enterVertex2vertex(self, ctx: reggieParser.Vertex2vertexContext):
+ # Clear out the recent vertex memory
+ self._vertices_stack.clear()
+
+ def exitVertex2vertex(self, ctx: reggieParser.Vertex2vertexContext):
+ # TODO - Check to see if the vertex is present in the structural template first
+
+ # Since the vertex is in the structural template
+ for i in range(1, len(self._vertices_stack)):
+ start = self._vertices_stack[i - 1]
+ end = self._vertices_stack[i]
+ # Generate the graph
+ self.structural_template.add_edge(start, end)
+
+ @staticmethod
+ def remove_quotes(s: str) -> str:
+ return s.replace('"', "")
diff --git a/lfr/graphmatch/nodefilter.py b/lfr/graphmatch/nodefilter.py
new file mode 100644
index 0000000..1b9daf7
--- /dev/null
+++ b/lfr/graphmatch/nodefilter.py
@@ -0,0 +1,29 @@
+from __future__ import annotations
+
+from typing import List, Tuple
+
+
+class NodeFilter:
+ def __init__(
+ self,
+ node_types_filter: List[str] = [],
+ node_attributes_filter: List[str] = [],
+ node_constraints: List[Tuple[str, str]] = [],
+ ) -> None:
+ self._node_types_filter: List[str] = node_types_filter
+ self._node_attributes_filter: List[str] = node_attributes_filter
+ self._node_constraints: List[Tuple[str, str]] = node_constraints
+
+ def is_valid_node_type(self, type_string: str) -> bool:
+ if len(self._node_types_filter) == 0:
+ # If there are no node type filters, then return true
+ return True
+ return type_string in self._node_types_filter
+
+ def is_valid_attribute_type(self, attributestring: str) -> bool:
+ # TODO - Figure out what this will be in tuture
+ raise NotImplementedError("Currently do not support node attributes")
+ return True
+
+ def get_constraints(self) -> List[Tuple[str, str]]:
+ return self._node_constraints
diff --git a/lfr/lfrbaseListener.py b/lfr/lfrbaseListener.py
index 9702d31..6f05a29 100644
--- a/lfr/lfrbaseListener.py
+++ b/lfr/lfrbaseListener.py
@@ -1,9 +1,10 @@
import re
from enum import Enum
+from os import error
from typing import List, Optional
-from lfr.antlrgen.lfrXListener import lfrXListener
-from lfr.antlrgen.lfrXParser import lfrXParser
+from lfr.antlrgen.lfr.lfrXListener import lfrXListener
+from lfr.antlrgen.lfr.lfrXParser import lfrXParser
from lfr.compiler.distribute.BitVector import BitVector
from lfr.compiler.language.concatenation import Concatenation
from lfr.compiler.language.fluidexpression import FluidExpression
@@ -35,7 +36,6 @@ class VariableTypes(Enum):
class LFRBaseListener(lfrXListener):
def __init__(self):
-
print("Initialized the lfrcompiler")
self.modules = []
self.currentModule: Optional[Module] = None
@@ -58,7 +58,7 @@ def __init__(self):
# This might be the new expression stack
self.stack = []
self.statestack = []
- self.binaryoperatorsstack = [[]]
+ self.binaryoperatorsstack: List[List[str]] = [[]]
# TODO - Figure out how to make this more elegant
self._lhs_store = None
@@ -85,15 +85,21 @@ def exitModule(self, ctx: lfrXParser.ModuleContext):
self.success = False
self.vectors = {}
self.expressionresults = None
- self.listermode: ListenerMode = ListenerMode.NONE
- self.lastlistenermode: ListenerMode = ListenerMode.NONE
+ self.listermode = ListenerMode.NONE
+ self.lastlistenermode = ListenerMode.NONE
self.stack = []
self.statestack = []
self.binaryoperatorsstack = [[]]
def enterIoblock(self, ctx: lfrXParser.IoblockContext):
+ if self.currentModule is None:
+ raise ValueError("currentModule set to None")
+
# If io block has an explicit declaration set the flag
+ if self.currentModule is None:
+ raise ValueError("currentModule set to None")
+
if ctx.explicitIOBlock() is not None:
self.EXPLICIT_MODULE_DECLARATION = True
@@ -111,11 +117,14 @@ def enterIoblock(self, ctx: lfrXParser.IoblockContext):
self.vectors[name] = v
self.typeMap[name] = VariableTypes.FLUID
- m = ModuleIO(name)
- m.vector_ref = v.get_range()
+ m = ModuleIO(name, IOType.FLOW_INPUT)
+ m.vector_ref = VectorRange.get_range_from_vector(v)
self.currentModule.add_io(m)
def exitExplicitIOBlock(self, ctx: lfrXParser.ExplicitIOBlockContext):
+ if self.currentModule is None:
+ raise ValueError("currentModule set to None")
+
# First check the type of the explicit io block
decltype = ctx.start.text
mode = None
@@ -166,9 +175,12 @@ def exitExplicitIOBlock(self, ctx: lfrXParser.ExplicitIOBlockContext):
for io in vec.get_items():
io.type = mode
+ # If IOType is None
+ if mode is None:
+ raise ValueError("IOType is None")
# Create and add a ModuleIO reference
m = ModuleIO(name, mode)
- m.vector_ref = vec.get_range()
+ m.vector_ref = VectorRange.get_range_from_vector(vec)
self.currentModule.add_io(m)
else:
@@ -180,6 +192,9 @@ def exitExplicitIOBlock(self, ctx: lfrXParser.ExplicitIOBlockContext):
)
def enterFluiddeclstat(self, ctx: lfrXParser.FluiddeclstatContext):
+ if self.currentModule is None:
+ raise ValueError("currentModule set to None")
+
self.__updateMode(ListenerMode.VARIABLE_DECLARATION_MODE)
for declvar in ctx.declvar():
name = declvar.ID().getText()
@@ -193,6 +208,8 @@ def enterFluiddeclstat(self, ctx: lfrXParser.FluiddeclstatContext):
v = self.__createVector(name, Flow, startindex, endindex)
for item in v.get_items():
+ if self.currentModule is None:
+ raise ValueError("currentModule set to None")
self.currentModule.add_fluid(item)
# Now that the declaration is done, we are going to save it
@@ -203,6 +220,9 @@ def exitFluiddeclstat(self, ctx: lfrXParser.FluiddeclstatContext):
self.__revertMode()
def enterStoragestat(self, ctx: lfrXParser.StoragestatContext):
+ if self.currentModule is None:
+ raise ValueError("currentModule set to None")
+
self.__updateMode(ListenerMode.VARIABLE_DECLARATION_MODE)
for declvar in ctx.declvar():
name = declvar.ID().getText()
@@ -226,6 +246,9 @@ def exitStoragestat(self, ctx: lfrXParser.StoragestatContext):
self.__revertMode()
def enterPumpvarstat(self, ctx: lfrXParser.PumpvarstatContext):
+ if self.currentModule is None:
+ raise ValueError("currentModule set to None")
+
self.__updateMode(ListenerMode.VARIABLE_DECLARATION_MODE)
for declvar in ctx.declvar():
name = declvar.ID().getText()
@@ -249,6 +272,9 @@ def exitPumpvarstat(self, ctx: lfrXParser.PumpvarstatContext):
self.__revertMode()
def enterSignalvarstat(self, ctx: lfrXParser.SignalvarstatContext):
+ if self.currentModule is None:
+ raise ValueError("currentModule set to None")
+
self.__updateMode(ListenerMode.VARIABLE_DECLARATION_MODE)
for declvar in ctx.declvar():
name = declvar.ID().getText()
@@ -382,7 +408,8 @@ def exitExpressionterm(self, ctx: lfrXParser.ExpressiontermContext):
self.stack.append(output)
elif ctx.number() is not None:
- # TODO: Figure out how one needs to process the number with a unary operator
+ # TODO: Figure out how one needs to process the number with a unary
+ # operator
raise Exception(
"Implement method to evaluate number with unary operator"
)
@@ -421,14 +448,18 @@ def exitBracketexpression(self, ctx: lfrXParser.BracketexpressionContext):
self.__revertMode()
# Perform the unary operation if present
if ctx.unary_operator() is not None:
-
operator = ctx.unary_operator().getText()
term = self.stack.pop()
+ if self.currentModule is None:
+ raise ValueError()
fluidexpession = FluidExpression(self.currentModule)
result = fluidexpession.process_unary_operation(term, operator)
self.stack.append(result)
def exitAssignstat(self, ctx: lfrXParser.AssignstatContext):
+ if self.currentModule is None:
+ raise ValueError("current module is set to None")
+
rhs = self.stack.pop()
lhs = self.stack.pop()
@@ -451,24 +482,25 @@ def exitAssignstat(self, ctx: lfrXParser.AssignstatContext):
# Make 1-1 connections
for source, target in zip(rhs, lhs):
print(source, target)
- sourceid = source.id
- targetid = target.id
+ sourceid = source.ID
+ targetid = target.ID
self.currentModule.add_fluid_connection(sourceid, targetid)
elif len(lhs) != len(rhs):
print("LHS not equal to RHS")
for source in rhs:
- sourceid = source.id
+ sourceid = source.ID
for target in lhs:
- targetid = target.id
+ targetid = target.ID
self.currentModule.add_fluid_connection(sourceid, targetid)
def exitLiteralassignstat(self, ctx: lfrXParser.LiteralassignstatContext):
rhs = self.stack.pop()
lhs = ctx.ID().getText()
- # TODO: Check all error conditions and if the right kinds of variables are being assigned here
+ # TODO: Check all error conditions and if the right kinds of variables are
+ # being assigned here
# self.vectors[lhs] = rhs
if self.listermode is ListenerMode.VARIABLE_DECLARATION_MODE:
@@ -498,7 +530,6 @@ def __createVector(
return v
def __createLiteralVector(self, name: str, values: List) -> Vector:
-
objectype = None
if isinstance(values, list):
@@ -523,6 +554,8 @@ def __performUnaryOperation(
)
)
# TODO: Return the vector range result of unary operator
+ if self.currentModule is None:
+ raise ValueError()
fluidexpression = FluidExpression(self.currentModule)
result = fluidexpression.process_unary_operation(operand, operator)
@@ -551,6 +584,8 @@ def __parseBinaryNumber(text: str) -> BitVector:
pattern = r"(\d+)'b(\d+)"
matches = re.search(pattern, text)
# size = int(matches.group(1))
+ if matches is None:
+ raise error("No matches found")
bit_pattern = matches.group(2)
n = BitVector(bitstring=bit_pattern)
return n
diff --git a/lfr/moduleinstanceListener.py b/lfr/moduleinstanceListener.py
index 298f050..0e43377 100644
--- a/lfr/moduleinstanceListener.py
+++ b/lfr/moduleinstanceListener.py
@@ -1,6 +1,7 @@
+from os import error
from typing import Dict, Optional
-from lfr.antlrgen.lfrXParser import lfrXParser
+from lfr.antlrgen.lfr.lfrXParser import lfrXParser
from lfr.compiler.lfrerror import ErrorType, LFRError
from lfr.compiler.module import Module
from lfr.distBlockListener import DistBlockListener
@@ -16,6 +17,9 @@ def __init__(self) -> None:
def enterModuleinstantiationstat(
self, ctx: lfrXParser.ModuleinstantiationstatContext
):
+ if self.currentModule is None:
+ raise ValueError("currentModule set to None")
+
# Check if the type exists in current compiler memory
type_id = ctx.moduletype().getText()
module_to_import = None
@@ -38,6 +42,9 @@ def enterModuleinstantiationstat(
def exitModuleinstantiationstat(
self, ctx: lfrXParser.ModuleinstantiationstatContext
):
+ if self.currentModule is None:
+ raise ValueError("currentModule set to None")
+
# Create new instance of the import the type
type_id = ctx.moduletype().getText()
io_mapping = self._io_mapping
@@ -52,6 +59,8 @@ def exitOrderedioblock(self, ctx: lfrXParser.OrderedioblockContext):
variables.insert(0, self.stack.pop())
# now go through the different connections in the module to import
+ if self._module_to_import is None:
+ raise ValueError("No module to import here")
module_io = self._module_to_import.io
assert len(module_io) == num_variables
@@ -63,7 +72,7 @@ def exitOrderedioblock(self, ctx: lfrXParser.OrderedioblockContext):
there_vector_ref = module_io[i].vector_ref
here_vector_ref = variables[i]
for i in range(len(there_vector_ref)):
- self._io_mapping[there_vector_ref[i].id] = here_vector_ref[i].id
+ self._io_mapping[there_vector_ref[i].ID] = here_vector_ref[i].ID
# def exitUnorderedioblock(self, ctx: lfrXParser.UnorderedioblockContext):
# num_variables = len(ctx.explicitinstanceiomapping())
@@ -78,11 +87,14 @@ def exitOrderedioblock(self, ctx: lfrXParser.OrderedioblockContext):
def exitExplicitinstanceiomapping(
self, ctx: lfrXParser.ExplicitinstanceiomappingContext
):
+ if self._module_to_import is None:
+ raise error("No module to import found in the listener store")
+
variable = self.stack.pop()
label = ctx.ID().getText()
# Check if label exists in module_to_import
- if label not in self._module_to_import.get_all_io():
+ if label not in [item.id for item in self._module_to_import.get_all_io()]:
self.compilingErrors.append(
LFRError(
ErrorType.MODULE_IO_NOT_FOUND,
@@ -94,6 +106,13 @@ def exitExplicitinstanceiomapping(
return
io = self._module_to_import.get_io(label)
- assert len(io.vector_ref) == len(variable)
+ if len(io.vector_ref) != len(variable):
+ self.compilingErrors.append(
+ LFRError(
+ ErrorType.MODULE_SIGNAL_BINDING_MISMATCH,
+ "Number of module instance signals and variables don't match",
+ )
+ )
+ return
for i in range(len(variable)):
- self._io_mapping[io.vector_ref[i].id] = variable[i].id
+ self._io_mapping[io.vector_ref[i].ID] = variable[i].ID
diff --git a/lfr/netlistgenerator/__init__.py b/lfr/netlistgenerator/__init__.py
index e69de29..79679e7 100644
--- a/lfr/netlistgenerator/__init__.py
+++ b/lfr/netlistgenerator/__init__.py
@@ -0,0 +1,8 @@
+"""Types generally used around there to pass along data
+
+TODO - Add detailed descriptions of all types
+"""
+
+from typing import Dict, Tuple
+
+LibraryPrimitivesEntry = Tuple[str, str, Dict[str, str]]
diff --git a/lfr/netlistgenerator/v2/connectingoption.py b/lfr/netlistgenerator/connectingoption.py
similarity index 91%
rename from lfr/netlistgenerator/v2/connectingoption.py
rename to lfr/netlistgenerator/connectingoption.py
index 0cdca43..c612f60 100644
--- a/lfr/netlistgenerator/v2/connectingoption.py
+++ b/lfr/netlistgenerator/connectingoption.py
@@ -5,7 +5,7 @@ class ConnectingOption:
def __init__(
self,
component_name: Optional[str] = None,
- component_port: List[Optional[str]] = None,
+ component_port: List[Optional[str]] = [],
) -> None:
if component_port is None:
component_port = []
diff --git a/lfr/netlistgenerator/connection_primitive.py b/lfr/netlistgenerator/connection_primitive.py
new file mode 100644
index 0000000..6992c99
--- /dev/null
+++ b/lfr/netlistgenerator/connection_primitive.py
@@ -0,0 +1,37 @@
+import hashlib
+
+from lfr.netlistgenerator.primitive import Primitive, PrimitiveType
+
+
+class ConnectionPrimitive(Primitive):
+ """
+ Connection primitive class.
+ """
+
+ def __init__(self, mint: str = "") -> None:
+ """Initializes the connection primitive.
+
+ Args:
+ mint (str, optional): MINT string to initialize the connection primitive. Defaults to "".
+ """
+ super().__init__(mint)
+ self._type = PrimitiveType.CONNECTION
+ self._uid = hashlib.md5(f"{self._mint}".encode("utf-8")).hexdigest()
+
+ @property
+ def mint(self) -> str:
+ """Returns the MINT string for the connection primitive.
+
+ Returns:
+ str: MINT string for the connection primitive
+ """
+ return self._mint
+
+ @property
+ def uid(self) -> str:
+ """Returns the UID of the connection primitive.
+
+ Returns:
+ str: UID of the connection primitive
+ """
+ return self._uid
diff --git a/lfr/netlistgenerator/constructiongraph/__init__.py b/lfr/netlistgenerator/constructiongraph/__init__.py
new file mode 100644
index 0000000..5dfc931
--- /dev/null
+++ b/lfr/netlistgenerator/constructiongraph/__init__.py
@@ -0,0 +1,2 @@
+from .constructiongraph import ConstructionGraph
+from .constructionnode import ConstructionNode
diff --git a/lfr/netlistgenerator/constructiongraph/constructiongraph.py b/lfr/netlistgenerator/constructiongraph/constructiongraph.py
new file mode 100644
index 0000000..647a8bb
--- /dev/null
+++ b/lfr/netlistgenerator/constructiongraph/constructiongraph.py
@@ -0,0 +1,160 @@
+from __future__ import annotations
+
+import os
+from typing import FrozenSet, List
+
+import networkx as nx
+
+from lfr import parameters
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+from lfr.netlistgenerator.constructiongraph.constructionnode import ConstructionNode
+
+
+class ConstructionGraph(nx.DiGraph):
+ """
+ This class is a sub-class of networkx.DiGraph.
+ It acts as a proxy datastructure for generating the device netlist.
+ """
+
+ def __init__(self, id: str, fig: FluidInteractionGraph) -> None:
+ """Initializes the construction graph
+
+ Args:
+ id (str): ID of the construction graph
+ fig (FluidInteractionGraph): Fluid interaction graph which the construction
+ """
+ super().__init__()
+ self._id = id
+ self._fig = fig
+ self._construction_nodes: List[ConstructionNode] = []
+
+ @property
+ def ID(self) -> str:
+ """Returns the ID of the construction graph
+
+ Returns:
+ str: ID of the construction graph
+ """
+ return self._id
+
+ @property
+ def construction_nodes(self) -> List[ConstructionNode]:
+ return self._construction_nodes
+
+ def add_construction_node(self, construction_node: ConstructionNode) -> None:
+ """Adds a construction node to the graph
+
+ Args:
+ construction_node (ConstructionNode): Node to add the the construction graph
+ """
+
+ self._construction_nodes.append(construction_node)
+ self.add_node(construction_node.ID)
+
+ def remove_construction_node(self, construction_node: ConstructionNode) -> None:
+ """Remove a construction node from the graph
+
+ Args:
+ construction_node (ConstructionNode): Node to remove from the construction
+ graph
+ """
+ # Remove the construction node from the graph
+ self.remove_node(construction_node.ID)
+ self._construction_nodes.remove(construction_node)
+
+ def get_construction_node(self, id: str) -> ConstructionNode:
+ """Returns the construction node with the given id
+
+ Args:
+ id (str): ID of the construction node to return
+
+ Raises:
+ ValueError: If the construction node with the given id does not exist
+
+ Returns:
+ ConstructionNode: Construction node with the given id
+ """
+ for cn in self._construction_nodes:
+ if cn.ID == id:
+ return cn
+ else:
+ raise ValueError("No construction node with id: " + id)
+
+ def connect_nodes(self, node_a: ConstructionNode, node_b: ConstructionNode) -> None:
+ """
+ This method connects two nodes in the graph.
+ """
+ self.add_edge(node_a.ID, node_b.ID)
+
+ def is_fig_fully_covered(self) -> bool:
+ """
+ This method checks if the FIG is fully covered by the construction graph
+ """
+ # Check if all the fig nodes are covered by construction nodes fig_subgraph
+ # Create a set of all the fig node ids
+ # Go through each of the construction nodes and the corresponding fig subgraph
+ # nodes if the fig subgraph node is not in the list of fig node ids, then the
+ # graph is not fully covered
+ fig_node_set = set([node for node in self._fig.nodes])
+ for cn in self._construction_nodes:
+ fig_subgraph = cn.fig_subgraph
+ for node in fig_subgraph.nodes:
+ if node not in fig_node_set:
+ return False
+ else:
+ return True
+
+ def generate_variant(self, new_id: str) -> ConstructionGraph:
+ # Generate a variant of the construction graph
+ ret = ConstructionGraph(new_id, self._fig)
+ for cn in self._construction_nodes:
+ ret.add_construction_node(cn)
+ # Get the existing edges and add them to the new graph
+ for edge in self.edges:
+ ret.add_edge(edge[0], edge[1])
+ return ret
+
+ def __eq__(self, __o: object) -> bool:
+ if isinstance(__o, ConstructionGraph):
+ if self.ID == __o.ID:
+ return True
+ else:
+ return False
+ else:
+ return False
+
+ def remove_node_for_exact_fig_cover(self, fig_node_cover: FrozenSet[str]) -> None:
+ """Removes the construction node which contains the exact fig node cover
+ provided.
+
+ This method Removes the construction node which contains the exact fig node
+ cover provided. i.e. if the fig_node_cover is {'A', 'B'} and the construction
+ should have a fig node mapping of {'A', 'B'}. This covers the cases where the
+ mapping is an exact match and you need to substitute the entire construction
+ node.
+
+ Use other methods when you need to account for partial cover matches.
+
+ Args:
+ fig_node_cover (FrozenSet[str]): A frozen set of fig node IDs which
+ represents the exact fig node cover.
+ """
+
+ for cn in self._construction_nodes:
+ if frozenset(list(cn.fig_subgraph.nodes)) == fig_node_cover:
+ self.remove_node(cn.ID)
+ break
+
+ def __str__(self):
+ ret = "Construction Graph: " + self.ID
+ return ret
+
+ def print_graph(self, filename: str) -> None:
+ """Prints the graph to a file
+
+ Args:
+ filename (str): Name of the file to print the graph to
+ """
+ tt = os.path.join(parameters.OUTPUT_DIR, filename)
+ print("File Path:", tt)
+ nx.nx_agraph.to_agraph(self).write(tt)
diff --git a/lfr/netlistgenerator/constructiongraph/constructionnode.py b/lfr/netlistgenerator/constructiongraph/constructionnode.py
new file mode 100644
index 0000000..0ae37b2
--- /dev/null
+++ b/lfr/netlistgenerator/constructiongraph/constructionnode.py
@@ -0,0 +1,247 @@
+from __future__ import annotations
+
+from typing import List, Optional, Set
+
+import networkx as nx
+
+from lfr.netlistgenerator.connectingoption import ConnectingOption
+from lfr.netlistgenerator.mappingoption import MappingOption
+from lfr.netlistgenerator.primitive import Primitive
+from lfr.postprocessor.constraints import Constraint
+
+
+class ConstructionNode:
+ def __init__(
+ self,
+ node_id: str,
+ primitive: Optional[Primitive] = None,
+ subgraph_view: Optional[nx.DiGraph] = None,
+ ) -> None:
+ """Initializes the construction node
+
+ Args:
+ node_id (str): ID of the node
+ primitive (Optional[Primitive], optional): Primitve to map. Defaults to
+ None.
+ subgraph_view (Optional[nx.DiGraph], optional): subgraph view of the FIG.
+ Defaults to None.
+ """
+ self._id = node_id
+ self._explict_mapping_flag = False
+ self._fig_subgraph: Optional[nx.DiGraph] = subgraph_view
+ self._primitive: Optional[Primitive] = primitive
+
+ # Connection options that we want to load here
+ self._input_options: List[ConnectingOption] = []
+ self._output_options: List[ConnectingOption] = []
+ self._loading_options: List[ConnectingOption] = []
+ self._carrier_options: List[ConnectingOption] = []
+
+ # Mapping Constraints
+ # These will be all the imported constraints
+ self._constraints: List[Constraint] = []
+
+ # Load the connection options
+ if self.primitive is not None:
+ self._load_connection_options()
+
+ @property
+ def primitive(self) -> Primitive:
+ """Returns the primitive that is associated with this construction node
+
+ Returns:
+ Primitive: Primitive that is associated with this construction node
+ """
+ if self._primitive is None:
+ raise ValueError(f"Primitive not set for construction node {self.ID}")
+ return self._primitive
+
+ @primitive.setter
+ def primitive(self, primitive: Primitive) -> None:
+ """Sets the primitive for the construction node
+
+ Args:
+ primitive (Primitive): Primitive that needs to be set
+ """
+ self._primitive = primitive
+ self._load_connection_options()
+
+ @property
+ def fig_subgraph(self) -> nx.DiGraph:
+ """Returns the FIG subgraph of the node
+
+ Returns:
+ nx.Digraph: FIG subgraph of the node
+ """
+ if self._fig_subgraph is None:
+ raise Exception(f"FIG subgraph not set for construction node {sel}")
+ return self._fig_subgraph
+
+ @fig_subgraph.setter
+ def fig_subgraph(self, subgraph: nx.DiGraph) -> None:
+ """Sets the FIG subgraph view of the node
+
+ Args:
+ subgraph (nx.DiGraph): Subgraph view of the node
+ """
+ self._fig_subgraph = subgraph
+
+ @property
+ def is_explictly_mapped(self) -> bool:
+ """Checks if the node is explicitly mapped or not
+
+ Returns:
+ bool: True if the node is explicitly mapped, False otherwise
+ """
+ return self._explict_mapping_flag
+
+ @property
+ def constraints(self) -> List[Constraint]:
+ """Returns the constraints that are associated with this node
+
+ Returns:
+ List[Constraint]: List of constraints associated with this node
+ """
+ return self._constraints
+
+ @constraints.setter
+ def constraints(self, vals: List[Constraint]) -> None:
+ """Sets the constraints for the node
+
+ Args:
+ vals (List[Constraint]): List of constraints to set
+ """
+ self._constraints = vals
+
+ @property
+ def input_options(self) -> List[ConnectingOption]:
+ """Returns the input options of the construction node
+
+ Returns:
+ List[ConnectingOption]: List of input options
+ """
+ return self._input_options
+
+ @property
+ def output_options(self) -> List[ConnectingOption]:
+ """Returns the output options of the construction node
+
+ Returns:
+ List[ConnectingOption]: List of output options
+ """
+ return self._output_options
+
+ @property
+ def loading_options(self) -> List[ConnectingOption]:
+ """Returns the list of loading options for the mapption option candidate
+
+ Returns:
+ List[ConnectingOption]: List of loading options
+ """
+ return self._loading_options
+
+ @property
+ def carrier_options(self) -> List[ConnectingOption]:
+ """Returns the list of carrier options set for the construction node
+
+ Returns:
+ List[ConnectingOption]: List of carrier options
+ """
+ return self._carrier_options
+
+ @property
+ def ID(self) -> str:
+ """Returns the id of the construction node
+
+ Returns:
+ str: ID of the construction node
+ """
+ return self._id
+
+ @property
+ def fig_cover(self) -> Set[str]:
+ """Returns the cover of the figure subgraph
+
+ Returns:
+ Set[str]: Cover of the figure subgraph
+ """
+ return set(self.fig_subgraph.nodes)
+
+ def use_explicit_mapping(self, mapping: MappingOption) -> None:
+ """Uses the explicit mapping option passed as the parameter
+
+ Args:
+ mapping (MappingOption): MappingOption that needs to set
+ here explicitly
+ """
+ # Set the flag for explicit mapping
+ self._explict_mapping_flag = True
+ # Delete all the existing mapping options
+ self._primitive = mapping.primitive
+ # Now that we have overwritten all the netlist options here
+ # we basically cherry pick the one little bit that we want to attach here
+ self._load_connection_options()
+
+ def _load_connection_options(self) -> None:
+ """Loads the corresponding different connecting options into
+ the construction node
+ """
+ # Load the input options
+ if self.primitive is None:
+ raise ValueError(f"Primitive not set for construction node {self.ID}")
+
+ self._input_options = self.primitive.export_inputs(self.fig_subgraph)
+ self._output_options = self.primitive.export_outputs(self.fig_subgraph)
+
+ options = self.primitive.export_loadings(self.fig_subgraph)
+ if options is None:
+ options = []
+
+ self._loading_options = options
+
+ options = self.primitive.export_carriers(self.fig_subgraph)
+ if options is None:
+ options = []
+
+ self._carrier_options = options
+
+ def merge_construction_node(self, construction_node: ConstructionNode) -> None:
+ """Merges the construction node passed as an arugment into the this
+ construction node.
+
+ This will let us handle the scenario where we might want to merge
+ construction nodes that have undercoverage and help support the future
+ combinatorial generation options
+
+
+ Args:
+ construction_node (ConstructionNode): [description]
+ """
+ raise NotImplementedError(
+ "Implement this when we are trying to make combinatorial operations work"
+ )
+
+ def has_border_overlap(self, other_node: ConstructionNode) -> bool:
+ """Checks if the border of the current node overlaps with the border"""
+
+ # Step 1 - Get the intersection of the two covers, If the intersection is empty
+ # then we do not have a border overlap
+ # Step 2 - If any of thos are in the border of the subgraph (i.e. the incoming
+ # or outgoing edges are 0)
+ # then we have a border overlap
+
+ intersection_cover = self.fig_cover.intersection(other_node.fig_cover)
+ if len(intersection_cover) == 0:
+ return False
+ else:
+ # Check if any of the intersection cover is in the border of the subgraph
+ for node in intersection_cover:
+ if (
+ self.fig_subgraph.in_degree(node) == 0
+ or self.fig_subgraph.out_degree(node) == 0
+ ):
+ return True
+ return False
+
+ def __str__(self) -> str:
+ return f"Construction Node: {self.ID}"
diff --git a/lfr/netlistgenerator/constructiongraph/edge_generation.py b/lfr/netlistgenerator/constructiongraph/edge_generation.py
new file mode 100644
index 0000000..6ee1870
--- /dev/null
+++ b/lfr/netlistgenerator/constructiongraph/edge_generation.py
@@ -0,0 +1,285 @@
+from typing import List
+
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+from lfr.netlistgenerator.constructiongraph.constructiongraph import ConstructionGraph
+from lfr.netlistgenerator.constructiongraph.constructionnode import ConstructionNode
+
+# def _bridge_channel_networks(construction_graph: ConstructionGraph) -> None:
+# # TODO - Bridge the channel networks
+# # Find all the passthrough nodes in the fig
+# # Make a copy of the fig and eliminate all the fig nodes that are either not
+# # FLOW or are not covered by the construction nodes
+# copy_fig = self._fig.copy(as_view=False)
+# for cn in self._construction_nodes:
+# for fig_node in cn.fig_subgraph.nodes:
+# copy_fig.remove_node(fig_node.ID)
+# # Delete all the non-flow nodes
+# for node in copy_fig.nodes:
+# if isinstance(node, Flow) is not True and isinstance(node, Signal) is not True:
+# copy_fig.remove_node(node.ID)
+
+# # Get all the disconnected components in the fig
+# components = list(nx.connected_components(copy_fig))
+# # Check if each of the components are pass through or not
+# for component in components:
+# is_passthrough = self.__check_if_passthrough(component)
+# if is_passthrough is True:
+# # Generate an edge bewtween the passthrough nodes
+# self.__generate_edge_between_passthrough_nodes(component)
+
+
+# def generate_construction_edges(self) -> None:
+# """
+# This method generates the connections between the nodes in the graph.
+# """
+# # Step 1 - Generate a map where the key is a fig node and the value is a list of
+# # construction nodes that have a fig node in their fig_subgraph
+# fig_node_to_cn_map = self._generate_fignode_to_cn_map()
+
+# # Step 2 - Generate edges for between the construction node with the biggest
+# # fig_cover and the rest of the nodes
+# for fig_node in fig_node_to_cn_map:
+# cn_list = fig_node_to_cn_map[fig_node]
+# # Get the construction node with the biggest fig_cover
+# cn_with_biggest_fig_cover = max(cn_list, key=lambda x: len(x.fig_cover))
+# # Get the rest of the construction nodes
+# cn_list.remove(cn_with_biggest_fig_cover)
+# # Generate edges between the construction nodes
+# for cn in cn_list:
+# self.add_edge(cn_with_biggest_fig_cover.ID, cn.ID)
+
+# # Step 3 - Generate edges between the construction nodes that have fig nodes
+# # that are neighbors of each other
+# # Utilize the networkx.Graph.neighbors method to get the neighbors of each fig
+# # node in the fignode map
+# for fig_node in fig_node_to_cn_map:
+# fig_node_neighbors = self._fig.neighbors(fig_node)
+# for fig_node_neighbor in fig_node_neighbors:
+# # Get the construction nodes that have the neighbor fig node
+# cn_list = fig_node_to_cn_map[fig_node_neighbor]
+# # Get the construction nodes that have the original fig node
+# cn_list_with_fig_node = fig_node_to_cn_map[fig_node]
+# # Generate edges between the construction nodes
+# for cn in cn_list_with_fig_node:
+# for cn_neighbor in cn_list:
+# self.add_edge(cn.ID, cn_neighbor.ID)
+
+# def _generate_fignode_to_cn_map(self):
+# fig_node_to_cn_map = {}
+# for cn in self._construction_nodes:
+# for fig_node in cn.fig_subgraph.nodes:
+# if fig_node.ID not in fig_node_to_cn_map:
+# fig_node_to_cn_map[fig_node.ID] = []
+# fig_node_to_cn_map[fig_node.ID].append(cn)
+# return fig_node_to_cn_map
+
+
+# def __generate_edge_between_passthrough_nodes(
+# construction_graph: ConstructionGraph,
+# sub,
+# ) -> None:
+# # Get the fig node to cn map
+# fig_node_to_cn_map = construction_graph: ConstructionGraph._generate_fignode_to_cn_map()
+# # Generate a pass through construciton node
+# # If it getting till here we know for a fact that the subgraph is a passthrough
+# # and has 1 input and 1 output node
+# # Get the in node and the out node
+# in_node = None
+# out_node = None
+# for node in list(sub.nodes):
+# if sub.in_degree(node) == 0:
+# in_node = node
+# if sub.out_degree(node) == 0:
+# out_node = node
+
+# # Find the neighbooring fig nodes
+# if in_node is None or out_node is None:
+# raise ValueError(
+# "In and out nodes are not found, cannot apply passthrough connection in"
+# " construction graph, check passthrough candidate identification logic"
+# )
+# in_neighbors = list(sub.neighbors(in_node))
+# out_neighbors = list(sub.neighbors(out_node))
+# # Find the corresponding construction nodes
+# in_cn_list = fig_node_to_cn_map[in_neighbors[0].ID]
+# out_cn_list = fig_node_to_cn_map[out_neighbors[0].ID]
+# # If construction nodes are the same, throw and error since we can cant have
+# # passthrough if its looping around
+# for in_cn in in_cn_list:
+# if in_cn in out_cn_list:
+# raise ValueError(
+# "Encountered situation where in_cn is also out_cn, cannot have construction_graph: ConstructionGraph"
+# " loops"
+# )
+# # Now for each of the cases 1->1 , 1->n, n->1, n->n, n->m cases generate
+# # connections
+# if len(in_cn_list) == 1 and len(out_cn_list) == 1:
+# # 1->1
+# self.add_edge(in_cn_list[0], out_cn_list[0])
+# elif len(in_cn_list) == 1 and len(out_cn_list) > 1:
+# # 1->n
+# for out_cn in out_cn_list:
+# self.add_edge(in_cn_list[0], out_cn)
+# elif len(in_cn_list) > 1 and len(out_cn_list) == 1:
+# # n->1
+# for in_cn in in_cn_list:
+# self.add_edge(in_cn, out_cn_list[0])
+# elif len(in_cn_list) > 1 and len(out_cn_list) == len(in_cn_list):
+# # n->n
+# for in_cn, out_cn in zip(in_cn_list, out_cn_list):
+# self.add_edge(in_cn, out_cn)
+# elif (
+# len(in_cn_list) > 1
+# and len(out_cn_list) > 1
+# and len(in_cn_list) != len(out_cn_list)
+# ):
+# # n->m
+# for in_cn in in_cn_list:
+# for out_cn in out_cn_list:
+# self.add_edge(in_cn, out_cn)
+
+# raise NotImplementedError()
+
+
+# def generate_construction_graph_edges(construction_graph: ConstructionGraph) -> None:
+# """
+# This method generates the connections between the nodes in the graph.
+# """
+# # Check if the FIG cover of neighboring construction nodes
+# # and generate connection candidates
+# self._bridge_channel_networks()
+# # Step 1 - Generate a map where the key is a fig node and the value is a list of
+# # construction nodes that have a fig node in their fig_subgraph
+# fig_node_to_cn_map = self._generate_fignode_to_cn_map()
+# # Step 2 - Generate edges for between the construction node with the biggest
+# # fig_cover and the rest of the nodes
+# for fig_node in fig_node_to_cn_map:
+# cn_list = fig_node_to_cn_map[fig_node]
+# # Get the construction node with the biggest fig_cover
+# cn_with_biggest_fig_cover = max(cn_list, key=lambda x: len(x.fig_cover))
+# # Get the rest of the construction nodes
+# cn_list.remove(cn_with_biggest_fig_cover)
+# # Generate edges between the construction nodes
+# for cn in cn_list:
+# self.add_edge(cn_with_biggest_fig_cover.ID, cn.ID)
+
+# # Step 3 - Generate edges between the construction nodes that have fig nodes
+# # that are neighbors of each other
+# # Utilize the networkx.Graph.neighbors method to get the neighbors of each fig
+# # node in the fignode map
+# for fig_node in fig_node_to_cn_map:
+# fig_node_neighbors = self._fig.neighbors(fig_node)
+# for fig_node_neighbor in fig_node_neighbors:
+# # Get the construction nodes that have the neighbor fig node
+# cn_list = fig_node_to_cn_map[fig_node_neighbor]
+# # Get the construction nodes that have the original fig node
+# cn_list_with_fig_node = fig_node_to_cn_map[fig_node]
+# # Generate edges between the construction nodes
+# for cn in cn_list_with_fig_node:
+# for cn_neighbor in cn_list:
+# self.add_edge(cn.ID, cn_neighbor.ID)
+
+
+# def _generate_fignode_to_cn_map(construction_graph: ConstructionGraph):
+# fig_node_to_cn_map = {}
+# for cn in construction_graph.construction_nodes:
+# for fig_node in cn.fig_subgraph.nodes:
+# if fig_node.ID not in fig_node_to_cn_map:
+# fig_node_to_cn_map[fig_node.ID] = []
+# fig_node_to_cn_map[fig_node.ID].append(cn)
+# return fig_node_to_cn_map
+
+
+def check_overlap_criteria_1(
+ construction_node_a: ConstructionNode, construction_node_b: ConstructionNode
+) -> bool:
+ """
+ This method checks if the two construction nodes overlap in the following
+ criteria:
+ 1. if the the two nodes have any common fig nodes
+ 2. if the overlapping fig nodes are border nodes
+ """
+ cover_a = set(construction_node_a.fig_subgraph.nodes)
+ cover_b = set(construction_node_b.fig_subgraph.nodes)
+ overlap_nodes_set = cover_a.intersection(cover_b)
+
+ # TODO - Figure if we need to check if the overlapping nodes are border nodes
+ return len(overlap_nodes_set) > 0
+
+
+def check_adjecent_criteria_1(
+ construction_node_a: ConstructionNode,
+ construction_node_b: ConstructionNode,
+ fig: FluidInteractionGraph,
+) -> bool:
+ """
+ This method checks if the two construction nodes are adjacent in the following
+ criteria:
+
+ Args:
+ construction_node_a (ConstructionNode): The first construction node
+ construction_node_b (ConstructionNode): The second construction node
+
+ Returns:
+ bool: True if the two nodes are adjacent, False otherwise
+ """
+ cover_a = set(construction_node_a.fig_subgraph.nodes)
+ cover_b = set(construction_node_b.fig_subgraph.nodes)
+ for fig_node_a in cover_a:
+ for fig_node_b in cover_b:
+ if fig_node_b in fig.neighbors(fig_node_a):
+ return True
+
+ return False
+
+
+def generate_construction_graph_edges(
+ fig: FluidInteractionGraph, construction_graph: ConstructionGraph
+) -> None:
+ # The construction nodes that have overlaps (border nodes) with each other or are
+ # neighbors and make the connection between them.
+
+ # Go through all the construction nodes
+ cn_nodes = list(construction_graph.nodes)
+ for i in range(len(cn_nodes)):
+ for j in range(len(cn_nodes)):
+ if i == j:
+ continue
+ source_node_id = cn_nodes[i]
+ source_cn_node = construction_graph.get_construction_node(source_node_id)
+
+ target_node_id = cn_nodes[j]
+ target_cn_node = construction_graph.get_construction_node(target_node_id)
+
+ # Check if they overlap
+ is_overlapped = check_overlap_criteria_1(source_cn_node, target_cn_node)
+
+ if is_overlapped:
+ # Check if the two nodes are already connected
+ if construction_graph.has_edge(
+ source_node_id, target_node_id
+ ) or construction_graph.has_edge(target_node_id, source_node_id):
+ print(
+ f"Nodes {source_node_id}, {target_node_id} has edge, skipping"
+ " adding edge"
+ )
+ continue
+
+ construction_graph.connect_nodes(source_cn_node, target_cn_node)
+ continue
+
+ # Check if they are neighbors
+ is_neighbor = check_adjecent_criteria_1(source_cn_node, target_cn_node, fig)
+
+ if is_neighbor:
+ if construction_graph.has_edge(
+ source_node_id, target_node_id
+ ) or construction_graph.has_edge(target_node_id, source_node_id):
+ print(
+ f"Nodes {source_node_id}, {target_node_id} has edge, skipping"
+ " adding edge"
+ )
+ continue
+
+ construction_graph.connect_nodes(source_cn_node, target_cn_node)
+ continue
diff --git a/lfr/netlistgenerator/constructiongraph/variant_criteria.py b/lfr/netlistgenerator/constructiongraph/variant_criteria.py
new file mode 100644
index 0000000..a3efd27
--- /dev/null
+++ b/lfr/netlistgenerator/constructiongraph/variant_criteria.py
@@ -0,0 +1,25 @@
+from enum import Enum
+from typing import Tuple
+
+from lfr.netlistgenerator.constructiongraph.constructiongraph import ConstructionGraph
+from lfr.netlistgenerator.constructiongraph.constructionnode import ConstructionNode
+
+
+class VariantType(Enum):
+ SUBSTITUTION = 1
+ ADDITION = 2
+
+
+def check_variant_criteria(
+ variant: ConstructionGraph, node: ConstructionNode
+) -> VariantType:
+ # Check if the node's fig mapping overlaps with the fig cover of the
+ # existing construction nodes according to the axioms definined. If it does
+ # return ADDITION, else return SUBSTITUTION.
+ for cn in variant._construction_nodes:
+ if cn.fig_cover == node.fig_cover:
+ return VariantType.SUBSTITUTION
+ elif node.has_border_overlap(cn):
+ return VariantType.ADDITION
+ else:
+ return VariantType.ADDITION
diff --git a/lfr/netlistgenerator/constructiongraph/variant_generator.py b/lfr/netlistgenerator/constructiongraph/variant_generator.py
new file mode 100644
index 0000000..5a64f05
--- /dev/null
+++ b/lfr/netlistgenerator/constructiongraph/variant_generator.py
@@ -0,0 +1,225 @@
+from typing import Dict, FrozenSet, List, Optional, Set, Tuple
+
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+from lfr.netlistgenerator import LibraryPrimitivesEntry
+from lfr.netlistgenerator.constructiongraph.constructiongraph import ConstructionGraph
+from lfr.netlistgenerator.constructiongraph.constructionnode import ConstructionNode
+from lfr.netlistgenerator.constructiongraph.variant_criteria import (
+ VariantType,
+ check_variant_criteria,
+)
+from lfr.netlistgenerator.constructiongraph.varianttree import VariantTree
+from lfr.netlistgenerator.gen_strategies.genstrategy import GenStrategy
+from lfr.netlistgenerator.mappinglibrary import MappingLibrary, MatchPatternEntry
+from lfr.netlistgenerator.namegenerator import NameGenerator
+from lfr.postprocessor.mapping import NodeMappingTemplate
+
+
+def generate_match_variants(
+ matches: List[LibraryPrimitivesEntry],
+ fig: FluidInteractionGraph,
+ library: MappingLibrary,
+ active_strategy: GenStrategy,
+ explicit_mapping_covers: Optional[List[Set[str]]] = None,
+) -> List[ConstructionGraph]:
+ """
+ Generate all possible match variants of a given graph.
+
+ Args:
+ fig: The graph to generate match variants for.
+
+ Returns:
+ A tree view of the matches
+ """
+
+ def find_index_of_match_entry(
+ fig_cover_set: Set[str],
+ matches: List[LibraryPrimitivesEntry],
+ ) -> int:
+ """Find the index of a match entry in a list of matches."""
+ for index, entry in enumerate(matches):
+ if fig_cover_set == set(list(entry[2].keys())):
+ return index
+ raise KeyError("Could not find the index of the match entry")
+
+ def move_entry_to_front(
+ entries_list: List[LibraryPrimitivesEntry],
+ index: int,
+ ) -> None:
+ """Move an entry to the front of a list."""
+ entries_list.insert(0, entries_list.pop(index))
+
+ def generate_match_subgraph(match: LibraryPrimitivesEntry):
+ """Generate a fig subgraph view of a match."""
+ nodes_list = list(match[2].keys())
+ return fig.subgraph(nodes_list)
+
+ def create_variant(
+ node: ConstructionNode,
+ variant: ConstructionGraph,
+ fig_node_cover: FrozenSet[str],
+ ):
+ print(f"Generating new variant for substitution {node.ID}")
+ new_variant = variant.generate_variant(f"variant_{variant_index}")
+
+ # TODO - Substitute the node with the new node
+ new_variant.remove_node_for_exact_fig_cover(fig_node_cover)
+ new_variant.add_construction_node(node)
+ # Creates a new variant branch and add it to the variant tree
+ print(f"Adding node {node.ID} to variant {variant.ID}")
+
+ variant_tree.add_variant(variant, new_variant)
+
+ variant_tree: VariantTree[ConstructionGraph] = VariantTree[ConstructionGraph]()
+ cn_name_generator = NameGenerator()
+ # sort the matches based on the size of the dict keys
+ matches.sort(key=lambda x: len(x[1]))
+
+ # Step 1 - First group all the matches with the same node mapping
+ # Step 2 - Sort earch group by the size of the dict keys (i.e. the number of nodes)
+ # Step 3 - Start with the smallest and find all the non overlapping matches sets.
+ # This, allows us to reduce the number of variants generated.
+ # there.
+ # Step 4 - We create a Variant Tree for each of the non overlapping match sets.
+ # We can use a greedy set packing problem to solve this.
+ # Step 5 - We create a Variant Tree for each of the non overlapping match sets.
+
+ # TODO - take all the matches and start creating construction graphs and variants
+ # Loop trhough each of the matches
+ variant_index = 0
+
+ # Create the first variant here
+ seed_variant = ConstructionGraph(f"variant_{variant_index}", fig)
+ variant_tree.add_variant(seed_variant, None)
+
+ # Find the set of matches that are non overlapping using a greedy cover algorithm
+ subsets = []
+ universe = set()
+
+ for match in matches:
+ nodes_set = set(list(match[2].keys()))
+ if nodes_set not in subsets:
+ subsets.append(nodes_set)
+ universe.union(nodes_set)
+
+ # Group all the matches based on the node mappings
+
+ # Order all the matches based on:
+ # 1. Explicit Matches
+ # 2. Set Cover Matches
+ # 3. Smallest Cover Matches
+ cover = generate_set_cover(universe, subsets)
+ print("Moving Max Set Cover to the front:", cover)
+ for cover_set_entry in cover:
+ move_entry_to_front(
+ matches, find_index_of_match_entry(cover_set_entry, matches)
+ )
+
+ if explicit_mapping_covers is not None:
+ # Moving all the explicit matches to the front
+ print("Moving Explicit Matches to the front:", explicit_mapping_covers)
+ for explicit_mapping_cover in explicit_mapping_covers:
+ move_entry_to_front(
+ matches, find_index_of_match_entry(explicit_mapping_cover, matches)
+ )
+
+ # Loop through every match
+ for match in matches:
+ print("Checking Match:", match)
+ # For each match, create a construction node
+ primitive_uid = match[0]
+ primitive_technology = match[1]
+ node = ConstructionNode(
+ cn_name_generator.generate_name(f"cn_{primitive_technology}"),
+ library.get_primitive(primitive_uid),
+ generate_match_subgraph(match),
+ )
+
+ fig_nodes_set = frozenset(list(match[2].keys()))
+
+ # Check if Variant Tree has a saved divergence for this node, we do a new
+ # divergence branch and create a new variant.
+ divergence_node_payload = variant_tree.get_divergence(fig_nodes_set)
+ if divergence_node_payload is not None:
+ # Create the new variant and continue with the next match
+ variant_index += 1
+ create_variant(node, divergence_node_payload, fig_nodes_set)
+ continue
+
+ # Check if the construction node satisfies the variant criteria for each of the
+ # variants
+ for variant in variant_tree.walk_tree():
+ variant_type = check_variant_criteria(variant, node)
+
+ # VARIANT_TYPE.SUBSTITUTION
+ if variant_type is VariantType.ADDITION:
+ # Just add the node to the variant
+ print(f"Adding node {node.ID} to variant {variant.ID}")
+ variant.add_construction_node(node)
+ elif variant_type is VariantType.SUBSTITUTION:
+ # Create a new variant and add the node to it
+ variant_index += 1
+ create_variant(node, variant, fig_nodes_set)
+ # Save Divergence in the Variant Tree for the corresponding delta
+ variant_tree.save_divergence(fig_nodes_set, variant)
+ else:
+ raise ValueError(f"Unknown variant type {variant_type}")
+
+ # Next steps:
+ # 1. Find ways to map the flow elements to the construction nodes
+ # 2. Do the pruning of the variant tree utilizing the active strategy
+ # 3. Eliminate all the undercovered variants
+
+ # Print out all the nodes in each of the variants
+ ret = variant_tree.walk_tree()
+ for variant in ret:
+ print(f"Variant {variant.ID}:")
+ for node in variant.nodes:
+ print(node)
+ return ret
+
+
+def generate_set_cover(universe: Set[str], subsets: List[Set[str]]) -> List[Set[str]]:
+ """Find a family of subsets that covers the universal set
+
+ Code replicated from:
+ http://www.martinbroadhurst.com/greedy-set-cover-in-python.html
+ """
+ elements = set(e for s in subsets for e in s)
+ # Check the subsets cover the universe
+ # if elements != universe:
+ # return None
+ covered = set()
+ cover = []
+ # Greedily add the subsets with the most uncovered points
+ while covered != elements:
+ subset = max(subsets, key=lambda s: len(s - covered))
+ cover.append(subset)
+ covered |= subset
+
+ return cover
+
+
+# def add_construction_node(
+# self, construction_node: ConstructionNode, variant_type: VariantType
+# ) -> None:
+
+# # TODO - Just add the construction node into the graph
+# if variant_type == VariantType.SUBSTITUTION:
+# # Remove the existing construction node that has an intersecting fig cover
+# # with the new construction node
+# for cn in self._construction_nodes:
+# if cn.fig_cover.intersection(construction_node.fig_cover):
+# self.remove_construction_node(cn)
+# break
+# else:
+# raise ValueError(
+# "No construction node found with an intersecting fig cover"
+# )
+# self._construction_nodes.append(construction_node)
+# self.add_node(construction_node.ID)
+# elif variant_type == VariantType.ADDITION:
+# self._construction_nodes.append(construction_node)
+# self.add_node(construction_node.ID)
+# else:
+# raise ValueError("Invalid variant type")
diff --git a/lfr/netlistgenerator/constructiongraph/varianttree.py b/lfr/netlistgenerator/constructiongraph/varianttree.py
new file mode 100644
index 0000000..7709c5e
--- /dev/null
+++ b/lfr/netlistgenerator/constructiongraph/varianttree.py
@@ -0,0 +1,236 @@
+from __future__ import annotations
+
+from typing import Dict, Generic, List, Optional, TypeVar
+
+T = TypeVar("T")
+
+
+class VariantNode(Generic[T]):
+ """Variant Node Describes the node in the variant tree
+
+ Its payload is a ConstructionGraph object and it contains the links to the parent
+ and children
+ """
+
+ def __init__(self, variant: T) -> None:
+ self._payload: T = variant
+ self._parent: Optional[VariantNode] = None
+ self._children: List[VariantNode] = []
+
+ @property
+ def payload(self) -> T:
+ return self._payload
+
+ @property
+ def children(self) -> List[VariantNode]:
+ return self._children
+
+ @property
+ def parent(self) -> Optional[VariantNode]:
+ return self._parent
+
+ @parent.setter
+ def parent(self, parent: VariantNode) -> None:
+ self._parent = parent
+
+ def add_child(self, child: VariantNode) -> None:
+ self._children.append(child)
+ child._parent = self
+
+ def __eq__(self, __o: object) -> bool:
+ if isinstance(__o, VariantNode):
+ # Check if the payloads are equal
+ return self._payload == __o._payload
+ else:
+ return False
+
+
+class VariantTree(Generic[T]):
+ def __init__(
+ self,
+ ) -> None:
+ self._root: Optional[VariantNode] = None
+ self._node_walk: Optional[VariantNode] = None
+ self._divergence_map: Dict[object, VariantNode] = {}
+
+ def add_variant(
+ self,
+ variant_parent: T,
+ variant_decendant: Optional[T],
+ ) -> None:
+ """Adds a new variant to the tree
+
+ When adding the root node, the variant_leaf is set to None
+
+ Args:
+ variant_parent (ConstructionGraph): The parent variant to which we say that,
+ when the variant tree is empty, this is the root.
+ variant_decendant (Optional[ConstructionGraph]): The new variant to add to
+ the tree, its set to None when adding the root.
+
+ Raises:
+ ValueError: The variant_parent is not in the tree, or the variant_decendant
+ is set to None when we are not setting the root
+ """
+ if self._root is None:
+ root = VariantNode(variant_parent)
+ self._root = root
+
+ if variant_decendant is not None:
+ leaf = VariantNode(variant_decendant)
+ leaf.parent = root
+ self._root.add_child(leaf)
+
+ else:
+ # Cancel if only the variant root is provided
+ if variant_decendant is None:
+ raise ValueError("variant_decendant is None")
+
+ # Find the parent of the variant and add the variant as the child
+ parent = self._find_node(variant_parent)
+ if parent is None:
+ raise ValueError(f"Could not find parent of variant {variant_parent}")
+
+ leaf = VariantNode(variant_decendant)
+ leaf.parent = parent
+ parent.add_child(leaf)
+
+ def _find_node(self, variant: T) -> Optional[VariantNode]:
+ """Find the node in the tree that matches the variant"""
+ if self._root is None:
+ return None
+
+ # Perform recursive search to identify the variant provided
+ # If the variant is found, return the node
+ # If the variant is not found, return None
+
+ def _find_node_recursive(
+ node: VariantNode, variant: T
+ ) -> Optional[VariantNode]:
+ if node.payload == variant:
+ return node
+
+ for child in node.children:
+ result = _find_node_recursive(child, variant)
+ if result is not None:
+ return result
+
+ return None
+
+ return _find_node_recursive(self._root, variant)
+
+ def prune_variant(self, variant: T) -> None:
+ """Prune the variant tree to remove any variants that do not fully cover the
+ fig"""
+
+ def _prune_variant_recursive(node: VariantNode, variant: T) -> None:
+ if node.payload == variant:
+ # If the variant is found, remove the node from the tree
+ if node.parent is not None:
+ node.parent.children.remove(node)
+ return
+
+ for child in node.children:
+ _prune_variant_recursive(child, variant)
+
+ if self._root is not None:
+ # Check the trivial case if the root is the variant
+ if self._root.payload == variant:
+ self._root = None
+ return
+
+ _prune_variant_recursive(self._root, variant)
+
+ def get_edge_leaves(self) -> List[T]:
+ """Return all the ConstructionGraphs in the leaves of the variant tree"""
+ leaves: List[T] = []
+
+ def _edge_leaves_recursive(node: VariantNode) -> None:
+ if len(node.children) == 0:
+ leaves.append(node.payload)
+ return
+
+ for child in node.children:
+ _edge_leaves_recursive(child)
+
+ if self._root is not None:
+ _edge_leaves_recursive(self._root)
+
+ return leaves
+
+ def walk_tree(self) -> List[T]:
+ """Return an iterator that walks the variant tree
+
+ Raises:
+ ValueError: If the root is not set
+
+ Returns:
+ List[ConstructionGraph]: List of ConstructionGraphs that are in the variant
+ """ """"""
+
+ def _walker_recursive(level_nodes: List[VariantNode], output: List[T]) -> None:
+ next_level_nodes: List[VariantNode] = []
+ for level_node in level_nodes:
+ for child in level_node.children:
+ next_level_nodes.append(child)
+ output.append(child.payload)
+
+ for level_node in level_nodes:
+ _walker_recursive(next_level_nodes, output)
+
+ if self._root is None:
+ raise ValueError("Variant tree root is empty")
+
+ node_walk: List[T] = [self._root.payload]
+ _walker_recursive([self._root], node_walk)
+ return node_walk
+
+ def has_divergence(self, divergence: object) -> bool:
+ """Check if the variant has divergence
+
+ Args:
+ divergence (object): divergence object that needs to be checked
+
+ Returns:
+ bool: True if the divergence is found, False otherwise
+ """
+ if divergence in self._divergence_map:
+ return True
+ else:
+ return False
+
+ def save_divergence(self, divergence: object, variant: T) -> None:
+ """Save the divergence of the variant to the variant tree
+
+ Args:
+ divergence (str): The delta that is being saved as the cause of the
+ divergence
+ variant (T): the payload corresponding to the divergence
+
+ Raises:
+ ValueError: If the payload cannot be found in the tree
+ ValueError: If the divergence is already saved
+ """
+ node = self._find_node(variant)
+ if node is None:
+ raise ValueError(f"Could not find variant {variant}")
+
+ if divergence in self._divergence_map:
+ raise ValueError(f"Divergence {divergence} already exists")
+
+ self._divergence_map[divergence] = node
+
+ def get_divergence(self, divergence: object) -> Optional[T]:
+ """Get the payload corresponding to the divergence
+
+ Args:
+ divergence (object): object indicating the divergence
+
+ Returns:
+ Optional[T]: the payload corresponding to the divergence
+ """
+
+ if divergence in self._divergence_map:
+ return self._divergence_map[divergence].payload
+ else:
+ return None
diff --git a/lfr/netlistgenerator/dafdadapter.py b/lfr/netlistgenerator/dafdadapter.py
index 0a6115a..dbef1d3 100644
--- a/lfr/netlistgenerator/dafdadapter.py
+++ b/lfr/netlistgenerator/dafdadapter.py
@@ -1,35 +1,49 @@
-from typing import List, Optional
+from typing import Dict, List
-from dafd import DAFD_Interface
-from pymint.mintcomponent import MINTComponent
+from parchmint import Component
from pymint.mintdevice import MINTDevice
+from lfr.postprocessor.constraints import Constraint
-class DAFDSizingAdapter:
+
+class DAFDAdapter:
def __init__(self, device: MINTDevice) -> None:
- self.__device = device
- self.solver = DAFD_Interface()
+ super().__init__()
+ self._device = device
+
+ def size_droplet_generator(
+ self, component: Component, constriants: List[Constraint]
+ ) -> None:
+ import faulthandler
+
+ faulthandler.enable()
+
+ from dafd import DAFD_Interface
- def size_droplet_generator(self, constriants: ConstraintList) -> None:
+ self.solver = DAFD_Interface()
# TODO: Check the type of the component and pull info from DAFD Interface
targets_dict = {}
- constriants_dict = {}
+ constriants_dict: Dict[str, Constraint] = {}
for constraint in constriants:
- if isinstance(constraint, FunctionalConstraint):
- if constraint.key == "volume":
- # r≈0.62035V1/3
- volume = constraint.get_target_value()
- targets_dict["droplet_size"] = float(volume) ** 0.33 * 0.62035 * 2
- elif isinstance(constraint, PerformanceConstraint):
- if constraint.key == "generation_rate":
- generate_rate = constraint.get_target_value()
- targets_dict["generation_rate"] = generate_rate
- elif isinstance(constraint, GeometryConstraint):
+ if constraint.key == "volume":
+ # r≈0.62035V1/3
+ volume = constraint.get_target_value()
+ if volume is None:
+ raise ValueError(
+ "Could not retrieve target value from constraint : volume for"
+ f" component:{component.ID}"
+ )
+ targets_dict["droplet_size"] = volume**0.33 * 0.62035 * 2
+ elif constraint.key == "generation_rate":
+ generate_rate = constraint.get_target_value()
+ targets_dict["generation_rate"] = generate_rate
+ else:
raise Exception("Error: Geometry constraint not defined")
- results = self.solver.runInterp(targets_dict, constriants_dict)
- component = constriants.component
+ results = self.solver.runInterp(
+ targets_dict, constriants_dict, tolerance_test=True
+ )
if component is None:
raise Exception("No component attached to the constraints")
@@ -55,12 +69,3 @@ def size_droplet_generator(self, constriants: ConstraintList) -> None:
component.params.set_param("outputWidth", round(orifice_size * expansion_ratio))
component.params.set_param("outputLength", 5000)
component.params.set_param("height", round(orifice_size / aspect_ratio))
-
- # TODO: Figure out how to propagate the results to the rest of the design. Additionally we need to set all the operation considtions
- pass
-
- def size_component(self, constriants: ConstraintList) -> None:
- if constriants.component.entity == "NOZZLE DROPLET GENERATOR":
- self.size_droplet_generator(constriants)
- else:
- print("Error: {} is not supported".format(constriants.component.entity))
diff --git a/lfr/netlistgenerator/explicitmapping.py b/lfr/netlistgenerator/explicitmapping.py
index 25d0caf..fb25d5a 100644
--- a/lfr/netlistgenerator/explicitmapping.py
+++ b/lfr/netlistgenerator/explicitmapping.py
@@ -6,9 +6,15 @@ class ExplicitMappingType(Enum):
FLUID_INTERACTION = 0
STORAGE = 1
NETWORK = 2
+ PUMP = 3
class ExplicitMapping:
+ """Explicit Mapping
+
+ This is the main class that is used to map micorfluidic technologies to a fluid interaction graph.
+ """
+
def __init__(
self, mapping_type: ExplicitMappingType = ExplicitMappingType.FLUID_INTERACTION
):
@@ -39,4 +45,4 @@ def map(self, netlist, fig):
# start and end and remove the correspoinding connections.
# TODO: In scenarios where there are inbetween nodes, we probably need to be more careful and
# this might not be the right place to do that kind of mapping
- pass
+ raise NotImplementedError()
diff --git a/lfr/netlistgenerator/v2/explicitmappingoption.py b/lfr/netlistgenerator/explicitmappingoption.py
similarity index 85%
rename from lfr/netlistgenerator/v2/explicitmappingoption.py
rename to lfr/netlistgenerator/explicitmappingoption.py
index 295272e..6e7e02b 100644
--- a/lfr/netlistgenerator/v2/explicitmappingoption.py
+++ b/lfr/netlistgenerator/explicitmappingoption.py
@@ -1,7 +1,7 @@
from typing import List
-from lfr.netlistgenerator.v2.mappingoption import MappingOption
-from lfr.netlistgenerator.v2.networkmappingoption import NetworkMappingOption
+from lfr.netlistgenerator.mappingoption import MappingOption
+from lfr.netlistgenerator.networkmappingoption import NetworkMappingOption
from lfr.postprocessor.constraints import Constraint
diff --git a/lfr/netlistgenerator/flownetworkmatching.py b/lfr/netlistgenerator/flownetworkmatching.py
new file mode 100644
index 0000000..bd1c268
--- /dev/null
+++ b/lfr/netlistgenerator/flownetworkmatching.py
@@ -0,0 +1,89 @@
+from typing import List
+
+import networkx as nx
+
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+from lfr.netlistgenerator.constructiongraph.constructiongraph import ConstructionGraph
+from lfr.netlistgenerator.constructiongraph.constructionnode import ConstructionNode
+from lfr.netlistgenerator.gen_strategies.genstrategy import GenStrategy
+from lfr.netlistgenerator.networkmappingoption import (
+ NetworkMappingOption,
+ NetworkMappingOptionType,
+)
+from lfr.netlistgenerator.primitive import NetworkPrimitive
+
+
+def add_flow_flow_matching_candidates(
+ fig: FluidInteractionGraph,
+ variants: List[ConstructionGraph],
+ gen_strategy: GenStrategy,
+) -> None:
+ flow_cns = get_flow_flow_candidates(fig, gen_strategy)
+ print("Found New Flow-Flow match nodes:", flow_cns)
+ add_flow_flow_candadates_to_variants(variants, flow_cns)
+ print("New variant Mappings:", [str(v) for v in variants])
+
+
+def add_flow_flow_candadates_to_variants(
+ variants: List[ConstructionGraph], flow_cns: List[ConstructionNode]
+) -> None:
+ # TODO: Map the flow flow candidates to the variants
+ # raise NotImplementedError("Need to implement this")
+ print(
+ "Warning: FLow Flow Mapping to variants not implemented yet since it might"
+ " generate network primitives"
+ )
+ pass
+
+
+def get_flow_flow_candidates(
+ fig: FluidInteractionGraph, gen_strategy: GenStrategy
+) -> List[ConstructionNode]:
+ # TODO - go through all the edges and see which ones are between flow-flow graphs
+ # If these connectsions are between flow-flow nodes then we need to figure out
+ # which ones are part of the same network/connected graphs with only flow nodes
+ # The networks with only the flow nodes will need to be covered as a part of.
+ # these construction nodes.
+
+ ret = []
+
+ # Step 1. Do a shallow copy of the graph
+ # Step 2. Remove all the fignodes that are not Flow
+ # Step 3. Now get the all the disconnected pieces of the graph
+ # Step 4. Create a Construction node for each of the disconnected pieces
+ # Return all the constructions nodes
+
+ # Step 1. Do a shallow copy of the graph
+ fig_original = fig
+ fig_copy = fig.copy(
+ as_view=False
+ ) # Note this does not copy anything besides the nx.DiGraph at the moment
+
+ # Step 2. Remove all the fignodes that are not Flow
+ remove_list = []
+ for node_id in fig_copy.nodes:
+ node = fig_original.get_fignode(node_id)
+ if node.match_string != "FLOW":
+ remove_list.append(node_id)
+
+ for node_id in remove_list:
+ fig_copy.remove_node(node_id)
+
+ # Step 3. Now get the all the disconnected pieces of the graph
+ i = 0
+ for component in nx.connected_components(fig_copy.to_undirected()):
+ print("Flow candidate", component)
+ sub = fig_original.subgraph(component)
+ # TODO - Decide what the mapping type should be. for now assume that we just a single
+ # passthrough type scenario where we don't have to do much work
+ nprimitive = NetworkPrimitive(sub, gen_strategy)
+ nprimitive.generate_netlist()
+ # mapping_option = NetworkMappingOption(nprimitive, mapping_type, sub)
+ # Step 4. Create a Construction node for each of the disconnected pieces
+ # TODO - Check and see what happens here
+ cn = ConstructionNode("flow_network_{}".format(i), nprimitive, sub)
+
+ i += 1
+ ret.append(cn)
+
+ return ret
diff --git a/lfr/netlistgenerator/gen_strategies/dropxstrategy.py b/lfr/netlistgenerator/gen_strategies/dropxstrategy.py
new file mode 100644
index 0000000..9596709
--- /dev/null
+++ b/lfr/netlistgenerator/gen_strategies/dropxstrategy.py
@@ -0,0 +1,146 @@
+# from lfr.netlistgenerator.constructiongraph import ConstructionGraph
+from typing import List
+
+import networkx as nx
+from pymint import MINTDevice
+
+from lfr.fig.fignode import FIGNode
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+from lfr.fig.interaction import Interaction, InteractionType
+from lfr.netlistgenerator.constructiongraph.constructiongraph import ConstructionGraph
+from lfr.netlistgenerator.constructiongraph.constructionnode import ConstructionNode
+from lfr.netlistgenerator.dafdadapter import DAFDAdapter
+from lfr.netlistgenerator.gen_strategies.genstrategy import GenStrategy
+
+
+class DropXStrategy(GenStrategy):
+ def __init__(self, fig: FluidInteractionGraph) -> None:
+ super().__init__("dropx", fig)
+
+ def validate_construction_graph_flow(
+ self, construction_graph: ConstructionGraph
+ ) -> bool:
+ """
+ Validate the construction graph against the rules of the dropx
+ generation strategy strategy
+
+ TODO - Future version of this should use a rule based grammar
+
+ Current ruleset for the dropx strategy: can be found in the notes
+
+ Args:
+ construction_graph (ConstructionGraph): Construction graph to validate
+
+ Returns:
+ bool: True if the construction graph is valid
+ """
+ # TODO -
+ # Step 1 - Perform a topological sort of the fignodes so that we
+ # know how to traverse anc check the rules against each of the nodes
+ # Step 2 - For each of these fig nodes call the individual rules (all 6/7 of them).
+ # Step 3 - If response of any of those 7 is false then return false indicating that
+ # its an invalid design. Skip rulecheck if explicitly mapped
+ #
+ sorted_fignodes = list(nx.topological_sort(self._fig))
+ for fignode in sorted_fignodes:
+ # TODO - Skip check if explicitly mapped. Rationale is that user knows best
+ rule_1_success = self.__check_rule_1_validity(fignode, construction_graph)
+ if rule_1_success is False:
+ return False
+ rule_2_success = self.__check_rule_2_validity(fignode, construction_graph)
+ if rule_2_success is False:
+ return False
+ rule_3_success = self.__check_rule_3_validity(fignode, construction_graph)
+ if rule_3_success is False:
+ return False
+ rule_4_success = self.__check_rule_4_validity(fignode, construction_graph)
+ if rule_4_success is False:
+ return False
+ rule_5_success = self.__check_rule_5_validity(fignode, construction_graph)
+ if rule_5_success is False:
+ return False
+ rule_6_success = self.__check_rule_6_validity(fignode, construction_graph)
+ if rule_6_success is False:
+ return False
+ rule_7_success = self.__check_rule_7_validity(fignode, construction_graph)
+ if rule_7_success is False:
+ return False
+
+ return True
+
+ def __search_predecessors(self, fignode_id: str, search_type: InteractionType):
+ """recursive function searches for the specified InteractionType in the
+ predecessors of the specified fignode_id
+
+ Args:
+ fignode_id (str): Starting node to find the
+ predecessors
+ search_type (InteractionType): Interaction type to find in the predecessors
+
+ Returns:
+ Bool: If found, returns true. Else false
+ """
+ fignode = self._fig.get_fignode(fignode_id)
+
+ if self.__check_if_type(fignode, search_type):
+ return True
+
+ else:
+ for prednode_id in self._fig.predecessors(fignode_id):
+ if self.__search_predecessors(prednode_id, search_type):
+ return True
+
+ return False
+
+ def __check_rule_1_validity(
+ self, fignode: str, constructin_graph: ConstructionGraph
+ ) -> bool:
+ raise NotImplementedError()
+
+ def __check_rule_2_validity(
+ self, fignode: str, constructin_graph: ConstructionGraph
+ ) -> bool:
+ raise NotImplementedError()
+
+ def __check_rule_3_validity(
+ self, fignode: str, constructin_graph: ConstructionGraph
+ ) -> bool:
+ raise NotImplementedError()
+
+ def __check_rule_4_validity(
+ self, fignode: str, constructin_graph: ConstructionGraph
+ ) -> bool:
+ raise NotImplementedError()
+
+ def __check_rule_5_validity(
+ self, fignode: str, constructin_graph: ConstructionGraph
+ ) -> bool:
+ raise NotImplementedError()
+
+ def __check_rule_6_validity(
+ self, fignode: str, constructin_graph: ConstructionGraph
+ ) -> bool:
+ raise NotImplementedError()
+
+ def __check_rule_7_validity(
+ self, fignode: str, constructin_graph: ConstructionGraph
+ ) -> bool:
+ raise NotImplementedError()
+
+ @staticmethod
+ def __check_if_type(fignode: FIGNode, search_type: InteractionType):
+ """helper function for __search_predecessors and __check_continuous. Check if
+ the specified search_type matches to the fignode.type
+
+ Args:
+ fignode (FIGNode): fignode that contains InteractionType as type
+ search_type ([type]): desired type to check
+
+ Returns:
+ Bool: if fignode.type matches to search_type, returns true. Else false
+ """
+ if isinstance(fignode, Interaction):
+ if fignode.type is search_type:
+ return True
+
+ return False
diff --git a/lfr/netlistgenerator/gen_strategies/dummy.py b/lfr/netlistgenerator/gen_strategies/dummy.py
new file mode 100644
index 0000000..6816d5b
--- /dev/null
+++ b/lfr/netlistgenerator/gen_strategies/dummy.py
@@ -0,0 +1,9 @@
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+from lfr.netlistgenerator.gen_strategies.genstrategy import GenStrategy
+from lfr.netlistgenerator.mappingoption import MappingOption
+
+# from lfr.netlistgenerator.constructiongraph import ConstructionGraph
+
+
+class DummyStrategy(GenStrategy):
+ pass
diff --git a/lfr/netlistgenerator/gen_strategies/genstrategy.py b/lfr/netlistgenerator/gen_strategies/genstrategy.py
new file mode 100644
index 0000000..1d70a6d
--- /dev/null
+++ b/lfr/netlistgenerator/gen_strategies/genstrategy.py
@@ -0,0 +1,118 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Dict
+
+from pymint.mintlayer import MINTLayerType
+
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+
+if TYPE_CHECKING:
+ from lfr.netlistgenerator.constructiongraph import ConstructionGraph
+
+from typing import List
+
+from parchmint import Target
+from pymint.mintdevice import MINTDevice
+from pymint.mintnode import MINTNode
+
+from lfr.netlistgenerator.connectingoption import ConnectingOption
+
+
+class GenStrategy:
+ def __init__(self, name: str, fig: FluidInteractionGraph) -> None:
+ self._name: str = name
+ self._fig: FluidInteractionGraph = fig
+
+ def validate_construction_graph_flow(
+ self, construction_graph: ConstructionGraph
+ ) -> bool:
+ """
+ Validate the construction graph against a set of rules
+
+ TODO - Future version of this should use a rule based grammar
+ like Eugene but for topologically sorted FIGs where we
+ figure out where the outputs of a certain flow network
+ can be connected to the inputs of another flow network
+ (Needs to be put in theorem form).
+
+ Args:
+ construction_graph (ConstructionGraph): Construction graph to validate
+
+ Returns:
+ bool: True if the construction graph is valid
+ """
+ raise NotImplementedError()
+
+ def reduce_mapping_options(self) -> None:
+ """
+ Reduce the mapping options for the construction graph
+
+ TODO - In the future go through the options by looking at Rama
+ like apps that can be used for pruning technologies based on
+ the physics parameters.
+
+ Raises:
+ NotImplementedError: If the method is not implemented
+ """
+ raise NotImplementedError()
+
+ def generate_flow_network(self) -> None:
+ """Generate the flow flow network mappings
+
+ TODO - Use this to sort through the correct kinds of network primitives
+ to use for the flow-flow networks
+ """
+ raise NotImplementedError()
+
+ def generate_input_connectingoptions(self):
+ """Unsure if this is necessary in the future with the new architecture
+
+ Raises:
+ NotImplementedError: Raises if the method is not implemented
+ """
+ raise NotImplementedError()
+
+ def generate_output_connectingoptions(self):
+ """Unsure if this is necessary in the future with the new architecture
+
+ Raises:
+ NotImplementedError: Raises if the method is not implemented
+ """
+ raise NotImplementedError()
+
+ @staticmethod
+ def generate_carrier_connectingoptions():
+ """
+ Generate the connecting options for the carrier networks.
+
+ TODO - In the future version, go through the connectivity of the flow network,
+ compute what options would need to be pipelined and then optimize the carrier
+ network to have the least number of carrier inputs and wastes.
+ """
+ return []
+
+ @staticmethod
+ def generate_loading_connectingoptions():
+ """
+ Generate the connecting options for the loading networks.
+
+ TODO - In the future version, go through the connectivity of the flow network,
+ compute what options would need to be pipelined and then optimize the loading
+ network to have the least number of carrier inputs and wastes.
+
+ Args:
+ subgraph_view (_type_): _description_
+
+ Returns:
+ List[ConnectingOption]: _description_
+ """
+ raise NotImplementedError()
+
+ def size_netlist(self, device: MINTDevice) -> None:
+ raise NotImplementedError()
+
+ def prune_variants(self, variants: List[ConstructionGraph]) -> None:
+ for variant in variants:
+ if variant.is_fig_fully_covered() is not True:
+ print(f"Removing variant (Construction Graph): {variant.ID}")
+ variants.remove(variant)
diff --git a/lfr/netlistgenerator/gen_strategies/marsstrategy.py b/lfr/netlistgenerator/gen_strategies/marsstrategy.py
new file mode 100644
index 0000000..1caa895
--- /dev/null
+++ b/lfr/netlistgenerator/gen_strategies/marsstrategy.py
@@ -0,0 +1,27 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Dict
+
+from pymint.mintlayer import MINTLayerType
+
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+from lfr.netlistgenerator.constructiongraph.constructionnode import ConstructionNode
+from lfr.netlistgenerator.dafdadapter import DAFDAdapter
+from lfr.netlistgenerator.gen_strategies.genstrategy import GenStrategy
+
+if TYPE_CHECKING:
+ from lfr.netlistgenerator.constructiongraph.constructiongraph import (
+ ConstructionGraph,
+ )
+
+from typing import List
+
+from parchmint import Target
+from pymint.mintdevice import MINTDevice
+from pymint.mintnode import MINTNode
+
+from lfr.netlistgenerator.connectingoption import ConnectingOption
+
+
+class MarsStrategy(GenStrategy):
+ pass
diff --git a/lfr/netlistgenerator/generator.py b/lfr/netlistgenerator/generator.py
new file mode 100644
index 0000000..e339938
--- /dev/null
+++ b/lfr/netlistgenerator/generator.py
@@ -0,0 +1,336 @@
+from typing import Dict, FrozenSet, List, Optional, Set, Tuple
+
+from pymint.mintdevice import MINTDevice
+from pymint.mintlayer import MINTLayerType
+
+from lfr.compiler.module import Module
+from lfr.fig.simplification import remove_passthrough_nodes
+from lfr.graphmatch.interface import get_fig_matches
+from lfr.netlistgenerator import LibraryPrimitivesEntry
+from lfr.netlistgenerator.constructiongraph.edge_generation import (
+ generate_construction_graph_edges,
+)
+from lfr.netlistgenerator.constructiongraph.variant_generator import (
+ generate_match_variants,
+)
+from lfr.netlistgenerator.flownetworkmatching import add_flow_flow_matching_candidates
+from lfr.netlistgenerator.gen_strategies.dropxstrategy import DropXStrategy
+from lfr.netlistgenerator.gen_strategies.dummy import DummyStrategy
+from lfr.netlistgenerator.gen_strategies.marsstrategy import MarsStrategy
+from lfr.netlistgenerator.mappinglibrary import MappingLibrary
+from lfr.netlistgenerator.namegenerator import NameGenerator
+from lfr.netlistgenerator.netlist_generation import generate_device
+from lfr.postprocessor.mapping import (
+ FluidicOperatorMapping,
+ NetworkMapping,
+ NodeMappingInstance,
+ NodeMappingTemplate,
+ PumpMapping,
+ StorageMapping,
+)
+from lfr.utils import printgraph
+
+
+def generate(module: Module, library: MappingLibrary) -> List[MINTDevice]:
+ # In order to create the device, we do the following
+ # STEP 1 - Simplify the Fluid Interaction Graphs
+ # STEP 2 - Initialize the active strategy
+ # STEP 3 - Get all the technology mapping matches for the FIG
+ # STEP 4 - Eliminate the matches that are exactly the same as the explicit matches
+ # STEP 5 - Generate the waste outputs
+ # STEP 6 - Generate the mapping variants
+ # STEP 6.5 - Generate the flow subgraph matches (TODO - Add test cases for this)
+ # STEP 6.10 - Before generating teh device, delete all the variants with incomplete mappings
+ # STEP 7 - Generate the control logic network
+ # STEP 8 - Generate the connections
+ # STEP 9 - Size the components
+ # STEP 10 - Size the connections
+
+ # construction_graph = ConstructionGraph()
+
+ # Step 1 - Simplify the Fluid Interaction Graphs
+ printgraph(module.FIG, f"{module.name}_FIG")
+ remove_passthrough_nodes(module.FIG)
+ printgraph(module.FIG, f"{module.name}_FIG_simplified")
+
+ # STEP 2 - Initialize the active strategy
+ # TODO - I need to change this DummyStrategy later on
+ if library.name == "dropx":
+ active_strategy = DropXStrategy(module.FIG)
+ elif library.name == "mars":
+ # raise NotImplementedError()
+ active_strategy = MarsStrategy(module.FIG)
+ elif library.name == "hmlp":
+ raise NotImplementedError()
+ else:
+ active_strategy = DummyStrategy(module.FIG)
+
+ # STEP 3 - Get all the technology mapping matches for the FIG
+ # Do the reggie matching to find the mapping options
+ # This means that we might need to have a forest of construction of graphs
+ # as there would be alternatives for each type of mapping
+ matches = get_fig_matches(module.FIG, library)
+ print(f"Total Matches against library : {len(matches)}")
+ for match in matches:
+ # Generate an object that is usable going forward (mapping template perhaps)
+ print(match)
+
+ # STEP 4 - Eliminate the matches that are exactly the same as the explicit matches
+ # Get the explicit mapping and find the explicit mappings here
+ explicit_mappings = module.get_explicit_mappings()
+ matches, explict_cover_sets = eliminate_explicit_match_alternates(
+ matches, explicit_mappings, library
+ )
+
+ print(
+ "Total matches against library after explicit mapping eliminations:"
+ f" {len(matches)}"
+ )
+ for match in matches:
+ print(match)
+
+ # STEP 5 - Generate the waste outputs
+ # TODO - Add fignodes to all the orphaned flow nodes for this to function
+ # connect_orphan_IO()
+
+ # STEP 6 - Generate the mapping variants
+ variants = generate_match_variants(
+ matches, module.FIG, library, active_strategy, explict_cover_sets
+ )
+
+ # STEP 6.5 -Generate the matches for the flow subgraphs
+ add_flow_flow_matching_candidates(module.FIG, variants, active_strategy)
+
+ # STEP 8 - Generate the edges in the construction graph
+ print("Generating the construction graph edges...")
+ for variant in variants:
+ generate_construction_graph_edges(module.FIG, variant)
+ variant.print_graph(f"{variant.ID}_construction_graph.dot")
+
+ # STEP 6.10 - Before generating the device, delete all the variants with incomplete coverage of the FIG
+ variants = [variant for variant in variants if variant.is_fig_fully_covered()]
+
+ # Perform the various validate using the active strategy
+ validated_variants = []
+ for variant in variants:
+ flow_validation_success = active_strategy.validate_construction_graph_flow(
+ variant
+ )
+
+ # TODO - Add other kinds of validation here
+ # Eg. active_strategy.whatever_else_validation()
+
+ if flow_validation_success:
+ validated_variants.append(variant)
+
+ # Now generate the devices for each of the variants
+ generated_devices = []
+ for variant in validated_variants:
+ # Create the device for each of the variants
+ name_generator = NameGenerator()
+
+ cur_device = MINTDevice(module.name)
+
+ # Add a MINT Layer so that the device has something to work with
+ cur_device.create_mint_layer("0", "0", 0, MINTLayerType.FLOW)
+
+ generate_device(
+ construction_graph=variant,
+ scaffhold_device=cur_device,
+ name_generator=name_generator,
+ mapping_library=library,
+ )
+ # STEP 8 - Generate the control logic network
+ # TODO - Whatever this entails (put in the implementation)
+
+ # STEP 9 - Generate the connection optimizations
+ # TODO - write the algorithm for carriers and optimize the flows
+ # Generate all the unaccounted carriers and waste output lines necessary
+
+ # STEP 10 - Size the components
+ # TODO - Size the component netlist
+
+ generated_devices.append(cur_device)
+
+ return generated_devices
+
+
+def eliminate_explicit_match_alternates(
+ matches: List[LibraryPrimitivesEntry],
+ explict_mappings: List[NodeMappingTemplate],
+ library: MappingLibrary,
+) -> Tuple[List[LibraryPrimitivesEntry], List[Set[str]]]:
+ """Eliminates the alternatives for explicit matches from the list of matches.
+
+ Args:
+ matches (List[LibraryPrimitivesEntry]): List of matches to eliminate from
+ explict_mappings (List[NodeMappingTemplate]): The mappings that are explicitly
+ defined by the user
+
+ Returns:
+ List[Tuple[str, Dict[str, str]]]: _description_
+ """
+ # extract the fignode ID set from matches
+ match_node_set_dict: Dict[FrozenSet, List[LibraryPrimitivesEntry]] = {}
+ for match in matches:
+ frozen_set = frozenset(match[2].keys())
+ if frozen_set not in match_node_set_dict:
+ match_node_set_dict[frozen_set] = []
+ match_node_set_dict[frozen_set].append(match)
+ else:
+ match_node_set_dict[frozen_set].append(match)
+
+ # This is the explit match store that we keep track of explicitly defined mappings
+ explicit_matches: List[LibraryPrimitivesEntry] = []
+
+ # This is the set of cover sets that are found and returned
+ explicit_cover_sets: List[Set[str]] = []
+
+ # Go through each of the explict matches, generate a subgraph and compare against
+ # all the matches
+ for explicit_mapping in explict_mappings:
+ # Only do the explicit mapping if the the mapping object has a technology
+ # associated with it else skip it
+ if explicit_mapping.technology_string is None:
+ continue
+
+ # Generate a subgraph for each of the mapping instance fig
+ for instance in explicit_mapping.instances:
+ node_set = set()
+
+ # Check what kind of an instance this is
+ if isinstance(instance, NodeMappingInstance):
+ # This is a single node scenario
+ node_set.add(instance.node.ID)
+ elif isinstance(instance, FluidicOperatorMapping):
+ node_set.add(instance.node.ID)
+
+ elif isinstance(instance, StorageMapping):
+ node_set.add(instance.node.ID)
+
+ elif isinstance(instance, PumpMapping):
+ node_set.add(instance.node.ID)
+
+ elif isinstance(instance, NetworkMapping):
+ node_set = set()
+ node_set.union(set([node.ID for node in instance.input_nodes]))
+ node_set.union(set([node.ID for node in instance.output_nodes]))
+
+ if frozenset(node_set) in match_node_set_dict:
+ # This is an explicit match
+ # Remove the explicit match from the list of matches
+ print(
+ "Eliminating match: {}".format(
+ match_node_set_dict[frozenset(node_set)]
+ )
+ )
+ match_node_set_dict[frozenset(node_set)].clear()
+
+ # Now generate a match tuple for this instance
+ match_primitive_uid: Optional[str] = None
+ match_technology_string = explicit_mapping.technology_string
+ match_mapping: Dict[str, str] = {}
+
+ # TODO - Retouch this part if we ever go into modifying how the matches are
+ # generated if we use the match string coordinates (use the match interface
+ # for this) (function - generate_single_match)
+
+ # Check what kind of an instance this is
+ if isinstance(instance, NodeMappingInstance):
+ # This is a single node scenario
+ match_mapping[instance.node.ID] = "v1"
+ elif isinstance(instance, FluidicOperatorMapping):
+ match_mapping[instance.node.ID] = "v1"
+
+ elif isinstance(instance, StorageMapping):
+ match_mapping[instance.node.ID] = "v1"
+
+ elif isinstance(instance, PumpMapping):
+ match_mapping[instance.node.ID] = "v1"
+
+ elif isinstance(instance, NetworkMapping):
+ for i in range(len(instance.input_nodes)):
+ node = instance.input_nodes[i]
+ match_mapping[node.ID] = f"vi{i}"
+ for i in range(len(instance.output_nodes)):
+ node = instance.output_nodes[i]
+ match_mapping[node.ID] = f"vo{i}"
+
+ # Rewrite the matchid for the explicit matches
+ # based on the library entry
+ if frozenset(node_set) in match_node_set_dict:
+ # Find the primitive that matches the technology string
+ for primitive in match_node_set_dict[frozenset(node_set)]:
+ if primitive[1] == explicit_mapping.technology_string:
+ # This is the match we want to replace
+ # Replace the match id with the match tuple
+ match_primitive_uid = primitive[0]
+ # This is an explicit match
+ # Remove the explicit match from the list of matches
+ print(
+ "Eliminating match: {}".format(
+ match_node_set_dict[frozenset(node_set)]
+ )
+ )
+ match_node_set_dict[frozenset(node_set)].clear()
+
+ # If the match_primitive ID is None, we need to query a match from the
+ # library
+ if match_primitive_uid is None:
+ primitives_with_technology = library.get_primitives(
+ match_technology_string
+ )
+ # TODO - We need to have a better way to pick between the primitives
+ # as a temprorary fix we just pick the first one
+ match_primitive_uid = primitives_with_technology[0].uid
+
+ # Add this match tuple to the list of matches
+ match_tuple: LibraryPrimitivesEntry = (
+ match_primitive_uid,
+ match_technology_string,
+ match_mapping,
+ )
+
+ explicit_matches.append(match_tuple)
+ # This is something we need to return to the to the caller
+ explicit_cover_sets.append(node_set)
+
+ # Modify the matches list
+ eliminated_matches = []
+ for match_tuple_list in match_node_set_dict.values():
+ for match_tuple in match_tuple_list:
+ eliminated_matches.append(match_tuple)
+
+ # Add the explicit matches to the list of matches
+ eliminated_matches.extend(explicit_matches)
+
+ return (eliminated_matches, explicit_cover_sets)
+
+
+def connect_orphan_IO():
+ print("Implement the orphan io generation system")
+
+
+def __check_if_passthrough(sub) -> bool:
+ """Checks if its a passthrough chain
+
+ Args:
+ sub (subgraph): subgraph
+
+ Returns:
+ bool: Return true if its a single chain of flow channels
+ """
+ in_count = 0
+ out_count = 0
+ for node in list(sub.nodes):
+ inedges = list(sub.in_edges(node))
+ outedges = list(sub.out_edges(node))
+ if len(inedges) == 0:
+ in_count += 1
+ if len(outedges) == 0:
+ out_count += 1
+
+ if in_count == 1 and out_count == 1:
+ return True
+ else:
+ return False
diff --git a/lfr/netlistgenerator/mappinglibrary.py b/lfr/netlistgenerator/mappinglibrary.py
index 5186d7a..4077c89 100644
--- a/lfr/netlistgenerator/mappinglibrary.py
+++ b/lfr/netlistgenerator/mappinglibrary.py
@@ -1,80 +1,149 @@
-from typing import Dict, List
+from typing import Dict, List, Tuple
from lfr.fig.interaction import InteractionType
+from lfr.netlistgenerator.connection_primitive import ConnectionPrimitive
from lfr.netlistgenerator.primitive import Primitive, ProceduralPrimitive
+MatchPatternEntry = Tuple[str, str, str]
+
class MappingLibrary:
- def __init__(self, name) -> None:
+ """Mapping Lirbrary containing all the primitives we can match against"""
+
+ def __init__(self, name: str) -> None:
+ """Initializes the mapping library.
+
+ Args:
+ name (str): Name of the mapping library
+ """
self.__name = name
- self.__mix_operators = []
- self.__meter_operators = []
- self.__seive_operators = []
- self.__dilute_operators = []
- self.__divide_operators = []
- self.__technology_process_operators = []
- self.__storage_primitives = []
- self.__pump_primitives = []
- self.__io_primitives = []
+ self.__mix_operators: List[Primitive] = []
+ self.__meter_operators: List[Primitive] = []
+ self.__seive_operators: List[Primitive] = []
+ self.__dilute_operators: List[Primitive] = []
+ self.__divide_operators: List[Primitive] = []
+ self.__technology_process_operators: List[Primitive] = []
+ self.__storage_primitives: List[Primitive] = []
+ self.__pump_primitives: List[Primitive] = []
+ self.__io_primitives: List[Primitive] = []
self.__all_primitives: Dict[str, Primitive] = {}
self.__procedural_primitves: List[ProceduralPrimitive] = []
+ self.__connection_primitives: List[ConnectionPrimitive] = []
self._default_IO_primitive = None
@property
def name(self) -> str:
+ """Returns the name of the library.
+
+ Returns:
+ str: Name of the library
+ """
return self.__name
def add_io_entry(self, primitive: Primitive) -> None:
+ """Adds a primitive to the list of IO primitives.
+
+ Args:
+ primitive (Primitive): Primitive to add to the list of IO primitives
+ """
self.__io_primitives.append(primitive)
- self.__all_primitives[primitive.mint] = primitive
+ self.__all_primitives[primitive.uid] = primitive
def add_operator_entry(
self, primitive: Primitive, interaction_type: InteractionType
) -> None:
+ """Adds a primitive to the list of operators for the given interaction type.
+
+ Args:
+ primitive (Primitive): Primitive to add to the list of operators
+ interaction_type (InteractionType): Type of interaction to add the primitive to
+ """
if interaction_type is InteractionType.MIX:
self.__mix_operators.append(primitive)
- self.__all_primitives[primitive.mint] = primitive
+ self.__all_primitives[primitive.uid] = primitive
elif interaction_type is InteractionType.SIEVE:
self.__seive_operators.append(primitive)
- self.__all_primitives[primitive.mint] = primitive
+ self.__all_primitives[primitive.uid] = primitive
elif interaction_type is InteractionType.DILUTE:
self.__dilute_operators.append(primitive)
- self.__all_primitives[primitive.mint] = primitive
+ self.__all_primitives[primitive.uid] = primitive
elif interaction_type is InteractionType.METER:
self.__meter_operators.append(primitive)
- self.__all_primitives[primitive.mint] = primitive
+ self.__all_primitives[primitive.uid] = primitive
elif interaction_type is InteractionType.DIVIDE:
self.__divide_operators.append(primitive)
- self.__all_primitives[primitive.mint] = primitive
+ self.__all_primitives[primitive.uid] = primitive
else:
self.__technology_process_operators.append(primitive)
- self.__all_primitives[primitive.mint] = primitive
+ self.__all_primitives[primitive.uid] = primitive
+
+ def add_entry(self, primitive: Primitive) -> None:
+ """Adds a primitive to the library."""
+ self.__all_primitives[primitive.uid] = primitive
def add_procedural_entry(self, primitive: ProceduralPrimitive) -> None:
+ """Adds a procedural primitive to the library.
+
+ Args:
+ primitive (ProceduralPrimitive): Primitive to add to the library
+ """
self.__procedural_primitves.append(primitive)
- self.__all_primitives[primitive.mint] = primitive
+ self.__all_primitives[primitive.uid] = primitive
def add_storage_entry(self, primitive: Primitive) -> None:
+ """Adds a primitive to the list of storage primitives.
+
+ Args:
+ primitive (Primitive): Primitive to add to the list of storage primitives
+ """
self.__storage_primitives.append(primitive)
- self.__all_primitives[primitive.mint] = primitive
+ self.__all_primitives[primitive.uid] = primitive
def add_pump_entry(self, primitive: Primitive) -> None:
+ """Adds a primitive to the list of pump primitives.
+
+ Args:
+ primitive (Primitive): Primitive to add to the list of pump primitives
+ """
self.__pump_primitives.append(primitive)
- self.__all_primitives[primitive.mint] = primitive
+ self.__all_primitives[primitive.uid] = primitive
def get_storage_entries(self) -> List[Primitive]:
+ """Returns the list of storage primitives.
+
+ Returns:
+ List[Primitive]: List of storage primitives
+ """
return self.__storage_primitives
def get_pump_entries(self) -> List[Primitive]:
+ """Returns the list of pump primitives.
+
+ Returns:
+ List[Primitive]: List of pump primitives
+ """
return self.__pump_primitives
def get_default_IO(self) -> Primitive:
+ """Returns the default IO primitive.
+
+ Returns:
+ Primitive: Default IO primitive
+ """
if self._default_IO_primitive is None:
return self.__io_primitives[0]
else:
return self._default_IO_primitive
def get_operators(self, interaction_type: InteractionType) -> List[Primitive]:
+ """Gets the primitives for the given interaction type.
+
+ Args:
+ interaction_type (InteractionType): Type of interaction to get primitives
+
+ Returns:
+ List[Primitive]: List of primitives for the given interaction type
+ """
if interaction_type is InteractionType.MIX:
return self.__mix_operators
elif interaction_type is InteractionType.SIEVE:
@@ -88,8 +157,86 @@ def get_operators(self, interaction_type: InteractionType) -> List[Primitive]:
else:
return self.__technology_process_operators
- def get_primitive(self, technology_string: str) -> Primitive:
- return self.__all_primitives[technology_string]
+ def get_primitive(self, uid: str) -> Primitive:
+ """Returns the primitive with the given uid.
+
+ Args:
+ uid (str): UID of the primitive to return
+
+ Raises:
+ KeyError: If the primitive is not found
+
+ Returns:
+ Primitive: The primitive with the given uid
+ """
+ if uid in self.__all_primitives:
+ return self.__all_primitives[uid]
+
+ raise KeyError("No primitive with uid: " + uid)
+
+ def get_primitives(self, technology_string: str) -> List[Primitive]:
+ """Get the primitive with the given technology string.
+
+
+ Args:
+ technology_string (str): MINT String around which the
+ primitive is defined
+
+ Returns:
+ List[Primitive]: List of primitives with the given technology string.
+ Returns an empty list if no primitives are found.
+ """
+ ret = []
+ for primitive in self.__all_primitives.values():
+ if primitive.mint == technology_string:
+ ret.append(primitive)
+ return ret
def has_primitive(self, technology_string: str) -> bool:
- return technology_string in self.__all_primitives.keys()
+ """Checks whether the library contains a primitive with the given technology string.
+
+
+ Args:
+ technology_string (str): MINT String of the technology
+
+ Returns:
+ bool: whether it exists or not
+ """
+ # Go through each of the entries in the all_primitives dictionary and see if the
+ # technology string is in there.
+ ret = False
+ for primitive in self.__all_primitives.values():
+ if primitive.mint == technology_string:
+ ret = True
+ break
+
+ return ret
+
+ def get_match_patterns(self) -> List[MatchPatternEntry]:
+ """Returns the match patterns for the library.
+
+ Returns:
+ List[MatchPattern]: Match patterns for the library
+ """
+ ret = []
+ for primitive in self.__all_primitives.values():
+ ret.append((primitive.uid, primitive.mint, primitive.match_string))
+
+ return ret
+
+ def add_connection_entry(self, primitive: ConnectionPrimitive) -> None:
+ """Adds a primitive to the list of connection primitives.
+
+ Args:
+ primitive (Primitive): Primitive to add to the list of connection primitives
+ """
+ self.__connection_primitives.append(primitive)
+ self.__all_primitives[primitive.uid] = primitive
+
+ def get_default_connection_entry(self) -> ConnectionPrimitive:
+ """Returns the default connection primitive.
+
+ Returns:
+ ConnectionPrimitive: Default connection primitive
+ """
+ return self.__connection_primitives[0]
diff --git a/lfr/netlistgenerator/mappinglibrary_generator.py b/lfr/netlistgenerator/mappinglibrary_generator.py
new file mode 100644
index 0000000..bfa8cba
--- /dev/null
+++ b/lfr/netlistgenerator/mappinglibrary_generator.py
@@ -0,0 +1,936 @@
+from typing import Dict, List
+
+from lfr.fig.interaction import InteractionType
+from lfr.netlistgenerator.connectingoption import ConnectingOption
+from lfr.netlistgenerator.connection_primitive import ConnectionPrimitive
+from lfr.netlistgenerator.mappinglibrary import MappingLibrary
+from lfr.netlistgenerator.primitive import Primitive, PrimitiveType
+from lfr.netlistgenerator.procedural_component_algorithms.ytree import YTREE
+
+
+def generate_mlsi_library() -> MappingLibrary:
+ library = MappingLibrary("mlsi")
+ # PORT
+ port_inputs: List[ConnectingOption] = []
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+
+ port_outputs: List[ConnectingOption] = []
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+
+ port = Primitive(
+ "PORT",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:IO
+ }""",
+ False,
+ False,
+ port_inputs,
+ port_outputs,
+ None,
+ None,
+ None,
+ )
+
+ library.add_io_entry(port)
+
+ # MIXER - CONTINOUS FLOW ONE
+
+ cf_mixer_inputs: List[ConnectingOption] = []
+
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+
+ cf_mixer_outputs: List[ConnectingOption] = []
+
+ cf_mixer_outputs.append(ConnectingOption(None, ["2"]))
+
+ cf_mixer_loadings: List[ConnectingOption] = []
+ cf_mixer_carriers: List[ConnectingOption] = []
+
+ cf_mixer = Primitive(
+ "MIXER",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:MIX
+ }""",
+ False,
+ False,
+ cf_mixer_inputs,
+ cf_mixer_outputs,
+ cf_mixer_loadings,
+ cf_mixer_carriers,
+ None,
+ )
+
+ library.add_operator_entry(cf_mixer, InteractionType.MIX)
+
+ # MUX2
+
+ mux2_inputs: List[ConnectingOption] = []
+ mux2_inputs.append(ConnectingOption(None, ["1"]))
+
+ mux2_outputs: List[ConnectingOption] = []
+ mux2_outputs.append(ConnectingOption(None, ["2"]))
+ mux2_outputs.append(ConnectingOption(None, ["3"]))
+
+ mux2 = Primitive(
+ "MUX",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo1 { "DISTRIBUTE_OR", "or_1" },
+ v1 -> vo2 { "DISTRIBUTE_OR", "or_1" }
+ }
+ """,
+ False,
+ False,
+ mux2_inputs,
+ mux2_outputs,
+ None,
+ None,
+ None,
+ )
+
+ library.add_entry(mux2)
+
+ return library
+
+
+def generate_mars_library() -> MappingLibrary:
+ library = MappingLibrary("mars")
+
+ # PORT
+ port_inputs: List[ConnectingOption] = []
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+
+ port_outputs: List[ConnectingOption] = []
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+
+ port = Primitive(
+ "PORT",
+ PrimitiveType.COMPONENT,
+ "IO",
+ False,
+ False,
+ port_inputs,
+ port_outputs,
+ None,
+ None,
+ None,
+ )
+
+ library.add_io_entry(port)
+
+ # NORMAL MIXER
+
+ mixer_inputs: List[ConnectingOption] = []
+
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+
+ mixer_outputs: List[ConnectingOption] = []
+
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+
+ mixer_loadings: List[ConnectingOption] = []
+ mixer_carriers: List[ConnectingOption] = []
+
+ mixer = Primitive(
+ "MIXER",
+ PrimitiveType.COMPONENT,
+ "MIX",
+ False,
+ False,
+ mixer_inputs,
+ mixer_outputs,
+ mixer_loadings,
+ mixer_carriers,
+ None,
+ )
+
+ library.add_operator_entry(mixer, InteractionType.MIX)
+
+ # DIAMOND REACTION CHAMBER
+
+ diamond_chamber_inputs: List[ConnectingOption] = []
+
+ diamond_chamber_inputs.append(ConnectingOption("default_component", ["1"]))
+
+ diamond_chamber_outputs: List[ConnectingOption] = []
+
+ diamond_chamber_outputs.append(ConnectingOption("default_component", ["2"]))
+
+ diamond_chamber_loadings: List[ConnectingOption] = []
+ diamond_chamber_carriers: List[ConnectingOption] = []
+
+ diamond_chamber = Primitive(
+ "DIAMOND REACTION CHAMBER",
+ PrimitiveType.COMPONENT,
+ "PROCESS",
+ False,
+ False,
+ diamond_chamber_inputs,
+ diamond_chamber_outputs,
+ diamond_chamber_loadings,
+ diamond_chamber_carriers,
+ None,
+ )
+
+ library.add_operator_entry(diamond_chamber, InteractionType.TECHNOLOGY_PROCESS)
+
+ # METER
+
+ meter_inputs: List[ConnectingOption] = []
+
+ meter_outputs: List[ConnectingOption] = []
+
+ meter_outputs.append(ConnectingOption("default_component", ["1"]))
+
+ meter_loadings: List[ConnectingOption] = []
+
+ meter_loadings.append(ConnectingOption("default_component", ["2"]))
+
+ meter_carriers: List[ConnectingOption] = []
+
+ meter_carriers.append(ConnectingOption("default_component", ["3"]))
+
+ meter = Primitive(
+ "METER",
+ PrimitiveType.NETLIST,
+ "METER",
+ False,
+ False,
+ meter_inputs,
+ meter_outputs,
+ meter_loadings,
+ meter_carriers,
+ "default-netlists/dropletgenerator.mint",
+ ["droplet_size", "generation_rate"],
+ [
+ "orifice_size",
+ "aspect_ratio",
+ "capillary_number",
+ "expansion_ratio",
+ "flow_rate_ratio",
+ "normalized_oil_inlet",
+ "normalized_orifice_length",
+ "normalized_water_inlet",
+ ],
+ )
+
+ library.add_operator_entry(meter, InteractionType.METER)
+
+ # Incubator
+
+ incubator_inputs: List[ConnectingOption] = []
+
+ incubator_inputs.append(ConnectingOption("default_component", ["1"]))
+
+ incubator_outputs: List[ConnectingOption] = []
+
+ incubator_outputs.append(ConnectingOption("default_component", ["1"]))
+
+ incubator_loadings: List[ConnectingOption] = []
+ incubator_carriers: List[ConnectingOption] = []
+
+ incubator = Primitive(
+ "INCUBATOR",
+ PrimitiveType.COMPONENT,
+ "PROCESS",
+ False,
+ False,
+ incubator_inputs,
+ incubator_outputs,
+ incubator_loadings,
+ incubator_carriers,
+ )
+
+ library.add_operator_entry(incubator, InteractionType.TECHNOLOGY_PROCESS)
+
+ # SORTER
+
+ sorter_inputs: List[ConnectingOption] = []
+
+ sorter_inputs.append(ConnectingOption(None, ["1"]))
+
+ sorter_outputs: List[ConnectingOption] = []
+
+ sorter_outputs.append(ConnectingOption(None, ["2"]))
+ sorter_outputs.append(ConnectingOption(None, ["3"]))
+
+ sorter_loadings: List[ConnectingOption] = []
+ sorter_carriers: List[ConnectingOption] = []
+
+ # TODO - Modify this later on
+ sorter = Primitive(
+ "DROPLET SORTER",
+ PrimitiveType.COMPONENT,
+ "SIEVE",
+ False,
+ False,
+ sorter_inputs,
+ sorter_outputs,
+ sorter_loadings,
+ sorter_carriers,
+ None,
+ )
+
+ library.add_operator_entry(sorter, InteractionType.SIEVE)
+
+ return library
+
+
+def generate_dropx_library() -> MappingLibrary:
+ library = MappingLibrary("dropx")
+
+ # PORT
+ port_inputs: List[ConnectingOption] = []
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+ port_inputs.append(ConnectingOption(None, [None]))
+
+ port_outputs: List[ConnectingOption] = []
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+ port_outputs.append(ConnectingOption(None, []))
+
+ port = Primitive(
+ "PORT",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:IO
+ }""",
+ False,
+ False,
+ port_inputs,
+ port_outputs,
+ None,
+ None,
+ None,
+ )
+
+ library.add_io_entry(port)
+
+ # PICO INJECTOR
+
+ pico_injector_inputs: List[ConnectingOption] = []
+
+ pico_injector_inputs.append(ConnectingOption(None, ["1"]))
+ pico_injector_inputs.append(ConnectingOption(None, ["2"]))
+
+ pico_injector_outputs: List[ConnectingOption] = []
+
+ pico_injector_outputs.append(ConnectingOption(None, ["3"]))
+
+ pico_injector_loadings: List[ConnectingOption] = []
+ pico_injector_carriers: List[ConnectingOption] = []
+
+ pico_injector = Primitive(
+ "PICOINJECTOR",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:MIX
+ }""",
+ False,
+ False,
+ pico_injector_inputs,
+ pico_injector_outputs,
+ pico_injector_loadings,
+ pico_injector_carriers,
+ None,
+ )
+
+ library.add_operator_entry(pico_injector, InteractionType.MIX)
+
+ # DROPLET ELECTROPHORESIS MERGER
+
+ electrophoresis_merger_inputs: List[ConnectingOption] = []
+
+ electrophoresis_merger_inputs.append(ConnectingOption(None, ["1"]))
+ electrophoresis_merger_inputs.append(ConnectingOption(None, ["2"]))
+
+ electrophoresis_merger_outputs: List[ConnectingOption] = []
+
+ electrophoresis_merger_outputs.append(ConnectingOption(None, ["3"]))
+
+ electrophoresis_merger_loadings: List[ConnectingOption] = []
+ electrophoresis_merger_carriers: List[ConnectingOption] = []
+
+ # TODO - Modify this later on
+ electrophoresis_merger = Primitive(
+ "DROPLET MERGER",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:MIX
+ }""",
+ False,
+ False,
+ electrophoresis_merger_inputs,
+ electrophoresis_merger_outputs,
+ electrophoresis_merger_loadings,
+ electrophoresis_merger_carriers,
+ None,
+ )
+
+ library.add_operator_entry(electrophoresis_merger, InteractionType.MIX)
+
+ # DROPLET SORTER
+
+ droplet_sorter_inputs: List[ConnectingOption] = []
+
+ droplet_sorter_inputs.append(ConnectingOption(None, ["1"]))
+
+ droplet_sorter_outputs: List[ConnectingOption] = []
+
+ droplet_sorter_outputs.append(ConnectingOption(None, ["2"]))
+ droplet_sorter_outputs.append(ConnectingOption(None, ["3"]))
+
+ droplet_sorter_loadings: List[ConnectingOption] = []
+ droplet_sorter_carriers: List[ConnectingOption] = []
+
+ # TODO - Modify this later on
+ droplet_sorter = Primitive(
+ "DROPLET SORTER",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:SIEVE
+ }""",
+ False,
+ False,
+ droplet_sorter_inputs,
+ droplet_sorter_outputs,
+ droplet_sorter_loadings,
+ droplet_sorter_carriers,
+ None,
+ )
+
+ library.add_operator_entry(droplet_sorter, InteractionType.SIEVE)
+
+ # DROPLET GENERATOR
+
+ droplet_generator_inputs: List[ConnectingOption] = []
+
+ droplet_generator_inputs.append(ConnectingOption("default_component", ["1"]))
+
+ droplet_generator_outputs: List[ConnectingOption] = []
+
+ droplet_generator_outputs.append(ConnectingOption("default_component", ["3"]))
+
+ droplet_generator_loadings: List[ConnectingOption] = []
+ droplet_generator_carriers: List[ConnectingOption] = []
+
+ droplet_generator = Primitive(
+ "NOZZLE DROPLET GENERATOR",
+ PrimitiveType.NETLIST,
+ r"""{
+ v1:METER
+ }""",
+ False,
+ False,
+ droplet_generator_inputs,
+ droplet_generator_outputs,
+ droplet_generator_loadings,
+ droplet_generator_carriers,
+ "default-netlists/dropletgenerator.mint",
+ ["droplet_size", "generation_rate"],
+ [
+ "orifice_size",
+ "aspect_ratio",
+ "capillary_number",
+ "expansion_ratio",
+ "flow_rate_ratio",
+ "normalized_oil_inlet",
+ "normalized_orifice_length",
+ "normalized_water_inlet",
+ ],
+ )
+
+ library.add_operator_entry(droplet_generator, InteractionType.METER)
+
+ droplet_merger_junction_inputs: List[ConnectingOption] = []
+
+ droplet_merger_junction_inputs.append(ConnectingOption(None, ["1"]))
+ droplet_merger_junction_inputs.append(ConnectingOption(None, ["2"]))
+
+ droplet_merger_junction_outputs: List[ConnectingOption] = []
+
+ droplet_merger_junction_outputs.append(ConnectingOption(None, ["3"]))
+
+ droplet_merger_junction_loadings: List[ConnectingOption] = []
+ droplet_merger_junction_carriers: List[ConnectingOption] = []
+
+ droplet_merger_junction = Primitive(
+ "DROPLET MERGER JUNCTION",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:MIX
+ }""",
+ False,
+ False,
+ droplet_merger_junction_inputs,
+ droplet_merger_junction_outputs,
+ droplet_merger_junction_loadings,
+ droplet_merger_junction_carriers,
+ None,
+ )
+
+ library.add_operator_entry(droplet_merger_junction, InteractionType.MIX)
+
+ # DROPLET MERGER CHANNEL
+
+ droplet_merger_channel_inputs: List[ConnectingOption] = []
+
+ droplet_merger_channel_inputs.append(ConnectingOption(None, ["1"]))
+
+ droplet_merger_channel_outputs: List[ConnectingOption] = []
+
+ droplet_merger_channel_outputs.append(ConnectingOption(None, ["2"]))
+
+ droplet_merger_channel_loadings: List[ConnectingOption] = []
+ droplet_merger_channel_carriers: List[ConnectingOption] = []
+
+ droplet_merger_channel = Primitive(
+ "DROPLET MERGER CHANNEL",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:MIX
+ }""",
+ False,
+ False,
+ droplet_merger_channel_inputs,
+ droplet_merger_channel_outputs,
+ droplet_merger_channel_loadings,
+ droplet_merger_channel_carriers,
+ None,
+ )
+
+ library.add_operator_entry(droplet_merger_channel, InteractionType.MIX)
+
+ # MIXER - CONTINOUS FLOW ONE
+
+ cf_mixer_inputs: List[ConnectingOption] = []
+
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+ cf_mixer_inputs.append(ConnectingOption(None, ["1"]))
+
+ cf_mixer_outputs: List[ConnectingOption] = []
+
+ cf_mixer_outputs.append(ConnectingOption(None, ["2"]))
+
+ cf_mixer_loadings: List[ConnectingOption] = []
+ cf_mixer_carriers: List[ConnectingOption] = []
+
+ cf_mixer = Primitive(
+ "MIXER",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:MIX
+ }""",
+ False,
+ False,
+ cf_mixer_inputs,
+ cf_mixer_outputs,
+ cf_mixer_loadings,
+ cf_mixer_carriers,
+ None,
+ )
+
+ library.add_operator_entry(cf_mixer, InteractionType.MIX)
+
+ # DROPLET SPLITTER
+
+ droplet_splitter_inputs: List[ConnectingOption] = []
+
+ droplet_splitter_inputs.append(ConnectingOption(None, ["1"]))
+
+ droplet_splitter_outputs: List[ConnectingOption] = []
+
+ droplet_splitter_outputs.append(ConnectingOption(None, ["2"]))
+ droplet_splitter_outputs.append(ConnectingOption(None, ["3"]))
+
+ droplet_splitter_loadings: List[ConnectingOption] = []
+ droplet_splitter_carriers: List[ConnectingOption] = []
+
+ droplet_splitter = Primitive(
+ "DROPLET SPLITTER",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:DIVIDE
+ }""",
+ False,
+ False,
+ droplet_splitter_inputs,
+ droplet_splitter_outputs,
+ droplet_splitter_loadings,
+ droplet_splitter_carriers,
+ None,
+ )
+
+ library.add_operator_entry(droplet_splitter, InteractionType.DIVIDE)
+
+ # NORMAL MIXER
+
+ mixer_inputs: List[ConnectingOption] = []
+
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+ mixer_inputs.append(ConnectingOption(None, ["1"]))
+
+ mixer_outputs: List[ConnectingOption] = []
+
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+ mixer_outputs.append(ConnectingOption(None, ["2"]))
+
+ mixer_loadings: List[ConnectingOption] = []
+ mixer_carriers: List[ConnectingOption] = []
+
+ mixer = Primitive(
+ "MIXER",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:MIX
+ }""",
+ False,
+ False,
+ mixer_inputs,
+ mixer_outputs,
+ mixer_loadings,
+ mixer_carriers,
+ None,
+ )
+
+ library.add_operator_entry(mixer, InteractionType.MIX)
+
+ # DROPLET CAPACITANCE SENSOR
+
+ droplet_capacitance_sensor_inputs: List[ConnectingOption] = []
+
+ droplet_capacitance_sensor_inputs.append(ConnectingOption(None, ["1"]))
+
+ droplet_capacitance_sensor_outputs: List[ConnectingOption] = []
+
+ droplet_capacitance_sensor_outputs.append(ConnectingOption(None, ["2"]))
+
+ droplet_capacitance_sensor_loadings: List[ConnectingOption] = []
+ droplet_capacitance_sensor_carriers: List[ConnectingOption] = []
+
+ droplet_capacitance_sensor = Primitive(
+ "DROPLET CAPACITANCE SENSOR",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:PROCESS
+ }""",
+ False,
+ False,
+ droplet_capacitance_sensor_inputs,
+ droplet_capacitance_sensor_outputs,
+ droplet_capacitance_sensor_loadings,
+ droplet_capacitance_sensor_carriers,
+ None,
+ )
+
+ library.add_operator_entry(
+ droplet_capacitance_sensor, InteractionType.TECHNOLOGY_PROCESS
+ )
+
+ # FILTER
+
+ filter_inputs: List[ConnectingOption] = []
+
+ filter_inputs.append(ConnectingOption(None, ["1"]))
+
+ filter_outputs: List[ConnectingOption] = []
+
+ filter_outputs.append(ConnectingOption(None, ["2"]))
+
+ filter_loadings: List[ConnectingOption] = []
+ filter_carriers: List[ConnectingOption] = []
+
+ filter = Primitive(
+ "FILTER",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:PROCESS
+ }""",
+ False,
+ False,
+ filter_inputs,
+ filter_outputs,
+ filter_loadings,
+ filter_carriers,
+ None,
+ )
+
+ library.add_operator_entry(filter, InteractionType.TECHNOLOGY_PROCESS)
+
+ # DROPLET FLUORESCENCE SENSOR
+
+ droplet_fluorescence_sensor_inputs: List[ConnectingOption] = []
+
+ droplet_fluorescence_sensor_inputs.append(ConnectingOption(None, ["1"]))
+
+ droplet_fluorescence_sensor_outputs: List[ConnectingOption] = []
+
+ droplet_fluorescence_sensor_outputs.append(ConnectingOption(None, ["2"]))
+
+ droplet_fluorescence_sensor_loadings: List[ConnectingOption] = []
+ droplet_fluorescence_sensor_carriers: List[ConnectingOption] = []
+
+ droplet_fluorescence_sensor = Primitive(
+ "DROPLET FLUORESCENCE SENSOR",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:PROCESS
+ }""",
+ False,
+ False,
+ droplet_fluorescence_sensor_inputs,
+ droplet_fluorescence_sensor_outputs,
+ droplet_fluorescence_sensor_loadings,
+ droplet_fluorescence_sensor_carriers,
+ None,
+ )
+
+ library.add_operator_entry(
+ droplet_fluorescence_sensor, InteractionType.TECHNOLOGY_PROCESS
+ )
+
+ # DROPLET LUMINESCENCE SENSOR
+ droplet_luminescence_sensor_inputs: List[ConnectingOption] = []
+
+ droplet_luminescence_sensor_inputs.append(ConnectingOption(None, ["1"]))
+
+ droplet_luminescence_sensor_outputs: List[ConnectingOption] = []
+
+ droplet_luminescence_sensor_outputs.append(ConnectingOption(None, ["2"]))
+
+ droplet_luminescence_sensor_loadings: List[ConnectingOption] = []
+ droplet_luminescence_sensor_carriers: List[ConnectingOption] = []
+
+ droplet_luminescence_sensor = Primitive(
+ "DROPLET LUMINESCENCE SENSOR",
+ PrimitiveType.COMPONENT,
+ r"""{
+ v1:PROCESS
+ }""",
+ False,
+ False,
+ droplet_luminescence_sensor_inputs,
+ droplet_luminescence_sensor_outputs,
+ droplet_luminescence_sensor_loadings,
+ droplet_luminescence_sensor_carriers,
+ None,
+ )
+
+ library.add_operator_entry(
+ droplet_luminescence_sensor, InteractionType.TECHNOLOGY_PROCESS
+ )
+
+ # DROPLET SPACER
+
+ droplet_spacer_inputs: List[ConnectingOption] = []
+
+ droplet_spacer_inputs.append(ConnectingOption("default_component", ["1"]))
+
+ droplet_spacer_outputs: List[ConnectingOption] = []
+
+ droplet_spacer_outputs.append(ConnectingOption("default_component", ["2"]))
+
+ droplet_spacer_loadings: List[ConnectingOption] = []
+ droplet_spacer_carriers: List[ConnectingOption] = []
+
+ droplet_spacer = Primitive(
+ "DROPLET SPACER",
+ PrimitiveType.NETLIST,
+ r"""{
+ v1:PROCESS
+ }""",
+ False,
+ False,
+ droplet_spacer_inputs,
+ droplet_spacer_outputs,
+ droplet_spacer_loadings,
+ droplet_spacer_carriers,
+ "default-netlists/dropletspacer.mint",
+ )
+
+ library.add_operator_entry(droplet_spacer, InteractionType.TECHNOLOGY_PROCESS)
+
+ # YTREE - This is a procedural primitives
+
+ ytree = YTREE()
+
+ library.add_procedural_entry(ytree)
+
+ # Connections / Channels
+ connection_primitive = ConnectionPrimitive("CHANNEL")
+ library.add_connection_entry(connection_primitive)
+
+ return library
+
+
+# def generate_MARS_library() -> MappingLibrary:
+# # TODO - Programatically create each of the items necessary for the MARS
+# primitive library,
+# # we shall serialize them after experimentation
+
+# # mix_primitive = MappingOption()
+
+
+# # mix_primitive.init_single_component(mint_component)
+
+# # mix_primitive.add
+# pass
diff --git a/lfr/netlistgenerator/v2/mappingoption.py b/lfr/netlistgenerator/mappingoption.py
similarity index 75%
rename from lfr/netlistgenerator/v2/mappingoption.py
rename to lfr/netlistgenerator/mappingoption.py
index 44dffc6..d6ebd0b 100644
--- a/lfr/netlistgenerator/v2/mappingoption.py
+++ b/lfr/netlistgenerator/mappingoption.py
@@ -1,17 +1,18 @@
from typing import Optional
-from networkx import nx
+import networkx as nx
from lfr.fig.interaction import InteractionType
from lfr.netlistgenerator.mappinglibrary import Primitive
class MappingOption:
- def __init__(self, primitive: Primitive = None, subgraph_view=None) -> None:
-
+ def __init__(
+ self, primitive: Optional[Primitive] = None, subgraph_view=None
+ ) -> None:
self._primitive: Optional[Primitive] = primitive
- self.fig_subgraph: nx.DiGraph = subgraph_view
+ self.fig_subgraph: Optional[nx.DiGraph] = subgraph_view
# Figure out what computation needs to get done with this
self._interaction_type: Optional[InteractionType] = None
diff --git a/lfr/netlistgenerator/namegenerator.py b/lfr/netlistgenerator/namegenerator.py
index 8a8b201..4b4aec5 100644
--- a/lfr/netlistgenerator/namegenerator.py
+++ b/lfr/netlistgenerator/namegenerator.py
@@ -1,6 +1,7 @@
from typing import Dict
-from pymint import MINTComponent, MINTConnection, MINTDevice
+from parchmint import Component, Connection
+from pymint.mintdevice import MINTDevice
class NameGenerator:
@@ -15,7 +16,7 @@ class NameGenerator:
"""
def __init__(self) -> None:
- self._counter_dictionary = {}
+ self._counter_dictionary: Dict[str, int] = {}
# Key - Old NAme, Value - new name
self._cn_rename_map: Dict[str, Dict[str, str]] = {}
self._rename_map: Dict[str, str] = {}
@@ -43,7 +44,7 @@ def generate_name(self, technology_string: str) -> str:
self._counter_dictionary[technology_string] = 1
return "{}_{}".format(technology_string, 1).lower().replace(" ", "_")
- def rename_component(self, component: MINTComponent) -> str:
+ def rename_component(self, component: Component) -> str:
"""Renames the component
Renames the component and stores the old name->new name reference in
@@ -52,7 +53,7 @@ def rename_component(self, component: MINTComponent) -> str:
NOTE - Renames the ID of the component too
Args:
- component (MINTComponent): Component we want to rename
+ component (Component): Component we want to rename
Returns:
str: Returns the new name for the component
@@ -61,10 +62,10 @@ def rename_component(self, component: MINTComponent) -> str:
new_name = self.generate_name(component.entity)
self._rename_map[old_name] = new_name
component.name = new_name
- component.overwrite_id(new_name)
+ component.ID = new_name
return new_name
- def rename_cn_component(self, cn_id: str, component: MINTComponent) -> str:
+ def rename_cn_component(self, cn_id: str, component: Component) -> str:
"""Renames the Construction Node related component
Also stores what the corresponding rename map against the construction
@@ -72,7 +73,7 @@ def rename_cn_component(self, cn_id: str, component: MINTComponent) -> str:
Args:
cn_id (str): ConstructionNode ID
- component (MINTComponent): Component we want to rename
+ component (Component): Component we want to rename
Returns:
str: New name of the component
@@ -82,10 +83,10 @@ def rename_cn_component(self, cn_id: str, component: MINTComponent) -> str:
# self._rename_map[old_name] = new_name
self.store_cn_name(cn_id, old_name, new_name)
component.name = new_name
- component.overwrite_id(new_name)
+ component.ID = new_name
return new_name
- def rename_connection(self, connection: MINTConnection) -> str:
+ def rename_connection(self, connection: Connection) -> str:
"""Renames the connection
Also renames the name of the components in the source/sink(s)
@@ -94,7 +95,7 @@ def rename_connection(self, connection: MINTConnection) -> str:
Keeps track of the rename in internal datastruction
Args:
- connection (MINTConnection): Connection we want to rename
+ connection (Connection): Connection we want to rename
Returns:
str: New name of the connection
@@ -107,8 +108,11 @@ def rename_connection(self, connection: MINTConnection) -> str:
new_name = self.generate_name(connection.entity)
self._rename_map[old_name] = new_name
connection.name = new_name
- connection.overwrite_id(new_name)
+ connection.ID = new_name
+ # Check if Source is none
+ if connection.source is None:
+ raise ValueError("Source of connection {} is None".format(connection.ID))
# Rename source
connection.source.component = self._rename_map[connection.source.component]
@@ -118,7 +122,7 @@ def rename_connection(self, connection: MINTConnection) -> str:
return new_name
- def rename_cn_connection(self, cn_id: str, connection: MINTConnection) -> str:
+ def rename_cn_connection(self, cn_id: str, connection: Connection) -> str:
"""Renames connection with reference to construciton node
Uses the internal data struction to save the
@@ -126,7 +130,7 @@ def rename_cn_connection(self, cn_id: str, connection: MINTConnection) -> str:
Args:
cn_id (str): ConstructionNode ID
- connection (MINTConnection): Connection we need to rename
+ connection (Connection): Connection we need to rename
Returns:
str: New name of the connection
@@ -140,8 +144,11 @@ def rename_cn_connection(self, cn_id: str, connection: MINTConnection) -> str:
# self._rename_map[old_name] = new_name
self.store_cn_name(cn_id, old_name, new_name)
connection.name = new_name
- connection.overwrite_id(new_name)
+ connection.ID = new_name
+ # Check if Source is none
+ if connection.source is None:
+ raise ValueError("Source of connection {} is None".format(connection.ID))
# Rename source
connection.source.component = self.get_cn_name(
cn_id, connection.source.component
@@ -153,7 +160,7 @@ def rename_cn_connection(self, cn_id: str, connection: MINTConnection) -> str:
return new_name
- def rename_netlist(self, cn_id: str, device: MINTDevice) -> None:
+ def rename_netlist(self, cn_id: str, mint_device: MINTDevice) -> None:
"""Renames the entire netlist corresponding to a ConstructionNode
Calls upon all the different rename component, connection
@@ -163,10 +170,10 @@ def rename_netlist(self, cn_id: str, device: MINTDevice) -> None:
cn_id (str): ConstructionNode Id
device (MINTDevice): Device we want to rename
"""
- for component in device.components:
+ for component in mint_device.device.components:
self.rename_cn_component(cn_id, component)
- for connection in device.connections:
+ for connection in mint_device.device.connections:
self.rename_cn_connection(cn_id, connection)
def store_name(self, old_name: str, new_name: str) -> None:
diff --git a/lfr/netlistgenerator/netlist_generation.py b/lfr/netlistgenerator/netlist_generation.py
new file mode 100644
index 0000000..5742f01
--- /dev/null
+++ b/lfr/netlistgenerator/netlist_generation.py
@@ -0,0 +1,161 @@
+from typing import Dict, List
+
+import networkx as nx
+from parchmint import Target
+from parchmint.connection import Connection
+from pymint.mintdevice import MINTDevice
+
+from lfr.netlistgenerator.connectingoption import ConnectingOption
+from lfr.netlistgenerator.constructiongraph.constructiongraph import ConstructionGraph
+from lfr.netlistgenerator.mappinglibrary import MappingLibrary
+from lfr.netlistgenerator.namegenerator import NameGenerator
+from lfr.netlistgenerator.primitive import PrimitiveType
+
+
+def generate_device(
+ construction_graph: ConstructionGraph,
+ scaffhold_device: MINTDevice,
+ name_generator: NameGenerator,
+ mapping_library: MappingLibrary,
+) -> None:
+ # TODO - Generate the device
+ # Step 1 - go though each of the construction nodes and genrate the corresponding
+ # components
+ # Step 2 - generate the connections between the outputs to input on the connected
+ # construction nodes
+ # Step 3 - TODO - Generate the control network
+
+ cn_component_mapping: Dict[str, List[str]] = {}
+
+ node_ids = nx.dfs_preorder_nodes(construction_graph)
+ print("Nodes to Traverse:", node_ids)
+
+ # Go through the ordered nodes and start creating the components
+ for node_id in node_ids:
+ cn = construction_graph.get_construction_node(node_id)
+
+ # raise and error if the construction node has no primitive
+ if cn.primitive is None:
+ raise ValueError(f"Construction Node: {node_id} has no primitive")
+
+ # Generate the netlist based on the primitive type
+ if cn.primitive.type is PrimitiveType.COMPONENT:
+ # Generate the component
+ component = cn.primitive.get_default_component(
+ name_generator, scaffhold_device.device.layers[0]
+ )
+
+ # Add to the scaffhold device
+ scaffhold_device.device.add_component(component)
+
+ # Add to the component mapping
+ cn_component_mapping[node_id] = [component.ID]
+
+ elif cn.primitive.type is PrimitiveType.NETLIST:
+ netlist = cn.primitive.get_default_netlist(cn.ID, name_generator)
+
+ # Merge the netlist into the scaffhold device
+ scaffhold_device.device.merge_netlist(netlist)
+
+ # Add to the component mapping
+ cn_component_mapping[node_id] = [
+ component.ID for component in netlist.components
+ ]
+
+ # Go through the edges and connect the components using the inputs and outputs of
+ # the primitives
+ for source_cn_id, target_cn_id in construction_graph.edges:
+ source_cn = construction_graph.get_construction_node(source_cn_id)
+ target_cn = construction_graph.get_construction_node(target_cn_id)
+
+ # Get the output ConnectingOptions of the source cn
+ output_options = source_cn.output_options.copy()
+ input_options = target_cn.input_options.copy()
+
+ # Pop and make a connection between the output and the input
+ source_option = output_options.pop()
+ target_option = input_options.pop()
+
+ # Generate the target from the source option
+ source_targets = get_targets(
+ source_option, source_cn_id, name_generator, cn_component_mapping
+ )
+ target_targets = get_targets(
+ target_option, target_cn_id, name_generator, cn_component_mapping
+ )
+
+ # If there is 1 source and 1 target, then connect the components
+ if len(source_targets) == 1 and len(target_targets) == 1:
+ create_device_connection(
+ source_targets.pop(),
+ target_targets.pop(),
+ name_generator,
+ scaffhold_device,
+ mapping_library,
+ )
+
+ elif len(source_targets) == len(target_targets):
+ raise NotImplementedError("Bus targets not implemented")
+ elif len(source_targets) == 1 and len(target_targets) > 1:
+ raise NotImplementedError("Multiple targets not implemented")
+ elif len(source_targets) > 1 and len(target_targets) == 1:
+ raise NotImplementedError("Multiple sources not implemented")
+
+
+def create_device_connection(
+ source_target: Target,
+ target_target: Target,
+ name_generator: NameGenerator,
+ scaffhold_device: MINTDevice,
+ mapping_library: MappingLibrary,
+) -> None:
+ # TODO - Create the connection based on parameters from the connecting option
+ # Step 1 - Get the connection from the mapping library
+ # TODO: Create new method stubs to get the right connection primitives from the
+ # mapping library (this would need extra criteria that that will need evaulation
+ # in the future (RAMA Extension))
+ primitive = mapping_library.get_default_connection_entry()
+ # Step 2 - Create the connection in the device
+ connection_name = name_generator.generate_name(primitive.mint)
+ connection = Connection(
+ name=connection_name,
+ ID=connection_name,
+ entity=primitive.mint,
+ source=source_target,
+ sinks=[target_target],
+ layer=scaffhold_device.device.layers[
+ 0
+ ], # TODO - This will be replaced in the future when we introduce layer sharding
+ )
+ scaffhold_device.device.add_connection(connection)
+
+
+def get_targets(
+ option: ConnectingOption,
+ connection_node_id: str,
+ name_generator: NameGenerator,
+ cn_name_map,
+) -> List[Target]:
+ ret: List[Target] = []
+
+ if option.component_name is None:
+ # TODO: Clarify the logic for doing this later on and put it in the docstring
+ component_names = cn_name_map[connection_node_id]
+ else:
+ # TODO: Clarify the logic for doing this later on and put it in the docstring
+ old_name = option.component_name
+ component_name = name_generator.get_cn_name(connection_node_id, old_name)
+ component_names = [component_name]
+
+ for component_name in component_names:
+ for port_name in option.component_port:
+ # Check and make sure that the component name is valid
+ if component_name is None:
+ raise ValueError(
+ "Could not generate connection target for construction node"
+ f" {connection_node_id} since Port name is None"
+ )
+ target = Target(component_name, port_name)
+ ret.append(target)
+
+ return ret
diff --git a/lfr/netlistgenerator/netlistsizor.py b/lfr/netlistgenerator/netlistsizor.py
index 42b1903..040c027 100644
--- a/lfr/netlistgenerator/netlistsizor.py
+++ b/lfr/netlistgenerator/netlistsizor.py
@@ -1,4 +1,5 @@
from lfr.fig.interaction import InteractionType
+from lfr.postprocessor.constraints import ConstraintList
class NetlistSizor:
@@ -11,8 +12,7 @@ def __init__(self, netlist_generator):
self.blacklist_map = netlist_generator.blacklist_map
def size_netlist(self):
- from .dafdadapter import (
- ConstraintList,
+ from lfr.netlistgenerator.dafdadapter import (
DAFDSizingAdapter,
FunctionalConstraint,
GeometryConstraint,
diff --git a/lfr/netlistgenerator/v2/networkmappingoption.py b/lfr/netlistgenerator/networkmappingoption.py
similarity index 92%
rename from lfr/netlistgenerator/v2/networkmappingoption.py
rename to lfr/netlistgenerator/networkmappingoption.py
index 556732e..6072450 100644
--- a/lfr/netlistgenerator/v2/networkmappingoption.py
+++ b/lfr/netlistgenerator/networkmappingoption.py
@@ -1,7 +1,7 @@
from enum import Enum
+from lfr.netlistgenerator.mappingoption import MappingOption
from lfr.netlistgenerator.primitive import NetworkPrimitive
-from lfr.netlistgenerator.v2.mappingoption import MappingOption
class NetworkMappingOptionType(Enum):
diff --git a/lfr/netlistgenerator/packaged_libraries/dropx.py b/lfr/netlistgenerator/packaged_libraries/dropx.py
index ed4732e..128eb87 100644
--- a/lfr/netlistgenerator/packaged_libraries/dropx.py
+++ b/lfr/netlistgenerator/packaged_libraries/dropx.py
@@ -1,406 +1,405 @@
from lfr.fig.interaction import InteractionType
+from lfr.netlistgenerator.connectingoption import ConnectingOption
from lfr.netlistgenerator.mappinglibrary import MappingLibrary
from lfr.netlistgenerator.primitive import Primitive, PrimitiveType
-from lfr.netlistgenerator.v2.connectingoption import ConnectingOption
def generate_dropx_library() -> MappingLibrary:
-
library = MappingLibrary("dropX")
- # PORT
- port_inputs = []
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
-
- port_outputs = []
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
-
- port = Primitive(
- "PORT",
- PrimitiveType.COMPONENT,
- "IO",
- False,
- False,
- port_inputs,
- port_outputs,
- None,
- None,
- None,
- None,
- None,
- )
-
- library.add_io_entry(port)
-
- # PICO INJECTOR
-
- pico_injector_inputs = []
-
- pico_injector_inputs.append(ConnectingOption(None, [1]))
- pico_injector_inputs.append(ConnectingOption(None, [2]))
-
- pico_injector_outputs = []
-
- pico_injector_outputs.append(ConnectingOption(None, [3]))
-
- pico_injector_loadings = []
- pico_injector_carriers = []
-
- pico_injector = Primitive(
- "PICO INJECTOR",
- PrimitiveType.COMPONENT,
- "MIX",
- False,
- False,
- pico_injector_inputs,
- pico_injector_outputs,
- pico_injector_loadings,
- pico_injector_carriers,
- None,
- )
-
- library.add_operator_entry(pico_injector, InteractionType.MIX)
-
- # DROPLET ELECTROPHORESIS MERGER
-
- electrophoresis_merger_inputs = []
-
- electrophoresis_merger_inputs.append(ConnectingOption(None, [1]))
- electrophoresis_merger_inputs.append(ConnectingOption(None, [2]))
-
- electrophoresis_merger_outputs = []
-
- electrophoresis_merger_outputs.append(ConnectingOption(None, [3]))
-
- electrophoresis_merger_loadings = []
- electrophoresis_merger_carriers = []
-
- electrophoresis_merger = Primitive(
- "DROPLET ELECTROPHORESIS MERGER",
- PrimitiveType.COMPONENT,
- "MIX",
- False,
- False,
- electrophoresis_merger_inputs,
- electrophoresis_merger_outputs,
- electrophoresis_merger_loadings,
- electrophoresis_merger_carriers,
- None,
- )
-
- library.add_operator_entry(electrophoresis_merger, InteractionType.MIX)
-
- # DROPLET GENERATOR
-
- droplet_generator_inputs = []
-
- droplet_generator_inputs.append(ConnectingOption("default_component", [1]))
-
- droplet_generator_outputs = []
-
- droplet_generator_outputs.append(ConnectingOption("default_component", [3]))
-
- droplet_generator_loadings = []
- droplet_generator_carriers = []
-
- droplet_generator = Primitive(
- "NOZZLE DROPLET GENERATOR",
- PrimitiveType.NETLIST,
- "METER",
- False,
- False,
- droplet_generator_inputs,
- droplet_generator_outputs,
- droplet_generator_loadings,
- droplet_generator_carriers,
- "default-netlists/dropletgenerator.mint",
- ["droplet_size", "generation_rate"],
- [
- "orifice_size",
- "aspect_ratio",
- "capillary_number",
- "expansion_ratio",
- "flow_rate_ratio",
- "normalized_oil_inlet",
- "normalized_orifice_length",
- "normalized_water_inlet",
- ],
- )
+ # # PORT
+ # port_inputs = []
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+ # port_inputs.append(ConnectingOption(None, [None]))
+
+ # port_outputs = []
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+ # port_outputs.append(ConnectingOption(None, []))
+
+ # port = Primitive(
+ # "PORT",
+ # PrimitiveType.COMPONENT,
+ # "IO",
+ # False,
+ # False,
+ # port_inputs,
+ # port_outputs,
+ # None,
+ # None,
+ # None,
+ # None,
+ # None,
+ # )
+
+ # library.add_io_entry(port)
+
+ # # PICO INJECTOR
+
+ # pico_injector_inputs = []
+
+ # pico_injector_inputs.append(ConnectingOption(None, [1]))
+ # pico_injector_inputs.append(ConnectingOption(None, [2]))
+
+ # pico_injector_outputs = []
+
+ # pico_injector_outputs.append(ConnectingOption(None, [3]))
+
+ # pico_injector_loadings = []
+ # pico_injector_carriers = []
+
+ # pico_injector = Primitive(
+ # "PICO INJECTOR",
+ # PrimitiveType.COMPONENT,
+ # "MIX",
+ # False,
+ # False,
+ # pico_injector_inputs,
+ # pico_injector_outputs,
+ # pico_injector_loadings,
+ # pico_injector_carriers,
+ # None,
+ # )
+
+ # library.add_operator_entry(pico_injector, InteractionType.MIX)
+
+ # # DROPLET ELECTROPHORESIS MERGER
+
+ # electrophoresis_merger_inputs = []
+
+ # electrophoresis_merger_inputs.append(ConnectingOption(None, [1]))
+ # electrophoresis_merger_inputs.append(ConnectingOption(None, [2]))
+
+ # electrophoresis_merger_outputs = []
+
+ # electrophoresis_merger_outputs.append(ConnectingOption(None, [3]))
+
+ # electrophoresis_merger_loadings = []
+ # electrophoresis_merger_carriers = []
+
+ # electrophoresis_merger = Primitive(
+ # "DROPLET ELECTROPHORESIS MERGER",
+ # PrimitiveType.COMPONENT,
+ # "MIX",
+ # False,
+ # False,
+ # electrophoresis_merger_inputs,
+ # electrophoresis_merger_outputs,
+ # electrophoresis_merger_loadings,
+ # electrophoresis_merger_carriers,
+ # None,
+ # )
+
+ # library.add_operator_entry(electrophoresis_merger, InteractionType.MIX)
+
+ # # DROPLET GENERATOR
+
+ # droplet_generator_inputs = []
+
+ # droplet_generator_inputs.append(ConnectingOption("default_component", [1]))
+
+ # droplet_generator_outputs = []
+
+ # droplet_generator_outputs.append(ConnectingOption("default_component", [3]))
+
+ # droplet_generator_loadings = []
+ # droplet_generator_carriers = []
+
+ # droplet_generator = Primitive(
+ # "NOZZLE DROPLET GENERATOR",
+ # PrimitiveType.NETLIST,
+ # "METER",
+ # False,
+ # False,
+ # droplet_generator_inputs,
+ # droplet_generator_outputs,
+ # droplet_generator_loadings,
+ # droplet_generator_carriers,
+ # "default-netlists/dropletgenerator.mint",
+ # ["droplet_size", "generation_rate"],
+ # [
+ # "orifice_size",
+ # "aspect_ratio",
+ # "capillary_number",
+ # "expansion_ratio",
+ # "flow_rate_ratio",
+ # "normalized_oil_inlet",
+ # "normalized_orifice_length",
+ # "normalized_water_inlet",
+ # ],
+ # )
- library.add_operator_entry(droplet_generator, InteractionType.METER)
+ # library.add_operator_entry(droplet_generator, InteractionType.METER)
- droplet_merger_junction_inputs = []
+ # droplet_merger_junction_inputs = []
- droplet_merger_junction_inputs.append(ConnectingOption(None, [1]))
- droplet_merger_junction_inputs.append(ConnectingOption(None, [2]))
+ # droplet_merger_junction_inputs.append(ConnectingOption(None, [1]))
+ # droplet_merger_junction_inputs.append(ConnectingOption(None, [2]))
- droplet_merger_junction_outputs = []
+ # droplet_merger_junction_outputs = []
- droplet_merger_junction_outputs.append(ConnectingOption(None, [3]))
+ # droplet_merger_junction_outputs.append(ConnectingOption(None, [3]))
- droplet_merger_junction_loadings = []
- droplet_merger_junction_carriers = []
+ # droplet_merger_junction_loadings = []
+ # droplet_merger_junction_carriers = []
- droplet_merger_junction = Primitive(
- "DROPLET MERGER JUNCTION",
- PrimitiveType.COMPONENT,
- "MIX",
- False,
- False,
- droplet_merger_junction_inputs,
- droplet_merger_junction_outputs,
- droplet_merger_junction_loadings,
- droplet_merger_junction_carriers,
- None,
- )
+ # droplet_merger_junction = Primitive(
+ # "DROPLET MERGER JUNCTION",
+ # PrimitiveType.COMPONENT,
+ # "MIX",
+ # False,
+ # False,
+ # droplet_merger_junction_inputs,
+ # droplet_merger_junction_outputs,
+ # droplet_merger_junction_loadings,
+ # droplet_merger_junction_carriers,
+ # None,
+ # )
- library.add_operator_entry(droplet_merger_junction, InteractionType.MIX)
+ # library.add_operator_entry(droplet_merger_junction, InteractionType.MIX)
- # DROPLET MERGER CHANNEL
+ # # DROPLET MERGER CHANNEL
- droplet_merger_channel_inputs = []
+ # droplet_merger_channel_inputs = []
- droplet_merger_channel_inputs.append(ConnectingOption(None, [1]))
+ # droplet_merger_channel_inputs.append(ConnectingOption(None, [1]))
- droplet_merger_channel_outputs = []
+ # droplet_merger_channel_outputs = []
- droplet_merger_channel_outputs.append(ConnectingOption(None, [2]))
+ # droplet_merger_channel_outputs.append(ConnectingOption(None, [2]))
- droplet_merger_channel_loadings = []
- droplet_merger_channel_carriers = []
+ # droplet_merger_channel_loadings = []
+ # droplet_merger_channel_carriers = []
- droplet_merger_channel = Primitive(
- "DROPLET MERGER CHANNEL",
- PrimitiveType.COMPONENT,
- "MIX",
- False,
- False,
- droplet_merger_channel_inputs,
- droplet_merger_channel_outputs,
- droplet_merger_channel_loadings,
- droplet_merger_channel_carriers,
- None,
- )
+ # droplet_merger_channel = Primitive(
+ # "DROPLET MERGER CHANNEL",
+ # PrimitiveType.COMPONENT,
+ # "MIX",
+ # False,
+ # False,
+ # droplet_merger_channel_inputs,
+ # droplet_merger_channel_outputs,
+ # droplet_merger_channel_loadings,
+ # droplet_merger_channel_carriers,
+ # None,
+ # )
- library.add_operator_entry(droplet_merger_channel, InteractionType.MIX)
+ # library.add_operator_entry(droplet_merger_channel, InteractionType.MIX)
- # MIXER - CONTINOUS FLOW ONE
+ # # MIXER - CONTINOUS FLOW ONE
- cf_mixer_inputs = []
+ # cf_mixer_inputs = []
- cf_mixer_inputs.append(ConnectingOption(None, [1]))
- cf_mixer_inputs.append(ConnectingOption(None, [1]))
- cf_mixer_inputs.append(ConnectingOption(None, [1]))
- cf_mixer_inputs.append(ConnectingOption(None, [1]))
- cf_mixer_inputs.append(ConnectingOption(None, [1]))
- cf_mixer_inputs.append(ConnectingOption(None, [1]))
- cf_mixer_inputs.append(ConnectingOption(None, [1]))
- cf_mixer_inputs.append(ConnectingOption(None, [1]))
- cf_mixer_inputs.append(ConnectingOption(None, [1]))
- cf_mixer_inputs.append(ConnectingOption(None, [1]))
-
- cf_mixer_outputs = []
-
- cf_mixer_outputs.append(ConnectingOption(None, [2]))
-
- cf_mixer_loadings = []
- cf_mixer_carriers = []
-
- cf_mixer = Primitive(
- "MIXER",
- PrimitiveType.COMPONENT,
- "MIX",
- False,
- False,
- cf_mixer_inputs,
- cf_mixer_outputs,
- cf_mixer_loadings,
- cf_mixer_carriers,
- None,
- )
+ # cf_mixer_inputs.append(ConnectingOption(None, [1]))
+ # cf_mixer_inputs.append(ConnectingOption(None, [1]))
+ # cf_mixer_inputs.append(ConnectingOption(None, [1]))
+ # cf_mixer_inputs.append(ConnectingOption(None, [1]))
+ # cf_mixer_inputs.append(ConnectingOption(None, [1]))
+ # cf_mixer_inputs.append(ConnectingOption(None, [1]))
+ # cf_mixer_inputs.append(ConnectingOption(None, [1]))
+ # cf_mixer_inputs.append(ConnectingOption(None, [1]))
+ # cf_mixer_inputs.append(ConnectingOption(None, [1]))
+ # cf_mixer_inputs.append(ConnectingOption(None, [1]))
+
+ # cf_mixer_outputs = []
+
+ # cf_mixer_outputs.append(ConnectingOption(None, [2]))
+
+ # cf_mixer_loadings = []
+ # cf_mixer_carriers = []
+
+ # cf_mixer = Primitive(
+ # "MIXER",
+ # PrimitiveType.COMPONENT,
+ # "MIX",
+ # False,
+ # False,
+ # cf_mixer_inputs,
+ # cf_mixer_outputs,
+ # cf_mixer_loadings,
+ # cf_mixer_carriers,
+ # None,
+ # )
- library.add_operator_entry(cf_mixer, InteractionType.MIX)
+ # library.add_operator_entry(cf_mixer, InteractionType.MIX)
- # DROPLET SPLITTER
+ # # DROPLET SPLITTER
- droplet_splitter_inputs = []
+ # droplet_splitter_inputs = []
- droplet_splitter_inputs.append(ConnectingOption(None, [1]))
+ # droplet_splitter_inputs.append(ConnectingOption(None, [1]))
- droplet_splitter_outputs = []
+ # droplet_splitter_outputs = []
- droplet_splitter_outputs.append(ConnectingOption(None, [2]))
- droplet_splitter_outputs.append(ConnectingOption(None, [3]))
+ # droplet_splitter_outputs.append(ConnectingOption(None, [2]))
+ # droplet_splitter_outputs.append(ConnectingOption(None, [3]))
- droplet_splitter_loadings = []
- droplet_splitter_carriers = []
+ # droplet_splitter_loadings = []
+ # droplet_splitter_carriers = []
- droplet_splitter = Primitive(
- "DROPLET SPLITTER",
- PrimitiveType.COMPONENT,
- "DIVIDE",
- False,
- False,
- droplet_splitter_inputs,
- droplet_splitter_outputs,
- droplet_splitter_loadings,
- droplet_splitter_carriers,
- None,
- )
+ # droplet_splitter = Primitive(
+ # "DROPLET SPLITTER",
+ # PrimitiveType.COMPONENT,
+ # "DIVIDE",
+ # False,
+ # False,
+ # droplet_splitter_inputs,
+ # droplet_splitter_outputs,
+ # droplet_splitter_loadings,
+ # droplet_splitter_carriers,
+ # None,
+ # )
- library.add_operator_entry(droplet_splitter, InteractionType.DIVIDE)
+ # library.add_operator_entry(droplet_splitter, InteractionType.DIVIDE)
- # DROPLET CAPACITANCE SENSOR
+ # # DROPLET CAPACITANCE SENSOR
- droplet_capacitance_sensor_inputs = []
+ # droplet_capacitance_sensor_inputs = []
- droplet_capacitance_sensor_inputs.append(ConnectingOption(None, [1]))
+ # droplet_capacitance_sensor_inputs.append(ConnectingOption(None, [1]))
- droplet_capacitance_sensor_outputs = []
+ # droplet_capacitance_sensor_outputs = []
- droplet_capacitance_sensor_outputs.append(ConnectingOption(None, [2]))
+ # droplet_capacitance_sensor_outputs.append(ConnectingOption(None, [2]))
- droplet_capacitance_sensor_loadings = []
- droplet_capacitance_sensor_carriers = []
+ # droplet_capacitance_sensor_loadings = []
+ # droplet_capacitance_sensor_carriers = []
- droplet_capacitance_sensor = Primitive(
- "DROPLET CAPACITANCE SENSOR",
- PrimitiveType.COMPONENT,
- "PROCESS",
- False,
- False,
- droplet_capacitance_sensor_inputs,
- droplet_capacitance_sensor_outputs,
- droplet_capacitance_sensor_loadings,
- droplet_capacitance_sensor_carriers,
- None,
- )
+ # droplet_capacitance_sensor = Primitive(
+ # "DROPLET CAPACITANCE SENSOR",
+ # PrimitiveType.COMPONENT,
+ # "PROCESS",
+ # False,
+ # False,
+ # droplet_capacitance_sensor_inputs,
+ # droplet_capacitance_sensor_outputs,
+ # droplet_capacitance_sensor_loadings,
+ # droplet_capacitance_sensor_carriers,
+ # None,
+ # )
- library.add_operator_entry(
- droplet_capacitance_sensor, InteractionType.TECHNOLOGY_PROCESS
- )
+ # library.add_operator_entry(
+ # droplet_capacitance_sensor, InteractionType.TECHNOLOGY_PROCESS
+ # )
- # DROPLET FLUORESCENCE SENSOR
+ # # DROPLET FLUORESCENCE SENSOR
- droplet_fluorescence_sensor_inputs = []
+ # droplet_fluorescence_sensor_inputs = []
- droplet_fluorescence_sensor_inputs.append(ConnectingOption(None, [1]))
+ # droplet_fluorescence_sensor_inputs.append(ConnectingOption(None, [1]))
- droplet_fluorescence_sensor_outputs = []
+ # droplet_fluorescence_sensor_outputs = []
- droplet_fluorescence_sensor_outputs.append(ConnectingOption(None, [2]))
+ # droplet_fluorescence_sensor_outputs.append(ConnectingOption(None, [2]))
- droplet_fluorescence_sensor_loadings = []
- droplet_fluorescence_sensor_carriers = []
+ # droplet_fluorescence_sensor_loadings = []
+ # droplet_fluorescence_sensor_carriers = []
- droplet_fluorescence_sensor = Primitive(
- "DROPLET FLUORESCENCE SENSOR",
- PrimitiveType.COMPONENT,
- "PROCESS",
- False,
- False,
- droplet_fluorescence_sensor_inputs,
- droplet_fluorescence_sensor_outputs,
- droplet_fluorescence_sensor_loadings,
- droplet_fluorescence_sensor_carriers,
- None,
- )
+ # droplet_fluorescence_sensor = Primitive(
+ # "DROPLET FLUORESCENCE SENSOR",
+ # PrimitiveType.COMPONENT,
+ # "PROCESS",
+ # False,
+ # False,
+ # droplet_fluorescence_sensor_inputs,
+ # droplet_fluorescence_sensor_outputs,
+ # droplet_fluorescence_sensor_loadings,
+ # droplet_fluorescence_sensor_carriers,
+ # None,
+ # )
- library.add_operator_entry(
- droplet_fluorescence_sensor, InteractionType.TECHNOLOGY_PROCESS
- )
+ # library.add_operator_entry(
+ # droplet_fluorescence_sensor, InteractionType.TECHNOLOGY_PROCESS
+ # )
- # DROPLET LUMINESCENCE SENSOR
- droplet_luminescence_sensor_inputs = []
+ # # DROPLET LUMINESCENCE SENSOR
+ # droplet_luminescence_sensor_inputs = []
- droplet_luminescence_sensor_inputs.append(ConnectingOption(None, [1]))
+ # droplet_luminescence_sensor_inputs.append(ConnectingOption(None, [1]))
- droplet_luminescence_sensor_outputs = []
+ # droplet_luminescence_sensor_outputs = []
- droplet_luminescence_sensor_outputs.append(ConnectingOption(None, [2]))
+ # droplet_luminescence_sensor_outputs.append(ConnectingOption(None, [2]))
- droplet_luminescence_sensor_loadings = []
- droplet_luminescence_sensor_carriers = []
+ # droplet_luminescence_sensor_loadings = []
+ # droplet_luminescence_sensor_carriers = []
- droplet_luminescence_sensor = Primitive(
- "DROPLET CAPACITANCE SENSOR",
- PrimitiveType.COMPONENT,
- "PROCESS",
- False,
- False,
- droplet_luminescence_sensor_inputs,
- droplet_luminescence_sensor_outputs,
- droplet_luminescence_sensor_loadings,
- droplet_luminescence_sensor_carriers,
- None,
- )
+ # droplet_luminescence_sensor = Primitive(
+ # "DROPLET CAPACITANCE SENSOR",
+ # PrimitiveType.COMPONENT,
+ # "PROCESS",
+ # False,
+ # False,
+ # droplet_luminescence_sensor_inputs,
+ # droplet_luminescence_sensor_outputs,
+ # droplet_luminescence_sensor_loadings,
+ # droplet_luminescence_sensor_carriers,
+ # None,
+ # )
- library.add_operator_entry(
- droplet_luminescence_sensor, InteractionType.TECHNOLOGY_PROCESS
- )
+ # library.add_operator_entry(
+ # droplet_luminescence_sensor, InteractionType.TECHNOLOGY_PROCESS
+ # )
- # DROPLET SPACER
+ # # DROPLET SPACER
- droplet_spacer_inputs = []
+ # droplet_spacer_inputs = []
- droplet_spacer_inputs.append(ConnectingOption("default_component", [1]))
+ # droplet_spacer_inputs.append(ConnectingOption("default_component", [1]))
- droplet_spacer_outputs = []
+ # droplet_spacer_outputs = []
- droplet_spacer_outputs.append(ConnectingOption("default_component", [2]))
+ # droplet_spacer_outputs.append(ConnectingOption("default_component", [2]))
- droplet_spacer_loadings = []
- droplet_spacer_carriers = []
+ # droplet_spacer_loadings = []
+ # droplet_spacer_carriers = []
- droplet_spacer = Primitive(
- "DROPLET SPACER",
- PrimitiveType.NETLIST,
- "PROCESS",
- False,
- False,
- droplet_spacer_inputs,
- droplet_spacer_outputs,
- droplet_spacer_loadings,
- droplet_spacer_carriers,
- "default-netlists/dropletspacer.mint",
- )
-
- library.add_operator_entry(droplet_spacer, InteractionType.TECHNOLOGY_PROCESS)
+ # droplet_spacer = Primitive(
+ # "DROPLET SPACER",
+ # PrimitiveType.NETLIST,
+ # "PROCESS",
+ # False,
+ # False,
+ # droplet_spacer_inputs,
+ # droplet_spacer_outputs,
+ # droplet_spacer_loadings,
+ # droplet_spacer_carriers,
+ # "default-netlists/dropletspacer.mint",
+ # )
+
+ # library.add_operator_entry(droplet_spacer, InteractionType.TECHNOLOGY_PROCESS)
return library
diff --git a/lfr/netlistgenerator/primitive.py b/lfr/netlistgenerator/primitive.py
index 42c39ae..8103f9d 100644
--- a/lfr/netlistgenerator/primitive.py
+++ b/lfr/netlistgenerator/primitive.py
@@ -1,22 +1,22 @@
import copy
+import hashlib
from enum import Enum
from typing import List, Optional
-from pymint.mintcomponent import MINTComponent
+from parchmint import Component, Device, Layer, Params
from pymint.mintdevice import MINTDevice
-from pymint.mintlayer import MINTLayer
-from pymint.mintparams import MINTParams
from lfr import parameters
+from lfr.netlistgenerator.connectingoption import ConnectingOption
+from lfr.netlistgenerator.gen_strategies.genstrategy import GenStrategy
from lfr.netlistgenerator.namegenerator import NameGenerator
-from lfr.netlistgenerator.v2.connectingoption import ConnectingOption
-from lfr.netlistgenerator.v2.gen_strategies.genstrategy import GenStrategy
class PrimitiveType(Enum):
COMPONENT = 0
NETLIST = 1
PROCEDURAL = 2
+ CONNECTION = 3
class Primitive:
@@ -27,14 +27,14 @@ def __init__(
match_string: str = "",
is_storage: bool = False,
has_storage_control: bool = False,
- inputs: List[ConnectingOption] = None,
- outputs: List[ConnectingOption] = None,
+ inputs: Optional[List[ConnectingOption]] = None,
+ outputs: Optional[List[ConnectingOption]] = None,
loadings: Optional[List[ConnectingOption]] = None,
carriers: Optional[List[ConnectingOption]] = None,
default_netlist: Optional[str] = None,
- functional_input_params: List[str] = None,
- output_params: List[str] = None,
- user_defined_params: MINTParams = MINTParams({}),
+ functional_input_params: Optional[List[str]] = None,
+ output_params: Optional[List[str]] = None,
+ user_defined_params: Params = Params({}),
) -> None:
if inputs is None:
inputs = []
@@ -69,7 +69,16 @@ def __init__(
self._functional_input_params = functional_input_params
self._output_params = output_params
- self._user_defined_params: MINTParams = user_defined_params
+ self._user_defined_params: Params = user_defined_params
+
+ # Generate the UID for the primitive
+ self._uid = hashlib.md5(
+ f"{self._mint}_{self._match_string}".encode("utf-8")
+ ).hexdigest()
+
+ @property
+ def uid(self) -> str:
+ return self._uid
@property
def type(self) -> PrimitiveType:
@@ -79,18 +88,38 @@ def type(self) -> PrimitiveType:
def mint(self) -> str:
return self._mint
+ @property
+ def match_string(self) -> str:
+ return self._match_string
+
def export_inputs(self, subgraph) -> List[ConnectingOption]:
+ # TODO - Figure out how to map connecting options to match string nodes
+ print(
+ "Warning: Implment how the connecting option is mapped to match string node"
+ )
return [copy.copy(c) for c in self._inputs]
def export_outputs(self, subgraph) -> List[ConnectingOption]:
+ # TODO - Figure out how to map connecting options to match string nodes
+ print(
+ "Warning: Implment how the connecting option is mapped to match string node"
+ )
return [copy.copy(c) for c in self._outputs]
def export_loadings(self, subgraph) -> Optional[List[ConnectingOption]]:
+ # TODO - Figure out how to map connecting options to match string nodes
+ print(
+ "Warning: Implment how the connecting option is mapped to match string node"
+ )
if self._loadings is None:
return None
return [copy.copy(c) for c in self._loadings]
def export_carriers(self, subgraph) -> Optional[List[ConnectingOption]]:
+ # TODO - Figure out how to map connecting options to match string nodes
+ print(
+ "Warning: Implment how the connecting option is mapped to match string node"
+ )
if self._carriers is None:
return None
return [copy.copy(c) for c in self._carriers]
@@ -107,41 +136,66 @@ def inverse_design_query_params(self):
def output_params(self):
return self._output_params
- def get_default_component(
- self, name_gen: NameGenerator, layer: MINTLayer
- ) -> MINTComponent:
+ def get_default_component(self, name_gen: NameGenerator, layer: Layer) -> Component:
+ """Gets the default component for the primitive
+
+ Utilizes the NameGenerator instance to generate a new component instance of
+ the corresponding MINT type
+
+ Args:
+ name_gen (NameGenerator): NameGenerator instance that will generate the
+ new name for the component
+ layer (Layer): Layer object in which the component exists
+
+ Raises:
+ Exception: Raises an exception when the entry is not of the type COMPONENT
+
+ Returns:
+ Component: New component object
+ """
if self.type is not PrimitiveType.COMPONENT:
raise Exception("Cannot execute this method for this kind of a primitive")
name = name_gen.generate_name(self.mint)
- mc = MINTComponent(name, self.mint, {}, [layer])
+ mc = Component(
+ name=name, ID=name, entity=self.mint, params=Params({}), layers=[layer]
+ )
return mc
- def get_default_netlist(self, cn_id: str, name_gen: NameGenerator) -> MINTDevice:
+ def get_default_netlist(self, cn_id: str, name_gen: NameGenerator) -> Device:
"""Returns the default netlist for the primitive
Args:
- cn_id (str): ID of the construction node so that we can prefix the id's of all the components that are part of the default netlist
- name_gen (NameGenerator): A namegenerator instance that is used for the globally for synthesizing the design
+ cn_id (str): ID of the construction node so that we can prefix the id's of
+ all the components that are part of the default netlist
+ name_gen (NameGenerator): A namegenerator instance that is used for the
+ globally for synthesizing the design
Returns:
MINTDevice: Default netlist of whatever the primitive is
"""
if self.type is not PrimitiveType.NETLIST:
raise Exception("Cannot execute this method for this kind of a primitive")
-
+ if self._default_netlist is None:
+ raise Exception(
+ "Cannot parse MINT file for primitive {} since default netlist"
+ " parameter is set to None".format(self.mint)
+ )
default_mint_file = parameters.LIB_DIR.joinpath(self._default_netlist).resolve()
- device = MINTDevice.from_mint_file(str(default_mint_file))
+ mint_device = MINTDevice.from_mint_file(str(default_mint_file))
- if device is None:
+ if mint_device is None:
raise Exception(
"Unable to parse MINT file: {} for construction node {}".format(
str(default_mint_file), cn_id
)
)
- name_gen.rename_netlist(cn_id, device)
+ name_gen.rename_netlist(cn_id, mint_device)
# Return the default netlist
- return device
+ return mint_device.device
+
+ def __hash__(self) -> int:
+ return hash("{}_{}".format(self.mint, self.match_string))
class ProceduralPrimitive(Primitive):
@@ -158,7 +212,7 @@ def __init__(
default_netlist: Optional[str],
functional_input_params: List[str],
output_params: List[str],
- user_defined_params: MINTParams,
+ user_defined_params: Params = Params({}),
) -> None:
super().__init__(
mint=mint,
@@ -188,14 +242,12 @@ def export_loadings(self, subgraph) -> Optional[List[ConnectingOption]]:
def export_carriers(self, subgraph) -> Optional[List[ConnectingOption]]:
raise NotImplementedError()
- def get_default_component(
- self, name_gen: NameGenerator, layer: MINTLayer
- ) -> MINTComponent:
+ def get_default_component(self, name_gen: NameGenerator, layer: Layer) -> Component:
raise NotImplementedError()
def get_procedural_component(
- self, name_gen: NameGenerator, layer: MINTLayer
- ) -> MINTComponent:
+ self, name_gen: NameGenerator, layer: Layer
+ ) -> Component:
raise NotImplementedError()
def generate_input_connectingoptions(self, subgraph_view) -> List[ConnectingOption]:
@@ -203,7 +255,8 @@ def generate_input_connectingoptions(self, subgraph_view) -> List[ConnectingOpti
be connected to the primitive
Args:
- subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid Interaction Graph
+ subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid
+ Interaction Graph
Raises:
NotImplementedError: Raised when its not implemented
@@ -220,8 +273,8 @@ def generate_output_connectingoptions(
be connected to the primitive
Args:
- subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid Interaction Graph
-
+ subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid
+ Interaction Graph
Raises:
NotImplementedError: Raised when its not implemented
@@ -238,7 +291,8 @@ def generate_carrier_connectingoptions(
be connected to the primitive
Args:
- subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid Interaction Graph
+ subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid
+ Interaction Graph
Raises:
NotImplementedError: Raised when its not implemented
@@ -255,7 +309,8 @@ def generate_loading_connectingoptions(
be connected to the primitive
Args:
- subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid Interaction Graph
+ subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid
+ Interaction Graph
Raises:
NotImplementedError: Raised when its not implemented
@@ -284,13 +339,14 @@ def __init__(self, fig_subgraph_view, gen_strategy: GenStrategy) -> None:
# Write methods that will utilize the subgraph view to generate the
# netlist
self._fig_subgraph_view = fig_subgraph_view
- self._netlist: Optional[MINTDevice] = None
+ self._default_netlist: Optional[MINTDevice] = None
def generate_netlist(self) -> None:
- """Generates the netlist for the given network primitive, this method generates the flow
- network, input , output, carriers and loadings into the primitve properties
+ """Generates the netlist for the given network primitive, this method generates
+ the flow network, input , output, carriers and loadings into the primitve
+ properties
"""
- self._netlist = self._gen_strategy.generate_flow_network(
+ self._default_netlist = self._gen_strategy.generate_flow_network(
self._fig_subgraph_view
)
self._inputs = self._gen_strategy.generate_input_connectingoptions(
@@ -306,12 +362,14 @@ def generate_netlist(self) -> None:
self._fig_subgraph_view
)
- def get_default_netlist(self, cn_id: str, name_gen: NameGenerator) -> MINTDevice:
+ def get_default_netlist(self, cn_id: str, name_gen: NameGenerator) -> Device:
"""Returns the default netlist for the primitive
Args:
- cn_id (str): ID of the construction node so that we can prefix the id's of all the components that are part of the default netlist
- name_gen (NameGenerator): A namegenerator instance that is used for the globally for synthesizing the design
+ cn_id (str): ID of the construction node so that we can prefix the id's of
+ all the components that are part of the default netlist
+ name_gen (NameGenerator): A namegenerator instance that is used for the
+ globally for synthesizing the design
Raises:
Exception: Raised when there is no defualt netlist is generated
@@ -319,10 +377,10 @@ def get_default_netlist(self, cn_id: str, name_gen: NameGenerator) -> MINTDevice
Returns:
MINTDevice: Default netlist of whatever the primitive is
"""
- if self._netlist is None:
+ if self._default_netlist is None:
raise Exception("No default netlist present for the primitive")
# Utilise the subgraph view to decide how you want to generate a netlist
# Load all the inputs and outputs based on that information
- name_gen.rename_netlist(cn_id, self._netlist)
- return self._netlist
+ name_gen.rename_netlist(cn_id, self._default_netlist)
+ return self._default_netlist.device
diff --git a/lfr/netlistgenerator/v2/procedural_component_algorithms/gradient_generator.py b/lfr/netlistgenerator/procedural_component_algorithms/gradient_generator.py
similarity index 90%
rename from lfr/netlistgenerator/v2/procedural_component_algorithms/gradient_generator.py
rename to lfr/netlistgenerator/procedural_component_algorithms/gradient_generator.py
index a1c41b6..6ede9ed 100644
--- a/lfr/netlistgenerator/v2/procedural_component_algorithms/gradient_generator.py
+++ b/lfr/netlistgenerator/procedural_component_algorithms/gradient_generator.py
@@ -1,7 +1,7 @@
from typing import List
+from lfr.netlistgenerator.connectingoption import ConnectingOption
from lfr.netlistgenerator.primitive import ProceduralPrimitive
-from lfr.netlistgenerator.v2.connectingoption import ConnectingOption
class GRADIENTGENERATOR(ProceduralPrimitive):
@@ -18,7 +18,8 @@ def generate_input_connectingoptions(self, subgraph_view) -> List[ConnectingOpti
be connected to the primitive
Args:
- subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid Interaction Graph
+ subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid
+ Interaction Graph
Raises:
NotImplementedError: Raised when its not implemented
@@ -35,7 +36,8 @@ def generate_output_connectingoptions(
be connected to the primitive
Args:
- subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid Interaction Graph
+ subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid
+ Interaction Graph
Raises:
@@ -53,7 +55,8 @@ def generate_carrier_connectingoptions(
be connected to the primitive
Args:
- subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid Interaction Graph
+ subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid
+ Interaction Graph
Raises:
NotImplementedError: Raised when its not implemented
@@ -70,7 +73,8 @@ def generate_loading_connectingoptions(
be connected to the primitive
Args:
- subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid Interaction Graph
+ subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid
+ Interaction Graph
Raises:
NotImplementedError: Raised when its not implemented
diff --git a/lfr/netlistgenerator/v2/procedural_component_algorithms/mux.py b/lfr/netlistgenerator/procedural_component_algorithms/mux.py
similarity index 95%
rename from lfr/netlistgenerator/v2/procedural_component_algorithms/mux.py
rename to lfr/netlistgenerator/procedural_component_algorithms/mux.py
index 2b1937a..cde9349 100644
--- a/lfr/netlistgenerator/v2/procedural_component_algorithms/mux.py
+++ b/lfr/netlistgenerator/procedural_component_algorithms/mux.py
@@ -1,7 +1,7 @@
from typing import List
+from lfr.netlistgenerator.connectingoption import ConnectingOption
from lfr.netlistgenerator.primitive import ProceduralPrimitive
-from lfr.netlistgenerator.v2.connectingoption import ConnectingOption
class MUX(ProceduralPrimitive):
@@ -18,7 +18,8 @@ def generate_input_connectingoptions(self, subgraph_view) -> List[ConnectingOpti
be connected to the primitive
Args:
- subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid Interaction Graph
+ subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid
+ Interaction Graph
Raises:
NotImplementedError: Raised when its not implemented
diff --git a/lfr/netlistgenerator/v2/procedural_component_algorithms/mux3d.py b/lfr/netlistgenerator/procedural_component_algorithms/mux3d.py
similarity index 92%
rename from lfr/netlistgenerator/v2/procedural_component_algorithms/mux3d.py
rename to lfr/netlistgenerator/procedural_component_algorithms/mux3d.py
index d9662cd..dd022f1 100644
--- a/lfr/netlistgenerator/v2/procedural_component_algorithms/mux3d.py
+++ b/lfr/netlistgenerator/procedural_component_algorithms/mux3d.py
@@ -1,7 +1,7 @@
from typing import List
+from lfr.netlistgenerator.connectingoption import ConnectingOption
from lfr.netlistgenerator.primitive import ProceduralPrimitive
-from lfr.netlistgenerator.v2.connectingoption import ConnectingOption
class MUX3D(ProceduralPrimitive):
@@ -18,7 +18,8 @@ def generate_input_connectingoptions(self, subgraph_view) -> List[ConnectingOpti
be connected to the primitive
Args:
- subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid Interaction Graph
+ subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid
+ Interaction Graph
Raises:
NotImplementedError: Raised when its not implemented
@@ -53,7 +54,8 @@ def generate_carrier_connectingoptions(
be connected to the primitive
Args:
- subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid Interaction Graph
+ subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid
+ Interaction Graph
Raises:
NotImplementedError: Raised when its not implemented
@@ -70,7 +72,8 @@ def generate_loading_connectingoptions(
be connected to the primitive
Args:
- subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid Interaction Graph
+ subgraph_view (networkx.Graph.subgraph): A subgraph view of the Fluid
+ Interaction Graph
Raises:
NotImplementedError: Raised when its not implemented
diff --git a/lfr/netlistgenerator/v2/procedural_component_algorithms/transposer.py b/lfr/netlistgenerator/procedural_component_algorithms/transposer.py
similarity index 97%
rename from lfr/netlistgenerator/v2/procedural_component_algorithms/transposer.py
rename to lfr/netlistgenerator/procedural_component_algorithms/transposer.py
index a3200df..fe37c1a 100644
--- a/lfr/netlistgenerator/v2/procedural_component_algorithms/transposer.py
+++ b/lfr/netlistgenerator/procedural_component_algorithms/transposer.py
@@ -1,7 +1,7 @@
from typing import List
+from lfr.netlistgenerator.connectingoption import ConnectingOption
from lfr.netlistgenerator.primitive import ProceduralPrimitive
-from lfr.netlistgenerator.v2.connectingoption import ConnectingOption
class TRANSPOSER(ProceduralPrimitive):
diff --git a/lfr/netlistgenerator/v2/procedural_component_algorithms/tree.py b/lfr/netlistgenerator/procedural_component_algorithms/tree.py
similarity index 97%
rename from lfr/netlistgenerator/v2/procedural_component_algorithms/tree.py
rename to lfr/netlistgenerator/procedural_component_algorithms/tree.py
index 7569f96..0e5dc5d 100644
--- a/lfr/netlistgenerator/v2/procedural_component_algorithms/tree.py
+++ b/lfr/netlistgenerator/procedural_component_algorithms/tree.py
@@ -1,7 +1,7 @@
from typing import List
+from lfr.netlistgenerator.connectingoption import ConnectingOption
from lfr.netlistgenerator.primitive import ProceduralPrimitive
-from lfr.netlistgenerator.v2.connectingoption import ConnectingOption
class TREE(ProceduralPrimitive):
diff --git a/lfr/netlistgenerator/v2/procedural_component_algorithms/ytree.py b/lfr/netlistgenerator/procedural_component_algorithms/ytree.py
similarity index 93%
rename from lfr/netlistgenerator/v2/procedural_component_algorithms/ytree.py
rename to lfr/netlistgenerator/procedural_component_algorithms/ytree.py
index 0b28874..3009e97 100644
--- a/lfr/netlistgenerator/v2/procedural_component_algorithms/ytree.py
+++ b/lfr/netlistgenerator/procedural_component_algorithms/ytree.py
@@ -1,10 +1,10 @@
from typing import List, Optional
-from pymint import MINTComponent, MINTLayer
+from parchmint import Component, Layer, Params
+from lfr.netlistgenerator.connectingoption import ConnectingOption
from lfr.netlistgenerator.namegenerator import NameGenerator
from lfr.netlistgenerator.primitive import ProceduralPrimitive
-from lfr.netlistgenerator.v2.connectingoption import ConnectingOption
class YTREE(ProceduralPrimitive):
@@ -62,8 +62,8 @@ def export_carriers(self, subgraph) -> Optional[List[ConnectingOption]]:
return None
def get_procedural_component(
- self, name_gen: NameGenerator, layer: MINTLayer, subgraph
- ) -> MINTComponent:
+ self, name_gen: NameGenerator, layer: Layer, subgraph
+ ) -> Component:
name = name_gen.generate_name(self.mint)
params = {}
# Calculate param values based on the subgraph
@@ -77,7 +77,9 @@ def get_procedural_component(
params["width"] = 5
params["height"] = 5
params["stageLength"] = 5
- mc = MINTComponent(name, self.mint, params, [layer])
+ mc = Component(
+ ID=name, name=name, entity=self.mint, params=Params(params), layers=[layer]
+ )
return mc
def generate_input_connectingoptions(self, subgraph_view) -> List[ConnectingOption]:
diff --git a/lfr/netlistgenerator/v2/gen_strategies/dummy.py b/lfr/netlistgenerator/v2/gen_strategies/dummy.py
deleted file mode 100644
index e5935fe..0000000
--- a/lfr/netlistgenerator/v2/gen_strategies/dummy.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
-from lfr.netlistgenerator.v2.constructiongraph import ConstructionGraph
-from lfr.netlistgenerator.v2.gen_strategies.genstrategy import GenStrategy
-from lfr.netlistgenerator.v2.mappingoption import MappingOption
-
-
-class DummyStrategy(GenStrategy):
- def __init__(
- self, construction_graph: ConstructionGraph, fig: FluidInteractionGraph
- ) -> None:
- super().__init__(construction_graph, fig)
-
- def reduce_mapping_options(self) -> None:
- super().reduce_mapping_options()
-
- @staticmethod
- def get_flow_flow_mapping_option(subgraph_view) -> MappingOption:
- return None
diff --git a/lfr/netlistgenerator/v2/gen_strategies/mars.py b/lfr/netlistgenerator/v2/gen_strategies/mars.py
deleted file mode 100644
index b21135d..0000000
--- a/lfr/netlistgenerator/v2/gen_strategies/mars.py
+++ /dev/null
@@ -1,24 +0,0 @@
-from typing import overload
-
-from lfr.netlistgenerator.v2.constructiongraph import ConstructionGraph
-from lfr.netlistgenerator.v2.gen_strategies.genstrategy import GenStrategy
-
-
-class MARSStrategy(GenStrategy):
- def __init__(self, construction_graph: ConstructionGraph) -> None:
- super().__init__(construction_graph)
-
- def reduce_mapping_options(self) -> None:
- # TODO - Implement Generalized Ali Strategy 1
-
- # Dummy strategy
- for cn in [v for k, v in self._construction_nodes.items()]:
- print(len(cn.mapping_options))
- # Remove the extra mappings
- del cn.mapping_options[1 : len(cn.mapping_options)]
- print(len(cn.mapping_options))
- pass
-
- @overload
- def size_netlist():
- super()
diff --git a/lfr/notes.md b/lfr/notes.md
new file mode 100644
index 0000000..24351f1
--- /dev/null
+++ b/lfr/notes.md
@@ -0,0 +1,29 @@
+# Gen Strategys:
+
+
+## DropX Flow Validation Rules:
+
+### Rule 1 -
+
+The first level of % should be mapping to a Droplet Generator
+
+### Rule 2 –
+
+Any +-, distribute nodes before % should be in continuous flow
+
+### (Incorrect) Rule 3 -
+
+Any Remetering (%) should require a droplet breakdown and regeneration
+
+### Rule 4 –
+
+Distribute network post Metering stage should be mapped to different kinds of separator / selection/ storage networks
+
+### Rule 5 –
+
+If plus is shown between node that has % in pred and non % in pred, then its pico injection
+
+### Rule 6 –
+
+If plus is sown between two nodes that has % in pred, then its droplet merging
+
diff --git a/lfr/parameters.py b/lfr/parameters.py
index 9e414fa..e365e24 100644
--- a/lfr/parameters.py
+++ b/lfr/parameters.py
@@ -6,3 +6,4 @@
LFR_DIR = pathlib.Path(lfr.__file__).parent.parent.absolute()
LIB_DIR = LFR_DIR.joinpath("library")
OUTPUT_DIR = LFR_DIR.joinpath("output")
+PREPROCESSOR_DUMP_FILE_NAME = "pre_processor_dump.lfr"
diff --git a/lfr/postProcessListener.py b/lfr/postProcessListener.py
index 2a9a1df..49b2726 100644
--- a/lfr/postProcessListener.py
+++ b/lfr/postProcessListener.py
@@ -1,6 +1,6 @@
from typing import Dict, List
-from lfr.antlrgen.lfrXParser import lfrXParser
+from lfr.antlrgen.lfr.lfrXParser import lfrXParser
from lfr.fig.fignode import FIGNode
from lfr.fig.interaction import FluidProcessInteraction, Interaction
from lfr.moduleinstanceListener import ModuleInstanceListener
@@ -24,7 +24,8 @@ def __init__(self) -> None:
def enterPerformancedirective(self, ctx: lfrXParser.PerformancedirectiveContext):
super().enterPerformancedirective(ctx)
# TODO - Make a list of all the nodes previous
- fig = self.currentModule.FIG
+ # TODO - Check is this needs to be utilized in the future
+ # fig = self.currentModule.FIG
# Update the previous list of nodes
self.__make_prev_fig_nodes_list()
@@ -40,7 +41,7 @@ def enterPerformancedirective(self, ctx: lfrXParser.PerformancedirectiveContext)
# mapping.operator = operator
self._current_mappings[operator] = mapping
- for constraint in ctx.constraint():
+ for constraint in ctx.constraint(): # type: ignore
param_name = constraint.ID().getText()
conditional_operator = constraint.operator.text
value = float(constraint.number().getText())
@@ -145,20 +146,20 @@ def exitAssignstat(self, ctx: lfrXParser.AssignstatContext):
# to the fig (get the inputs and output nodes from the LHS and RHS)
if "assign" in self._current_mappings.keys():
# Get the LHS and RHS nodes here
- lhs = self._lhs_store
- rhs = self._rhs_store
+ lhs: List[FIGNode] = self._lhs_store
+ rhs: List[FIGNode] = self._rhs_store
# Check if there is an `assign` mapping
if "assign" in self._current_mappings.keys():
mapping = self._current_mappings["assign"]
# Now add the LHS and RHS nodes into the mapping
- mapping_instance = NetworkMapping()
+ network_mapping_instance = NetworkMapping()
for node in rhs:
- mapping_instance.input_nodes.append(node)
+ network_mapping_instance.input_nodes.append(node)
for node in lhs:
- mapping_instance.output_nodes.append(node)
+ network_mapping_instance.output_nodes.append(node)
- mapping.instances.append(mapping_instance)
+ mapping.instances.append(network_mapping_instance)
# TODO - Go through the `nodes_of_interest` and then check to see
# if any of the nodes have the corresponding mappings in the cache
@@ -178,6 +179,8 @@ def exitAssignstat(self, ctx: lfrXParser.AssignstatContext):
self.__clear_mappings()
def __make_prev_fig_nodes_list(self):
+ if self.currentModule is None:
+ raise ValueError("No module found")
fig = self.currentModule.FIG
self._prev_node_list = []
self._after_node_list = []
@@ -185,6 +188,8 @@ def __make_prev_fig_nodes_list(self):
self._prev_node_list.append(node)
def __find_new_fig_nodes(self) -> List[FIGNode]:
+ if self.currentModule is None:
+ raise ValueError("No module found")
fig = self.currentModule.FIG
for node in fig.nodes:
self._after_node_list.append(node)
@@ -196,5 +201,7 @@ def __find_new_fig_nodes(self) -> List[FIGNode]:
return [fig.get_fignode(n) for n in nodes_of_interest]
def __clear_mappings(self) -> None:
+ if self.currentModule is None:
+ raise ValueError("No module found")
self.currentModule.mappings.extend(self._current_mappings.values())
self._current_mappings.clear()
diff --git a/lfr/postprocessor/constraints.py b/lfr/postprocessor/constraints.py
index 6f68218..1838f44 100644
--- a/lfr/postprocessor/constraints.py
+++ b/lfr/postprocessor/constraints.py
@@ -1,6 +1,7 @@
+from enum import Enum
from typing import List, Optional
-from pymint import MINTComponent
+from parchmint import Component
"""
# TODO - Generate the constraints in the right way:
@@ -36,54 +37,78 @@
"""
+class ConstriantType(Enum):
+ MIN = "MIN"
+ MAX = "MAX"
+ TARGET = "TARGET"
+
+
class Constraint:
+ """Base Constraints Class that accepts the different
+ kinds of constraints that will be used throughout the
+ postprocessing.
+
+ Individual constraints are currently not uniquely identifyable
+ Generate the constraint and set the corresponding min max target values
+
+ TODO - Maybe simplify the interfacet to automatically check the constraint
+ type while retrieving data
+ """
+
def __init__(self) -> None:
- self.__constraint_key = None
+ # This will always be something
+ self._constraint_key = ""
+
+ # Constraint Type that we will use in the future
+ self._constraint_type: ConstriantType = ConstriantType.TARGET
# Store here if its '='
# Also store here when its '<=' and '>='
- self.__target_value = None
+ self._target_value: Optional[float] = None
# Store here if its '>'
- self.__min_value = None
+ self._min_value: Optional[float] = None
# Store here if its '<'
- self.__max_value = None
+ self._max_value: Optional[float] = None
- self.__unit_string: Optional[str] = None
+ self._unit_string: Optional[str] = None
@property
def unit(self) -> Optional[str]:
- return self.__unit_string
+ return self._unit_string
@unit.setter
def unit(self, value: str) -> None:
- self.__unit_string = value
+ self._unit_string = value
@property
def key(self):
- return self.__constraint_key
+ return self._constraint_key
def add_target_value(self, key: str, value: float) -> None:
- self.__target_value = value
- self.__constraint_key = key
+ self._constraint_type = ConstriantType.TARGET
+ self._target_value = value
+ self._constraint_key = key
- def get_target_value(self):
- return self.__target_value
+ def get_target_value(self) -> Optional[float]:
+ return self._target_value
def add_min_value(self, key: str, value: float) -> None:
- self.__min_value = value
- self.__constraint_key = key
+ self._constraint_type = ConstriantType.MIN
+ self._min_value = value
+ self._constraint_key = key
- def get_min_value(self):
- return self.__min_value
+ def get_min_value(self) -> Optional[float]:
+ return self._min_value
def add_max_value(self, key: str, value: float) -> None:
- self.__max_value = value
- self.__constraint_key = key
+ self._constraint_type = ConstriantType.MAX
+ self._max_value = value
+ self._constraint_key = key
- def get_max_value(self):
- return self.__max_value
+ def get_max_value(self) -> Optional[float]:
+ return self._max_value
class PerformanceConstraint(Constraint):
@@ -102,22 +127,31 @@ def __init__(self) -> None:
class MaterialConstraint(Constraint):
- def __init__(self):
+ def __init__(self) -> None:
super().__init__()
class ConstraintList:
- def __init__(self, component: MINTComponent):
+ """Stores the constraints for a specific component
+
+ This is a mapping between a component and its constraints
+ """
+
+ def __init__(self, component: Component):
+ """Creates a new instance of a constraint list
+
+ Args:
+ component (Component): Component against which we want to store the constraints
+ """
super().__init__()
self.__constraints: List[Constraint] = []
- self.__component: Optional[MINTComponent] = component
+ self.__component: Optional[Component] = component
def add_constraint(self, constraint: Constraint) -> None:
- constraint = FunctionalConstraint()
self.__constraints.append(constraint)
@property
- def component(self) -> Optional[MINTComponent]:
+ def component(self) -> Optional[Component]:
return self.__component
def __len__(self):
diff --git a/lfr/preprocessor.py b/lfr/preprocessor.py
index a700a75..8da023f 100644
--- a/lfr/preprocessor.py
+++ b/lfr/preprocessor.py
@@ -1,45 +1,59 @@
import re
import sys
from pathlib import Path
-from typing import List
+from typing import Dict, List
import networkx as nx
from antlr4.CommonTokenStream import CommonTokenStream
from antlr4.FileStream import FileStream
-from lfr.antlrgen.lfrXLexer import lfrXLexer
-from lfr.antlrgen.lfrXParser import lfrXParser
+from lfr.antlrgen.lfr.lfrXLexer import lfrXLexer
+from lfr.antlrgen.lfr.lfrXParser import lfrXParser
+from lfr.parameters import PREPROCESSOR_DUMP_FILE_NAME
IMPORT_FILE_PATTERN = r"(`import\s+\"(\w+.lfr)\")"
class PreProcessor:
- def __init__(self, file_list: List[str]) -> None:
- self.resolved_paths = {}
- self.full_text = {}
+ def __init__(self, file_list: List[str], lib_dir_list: List[str] = []) -> None:
+ """Instantiates a new instance of the preprocessor
+
+ Args:
+ file_list (List[str]): List of files to be preprocessed
+ lib_dir_list (List[str], optional): Directory path for the library. Defaults to [].
+ """
+ self.resolved_paths: Dict[str, Path] = {}
+ self.full_text: Dict[str, str] = {}
self.text_dump = None
- for file_path in file_list:
+ self._lib_file_list: Dict[str, str] = {} # Stores file path to file
+
+ print("Loading all LFR Files from lib Directories:")
+ if lib_dir_list is not None:
+ for dir_ref in lib_dir_list:
+ print("-- Loading form path {}".format(dir_ref))
+ path = Path(dir_ref).resolve()
+
+ for file in path.rglob("*.lfr"):
+ path_object = Path(file)
+ full_path = path_object.resolve()
+ print("Storing into library: {}".format(full_path))
+ self._lib_file_list[str(path_object.name)] = str(full_path)
+ for file_path in file_list:
extension = Path(file_path).suffix
if extension != ".lfr":
print("Unrecognized file Extension")
sys.exit()
p = Path(file_path).resolve()
- print("Input Path: {0}".format(p))
- # Open a file: file
- file = open(p, mode="r")
-
- # read all lines at once
- all_of_it = file.read()
-
- # close the file
- file.close()
-
- self.resolved_paths[p.name] = p
- self.full_text[p.name] = all_of_it
+ self.__store_full_text(p)
def check_syntax_errors(self) -> bool:
+ """Checks if there are any syntax errors in the input files
+
+ Returns:
+ bool: True if there are syntax errors, False otherwise
+ """
syntax_errors = 0
for file_path in list(self.resolved_paths.values()):
print("File: {}".format(file_path))
@@ -56,14 +70,26 @@ def check_syntax_errors(self) -> bool:
return syntax_errors > 0
- def process(self) -> None:
+ def process(
+ self, preprocesser_dump_path: Path = Path(f"./{PREPROCESSOR_DUMP_FILE_NAME}")
+ ) -> None:
+ """Processes the preprocessor and generates the preprocessor dump file
+
+ Args:
+ preprocesser_dump_path (Path, optional): Path for the preprocessor dump file. Defaults to Path(f"./{PREPROCESSOR_DUMP_FILE_NAME}").
+ Raises:
+ Exception: TBA
+ """
dep_graph = nx.DiGraph()
# add the nodes in the dep graph
for file_handle in self.full_text:
dep_graph.add_node(file_handle)
- for file_handle in self.full_text:
+ # We extract his because these are all the files defined by the user
+ user_derfined_list = list(self.full_text.keys())
+
+ for file_handle in user_derfined_list:
# Find all imports and generate the edges
text = self.full_text[file_handle]
find_results = re.findall(IMPORT_FILE_PATTERN, text)
@@ -71,8 +97,22 @@ def process(self) -> None:
new_file_handle = result[1]
delete_string = result[0]
+ # Check if the file handle is found in the dependency graph
if new_file_handle not in list(dep_graph.nodes):
- raise Exception("Could not find file - {}".format(result[1]))
+ # Since its not in the dependency graph we check if
+ # its in the preloaded library
+ if new_file_handle not in list(self._lib_file_list.keys()):
+ # Since its not in the preloaded library either...
+ raise Exception("Could not find file - {}".format(result[1]))
+ else:
+ # Pull all the text, add it to the full text store
+ file_path = self._lib_file_list[new_file_handle]
+ p = Path(file_path).resolve()
+ print("Using Library Design at Path: {0}".format(p))
+ self.__store_full_text(p)
+
+ # Add the file node to the dependency graph here
+ dep_graph.add_node(new_file_handle)
dep_graph.add_edge(file_handle, new_file_handle)
@@ -90,6 +130,25 @@ def process(self) -> None:
final_dump += "\n\n\n\n\n"
# Generating the Dump
- file = open("pre_processor_dump.lfr", "w")
+ file = open(preprocesser_dump_path, "w")
file.write(final_dump)
file.close()
+
+ def __store_full_text(self, file_path: Path):
+ """Stores the full text of the give file into the preprocessor store
+
+ Args:
+ file_path (Path): Path object of the file
+ """
+ print("Input Path: {0}".format(file_path))
+ # Open a file: file
+ file = open(file_path, mode="r")
+
+ # read all lines at once
+ all_of_the_file_text = file.read()
+
+ # close the file
+ file.close()
+
+ self.resolved_paths[file_path.name] = file_path
+ self.full_text[file_path.name] = all_of_the_file_text
diff --git a/lfr/utils.py b/lfr/utils.py
index 108f7d4..1a4f3ec 100644
--- a/lfr/utils.py
+++ b/lfr/utils.py
@@ -1,37 +1,70 @@
import json
import os
+from pathlib import Path
+from typing import List
-from networkx import nx
+import networkx as nx
from pymint.mintdevice import MINTDevice
-import lfr.parameters as parameters
+from lfr.parameters import OUTPUT_DIR
-def printgraph(G, filename: str) -> None:
- tt = os.path.join(parameters.OUTPUT_DIR, filename)
- print("output:", parameters.OUTPUT_DIR)
- print("output:", tt)
- nx.nx_agraph.to_agraph(G).write(tt)
+def printgraph(graph: nx.Graph, filename: str, output_dir: Path = OUTPUT_DIR) -> None:
+ """Prints the graph in a .dot file and a .pdf file
- os.system("dot -Tpdf {} -o {}.pdf".format(tt, tt))
+ Args:
+ graph (nx.Graph): graph we need to print
+ filename (str): name of the file
+ output_dir (Path, optional): Output folder path. Defaults to OUTPUT_DIR.
+ """
+ # Generate labels and whatnot for the graph
+ graph_copy = graph.copy(as_view=False)
+ # Print out the dot file and then run the conversion
+ dot_path = Path.joinpath(output_dir, f"{filename}.dot")
+ pdf_path = Path.joinpath(output_dir, f"{filename}.pdf")
+ print("output:", output_dir)
+ print("output:", dot_path)
+ nx.nx_agraph.to_agraph(graph_copy).write(dot_path)
+
+ os.system(f"dot -Tpdf {str(dot_path.absolute())} -o {str(pdf_path.absolute())}")
def get_ouput_path(filename: str) -> str:
- return os.path.join(parameters.OUTPUT_DIR, filename)
+ """Returns the path to the output file"""
+ return os.path.join(OUTPUT_DIR, filename)
+
+def serialize_netlist(output_path: Path, mint_device: MINTDevice) -> None:
+ """Serializes the netlist to a json file"""
-def serialize_netlist(device: MINTDevice) -> None:
# Generate the MINT file from the pyparchmint device
- json_data = device.to_parchmint_v1()
+ json_data = mint_device.to_parchmint()
json_string = json.dumps(json_data)
- json_file = open(get_ouput_path(device.name + ".json"), "wt")
+ file_path = output_path.joinpath(f"{mint_device.device.name}.json")
+ json_file = open(file_path, "wt")
json_file.write(json_string)
json_file.close()
-def print_netlist(device: MINTDevice) -> None:
+def print_netlist(output_path: Path, mint_device: MINTDevice) -> None:
+ """Prints the netlist to the console"""
+
# Generate the MINT file from the pyparchmint device
- minttext = device.to_MINT()
- mint_file = open(get_ouput_path(device.name + ".mint"), "wt")
+ minttext = mint_device.to_MINT()
+ file_path = Path.joinpath(output_path, f"{mint_device.device.name}.mint")
+ mint_file = open(file_path, "wt")
mint_file.write(minttext)
mint_file.close()
+
+
+def convert_list_to_str(lst: List) -> str:
+ """Returns a string list formatted as a string
+
+ Args:
+ lst (List): list we need to convert into a string
+
+ Returns:
+ str: list formatted as a string
+ """
+ ret = "[{0}]".format(", ".join([str(i) for i in lst]))
+ return ret
diff --git a/library/mars.json b/library/mars.json
index 5e9ecc0..a4c2b0a 100644
--- a/library/mars.json
+++ b/library/mars.json
@@ -81,7 +81,7 @@
"default-netlist": null
},
{
- "mint": "DIAMOND CHAMBER",
+ "mint": "DIAMOND REACTION CHAMBER",
"component-type": "primitive",
"is-storage": "false",
"inputs": [
diff --git a/nodes_todo.md b/nodes_todo.md
new file mode 100644
index 0000000..81817cc
--- /dev/null
+++ b/nodes_todo.md
@@ -0,0 +1,5 @@
+TODO - Need to revisit how the datavaules are getting passed around and if the
+FluidicInteraction creation funcitons should take in vectors as values
+(I think not...).
+
+Working on improving the logic expression processing and whatnot should help the situation
\ No newline at end of file
diff --git a/notes_matchstrings.md b/notes_matchstrings.md
new file mode 100644
index 0000000..a2566d3
--- /dev/null
+++ b/notes_matchstrings.md
@@ -0,0 +1,259 @@
+### MIXER
+
+```
+{
+ v1:MIX
+}
+```
+
+### DROPLET CAPACITANCE SENSOR
+
+```
+{
+ v1:TECHNOLOGY
+}
+```
+
+### LONG CELL TRAP
+
+```
+{
+ v1:STORAGE
+}
+```
+
+### SQUARE CELL TRAP
+
+```
+{
+ v1:STORAGE
+}
+```
+
+### REACTION CHAMBER
+
+```
+{
+ v1:STROAGE
+}
+```
+
+### CHEMOSTAT RING
+
+```
+{
+ v1:STORAGE
+}
+```
+
+### CURVED MIXER
+
+```
+{
+ v1:MIX
+}
+```
+
+### DIAMOND REACTION CHAMBER
+
+```
+{
+ v1:STORAGE
+}
+```
+
+### NOZZLE DROPLET GENERATOR
+
+```
+{
+ v1:METER
+}
+```
+
+### DROPLET GENERATOR FLOW FOCUS
+
+```
+{
+ v1:IO -> v2:METER
+}
+```
+
+### DROPLET GENERATOR T
+
+```
+{
+ v1:METER
+}
+```
+
+### DROPLET MERGER
+
+```
+{
+ v1:MIX
+}
+```
+
+### FILTER
+
+```
+{
+ v1:TECHNOLOGY
+}
+```
+
+### GRADIENT GENERATOR
+
+TODO - Figure out how to show this as the gradient generator
+```
+{
+ ???????
+}
+```
+
+### LL CHAMBER
+TODO - Change the name of this
+
+```
+{
+ v1:MIX -> v2:STORAGE
+}
+```
+
+### LOGIC ARRAY
+
+TODO - Figure out how to control sequences work from an LFR file. Also figure out where the
+
+```
+{
+ v1:STORAGE <-> v2:STORAGE,
+ v1:STORAGE <-> v3:STORAGE,
+ v1:STORAGE <-> v4:STORAGE,
+ v2:STORAGE <-> v3:STORAGE,
+ v3:STORAGE <-> v4:STORAGE
+}
+```
+
+### DROPLET MERGER
+
+```
+{
+ v1:MIX
+}
+```
+
+### MUX
+```
+{
+ ?:DISTRIBUTE_OR { "or_1" } -> v1,
+ (?:DISTRIBUTE_OR { "or_1" } -> v1)+
+}
+```
+
+```
+{
+ v1 -> ?:DISTRIBUTE_OR { "or_1" },
+ (v1 -> ?:DISTRIBUTE_OR { "or_1" })+
+}
+```
+
+### PICOINJECTOR
+```
+{
+ v1:MIX
+}
+```
+
+### PORT
+
+```
+{
+ v1:IO
+}
+```
+
+### PUMP
+
+```
+{
+ v1:PUMP
+}
+```
+
+### PUMP3D
+
+```
+{
+ v1:PUMP
+}
+```
+
+### ROTARY MIXER
+
+```
+{
+ v1:MIX -> v2:STROAGE
+}
+```
+
+```
+{
+ v1:STORAGE -> v2:MIX
+}
+```
+
+### DROPLET SORTER
+
+```
+{
+ v1:SIEVE
+}
+```
+
+### MIXER3D
+
+```
+{
+ v1:MIX
+}
+```
+
+### TRANSPOSER
+
+```
+{
+
+}
+```
+
+### TREE
+
+```
+{
+ v1:FLOW -> ?:FLOW,
+ (v1:FLOW -> ?:FLOW)+
+}
+```
+
+```
+{
+ ?:FLOW -> v1:FLOW,
+ (?: FLOW -> v1:FLOW)+
+}
+```
+
+### YTREE
+
+```
+{
+ v1:FLOW -> ?:FLOW,
+ (v1:FLOW -> ?:FLOW)+
+}
+```
+
+```
+{
+ ?:FLOW -> v1:FLOW,
+ (?: FLOW -> v1:FLOW)+
+}
+```
\ No newline at end of file
diff --git a/lfr/netlistgenerator/v2/constructiongraph.py b/old-stuff/constructiongraph-old.py
similarity index 84%
rename from lfr/netlistgenerator/v2/constructiongraph.py
rename to old-stuff/constructiongraph-old.py
index 3f7c42b..44ba83e 100644
--- a/lfr/netlistgenerator/v2/constructiongraph.py
+++ b/old-stuff/constructiongraph-old.py
@@ -1,10 +1,9 @@
from copy import copy
-from typing import Dict, List, Set, Tuple
+from typing import Dict, List, Optional, Set, Tuple
-from networkx import nx
+import networkx as nx
from networkx.algorithms import isomorphism
from networkx.classes.digraph import DiGraph
-from networkx.classes.function import subgraph
from pymint.mintcomponent import MINTComponent
from pymint.mintdevice import MINTDevice
from pymint.minttarget import MINTTarget
@@ -12,16 +11,22 @@
from lfr.compiler.module import Module
from lfr.fig.fignode import FIGNode
from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+from lfr.netlistgenerator.constructionnode import ConstructionNode
from lfr.netlistgenerator.namegenerator import NameGenerator
-from lfr.netlistgenerator.primitive import PrimitiveType, ProceduralPrimitive
-from lfr.netlistgenerator.v2.constructionnode import ConstructionNode
-from lfr.netlistgenerator.v2.networkmappingoption import (
+from lfr.netlistgenerator.networkmappingoption import (
NetworkMappingOption,
NetworkMappingOptionType,
)
+from lfr.netlistgenerator.primitive import PrimitiveType, ProceduralPrimitive
+
+class OLDConstructionGraph(nx.DiGraph):
+ """Construction Graph is the proxy datastructure that we use for representing the
+ loose connections between the fluid interaction graph and the real hardware
+ design primitives that would be pieced together.
+
+ """
-class ConstructionGraph(nx.DiGraph):
def __init__(self, data=None, val=None, **attr) -> None:
super(ConstructionGraph, self).__init__()
self._construction_nodes: Dict[str, ConstructionNode] = {}
@@ -29,8 +34,35 @@ def __init__(self, data=None, val=None, **attr) -> None:
self._component_refs: Dict[str, List[str]] = {}
self._fixed_edges: List[Tuple[str, str]] = []
+ # TODO - Figure out if this is where we want to store this
+ self._connection_technology: Optional[str] = None
+
+ @property
+ def connection_technology(self) -> Optional[str]:
+ """Returns the default connection technology being used during
+ connection creation
+
+ Returns:
+ Optional[str]: MINT string
+ """
+ return self._connection_technology
+
+ @connection_technology.setter
+ def connection_technology(self, technology_string: str) -> None:
+ """Sets the default connection technology
+
+ Args:
+ technology_string (str): MINT technology string
+ """
+ self._connection_technology = technology_string
+
@property
def construction_nodes(self) -> List[ConstructionNode]:
+ """Returns the list of construction nodes in the construction graph
+
+ Returns:
+ List[ConstructionNode]:
+ """
return [v for k, v in self._construction_nodes.items()]
def get_cn(self, id: str) -> ConstructionNode:
@@ -40,8 +72,8 @@ def get_cn(self, id: str) -> ConstructionNode:
raise KeyError()
def add_construction_node(self, node: ConstructionNode) -> None:
- self._construction_nodes[node.id] = node
- self.add_node(node.id)
+ self._construction_nodes[node.ID] = node
+ self.add_node(node.ID)
def delete_node(self, id: str) -> None:
self.remove_node(id)
@@ -69,12 +101,13 @@ def construct_components(
continue
elif (
mapping_option.mapping_type
- == NetworkMappingOptionType.COMPONENT_REPLACEMENT
+ is NetworkMappingOptionType.COMPONENT_REPLACEMENT
):
# Create a new component here based on the primitive technology
# and the name generator
# Then merge with the larger device
- # Save the copy of subgraph view of the netlist in the construction node
+ # Save the copy of subgraph view of the netlist in the
+ # construction node
component_to_add = None
if (
@@ -94,7 +127,7 @@ def construct_components(
)
device.add_component(component_to_add)
- self._component_refs[cn.id] = [component_to_add.ID]
+ self._component_refs[cn.ID] = [component_to_add.ID]
# for connecting_option in cn
# TODO - save the subgraph view reference
@@ -102,19 +135,20 @@ def construct_components(
# Create a new component here based on the primitive technology
# and the name generator
# Then merge with the larger device
- # Save the copy of subgraph view of the netlist in the construction node
+ # Save the copy of subgraph view of the netlist in the construction
+ # node
component_to_add = mapping_option.primitive.get_default_component(
name_generator, layer
)
device.add_component(component_to_add)
- self._component_refs[cn.id] = [component_to_add.ID]
+ self._component_refs[cn.ID] = [component_to_add.ID]
# for connecting_option in cn
# TODO - save the subgraph view reference
elif mapping_option.primitive.type is PrimitiveType.NETLIST:
netlist = mapping_option.primitive.get_default_netlist(
- cn.id, name_generator
+ cn.ID, name_generator
)
- self._component_refs[cn.id] = [
+ self._component_refs[cn.ID] = [
component.ID for component in netlist.components
]
device.merge_netlist(netlist)
@@ -122,9 +156,9 @@ def construct_components(
# TODO - Save the subgraph view reference
elif mapping_option.primitive.type is PrimitiveType.PROCEDURAL:
netlist = mapping_option.primitive.get_default_netlist(
- cn.id, name_generator
+ cn.ID, name_generator
)
- self._component_refs[cn.id] = [
+ self._component_refs[cn.ID] = [
component.ID for component in netlist.components
]
device.merge_netlist(netlist)
@@ -142,12 +176,12 @@ def construct_components(
def get_fignode_cn(self, fig_node: FIGNode) -> ConstructionNode:
for cn in self._construction_nodes.values():
for mapping_option in cn.mapping_options:
- if fig_node.id in mapping_option.fig_subgraph.nodes:
+ if fig_node.ID in mapping_option.fig_subgraph.nodes:
return cn
raise Exception(
"Could not find construction node with an active mappingoption that covers"
- " FIG node: {}".format(fig_node.id)
+ " FIG node: {}".format(fig_node.ID)
)
def split_cn(
@@ -167,10 +201,12 @@ def split_cn(
between all the nodes based on how the FIG subgraph is connected
Args:
- cn_to_split (ConstructionNode): Construction node that needs to be split into multiple nodes
- split_groups (List[List[str]]): A list of lists where each list should contain the FIG node IDs that neet to be in differnt nodes
+ cn_to_split (ConstructionNode): Construction node that needs to be split
+ into multiple nodes
+ split_groups (List[List[str]]): A list of lists where each list should
+ contain the FIG node IDs that neet to be in differnt nodes
"""
- name = cn_to_split.id
+ name = cn_to_split.ID
fig_nodes = []
for nodes in split_groups:
fig_nodes.extend(nodes)
@@ -181,7 +217,7 @@ def split_cn(
cn = ConstructionNode("{}_split_{}".format(name, group_index))
# Copy all the mapping options but have a differet fig_subgraph
for mapping_option in cn_to_split.mapping_options:
- # TODO = Figure out what kind of a network mapping I need to get for this
+ # TODO = Figure out what kind of a network mapping I need to get
mapping_copy = copy(mapping_option)
mapping_copy.fig_subgraph = fig_subgraph
cn.add_mapping_option(mapping_option)
@@ -189,7 +225,7 @@ def split_cn(
self.add_construction_node(cn)
# Delete the node now
- self.delete_node(cn_to_split.id)
+ self.delete_node(cn_to_split.ID)
# TODO - create connections between the cns based on the figs
self.generate_edges(full_subgraph)
@@ -206,17 +242,17 @@ def insert_cn(
# Delete all the edges between the input nodes and the output nodes
for input_cn in input_cns:
for output_cn in output_cns:
- if self.has_edge(input_cn.id, output_cn.id):
- self.remove_edge(input_cn.id, output_cn.id)
+ if self.has_edge(input_cn.ID, output_cn.ID):
+ self.remove_edge(input_cn.ID, output_cn.ID)
# Add the cn
self.add_construction_node(cn_to_insert)
# Create the connections between the intermediate cn
for input_cn in input_cns:
- self.add_edge(input_cn.id, cn_to_insert.id)
+ self.add_edge(input_cn.ID, cn_to_insert.ID)
for output_cn in output_cns:
- self.add_edge(cn_to_insert.id, output_cn.id)
+ self.add_edge(cn_to_insert.ID, output_cn.ID)
def get_component_cn(self, component: MINTComponent) -> ConstructionNode:
"""Get the Construction Node associated with the given component
@@ -251,30 +287,36 @@ def construct_connections(
# src = self._construction_nodes[edge[0]]
# tar = self._construction_nodes[edge[1]]
- # Step 2 - Get the output requirement from src mapping option and the input mapping
- # option and make a simple channel between them (I guess no parameters right now)
+ # Step 2 - Get the output requirement from src mapping option and the input
+ # mapping option and make a simple channel between them (I guess no parameters
+ # right now)
# TODO - Modify this based on what mapping option is enabled here later on
# src.load_connection_options()
# tar.load_connection_options()
- # Step 3 - Loop through all the nodes and start filling out this input/output requirements
- # This exploration could be using the reverse DFS traversal this way we can probably fill out
- # the entire set of flows that way.
+ # Step 3 - Loop through all the nodes and start filling out this input/output
+ # requirements
+ #
+ # This exploration could be using the reverse DFS traversal this way we can
+ # probably fill out the entire set of flows that way.
# -----------------------
- # TODO - This could probably be converted into network flow problems. Since this an extension
- # of bipartitie matching at every step, I think that can be converted into a max flow problem
- # However, what needs to be determined is what factor becomes the capacity, weight, etc.
- # The only constraints that are known is that everything will have infinite capacity,
- # Technically every node might be an edge and every edge might be a node, that way we can
- # take the input / output capacities and treat them as. This needs to eb thought through a little
-
- # We first do the channel creation for the pass throughs so that we don't finish up the input
- # output resources.
+ # TODO - This could probably be converted into network flow problems. Since
+ # this an extension of bipartitie matching at every step, I think that can be
+ # converted into a max flow problem However, what needs to be determined is
+ # what factor becomes the capacity, weight, etc. The only constraints that are
+ # known is that everything will have infinite capacity, Technically every node
+ # might be an edge and every edge might be a node, that way we can take the
+ # input / output capacities and treat them as. This needs to eb thought
+ # through a little
+
+ # We first do the channel creation for the pass throughs so that we don't
+ # finish up the input output resources.
skip_list = []
for cn_id in self.nodes:
- # Step 3.1 - Check to see if there are as many input options are there are incoming edges
- # if its n->n or n->1, it'll be easy otherwise we need to figure out something else
+ # Step 3.1 - Check to see if there are as many input options are there are
+ # incoming edges if its n->n or n->1, it'll be easy otherwise we need to
+ # figure out something else
in_neighbours = self.in_edges(cn_id)
cn = self._construction_nodes[cn_id]
@@ -282,11 +324,15 @@ def construct_connections(
continue
# TODO - Go through netlist and then figure out what needs to get done
- # based on the strategy we need to do different things. This is the requirement for when its a
+ # based on the strategy we need to do different things. This is the
+ # requirement for when its a
# FLOW-FLOW-CONSTRUCTION-NODE
- # In this case it needs to treat as an empty netlist because a pass through would just connect the neighbours instead
- # TODO - This will potentially get removed later as we might just want to eliminate the construction node later on
+ # In this case it needs to treat as an empty netlist because a pass through
+ # would just connect the neighbours instead
+ # TODO - This will potentially get removed later as we might just want to
+ # eliminate the construction node later on
+
# if isinstance(cn.mapping_options[0], NetworkMappingOption):
# if cn.mapping_options[0].mapping_type is NetworkMappingOptionType.PASS_THROUGH:
# # Figure out what the pass through strategy is for this, find the input
@@ -310,7 +356,9 @@ def construct_connections(
# device
# )
- # TODO - Figure out if these conditions require any more thought in terms of implementation
+ # TODO - Figure out if these conditions require any more thought in terms
+ # of implementation
+
# elif self._mapping_type is NetworkMappingOptionType.COMPONENT_REPLACEMENT:
# # TODO - In this case it needs to be an component with the corresponding
# # input and output options loaded into the placeholder primitive
@@ -326,12 +374,15 @@ def construct_connections(
if cn_id in skip_list:
continue
- # Step 3.1 - Check to see if there are as many input options are there are incoming edges
- # if its n->n or n->1, it'll be easy otherwise we need to figure out something else
+ # Step 3.1 - Check to see if there are as many input options are there are
+ # incoming edges
+ # if its n->n or n->1, it'll be easy otherwise we need to figure out
+ # something else
in_neighbours = self.in_edges(cn_id)
cn = self._construction_nodes[cn_id]
- # Check if any inputs are left to deal with , skip if there are no more inputs left
+ # Check if any inputs are left to deal with , skip if there are no
+ # more inputs left
if len(cn.input_options) == 0:
continue
@@ -408,7 +459,9 @@ def __create_passthrough_channel(
)
# TODO - Change how we retrieve the technology type for the channel
- tech_string = "CHANNEL"
+ if self._connection_technology is None:
+ raise ValueError()
+ tech_string = self._connection_technology
# channel_name = name_generator.generate_name(tech_string)
# TODO - Figure out how to hande a scenario where this isn't ture
@@ -435,8 +488,8 @@ def __create_passthrough_channel(
"0",
)
- # TODO - Once we are done creating a path, we need to delete the start and end point options
- # from their respective construction nodes.
+ # TODO - Once we are done creating a path, we need to delete the start and end
+ # point options from their respective construction nodes.
print(
"Updated the connectionoptions in {} - Removing {}".format(
cn_start, start_point
@@ -451,6 +504,7 @@ def __create_passthrough_channel(
)
cn_end.input_options.remove(end_point)
+ # TODO - Rewrite intercn channel implementatino
def __create_intercn_channel(
self,
src_id: str,
@@ -473,10 +527,10 @@ def __create_intercn_channel(
if end_point.component_name is None:
# This means a single component was mapped here
- tar_component_name = self._component_refs[cn.id][0]
+ tar_component_name = self._component_refs[cn.ID][0]
else:
tar_component_name = name_generator.get_cn_name(
- cn.id, end_point.component_name
+ cn.ID, end_point.component_name
)
print(
@@ -516,8 +570,8 @@ def __create_intercn_channel(
"0",
)
- # TODO - Once we are done creating a path, we need to delete the start and end point options
- # from their respective construction nodes.
+ # TODO - Once we are done creating a path, we need to delete the start and end
+ # point options from their respective construction nodes.
print(
"Updated the connectionoptions in {} - Removing {}".format(src, start_point)
)
@@ -528,18 +582,18 @@ def __create_intercn_channel(
def generate_edges(self, fig: FluidInteractionGraph) -> None:
# Look at the mapping options for each of the constructionnodes,
- # Figure out which other subgraphs are they connected to based on the original fig
- # connectivity make the constructionnode based on which other cn subgraphs they are
- # connected to
+ # Figure out which other subgraphs are they connected to based on the original
+ # fig connectivity make the constructionnode based on which other cn subgraphs
+ # they are connected to
- # Step 1 - create a map for each fig element and see what all cn's they're present in
- # (this will account for double coverage cases too)
+ # Step 1 - create a map for each fig element and see what all cn's they're
+ # present in (this will account for double coverage cases too)
# Step 2 - Now that we know the mapping, go through each connection in the fig,
- # Step 3 - if both source and target are in the same cn, skip, create an edge between
- # the cn's
+ # Step 3 - if both source and target are in the same cn, skip, create an edge
+ # between the cn's
- # Step 1 - create a map for each fig element and see what all cn's they're present in
- # (this will account for double coverage cases too)
+ # Step 1 - create a map for each fig element and see what all cn's they're
+ # present in (this will account for double coverage cases too)
# TODO - For combinatorial design space, figure out what to do with this
fig_nodes_cn_reverse_map: Dict[str, List[str]] = {}
@@ -548,7 +602,6 @@ def generate_edges(self, fig: FluidInteractionGraph) -> None:
# combinatorial design space
assert len(cn.mapping_options) == 1
for mapping_option in cn.mapping_options:
-
# TODO - Figure out how to not explicity check for this scenario'
# right now I'm using component replace as a coarse way of ensure
# no double takes
@@ -566,13 +619,12 @@ def generate_edges(self, fig: FluidInteractionGraph) -> None:
# continue
for node_id in mapping_option.fig_subgraph.nodes:
if node_id in fig_nodes_cn_reverse_map.keys():
-
# Make sure there are no repeats here
- if cn.id not in fig_nodes_cn_reverse_map[node_id]:
- fig_nodes_cn_reverse_map[node_id].append(cn.id)
+ if cn.ID not in fig_nodes_cn_reverse_map[node_id]:
+ fig_nodes_cn_reverse_map[node_id].append(cn.ID)
else:
fig_nodes_cn_reverse_map[node_id] = []
- fig_nodes_cn_reverse_map[node_id].append(cn.id)
+ fig_nodes_cn_reverse_map[node_id].append(cn.ID)
# Step 1.5 - Handle the overcoverage scenarios, currently we assume that
# the undercoverage scenarios are only in the case of networkmappings.
@@ -645,13 +697,16 @@ def generate_edges(self, fig: FluidInteractionGraph) -> None:
# )
continue
else:
- # TODO - When the asserts fail, its an overcoverage issue, decide what needs to be done here
+ # TODO - When the asserts fail, its an overcoverage issue, decide what
+ # needs to be done here
src_cn = fig_nodes_cn_reverse_map[src]
assert len(src_cn) == 1
tar_cn = fig_nodes_cn_reverse_map[tar]
assert len(tar_cn) == 1
- # Step 3 - now check to see if both are in the same cn or not, if they're not create an cn_edge
+ # Step 3 - now check to see if both are in the same cn or not, if
+ # they're not create an cn_edge
+
# TODO - implement list search/edge creation incase there are multiple cn's associated
if src_cn[0] != tar_cn[0]:
self.add_edge(src_cn[0], tar_cn[0])
diff --git a/lfr/netlistgenerator/v2/constructionnode.py b/old-stuff/constructionnode-old.py
similarity index 61%
rename from lfr/netlistgenerator/v2/constructionnode.py
rename to old-stuff/constructionnode-old.py
index ea468da..c935ff0 100644
--- a/lfr/netlistgenerator/v2/constructionnode.py
+++ b/old-stuff/constructionnode-old.py
@@ -1,13 +1,11 @@
-import copy
from typing import List
-from lfr.netlistgenerator.primitive import ProceduralPrimitive
-from lfr.netlistgenerator.v2.connectingoption import ConnectingOption
-from lfr.netlistgenerator.v2.mappingoption import MappingOption
+from lfr.netlistgenerator.connectingoption import ConnectingOption
+from lfr.netlistgenerator.mappingoption import MappingOption
from lfr.postprocessor.constraints import Constraint
-class ConstructionNode:
+class OLDConstructionNode:
def __init__(self, node_id: str) -> None:
self._id = node_id
self._mapping_options: List[MappingOption] = []
@@ -46,25 +44,57 @@ def output_options(self) -> List[ConnectingOption]:
@property
def loading_options(self) -> List[ConnectingOption]:
+ """Returns the list of loading options for the mapption option candidate
+
+ Returns:
+ List[ConnectingOption]: List of loading options
+ """
return self._loading_options
@property
def carrier_options(self) -> List[ConnectingOption]:
+ """Returns the list of carrier options set for the construction node
+
+ Returns:
+ List[ConnectingOption]: List of carrier options
+ """
return self._carrier_options
@property
- def id(self) -> str:
+ def ID(self) -> str:
+ """Returns the id of the construction node
+
+ Returns:
+ str: ID of the construction node
+ """
return self._id
@property
def mapping_options(self) -> List[MappingOption]:
+ """Returns the list connecting options on the
+ construction node
+
+ Returns:
+ List[MappingOption]: Mapping options available for the construction node
+ """
return self._mapping_options
@mapping_options.setter
def mapping_options(self, options: List[MappingOption]):
+ """Sets the mapping options
+
+ Args:
+ options (List[MappingOption]): MappingOptions
+ """
self._mapping_options = options
def use_explicit_mapping(self, mapping: MappingOption) -> None:
+ """Uses the explicit mapping option passed as the parameter
+
+ Args:
+ mapping (MappingOption): MappingOption that needs to set
+ here explicitly
+ """
# Set the flag for explicit mapping
self._explict_mapping_flag = True
# Delete all the existing mapping options
@@ -72,6 +102,7 @@ def use_explicit_mapping(self, mapping: MappingOption) -> None:
# Now that we have overwritten all the netlist options here
# we basically cherry pick the one little bit that we want to attach here
self._mapping_options.append(mapping)
+ self.load_connection_options()
def add_mapping_option(self, mapping_option: MappingOption) -> None:
if self._explict_mapping_flag is True:
@@ -84,7 +115,15 @@ def add_mapping_option(self, mapping_option: MappingOption) -> None:
self._mapping_options.append(mapping_option)
def load_connection_options(self) -> None:
+ """Loads the corresponding different connecting options into
+ the construction node
+ """
# TODO - Figure out what do do if its a combinatorial design
+ if len(self._mapping_options) != 1:
+ raise Exception(
+ "More than one mapping options present for construction node, cannot"
+ " load connecting options"
+ )
assert len(self._mapping_options) == 1
primitive_ref = self._mapping_options[0].primitive
@@ -107,5 +146,21 @@ def load_connection_options(self) -> None:
self._carrier_options = options
+ def merge_construction_node(self, construction_node: "ConstructionNode") -> None:
+ """Merges the construction node passed as an arugment into the this
+ construction node.
+
+ This will let us handle the scenario where we might want to merge
+ construction nodes that have undercoverage and help support the future
+ combinatorial generation options
+
+
+ Args:
+ construction_node (ConstructionNode): [description]
+ """
+ raise NotImplementedError(
+ "Implement this when we are trying to make combinatorial operations work"
+ )
+
def __str__(self) -> str:
- return "Construction Node: {}".format(self.id)
+ return "Construction Node: {}".format(self.ID)
diff --git a/lfr/netlistgenerator/v2/dafdadapter.py b/old-stuff/dafdadapter-old.py
similarity index 53%
rename from lfr/netlistgenerator/v2/dafdadapter.py
rename to old-stuff/dafdadapter-old.py
index a9e7922..9c9f90d 100644
--- a/lfr/netlistgenerator/v2/dafdadapter.py
+++ b/old-stuff/dafdadapter-old.py
@@ -1,42 +1,40 @@
-from typing import List
-
-from pymint.mintcomponent import MINTComponent
+from dafd import DAFD_Interface
from pymint.mintdevice import MINTDevice
-from lfr.postprocessor.constraints import Constraint
+from lfr.postprocessor.constraints import (
+ ConstraintList,
+ FunctionalConstraint,
+ GeometryConstraint,
+ PerformanceConstraint,
+)
-class DAFDAdapter:
+class DAFDSizingAdapter:
def __init__(self, device: MINTDevice) -> None:
- super().__init__()
- self._device = device
-
- def size_droplet_generator(
- self, component: MINTComponent, constriants: List[Constraint]
- ) -> None:
- import faulthandler
-
- faulthandler.enable()
-
- from dafd import DAFD_Interface
-
+ self.__device = device
self.solver = DAFD_Interface()
+
+ def size_droplet_generator(self, constriants: ConstraintList) -> None:
# TODO: Check the type of the component and pull info from DAFD Interface
targets_dict = {}
constriants_dict = {}
for constraint in constriants:
- if constraint.key == "volume":
- # r≈0.62035V1/3
- volume = constraint.get_target_value()
- targets_dict["droplet_size"] = float(volume) ** 0.33 * 0.62035 * 2
- elif constraint.key == "generation_rate":
- generate_rate = constraint.get_target_value()
- targets_dict["generation_rate"] = generate_rate
- else:
+ if isinstance(constraint, FunctionalConstraint):
+ if constraint.key == "volume":
+ # r≈0.62035V1/3
+ volume = constraint.get_target_value()
+ assert volume is not None
+ targets_dict["droplet_size"] = float(volume) ** 0.33 * 0.62035 * 2
+ elif isinstance(constraint, PerformanceConstraint):
+ if constraint.key == "generation_rate":
+ generate_rate = constraint.get_target_value()
+ targets_dict["generation_rate"] = generate_rate
+ elif isinstance(constraint, GeometryConstraint):
raise Exception("Error: Geometry constraint not defined")
results = self.solver.runInterp(targets_dict, constriants_dict)
+ component = constriants.component
if component is None:
raise Exception("No component attached to the constraints")
@@ -62,3 +60,12 @@ def size_droplet_generator(
component.params.set_param("outputWidth", round(orifice_size * expansion_ratio))
component.params.set_param("outputLength", 5000)
component.params.set_param("height", round(orifice_size / aspect_ratio))
+
+ # TODO: Figure out how to propagate the results to the rest of the design. Additionally we need to set all the operation considtions
+ pass
+
+ def size_component(self, constriants: ConstraintList) -> None:
+ if constriants.component.entity == "NOZZLE DROPLET GENERATOR":
+ self.size_droplet_generator(constriants)
+ else:
+ print("Error: {} is not supported".format(constriants.component.entity))
diff --git a/lfr/netlistgenerator/v2/gen_strategies/dropxstrategy.py b/old-stuff/dropxstrategy-old.py
similarity index 84%
rename from lfr/netlistgenerator/v2/gen_strategies/dropxstrategy.py
rename to old-stuff/dropxstrategy-old.py
index 6ba2b5e..d208322 100644
--- a/lfr/netlistgenerator/v2/gen_strategies/dropxstrategy.py
+++ b/old-stuff/dropxstrategy-old.py
@@ -1,19 +1,20 @@
+# from lfr.netlistgenerator.constructiongraph import ConstructionGraph
+from typing import List
+
import networkx as nx
from pymint import MINTDevice
from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
from lfr.fig.interaction import Interaction, InteractionType
-from lfr.netlistgenerator.v2.constructiongraph import ConstructionGraph
-from lfr.netlistgenerator.v2.constructionnode import ConstructionNode
-from lfr.netlistgenerator.v2.dafdadapter import DAFDAdapter
-from lfr.netlistgenerator.v2.gen_strategies.genstrategy import GenStrategy
+from lfr.netlistgenerator.constructiongraph.constructiongraph import ConstructionGraph
+from lfr.netlistgenerator.constructiongraph.constructionnode import ConstructionNode
+from lfr.netlistgenerator.dafdadapter import DAFDAdapter
+from lfr.netlistgenerator.gen_strategies.genstrategy import GenStrategy
class DropXStrategy(GenStrategy):
- def __init__(
- self, construction_graph: ConstructionGraph, fig: FluidInteractionGraph
- ) -> None:
- super().__init__(construction_graph, fig)
+ def __init__(self, fig: FluidInteractionGraph) -> None:
+ super().__init__(fig)
def reduce_mapping_options(self) -> None:
# Generate a topological order for the FIG to make sure athat we know the order of things
@@ -24,22 +25,28 @@ def reduce_mapping_options(self) -> None:
fignode = self._fig.get_fignode(fignode_id)
# check if construction node
- if ConstructionNode(fignode.id).is_explictly_mapped:
+ if ConstructionNode(fignode.ID).is_explictly_mapped:
pass
# TODO - Implement Generalized Ali Strategy 1
- # Rule 1 - The first level of % should be mapping to a Droplet Generator (TODO - Talk to ali about this or a T junction generator)
- # Step 1 - Check if fig node is interaction and of type METER (%) this is the check condition for rule 1
+ # Rule 1 - The first level of % should be mapping to a Droplet Generator
+ # (TODO - Talk to ali about this or a T junction generator)
+ # Step 1 - Check if fig node is interaction and of type METER (%) this is t
+ # he check condition for rule 1
else:
if isinstance(fignode, Interaction):
if fignode.type is InteractionType.METER:
is_first_metering_node = True
- # TODO - Check if DROPLET GENERATOR is one of the mapping options, skip if not
- # Step 2 - If type is meter then check to see if other it is the first meter operation from inputs to current fignode
+ # TODO - Check if DROPLET GENERATOR is one of the mapping
+ # options, skip if not
+ # Step 2 - If type is meter then check to see if other it is
+ # the first meter operation from inputs to current fignode
for sorted_fignode_id in figs_in_order:
if fignode_id == sorted_fignode_id:
# End of checking
if is_first_metering_node is True:
- # TODO - Eliminate all options other than Nozzle droplet generator for the associated construction node(s)
+ # TODO - Eliminate all options other than Nozzle
+ # droplet generator for the associated construction
+ # node(s)
cn = self._construction_graph.get_fignode_cn(
fignode
)
@@ -64,20 +71,22 @@ def reduce_mapping_options(self) -> None:
)
if isinstance(sorted_fignode, Interaction):
if sorted_fignode.type is InteractionType.METER:
- # check if node is connected to our node of interest
+ # check if node is connected to our node of
+ # interest
if sorted_fignode_id in self._fig.predecessors(
fignode_id
):
is_first_metering_node = False
- # Rule 2 – Any +-, distribute nodes before % should be in continuous flow (figure out components for this)
+ # Rule 2 – Any +-, distribute nodes before % should be in continuous flow
+ # (figure out components for this)
# TODO - Go through each of the FIG nodes, if the fig node has
for fignode_id in self._fig.nodes:
fignode = self._fig.get_fignode(fignode_id)
# check if explicitly mapped
- if not ConstructionNode(fignode.id).is_explictly_mapped:
+ if not ConstructionNode(fignode.ID).is_explictly_mapped:
if isinstance(fignode, Interaction):
if (
fignode.type is InteractionType.MIX
@@ -87,15 +96,18 @@ def reduce_mapping_options(self) -> None:
# this is NOT continuous
raise Exception("flow before METER is not continuous")
- # Rule 3 – Any Remetering (%) should require a droplet breakdown and regeneration (Ask Ali)
- # Rule 4 – Distribute network post Metering stage should be mapped to different kinds of separator / selection/ storage networks
- # Rule 5 – If plus is shown between node that has % in pred and non % in pred, then its pico injection
+ # Rule 3 – Any Remetering (%) should require a droplet breakdown and
+ # regeneration (Ask Ali)
+ # Rule 4 – Distribute network post Metering stage should be mapped to different
+ # kinds of separator / selection/ storage networks
+ # Rule 5 – If plus is shown between node that has % in pred and non % in pred, t
+ # hen its pico injection
for fignode_id in self._fig.nodes:
fignode = self._fig.get_fignode(fignode_id)
# check if map
- if not ConstructionNode(fignode.id).is_explictly_mapped:
+ if not ConstructionNode(fignode.ID).is_explictly_mapped:
if isinstance(fignode, Interaction):
# if +
if (
@@ -121,7 +133,6 @@ def reduce_mapping_options(self) -> None:
numTrue = meter_in_pred.count(True)
if fignode.type is InteractionType.MIX:
-
if numTrue == 1:
# this is a pico injection
cn = self._construction_graph.get_fignode_cn(fignode)
@@ -168,11 +179,21 @@ def reduce_mapping_options(self) -> None:
print("-", cn_part.primitive.mint)
pass
- # Rule 6 – if plus is sown between two nodes that has % in pred, then its droplet merging
+ # Rule 6 – if plus is sown between two nodes that has % in pred, then its
+ # droplet merging
# Rule 7 – TBD Rule for droplet splitting
# Finally just reduce the total number of mapping options if greater than 1
super().reduce_mapping_options()
+ def prune_variants(self, variants: List[ConstructionGraph]) -> None:
+ """
+ Prunes the variants by removing the ones that are not feasible.
+
+ :param variants: The variants to prune.
+ :return: None
+ """
+ super().prune_variants(variants)
+
@staticmethod
def __exist_in_cn(cn, mint_name):
"""helper function to check if the construction node contains undesired mints.
@@ -191,10 +212,12 @@ def __exist_in_cn(cn, mint_name):
return False
def __search_predecessors(self, fignode_id, search_type):
- """recursive function searches for the specified InteractionType in the predecessors of the specified fignode_id
+ """recursive function searches for the specified InteractionType in the
+ predecessors of the specified fignode_id
Args:
- fignode_id (elements in self._fig.nodes): Starting node to find the predecessors
+ fignode_id (elements in self._fig.nodes): Starting node to find the
+ predecessors
search_type (InteractionType): Interaction type to find in the predecessors
Returns:
@@ -214,7 +237,8 @@ def __search_predecessors(self, fignode_id, search_type):
@staticmethod
def __check_if_type(fignode, search_type):
- """helper function for __search_predecessors and __check_continuous. Check if the specified search_type matches to the fignode.type
+ """helper function for __search_predecessors and __check_continuous. Check if
+ the specified search_type matches to the fignode.type
Args:
fignode (FIGNode): fignode that contains InteractionType as type
@@ -229,7 +253,8 @@ def __check_if_type(fignode, search_type):
return False
- # this function checks if the predecessors before METER has METER or not. If not, continuous.
+ # this function checks if the predecessors before METER has METER or not. If not,
+ # continuous.
def __check_continuous(self, fignode_id):
"""recursive function to check if the flow before METER is continuous at MIX or SIEVE
@@ -237,7 +262,8 @@ def __check_continuous(self, fignode_id):
fignode_id (elements in self._fig.nodes): Starting node to find predecessors
Returns:
- Bool: if METER is found in the predecessors of METER, returns true (not continuous), Else false
+ Bool: if METER is found in the predecessors of METER, returns true
+ (not continuous), Else false
"""
fignode = self._fig.get_fignode(fignode_id)
diff --git a/old-stuff/dummy-old.py b/old-stuff/dummy-old.py
new file mode 100644
index 0000000..6816d5b
--- /dev/null
+++ b/old-stuff/dummy-old.py
@@ -0,0 +1,9 @@
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+from lfr.netlistgenerator.gen_strategies.genstrategy import GenStrategy
+from lfr.netlistgenerator.mappingoption import MappingOption
+
+# from lfr.netlistgenerator.constructiongraph import ConstructionGraph
+
+
+class DummyStrategy(GenStrategy):
+ pass
diff --git a/lfr/netlistgenerator/v2/generator.py b/old-stuff/generator-old.py
similarity index 62%
rename from lfr/netlistgenerator/v2/generator.py
rename to old-stuff/generator-old.py
index d283821..18dc575 100644
--- a/lfr/netlistgenerator/v2/generator.py
+++ b/old-stuff/generator-old.py
@@ -1,34 +1,32 @@
-import sys
-from copy import deepcopy
-from typing import List, Set
+from typing import List
+import networkx as nx
+from pymint.mintdevice import MINTDevice
from pymint.mintlayer import MINTLayerType
-from pymint import MINTDevice
from lfr.compiler.module import Module
-from lfr.fig.fignode import IOType, Pump, Storage, ValueNode
+from lfr.fig.fignode import IOType, ValueNode
from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
from lfr.fig.interaction import (
FluidIntegerInteraction,
FluidNumberInteraction,
InteractionType,
)
+from lfr.netlistgenerator.connectingoption import ConnectingOption
+from lfr.netlistgenerator.constructiongraph import ConstructionGraph
+from lfr.netlistgenerator.constructionnode import ConstructionNode
+from lfr.netlistgenerator.gen_strategies.dropxstrategy import DropXStrategy
+from lfr.netlistgenerator.gen_strategies.dummy import DummyStrategy
+from lfr.netlistgenerator.gen_strategies.genstrategy import GenStrategy
from lfr.netlistgenerator.mappinglibrary import MappingLibrary
+from lfr.netlistgenerator.mappingoption import MappingOption
from lfr.netlistgenerator.namegenerator import NameGenerator
-from lfr.netlistgenerator.primitive import NetworkPrimitive, Primitive, PrimitiveType
-from lfr.netlistgenerator.v2.connectingoption import ConnectingOption
-from lfr.netlistgenerator.v2.constructiongraph import ConstructionGraph
-from lfr.netlistgenerator.v2.constructionnode import ConstructionNode
-from lfr.netlistgenerator.v2.gen_strategies.dropxstrategy import DropXStrategy
-from lfr.netlistgenerator.v2.gen_strategies.dummy import DummyStrategy
-from lfr.netlistgenerator.v2.gen_strategies.genstrategy import GenStrategy
-from lfr.netlistgenerator.v2.gen_strategies.marsstrategy import MarsStrategy
-from lfr.netlistgenerator.v2.mappingoption import MappingOption
-from lfr.netlistgenerator.v2.networkmappingoption import (
+from lfr.netlistgenerator.networkmappingoption import (
NetworkMappingOption,
NetworkMappingOptionType,
)
-from lfr.netlistgenerator.v2.procedural_component_algorithms.ytree import YTREE
+from lfr.netlistgenerator.primitive import NetworkPrimitive, Primitive, PrimitiveType
+from lfr.netlistgenerator.procedural_component_algorithms.ytree import YTREE
from lfr.postprocessor.mapping import NetworkMapping, NodeMappingTemplate
# def generate_MARS_library() -> MappingLibrary:
@@ -44,246 +42,7 @@
# pass
-def generate_mars_library() -> MappingLibrary:
-
- library = MappingLibrary("mars")
-
- # PORT
- port_inputs = []
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
- port_inputs.append(ConnectingOption(None, [None]))
-
- port_outputs = []
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
- port_outputs.append(ConnectingOption(None, []))
-
- port = Primitive(
- "PORT",
- PrimitiveType.COMPONENT,
- "IO",
- False,
- False,
- port_inputs,
- port_outputs,
- None,
- None,
- None,
- )
-
- library.add_io_entry(port)
-
- # NORMAL MIXER
-
- mixer_inputs = []
-
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
-
- mixer_outputs = []
-
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
-
- mixer_loadings = []
- mixer_carriers = []
-
- mixer = Primitive(
- "MIXER",
- PrimitiveType.COMPONENT,
- "MIX",
- False,
- False,
- mixer_inputs,
- mixer_outputs,
- mixer_loadings,
- mixer_carriers,
- None,
- )
-
- library.add_operator_entry(mixer, InteractionType.MIX)
-
- # DIAMOND CHAMBER
-
- diamond_chamber_inputs = []
-
- diamond_chamber_inputs.append(ConnectingOption("default_component", ["1"]))
-
- diamond_chamber_outputs = []
-
- diamond_chamber_outputs.append(ConnectingOption("default_component", ["2"]))
-
- diamond_chamber_loadings = []
- diamond_chamber_carriers = []
-
- diamond_chamber = Primitive(
- "DIAMOND CHAMBER",
- PrimitiveType.COMPONENT,
- "PROCESS",
- False,
- False,
- diamond_chamber_inputs,
- diamond_chamber_outputs,
- diamond_chamber_loadings,
- diamond_chamber_carriers,
- None,
- )
-
- library.add_operator_entry(diamond_chamber, InteractionType.TECHNOLOGY_PROCESS)
-
- # METER
-
- meter_inputs = []
-
- meter_outputs = []
-
- meter_outputs.append(ConnectingOption("default_component", ["1"]))
-
- meter_loadings = []
-
- meter_loadings.append(ConnectingOption("default_component", ["2"]))
-
- meter_carriers = []
-
- meter_carriers.append(ConnectingOption("default_component", ["3"]))
-
- meter = Primitive(
- "METER",
- PrimitiveType.NETLIST,
- "METER",
- False,
- False,
- meter_inputs,
- meter_outputs,
- meter_loadings,
- meter_carriers,
- "default-netlists/dropletgenerator.mint",
- ["droplet_size", "generation_rate"],
- [
- "orifice_size",
- "aspect_ratio",
- "capillary_number",
- "expansion_ratio",
- "flow_rate_ratio",
- "normalized_oil_inlet",
- "normalized_orifice_length",
- "normalized_water_inlet",
- ],
- )
-
- library.add_operator_entry(meter, InteractionType.METER)
-
- # Incubator
-
- incubator_inputs = []
-
- incubator_inputs.append(ConnectingOption("default_component", ["1"]))
-
- incubator_outputs = []
-
- incubator_outputs.append(ConnectingOption("default_component", ["1"]))
-
- incubator_loadings = []
- incubator_carriers = []
-
- incubator = Primitive(
- "INCUBATOR",
- PrimitiveType.COMPONENT,
- "PROCESS",
- False,
- False,
- incubator_inputs,
- incubator_outputs,
- incubator_loadings,
- incubator_carriers,
- )
-
- library.add_operator_entry(incubator, InteractionType.TECHNOLOGY_PROCESS)
-
- # SORTER
-
- sorter_inputs = []
-
- sorter_inputs.append(ConnectingOption(None, ["1"]))
-
- sorter_outputs = []
-
- sorter_outputs.append(ConnectingOption(None, ["2"]))
- sorter_outputs.append(ConnectingOption(None, ["3"]))
-
- sorter_loadings = []
- sorter_carriers = []
-
- # TODO - Modify this later on
- sorter = Primitive(
- "DROPLET SORTER",
- PrimitiveType.COMPONENT,
- "SIEVE",
- False,
- False,
- sorter_inputs,
- sorter_outputs,
- sorter_loadings,
- sorter_carriers,
- None,
- )
-
- library.add_operator_entry(sorter, InteractionType.SIEVE)
-
- return library
-
-
def generate_dropx_library() -> MappingLibrary:
-
library = MappingLibrary("dropx")
# PORT
@@ -340,6 +99,8 @@ def generate_dropx_library() -> MappingLibrary:
None,
None,
None,
+ None,
+ None,
)
library.add_io_entry(port)
@@ -359,7 +120,7 @@ def generate_dropx_library() -> MappingLibrary:
pico_injector_carriers = []
pico_injector = Primitive(
- "PICOINJECTOR",
+ "PICO INJECTOR",
PrimitiveType.COMPONENT,
"MIX",
False,
@@ -387,9 +148,8 @@ def generate_dropx_library() -> MappingLibrary:
electrophoresis_merger_loadings = []
electrophoresis_merger_carriers = []
- # TODO - Modify this later on
electrophoresis_merger = Primitive(
- "DROPLET MERGER",
+ "DROPLET ELECTROPHORESIS MERGER",
PrimitiveType.COMPONENT,
"MIX",
False,
@@ -403,36 +163,6 @@ def generate_dropx_library() -> MappingLibrary:
library.add_operator_entry(electrophoresis_merger, InteractionType.MIX)
- # DROPLET SORTER
-
- droplet_sorter_inputs = []
-
- droplet_sorter_inputs.append(ConnectingOption(None, ["1"]))
-
- droplet_sorter_outputs = []
-
- droplet_sorter_outputs.append(ConnectingOption(None, ["2"]))
- droplet_sorter_outputs.append(ConnectingOption(None, ["3"]))
-
- droplet_sorter_loadings = []
- droplet_sorter_carriers = []
-
- # TODO - Modify this later on
- droplet_sorter = Primitive(
- "DROPLET SORTER",
- PrimitiveType.COMPONENT,
- "SIEVE",
- False,
- False,
- droplet_sorter_inputs,
- droplet_sorter_outputs,
- droplet_sorter_loadings,
- droplet_sorter_carriers,
- None,
- )
-
- library.add_operator_entry(droplet_sorter, InteractionType.SIEVE)
-
# DROPLET GENERATOR
droplet_generator_inputs = []
@@ -593,52 +323,6 @@ def generate_dropx_library() -> MappingLibrary:
library.add_operator_entry(droplet_splitter, InteractionType.DIVIDE)
- # NORMAL MIXER
-
- mixer_inputs = []
-
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
- mixer_inputs.append(ConnectingOption(None, ["1"]))
-
- mixer_outputs = []
-
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
- mixer_outputs.append(ConnectingOption(None, ["2"]))
-
- mixer_loadings = []
- mixer_carriers = []
-
- mixer = Primitive(
- "MIXER",
- PrimitiveType.COMPONENT,
- "MIX",
- False,
- False,
- mixer_inputs,
- mixer_outputs,
- mixer_loadings,
- mixer_carriers,
- None,
- )
-
- library.add_operator_entry(mixer, InteractionType.MIX)
-
# DROPLET CAPACITANCE SENSOR
droplet_capacitance_sensor_inputs = []
@@ -669,34 +353,6 @@ def generate_dropx_library() -> MappingLibrary:
droplet_capacitance_sensor, InteractionType.TECHNOLOGY_PROCESS
)
- # FILTER
-
- filter_inputs = []
-
- filter_inputs.append(ConnectingOption(None, ["1"]))
-
- filter_outputs = []
-
- filter_outputs.append(ConnectingOption(None, ["2"]))
-
- filter_loadings = []
- filter_carriers = []
-
- filter = Primitive(
- "FILTER",
- PrimitiveType.COMPONENT,
- "PROCESS",
- False,
- False,
- filter_inputs,
- filter_outputs,
- filter_loadings,
- filter_carriers,
- None,
- )
-
- library.add_operator_entry(filter, InteractionType.TECHNOLOGY_PROCESS)
-
# DROPLET FLUORESCENCE SENSOR
droplet_fluorescence_sensor_inputs = []
@@ -794,7 +450,6 @@ def generate_dropx_library() -> MappingLibrary:
def generate(module: Module, library: MappingLibrary) -> MINTDevice:
-
construction_graph = ConstructionGraph()
name_generator = NameGenerator()
@@ -808,8 +463,7 @@ def generate(module: Module, library: MappingLibrary) -> MINTDevice:
if library.name == "dropx":
active_strategy = DropXStrategy(construction_graph, module.FIG)
elif library.name == "mars":
- # raise NotImplementedError()
- active_strategy = MarsStrategy(construction_graph, module.FIG)
+ raise NotImplementedError()
elif library.name == "hmlp":
raise NotImplementedError()
else:
@@ -828,25 +482,25 @@ def generate(module: Module, library: MappingLibrary) -> MINTDevice:
# as there would be alternatives for each type of mapping
for interaction in module.FIG.get_interactions():
operator_candidates = library.get_operators(interaction_type=interaction.type)
- cn = ConstructionNode(interaction.id)
+ cn = ConstructionNode(interaction.ID)
# if isinstance(interaction, ValueNode):
# continue
for operator_candidate in operator_candidates:
# TODO: This will change in the future when we can match subgraphs correctly
- if isinstance(
- interaction, (FluidNumberInteraction, FluidIntegerInteraction)
+ if isinstance(interaction, FluidNumberInteraction) or isinstance(
+ interaction, FluidIntegerInteraction
):
# Basically add the value node id into the subgraph view also
node_ids = [
- module.FIG.get_fignode(edge[0]).id
- for edge in module.FIG.in_edges(interaction.id)
+ module.FIG.get_fignode(edge[0]).ID
+ for edge in module.FIG.in_edges(interaction.ID)
if isinstance(module.FIG.get_fignode(edge[0]), ValueNode)
]
- node_ids.append(interaction.id)
+ node_ids.append(interaction.ID)
sub_graph = module.FIG.subgraph(node_ids)
else:
- sub_graph = module.FIG.subgraph(interaction.id)
+ sub_graph = module.FIG.subgraph(interaction.ID)
mapping_option = MappingOption(operator_candidate, sub_graph)
cn.add_mapping_option(mapping_option)
@@ -869,29 +523,6 @@ def generate(module: Module, library: MappingLibrary) -> MINTDevice:
construction_graph.add_construction_node(cn)
- # Map the storage and pump elements to their own individual construction graph nodes
- for fig_node_id in list(module.FIG.nodes):
- fig_node = module.FIG.get_fignode(fig_node_id)
- if isinstance(fig_node, Pump):
- cn = ConstructionNode(fig_node.id)
- sub_graph = module.FIG.subgraph(fig_node_id)
- mapping_candidates = library.get_pump_entries()
- for mapping_candidate in mapping_candidates:
- mapping_option = MappingOption(mapping_candidate, sub_graph)
- cn.add_mapping_option(mapping_option)
-
- elif isinstance(fig_node, Storage):
- cn = ConstructionNode(fig_node.id)
- sub_graph = module.FIG.subgraph(fig_node_id)
- mapping_candidates = library.get_storage_entries()
- for mapping_candidate in mapping_candidates:
- mapping_option = MappingOption(mapping_candidate, sub_graph)
- cn.add_mapping_option(mapping_option)
-
- # TODO - Validate if this is a legit way to do things
- mappings = module.get_explicit_mappings()
- override_network_mappings(mappings, library, module.FIG, construction_graph)
-
# TODO - Go through the different flow-flow edge networks to generate construction nodes
# specific to these networks, Conditions:
# if its a 1-1 flow-flow connection, then create a construction node for the two flow nodes
@@ -908,6 +539,7 @@ def generate(module: Module, library: MappingLibrary) -> MINTDevice:
# TODO - Modify Explicit Mapping Data structure
# Find all the explicit mappings and override them in the construction graph
+ mappings = module.get_explicit_mappings()
override_mappings(mappings, library, module.FIG, construction_graph)
# Whittle Down the mapping options here to only include the requried single candidates
@@ -920,6 +552,9 @@ def generate(module: Module, library: MappingLibrary) -> MINTDevice:
# reduction of path and pipelineing that needs to get done for mars devices
construction_graph.generate_edges(module.FIG)
+ # TODO - Validate if this is a legit way to do things
+ override_network_mappings(mappings, library, module.FIG, construction_graph)
+
# TODO - Extract all pass through networks
eliminate_passthrough_nodes(construction_graph)
@@ -956,13 +591,13 @@ def override_mappings(
# Step 1 - Loop through each of the mappingtemplates
# Step 2 - Loop through each of the instances in teh mappingtemplate
# Step 3 - Find the cn associated with each of the fig nodes and override the explicit mapping if mappingtemplate has an associated technology string
+ assign_node_index = 0
for mapping in mappings:
for instance in mapping.instances:
-
primitive_to_use = None
if mapping.technology_string is not None:
# Create a mapping option from the library with the corresponding info
- primitive_to_use = mapping_library.get_primitive(
+ primitive_to_use = mapping_library.get_primitives(
mapping.technology_string
)
@@ -971,10 +606,50 @@ def override_mappings(
cn_mapping_options = []
if isinstance(instance, NetworkMapping):
+ # node_ids.extend(n.id for n in instance.input_nodes)
+ # node_ids.extend(n.id for n in instance.output_nodes)
+ # subgraph = fig.subgraph(node_ids)
+ # try:
+ # # TODO - Incase this is a flow-flow candidate, we need to get the
+ # # cn corresponding to this mapping.
+ # # TODO - do we need to have a new flow node constructed
+
+ # cn = construction_graph.get_subgraph_cn(subgraph)
+ # except Exception as e:
+ # # Incase we cannot find a corresponding construction node,
+ # # we need to create a new construction node
+ # print(e)
+ # cn = ConstructionNode("assign_{}".format(assign_node_index))
+ # # Increment the index of the assign construction node
+ # assign_node_index += 1
+
+ # # Find the cn's associated with the input nodes
+ # input_cns = []
+ # output_cns = []
+ # for fig_node in instance.input_nodes:
+ # cn_temp = construction_graph.get_fignode_cn(fig_node)
+ # if cn_temp not in input_cns:
+ # input_cns.append(cn_temp)
+ # for fig_node in instance.output_nodes:
+ # cn_temp = construction_graph.get_fignode_cn(fig_node)
+ # if cn_temp not in output_cns:
+ # output_cns.append(cn_temp)
+
+ # # Now insert the node
+ # construction_graph.insert_cn(cn, input_cns, output_cns)
+
+ # mapping_option = NetworkMappingOption(
+ # network_primitive=primitive_to_use,
+ # mapping_type=NetworkMappingOptionType.COMPONENT_REPLACEMENT,
+ # subgraph_view=subgraph,
+ # )
+ # cn.use_explicit_mapping(mapping_option)
+ # cn_mapping_options.append(mapping_option)
+ # cn_mapping_options.extend(cn.mapping_options)
print(
"Skipping Network Mapping: \n Input - {} \n Output - {}".format(
- ",".join([n.id for n in instance.input_nodes]),
- ",".join([n.id for n in instance.output_nodes]),
+ ",".join([n.ID for n in instance.input_nodes]),
+ ",".join([n.ID for n in instance.output_nodes]),
)
)
continue
@@ -994,12 +669,12 @@ def override_mappings(
# In the case of an Fluid Value interaction put all valuenodes in the subgraph
node_ids.extend(
[
- fig.get_fignode(edge[0]).id
- for edge in fig.in_edges(instance.node.id)
+ fig.get_fignode(edge[0]).ID
+ for edge in fig.in_edges(instance.node.ID)
if isinstance(fig.get_fignode(edge[0]), ValueNode)
]
)
- node_ids.append(instance.node.id)
+ node_ids.append(instance.node.ID)
subgraph = fig.subgraph(node_ids)
# Get the Construction node that has the corresponding subgraph,
@@ -1037,21 +712,12 @@ def override_network_mappings(
assign_node_index = 0
for mapping in mappings:
for instance in mapping.instances:
-
primitive_to_use = None
if mapping.technology_string is not None:
# Create a mapping option from the library with the corresponding info
- try:
- primitive_to_use = mapping_library.get_primitive(
- mapping.technology_string
- )
- except Exception:
- print(
- "Could not find primitive with technology: {}".format(
- mapping.technology_string
- )
- )
- sys.exit(-100)
+ primitive_to_use = mapping_library.get_primitives(
+ mapping.technology_string
+ )
node_ids = []
cn = None # Get the right construction node for doing the stuff
@@ -1060,94 +726,87 @@ def override_network_mappings(
if isinstance(instance, NetworkMapping):
print(
"Applying Network Mapping: \n Input - {} \n Output - {}".format(
- ",".join([n.id for n in instance.input_nodes]),
- ",".join([n.id for n in instance.output_nodes]),
+ ",".join([n.ID for n in instance.input_nodes]),
+ ",".join([n.ID for n in instance.output_nodes]),
)
)
- node_ids.extend(n.id for n in instance.input_nodes)
- node_ids.extend(n.id for n in instance.output_nodes)
+ node_ids.extend(n.ID for n in instance.input_nodes)
+ node_ids.extend(n.ID for n in instance.output_nodes)
subgraph = fig.subgraph(node_ids)
- # try:
- # # TODO - Incase this is a flow-flow candidate, we need to get the
- # # cn corresponding to this mapping.
- # # TODO - do we need to have a new flow node constructed
-
- # cn = construction_graph.get_subgraph_cn(subgraph)
- # except Exception as e:
- # # Incase we cannot find a corresponding construction node,
- # # we need to create a new construction node
- # print(e)
- # cn = ConstructionNode("assign_{}".format(assign_node_index))
- # # Increment the index of the assign construction node
- # assign_node_index += 1
-
- # # Find the cn's associated with the input nodes
- # input_cns = []
- # output_cns = []
- # for fig_node in instance.input_nodes:
- # cn_temp = construction_graph.get_fignode_cn(fig_node)
- # if cn_temp not in input_cns:
- # input_cns.append(cn_temp)
- # for fig_node in instance.output_nodes:
- # cn_temp = construction_graph.get_fignode_cn(fig_node)
- # if cn_temp not in output_cns:
- # output_cns.append(cn_temp)
-
- # # split_groups = []
- # # # TODO - If we need to split the we first are gonna make a copy
- # # # of the subgraph and then delete any edges between the inputs
- # # # and the outputs
- # # subgraph_copy = deepcopy(subgraph)
- # # # Delete any edges between inputs and outputs
- # # for input_node in instance.input_nodes:
- # # for output_node in instance.output_nodes:
- # # if subgraph_copy.has_edge(input_node.id, output_node.id):
- # # subgraph_copy.remove_edge(input_node.id, output_node.id)
-
- # # components = subgraph_copy.connected_components()
- # # for component in components:
- # # split_groups.append(list(component.nodes))
-
- # # TODO - If inputcns and output cns are the same, we split them
- # for input_cn in input_cns:
- # if input_cn in output_cns:
- # split_groups = generate_split_groups(
- # input_cn.mapping_options[0].fig_subgraph, instance
- # )
- # construction_graph.split_cn(input_cn, split_groups, fig)
- # # Now insert the node
- # construction_graph.insert_cn(cn, input_cns, output_cns)
-
- # # Check to see if this works or not
- # cn = construction_graph.get_subgraph_cn(subgraph)
+ try:
+ # TODO - Incase this is a flow-flow candidate, we need to get the
+ # cn corresponding to this mapping.
+ # TODO - do we need to have a new flow node constructed
+
+ cn = construction_graph.get_subgraph_cn(subgraph)
+ except Exception as e:
+ # Incase we cannot find a corresponding construction node,
+ # we need to create a new construction node
+ print(e)
+ cn = ConstructionNode("assign_{}".format(assign_node_index))
+ # Increment the index of the assign construction node
+ assign_node_index += 1
+
+ # Find the cn's associated with the input nodes
+ input_cns = []
+ output_cns = []
+ for fig_node in instance.input_nodes:
+ cn_temp = construction_graph.get_fignode_cn(fig_node)
+ if cn_temp not in input_cns:
+ input_cns.append(cn_temp)
+ for fig_node in instance.output_nodes:
+ cn_temp = construction_graph.get_fignode_cn(fig_node)
+ if cn_temp not in output_cns:
+ output_cns.append(cn_temp)
+
+ # Now insert the node
+ construction_graph.insert_cn(cn, input_cns, output_cns)
- # Find the cn's associated with the input nodes
- input_cns = []
- output_cns = []
- for fig_node in instance.input_nodes:
- cn_temp = construction_graph.get_fignode_cn(fig_node)
- if cn_temp not in input_cns:
- input_cns.append(cn_temp)
- for fig_node in instance.output_nodes:
- cn_temp = construction_graph.get_fignode_cn(fig_node)
- if cn_temp not in output_cns:
- output_cns.append(cn_temp)
-
- cn = ConstructionNode("assign_{}".format(assign_node_index))
- assign_node_index += 1
- if isinstance(primitive_to_use, NetworkPrimitive) is not True:
- raise TypeError()
- if primitive_to_use is None:
- raise ValueError()
mapping_option = NetworkMappingOption(
network_primitive=primitive_to_use,
mapping_type=NetworkMappingOptionType.COMPONENT_REPLACEMENT,
subgraph_view=subgraph,
)
cn.use_explicit_mapping(mapping_option)
- construction_graph.insert_cn(cn, input_cns, output_cns, fig)
+ cn_mapping_options.append(mapping_option)
+ cn_mapping_options.extend(cn.mapping_options)
else:
+ # # Find the construction node assicated with the
+ # # FIG node and then do the followinging:
+ # # Step 1 - If the mappingtemplate has no technology string assiciated
+ # # with the mapping, just apply the constraints to the associated mapping
+ # # options
+
+ # # Step 2 - In there is a string assiciated with the mappingtemplate, we
+ # # eliminate all mapping options that dont have a matching string / generate
+ # # a mapping option with the corresponding
+
+ # # In the case of an Fluid Value interaction put all valuenodes in the subgraph
+ # node_ids.extend(
+ # [
+ # fig.get_fignode(edge[0]).id
+ # for edge in fig.in_edges(instance.node.id)
+ # if isinstance(fig.get_fignode(edge[0]), ValueNode)
+ # ]
+ # )
+ # node_ids.append(instance.node.id)
+ # subgraph = fig.subgraph(node_ids)
+
+ # # Get the Construction node that has the corresponding subgraph,
+ # # and then replace the mapping option
+ # cn = construction_graph.get_subgraph_cn(subgraph)
+ # if primitive_to_use is not None:
+ # mapping_option = MappingOption(primitive_to_use, subgraph)
+ # cn.use_explicit_mapping(mapping_option)
+ # cn_mapping_options.append(mapping_option)
+ # else:
+ # # Add the constraints to all the mapping options
+ # # This is an example where since no explicit mapping
+ # # was specified, we only add the performance/material
+ # # constraints. This can be ulitized for whittling down
+ # # options later if necessary.
+ # cn_mapping_options.extend(cn.mapping_options)
continue
# Now that we know what the mapping options are (either explicit
# loaded from the library, we can add the performance constraints)
@@ -1163,8 +822,7 @@ def eliminate_passthrough_nodes(construction_graph: ConstructionGraph):
mapping_option = cn.mapping_options[0]
if isinstance(mapping_option, NetworkMappingOption):
if mapping_option.mapping_type is NetworkMappingOptionType.PASS_THROUGH:
-
- print("Eliminating PASS THROUGH construction node = {}".format(cn.id))
+ print("Eliminating PASS THROUGH construction node = {}".format(cn.ID))
# First get all the in and out edges
in_edges = list(construction_graph.in_edges(node_id))
@@ -1196,26 +854,6 @@ def eliminate_passthrough_nodes(construction_graph: ConstructionGraph):
)
-def generate_split_groups(subgraph, instance) -> List[Set[str]]:
- split_groups = []
- # TODO - If we need to split the we first are gonna make a copy
- # of the subgraph and then delete any edges between the inputs
- # and the outputs
- subgraph_copy = deepcopy(subgraph)
- # Delete delete all the input and output nodes here
- for input_node in instance.input_nodes:
- subgraph_copy.remove_node(input_node.id)
-
- for output_node in instance.output_nodes:
- subgraph_copy.remove_node(output_node.id)
-
- components = nx.connected_components(nx.to_undirected(subgraph_copy))
- for component in components:
- split_groups.append(component)
-
- return split_groups
-
-
def connect_orphan_IO():
print("Implement the orphan io generation system")
@@ -1245,22 +883,11 @@ def get_flow_flow_candidates(
# Step 2. Remove all the fignodes that are not Flow
remove_list = []
-
- # Remove nodes from the explicit mapping construction nodes
- for mapping in module.mappings:
- for instance in mapping.instances:
- if isinstance(instance, NetworkMapping):
- remove_list.extend([n.id for n in instance.input_nodes])
- remove_list.extend([n.id for n in instance.output_nodes])
- else:
- remove_list.append(instance.node.id)
-
for node_id in fig_copy.nodes:
node = fig_original.get_fignode(node_id)
if node.match_string != "FLOW":
remove_list.append(node_id)
- remove_list = list(set(remove_list))
for node_id in remove_list:
fig_copy.remove_node(node_id)
@@ -1290,32 +917,14 @@ def get_flow_flow_candidates(
return ret
-# def size_netlist():
-# # Size all the node's netlist components to based on the CONSTRAINTS set
-# # by the postprocessor
-# # TODO - Modify datastructure in library and other places
-# netlist_user_constriants = module.get_user_constriants()
+def size_netlist():
+ # Size all the node's netlist components to based on the CONSTRAINTS set
+ # by the postprocessor
+ # TODO - Modify datastructure in library and other places
+ netlist_user_constriants = module.get_user_constriants()
-# construction_graph.fix_component_params(netlist_user_constriants)
+ construction_graph.fix_component_params(netlist_user_constriants)
-# # Size all the Meter/Dilute/Divide nodes based on the value nodes
-# # TODO - Talk to Ali about this for strategy
-# construction_graph.size_components()
-
-
-def __check_if_passthrough(sub) -> bool:
- # Return true if its a single chain of flow channels
- in_count = 0
- out_count = 0
- for node in list(sub.nodes):
- inedges = list(sub.in_edges(node))
- outedges = list(sub.out_edges(node))
- if len(inedges) == 0:
- in_count += 1
- if len(outedges) == 0:
- out_count += 1
-
- if in_count == 1 and out_count == 1:
- return True
- else:
- return False
+ # Size all the Meter/Dilute/Divide nodes based on the value nodes
+ # TODO - Talk to Ali about this for strategy
+ construction_graph.size_components()
diff --git a/lfr/netlistgenerator/v2/gen_strategies/genstrategy.py b/old-stuff/genstrategy-old.py
similarity index 61%
rename from lfr/netlistgenerator/v2/gen_strategies/genstrategy.py
rename to old-stuff/genstrategy-old.py
index b554d23..95b4999 100644
--- a/lfr/netlistgenerator/v2/gen_strategies/genstrategy.py
+++ b/old-stuff/genstrategy-old.py
@@ -7,49 +7,46 @@
from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
if TYPE_CHECKING:
- from lfr.netlistgenerator.v2.constructiongraph import ConstructionGraph
+ from lfr.netlistgenerator.constructiongraph import ConstructionGraph
from typing import List
+from parchmint import Target
from pymint.mintdevice import MINTDevice
from pymint.mintnode import MINTNode
-from pymint.minttarget import MINTTarget
-from lfr.netlistgenerator.v2.connectingoption import ConnectingOption
+from lfr.netlistgenerator.connectingoption import ConnectingOption
class GenStrategy:
- def __init__(
- self, construction_graph: ConstructionGraph, fig: FluidInteractionGraph
- ) -> None:
- self._construction_graph: ConstructionGraph = construction_graph
+ def __init__(self, fig: FluidInteractionGraph) -> None:
self._fig: FluidInteractionGraph = fig
self._fig_netlist_map: Dict[str, str] = {}
def reduce_mapping_options(self) -> None:
# Dummy strategy
- for cn in self._construction_graph.construction_nodes:
- # print(len(cn.mapping_options))
- # clean this
- # Remove the extra mappings
- print(
- "Reducing mapping options for Construction node: {} from {} to {}".format(
- cn.id, len(cn.mapping_options), 1
- ),
- )
- if len(cn.mapping_options) > 1:
- for option in cn.mapping_options:
- print(" -{}".format(option.primitive.mint))
- del cn.mapping_options[1 : len(cn.mapping_options)]
- # print("... -> {}".format(len(cn.mapping_options)))
-
- print("Printing all final mapping options:")
- for cn in self._construction_graph.construction_nodes:
- print("Construction node: {}".format(cn.id))
- print("Options: ")
-
- for mapping_option in cn.mapping_options:
- print(mapping_option.primitive.mint)
+ # for cn in self._construction_graph.construction_nodes:
+ # # print(len(cn.mapping_options))
+ # # clean this
+ # # Remove the extra mappings
+ # print(
+ # "Reducing mapping options for Construction node: {} from {} to {}"
+ # .format(cn.ID, len(cn.mapping_options), 1),
+ # )
+ # if len(cn.mapping_options) > 1:
+ # for option in cn.mapping_options:
+ # print(" -{}".format(option.primitive.mint))
+ # del cn.mapping_options[1 : len(cn.mapping_options)]
+ # # print("... -> {}".format(len(cn.mapping_options)))
+
+ # print("Printing all final mapping options:")
+ # for cn in self._construction_graph.construction_nodes:
+ # print("Construction node: {}".format(cn.ID))
+ # print("Options: ")
+
+ # for mapping_option in cn.mapping_options:
+ # print(mapping_option.primitive.mint)
+ pass
def generate_flow_network(self, fig_subgraph_view) -> MINTDevice:
# TODO - For now just assume that the networks basically are a bunch
@@ -58,8 +55,8 @@ def generate_flow_network(self, fig_subgraph_view) -> MINTDevice:
mint_layer = ret.create_mint_layer("0", "0", 0, MINTLayerType.FLOW)
for node in fig_subgraph_view.nodes:
n = MINTNode("node_{}".format(node), mint_layer)
- ret.add_component(n)
- self._store_fig_netlist_name(node, n.ID)
+ ret.device.add_component(n.component)
+ self._store_fig_netlist_name(node, n.component.ID)
i = 1
for node in fig_subgraph_view.nodes:
@@ -68,18 +65,18 @@ def generate_flow_network(self, fig_subgraph_view) -> MINTDevice:
i += 1
params = {}
params["channelWidth"] = 400
- source = MINTTarget("node_{}".format(node))
+ source = Target("node_{}".format(node))
sinks = []
# Add all the outgoing edges
for edge in fig_subgraph_view.out_edges(node):
tar = edge[1]
if tar not in fig_subgraph_view.nodes:
- # We skip because this might be a weird edge that we were not supposed
- # to have in this network
+ # We skip because this might be a weird edge that we
+ # were not supposed to have in this network
continue
- sinks.append(MINTTarget("node_{}".format(tar)))
+ sinks.append(Target("node_{}".format(tar)))
ret.create_mint_connection(
channel_name, "CHANNEL", params, source, sinks, "0"
@@ -125,3 +122,9 @@ def generate_loading_connectingoptions(subgraph_view) -> List[ConnectingOption]:
def size_netlist(self, device: MINTDevice) -> None:
raise NotImplementedError()
+
+ def prune_variants(self, variants: List[ConstructionGraph]) -> None:
+ for variant in variants:
+ if variant.is_fig_fully_covered() is not True:
+ print("Removing variant (Construction Graph): {}".format(variant.ID))
+ variants.remove(variant)
diff --git a/old-stuff/mars-old.py b/old-stuff/mars-old.py
new file mode 100644
index 0000000..510db5b
--- /dev/null
+++ b/old-stuff/mars-old.py
@@ -0,0 +1,24 @@
+from typing import overload
+
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+from lfr.netlistgenerator.gen_strategies.genstrategy import GenStrategy
+
+
+class MARSStrategy(GenStrategy):
+ def __init__(self, fig: FluidInteractionGraph) -> None:
+ super().__init__(fig)
+
+ def reduce_mapping_options(self) -> None:
+ # TODO - Implement Generalized Ali Strategy 1
+
+ # # Dummy strategy
+ # for cn in [v for k, v in self._construction_nodes.items()]:
+ # print(len(cn.mapping_options))
+ # # Remove the extra mappings
+ # del cn.mapping_options[1 : len(cn.mapping_options)]
+ # print(len(cn.mapping_options))
+ # pass
+ pass
+
+ def size_netlist(self):
+ super()
diff --git a/lfr/netlistgenerator/v2/gen_strategies/marsstrategy.py b/old-stuff/marsstrategy-old.py
similarity index 67%
rename from lfr/netlistgenerator/v2/gen_strategies/marsstrategy.py
rename to old-stuff/marsstrategy-old.py
index 21d52cc..332701d 100644
--- a/lfr/netlistgenerator/v2/gen_strategies/marsstrategy.py
+++ b/old-stuff/marsstrategy-old.py
@@ -2,46 +2,44 @@
from typing import TYPE_CHECKING, Dict
-from networkx.generators.degree_seq import directed_configuration_model
from pymint.mintlayer import MINTLayerType
from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
-from lfr.fig.interaction import Interaction
-from lfr.netlistgenerator.v2.constructionnode import ConstructionNode
-from lfr.netlistgenerator.v2.dafdadapter import DAFDAdapter
+from lfr.netlistgenerator.constructiongraph.constructionnode import ConstructionNode
+from lfr.netlistgenerator.dafdadapter import DAFDAdapter
+from lfr.netlistgenerator.gen_strategies.genstrategy import GenStrategy
if TYPE_CHECKING:
- from lfr.netlistgenerator.v2.constructiongraph import ConstructionGraph
+ from lfr.netlistgenerator.constructiongraph.constructiongraph import (
+ ConstructionGraph,
+ )
from typing import List
+from parchmint import Target
from pymint.mintdevice import MINTDevice
from pymint.mintnode import MINTNode
-from pymint.minttarget import MINTTarget
-from lfr.netlistgenerator.v2.connectingoption import ConnectingOption
+from lfr.netlistgenerator.connectingoption import ConnectingOption
-class MarsStrategy:
- def __init__(
- self, construction_graph: ConstructionGraph, fig: FluidInteractionGraph
- ) -> None:
- self._construction_graph: ConstructionGraph = construction_graph
+class MarsStrategy(GenStrategy):
+ def __init__(self, fig: FluidInteractionGraph) -> None:
self._fig: FluidInteractionGraph = fig
self._fig_netlist_map: Dict[str, str] = dict()
def reduce_mapping_options(self) -> None:
# Dummy strategy
- for fignode_id in self._fig.nodes:
- fignode = self._fig.get_fignode(fignode_id)
+ # for fignode_id in self._fig.nodes:
+ # fignode = self._fig.get_fignode(fignode_id)
- if ConstructionNode(fignode_id).is_explictly_mapped:
- pass
- else:
- if isinstance(fignode, Interaction):
- cn = self._construction_graph.get_fignode_cn(fignode)
+ # if ConstructionNode(fignode_id).is_explictly_mapped:
+ # pass
+ # else:
+ # if isinstance(fignode, Interaction):
+ # cn = self._construction_graph.get_fignode_cn(fignode)
- del cn.mapping_options[1 : len(cn.mapping_options)]
+ # del cn.mapping_options[1 : len(cn.mapping_options)]
# for cn in self._construction_graph.construction_nodes:
# # print(len(cn.mapping_options))
@@ -65,6 +63,7 @@ def reduce_mapping_options(self) -> None:
# for mapping_option in cn.mapping_options:
# print(mapping_option.primitive.mint)
+ pass
def generate_flow_network(self, fig_subgraph_view) -> MINTDevice:
# TODO - For now just assume that the networks basically are a bunch
@@ -72,9 +71,10 @@ def generate_flow_network(self, fig_subgraph_view) -> MINTDevice:
ret = MINTDevice("flow_network_temp")
mint_layer = ret.create_mint_layer("0", "0", 0, MINTLayerType.FLOW)
for node in fig_subgraph_view.nodes:
- n = MINTNode("node_{}".format(node), mint_layer)
- ret.add_component(n)
- self._store_fig_netlist_name(node, n.ID)
+ node = MINTNode("node_{}".format(str(node)), mint_layer)
+ ret.device.add_component(node.component)
+ # TODO - Add method to store NODES
+ self._store_fig_netlist_name(str(node), node.component.ID)
i = 1
for node in fig_subgraph_view.nodes:
@@ -83,7 +83,7 @@ def generate_flow_network(self, fig_subgraph_view) -> MINTDevice:
i += 1
params = dict()
params["channelWidth"] = 400
- source = MINTTarget("node_{}".format(node))
+ source = Target("node_{}".format(node))
sinks = []
# Add all the outgoing edges
@@ -94,7 +94,7 @@ def generate_flow_network(self, fig_subgraph_view) -> MINTDevice:
# to have in this network
continue
- sinks.append(MINTTarget("node_{}".format(tar)))
+ sinks.append(Target("node_{}".format(tar)))
ret.create_mint_connection(
channel_name, "CHANNEL", params, source, sinks, "0"
@@ -144,14 +144,15 @@ def size_netlist(self, device: MINTDevice) -> None:
"""
Sizes the device based on either lookup tables, inverse design algorithms, etc.
"""
- dafd_adapter = DAFDAdapter(device)
- # Default size for PORT is 2000 um
- for component in device.components:
- constraints = self._construction_graph.get_component_cn(
- component
- ).constraints
- if component.entity == "NOZZLE DROPLET GENERATOR":
- # dafd_adapter.size_droplet_generator(component, constraints)
- print("Skipping calling DAFD since its crashing everything right now")
- elif component.entity == "PORT":
- component.params.set_param("portRadius", 2000)
+ # dafd_adapter = DAFDAdapter(device)
+ # # Default size for PORT is 2000 um
+ # for component in device.components:
+ # constraints = self._construction_graph.get_component_cn(
+ # component
+ # ).constraints
+ # if component.entity == "NOZZLE DROPLET GENERATOR":
+ # # dafd_adapter.size_droplet_generator(component, constraints)
+ # print("Skipping calling DAFD since its crashing everything right now")
+ # elif component.entity == "PORT":
+ # component.params.set_param("portRadius", 2000)
+ pass
diff --git a/poetry.lock b/poetry.lock
index 529fedb..1c78ee7 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,29 +1,40 @@
+# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand.
+
[[package]]
name = "absl-py"
-version = "0.13.0"
+version = "1.4.0"
description = "Abseil Python Common Libraries, see https://github.com/abseil/abseil-py."
-category = "dev"
+category = "main"
optional = false
-python-versions = "*"
-
-[package.dependencies]
-six = "*"
+python-versions = ">=3.6"
+files = [
+ {file = "absl-py-1.4.0.tar.gz", hash = "sha256:d2c244d01048ba476e7c080bd2c6df5e141d211de80223460d5b3b8a2a58433d"},
+ {file = "absl_py-1.4.0-py3-none-any.whl", hash = "sha256:0d3fe606adfa4f7db64792dd4c7aee4ee0c38ab75dfd353b7a83ed3e957fcb47"},
+]
[[package]]
-name = "antlr4-python3-runtime"
-version = "4.8"
-description = "ANTLR 4.8 runtime for Python 3.7"
-category = "main"
+name = "alabaster"
+version = "0.7.13"
+description = "A configurable sidebar-enabled Sphinx theme"
+category = "dev"
optional = false
-python-versions = "*"
+python-versions = ">=3.6"
+files = [
+ {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"},
+ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"},
+]
[[package]]
-name = "appdirs"
-version = "1.4.4"
-description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
-category = "dev"
+name = "antlr4-python3-runtime"
+version = "4.12.0"
+description = "ANTLR 4.12.0 runtime for Python 3"
+category = "main"
optional = false
python-versions = "*"
+files = [
+ {file = "antlr4-python3-runtime-4.12.0.tar.gz", hash = "sha256:0a8b82f55032734f43ed6b60b8a48c25754721a75cd714eb1fe9ce6ed418b361"},
+ {file = "antlr4_python3_runtime-4.12.0-py3-none-any.whl", hash = "sha256:2c08f4dfbdc7dfd10f680681a96a55579c1e4f866f01d27099c9a54027923d70"},
+]
[[package]]
name = "argparse"
@@ -32,184 +43,516 @@ description = "Python command-line parsing library"
category = "main"
optional = false
python-versions = "*"
+files = [
+ {file = "argparse-1.4.0-py2.py3-none-any.whl", hash = "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314"},
+ {file = "argparse-1.4.0.tar.gz", hash = "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4"},
+]
+
+[[package]]
+name = "art"
+version = "5.8"
+description = "ASCII Art Library For Python"
+category = "main"
+optional = false
+python-versions = ">=2.7"
+files = [
+ {file = "art-5.8-py2.py3-none-any.whl", hash = "sha256:cd77a9dcfe49dfb82f37a7b2401ae771fde6e155942b4e3dbc50a68c2bc7027c"},
+ {file = "art-5.8.tar.gz", hash = "sha256:83e383910e07eb7844a6618498708e0080ea842d584128ee6b0dc62d8b48cf36"},
+]
+
+[package.extras]
+dev = ["bandit (>=1.5.1)", "codecov (>=2.0.15)", "coverage (>=4.1)", "pydocstyle (>=3.0.0)", "vulture (>=1.0)"]
[[package]]
name = "astunparse"
version = "1.6.3"
description = "An AST unparser for Python"
-category = "dev"
+category = "main"
optional = false
python-versions = "*"
+files = [
+ {file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"},
+ {file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"},
+]
[package.dependencies]
six = ">=1.6.1,<2.0"
+wheel = ">=0.23.0,<1.0"
[[package]]
name = "attrs"
-version = "21.2.0"
+version = "22.2.0"
description = "Classes Without Boilerplate"
category = "main"
optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.6"
+files = [
+ {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"},
+ {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"},
+]
[package.extras]
-dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"]
-docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
-tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"]
-tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"]
+cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"]
+dev = ["attrs[docs,tests]"]
+docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"]
+tests = ["attrs[tests-no-zope]", "zope.interface"]
+tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"]
+
+[[package]]
+name = "babel"
+version = "2.12.1"
+description = "Internationalization utilities"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"},
+ {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"},
+]
+
+[package.dependencies]
+pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""}
[[package]]
name = "black"
-version = "20.8b1"
+version = "22.3.0"
description = "The uncompromising code formatter."
category = "dev"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.6.2"
+files = [
+ {file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"},
+ {file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"},
+ {file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"},
+ {file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"},
+ {file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"},
+ {file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"},
+ {file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"},
+ {file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"},
+ {file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"},
+ {file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"},
+ {file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"},
+ {file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"},
+ {file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"},
+ {file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"},
+ {file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"},
+ {file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"},
+ {file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"},
+ {file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"},
+ {file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"},
+ {file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"},
+ {file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"},
+ {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"},
+ {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"},
+]
[package.dependencies]
-appdirs = "*"
-click = ">=7.1.2"
+click = ">=8.0.0"
mypy-extensions = ">=0.4.3"
-pathspec = ">=0.6,<1"
-regex = ">=2020.1.8"
-toml = ">=0.10.1"
-typed-ast = ">=1.4.0"
-typing-extensions = ">=3.7.4"
+pathspec = ">=0.9.0"
+platformdirs = ">=2"
+tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
+typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
[package.extras]
colorama = ["colorama (>=0.4.3)"]
-d = ["aiohttp (>=3.3.2)", "aiohttp-cors"]
+d = ["aiohttp (>=3.7.4)"]
+jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
+uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "cachetools"
-version = "4.2.2"
+version = "5.3.0"
description = "Extensible memoizing collections and decorators"
-category = "dev"
+category = "main"
optional = false
-python-versions = "~=3.5"
+python-versions = "~=3.7"
+files = [
+ {file = "cachetools-5.3.0-py3-none-any.whl", hash = "sha256:429e1a1e845c008ea6c85aa35d4b98b65d6a9763eeef3e37e92728a12d1de9d4"},
+ {file = "cachetools-5.3.0.tar.gz", hash = "sha256:13dfddc7b8df938c21a940dfa6557ce6e94a2f1cdfa58eb90c805721d58f2c14"},
+]
[[package]]
name = "certifi"
-version = "2021.5.30"
+version = "2022.12.7"
description = "Python package for providing Mozilla's CA Bundle."
-category = "dev"
+category = "main"
optional = false
-python-versions = "*"
+python-versions = ">=3.6"
+files = [
+ {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"},
+ {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"},
+]
[[package]]
-name = "chardet"
-version = "4.0.0"
-description = "Universal encoding detector for Python 2 and 3"
-category = "dev"
+name = "charset-normalizer"
+version = "3.1.0"
+description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
+category = "main"
optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.7.0"
+files = [
+ {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"},
+ {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"},
+ {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"},
+ {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"},
+ {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"},
+ {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"},
+ {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"},
+]
[[package]]
name = "click"
-version = "7.1.2"
+version = "8.1.3"
description = "Composable command line interface toolkit"
-category = "dev"
+category = "main"
optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.7"
+files = [
+ {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
+ {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
-name = "cycler"
-version = "0.10.0"
-description = "Composable style cycles"
-category = "dev"
+name = "colorama"
+version = "0.4.6"
+description = "Cross-platform colored terminal text."
+category = "main"
optional = false
-python-versions = "*"
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+files = [
+ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
+ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
+]
+
+[[package]]
+name = "contourpy"
+version = "1.0.7"
+description = "Python library for calculating contours of 2D quadrilateral grids"
+category = "main"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:95c3acddf921944f241b6773b767f1cbce71d03307270e2d769fd584d5d1092d"},
+ {file = "contourpy-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fc1464c97579da9f3ab16763c32e5c5d5bb5fa1ec7ce509a4ca6108b61b84fab"},
+ {file = "contourpy-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8acf74b5d383414401926c1598ed77825cd530ac7b463ebc2e4f46638f56cce6"},
+ {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c71fdd8f1c0f84ffd58fca37d00ca4ebaa9e502fb49825484da075ac0b0b803"},
+ {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f99e9486bf1bb979d95d5cffed40689cb595abb2b841f2991fc894b3452290e8"},
+ {file = "contourpy-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87f4d8941a9564cda3f7fa6a6cd9b32ec575830780677932abdec7bcb61717b0"},
+ {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9e20e5a1908e18aaa60d9077a6d8753090e3f85ca25da6e25d30dc0a9e84c2c6"},
+ {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a877ada905f7d69b2a31796c4b66e31a8068b37aa9b78832d41c82fc3e056ddd"},
+ {file = "contourpy-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6381fa66866b0ea35e15d197fc06ac3840a9b2643a6475c8fff267db8b9f1e69"},
+ {file = "contourpy-1.0.7-cp310-cp310-win32.whl", hash = "sha256:3c184ad2433635f216645fdf0493011a4667e8d46b34082f5a3de702b6ec42e3"},
+ {file = "contourpy-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:3caea6365b13119626ee996711ab63e0c9d7496f65641f4459c60a009a1f3e80"},
+ {file = "contourpy-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ed33433fc3820263a6368e532f19ddb4c5990855e4886088ad84fd7c4e561c71"},
+ {file = "contourpy-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38e2e577f0f092b8e6774459317c05a69935a1755ecfb621c0a98f0e3c09c9a5"},
+ {file = "contourpy-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ae90d5a8590e5310c32a7630b4b8618cef7563cebf649011da80874d0aa8f414"},
+ {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130230b7e49825c98edf0b428b7aa1125503d91732735ef897786fe5452b1ec2"},
+ {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58569c491e7f7e874f11519ef46737cea1d6eda1b514e4eb5ac7dab6aa864d02"},
+ {file = "contourpy-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54d43960d809c4c12508a60b66cb936e7ed57d51fb5e30b513934a4a23874fae"},
+ {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:152fd8f730c31fd67fe0ffebe1df38ab6a669403da93df218801a893645c6ccc"},
+ {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9056c5310eb1daa33fc234ef39ebfb8c8e2533f088bbf0bc7350f70a29bde1ac"},
+ {file = "contourpy-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a9d7587d2fdc820cc9177139b56795c39fb8560f540bba9ceea215f1f66e1566"},
+ {file = "contourpy-1.0.7-cp311-cp311-win32.whl", hash = "sha256:4ee3ee247f795a69e53cd91d927146fb16c4e803c7ac86c84104940c7d2cabf0"},
+ {file = "contourpy-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:5caeacc68642e5f19d707471890f037a13007feba8427eb7f2a60811a1fc1350"},
+ {file = "contourpy-1.0.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd7dc0e6812b799a34f6d12fcb1000539098c249c8da54f3566c6a6461d0dbad"},
+ {file = "contourpy-1.0.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0f9d350b639db6c2c233d92c7f213d94d2e444d8e8fc5ca44c9706cf72193772"},
+ {file = "contourpy-1.0.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e96a08b62bb8de960d3a6afbc5ed8421bf1a2d9c85cc4ea73f4bc81b4910500f"},
+ {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:031154ed61f7328ad7f97662e48660a150ef84ee1bc8876b6472af88bf5a9b98"},
+ {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e9ebb4425fc1b658e13bace354c48a933b842d53c458f02c86f371cecbedecc"},
+ {file = "contourpy-1.0.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efb8f6d08ca7998cf59eaf50c9d60717f29a1a0a09caa46460d33b2924839dbd"},
+ {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6c180d89a28787e4b73b07e9b0e2dac7741261dbdca95f2b489c4f8f887dd810"},
+ {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b8d587cc39057d0afd4166083d289bdeff221ac6d3ee5046aef2d480dc4b503c"},
+ {file = "contourpy-1.0.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:769eef00437edf115e24d87f8926955f00f7704bede656ce605097584f9966dc"},
+ {file = "contourpy-1.0.7-cp38-cp38-win32.whl", hash = "sha256:62398c80ef57589bdbe1eb8537127321c1abcfdf8c5f14f479dbbe27d0322e66"},
+ {file = "contourpy-1.0.7-cp38-cp38-win_amd64.whl", hash = "sha256:57119b0116e3f408acbdccf9eb6ef19d7fe7baf0d1e9aaa5381489bc1aa56556"},
+ {file = "contourpy-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:30676ca45084ee61e9c3da589042c24a57592e375d4b138bd84d8709893a1ba4"},
+ {file = "contourpy-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e927b3868bd1e12acee7cc8f3747d815b4ab3e445a28d2e5373a7f4a6e76ba1"},
+ {file = "contourpy-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:366a0cf0fc079af5204801786ad7a1c007714ee3909e364dbac1729f5b0849e5"},
+ {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89ba9bb365446a22411f0673abf6ee1fea3b2cf47b37533b970904880ceb72f3"},
+ {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71b0bf0c30d432278793d2141362ac853859e87de0a7dee24a1cea35231f0d50"},
+ {file = "contourpy-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7281244c99fd7c6f27c1c6bfafba878517b0b62925a09b586d88ce750a016d2"},
+ {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b6d0f9e1d39dbfb3977f9dd79f156c86eb03e57a7face96f199e02b18e58d32a"},
+ {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7f6979d20ee5693a1057ab53e043adffa1e7418d734c1532e2d9e915b08d8ec2"},
+ {file = "contourpy-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5dd34c1ae752515318224cba7fc62b53130c45ac6a1040c8b7c1a223c46e8967"},
+ {file = "contourpy-1.0.7-cp39-cp39-win32.whl", hash = "sha256:c5210e5d5117e9aec8c47d9156d1d3835570dd909a899171b9535cb4a3f32693"},
+ {file = "contourpy-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:60835badb5ed5f4e194a6f21c09283dd6e007664a86101431bf870d9e86266c4"},
+ {file = "contourpy-1.0.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ce41676b3d0dd16dbcfabcc1dc46090aaf4688fd6e819ef343dbda5a57ef0161"},
+ {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a011cf354107b47c58ea932d13b04d93c6d1d69b8b6dce885e642531f847566"},
+ {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:31a55dccc8426e71817e3fe09b37d6d48ae40aae4ecbc8c7ad59d6893569c436"},
+ {file = "contourpy-1.0.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69f8ff4db108815addd900a74df665e135dbbd6547a8a69333a68e1f6e368ac2"},
+ {file = "contourpy-1.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efe99298ba37e37787f6a2ea868265465410822f7bea163edcc1bd3903354ea9"},
+ {file = "contourpy-1.0.7-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a1e97b86f73715e8670ef45292d7cc033548266f07d54e2183ecb3c87598888f"},
+ {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc331c13902d0f50845099434cd936d49d7a2ca76cb654b39691974cb1e4812d"},
+ {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24847601071f740837aefb730e01bd169fbcaa610209779a78db7ebb6e6a7051"},
+ {file = "contourpy-1.0.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abf298af1e7ad44eeb93501e40eb5a67abbf93b5d90e468d01fc0c4451971afa"},
+ {file = "contourpy-1.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:64757f6460fc55d7e16ed4f1de193f362104285c667c112b50a804d482777edd"},
+ {file = "contourpy-1.0.7.tar.gz", hash = "sha256:d8165a088d31798b59e91117d1f5fc3df8168d8b48c4acc10fc0df0d0bdbcc5e"},
+]
[package.dependencies]
-six = "*"
+numpy = ">=1.16"
+
+[package.extras]
+bokeh = ["bokeh", "chromedriver", "selenium"]
+docs = ["furo", "sphinx-copybutton"]
+mypy = ["contourpy[bokeh]", "docutils-stubs", "mypy (==0.991)", "types-Pillow"]
+test = ["Pillow", "matplotlib", "pytest"]
+test-no-images = ["pytest"]
+
+[[package]]
+name = "cycler"
+version = "0.11.0"
+description = "Composable style cycles"
+category = "main"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"},
+ {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"},
+]
[[package]]
name = "dafd"
version = "0.1.1"
description = "Python package for the library for DAFD."
-category = "dev"
+category = "main"
optional = false
python-versions = "^3.8"
-develop = true
+files = []
+develop = false
[package.dependencies]
-keras = ">=2.4.3,<3.0.0"
-Markdown = ">=3.3.3,<4.0.0"
-matplotlib = ">=3.3.1,<4.0.0"
-pandas = ">=1.1.2,<2.0.0"
-SALib = ">=1.3.12,<2.0.0"
-scikit-learn = ">=0.23.2,<0.24.0"
-seaborn = ">=0.11.1,<0.12.0"
-tensorflow = ">=2.3.0,<3.0.0"
-tqdm = ">=4.48.2,<5.0.0"
+keras = "^2.4.3"
+Markdown = "^3.3.3"
+matplotlib = "^3.3.1"
+pandas = "^1.1.2"
+SALib = "^1.3.12"
+scikit-learn = "^0.23.2"
+seaborn = "^0.11.1"
+tensorflow = "^2.3.0"
+tqdm = "^4.48.2"
[package.source]
type = "directory"
-url = "../dafd"
+url = "dafd"
[[package]]
-name = "decorator"
-version = "4.4.2"
-description = "Decorators for Humans"
+name = "dill"
+version = "0.3.6"
+description = "serialize all of python"
category = "main"
optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*"
+python-versions = ">=3.7"
+files = [
+ {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"},
+ {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"},
+]
+
+[package.extras]
+graph = ["objgraph (>=1.7.2)"]
+
+[[package]]
+name = "docutils"
+version = "0.16"
+description = "Docutils -- Python Documentation Utilities"
+category = "dev"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+files = [
+ {file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"},
+ {file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"},
+]
+
+[[package]]
+name = "exceptiongroup"
+version = "1.1.1"
+description = "Backport of PEP 654 (exception groups)"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"},
+ {file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"},
+]
+
+[package.extras]
+test = ["pytest (>=6)"]
[[package]]
name = "flake8"
-version = "3.8.4"
+version = "3.9.2"
description = "the modular source code checker: pep8 pyflakes and co"
category = "dev"
optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
+files = [
+ {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"},
+ {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"},
+]
[package.dependencies]
mccabe = ">=0.6.0,<0.7.0"
-pycodestyle = ">=2.6.0a1,<2.7.0"
-pyflakes = ">=2.2.0,<2.3.0"
+pycodestyle = ">=2.7.0,<2.8.0"
+pyflakes = ">=2.3.0,<2.4.0"
[[package]]
name = "flatbuffers"
-version = "1.12"
+version = "23.3.3"
description = "The FlatBuffers serialization format for Python"
-category = "dev"
+category = "main"
optional = false
python-versions = "*"
+files = [
+ {file = "flatbuffers-23.3.3-py2.py3-none-any.whl", hash = "sha256:5ad36d376240090757e8f0a2cfaf6abcc81c6536c0dc988060375fd0899121f8"},
+ {file = "flatbuffers-23.3.3.tar.gz", hash = "sha256:cabd87c4882f37840f6081f094b2c5bc28cefc2a6357732746936d055ab45c3d"},
+]
+
+[[package]]
+name = "fonttools"
+version = "4.39.0"
+description = "Tools to manipulate font files"
+category = "main"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "fonttools-4.39.0-py3-none-any.whl", hash = "sha256:f5e764e1fd6ad54dfc201ff32af0ba111bcfbe0d05b24540af74c63db4ed6390"},
+ {file = "fonttools-4.39.0.zip", hash = "sha256:909c104558835eac27faeb56be5a4c32694192dca123d073bf746ce9254054af"},
+]
+
+[package.extras]
+all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.0.0)", "xattr", "zopfli (>=0.1.4)"]
+graphite = ["lz4 (>=1.7.4.2)"]
+interpolatable = ["munkres", "scipy"]
+lxml = ["lxml (>=4.0,<5)"]
+pathops = ["skia-pathops (>=0.5.0)"]
+plot = ["matplotlib"]
+repacker = ["uharfbuzz (>=0.23.0)"]
+symfont = ["sympy"]
+type1 = ["xattr"]
+ufo = ["fs (>=2.2.0,<3)"]
+unicode = ["unicodedata2 (>=15.0.0)"]
+woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"]
[[package]]
name = "gast"
version = "0.4.0"
description = "Python AST that abstracts the underlying Python version"
-category = "dev"
+category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+ {file = "gast-0.4.0-py3-none-any.whl", hash = "sha256:b7adcdd5adbebf1adf17378da5ba3f543684dbec47b1cda1f3997e573cd542c4"},
+ {file = "gast-0.4.0.tar.gz", hash = "sha256:40feb7b8b8434785585ab224d1568b857edb18297e5a3047f1ba012bc83b42c1"},
+]
[[package]]
name = "google-auth"
-version = "1.31.0"
+version = "2.16.2"
description = "Google Authentication Library"
-category = "dev"
+category = "main"
optional = false
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*"
+files = [
+ {file = "google-auth-2.16.2.tar.gz", hash = "sha256:07e14f34ec288e3f33e00e2e3cc40c8942aa5d4ceac06256a28cd8e786591420"},
+ {file = "google_auth-2.16.2-py2.py3-none-any.whl", hash = "sha256:2fef3cf94876d1a0e204afece58bb4d83fb57228aaa366c64045039fda6770a2"},
+]
[package.dependencies]
-cachetools = ">=2.0.0,<5.0"
+cachetools = ">=2.0.0,<6.0"
pyasn1-modules = ">=0.2.1"
rsa = {version = ">=3.1.4,<5", markers = "python_version >= \"3.6\""}
six = ">=1.9.0"
[package.extras]
-aiohttp = ["requests (>=2.20.0,<3.0.0dev)", "aiohttp (>=3.6.2,<4.0.0dev)"]
-pyopenssl = ["pyopenssl (>=20.0.0)"]
+aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)", "requests (>=2.20.0,<3.0.0dev)"]
+enterprise-cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"]
+pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"]
reauth = ["pyu2f (>=0.1.5)"]
+requests = ["requests (>=2.20.0,<3.0.0dev)"]
[[package]]
name = "google-auth-oauthlib"
-version = "0.4.4"
+version = "0.4.6"
description = "Google Authentication Library"
-category = "dev"
+category = "main"
optional = false
python-versions = ">=3.6"
+files = [
+ {file = "google-auth-oauthlib-0.4.6.tar.gz", hash = "sha256:a90a072f6993f2c327067bf65270046384cda5a8ecb20b94ea9a687f1f233a7a"},
+ {file = "google_auth_oauthlib-0.4.6-py2.py3-none-any.whl", hash = "sha256:3f2a6e802eebbb6fb736a370fbf3b055edcb6b52878bf2f26330b5e041316c73"},
+]
[package.dependencies]
google-auth = ">=1.0.0"
@@ -222,450 +565,1254 @@ tool = ["click (>=6.0.0)"]
name = "google-pasta"
version = "0.2.0"
description = "pasta is an AST-based Python refactoring library"
-category = "dev"
+category = "main"
optional = false
python-versions = "*"
+files = [
+ {file = "google-pasta-0.2.0.tar.gz", hash = "sha256:c9f2c8dfc8f96d0d5808299920721be30c9eec37f2389f28904f454565c8a16e"},
+ {file = "google_pasta-0.2.0-py2-none-any.whl", hash = "sha256:4612951da876b1a10fe3960d7226f0c7682cf901e16ac06e473b267a5afa8954"},
+ {file = "google_pasta-0.2.0-py3-none-any.whl", hash = "sha256:b32482794a366b5366a32c92a9a9201b107821889935a02b3e51f6b432ea84ed"},
+]
[package.dependencies]
six = "*"
[[package]]
name = "grpcio"
-version = "1.34.1"
+version = "1.51.3"
description = "HTTP/2-based RPC framework"
-category = "dev"
+category = "main"
optional = false
-python-versions = "*"
-
-[package.dependencies]
-six = ">=1.5.2"
+python-versions = ">=3.7"
+files = [
+ {file = "grpcio-1.51.3-cp310-cp310-linux_armv7l.whl", hash = "sha256:f601aaeae18dab81930fb8d4f916b0da21e89bb4b5f7367ef793f46b4a76b7b0"},
+ {file = "grpcio-1.51.3-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:eef0450a4b5ed11feab639bf3eb1b6e23d0efa9b911bf7b06fb60e14f5f8a585"},
+ {file = "grpcio-1.51.3-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:82b0ad8ac825d4bb31bff9f638557c045f4a6d824d84b21e893968286f88246b"},
+ {file = "grpcio-1.51.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3667c06e37d6cd461afdd51cefe6537702f3d1dc5ff4cac07e88d8b4795dc16f"},
+ {file = "grpcio-1.51.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3709048fe0aa23dda09b3e69849a12055790171dab9e399a72ea8f9dfbf9ac80"},
+ {file = "grpcio-1.51.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:200d69857f9910f7458b39b9bcf83ee4a180591b40146ba9e49314e3a7419313"},
+ {file = "grpcio-1.51.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cd9a5e68e79c5f031500e67793048a90209711e0854a9ddee8a3ce51728de4e5"},
+ {file = "grpcio-1.51.3-cp310-cp310-win32.whl", hash = "sha256:6604f614016127ae10969176bbf12eb0e03d2fb3d643f050b3b69e160d144fb4"},
+ {file = "grpcio-1.51.3-cp310-cp310-win_amd64.whl", hash = "sha256:e95c7ccd4c5807adef1602005513bf7c7d14e5a41daebcf9d8d30d8bf51b8f81"},
+ {file = "grpcio-1.51.3-cp311-cp311-linux_armv7l.whl", hash = "sha256:5e77ee138100f0bb55cbd147840f87ee6241dbd25f09ea7cd8afe7efff323449"},
+ {file = "grpcio-1.51.3-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:68a7514b754e38e8de9075f7bb4dee919919515ec68628c43a894027e40ddec4"},
+ {file = "grpcio-1.51.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c1b9f8afa62ff265d86a4747a2990ec5a96e4efce5d5888f245a682d66eca47"},
+ {file = "grpcio-1.51.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8de30f0b417744288cec65ec8cf84b8a57995cf7f1e84ccad2704d93f05d0aae"},
+ {file = "grpcio-1.51.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b69c7adc7ed60da1cb1b502853db61f453fc745f940cbcc25eb97c99965d8f41"},
+ {file = "grpcio-1.51.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d81528ffe0e973dc840ec73a4132fd18b8203ad129d7410155d951a0a7e4f5d0"},
+ {file = "grpcio-1.51.3-cp311-cp311-win32.whl", hash = "sha256:040eb421613b57c696063abde405916dd830203c184c9000fc8c3b3b3c950325"},
+ {file = "grpcio-1.51.3-cp311-cp311-win_amd64.whl", hash = "sha256:2a8e17286c4240137d933b8ca506465472248b4ce0fe46f3404459e708b65b68"},
+ {file = "grpcio-1.51.3-cp37-cp37m-linux_armv7l.whl", hash = "sha256:d5cd1389669a847555df54177b911d9ff6f17345b2a6f19388707b7a9f724c88"},
+ {file = "grpcio-1.51.3-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:be1bf35ce82cdbcac14e39d5102d8de4079a1c1a6a06b68e41fcd9ef64f9dd28"},
+ {file = "grpcio-1.51.3-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:5eed34994c095e2bf7194ffac7381c6068b057ef1e69f8f08db77771350a7566"},
+ {file = "grpcio-1.51.3-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f9a7d88082b2a17ae7bd3c2354d13bab0453899e0851733f6afa6918373f476"},
+ {file = "grpcio-1.51.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c8abbc5f837111e7bd619612eedc223c290b0903b952ce0c7b00840ea70f14"},
+ {file = "grpcio-1.51.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:165b05af77e6aecb4210ae7663e25acf234ba78a7c1c157fa5f2efeb0d6ec53c"},
+ {file = "grpcio-1.51.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:54e36c2ee304ff15f2bfbdc43d2b56c63331c52d818c364e5b5214e5bc2ad9f6"},
+ {file = "grpcio-1.51.3-cp37-cp37m-win32.whl", hash = "sha256:cd0daac21d9ef5e033a5100c1d3aa055bbed28bfcf070b12d8058045c4e821b1"},
+ {file = "grpcio-1.51.3-cp37-cp37m-win_amd64.whl", hash = "sha256:2fdd6333ce96435408565a9dbbd446212cd5d62e4d26f6a3c0feb1e3c35f1cc8"},
+ {file = "grpcio-1.51.3-cp38-cp38-linux_armv7l.whl", hash = "sha256:54b0c29bdd9a3b1e1b61443ab152f060fc719f1c083127ab08d03fac5efd51be"},
+ {file = "grpcio-1.51.3-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:ffaaf7e93fcb437356b5a4b23bf36e8a3d0221399ff77fd057e4bc77776a24be"},
+ {file = "grpcio-1.51.3-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:eafbe7501a3268d05f2e450e1ddaffb950d842a8620c13ec328b501d25d2e2c3"},
+ {file = "grpcio-1.51.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:881ecb34feabf31c6b3b9bbbddd1a5b57e69f805041e5a2c6c562a28574f71c4"},
+ {file = "grpcio-1.51.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e860a3222139b41d430939bbec2ec9c3f6c740938bf7a04471a9a8caaa965a2e"},
+ {file = "grpcio-1.51.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:49ede0528e9dac7e8a9fe30b16c73b630ddd9a576bf4b675eb6b0c53ee5ca00f"},
+ {file = "grpcio-1.51.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6972b009638b40a448d10e1bc18e2223143b8a7aa20d7def0d78dd4af4126d12"},
+ {file = "grpcio-1.51.3-cp38-cp38-win32.whl", hash = "sha256:5694448256e3cdfe5bd358f1574a3f2f51afa20cc834713c4b9788d60b7cc646"},
+ {file = "grpcio-1.51.3-cp38-cp38-win_amd64.whl", hash = "sha256:3ea4341efe603b049e8c9a5f13c696ca37fcdf8a23ca35f650428ad3606381d9"},
+ {file = "grpcio-1.51.3-cp39-cp39-linux_armv7l.whl", hash = "sha256:6c677581ce129f5fa228b8f418cee10bd28dd449f3a544ea73c8ba590ee49d0b"},
+ {file = "grpcio-1.51.3-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:30e09b5e0531685e176f49679b6a3b190762cc225f4565e55a899f5e14b3aa62"},
+ {file = "grpcio-1.51.3-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:c831f31336e81243f85b6daff3e5e8a123302ce0ea1f2726ad752fd7a59f3aee"},
+ {file = "grpcio-1.51.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2cd2e4cefb724cab1ba2df4b7535a9980531b9ec51b4dbb5f137a1f3a3754ef0"},
+ {file = "grpcio-1.51.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7a0d0bf44438869d307f85a54f25a896ad6b4b0ca12370f76892ad732928d87"},
+ {file = "grpcio-1.51.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c02abd55409bfb293371554adf6a4401197ec2133dd97727c01180889014ba4d"},
+ {file = "grpcio-1.51.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2f8ff75e61e1227ba7a3f16b2eadbcc11d0a54096d52ab75a6b88cfbe56f55d1"},
+ {file = "grpcio-1.51.3-cp39-cp39-win32.whl", hash = "sha256:6c99a73a6260bdf844b2e5ddad02dcd530310f80e1fa72c300fa19c1c7496962"},
+ {file = "grpcio-1.51.3-cp39-cp39-win_amd64.whl", hash = "sha256:22bdfac4f7f27acdd4da359b5e7e1973dc74bf1ed406729b07d0759fde2f064b"},
+ {file = "grpcio-1.51.3.tar.gz", hash = "sha256:be7b2265b7527bb12109a7727581e274170766d5b3c9258d4e466f4872522d7a"},
+]
[package.extras]
-protobuf = ["grpcio-tools (>=1.34.1)"]
+protobuf = ["grpcio-tools (>=1.51.3)"]
[[package]]
name = "h5py"
-version = "3.1.0"
+version = "3.8.0"
description = "Read and write HDF5 files from Python"
-category = "dev"
+category = "main"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
+files = [
+ {file = "h5py-3.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:533d7dad466ddb7e3b30af274b630eb7c1a6e4ddf01d1c373a0334dc2152110a"},
+ {file = "h5py-3.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c873ba9fd4fa875ad62ce0e4891725e257a8fe7f5abdbc17e51a5d54819be55c"},
+ {file = "h5py-3.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98a240cd4c1bfd568aaa52ec42d263131a2582dab82d74d3d42a0d954cac12be"},
+ {file = "h5py-3.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3389b63222b1c7a158bb7fe69d11ca00066740ec5574596d47a2fe5317f563a"},
+ {file = "h5py-3.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:7f3350fc0a8407d668b13247861c2acd23f7f5fe7d060a3ad9b0820f5fcbcae0"},
+ {file = "h5py-3.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db03e3f2c716205fbdabb34d0848459840585225eb97b4f08998c743821ca323"},
+ {file = "h5py-3.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:36761693efbe53df179627a775476dcbc37727d6e920958277a7efbc18f1fb73"},
+ {file = "h5py-3.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a506fc223def428f4329e7e1f9fe1c8c593eab226e7c0942c8d75308ad49950"},
+ {file = "h5py-3.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33b15aae79e9147aebe1d0e54099cbcde8d65e3e227cd5b59e49b1272aa0e09d"},
+ {file = "h5py-3.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:9f6f6ffadd6bfa9b2c5b334805eb4b19ca0a5620433659d8f7fb86692c40a359"},
+ {file = "h5py-3.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8f55d9c6c84d7d09c79fb85979e97b81ec6071cc776a97eb6b96f8f6ec767323"},
+ {file = "h5py-3.8.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b685453e538b2b5934c58a644ac3f3b3d0cec1a01b6fb26d57388e9f9b674ad0"},
+ {file = "h5py-3.8.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:377865821fe80ad984d003723d6f8890bd54ceeb5981b43c0313b9df95411b30"},
+ {file = "h5py-3.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:0fef76e10b9216657fa37e7edff6d8be0709b25bd5066474c229b56cf0098df9"},
+ {file = "h5py-3.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:26ffc344ec9984d2cd3ca0265007299a8bac8d85c1ad48f4639d8d3aed2af171"},
+ {file = "h5py-3.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bacaa1c16810dd2b3e4417f8e730971b7c4d53d234de61fe4a918db78e80e1e4"},
+ {file = "h5py-3.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bae730580ae928de409d63cbe4fdca4c82c3ad2bed30511d19d34e995d63c77e"},
+ {file = "h5py-3.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f47f757d1b76f0ecb8aa0508ec8d1b390df67a8b67ee2515dc1b046f3a1596ea"},
+ {file = "h5py-3.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:f891b17e3a3e974e93f9e34e7cca9f530806543571ce078998676a555837d91d"},
+ {file = "h5py-3.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:290e00fa2de74a10688d1bac98d5a9cdd43f14f58e562c580b5b3dfbd358ecae"},
+ {file = "h5py-3.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:03890b1c123d024fb0239a3279737d5432498c1901c354f8b10d8221d1d16235"},
+ {file = "h5py-3.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7865de06779b14d98068da387333ad9bf2756b5b579cc887fac169bc08f87c3"},
+ {file = "h5py-3.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49bc857635f935fa30e92e61ac1e87496df8f260a6945a3235e43a9890426866"},
+ {file = "h5py-3.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:5fd2252d1fc364ba0e93dd0b7089f4906b66805cb4e6aca7fa8874ac08649647"},
+ {file = "h5py-3.8.0.tar.gz", hash = "sha256:6fead82f0c4000cf38d53f9c030780d81bfa0220218aee13b90b7701c937d95f"},
+]
[package.dependencies]
-numpy = [
- {version = ">=1.17.5", markers = "python_version == \"3.8\""},
- {version = ">=1.19.3", markers = "python_version >= \"3.9\""},
-]
+numpy = ">=1.14.5"
[[package]]
name = "idna"
-version = "2.10"
+version = "3.4"
description = "Internationalized Domain Names in Applications (IDNA)"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[[package]]
-name = "install"
-version = "1.3.4"
-description = "Install packages from within code"
category = "main"
optional = false
-python-versions = ">=2.7, >=3.5"
+python-versions = ">=3.5"
+files = [
+ {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
+ {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
+]
[[package]]
-name = "joblib"
-version = "1.0.1"
-description = "Lightweight pipelining with Python functions"
+name = "imagesize"
+version = "1.4.1"
+description = "Getting image size from png/jpeg/jpeg2000/gif file"
category = "dev"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+ {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
+ {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
+]
[[package]]
-name = "jsonschema"
-version = "3.2.0"
-description = "An implementation of JSON Schema validation for Python"
+name = "importlib-metadata"
+version = "6.0.0"
+description = "Read metadata from Python packages"
category = "main"
optional = false
-python-versions = "*"
+python-versions = ">=3.7"
+files = [
+ {file = "importlib_metadata-6.0.0-py3-none-any.whl", hash = "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad"},
+ {file = "importlib_metadata-6.0.0.tar.gz", hash = "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d"},
+]
[package.dependencies]
-attrs = ">=17.4.0"
-pyrsistent = ">=0.14.0"
-six = ">=1.11.0"
+zipp = ">=0.5"
[package.extras]
-format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"]
-format_nongpl = ["idna", "jsonpointer (>1.13)", "webcolors", "rfc3986-validator (>0.1.0)", "rfc3339-validator"]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+perf = ["ipython"]
+testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"]
[[package]]
-name = "keras"
-version = "2.4.3"
-description = "Deep Learning for humans"
-category = "dev"
+name = "importlib-resources"
+version = "5.12.0"
+description = "Read resources from Python packages"
+category = "main"
optional = false
-python-versions = "*"
+python-versions = ">=3.7"
+files = [
+ {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"},
+ {file = "importlib_resources-5.12.0.tar.gz", hash = "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6"},
+]
[package.dependencies]
-h5py = "*"
-numpy = ">=1.9.1"
-pyyaml = "*"
-scipy = ">=0.14"
+zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""}
[package.extras]
-tests = ["pytest", "pytest-pep8", "pytest-xdist", "flaky", "pytest-cov", "pandas", "requests", "markdown"]
-visualize = ["pydot (>=1.2.4)"]
-
-[[package]]
-name = "keras-nightly"
-version = "2.6.0.dev2021061400"
-description = "TensorFlow Keras."
-category = "dev"
-optional = false
-python-versions = "*"
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
[[package]]
-name = "keras-preprocessing"
-version = "1.1.2"
-description = "Easy data preprocessing and data augmentation for deep learning models"
+name = "iniconfig"
+version = "2.0.0"
+description = "brain-dead simple config-ini parsing"
category = "dev"
optional = false
-python-versions = "*"
-
-[package.dependencies]
-numpy = ">=1.9.1"
-six = ">=1.9.0"
-
-[package.extras]
-image = ["scipy (>=0.14)", "Pillow (>=5.2.0)"]
-pep8 = ["flake8"]
-tests = ["pandas", "pillow", "tensorflow", "keras", "pytest", "pytest-xdist", "pytest-cov"]
+python-versions = ">=3.7"
+files = [
+ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
+ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
+]
[[package]]
-name = "kiwisolver"
-version = "1.3.1"
-description = "A fast implementation of the Cassowary constraint solver"
-category = "dev"
+name = "install"
+version = "1.3.5"
+description = "Install packages from within code"
+category = "main"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=2.7, >=3.5"
+files = [
+ {file = "install-1.3.5-py3-none-any.whl", hash = "sha256:0d3fadf4aa62c95efe8d34757c8507eb46177f86c016c21c6551eafc6a53d5a9"},
+ {file = "install-1.3.5.tar.gz", hash = "sha256:e67c8a0be5ccf8cb4ffa17d090f3a61b6e820e6a7e21cd1d2c0f7bc59b18e647"},
+]
[[package]]
-name = "markdown"
-version = "3.3.4"
-description = "Python implementation of Markdown."
+name = "isort"
+version = "5.12.0"
+description = "A Python utility / library to sort Python imports."
category = "dev"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.8.0"
+files = [
+ {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"},
+ {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"},
+]
[package.extras]
-testing = ["coverage", "pyyaml"]
+colors = ["colorama (>=0.4.3)"]
+pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"]
+plugins = ["setuptools"]
+requirements-deprecated-finder = ["pip-api", "pipreqs"]
[[package]]
-name = "matplotlib"
-version = "3.4.2"
-description = "Python plotting package"
+name = "jinja2"
+version = "3.1.2"
+description = "A very fast and expressive template engine."
category = "dev"
optional = false
python-versions = ">=3.7"
+files = [
+ {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
+ {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
+]
[package.dependencies]
-cycler = ">=0.10"
-kiwisolver = ">=1.0.1"
-numpy = ">=1.16"
-pillow = ">=6.2.0"
-pyparsing = ">=2.2.1"
-python-dateutil = ">=2.7"
+MarkupSafe = ">=2.0"
+
+[package.extras]
+i18n = ["Babel (>=2.7)"]
[[package]]
-name = "mccabe"
-version = "0.6.1"
-description = "McCabe checker, plugin for flake8"
-category = "dev"
+name = "joblib"
+version = "1.2.0"
+description = "Lightweight pipelining with Python functions"
+category = "main"
optional = false
-python-versions = "*"
+python-versions = ">=3.7"
+files = [
+ {file = "joblib-1.2.0-py3-none-any.whl", hash = "sha256:091138ed78f800342968c523bdde947e7a305b8594b910a0fea2ab83c3c6d385"},
+ {file = "joblib-1.2.0.tar.gz", hash = "sha256:e1cee4a79e4af22881164f218d4311f60074197fb707e082e803b61f6d137018"},
+]
[[package]]
-name = "mypy"
-version = "0.782"
-description = "Optional static typing for Python"
-category = "dev"
+name = "jsonschema"
+version = "3.2.0"
+description = "An implementation of JSON Schema validation for Python"
+category = "main"
optional = false
-python-versions = ">=3.5"
+python-versions = "*"
+files = [
+ {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"},
+ {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"},
+]
[package.dependencies]
-mypy-extensions = ">=0.4.3,<0.5.0"
-typed-ast = ">=1.4.0,<1.5.0"
-typing-extensions = ">=3.7.4"
+attrs = ">=17.4.0"
+pyrsistent = ">=0.14.0"
+setuptools = "*"
+six = ">=1.11.0"
[package.extras]
-dmypy = ["psutil (>=4.0)"]
+format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"]
+format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"]
[[package]]
-name = "mypy-extensions"
-version = "0.4.3"
-description = "Experimental type system extensions for programs checked with the mypy typechecker."
+name = "keras"
+version = "2.11.0"
+description = "Deep learning for humans."
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "keras-2.11.0-py2.py3-none-any.whl", hash = "sha256:38c6fff0ea9a8b06a2717736565c92a73c8cd9b1c239e7125ccb188b7848f65e"},
+]
+
+[[package]]
+name = "kiwisolver"
+version = "1.4.4"
+description = "A fast implementation of the Cassowary constraint solver"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2f5e60fabb7343a836360c4f0919b8cd0d6dbf08ad2ca6b9cf90bf0c76a3c4f6"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:10ee06759482c78bdb864f4109886dff7b8a56529bc1609d4f1112b93fe6423c"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c79ebe8f3676a4c6630fd3f777f3cfecf9289666c84e775a67d1d358578dc2e3"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbe9fa13da955feb8202e215c4018f4bb57469b1b78c7a4c5c7b93001699938"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7577c1987baa3adc4b3c62c33bd1118c3ef5c8ddef36f0f2c950ae0b199e100d"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ad8285b01b0d4695102546b342b493b3ccc6781fc28c8c6a1bb63e95d22f09"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed58b8acf29798b036d347791141767ccf65eee7f26bde03a71c944449e53de"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a68b62a02953b9841730db7797422f983935aeefceb1679f0fc85cbfbd311c32"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-win32.whl", hash = "sha256:e92a513161077b53447160b9bd8f522edfbed4bd9759e4c18ab05d7ef7e49408"},
+ {file = "kiwisolver-1.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fe20f63c9ecee44560d0e7f116b3a747a5d7203376abeea292ab3152334d004"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ea21f66820452a3f5d1655f8704a60d66ba1191359b96541eaf457710a5fc6"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc9db8a3efb3e403e4ecc6cd9489ea2bac94244f80c78e27c31dcc00d2790ac2"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d5b61785a9ce44e5a4b880272baa7cf6c8f48a5180c3e81c59553ba0cb0821ca"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2dbb44c3f7e6c4d3487b31037b1bdbf424d97687c1747ce4ff2895795c9bf69"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6295ecd49304dcf3bfbfa45d9a081c96509e95f4b9d0eb7ee4ec0530c4a96514"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bd472dbe5e136f96a4b18f295d159d7f26fd399136f5b17b08c4e5f498cd494"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf7d9fce9bcc4752ca4a1b80aabd38f6d19009ea5cbda0e0856983cf6d0023f5"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d6601aed50c74e0ef02f4204da1816147a6d3fbdc8b3872d263338a9052c51"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:877272cf6b4b7e94c9614f9b10140e198d2186363728ed0f701c6eee1baec1da"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:db608a6757adabb32f1cfe6066e39b3706d8c3aa69bbc353a5b61edad36a5cb4"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5853eb494c71e267912275e5586fe281444eb5e722de4e131cddf9d442615626"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f0a1dbdb5ecbef0d34eb77e56fcb3e95bbd7e50835d9782a45df81cc46949750"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:283dffbf061a4ec60391d51e6155e372a1f7a4f5b15d59c8505339454f8989e4"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-win32.whl", hash = "sha256:d06adcfa62a4431d404c31216f0f8ac97397d799cd53800e9d3efc2fbb3cf14e"},
+ {file = "kiwisolver-1.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e7da3fec7408813a7cebc9e4ec55afed2d0fd65c4754bc376bf03498d4e92686"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:62ac9cc684da4cf1778d07a89bf5f81b35834cb96ca523d3a7fb32509380cbf6"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41dae968a94b1ef1897cb322b39360a0812661dba7c682aa45098eb8e193dbdf"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02f79693ec433cb4b5f51694e8477ae83b3205768a6fb48ffba60549080e295b"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0611a0a2a518464c05ddd5a3a1a0e856ccc10e67079bb17f265ad19ab3c7597"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:db5283d90da4174865d520e7366801a93777201e91e79bacbac6e6927cbceede"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1041feb4cda8708ce73bb4dcb9ce1ccf49d553bf87c3954bdfa46f0c3f77252c"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-win32.whl", hash = "sha256:a553dadda40fef6bfa1456dc4be49b113aa92c2a9a9e8711e955618cd69622e3"},
+ {file = "kiwisolver-1.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:03baab2d6b4a54ddbb43bba1a3a2d1627e82d205c5cf8f4c924dc49284b87166"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:841293b17ad704d70c578f1f0013c890e219952169ce8a24ebc063eecf775454"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f4f270de01dd3e129a72efad823da90cc4d6aafb64c410c9033aba70db9f1ff0"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f9f39e2f049db33a908319cf46624a569b36983c7c78318e9726a4cb8923b26c"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c97528e64cb9ebeff9701e7938653a9951922f2a38bd847787d4a8e498cc83ae"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d1573129aa0fd901076e2bfb4275a35f5b7aa60fbfb984499d661ec950320b0"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad881edc7ccb9d65b0224f4e4d05a1e85cf62d73aab798943df6d48ab0cd79a1"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b428ef021242344340460fa4c9185d0b1f66fbdbfecc6c63eff4b7c29fad429d"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e407cb4bd5a13984a6c2c0fe1845e4e41e96f183e5e5cd4d77a857d9693494c"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-win32.whl", hash = "sha256:75facbe9606748f43428fc91a43edb46c7ff68889b91fa31f53b58894503a191"},
+ {file = "kiwisolver-1.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:5bce61af018b0cb2055e0e72e7d65290d822d3feee430b7b8203d8a855e78766"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8c808594c88a025d4e322d5bb549282c93c8e1ba71b790f539567932722d7bd8"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0a71d85ecdd570ded8ac3d1c0f480842f49a40beb423bb8014539a9f32a5897"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b533558eae785e33e8c148a8d9921692a9fe5aa516efbdff8606e7d87b9d5824"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:efda5fc8cc1c61e4f639b8067d118e742b812c930f708e6667a5ce0d13499e29"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7c43e1e1206cd421cd92e6b3280d4385d41d7166b3ed577ac20444b6995a445f"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc8d3bd6c72b2dd9decf16ce70e20abcb3274ba01b4e1c96031e0c4067d1e7cd"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4ea39b0ccc4f5d803e3337dd46bcce60b702be4d86fd0b3d7531ef10fd99a1ac"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:968f44fdbf6dd757d12920d63b566eeb4d5b395fd2d00d29d7ef00a00582aac9"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-win32.whl", hash = "sha256:da7e547706e69e45d95e116e6939488d62174e033b763ab1496b4c29b76fabea"},
+ {file = "kiwisolver-1.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:ba59c92039ec0a66103b1d5fe588fa546373587a7d68f5c96f743c3396afc04b"},
+ {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:91672bacaa030f92fc2f43b620d7b337fd9a5af28b0d6ed3f77afc43c4a64b5a"},
+ {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787518a6789009c159453da4d6b683f468ef7a65bbde796bcea803ccf191058d"},
+ {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da152d8cdcab0e56e4f45eb08b9aea6455845ec83172092f09b0e077ece2cf7a"},
+ {file = "kiwisolver-1.4.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ecb1fa0db7bf4cff9dac752abb19505a233c7f16684c5826d1f11ebd9472b871"},
+ {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:28bc5b299f48150b5f822ce68624e445040595a4ac3d59251703779836eceff9"},
+ {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:81e38381b782cc7e1e46c4e14cd997ee6040768101aefc8fa3c24a4cc58e98f8"},
+ {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2a66fdfb34e05b705620dd567f5a03f239a088d5a3f321e7b6ac3239d22aa286"},
+ {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:872b8ca05c40d309ed13eb2e582cab0c5a05e81e987ab9c521bf05ad1d5cf5cb"},
+ {file = "kiwisolver-1.4.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70e7c2e7b750585569564e2e5ca9845acfaa5da56ac46df68414f29fea97be9f"},
+ {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9f85003f5dfa867e86d53fac6f7e6f30c045673fa27b603c397753bebadc3008"},
+ {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e307eb9bd99801f82789b44bb45e9f541961831c7311521b13a6c85afc09767"},
+ {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1792d939ec70abe76f5054d3f36ed5656021dcad1322d1cc996d4e54165cef9"},
+ {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6cb459eea32a4e2cf18ba5fcece2dbdf496384413bc1bae15583f19e567f3b2"},
+ {file = "kiwisolver-1.4.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36dafec3d6d6088d34e2de6b85f9d8e2324eb734162fba59d2ba9ed7a2043d5b"},
+ {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"},
+]
+
+[[package]]
+name = "libclang"
+version = "15.0.6.1"
+description = "Clang Python Bindings, mirrored from the official LLVM repo: https://github.com/llvm/llvm-project/tree/main/clang/bindings/python, to make the installation process easier."
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+ {file = "libclang-15.0.6.1-py2.py3-none-macosx_10_9_x86_64.whl", hash = "sha256:8621795e07b87e17fc7aac9f071bc7fe6b52ed6110c0a96a9975d8113c8c2527"},
+ {file = "libclang-15.0.6.1-py2.py3-none-manylinux2010_x86_64.whl", hash = "sha256:69b01a23ab543908a661532595daa23cf88bd96d80e41f58ba0eaa6a378fe0d8"},
+ {file = "libclang-15.0.6.1-py2.py3-none-manylinux2014_aarch64.whl", hash = "sha256:4a5188184b937132c198ee9de9a8a2316d5fdd1a825398d5ad1a8f5e06f9b40e"},
+ {file = "libclang-15.0.6.1-py2.py3-none-manylinux2014_armv7l.whl", hash = "sha256:f7ffa02ac5e586cfffde039dcccc439d88d0feac7d77bf9426d9ba7543d16545"},
+ {file = "libclang-15.0.6.1-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:aaebb6aa1db73bac3a0ac41e57ef78743079eb68728adbf7e80ee917ae171529"},
+ {file = "libclang-15.0.6.1-py2.py3-none-win_amd64.whl", hash = "sha256:85afb47630d2070e74b886040ceea1846097ca53cc88d0f1d7751d0f49220028"},
+ {file = "libclang-15.0.6.1-py2.py3-none-win_arm64.whl", hash = "sha256:687d8549c110c700fece58dd87727421d0710fdd111aa7eecb01faf8e3f50d4e"},
+ {file = "libclang-15.0.6.1.tar.gz", hash = "sha256:a1a8fe038af2962c787c5bac81bfa4b82bb8e279e61e70cc934c10f6e20c73ec"},
+]
+
+[[package]]
+name = "markdown"
+version = "3.4.1"
+description = "Python implementation of Markdown."
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "Markdown-3.4.1-py3-none-any.whl", hash = "sha256:08fb8465cffd03d10b9dd34a5c3fea908e20391a2a90b88d66362cb05beed186"},
+ {file = "Markdown-3.4.1.tar.gz", hash = "sha256:3b809086bb6efad416156e00a0da66fe47618a5d6918dd688f53f40c8e4cfeff"},
+]
+
+[package.dependencies]
+importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""}
+
+[package.extras]
+testing = ["coverage", "pyyaml"]
+
+[[package]]
+name = "markupsafe"
+version = "2.1.2"
+description = "Safely add untrusted strings to HTML/XML markup."
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"},
+ {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"},
+ {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"},
+ {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"},
+ {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"},
+ {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"},
+ {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"},
+ {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"},
+ {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"},
+ {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"},
+ {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"},
+ {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"},
+ {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"},
+ {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"},
+ {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"},
+ {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"},
+ {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"},
+ {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"},
+ {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"},
+ {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"},
+ {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"},
+ {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"},
+ {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"},
+ {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"},
+ {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"},
+ {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"},
+ {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"},
+ {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"},
+ {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"},
+ {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"},
+ {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"},
+ {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"},
+ {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"},
+ {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"},
+ {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"},
+ {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"},
+ {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"},
+ {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"},
+ {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"},
+ {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"},
+ {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"},
+ {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"},
+ {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"},
+ {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"},
+ {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"},
+ {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"},
+ {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"},
+ {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"},
+ {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"},
+ {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"},
+]
+
+[[package]]
+name = "matplotlib"
+version = "3.7.1"
+description = "Python plotting package"
+category = "main"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_universal2.whl", hash = "sha256:95cbc13c1fc6844ab8812a525bbc237fa1470863ff3dace7352e910519e194b1"},
+ {file = "matplotlib-3.7.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:08308bae9e91aca1ec6fd6dda66237eef9f6294ddb17f0d0b3c863169bf82353"},
+ {file = "matplotlib-3.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:544764ba51900da4639c0f983b323d288f94f65f4024dc40ecb1542d74dc0500"},
+ {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56d94989191de3fcc4e002f93f7f1be5da476385dde410ddafbb70686acf00ea"},
+ {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e99bc9e65901bb9a7ce5e7bb24af03675cbd7c70b30ac670aa263240635999a4"},
+ {file = "matplotlib-3.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb7d248c34a341cd4c31a06fd34d64306624c8cd8d0def7abb08792a5abfd556"},
+ {file = "matplotlib-3.7.1-cp310-cp310-win32.whl", hash = "sha256:ce463ce590f3825b52e9fe5c19a3c6a69fd7675a39d589e8b5fbe772272b3a24"},
+ {file = "matplotlib-3.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:3d7bc90727351fb841e4d8ae620d2d86d8ed92b50473cd2b42ce9186104ecbba"},
+ {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_universal2.whl", hash = "sha256:770a205966d641627fd5cf9d3cb4b6280a716522cd36b8b284a8eb1581310f61"},
+ {file = "matplotlib-3.7.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f67bfdb83a8232cb7a92b869f9355d677bce24485c460b19d01970b64b2ed476"},
+ {file = "matplotlib-3.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2bf092f9210e105f414a043b92af583c98f50050559616930d884387d0772aba"},
+ {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89768d84187f31717349c6bfadc0e0d8c321e8eb34522acec8a67b1236a66332"},
+ {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83111e6388dec67822e2534e13b243cc644c7494a4bb60584edbff91585a83c6"},
+ {file = "matplotlib-3.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a867bf73a7eb808ef2afbca03bcdb785dae09595fbe550e1bab0cd023eba3de0"},
+ {file = "matplotlib-3.7.1-cp311-cp311-win32.whl", hash = "sha256:fbdeeb58c0cf0595efe89c05c224e0a502d1aa6a8696e68a73c3efc6bc354304"},
+ {file = "matplotlib-3.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:c0bd19c72ae53e6ab979f0ac6a3fafceb02d2ecafa023c5cca47acd934d10be7"},
+ {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_universal2.whl", hash = "sha256:6eb88d87cb2c49af00d3bbc33a003f89fd9f78d318848da029383bfc08ecfbfb"},
+ {file = "matplotlib-3.7.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:cf0e4f727534b7b1457898c4f4ae838af1ef87c359b76dcd5330fa31893a3ac7"},
+ {file = "matplotlib-3.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:46a561d23b91f30bccfd25429c3c706afe7d73a5cc64ef2dfaf2b2ac47c1a5dc"},
+ {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8704726d33e9aa8a6d5215044b8d00804561971163563e6e6591f9dcf64340cc"},
+ {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4cf327e98ecf08fcbb82685acaf1939d3338548620ab8dfa02828706402c34de"},
+ {file = "matplotlib-3.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:617f14ae9d53292ece33f45cba8503494ee199a75b44de7717964f70637a36aa"},
+ {file = "matplotlib-3.7.1-cp38-cp38-win32.whl", hash = "sha256:7c9a4b2da6fac77bcc41b1ea95fadb314e92508bf5493ceff058e727e7ecf5b0"},
+ {file = "matplotlib-3.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:14645aad967684e92fc349493fa10c08a6da514b3d03a5931a1bac26e6792bd1"},
+ {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_universal2.whl", hash = "sha256:81a6b377ea444336538638d31fdb39af6be1a043ca5e343fe18d0f17e098770b"},
+ {file = "matplotlib-3.7.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:28506a03bd7f3fe59cd3cd4ceb2a8d8a2b1db41afede01f66c42561b9be7b4b7"},
+ {file = "matplotlib-3.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8c587963b85ce41e0a8af53b9b2de8dddbf5ece4c34553f7bd9d066148dc719c"},
+ {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8bf26ade3ff0f27668989d98c8435ce9327d24cffb7f07d24ef609e33d582439"},
+ {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:def58098f96a05f90af7e92fd127d21a287068202aa43b2a93476170ebd99e87"},
+ {file = "matplotlib-3.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f883a22a56a84dba3b588696a2b8a1ab0d2c3d41be53264115c71b0a942d8fdb"},
+ {file = "matplotlib-3.7.1-cp39-cp39-win32.whl", hash = "sha256:4f99e1b234c30c1e9714610eb0c6d2f11809c9c78c984a613ae539ea2ad2eb4b"},
+ {file = "matplotlib-3.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:3ba2af245e36990facf67fde840a760128ddd71210b2ab6406e640188d69d136"},
+ {file = "matplotlib-3.7.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3032884084f541163f295db8a6536e0abb0db464008fadca6c98aaf84ccf4717"},
+ {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a2cb34336110e0ed8bb4f650e817eed61fa064acbefeb3591f1b33e3a84fd96"},
+ {file = "matplotlib-3.7.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b867e2f952ed592237a1828f027d332d8ee219ad722345b79a001f49df0936eb"},
+ {file = "matplotlib-3.7.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:57bfb8c8ea253be947ccb2bc2d1bb3862c2bccc662ad1b4626e1f5e004557042"},
+ {file = "matplotlib-3.7.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:438196cdf5dc8d39b50a45cb6e3f6274edbcf2254f85fa9b895bf85851c3a613"},
+ {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:21e9cff1a58d42e74d01153360de92b326708fb205250150018a52c70f43c290"},
+ {file = "matplotlib-3.7.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d4725d70b7c03e082bbb8a34639ede17f333d7247f56caceb3801cb6ff703d"},
+ {file = "matplotlib-3.7.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:97cc368a7268141afb5690760921765ed34867ffb9655dd325ed207af85c7529"},
+ {file = "matplotlib-3.7.1.tar.gz", hash = "sha256:7b73305f25eab4541bd7ee0b96d87e53ae9c9f1823be5659b806cd85786fe882"},
+]
+
+[package.dependencies]
+contourpy = ">=1.0.1"
+cycler = ">=0.10"
+fonttools = ">=4.22.0"
+importlib-resources = {version = ">=3.2.0", markers = "python_version < \"3.10\""}
+kiwisolver = ">=1.0.1"
+numpy = ">=1.20"
+packaging = ">=20.0"
+pillow = ">=6.2.0"
+pyparsing = ">=2.3.1"
+python-dateutil = ">=2.7"
+
+[[package]]
+name = "mccabe"
+version = "0.6.1"
+description = "McCabe checker, plugin for flake8"
category = "dev"
optional = false
python-versions = "*"
+files = [
+ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
+ {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
+]
[[package]]
-name = "networkx"
-version = "2.5"
-description = "Python package for creating and manipulating graphs and networks"
+name = "multiprocess"
+version = "0.70.14"
+description = "better multiprocessing and multithreading in python"
category = "main"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
+files = [
+ {file = "multiprocess-0.70.14-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:560a27540daef4ce8b24ed3cc2496a3c670df66c96d02461a4da67473685adf3"},
+ {file = "multiprocess-0.70.14-pp37-pypy37_pp73-manylinux_2_24_i686.whl", hash = "sha256:bfbbfa36f400b81d1978c940616bc77776424e5e34cb0c94974b178d727cfcd5"},
+ {file = "multiprocess-0.70.14-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:89fed99553a04ec4f9067031f83a886d7fdec5952005551a896a4b6a59575bb9"},
+ {file = "multiprocess-0.70.14-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:40a5e3685462079e5fdee7c6789e3ef270595e1755199f0d50685e72523e1d2a"},
+ {file = "multiprocess-0.70.14-pp38-pypy38_pp73-manylinux_2_24_i686.whl", hash = "sha256:44936b2978d3f2648727b3eaeab6d7fa0bedf072dc5207bf35a96d5ee7c004cf"},
+ {file = "multiprocess-0.70.14-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:e628503187b5d494bf29ffc52d3e1e57bb770ce7ce05d67c4bbdb3a0c7d3b05f"},
+ {file = "multiprocess-0.70.14-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0d5da0fc84aacb0e4bd69c41b31edbf71b39fe2fb32a54eaedcaea241050855c"},
+ {file = "multiprocess-0.70.14-pp39-pypy39_pp73-manylinux_2_24_i686.whl", hash = "sha256:6a7b03a5b98e911a7785b9116805bd782815c5e2bd6c91c6a320f26fd3e7b7ad"},
+ {file = "multiprocess-0.70.14-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:cea5bdedd10aace3c660fedeac8b087136b4366d4ee49a30f1ebf7409bce00ae"},
+ {file = "multiprocess-0.70.14-py310-none-any.whl", hash = "sha256:7dc1f2f6a1d34894c8a9a013fbc807971e336e7cc3f3ff233e61b9dc679b3b5c"},
+ {file = "multiprocess-0.70.14-py37-none-any.whl", hash = "sha256:93a8208ca0926d05cdbb5b9250a604c401bed677579e96c14da3090beb798193"},
+ {file = "multiprocess-0.70.14-py38-none-any.whl", hash = "sha256:6725bc79666bbd29a73ca148a0fb5f4ea22eed4a8f22fce58296492a02d18a7b"},
+ {file = "multiprocess-0.70.14-py39-none-any.whl", hash = "sha256:63cee628b74a2c0631ef15da5534c8aedbc10c38910b9c8b18dcd327528d1ec7"},
+ {file = "multiprocess-0.70.14.tar.gz", hash = "sha256:3eddafc12f2260d27ae03fe6069b12570ab4764ab59a75e81624fac453fbf46a"},
+]
+
+[package.dependencies]
+dill = ">=0.3.6"
+
+[[package]]
+name = "mypy"
+version = "1.1.1"
+description = "Optional static typing for Python"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "mypy-1.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39c7119335be05630611ee798cc982623b9e8f0cff04a0b48dfc26100e0b97af"},
+ {file = "mypy-1.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:61bf08362e93b6b12fad3eab68c4ea903a077b87c90ac06c11e3d7a09b56b9c1"},
+ {file = "mypy-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbb19c9f662e41e474e0cff502b7064a7edc6764f5262b6cd91d698163196799"},
+ {file = "mypy-1.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:315ac73cc1cce4771c27d426b7ea558fb4e2836f89cb0296cbe056894e3a1f78"},
+ {file = "mypy-1.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:5cb14ff9919b7df3538590fc4d4c49a0f84392237cbf5f7a816b4161c061829e"},
+ {file = "mypy-1.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:26cdd6a22b9b40b2fd71881a8a4f34b4d7914c679f154f43385ca878a8297389"},
+ {file = "mypy-1.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5b5f81b40d94c785f288948c16e1f2da37203c6006546c5d947aab6f90aefef2"},
+ {file = "mypy-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21b437be1c02712a605591e1ed1d858aba681757a1e55fe678a15c2244cd68a5"},
+ {file = "mypy-1.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d809f88734f44a0d44959d795b1e6f64b2bbe0ea4d9cc4776aa588bb4229fc1c"},
+ {file = "mypy-1.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:a380c041db500e1410bb5b16b3c1c35e61e773a5c3517926b81dfdab7582be54"},
+ {file = "mypy-1.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b7c7b708fe9a871a96626d61912e3f4ddd365bf7f39128362bc50cbd74a634d5"},
+ {file = "mypy-1.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1c10fa12df1232c936830839e2e935d090fc9ee315744ac33b8a32216b93707"},
+ {file = "mypy-1.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0a28a76785bf57655a8ea5eb0540a15b0e781c807b5aa798bd463779988fa1d5"},
+ {file = "mypy-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ef6a01e563ec6a4940784c574d33f6ac1943864634517984471642908b30b6f7"},
+ {file = "mypy-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d64c28e03ce40d5303450f547e07418c64c241669ab20610f273c9e6290b4b0b"},
+ {file = "mypy-1.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:64cc3afb3e9e71a79d06e3ed24bb508a6d66f782aff7e56f628bf35ba2e0ba51"},
+ {file = "mypy-1.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce61663faf7a8e5ec6f456857bfbcec2901fbdb3ad958b778403f63b9e606a1b"},
+ {file = "mypy-1.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2b0c373d071593deefbcdd87ec8db91ea13bd8f1328d44947e88beae21e8d5e9"},
+ {file = "mypy-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:2888ce4fe5aae5a673386fa232473014056967f3904f5abfcf6367b5af1f612a"},
+ {file = "mypy-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:19ba15f9627a5723e522d007fe708007bae52b93faab00f95d72f03e1afa9598"},
+ {file = "mypy-1.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:59bbd71e5c58eed2e992ce6523180e03c221dcd92b52f0e792f291d67b15a71c"},
+ {file = "mypy-1.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9401e33814cec6aec8c03a9548e9385e0e228fc1b8b0a37b9ea21038e64cdd8a"},
+ {file = "mypy-1.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4b398d8b1f4fba0e3c6463e02f8ad3346f71956b92287af22c9b12c3ec965a9f"},
+ {file = "mypy-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:69b35d1dcb5707382810765ed34da9db47e7f95b3528334a3c999b0c90fe523f"},
+ {file = "mypy-1.1.1-py3-none-any.whl", hash = "sha256:4e4e8b362cdf99ba00c2b218036002bdcdf1e0de085cdb296a49df03fb31dfc4"},
+ {file = "mypy-1.1.1.tar.gz", hash = "sha256:ae9ceae0f5b9059f33dbc62dea087e942c0ccab4b7a003719cb70f9b8abfa32f"},
+]
[package.dependencies]
-decorator = ">=4.3.0"
+mypy-extensions = ">=1.0.0"
+tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
+typing-extensions = ">=3.10"
+
+[package.extras]
+dmypy = ["psutil (>=4.0)"]
+install-types = ["pip"]
+python2 = ["typed-ast (>=1.4.0,<2)"]
+reports = ["lxml"]
+
+[[package]]
+name = "mypy-extensions"
+version = "1.0.0"
+description = "Type system extensions for programs checked with the mypy type checker."
+category = "dev"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
+ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
+]
+
+[[package]]
+name = "networkx"
+version = "3.0"
+description = "Python package for creating and manipulating graphs and networks"
+category = "main"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "networkx-3.0-py3-none-any.whl", hash = "sha256:58058d66b1818043527244fab9d41a51fcd7dcc271748015f3c181b8a90c8e2e"},
+ {file = "networkx-3.0.tar.gz", hash = "sha256:9a9992345353618ae98339c2b63d8201c381c2944f38a2ab49cb45a4c667e412"},
+]
[package.extras]
-all = ["numpy", "scipy", "pandas", "matplotlib", "pygraphviz", "pydot", "pyyaml", "lxml", "pytest"]
-gdal = ["gdal"]
-lxml = ["lxml"]
-matplotlib = ["matplotlib"]
-numpy = ["numpy"]
-pandas = ["pandas"]
-pydot = ["pydot"]
-pygraphviz = ["pygraphviz"]
-pytest = ["pytest"]
-pyyaml = ["pyyaml"]
-scipy = ["scipy"]
+default = ["matplotlib (>=3.4)", "numpy (>=1.20)", "pandas (>=1.3)", "scipy (>=1.8)"]
+developer = ["mypy (>=0.991)", "pre-commit (>=2.20)"]
+doc = ["nb2plots (>=0.6)", "numpydoc (>=1.5)", "pillow (>=9.2)", "pydata-sphinx-theme (>=0.11)", "sphinx (==5.2.3)", "sphinx-gallery (>=0.11)", "texext (>=0.6.7)"]
+extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.10)", "sympy (>=1.10)"]
+test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"]
[[package]]
name = "numpy"
-version = "1.19.5"
-description = "NumPy is the fundamental package for array computing with Python."
+version = "1.24.2"
+description = "Fundamental package for array computing in Python"
category = "main"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.8"
+files = [
+ {file = "numpy-1.24.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eef70b4fc1e872ebddc38cddacc87c19a3709c0e3e5d20bf3954c147b1dd941d"},
+ {file = "numpy-1.24.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d2859428712785e8a8b7d2b3ef0a1d1565892367b32f915c4a4df44d0e64f5"},
+ {file = "numpy-1.24.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6524630f71631be2dabe0c541e7675db82651eb998496bbe16bc4f77f0772253"},
+ {file = "numpy-1.24.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a51725a815a6188c662fb66fb32077709a9ca38053f0274640293a14fdd22978"},
+ {file = "numpy-1.24.2-cp310-cp310-win32.whl", hash = "sha256:2620e8592136e073bd12ee4536149380695fbe9ebeae845b81237f986479ffc9"},
+ {file = "numpy-1.24.2-cp310-cp310-win_amd64.whl", hash = "sha256:97cf27e51fa078078c649a51d7ade3c92d9e709ba2bfb97493007103c741f1d0"},
+ {file = "numpy-1.24.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7de8fdde0003f4294655aa5d5f0a89c26b9f22c0a58790c38fae1ed392d44a5a"},
+ {file = "numpy-1.24.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4173bde9fa2a005c2c6e2ea8ac1618e2ed2c1c6ec8a7657237854d42094123a0"},
+ {file = "numpy-1.24.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cecaed30dc14123020f77b03601559fff3e6cd0c048f8b5289f4eeabb0eb281"},
+ {file = "numpy-1.24.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a23f8440561a633204a67fb44617ce2a299beecf3295f0d13c495518908e910"},
+ {file = "numpy-1.24.2-cp311-cp311-win32.whl", hash = "sha256:e428c4fbfa085f947b536706a2fc349245d7baa8334f0c5723c56a10595f9b95"},
+ {file = "numpy-1.24.2-cp311-cp311-win_amd64.whl", hash = "sha256:557d42778a6869c2162deb40ad82612645e21d79e11c1dc62c6e82a2220ffb04"},
+ {file = "numpy-1.24.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d0a2db9d20117bf523dde15858398e7c0858aadca7c0f088ac0d6edd360e9ad2"},
+ {file = "numpy-1.24.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c72a6b2f4af1adfe193f7beb91ddf708ff867a3f977ef2ec53c0ffb8283ab9f5"},
+ {file = "numpy-1.24.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c29e6bd0ec49a44d7690ecb623a8eac5ab8a923bce0bea6293953992edf3a76a"},
+ {file = "numpy-1.24.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2eabd64ddb96a1239791da78fa5f4e1693ae2dadc82a76bc76a14cbb2b966e96"},
+ {file = "numpy-1.24.2-cp38-cp38-win32.whl", hash = "sha256:e3ab5d32784e843fc0dd3ab6dcafc67ef806e6b6828dc6af2f689be0eb4d781d"},
+ {file = "numpy-1.24.2-cp38-cp38-win_amd64.whl", hash = "sha256:76807b4063f0002c8532cfeac47a3068a69561e9c8715efdad3c642eb27c0756"},
+ {file = "numpy-1.24.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4199e7cfc307a778f72d293372736223e39ec9ac096ff0a2e64853b866a8e18a"},
+ {file = "numpy-1.24.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:adbdce121896fd3a17a77ab0b0b5eedf05a9834a18699db6829a64e1dfccca7f"},
+ {file = "numpy-1.24.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:889b2cc88b837d86eda1b17008ebeb679d82875022200c6e8e4ce6cf549b7acb"},
+ {file = "numpy-1.24.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f64bb98ac59b3ea3bf74b02f13836eb2e24e48e0ab0145bbda646295769bd780"},
+ {file = "numpy-1.24.2-cp39-cp39-win32.whl", hash = "sha256:63e45511ee4d9d976637d11e6c9864eae50e12dc9598f531c035265991910468"},
+ {file = "numpy-1.24.2-cp39-cp39-win_amd64.whl", hash = "sha256:a77d3e1163a7770164404607b7ba3967fb49b24782a6ef85d9b5f54126cc39e5"},
+ {file = "numpy-1.24.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:92011118955724465fb6853def593cf397b4a1367495e0b59a7e69d40c4eb71d"},
+ {file = "numpy-1.24.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9006288bcf4895917d02583cf3411f98631275bc67cce355a7f39f8c14338fa"},
+ {file = "numpy-1.24.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:150947adbdfeceec4e5926d956a06865c1c690f2fd902efede4ca6fe2e657c3f"},
+ {file = "numpy-1.24.2.tar.gz", hash = "sha256:003a9f530e880cb2cd177cba1af7220b9aa42def9c4afc2a2fc3ee6be7eb2b22"},
+]
[[package]]
name = "oauthlib"
-version = "3.1.1"
+version = "3.2.2"
description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic"
-category = "dev"
+category = "main"
optional = false
python-versions = ">=3.6"
+files = [
+ {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"},
+ {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"},
+]
[package.extras]
-rsa = ["cryptography (>=3.0.0,<4)"]
+rsa = ["cryptography (>=3.0.0)"]
signals = ["blinker (>=1.4.0)"]
-signedtoken = ["cryptography (>=3.0.0,<4)", "pyjwt (>=2.0.0,<3)"]
+signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"]
[[package]]
name = "opt-einsum"
version = "3.3.0"
description = "Optimizing numpys einsum function"
-category = "dev"
+category = "main"
optional = false
python-versions = ">=3.5"
+files = [
+ {file = "opt_einsum-3.3.0-py3-none-any.whl", hash = "sha256:2455e59e3947d3c275477df7f5205b30635e266fe6dc300e3d9f9646bfcea147"},
+ {file = "opt_einsum-3.3.0.tar.gz", hash = "sha256:59f6475f77bbc37dcf7cd748519c0ec60722e91e63ca114e68821c0c54a46549"},
+]
[package.dependencies]
numpy = ">=1.7"
[package.extras]
-docs = ["sphinx (1.2.3)", "sphinxcontrib-napoleon", "sphinx-rtd-theme", "numpydoc"]
+docs = ["numpydoc", "sphinx (==1.2.3)", "sphinx-rtd-theme", "sphinxcontrib-napoleon"]
tests = ["pytest", "pytest-cov", "pytest-pep8"]
+[[package]]
+name = "packaging"
+version = "23.0"
+description = "Core utilities for Python packages"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"},
+ {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"},
+]
+
[[package]]
name = "pandas"
-version = "1.2.4"
+version = "1.5.3"
description = "Powerful data structures for data analysis, time series, and statistics"
-category = "dev"
+category = "main"
optional = false
-python-versions = ">=3.7.1"
+python-versions = ">=3.8"
+files = [
+ {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"},
+ {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572"},
+ {file = "pandas-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996"},
+ {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ac844a0fe00bfaeb2c9b51ab1424e5c8744f89860b138434a363b1f620f354"},
+ {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a0a56cef15fd1586726dace5616db75ebcfec9179a3a55e78f72c5639fa2a23"},
+ {file = "pandas-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:478ff646ca42b20376e4ed3fa2e8d7341e8a63105586efe54fa2508ee087f328"},
+ {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6973549c01ca91ec96199e940495219c887ea815b2083722821f1d7abfa2b4dc"},
+ {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c39a8da13cede5adcd3be1182883aea1c925476f4e84b2807a46e2775306305d"},
+ {file = "pandas-1.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc"},
+ {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae"},
+ {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f2b952406a1588ad4cad5b3f55f520e82e902388a6d5a4a91baa8d38d23c7f6"},
+ {file = "pandas-1.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc4c368f42b551bf72fac35c5128963a171b40dce866fb066540eeaf46faa003"},
+ {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14e45300521902689a81f3f41386dc86f19b8ba8dd5ac5a3c7010ef8d2932813"},
+ {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9842b6f4b8479e41968eced654487258ed81df7d1c9b7b870ceea24ed9459b31"},
+ {file = "pandas-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26d9c71772c7afb9d5046e6e9cf42d83dd147b5cf5bcb9d97252077118543792"},
+ {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fbcb19d6fceb9e946b3e23258757c7b225ba450990d9ed63ccceeb8cae609f7"},
+ {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:565fa34a5434d38e9d250af3c12ff931abaf88050551d9fbcdfafca50d62babf"},
+ {file = "pandas-1.5.3-cp38-cp38-win32.whl", hash = "sha256:87bd9c03da1ac870a6d2c8902a0e1fd4267ca00f13bc494c9e5a9020920e1d51"},
+ {file = "pandas-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:41179ce559943d83a9b4bbacb736b04c928b095b5f25dd2b7389eda08f46f373"},
+ {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c74a62747864ed568f5a82a49a23a8d7fe171d0c69038b38cedf0976831296fa"},
+ {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c4c00e0b0597c8e4f59e8d461f797e5d70b4d025880516a8261b2817c47759ee"},
+ {file = "pandas-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a50d9a4336a9621cab7b8eb3fb11adb82de58f9b91d84c2cd526576b881a0c5a"},
+ {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd05f7783b3274aa206a1af06f0ceed3f9b412cf665b7247eacd83be41cf7bf0"},
+ {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f69c4029613de47816b1bb30ff5ac778686688751a5e9c99ad8c7031f6508e5"},
+ {file = "pandas-1.5.3-cp39-cp39-win32.whl", hash = "sha256:7cec0bee9f294e5de5bbfc14d0573f65526071029d036b753ee6507d2a21480a"},
+ {file = "pandas-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9"},
+ {file = "pandas-1.5.3.tar.gz", hash = "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1"},
+]
[package.dependencies]
-numpy = ">=1.16.5"
-python-dateutil = ">=2.7.3"
-pytz = ">=2017.3"
+numpy = [
+ {version = ">=1.20.3", markers = "python_version < \"3.10\""},
+ {version = ">=1.21.0", markers = "python_version >= \"3.10\""},
+]
+python-dateutil = ">=2.8.1"
+pytz = ">=2020.1"
[package.extras]
-test = ["pytest (>=5.0.1)", "pytest-xdist", "hypothesis (>=3.58)"]
+test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"]
[[package]]
name = "parchmint"
-version = "0.2.9"
+version = "0.3.3"
description = "Parchmint is data interchange standard for representing microfluidic designs. Check out https://parchmint.org for more information."
category = "main"
optional = false
-python-versions = "^3.8"
+python-versions = ">=3.8,<3.11"
+files = []
develop = true
[package.dependencies]
-argparse = ">=1.4.0,<2.0.0"
-jsonschema = ">=3.2.0,<4.0.0"
-networkx = ">=2.5,<3.0"
+argparse = "^1.4.0"
+jsonschema = "^3.2.0"
+networkx = "^3.0"
+numpy = "^1.22.4"
+tabulate = "^0.8.9"
+
+[package.extras]
+docs = []
[package.source]
type = "directory"
-url = "../pyparchmint"
+url = "pyparchmint"
[[package]]
name = "pathspec"
-version = "0.8.1"
+version = "0.11.0"
description = "Utility library for gitignore style pattern matching of file paths."
category = "dev"
optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.7"
+files = [
+ {file = "pathspec-0.11.0-py3-none-any.whl", hash = "sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229"},
+ {file = "pathspec-0.11.0.tar.gz", hash = "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"},
+]
[[package]]
name = "pillow"
-version = "8.2.0"
+version = "9.4.0"
description = "Python Imaging Library (Fork)"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "Pillow-9.4.0-1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b4b4e9dda4f4e4c4e6896f93e84a8f0bcca3b059de9ddf67dac3c334b1195e1"},
+ {file = "Pillow-9.4.0-1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:fb5c1ad6bad98c57482236a21bf985ab0ef42bd51f7ad4e4538e89a997624e12"},
+ {file = "Pillow-9.4.0-1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:f0caf4a5dcf610d96c3bd32932bfac8aee61c96e60481c2a0ea58da435e25acd"},
+ {file = "Pillow-9.4.0-1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:3f4cc516e0b264c8d4ccd6b6cbc69a07c6d582d8337df79be1e15a5056b258c9"},
+ {file = "Pillow-9.4.0-1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:b8c2f6eb0df979ee99433d8b3f6d193d9590f735cf12274c108bd954e30ca858"},
+ {file = "Pillow-9.4.0-1-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b70756ec9417c34e097f987b4d8c510975216ad26ba6e57ccb53bc758f490dab"},
+ {file = "Pillow-9.4.0-1-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:43521ce2c4b865d385e78579a082b6ad1166ebed2b1a2293c3be1d68dd7ca3b9"},
+ {file = "Pillow-9.4.0-2-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:9d9a62576b68cd90f7075876f4e8444487db5eeea0e4df3ba298ee38a8d067b0"},
+ {file = "Pillow-9.4.0-2-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:87708d78a14d56a990fbf4f9cb350b7d89ee8988705e58e39bdf4d82c149210f"},
+ {file = "Pillow-9.4.0-2-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:8a2b5874d17e72dfb80d917213abd55d7e1ed2479f38f001f264f7ce7bae757c"},
+ {file = "Pillow-9.4.0-2-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:83125753a60cfc8c412de5896d10a0a405e0bd88d0470ad82e0869ddf0cb3848"},
+ {file = "Pillow-9.4.0-2-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9e5f94742033898bfe84c93c831a6f552bb629448d4072dd312306bab3bd96f1"},
+ {file = "Pillow-9.4.0-2-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:013016af6b3a12a2f40b704677f8b51f72cb007dac785a9933d5c86a72a7fe33"},
+ {file = "Pillow-9.4.0-2-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:99d92d148dd03fd19d16175b6d355cc1b01faf80dae93c6c3eb4163709edc0a9"},
+ {file = "Pillow-9.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:2968c58feca624bb6c8502f9564dd187d0e1389964898f5e9e1fbc8533169157"},
+ {file = "Pillow-9.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c5c1362c14aee73f50143d74389b2c158707b4abce2cb055b7ad37ce60738d47"},
+ {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd752c5ff1b4a870b7661234694f24b1d2b9076b8bf337321a814c612665f343"},
+ {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a3049a10261d7f2b6514d35bbb7a4dfc3ece4c4de14ef5876c4b7a23a0e566d"},
+ {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16a8df99701f9095bea8a6c4b3197da105df6f74e6176c5b410bc2df2fd29a57"},
+ {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:94cdff45173b1919350601f82d61365e792895e3c3a3443cf99819e6fbf717a5"},
+ {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:ed3e4b4e1e6de75fdc16d3259098de7c6571b1a6cc863b1a49e7d3d53e036070"},
+ {file = "Pillow-9.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5b2f8a31bd43e0f18172d8ac82347c8f37ef3e0b414431157718aa234991b28"},
+ {file = "Pillow-9.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:09b89ddc95c248ee788328528e6a2996e09eaccddeeb82a5356e92645733be35"},
+ {file = "Pillow-9.4.0-cp310-cp310-win32.whl", hash = "sha256:f09598b416ba39a8f489c124447b007fe865f786a89dbfa48bb5cf395693132a"},
+ {file = "Pillow-9.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:f6e78171be3fb7941f9910ea15b4b14ec27725865a73c15277bc39f5ca4f8391"},
+ {file = "Pillow-9.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:3fa1284762aacca6dc97474ee9c16f83990b8eeb6697f2ba17140d54b453e133"},
+ {file = "Pillow-9.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:eaef5d2de3c7e9b21f1e762f289d17b726c2239a42b11e25446abf82b26ac132"},
+ {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4dfdae195335abb4e89cc9762b2edc524f3c6e80d647a9a81bf81e17e3fb6f0"},
+ {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6abfb51a82e919e3933eb137e17c4ae9c0475a25508ea88993bb59faf82f3b35"},
+ {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:451f10ef963918e65b8869e17d67db5e2f4ab40e716ee6ce7129b0cde2876eab"},
+ {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:6663977496d616b618b6cfa43ec86e479ee62b942e1da76a2c3daa1c75933ef4"},
+ {file = "Pillow-9.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:60e7da3a3ad1812c128750fc1bc14a7ceeb8d29f77e0a2356a8fb2aa8925287d"},
+ {file = "Pillow-9.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:19005a8e58b7c1796bc0167862b1f54a64d3b44ee5d48152b06bb861458bc0f8"},
+ {file = "Pillow-9.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f715c32e774a60a337b2bb8ad9839b4abf75b267a0f18806f6f4f5f1688c4b5a"},
+ {file = "Pillow-9.4.0-cp311-cp311-win32.whl", hash = "sha256:b222090c455d6d1a64e6b7bb5f4035c4dff479e22455c9eaa1bdd4c75b52c80c"},
+ {file = "Pillow-9.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:ba6612b6548220ff5e9df85261bddc811a057b0b465a1226b39bfb8550616aee"},
+ {file = "Pillow-9.4.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:5f532a2ad4d174eb73494e7397988e22bf427f91acc8e6ebf5bb10597b49c493"},
+ {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dd5a9c3091a0f414a963d427f920368e2b6a4c2f7527fdd82cde8ef0bc7a327"},
+ {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef21af928e807f10bf4141cad4746eee692a0dd3ff56cfb25fce076ec3cc8abe"},
+ {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:847b114580c5cc9ebaf216dd8c8dbc6b00a3b7ab0131e173d7120e6deade1f57"},
+ {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:653d7fb2df65efefbcbf81ef5fe5e5be931f1ee4332c2893ca638c9b11a409c4"},
+ {file = "Pillow-9.4.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:46f39cab8bbf4a384ba7cb0bc8bae7b7062b6a11cfac1ca4bc144dea90d4a9f5"},
+ {file = "Pillow-9.4.0-cp37-cp37m-win32.whl", hash = "sha256:7ac7594397698f77bce84382929747130765f66406dc2cd8b4ab4da68ade4c6e"},
+ {file = "Pillow-9.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:46c259e87199041583658457372a183636ae8cd56dbf3f0755e0f376a7f9d0e6"},
+ {file = "Pillow-9.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:0e51f608da093e5d9038c592b5b575cadc12fd748af1479b5e858045fff955a9"},
+ {file = "Pillow-9.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:765cb54c0b8724a7c12c55146ae4647e0274a839fb6de7bcba841e04298e1011"},
+ {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:519e14e2c49fcf7616d6d2cfc5c70adae95682ae20f0395e9280db85e8d6c4df"},
+ {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d197df5489004db87d90b918033edbeee0bd6df3848a204bca3ff0a903bef837"},
+ {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0845adc64fe9886db00f5ab68c4a8cd933ab749a87747555cec1c95acea64b0b"},
+ {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:e1339790c083c5a4de48f688b4841f18df839eb3c9584a770cbd818b33e26d5d"},
+ {file = "Pillow-9.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:a96e6e23f2b79433390273eaf8cc94fec9c6370842e577ab10dabdcc7ea0a66b"},
+ {file = "Pillow-9.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7cfc287da09f9d2a7ec146ee4d72d6ea1342e770d975e49a8621bf54eaa8f30f"},
+ {file = "Pillow-9.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d7081c084ceb58278dd3cf81f836bc818978c0ccc770cbbb202125ddabec6628"},
+ {file = "Pillow-9.4.0-cp38-cp38-win32.whl", hash = "sha256:df41112ccce5d47770a0c13651479fbcd8793f34232a2dd9faeccb75eb5d0d0d"},
+ {file = "Pillow-9.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:7a21222644ab69ddd9967cfe6f2bb420b460dae4289c9d40ff9a4896e7c35c9a"},
+ {file = "Pillow-9.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0f3269304c1a7ce82f1759c12ce731ef9b6e95b6df829dccd9fe42912cc48569"},
+ {file = "Pillow-9.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cb362e3b0976dc994857391b776ddaa8c13c28a16f80ac6522c23d5257156bed"},
+ {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2e0f87144fcbbe54297cae708c5e7f9da21a4646523456b00cc956bd4c65815"},
+ {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:28676836c7796805914b76b1837a40f76827ee0d5398f72f7dcc634bae7c6264"},
+ {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0884ba7b515163a1a05440a138adeb722b8a6ae2c2b33aea93ea3118dd3a899e"},
+ {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:53dcb50fbdc3fb2c55431a9b30caeb2f7027fcd2aeb501459464f0214200a503"},
+ {file = "Pillow-9.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:e8c5cf126889a4de385c02a2c3d3aba4b00f70234bfddae82a5eaa3ee6d5e3e6"},
+ {file = "Pillow-9.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6c6b1389ed66cdd174d040105123a5a1bc91d0aa7059c7261d20e583b6d8cbd2"},
+ {file = "Pillow-9.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0dd4c681b82214b36273c18ca7ee87065a50e013112eea7d78c7a1b89a739153"},
+ {file = "Pillow-9.4.0-cp39-cp39-win32.whl", hash = "sha256:6d9dfb9959a3b0039ee06c1a1a90dc23bac3b430842dcb97908ddde05870601c"},
+ {file = "Pillow-9.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:54614444887e0d3043557d9dbc697dbb16cfb5a35d672b7a0fcc1ed0cf1c600b"},
+ {file = "Pillow-9.4.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b9b752ab91e78234941e44abdecc07f1f0d8f51fb62941d32995b8161f68cfe5"},
+ {file = "Pillow-9.4.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3b56206244dc8711f7e8b7d6cad4663917cd5b2d950799425076681e8766286"},
+ {file = "Pillow-9.4.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aabdab8ec1e7ca7f1434d042bf8b1e92056245fb179790dc97ed040361f16bfd"},
+ {file = "Pillow-9.4.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:db74f5562c09953b2c5f8ec4b7dfd3f5421f31811e97d1dbc0a7c93d6e3a24df"},
+ {file = "Pillow-9.4.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e9d7747847c53a16a729b6ee5e737cf170f7a16611c143d95aa60a109a59c336"},
+ {file = "Pillow-9.4.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b52ff4f4e002f828ea6483faf4c4e8deea8d743cf801b74910243c58acc6eda3"},
+ {file = "Pillow-9.4.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:575d8912dca808edd9acd6f7795199332696d3469665ef26163cd090fa1f8bfa"},
+ {file = "Pillow-9.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3c4ed2ff6760e98d262e0cc9c9a7f7b8a9f61aa4d47c58835cdaf7b0b8811bb"},
+ {file = "Pillow-9.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e621b0246192d3b9cb1dc62c78cfa4c6f6d2ddc0ec207d43c0dedecb914f152a"},
+ {file = "Pillow-9.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8f127e7b028900421cad64f51f75c051b628db17fb00e099eb148761eed598c9"},
+ {file = "Pillow-9.4.0.tar.gz", hash = "sha256:a1c2d7780448eb93fbcc3789bf3916aa5720d942e37945f4056680317f1cd23e"},
+]
+
+[package.extras]
+docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinxext-opengraph"]
+tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"]
+
+[[package]]
+name = "pip"
+version = "23.0.1"
+description = "The PyPA recommended tool for installing Python packages."
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "pip-23.0.1-py3-none-any.whl", hash = "sha256:236bcb61156d76c4b8a05821b988c7b8c35bf0da28a4b614e8d6ab5212c25c6f"},
+ {file = "pip-23.0.1.tar.gz", hash = "sha256:cd015ea1bfb0fcef59d8a286c1f8bebcb983f6317719d415dc5351efb7cd7024"},
+]
+
+[[package]]
+name = "platformdirs"
+version = "3.1.1"
+description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "platformdirs-3.1.1-py3-none-any.whl", hash = "sha256:e5986afb596e4bb5bde29a79ac9061aa955b94fca2399b7aaac4090860920dd8"},
+ {file = "platformdirs-3.1.1.tar.gz", hash = "sha256:024996549ee88ec1a9aa99ff7f8fc819bb59e2c3477b410d90a16d32d6e707aa"},
+]
+
+[package.extras]
+docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
+
+[[package]]
+name = "pluggy"
+version = "1.0.0"
+description = "plugin and hook calling mechanisms for python"
category = "dev"
optional = false
python-versions = ">=3.6"
+files = [
+ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
+ {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
+]
+
+[package.extras]
+dev = ["pre-commit", "tox"]
+testing = ["pytest", "pytest-benchmark"]
[[package]]
-name = "protobuf"
-version = "3.17.3"
-description = "Protocol Buffers"
+name = "pockets"
+version = "0.9.1"
+description = "A collection of helpful Python tools!"
category = "dev"
optional = false
python-versions = "*"
+files = [
+ {file = "pockets-0.9.1-py2.py3-none-any.whl", hash = "sha256:68597934193c08a08eb2bf6a1d85593f627c22f9b065cc727a4f03f669d96d86"},
+ {file = "pockets-0.9.1.tar.gz", hash = "sha256:9320f1a3c6f7a9133fe3b571f283bcf3353cd70249025ae8d618e40e9f7e92b3"},
+]
[package.dependencies]
-six = ">=1.9"
+six = ">=1.5.2"
+
+[[package]]
+name = "protobuf"
+version = "3.19.6"
+description = "Protocol Buffers"
+category = "main"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "protobuf-3.19.6-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:010be24d5a44be7b0613750ab40bc8b8cedc796db468eae6c779b395f50d1fa1"},
+ {file = "protobuf-3.19.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11478547958c2dfea921920617eb457bc26867b0d1aa065ab05f35080c5d9eb6"},
+ {file = "protobuf-3.19.6-cp310-cp310-win32.whl", hash = "sha256:559670e006e3173308c9254d63facb2c03865818f22204037ab76f7a0ff70b5f"},
+ {file = "protobuf-3.19.6-cp310-cp310-win_amd64.whl", hash = "sha256:347b393d4dd06fb93a77620781e11c058b3b0a5289262f094379ada2920a3730"},
+ {file = "protobuf-3.19.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a8ce5ae0de28b51dff886fb922012dad885e66176663950cb2344c0439ecb473"},
+ {file = "protobuf-3.19.6-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90b0d02163c4e67279ddb6dc25e063db0130fc299aefabb5d481053509fae5c8"},
+ {file = "protobuf-3.19.6-cp36-cp36m-win32.whl", hash = "sha256:30f5370d50295b246eaa0296533403961f7e64b03ea12265d6dfce3a391d8992"},
+ {file = "protobuf-3.19.6-cp36-cp36m-win_amd64.whl", hash = "sha256:0c0714b025ec057b5a7600cb66ce7c693815f897cfda6d6efb58201c472e3437"},
+ {file = "protobuf-3.19.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5057c64052a1f1dd7d4450e9aac25af6bf36cfbfb3a1cd89d16393a036c49157"},
+ {file = "protobuf-3.19.6-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:bb6776bd18f01ffe9920e78e03a8676530a5d6c5911934c6a1ac6eb78973ecb6"},
+ {file = "protobuf-3.19.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84a04134866861b11556a82dd91ea6daf1f4925746b992f277b84013a7cc1229"},
+ {file = "protobuf-3.19.6-cp37-cp37m-win32.whl", hash = "sha256:4bc98de3cdccfb5cd769620d5785b92c662b6bfad03a202b83799b6ed3fa1fa7"},
+ {file = "protobuf-3.19.6-cp37-cp37m-win_amd64.whl", hash = "sha256:aa3b82ca1f24ab5326dcf4ea00fcbda703e986b22f3d27541654f749564d778b"},
+ {file = "protobuf-3.19.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2b2d2913bcda0e0ec9a784d194bc490f5dc3d9d71d322d070b11a0ade32ff6ba"},
+ {file = "protobuf-3.19.6-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:d0b635cefebd7a8a0f92020562dead912f81f401af7e71f16bf9506ff3bdbb38"},
+ {file = "protobuf-3.19.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a552af4dc34793803f4e735aabe97ffc45962dfd3a237bdde242bff5a3de684"},
+ {file = "protobuf-3.19.6-cp38-cp38-win32.whl", hash = "sha256:0469bc66160180165e4e29de7f445e57a34ab68f49357392c5b2f54c656ab25e"},
+ {file = "protobuf-3.19.6-cp38-cp38-win_amd64.whl", hash = "sha256:91d5f1e139ff92c37e0ff07f391101df77e55ebb97f46bbc1535298d72019462"},
+ {file = "protobuf-3.19.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c0ccd3f940fe7f3b35a261b1dd1b4fc850c8fde9f74207015431f174be5976b3"},
+ {file = "protobuf-3.19.6-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:30a15015d86b9c3b8d6bf78d5b8c7749f2512c29f168ca259c9d7727604d0e39"},
+ {file = "protobuf-3.19.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:878b4cd080a21ddda6ac6d1e163403ec6eea2e206cf225982ae04567d39be7b0"},
+ {file = "protobuf-3.19.6-cp39-cp39-win32.whl", hash = "sha256:5a0d7539a1b1fb7e76bf5faa0b44b30f812758e989e59c40f77a7dab320e79b9"},
+ {file = "protobuf-3.19.6-cp39-cp39-win_amd64.whl", hash = "sha256:bbf5cea5048272e1c60d235c7bd12ce1b14b8a16e76917f371c718bd3005f045"},
+ {file = "protobuf-3.19.6-py2.py3-none-any.whl", hash = "sha256:14082457dc02be946f60b15aad35e9f5c69e738f80ebbc0900a19bc83734a5a4"},
+ {file = "protobuf-3.19.6.tar.gz", hash = "sha256:5f5540d57a43042389e87661c6eaa50f47c19c6176e8cf1c4f287aeefeccb5c4"},
+]
[[package]]
name = "pyasn1"
version = "0.4.8"
description = "ASN.1 types and codecs"
-category = "dev"
+category = "main"
optional = false
python-versions = "*"
+files = [
+ {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"},
+ {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"},
+]
[[package]]
name = "pyasn1-modules"
version = "0.2.8"
description = "A collection of ASN.1-based protocols modules."
-category = "dev"
+category = "main"
optional = false
python-versions = "*"
+files = [
+ {file = "pyasn1-modules-0.2.8.tar.gz", hash = "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e"},
+ {file = "pyasn1_modules-0.2.8-py2.py3-none-any.whl", hash = "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"},
+]
[package.dependencies]
pyasn1 = ">=0.4.6,<0.5.0"
[[package]]
name = "pycodestyle"
-version = "2.6.0"
+version = "2.7.0"
description = "Python style guide checker"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+ {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"},
+ {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"},
+]
+
+[[package]]
+name = "pyeda"
+version = "0.28.0"
+description = "Python Electronic Design Automation"
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+ {file = "pyeda-0.28.0.tar.gz", hash = "sha256:07185f458d5d0b2ba5058da8b95dad6ab7684ceaf41237a25bcd3f005490f59d"},
+ {file = "pyeda-0.28.0.zip", hash = "sha256:e34c7a6332d24914d1be524b3d9fe97feb165dbfe63473b3a112c1aeda2c002e"},
+]
+
+[[package]]
+name = "pyfiglet"
+version = "0.8.post1"
+description = "Pure-python FIGlet implementation"
+category = "main"
+optional = false
+python-versions = "*"
+files = [
+ {file = "pyfiglet-0.8.post1-py2.py3-none-any.whl", hash = "sha256:d555bcea17fbeaf70eaefa48bb119352487e629c9b56f30f383e2c62dd67a01c"},
+ {file = "pyfiglet-0.8.post1.tar.gz", hash = "sha256:c6c2321755d09267b438ec7b936825a4910fec696292139e664ca8670e103639"},
+]
[[package]]
name = "pyflakes"
-version = "2.2.0"
+version = "2.3.1"
description = "passive checker of Python programs"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+ {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"},
+ {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"},
+]
+
+[[package]]
+name = "pygments"
+version = "2.14.0"
+description = "Pygments is a syntax highlighting package written in Python."
+category = "dev"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"},
+ {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"},
+]
+
+[package.extras]
+plugins = ["importlib-metadata"]
[[package]]
name = "pygraphviz"
-version = "1.6"
+version = "1.10"
description = "Python interface to Graphviz"
category = "main"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.8"
+files = [
+ {file = "pygraphviz-1.10.zip", hash = "sha256:457e093a888128903251a266a8cc16b4ba93f3f6334b3ebfed92c7471a74d867"},
+]
[[package]]
name = "pymint"
-version = "0.2.7"
+version = "0.3.1"
description = "MINT is a human readable language to describe Microfluidic Hardware Netlists. MINT is the name of the Microfluidic Netlist language used to describe microfluidic devices for Fluigi to place and route. Mint is a flavor of (MHDL) Microfluidic Hardware Description Language that can be used to represent Microfluidic Circuits."
category = "main"
optional = false
-python-versions = "^3.8"
+python-versions = ">=3.8,<3.11"
+files = []
develop = true
[package.dependencies]
-antlr4-python3-runtime = ">=4.8,<5.0"
-install = ">=1.3.3,<2.0.0"
-parchmint = ">=0.2.6,<0.3.0"
+antlr4-python3-runtime = "^4.8"
+click = "^8.1.3"
+install = "^1.3.3"
+networkx = "^3.0"
+parchmint = {path = "../pyparchmint", develop = true}
+pyfiglet = "^0.8.post1"
+pygraphviz = "^1.9"
+
+[package.extras]
+docs = []
[package.source]
type = "directory"
-url = "../pymint"
+url = "pymint"
[[package]]
name = "pyparsing"
-version = "2.4.7"
-description = "Python parsing module"
-category = "dev"
+version = "3.0.9"
+description = "pyparsing module - Classes and methods to define and execute parsing grammars"
+category = "main"
optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
+python-versions = ">=3.6.8"
+files = [
+ {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
+ {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
+]
+
+[package.extras]
+diagrams = ["jinja2", "railroad-diagrams"]
[[package]]
name = "pyrsistent"
-version = "0.17.3"
+version = "0.19.3"
description = "Persistent/Functional/Immutable data structures"
category = "main"
optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.7"
+files = [
+ {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"},
+ {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"},
+ {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"},
+ {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"},
+ {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"},
+ {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"},
+ {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"},
+ {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"},
+ {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"},
+ {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"},
+ {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"},
+ {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"},
+ {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"},
+ {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"},
+ {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"},
+ {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"},
+ {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"},
+ {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"},
+ {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"},
+ {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"},
+ {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"},
+ {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"},
+ {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"},
+ {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"},
+ {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"},
+ {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"},
+ {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"},
+]
+
+[[package]]
+name = "pytest"
+version = "7.2.2"
+description = "pytest: simple powerful testing with Python"
+category = "dev"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "pytest-7.2.2-py3-none-any.whl", hash = "sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e"},
+ {file = "pytest-7.2.2.tar.gz", hash = "sha256:c99ab0c73aceb050f68929bc93af19ab6db0558791c6a0715723abe9d0ade9d4"},
+]
+
+[package.dependencies]
+attrs = ">=19.2.0"
+colorama = {version = "*", markers = "sys_platform == \"win32\""}
+exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
+iniconfig = "*"
+packaging = "*"
+pluggy = ">=0.12,<2.0"
+tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
+
+[package.extras]
+testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"]
[[package]]
name = "python-dateutil"
-version = "2.8.1"
+version = "2.8.2"
description = "Extensions to the standard Python datetime module"
-category = "dev"
+category = "main"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
+files = [
+ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
+ {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
+]
[package.dependencies]
six = ">=1.5"
[[package]]
name = "pytz"
-version = "2021.1"
+version = "2022.7.1"
description = "World timezone definitions, modern and historical"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "pyyaml"
-version = "5.4.1"
-description = "YAML parser and emitter for Python"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
-
-[[package]]
-name = "regex"
-version = "2020.11.11"
-description = "Alternative regular expression module, to replace re."
-category = "dev"
+category = "main"
optional = false
python-versions = "*"
+files = [
+ {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"},
+ {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"},
+]
[[package]]
name = "requests"
-version = "2.25.1"
+version = "2.28.2"
description = "Python HTTP for Humans."
-category = "dev"
+category = "main"
optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+python-versions = ">=3.7, <4"
+files = [
+ {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"},
+ {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"},
+]
[package.dependencies]
certifi = ">=2017.4.17"
-chardet = ">=3.0.2,<5"
-idna = ">=2.5,<3"
+charset-normalizer = ">=2,<4"
+idna = ">=2.5,<4"
urllib3 = ">=1.21.1,<1.27"
[package.extras]
-security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"]
-socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"]
+socks = ["PySocks (>=1.5.6,!=1.5.7)"]
+use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
name = "requests-oauthlib"
-version = "1.3.0"
+version = "1.3.1"
description = "OAuthlib authentication support for Requests."
-category = "dev"
+category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+ {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"},
+ {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"},
+]
[package.dependencies]
oauthlib = ">=3.0.0"
@@ -681,74 +1828,138 @@ description = "a python refactoring library..."
category = "dev"
optional = false
python-versions = "*"
+files = [
+ {file = "rope-0.18.0.tar.gz", hash = "sha256:786b5c38c530d4846aa68a42604f61b4e69a493390e3ca11b88df0fbfdc3ed04"},
+]
[package.extras]
dev = ["pytest"]
[[package]]
name = "rsa"
-version = "4.7.2"
+version = "4.9"
description = "Pure-Python RSA implementation"
-category = "dev"
+category = "main"
optional = false
-python-versions = ">=3.5, <4"
+python-versions = ">=3.6,<4"
+files = [
+ {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"},
+ {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"},
+]
[package.dependencies]
pyasn1 = ">=0.1.3"
[[package]]
name = "salib"
-version = "1.3.13"
-description = "Tools for sensitivity analysis. Contains Sobol, Morris, and FAST methods"
-category = "dev"
+version = "1.4.7"
+description = "Tools for global sensitivity analysis. Contains Sobol', Morris, FAST, DGSM, PAWN, HDMR, Moment Independent and fractional factorial methods"
+category = "main"
optional = false
-python-versions = "*"
+python-versions = ">=3.8"
+files = [
+ {file = "salib-1.4.7-py3-none-any.whl", hash = "sha256:d04657d9a4972b56ca34ac0f0b1128f21e464d505892adbf921ec70f20662e84"},
+ {file = "salib-1.4.7.tar.gz", hash = "sha256:2e6cb19ec772d6cb7368feceae0f61e51f2d6afdbc4f8986a780b87d657b38cc"},
+]
[package.dependencies]
-matplotlib = "*"
-numpy = "*"
-pandas = "*"
-scipy = "*"
+matplotlib = ">=3.2.2"
+multiprocess = "*"
+numpy = ">=1.20.3"
+pandas = ">=1.1.2"
+scipy = ">=1.7.3"
[package.extras]
-gurobipy = ["gurobipy"]
-testing = ["pytest", "pytest-cov"]
+dev = ["hatch", "pre-commit", "salib[distributed]", "salib[doc]", "salib[test]"]
+distributed = ["pathos (>=0.2.5)"]
+doc = ["myst-parser", "numpydoc", "pydata-sphinx-theme (>=0.10)", "sphinx"]
+test = ["pytest", "pytest-cov", "salib[distributed]"]
[[package]]
name = "scikit-learn"
version = "0.23.2"
description = "A set of python modules for machine learning and data mining"
-category = "dev"
+category = "main"
optional = false
python-versions = ">=3.6"
-
-[package.dependencies]
-joblib = ">=0.11"
-numpy = ">=1.13.3"
-scipy = ">=0.19.1"
-threadpoolctl = ">=2.0.0"
-
-[package.extras]
-alldeps = ["numpy (>=1.13.3)", "scipy (>=0.19.1)"]
-
-[[package]]
-name = "scipy"
-version = "1.6.1"
-description = "SciPy: Scientific Library for Python"
-category = "dev"
+files = [
+ {file = "scikit-learn-0.23.2.tar.gz", hash = "sha256:20766f515e6cd6f954554387dfae705d93c7b544ec0e6c6a5d8e006f6f7ef480"},
+ {file = "scikit_learn-0.23.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:98508723f44c61896a4e15894b2016762a55555fbf09365a0bb1870ecbd442de"},
+ {file = "scikit_learn-0.23.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a64817b050efd50f9abcfd311870073e500ae11b299683a519fbb52d85e08d25"},
+ {file = "scikit_learn-0.23.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:daf276c465c38ef736a79bd79fc80a249f746bcbcae50c40945428f7ece074f8"},
+ {file = "scikit_learn-0.23.2-cp36-cp36m-win32.whl", hash = "sha256:cb3e76380312e1f86abd20340ab1d5b3cc46a26f6593d3c33c9ea3e4c7134028"},
+ {file = "scikit_learn-0.23.2-cp36-cp36m-win_amd64.whl", hash = "sha256:0a127cc70990d4c15b1019680bfedc7fec6c23d14d3719fdf9b64b22d37cdeca"},
+ {file = "scikit_learn-0.23.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2aa95c2f17d2f80534156215c87bee72b6aa314a7f8b8fe92a2d71f47280570d"},
+ {file = "scikit_learn-0.23.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6c28a1d00aae7c3c9568f61aafeaad813f0f01c729bee4fd9479e2132b215c1d"},
+ {file = "scikit_learn-0.23.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:da8e7c302003dd765d92a5616678e591f347460ac7b53e53d667be7dfe6d1b10"},
+ {file = "scikit_learn-0.23.2-cp37-cp37m-win32.whl", hash = "sha256:d9a1ce5f099f29c7c33181cc4386660e0ba891b21a60dc036bf369e3a3ee3aec"},
+ {file = "scikit_learn-0.23.2-cp37-cp37m-win_amd64.whl", hash = "sha256:914ac2b45a058d3f1338d7736200f7f3b094857758895f8667be8a81ff443b5b"},
+ {file = "scikit_learn-0.23.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7671bbeddd7f4f9a6968f3b5442dac5f22bf1ba06709ef888cc9132ad354a9ab"},
+ {file = "scikit_learn-0.23.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:d0dcaa54263307075cb93d0bee3ceb02821093b1b3d25f66021987d305d01dce"},
+ {file = "scikit_learn-0.23.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5ce7a8021c9defc2b75620571b350acc4a7d9763c25b7593621ef50f3bd019a2"},
+ {file = "scikit_learn-0.23.2-cp38-cp38-win32.whl", hash = "sha256:0d39748e7c9669ba648acf40fb3ce96b8a07b240db6888563a7cb76e05e0d9cc"},
+ {file = "scikit_learn-0.23.2-cp38-cp38-win_amd64.whl", hash = "sha256:1b8a391de95f6285a2f9adffb7db0892718950954b7149a70c783dc848f104ea"},
+]
+
+[package.dependencies]
+joblib = ">=0.11"
+numpy = ">=1.13.3"
+scipy = ">=0.19.1"
+threadpoolctl = ">=2.0.0"
+
+[package.extras]
+alldeps = ["numpy (>=1.13.3)", "scipy (>=0.19.1)"]
+
+[[package]]
+name = "scipy"
+version = "1.10.1"
+description = "Fundamental algorithms for scientific computing in Python"
+category = "main"
optional = false
-python-versions = ">=3.7"
+python-versions = "<3.12,>=3.8"
+files = [
+ {file = "scipy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7354fd7527a4b0377ce55f286805b34e8c54b91be865bac273f527e1b839019"},
+ {file = "scipy-1.10.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4b3f429188c66603a1a5c549fb414e4d3bdc2a24792e061ffbd607d3d75fd84e"},
+ {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1553b5dcddd64ba9a0d95355e63fe6c3fc303a8fd77c7bc91e77d61363f7433f"},
+ {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c0ff64b06b10e35215abce517252b375e580a6125fd5fdf6421b98efbefb2d2"},
+ {file = "scipy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:fae8a7b898c42dffe3f7361c40d5952b6bf32d10c4569098d276b4c547905ee1"},
+ {file = "scipy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0f1564ea217e82c1bbe75ddf7285ba0709ecd503f048cb1236ae9995f64217bd"},
+ {file = "scipy-1.10.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d925fa1c81b772882aa55bcc10bf88324dadb66ff85d548c71515f6689c6dac5"},
+ {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaea0a6be54462ec027de54fca511540980d1e9eea68b2d5c1dbfe084797be35"},
+ {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15a35c4242ec5f292c3dd364a7c71a61be87a3d4ddcc693372813c0b73c9af1d"},
+ {file = "scipy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:43b8e0bcb877faf0abfb613d51026cd5cc78918e9530e375727bf0625c82788f"},
+ {file = "scipy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5678f88c68ea866ed9ebe3a989091088553ba12c6090244fdae3e467b1139c35"},
+ {file = "scipy-1.10.1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:39becb03541f9e58243f4197584286e339029e8908c46f7221abeea4b749fa88"},
+ {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bce5869c8d68cf383ce240e44c1d9ae7c06078a9396df68ce88a1230f93a30c1"},
+ {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07c3457ce0b3ad5124f98a86533106b643dd811dd61b548e78cf4c8786652f6f"},
+ {file = "scipy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:049a8bbf0ad95277ffba9b3b7d23e5369cc39e66406d60422c8cfef40ccc8415"},
+ {file = "scipy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cd9f1027ff30d90618914a64ca9b1a77a431159df0e2a195d8a9e8a04c78abf9"},
+ {file = "scipy-1.10.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:79c8e5a6c6ffaf3a2262ef1be1e108a035cf4f05c14df56057b64acc5bebffb6"},
+ {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51af417a000d2dbe1ec6c372dfe688e041a7084da4fdd350aeb139bd3fb55353"},
+ {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b4735d6c28aad3cdcf52117e0e91d6b39acd4272f3f5cd9907c24ee931ad601"},
+ {file = "scipy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ff7f37b1bf4417baca958d254e8e2875d0cc23aaadbe65b3d5b3077b0eb23ea"},
+ {file = "scipy-1.10.1.tar.gz", hash = "sha256:2cf9dfb80a7b4589ba4c40ce7588986d6d5cebc5457cad2c2880f6bc2d42f3a5"},
+]
[package.dependencies]
-numpy = ">=1.16.5"
+numpy = ">=1.19.5,<1.27.0"
+
+[package.extras]
+dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", "rich-click", "typing_extensions"]
+doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"]
+test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"]
[[package]]
name = "seaborn"
-version = "0.11.1"
+version = "0.11.2"
description = "seaborn: statistical data visualization"
-category = "dev"
+category = "main"
optional = false
python-versions = ">=3.6"
+files = [
+ {file = "seaborn-0.11.2-py3-none-any.whl", hash = "sha256:85a6baa9b55f81a0623abddc4a26b334653ff4c6b18c418361de19dbba0ef283"},
+ {file = "seaborn-0.11.2.tar.gz", hash = "sha256:cf45e9286d40826864be0e3c066f98536982baf701a7caa386511792d61ff4f6"},
+]
[package.dependencies]
matplotlib = ">=2.2"
@@ -756,842 +1967,610 @@ numpy = ">=1.15"
pandas = ">=0.23"
scipy = ">=1.0"
+[[package]]
+name = "setuptools"
+version = "67.6.0"
+description = "Easily download, build, install, upgrade, and uninstall Python packages"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "setuptools-67.6.0-py3-none-any.whl", hash = "sha256:b78aaa36f6b90a074c1fa651168723acbf45d14cb1196b6f02c0fd07f17623b2"},
+ {file = "setuptools-67.6.0.tar.gz", hash = "sha256:2ee892cd5f29f3373097f5a814697e397cf3ce313616df0af11231e2ad118077"},
+]
+
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
+testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
+testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
+
[[package]]
name = "six"
-version = "1.15.0"
+version = "1.16.0"
description = "Python 2 and 3 compatibility utilities"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
+files = [
+ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
+ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
+]
+
+[[package]]
+name = "snowballstemmer"
+version = "2.2.0"
+description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
+category = "dev"
+optional = false
+python-versions = "*"
+files = [
+ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
+ {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
+]
+
+[[package]]
+name = "sphinx"
+version = "3.5.4"
+description = "Python documentation generator"
+category = "dev"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "Sphinx-3.5.4-py3-none-any.whl", hash = "sha256:2320d4e994a191f4b4be27da514e46b3d6b420f2ff895d064f52415d342461e8"},
+ {file = "Sphinx-3.5.4.tar.gz", hash = "sha256:19010b7b9fa0dc7756a6e105b2aacd3a80f798af3c25c273be64d7beeb482cb1"},
+]
+
+[package.dependencies]
+alabaster = ">=0.7,<0.8"
+babel = ">=1.3"
+colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""}
+docutils = ">=0.12,<0.17"
+imagesize = "*"
+Jinja2 = ">=2.3"
+packaging = "*"
+Pygments = ">=2.0"
+requests = ">=2.5.0"
+setuptools = "*"
+snowballstemmer = ">=1.1"
+sphinxcontrib-applehelp = "*"
+sphinxcontrib-devhelp = "*"
+sphinxcontrib-htmlhelp = "*"
+sphinxcontrib-jsmath = "*"
+sphinxcontrib-qthelp = "*"
+sphinxcontrib-serializinghtml = "*"
+
+[package.extras]
+docs = ["sphinxcontrib-websupport"]
+lint = ["docutils-stubs", "flake8 (>=3.5.0)", "isort", "mypy (>=0.800)"]
+test = ["cython", "html5lib", "pytest", "pytest-cov", "typed-ast"]
+
+[[package]]
+name = "sphinx-rtd-theme"
+version = "0.5.2"
+description = "Read the Docs theme for Sphinx"
+category = "dev"
+optional = false
+python-versions = "*"
+files = [
+ {file = "sphinx_rtd_theme-0.5.2-py2.py3-none-any.whl", hash = "sha256:4a05bdbe8b1446d77a01e20a23ebc6777c74f43237035e76be89699308987d6f"},
+ {file = "sphinx_rtd_theme-0.5.2.tar.gz", hash = "sha256:32bd3b5d13dc8186d7a42fc816a23d32e83a4827d7d9882948e7b837c232da5a"},
+]
+
+[package.dependencies]
+docutils = "<0.17"
+sphinx = "*"
+
+[package.extras]
+dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client"]
+
+[[package]]
+name = "sphinxcontrib-applehelp"
+version = "1.0.4"
+description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
+category = "dev"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"},
+ {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-devhelp"
+version = "1.0.2"
+description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document."
+category = "dev"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"},
+ {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-htmlhelp"
+version = "2.0.1"
+description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
+category = "dev"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"},
+ {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["html5lib", "pytest"]
+
+[[package]]
+name = "sphinxcontrib-jsmath"
+version = "1.0.1"
+description = "A sphinx extension which renders display math in HTML via JavaScript"
+category = "dev"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
+ {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
+]
+
+[package.extras]
+test = ["flake8", "mypy", "pytest"]
+
+[[package]]
+name = "sphinxcontrib-napoleon"
+version = "0.7"
+description = "Sphinx \"napoleon\" extension."
+category = "dev"
+optional = false
+python-versions = "*"
+files = [
+ {file = "sphinxcontrib-napoleon-0.7.tar.gz", hash = "sha256:407382beed396e9f2d7f3043fad6afda95719204a1e1a231ac865f40abcbfcf8"},
+ {file = "sphinxcontrib_napoleon-0.7-py2.py3-none-any.whl", hash = "sha256:711e41a3974bdf110a484aec4c1a556799eb0b3f3b897521a018ad7e2db13fef"},
+]
+
+[package.dependencies]
+pockets = ">=0.3"
+six = ">=1.5.2"
+
+[[package]]
+name = "sphinxcontrib-qthelp"
+version = "1.0.3"
+description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document."
+category = "dev"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"},
+ {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
+
+[[package]]
+name = "sphinxcontrib-serializinghtml"
+version = "1.1.5"
+description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)."
+category = "dev"
+optional = false
+python-versions = ">=3.5"
+files = [
+ {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"},
+ {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"},
+]
+
+[package.extras]
+lint = ["docutils-stubs", "flake8", "mypy"]
+test = ["pytest"]
[[package]]
name = "tabulate"
-version = "0.8.9"
+version = "0.8.10"
description = "Pretty-print tabular data"
category = "main"
optional = false
-python-versions = "*"
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+files = [
+ {file = "tabulate-0.8.10-py3-none-any.whl", hash = "sha256:0ba055423dbaa164b9e456abe7920c5e8ed33fcc16f6d1b2f2d152c8e1e8b4fc"},
+ {file = "tabulate-0.8.10.tar.gz", hash = "sha256:6c57f3f3dd7ac2782770155f3adb2db0b1a269637e42f27599925e64b114f519"},
+]
[package.extras]
widechars = ["wcwidth"]
[[package]]
name = "tensorboard"
-version = "2.5.0"
+version = "2.11.2"
description = "TensorBoard lets you watch Tensors Flow"
-category = "dev"
+category = "main"
optional = false
-python-versions = ">= 2.7, != 3.0.*, != 3.1.*"
+python-versions = ">=3.7"
+files = [
+ {file = "tensorboard-2.11.2-py3-none-any.whl", hash = "sha256:cbaa2210c375f3af1509f8571360a19ccc3ded1d9641533414874b5deca47e89"},
+]
[package.dependencies]
absl-py = ">=0.4"
-google-auth = ">=1.6.3,<2"
+google-auth = ">=1.6.3,<3"
google-auth-oauthlib = ">=0.4.1,<0.5"
grpcio = ">=1.24.3"
markdown = ">=2.6.8"
numpy = ">=1.12.0"
-protobuf = ">=3.6.0"
+protobuf = ">=3.9.2,<4"
requests = ">=2.21.0,<3"
+setuptools = ">=41.0.0"
tensorboard-data-server = ">=0.6.0,<0.7.0"
tensorboard-plugin-wit = ">=1.6.0"
-werkzeug = ">=0.11.15"
+werkzeug = ">=1.0.1"
+wheel = ">=0.26"
[[package]]
name = "tensorboard-data-server"
version = "0.6.1"
description = "Fast data loading for TensorBoard"
-category = "dev"
+category = "main"
optional = false
python-versions = ">=3.6"
+files = [
+ {file = "tensorboard_data_server-0.6.1-py3-none-any.whl", hash = "sha256:809fe9887682d35c1f7d1f54f0f40f98bb1f771b14265b453ca051e2ce58fca7"},
+ {file = "tensorboard_data_server-0.6.1-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:fa8cef9be4fcae2f2363c88176638baf2da19c5ec90addb49b1cde05c95c88ee"},
+ {file = "tensorboard_data_server-0.6.1-py3-none-manylinux2010_x86_64.whl", hash = "sha256:d8237580755e58eff68d1f3abefb5b1e39ae5c8b127cc40920f9c4fb33f4b98a"},
+]
[[package]]
name = "tensorboard-plugin-wit"
-version = "1.8.0"
+version = "1.8.1"
description = "What-If Tool TensorBoard plugin."
-category = "dev"
+category = "main"
optional = false
python-versions = "*"
+files = [
+ {file = "tensorboard_plugin_wit-1.8.1-py3-none-any.whl", hash = "sha256:ff26bdd583d155aa951ee3b152b3d0cffae8005dc697f72b44a8e8c2a77a8cbe"},
+]
[[package]]
name = "tensorflow"
-version = "2.5.0"
+version = "2.11.0"
description = "TensorFlow is an open source machine learning framework for everyone."
-category = "dev"
+category = "main"
optional = false
-python-versions = "*"
+python-versions = ">=3.7"
+files = [
+ {file = "tensorflow-2.11.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:6c049fec6c2040685d6f43a63e17ccc5d6b0abc16b70cc6f5e7d691262b5d2d0"},
+ {file = "tensorflow-2.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcc8380820cea8f68f6c90b8aee5432e8537e5bb9ec79ac61a98e6a9a02c7d40"},
+ {file = "tensorflow-2.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d973458241c8771bf95d4ba68ad5d67b094f72dd181c2d562ffab538c1b0dad7"},
+ {file = "tensorflow-2.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:d470b772ee3c291a8c7be2331e7c379e0c338223c0bf532f5906d4556f17580d"},
+ {file = "tensorflow-2.11.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:d29c1179149fa469ad68234c52c83081d037ead243f90e826074e2563a0f938a"},
+ {file = "tensorflow-2.11.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cdba2fce00d6c924470d4fb65d5e95a4b6571a863860608c0c13f0393f4ca0d"},
+ {file = "tensorflow-2.11.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2ab20f93d2b52a44b414ec6dcf82aa12110e90e0920039a27108de28ae2728"},
+ {file = "tensorflow-2.11.0-cp37-cp37m-win_amd64.whl", hash = "sha256:445510f092f7827e1f60f59b8bfb58e664aaf05d07daaa21c5735a7f76ca2b25"},
+ {file = "tensorflow-2.11.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:056d29f2212342536ce3856aa47910a2515eb97ec0a6cc29ed47fc4be1369ec8"},
+ {file = "tensorflow-2.11.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17b29d6d360fad545ab1127db52592efd3f19ac55c1a45e5014da328ae867ab4"},
+ {file = "tensorflow-2.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:335ab5cccd7a1c46e3d89d9d46913f0715e8032df8d7438f9743b3fb97b39f69"},
+ {file = "tensorflow-2.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:d48da37c8ae711eb38047a56a052ca8bb4ee018a91a479e42b7a8d117628c32e"},
+ {file = "tensorflow-2.11.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:d9cf25bca641f2e5c77caa3bfd8dd6b892a7aec0695c54d2a7c9f52a54a8d487"},
+ {file = "tensorflow-2.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d28f9691ebc48c0075e271023b3f147ae2bc29a3d3a7f42d45019c6b4a700d2"},
+ {file = "tensorflow-2.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:276a44210d956701899dc78ad0aa116a0071f22fb0bcc1ea6bb59f7646b08d11"},
+ {file = "tensorflow-2.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:cc3444fe1d58c65a195a69656bf56015bf19dc2916da607d784b0a1e215ec008"},
+]
[package.dependencies]
-absl-py = ">=0.10,<1.0"
-astunparse = ">=1.6.3,<1.7.0"
-flatbuffers = ">=1.12.0,<1.13.0"
-gast = "0.4.0"
-google-pasta = ">=0.2,<1.0"
-grpcio = ">=1.34.0,<1.35.0"
-h5py = ">=3.1.0,<3.2.0"
-keras-nightly = ">=2.5.0.dev,<2.6.0"
-keras-preprocessing = ">=1.1.2,<1.2.0"
-numpy = ">=1.19.2,<1.20.0"
-opt-einsum = ">=3.3.0,<3.4.0"
-protobuf = ">=3.9.2"
-six = ">=1.15.0,<1.16.0"
-tensorboard = ">=2.5,<3.0"
-tensorflow-estimator = ">=2.5.0rc0,<2.6.0"
-termcolor = ">=1.1.0,<1.2.0"
-typing-extensions = ">=3.7.4,<3.8.0"
-wrapt = ">=1.12.1,<1.13.0"
+absl-py = ">=1.0.0"
+astunparse = ">=1.6.0"
+flatbuffers = ">=2.0"
+gast = ">=0.2.1,<=0.4.0"
+google-pasta = ">=0.1.1"
+grpcio = ">=1.24.3,<2.0"
+h5py = ">=2.9.0"
+keras = ">=2.11.0,<2.12"
+libclang = ">=13.0.0"
+numpy = ">=1.20"
+opt-einsum = ">=2.3.2"
+packaging = "*"
+protobuf = ">=3.9.2,<3.20"
+setuptools = "*"
+six = ">=1.12.0"
+tensorboard = ">=2.11,<2.12"
+tensorflow-estimator = ">=2.11.0,<2.12"
+tensorflow-io-gcs-filesystem = {version = ">=0.23.1", markers = "platform_machine != \"arm64\" or platform_system != \"Darwin\""}
+termcolor = ">=1.1.0"
+typing-extensions = ">=3.6.6"
+wrapt = ">=1.11.0"
[[package]]
name = "tensorflow-estimator"
-version = "2.5.0"
+version = "2.11.0"
description = "TensorFlow Estimator."
-category = "dev"
+category = "main"
optional = false
-python-versions = "*"
+python-versions = ">=3.7"
+files = [
+ {file = "tensorflow_estimator-2.11.0-py2.py3-none-any.whl", hash = "sha256:ea3b64acfff3d9a244f06178c9bdedcbdd3f125b67d0888dba8229498d06468b"},
+]
+
+[[package]]
+name = "tensorflow-io-gcs-filesystem"
+version = "0.31.0"
+description = "TensorFlow IO"
+category = "main"
+optional = false
+python-versions = ">=3.7, <3.12"
+files = [
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:a71421f8d75a093b6aac65b4c8c8d2f768c3ca6215307cf8c16192e62d992bcf"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:359134ecbd3bf938bb0cf65be4526106c30da461b2e2ce05446a229ed35f6832"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b658b33567552f155af2ed848130f787bfda29381fa78cd905d5ee8254364f3c"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp310-cp310-win_amd64.whl", hash = "sha256:961353b38c76471fa296bb7d883322c66b91415e7d47087236a6706db3ab2758"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:8909c4344b0e96aa356230ab460ffafe5900c33c1aaced65fafae71d177a1966"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp311-cp311-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e417faf8755aafe52d8f8c6b5ae5bae6e4fae8326ee3acd5e9181b83bbfbae87"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37c40e3c4ee1f8dda3b545deea6b8839192c82037d8021db9f589908034ad975"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp311-cp311-win_amd64.whl", hash = "sha256:4bb37d23f21c434687b11059cb7ffd094d52a7813368915ba1b7057e3c16e414"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:a7e8d4bd0a25de7637e562997c011294d7ea595a76f315427a5dd522d56e9d49"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fbcfb4aa2eaa9a3038d2487e570ff93feb1dbe51c3a4663d7d9ab9f9a9f9a9d8"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e3933059b1c53e062075de2e355ec136b655da5883c3c26736c45dfeb1901945"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:f0adfbcd264262797d429311843733da2d5c1ffb119fbfa6339269b6c0414113"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:20e3ee5df01f2bd81d37fc715816c329b7533ccca967c47946eb458a5b7a7280"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd628609b77aee0e385eadf1628222486f19b8f1d81b5f0a344f2470204df116"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp38-cp38-win_amd64.whl", hash = "sha256:b4ebb30ad7ce5f3769e3d959ea99bd95d80a44099bcf94da6042f9755ac6e850"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:68b89ef9f63f297de1cd9d545bc45dddc7d8fe12bcda4266279b244e8cf3b7c0"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e6d8cc7b14ade870168b9704ee44f9c55b468b9a00ed40e12d20fffd321193b5"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97ebb9a8001a38f615aa1f90d2e998b7bd6eddae7aafc92897833610b039401b"},
+ {file = "tensorflow_io_gcs_filesystem-0.31.0-cp39-cp39-win_amd64.whl", hash = "sha256:cb7459c15608fe42973a78e4d3ad7ac79cfc7adae1ccb1b1846db3165fbc081a"},
+]
+
+[package.extras]
+tensorflow = ["tensorflow (>=2.11.0,<2.12.0)"]
+tensorflow-aarch64 = ["tensorflow-aarch64 (>=2.11.0,<2.12.0)"]
+tensorflow-cpu = ["tensorflow-cpu (>=2.11.0,<2.12.0)"]
+tensorflow-gpu = ["tensorflow-gpu (>=2.11.0,<2.12.0)"]
+tensorflow-rocm = ["tensorflow-rocm (>=2.11.0,<2.12.0)"]
[[package]]
name = "termcolor"
-version = "1.1.0"
-description = "ANSII Color formatting for output in terminal."
-category = "dev"
+version = "2.2.0"
+description = "ANSI color formatting for output in terminal"
+category = "main"
optional = false
-python-versions = "*"
+python-versions = ">=3.7"
+files = [
+ {file = "termcolor-2.2.0-py3-none-any.whl", hash = "sha256:91ddd848e7251200eac969846cbae2dacd7d71c2871e92733289e7e3666f48e7"},
+ {file = "termcolor-2.2.0.tar.gz", hash = "sha256:dfc8ac3f350788f23b2947b3e6cfa5a53b630b612e6cd8965a015a776020b99a"},
+]
+
+[package.extras]
+tests = ["pytest", "pytest-cov"]
[[package]]
name = "threadpoolctl"
-version = "2.1.0"
+version = "3.1.0"
description = "threadpoolctl"
-category = "dev"
+category = "main"
optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.6"
+files = [
+ {file = "threadpoolctl-3.1.0-py3-none-any.whl", hash = "sha256:8b99adda265feb6773280df41eece7b2e6561b772d21ffd52e372f999024907b"},
+ {file = "threadpoolctl-3.1.0.tar.gz", hash = "sha256:a335baacfaa4400ae1f0d8e3a58d6674d2f8828e3716bb2802c44955ad391380"},
+]
[[package]]
-name = "toml"
-version = "0.10.2"
-description = "Python Library for Tom's Obvious, Minimal Language"
+name = "tomli"
+version = "2.0.1"
+description = "A lil' TOML parser"
category = "dev"
optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
+python-versions = ">=3.7"
+files = [
+ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
+ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
+]
[[package]]
name = "tqdm"
-version = "4.61.1"
+version = "4.65.0"
description = "Fast, Extensible Progress Meter"
-category = "dev"
+category = "main"
optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
+python-versions = ">=3.7"
+files = [
+ {file = "tqdm-4.65.0-py3-none-any.whl", hash = "sha256:c4f53a17fe37e132815abceec022631be8ffe1b9381c2e6e30aa70edc99e9671"},
+ {file = "tqdm-4.65.0.tar.gz", hash = "sha256:1871fb68a86b8fb3b59ca4cdd3dcccbc7e6d613eeed31f4c332531977b89beb5"},
+]
+
+[package.dependencies]
+colorama = {version = "*", markers = "platform_system == \"Windows\""}
[package.extras]
dev = ["py-make (>=0.1.0)", "twine", "wheel"]
notebook = ["ipywidgets (>=6)"]
+slack = ["slack-sdk"]
telegram = ["requests"]
[[package]]
-name = "typed-ast"
-version = "1.4.1"
-description = "a fork of Python 2 and 3 ast modules with type comment support"
-category = "dev"
+name = "types-tabulate"
+version = "0.9.0.1"
+description = "Typing stubs for tabulate"
+category = "main"
optional = false
python-versions = "*"
+files = [
+ {file = "types-tabulate-0.9.0.1.tar.gz", hash = "sha256:e486292c279f19247865bdabe802419740a0e74b53444e7f7a8009e08129da5d"},
+ {file = "types_tabulate-0.9.0.1-py3-none-any.whl", hash = "sha256:be2ea0de05f615ccfcbadf6206aa720e265955eb1de23e343aec9d8bf3fa9aaa"},
+]
[[package]]
name = "typing-extensions"
-version = "3.7.4.3"
-description = "Backported and Experimental Type Hints for Python 3.5+"
-category = "dev"
+version = "4.5.0"
+description = "Backported and Experimental Type Hints for Python 3.7+"
+category = "main"
optional = false
-python-versions = "*"
+python-versions = ">=3.7"
+files = [
+ {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"},
+ {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"},
+]
[[package]]
name = "urllib3"
-version = "1.26.5"
+version = "1.26.15"
description = "HTTP library with thread-safe connection pooling, file post, and more."
-category = "dev"
+category = "main"
optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
+files = [
+ {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"},
+ {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"},
+]
[package.extras]
-brotli = ["brotlipy (>=0.6.0)"]
-secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
-socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"]
+brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"]
+secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"]
+socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
[[package]]
name = "werkzeug"
-version = "2.0.1"
+version = "2.2.3"
description = "The comprehensive WSGI web application library."
-category = "dev"
+category = "main"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
+files = [
+ {file = "Werkzeug-2.2.3-py3-none-any.whl", hash = "sha256:56433961bc1f12533306c624f3be5e744389ac61d722175d543e1751285da612"},
+ {file = "Werkzeug-2.2.3.tar.gz", hash = "sha256:2e1ccc9417d4da358b9de6f174e3ac094391ea1d4fbef2d667865d819dfd0afe"},
+]
+
+[package.dependencies]
+MarkupSafe = ">=2.1.1"
[package.extras]
watchdog = ["watchdog"]
+[[package]]
+name = "wheel"
+version = "0.40.0"
+description = "A built-package format for Python"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "wheel-0.40.0-py3-none-any.whl", hash = "sha256:d236b20e7cb522daf2390fa84c55eea81c5c30190f90f29ae2ca1ad8355bf247"},
+ {file = "wheel-0.40.0.tar.gz", hash = "sha256:cd1196f3faee2b31968d626e1731c94f99cbdb67cf5a46e4f5656cbee7738873"},
+]
+
+[package.extras]
+test = ["pytest (>=6.0.0)"]
+
[[package]]
name = "wrapt"
-version = "1.12.1"
+version = "1.15.0"
description = "Module for decorators, wrappers and monkey patching."
-category = "dev"
+category = "main"
optional = false
-python-versions = "*"
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
+files = [
+ {file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"},
+ {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"},
+ {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"},
+ {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46"},
+ {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c"},
+ {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09"},
+ {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079"},
+ {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e"},
+ {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a"},
+ {file = "wrapt-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923"},
+ {file = "wrapt-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee"},
+ {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727"},
+ {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7"},
+ {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0"},
+ {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec"},
+ {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90"},
+ {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975"},
+ {file = "wrapt-1.15.0-cp310-cp310-win32.whl", hash = "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1"},
+ {file = "wrapt-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e"},
+ {file = "wrapt-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7"},
+ {file = "wrapt-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72"},
+ {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb"},
+ {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e"},
+ {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c"},
+ {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3"},
+ {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92"},
+ {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98"},
+ {file = "wrapt-1.15.0-cp311-cp311-win32.whl", hash = "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416"},
+ {file = "wrapt-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705"},
+ {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29"},
+ {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd"},
+ {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb"},
+ {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248"},
+ {file = "wrapt-1.15.0-cp35-cp35m-win32.whl", hash = "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559"},
+ {file = "wrapt-1.15.0-cp35-cp35m-win_amd64.whl", hash = "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639"},
+ {file = "wrapt-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba"},
+ {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752"},
+ {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364"},
+ {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475"},
+ {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8"},
+ {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418"},
+ {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2"},
+ {file = "wrapt-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1"},
+ {file = "wrapt-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420"},
+ {file = "wrapt-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317"},
+ {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e"},
+ {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e"},
+ {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0"},
+ {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019"},
+ {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034"},
+ {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653"},
+ {file = "wrapt-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0"},
+ {file = "wrapt-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e"},
+ {file = "wrapt-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145"},
+ {file = "wrapt-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f"},
+ {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd"},
+ {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b"},
+ {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f"},
+ {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6"},
+ {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094"},
+ {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7"},
+ {file = "wrapt-1.15.0-cp38-cp38-win32.whl", hash = "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b"},
+ {file = "wrapt-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1"},
+ {file = "wrapt-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86"},
+ {file = "wrapt-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c"},
+ {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d"},
+ {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc"},
+ {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29"},
+ {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a"},
+ {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8"},
+ {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9"},
+ {file = "wrapt-1.15.0-cp39-cp39-win32.whl", hash = "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff"},
+ {file = "wrapt-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6"},
+ {file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"},
+ {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"},
+]
+
+[[package]]
+name = "zipp"
+version = "3.15.0"
+description = "Backport of pathlib-compatible object wrapper for zip files"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"},
+ {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"},
+]
-[metadata]
-lock-version = "1.1"
-python-versions = "^3.8"
-content-hash = "420af24babeef05b5fd49c1fc0a62467323827140b173d31f4db17a84708f2ef"
+[package.extras]
+docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
+testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
-[metadata.files]
-absl-py = [
- {file = "absl-py-0.13.0.tar.gz", hash = "sha256:6953272383486044699fd0e9f00aad167a27e08ce19aae66c6c4b10e7e767793"},
- {file = "absl_py-0.13.0-py3-none-any.whl", hash = "sha256:62bd4e248ddb19d81aec8f9446b407ff37c8175c2ba88266a7afa9b4ce4a333b"},
-]
-antlr4-python3-runtime = [
- {file = "antlr4-python3-runtime-4.8.tar.gz", hash = "sha256:15793f5d0512a372b4e7d2284058ad32ce7dd27126b105fb0b2245130445db33"},
-]
-appdirs = [
- {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"},
- {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"},
-]
-argparse = [
- {file = "argparse-1.4.0-py2.py3-none-any.whl", hash = "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314"},
- {file = "argparse-1.4.0.tar.gz", hash = "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4"},
-]
-astunparse = [
- {file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"},
- {file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"},
-]
-attrs = [
- {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"},
- {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"},
-]
-black = [
- {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"},
-]
-cachetools = [
- {file = "cachetools-4.2.2-py3-none-any.whl", hash = "sha256:2cc0b89715337ab6dbba85b5b50effe2b0c74e035d83ee8ed637cf52f12ae001"},
- {file = "cachetools-4.2.2.tar.gz", hash = "sha256:61b5ed1e22a0924aed1d23b478f37e8d52549ff8a961de2909c69bf950020cff"},
-]
-certifi = [
- {file = "certifi-2021.5.30-py2.py3-none-any.whl", hash = "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"},
- {file = "certifi-2021.5.30.tar.gz", hash = "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"},
-]
-chardet = [
- {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"},
- {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"},
-]
-click = [
- {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"},
- {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"},
-]
-cycler = [
- {file = "cycler-0.10.0-py2.py3-none-any.whl", hash = "sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d"},
- {file = "cycler-0.10.0.tar.gz", hash = "sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8"},
-]
-dafd = []
-decorator = [
- {file = "decorator-4.4.2-py2.py3-none-any.whl", hash = "sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760"},
- {file = "decorator-4.4.2.tar.gz", hash = "sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7"},
-]
-flake8 = [
- {file = "flake8-3.8.4-py2.py3-none-any.whl", hash = "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839"},
- {file = "flake8-3.8.4.tar.gz", hash = "sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b"},
-]
-flatbuffers = [
- {file = "flatbuffers-1.12-py2.py3-none-any.whl", hash = "sha256:9e9ef47fa92625c4721036e7c4124182668dc6021d9e7c73704edd395648deb9"},
- {file = "flatbuffers-1.12.tar.gz", hash = "sha256:63bb9a722d5e373701913e226135b28a6f6ac200d5cc7b4d919fa38d73b44610"},
-]
-gast = [
- {file = "gast-0.4.0-py3-none-any.whl", hash = "sha256:b7adcdd5adbebf1adf17378da5ba3f543684dbec47b1cda1f3997e573cd542c4"},
- {file = "gast-0.4.0.tar.gz", hash = "sha256:40feb7b8b8434785585ab224d1568b857edb18297e5a3047f1ba012bc83b42c1"},
-]
-google-auth = [
- {file = "google-auth-1.31.0.tar.gz", hash = "sha256:154f7889c5d679a6f626f36adb12afbd4dbb0a9a04ec575d989d6ba79c4fd65e"},
- {file = "google_auth-1.31.0-py2.py3-none-any.whl", hash = "sha256:6d47c79b5d09fbc7e8355fd9594cc4cf65fdde5d401c63951eaac4baa1ba2ae1"},
-]
-google-auth-oauthlib = [
- {file = "google-auth-oauthlib-0.4.4.tar.gz", hash = "sha256:09832c6e75032f93818edf1affe4746121d640c625a5bef9b5c96af676e98eee"},
- {file = "google_auth_oauthlib-0.4.4-py2.py3-none-any.whl", hash = "sha256:0e92aacacfb94978de3b7972cf4b0f204c3cd206f74ddd0dc0b31e91164e6317"},
-]
-google-pasta = [
- {file = "google-pasta-0.2.0.tar.gz", hash = "sha256:c9f2c8dfc8f96d0d5808299920721be30c9eec37f2389f28904f454565c8a16e"},
- {file = "google_pasta-0.2.0-py2-none-any.whl", hash = "sha256:4612951da876b1a10fe3960d7226f0c7682cf901e16ac06e473b267a5afa8954"},
- {file = "google_pasta-0.2.0-py3-none-any.whl", hash = "sha256:b32482794a366b5366a32c92a9a9201b107821889935a02b3e51f6b432ea84ed"},
-]
-grpcio = [
- {file = "grpcio-1.34.1-cp27-cp27m-macosx_10_10_x86_64.whl", hash = "sha256:5c4402fd8ce28e2847112105591139dc121c8980770f683eb781be1568a64097"},
- {file = "grpcio-1.34.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c6f756c11144c7ecb51b87f0d60a4b72e05635b9f24ddfa004286ab0c8527fa0"},
- {file = "grpcio-1.34.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:ec6d1b3daed886a73e40b4dc553474ef415acc111e913d7324cc2c6b0ba9efe0"},
- {file = "grpcio-1.34.1-cp27-cp27m-win32.whl", hash = "sha256:d757bc8bb12f07014dde55a04b5261c94828b605cf0726d02d491c3dc71aa6bb"},
- {file = "grpcio-1.34.1-cp27-cp27m-win_amd64.whl", hash = "sha256:f74cb93cd090b07528cf586a18628370e5780c08e0239f4af796f60a5e773568"},
- {file = "grpcio-1.34.1-cp27-cp27mu-linux_armv7l.whl", hash = "sha256:c4355fa382dfc71c130dc3eccd8ae606a13e1729be2a77b6c44cd5a130d0c616"},
- {file = "grpcio-1.34.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f1a8048428a7a1e5b12322b3ee44ee0bb8e1bea1d67f08fa1813c455f3ef638c"},
- {file = "grpcio-1.34.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:0bd906496b9dd3751b9e5cacc7ceb25a57c16ce2aa67315b85ee86a4ba7246f1"},
- {file = "grpcio-1.34.1-cp35-cp35m-linux_armv7l.whl", hash = "sha256:5e488a40ebeb883117aa0dba2cea410ef2ab545a2403b2ac9101e62d42808c71"},
- {file = "grpcio-1.34.1-cp35-cp35m-macosx_10_10_intel.whl", hash = "sha256:98c06f0f7feeca736cc98f3f46b9b74c5f5fdc5febfc7d72728d1895c57be87f"},
- {file = "grpcio-1.34.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:90a4799c15b8b5aa587f65650a0cea28ea88bcd2c5fdf4f1adb2b8b7b4e77a5e"},
- {file = "grpcio-1.34.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:121af89d0b9ba1d47c738242783675009dd4e9067359481e4b743eb9e5886682"},
- {file = "grpcio-1.34.1-cp35-cp35m-manylinux2014_i686.whl", hash = "sha256:1be193803c706f78d0df12c817eaf2415fb4d39472fa00d860700e6c7a99f8f7"},
- {file = "grpcio-1.34.1-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:9e465a1d594a9a5f4252c4abbb93909c42768bee5fbfcd18098d60bf06a35573"},
- {file = "grpcio-1.34.1-cp35-cp35m-win32.whl", hash = "sha256:8b16d14160b7fd8bc43600be70e0da677d17dd8aafb5a258bbda996fe410320e"},
- {file = "grpcio-1.34.1-cp35-cp35m-win_amd64.whl", hash = "sha256:8a543209ab606dd55c58dc218be8e8619214607f03717dded78c7d27f1d05ba5"},
- {file = "grpcio-1.34.1-cp36-cp36m-linux_armv7l.whl", hash = "sha256:f74f270550df347a18f839331f84838b938c8923a9e13a6fa7cc69c79087a686"},
- {file = "grpcio-1.34.1-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:163a2cf7f4df3ff0a04f49e634526e3d88f02393a7ebf8f34a2134c88b06322e"},
- {file = "grpcio-1.34.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:11735ac4efd53691afeb36d006e20db9b7d4b6f3356c751f32d5747aee38fa4c"},
- {file = "grpcio-1.34.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:79bda20756e2fc7236b94468ffcce4b516953f946a80b7ea883f89d9e9b25a41"},
- {file = "grpcio-1.34.1-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:1857f88b351e2382aa57ed892960361a8b71acca4aa1b90998007b4177f15114"},
- {file = "grpcio-1.34.1-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:6f81fbf9f830e20aee93480305877f73f15bfa58fa87433eb331696be47ae7ba"},
- {file = "grpcio-1.34.1-cp36-cp36m-win32.whl", hash = "sha256:ff8aef869c2e9de65c3a693406f7d1200d87e6d541d096eae69f98e7f301fa60"},
- {file = "grpcio-1.34.1-cp36-cp36m-win_amd64.whl", hash = "sha256:ece7459c182e00ca90b2e5823940a552651b5eb3acdeee9350377ddb44d9c412"},
- {file = "grpcio-1.34.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:7924ef3a898f6ff985540ee5d8c7554f0c925dc7668c3d63461600ea50b39658"},
- {file = "grpcio-1.34.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:b5e96ca83d5c34c9b60d8951e52492b0d9d072c3fe38a1c19765932e121036ce"},
- {file = "grpcio-1.34.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:fe9360347a3f4f2ec6923d8afb03a9194f3f14e054cb09e75e8346af9c0aa9f6"},
- {file = "grpcio-1.34.1-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:cadc09c9bd24ecf3ba7ae55b5a741f7de694a8843e97e82a7c3fa2e6e81e0f9a"},
- {file = "grpcio-1.34.1-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:5971e6dfcfa0ebeb0df2d15383e1b53fa36208198c8aff9a4eed5ece2a6d4571"},
- {file = "grpcio-1.34.1-cp37-cp37m-win32.whl", hash = "sha256:a181092b534e996e36d0c0216d81280d4942322170c823b2fb84ec4597dc0bd5"},
- {file = "grpcio-1.34.1-cp37-cp37m-win_amd64.whl", hash = "sha256:2b97cdd4582445ad7bd441f5f3c57d838bcdc518a05713dab0c7f4b945afb39e"},
- {file = "grpcio-1.34.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:ff760c5ce73c177851864e8caaf75467eaf06c1b6857b21e1789658375e720fb"},
- {file = "grpcio-1.34.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:fd58ea88dd5439e03c6587f0b672db1627ec8ed47be312c74632650dfed33c2e"},
- {file = "grpcio-1.34.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:f6fee4445cffb45593b4c1d9bb0bc7922e77ec846a1237e2e744b1223d69c863"},
- {file = "grpcio-1.34.1-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:cd4da71e105088b1a7e629d1b033f16d87dec08524d0e4f5d77982af6fe1b6c2"},
- {file = "grpcio-1.34.1-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:9d43849d8925ec24bf121bccd941a13d4e8c2cffdfa769a04a6d4ed38c6b88a2"},
- {file = "grpcio-1.34.1-cp38-cp38-win32.whl", hash = "sha256:696f0de4d47f738063432bbbcecd07f78256864f0839e41369458421f539f00a"},
- {file = "grpcio-1.34.1-cp38-cp38-win_amd64.whl", hash = "sha256:8fff784ec5d12252a7cc0ab6f1a3206861b94e45ee0ebeba2439bd10a6db2f1a"},
- {file = "grpcio-1.34.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:ed8ac4f76cbbef5dc54594cb7bf6fbb985f5be66abcb1f9da8142500e4d76492"},
- {file = "grpcio-1.34.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:8dad4184e4669672e126de26776eba8e3db4914660b4a0a6c7edbdbcf3e2f05f"},
- {file = "grpcio-1.34.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:011e9b5e47cb9d2a808e8c2dd5ae86df085d5879d9e8095a24631a32c577f231"},
- {file = "grpcio-1.34.1-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:49ffc5bb78b201db24d8d1644193beb50a896c3cb35b259b4fb9c44dba18585f"},
- {file = "grpcio-1.34.1-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:cfe0e015cb8db5a27a92621fdd9dc8e69b2f7130db326601802e6ff36626deff"},
- {file = "grpcio-1.34.1-cp39-cp39-win32.whl", hash = "sha256:809732f300fa8093b40f843c36f6f78423ffb40493098185bc4a96bd67126db5"},
- {file = "grpcio-1.34.1-cp39-cp39-win_amd64.whl", hash = "sha256:96dc85c059f15390beb7ac6bf075d1e4cf72e8f5c9b6c37ea179b7cc579816fd"},
- {file = "grpcio-1.34.1.tar.gz", hash = "sha256:1c746a3cd8a830d8d916a9d0476a786aaa98c5cc2a096344af2be955e439f8ac"},
-]
-h5py = [
- {file = "h5py-3.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:1cd367f89a5441236bdbb795e9fb9a9e3424929c00b4a54254ca760437f83d69"},
- {file = "h5py-3.1.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fea05349f63625a8fb808e57e42bb4c76930cf5d50ac58b678c52f913a48a89b"},
- {file = "h5py-3.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:2e37352ddfcf9d77a2a47f7c8f7e125c6d20cc06c2995edeb7be222d4e152636"},
- {file = "h5py-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e33f61d3eb862614c0f273a1f993a64dc2f093e1a3094932c50ada9d2db2170f"},
- {file = "h5py-3.1.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:236ac8d943be30b617ab615c3d4a4bf4a438add2be87e54af3687ab721a18fac"},
- {file = "h5py-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:02c391fdb980762a1cc03a4bcaecd03dc463994a9a63a02264830114a96e111f"},
- {file = "h5py-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f89a3dae38843ffa49d17a31a3509a8129e9b46ece602a0138e1ed79e685c361"},
- {file = "h5py-3.1.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ba71f6229d2013fbb606476ecc29c6223fc16b244d35fcd8566ad9dbaf910857"},
- {file = "h5py-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:dccb89358bc84abcd711363c3e138f9f4eccfdf866f2139a8e72308328765b2c"},
- {file = "h5py-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cb74df83709d6d03d11e60b9480812f58da34f194beafa8c8314dbbeeedfe0a6"},
- {file = "h5py-3.1.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:80c623be10479e81b64fa713b7ed4c0bbe9f02e8e7d2a2e5382336087b615ce4"},
- {file = "h5py-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:1cdfd1c5449ca1329d152f0b66830e93226ebce4f5e07dd8dc16bfc2b1a49d7b"},
- {file = "h5py-3.1.0.tar.gz", hash = "sha256:1e2516f190652beedcb8c7acfa1c6fa92d99b42331cbef5e5c7ec2d65b0fc3c2"},
-]
-idna = [
- {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"},
- {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"},
-]
-install = [
- {file = "install-1.3.4-py3-none-any.whl", hash = "sha256:dfec614e0cc90f00659067a078bc2ec032d9f0758f3df230c073eeaffd0cefa1"},
- {file = "install-1.3.4.tar.gz", hash = "sha256:1455304a2475b6753a9b0c28243ca7d8b7d71aeea1a88e6de94034fc57d765a0"},
-]
-joblib = [
- {file = "joblib-1.0.1-py3-none-any.whl", hash = "sha256:feeb1ec69c4d45129954f1b7034954241eedfd6ba39b5e9e4b6883be3332d5e5"},
- {file = "joblib-1.0.1.tar.gz", hash = "sha256:9c17567692206d2f3fb9ecf5e991084254fe631665c450b443761c4186a613f7"},
-]
-jsonschema = [
- {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"},
- {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"},
-]
-keras = [
- {file = "Keras-2.4.3-py2.py3-none-any.whl", hash = "sha256:05e2faf6885f7899482a7d18fc00ba9655fe2c9296a35ad96949a07a9c27d1bb"},
- {file = "Keras-2.4.3.tar.gz", hash = "sha256:fedd729b52572fb108a98e3d97e1bac10a81d3917d2103cc20ab2a5f03beb973"},
-]
-keras-nightly = [
- {file = "keras_nightly-2.6.0.dev2021061400-py2.py3-none-any.whl", hash = "sha256:43bddfdb966d3927f817e6cbfeff3a2e17c65f864b368b7df0bf04768110f0f8"},
-]
-keras-preprocessing = [
- {file = "Keras_Preprocessing-1.1.2-py2.py3-none-any.whl", hash = "sha256:7b82029b130ff61cc99b55f3bd27427df4838576838c5b2f65940e4fcec99a7b"},
- {file = "Keras_Preprocessing-1.1.2.tar.gz", hash = "sha256:add82567c50c8bc648c14195bf544a5ce7c1f76761536956c3d2978970179ef3"},
-]
-kiwisolver = [
- {file = "kiwisolver-1.3.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:fd34fbbfbc40628200730bc1febe30631347103fc8d3d4fa012c21ab9c11eca9"},
- {file = "kiwisolver-1.3.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:d3155d828dec1d43283bd24d3d3e0d9c7c350cdfcc0bd06c0ad1209c1bbc36d0"},
- {file = "kiwisolver-1.3.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5a7a7dbff17e66fac9142ae2ecafb719393aaee6a3768c9de2fd425c63b53e21"},
- {file = "kiwisolver-1.3.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:f8d6f8db88049a699817fd9178782867bf22283e3813064302ac59f61d95be05"},
- {file = "kiwisolver-1.3.1-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:5f6ccd3dd0b9739edcf407514016108e2280769c73a85b9e59aa390046dbf08b"},
- {file = "kiwisolver-1.3.1-cp36-cp36m-win32.whl", hash = "sha256:225e2e18f271e0ed8157d7f4518ffbf99b9450fca398d561eb5c4a87d0986dd9"},
- {file = "kiwisolver-1.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:cf8b574c7b9aa060c62116d4181f3a1a4e821b2ec5cbfe3775809474113748d4"},
- {file = "kiwisolver-1.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:232c9e11fd7ac3a470d65cd67e4359eee155ec57e822e5220322d7b2ac84fbf0"},
- {file = "kiwisolver-1.3.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:b38694dcdac990a743aa654037ff1188c7a9801ac3ccc548d3341014bc5ca278"},
- {file = "kiwisolver-1.3.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ca3820eb7f7faf7f0aa88de0e54681bddcb46e485beb844fcecbcd1c8bd01689"},
- {file = "kiwisolver-1.3.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:c8fd0f1ae9d92b42854b2979024d7597685ce4ada367172ed7c09edf2cef9cb8"},
- {file = "kiwisolver-1.3.1-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:1e1bc12fb773a7b2ffdeb8380609f4f8064777877b2225dec3da711b421fda31"},
- {file = "kiwisolver-1.3.1-cp37-cp37m-win32.whl", hash = "sha256:72c99e39d005b793fb7d3d4e660aed6b6281b502e8c1eaf8ee8346023c8e03bc"},
- {file = "kiwisolver-1.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:8be8d84b7d4f2ba4ffff3665bcd0211318aa632395a1a41553250484a871d454"},
- {file = "kiwisolver-1.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:31dfd2ac56edc0ff9ac295193eeaea1c0c923c0355bf948fbd99ed6018010b72"},
- {file = "kiwisolver-1.3.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:563c649cfdef27d081c84e72a03b48ea9408c16657500c312575ae9d9f7bc1c3"},
- {file = "kiwisolver-1.3.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:78751b33595f7f9511952e7e60ce858c6d64db2e062afb325985ddbd34b5c131"},
- {file = "kiwisolver-1.3.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:a357fd4f15ee49b4a98b44ec23a34a95f1e00292a139d6015c11f55774ef10de"},
- {file = "kiwisolver-1.3.1-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:5989db3b3b34b76c09253deeaf7fbc2707616f130e166996606c284395da3f18"},
- {file = "kiwisolver-1.3.1-cp38-cp38-win32.whl", hash = "sha256:c08e95114951dc2090c4a630c2385bef681cacf12636fb0241accdc6b303fd81"},
- {file = "kiwisolver-1.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:44a62e24d9b01ba94ae7a4a6c3fb215dc4af1dde817e7498d901e229aaf50e4e"},
- {file = "kiwisolver-1.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:50af681a36b2a1dee1d3c169ade9fdc59207d3c31e522519181e12f1b3ba7000"},
- {file = "kiwisolver-1.3.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:a53d27d0c2a0ebd07e395e56a1fbdf75ffedc4a05943daf472af163413ce9598"},
- {file = "kiwisolver-1.3.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:834ee27348c4aefc20b479335fd422a2c69db55f7d9ab61721ac8cd83eb78882"},
- {file = "kiwisolver-1.3.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:5c3e6455341008a054cccee8c5d24481bcfe1acdbc9add30aa95798e95c65621"},
- {file = "kiwisolver-1.3.1-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:acef3d59d47dd85ecf909c359d0fd2c81ed33bdff70216d3956b463e12c38a54"},
- {file = "kiwisolver-1.3.1-cp39-cp39-win32.whl", hash = "sha256:c5518d51a0735b1e6cee1fdce66359f8d2b59c3ca85dc2b0813a8aa86818a030"},
- {file = "kiwisolver-1.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:b9edd0110a77fc321ab090aaa1cfcaba1d8499850a12848b81be2222eab648f6"},
- {file = "kiwisolver-1.3.1-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0cd53f403202159b44528498de18f9285b04482bab2a6fc3f5dd8dbb9352e30d"},
- {file = "kiwisolver-1.3.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:33449715e0101e4d34f64990352bce4095c8bf13bed1b390773fc0a7295967b3"},
- {file = "kiwisolver-1.3.1-pp36-pypy36_pp73-win32.whl", hash = "sha256:401a2e9afa8588589775fe34fc22d918ae839aaaf0c0e96441c0fdbce6d8ebe6"},
- {file = "kiwisolver-1.3.1.tar.gz", hash = "sha256:950a199911a8d94683a6b10321f9345d5a3a8433ec58b217ace979e18f16e248"},
-]
-markdown = [
- {file = "Markdown-3.3.4-py3-none-any.whl", hash = "sha256:96c3ba1261de2f7547b46a00ea8463832c921d3f9d6aba3f255a6f71386db20c"},
- {file = "Markdown-3.3.4.tar.gz", hash = "sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49"},
-]
-matplotlib = [
- {file = "matplotlib-3.4.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c541ee5a3287efe066bbe358320853cf4916bc14c00c38f8f3d8d75275a405a9"},
- {file = "matplotlib-3.4.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:3a5c18dbd2c7c366da26a4ad1462fe3e03a577b39e3b503bbcf482b9cdac093c"},
- {file = "matplotlib-3.4.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a9d8cb5329df13e0cdaa14b3b43f47b5e593ec637f13f14db75bb16e46178b05"},
- {file = "matplotlib-3.4.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:7ad19f3fb6145b9eb41c08e7cbb9f8e10b91291396bee21e9ce761bb78df63ec"},
- {file = "matplotlib-3.4.2-cp37-cp37m-win32.whl", hash = "sha256:7a58f3d8fe8fac3be522c79d921c9b86e090a59637cb88e3bc51298d7a2c862a"},
- {file = "matplotlib-3.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6382bc6e2d7e481bcd977eb131c31dee96e0fb4f9177d15ec6fb976d3b9ace1a"},
- {file = "matplotlib-3.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6a6a44f27aabe720ec4fd485061e8a35784c2b9ffa6363ad546316dfc9cea04e"},
- {file = "matplotlib-3.4.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1c1779f7ab7d8bdb7d4c605e6ffaa0614b3e80f1e3c8ccf7b9269a22dbc5986b"},
- {file = "matplotlib-3.4.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5826f56055b9b1c80fef82e326097e34dc4af8c7249226b7dd63095a686177d1"},
- {file = "matplotlib-3.4.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:0bea5ec5c28d49020e5d7923c2725b837e60bc8be99d3164af410eb4b4c827da"},
- {file = "matplotlib-3.4.2-cp38-cp38-win32.whl", hash = "sha256:6475d0209024a77f869163ec3657c47fed35d9b6ed8bccba8aa0f0099fbbdaa8"},
- {file = "matplotlib-3.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:21b31057bbc5e75b08e70a43cefc4c0b2c2f1b1a850f4a0f7af044eb4163086c"},
- {file = "matplotlib-3.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b26535b9de85326e6958cdef720ecd10bcf74a3f4371bf9a7e5b2e659c17e153"},
- {file = "matplotlib-3.4.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:32fa638cc10886885d1ca3d409d4473d6a22f7ceecd11322150961a70fab66dd"},
- {file = "matplotlib-3.4.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:956c8849b134b4a343598305a3ca1bdd3094f01f5efc8afccdebeffe6b315247"},
- {file = "matplotlib-3.4.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:85f191bb03cb1a7b04b5c2cca4792bef94df06ef473bc49e2818105671766fee"},
- {file = "matplotlib-3.4.2-cp39-cp39-win32.whl", hash = "sha256:b1d5a2cedf5de05567c441b3a8c2651fbde56df08b82640e7f06c8cd91e201f6"},
- {file = "matplotlib-3.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:df815378a754a7edd4559f8c51fc7064f779a74013644a7f5ac7a0c31f875866"},
- {file = "matplotlib-3.4.2.tar.gz", hash = "sha256:d8d994cefdff9aaba45166eb3de4f5211adb4accac85cbf97137e98f26ea0219"},
-]
-mccabe = [
- {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
- {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
-]
-mypy = [
- {file = "mypy-0.782-cp35-cp35m-macosx_10_6_x86_64.whl", hash = "sha256:2c6cde8aa3426c1682d35190b59b71f661237d74b053822ea3d748e2c9578a7c"},
- {file = "mypy-0.782-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9c7a9a7ceb2871ba4bac1cf7217a7dd9ccd44c27c2950edbc6dc08530f32ad4e"},
- {file = "mypy-0.782-cp35-cp35m-win_amd64.whl", hash = "sha256:c05b9e4fb1d8a41d41dec8786c94f3b95d3c5f528298d769eb8e73d293abc48d"},
- {file = "mypy-0.782-cp36-cp36m-macosx_10_6_x86_64.whl", hash = "sha256:6731603dfe0ce4352c555c6284c6db0dc935b685e9ce2e4cf220abe1e14386fd"},
- {file = "mypy-0.782-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:f05644db6779387ccdb468cc47a44b4356fc2ffa9287135d05b70a98dc83b89a"},
- {file = "mypy-0.782-cp36-cp36m-win_amd64.whl", hash = "sha256:b7fbfabdbcc78c4f6fc4712544b9b0d6bf171069c6e0e3cb82440dd10ced3406"},
- {file = "mypy-0.782-cp37-cp37m-macosx_10_6_x86_64.whl", hash = "sha256:3fdda71c067d3ddfb21da4b80e2686b71e9e5c72cca65fa216d207a358827f86"},
- {file = "mypy-0.782-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d7df6eddb6054d21ca4d3c6249cae5578cb4602951fd2b6ee2f5510ffb098707"},
- {file = "mypy-0.782-cp37-cp37m-win_amd64.whl", hash = "sha256:a4a2cbcfc4cbf45cd126f531dedda8485671545b43107ded25ce952aac6fb308"},
- {file = "mypy-0.782-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6bb93479caa6619d21d6e7160c552c1193f6952f0668cdda2f851156e85186fc"},
- {file = "mypy-0.782-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:81c7908b94239c4010e16642c9102bfc958ab14e36048fa77d0be3289dda76ea"},
- {file = "mypy-0.782-cp38-cp38-win_amd64.whl", hash = "sha256:5dd13ff1f2a97f94540fd37a49e5d255950ebcdf446fb597463a40d0df3fac8b"},
- {file = "mypy-0.782-py3-none-any.whl", hash = "sha256:e0b61738ab504e656d1fe4ff0c0601387a5489ca122d55390ade31f9ca0e252d"},
- {file = "mypy-0.782.tar.gz", hash = "sha256:eff7d4a85e9eea55afa34888dfeaccde99e7520b51f867ac28a48492c0b1130c"},
-]
-mypy-extensions = [
- {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
- {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
-]
-networkx = [
- {file = "networkx-2.5-py3-none-any.whl", hash = "sha256:8c5812e9f798d37c50570d15c4a69d5710a18d77bafc903ee9c5fba7454c616c"},
- {file = "networkx-2.5.tar.gz", hash = "sha256:7978955423fbc9639c10498878be59caf99b44dc304c2286162fd24b458c1602"},
-]
-numpy = [
- {file = "numpy-1.19.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc6bd4fd593cb261332568485e20a0712883cf631f6f5e8e86a52caa8b2b50ff"},
- {file = "numpy-1.19.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:aeb9ed923be74e659984e321f609b9ba54a48354bfd168d21a2b072ed1e833ea"},
- {file = "numpy-1.19.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8b5e972b43c8fc27d56550b4120fe6257fdc15f9301914380b27f74856299fea"},
- {file = "numpy-1.19.5-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:43d4c81d5ffdff6bae58d66a3cd7f54a7acd9a0e7b18d97abb255defc09e3140"},
- {file = "numpy-1.19.5-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:a4646724fba402aa7504cd48b4b50e783296b5e10a524c7a6da62e4a8ac9698d"},
- {file = "numpy-1.19.5-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:2e55195bc1c6b705bfd8ad6f288b38b11b1af32f3c8289d6c50d47f950c12e76"},
- {file = "numpy-1.19.5-cp36-cp36m-win32.whl", hash = "sha256:39b70c19ec771805081578cc936bbe95336798b7edf4732ed102e7a43ec5c07a"},
- {file = "numpy-1.19.5-cp36-cp36m-win_amd64.whl", hash = "sha256:dbd18bcf4889b720ba13a27ec2f2aac1981bd41203b3a3b27ba7a33f88ae4827"},
- {file = "numpy-1.19.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:603aa0706be710eea8884af807b1b3bc9fb2e49b9f4da439e76000f3b3c6ff0f"},
- {file = "numpy-1.19.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:cae865b1cae1ec2663d8ea56ef6ff185bad091a5e33ebbadd98de2cfa3fa668f"},
- {file = "numpy-1.19.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:36674959eed6957e61f11c912f71e78857a8d0604171dfd9ce9ad5cbf41c511c"},
- {file = "numpy-1.19.5-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:06fab248a088e439402141ea04f0fffb203723148f6ee791e9c75b3e9e82f080"},
- {file = "numpy-1.19.5-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6149a185cece5ee78d1d196938b2a8f9d09f5a5ebfbba66969302a778d5ddd1d"},
- {file = "numpy-1.19.5-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:50a4a0ad0111cc1b71fa32dedd05fa239f7fb5a43a40663269bb5dc7877cfd28"},
- {file = "numpy-1.19.5-cp37-cp37m-win32.whl", hash = "sha256:d051ec1c64b85ecc69531e1137bb9751c6830772ee5c1c426dbcfe98ef5788d7"},
- {file = "numpy-1.19.5-cp37-cp37m-win_amd64.whl", hash = "sha256:a12ff4c8ddfee61f90a1633a4c4afd3f7bcb32b11c52026c92a12e1325922d0d"},
- {file = "numpy-1.19.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cf2402002d3d9f91c8b01e66fbb436a4ed01c6498fffed0e4c7566da1d40ee1e"},
- {file = "numpy-1.19.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1ded4fce9cfaaf24e7a0ab51b7a87be9038ea1ace7f34b841fe3b6894c721d1c"},
- {file = "numpy-1.19.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:012426a41bc9ab63bb158635aecccc7610e3eff5d31d1eb43bc099debc979d94"},
- {file = "numpy-1.19.5-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:759e4095edc3c1b3ac031f34d9459fa781777a93ccc633a472a5468587a190ff"},
- {file = "numpy-1.19.5-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:a9d17f2be3b427fbb2bce61e596cf555d6f8a56c222bd2ca148baeeb5e5c783c"},
- {file = "numpy-1.19.5-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:99abf4f353c3d1a0c7a5f27699482c987cf663b1eac20db59b8c7b061eabd7fc"},
- {file = "numpy-1.19.5-cp38-cp38-win32.whl", hash = "sha256:384ec0463d1c2671170901994aeb6dce126de0a95ccc3976c43b0038a37329c2"},
- {file = "numpy-1.19.5-cp38-cp38-win_amd64.whl", hash = "sha256:811daee36a58dc79cf3d8bdd4a490e4277d0e4b7d103a001a4e73ddb48e7e6aa"},
- {file = "numpy-1.19.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c843b3f50d1ab7361ca4f0b3639bf691569493a56808a0b0c54a051d260b7dbd"},
- {file = "numpy-1.19.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d6631f2e867676b13026e2846180e2c13c1e11289d67da08d71cacb2cd93d4aa"},
- {file = "numpy-1.19.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7fb43004bce0ca31d8f13a6eb5e943fa73371381e53f7074ed21a4cb786c32f8"},
- {file = "numpy-1.19.5-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:2ea52bd92ab9f768cc64a4c3ef8f4b2580a17af0a5436f6126b08efbd1838371"},
- {file = "numpy-1.19.5-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:400580cbd3cff6ffa6293df2278c75aef2d58d8d93d3c5614cd67981dae68ceb"},
- {file = "numpy-1.19.5-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:df609c82f18c5b9f6cb97271f03315ff0dbe481a2a02e56aeb1b1a985ce38e60"},
- {file = "numpy-1.19.5-cp39-cp39-win32.whl", hash = "sha256:ab83f24d5c52d60dbc8cd0528759532736b56db58adaa7b5f1f76ad551416a1e"},
- {file = "numpy-1.19.5-cp39-cp39-win_amd64.whl", hash = "sha256:0eef32ca3132a48e43f6a0f5a82cb508f22ce5a3d6f67a8329c81c8e226d3f6e"},
- {file = "numpy-1.19.5-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:a0d53e51a6cb6f0d9082decb7a4cb6dfb33055308c4c44f53103c073f649af73"},
- {file = "numpy-1.19.5.zip", hash = "sha256:a76f502430dd98d7546e1ea2250a7360c065a5fdea52b2dffe8ae7180909b6f4"},
-]
-oauthlib = [
- {file = "oauthlib-3.1.1-py2.py3-none-any.whl", hash = "sha256:42bf6354c2ed8c6acb54d971fce6f88193d97297e18602a3a886603f9d7730cc"},
- {file = "oauthlib-3.1.1.tar.gz", hash = "sha256:8f0215fcc533dd8dd1bee6f4c412d4f0cd7297307d43ac61666389e3bc3198a3"},
-]
-opt-einsum = [
- {file = "opt_einsum-3.3.0-py3-none-any.whl", hash = "sha256:2455e59e3947d3c275477df7f5205b30635e266fe6dc300e3d9f9646bfcea147"},
- {file = "opt_einsum-3.3.0.tar.gz", hash = "sha256:59f6475f77bbc37dcf7cd748519c0ec60722e91e63ca114e68821c0c54a46549"},
-]
-pandas = [
- {file = "pandas-1.2.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c601c6fdebc729df4438ec1f62275d6136a0dd14d332fc0e8ce3f7d2aadb4dd6"},
- {file = "pandas-1.2.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:8d4c74177c26aadcfb4fd1de6c1c43c2bf822b3e0fc7a9b409eeaf84b3e92aaa"},
- {file = "pandas-1.2.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:b730add5267f873b3383c18cac4df2527ac4f0f0eed1c6cf37fcb437e25cf558"},
- {file = "pandas-1.2.4-cp37-cp37m-win32.whl", hash = "sha256:2cb7e8f4f152f27dc93f30b5c7a98f6c748601ea65da359af734dd0cf3fa733f"},
- {file = "pandas-1.2.4-cp37-cp37m-win_amd64.whl", hash = "sha256:2111c25e69fa9365ba80bbf4f959400054b2771ac5d041ed19415a8b488dc70a"},
- {file = "pandas-1.2.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:167693a80abc8eb28051fbd184c1b7afd13ce2c727a5af47b048f1ea3afefff4"},
- {file = "pandas-1.2.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:612add929bf3ba9d27b436cc8853f5acc337242d6b584203f207e364bb46cb12"},
- {file = "pandas-1.2.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:971e2a414fce20cc5331fe791153513d076814d30a60cd7348466943e6e909e4"},
- {file = "pandas-1.2.4-cp38-cp38-win32.whl", hash = "sha256:68d7baa80c74aaacbed597265ca2308f017859123231542ff8a5266d489e1858"},
- {file = "pandas-1.2.4-cp38-cp38-win_amd64.whl", hash = "sha256:bd659c11a4578af740782288cac141a322057a2e36920016e0fc7b25c5a4b686"},
- {file = "pandas-1.2.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9db70ffa8b280bb4de83f9739d514cd0735825e79eef3a61d312420b9f16b758"},
- {file = "pandas-1.2.4-cp39-cp39-manylinux1_i686.whl", hash = "sha256:298f0553fd3ba8e002c4070a723a59cdb28eda579f3e243bc2ee397773f5398b"},
- {file = "pandas-1.2.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:52d2472acbb8a56819a87aafdb8b5b6d2b3386e15c95bde56b281882529a7ded"},
- {file = "pandas-1.2.4-cp39-cp39-win32.whl", hash = "sha256:d0877407359811f7b853b548a614aacd7dea83b0c0c84620a9a643f180060950"},
- {file = "pandas-1.2.4-cp39-cp39-win_amd64.whl", hash = "sha256:2b063d41803b6a19703b845609c0b700913593de067b552a8b24dd8eeb8c9895"},
- {file = "pandas-1.2.4.tar.gz", hash = "sha256:649ecab692fade3cbfcf967ff936496b0cfba0af00a55dfaacd82bdda5cb2279"},
-]
-parchmint = []
-pathspec = [
- {file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"},
- {file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"},
-]
-pillow = [
- {file = "Pillow-8.2.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:dc38f57d8f20f06dd7c3161c59ca2c86893632623f33a42d592f097b00f720a9"},
- {file = "Pillow-8.2.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a013cbe25d20c2e0c4e85a9daf438f85121a4d0344ddc76e33fd7e3965d9af4b"},
- {file = "Pillow-8.2.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8bb1e155a74e1bfbacd84555ea62fa21c58e0b4e7e6b20e4447b8d07990ac78b"},
- {file = "Pillow-8.2.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c5236606e8570542ed424849f7852a0ff0bce2c4c8d0ba05cc202a5a9c97dee9"},
- {file = "Pillow-8.2.0-cp36-cp36m-win32.whl", hash = "sha256:12e5e7471f9b637762453da74e390e56cc43e486a88289995c1f4c1dc0bfe727"},
- {file = "Pillow-8.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:5afe6b237a0b81bd54b53f835a153770802f164c5570bab5e005aad693dab87f"},
- {file = "Pillow-8.2.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:cb7a09e173903541fa888ba010c345893cd9fc1b5891aaf060f6ca77b6a3722d"},
- {file = "Pillow-8.2.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0d19d70ee7c2ba97631bae1e7d4725cdb2ecf238178096e8c82ee481e189168a"},
- {file = "Pillow-8.2.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:083781abd261bdabf090ad07bb69f8f5599943ddb539d64497ed021b2a67e5a9"},
- {file = "Pillow-8.2.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:c6b39294464b03457f9064e98c124e09008b35a62e3189d3513e5148611c9388"},
- {file = "Pillow-8.2.0-cp37-cp37m-win32.whl", hash = "sha256:01425106e4e8cee195a411f729cff2a7d61813b0b11737c12bd5991f5f14bcd5"},
- {file = "Pillow-8.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3b570f84a6161cf8865c4e08adf629441f56e32f180f7aa4ccbd2e0a5a02cba2"},
- {file = "Pillow-8.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:031a6c88c77d08aab84fecc05c3cde8414cd6f8406f4d2b16fed1e97634cc8a4"},
- {file = "Pillow-8.2.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:66cc56579fd91f517290ab02c51e3a80f581aba45fd924fcdee01fa06e635812"},
- {file = "Pillow-8.2.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6c32cc3145928c4305d142ebec682419a6c0a8ce9e33db900027ddca1ec39178"},
- {file = "Pillow-8.2.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:624b977355cde8b065f6d51b98497d6cd5fbdd4f36405f7a8790e3376125e2bb"},
- {file = "Pillow-8.2.0-cp38-cp38-win32.whl", hash = "sha256:5cbf3e3b1014dddc45496e8cf38b9f099c95a326275885199f427825c6522232"},
- {file = "Pillow-8.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:463822e2f0d81459e113372a168f2ff59723e78528f91f0bd25680ac185cf797"},
- {file = "Pillow-8.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:95d5ef984eff897850f3a83883363da64aae1000e79cb3c321915468e8c6add5"},
- {file = "Pillow-8.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b91c36492a4bbb1ee855b7d16fe51379e5f96b85692dc8210831fbb24c43e484"},
- {file = "Pillow-8.2.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d68cb92c408261f806b15923834203f024110a2e2872ecb0bd2a110f89d3c602"},
- {file = "Pillow-8.2.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f217c3954ce5fd88303fc0c317af55d5e0204106d86dea17eb8205700d47dec2"},
- {file = "Pillow-8.2.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:5b70110acb39f3aff6b74cf09bb4169b167e2660dabc304c1e25b6555fa781ef"},
- {file = "Pillow-8.2.0-cp39-cp39-win32.whl", hash = "sha256:a7d5e9fad90eff8f6f6106d3b98b553a88b6f976e51fce287192a5d2d5363713"},
- {file = "Pillow-8.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:238c197fc275b475e87c1453b05b467d2d02c2915fdfdd4af126145ff2e4610c"},
- {file = "Pillow-8.2.0-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:0e04d61f0064b545b989126197930807c86bcbd4534d39168f4aa5fda39bb8f9"},
- {file = "Pillow-8.2.0-pp36-pypy36_pp73-manylinux2010_i686.whl", hash = "sha256:63728564c1410d99e6d1ae8e3b810fe012bc440952168af0a2877e8ff5ab96b9"},
- {file = "Pillow-8.2.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:c03c07ed32c5324939b19e36ae5f75c660c81461e312a41aea30acdd46f93a7c"},
- {file = "Pillow-8.2.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:4d98abdd6b1e3bf1a1cbb14c3895226816e666749ac040c4e2554231068c639b"},
- {file = "Pillow-8.2.0-pp37-pypy37_pp73-manylinux2010_i686.whl", hash = "sha256:aac00e4bc94d1b7813fe882c28990c1bc2f9d0e1aa765a5f2b516e8a6a16a9e4"},
- {file = "Pillow-8.2.0-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:22fd0f42ad15dfdde6c581347eaa4adb9a6fc4b865f90b23378aa7914895e120"},
- {file = "Pillow-8.2.0-pp37-pypy37_pp73-win32.whl", hash = "sha256:e98eca29a05913e82177b3ba3d198b1728e164869c613d76d0de4bde6768a50e"},
- {file = "Pillow-8.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:8b56553c0345ad6dcb2e9b433ae47d67f95fc23fe28a0bde15a120f25257e291"},
- {file = "Pillow-8.2.0.tar.gz", hash = "sha256:a787ab10d7bb5494e5f76536ac460741788f1fbce851068d73a87ca7c35fc3e1"},
-]
-protobuf = [
- {file = "protobuf-3.17.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ab6bb0e270c6c58e7ff4345b3a803cc59dbee19ddf77a4719c5b635f1d547aa8"},
- {file = "protobuf-3.17.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:13ee7be3c2d9a5d2b42a1030976f760f28755fcf5863c55b1460fd205e6cd637"},
- {file = "protobuf-3.17.3-cp35-cp35m-macosx_10_9_intel.whl", hash = "sha256:1556a1049ccec58c7855a78d27e5c6e70e95103b32de9142bae0576e9200a1b0"},
- {file = "protobuf-3.17.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:f0e59430ee953184a703a324b8ec52f571c6c4259d496a19d1cabcdc19dabc62"},
- {file = "protobuf-3.17.3-cp35-cp35m-win32.whl", hash = "sha256:a981222367fb4210a10a929ad5983ae93bd5a050a0824fc35d6371c07b78caf6"},
- {file = "protobuf-3.17.3-cp35-cp35m-win_amd64.whl", hash = "sha256:6d847c59963c03fd7a0cd7c488cadfa10cda4fff34d8bc8cba92935a91b7a037"},
- {file = "protobuf-3.17.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:145ce0af55c4259ca74993ddab3479c78af064002ec8227beb3d944405123c71"},
- {file = "protobuf-3.17.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6ce4d8bf0321e7b2d4395e253f8002a1a5ffbcfd7bcc0a6ba46712c07d47d0b4"},
- {file = "protobuf-3.17.3-cp36-cp36m-win32.whl", hash = "sha256:7a4c97961e9e5b03a56f9a6c82742ed55375c4a25f2692b625d4087d02ed31b9"},
- {file = "protobuf-3.17.3-cp36-cp36m-win_amd64.whl", hash = "sha256:a22b3a0dbac6544dacbafd4c5f6a29e389a50e3b193e2c70dae6bbf7930f651d"},
- {file = "protobuf-3.17.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ffea251f5cd3c0b9b43c7a7a912777e0bc86263436a87c2555242a348817221b"},
- {file = "protobuf-3.17.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:9b7a5c1022e0fa0dbde7fd03682d07d14624ad870ae52054849d8960f04bc764"},
- {file = "protobuf-3.17.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:8727ee027157516e2c311f218ebf2260a18088ffb2d29473e82add217d196b1c"},
- {file = "protobuf-3.17.3-cp37-cp37m-win32.whl", hash = "sha256:14c1c9377a7ffbeaccd4722ab0aa900091f52b516ad89c4b0c3bb0a4af903ba5"},
- {file = "protobuf-3.17.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c56c050a947186ba51de4f94ab441d7f04fcd44c56df6e922369cc2e1a92d683"},
- {file = "protobuf-3.17.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2ae692bb6d1992afb6b74348e7bb648a75bb0d3565a3f5eea5bec8f62bd06d87"},
- {file = "protobuf-3.17.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:99938f2a2d7ca6563c0ade0c5ca8982264c484fdecf418bd68e880a7ab5730b1"},
- {file = "protobuf-3.17.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6902a1e4b7a319ec611a7345ff81b6b004b36b0d2196ce7a748b3493da3d226d"},
- {file = "protobuf-3.17.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4ffbd23640bb7403574f7aff8368e2aeb2ec9a5c6306580be48ac59a6bac8bde"},
- {file = "protobuf-3.17.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:26010f693b675ff5a1d0e1bdb17689b8b716a18709113288fead438703d45539"},
- {file = "protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e76d9686e088fece2450dbc7ee905f9be904e427341d289acbe9ad00b78ebd47"},
- {file = "protobuf-3.17.3-py2.py3-none-any.whl", hash = "sha256:2bfb815216a9cd9faec52b16fd2bfa68437a44b67c56bee59bc3926522ecb04e"},
- {file = "protobuf-3.17.3.tar.gz", hash = "sha256:72804ea5eaa9c22a090d2803813e280fb273b62d5ae497aaf3553d141c4fdd7b"},
-]
-pyasn1 = [
- {file = "pyasn1-0.4.8-py2.4.egg", hash = "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"},
- {file = "pyasn1-0.4.8-py2.5.egg", hash = "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf"},
- {file = "pyasn1-0.4.8-py2.6.egg", hash = "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"},
- {file = "pyasn1-0.4.8-py2.7.egg", hash = "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8"},
- {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"},
- {file = "pyasn1-0.4.8-py3.1.egg", hash = "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86"},
- {file = "pyasn1-0.4.8-py3.2.egg", hash = "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"},
- {file = "pyasn1-0.4.8-py3.3.egg", hash = "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576"},
- {file = "pyasn1-0.4.8-py3.4.egg", hash = "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"},
- {file = "pyasn1-0.4.8-py3.5.egg", hash = "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"},
- {file = "pyasn1-0.4.8-py3.6.egg", hash = "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359"},
- {file = "pyasn1-0.4.8-py3.7.egg", hash = "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776"},
- {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"},
-]
-pyasn1-modules = [
- {file = "pyasn1-modules-0.2.8.tar.gz", hash = "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e"},
- {file = "pyasn1_modules-0.2.8-py2.4.egg", hash = "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199"},
- {file = "pyasn1_modules-0.2.8-py2.5.egg", hash = "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405"},
- {file = "pyasn1_modules-0.2.8-py2.6.egg", hash = "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb"},
- {file = "pyasn1_modules-0.2.8-py2.7.egg", hash = "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8"},
- {file = "pyasn1_modules-0.2.8-py2.py3-none-any.whl", hash = "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"},
- {file = "pyasn1_modules-0.2.8-py3.1.egg", hash = "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d"},
- {file = "pyasn1_modules-0.2.8-py3.2.egg", hash = "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45"},
- {file = "pyasn1_modules-0.2.8-py3.3.egg", hash = "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4"},
- {file = "pyasn1_modules-0.2.8-py3.4.egg", hash = "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811"},
- {file = "pyasn1_modules-0.2.8-py3.5.egg", hash = "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed"},
- {file = "pyasn1_modules-0.2.8-py3.6.egg", hash = "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0"},
- {file = "pyasn1_modules-0.2.8-py3.7.egg", hash = "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd"},
-]
-pycodestyle = [
- {file = "pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"},
- {file = "pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"},
-]
-pyflakes = [
- {file = "pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"},
- {file = "pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"},
-]
-pygraphviz = [
- {file = "pygraphviz-1.6.zip", hash = "sha256:411ae84a5bc313e3e1523a1cace59159f512336318a510573b47f824edef8860"},
-]
-pymint = []
-pyparsing = [
- {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"},
- {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
-]
-pyrsistent = [
- {file = "pyrsistent-0.17.3.tar.gz", hash = "sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e"},
-]
-python-dateutil = [
- {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"},
- {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"},
-]
-pytz = [
- {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"},
- {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"},
-]
-pyyaml = [
- {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"},
- {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"},
- {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"},
- {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"},
- {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"},
- {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"},
- {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"},
- {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"},
- {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"},
- {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"},
- {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"},
- {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"},
- {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"},
- {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"},
- {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"},
- {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"},
- {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"},
- {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"},
- {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"},
- {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"},
- {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"},
-]
-regex = [
- {file = "regex-2020.11.11-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:dd7bee615680d940dd44ac0a479f2bc5f73d6ca63a5915cd8d30739c14ca522c"},
- {file = "regex-2020.11.11-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:3002ee2d4e8bbe4656237627203d8290a562d1fc1962deee470905ab63570345"},
- {file = "regex-2020.11.11-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:064d2fc83ab4ee0055fcc1ef38ec60e505742850a40061f854ac64cb3d8d6dd3"},
- {file = "regex-2020.11.11-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:83a390a653c13be1ab26287240df1fd9324ca8a0d31b603fa57cd7d9520648fa"},
- {file = "regex-2020.11.11-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:412969d58ecd4f576510ec88bcb7602e9e582bbef78859ed8c9ca4de4f9e891c"},
- {file = "regex-2020.11.11-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:ccfea4911ac28a8f744096bce1559e0bd86b09a53c8a9d5856ca8e1f5f4de1f5"},
- {file = "regex-2020.11.11-cp36-cp36m-manylinux2014_i686.whl", hash = "sha256:cefcdb2ac3b67fd9f7244820ce1965c8cf352366199cc1358d67c6cc3c5c8bbc"},
- {file = "regex-2020.11.11-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:9e8b3187f6beea8e56cb4b33c35049cbe376cf69aefaee5bc035309d88c98ca5"},
- {file = "regex-2020.11.11-cp36-cp36m-win32.whl", hash = "sha256:787e44e5f4fd027dd90b5ee0240b05dc1752cb43c2903617f25baa495fe551e9"},
- {file = "regex-2020.11.11-cp36-cp36m-win_amd64.whl", hash = "sha256:a9f76d9122359b09e38f27cd9c41729169171cf0fd73ec5b22cc4628f9e486ca"},
- {file = "regex-2020.11.11-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6d128368def4b0cd95c0fc9d99a89ae73c083b25e67f27a410830e30f9df0edc"},
- {file = "regex-2020.11.11-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:df50ba964812606663ca9d23d374036bc5ae3d71e86168409cdd84ca7948d8a3"},
- {file = "regex-2020.11.11-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d1e57c16c4840f1c3543507742e99b8398609474a0e6a6925476914479de3488"},
- {file = "regex-2020.11.11-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:6e50b3b417ab2fd67bfa6235f0df4782fe2ff8be83f0c4435e1dc43d25052ee8"},
- {file = "regex-2020.11.11-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bb17a7fe9c47167337009ce18cd6e6b3edf3ca0063bf6bed6ce02515129c016a"},
- {file = "regex-2020.11.11-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:826d0119f14f9a9ce25999a13ed5922c785b50e469800f6e5a6721318650ef49"},
- {file = "regex-2020.11.11-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:8cc3717146ce4040419639cf45455663a002a554806ddac46304acc5bd41dae2"},
- {file = "regex-2020.11.11-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:86ad88c7c2512094a85b0a01ce053bab1e28eafb8f3868bb8c22f4903e33f147"},
- {file = "regex-2020.11.11-cp37-cp37m-win32.whl", hash = "sha256:e03867f3baf64ecab47dfc9ddb58afc67acb6a0f80f6cf8ff9fa82962ec4d1cd"},
- {file = "regex-2020.11.11-cp37-cp37m-win_amd64.whl", hash = "sha256:56d1e298bb6482d0466399a6383181bf2627c37ad414e205b3ce0f85aa140be7"},
- {file = "regex-2020.11.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:19ac2bf0048a2f4d460ee20647e84ca160512a7ee8af844dc9207720778470f1"},
- {file = "regex-2020.11.11-cp38-cp38-manylinux1_i686.whl", hash = "sha256:84ab584dcb5e81815040d86148805a808acb0bee303d19638fe2f9488d704bc1"},
- {file = "regex-2020.11.11-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:4159ecf20dffea07f4a7241b2a236f90eb622c7e8caab9f43caba5f27ca37284"},
- {file = "regex-2020.11.11-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:8060be04baec546fe3afa6975d2998e15d1b655d7255f0e6b0ed3f482cccc218"},
- {file = "regex-2020.11.11-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:cdb98be55db1b94c950822cbc10d3d768f01e184365851ebb42cd377486ced7b"},
- {file = "regex-2020.11.11-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:11d9100bd874ce8b2a037db9150e732cd768359fc25fe5f77973208aa24eb13e"},
- {file = "regex-2020.11.11-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:0951c78fa4cb26d1278a4b3784fcf973fc97ec39c07483328a74b034b0cc569c"},
- {file = "regex-2020.11.11-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:c8b1ad791debd67221fb1266f8d09730ae927acacb32d0dad9fd07a7d341a28f"},
- {file = "regex-2020.11.11-cp38-cp38-win32.whl", hash = "sha256:beae9db1545f8116cfc9301a9601e9c975bb56ca22a38ac0fe06a72c3460f31a"},
- {file = "regex-2020.11.11-cp38-cp38-win_amd64.whl", hash = "sha256:48e94218f06317b6d32feb4ecff8b6025695450009bcb3291fb23daf79689431"},
- {file = "regex-2020.11.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c67fd5f3ad81f8301184354014e8e7510ab77e0c7e450a427d77f28ae8effbef"},
- {file = "regex-2020.11.11-cp39-cp39-manylinux1_i686.whl", hash = "sha256:e7cdd5ee8053c82607432b7ebad37e2ece54548fef2b254f7bce6f7831904586"},
- {file = "regex-2020.11.11-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:394b5be4fa72354a78763b317f82997ad881896dd4a860e429a6fa74afaacb07"},
- {file = "regex-2020.11.11-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:3b46a4c73ec1f25361147a7a0fd86084f3627dc78d09bcbe14e70db12683efec"},
- {file = "regex-2020.11.11-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:267d1b13f863e664150948ce2a9ed4927bf4ac7a068780f1ee8af83352aa17a2"},
- {file = "regex-2020.11.11-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:68267a7a5fb0bd9676b86f967143b6a6ecefb3eed4042ecc9e7f0e014aef8f74"},
- {file = "regex-2020.11.11-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:e899b69dd5d26655cb454835ea2fceb18832c9ee9c4fb45dc4cf8a6089d35312"},
- {file = "regex-2020.11.11-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:396411bb5a7849aeda9c49873b8295919fdc118c50b57122b09cb2097047c118"},
- {file = "regex-2020.11.11-cp39-cp39-win32.whl", hash = "sha256:32f8714c4bcc4b0d2aa259b1647e3c5b6cfe2e923c6c124234a5e03408224227"},
- {file = "regex-2020.11.11-cp39-cp39-win_amd64.whl", hash = "sha256:bf02ab95ff5261ba108725dbd795bf6395eaac1b8468b41472d82d35b12b0295"},
- {file = "regex-2020.11.11.tar.gz", hash = "sha256:0a235841237d4487329bcabcb5b902858f7967f5e684e08e968367f25b2c3d37"},
-]
-requests = [
- {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"},
- {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"},
-]
-requests-oauthlib = [
- {file = "requests-oauthlib-1.3.0.tar.gz", hash = "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a"},
- {file = "requests_oauthlib-1.3.0-py2.py3-none-any.whl", hash = "sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d"},
- {file = "requests_oauthlib-1.3.0-py3.7.egg", hash = "sha256:fa6c47b933f01060936d87ae9327fead68768b69c6c9ea2109c48be30f2d4dbc"},
-]
-rope = [
- {file = "rope-0.18.0.tar.gz", hash = "sha256:786b5c38c530d4846aa68a42604f61b4e69a493390e3ca11b88df0fbfdc3ed04"},
-]
-rsa = [
- {file = "rsa-4.7.2-py3-none-any.whl", hash = "sha256:78f9a9bf4e7be0c5ded4583326e7461e3a3c5aae24073648b4bdfa797d78c9d2"},
- {file = "rsa-4.7.2.tar.gz", hash = "sha256:9d689e6ca1b3038bc82bf8d23e944b6b6037bc02301a574935b2dd946e0353b9"},
-]
-salib = [
- {file = "SALib-1.3.13.tar.gz", hash = "sha256:509c149c81d9cbf7e54ab275769bd855fb0aa5a699570c76f2ffa183a9c4041a"},
-]
-scikit-learn = [
- {file = "scikit-learn-0.23.2.tar.gz", hash = "sha256:20766f515e6cd6f954554387dfae705d93c7b544ec0e6c6a5d8e006f6f7ef480"},
- {file = "scikit_learn-0.23.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:98508723f44c61896a4e15894b2016762a55555fbf09365a0bb1870ecbd442de"},
- {file = "scikit_learn-0.23.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a64817b050efd50f9abcfd311870073e500ae11b299683a519fbb52d85e08d25"},
- {file = "scikit_learn-0.23.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:daf276c465c38ef736a79bd79fc80a249f746bcbcae50c40945428f7ece074f8"},
- {file = "scikit_learn-0.23.2-cp36-cp36m-win32.whl", hash = "sha256:cb3e76380312e1f86abd20340ab1d5b3cc46a26f6593d3c33c9ea3e4c7134028"},
- {file = "scikit_learn-0.23.2-cp36-cp36m-win_amd64.whl", hash = "sha256:0a127cc70990d4c15b1019680bfedc7fec6c23d14d3719fdf9b64b22d37cdeca"},
- {file = "scikit_learn-0.23.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2aa95c2f17d2f80534156215c87bee72b6aa314a7f8b8fe92a2d71f47280570d"},
- {file = "scikit_learn-0.23.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6c28a1d00aae7c3c9568f61aafeaad813f0f01c729bee4fd9479e2132b215c1d"},
- {file = "scikit_learn-0.23.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:da8e7c302003dd765d92a5616678e591f347460ac7b53e53d667be7dfe6d1b10"},
- {file = "scikit_learn-0.23.2-cp37-cp37m-win32.whl", hash = "sha256:d9a1ce5f099f29c7c33181cc4386660e0ba891b21a60dc036bf369e3a3ee3aec"},
- {file = "scikit_learn-0.23.2-cp37-cp37m-win_amd64.whl", hash = "sha256:914ac2b45a058d3f1338d7736200f7f3b094857758895f8667be8a81ff443b5b"},
- {file = "scikit_learn-0.23.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7671bbeddd7f4f9a6968f3b5442dac5f22bf1ba06709ef888cc9132ad354a9ab"},
- {file = "scikit_learn-0.23.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:d0dcaa54263307075cb93d0bee3ceb02821093b1b3d25f66021987d305d01dce"},
- {file = "scikit_learn-0.23.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5ce7a8021c9defc2b75620571b350acc4a7d9763c25b7593621ef50f3bd019a2"},
- {file = "scikit_learn-0.23.2-cp38-cp38-win32.whl", hash = "sha256:0d39748e7c9669ba648acf40fb3ce96b8a07b240db6888563a7cb76e05e0d9cc"},
- {file = "scikit_learn-0.23.2-cp38-cp38-win_amd64.whl", hash = "sha256:1b8a391de95f6285a2f9adffb7db0892718950954b7149a70c783dc848f104ea"},
-]
-scipy = [
- {file = "scipy-1.6.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a15a1f3fc0abff33e792d6049161b7795909b40b97c6cc2934ed54384017ab76"},
- {file = "scipy-1.6.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:e79570979ccdc3d165456dd62041d9556fb9733b86b4b6d818af7a0afc15f092"},
- {file = "scipy-1.6.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:a423533c55fec61456dedee7b6ee7dce0bb6bfa395424ea374d25afa262be261"},
- {file = "scipy-1.6.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:33d6b7df40d197bdd3049d64e8e680227151673465e5d85723b3b8f6b15a6ced"},
- {file = "scipy-1.6.1-cp37-cp37m-win32.whl", hash = "sha256:6725e3fbb47da428794f243864f2297462e9ee448297c93ed1dcbc44335feb78"},
- {file = "scipy-1.6.1-cp37-cp37m-win_amd64.whl", hash = "sha256:5fa9c6530b1661f1370bcd332a1e62ca7881785cc0f80c0d559b636567fab63c"},
- {file = "scipy-1.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bd50daf727f7c195e26f27467c85ce653d41df4358a25b32434a50d8870fc519"},
- {file = "scipy-1.6.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:f46dd15335e8a320b0fb4685f58b7471702234cba8bb3442b69a3e1dc329c345"},
- {file = "scipy-1.6.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:0e5b0ccf63155d90da576edd2768b66fb276446c371b73841e3503be1d63fb5d"},
- {file = "scipy-1.6.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:2481efbb3740977e3c831edfd0bd9867be26387cacf24eb5e366a6a374d3d00d"},
- {file = "scipy-1.6.1-cp38-cp38-win32.whl", hash = "sha256:68cb4c424112cd4be886b4d979c5497fba190714085f46b8ae67a5e4416c32b4"},
- {file = "scipy-1.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:5f331eeed0297232d2e6eea51b54e8278ed8bb10b099f69c44e2558c090d06bf"},
- {file = "scipy-1.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0c8a51d33556bf70367452d4d601d1742c0e806cd0194785914daf19775f0e67"},
- {file = "scipy-1.6.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:83bf7c16245c15bc58ee76c5418e46ea1811edcc2e2b03041b804e46084ab627"},
- {file = "scipy-1.6.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:794e768cc5f779736593046c9714e0f3a5940bc6dcc1dba885ad64cbfb28e9f0"},
- {file = "scipy-1.6.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:5da5471aed911fe7e52b86bf9ea32fb55ae93e2f0fac66c32e58897cfb02fa07"},
- {file = "scipy-1.6.1-cp39-cp39-win32.whl", hash = "sha256:8e403a337749ed40af60e537cc4d4c03febddcc56cd26e774c9b1b600a70d3e4"},
- {file = "scipy-1.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:a5193a098ae9f29af283dcf0041f762601faf2e595c0db1da929875b7570353f"},
- {file = "scipy-1.6.1.tar.gz", hash = "sha256:c4fceb864890b6168e79b0e714c585dbe2fd4222768ee90bc1aa0f8218691b11"},
-]
-seaborn = [
- {file = "seaborn-0.11.1-py3-none-any.whl", hash = "sha256:4e1cce9489449a1c6ff3c567f2113cdb41122f727e27a984950d004a88ef3c5c"},
- {file = "seaborn-0.11.1.tar.gz", hash = "sha256:44e78eaed937c5a87fc7a892c329a7cc091060b67ebd1d0d306b446a74ba01ad"},
-]
-six = [
- {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"},
- {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"},
-]
-tabulate = [
- {file = "tabulate-0.8.9-py3-none-any.whl", hash = "sha256:d7c013fe7abbc5e491394e10fa845f8f32fe54f8dc60c6622c6cf482d25d47e4"},
- {file = "tabulate-0.8.9.tar.gz", hash = "sha256:eb1d13f25760052e8931f2ef80aaf6045a6cceb47514db8beab24cded16f13a7"},
-]
-tensorboard = [
- {file = "tensorboard-2.5.0-py3-none-any.whl", hash = "sha256:e167460085b6528956b33bab1c970c989cdce47a6616273880733f5e7bde452e"},
-]
-tensorboard-data-server = [
- {file = "tensorboard_data_server-0.6.1-py3-none-any.whl", hash = "sha256:809fe9887682d35c1f7d1f54f0f40f98bb1f771b14265b453ca051e2ce58fca7"},
- {file = "tensorboard_data_server-0.6.1-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:fa8cef9be4fcae2f2363c88176638baf2da19c5ec90addb49b1cde05c95c88ee"},
- {file = "tensorboard_data_server-0.6.1-py3-none-manylinux2010_x86_64.whl", hash = "sha256:d8237580755e58eff68d1f3abefb5b1e39ae5c8b127cc40920f9c4fb33f4b98a"},
-]
-tensorboard-plugin-wit = [
- {file = "tensorboard_plugin_wit-1.8.0-py3-none-any.whl", hash = "sha256:2a80d1c551d741e99b2f197bb915d8a133e24adb8da1732b840041860f91183a"},
-]
-tensorflow = [
- {file = "tensorflow-2.5.0-cp36-cp36m-macosx_10_11_x86_64.whl", hash = "sha256:7e1351ce05b897d5cf1042066b6929ca3f595a717849421ae92dbe8d6d2f1c74"},
- {file = "tensorflow-2.5.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:31a3ea994c336fc5a6ba0e6d61f131262b2c6dbff97e2b7473ff6da0cf9383f7"},
- {file = "tensorflow-2.5.0-cp36-cp36m-win_amd64.whl", hash = "sha256:c45059b42bca01ce441004abb965acf7838b40d12e036920063bd7ac540def9a"},
- {file = "tensorflow-2.5.0-cp37-cp37m-macosx_10_11_x86_64.whl", hash = "sha256:616bc8094cb289b3bd21eded2196b0dba65bce53bad112efcaf2acb6f7d9e6a5"},
- {file = "tensorflow-2.5.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:739d25273ccc10fedc74517de099bd5b16a274d1295fad6bfef834ad28cc3401"},
- {file = "tensorflow-2.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:68b70ca7df7f5f8fbe3d7240e937b3ea8b1a25e51710f60293e7edada00257a2"},
- {file = "tensorflow-2.5.0-cp38-cp38-macosx_10_11_x86_64.whl", hash = "sha256:c46b1d1b0eec54577d7ba545e3951c9dd0355ca05a8eb776c95d9a3e22e7be9c"},
- {file = "tensorflow-2.5.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:34ab87aac9093de98cbba68d7e8dca9159c36acd06a03e5749c956c7ab08d9da"},
- {file = "tensorflow-2.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:46f10a2edc694bb54a2d869a65b5a09705dab1874a89b529990a943416ad48aa"},
- {file = "tensorflow-2.5.0-cp39-cp39-macosx_10_11_x86_64.whl", hash = "sha256:baebb9c95ef1815bb410317ad525dd3dbb26064fe95636b51486459b6536bc6e"},
- {file = "tensorflow-2.5.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:1ea003f9e11508d0336c242a2a3bc73aea205dd5b31892c3e1d7f5d0f0e60c0a"},
- {file = "tensorflow-2.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:4edec9b9f6ef8f1407762a3a6bd050173177f686d5ea6b59e91487b645173f73"},
-]
-tensorflow-estimator = [
- {file = "tensorflow_estimator-2.5.0-py2.py3-none-any.whl", hash = "sha256:d1fe76dee8b1dcab865d807a0246da0a9c4a635b1eba6e9545bf216c3aad6955"},
-]
-termcolor = [
- {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"},
-]
-threadpoolctl = [
- {file = "threadpoolctl-2.1.0-py3-none-any.whl", hash = "sha256:38b74ca20ff3bb42caca8b00055111d74159ee95c4370882bbff2b93d24da725"},
- {file = "threadpoolctl-2.1.0.tar.gz", hash = "sha256:ddc57c96a38beb63db45d6c159b5ab07b6bced12c45a1f07b2b92f272aebfa6b"},
-]
-toml = [
- {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
- {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
-]
-tqdm = [
- {file = "tqdm-4.61.1-py2.py3-none-any.whl", hash = "sha256:aa0c29f03f298951ac6318f7c8ce584e48fa22ec26396e6411e43d038243bdb2"},
- {file = "tqdm-4.61.1.tar.gz", hash = "sha256:24be966933e942be5f074c29755a95b315c69a91f839a29139bf26ffffe2d3fd"},
-]
-typed-ast = [
- {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3"},
- {file = "typed_ast-1.4.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb"},
- {file = "typed_ast-1.4.1-cp35-cp35m-win32.whl", hash = "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919"},
- {file = "typed_ast-1.4.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01"},
- {file = "typed_ast-1.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75"},
- {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652"},
- {file = "typed_ast-1.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"},
- {file = "typed_ast-1.4.1-cp36-cp36m-win32.whl", hash = "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1"},
- {file = "typed_ast-1.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa"},
- {file = "typed_ast-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614"},
- {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41"},
- {file = "typed_ast-1.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b"},
- {file = "typed_ast-1.4.1-cp37-cp37m-win32.whl", hash = "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe"},
- {file = "typed_ast-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355"},
- {file = "typed_ast-1.4.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6"},
- {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907"},
- {file = "typed_ast-1.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d"},
- {file = "typed_ast-1.4.1-cp38-cp38-win32.whl", hash = "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c"},
- {file = "typed_ast-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4"},
- {file = "typed_ast-1.4.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34"},
- {file = "typed_ast-1.4.1.tar.gz", hash = "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b"},
-]
-typing-extensions = [
- {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"},
- {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"},
- {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"},
-]
-urllib3 = [
- {file = "urllib3-1.26.5-py2.py3-none-any.whl", hash = "sha256:753a0374df26658f99d826cfe40394a686d05985786d946fbe4165b5148f5a7c"},
- {file = "urllib3-1.26.5.tar.gz", hash = "sha256:a7acd0977125325f516bda9735fa7142b909a8d01e8b2e4c8108d0984e6e0098"},
-]
-werkzeug = [
- {file = "Werkzeug-2.0.1-py3-none-any.whl", hash = "sha256:6c1ec500dcdba0baa27600f6a22f6333d8b662d22027ff9f6202e3367413caa8"},
- {file = "Werkzeug-2.0.1.tar.gz", hash = "sha256:1de1db30d010ff1af14a009224ec49ab2329ad2cde454c8a708130642d579c42"},
-]
-wrapt = [
- {file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"},
-]
+[metadata]
+lock-version = "2.0"
+python-versions = ">=3.8,<3.11"
+content-hash = "32adb8323e0b1fc99dc795fd69857361d48b0aa0cb088cc88f4c3acc0a21a11c"
diff --git a/pyeda_test.py b/pyeda_test.py
new file mode 100644
index 0000000..10f3976
--- /dev/null
+++ b/pyeda_test.py
@@ -0,0 +1,13 @@
+import pyeda
+
+a, b, c, d = map(exprvar, "abcd")
+
+f0 = ~a & b | c & ~d
+f1 = a >> b
+
+print(f0)
+print(f1)
+
+f3 = OneHot(a, b, c, d)
+
+f1 = Or(~a & ~b & ~c, ~a & ~b & c, a & ~b & c, a & b & c, a & b & ~c)
diff --git a/pylfr.code-workspace b/pylfr.code-workspace
new file mode 100644
index 0000000..7e01cbb
--- /dev/null
+++ b/pylfr.code-workspace
@@ -0,0 +1,14 @@
+{
+ "folders": [
+ {
+ "path": "."
+ },
+ {
+ "path": "pymint"
+ },
+ {
+ "path": "pyparchmint"
+ }
+ ],
+ "settings": {}
+}
\ No newline at end of file
diff --git a/pymint b/pymint
new file mode 160000
index 0000000..5d75137
--- /dev/null
+++ b/pymint
@@ -0,0 +1 @@
+Subproject commit 5d7513757d8129f2c914e4c022c4d4273487f956
diff --git a/pyparchmint b/pyparchmint
new file mode 160000
index 0000000..4eec890
--- /dev/null
+++ b/pyparchmint
@@ -0,0 +1 @@
+Subproject commit 4eec89062f5706df638c363d6616ace3156082ed
diff --git a/pyproject.toml b/pyproject.toml
index 96639d5..4e9c1d2 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -13,30 +13,77 @@ include = [
]
[tool.poetry.dependencies]
-python = "^3.8"
-networkx = "^2.5"
+python = ">=3.8,<3.11"
+networkx = "^3.0"
argparse = "^1.4.0"
-antlr4-python3-runtime = "^4.8"
+antlr4-python3-runtime = "^4.10"
pygraphviz = "^1.6"
-parchmint = "latest"
-dafd = "latest"
numpy = "^1.19.4"
tabulate = "^0.8.7"
-pymint = "^0.2.11"
+art = "^5.2"
+jsonschema = "^3.2.0"
+pyeda = "^0.28.0"
+pymint = {path = "pymint", develop=true}
+parchmint = {path = "pyparchmint", develop=true}
+scipy = "^1.8.1"
+click = "^8.1.3"
+dafd = {path = "dafd"}
+types-tabulate = "^0.9.0.1"
[tool.poetry.dev-dependencies]
-mypy = "^0.782"
-black = "^20.8b1"
flake8 = "^3.8.3"
rope = "^0.18.0"
+black = "22.3.0"
+pytest = "^7.1.2"
+isort = "^5.10.1"
+mypy = "^1.1.1"
+Sphinx = "^3.4.3"
+sphinx-rtd-theme = "^0.5.1"
+sphinxcontrib-napoleon = "^0.7"
+pip = "^23.0.1"
[tool.poetry.scripts]
lfr-compile = "lfr.cmdline:main"
+test = "scripts:test"
+format = "scripts:format"
+static-analysis = "scripts:static_analysis"
[tool.black]
-line-length = 88
+include = "lfr/.*\\.py$"
+extend-exclude = '''
+# A regex preceded with ^/ will apply only to files and directories
+# in the root of the project.
+(
+ ^/lfr/compiler/distribute/BitVector.py # exclude a file named foo.py in the root of the project
+ | .*_pb2.py # exclude autogenerated Protocol Buffer files anywhere in the project
+ | ^/lfr/antlrgen/\.* # ANTLR Generated files
+)
+'''
+
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
+[tool.mypy]
+python_version = 3.8
+ignore_missing_imports = "True"
+check_untyped_defs = "True"
+exclude = """
+(?x)(
+ ^lfr/antlrgen/.*.py$ # files named "one.py"
+ | BitVector.py$ # or files ending with "two.pyi"
+ | ^three. # or files starting with "three."
+)
+"""
+
+[tool.isort]
+profile = "black"
+src_paths = ["lfr"]
+skip = ["dafd", "lfr/antlrgen/", "lfr/compiler/distribute/BitVector.py"]
+
+[tool.pytest.ini_options]
+minversion = "6.0"
+testpaths = [
+ "./tests/"
+]
diff --git a/reggie.g4 b/reggie.g4
new file mode 100644
index 0000000..93ddfe8
--- /dev/null
+++ b/reggie.g4
@@ -0,0 +1,63 @@
+grammar reggie;
+
+graph: '{' graphstatement (',' graphstatement)* '}';
+
+graphstatement:
+ basestatement
+ | ('(' basestatement ')' statementmodifier);
+
+statementmodifier: intmodifier | plusmodifier | starmodifier;
+
+basestatement: subgraph | vertex2vertex | vertex;
+
+subgraph: (ID ':') '{' vertex2vertex (',' vertex2vertex)* '}';
+
+vertex:
+ structuralid (':' labelfilter)? coloringfilter? structuralvertexpattern*;
+
+coloringfilter: '{' STRING (',' STRING)* '}';
+
+structuralvertexpattern: (
+ intmodifier
+ | starmodifier
+ | plusmodifier
+ );
+
+intmodifier: '[' INT ']';
+
+starmodifier: '*';
+
+plusmodifier: '+';
+
+structuralid: (ID | QUESTIONMARK_WILDCARD);
+
+labelfilter: label ( '|' label)* | '(' label ( '|' label)* ')';
+
+label: ID;
+
+vertex2vertex: vertex (edge vertex)*;
+
+edge: '->' | '<->';
+
+ID: ('a' ..'z' | 'A' ..'Z' | '_') (
+ 'a' ..'z'
+ | 'A' ..'Z'
+ | '0' ..'9'
+ | '_'
+ )*;
+
+//ARROW: '->'; STAR_WILDCARD: '*'; //Not used to describe any label but rather PLUS_WILDCARD: '+';
+QUESTIONMARK_WILDCARD: '?';
+WS: [ \t]+ -> skip;
+NL: [\r\n]+ -> skip; // Define whitespace rule, toss it out
+INT: [0-9]+;
+
+STRING: '"' (ESC | SAFECODEPOINT)* '"';
+
+fragment HEX: [0-9a-fA-F];
+
+fragment UNICODE: 'u' HEX HEX HEX HEX;
+
+fragment ESC: '\\' (["\\/bfnrt] | UNICODE);
+
+fragment SAFECODEPOINT: ~ ["\\\u0000-\u001F];
diff --git a/scripts.py b/scripts.py
new file mode 100644
index 0000000..55ae68e
--- /dev/null
+++ b/scripts.py
@@ -0,0 +1,24 @@
+import subprocess
+
+
+def test():
+ """
+ Run all unittests. Equivalent to:
+ `poetry run python -u -m unittest discover`
+ """
+ subprocess.run(["pytest", "-vv", "tests"], check=True)
+
+
+def format():
+ """
+ Runs black and isort
+ """
+ subprocess.run(["isort", "."], check=True)
+ subprocess.run(["black", "lfr"], check=True)
+
+
+def static_analysis():
+ """
+ Runs mypy and flake8
+ """
+ subprocess.run(["mypy", "lfr"], check=True)
diff --git a/scripts/all.sh b/scripts/all.sh
new file mode 100755
index 0000000..1995c6e
--- /dev/null
+++ b/scripts/all.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+
+
+echo "Synthesizing DropX designs"
+
+for f in ./Microfluidics-Benchmarks/LFR-Testcases/dropx/*.lfr;
+
+do
+ echo "Running File $f";
+ lfr-compile $f --no-gen --outpath ./Microfluidics-Benchmarks/LFR-Dry-Run/dropx/ --pre-load ./Microfluidics-Benchmarks/LFR-Testcases/distribute-library
+done
+
+
+echo "Synthesizing Cassie Thesis Designs"
+
+for f in ./Microfluidics-Benchmarks/LFR-Testcases/chthesis/*.lfr;
+
+do
+ echo "Running File $f";
+ lfr-compile $f --no-gen --outpath ./Microfluidics-Benchmarks/LFR-Dry-Run/chthesis/ --pre-load ./Microfluidics-Benchmarks/LFR-Testcases/distribute-library
+done
+
+
+
+echo "Synthesizing COVID"
+
+for f in ./Microfluidics-Benchmarks/LFR-Testcases/COVID/*.lfr;
+
+do
+ echo "Running File $f";
+ lfr-compile $f --no-gen --outpath ./Microfluidics-Benchmarks/LFR-Dry-Run/COVID/ --pre-load ./Microfluidics-Benchmarks/LFR-Testcases/distribute-library
+done
+
+
+echo "Synthesizing Expressions"
+
+for f in ./Microfluidics-Benchmarks/LFR-Testcases/Expressions/*.lfr;
+
+do
+ echo "Running File $f";
+ lfr-compile $f --no-gen --outpath ./Microfluidics-Benchmarks/LFR-Dry-Run/Expressions/ --pre-load ./Microfluidics-Benchmarks/LFR-Testcases/distribute-library
+done
+
+echo "Synthesizing ghissues"
+
+for f in ./Microfluidics-Benchmarks/LFR-Testcases/ghissues/*.lfr;
+
+do
+ echo "Running File $f";
+ lfr-compile $f --no-gen --outpath ./Microfluidics-Benchmarks/LFR-Dry-Run/ghissues/ --pre-load ./Microfluidics-Benchmarks/LFR-Testcases/distribute-library
+done
+
+
+
+echo "Synthesizing Graph Coverage"
+
+for f in ./Microfluidics-Benchmarks/LFR-Testcases/GraphCoverage/*.lfr;
+
+do
+ echo "Running File $f";
+ lfr-compile $f --no-gen --outpath ./Microfluidics-Benchmarks/LFR-Dry-Run/GraphCoverage/ --pre-load ./Microfluidics-Benchmarks/LFR-Testcases/distribute-library
+done
+
+
+echo "Synthesizing Parser Test"
+
+for f in ./Microfluidics-Benchmarks/LFR-Testcases/ParserTest/*.lfr;
+
+do
+ echo "Running File $f";
+ lfr-compile $f --no-gen --outpath ./Microfluidics-Benchmarks/LFR-Dry-Run/ParserTest/ --pre-load ./Microfluidics-Benchmarks/LFR-Testcases/distribute-library
+done
+
+
+
+echo "Synthesizing Protocols"
+
+for f in ./Microfluidics-Benchmarks/LFR-Testcases/Protocols/*.lfr;
+
+do
+ echo "Running File $f";
+ lfr-compile $f --no-gen --outpath ./Microfluidics-Benchmarks/LFR-Dry-Run/Protocols/ --pre-load ./Microfluidics-Benchmarks/LFR-Testcases/distribute-library
+done
+
+
+echo "Synthesizing Ryuichi's Designs"
+
+for f in ./Microfluidics-Benchmarks/LFR-Testcases/Ryuichi\'s\ designs/*.lfr;
+
+do
+ echo "Running File $f";
+ lfr-compile $f --no-gen --outpath ./Microfluidics-Benchmarks/LFR-Dry-Run/Ryuichi\'s\ designs/ --pre-load ./Microfluidics-Benchmarks/LFR-Testcases/distribute-library
+done
+
+
+echo "Synthesizing Technology Mapping"
+
+for f in ./Microfluidics-Benchmarks/LFR-Testcases/TechnologyMapping/*.lfr;
+
+do
+ echo "Running File $f";
+ lfr-compile $f --no-gen --outpath ./Microfluidics-Benchmarks/LFR-Dry-Run/TechnologyMapping/ --pre-load ./Microfluidics-Benchmarks/LFR-Testcases/distribute-library
+done
+
diff --git a/scripts/dropx.sh b/scripts/dropx.sh
index 7e26582..66009cb 100755
--- a/scripts/dropx.sh
+++ b/scripts/dropx.sh
@@ -3,9 +3,9 @@
echo "Synthesizing DropX designs"
-for f in ~/CIDAR/LFR-Testcases/dropx/*.lfr;
+for f in ./Microfluidics-Benchmarks/LFR-Testcases/dropx/*.lfr;
do
echo "Running File $f";
- lfr-compile $f --outpath ~/CIDAR/MINT-TestCases/dropx/
+ lfr-compile $f --outpath ./Microfluidics-Benchmarks/MINT-TestCases/dropx/
done
\ No newline at end of file
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644
index 0000000..4755b12
--- /dev/null
+++ b/tests/conftest.py
@@ -0,0 +1,15 @@
+from pathlib import Path
+
+import networkx
+
+from lfr.fig.fluidinteractiongraph import FluidInteractionGraph
+
+TEST_OUTPATH = Path(__file__).parent.joinpath("out").absolute()
+TEST_DATA_FOLDER = Path(__file__).parent.joinpath("data")
+LIBRARY_PATH = Path(__file__).parent.parent.joinpath("library").absolute()
+
+
+def to_agraph(fig):
+ fig_copy = fig.copy(as_view=False)
+ ret = networkx.nx_agraph.to_agraph(fig_copy)
+ return ret
diff --git a/tests/data/DropX/dx1.lfr b/tests/data/DropX/dx1.lfr
new file mode 100644
index 0000000..f00e721
--- /dev/null
+++ b/tests/data/DropX/dx1.lfr
@@ -0,0 +1,21 @@
+module dx1(
+ finput in1, in2,
+ foutput out1, out2
+);
+
+ flow base_droplets, injected_droplets, incubated_droplets, sorted_droplets, discarded_droplets;
+
+ assign base_droplets = in1%100;
+
+ assign injected_droplets = base_droplets + in2;
+
+ #MAP "MIXER" "~"
+ assign incubated_droplets = ~injected_droplets;
+
+ assign sorted_droplets = incubated_droplets - discarded_droplets;
+
+ assign out1 = sorted_droplets;
+ assign out2 = discarded_droplets;
+
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/DropX/dx10.lfr b/tests/data/DropX/dx10.lfr
new file mode 100644
index 0000000..e903814
--- /dev/null
+++ b/tests/data/DropX/dx10.lfr
@@ -0,0 +1,11 @@
+// Based on the design by Samuel Oliveria
+
+module dx10(
+ finput in1, in2,
+ foutput out1, out2
+);
+ flow temp;
+ assign temp = in1 % 100 + in2;
+ assign out1 = temp - out2;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/DropX/dx11.lfr b/tests/data/DropX/dx11.lfr
new file mode 100644
index 0000000..34f38a4
--- /dev/null
+++ b/tests/data/DropX/dx11.lfr
@@ -0,0 +1,25 @@
+// Based on the design by Eric South
+
+module dx11(
+ finput in1, in2, in3,
+ foutput waste1, waste2, final_winners
+);
+ flow injected_droplets;
+
+ assign injected_droplets = in1 % 100 + in2;
+
+ flow sort_candidates1, sort_candidates2, temp_winners;
+
+ #MAP "MIXER" "~"
+ assign sort_candidates1 = ~(injected_droplets);
+
+ assign temp_winners = sort_candidates1 - waste1;
+
+
+ #MAP "MIXER" "~"
+ assign sort_candidates2 = ~(in3 + temp_winners);
+
+ assign final_winners = sort_candidates2 - waste2;
+
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/DropX/dx12.lfr b/tests/data/DropX/dx12.lfr
new file mode 100644
index 0000000..86db299
--- /dev/null
+++ b/tests/data/DropX/dx12.lfr
@@ -0,0 +1,23 @@
+// Based on the Design by Rita Chen
+
+module dx12(
+ finput plasmids, dig1, dig2,
+ foutput dig_plasmids, waste
+);
+
+ flow enc_plasmids, injected_dig, incubated_plasmids, digest_plasmids, discarded_droplets;
+
+ assign enc_plasmids = plasmids%100;
+
+ assign injected_dig = enc_plasmids + dig1 + dig2;
+
+ #MAP "MIXER" "~"
+ assign incubated_plasmids = ~injected_dig;
+
+ assign digest_plasmids = incubated_plasmids - discarded_droplets;
+
+ assign dig_plasmids = digest_plasmids;
+ assign waste = discarded_droplets;
+
+
+endmodule
diff --git a/tests/data/DropX/dx13.lfr b/tests/data/DropX/dx13.lfr
new file mode 100644
index 0000000..5028346
--- /dev/null
+++ b/tests/data/DropX/dx13.lfr
@@ -0,0 +1,36 @@
+// Based on the design by Diana Arguijo
+
+module dx13(
+ finput in1, in2, in3,
+ foutput out1, out2, out3, out4
+);
+
+ flow droplets_1, mix_1, pico_1, mix_2, sorted_trash_1, sorted_1, pico_2, mix_3, sorted_trash_2, sorted_2, splitter_1, splitter_2;
+
+ assign droplets_1 = in1%100;
+
+ #MAP "MIXER" "~"
+ assign mix_1 = ~droplets_1;
+
+ assign pico_1 = mix_1 + in2;
+
+ #MAP "MIXER" "~"
+ assign mix_2 = ~pico_1;
+
+ assign sorted_1 = mix_2 - sorted_trash_1;
+
+ assign pico_2 = sorted_1 + in3;
+
+ #MAP "MIXER" "~"
+ assign mix_3 = ~pico_2;
+
+ assign sorted_2 = mix_3 - sorted_trash_2;
+
+ assign {splitter_1, splitter_2} = sorted_2/2;
+
+ assign out1 = sorted_trash_1;
+ assign out2 = sorted_trash_2;
+ assign out3 = splitter_1;
+ assign out4 = splitter_2;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/DropX/dx14.lfr b/tests/data/DropX/dx14.lfr
new file mode 100644
index 0000000..59b6790
--- /dev/null
+++ b/tests/data/DropX/dx14.lfr
@@ -0,0 +1,21 @@
+// Based on the design by Ali Lashkaripour
+
+module dx14(
+ finput in1, in2, in3,
+ foutput waste, keep
+);
+
+ flow input_mix;
+ assign input_mix = in1 + in2 + in3;
+
+ flow [0:1] droplet_inputs;
+ assign droplet_inputs = ~input_mix;
+
+ flow join;
+
+ #MAP "MIXER" "~"
+ assign join = ~(droplet_inputs%100);
+
+ assign keep = join - waste;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/DropX/dx15.lfr b/tests/data/DropX/dx15.lfr
new file mode 100644
index 0000000..3fab413
--- /dev/null
+++ b/tests/data/DropX/dx15.lfr
@@ -0,0 +1,9 @@
+// Based on the design by Helen Huang
+
+module dx15(
+ finput in1,
+ foutput collection, waste
+);
+ assign collection = ~(in1%100) - waste;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/DropX/dx2.lfr b/tests/data/DropX/dx2.lfr
new file mode 100644
index 0000000..b993432
--- /dev/null
+++ b/tests/data/DropX/dx2.lfr
@@ -0,0 +1,18 @@
+module dx2(
+ foutput in1, in2,
+ foutput out1, out2
+);
+
+ flow droplets1, droplets2, merged_droplets, incubated_droplets;
+
+ assign droplets1 = in1%100;
+ assign droplets2 = in2%200;
+
+ assign merged_droplets = droplets1 + droplets2;
+
+ #MAP "MIXER" "~"
+ assign incubated_droplets = ~merged_droplets;
+
+ assign out1 = incubated_droplets - out2;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/DropX/dx3.lfr b/tests/data/DropX/dx3.lfr
new file mode 100644
index 0000000..1f80eb4
--- /dev/null
+++ b/tests/data/DropX/dx3.lfr
@@ -0,0 +1,21 @@
+module dx3(
+ finput in1, in2, in3,
+ foutput out1, out2
+);
+
+ flow droplets, split1, split2;
+
+ assign droplets = in1%100;
+
+ assign {split1, split2} = droplets/2;
+
+ flow injected_droplets1, injected_droplets2;
+
+ assign injected_droplets1 = split1 + in2;
+
+ assign injected_droplets2 = split2 + in3;
+
+ assign out1 = injected_droplets1;
+ assign out2 = injected_droplets2;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/DropX/dx4.lfr b/tests/data/DropX/dx4.lfr
new file mode 100644
index 0000000..a170fab
--- /dev/null
+++ b/tests/data/DropX/dx4.lfr
@@ -0,0 +1,22 @@
+module dx4(
+ finput in1, pico_in1, pico_in2, pico_in3, pico_in4,
+ foutput sort_keep1, sort_keep2, sort_waste1, sort_waste2
+);
+
+ flow pico_mix;
+ assign pico_mix = pico_in1 + pico_in2 + pico_in3 + pico_in3 + pico_in4;
+
+ flow droplets;
+ assign droplets = in1%100;
+
+ flow injected_droplets;
+ assign injected_droplets = droplets + pico_mix;
+
+ flow sort_keep_temp, sort_waste_temp;
+
+ assign sort_keep_temp = injected_droplets - sort_waste_temp;
+
+ assign sort_keep1 = sort_keep_temp - sort_waste1;
+ assign sort_keep2 = sort_waste_temp - sort_waste2;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/DropX/dx5.lfr b/tests/data/DropX/dx5.lfr
new file mode 100644
index 0000000..b35435a
--- /dev/null
+++ b/tests/data/DropX/dx5.lfr
@@ -0,0 +1,18 @@
+module dx5 (
+ finput in1, in2,
+ foutput sort_keep1, sort_keep2, sort_waste1, sort_waste2
+);
+
+ flow injected_droplets;
+ assign injected_droplets = in2 + in1%100;
+
+ flow split1, split2;
+ assign {split1, split2} = injected_droplets/2;
+
+ #MAP "MIXER" "~"
+ assign sort_keep1 = ~split1 - sort_waste1;
+
+ #MAP "MIXER" "~"
+ assign sort_keep2 = ~split2 - sort_waste2;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/DropX/dx6.lfr b/tests/data/DropX/dx6.lfr
new file mode 100644
index 0000000..f92ecf7
--- /dev/null
+++ b/tests/data/DropX/dx6.lfr
@@ -0,0 +1,18 @@
+module dx6(
+ finput in1, in2,
+ foutput out1, out2
+);
+
+ flow mix;
+ assign mix = in1 + in2;
+
+ flow droplets;
+ assign droplets = mix%50;
+
+ flow split1, split2;
+ assign {split1, split2} = droplets/2;
+
+ assign out1 = split1;
+ assign out2 = split2;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/DropX/dx7.lfr b/tests/data/DropX/dx7.lfr
new file mode 100644
index 0000000..5507208
--- /dev/null
+++ b/tests/data/DropX/dx7.lfr
@@ -0,0 +1,13 @@
+module dx7(
+ finput in1, in2, pico_in1, pico_in2,
+ foutput out1, out2
+);
+
+ flow merged_droplets, injected_droplets;
+ assign merged_droplets = in1%100 + in2%100;
+
+ assign injected_droplets = (pico_in1 + pico_in2) + merged_droplets;
+
+ assign {out1, out2} = injected_droplets/2;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/DropX/dx8.lfr b/tests/data/DropX/dx8.lfr
new file mode 100644
index 0000000..6770a99
--- /dev/null
+++ b/tests/data/DropX/dx8.lfr
@@ -0,0 +1,25 @@
+// Based on the design by Leslie Huang
+
+module dx8(
+ finput in1, in2, in3, in4, in5, in6,
+ foutput out1, out2, out3
+);
+
+ flow in_mix;
+ assign in_mix = in1 + in2 + in3;
+
+ flow droplets;
+ assign droplets = in_mix % 100;
+
+ flow injected_droplets;
+ assign injected_droplets = (in6 + (in5 + (in4 + droplets)));
+
+ flow mixed_droplets;
+
+ #MAP "MIXER" "~"
+ assign mixed_droplets = ~injected_droplets;
+ flow temp;
+ assign temp = mixed_droplets - out2;
+ assign out3 = temp - out1;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/DropX/dx9.lfr b/tests/data/DropX/dx9.lfr
new file mode 100644
index 0000000..761e8e3
--- /dev/null
+++ b/tests/data/DropX/dx9.lfr
@@ -0,0 +1,17 @@
+// Based on the design by David McIntyre
+
+module dx9(
+ finput in1, in2, in3,
+ foutput out1, out2
+);
+
+
+ flow merged_droplets;
+ assign merged_droplets = in1 % 100 + in2 % 50;
+
+ flow injected_droplets;
+ assign injected_droplets = merged_droplets + in3;
+
+ assign out2 = injected_droplets - out1;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/DropX/figs/dx1.dot b/tests/data/DropX/figs/dx1.dot
new file mode 100644
index 0000000..df453bd
--- /dev/null
+++ b/tests/data/DropX/figs/dx1.dot
@@ -0,0 +1,15 @@
+strict digraph "" {
+ in1 -> "in1_METER_(%)_60";
+ in2 -> "base_droplets_MIX_(+)_in2_61";
+ base_droplets -> "base_droplets_MIX_(+)_in2_61";
+ injected_droplets -> "injected_droplets_PROCESS_(~)_62";
+ incubated_droplets -> "discarded_droplets_SIEVE_(-)_incubated_droplets_63";
+ sorted_droplets -> out1;
+ discarded_droplets -> out2;
+ "in1_METER_(%)_60" -> base_droplets;
+ val_1 -> "in1_METER_(%)_60";
+ "base_droplets_MIX_(+)_in2_61" -> injected_droplets;
+ "injected_droplets_PROCESS_(~)_62" -> incubated_droplets;
+ "discarded_droplets_SIEVE_(-)_incubated_droplets_63" -> sorted_droplets;
+ "discarded_droplets_SIEVE_(-)_incubated_droplets_63" -> discarded_droplets;
+}
diff --git a/tests/data/DropX/figs/dx1.dot.pdf b/tests/data/DropX/figs/dx1.dot.pdf
new file mode 100644
index 0000000..d8c9cab
Binary files /dev/null and b/tests/data/DropX/figs/dx1.dot.pdf differ
diff --git a/tests/data/DropX/figs/dx10.dot b/tests/data/DropX/figs/dx10.dot
new file mode 100644
index 0000000..ffc47b4
--- /dev/null
+++ b/tests/data/DropX/figs/dx10.dot
@@ -0,0 +1,10 @@
+strict digraph "" {
+ in1 -> "in1_METER_(%)_112";
+ in2 -> "in1_METER_(%)_112_MIX_(+)_in2_113";
+ temp -> "out2_SIEVE_(-)_temp_114";
+ "in1_METER_(%)_112" -> "in1_METER_(%)_112_MIX_(+)_in2_113";
+ val_1 -> "in1_METER_(%)_112";
+ "in1_METER_(%)_112_MIX_(+)_in2_113" -> temp;
+ "out2_SIEVE_(-)_temp_114" -> out1;
+ "out2_SIEVE_(-)_temp_114" -> out2;
+}
diff --git a/tests/data/DropX/figs/dx10.dot.pdf b/tests/data/DropX/figs/dx10.dot.pdf
new file mode 100644
index 0000000..f894904
Binary files /dev/null and b/tests/data/DropX/figs/dx10.dot.pdf differ
diff --git a/tests/data/DropX/figs/dx11.dot b/tests/data/DropX/figs/dx11.dot
new file mode 100644
index 0000000..cd157e3
--- /dev/null
+++ b/tests/data/DropX/figs/dx11.dot
@@ -0,0 +1,19 @@
+strict digraph "" {
+ in1 -> "in1_METER_(%)_115";
+ in2 -> "in1_METER_(%)_115_MIX_(+)_in2_116";
+ in3 -> "in3_MIX_(+)_temp_winners_119";
+ injected_droplets -> "injected_droplets_PROCESS_(~)_117";
+ "in1_METER_(%)_115" -> "in1_METER_(%)_115_MIX_(+)_in2_116";
+ val_1 -> "in1_METER_(%)_115";
+ "in1_METER_(%)_115_MIX_(+)_in2_116" -> injected_droplets;
+ sort_candidates1 -> "sort_candidates1_SIEVE_(-)_waste1_118";
+ sort_candidates2 -> "sort_candidates2_SIEVE_(-)_waste2_121";
+ temp_winners -> "in3_MIX_(+)_temp_winners_119";
+ "injected_droplets_PROCESS_(~)_117" -> sort_candidates1;
+ "sort_candidates1_SIEVE_(-)_waste1_118" -> waste1;
+ "sort_candidates1_SIEVE_(-)_waste1_118" -> temp_winners;
+ "in3_MIX_(+)_temp_winners_119" -> "in3_MIX_(+)_temp_winners_119_PROCESS_(~)_120";
+ "in3_MIX_(+)_temp_winners_119_PROCESS_(~)_120" -> sort_candidates2;
+ "sort_candidates2_SIEVE_(-)_waste2_121" -> waste2;
+ "sort_candidates2_SIEVE_(-)_waste2_121" -> final_winners;
+}
diff --git a/tests/data/DropX/figs/dx11.dot.pdf b/tests/data/DropX/figs/dx11.dot.pdf
new file mode 100644
index 0000000..27fe0eb
Binary files /dev/null and b/tests/data/DropX/figs/dx11.dot.pdf differ
diff --git a/tests/data/DropX/figs/dx12.dot b/tests/data/DropX/figs/dx12.dot
new file mode 100644
index 0000000..2102638
--- /dev/null
+++ b/tests/data/DropX/figs/dx12.dot
@@ -0,0 +1,17 @@
+strict digraph "" {
+ plasmids -> "plasmids_METER_(%)_122";
+ dig1 -> "dig1_MIX_(+)_enc_plasmids_123";
+ dig2 -> "dig1_MIX_(+)_enc_plasmids_123_MIX_(+)_dig2_124";
+ enc_plasmids -> "dig1_MIX_(+)_enc_plasmids_123";
+ injected_dig -> "injected_dig_PROCESS_(~)_125";
+ incubated_plasmids -> "discarded_droplets_SIEVE_(-)_incubated_plasmids_126";
+ digest_plasmids -> dig_plasmids;
+ discarded_droplets -> waste;
+ "plasmids_METER_(%)_122" -> enc_plasmids;
+ val_1 -> "plasmids_METER_(%)_122";
+ "dig1_MIX_(+)_enc_plasmids_123" -> "dig1_MIX_(+)_enc_plasmids_123_MIX_(+)_dig2_124";
+ "dig1_MIX_(+)_enc_plasmids_123_MIX_(+)_dig2_124" -> injected_dig;
+ "injected_dig_PROCESS_(~)_125" -> incubated_plasmids;
+ "discarded_droplets_SIEVE_(-)_incubated_plasmids_126" -> digest_plasmids;
+ "discarded_droplets_SIEVE_(-)_incubated_plasmids_126" -> discarded_droplets;
+}
diff --git a/tests/data/DropX/figs/dx12.dot.pdf b/tests/data/DropX/figs/dx12.dot.pdf
new file mode 100644
index 0000000..6400deb
Binary files /dev/null and b/tests/data/DropX/figs/dx12.dot.pdf differ
diff --git a/tests/data/DropX/figs/dx13.dot b/tests/data/DropX/figs/dx13.dot
new file mode 100644
index 0000000..bc3d846
--- /dev/null
+++ b/tests/data/DropX/figs/dx13.dot
@@ -0,0 +1,31 @@
+strict digraph "" {
+ in1 -> "in1_METER_(%)_127";
+ in2 -> "in2_MIX_(+)_mix_1_129";
+ in3 -> "in3_MIX_(+)_sorted_1_132";
+ droplets_1 -> "droplets_1_PROCESS_(~)_128";
+ mix_1 -> "in2_MIX_(+)_mix_1_129";
+ pico_1 -> "pico_1_PROCESS_(~)_130";
+ mix_2 -> "mix_2_SIEVE_(-)_sorted_trash_1_131";
+ sorted_trash_1 -> out1;
+ sorted_1 -> "in3_MIX_(+)_sorted_1_132";
+ pico_2 -> "pico_2_PROCESS_(~)_133";
+ mix_3 -> "mix_3_SIEVE_(-)_sorted_trash_2_134";
+ sorted_trash_2 -> out2;
+ sorted_2 -> "sorted_2_DIVIDE_(/)_135";
+ splitter_1 -> out3;
+ splitter_2 -> out4;
+ "in1_METER_(%)_127" -> droplets_1;
+ val_1 -> "in1_METER_(%)_127";
+ "droplets_1_PROCESS_(~)_128" -> mix_1;
+ "in2_MIX_(+)_mix_1_129" -> pico_1;
+ "pico_1_PROCESS_(~)_130" -> mix_2;
+ "mix_2_SIEVE_(-)_sorted_trash_1_131" -> sorted_trash_1;
+ "mix_2_SIEVE_(-)_sorted_trash_1_131" -> sorted_1;
+ "in3_MIX_(+)_sorted_1_132" -> pico_2;
+ "pico_2_PROCESS_(~)_133" -> mix_3;
+ "mix_3_SIEVE_(-)_sorted_trash_2_134" -> sorted_trash_2;
+ "mix_3_SIEVE_(-)_sorted_trash_2_134" -> sorted_2;
+ "sorted_2_DIVIDE_(/)_135" -> splitter_1;
+ "sorted_2_DIVIDE_(/)_135" -> splitter_2;
+ val_2 -> "sorted_2_DIVIDE_(/)_135";
+}
diff --git a/tests/data/DropX/figs/dx13.dot.pdf b/tests/data/DropX/figs/dx13.dot.pdf
new file mode 100644
index 0000000..ac88b39
Binary files /dev/null and b/tests/data/DropX/figs/dx13.dot.pdf differ
diff --git a/tests/data/DropX/figs/dx14.dot b/tests/data/DropX/figs/dx14.dot
new file mode 100644
index 0000000..a020bc5
--- /dev/null
+++ b/tests/data/DropX/figs/dx14.dot
@@ -0,0 +1,21 @@
+strict digraph "" {
+ in1 -> "in1_MIX_(+)_in2_136";
+ in2 -> "in1_MIX_(+)_in2_136";
+ in3 -> "in1_MIX_(+)_in2_136_MIX_(+)_in3_137";
+ input_mix -> "input_mix_PROCESS_(~)_138";
+ "in1_MIX_(+)_in2_136" -> "in1_MIX_(+)_in2_136_MIX_(+)_in3_137";
+ "in1_MIX_(+)_in2_136_MIX_(+)_in3_137" -> input_mix;
+ droplet_inputs_0 -> "droplet_inputs_0_METER_(%)_139";
+ droplet_inputs_1 -> "droplet_inputs_1_METER_(%)_140";
+ "input_mix_PROCESS_(~)_138" -> droplet_inputs_0;
+ "input_mix_PROCESS_(~)_138" -> droplet_inputs_1;
+ join -> "join_SIEVE_(-)_waste_143";
+ "droplet_inputs_0_METER_(%)_139" -> "droplet_inputs_0_METER_(%)_139_PROCESS_(~)_141";
+ val_1 -> "droplet_inputs_0_METER_(%)_139";
+ "droplet_inputs_1_METER_(%)_140" -> "droplet_inputs_1_METER_(%)_140_PROCESS_(~)_142";
+ val_2 -> "droplet_inputs_1_METER_(%)_140";
+ "droplet_inputs_0_METER_(%)_139_PROCESS_(~)_141" -> join;
+ "droplet_inputs_1_METER_(%)_140_PROCESS_(~)_142" -> join;
+ "join_SIEVE_(-)_waste_143" -> waste;
+ "join_SIEVE_(-)_waste_143" -> keep;
+}
diff --git a/tests/data/DropX/figs/dx14.dot.pdf b/tests/data/DropX/figs/dx14.dot.pdf
new file mode 100644
index 0000000..d5e41c4
Binary files /dev/null and b/tests/data/DropX/figs/dx14.dot.pdf differ
diff --git a/tests/data/DropX/figs/dx15.dot b/tests/data/DropX/figs/dx15.dot
new file mode 100644
index 0000000..c9d5e03
--- /dev/null
+++ b/tests/data/DropX/figs/dx15.dot
@@ -0,0 +1,8 @@
+strict digraph "" {
+ in1 -> "in1_METER_(%)_144";
+ "in1_METER_(%)_144" -> "in1_METER_(%)_144_PROCESS_(~)_145";
+ val_1 -> "in1_METER_(%)_144";
+ "in1_METER_(%)_144_PROCESS_(~)_145" -> "in1_METER_(%)_144_PROCESS_(~)_145_SIEVE_(-)_waste_146";
+ "in1_METER_(%)_144_PROCESS_(~)_145_SIEVE_(-)_waste_146" -> collection;
+ "in1_METER_(%)_144_PROCESS_(~)_145_SIEVE_(-)_waste_146" -> waste;
+}
diff --git a/tests/data/DropX/figs/dx15.dot.pdf b/tests/data/DropX/figs/dx15.dot.pdf
new file mode 100644
index 0000000..cf296ea
Binary files /dev/null and b/tests/data/DropX/figs/dx15.dot.pdf differ
diff --git a/tests/data/DropX/figs/dx2.dot b/tests/data/DropX/figs/dx2.dot
new file mode 100644
index 0000000..0788770
--- /dev/null
+++ b/tests/data/DropX/figs/dx2.dot
@@ -0,0 +1,16 @@
+strict digraph "" {
+ in1 -> "in1_METER_(%)_64";
+ in2 -> "in2_METER_(%)_65";
+ droplets1 -> "droplets1_MIX_(+)_droplets2_66";
+ droplets2 -> "droplets1_MIX_(+)_droplets2_66";
+ merged_droplets -> "merged_droplets_PROCESS_(~)_67";
+ incubated_droplets -> "incubated_droplets_SIEVE_(-)_out2_68";
+ "in1_METER_(%)_64" -> droplets1;
+ val_1 -> "in1_METER_(%)_64";
+ "in2_METER_(%)_65" -> droplets2;
+ val_2 -> "in2_METER_(%)_65";
+ "droplets1_MIX_(+)_droplets2_66" -> merged_droplets;
+ "merged_droplets_PROCESS_(~)_67" -> incubated_droplets;
+ "incubated_droplets_SIEVE_(-)_out2_68" -> out1;
+ "incubated_droplets_SIEVE_(-)_out2_68" -> out2;
+}
diff --git a/tests/data/DropX/figs/dx2.dot.pdf b/tests/data/DropX/figs/dx2.dot.pdf
new file mode 100644
index 0000000..6b475b0
Binary files /dev/null and b/tests/data/DropX/figs/dx2.dot.pdf differ
diff --git a/tests/data/DropX/figs/dx3.dot b/tests/data/DropX/figs/dx3.dot
new file mode 100644
index 0000000..20a673b
--- /dev/null
+++ b/tests/data/DropX/figs/dx3.dot
@@ -0,0 +1,17 @@
+strict digraph "" {
+ in1 -> "in1_METER_(%)_69";
+ in2 -> "in2_MIX_(+)_split1_71";
+ in3 -> "in3_MIX_(+)_split2_72";
+ droplets -> "droplets_DIVIDE_(/)_70";
+ split1 -> "in2_MIX_(+)_split1_71";
+ split2 -> "in3_MIX_(+)_split2_72";
+ "in1_METER_(%)_69" -> droplets;
+ val_1 -> "in1_METER_(%)_69";
+ "droplets_DIVIDE_(/)_70" -> split1;
+ "droplets_DIVIDE_(/)_70" -> split2;
+ val_2 -> "droplets_DIVIDE_(/)_70";
+ injected_droplets1 -> out1;
+ injected_droplets2 -> out2;
+ "in2_MIX_(+)_split1_71" -> injected_droplets1;
+ "in3_MIX_(+)_split2_72" -> injected_droplets2;
+}
diff --git a/tests/data/DropX/figs/dx3.dot.pdf b/tests/data/DropX/figs/dx3.dot.pdf
new file mode 100644
index 0000000..50a0e75
Binary files /dev/null and b/tests/data/DropX/figs/dx3.dot.pdf differ
diff --git a/tests/data/DropX/figs/dx4.dot b/tests/data/DropX/figs/dx4.dot
new file mode 100644
index 0000000..6149615
--- /dev/null
+++ b/tests/data/DropX/figs/dx4.dot
@@ -0,0 +1,26 @@
+strict digraph "" {
+ in1 -> "in1_METER_(%)_77";
+ pico_in1 -> "pico_in1_MIX_(+)_pico_in2_73";
+ pico_in2 -> "pico_in1_MIX_(+)_pico_in2_73";
+ pico_in3 -> "pico_in1_MIX_(+)_pico_in2_73_MIX_(+)_pico_in3_74";
+ pico_in3 -> "pico_in1_MIX_(+)_pico_in2_73_MIX_(+)_pico_in3_74_MIX_(+)_pico_in3_75";
+ pico_in4 -> "pico_in1_MIX_(+)_pico_in2_73_MIX_(+)_pico_in3_74_MIX_(+)_pico_in3_75_MIX_(+)_pico_in4_76";
+ pico_mix -> "droplets_MIX_(+)_pico_mix_78";
+ "pico_in1_MIX_(+)_pico_in2_73" -> "pico_in1_MIX_(+)_pico_in2_73_MIX_(+)_pico_in3_74";
+ "pico_in1_MIX_(+)_pico_in2_73_MIX_(+)_pico_in3_74" -> "pico_in1_MIX_(+)_pico_in2_73_MIX_(+)_pico_in3_74_MIX_(+)_pico_in3_75";
+ "pico_in1_MIX_(+)_pico_in2_73_MIX_(+)_pico_in3_74_MIX_(+)_pico_in3_75" -> "pico_in1_MIX_(+)_pico_in2_73_MIX_(+)_pico_in3_74_MIX_(+)_pico_in3_75_MIX_(+)_pico_in4_76";
+ "pico_in1_MIX_(+)_pico_in2_73_MIX_(+)_pico_in3_74_MIX_(+)_pico_in3_75_MIX_(+)_pico_in4_76" -> pico_mix;
+ droplets -> "droplets_MIX_(+)_pico_mix_78";
+ "in1_METER_(%)_77" -> droplets;
+ val_1 -> "in1_METER_(%)_77";
+ injected_droplets -> "injected_droplets_SIEVE_(-)_sort_waste_temp_79";
+ "droplets_MIX_(+)_pico_mix_78" -> injected_droplets;
+ sort_keep_temp -> "sort_keep_temp_SIEVE_(-)_sort_waste1_80";
+ sort_waste_temp -> "sort_waste2_SIEVE_(-)_sort_waste_temp_81";
+ "injected_droplets_SIEVE_(-)_sort_waste_temp_79" -> sort_keep_temp;
+ "injected_droplets_SIEVE_(-)_sort_waste_temp_79" -> sort_waste_temp;
+ "sort_keep_temp_SIEVE_(-)_sort_waste1_80" -> sort_keep1;
+ "sort_keep_temp_SIEVE_(-)_sort_waste1_80" -> sort_waste1;
+ "sort_waste2_SIEVE_(-)_sort_waste_temp_81" -> sort_keep2;
+ "sort_waste2_SIEVE_(-)_sort_waste_temp_81" -> sort_waste2;
+}
diff --git a/tests/data/DropX/figs/dx4.dot.pdf b/tests/data/DropX/figs/dx4.dot.pdf
new file mode 100644
index 0000000..2d8c7c2
Binary files /dev/null and b/tests/data/DropX/figs/dx4.dot.pdf differ
diff --git a/tests/data/DropX/figs/dx5.dot b/tests/data/DropX/figs/dx5.dot
new file mode 100644
index 0000000..3740e0b
--- /dev/null
+++ b/tests/data/DropX/figs/dx5.dot
@@ -0,0 +1,19 @@
+strict digraph "" {
+ in1 -> "in1_METER_(%)_82";
+ in2 -> "in1_METER_(%)_82_MIX_(+)_in2_83";
+ injected_droplets -> "injected_droplets_DIVIDE_(/)_84";
+ "in1_METER_(%)_82" -> "in1_METER_(%)_82_MIX_(+)_in2_83";
+ val_1 -> "in1_METER_(%)_82";
+ "in1_METER_(%)_82_MIX_(+)_in2_83" -> injected_droplets;
+ split1 -> "split1_PROCESS_(~)_85";
+ split2 -> "split2_PROCESS_(~)_87";
+ "injected_droplets_DIVIDE_(/)_84" -> split1;
+ "injected_droplets_DIVIDE_(/)_84" -> split2;
+ val_2 -> "injected_droplets_DIVIDE_(/)_84";
+ "split1_PROCESS_(~)_85" -> "sort_waste1_SIEVE_(-)_split1_PROCESS_(~)_85_86";
+ "sort_waste1_SIEVE_(-)_split1_PROCESS_(~)_85_86" -> sort_keep1;
+ "sort_waste1_SIEVE_(-)_split1_PROCESS_(~)_85_86" -> sort_waste1;
+ "split2_PROCESS_(~)_87" -> "sort_waste2_SIEVE_(-)_split2_PROCESS_(~)_87_88";
+ "sort_waste2_SIEVE_(-)_split2_PROCESS_(~)_87_88" -> sort_keep2;
+ "sort_waste2_SIEVE_(-)_split2_PROCESS_(~)_87_88" -> sort_waste2;
+}
diff --git a/tests/data/DropX/figs/dx5.dot.pdf b/tests/data/DropX/figs/dx5.dot.pdf
new file mode 100644
index 0000000..dea3cad
Binary files /dev/null and b/tests/data/DropX/figs/dx5.dot.pdf differ
diff --git a/tests/data/DropX/figs/dx6.dot b/tests/data/DropX/figs/dx6.dot
new file mode 100644
index 0000000..02407aa
--- /dev/null
+++ b/tests/data/DropX/figs/dx6.dot
@@ -0,0 +1,14 @@
+strict digraph "" {
+ in1 -> "in1_MIX_(+)_in2_89";
+ in2 -> "in1_MIX_(+)_in2_89";
+ mix -> "mix_METER_(%)_90";
+ "in1_MIX_(+)_in2_89" -> mix;
+ droplets -> "droplets_DIVIDE_(/)_91";
+ "mix_METER_(%)_90" -> droplets;
+ val_1 -> "mix_METER_(%)_90";
+ split1 -> out1;
+ split2 -> out2;
+ "droplets_DIVIDE_(/)_91" -> split1;
+ "droplets_DIVIDE_(/)_91" -> split2;
+ val_2 -> "droplets_DIVIDE_(/)_91";
+}
diff --git a/tests/data/DropX/figs/dx6.dot.pdf b/tests/data/DropX/figs/dx6.dot.pdf
new file mode 100644
index 0000000..c5d5c7d
Binary files /dev/null and b/tests/data/DropX/figs/dx6.dot.pdf differ
diff --git a/tests/data/DropX/figs/dx7.dot b/tests/data/DropX/figs/dx7.dot
new file mode 100644
index 0000000..6f4e9d1
--- /dev/null
+++ b/tests/data/DropX/figs/dx7.dot
@@ -0,0 +1,18 @@
+strict digraph "" {
+ in1 -> "in1_METER_(%)_92";
+ in2 -> "in2_METER_(%)_93";
+ pico_in1 -> "pico_in1_MIX_(+)_pico_in2_95";
+ pico_in2 -> "pico_in1_MIX_(+)_pico_in2_95";
+ merged_droplets -> "merged_droplets_MIX_(+)_pico_in1_MIX_(+)_pico_in2_95_96";
+ injected_droplets -> "injected_droplets_DIVIDE_(/)_97";
+ "in1_METER_(%)_92" -> "in1_METER_(%)_92_MIX_(+)_in2_METER_(%)_93_94";
+ val_1 -> "in1_METER_(%)_92";
+ "in2_METER_(%)_93" -> "in1_METER_(%)_92_MIX_(+)_in2_METER_(%)_93_94";
+ val_2 -> "in2_METER_(%)_93";
+ "in1_METER_(%)_92_MIX_(+)_in2_METER_(%)_93_94" -> merged_droplets;
+ "pico_in1_MIX_(+)_pico_in2_95" -> "merged_droplets_MIX_(+)_pico_in1_MIX_(+)_pico_in2_95_96";
+ "merged_droplets_MIX_(+)_pico_in1_MIX_(+)_pico_in2_95_96" -> injected_droplets;
+ "injected_droplets_DIVIDE_(/)_97" -> out1;
+ "injected_droplets_DIVIDE_(/)_97" -> out2;
+ val_3 -> "injected_droplets_DIVIDE_(/)_97";
+}
diff --git a/tests/data/DropX/figs/dx7.dot.pdf b/tests/data/DropX/figs/dx7.dot.pdf
new file mode 100644
index 0000000..377e926
Binary files /dev/null and b/tests/data/DropX/figs/dx7.dot.pdf differ
diff --git a/tests/data/DropX/figs/dx8.dot b/tests/data/DropX/figs/dx8.dot
new file mode 100644
index 0000000..eb31d08
--- /dev/null
+++ b/tests/data/DropX/figs/dx8.dot
@@ -0,0 +1,25 @@
+strict digraph "" {
+ in1 -> "in1_MIX_(+)_in2_98";
+ in2 -> "in1_MIX_(+)_in2_98";
+ in3 -> "in1_MIX_(+)_in2_98_MIX_(+)_in3_99";
+ in4 -> "droplets_MIX_(+)_in4_101";
+ in5 -> "droplets_MIX_(+)_in4_101_MIX_(+)_in5_102";
+ in6 -> "droplets_MIX_(+)_in4_101_MIX_(+)_in5_102_MIX_(+)_in6_103";
+ in_mix -> "in_mix_METER_(%)_100";
+ "in1_MIX_(+)_in2_98" -> "in1_MIX_(+)_in2_98_MIX_(+)_in3_99";
+ "in1_MIX_(+)_in2_98_MIX_(+)_in3_99" -> in_mix;
+ droplets -> "droplets_MIX_(+)_in4_101";
+ "in_mix_METER_(%)_100" -> droplets;
+ val_1 -> "in_mix_METER_(%)_100";
+ injected_droplets -> "injected_droplets_PROCESS_(~)_104";
+ "droplets_MIX_(+)_in4_101" -> "droplets_MIX_(+)_in4_101_MIX_(+)_in5_102";
+ "droplets_MIX_(+)_in4_101_MIX_(+)_in5_102" -> "droplets_MIX_(+)_in4_101_MIX_(+)_in5_102_MIX_(+)_in6_103";
+ "droplets_MIX_(+)_in4_101_MIX_(+)_in5_102_MIX_(+)_in6_103" -> injected_droplets;
+ mixed_droplets -> "mixed_droplets_SIEVE_(-)_out2_105";
+ "injected_droplets_PROCESS_(~)_104" -> mixed_droplets;
+ temp -> "out1_SIEVE_(-)_temp_106";
+ "mixed_droplets_SIEVE_(-)_out2_105" -> out2;
+ "mixed_droplets_SIEVE_(-)_out2_105" -> temp;
+ "out1_SIEVE_(-)_temp_106" -> out1;
+ "out1_SIEVE_(-)_temp_106" -> out3;
+}
diff --git a/tests/data/DropX/figs/dx8.dot.pdf b/tests/data/DropX/figs/dx8.dot.pdf
new file mode 100644
index 0000000..7b55f7f
Binary files /dev/null and b/tests/data/DropX/figs/dx8.dot.pdf differ
diff --git a/tests/data/DropX/figs/dx9.dot b/tests/data/DropX/figs/dx9.dot
new file mode 100644
index 0000000..53e8516
--- /dev/null
+++ b/tests/data/DropX/figs/dx9.dot
@@ -0,0 +1,15 @@
+strict digraph "" {
+ in1 -> "in1_METER_(%)_107";
+ in2 -> "in2_METER_(%)_108";
+ in3 -> "in3_MIX_(+)_merged_droplets_110";
+ merged_droplets -> "in3_MIX_(+)_merged_droplets_110";
+ "in1_METER_(%)_107" -> "in1_METER_(%)_107_MIX_(+)_in2_METER_(%)_108_109";
+ val_1 -> "in1_METER_(%)_107";
+ "in2_METER_(%)_108" -> "in1_METER_(%)_107_MIX_(+)_in2_METER_(%)_108_109";
+ val_2 -> "in2_METER_(%)_108";
+ "in1_METER_(%)_107_MIX_(+)_in2_METER_(%)_108_109" -> merged_droplets;
+ injected_droplets -> "injected_droplets_SIEVE_(-)_out1_111";
+ "in3_MIX_(+)_merged_droplets_110" -> injected_droplets;
+ "injected_droplets_SIEVE_(-)_out1_111" -> out1;
+ "injected_droplets_SIEVE_(-)_out1_111" -> out2;
+}
diff --git a/tests/data/DropX/figs/dx9.dot.pdf b/tests/data/DropX/figs/dx9.dot.pdf
new file mode 100644
index 0000000..f3ab7db
Binary files /dev/null and b/tests/data/DropX/figs/dx9.dot.pdf differ
diff --git a/tests/data/DropX/netlists/Standard Sizes.md b/tests/data/DropX/netlists/Standard Sizes.md
new file mode 100644
index 0000000..4deff71
--- /dev/null
+++ b/tests/data/DropX/netlists/Standard Sizes.md
@@ -0,0 +1,101 @@
+# NOZZLE DROPLET GENERATOR
+
+```
+orificeSize=150
+orificeLength=375
+oilInputWidth=600
+waterInputWidth=375
+outputWidth=300
+outputLength=5000
+height=300
+```
+
+# MIXER
+
+```
+bendSpacing=600
+numberOfBends=5
+channelWidth=300
+bendLength=2000
+height=300
+```
+
+# DROPLET SORTER
+
+```
+height=300
+inletWidth=300
+inletLength=4000
+inletLength=4000
+electrodeDistance=1000
+electrodeWidth=700
+electrodeLength=5000
+outletWidth=300
+angle=45
+wasteWidth=600
+outputLength=4000
+keepWidth=600
+pressureWidth=1000
+numberofDistributors=5
+channelDepth=300
+electrodeDepth=300
+pressureDepth=200
+```
+
+# DROPLET CAPACITANCE SENSOR
+
+```
+height=300
+inletWidth=300
+inletLength=10000
+electrodeWidth=1500
+electrodeLength=4000
+electrodeDistance=500
+sensorWidth=1000
+sensorLength=3000
+channelDepth=300
+electrodeDepth=300
+```
+
+# PICOINJECTOR
+
+```
+height=300
+injectorWidth=1000
+width=10000
+injectorWidth=1000
+injectorLength=5000
+dropletWidth=100
+nozzleWidth=50
+nozzleLength=500
+electrodeDistance=500
+electrodeWidth=800
+electrodeLength=3000
+```
+
+# DROPLET SPLITTER
+```
+height=30
+inletWidth=300
+inletLength=2000
+outletWidth1=300
+outletLength1=2000
+outletWidth2=300
+outletLength2=2000
+```
+
+# DROPLET MERGER
+```
+height=200
+inletWidth=300
+inletLength=4000
+electrodeWidth=1000
+electrodeLength=5000
+electrodeDistance=800
+outletWidth=300
+outletLength=4000
+chamberHeight=800
+chamberLength=800
+channelDepth=300
+electrodeDepth=200
+```
\ No newline at end of file
diff --git a/tests/data/DropX/netlists/dx10_ref.mint b/tests/data/DropX/netlists/dx10_ref.mint
new file mode 100644
index 0000000..fbcd0ae
--- /dev/null
+++ b/tests/data/DropX/netlists/dx10_ref.mint
@@ -0,0 +1,68 @@
+DEVICE dx10_ref
+
+LAYER FLOW
+
+PORT port_oil1 portRadius=2000;
+PORT port_water1 portRadius=2000;
+PORT port_oil2 portRadius=2000;
+
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_1
+ orificeSize=150
+ orificeLength=375
+ oilInputWidth=600
+ waterInputWidth=375
+ outputWidth=300
+ outputLength=5000
+ height=300;
+
+CHANNEL connection_1 from port_oil1 to nozzle_droplet_generator_1 1 channelWidth=300;
+CHANNEL connection_2 from port_water1 to nozzle_droplet_generator_1 4 channelWidth=300;
+CHANNEL connection_3 from port_oil2 to nozzle_droplet_generator_1 3 channelWidth=300;
+
+PORT port_injector1 portRadius=2000;
+
+PICOINJECTOR pico_injector_1
+ height=300
+ injectorWidth=1000
+ width=10000
+ injectorWidth=1000
+ injectorLength=5000
+ dropletWidth=100
+ nozzleWidth=50
+ nozzleLength=500
+ electrodeDistance=500
+ electrodeWidth=800
+ electrodeLength=3000;
+
+CHANNEL connection_4 from nozzle_droplet_generator_1 2 to pico_injector_1 1 channelWidth=300;
+CHANNEL connection_5 from port_injector1 to pico_injector_1 3 channelWidth=300;
+
+DROPLET SORTER droplet_sorter_1
+ height=300
+ inletWidth=300
+ inletLength=4000
+ inletLength=4000
+ electrodeDistance=1000
+ electrodeWidth=700
+ electrodeLength=5000
+ outletWidth=300
+ angle=45
+ wasteWidth=600
+ outputLength=4000
+ keepWidth=600
+ pressureWidth=1000
+ numberofDistributors=5
+ channelDepth=300
+ electrodeDepth=300
+ pressureDepth=200;
+
+CHANNEL connection_6 from pico_injector_1 2 to droplet_sorter_1 1 channelWidth=300;
+
+PORT port_out_1 portRadius=2000;
+PORT port_out_2 portRadius=2000;
+
+CHANNEL connection_7 from droplet_sorter_1 2 to port_out_1 channelWidth=300;
+CHANNEL connection_8 from droplet_sorter_1 3 to port_out_2 channelWidth=300;
+
+END LAYER
+
diff --git a/tests/data/DropX/netlists/dx11_ref.mint b/tests/data/DropX/netlists/dx11_ref.mint
new file mode 100644
index 0000000..4fac312
--- /dev/null
+++ b/tests/data/DropX/netlists/dx11_ref.mint
@@ -0,0 +1,135 @@
+DEVICE dx11_ref
+
+LAYER FLOW
+
+PORT port_oil1 portRadius=2000;
+PORT port_water1 portRadius=2000;
+PORT port_oil2 portRadius=2000;
+
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_1
+ orificeSize=150
+ orificeLength=375
+ oilInputWidth=600
+ waterInputWidth=375
+ outputWidth=300
+ outputLength=5000
+ height=300;
+
+CHANNEL connection_1 from port_oil1 to nozzle_droplet_generator_1 1 channelWidth=300;
+CHANNEL connection_2 from port_water1 to nozzle_droplet_generator_1 4 channelWidth=300;
+CHANNEL connection_3 from port_oil2 to nozzle_droplet_generator_1 3 channelWidth=300;
+
+
+PORT port_injector1 portRadius=2000;
+PICOINJECTOR pico_injector_1
+ height=300
+ injectorWidth=1000
+ width=10000
+ injectorWidth=1000
+ injectorLength=5000
+ dropletWidth=100
+ nozzleWidth=50
+ nozzleLength=500
+ electrodeDistance=500
+ electrodeWidth=800
+ electrodeLength=3000;
+
+CHANNEL connection_4 from port_injector1 to pico_injector_1 3 channelWidth=300;
+
+MIXER mix_1
+ bendSpacing=600
+ numberOfBends=5
+ channelWidth=300
+ bendLength=2000
+ height=300;
+
+CHANNEL connection_5 from pico_injector_1 2 to mix_1 1 channelWidth=300;
+CHANNEL connection_6 from nozzle_droplet_generator_1 2 to pico_injector_1 1 channelWidth=300;
+
+DROPLET SORTER droplet_sorter_1
+ inletWidth=300
+ inletLength=4000
+ inletLength=4000
+ electrodeDistance=1000
+ electrodeWidth=700
+ electrodeLength=5000
+ outletWidth=300
+ angle=45
+ wasteWidth=600
+ outputLength=4000
+ keepWidth=600
+ pressureWidth=1000
+ numberofDistributors=5
+ channelDepth=300
+ electrodeDepth=300
+ pressureDepth=200;
+
+CHANNEL connection_7 from mix_1 2 to droplet_sorter_1 1 channelWidth=300;
+
+MIXER mix_2
+ bendSpacing=600
+ numberOfBends=5
+ channelWidth=300
+ bendLength=2000
+ height=300;
+
+CHANNEL connection_8 from droplet_sorter_1 2 to mix_2 1 channelWidth=300;
+
+PORT port_out_waste1 portRadius=2000;
+CHANNEL connection_15 from droplet_sorter_1 2 to port_out_waste1 channelWidth=300;
+
+PORT port_injector2 portRadius=2000;
+PICOINJECTOR pico_injector_2
+ height=300
+ injectorWidth=1000
+ width=10000
+ injectorWidth=1000
+ injectorLength=5000
+ dropletWidth=100
+ nozzleWidth=50
+ nozzleLength=500
+ electrodeDistance=500
+ electrodeWidth=800
+ electrodeLength=3000;
+
+CHANNEL connection_9 from mix_2 2 to pico_injector_2 1 channelWidth=300;
+CHANNEL connection_10 from port_injector2 to pico_injector_2 3 channelWidth=300;
+
+MIXER mix_3
+ bendSpacing=600
+ numberOfBends=5
+ channelWidth=300
+ bendLength=2000
+ height=300;
+
+CHANNEL connection_11 from pico_injector_2 2 to mix_3 1 channelWidth=300;
+
+DROPLET SORTER droplet_sorter_2
+ height=300
+ inletWidth=300
+ inletLength=4000
+ inletLength=4000
+ electrodeDistance=1000
+ electrodeWidth=700
+ electrodeLength=5000
+ outletWidth=300
+ angle=45
+ wasteWidth=600
+ outputLength=4000
+ keepWidth=600
+ pressureWidth=1000
+ numberofDistributors=5
+ channelDepth=300
+ electrodeDepth=300
+ pressureDepth=200;
+
+CHANNEL connection_12 from mix_3 2 to droplet_sorter_2 1 channelWidth=300;
+
+PORT port_out_waste2 portRadius=2000;
+PORT port_out_keep portRadius=2000;
+
+CHANNEL connection_13 from droplet_sorter_2 2 to port_out_waste2 channelWidth=300;
+CHANNEL connection_14 from droplet_sorter_2 3 to port_out_keep channelWidth=300;
+
+END LAYER
+
diff --git a/tests/data/DropX/netlists/dx12_ref.mint b/tests/data/DropX/netlists/dx12_ref.mint
new file mode 100644
index 0000000..957f59d
--- /dev/null
+++ b/tests/data/DropX/netlists/dx12_ref.mint
@@ -0,0 +1,73 @@
+DEVICE dx12_ref
+
+LAYER FLOW
+
+PORT port_oil1 portRadius=2000;
+PORT port_water1 portRadius=2000;
+PORT port_oil2 portRadius=2000;
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_1
+ orificeSize=150
+ orificeLength=375
+ oilInputWidth=600
+ waterInputWidth=375
+ outputWidth=300
+ outputLength=5000
+ height=300;
+
+CHANNEL connection_1 from port_oil1 to nozzle_droplet_generator_1 1 channelWidth=300 channelWidth=300;
+CHANNEL connection_2 from port_water1 to nozzle_droplet_generator_1 4 channelWidth=300 channelWidth=300;
+CHANNEL connection_3 from port_oil2 to nozzle_droplet_generator_1 3 channelWidth=300 channelWidth=300;
+
+PORT port_injector portRadius=2000;
+PICOINJECTOR pico_injector_1
+ height=300
+ injectorWidth=1000
+ width=10000
+ injectorWidth=1000
+ injectorLength=5000
+ dropletWidth=100
+ nozzleWidth=50
+ nozzleLength=500
+ electrodeDistance=500
+ electrodeWidth=800
+ electrodeLength=3000;
+
+CHANNEL connection_4 from port_injector to pico_injector_1 3 channelWidth=300;
+CHANNEL connection_5 from nozzle_droplet_generator_1 2 to pico_injector_1 1 channelWidth=300;
+
+MIXER mixer_1
+ bendSpacing=600
+ numberOfBends=5
+ channelWidth=300
+ bendLength=2000
+ height=300;
+
+CHANNEL connection_6 from pico_injector_1 2 to mixer_1 1 channelWidth=300;
+
+PORT port_out_waste portRadius=2000;
+PORT port_out_keep portRadius=2000;
+DROPLET SORTER droplet_sorter_1
+ height=300
+ inletWidth=300
+ inletLength=4000
+ inletLength=4000
+ electrodeDistance=1000
+ electrodeWidth=700
+ electrodeLength=5000
+ outletWidth=300
+ angle=45
+ wasteWidth=600
+ outputLength=4000
+ keepWidth=600
+ pressureWidth=1000
+ numberofDistributors=5
+ channelDepth=300
+ electrodeDepth=300
+ pressureDepth=200;
+
+CHANNEL connection_7 from mixer_1 2 to droplet_sorter_1 1 channelWidth=300;
+CHANNEL connection_8 from droplet_sorter_1 2 to port_out_waste channelWidth=300;
+CHANNEL connection_9 from droplet_sorter_1 3 to port_out_keep channelWidth=300;
+
+END LAYER
+
diff --git a/tests/data/DropX/netlists/dx13_ref.mint b/tests/data/DropX/netlists/dx13_ref.mint
new file mode 100644
index 0000000..ffa05bb
--- /dev/null
+++ b/tests/data/DropX/netlists/dx13_ref.mint
@@ -0,0 +1,138 @@
+DEVICE dx13_ref
+
+LAYER FLOW
+
+PORT port_oil1, port_oil2, port_water1 portRadius=2000;
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_1 orificeSize=150
+orificeLength=375
+oilInputWidth=600
+waterInputWidth=375
+outputWidth=300
+outputLength=5000
+height=300;
+
+CHANNEL c1 from port_oil1 to nozzle_droplet_generator_1 1 channelWidth=300;
+CHANNEL c2 from port_oil2 to nozzle_droplet_generator_1 3 channelWidth=300;
+CHANNEL c3 from port_water1 to nozzle_droplet_generator_1 4 channelWidth=300;
+
+MIXER mixer_1 bendSpacing=600
+numberOfBends=5
+channelWidth=300
+bendLength=2000
+height=300
+;
+
+CHANNEL c4 from nozzle_droplet_generator_1 to mixer_1 1 channelWidth=300;
+
+PORT port_injector1 portRadius=2000;
+PICOINJECTOR pico_injector_1 height=300
+injectorWidth=1000
+width=10000
+injectorWidth=1000
+injectorLength=5000
+dropletWidth=100
+nozzleWidth=50
+nozzleLength=500
+electrodeDistance=500
+electrodeWidth=800
+electrodeLength=3000;
+
+CHANNEL c5 from port_injector1 to pico_injector_1 3 channelWidth=300;
+
+CHANNEL c6 from mixer_1 2 to pico_injector_1 1 channelWidth=300;
+
+MIXER mixer_2 bendSpacing=600
+numberOfBends=5
+channelWidth=300
+bendLength=2000
+height=300
+;
+
+CHANNEL c7 from pico_injector_1 2 to mixer_2 1 channelWidth=300 channelWidth=300;
+
+PORT port_waste1 portRadius=2000;
+DROPLET SORTER droplet_sorter_1 height=300
+inletWidth=300
+inletLength=4000
+inletLength=4000
+electrodeDistance=1000
+electrodeWidth=700
+electrodeLength=5000
+outletWidth=300
+angle=45
+wasteWidth=600
+outputLength=4000
+keepWidth=600
+pressureWidth=1000
+numberofDistributors=5
+channelDepth=300
+electrodeDepth=300
+pressureDepth=200;
+
+CHANNEL c11 from droplet_sorter_1 2 to port_waste1 channelWidth=300;
+
+CHANNEL c8 from mixer_2 2 to droplet_sorter_1 1 channelWidth=300;
+
+PORT port_injector2 portRadius=2000;
+PICOINJECTOR pico_injector_2 height=300
+injectorWidth=1000
+width=10000
+injectorWidth=1000
+injectorLength=5000
+dropletWidth=100
+nozzleWidth=50
+nozzleLength=500
+electrodeDistance=500
+electrodeWidth=800
+electrodeLength=3000;
+
+CHANNEL c9 from port_injector2 to pico_injector_2 3 channelWidth=300;
+CHANNEL c10 from droplet_sorter_1 3 to pico_injector_2 1 channelWidth=300;
+
+MIXER mixer_3 bendSpacing=600
+numberOfBends=5
+channelWidth=300
+bendLength=2000
+height=300
+;
+
+CHANNEL c10 from pico_injector_2 2 to mixer_3 1 channelWidth=300;
+
+PORT port_waste2 portRadius=2000;
+DROPLET SORTER droplet_sorter_2 height=300
+inletWidth=300
+inletLength=4000
+inletLength=4000
+electrodeDistance=1000
+electrodeWidth=700
+electrodeLength=5000
+outletWidth=300
+angle=45
+wasteWidth=600
+outputLength=4000
+keepWidth=600
+pressureWidth=1000
+numberofDistributors=5
+channelDepth=300
+electrodeDepth=300
+pressureDepth=200;
+
+CHANNEL c12 from mixer_3 2 to droplet_sorter_2 1 channelWidth=300;
+CHANNEL c13 from droplet_sorter_2 2 to port_waste2 channelWidth=300;
+
+DROPLET SPLITTER droplet_splitter_1 height=30
+inletWidth=300
+inletLength=2000
+outletWidth1=300
+outletLength1=2000
+outletWidth2=300
+outletLength2=2000;
+CHANNEL c14 from droplet_sorter_2 3 to droplet_splitter_1 1 channelWidth=300;
+
+PORT port_out1, port_out2 portRadius=2000;
+CHANNEL c15 from droplet_splitter_1 2 to port_out1 channelWidth=300;
+CHANNEL c16 from droplet_splitter_1 3 to port_out2 channelWidth=300 channelWidth=300;
+
+
+END LAYER
+
diff --git a/tests/data/DropX/netlists/dx14_ref.mint b/tests/data/DropX/netlists/dx14_ref.mint
new file mode 100644
index 0000000..666be27
--- /dev/null
+++ b/tests/data/DropX/netlists/dx14_ref.mint
@@ -0,0 +1,73 @@
+DEVICE dx14_ref
+
+LAYER FLOW
+
+PORT port_in1, port_in2, port_in3 portRadius=2000;
+MIXER mixer_in bendSpacing=600
+numberOfBends=5
+channelWidth=300
+bendLength=2000
+height=300;
+
+CHANNEL channel_1 from port_in1 to mixer_in 1 channelWidth=300;
+CHANNEL channel_2 from port_in2 to mixer_in 1 channelWidth=300;
+CHANNEL channel_3 from port_in3 to mixer_in 1 channelWidth=300;
+
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator1 orificeSize=150
+orificeLength=375
+oilInputWidth=600
+waterInputWidth=375
+outputWidth=300
+outputLength=5000
+height=300;
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator2 orificeSize=150
+orificeLength=375
+oilInputWidth=600
+waterInputWidth=375
+outputWidth=300
+outputLength=5000
+height=300;
+
+CHANNEL channel_mixed_1 from mixer_in 2 to nozzle_droplet_generator1 4 channelWidth=300;
+CHANNEL channel_mixed_2 from mixer_in 2 to nozzle_droplet_generator2 4 channelWidth=300;
+
+PORT port_oil1, port_oil2, port_oil3, port_oil4 portRadius=2000;
+CHANNEL channel_oil1 from port_oil1 to nozzle_droplet_generator1 1 channelWidth=300;
+CHANNEL channel_oil2 from port_oil2 to nozzle_droplet_generator1 3 channelWidth=300;
+CHANNEL channel_oil3 from port_oil3 to nozzle_droplet_generator2 1 channelWidth=300;
+CHANNEL channel_oil4 from port_oil4 to nozzle_droplet_generator2 3 channelWidth=300;
+
+MIXER mixer_incubate1, mixer_incubate2 bendSpacing=600
+numberOfBends=5
+channelWidth=300
+bendLength=2000
+height=300;
+CHANNEL channel_incubate1 from nozzle_droplet_generator1 2 to mixer_incubate1 1 channelWidth=300;
+CHANNEL channel_incubate2 from nozzle_droplet_generator2 2 to mixer_incubate2 1 channelWidth=300;
+
+DROPLET SORTER droplet_sorter1 height=300
+inletWidth=300
+inletLength=4000
+inletLength=4000
+electrodeDistance=1000
+electrodeWidth=700
+electrodeLength=5000
+outletWidth=300
+angle=45
+wasteWidth=600
+outputLength=4000
+keepWidth=600
+pressureWidth=1000
+numberofDistributors=5
+channelDepth=300
+electrodeDepth=300
+pressureDepth=200 ;
+CHANNEL channel_incubate3 from mixer_incubate1 1 to droplet_sorter1 1 channelWidth=300;
+CHANNEL channel_incubate4 from mixer_incubate2 1 to droplet_sorter1 1 channelWidth=300;
+
+PORT port_out1, port_out2 portRadius=2000;
+CHANNEL channel_out1 from droplet_sorter1 2 to port_out1 channelWidth=300;
+CHANNEL channel_out2 from droplet_sorter1 3 to port_out2 channelWidth=300;
+
+END LAYER
+
diff --git a/tests/data/DropX/netlists/dx15_ref.mint b/tests/data/DropX/netlists/dx15_ref.mint
new file mode 100644
index 0000000..113f091
--- /dev/null
+++ b/tests/data/DropX/netlists/dx15_ref.mint
@@ -0,0 +1,43 @@
+DEVICE dx15_ref
+
+LAYER FLOW
+
+PORT port_in1, port_in2, port_in3 portRadius=2000 ;
+
+MIXER mixer1 bendSpacing=600
+numberOfBends=5
+channelWidth=300
+bendLength=2000
+height=300 ;
+
+CHANNEL c1 from port_in1 to mixer1 1 channelWidth=300 ;
+CHANNEL c2 from port_in2 to mixer1 1 channelWidth=300 ;
+CHANNEL c3 from port_in3 to mixer1 1 channelWidth=300 ;
+
+DROPLET SORTER droplet_sorter1 height=300
+inletWidth=300
+inletLength=4000
+inletLength=4000
+electrodeDistance=1000
+electrodeWidth=700
+electrodeLength=5000
+outletWidth=300
+angle=45
+wasteWidth=600
+outputLength=4000
+keepWidth=600
+pressureWidth=1000
+numberofDistributors=5
+channelDepth=300
+electrodeDepth=300
+pressureDepth=200;
+
+CHANNEL c4 from mixer1 2 to droplet_sorter1 1 channelWidth=300;
+
+PORT port_out_keep, port_out_waste portRadius=2000;
+
+CHANNEL c5 from droplet_sorter1 3 to port_out_keep 1 channelWidth=300;
+CHANNEL c6 from droplet_sorter1 2 to port_out_waste 1 channelWidth=300;
+
+END LAYER
+
diff --git a/tests/data/DropX/netlists/dx1_ref.mint b/tests/data/DropX/netlists/dx1_ref.mint
new file mode 100644
index 0000000..1ee0034
--- /dev/null
+++ b/tests/data/DropX/netlists/dx1_ref.mint
@@ -0,0 +1,42 @@
+DEVICE dx1_ref
+
+LAYER FLOW
+
+PORT port_oil1 portRadius=2000 ;
+PORT port_oil2 portRadius=2000 ;
+PORT port_water portRadius=2000 ;
+PORT port_injector portRadius=2000 ;
+PORT port_out_waste portRadius=2000 ;
+PORT port_out_keep portRadius=2000 ;
+
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_1 orificeSize=150 orificeLength=375
+ oilInputWidth=600 waterInputWidth=375 outputWidth=300 outputLength=5000 height=300 ;
+
+PICOINJECTOR picoinjector_1 height=300
+ injectorWidth=1000
+ width=10000
+ injectorWidth=1000
+ injectorLength=5000
+ dropletWidth=100
+ nozzleWidth=50
+ nozzleLength=500
+ electrodeDistance=500
+ electrodeWidth=800
+ electrodeLength=3000;
+
+MIXER mixer_1 bendSpacing=600 numberOfBends=5 channelWidth=300 bendLength=2000 height=300;
+
+DROPLET SORTER droplet_sorter_1 ;
+
+CHANNEL connection_1 from port_oil1 to nozzle_droplet_generator_1 1 channelWidth=300 ;
+CHANNEL connection_2 from port_oil2 to nozzle_droplet_generator_1 3 channelWidth=300 ;
+CHANNEL connection_3 from port_water to nozzle_droplet_generator_1 4 channelWidth=300 ;
+CHANNEL connection_4 from port_injector to picoinjector_1 3 channelWidth=300 ;
+CHANNEL connection_5 from nozzle_droplet_generator_1 2 to picoinjector_1 1 channelWidth=300 ;
+CHANNEL connection_6 from picoinjector_1 2 to mixer_1 1 channelWidth=300 ;
+CHANNEL connection_7 from mixer_1 2 to droplet_sorter_1 1 channelWidth=300 ;
+CHANNEL connection_8 from droplet_sorter_1 2 to port_out_waste channelWidth=300 ;
+CHANNEL connection_9 from droplet_sorter_1 3 to port_out_keep channelWidth=300 ;
+
+END LAYER
+
diff --git a/tests/data/DropX/netlists/dx2_ref.mint b/tests/data/DropX/netlists/dx2_ref.mint
new file mode 100644
index 0000000..22a530f
--- /dev/null
+++ b/tests/data/DropX/netlists/dx2_ref.mint
@@ -0,0 +1,59 @@
+DEVICE dx2_ref
+
+LAYER FLOW
+
+PORT port_oil1 portRadius=2000 ;
+PORT port_oil2 portRadius=2000 ;
+PORT port_water1 portRadius=2000 ;
+PORT port_out_waste portRadius=2000 ;
+PORT port_out_keep portRadius=2000 ;
+
+PORT port_oil3 portRadius=2000 ;
+PORT port_oil4 portRadius=2000 ;
+PORT port_water2 portRadius=2000 ;
+
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_1 orificeSize=150 orificeLength=375
+ oilInputWidth=600 waterInputWidth=375 outputWidth=300 outputLength=5000 height=300 ;
+
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_2 orificeSize=150 orificeLength=375
+ oilInputWidth=600 waterInputWidth=375 outputWidth=300 outputLength=5000 height=300 ;
+
+MIXER mixer_1 bendSpacing=600 numberOfBends=5 channelWidth=300 bendLength=2000 height=300;
+
+DROPLET SORTER droplet_sorter_1
+ height=300
+ inletWidth=300
+ inletLength=4000
+ inletLength=4000
+ electrodeDistance=1000
+ electrodeWidth=700
+ electrodeLength=5000
+ outletWidth=300
+ angle=45
+ wasteWidth=600
+ outputLength=4000
+ keepWidth=600
+ pressureWidth=1000
+ numberofDistributors=5
+ channelDepth=300
+ electrodeDepth=300
+ pressureDepth=200;
+
+CHANNEL connection_1 from port_oil1 to nozzle_droplet_generator_1 1 channelWidth=300 ;
+CHANNEL connection_2 from port_oil2 to nozzle_droplet_generator_1 3 channelWidth=300 ;
+CHANNEL connection_3 from port_water1 to nozzle_droplet_generator_1 4 channelWidth=300 ;
+CHANNEL connection_4 from port_water2 to nozzle_droplet_generator_2 4 channelWidth=300 ;
+
+CHANNEL connection_5 from nozzle_droplet_generator_1 2 to mixer_1 1 channelWidth=300 ;
+
+CHANNEL connection_10 from port_oil3 to nozzle_droplet_generator_2 1 channelWidth=300 ;
+CHANNEL connection_11 from port_oil4 to nozzle_droplet_generator_2 3 channelWidth=300 ;
+CHANNEL connection_13 from nozzle_droplet_generator_2 2 to mixer_1 1 channelWidth=300 ;
+
+CHANNEL connection_7 from mixer_1 2 to droplet_sorter_1 1 channelWidth=300 ;
+
+CHANNEL connection_8 from droplet_sorter_1 2 to port_out_waste channelWidth=300 ;
+CHANNEL connection_9 from droplet_sorter_1 3 to port_out_keep channelWidth=300 ;
+
+END LAYER
+
diff --git a/tests/data/DropX/netlists/dx3_ref.mint b/tests/data/DropX/netlists/dx3_ref.mint
new file mode 100644
index 0000000..52893d8
--- /dev/null
+++ b/tests/data/DropX/netlists/dx3_ref.mint
@@ -0,0 +1,65 @@
+DEVICE dx3_ref
+
+LAYER FLOW
+
+PORT port_oil1 portRadius=2000 ;
+PORT port_oil2 portRadius=2000 ;
+PORT port_water portRadius=2000 ;
+
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_1 orificeSize=150 orificeLength=375
+ oilInputWidth=600 waterInputWidth=375 outputWidth=300 outputLength=5000 height=300 ;
+
+CHANNEL connection_1 from port_oil1 to nozzle_droplet_generator_1 1 channelWidth=300 ;
+CHANNEL connection_2 from port_oil2 to nozzle_droplet_generator_1 3 channelWidth=300 ;
+CHANNEL connection_3 from port_water to nozzle_droplet_generator_1 4 channelWidth=300 ;
+
+DROPLET SPLITTER droplet_splitter_1
+ height=30
+ inletWidth=300
+ inletLength=2000
+ outletWidth1=300
+ outletLength1=2000
+ outletWidth2=300
+ outletLength2=2000;
+
+PORT port_injector1 portRadius=2000 ;
+PORT port_injector2 portRadius=2000 ;
+
+PICOINJECTOR picoinjector_1 height=300
+ injectorWidth=1000
+ width=10000
+ injectorWidth=1000
+ injectorLength=5000
+ dropletWidth=100
+ nozzleWidth=50
+ nozzleLength=500
+ electrodeDistance=500
+ electrodeWidth=800
+ electrodeLength=3000;
+
+PICOINJECTOR picoinjector_2 height=300
+ injectorWidth=1000
+ width=10000
+ injectorWidth=1000
+ injectorLength=5000
+ dropletWidth=100
+ nozzleWidth=50
+ nozzleLength=500
+ electrodeDistance=500
+ electrodeWidth=800
+ electrodeLength=3000;
+
+CHANNEL connection_4 from nozzle_droplet_generator_1 2 to droplet_splitter_1 1 channelWidth=300 ;
+CHANNEL connection_5 from droplet_splitter_1 2 to picoinjector_1 1 channelWidth=300 ;
+CHANNEL connection_6 from droplet_splitter_1 3 to picoinjector_2 1 channelWidth=300 ;
+CHANNEL connection_7 from port_injector1 to picoinjector_1 3 channelWidth=300 ;
+CHANNEL connection_8 from port_injector2 to picoinjector_2 3 channelWidth=300 ;
+
+PORT port_out1 portRadius=2000 ;
+PORT port_out2 portRadius=2000 ;
+
+CHANNEL connection_9 from picoinjector_1 2 to port_out1 1 channelWidth=300 ;
+CHANNEL connection_10 from picoinjector_2 2 to port_out2 1 channelWidth=300 ;
+
+END LAYER
+
diff --git a/tests/data/DropX/netlists/dx4_ref.mint b/tests/data/DropX/netlists/dx4_ref.mint
new file mode 100644
index 0000000..84fb3d9
--- /dev/null
+++ b/tests/data/DropX/netlists/dx4_ref.mint
@@ -0,0 +1,131 @@
+DEVICE dx4_ref
+
+LAYER FLOW
+
+PORT port_oil1 portRadius=2000;
+PORT port_oil2 portRadius=2000;
+PORT port_water portRadius=2000;
+
+PORT port_injector1 portRadius=2000;
+PORT port_injector2 portRadius=2000;
+PORT port_injector3 portRadius=2000;
+PORT port_injector4 portRadius=2000;
+
+MIXER mix_1
+ bendSpacing=600
+ numberOfBends=5
+ channelWidth=300
+ bendLength=2000
+ height=300;
+
+CHANNEL connection_4 from port_injector1 to mix_1 1 channelWidth=50;
+CHANNEL connection_5 from port_injector2 to mix_1 1 channelWidth=50;
+CHANNEL connection_6 from port_injector3 to mix_1 1 channelWidth=50;
+CHANNEL connection_7 from port_injector4 to mix_1 1 channelWidth=50;
+
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_1
+ orificeSize=150
+ orificeLength=375
+ oilInputWidth=600
+ waterInputWidth=375
+ outputWidth=300
+ outputLength=5000
+ height=300;
+
+CHANNEL connection_1 from port_oil1 to nozzle_droplet_generator_1 1 channelWidth=300;
+CHANNEL connection_2 from port_oil2 to nozzle_droplet_generator_1 3 channelWidth=300;
+CHANNEL connection_3 from port_water to nozzle_droplet_generator_1 4 channelWidth=300;
+
+PICOINJECTOR pico_injector_1
+ height=300
+ injectorWidth=1000
+ width=10000
+ injectorWidth=1000
+ injectorLength=5000
+ dropletWidth=100
+ nozzleWidth=50
+ nozzleLength=500
+ electrodeDistance=500
+ electrodeWidth=800
+ electrodeLength=3000;
+
+CHANNEL connection_8 from nozzle_droplet_generator_1 2 to pico_injector_1 1 channelWidth=300;
+CHANNEL connection_9 from mix_1 2 to pico_injector_1 3 channelWidth=50;
+
+DROPLET SORTER droplet_sorter_1
+ height=300
+ inletWidth=300
+ inletLength=4000
+ inletLength=4000
+ electrodeDistance=1000
+ electrodeWidth=700
+ electrodeLength=5000
+ outletWidth=300
+ angle=45
+ wasteWidth=600
+ outputLength=4000
+ keepWidth=600
+ pressureWidth=1000
+ numberofDistributors=5
+ channelDepth=300
+ electrodeDepth=300
+ pressureDepth=200;
+
+CHANNEL connection_10 from pico_injector_1 2 to droplet_sorter_1 1 channelWidth=300;
+
+DROPLET SORTER droplet_sorter_2
+ height=300
+ inletWidth=300
+ inletLength=4000
+ inletLength=4000
+ electrodeDistance=1000
+ electrodeWidth=700
+ electrodeLength=5000
+ outletWidth=300
+ angle=45
+ wasteWidth=600
+ outputLength=4000
+ keepWidth=600
+ pressureWidth=1000
+ numberofDistributors=5
+ channelDepth=300
+ electrodeDepth=300
+ pressureDepth=200;
+
+DROPLET SORTER droplet_sorter_3
+ height=300
+ inletWidth=300
+ inletLength=4000
+ inletLength=4000
+ electrodeDistance=1000
+ electrodeWidth=700
+ electrodeLength=5000
+ outletWidth=300
+ angle=45
+ wasteWidth=600
+ outputLength=4000
+ keepWidth=600
+ pressureWidth=1000
+ numberofDistributors=5
+ channelDepth=300
+ electrodeDepth=300
+ pressureDepth=200;
+
+
+CHANNEL connection_11 from droplet_sorter_1 2 to droplet_sorter_2 1 channelWidth=300;
+CHANNEL connection_12 from droplet_sorter_1 3 to droplet_sorter_3 1 channelWidth=300;
+
+PORT port_out_waste1 portRadius=2000;
+PORT port_out_waste2 portRadius=2000;
+
+PORT port_out_keep1 portRadius=2000;
+PORT port_out_keep2 portRadius=2000;
+
+CHANNEL connection_13 from droplet_sorter_2 2 to port_out_waste1 channelWidth=300;
+CHANNEL connection_14 from droplet_sorter_3 2 to port_out_waste2 channelWidth=300;
+
+CHANNEL connection_15 from droplet_sorter_2 3 to port_out_keep1 channelWidth=300;
+CHANNEL connection_16 from droplet_sorter_3 3 to port_out_keep2 channelWidth=300;
+
+END LAYER
+
diff --git a/tests/data/DropX/netlists/dx5_ref.mint b/tests/data/DropX/netlists/dx5_ref.mint
new file mode 100644
index 0000000..1f5a997
--- /dev/null
+++ b/tests/data/DropX/netlists/dx5_ref.mint
@@ -0,0 +1,112 @@
+DEVICE dx5_ref
+
+LAYER FLOW
+
+PORT port_oil1 portRadius=2000;
+PORT port_oil2 portRadius=2000;
+PORT port_water portRadius=2000;
+
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_1
+ orificeSize=150
+ orificeLength=375
+ oilInputWidth=600
+ waterInputWidth=375
+ outputWidth=300
+ outputLength=5000
+ height=300;
+
+CHANNEL connection_1 from port_oil1 to nozzle_droplet_generator_1 1 channelWidth=300;
+CHANNEL connection_2 from port_oil2 to nozzle_droplet_generator_1 3 channelWidth=300;
+CHANNEL connection_3 from port_water to nozzle_droplet_generator_1 4 channelWidth=300;
+
+PICOINJECTOR picoinjector_1
+ height=300
+ injectorWidth=1000
+ width=10000
+ injectorWidth=1000
+ injectorLength=5000
+ dropletWidth=100
+ nozzleWidth=50
+ nozzleLength=500
+ electrodeDistance=500
+ electrodeWidth=800
+ electrodeLength=3000
+;
+
+CHANNEL connection_4 from nozzle_droplet_generator_1 2 to picoinjector_1 1 channelWidth=300;
+
+PORT port_injection portRadius=2000;
+
+CHANNEL connection_5 from port_injection to picoinjector_1 3 channelWidth=300;
+
+DROPLET SPLITTER droplet_splitter_1
+ height=30
+ inletWidth=300
+ inletLength=2000
+ outletWidth1=300
+ outletLength1=2000
+ outletWidth2=300
+ outletLength2=2000;
+
+CHANNEL connection_6 from picoinjector_1 2 to droplet_splitter_1 1 channelWidth=300;
+
+MIXER mixer_1;
+MIXER mixer_2;
+
+CHANNEL connection_7 from droplet_splitter_1 2 to mixer_1 1 channelWidth=300;
+CHANNEL connection_8 from droplet_splitter_1 3 to mixer_2 1 channelWidth=300;
+
+DROPLET SORTER droplet_sorter_1
+ height=300
+ inletWidth=300
+ inletLength=4000
+ inletLength=4000
+ electrodeDistance=1000
+ electrodeWidth=700
+ electrodeLength=5000
+ outletWidth=300
+ angle=45
+ wasteWidth=600
+ outputLength=4000
+ keepWidth=600
+ pressureWidth=1000
+ numberofDistributors=5
+ channelDepth=300
+ electrodeDepth=300
+ pressureDepth=200;
+
+
+DROPLET SORTER droplet_sorter_2
+ height=300
+ inletWidth=300
+ inletLength=4000
+ inletLength=4000
+ electrodeDistance=1000
+ electrodeWidth=700
+ electrodeLength=5000
+ outletWidth=300
+ angle=45
+ wasteWidth=600
+ outputLength=4000
+ keepWidth=600
+ pressureWidth=1000
+ numberofDistributors=5
+ channelDepth=300
+ electrodeDepth=300
+ pressureDepth=200;
+
+CHANNEL connection_9 from mixer_1 2 to droplet_sorter_1 1 channelWidth=300;
+CHANNEL connection_10 from mixer_2 2 to droplet_sorter_2 1 channelWidth=300;
+
+PORT port_out_waste1 portRadius=2000;
+PORT port_out_waste2 portRadius=2000;
+PORT port_out_keep1 portRadius=2000;
+PORT port_out_keep2 portRadius=2000;
+
+CHANNEL connection_11 from droplet_sorter_1 2 to port_out_waste1 1 channelWidth=300;
+CHANNEL connection_12 from droplet_sorter_2 2 to port_out_waste2 1 channelWidth=300;
+CHANNEL connection_13 from droplet_sorter_1 3 to port_out_keep1 1 channelWidth=300;
+CHANNEL connection_14 from droplet_sorter_2 3 to port_out_keep2 1 channelWidth=300;
+
+END LAYER
+
diff --git a/tests/data/DropX/netlists/dx6_ref.mint b/tests/data/DropX/netlists/dx6_ref.mint
new file mode 100644
index 0000000..e574ef2
--- /dev/null
+++ b/tests/data/DropX/netlists/dx6_ref.mint
@@ -0,0 +1,51 @@
+DEVICE dx6_ref
+
+LAYER FLOW
+
+PORT port_in1 portRadius=2000;
+PORT port_in2 portRadius=2000;
+MIXER mixer_1
+ bendSpacing=600
+ numberOfBends=5
+ channelWidth=300
+ bendLength=2000
+ height=300;
+
+CHANNEL connection_1 from port_in1 to mixer_1 1 channelWidth=300;
+CHANNEL connection_2 from port_in2 to mixer_1 1 channelWidth=300;
+
+PORT port_oil1 portRadius=2000;
+PORT port_oil2 portRadius=2000;
+
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_1
+ orificeSize=150
+ orificeLength=375
+ oilInputWidth=600
+ waterInputWidth=375
+ outputWidth=300
+ outputLength=5000
+ height=300;
+
+CHANNEL connection_3 from port_oil1 to nozzle_droplet_generator_1 1 channelWidth=300;
+CHANNEL connection_4 from port_oil2 to nozzle_droplet_generator_1 3 channelWidth=300;
+CHANNEL connection_5 from mixer_1 2 to nozzle_droplet_generator_1 4 channelWidth=300;
+
+DROPLET SPLITTER droplet_splitter_1
+ height=30
+ inletWidth=300
+ inletLength=2000
+ outletWidth1=300
+ outletLength1=2000
+ outletWidth2=300
+ outletLength2=2000;
+
+CHANNEL connection_6 from nozzle_droplet_generator_1 2 to droplet_splitter_1 1 channelWidth=300;
+
+PORT port_out1 portRadius=2000;
+PORT port_out2 portRadius=2000;
+
+CHANNEL connection_7 from droplet_splitter_1 2 to port_out1 channelWidth=300;
+CHANNEL connection_8 from droplet_splitter_1 3 to port_out2 channelWidth=300;
+
+END LAYER
+
diff --git a/tests/data/DropX/netlists/dx7_ref.mint b/tests/data/DropX/netlists/dx7_ref.mint
new file mode 100644
index 0000000..ad2d825
--- /dev/null
+++ b/tests/data/DropX/netlists/dx7_ref.mint
@@ -0,0 +1,113 @@
+DEVICE dx7_ref
+
+LAYER FLOW
+
+PORT port_oil1 portRadius=2000;
+PORT port_oil2 portRadius=2000;
+PORT port_water1 portRadius=2000;
+
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_1
+ orificeSize=150
+ orificeLength=375
+ oilInputWidth=600
+ waterInputWidth=375
+ outputWidth=300
+ outputLength=5000
+ height=300;
+
+CHANNEL connection_1 from port_oil1 to nozzle_droplet_generator_1 1 channelWidth=300;
+CHANNEL connection_2 from port_oil2 to nozzle_droplet_generator_1 3 channelWidth=300;
+CHANNEL connection_3 from port_water1 to nozzle_droplet_generator_1 4 channelWidth=300;
+
+PORT port_oil3 portRadius=2000;
+PORT port_oil4 portRadius=2000;
+PORT port_water2 portRadius=2000;
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_2
+ orificeSize=150
+ orificeLength=375
+ oilInputWidth=600
+ waterInputWidth=375
+ outputWidth=300
+ outputLength=5000
+ height=300;
+
+CHANNEL connection_4 from port_oil3 to nozzle_droplet_generator_2 1 channelWidth=300;
+CHANNEL connection_5 from port_oil4 to nozzle_droplet_generator_2 3 channelWidth=300;
+CHANNEL connection_6 from port_water2 to nozzle_droplet_generator_2 4 channelWidth=300;
+
+DROPLET MERGER droplet_merger_1
+ height=200
+ inletWidth=300
+ inletLength=4000
+ electrodeWidth=1000
+ electrodeLength=5000
+ electrodeDistance=800
+ outletWidth=300
+ outletLength=4000
+ chamberHeight=800
+ chamberLength=800
+ channelDepth=300
+ electrodeDepth=200;
+
+CHANNEL connection_7 from nozzle_droplet_generator_1 2 to droplet_merger_1 1 channelWidth=300;
+CHANNEL connection_8 from nozzle_droplet_generator_2 2 to droplet_merger_1 1 channelWidth=300;
+
+PORT port_injector1 portRadius=2000;
+PORT port_injector2 portRadius=2000;
+
+MIXER mixer_1
+ bendSpacing=600
+ numberOfBends=5
+ channelWidth=300
+ bendLength=2000
+ height=300;
+
+CHANNEL connection_9 from port_injector1 to mixer_1 1 channelWidth=300;
+CHANNEL connection_10 from port_injector2 to mixer_1 1 channelWidth=300;
+
+PICOINJECTOR picoinjector_1
+ height=300
+ injectorWidth=1000
+ width=10000
+ injectorWidth=1000
+ injectorLength=5000
+ dropletWidth=100
+ nozzleWidth=50
+ nozzleLength=500
+ electrodeDistance=500
+ electrodeWidth=800
+ electrodeLength=3000;
+
+CHANNEL connection_11 from mixer_1 2 to picoinjector_1 3 channelWidth=300;
+
+DROPLET SORTER droplet_sorter_1
+ height=300
+ inletWidth=300
+ inletLength=4000
+ inletLength=4000
+ electrodeDistance=1000
+ electrodeWidth=700
+ electrodeLength=5000
+ outletWidth=300
+ angle=45
+ wasteWidth=600
+ outputLength=4000
+ keepWidth=600
+ pressureWidth=1000
+ numberofDistributors=5
+ channelDepth=300
+ electrodeDepth=300
+ pressureDepth=200;
+
+CHANNEL connection_12 from picoinjector_1 2 to droplet_sorter_1 1 channelWidth=300;
+
+PORT port_out_waste portRadius=2000;
+PORT port_out_keep portRadius=2000;
+
+CHANNEL connection_13 from droplet_sorter_1 2 to port_out_waste channelWidth=300;
+CHANNEL connection_14 from droplet_sorter_1 3 to port_out_keep channelWidth=300;
+
+CHANNEL connection_15 from droplet_merger_1 2 to picoinjector_1 1 channelWidth=300;
+
+END LAYER
+
diff --git a/tests/data/DropX/netlists/dx8_ref.mint b/tests/data/DropX/netlists/dx8_ref.mint
new file mode 100644
index 0000000..8e62379
--- /dev/null
+++ b/tests/data/DropX/netlists/dx8_ref.mint
@@ -0,0 +1,136 @@
+DEVICE dx8_ref
+
+LAYER FLOW
+
+PORT port_oil1 portRadius=2000;
+PORT port_oil2 portRadius=2000;
+
+PORT port_in1 portRadius=2000;
+PORT port_in2 portRadius=2000;
+PORT port_in3 portRadius=2000;
+
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_1
+ orificeSize=150
+ orificeLength=375
+ oilInputWidth=600
+ waterInputWidth=375
+ outputWidth=300
+ outputLength=5000
+ height=300;
+
+CHANNEL connection_1 from port_in1 to nozzle_droplet_generator_1 4 channelWidth=300;
+CHANNEL connection_2 from port_in2 to nozzle_droplet_generator_1 4 channelWidth=300;
+CHANNEL connection_3 from port_in3 to nozzle_droplet_generator_1 4 channelWidth=300;
+
+CHANNEL connection_4 from port_oil1 to nozzle_droplet_generator_1 1 channelWidth=300;
+CHANNEL connection_5 from port_oil2 to nozzle_droplet_generator_1 3 channelWidth=300;
+
+PICOINJECTOR pico_injector_1 height=300
+ injectorWidth=1000
+ width=10000
+ injectorWidth=1000
+ injectorLength=5000
+ dropletWidth=100
+ nozzleWidth=50
+ nozzleLength=500
+ electrodeDistance=500
+ electrodeWidth=800
+ electrodeLength=3000;
+
+PICOINJECTOR pico_injector_2 height=300
+ injectorWidth=1000
+ width=10000
+ injectorWidth=1000
+ injectorLength=5000
+ dropletWidth=100
+ nozzleWidth=50
+ nozzleLength=500
+ electrodeDistance=500
+ electrodeWidth=800
+ electrodeLength=3000;
+
+PICOINJECTOR pico_injector_3 height=300
+ injectorWidth=1000
+ width=10000
+ injectorWidth=1000
+ injectorLength=5000
+ dropletWidth=100
+ nozzleWidth=50
+ nozzleLength=500
+ electrodeDistance=500
+ electrodeWidth=800
+ electrodeLength=3000;
+
+
+CHANNEL connection_6 from nozzle_droplet_generator_1 2 to pico_injector_1 1 channelWidth=300;
+CHANNEL connection_7 from pico_injector_1 2 to pico_injector_2 1 channelWidth=300;
+CHANNEL connection_8 from pico_injector_2 2 to pico_injector_3 1 channelWidth=300;
+
+PORT port_injector1 portRadius=2000;
+PORT port_injector2 portRadius=2000;
+PORT port_injector3 portRadius=2000;
+
+CHANNEL connection_9 from port_injector1 to pico_injector_1 3 channelWidth=300;
+CHANNEL connection_10 from port_injector2 to pico_injector_2 3 channelWidth=300;
+CHANNEL connection_11 from port_injector3 to pico_injector_3 3 channelWidth=300;
+
+MIXER mixer_1
+ bendSpacing=600
+ numberOfBends=5
+ channelWidth=300
+ bendLength=2000
+ height=300;
+
+CHANNEL connection_12 from pico_injector_3 2 to mixer_1 1 channelWidth=300;
+
+DROPLET SORTER droplet_sorter_1
+ height=300
+ inletWidth=300
+ inletLength=4000
+ inletLength=4000
+ electrodeDistance=1000
+ electrodeWidth=700
+ electrodeLength=5000
+ outletWidth=300
+ angle=45
+ wasteWidth=600
+ outputLength=4000
+ keepWidth=600
+ pressureWidth=1000
+ numberofDistributors=5
+ channelDepth=300
+ electrodeDepth=300
+ pressureDepth=200;
+
+DROPLET SORTER droplet_sorter_2
+ height=300
+ inletWidth=300
+ inletLength=4000
+ inletLength=4000
+ electrodeDistance=1000
+ electrodeWidth=700
+ electrodeLength=5000
+ outletWidth=300
+ angle=45
+ wasteWidth=600
+ outputLength=4000
+ keepWidth=600
+ pressureWidth=1000
+ numberofDistributors=5
+ channelDepth=300
+ electrodeDepth=300
+ pressureDepth=200;
+
+
+CHANNEL connection_13 from mixer_1 2 to droplet_sorter_1 1 channelWidth=300;
+
+PORT port_out1 portRadius=2000;
+PORT port_out2 portRadius=2000;
+PORT port_out3 portRadius=2000;
+
+CHANNEL connection_14 from droplet_sorter_1 3 to port_out1 channelWidth=300;
+CHANNEL connection_15 from droplet_sorter_2 3 to port_out2 channelWidth=300;
+CHANNEL connection_16 from droplet_sorter_1 2 to droplet_sorter_2 1 channelWidth=300;
+
+END LAYER
+
diff --git a/tests/data/DropX/netlists/dx9_ref.mint b/tests/data/DropX/netlists/dx9_ref.mint
new file mode 100644
index 0000000..e87b4ec
--- /dev/null
+++ b/tests/data/DropX/netlists/dx9_ref.mint
@@ -0,0 +1,101 @@
+DEVICE dx9_ref
+
+LAYER FLOW
+
+PORT port_oil1 portRadius=2000;
+PORT port_oil2 portRadius=2000;
+PORT port_water1 portRadius=2000;
+
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_1
+ orificeSize=150
+ orificeLength=375
+ oilInputWidth=600
+ waterInputWidth=375
+ outputWidth=300
+ outputLength=5000
+ height=300;
+
+CHANNEL connection_1 from port_oil1 to nozzle_droplet_generator_1 1 channelWidth=300;
+CHANNEL connection_2 from port_oil2 to nozzle_droplet_generator_1 3 channelWidth=300;
+CHANNEL connection_3 from port_water1 to nozzle_droplet_generator_1 4 channelWidth=300;
+
+PORT port_oil3 portRadius=2000;
+PORT port_oil4 portRadius=2000;
+PORT port_water2 portRadius=2000;
+
+NOZZLE DROPLET GENERATOR nozzle_droplet_generator_2
+ orificeSize=150
+ orificeLength=375
+ oilInputWidth=600
+ waterInputWidth=375
+ outputWidth=300
+ outputLength=5000
+ height=300;
+
+CHANNEL connection_4 from port_oil3 to nozzle_droplet_generator_2 1 channelWidth=300;
+CHANNEL connection_5 from port_oil4 to nozzle_droplet_generator_2 3 channelWidth=300;
+CHANNEL connection_6 from port_water2 to nozzle_droplet_generator_2 4 channelWidth=300;
+
+DROPLET MERGER droplet_merger_1
+ height=200
+ inletWidth=300
+ inletLength=4000
+ electrodeWidth=1000
+ electrodeLength=5000
+ electrodeDistance=800
+ outletWidth=300
+ outletLength=4000
+ chamberHeight=800
+ chamberLength=800
+ channelDepth=300
+ electrodeDepth=200;
+
+CHANNEL connection_7 from nozzle_droplet_generator_1 2 to droplet_merger_1 1 channelWidth=300;
+CHANNEL connection_8 from nozzle_droplet_generator_2 2 to droplet_merger_1 1 channelWidth=300;
+
+PORT port_injector portRadius=2000;
+PICOINJECTOR pico_injector_1
+ height=300
+ injectorWidth=1000
+ width=10000
+ injectorWidth=1000
+ injectorLength=5000
+ dropletWidth=100
+ nozzleWidth=50
+ nozzleLength=500
+ electrodeDistance=500
+ electrodeWidth=800
+ electrodeLength=3000;
+
+CHANNEL connection_9 from port_injector to pico_injector_1 3 channelWidth=300;
+CHANNEL connection_10 from droplet_merger_1 2 to pico_injector_1 1 channelWidth=300;
+
+DROPLET SORTER droplet_sorter_1
+ height=300
+ inletWidth=300
+ inletLength=4000
+ inletLength=4000
+ electrodeDistance=1000
+ electrodeWidth=700
+ electrodeLength=5000
+ outletWidth=300
+ angle=45
+ wasteWidth=600
+ outputLength=4000
+ keepWidth=600
+ pressureWidth=1000
+ numberofDistributors=5
+ channelDepth=300
+ electrodeDepth=300
+ pressureDepth=200;
+
+CHANNEL connection_11 from pico_injector_1 2 to droplet_sorter_1 1 channelWidth=300;
+
+PORT port_outlet portRadius=2000;
+PORT port_waste portRadius=2000;
+
+CHANNEL connection_12 from droplet_sorter_1 3 to port_outlet channelWidth=300;
+CHANNEL connection_13 from droplet_sorter_1 2 to port_waste channelWidth=300;
+
+END LAYER
+
diff --git a/tests/data/Expressions/expression1.lfr b/tests/data/Expressions/expression1.lfr
new file mode 100644
index 0000000..7454382
--- /dev/null
+++ b/tests/data/Expressions/expression1.lfr
@@ -0,0 +1,10 @@
+module expression1(finput in1, in2, foutput out);
+
+ flow temp_out;
+
+ assign temp_out = in1 % 50.88;
+ assign temp_out = in2 % 100;
+
+ assign out = temp_out;
+
+endmodule
diff --git a/tests/data/Expressions/expression10.lfr b/tests/data/Expressions/expression10.lfr
new file mode 100644
index 0000000..2bcc759
--- /dev/null
+++ b/tests/data/Expressions/expression10.lfr
@@ -0,0 +1,11 @@
+module expression10(finput in1, in2, foutput out);
+
+ flow temp_out;
+ number val1 = 9;
+
+ val1 = 10 + 78 - 65 / 67 * 44;
+ assign temp_out = in1 % 50.88 + &in2;
+
+ assign out = temp_out;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/Expressions/expression11.lfr b/tests/data/Expressions/expression11.lfr
new file mode 100644
index 0000000..255ba83
--- /dev/null
+++ b/tests/data/Expressions/expression11.lfr
@@ -0,0 +1,9 @@
+module expression11(finput in1, in2, foutput out);
+
+ flow temp_out;
+
+ assign temp_out = in1 + in2;
+
+ assign out = temp_out;
+
+endmodule
diff --git a/tests/data/Expressions/expression12.lfr b/tests/data/Expressions/expression12.lfr
new file mode 100644
index 0000000..f9ea7a2
--- /dev/null
+++ b/tests/data/Expressions/expression12.lfr
@@ -0,0 +1,9 @@
+module expression12(finput [0:7] in1, [0:7] in2, foutput out);
+
+ flow temp_out;
+
+ assign temp_out = in1 + in2;
+
+ assign out = temp_out;
+
+endmodule
diff --git a/tests/data/Expressions/expression13.lfr b/tests/data/Expressions/expression13.lfr
new file mode 100644
index 0000000..ed58546
--- /dev/null
+++ b/tests/data/Expressions/expression13.lfr
@@ -0,0 +1,11 @@
+//This design tests the DIVIDE interaction
+module expression13(finput in1, foutput out1, out2);
+
+ flow temp_1, temp_2;
+
+ assign {temp_1, temp_2} = in1/2;
+
+ assign out1 = temp_1;
+ assign out2 = temp_2;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/Expressions/expression14.lfr b/tests/data/Expressions/expression14.lfr
new file mode 100644
index 0000000..36894b0
--- /dev/null
+++ b/tests/data/Expressions/expression14.lfr
@@ -0,0 +1,6 @@
+//This design tests if N fluid number operations work
+module expression14(finput [0:7] in, foutput [0:7] out);
+
+ assign out = in%50;
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/Expressions/expression15.lfr b/tests/data/Expressions/expression15.lfr
new file mode 100644
index 0000000..6251419
--- /dev/null
+++ b/tests/data/Expressions/expression15.lfr
@@ -0,0 +1,9 @@
+module expression15(
+ finput f1, f2, f3, f4, f5, f6,
+ foutput fout
+);
+
+ assign fout = f1*0.2 + f2*0.4 + f3*0.1 + f4*0.1 + f5*0.1 + f6*0.1;
+
+
+endmodule
\ No newline at end of file
diff --git a/tests/data/Expressions/expression2.lfr b/tests/data/Expressions/expression2.lfr
new file mode 100644
index 0000000..04f6aeb
--- /dev/null
+++ b/tests/data/Expressions/expression2.lfr
@@ -0,0 +1,9 @@
+module expression2(finput in1, in2, foutput out);
+
+ flow temp_out;
+
+ assign temp_out = in1 + in2 % 50;
+
+ assign out = temp_out;
+
+endmodule
diff --git a/tests/data/Expressions/expression3.lfr b/tests/data/Expressions/expression3.lfr
new file mode 100644
index 0000000..eaad913
--- /dev/null
+++ b/tests/data/Expressions/expression3.lfr
@@ -0,0 +1,9 @@
+module expression3(finput in1, in2, in3, foutput out);
+
+ flow temp_out;
+
+ assign temp_out = &(in1 + in2 + in3) ;
+
+ assign out = temp_out;
+
+endmodule
diff --git a/tests/data/Expressions/expression4.lfr b/tests/data/Expressions/expression4.lfr
new file mode 100644
index 0000000..55774a3
--- /dev/null
+++ b/tests/data/Expressions/expression4.lfr
@@ -0,0 +1,9 @@
+module expression4(finput in1, in2, in3, in4, foutput out);
+
+ flow temp_out;
+
+ assign temp_out = in1 + (in2 + (in3 + in4)) ;
+
+ assign out = temp_out;
+
+endmodule
diff --git a/tests/data/Expressions/expression5.lfr b/tests/data/Expressions/expression5.lfr
new file mode 100644
index 0000000..4761500
--- /dev/null
+++ b/tests/data/Expressions/expression5.lfr
@@ -0,0 +1,9 @@
+module expression5(finput in1, in2, in3, in4, foutput out);
+
+ flow temp_out;
+
+ assign temp_out = in1 + (in2 + (in3 + &in4)) ;
+
+ assign out = temp_out;
+
+endmodule
diff --git a/tests/data/Expressions/expression6.lfr b/tests/data/Expressions/expression6.lfr
new file mode 100644
index 0000000..ce67362
--- /dev/null
+++ b/tests/data/Expressions/expression6.lfr
@@ -0,0 +1,10 @@
+module expression6(finput in1, in2, in3, in4, foo, foutput out);
+
+ flow temp_out;
+
+ assign temp_out = foo + (in1 + (in2 + &(in3 + in4))) ;
+
+ assign out = temp_out;
+
+endmodule
+
diff --git a/tests/data/Expressions/expression7.lfr b/tests/data/Expressions/expression7.lfr
new file mode 100644
index 0000000..c85434d
--- /dev/null
+++ b/tests/data/Expressions/expression7.lfr
@@ -0,0 +1,10 @@
+module expression7(finput [0:2] in1, in2, in3, in4, foutput out);
+
+ flow temp_out;
+
+ assign temp_out = in1 + { in2, in3, in4 } ;
+
+ assign out = temp_out;
+
+endmodule
+
diff --git a/tests/data/Expressions/expression8.lfr b/tests/data/Expressions/expression8.lfr
new file mode 100644
index 0000000..992984a
--- /dev/null
+++ b/tests/data/Expressions/expression8.lfr
@@ -0,0 +1,11 @@
+module expression8(finput in1, in2, in3, in4, foutput out1, out2);
+
+ flow temp_out1, temp_out2;
+
+ assign {temp_out1, temp_out2} = {in1, in1, in1} + { in2, in3, in4 } ;
+
+ assign out1 = temp_out1;
+ assign out2 = temp_out2;
+
+endmodule
+
diff --git a/tests/data/Expressions/expression9.lfr b/tests/data/Expressions/expression9.lfr
new file mode 100644
index 0000000..328172b
--- /dev/null
+++ b/tests/data/Expressions/expression9.lfr
@@ -0,0 +1,9 @@
+module expression9(finput in1, in2, foutput out);
+
+ flow temp_out;
+
+ assign temp_out = in1 % 50.88 + &in2;
+
+ assign out = temp_out;
+
+endmodule
\ No newline at end of file
diff --git a/tests/pylfr/e2e/__init__.py b/tests/pylfr/e2e/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/pylfr/e2e/compiler/__init__.py b/tests/pylfr/e2e/compiler/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/pylfr/e2e/compiler/test_devicegen.py b/tests/pylfr/e2e/compiler/test_devicegen.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/pylfr/e2e/compiler/test_expressions.py b/tests/pylfr/e2e/compiler/test_expressions.py
new file mode 100644
index 0000000..5a8f273
--- /dev/null
+++ b/tests/pylfr/e2e/compiler/test_expressions.py
@@ -0,0 +1,215 @@
+from tests.conftest import LIBRARY_PATH, TEST_DATA_FOLDER, TEST_OUTPATH
+
+from lfr import api
+
+TEST_CASES_FOLDER = TEST_DATA_FOLDER.joinpath("Expressions")
+
+
+def test_expression1():
+ # expression1.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression1.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
+
+
+def test_expression2():
+ # expression2.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression2.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
+
+
+def test_expression3():
+ # expression3.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression3.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
+
+
+def test_expression4():
+ # expression4.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression4.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
+
+
+def test_expression5():
+ # expression5.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression5.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
+
+
+def test_expression6():
+ # expression6.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression6.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
+
+
+def test_expression7():
+ # expression7.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression7.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
+
+
+def test_expression8():
+ # expression8.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression8.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
+
+
+def test_expression9():
+ # expression9.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression9.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
+
+
+def test_expression10():
+ # expression10.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression10.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
+
+
+def test_expression11():
+ # expression11.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression11.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
+
+
+def test_expression12():
+ # expression12.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression12.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
+
+
+def test_expression13():
+ # expression13.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression13.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
+
+
+def test_expression14():
+ # expression14.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression14.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
+
+
+def test_expression15():
+ # expression15.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("expression15.lfr")
+ # Read the text and dump it on console
+ api.compile_lfr(
+ input_files=[str(test_file.absolute())],
+ outpath=str(TEST_OUTPATH),
+ library_path=str(LIBRARY_PATH),
+ no_gen_flag=True,
+ no_annotations_flag=True,
+ pre_load=[],
+ )
diff --git a/tests/pylfr/e2e/compiler/test_figgen.py b/tests/pylfr/e2e/compiler/test_figgen.py
new file mode 100644
index 0000000..30584b2
--- /dev/null
+++ b/tests/pylfr/e2e/compiler/test_figgen.py
@@ -0,0 +1,400 @@
+from pathlib import Path
+
+import networkx
+from networkx import is_isomorphic
+from tests.conftest import LIBRARY_PATH, TEST_DATA_FOLDER, TEST_OUTPATH
+
+from lfr import api
+from lfr.utils import printgraph
+
+TEST_CASES_FOLDER = TEST_DATA_FOLDER.joinpath("DropX")
+REF_DATA_FIG_FOLDER = TEST_CASES_FOLDER.joinpath("figs")
+
+
+def test_dx1():
+ # dx1.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx1.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx1.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
+
+
+def test_dx2():
+ # dx2.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx2.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx2.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
+
+
+def test_dx3():
+ # dx3.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx3.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx3.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
+
+
+def test_dx4():
+ # dx4.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx4.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx4.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
+
+
+def test_dx5():
+ # dx5.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx5.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx5.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
+
+
+def test_dx6():
+ # dx6.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx6.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx6.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
+
+
+def test_dx7():
+ # dx7.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx7.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx7.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
+
+
+def test_dx8():
+ # dx8.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx8.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx8.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
+
+
+def test_dx9():
+ # dx9.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx9.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx9.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
+
+
+def test_dx10():
+ # dx10.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx10.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx10.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
+
+
+def test_dx11():
+ # dx11.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx11.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx11.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
+
+
+def test_dx12():
+ # dx12.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx12.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx12.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
+
+
+def test_dx13():
+ # dx13.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx13.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx13.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
+
+
+def test_dx14():
+ # dx14.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx14.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx14.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
+
+
+def test_dx15():
+ # dx15.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx15.lfr")
+ # Read the text and dump it on console
+ module_listener = api.synthesize_module(
+ input_path=test_file,
+ no_annotations_flag=True,
+ print_fig=False,
+ )
+
+ assert module_listener.success is True
+ assert module_listener.currentModule is not None
+
+ # Get FIG from the module
+ fig = module_listener.currentModule.FIG
+
+ # Load the reference data
+ ref_fig_data = REF_DATA_FIG_FOLDER.joinpath("dx15.dot")
+ ref_graph = networkx.nx_agraph.read_dot(ref_fig_data)
+ # Compare the reference data with the generated data and assert equality
+ # Ref data load the dot file using networkx
+ # Generated data load the dot file using pydot
+ success = is_isomorphic(ref_graph, fig)
+ assert success is True
diff --git a/tests/pylfr/e2e/compiler/test_mintgen.py b/tests/pylfr/e2e/compiler/test_mintgen.py
new file mode 100644
index 0000000..ae6f9f8
--- /dev/null
+++ b/tests/pylfr/e2e/compiler/test_mintgen.py
@@ -0,0 +1,32 @@
+from pathlib import Path
+
+import networkx
+from networkx import is_isomorphic
+from tests.conftest import LIBRARY_PATH, TEST_DATA_FOLDER, TEST_OUTPATH
+
+from lfr import api
+from lfr.utils import printgraph
+
+TEST_CASES_FOLDER = TEST_DATA_FOLDER.joinpath("DropX")
+REF_DATA_FIG_FOLDER = TEST_CASES_FOLDER.joinpath("netlists")
+
+
+def test_dx1():
+ # Create output directories
+ TEST_OUTPATH.mkdir(parents=True, exist_ok=True)
+
+ # dx1.lfr
+ test_file = TEST_CASES_FOLDER.joinpath("dx1.lfr")
+
+ # Run through the full compiler
+ return_code = api.compile_lfr(
+ input_files=[str(test_file)],
+ outpath=str(TEST_OUTPATH),
+ technology="dropx",
+ pre_load=[str(LIBRARY_PATH.absolute())],
+ )
+
+ assert return_code == 0
+
+ # Load the data from the output path
+ # Parse this and compare it with the reference data