standard-evaluator 0.1.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. standard_evaluator-0.1.7/.github/workflows/pages.yml +56 -0
  2. standard_evaluator-0.1.7/.github/workflows/publish-pypi.yml +68 -0
  3. standard_evaluator-0.1.7/.github/workflows/python-package.yml +35 -0
  4. standard_evaluator-0.1.7/.gitignore +40 -0
  5. standard_evaluator-0.1.7/LICENSE +13 -0
  6. standard_evaluator-0.1.7/PKG-INFO +61 -0
  7. standard_evaluator-0.1.7/README.md +16 -0
  8. standard_evaluator-0.1.7/additional_options.json +1 -0
  9. standard_evaluator-0.1.7/docs/source/_ext/format-class.py +242 -0
  10. standard_evaluator-0.1.7/docs/source/_static/css/class_doc.css +35 -0
  11. standard_evaluator-0.1.7/docs/source/_static/css/general.css +35 -0
  12. standard_evaluator-0.1.7/docs/source/_static/js/custom.js +7 -0
  13. standard_evaluator-0.1.7/docs/source/_static/js/require.min.js +5 -0
  14. standard_evaluator-0.1.7/docs/source/_templates/footer.html +2 -0
  15. standard_evaluator-0.1.7/docs/source/conf.py +190 -0
  16. standard_evaluator-0.1.7/docs/source/demos/Problem_explanation.ipynb +1043 -0
  17. standard_evaluator-0.1.7/docs/source/demos/after.json +3957 -0
  18. standard_evaluator-0.1.7/docs/source/demos/after.n2.html +14805 -0
  19. standard_evaluator-0.1.7/docs/source/demos/before.n2.html +14805 -0
  20. standard_evaluator-0.1.7/docs/source/demos/before_NASA.n2.html +14805 -0
  21. standard_evaluator-0.1.7/docs/source/demos/defining_options.ipynb +245 -0
  22. standard_evaluator-0.1.7/docs/source/demos/demo_group_nasa.json +4681 -0
  23. standard_evaluator-0.1.7/docs/source/demos/design_space_exploration.drawio.png +0 -0
  24. standard_evaluator-0.1.7/docs/source/demos/design_space_exploration.ipynb +654 -0
  25. standard_evaluator-0.1.7/docs/source/demos/design_space_exploration_2.ipynb +1066 -0
  26. standard_evaluator-0.1.7/docs/source/demos/gitignore +7 -0
  27. standard_evaluator-0.1.7/docs/source/demos/group_creation.ipynb +540 -0
  28. standard_evaluator-0.1.7/docs/source/demos/group_creation_NASA.ipynb +408 -0
  29. standard_evaluator-0.1.7/docs/source/demos/group_demo.md +24 -0
  30. standard_evaluator-0.1.7/docs/source/demos/group_manipulation.ipynb +135 -0
  31. standard_evaluator-0.1.7/docs/source/demos/group_reading.ipynb +313 -0
  32. standard_evaluator-0.1.7/docs/source/demos/ideas.drawio.svg +455 -0
  33. standard_evaluator-0.1.7/docs/source/demos/index.rst +14 -0
  34. standard_evaluator-0.1.7/docs/source/demos/input.csv +2 -0
  35. standard_evaluator-0.1.7/docs/source/demos/overview.drawio.png +0 -0
  36. standard_evaluator-0.1.7/docs/source/demos/problem_structure_flow.drawio.png +0 -0
  37. standard_evaluator-0.1.7/docs/source/demos/replace.html +14805 -0
  38. standard_evaluator-0.1.7/docs/source/demos/replace_after_surrogate.html +14805 -0
  39. standard_evaluator-0.1.7/docs/source/demos/replace_group.drawio.svg +223 -0
  40. standard_evaluator-0.1.7/docs/source/demos/replace_group.ipynb +590 -0
  41. standard_evaluator-0.1.7/docs/source/demos/replace_group_details.drawio.svg +287 -0
  42. standard_evaluator-0.1.7/docs/source/demos/state.h5 +0 -0
  43. standard_evaluator-0.1.7/docs/source/demos/workflow.drawio.png +0 -0
  44. standard_evaluator-0.1.7/docs/source/demos/workflow.drawio.svg +1 -0
  45. standard_evaluator-0.1.7/docs/source/demos/workflow_catalog.drawio.png +0 -0
  46. standard_evaluator-0.1.7/docs/source/demos/workflow_catalog.drawio.svg +387 -0
  47. standard_evaluator-0.1.7/docs/source/index.rst +29 -0
  48. standard_evaluator-0.1.7/docs/source/theory/explicit_definition.drawio.png +0 -0
  49. standard_evaluator-0.1.7/docs/source/theory/explicit_definition.drawio.svg +303 -0
  50. standard_evaluator-0.1.7/docs/source/theory/index.rst +10 -0
  51. standard_evaluator-0.1.7/docs/source/theory/need_for_explicit_inputs_output_def.md +159 -0
  52. standard_evaluator-0.1.7/experimenting/assembly.json +1617 -0
  53. standard_evaluator-0.1.7/experimenting/connections_hide_internal.ipynb +854 -0
  54. standard_evaluator-0.1.7/experimenting/data.h5 +0 -0
  55. standard_evaluator-0.1.7/experimenting/optproblem1.json +78 -0
  56. standard_evaluator-0.1.7/experimenting/replace.html +14805 -0
  57. standard_evaluator-0.1.7/experimenting/replace_after.html +14805 -0
  58. standard_evaluator-0.1.7/experimenting/replace_after_surrogate.html +14805 -0
  59. standard_evaluator-0.1.7/experimenting/state.h5 +0 -0
  60. standard_evaluator-0.1.7/pyproject.toml +79 -0
  61. standard_evaluator-0.1.7/requirements.win64.py311.dev.txt +509 -0
  62. standard_evaluator-0.1.7/requirements.win64.py311.docs.txt +597 -0
  63. standard_evaluator-0.1.7/requirements.win64.py311.txt +181 -0
  64. standard_evaluator-0.1.7/setup.cfg +4 -0
  65. standard_evaluator-0.1.7/src/standard_evaluator/__init__.py +61 -0
  66. standard_evaluator-0.1.7/src/standard_evaluator/additional_component_options_test.json +1 -0
  67. standard_evaluator-0.1.7/src/standard_evaluator/additional_options.json +1 -0
  68. standard_evaluator-0.1.7/src/standard_evaluator/aviary_encoder.py +92 -0
  69. standard_evaluator-0.1.7/src/standard_evaluator/circuit_example.py +51 -0
  70. standard_evaluator-0.1.7/src/standard_evaluator/converters.py +22 -0
  71. standard_evaluator-0.1.7/src/standard_evaluator/evaluator.py +82 -0
  72. standard_evaluator-0.1.7/src/standard_evaluator/om_converter.py +606 -0
  73. standard_evaluator-0.1.7/src/standard_evaluator/problem.py +370 -0
  74. standard_evaluator-0.1.7/src/standard_evaluator/standard_base.py +619 -0
  75. standard_evaluator-0.1.7/src/standard_evaluator/standard_evaluator.py +57 -0
  76. standard_evaluator-0.1.7/src/standard_evaluator/standard_group.py +74 -0
  77. standard_evaluator-0.1.7/src/standard_evaluator/system_description_to_json.py +850 -0
  78. standard_evaluator-0.1.7/src/standard_evaluator/utilities.py +12 -0
  79. standard_evaluator-0.1.7/src/standard_evaluator/version.py +4 -0
  80. standard_evaluator-0.1.7/src/standard_evaluator.egg-info/PKG-INFO +61 -0
  81. standard_evaluator-0.1.7/src/standard_evaluator.egg-info/SOURCES.txt +90 -0
  82. standard_evaluator-0.1.7/src/standard_evaluator.egg-info/dependency_links.txt +1 -0
  83. standard_evaluator-0.1.7/src/standard_evaluator.egg-info/requires.txt +34 -0
  84. standard_evaluator-0.1.7/src/standard_evaluator.egg-info/top_level.txt +1 -0
  85. standard_evaluator-0.1.7/tests/.gitignore +1 -0
  86. standard_evaluator-0.1.7/tests/__init__.py +0 -0
  87. standard_evaluator-0.1.7/tests/system_description/additional_options.json +1 -0
  88. standard_evaluator-0.1.7/tests/system_description/reference_model.json +0 -0
  89. standard_evaluator-0.1.7/tests/system_description/test_system_description_to_json.py +164 -0
  90. standard_evaluator-0.1.7/tests/test_converters.py +26 -0
  91. standard_evaluator-0.1.7/tests/test_evaluator.py +247 -0
  92. standard_evaluator-0.1.7/tests/test_problem.py +336 -0
@@ -0,0 +1,56 @@
1
+ name: Deploy to GitHub Pages
2
+
3
+ on:
4
+ push:
5
+ branches: [ "main" ]
6
+
7
+ # Allows you to run this workflow manually from the Actions tab
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+ pages: write
13
+ id-token: write
14
+
15
+ # Allow only one concurrent deployment
16
+ concurrency:
17
+ group: "pages"
18
+ cancel-in-progress: false
19
+
20
+ jobs:
21
+ deploy:
22
+ environment:
23
+ name: github-pages
24
+ url: ${{ steps.deployment.outputs.page_url }}
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - name: Checkout
28
+ uses: actions/checkout@v4
29
+
30
+ - name: Setup Python
31
+ uses: actions/setup-python@v5
32
+ with:
33
+ python-version: "3.11"
34
+
35
+ - name: Install dependencies
36
+ run: |
37
+ python -m pip install --upgrade pip
38
+ pip install .[docs]
39
+
40
+ - name: Setup Pages
41
+ uses: actions/configure-pages@v4
42
+
43
+ - name: Build documentation
44
+ run: |
45
+ cd docs
46
+ python -m sphinx -b html source ./_html
47
+
48
+
49
+ - name: Upload artifact
50
+ uses: actions/upload-pages-artifact@v3
51
+ with:
52
+ path: 'docs/_html'
53
+
54
+ - name: Deploy to GitHub Pages
55
+ id: deployment
56
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,68 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*.*.*'
7
+
8
+ jobs:
9
+
10
+ test_publish:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: actions/setup-python@v5
15
+ with:
16
+ python-version: '3.11'
17
+ - run: pip install build
18
+ - run: python -m build
19
+ - name: Check if TEST_PYPI_API_TOKEN is set
20
+ run: |
21
+ if [ -z "$TEST_PYPI_API_TOKEN" ]; then
22
+ echo "❌ TEST_PYPI_API_TOKEN is not set"
23
+ exit 1
24
+ else
25
+ echo "✅ Secret is set"
26
+ fi
27
+ env:
28
+ TEST_PYPI_API_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}
29
+ - name: Upload to TestPyPI (debug)
30
+ run: |
31
+ ls -lh dist/
32
+ python -m pip install --quiet twine
33
+ twine check dist/* || exit 1
34
+ twine upload --verbose --repository-url https://test.pypi.org/legacy/ dist/*
35
+ env:
36
+ TWINE_USERNAME: __token__
37
+ TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
38
+ - name: Upload to TestPyPI
39
+ uses: pypa/gh-action-pypi-publish@release/v1
40
+ with:
41
+ repository-url: https://test.pypi.org/legacy/
42
+ password: ${{ secrets.TEST_PYPI_API_TOKEN }}
43
+ attestations: false
44
+
45
+ publish:
46
+ needs: test_publish
47
+ runs-on: ubuntu-latest
48
+ steps:
49
+ - uses: actions/checkout@v4
50
+ - uses: actions/setup-python@v5
51
+ with:
52
+ python-version: '3.11'
53
+ - run: pip install build
54
+ - run: python -m build
55
+ - name: Check if PYPI_API_TOKEN is set
56
+ run: |
57
+ if [ -z "$PYPI_API_TOKEN" ]; then
58
+ echo "❌ PYPI_API_TOKEN is not set"
59
+ exit 1
60
+ else
61
+ echo "✅ Secret is set"
62
+ fi
63
+ env:
64
+ PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
65
+ - name: Upload to PyPI
66
+ uses: pypa/gh-action-pypi-publish@release/v1
67
+ with:
68
+ password: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,35 @@
1
+ # This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3
+
4
+ name: Python package
5
+
6
+ on:
7
+ push:
8
+ branches: [ "main", "dev" ]
9
+ pull_request:
10
+ branches: [ "main", "dev" ]
11
+
12
+ jobs:
13
+ build:
14
+
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ python-version: ["3.9", "3.10", "3.11"]
20
+
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ - name: Set up Python ${{ matrix.python-version }}
24
+ uses: actions/setup-python@v3
25
+ with:
26
+ python-version: ${{ matrix.python-version }}
27
+ - name: Build package
28
+ run: |
29
+ python -m pip install --upgrade pip
30
+ python -m pip install build
31
+ python -m build
32
+ - name: Test package with pytest
33
+ run: |
34
+ pip install $(echo ./dist/*.whl)[test]
35
+ pytest
@@ -0,0 +1,40 @@
1
+ .env
2
+ .pytest_cache
3
+ *.pyc
4
+ __pycache__
5
+ dist/*
6
+ build/*
7
+ dist/
8
+ build/
9
+ *.egg-info/*
10
+ *.egg-info/
11
+ .local
12
+ venv
13
+ .venv
14
+ .coverage
15
+ coverage.xml
16
+ report.xml
17
+ .cache
18
+ .vscode
19
+ .python-gitlab.cfg
20
+ .cf-bucket-keys
21
+ .project-config
22
+ .project-config-local
23
+ scripts
24
+ experimenting/reports/*
25
+ experimenting/.ipynb_checkpoints/*
26
+ experimenting/problem*_out
27
+
28
+ docs/source/demos/reports/*
29
+ docs/source/demos/problem*_out
30
+ docs/source/demos/.ipynb_checkpoints/*
31
+ #docs/source/demos/after.json
32
+ #docs/source/demos/demo_group.json
33
+ #docs/source/demos/demo_group_NASA.json
34
+ #docs/source/demos/state.h5
35
+ #docs/source/demos/optproblem*.json
36
+ docs/_html
37
+ docs/jupyter_execute
38
+
39
+ scripts/
40
+ __main__*
@@ -0,0 +1,13 @@
1
+ Copyright 2024, The Boeing Company
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,61 @@
1
+ Metadata-Version: 2.4
2
+ Name: standard_evaluator
3
+ Version: 0.1.7
4
+ Summary: Project description
5
+ Author-email: joerg.m.gablonsky@boeing.com
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: Operating System :: OS Independent
8
+ Classifier: License :: OSI Approved :: Apache Software License
9
+ Requires-Python: >=3.7
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: numpy
13
+ Requires-Dist: openmdao<=3.37.0
14
+ Requires-Dist: om-aviary
15
+ Requires-Dist: json-numpy
16
+ Requires-Dist: pydantic==2.10.6
17
+ Requires-Dist: h5py
18
+ Requires-Dist: numpydantic
19
+ Provides-Extra: test
20
+ Requires-Dist: pytest; extra == "test"
21
+ Requires-Dist: pytest-cov; extra == "test"
22
+ Requires-Dist: coverage; extra == "test"
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest; extra == "dev"
25
+ Requires-Dist: pytest-cov; extra == "dev"
26
+ Requires-Dist: coverage; extra == "dev"
27
+ Requires-Dist: black; extra == "dev"
28
+ Requires-Dist: flake8; extra == "dev"
29
+ Requires-Dist: jupyter; extra == "dev"
30
+ Provides-Extra: docs
31
+ Requires-Dist: pytest; extra == "docs"
32
+ Requires-Dist: pytest-cov; extra == "docs"
33
+ Requires-Dist: coverage; extra == "docs"
34
+ Requires-Dist: black; extra == "docs"
35
+ Requires-Dist: flake8; extra == "docs"
36
+ Requires-Dist: sphinx; extra == "docs"
37
+ Requires-Dist: jupyter; extra == "docs"
38
+ Requires-Dist: autodocsumm; extra == "docs"
39
+ Requires-Dist: pytest-cov; extra == "docs"
40
+ Requires-Dist: sphinxcontrib-mermaid; extra == "docs"
41
+ Requires-Dist: sphinx-rtd-theme; extra == "docs"
42
+ Requires-Dist: jupyter_core<=5.1.0; extra == "docs"
43
+ Requires-Dist: myst-nb; extra == "docs"
44
+ Dynamic: license-file
45
+
46
+ # Standard Evaluator
47
+
48
+ This project expands the capabilities of the OpenMDAO components. It was developed under NASA Contract 80GRC023CA045.
49
+
50
+ Note that this is a very early prototype. We are actively working on improving the documentation and descriptions.
51
+
52
+ ## Installation
53
+
54
+ `pip install standard-evaluator`
55
+
56
+ Optionally clone the repo and install locally.
57
+
58
+ - The docs folder contains the source code of the documentation, which includes the demos. Note that this has not been moved here yet.
59
+ - Experimenting is a folder we use to experiment with code.
60
+ - The src folder contains the actual source code of the standard evaluator.
61
+ - Finally the tests folder contains our unit tests.
@@ -0,0 +1,16 @@
1
+ # Standard Evaluator
2
+
3
+ This project expands the capabilities of the OpenMDAO components. It was developed under NASA Contract 80GRC023CA045.
4
+
5
+ Note that this is a very early prototype. We are actively working on improving the documentation and descriptions.
6
+
7
+ ## Installation
8
+
9
+ `pip install standard-evaluator`
10
+
11
+ Optionally clone the repo and install locally.
12
+
13
+ - The docs folder contains the source code of the documentation, which includes the demos. Note that this has not been moved here yet.
14
+ - Experimenting is a folder we use to experiment with code.
15
+ - The src folder contains the actual source code of the standard evaluator.
16
+ - Finally the tests folder contains our unit tests.
@@ -0,0 +1 @@
1
+ {"n1": {"additional_option_1": "little", "additional_option_2": "big"}, "n2": {"additional_option_1": "little", "additional_option_2": "big"}, "D1": {"additional_option_1": "little", "additional_option_2": "big"}, "R1": {"additional_option_1": "little", "additional_option_2": "big"}}
@@ -0,0 +1,242 @@
1
+ """
2
+ Created Nov. 29, 2022
3
+
4
+ @author Mikel Woo
5
+ """
6
+ from typing import Optional
7
+
8
+ from autodocsumm import AutoSummClassDocumenter
9
+ from docutils.statemachine import StringList
10
+ from sphinx.application import Sphinx
11
+ from sphinx.ext.autodoc import bool_option
12
+
13
+
14
+ class FormatClass(AutoSummClassDocumenter):
15
+ """Adds the :print-options: option to the autoclass directive. Using this
16
+ option will print the unique identifier of the class as well as format the
17
+ available options in an easy to read manner. It can be used as follows:
18
+
19
+ .. autoclass:: sample.Class
20
+ :print-options:
21
+
22
+ Also adds the :known-solution: option which is used by test evaluators
23
+ to print out the known solution(s). Use the :known-solution: option.
24
+
25
+ This feature is implemented similarly to how the autodocsumm extension
26
+ creates the attribute and method summary tables. That extension simply
27
+ overrides the autodoc formatters and adds in the summary table capability.
28
+ To ensure compatability with that extension, this extension does the same
29
+ thing but overriding the autodocsumm class formatter.
30
+ """
31
+ # Set this to have highest priority
32
+ priority = 10 + AutoSummClassDocumenter.priority
33
+
34
+ # Copy options
35
+ option_spec = dict(AutoSummClassDocumenter.option_spec)
36
+ # Add print-options and knonw-solution options
37
+ option_spec['print-options'] = bool_option
38
+ option_spec['known-solution'] = bool_option
39
+
40
+ def add_content(self, more_content: Optional[StringList]) -> None:
41
+ """This method generates the RST content that will be rendered. When
42
+ Sphinx encounters an autoclass directive it will call this method to
43
+ fill in what content should be in place of the directive.
44
+
45
+ Parameters
46
+ ----------
47
+ more_content : Optional[StringList]
48
+ List of strings containing the content of anything placed within the
49
+ directive that is not an option. For example:
50
+
51
+ .. autoclass:: sample.Test
52
+ :print-options:
53
+
54
+ This line will show up
55
+ As will this one
56
+
57
+ .. math::
58
+ y = mx + b
59
+
60
+ This line and the equation above will show up
61
+
62
+ All the lines (even blank ones) after the blank line below
63
+ :print-options: will be in more_content
64
+ """
65
+ # Call add_content of the autodoc ClassDocumenter which the autosummary
66
+ # AutoSummClassDocumenter derives from. This is to allow us to control
67
+ # when the summary tables are printed
68
+ super(AutoSummClassDocumenter, self).add_content(more_content)
69
+
70
+ # Print options if print-options is set and no-print-options isn't
71
+ if 'print-options' in self.options and 'no-print-options' not in self.options:
72
+ self._print_options()
73
+
74
+ # Print known solution(s) if known-solution is set and no-known-solution isn't
75
+ if 'known-solution' in self.options and 'no-known-solution' not in self.options:
76
+ self._print_known_solution()
77
+
78
+ # Add table of attributes and methods below unique_name and options
79
+ # This method handles the :autosummary: option from autodocsumm. It's
80
+ # placed here to have options printed before the method summary.
81
+ self.add_autosummary(True)
82
+
83
+ def _print_options(self):
84
+ """Prints out and formats option information for a given class. If the
85
+ class has a ``unique_name`` attribute then that will be printed as well.
86
+ If the class has an ``options`` attribute with options defined in a
87
+ dictionary, then each option will be printed in a list with its
88
+ explanation, bounds, and default value.
89
+ """
90
+ # Source name tells sphinx which document is being writtne to
91
+ source_name = self.get_sourcename()
92
+ # A reference to the class object
93
+ obj = self.object
94
+
95
+ was_printed = False
96
+
97
+ # Print unique name
98
+ if hasattr(obj, 'unique_name'):
99
+ # Add space between class description and this
100
+ self.add_line('|', source_name)
101
+ self.add_line('', source_name)
102
+ # Give the title a CSS class for styling
103
+ self.add_line('.. rst-class:: title', source_name)
104
+ self.add_line('', source_name)
105
+ self.add_line(f'**Identifier:** *{obj.unique_name}*', source_name)
106
+ self.add_line('', source_name)
107
+
108
+ was_printed = True
109
+
110
+ # Print options list
111
+ if hasattr(obj, 'options'):
112
+ self.add_line('|', source_name)
113
+ self.add_line('', source_name)
114
+ self.add_line('.. rst-class:: title', source_name)
115
+ self.add_line('', source_name)
116
+ self.add_line('**Options**', source_name)
117
+ self.add_line('', source_name)
118
+
119
+ # Add options-list class to style options list
120
+ self.add_line('.. rst-class:: options-list', source_name)
121
+ self.add_line('', source_name)
122
+
123
+ tab = ' '
124
+ # Print option info
125
+ for name, info in obj.options.items():
126
+ # Name
127
+ self.add_line(f'- **{name}**', source_name)
128
+ self.add_line('', source_name)
129
+ # Explanation
130
+ self.add_line(' ' + info['expl'], source_name)
131
+ self.add_line('', source_name)
132
+ # Bounds
133
+ self.add_line(tab + f'- Bounds: {info["bounds"]}', source_name)
134
+ # Default value
135
+ if isinstance(info['value'], (int, float)):
136
+ self.add_line(tab + f'- Default: {info["value"]:,}', source_name)
137
+ else:
138
+ self.add_line(tab + f'- Default: {info["value"]}', source_name)
139
+
140
+ was_printed = True
141
+
142
+ # Add a gap between content printed above and method summary table
143
+ if was_printed:
144
+ self.add_line('', source_name)
145
+ self.add_line('|', source_name)
146
+
147
+ # Make sure there is a blank line at the end so nothing breaks
148
+ self.add_line('', source_name)
149
+
150
+ def _print_known_solution(self):
151
+ # Source name tells sphinx which document is being writtne to
152
+ source_name = self.get_sourcename()
153
+ # A reference to the class object
154
+ obj = self.object
155
+
156
+ # Don't print anything if there is no known_solution property
157
+ if not hasattr(obj, 'known_solution'):
158
+ return
159
+
160
+ # Instantiate the class so we can access it's properties
161
+ # Skip classes that aren't fully defined (ie. missing abstract methods)
162
+ try:
163
+ inst = obj()
164
+ except TypeError:
165
+ return
166
+
167
+ # Get known solution, variable names, and response names
168
+ sol = inst.known_solution
169
+ variables = list(inst.problem['variables'].keys())
170
+ responses = list(inst.problem['responses'].keys())
171
+
172
+ # Add space between docstring and solution table
173
+ self.add_line('|', source_name)
174
+ self.add_line('', source_name)
175
+ # Add CSS title class to format Known Solution title
176
+ self.add_line('.. rst-class:: title', source_name)
177
+ self.add_line('', source_name)
178
+
179
+ # No known solution
180
+ if sol is None:
181
+ self.add_line('**Known Solution**', source_name)
182
+ self.add_line('', source_name)
183
+ self.add_line('No known solution!', source_name)
184
+ # Print known solution(s)
185
+ else:
186
+ # Print title
187
+ if len(sol) == 1:
188
+ self.add_line('**Known Solution**', source_name)
189
+ else:
190
+ self.add_line('**Known Solutions**', source_name)
191
+
192
+ self.add_line('', source_name)
193
+
194
+ tab = ' '*4
195
+
196
+ # Create table with a row for each solution
197
+ self.add_line('.. list-table::', source_name)
198
+ # Table will span whole width of rendered area
199
+ self.add_line(tab + ':width: 100', source_name)
200
+ # Only one header row
201
+ self.add_line(tab + ':header-rows: 1', source_name)
202
+ self.add_line('', source_name)
203
+
204
+ # Fill in header row
205
+ for i, name in enumerate(variables + responses):
206
+ if i == 0:
207
+ self.add_line(tab + f'* - {name}', source_name)
208
+ else:
209
+ self.add_line(tab + f' - {name}', source_name)
210
+
211
+ # Fill in table
212
+ for i in range(len(sol)):
213
+ row = sol.iloc[i]
214
+
215
+ for j, name in enumerate(variables + responses):
216
+ if j == 0:
217
+ self.add_line(tab + f'* - {row[name]}', source_name)
218
+ else:
219
+ self.add_line(tab + f' - {row[name]}', source_name)
220
+
221
+ # Add gap between this and content below
222
+ self.add_line('', source_name)
223
+ self.add_line('|', source_name)
224
+ self.add_line('', source_name)
225
+
226
+
227
+ def setup(app: Sphinx) -> None:
228
+ """Loads in required extensions and registers actions, documenters, etc.
229
+ with Sphinx to allow them to be used.
230
+
231
+ Parameters
232
+ ----------
233
+ app : Sphinx
234
+ The current Sphinx instance.
235
+ """
236
+ # Load the autodoc and autodocsumm extentsions since both are required
237
+ app.setup_extension('sphinx.ext.autodoc')
238
+ app.setup_extension('autodocsumm')
239
+
240
+ # Register this custom documenter with Sphinx
241
+ # Set override to True so that warnings are not given about existing name
242
+ app.add_autodocumenter(FormatClass, override=True)
@@ -0,0 +1,35 @@
1
+ /* Put properties on their own lines */
2
+ dl.property {
3
+ display: block !important;
4
+ }
5
+
6
+
7
+ /* Add space between options */
8
+ ul.options-list > li:last-child {
9
+ margin-bottom: 1em;
10
+ }
11
+
12
+ /* Remove marker before option name */
13
+ ul.options-list > li::marker {
14
+ content: none;
15
+ }
16
+
17
+ /* Change spacing around option explanation */
18
+ ul.options-list > li > p:nth-child(2) {
19
+ margin: -.75em 0 -.25em .75em;
20
+ }
21
+
22
+ /* Change marker on option info to en dash */
23
+ ul.options-list > li > ul > li::marker {
24
+ content: "– ";
25
+ }
26
+
27
+ /* Increase font size on identifier and option title */
28
+ p.title {
29
+ font-size: 1.25em;
30
+ }
31
+
32
+ /* reduce space between titles */
33
+ .title ~ .line-block {
34
+ margin: 0;
35
+ }
@@ -0,0 +1,35 @@
1
+ /* Make the documentation content a little wider */
2
+ .wy-nav-content {
3
+ max-width: 65%;
4
+ }
5
+
6
+
7
+ /* Slightly reduce dataframe font size to make it easier to view/read. Also,
8
+ make it so that wide dataframes have a horizontal scrollbar */
9
+ div.output table.dataframe {
10
+ display: block;
11
+ font-size: .75em;
12
+ overflow-x: auto;
13
+ width: fit-content;
14
+ margin: auto;
15
+ }
16
+
17
+ /* Make index column stick to left */
18
+ table.dataframe tbody th {
19
+ position: sticky;
20
+ left: 0;
21
+ }
22
+
23
+ /* Give index cells a background to not show values beneath */
24
+ table.dataframe tbody tr:nth-child(even) th {
25
+ background-color: white;
26
+ }
27
+ table.dataframe tbody tr:nth-child(even):hover th {
28
+ background-color: #d9edfd;
29
+ }
30
+ table.dataframe tbody tr:nth-child(odd) th {
31
+ background-color: #f5f5f5;
32
+ }
33
+ table.dataframe tbody tr:nth-child(odd):hover th {
34
+ background: #d7e8f5;
35
+ }
@@ -0,0 +1,7 @@
1
+ // Configure the require.js package to recognize plotly
2
+ requirejs.config({
3
+ paths: {
4
+ base: '/static/base',
5
+ Plotly: 'https://cdn.plot.ly/plotly-latest.min.js',
6
+ },
7
+ });
@@ -0,0 +1,5 @@
1
+ /** vim: et:ts=4:sw=4:sts=4
2
+ * @license RequireJS 2.3.6 Copyright jQuery Foundation and other contributors.
3
+ * Released under MIT license, https://github.com/requirejs/requirejs/blob/master/LICENSE
4
+ */
5
+ var requirejs,require,define;!function(global,setTimeout){var req,s,head,baseElement,dataMain,src,interactiveScript,currentlyAddingScript,mainScript,subPath,version="2.3.6",commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,currDirRegExp=/^\.\//,op=Object.prototype,ostring=op.toString,hasOwn=op.hasOwnProperty,isBrowser=!("undefined"==typeof window||"undefined"==typeof navigator||!window.document),isWebWorker=!isBrowser&&"undefined"!=typeof importScripts,readyRegExp=isBrowser&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,defContextName="_",isOpera="undefined"!=typeof opera&&"[object Opera]"===opera.toString(),contexts={},cfg={},globalDefQueue=[],useInteractive=!1;function commentReplace(e,t){return t||""}function isFunction(e){return"[object Function]"===ostring.call(e)}function isArray(e){return"[object Array]"===ostring.call(e)}function each(e,t){var i;if(e)for(i=0;i<e.length&&(!e[i]||!t(e[i],i,e));i+=1);}function eachReverse(e,t){var i;if(e)for(i=e.length-1;-1<i&&(!e[i]||!t(e[i],i,e));i-=1);}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return hasProp(e,t)&&e[t]}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(i,e,r,n){return e&&eachProp(e,function(e,t){!r&&hasProp(i,t)||(!n||"object"!=typeof e||!e||isArray(e)||isFunction(e)||e instanceof RegExp?i[t]=e:(i[t]||(i[t]={}),mixin(i[t],e,r,n)))}),i}function bind(e,t){return function(){return t.apply(e,arguments)}}function scripts(){return document.getElementsByTagName("script")}function defaultOnError(e){throw e}function getGlobal(e){if(!e)return e;var t=global;return each(e.split("."),function(e){t=t[e]}),t}function makeError(e,t,i,r){var n=new Error(t+"\nhttps://requirejs.org/docs/errors.html#"+e);return n.requireType=e,n.requireModules=r,i&&(n.originalError=i),n}if(void 0===define){if(void 0!==requirejs){if(isFunction(requirejs))return;cfg=requirejs,requirejs=void 0}void 0===require||isFunction(require)||(cfg=require,require=void 0),req=requirejs=function(e,t,i,r){var n,o,a=defContextName;return isArray(e)||"string"==typeof e||(o=e,isArray(t)?(e=t,t=i,i=r):e=[]),o&&o.context&&(a=o.context),(n=getOwn(contexts,a))||(n=contexts[a]=req.s.newContext(a)),o&&n.configure(o),n.require(e,t,i)},req.config=function(e){return req(e)},req.nextTick=void 0!==setTimeout?function(e){setTimeout(e,4)}:function(e){e()},require||(require=req),req.version=version,req.jsExtRegExp=/^\/|:|\?|\.js$/,req.isBrowser=isBrowser,s=req.s={contexts:contexts,newContext:newContext},req({}),each(["toUrl","undef","defined","specified"],function(t){req[t]=function(){var e=contexts[defContextName];return e.require[t].apply(e,arguments)}}),isBrowser&&(head=s.head=document.getElementsByTagName("head")[0],baseElement=document.getElementsByTagName("base")[0],baseElement&&(head=s.head=baseElement.parentNode)),req.onError=defaultOnError,req.createNode=function(e,t,i){var r=e.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");return r.type=e.scriptType||"text/javascript",r.charset="utf-8",r.async=!0,r},req.load=function(t,i,r){var e,n=t&&t.config||{};if(isBrowser)return(e=req.createNode(n,i,r)).setAttribute("data-requirecontext",t.contextName),e.setAttribute("data-requiremodule",i),!e.attachEvent||e.attachEvent.toString&&e.attachEvent.toString().indexOf("[native code")<0||isOpera?(e.addEventListener("load",t.onScriptLoad,!1),e.addEventListener("error",t.onScriptError,!1)):(useInteractive=!0,e.attachEvent("onreadystatechange",t.onScriptLoad)),e.src=r,n.onNodeCreated&&n.onNodeCreated(e,n,i,r),currentlyAddingScript=e,baseElement?head.insertBefore(e,baseElement):head.appendChild(e),currentlyAddingScript=null,e;if(isWebWorker)try{setTimeout(function(){},0),importScripts(r),t.completeLoad(i)}catch(e){t.onError(makeError("importscripts","importScripts failed for "+i+" at "+r,e,[i]))}},isBrowser&&!cfg.skipDataMain&&eachReverse(scripts(),function(e){if(head||(head=e.parentNode),dataMain=e.getAttribute("data-main"))return mainScript=dataMain,cfg.baseUrl||-1!==mainScript.indexOf("!")||(mainScript=(src=mainScript.split("/")).pop(),subPath=src.length?src.join("/")+"/":"./",cfg.baseUrl=subPath),mainScript=mainScript.replace(jsSuffixRegExp,""),req.jsExtRegExp.test(mainScript)&&(mainScript=dataMain),cfg.deps=cfg.deps?cfg.deps.concat(mainScript):[mainScript],!0}),define=function(e,i,t){var r,n;"string"!=typeof e&&(t=i,i=e,e=null),isArray(i)||(t=i,i=null),!i&&isFunction(t)&&(i=[],t.length&&(t.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,t){i.push(t)}),i=(1===t.length?["require"]:["require","exports","module"]).concat(i))),useInteractive&&(r=currentlyAddingScript||getInteractiveScript())&&(e||(e=r.getAttribute("data-requiremodule")),n=contexts[r.getAttribute("data-requirecontext")]),n?(n.defQueue.push([e,i,t]),n.defQueueMap[e]=!0):globalDefQueue.push([e,i,t])},define.amd={jQuery:!0},req.exec=function(text){return eval(text)},req(cfg)}function newContext(u){var i,e,l,c,d,g={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},p={},f={},r={},h=[],m={},n={},v={},x=1,b=1;function q(e,t,i){var r,n,o,a,s,u,c,d,p,f,l=t&&t.split("/"),h=g.map,m=h&&h["*"];if(e&&(u=(e=e.split("/")).length-1,g.nodeIdCompat&&jsSuffixRegExp.test(e[u])&&(e[u]=e[u].replace(jsSuffixRegExp,"")),"."===e[0].charAt(0)&&l&&(e=l.slice(0,l.length-1).concat(e)),function(e){var t,i;for(t=0;t<e.length;t++)if("."===(i=e[t]))e.splice(t,1),t-=1;else if(".."===i){if(0===t||1===t&&".."===e[2]||".."===e[t-1])continue;0<t&&(e.splice(t-1,2),t-=2)}}(e),e=e.join("/")),i&&h&&(l||m)){e:for(o=(n=e.split("/")).length;0<o;o-=1){if(s=n.slice(0,o).join("/"),l)for(a=l.length;0<a;a-=1)if((r=getOwn(h,l.slice(0,a).join("/")))&&(r=getOwn(r,s))){c=r,d=o;break e}!p&&m&&getOwn(m,s)&&(p=getOwn(m,s),f=o)}!c&&p&&(c=p,d=f),c&&(n.splice(0,d,c),e=n.join("/"))}return getOwn(g.pkgs,e)||e}function E(t){isBrowser&&each(scripts(),function(e){if(e.getAttribute("data-requiremodule")===t&&e.getAttribute("data-requirecontext")===l.contextName)return e.parentNode.removeChild(e),!0})}function w(e){var t=getOwn(g.paths,e);if(t&&isArray(t)&&1<t.length)return t.shift(),l.require.undef(e),l.makeRequire(null,{skipMap:!0})([e]),!0}function y(e){var t,i=e?e.indexOf("!"):-1;return-1<i&&(t=e.substring(0,i),e=e.substring(i+1,e.length)),[t,e]}function S(e,t,i,r){var n,o,a,s,u=null,c=t?t.name:null,d=e,p=!0,f="";return e||(p=!1,e="_@r"+(x+=1)),u=(s=y(e))[0],e=s[1],u&&(u=q(u,c,r),o=getOwn(m,u)),e&&(u?f=i?e:o&&o.normalize?o.normalize(e,function(e){return q(e,c,r)}):-1===e.indexOf("!")?q(e,c,r):e:(u=(s=y(f=q(e,c,r)))[0],f=s[1],i=!0,n=l.nameToUrl(f))),{prefix:u,name:f,parentMap:t,unnormalized:!!(a=!u||o||i?"":"_unnormalized"+(b+=1)),url:n,originalName:d,isDefine:p,id:(u?u+"!"+f:f)+a}}function k(e){var t=e.id,i=getOwn(p,t);return i||(i=p[t]=new l.Module(e)),i}function M(e,t,i){var r=e.id,n=getOwn(p,r);!hasProp(m,r)||n&&!n.defineEmitComplete?(n=k(e)).error&&"error"===t?i(n.error):n.on(t,i):"defined"===t&&i(m[r])}function O(i,e){var t=i.requireModules,r=!1;e?e(i):(each(t,function(e){var t=getOwn(p,e);t&&(t.error=i,t.events.error&&(r=!0,t.emit("error",i)))}),r||req.onError(i))}function j(){globalDefQueue.length&&(each(globalDefQueue,function(e){var t=e[0];"string"==typeof t&&(l.defQueueMap[t]=!0),h.push(e)}),globalDefQueue=[])}function P(e){delete p[e],delete f[e]}function R(){var e,r,t=1e3*g.waitSeconds,n=t&&l.startTime+t<(new Date).getTime(),o=[],a=[],s=!1,u=!0;if(!i){if(i=!0,eachProp(f,function(e){var t=e.map,i=t.id;if(e.enabled&&(t.isDefine||a.push(e),!e.error))if(!e.inited&&n)w(i)?s=r=!0:(o.push(i),E(i));else if(!e.inited&&e.fetched&&t.isDefine&&(s=!0,!t.prefix))return u=!1}),n&&o.length)return(e=makeError("timeout","Load timeout for modules: "+o,null,o)).contextName=l.contextName,O(e);u&&each(a,function(e){!function n(o,a,s){var e=o.map.id;o.error?o.emit("error",o.error):(a[e]=!0,each(o.depMaps,function(e,t){var i=e.id,r=getOwn(p,i);!r||o.depMatched[t]||s[i]||(getOwn(a,i)?(o.defineDep(t,m[i]),o.check()):n(r,a,s))}),s[e]=!0)}(e,{},{})}),n&&!r||!s||!isBrowser&&!isWebWorker||d||(d=setTimeout(function(){d=0,R()},50)),i=!1}}function a(e){hasProp(m,e[0])||k(S(e[0],null,!0)).init(e[1],e[2])}function o(e,t,i,r){e.detachEvent&&!isOpera?r&&e.detachEvent(r,t):e.removeEventListener(i,t,!1)}function s(e){var t=e.currentTarget||e.srcElement;return o(t,l.onScriptLoad,"load","onreadystatechange"),o(t,l.onScriptError,"error"),{node:t,id:t&&t.getAttribute("data-requiremodule")}}function T(){var e;for(j();h.length;){if(null===(e=h.shift())[0])return O(makeError("mismatch","Mismatched anonymous define() module: "+e[e.length-1]));a(e)}l.defQueueMap={}}return c={require:function(e){return e.require?e.require:e.require=l.makeRequire(e.map)},exports:function(e){if(e.usingExports=!0,e.map.isDefine)return e.exports?m[e.map.id]=e.exports:e.exports=m[e.map.id]={}},module:function(e){return e.module?e.module:e.module={id:e.map.id,uri:e.map.url,config:function(){return getOwn(g.config,e.map.id)||{}},exports:e.exports||(e.exports={})}}},(e=function(e){this.events=getOwn(r,e.id)||{},this.map=e,this.shim=getOwn(g.shim,e.id),this.depExports=[],this.depMaps=[],this.depMatched=[],this.pluginMaps={},this.depCount=0}).prototype={init:function(e,t,i,r){r=r||{},this.inited||(this.factory=t,i?this.on("error",i):this.events.error&&(i=bind(this,function(e){this.emit("error",e)})),this.depMaps=e&&e.slice(0),this.errback=i,this.inited=!0,this.ignore=r.ignore,r.enabled||this.enabled?this.enable():this.check())},defineDep:function(e,t){this.depMatched[e]||(this.depMatched[e]=!0,this.depCount-=1,this.depExports[e]=t)},fetch:function(){if(!this.fetched){this.fetched=!0,l.startTime=(new Date).getTime();var e=this.map;if(!this.shim)return e.prefix?this.callPlugin():this.load();l.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],bind(this,function(){return e.prefix?this.callPlugin():this.load()}))}},load:function(){var e=this.map.url;n[e]||(n[e]=!0,l.load(this.map.id,e))},check:function(){if(this.enabled&&!this.enabling){var t,e,i=this.map.id,r=this.depExports,n=this.exports,o=this.factory;if(this.inited){if(this.error)this.emit("error",this.error);else if(!this.defining){if(this.defining=!0,this.depCount<1&&!this.defined){if(isFunction(o)){if(this.events.error&&this.map.isDefine||req.onError!==defaultOnError)try{n=l.execCb(i,o,r,n)}catch(e){t=e}else n=l.execCb(i,o,r,n);if(this.map.isDefine&&void 0===n&&((e=this.module)?n=e.exports:this.usingExports&&(n=this.exports)),t)return t.requireMap=this.map,t.requireModules=this.map.isDefine?[this.map.id]:null,t.requireType=this.map.isDefine?"define":"require",O(this.error=t)}else n=o;if(this.exports=n,this.map.isDefine&&!this.ignore&&(m[i]=n,req.onResourceLoad)){var a=[];each(this.depMaps,function(e){a.push(e.normalizedMap||e)}),req.onResourceLoad(l,this.map,a)}P(i),this.defined=!0}this.defining=!1,this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else hasProp(l.defQueueMap,i)||this.fetch()}},callPlugin:function(){var u=this.map,c=u.id,e=S(u.prefix);this.depMaps.push(e),M(e,"defined",bind(this,function(e){var o,t,i,r=getOwn(v,this.map.id),n=this.map.name,a=this.map.parentMap?this.map.parentMap.name:null,s=l.makeRequire(u.parentMap,{enableBuildCallback:!0});return this.map.unnormalized?(e.normalize&&(n=e.normalize(n,function(e){return q(e,a,!0)})||""),M(t=S(u.prefix+"!"+n,this.map.parentMap,!0),"defined",bind(this,function(e){this.map.normalizedMap=t,this.init([],function(){return e},null,{enabled:!0,ignore:!0})})),void((i=getOwn(p,t.id))&&(this.depMaps.push(t),this.events.error&&i.on("error",bind(this,function(e){this.emit("error",e)})),i.enable()))):r?(this.map.url=l.nameToUrl(r),void this.load()):((o=bind(this,function(e){this.init([],function(){return e},null,{enabled:!0})})).error=bind(this,function(e){this.inited=!0,(this.error=e).requireModules=[c],eachProp(p,function(e){0===e.map.id.indexOf(c+"_unnormalized")&&P(e.map.id)}),O(e)}),o.fromText=bind(this,function(e,t){var i=u.name,r=S(i),n=useInteractive;t&&(e=t),n&&(useInteractive=!1),k(r),hasProp(g.config,c)&&(g.config[i]=g.config[c]);try{req.exec(e)}catch(e){return O(makeError("fromtexteval","fromText eval for "+c+" failed: "+e,e,[c]))}n&&(useInteractive=!0),this.depMaps.push(r),l.completeLoad(i),s([i],o)}),void e.load(u.name,s,o,g))})),l.enable(e,this),this.pluginMaps[e.id]=e},enable:function(){(f[this.map.id]=this).enabled=!0,this.enabling=!0,each(this.depMaps,bind(this,function(e,t){var i,r,n;if("string"==typeof e){if(e=S(e,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap),this.depMaps[t]=e,n=getOwn(c,e.id))return void(this.depExports[t]=n(this));this.depCount+=1,M(e,"defined",bind(this,function(e){this.undefed||(this.defineDep(t,e),this.check())})),this.errback?M(e,"error",bind(this,this.errback)):this.events.error&&M(e,"error",bind(this,function(e){this.emit("error",e)}))}i=e.id,r=p[i],hasProp(c,i)||!r||r.enabled||l.enable(e,this)})),eachProp(this.pluginMaps,bind(this,function(e){var t=getOwn(p,e.id);t&&!t.enabled&&l.enable(e,this)})),this.enabling=!1,this.check()},on:function(e,t){var i=this.events[e];i||(i=this.events[e]=[]),i.push(t)},emit:function(e,t){each(this.events[e],function(e){e(t)}),"error"===e&&delete this.events[e]}},(l={config:g,contextName:u,registry:p,defined:m,urlFetched:n,defQueue:h,defQueueMap:{},Module:e,makeModuleMap:S,nextTick:req.nextTick,onError:O,configure:function(e){if(e.baseUrl&&"/"!==e.baseUrl.charAt(e.baseUrl.length-1)&&(e.baseUrl+="/"),"string"==typeof e.urlArgs){var i=e.urlArgs;e.urlArgs=function(e,t){return(-1===t.indexOf("?")?"?":"&")+i}}var r=g.shim,n={paths:!0,bundles:!0,config:!0,map:!0};eachProp(e,function(e,t){n[t]?(g[t]||(g[t]={}),mixin(g[t],e,!0,!0)):g[t]=e}),e.bundles&&eachProp(e.bundles,function(e,t){each(e,function(e){e!==t&&(v[e]=t)})}),e.shim&&(eachProp(e.shim,function(e,t){isArray(e)&&(e={deps:e}),!e.exports&&!e.init||e.exportsFn||(e.exportsFn=l.makeShimExports(e)),r[t]=e}),g.shim=r),e.packages&&each(e.packages,function(e){var t;t=(e="string"==typeof e?{name:e}:e).name,e.location&&(g.paths[t]=e.location),g.pkgs[t]=e.name+"/"+(e.main||"main").replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),eachProp(p,function(e,t){e.inited||e.map.unnormalized||(e.map=S(t,null,!0))}),(e.deps||e.callback)&&l.require(e.deps||[],e.callback)},makeShimExports:function(t){return function(){var e;return t.init&&(e=t.init.apply(global,arguments)),e||t.exports&&getGlobal(t.exports)}},makeRequire:function(o,a){function s(e,t,i){var r,n;return a.enableBuildCallback&&t&&isFunction(t)&&(t.__requireJsBuild=!0),"string"==typeof e?isFunction(t)?O(makeError("requireargs","Invalid require call"),i):o&&hasProp(c,e)?c[e](p[o.id]):req.get?req.get(l,e,o,s):(r=S(e,o,!1,!0).id,hasProp(m,r)?m[r]:O(makeError("notloaded",'Module name "'+r+'" has not been loaded yet for context: '+u+(o?"":". Use require([])")))):(T(),l.nextTick(function(){T(),(n=k(S(null,o))).skipMap=a.skipMap,n.init(e,t,i,{enabled:!0}),R()}),s)}return a=a||{},mixin(s,{isBrowser:isBrowser,toUrl:function(e){var t,i=e.lastIndexOf("."),r=e.split("/")[0];return-1!==i&&(!("."===r||".."===r)||1<i)&&(t=e.substring(i,e.length),e=e.substring(0,i)),l.nameToUrl(q(e,o&&o.id,!0),t,!0)},defined:function(e){return hasProp(m,S(e,o,!1,!0).id)},specified:function(e){return e=S(e,o,!1,!0).id,hasProp(m,e)||hasProp(p,e)}}),o||(s.undef=function(i){j();var e=S(i,o,!0),t=getOwn(p,i);t.undefed=!0,E(i),delete m[i],delete n[e.url],delete r[i],eachReverse(h,function(e,t){e[0]===i&&h.splice(t,1)}),delete l.defQueueMap[i],t&&(t.events.defined&&(r[i]=t.events),P(i))}),s},enable:function(e){getOwn(p,e.id)&&k(e).enable()},completeLoad:function(e){var t,i,r,n=getOwn(g.shim,e)||{},o=n.exports;for(j();h.length;){if(null===(i=h.shift())[0]){if(i[0]=e,t)break;t=!0}else i[0]===e&&(t=!0);a(i)}if(l.defQueueMap={},r=getOwn(p,e),!t&&!hasProp(m,e)&&r&&!r.inited){if(!(!g.enforceDefine||o&&getGlobal(o)))return w(e)?void 0:O(makeError("nodefine","No define call for "+e,null,[e]));a([e,n.deps||[],n.exportsFn])}R()},nameToUrl:function(e,t,i){var r,n,o,a,s,u,c=getOwn(g.pkgs,e);if(c&&(e=c),u=getOwn(v,e))return l.nameToUrl(u,t,i);if(req.jsExtRegExp.test(e))a=e+(t||"");else{for(r=g.paths,o=(n=e.split("/")).length;0<o;o-=1)if(s=getOwn(r,n.slice(0,o).join("/"))){isArray(s)&&(s=s[0]),n.splice(0,o,s);break}a=n.join("/"),a=("/"===(a+=t||(/^data\:|^blob\:|\?/.test(a)||i?"":".js")).charAt(0)||a.match(/^[\w\+\.\-]+:/)?"":g.baseUrl)+a}return g.urlArgs&&!/^blob\:/.test(a)?a+g.urlArgs(e,a):a},load:function(e,t){req.load(l,e,t)},execCb:function(e,t,i,r){return t.apply(r,i)},onScriptLoad:function(e){if("load"===e.type||readyRegExp.test((e.currentTarget||e.srcElement).readyState)){interactiveScript=null;var t=s(e);l.completeLoad(t.id)}},onScriptError:function(e){var i=s(e);if(!w(i.id)){var r=[];return eachProp(p,function(e,t){0!==t.indexOf("_@r")&&each(e.depMaps,function(e){if(e.id===i.id)return r.push(t),!0})}),O(makeError("scripterror",'Script error for "'+i.id+(r.length?'", needed by: '+r.join(", "):'"'),e,[i.id]))}}}).require=l.makeRequire(),l}function getInteractiveScript(){return interactiveScript&&"interactive"===interactiveScript.readyState||eachReverse(scripts(),function(e){if("interactive"===e.readyState)return interactiveScript=e}),interactiveScript}}(this,"undefined"==typeof setTimeout?void 0:setTimeout);
@@ -0,0 +1,2 @@
1
+ {% extends '!footer.html' %} {% block extrafooter %} {{super}}
2
+ {% endblock %}